diff --git a/.eslintrc.js b/.eslintrc.js index 194ad5ac..3f060f59 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -111,7 +111,8 @@ module.exports = { 'no-mixed-requires': 2, 'no-new-require': 0, 'no-path-concat': 1, - 'no-sync': 1 + 'no-sync': 1, + 'no-mixed-operators': 1 // stylistic (leaving up to standard) // ECMAScript 6 (tbd) diff --git a/lerna.json b/lerna.json index bbbf77cc..e365f79e 100644 --- a/lerna.json +++ b/lerna.json @@ -2,5 +2,5 @@ "packages": [ "packages/*" ], - "version": "0.10.0" + "version": "0.11.0" } diff --git a/packages/ptokens-deposit-address/package.json b/packages/ptokens-deposit-address/package.json index f7390534..7c5d496e 100644 --- a/packages/ptokens-deposit-address/package.json +++ b/packages/ptokens-deposit-address/package.json @@ -1,6 +1,6 @@ { "name": "ptokens-deposit-address", - "version": "0.10.0", + "version": "0.11.0", "description": "repo holding the code related to deposit addresses", "repository": "https://github.com/provable-things/ptokens.js/tree/master/packages/ptokens-deposit-address", "main": "dist/ptokens-deposit-address.cjs.js", @@ -32,9 +32,9 @@ "bitcoinjs-lib": "^5.1.6", "chai": "^4.2.0", "eosjs": "^20.0.3", - "ptokens-node": "^0.10.0", - "ptokens-providers": "^0.10.0", - "ptokens-utils": "^0.10.0", + "ptokens-node": "^0.11.0", + "ptokens-providers": "^0.11.0", + "ptokens-utils": "^0.11.0", "web3": "^1.2.2" }, "devDependencies": { diff --git a/packages/ptokens-deposit-address/src/index.js b/packages/ptokens-deposit-address/src/index.js index 197aa3b8..c112a8af 100644 --- a/packages/ptokens-deposit-address/src/index.js +++ b/packages/ptokens-deposit-address/src/index.js @@ -1,5 +1,4 @@ import Web3PromiEvent from 'web3-core-promievent' -import Web3Utils from 'web3-utils' import BigNumber from 'bignumber.js' import * as bitcoin from 'bitcoinjs-lib' import * as utils from 'ptokens-utils' @@ -10,7 +9,8 @@ const POLLING_TIME = 3000 const confirmations = { btc: 1, ltc: 4, - doge: 1 + doge: 1, + rvn: 25 } // NOTE: will be removed in versions >= 1.0.0 @@ -44,7 +44,7 @@ bitcoin.networks.litecoinTestnet = { } bitcoin.networks.dogecoin = { - messagePrefix: '\x19Dogecoin Signed Message:\n', + messagePrefix: '\x1aRavencoin Signed Message:\n', bip32: { public: 0x02facafd, private: 0x02fac398 @@ -54,10 +54,21 @@ bitcoin.networks.dogecoin = { wif: 0x9e } +bitcoin.networks.ravencoin = { + messagePrefix: '\x1aRavencoin Signed Message:\n', + bip32: { + public: 0x0488b21e, + private: 0x0488ade4 + }, + pubKeyHash: 0x3c, + scriptHash: 0x7a, + wif: 0x80 +} + const { constants: { - networks: { BitcoinMainnet, BitcoinTestnet, LitecoinMainnet, LitecoinTestnet, DogecoinMainnet }, - blockchains: { Bitcoin, Litecoin, Dogecoin } + networks: { BitcoinMainnet, BitcoinTestnet, LitecoinMainnet, LitecoinTestnet, DogecoinMainnet, RavencoinMainnet }, + blockchains: { Bitcoin, Litecoin, Dogecoin, Ravencoin } } } = utils const NETWORKS = { @@ -71,6 +82,9 @@ const NETWORKS = { }, [Dogecoin]: { [DogecoinMainnet]: bitcoin.networks.dogecoin + }, + [Ravencoin]: { + [RavencoinMainnet]: bitcoin.networks.ravencoin } } @@ -93,12 +107,6 @@ export class DepositAddress { * @param {String} _hostAddress */ async generate(_hostAddress) { - if (this.hostBlockchain === utils.constants.blockchains.Ethereum && !Web3Utils.isAddress(_hostAddress)) - throw new Error('Invalid Ethereum Address') - - if (this.hostBlockchain === utils.constants.blockchains.Eosio && !utils.eos.isValidAccountName(_hostAddress)) - throw new Error('Invalid EOS Account') - try { const { nonce, enclavePublicKey, nativeDepositAddress } = await this.node.getNativeDepositAddress(_hostAddress) @@ -122,6 +130,7 @@ export class DepositAddress { blockchains: { Eosio, Telos } } } = utils + const network = NETWORKS[this.nativeBlockchain][this.nativeNetwork] if (!network) throw new Error('Please use a valid combination of nativeNetwork and nativeBlockchain') @@ -152,12 +161,12 @@ export class DepositAddress { waitForDeposit() { const promiEvent = Web3PromiEvent() - if (!this.hostApi) { - promiEvent.reject('Provider not specified. Impossible to monitor the tx') - return - } - const start = async () => { + if (!this.hostApi) { + promiEvent.reject('Provider not specified. Impossible to monitor the tx') + return + } + if (!this.value) promiEvent.reject('Please generate a deposit address') const shortNativeBlockchain = utils.helpers.getBlockchainShortType(this.nativeBlockchain) @@ -174,7 +183,9 @@ export class DepositAddress { ) const broadcastedHostTxReport = await this.node.monitorIncomingTransaction(nativeTxId, promiEvent.eventEmitter) - const hostTxReceipt = await utils[shortHostBlockchain].waitForTransactionConfirmation( + const hostTxReceipt = await utils[ + shortHostBlockchain === 'bsc' ? 'eth' : shortHostBlockchain + ].waitForTransactionConfirmation( this.hostApi, broadcastedHostTxReport.broadcast_tx_hash, HOST_NODE_POLLING_TIME_INTERVAL diff --git a/packages/ptokens-deposit-address/tests/ptokens-deposit-address.test.js b/packages/ptokens-deposit-address/tests/ptokens-deposit-address.test.js index a6510981..88eaa922 100644 --- a/packages/ptokens-deposit-address/tests/ptokens-deposit-address.test.js +++ b/packages/ptokens-deposit-address/tests/ptokens-deposit-address.test.js @@ -13,6 +13,7 @@ const PLTC_ON_ETH_MAINNET = 'https://pltconeth-node-1a.ngrok.io' const PBTC_ON_ETH_ROPSTEN = 'https://nuc-bridge-3.ngrok.io/' const PLTC_ON_ETH_ROPSTEN = 'https://nuc-bridge-2.ngrok.io' const PDOGE_ON_ETH_MAINNET = 'http://51.195.136.212:3002' +const PRVN_ON_ETH_MAINNET = 'https://prvnonbsc-node-1a.ngrok.io' const INFURA_MAINNET = 'https://mainnet.infura.io/v3/4762c881ac0c4938be76386339358ed6' const INFURA_ROPSTEN = 'https://ropsten.infura.io/v3/4762c881ac0c4938be76386339358ed6' @@ -223,3 +224,20 @@ test('Should generate correctly a pDOGE deposit address on Ethereum Mainnet', as await depositAddress.generate(ETH_TESTING_ADDRESS) expect(depositAddress.verify()).to.be.eq(true) }) + +test('Should generate correctly a pRVN deposit address on Binance Smart Chain Mainnet', async () => { + const node = new Node({ + pToken: constants.pTokens.pRVN, + blockchain: constants.blockchains.BinanceSmartChain, + provider: new HttpProvider(PRVN_ON_ETH_MAINNET) + }) + const depositAddress = new DepositAddress({ + nativeBlockchain: constants.blockchains.Ravencoin, + nativeNetwork: constants.networks.RavencoinMainnet, + hostBlockchain: constants.blockchains.BinanceSmartChain, + hostNetwork: constants.networks.BinanceSmartChainMainnet, + node + }) + await depositAddress.generate(ETH_TESTING_ADDRESS) + expect(depositAddress.verify()).to.be.eq(true) +}) diff --git a/packages/ptokens-node-selector/package.json b/packages/ptokens-node-selector/package.json index 1fe548a5..61834078 100644 --- a/packages/ptokens-node-selector/package.json +++ b/packages/ptokens-node-selector/package.json @@ -1,6 +1,6 @@ { "name": "ptokens-node-selector", - "version": "0.10.0", + "version": "0.11.0", "description": "repo holding the code for selecting validator nodes", "repository": "https://github.com/provable-things/ptokens.js/tree/master/packages/ptokens-node-selector", "main": "dist/ptokens-node-selector.cjs.js", @@ -20,9 +20,9 @@ "@babel/runtime": "^7.3.1", "@types/node": "^12.6.1", "chai": "^4.2.0", - "ptokens-node": "^0.10.0", - "ptokens-providers": "^0.10.0", - "ptokens-utils": "^0.10.0" + "ptokens-node": "^0.11.0", + "ptokens-providers": "^0.11.0", + "ptokens-utils": "^0.11.0" }, "devDependencies": { "dtslint": "0.4.2", diff --git a/packages/ptokens-node-selector/src/index.js b/packages/ptokens-node-selector/src/index.js index db1d59f2..4f98a55f 100644 --- a/packages/ptokens-node-selector/src/index.js +++ b/packages/ptokens-node-selector/src/index.js @@ -8,49 +8,43 @@ export class NodeSelector { * @param {Object} configs */ constructor(_configs) { - const { pToken, defaultNode } = _configs + if (_configs) this.setParams(_configs) - if (!helpers.isValidPTokenName(pToken)) throw new Error('Invalid pToken name') - - // NOTE: pETH becomes pWETH for nodes interactions - this.pToken = pToken.toLowerCase() === constants.pTokens.pETH ? constants.pTokens.pWETH : pToken.toLowerCase() - - const { hostBlockchain, hostNetwork, nativeBlockchain, nativeNetwork } = helpers.parseParams( - _configs, - _configs.nativeBlockchain - ? helpers.getBlockchainType[_configs.nativeBlockchain] - : helpers.getNativeBlockchainFromPtokenName(this.pToken) - ) - - this.hostBlockchain = hostBlockchain - this.hostNetwork = hostNetwork - this.nativeBlockchain = nativeBlockchain - this.nativeNetwork = nativeNetwork - - this.selectedNode = defaultNode || null this.nodes = [] this.provider = new HttpProvider() } /** + * @description _timeout should be within _options but in order to don't break + * retrocompatibility has been left where it was * @param {String} _endpoint * @param {Number} _timeout + * @param {CheckConnectionOption} _options */ - async checkConnection(_endpoint, _timeout) { + async checkConnection(_endpoint, _timeout, _options = {}) { + const { + pToken: optionalPtoken, + hostBlockchain: optionalHostBlockchain, + hostNetwork: optionalHostNetwork, + nativeBlockchain: optionalNativeBlockchain, + nativeNetwork: optionalNativeNetwork + } = _options try { this.provider.setEndpoint(_endpoint) const { host_blockchain, host_network, native_blockchain, native_network } = await this.provider.call( 'GET', - `/${this.pToken}-on-${helpers.getBlockchainShortType(this.hostBlockchain)}/get-info`, + `/${optionalPtoken || this.pToken}-on-${helpers.getBlockchainShortType( + optionalHostBlockchain || this.hostBlockchain + )}/get-info`, null, _timeout ) return Boolean( - host_blockchain === this.hostBlockchain && - host_network === this.hostNetwork && - native_blockchain === this.nativeBlockchain && - native_network === this.nativeNetwork + host_blockchain === (optionalHostBlockchain || this.hostBlockchain) && + host_network === (optionalHostNetwork || this.hostNetwork) && + native_blockchain === (optionalNativeBlockchain || this.nativeBlockchain) && + native_network === (optionalNativeNetwork || this.nativeNetwork) ) } catch (_err) { throw new Error(`Error during checking node connection: ${_err.message}`) @@ -70,47 +64,120 @@ export class NodeSelector { } } - async select() { + /** + * @param {SelectOptions} _options + */ + async select(_options = {}) { + const { + timeout, + forceFetchingNodes, + nodes: optionalNodes, + pToken: optionalPtoken, + hostBlockchain: optionalHostBlockchain, + hostNetwork: optionalHostNetwork, + nativeBlockchain: optionalNativeBlockchain, + nativeNetwork: optionalNativeNetwork + } = _options + try { - this.provider.setEndpoint(getBootNodeEndpoint(helpers.getNetworkType(this.hostNetwork))) - this.nodes = (await this.provider.call('GET', '/peers')).peers + if ((this.nodes.length === 0 || forceFetchingNodes) && !optionalNodes) + await this.fetchNodes(helpers.getNetworkType(optionalHostNetwork || this.hostNetwork)) - const feature = `${this.pToken}-on-${helpers.getBlockchainShortType(this.hostBlockchain)}` - const filteredNodesByFeature = this.nodes.filter(node => node.features.includes(feature)) - if (filteredNodesByFeature.length === 0) throw new Error('No nodes available relating to the selected pToken') + // prettier-ignore + const feature = `${optionalPtoken || this.pToken}-on-${helpers.getBlockchainShortType(optionalHostBlockchain || this.hostBlockchain)}` + + const filteredNodesByFeature = optionalNodes + ? optionalNodes.filter(({ features }) => features.includes(feature)) + : this.nodes.filter(({ features }) => features.includes(feature)) + if (filteredNodesByFeature.length === 0) + throw new Error(`No nodes available relating to the selected pToken (${feature})`) const nodesNotReachable = [] for (;;) { const index = Math.floor(Math.random() * filteredNodesByFeature.length) const selectedNode = filteredNodesByFeature[index] - - if ((await this.checkConnection(selectedNode.webapi)) && !nodesNotReachable.includes(selectedNode)) - return this.setSelectedNode(selectedNode.webapi) - else if (!nodesNotReachable.includes(selectedNode)) nodesNotReachable.push(selectedNode) + if ( + (await this.checkConnection(selectedNode.webapi, timeout || 5000, { + pToken: optionalPtoken, + nativeNetwork: optionalNativeNetwork, + nativeBlockchain: optionalNativeBlockchain, + hostNetwork: optionalHostNetwork, + hostBlockchain: optionalHostBlockchain + })) && + !nodesNotReachable.includes(selectedNode) + ) { + return this.setSelectedNode(selectedNode.webapi, { + pToken: optionalPtoken, + hostBlockchain: optionalHostBlockchain + }) + } else if (!nodesNotReachable.includes(selectedNode)) { + nodesNotReachable.push(selectedNode) + } if (nodesNotReachable.length === filteredNodesByFeature.length) - throw new Error('All nodes relating to the selected pToken appear to be unavailable') + throw new Error(`All nodes relating to the selected pToken (${feature}) appear to be unavailable`) } - } catch (err) { - throw new Error(err.message) + } catch (_err) { + throw new Error(_err.message) } } /** * @param {String | Node} _node + * @param {SetSelectedNodeOptions} _options */ - setSelectedNode(_node) { + setSelectedNode(_node, _options = {}) { + const { pToken: optionalPtoken, hostBlockchain: optionalHostBlockchain } = _options if (_node instanceof Node) { this.selectedNode = _node return this.selectedNode } this.selectedNode = new Node({ - pToken: this.pToken, - blockchain: this.hostBlockchain, + pToken: optionalPtoken || this.pToken, + blockchain: optionalHostBlockchain || this.hostBlockchain, provider: new HttpProvider(_node) }) return this.selectedNode } + + /** + * @param {Object} configs + */ + setParams(_configs) { + const { defaultNode, pToken } = _configs + + if (!helpers.isValidPTokenName(pToken)) throw new Error('Invalid pToken name') + + // NOTE: pETH becomes pWETH for nodes interactions + this.pToken = pToken.toLowerCase() === constants.pTokens.pETH ? constants.pTokens.pWETH : pToken.toLowerCase() + + const { hostBlockchain, hostNetwork, nativeBlockchain, nativeNetwork } = helpers.parseParams( + _configs, + _configs.nativeBlockchain + ? helpers.getBlockchainType[_configs.nativeBlockchain] + : helpers.getNativeBlockchainFromPtokenName(this.pToken) + ) + + this.hostBlockchain = hostBlockchain + this.hostNetwork = hostNetwork + this.nativeBlockchain = nativeBlockchain + this.nativeNetwork = nativeNetwork + + this.selectedNode = defaultNode || null + } + + /** + * @param {String} _networkType + */ + async fetchNodes(_networkType) { + try { + this.provider.setEndpoint(getBootNodeEndpoint(_networkType)) + this.nodes = (await this.provider.call('GET', '/peers')).peers + return this.nodes + } catch (_err) { + throw new Error(_err.message) + } + } } diff --git a/packages/ptokens-node-selector/tests/ptokens-node-selector.test.js b/packages/ptokens-node-selector/tests/ptokens-node-selector.test.js index 785ed839..b0ed31cf 100644 --- a/packages/ptokens-node-selector/tests/ptokens-node-selector.test.js +++ b/packages/ptokens-node-selector/tests/ptokens-node-selector.test.js @@ -14,6 +14,23 @@ const PLTC_ON_EOS_MAINNET = 'https://pltconeos-node-1a.ngrok.io' // const PETH_ON_EOS_MAINNET = 'https://pethoneos-node-1a.ngrok.io' const UNREACHABLE_NODE = 'https://unreachable-node.io' +test('Should select a pBTC node on EOS Mainnet without constructor parameters', async () => { + const nodeSelector = new NodeSelector() + const node = await nodeSelector.select({ + pToken: constants.pTokens.pBTC, + nativeBlockchain: constants.blockchains.Bitcoin, + nativeNetwork: constants.networks.BitcoinMainnet, + hostNetwork: constants.networks.EosioMainnet, + hostBlockchain: constants.blockchains.Eosio + }) + + const info = await node.getInfo() + expect(info.host_network).to.be.equal(constants.networks.EosioMainnet) + expect(info.host_blockchain).to.be.equal(constants.blockchains.Eosio) + expect(info.native_blockchain).to.be.equal(constants.blockchains.Bitcoin) + expect(info.native_network).to.be.equal(constants.networks.BitcoinMainnet) +}) + test('Should select a pBTC node on EOS Mainnet', async () => { const nodeSelector = new NodeSelector({ pToken: constants.pTokens.pBTC, diff --git a/packages/ptokens-node-selector/types/index.d.ts b/packages/ptokens-node-selector/types/index.d.ts index faaca2dd..114e3d66 100644 --- a/packages/ptokens-node-selector/types/index.d.ts +++ b/packages/ptokens-node-selector/types/index.d.ts @@ -1,4 +1,4 @@ -import { Node, Report } from 'ptokens-node' +import { Node } from 'ptokens-node' import { HttpProvider } from 'ptokens-providers' export interface NodeSelectorConfigs { @@ -12,7 +12,29 @@ export interface NodeSelectorConfigs { defaultNode?: Node, } -export interface NodeList extends Array {} +export interface SelectOptions { + timeout: number, + forceFetchingNodes?: boolean, + nodes?: object[], + pToken: string, + nativeNetwork?: string, + nativeBlockchain?: string, + hostNetwork?: string, + hostBlockchain?: string +} + +export interface CheckConnectionOption { + pToken: string, + nativeNetwork?: string, + nativeBlockchain?: string, + hostNetwork?: string, + hostBlockchain?: string +} + +export interface SetSelectedNodeOptions { + pToken: string, + hostBlockchain?: string +} export class NodeSelector { constructor(_configs: NodeSelectorConfigs) @@ -27,7 +49,7 @@ export class NodeSelector { selectedNode: Node - nodes: NodeList + nodes: Node[] networkType: string @@ -35,11 +57,15 @@ export class NodeSelector { provider: HttpProvider | null - checkConnection(_endpoint: string, _timeout?: number): Promise + checkConnection(_endpoint: string, _timeout?: number, _options?: CheckConnectionOption): Promise getApi(): Promise - select(): Promise + select(_options?: SelectOptions): Promise + + setSelectedNode(_endpoint: string | Node, _options?: SetSelectedNodeOptions): Node + + setParams(_configs: object): any - setSelectedNode(_endpoint: string | Node): Node + fetchNodes(): Promise } diff --git a/packages/ptokens-node-selector/types/tests/ptokens-node-selector-test.ts b/packages/ptokens-node-selector/types/tests/ptokens-node-selector-test.ts index cd3cf255..2daad0f0 100644 --- a/packages/ptokens-node-selector/types/tests/ptokens-node-selector-test.ts +++ b/packages/ptokens-node-selector/types/tests/ptokens-node-selector-test.ts @@ -35,3 +35,13 @@ nodeSelector.setSelectedNode(new Node({ blockchain: 'eth', provider: new HttpProvider('https://unreachable-node.io'), })) + +// $ExpectType any +nodeSelector.setParams({ + pToken: 'pBTC', + network: 'testnet', + blockchain: 'ETH' +}) + +// $ExpectType Promise +nodeSelector.fetchNodes() diff --git a/packages/ptokens-node/package.json b/packages/ptokens-node/package.json index 55e387bf..11fde48e 100644 --- a/packages/ptokens-node/package.json +++ b/packages/ptokens-node/package.json @@ -1,6 +1,6 @@ { "name": "ptokens-node", - "version": "0.10.0", + "version": "0.11.0", "description": "repo holding the code for interacting with a Node", "repository": "https://github.com/provable-things/ptokens.js/tree/master/packages/ptokens-node", "main": "dist/ptokens-node.cjs.js", @@ -30,8 +30,8 @@ "eventemitter3": "^4.0.0", "jsonrpc-lite": "^2.2.0", "light-async-polling": "^1.0.2", - "ptokens-providers": "^0.10.0", - "ptokens-utils": "^0.10.0", + "ptokens-providers": "^0.11.0", + "ptokens-utils": "^0.11.0", "uuid": "^8.3.1", "web3-core-promievent": "^1.2.5-rc.0" }, diff --git a/packages/ptokens-pbep20/README.md b/packages/ptokens-pbep20/README.md new file mode 100644 index 00000000..7c77af17 --- /dev/null +++ b/packages/ptokens-pbep20/README.md @@ -0,0 +1,54 @@ +# ptokens-pbep20 + +It allows to easily convert any BEP20 tokens on the Binance Smart Chain blockchain into their pTokenized equivalents on the another blockchain. + +  + +*** + +  + +### Installation: + +``` +npm install ptokens-pbep20 +``` + +  + +*** + +  + +### Usage: + +```js +import { pBEP20 } from 'ptokens-pbep20' +import { HttpProvider } from 'ptokens-providers' +import { Node } from 'ptokens-node' + +const pbep20 = new pBEP20({ + blockchain: 'ETH', + network: 'testnet', // 'testnet' or 'mainnet', default 'testnet' + + // if you want to be more detailed + hostBlockchain: 'ETH', + hostNetwork: 'mainnet', + nativeBlockchain: 'BSC' + nativeNetwork: 'mainnet' + + ethPrivateKey: 'Eth private key', + ethProvider: 'Eth provider', // or instance of Web3 provider + defaultNode: new Node({ + pToken: 'OCP', + blockchain: 'ETH', + provider: new HttpProvider( + 'node endpoint', + { + 'Access-Control-Allow-Origin': '*', + ... + } + ) + }) +}) +``` \ No newline at end of file diff --git a/packages/ptokens-pbep20/jest.config.js b/packages/ptokens-pbep20/jest.config.js new file mode 100644 index 00000000..08880dad --- /dev/null +++ b/packages/ptokens-pbep20/jest.config.js @@ -0,0 +1,3 @@ +const jestConfig = require('../../jest.config') + +module.exports = jestConfig() diff --git a/packages/ptokens-pbep20/package.json b/packages/ptokens-pbep20/package.json new file mode 100644 index 00000000..2f85f6ce --- /dev/null +++ b/packages/ptokens-pbep20/package.json @@ -0,0 +1,46 @@ +{ + "name": "ptokens-pbep20", + "version": "0.11.0", + "description": "repo holding the code for interacting with a BEP20 token", + "repository": "https://github.com/provable-things/ptokens.js/tree/master/packages/ptokens-pbep20", + "main": "dist/ptokens-pbep20.cjs.js", + "module": "dist/ptokens-pbep20.esm.js", + "browser": "dist/ptokens-pbep20.umd.js", + "types": "types/index.d.ts", + "scripts": { + "build": "rollup -c", + "dev": "rollup -c -w", + "test": "jest --ci --forceExit --detectOpenHandles", + "lint": "npx eslint ./src --fix && npx eslint ./tests --fix", + "dtslint": "dtslint types --onlyTestTsNext" + }, + "keywords": [ + "ptokens", + "javaScript", + "ethereum", + "eos", + "pnetwork" + ], + "author": "alle.manfredi@gmail.com @provable-things", + "license": "LGPL-3.0", + "dependencies": { + "@babel/runtime": "^7.3.1", + "@types/node": "^12.6.1", + "bignumber.js": "^9.0.0", + "chai": "^4.2.0", + "ptokens-node": "^0.11.0", + "ptokens-node-selector": "^0.11.0", + "ptokens-utils": "^0.11.0", + "web3": "^1.2.2", + "web3-core-promievent": "^1.2.1", + "web3-utils": "^1.2.4" + }, + "devDependencies": { + "dtslint": "0.4.2", + "jest": "^24.8.0" + }, + "files": [ + "dist", + "types/index.d.ts" + ] +} diff --git a/packages/ptokens-pbep20/rollup.config.js b/packages/ptokens-pbep20/rollup.config.js new file mode 100644 index 00000000..b5c7ead1 --- /dev/null +++ b/packages/ptokens-pbep20/rollup.config.js @@ -0,0 +1,8 @@ +import pkg from './package.json' +import rollupConfig from '../../rollup.config' + +export default rollupConfig('pBEP20', pkg.name, { + 'ptokens-node-selector': 'ptokens-node-selector', + 'ptokens-node': 'ptokens-node', + 'ptokens-utils': 'ptokens-utils' +}) diff --git a/packages/ptokens-pbep20/src/index.js b/packages/ptokens-pbep20/src/index.js new file mode 100644 index 00000000..14f0a06e --- /dev/null +++ b/packages/ptokens-pbep20/src/index.js @@ -0,0 +1,209 @@ +import Web3 from 'web3' +import Web3PromiEvent from 'web3-core-promievent' +import { NodeSelector } from 'ptokens-node-selector' +import { abi, constants, eth, helpers, redeemFrom } from 'ptokens-utils' +import BigNumber from 'bignumber.js' +import Web3Utils from 'web3-utils' +import minimumAmounts from './minimum-amounts' + +export class pBEP20 extends NodeSelector { + constructor(_configs) { + const { hostBlockchain, hostNetwork, nativeBlockchain, nativeNetwork } = helpers.parseParams( + _configs, + constants.blockchains.BinanceSmartChain + ) + + super({ + pToken: _configs.pToken, + hostBlockchain, + hostNetwork, + nativeBlockchain, + nativeNetwork, + defaultNode: _configs.defaultNode + }) + + const { bscPrivateKey, bscProvider, ethPrivateKey, ethProvider } = _configs + + if (bscProvider) this.web3 = new Web3(bscProvider) + if (bscPrivateKey) { + const account = this.web3.eth.accounts.privateKeyToAccount(eth.addHexPrefix(bscPrivateKey)) + this.web3.eth.defaultAccount = account.address + this.bscPrivateKey = eth.addHexPrefix(bscPrivateKey) + } else { + this.bscPrivateKey = null + } + + if (ethProvider) this.hostApi = new Web3(ethProvider) + if (ethPrivateKey) { + const account = this.hostApi.eth.accounts.privateKeyToAccount(eth.addHexPrefix(ethPrivateKey)) + this.hostApi.eth.defaultAccount = account.address + this.hostPrivateKey = eth.addHexPrefix(ethPrivateKey) + } else { + this.hostPrivateKey = null + } + } + /** + * @param {String|BigNumber|BN} _amount in wei + * @param {String} _hostAccount + * @param {IssueOptions} _options + */ + issue(_amount, _hostAccount, _options = {}) { + const promiEvent = Web3PromiEvent() + const start = async () => { + try { + const { gas, gasPrice } = _options + const { blockchains } = constants + await this._loadData() + + const minimumAmount = minimumAmounts[this.nativeContractAddress.toLowerCase()].issue + if (BigNumber(_amount).isLessThan(minimumAmount)) { + promiEvent.reject(`Impossible to issue less than ${minimumAmount}`) + return + } + + if (this.hostBlockchain === blockchains.Ethereum && !Web3Utils.isAddress(_hostAccount)) { + promiEvent.reject('Invalid host account') + return + } + + if (!this.selectedNode) await this.select() + + let bscTxHash = null + const waitForEthTransaction = () => + new Promise((_resolve, _reject) => { + eth[this.bscPrivateKey ? 'sendSignedMethodTx' : 'makeContractSend']( + this.web3, + 'pegIn', + { + privateKey: this.bscPrivateKey, + abi: abi.pERC20Vault, + gas, + gasPrice, + contractAddress: eth.addHexPrefix(this.nativeVaultAddress), + value: 0 + }, + [_amount, this.nativeContractAddress, _hostAccount] + ) + .once('transactionHash', _hash => { + bscTxHash = _hash + promiEvent.eventEmitter.emit('nativeTxBroadcasted', bscTxHash) + }) + .once('receipt', _resolve) + .once('error', _reject) + }) + const ethTxReceipt = await waitForEthTransaction() + promiEvent.eventEmitter.emit('nativeTxConfirmed', ethTxReceipt) + + const incomingTxReport = await this.selectedNode.monitorIncomingTransaction(bscTxHash, promiEvent.eventEmitter) + + let hostTxReceipt + if (this.hostBlockchain === blockchains.Ethereum) + hostTxReceipt = await eth.waitForTransactionConfirmation(this.hostApi, incomingTxReport.broadcast_tx_hash) + + promiEvent.eventEmitter.emit('hostTxConfirmed', hostTxReceipt) + promiEvent.resolve({ + to: _hostAccount, + nativeTx: bscTxHash, + hostTx: incomingTxReport.broadcast_tx_hash, + amount: BigNumber(_amount).toFixed() + }) + } catch (_err) { + promiEvent.reject(_err) + } + } + + start() + return promiEvent.eventEmitter + } + + /** + * + * @param {string|number} _amount + * @param {string} _nativeAccount + * @param {Options} _options + */ + redeem(_amount, _nativeAccount, _options = {}) { + const promiEvent = Web3PromiEvent() + + const start = async () => { + try { + const { gas, gasPrice } = _options + const { blockchains } = constants + + await this._loadData() + + const minimumAmount = minimumAmounts[this.nativeContractAddress.toLowerCase()].redeem[this.hostBlockchain] + if (BigNumber(_amount).isLessThan(minimumAmount)) { + promiEvent.reject(`Impossible to redeem less than ${minimumAmount}`) + return + } + + if (this.nativeBlockchain === blockchains.Ethereum && !Web3Utils.isAddress(_nativeAccount)) { + promiEvent.reject('Invalid native account') + return + } + + if (!this.selectedNode) await this.select() + + const { redeemFromEvmCompatible } = redeemFrom + + let hostTxHash + if (this.hostBlockchain === blockchains.Ethereum) { + const hostTxReceipt = await redeemFromEvmCompatible( + this.hostApi, + { + privateKey: this.hostPrivateKey, + gas, + gasPrice, + contractAddress: this.hostContractAddress, + value: 0 + }, + [_amount, _nativeAccount], + promiEvent, + 'hostTxBroadcasted' + ) + + promiEvent.eventEmitter.emit('hostTxConfirmed', hostTxReceipt) + hostTxHash = hostTxReceipt.transactionHash + } + + const incomingTxReport = await this.selectedNode.monitorIncomingTransaction(hostTxHash, promiEvent.eventEmitter) + const nativeTxReceipt = await eth.waitForTransactionConfirmation( + this.hostApi, + incomingTxReport.broadcast_tx_hash + ) + promiEvent.eventEmitter.emit('nativeTxConfirmed', nativeTxReceipt) + + promiEvent.resolve({ + to: _nativeAccount, + nativeTx: nativeTxReceipt.transactionHash, + hostTx: hostTxHash, + amount: BigNumber(_amount).toFixed() + }) + } catch (_err) { + promiEvent.reject(_err) + } + } + + start() + return promiEvent.eventEmitter + } + + async _loadData() { + try { + if (!this.selectedNode) await this.select() + if (!this.nativeContractAddress || !this.hostContractAddress) { + const { + native_smart_contract_address, + host_smart_contract_address, + native_vault_address + } = await this.selectedNode.getInfo() + this.nativeContractAddress = eth.addHexPrefix(native_smart_contract_address) + this.hostContractAddress = eth.addHexPrefix(host_smart_contract_address) + this.nativeVaultAddress = native_vault_address ? eth.addHexPrefix(native_vault_address) : null + } + } catch (_err) { + throw new Error(`Error during loading data: ${_err.message}`) + } + } +} diff --git a/packages/ptokens-pbep20/src/minimum-amounts.js b/packages/ptokens-pbep20/src/minimum-amounts.js new file mode 100644 index 00000000..da0aacf2 --- /dev/null +++ b/packages/ptokens-pbep20/src/minimum-amounts.js @@ -0,0 +1,9 @@ +import { constants } from 'ptokens-utils' +export default { + [constants.tokens['binance-smart-chain'].mainnet.OCP]: { + issue: 1000000000, + redeem: { + [constants.blockchains.Ethereum]: 0.000000001 + } + } +} diff --git a/packages/ptokens-pbep20/tests/ptokens-ocp-on-eth.test.js b/packages/ptokens-pbep20/tests/ptokens-ocp-on-eth.test.js new file mode 100644 index 00000000..9cec94bb --- /dev/null +++ b/packages/ptokens-pbep20/tests/ptokens-ocp-on-eth.test.js @@ -0,0 +1,156 @@ +import { pBEP20 } from '../src/index' +import { expect } from 'chai' +import { constants, eth } from 'ptokens-utils' +import BigNumber from 'bignumber.js' +import Web3 from 'web3' + +const ETH_TESTING_ADDRESS = '' +const ETH_TESTING_PRIVATE_KEY = '' +const ETH_WEB3_PROVIDER = '' +const BSC_TESTING_ADDRESS = '' +const BSC_TESTING_PRIVATE_KEY = '' +const BSC_WEB3_PROVIDER = '' + +jest.setTimeout(3000000) + +let ocp = null +beforeEach(() => { + ocp = new pBEP20({ + blockchain: constants.blockchains.Ethereum, + network: constants.networks.Mainnet, + ethPrivateKey: ETH_TESTING_PRIVATE_KEY, + ethProvider: ETH_WEB3_PROVIDER, + bscPrivateKey: BSC_TESTING_PRIVATE_KEY, + bscProvider: BSC_WEB3_PROVIDER, + pToken: constants.pTokens.OCP + }) +}) + +test('Should not issue less than 1000000000 OCP', async () => { + const amountToIssue = BigNumber('900000000') + try { + await ocp.issue(amountToIssue, ETH_TESTING_ADDRESS) + } catch (_err) { + expect(_err).to.be.equal('Impossible to issue less than 1000000000') + } +}) + +test('Should issue 0.00002 OCP using ETH', async () => { + const amountToIssue = BigNumber('20000000000000') + let bscTxBroadcasted = 2 + let bscTxIsConfirmed = false + let nodeHasReceivedTx = false + let nodeHasBroadcastedTx = false + let ethTxIsConfirmed = false + + await ocp.select() + const { native_vault_address } = await ocp.selectedNode.getInfo() + + const web3 = new Web3(BSC_WEB3_PROVIDER) + web3.eth.defaultAccount = ETH_TESTING_ADDRESS + await eth.sendSignedMethodTx( + web3, + 'approve', + { + privateKey: BSC_TESTING_PRIVATE_KEY, + abi: [ + { + constant: false, + inputs: [ + { + name: '_spender', + type: 'address' + }, + { + name: '_value', + type: 'uint256' + } + ], + name: 'approve', + outputs: [ + { + name: '', + type: 'bool' + } + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + } + ], + gas: 200000, + gasPrice: 5e9, + contractAddress: constants.tokens['binance-smart-chain'].mainnet.OCP, + value: 0 + }, + [eth.addHexPrefix(native_vault_address), BigNumber('20000000000000')] + ) + + const start = () => + new Promise(resolve => { + ocp + .issue(amountToIssue, ETH_TESTING_ADDRESS, { + gasPrice: 5e9, + gas: 200000 + }) + .once('nativeTxBroadcasted', () => { + bscTxBroadcasted = true + }) + .once('nativeTxConfirmed', () => { + bscTxIsConfirmed = true + }) + .once('nodeReceivedTx', () => { + nodeHasReceivedTx = true + }) + .once('nodeBroadcastedTx', () => { + nodeHasBroadcastedTx = true + }) + .once('hostTxConfirmed', () => { + ethTxIsConfirmed = true + }) + .then(() => resolve()) + }) + await start() + expect(bscTxBroadcasted).to.equal(true) + expect(bscTxIsConfirmed).to.equal(true) + expect(nodeHasReceivedTx).to.equal(true) + expect(nodeHasBroadcastedTx).to.equal(true) + expect(ethTxIsConfirmed).to.equal(true) +}) + +test('Should redeem 0.00002 OCP from BSC', async () => { + const amountToRedeem = BigNumber('20000000000000') + let ethTxIsBroadcasted = false + let ethTxIsConfirmed = false + let nodeHasReceivedTx = false + let nodeHasBroadcastedTx = false + let bscTxIsConfirmed = false + const start = () => + new Promise((resolve, reject) => { + ocp + .redeem(amountToRedeem, BSC_TESTING_ADDRESS, { gasPrice: 75e9, gas: 200000 }) + .once('hostTxBroadcasted', () => { + ethTxIsBroadcasted = true + }) + .once('hostTxConfirmed', () => { + ethTxIsConfirmed = true + }) + .once('nodeReceivedTx', () => { + nodeHasReceivedTx = true + }) + .once('nodeBroadcastedTx', () => { + nodeHasBroadcastedTx = true + }) + .once('nativeTxConfirmed', () => { + bscTxIsConfirmed = true + }) + .then(() => resolve()) + .catch(_err => reject(_err)) + }) + await start() + expect(ethTxIsBroadcasted).to.equal(true) + expect(ethTxIsConfirmed).to.equal(true) + expect(nodeHasReceivedTx).to.equal(true) + expect(nodeHasBroadcastedTx).to.equal(true) + expect(bscTxIsConfirmed).to.equal(true) +}) diff --git a/packages/ptokens-pbep20/types/index.d.ts b/packages/ptokens-pbep20/types/index.d.ts new file mode 100644 index 00000000..33519d11 --- /dev/null +++ b/packages/ptokens-pbep20/types/index.d.ts @@ -0,0 +1,62 @@ +import { Node, Report } from 'ptokens-node' +import { TransactionReceipt, PromiEvent } from 'web3-core' +import Web3 from 'web3' +import { NodeSelector } from 'ptokens-node-selector' +import { BigNumber } from 'bignumber.js' +import BN = require('bn.js') + +export interface pBEP20Configs { + network?: string, + hostNetwork?: string, + blockchain?: string, + hostBlockchain?: string, + nativeNetwork?: string, + nativeBlockchain?: string, + ethPrivateKey?: string, + ethProvider?: string | object, + bscPrivateKey?: string, + bscProvider?: string | object, + defaultNode?: Node, + pToken: string +} + +export interface IssueOptions { + gas: number, + gasPrice: number | string | BigNumber, +} + +export interface RedeemOptions { + gasPrice: number | string | BigNumber, + gas: string | number +} + +export class pBEP20 extends NodeSelector { + constructor(configs: pBEP20Configs) + + nodeSelector: NodeSelector + + decimals: string | null + + nativeContractAddress: string | null + + hostContractAddress: string | null + + nativeVaultAddress: string | null + + hostPrivatekey?: string | null + + web3: Web3 + + hostApi?: Web3 + + issue(_amount: string | BigNumber | BN, _hostAddress: string, _options: IssueOptions): PromiEvent + + redeem(_amount: number | string, _nativeAddress: string, _options: RedeemOptions): PromiEvent +} + +export interface Result { + amount: number, + nativeTx: string, + hostTx: string, + to: string, +} diff --git a/packages/ptokens-pbep20/types/tests/ptokens-pbep20-test.ts b/packages/ptokens-pbep20/types/tests/ptokens-pbep20-test.ts new file mode 100644 index 00000000..3abbe09c --- /dev/null +++ b/packages/ptokens-pbep20/types/tests/ptokens-pbep20-test.ts @@ -0,0 +1,19 @@ +import { pBEP20 } from 'ptokens-pbep20' + +const pbep20 = new pBEP20({ + network: 'mainnet', + blockchain: 'eth', + pToken: 'ocp', +}) + +// $ExpectType PromiEvent +pbep20.issue('1000000000000', 'eos account', { + gas: 10, + gasPrice: 10 +}) + +// $ExpectType PromiEvent +pbep20.redeem(0.002, 'eth address', { + gas: 10, + gasPrice: 10 +}) diff --git a/packages/ptokens-pbep20/types/tsconfig.json b/packages/ptokens-pbep20/types/tsconfig.json new file mode 100644 index 00000000..62a8b270 --- /dev/null +++ b/packages/ptokens-pbep20/types/tsconfig.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "module": "commonjs", + "lib": ["es6", "dom"], + "target": "es6", + "noImplicitAny": true, + "noImplicitThis": true, + "strictNullChecks": true, + "strictFunctionTypes": true, + "noEmit": true, + "allowSyntheticDefaultImports": false, + "baseUrl": ".", + "paths": { + "ptokens-pbep20": ["."] + } + } +} diff --git a/packages/ptokens-pbep20/types/tslint.json b/packages/ptokens-pbep20/types/tslint.json new file mode 100644 index 00000000..0435f238 --- /dev/null +++ b/packages/ptokens-pbep20/types/tslint.json @@ -0,0 +1,10 @@ +{ + "extends": "dtslint/dtslint.json", + "rules": { + "semicolon": false, + "no-import-default-of-export-equals": false, + "file-name-casing": [true, "kebab-case"], + "whitespace": false, + "no-unnecessary-class": false + } +} diff --git a/packages/ptokens-pbtc/package.json b/packages/ptokens-pbtc/package.json index edf75cb1..8aac72cd 100644 --- a/packages/ptokens-pbtc/package.json +++ b/packages/ptokens-pbtc/package.json @@ -1,6 +1,6 @@ { "name": "ptokens-pbtc", - "version": "0.10.0", + "version": "0.11.0", "description": "repo holding the code for interacting with pBTC", "repository": "https://github.com/provable-things/ptokens.js/tree/master/packages/ptokens-pbtc", "main": "dist/ptokens-pbtc.cjs.js", @@ -30,11 +30,11 @@ "bitcoinjs-lib": "^5.1.6", "chai": "^4.2.0", "eosjs": "^20.0.0", - "ptokens-deposit-address": "^0.10.0", - "ptokens-node": "^0.10.0", - "ptokens-node-selector": "^0.10.0", - "ptokens-providers": "^0.10.0", - "ptokens-utils": "^0.10.0", + "ptokens-deposit-address": "^0.11.0", + "ptokens-node": "^0.11.0", + "ptokens-node-selector": "^0.11.0", + "ptokens-providers": "^0.11.0", + "ptokens-utils": "^0.11.0", "web3": "^1.2.2", "web3-core-promievent": "^1.2.1", "web3-utils": "^1.2.4" diff --git a/packages/ptokens-pbtc/src/index.js b/packages/ptokens-pbtc/src/index.js index 04ab4112..46cc1d7a 100644 --- a/packages/ptokens-pbtc/src/index.js +++ b/packages/ptokens-pbtc/src/index.js @@ -97,7 +97,7 @@ export class pBTC extends NodeSelector { const start = async () => { try { - const { gas, gasPrice, blocksBehind, expireSeconds, permission } = _options + const { gas, gasPrice, blocksBehind, expireSeconds, permission, actor } = _options if (_amount < MINIMUM_BTC_REDEEMABLE) { promiEvent.reject(`Impossible to burn less than ${MINIMUM_BTC_REDEEMABLE} pBTC`) @@ -113,7 +113,7 @@ export class pBTC extends NodeSelector { const contractAddress = await this._getContractAddress() - const { redeemFromEthereum, redeemFromEosio } = redeemFrom + const { redeemFromEvmCompatible, redeemFromEosio } = redeemFrom let hostTxHash = null if ( @@ -121,7 +121,7 @@ export class pBTC extends NodeSelector { this.hostBlockchain === constants.blockchains.BinanceSmartChain || this.hostBlockchain === constants.blockchains.Xdai ) { - const hostTxReceipt = await redeemFromEthereum( + const hostTxReceipt = await redeemFromEvmCompatible( this.hostApi, { privateKey: this.hostPrivateKey, @@ -156,7 +156,8 @@ export class pBTC extends NodeSelector { { blocksBehind, expireSeconds, - permission + permission, + actor } ) diff --git a/packages/ptokens-pbtc/types/index.d.ts b/packages/ptokens-pbtc/types/index.d.ts index af57ae06..6a073385 100644 --- a/packages/ptokens-pbtc/types/index.d.ts +++ b/packages/ptokens-pbtc/types/index.d.ts @@ -36,6 +36,7 @@ export interface RedeemOptions { gas?: number, gasPrice?: number | string | BigNumber, blocksBehind?: string, + actor?: string, expireSeconds?: string, permission?: string, } diff --git a/packages/ptokens-pdoge/package.json b/packages/ptokens-pdoge/package.json index 69b93676..c70a1172 100644 --- a/packages/ptokens-pdoge/package.json +++ b/packages/ptokens-pdoge/package.json @@ -1,6 +1,6 @@ { "name": "ptokens-pdoge", - "version": "0.10.0", + "version": "0.11.0", "description": "repo holding the code for interacting with pDOGE", "repository": "https://github.com/provable-things/ptokens.js/tree/master/packages/ptokens-pdoge", "main": "dist/ptokens-pdoge.cjs.js", @@ -28,10 +28,10 @@ "@types/node": "^12.6.1", "bignumber.js": "^9.0.0", "chai": "^4.2.0", - "ptokens-deposit-address": "^0.10.0", - "ptokens-node": "^0.10.0", - "ptokens-node-selector": "^0.10.0", - "ptokens-utils": "^0.10.0", + "ptokens-deposit-address": "^0.11.0", + "ptokens-node": "^0.11.0", + "ptokens-node-selector": "^0.11.0", + "ptokens-utils": "^0.11.0", "web3": "^1.2.2", "web3-core-promievent": "^1.2.1", "web3-utils": "^1.2.4" diff --git a/packages/ptokens-pdoge/src/index.js b/packages/ptokens-pdoge/src/index.js index f5825c63..cc02f557 100644 --- a/packages/ptokens-pdoge/src/index.js +++ b/packages/ptokens-pdoge/src/index.js @@ -5,7 +5,7 @@ import { constants, eth, doge, helpers, redeemFrom } from 'ptokens-utils' import { DepositAddress } from 'ptokens-deposit-address' import Web3Utils from 'web3-utils' -const MINIMUM_LTC_REDEEMABLE = 0.00005 +const MINIMUM_DOGE_REDEEMABLE = 50000000000000 export class pDOGE extends NodeSelector { /** @@ -57,8 +57,7 @@ export class pDOGE extends NodeSelector { nativeNetwork: this.nativeNetwork, hostBlockchain: this.hostBlockchain, hostNetwork: this.hostNetwork, - hostApi: this.hostApi, - nativeNode: this.dogecoinNode + hostApi: this.hostApi }) await depositAddress.generate(_hostAddress) @@ -78,8 +77,8 @@ export class pDOGE extends NodeSelector { try { const { gas, gasPrice } = _options - if (_amount < MINIMUM_LTC_REDEEMABLE) { - promiEvent.reject(`Impossible to burn less than ${MINIMUM_LTC_REDEEMABLE} pDOGE`) + if (_amount < MINIMUM_DOGE_REDEEMABLE) { + promiEvent.reject(`Impossible to burn less than ${MINIMUM_DOGE_REDEEMABLE} pDOGE`) return } @@ -92,11 +91,11 @@ export class pDOGE extends NodeSelector { const contractAddress = await this._getContractAddress() - const { redeemFromEthereum } = redeemFrom + const { redeemFromEvmCompatible } = redeemFrom let hostTxHash = null if (this.hostBlockchain === constants.blockchains.Ethereum) { - const ethTxReceipt = await redeemFromEthereum( + const ethTxReceipt = await redeemFromEvmCompatible( this.hostApi, { privateKey: this.hostPrivateKey, diff --git a/packages/ptokens-peosio-token/package.json b/packages/ptokens-peosio-token/package.json index 6ebfd7d8..6f449934 100644 --- a/packages/ptokens-peosio-token/package.json +++ b/packages/ptokens-peosio-token/package.json @@ -1,6 +1,6 @@ { "name": "ptokens-peosio-token", - "version": "0.10.0", + "version": "0.11.0", "description": "repo holding the code for interacting with pEosioToken", "repository": "https://github.com/provable-things/ptokens.js/tree/master/packages/ptokens-peosio-token", "main": "dist/ptokens-peosio-token.cjs.js", @@ -30,10 +30,10 @@ "bitcoinjs-lib": "^5.1.6", "chai": "^4.2.0", "eosjs": "^21.0.0", - "ptokens-node": "^0.10.0", - "ptokens-node-selector": "^0.10.0", - "ptokens-providers": "^0.10.0", - "ptokens-utils": "^0.10.0", + "ptokens-node": "^0.11.0", + "ptokens-node-selector": "^0.11.0", + "ptokens-providers": "^0.11.0", + "ptokens-utils": "^0.11.0", "web3": "^1.2.2", "web3-core-promievent": "^1.2.1", "web3-utils": "^1.2.4" diff --git a/packages/ptokens-peosio-token/src/index.js b/packages/ptokens-peosio-token/src/index.js index 8651fa6b..0d314626 100644 --- a/packages/ptokens-peosio-token/src/index.js +++ b/packages/ptokens-peosio-token/src/index.js @@ -25,6 +25,8 @@ export class pEosioToken extends NodeSelector { const { ethPrivateKey, ethProvider, + bscPrivateKey, + bscProvider, eosPrivateKey, eosRpc, eosSignatureProvider, @@ -59,6 +61,15 @@ export class pEosioToken extends NodeSelector { } else { this.hostPrivateKey = null } + + if (bscProvider) this.hostApi = new Web3(bscProvider) + if (bscPrivateKey) { + const account = this.hostApi.eth.accounts.privateKeyToAccount(eth.addHexPrefix(bscPrivateKey)) + this.hostApi.eth.defaultAccount = account.address + this.hostPrivateKey = eth.addHexPrefix(bscPrivateKey) + } else { + this.hostPrivateKey = null + } } /** * @param {String} _amount in wei @@ -69,7 +80,7 @@ export class pEosioToken extends NodeSelector { const promiEvent = Web3PromiEvent() const start = async () => { try { - const { blocksBehind, expireSeconds, permission } = _options + const { blocksBehind, expireSeconds, permission, actor } = _options await this._loadData() @@ -78,20 +89,17 @@ export class pEosioToken extends NodeSelector { return } - if (this.hostBlockchain === constants.blockchains.Ethereum && !Web3Utils.isAddress(_hostAccount)) { + if ( + (this.hostBlockchain === constants.blockchains.Ethereum || + this.hostBlockchain === constants.blockchains.BinanceSmartChain) && + !Web3Utils.isAddress(_hostAccount) + ) { promiEvent.reject('Invalid host account') return } if (!this.selectedNode) await this.select() - const eosPublicKeys = await this.nativeApi.signatureProvider.getAvailableKeys() - const eosAccountName = await eos.getAccountName(this.nativeApi.rpc, eosPublicKeys) - if (!eosAccountName) { - // prettier-ignore - throw new Error('Account name does not exist. Check that you entered it correctly or make sure to have enabled history plugin') - } - this.nativeApi.cachedAbis.set(this.nativeContractAddress, { abi: abi.EosioToken, rawAbi: null @@ -105,12 +113,12 @@ export class pEosioToken extends NodeSelector { name: 'transfer', authorization: [ { - actor: eosAccountName, + actor, permission } ], data: { - from: eosAccountName, + from: actor, to: this.nativeVaultAddress, quantity: eos.getAmountInEosFormat( _amount, @@ -181,9 +189,10 @@ export class pEosioToken extends NodeSelector { let hostTxHash = null if ( this.hostBlockchain === constants.blockchains.Ethereum || - this.hostBlockchain === constants.blockchains.Polygon + this.hostBlockchain === constants.blockchains.Polygon || + this.hostBlockchain === constants.blockchains.BinanceSmartChain ) { - const hostTxReceipt = await redeemFrom.redeemFromEthereum( + const hostTxReceipt = await redeemFrom.redeemFromEvmCompatible( this.hostApi, { privateKey: this.hostPrivateKey, diff --git a/packages/ptokens-peosio-token/types/index.d.ts b/packages/ptokens-peosio-token/types/index.d.ts index e22bcce5..a5025a32 100644 --- a/packages/ptokens-peosio-token/types/index.d.ts +++ b/packages/ptokens-peosio-token/types/index.d.ts @@ -16,6 +16,8 @@ export interface pEosioTokenConfigs { nativeBlockchain?: string, ethPrivateKey?: string, ethProvider?: string | object, + bscPrivateKey?: string, + bscProvider?: string | object, eosPrivateKey?: string, eosRpc?: string | JsonRpc, eosSignatureProvider?: JsSignatureProvider, @@ -33,7 +35,8 @@ export interface RedeemOptions { export interface IssueOptions { blocksBehind: number, expireSecond: number, - permission: string + permission: string, + actor: string, } export interface Result { diff --git a/packages/ptokens-peosio-token/types/tests/ptokens-peos-token-test.ts b/packages/ptokens-peosio-token/types/tests/ptokens-peosio-token-test.ts similarity index 91% rename from packages/ptokens-peosio-token/types/tests/ptokens-peos-token-test.ts rename to packages/ptokens-peosio-token/types/tests/ptokens-peosio-token-test.ts index 7fc3d328..73c85620 100644 --- a/packages/ptokens-peosio-token/types/tests/ptokens-peos-token-test.ts +++ b/packages/ptokens-peosio-token/types/tests/ptokens-peosio-token-test.ts @@ -9,7 +9,8 @@ const peos = new pEosioToken({ peos.issue('0.0015', '0xdf3B180694aB22C577f7114D822D28b92cadFd75', { blocksBehind: 30, expireSecond: 120, - permission: 'active' + permission: 'active', + actor: 'actor' }) // $ExpectType PromiEvent diff --git a/packages/ptokens-perc20/package.json b/packages/ptokens-perc20/package.json index c6af678e..7278f790 100644 --- a/packages/ptokens-perc20/package.json +++ b/packages/ptokens-perc20/package.json @@ -1,6 +1,6 @@ { "name": "ptokens-perc20", - "version": "0.10.0", + "version": "0.11.0", "description": "repo holding the code for interacting with Ether or a generic Ethereum ERC20 token", "repository": "https://github.com/provable-things/ptokens.js/tree/master/packages/ptokens-perc20", "main": "dist/ptokens-perc20.cjs.js", @@ -29,9 +29,9 @@ "bignumber.js": "^9.0.0", "chai": "^4.2.0", "eosjs": "^20.0.0", - "ptokens-node": "^0.10.0", - "ptokens-node-selector": "^0.10.0", - "ptokens-utils": "^0.10.0", + "ptokens-node": "^0.11.0", + "ptokens-node-selector": "^0.11.0", + "ptokens-utils": "^0.11.0", "web3": "^1.2.2", "web3-core-promievent": "^1.2.1", "web3-utils": "^1.2.4" diff --git a/packages/ptokens-perc20/src/index.js b/packages/ptokens-perc20/src/index.js index 24a2b34f..a94a4a25 100644 --- a/packages/ptokens-perc20/src/index.js +++ b/packages/ptokens-perc20/src/index.js @@ -22,18 +22,48 @@ export class pERC20 extends NodeSelector { defaultNode: _configs.defaultNode }) - const { ethPrivateKey, ethProvider, eosPrivateKey, eosRpc, eosSignatureProvider } = _configs + const { + ethPrivateKey, + ethProvider, + bscPrivateKey, + bscProvider, + xdaiPrivateKey, + xdaiProvider, + eosPrivateKey, + eosRpc, + eosSignatureProvider, + telosPrivateKey, + telosRpc, + telosSignatureProvider + } = _configs if (ethProvider) this.web3 = new Web3(ethProvider) if (ethPrivateKey) { const account = this.web3.eth.accounts.privateKeyToAccount(eth.addHexPrefix(ethPrivateKey)) - this.web3.eth.defaultAccount = account.address this.ethPrivateKey = eth.addHexPrefix(ethPrivateKey) } else { this.ethPrivateKey = null } + if (bscProvider) this.hostApi = new Web3(bscProvider) + if (bscPrivateKey) { + const account = this.hostApi.eth.accounts.privateKeyToAccount(eth.addHexPrefix(bscPrivateKey)) + this.hostApi.eth.defaultAccount = account.address + this.hostPrivateKey = eth.addHexPrefix(bscPrivateKey) + } else { + this.hostPrivateKey = null + } + + if (xdaiProvider) this.hostApi = new Web3(xdaiProvider) + if (xdaiPrivateKey) { + const account = this.hostApi.eth.accounts.privateKeyToAccount(eth.addHexPrefix(xdaiPrivateKey)) + this.hostApi.eth.defaultAccount = account.address + this.hostPrivateKey = eth.addHexPrefix(xdaiPrivateKey) + } else { + this.hostPrivateKey = null + } + if (eosSignatureProvider) { this.hostApi = eos.getApi(null, eosRpc, eosSignatureProvider) } else if (eosPrivateKey && eosRpc) { @@ -43,6 +73,15 @@ export class pERC20 extends NodeSelector { this.hostApi = eos.getApi(null, eosRpc, null) } + if (telosSignatureProvider) { + this.hostApi = eos.getApi(null, telosRpc, telosSignatureProvider) + } else if (telosPrivateKey && telosRpc) { + this.hostApi = eos.getApi(telosPrivateKey, telosRpc, null) + this.hostPrivateKey = telosPrivateKey + } else if (!telosSignatureProvider && !telosPrivateKey && telosRpc) { + this.hostApi = eos.getApi(null, telosRpc, null) + } + this._peginEth = _configs.pToken.toLowerCase() === constants.pTokens.pETH } /** @@ -52,18 +91,24 @@ export class pERC20 extends NodeSelector { */ issue(_amount, _hostAccount, _options = {}) { const promiEvent = Web3PromiEvent() - const { gas, gasPrice } = _options - const start = async () => { try { + const { gas, gasPrice } = _options + const { blockchains } = constants await this._loadData() - if (BigNumber(_amount).isLessThan(minimumAmounts[this.nativeContractAddress].issue)) { - promiEvent.reject(`Impossible to issue less than ${minimumAmounts[this.nativeContractAddress].issue}`) + const minimumAmount = minimumAmounts[this.nativeContractAddress.toLowerCase()].issue + if (BigNumber(_amount).isLessThan(minimumAmount)) { + promiEvent.reject(`Impossible to issue less than ${minimumAmount}`) return } - if (this.hostBlockchain === constants.blockchains.Eosio && !eos.isValidAccountName(_hostAccount)) { + if ( + ((this.hostBlockchain === blockchains.Eosio || this.hostBlockchain === blockchains.Telos) && + !eos.isValidAccountName(_hostAccount)) || + ((this.hostBlockchain === blockchains.BinanceSmartChain || this.hostBlockchain === blockchains.Xdai) && + !Web3Utils.isAddress(_hostAccount)) + ) { promiEvent.reject('Invalid host account') return } @@ -99,9 +144,12 @@ export class pERC20 extends NodeSelector { const incomingTxReport = await this.selectedNode.monitorIncomingTransaction(ethTxHash, promiEvent.eventEmitter) let hostTxReceipt - if (this.hostBlockchain === constants.blockchains.Eosio) + if (this.hostBlockchain === blockchains.Eosio || this.hostBlockchain === blockchains.Telos) hostTxReceipt = await eos.waitForTransactionConfirmation(this.hostApi, incomingTxReport.broadcast_tx_hash) + if (this.hostBlockchain === blockchains.Xdai || this.hostBlockchain === blockchains.BinanceSmartChain) + hostTxReceipt = await eth.waitForTransactionConfirmation(this.hostApi, incomingTxReport.broadcast_tx_hash) + promiEvent.eventEmitter.emit('hostTxConfirmed', hostTxReceipt) promiEvent.resolve({ to: _hostAccount, @@ -129,46 +177,70 @@ export class pERC20 extends NodeSelector { const start = async () => { try { - const { blocksBehind, expireSeconds, permission } = _options + const { blocksBehind, expireSeconds, permission, gas, gasPrice, actor } = _options + const { blockchains, tokens, pTokens } = constants await this._loadData() - if (BigNumber(_amount).isLessThan(minimumAmounts[this.nativeContractAddress].redeem)) { - promiEvent.reject(`Impossible to redeem less than ${minimumAmounts[this.nativeContractAddress].redeem}`) + const minimumAmount = minimumAmounts[this.nativeContractAddress.toLowerCase()].redeem[this.hostBlockchain] + if (BigNumber(_amount).isLessThan(minimumAmount)) { + promiEvent.reject(`Impossible to redeem less than ${minimumAmount}`) return } - if (this.nativeBlockchain === constants.blockchains.Ethereum && !Web3Utils.isAddress(_nativeAccount)) { + if (this.nativeBlockchain === blockchains.Ethereum && !Web3Utils.isAddress(_nativeAccount)) { promiEvent.reject('Invalid native account') return } if (!this.selectedNode) await this.select() - const { redeemFromEosio } = redeemFrom + const { redeemFromEosio, redeemFromEvmCompatible } = redeemFrom let hostTxHash - if (this.hostBlockchain === constants.blockchains.Eosio) { - const eosTxReceipt = await redeemFromEosio( + if (this.hostBlockchain === blockchains.BinanceSmartChain || this.hostBlockchain === blockchains.Xdai) { + const hostTxReceipt = await redeemFromEvmCompatible( + this.hostApi, + { + privateKey: this.hostPrivateKey, + gas, + gasPrice, + contractAddress: this.hostContractAddress, + value: 0 + }, + [_amount, _nativeAccount], + promiEvent, + 'hostTxBroadcasted' + ) + + promiEvent.eventEmitter.emit('hostTxConfirmed', hostTxReceipt) + hostTxHash = hostTxReceipt.transactionHash + } + + if (this.hostBlockchain === blockchains.Eosio || this.hostBlockchain === blockchains.Telos) { + const eosOrTelosTxReceipt = await redeemFromEosio( this.hostApi, _amount, _nativeAccount, - [constants.tokens.ethereum.mainnet.DAI, constants.tokens.ethereum.mainnet.UOS].includes( - this.nativeContractAddress - ) + [tokens.ethereum.mainnet.DAI, tokens.ethereum.mainnet.UOS].includes(this.nativeContractAddress) ? 4 - : 9, // NOTE: perc20 decimals on EOS except DAI and UOS + : [tokens.ethereum.mainnet.USDT, tokens.ethereum.mainnet.USDC].includes(this.nativeContractAddress) + ? 6 + : 9, this.hostContractAddress, - this.pToken === constants.pTokens.pWETH ? 'peth' : this.pToken, - { blocksBehind, expireSeconds, permission } + this.pToken === pTokens.pWETH ? 'peth' : this.pToken, + { blocksBehind, expireSeconds, permission, actor } ) - promiEvent.eventEmitter.emit('hostTxConfirmed', eosTxReceipt) - hostTxHash = eosTxReceipt.transaction_id + promiEvent.eventEmitter.emit('hostTxConfirmed', eosOrTelosTxReceipt) + hostTxHash = eosOrTelosTxReceipt.transaction_id } const incomingTxReport = await this.selectedNode.monitorIncomingTransaction(hostTxHash, promiEvent.eventEmitter) - const nativeTxReceipt = await eth.waitForTransactionConfirmation(this.web3, incomingTxReport.broadcast_tx_hash) + const nativeTxReceipt = await eth.waitForTransactionConfirmation( + this.hostApi, + incomingTxReport.broadcast_tx_hash + ) promiEvent.eventEmitter.emit('nativeTxConfirmed', nativeTxReceipt) promiEvent.resolve({ @@ -197,13 +269,11 @@ export class pERC20 extends NodeSelector { } = await this.selectedNode.getInfo() this.nativeContractAddress = eth.addHexPrefix(native_smart_contract_address) this.hostContractAddress = - this.hostBlockchain === constants.blockchains.Eosio + this.hostBlockchain === constants.blockchains.Eosio || this.hostBlockchain === constants.blockchains.Telos ? host_smart_contract_address : eth.addHexPrefix(host_smart_contract_address) this.nativeVaultAddress = native_vault_address ? eth.addHexPrefix(native_vault_address) : null } - - return this.nativeContractAddress } catch (_err) { throw new Error(`Error during loading data: ${_err.message}`) } diff --git a/packages/ptokens-perc20/src/minimum-amounts.js b/packages/ptokens-perc20/src/minimum-amounts.js index 630b76a5..a968e17c 100644 --- a/packages/ptokens-perc20/src/minimum-amounts.js +++ b/packages/ptokens-perc20/src/minimum-amounts.js @@ -2,86 +2,177 @@ import { constants } from 'ptokens-utils' export default { [constants.tokens.ethereum.mainnet.ETH]: { issue: 1000000000, - redeem: 0.000000001 + redeem: { + [constants.blockchains.Eosio]: 0.000000001, + [constants.blockchains.Telos]: 0.000000001 + } }, [constants.tokens.ethereum.mainnet.WETH]: { issue: 1000000000, - redeem: 0.000000001 + redeem: { + [constants.blockchains.Eosio]: 0.000000001, + [constants.blockchains.Telos]: 0.000000001 + } }, [constants.tokens.ethereum.mainnet.PNT]: { issue: 1000000000, - redeem: 0.000000001 + redeem: { + [constants.blockchains.Eosio]: 0.000000001, + [constants.blockchains.Telos]: 0.000000001, + [constants.blockchains.BinanceSmartChain]: 1000000000, + [constants.blockchains.Xdai]: 1000000000 + } }, [constants.tokens.ethereum.mainnet.LINK]: { issue: 1000000000, - redeem: 0.000000001 + redeem: { + [constants.blockchains.Eosio]: 0.000000001, + [constants.blockchains.Telos]: 0.000000001 + } }, [constants.tokens.ethereum.mainnet.MKR]: { issue: 1000000000, - redeem: 0.000000001 + redeem: { + [constants.blockchains.Eosio]: 0.000000001 + } }, [constants.tokens.ethereum.mainnet.YFI]: { issue: 1000000000, - redeem: 0.000000001 + redeem: { + [constants.blockchains.Eosio]: 0.000000001 + } }, [constants.tokens.ethereum.mainnet.PTERIA]: { issue: 1000000000, - redeem: 0.000000001 + redeem: { + [constants.blockchains.Eosio]: 0.000000001, + [constants.blockchains.BinanceSmartChain]: 1000000000 + } }, [constants.tokens.ethereum.mainnet.UNI]: { issue: 1000000000, - redeem: 0.000000001 + redeem: { + [constants.blockchains.Eosio]: 0.000000001 + } }, [constants.tokens.ethereum.mainnet.BAND]: { issue: 1000000000, - redeem: 0.000000001 + redeem: { + [constants.blockchains.Eosio]: 0.000000001 + } }, [constants.tokens.ethereum.mainnet.BAL]: { issue: 1000000000, - redeem: 0.000000001 + redeem: { + [constants.blockchains.Eosio]: 0.000000001 + } }, [constants.tokens.ethereum.mainnet.COMP]: { issue: 1000000000, - redeem: 0.000000001 + redeem: { + [constants.blockchains.Eosio]: 0.000000001 + } }, [constants.tokens.ethereum.mainnet.SNX]: { issue: 1000000000, - redeem: 0.000000001 + redeem: { + [constants.blockchains.Eosio]: 0.000000001 + } }, [constants.tokens.ethereum.mainnet.OMG]: { issue: 1000000000, - redeem: 0.000000001 + redeem: { + [constants.blockchains.Eosio]: 0.000000001 + } }, [constants.tokens.ethereum.mainnet.DAI]: { issue: 1000000000, - redeem: 0.0001 + redeem: { + [constants.blockchains.Eosio]: 0.000000001 + } }, [constants.tokens.ethereum.mainnet.ANT]: { issue: 1000000000, - redeem: 0.000000001 + redeem: { + [constants.blockchains.Eosio]: 0.000000001 + } }, [constants.tokens.ethereum.mainnet.LRC]: { issue: 1000000000, - redeem: 0.000000001 + redeem: { + [constants.blockchains.Eosio]: 0.000000001 + } }, [constants.tokens.ethereum.mainnet.UOS]: { issue: 1, - redeem: 0.0001 + redeem: { + [constants.blockchains.Eosio]: 0.000000001 + } }, [constants.tokens.ethereum.mainnet.BAT]: { issue: 1000000000, - redeem: 0.000000001 + redeem: { + [constants.blockchains.Eosio]: 0.000000001 + } }, [constants.tokens.ethereum.mainnet.REP]: { issue: 1000000000, - redeem: 0.000000001 + redeem: { + [constants.blockchains.Eosio]: 0.000000001 + } }, [constants.tokens.ethereum.mainnet.ZRX]: { issue: 1000000000, - redeem: 0.000000001 + redeem: { + [constants.blockchains.Eosio]: 0.000000001 + } }, [constants.tokens.ethereum.mainnet.PNK]: { issue: 1000000000, - redeem: 0.000000001 + redeem: { + [constants.blockchains.Eosio]: 0.000000001 + } + }, + [constants.tokens.ethereum.mainnet.OPIUM]: { + issue: 1000000000, + redeem: { + [constants.blockchains.BinanceSmartChain]: 1000000000 + } + }, + [constants.tokens.ethereum.mainnet['DEFI++']]: { + issue: 1000000000, + redeem: { + [constants.blockchains.BinanceSmartChain]: 1000000000 + } + }, + [constants.tokens.ethereum.mainnet.BCP]: { + issue: 1000000000, + redeem: { + [constants.blockchains.BinanceSmartChain]: 1000000000 + } + }, + [constants.tokens.ethereum.mainnet.CGG]: { + issue: 1000000000, + redeem: { + [constants.blockchains.BinanceSmartChain]: 1000000000 + } + }, + [constants.tokens.ethereum.mainnet.USDC]: { + issue: 5000000, + redeem: { + [constants.blockchains.Telos]: 0.000000001 + } + }, + [constants.tokens.ethereum.mainnet.USDT]: { + issue: 5000000, + redeem: { + [constants.blockchains.Telos]: 0.000000001 + } + }, + [constants.tokens.ethereum.mainnet.OPEN]: { + issue: 1000000000, + redeem: { + [constants.blockchains.BinanceSmartChain]: 1000000000 + } } } diff --git a/packages/ptokens-perc20/types/index.d.ts b/packages/ptokens-perc20/types/index.d.ts index 624ffce6..a58f086d 100644 --- a/packages/ptokens-perc20/types/index.d.ts +++ b/packages/ptokens-perc20/types/index.d.ts @@ -16,9 +16,16 @@ export interface pERC20Configs { nativeBlockchain?: string, ethPrivateKey?: string, ethProvider?: string | object, + bscPrivateKey?: string, + bscProvider?: string | object, + xdaiPrivateKey?: string, + xdaiProvider?: string | object, eosPrivateKey?: string, eosRpc?: string | JsonRpc, - eosSignatureProvider?: JsSignatureProvider + eosSignatureProvider?: JsSignatureProvider, + telosPrivateKey?: string, + telosRpc?: string | JsonRpc, + teolsSignatureProvider?: JsSignatureProvider, defaultNode?: Node, pToken: string } @@ -29,9 +36,12 @@ export interface IssueOptions { } export interface RedeemOptions { - blocksBehind: number, - expireSeconds: number, - permission: string, + blocksBehind?: number, + expireSeconds?: number, + permission?: string, + actor?: string, + gasPrice?: string | number, + gas?: string | number } /* diff --git a/packages/ptokens-pltc/package.json b/packages/ptokens-pltc/package.json index dd10132a..5684be6d 100644 --- a/packages/ptokens-pltc/package.json +++ b/packages/ptokens-pltc/package.json @@ -1,6 +1,6 @@ { "name": "ptokens-pltc", - "version": "0.10.0", + "version": "0.11.0", "description": "repo holding the code for interacting with PLTC", "repository": "https://github.com/provable-things/ptokens.js/tree/master/packages/ptokens-pltc", "main": "dist/ptokens-pltc.cjs.js", @@ -30,10 +30,10 @@ "bitcoinjs-lib": "^5.1.6", "chai": "^4.2.0", "eosjs": "^20.0.0", - "ptokens-deposit-address": "^0.10.0", - "ptokens-node": "^0.10.0", - "ptokens-node-selector": "^0.10.0", - "ptokens-utils": "^0.10.0", + "ptokens-deposit-address": "^0.11.0", + "ptokens-node": "^0.11.0", + "ptokens-node-selector": "^0.11.0", + "ptokens-utils": "^0.11.0", "web3": "^1.2.2", "web3-core-promievent": "^1.2.1", "web3-utils": "^1.2.4" diff --git a/packages/ptokens-pltc/src/index.js b/packages/ptokens-pltc/src/index.js index 4abbaa72..dff3471d 100644 --- a/packages/ptokens-pltc/src/index.js +++ b/packages/ptokens-pltc/src/index.js @@ -59,7 +59,7 @@ export class pLTC extends NodeSelector { throw new Error('Invalid Ethereum Address') const selectedNode = this.selectedNode ? this.selectedNode : await this.select() - if (!selectedNode) throw new Error('No node selected. Impossible to generate a BTC deposit Address.') + if (!selectedNode) throw new Error('No node selected. Impossible to generate a LTC deposit Address.') const depositAddress = new DepositAddress({ node: selectedNode, @@ -87,7 +87,7 @@ export class pLTC extends NodeSelector { const start = async () => { try { - const { gas, gasPrice, blocksBehind, expireSeconds, permission } = _options + const { gas, gasPrice, blocksBehind, expireSeconds, permission, actor } = _options if (_amount < MINIMUM_LTC_REDEEMABLE) { promiEvent.reject(`Impossible to burn less than ${MINIMUM_LTC_REDEEMABLE} pLTC`) @@ -103,11 +103,11 @@ export class pLTC extends NodeSelector { const contractAddress = await this._getContractAddress() - const { redeemFromEthereum, redeemFromEosio } = redeemFrom + const { redeemFromEvmCompatible, redeemFromEosio } = redeemFrom let hostTxHash = null if (this.hostBlockchain === constants.blockchains.Ethereum) { - const ethTxReceipt = await redeemFromEthereum( + const ethTxReceipt = await redeemFromEvmCompatible( this.hostApi, { privateKey: this.hostPrivateKey, @@ -137,7 +137,8 @@ export class pLTC extends NodeSelector { { blocksBehind, expireSeconds, - permission + permission, + actor } ) diff --git a/packages/ptokens-pltc/types/index.d.ts b/packages/ptokens-pltc/types/index.d.ts index cc997306..95f087ed 100644 --- a/packages/ptokens-pltc/types/index.d.ts +++ b/packages/ptokens-pltc/types/index.d.ts @@ -32,6 +32,7 @@ export interface RedeemOptions { blocksBehind?: string, expireSeconds?: string, permission?: string, + actor?: string } export class pLTC extends NodeSelector { diff --git a/packages/ptokens-providers/package.json b/packages/ptokens-providers/package.json index 684751ff..2639fa20 100644 --- a/packages/ptokens-providers/package.json +++ b/packages/ptokens-providers/package.json @@ -1,6 +1,6 @@ { "name": "ptokens-providers", - "version": "0.10.0", + "version": "0.11.0", "description": "repo holding the code related to network providers", "repository": "https://github.com/provable-things/ptokens.js/tree/master/packages/ptokens-providers", "main": "dist/ptokens-providers.cjs.js", diff --git a/packages/ptokens-prvn/README.md b/packages/ptokens-prvn/README.md new file mode 100644 index 00000000..2186837d --- /dev/null +++ b/packages/ptokens-prvn/README.md @@ -0,0 +1,57 @@ +# ptokens-prvn + +Module for interacting only with pRVN. + +  + +*** + +  + +### Installation: + +``` +npm install ptokens-prvn +``` + +  + +*** + +  + +### Usage: + +```js +import { pRVN } from 'ptokens-prvn' +import { HttpProvider } from 'ptokens-providers' +import { Node } from 'ptokens-node' +import { constants } from 'ptokens-utils' + +const { blockchains, networks, pTokens } = constants + +const prvn = new pRVN({ + blockchain: blockchains.BinanceSmartChain, + network: networks.Mainnet, // 'testnet' or 'mainnet', default 'testnet' + + // if you want to be more detailed + hostBlockchain: blockchains.BinanceSmartChain,, + hostNetwork: networks.BinanceSmartChainNetwork, + nativeBlockchain: blockchains.Ravencoin, + nativeNetwork: blockchains.RavenCoinMainnet + + // optionals + bscPrivateKey: 'BSC private key', + bscProvider: 'BSC provider', // or instance of Web3 provider + defaultNode: new Node({ + pToken: pTokens.pRVN, + blockchain: 'ETH', + provider: new HttpProvider( + 'node endpoint', + { + 'Access-Control-Allow-Origin': '*', + ... + } + ) + }) +}) \ No newline at end of file diff --git a/packages/ptokens-prvn/jest.config.js b/packages/ptokens-prvn/jest.config.js new file mode 100644 index 00000000..08880dad --- /dev/null +++ b/packages/ptokens-prvn/jest.config.js @@ -0,0 +1,3 @@ +const jestConfig = require('../../jest.config') + +module.exports = jestConfig() diff --git a/packages/ptokens-prvn/package.json b/packages/ptokens-prvn/package.json new file mode 100644 index 00000000..9b8091b9 --- /dev/null +++ b/packages/ptokens-prvn/package.json @@ -0,0 +1,49 @@ +{ + "name": "ptokens-prvn", + "version": "0.11.0", + "description": "repo holding the code for interacting with pRVN", + "repository": "https://github.com/provable-things/ptokens.js/tree/master/packages/ptokens-prvn", + "main": "dist/ptokens-prvn.cjs.js", + "module": "dist/ptokens-prvn.esm.js", + "browser": "dist/ptokens-prvn.umd.js", + "types": "types/index.d.ts", + "scripts": { + "build": "rollup -c", + "dev": "rollup -c -w", + "test": "jest --ci --forceExit --detectOpenHandles", + "lint": "npx eslint ./src --fix && npx eslint ./tests --fix", + "dtslint": "dtslint types --onlyTestTsNext" + }, + "keywords": [ + "ptokens", + "javaScript", + "ravencoin", + "pnetwork", + "binance-smart-chain" + ], + "author": "alle.manfredi@gmail.com @provable-things", + "license": "LGPL-3.0", + "dependencies": { + "@babel/runtime": "^7.3.1", + "@types/node": "^12.6.1", + "bignumber.js": "^9.0.0", + "chai": "^4.2.0", + "eosjs": "^20.0.0", + "ptokens-deposit-address": "^0.11.0", + "ptokens-node": "^0.11.0", + "ptokens-node-selector": "^0.11.0", + "ptokens-utils": "^0.11.0", + "web3": "^1.2.2", + "web3-core-promievent": "^1.2.1", + "web3-utils": "^1.2.4" + }, + "devDependencies": { + "dtslint": "0.4.2", + "jest": "^24.8.0", + "qrcode-terminal": "^0.12.0" + }, + "files": [ + "dist", + "types/index.d.ts" + ] +} diff --git a/packages/ptokens-prvn/rollup.config.js b/packages/ptokens-prvn/rollup.config.js new file mode 100644 index 00000000..52383267 --- /dev/null +++ b/packages/ptokens-prvn/rollup.config.js @@ -0,0 +1,9 @@ +import pkg from './package.json' +import rollupConfig from '../../rollup.config' + +export default rollupConfig('pRVN', pkg.name, { + 'ptokens-deposit-address': 'ptokens-deposit-address', + 'ptokens-node-selector': 'ptokens-node-selector', + 'ptokens-node': 'ptokens-node', + 'ptokens-utils': 'ptokens-utils' +}) diff --git a/packages/ptokens-prvn/src/index.js b/packages/ptokens-prvn/src/index.js new file mode 100644 index 00000000..6a4b679a --- /dev/null +++ b/packages/ptokens-prvn/src/index.js @@ -0,0 +1,154 @@ +import Web3 from 'web3' +import Web3PromiEvent from 'web3-core-promievent' +import { NodeSelector } from 'ptokens-node-selector' +import { constants, eth, rvn, helpers, redeemFrom } from 'ptokens-utils' +import { DepositAddress } from 'ptokens-deposit-address' +import Web3Utils from 'web3-utils' + +const MINIMUM_RVN_REDEEMABLE = 0.00005 + +export class pRVN extends NodeSelector { + /** + * @param {Object} _configs + */ + constructor(_configs) { + const { hostBlockchain, hostNetwork, nativeBlockchain, nativeNetwork } = helpers.parseParams( + _configs, + constants.blockchains.Ravencoin + ) + + super({ + pToken: constants.pTokens.pRVN, + hostBlockchain, + hostNetwork, + nativeBlockchain, + nativeNetwork, + defaultNode: _configs.defaultNode + }) + + const { bscPrivateKey, bscProvider } = _configs + + if (bscProvider) this.hostApi = new Web3(bscProvider) + if (bscPrivateKey) { + const account = this.hostApi.eth.accounts.privateKeyToAccount(eth.addHexPrefix(bscPrivateKey)) + this.hostApi.eth.defaultAccount = account.address + this.hostPrivateKey = eth.addHexPrefix(bscPrivateKey) + } else { + this.hostPrivateKey = null + } + + this.contractAddress = null + this.decimals = null + } + + /** + * @param {String} _hostAddress + */ + async getDepositAddress(_hostAddress) { + if (this.hostBlockchain === constants.blockchains.BinanceSmartChain && !Web3Utils.isAddress(_hostAddress)) + throw new Error('Invalid Binance Smart Chain Address') + + const selectedNode = this.selectedNode ? this.selectedNode : await this.select() + if (!selectedNode) throw new Error('No node selected. Impossible to generate a RVN deposit Address.') + + const depositAddress = new DepositAddress({ + node: selectedNode, + nativeBlockchain: this.nativeBlockchain, + nativeNetwork: this.nativeNetwork, + hostBlockchain: this.hostBlockchain, + hostNetwork: this.hostNetwork, + hostApi: this.hostApi + }) + + await depositAddress.generate(_hostAddress) + if (!depositAddress.verify()) throw new Error('Node deposit address does not match expected address') + return depositAddress + } + + /** + * @param {Number|String|BigNumber} _amount + * @param {String} _rvnAddress + * @param {RedeemOptions} _options + */ + redeem(_amount, _rvnAddress, _options = {}) { + const promiEvent = Web3PromiEvent() + + const start = async () => { + try { + const { gas, gasPrice } = _options + + if (_amount < MINIMUM_RVN_REDEEMABLE) { + promiEvent.reject(`Impossible to burn less than ${MINIMUM_RVN_REDEEMABLE} pRVN`) + return + } + + if (!rvn.isValidAddress(_rvnAddress)) { + promiEvent.reject('Invalid Ravecoin Address') + return + } + + if (!this.selectedNode) await this.select() + const contractAddress = await this._getContractAddress() + + const { redeemFromEvmCompatible } = redeemFrom + let hostTxHash = null + + if (this.hostBlockchain === constants.blockchains.BinanceSmartChain) { + const bscTxReceipt = await redeemFromEvmCompatible( + this.hostApi, + { + privateKey: this.hostPrivateKey, + gas, + gasPrice, + contractAddress, + value: 0 + }, + [_amount, _rvnAddress], + promiEvent, + 'hostTxBroadcasted' + ) + promiEvent.eventEmitter.emit('hostTxConfirmed', bscTxReceipt) + hostTxHash = bscTxReceipt.transactionHash + } + + const broadcastedRvnTxReport = await this.selectedNode.monitorIncomingTransaction( + hostTxHash, + promiEvent.eventEmitter + ) + + const broadcastedRvnTxReceipt = await rvn.waitForTransactionConfirmation( + this.nativeNetwork, + broadcastedRvnTxReport.broadcast_tx_hash + ) + promiEvent.eventEmitter.emit('nativeTxConfirmed', broadcastedRvnTxReceipt) + + promiEvent.resolve({ + amount: _amount, + hostTx: hostTxHash, + nativeTx: broadcastedRvnTxReport.broadcast_tx_hash, + to: _rvnAddress + }) + } catch (_err) { + promiEvent.reject(_err) + } + } + + start() + return promiEvent.eventEmitter + } + + async _getContractAddress() { + try { + if (!this.contractAddress) { + if (!this.selectedNode) await this.select() + + const { smart_contract_address } = await this.selectedNode.getInfo() + this.contractAddress = smart_contract_address + } + + return this.contractAddress + } catch (_err) { + throw new Error(`Error during getting contract address: ${_err.message}`) + } + } +} diff --git a/packages/ptokens-prvn/tests/ptokens-prvn-on-bsc.test.js b/packages/ptokens-prvn/tests/ptokens-prvn-on-bsc.test.js new file mode 100644 index 00000000..1a530348 --- /dev/null +++ b/packages/ptokens-prvn/tests/ptokens-prvn-on-bsc.test.js @@ -0,0 +1,119 @@ +import { pRVN } from '../src/index' +import { expect } from 'chai' +import { constants } from 'ptokens-utils' +import BigNumber from 'bignumber.js' +// import qrcode from 'qrcode-terminal' + +const BSC_TESTING_ADDRESS = '' +const BSC_TESTING_PRIVATE_KEY = '' +const RVN_TESTING_ADDRESS = '' +const WEB3_PROVIDER = '' + +jest.setTimeout(3000000) + +let prvn +beforeEach(() => { + prvn = new pRVN({ + blockchain: constants.blockchains.BinanceSmartChain, + network: constants.networks.Mainnet, + bscPrivateKey: BSC_TESTING_PRIVATE_KEY, + bscProvider: WEB3_PROVIDER + }) +}) + +test('Should get a RVN deposit address on Binance Smart Chain Mainnet', async () => { + const expectedHostNetwork = 'mainnet' + const depositAddress = await prvn.getDepositAddress(BSC_TESTING_ADDRESS) + expect(depositAddress.toString()).to.be.a('string') + expect(prvn.hostNetwork).to.be.equal(expectedHostNetwork) +}) + +test('Should not get a RVN deposit address because of invalid Binance Smart Chain address', async () => { + try { + await prvn.getDepositAddress('invalid address') + } catch (err) { + expect(err.message).to.be.equal('Invalid Binance Smart Chain Address') + } +}) + +test('Should monitor an issuing of pRVN on Binance Smart Chain', async () => { + const depositAddress = await prvn.getDepositAddress(BSC_TESTING_ADDRESS) + + /* qrcode.generate(depositAddress.toString(), { small: true }, _qrcode => { + console.log(_qrcode) + }) */ + + let rvnTxIsBroadcasted = false + let rvnTxIsConfirmed = false + let nodeHasReceivedTx = false + let nodeHasBroadcastedTx = false + let bscTxIsConfirmed = false + const start = () => + new Promise(resolve => { + depositAddress + .waitForDeposit() + .once('nativeTxBroadcasted', () => { + rvnTxIsBroadcasted = true + }) + .once('nativeTxConfirmed', () => { + rvnTxIsConfirmed = true + }) + .once('nodeReceivedTx', e => { + nodeHasReceivedTx = true + }) + .once('nodeBroadcastedTx', () => { + nodeHasBroadcastedTx = true + }) + .once('hostTxConfirmed', () => { + bscTxIsConfirmed = true + }) + .then(() => resolve()) + }) + await start() + + expect(rvnTxIsBroadcasted).to.equal(true) + expect(rvnTxIsConfirmed).to.equal(true) + expect(nodeHasReceivedTx).to.equal(true) + expect(nodeHasBroadcastedTx).to.equal(true) + expect(bscTxIsConfirmed).to.equal(true) +}) + +test('Should monitoring a redeem of 0.01 pRVN on Binance Smart Chain', async () => { + const amountToRedeem = BigNumber(0.01).multipliedBy(10 ** 18) + let bscTxBroadcasted = false + let bscTxIsConfirmed = false + let nodeHasReceivedTx = false + let nodeHasBroadcastedTx = false + let rvnTxIsConfirmed = false + const start = () => + new Promise((resolve, reject) => { + prvn + .redeem(amountToRedeem, RVN_TESTING_ADDRESS, { + gasPrice: 10e9, + gas: 200000 + }) + .once('hostTxBroadcasted', () => { + bscTxBroadcasted = true + }) + .once('hostTxConfirmed', () => { + bscTxIsConfirmed = true + }) + .once('nodeReceivedTx', () => { + nodeHasReceivedTx = true + }) + .once('nodeBroadcastedTx', () => { + nodeHasBroadcastedTx = true + }) + .once('nativeTxConfirmed', e => { + rvnTxIsConfirmed = true + }) + .then(() => resolve()) + .catch(_err => reject(_err)) + }) + await start() + expect(bscTxBroadcasted).to.equal(true) + expect(bscTxIsConfirmed).to.equal(true) + expect(nodeHasReceivedTx).to.equal(true) + expect(nodeHasBroadcastedTx).to.equal(true) + expect(rvnTxIsConfirmed).to.equal(true) +}) diff --git a/packages/ptokens-prvn/types/index.d.ts b/packages/ptokens-prvn/types/index.d.ts new file mode 100644 index 00000000..157943bf --- /dev/null +++ b/packages/ptokens-prvn/types/index.d.ts @@ -0,0 +1,50 @@ +import { Report } from 'ptokens-node' +import { + RavencoinTransactionReceipt +} from 'ptokens-utils' +import { TransactionReceipt, PromiEvent } from 'web3-core' +import Web3 from 'web3' +import { NodeSelector } from 'ptokens-node-selector' +import { BigNumber } from 'bignumber.js' +import { DepositAddress } from 'ptokens-deposit-address' + +export interface pRVNConfigs { + network?: string, + hostNetwork?: string, + blockchain?: string, + hostBlockchain?: string, + nativeNetwork?: string, + nativeBlockchain?: string, + bscPrivateKey?: string, + bscProvider?: string | object, +} + +export interface RedeemOptions { + gas?: number, + gasPrice?: number | string | BigNumber, +} + +export class pRVN extends NodeSelector { + constructor(configs: pRVNConfigs) + + nodeSelector: NodeSelector + + decimals: string | null + + contractAddress: string | null + + hostPrivatekey?: string | null + + hostApi?: Web3 + + getDepositAddress(_hostAddress: string): Promise + + redeem(_amount: number|string|BigNumber, _ltcAddress: string, _options: RedeemOptions): PromiEvent +} + +export interface RedeemResult { + amount: number, + nativeTx: string, + hostTx: string, + to: string, +} diff --git a/packages/ptokens-prvn/types/tests/ptokens-prvn-test.ts b/packages/ptokens-prvn/types/tests/ptokens-prvn-test.ts new file mode 100644 index 00000000..0a880d2f --- /dev/null +++ b/packages/ptokens-prvn/types/tests/ptokens-prvn-test.ts @@ -0,0 +1,15 @@ +import { pRVN } from 'ptokens-prvn' + +const prvn = new pRVN({ + network: 'mainnet', + blockchain: 'eth' +}) + +// $ExpectType Promise +prvn.getDepositAddress('eth address') + +// $ExpectType PromiEvent +prvn.redeem(10, 'rvn address', { + gas: 10, + gasPrice: 10 +}) diff --git a/packages/ptokens-prvn/types/tsconfig.json b/packages/ptokens-prvn/types/tsconfig.json new file mode 100644 index 00000000..798f6bb6 --- /dev/null +++ b/packages/ptokens-prvn/types/tsconfig.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "module": "commonjs", + "lib": ["es6", "dom"], + "target": "es6", + "noImplicitAny": true, + "noImplicitThis": true, + "strictNullChecks": true, + "strictFunctionTypes": true, + "noEmit": true, + "allowSyntheticDefaultImports": false, + "baseUrl": ".", + "paths": { + "ptokens-prvn": ["."] + } + } +} diff --git a/packages/ptokens-prvn/types/tslint.json b/packages/ptokens-prvn/types/tslint.json new file mode 100644 index 00000000..0435f238 --- /dev/null +++ b/packages/ptokens-prvn/types/tslint.json @@ -0,0 +1,10 @@ +{ + "extends": "dtslint/dtslint.json", + "rules": { + "semicolon": false, + "no-import-default-of-export-equals": false, + "file-name-casing": [true, "kebab-case"], + "whitespace": false, + "no-unnecessary-class": false + } +} diff --git a/packages/ptokens-utils/package.json b/packages/ptokens-utils/package.json index d5175a13..45d1882a 100644 --- a/packages/ptokens-utils/package.json +++ b/packages/ptokens-utils/package.json @@ -1,6 +1,6 @@ { "name": "ptokens-utils", - "version": "0.10.0", + "version": "0.11.0", "description": "repo holding some utils needed by other packages", "repository": "https://github.com/provable-things/ptokens.js/tree/master/packages/ptokens-utils", "main": "dist/ptokens-utils.cjs.js", diff --git a/packages/ptokens-utils/src/constants.js b/packages/ptokens-utils/src/constants.js index c153bc27..2e2db78a 100644 --- a/packages/ptokens-utils/src/constants.js +++ b/packages/ptokens-utils/src/constants.js @@ -21,6 +21,8 @@ import { PolygonMainnet, Xdai, XdaiMainnet, + Ravencoin, + RavencoinMainnet, Mainnet, Testnet, pBTC, @@ -49,7 +51,16 @@ import { pDOGE, pEOS, IQ, - TLOS + TLOS, + pOPIUM, + pBCP, + pDEFIPlusPlus, + CGG, + pUSDT, + pUSDC, + pRVN, + pOPEN, + OCP } from './helpers/names' import tokens from './helpers/tokens' @@ -66,7 +77,8 @@ const blockchains = { Dogecoin, BinanceSmartChain, Polygon, - Xdai + Xdai, + Ravencoin } /** @@ -88,7 +100,8 @@ const networks = { DogecoinMainnet, BinanceSmartChainMainnet, PolygonMainnet, - XdaiMainnet + XdaiMainnet, + RavencoinMainnet } /** @@ -122,7 +135,16 @@ const pTokens = { pDOGE, pEOS, IQ, - TLOS + TLOS, + pOPIUM, + pBCP, + pDEFIPlusPlus, + CGG, + pUSDT, + pUSDC, + pRVN, + pOPEN, + OCP } export { blockchains, networks, pTokens, tokens } diff --git a/packages/ptokens-utils/src/eos.js b/packages/ptokens-utils/src/eos.js index a48194b1..c159ddc4 100644 --- a/packages/ptokens-utils/src/eos.js +++ b/packages/ptokens-utils/src/eos.js @@ -6,7 +6,6 @@ import polling from 'light-async-polling' const EOS_MAX_ACCOUNT_LENGTH = 12 const EOS_TRANSACTION_EXECUTED = 'executed' -const EOS_NODE_POLLING_TIME_INTERVAL = 300 /** * @param {String} _privateKey @@ -36,19 +35,6 @@ const getApi = (_privateKey, _rpc, _signatureProvider = null) => { }) } -/** - * @param {JsonRpc} _rpc - * @param {Array} _pubkeys - */ -const getAccountName = (_rpc, _pubkeys) => - new Promise((resolve, reject) => { - const currentPublicKey = _pubkeys[0] - _rpc - .history_get_key_accounts(currentPublicKey) - .then(accounts => resolve(accounts.account_names[0])) - .catch(err => reject(err)) - }) - /** * @param {Number} _amount */ @@ -66,19 +52,18 @@ const isValidAccountName = _accountName => * @param {Api} _api * @param {String} _tx */ -const waitForTransactionConfirmation = async (_api, _tx) => { +const waitForTransactionConfirmation = async (_api, _tx, _pollingTime = 2000) => { let receipt = null await polling(async () => { try { receipt = await _api.rpc.history_get_transaction(_tx) - if (receipt && receipt.trx.receipt.status === EOS_TRANSACTION_EXECUTED) return true else return false } catch (err) { return false } - }, EOS_NODE_POLLING_TIME_INTERVAL) + }, _pollingTime) return receipt } -export { getApi, getAccountName, getAmountInEosFormat, isValidAccountName, waitForTransactionConfirmation } +export { getApi, getAmountInEosFormat, isValidAccountName, waitForTransactionConfirmation } diff --git a/packages/ptokens-utils/src/eth.js b/packages/ptokens-utils/src/eth.js index f3219648..c9859a59 100644 --- a/packages/ptokens-utils/src/eth.js +++ b/packages/ptokens-utils/src/eth.js @@ -169,7 +169,7 @@ const sendSignedMethodTx = (_web3, _method, _options, _params) => { * @param {String} _tx * @param {Number} _pollingTime */ -const waitForTransactionConfirmation = async (_web3, _tx, _pollingTime) => { +const waitForTransactionConfirmation = async (_web3, _tx, _pollingTime = 5000) => { let receipt = null await polling(async () => { receipt = await _web3.eth.getTransactionReceipt(_tx) diff --git a/packages/ptokens-utils/src/helpers/maps.js b/packages/ptokens-utils/src/helpers/maps.js index f0afba25..e85bb1aa 100644 --- a/packages/ptokens-utils/src/helpers/maps.js +++ b/packages/ptokens-utils/src/helpers/maps.js @@ -21,6 +21,8 @@ import { PolygonMainnet, Xdai, XdaiMainnet, + Ravencoin, + RavencoinMainnet, Mainnet, Testnet, pBTC, @@ -49,7 +51,16 @@ import { pDOGE, pEOS, IQ, - TLOS + TLOS, + pOPIUM, + pBCP, + pDEFIPlusPlus, + CGG, + pUSDC, + pUSDT, + pRVN, + pOPEN, + OCP } from './names' export const blockchainTypes = { @@ -68,7 +79,9 @@ export const blockchainTypes = { bsc: BinanceSmartChain, matic: Polygon, polygon: Polygon, - xdai: Xdai + xdai: Xdai, + ravencoin: Ravencoin, + rvn: Ravencoin } export const blockchainShortTypes = { @@ -81,7 +94,8 @@ export const blockchainShortTypes = { 'binance-smart-chain': 'bsc', matic: 'polygon', polygon: 'polygon', - xdai: 'xdai' + xdai: 'xdai', + ravencoin: 'rvn' } export const pTokenNativeBlockchain = { @@ -111,7 +125,16 @@ export const pTokenNativeBlockchain = { pdoge: Dogecoin, peos: Eosio, iq: Eosio, - tlos: Telos + tlos: Telos, + popium: Ethereum, + pbcp: Ethereum, + pdefiplusplus: Ethereum, + cgg: Ethereum, + pusdc: Ethereum, + pusdt: Ethereum, + prvn: Ravencoin, + popen: Ethereum, + ocp: BinanceSmartChain } export const networkLabels = { @@ -153,6 +176,10 @@ export const networkLabels = { }, xdai: { mainnet: XdaiMainnet + }, + ravencoin: { + mainnet: RavencoinMainnet, + ravencoin: RavencoinMainnet } } @@ -190,5 +217,14 @@ export const pTokensAvailables = [ pDOGE, pEOS, IQ, - TLOS + TLOS, + pOPIUM, + pBCP, + pDEFIPlusPlus, + CGG, + pUSDT, + pUSDC, + pRVN, + pOPEN, + OCP ] diff --git a/packages/ptokens-utils/src/helpers/names.js b/packages/ptokens-utils/src/helpers/names.js index f287df1b..87694234 100644 --- a/packages/ptokens-utils/src/helpers/names.js +++ b/packages/ptokens-utils/src/helpers/names.js @@ -7,6 +7,7 @@ export const Dogecoin = 'dogecoin' export const BinanceSmartChain = 'binance-smart-chain' export const Polygon = 'polygon' export const Xdai = 'xdai' +export const Ravencoin = 'ravencoin' export const Testnet = 'testnet' export const Mainnet = 'mainnet' @@ -24,6 +25,7 @@ export const DogecoinMainnet = 'mainnet' export const BinanceSmartChainMainnet = 'mainnet' export const PolygonMainnet = 'mainnet' export const XdaiMainnet = 'mainnet' +export const RavencoinMainnet = 'mainnet' export const pBTC = 'pbtc' export const pLTC = 'pltc' @@ -52,3 +54,12 @@ export const pDOGE = 'pdoge' export const pEOS = 'peos' export const IQ = 'iq' export const TLOS = 'tlos' +export const pOPIUM = 'popium' +export const pBCP = 'pbcp' +export const pDEFIPlusPlus = 'pdefiplusplus' +export const CGG = 'cgg' +export const pUSDC = 'pusdc' +export const pUSDT = 'pusdt' +export const pRVN = 'prvn' +export const pOPEN = 'popen' +export const OCP = 'ocp' diff --git a/packages/ptokens-utils/src/helpers/tokens.js b/packages/ptokens-utils/src/helpers/tokens.js index d2764ffa..3e2e9016 100644 --- a/packages/ptokens-utils/src/helpers/tokens.js +++ b/packages/ptokens-utils/src/helpers/tokens.js @@ -1,4 +1,13 @@ -import { EthereumMainnet, EosioMainnet, Ethereum, Eosio, Telos, TelosMainnet } from './names' +import { + EthereumMainnet, + EosioMainnet, + Ethereum, + Eosio, + Telos, + TelosMainnet, + BinanceSmartChain, + BinanceSmartChainMainnet +} from './names' export default { [Ethereum]: { @@ -23,7 +32,19 @@ export default { BAT: '0x0d8775f648430679a709e98d2b0cb6250d2887ef', REP: '0x221657776846890989a759ba2973e427dff5c9bb', ZRX: '0xe41d2489571d322189246dafa5ebde1f4699f498', - PNK: '0x93ed3fbe21207ec2e8f2d3c3de6e058cb73bc04d' + PNK: '0x93ed3fbe21207ec2e8f2d3c3de6e058cb73bc04d', + OPIUM: '0x888888888889c00c67689029d7856aac1065ec11', + BCP: '0xe4f726adc8e89c6a6017f01eada77865db22da14', + 'DEFI++': '0x8d1ce361eb68e9e05573443c407d4a3bed23b033', + CGG: '0x1fe24f25b1cf609b9c4e7e12d802e3640dfa5e43', + USDT: '0xdac17f958d2ee523a2206206994597c13d831ec7', + USDC: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', + OPEN: '0x69e8b9528cabda89fe846c67675b5d73d463a916' + } + }, + [BinanceSmartChain]: { + [BinanceSmartChainMainnet]: { + OCP: '0x3c70260eee0a2bfc4b375feb810325801f289fbd' } }, [Eosio]: { diff --git a/packages/ptokens-utils/src/index.js b/packages/ptokens-utils/src/index.js index 1f2727df..67d04fa8 100644 --- a/packages/ptokens-utils/src/index.js +++ b/packages/ptokens-utils/src/index.js @@ -4,10 +4,11 @@ import * as ltc from './ltc' import * as converters from './converters' import * as eth from './eth' import * as eos from './eos' +import * as rvn from './rvn' import * as helpers from './helpers/index' import * as constants from './constants' import { redeemFromEosio } from './redeem-from/redeem-from-eosio' -import { redeemFromEthereum } from './redeem-from/redeem-from-ethereum' +import { redeemFromEvmCompatible } from './redeem-from/redeem-from-evm-compatible' import pERC20VaultContractAbi from './abi/pERC20VaultContractAbi.json' import pTokenOnEosAbi from './abi/pTokenOnEOSContractAbi.json' import pTokenOnEthAbi from './abi/pTokenOnETHContractAbi.json' @@ -29,8 +30,9 @@ export default { telos: eos, helpers, ltc, + rvn, redeemFrom: { - redeemFromEthereum, + redeemFromEvmCompatible, redeemFromEosio } } diff --git a/packages/ptokens-utils/src/redeem-from/redeem-from-eosio.js b/packages/ptokens-utils/src/redeem-from/redeem-from-eosio.js index 00e80a88..e615cb13 100644 --- a/packages/ptokens-utils/src/redeem-from/redeem-from-eosio.js +++ b/packages/ptokens-utils/src/redeem-from/redeem-from-eosio.js @@ -1,16 +1,9 @@ -import { getAccountName, getAmountInEosFormat } from '../eos' +import { getAmountInEosFormat } from '../eos' import pTokenOnEosAbi from '../abi/pTokenOnEOSContractAbi.json' const redeemFromEosio = async (_api, _amount, _nativeAddress, _decimals, _contractAddress, _pToken, _options) => { try { - const { blocksBehind, expireSeconds, permission } = _options - const eosPublicKeys = await _api.signatureProvider.getAvailableKeys() - const eosAccountName = await getAccountName(_api.rpc, eosPublicKeys) - if (!eosAccountName) { - // prettier-ignore - throw new Error('Account name does not exist. Check that you entered it correctly or make sure to have enabled history plugin') - } - + const { blocksBehind, expireSeconds, permission, actor } = _options _api.cachedAbis.set(_contractAddress, { abi: pTokenOnEosAbi, rawAbi: null @@ -24,12 +17,12 @@ const redeemFromEosio = async (_api, _amount, _nativeAddress, _decimals, _contra name: 'redeem', authorization: [ { - actor: eosAccountName, + actor, permission } ], data: { - sender: eosAccountName, + sender: actor, quantity: getAmountInEosFormat(_amount, _decimals, _pToken.toUpperCase()), memo: _nativeAddress } diff --git a/packages/ptokens-utils/src/redeem-from/redeem-from-ethereum.js b/packages/ptokens-utils/src/redeem-from/redeem-from-evm-compatible.js similarity index 83% rename from packages/ptokens-utils/src/redeem-from/redeem-from-ethereum.js rename to packages/ptokens-utils/src/redeem-from/redeem-from-evm-compatible.js index 5fedc384..38f74cf3 100644 --- a/packages/ptokens-utils/src/redeem-from/redeem-from-ethereum.js +++ b/packages/ptokens-utils/src/redeem-from/redeem-from-evm-compatible.js @@ -1,7 +1,7 @@ import * as eth from '../eth' import pTokenOnEth from '../abi/pTokenOnETHContractAbi.json' -const redeemFromEthereum = (_web3, _options, _params, _promiEvent, _broadcastEventName) => +const redeemFromEvmCompatible = (_web3, _options, _params, _promiEvent, _broadcastEventName) => new Promise((_resolve, _reject) => { eth[_options.privateKey ? 'sendSignedMethodTx' : 'makeContractSend']( _web3, @@ -21,4 +21,4 @@ const redeemFromEthereum = (_web3, _options, _params, _promiEvent, _broadcastEve .once('error', _reject) }) -export { redeemFromEthereum } +export { redeemFromEvmCompatible } diff --git a/packages/ptokens-utils/src/rvn.js b/packages/ptokens-utils/src/rvn.js new file mode 100644 index 00000000..ca19361a --- /dev/null +++ b/packages/ptokens-utils/src/rvn.js @@ -0,0 +1,129 @@ +import axios from 'axios' +import polling from 'light-async-polling' +import { Testnet } from './helpers/names' + +const RVN_PTOKENS_NODE_MAINNET_API = 'https://corsproxy.ptokens.io/v1/?apiurl=https://api.ravencoin.org/api' + +const _getInsightLiteApi = _network => { + if (_network === Testnet) throw new Error('Ravecoin Testnet is not supported') + return axios.create({ + baseURL: RVN_PTOKENS_NODE_MAINNET_API, + timeout: 50000, + headers: { + 'Content-Type': 'application/json' + } + }) +} + +const _makeInsightLiteApiCall = (_network, _callType, _apiPath, _params) => + new Promise((resolve, reject) => { + _getInsightLiteApi(_network) + [_callType.toLowerCase()](_apiPath, _params) + .then(_res => resolve(_res.data)) + .catch(_err => reject(_err)) + }) + +/** + * + * @param {String} _network + * @param {String} _tx + */ +const broadcastTransaction = (_network, _tx) => + _makeInsightLiteApiCall(_network, 'POST', '/tx/send', { + rawtx: _tx + }) + +/** + * + * @param {String} _network + * @param {String} _address + */ +const getUtxoByAddress = (_network, _address) => _makeInsightLiteApiCall(_network, 'GET', `/addrs/${_address}/utxo`) + +/** + * + * @param {String} _network + * @param {String} _txId + */ +const getTransactionHexById = (_network, _txId) => _makeInsightLiteApiCall(_network, 'GET', `/rawtx/${_txId}`) + +/** + * @param {String} _address + * @param {String} _network + */ +const isValidAddress = _address => { + const res = _address.match(/(r|R)[a-zA-HJ-NP-Z0-9]{26,40}/g) + if (!res) return false + return res[0] === _address +} + +/** + * @param {String} _address + * @param {EventEmitter} _eventEmitter + */ +const monitorUtxoByAddress = async ( + _network, + _address, + _eventEmitter, + _pollingTime, + _broadcastEventName, + _confirmationEventName, + _confirmations = 1 +) => { + let isBroadcasted = false + let utxo = null + let utxos = [] + await polling(async () => { + utxos = await _makeInsightLiteApiCall(_network, 'GET', `/addrs/${_address}/utxo`) + + if (utxos.length > 0) { + if (utxos[0].confirmations > 0) { + if (!isBroadcasted) { + _eventEmitter.emit(_broadcastEventName, utxos[0]) + isBroadcasted = true + } + + if (utxos[0].confirmations >= _confirmations) { + _eventEmitter.emit(_confirmationEventName, utxos[0]) + utxo = utxos[0].txid + return true + } + return false + } else if (!isBroadcasted) { + isBroadcasted = true + _eventEmitter.emit(_broadcastEventName, utxos[0]) + return false + } + } else { + return false + } + }, _pollingTime) + return utxo +} + +/** + * @param {String} _network + * @param {String} _tx + * @param {Number} _pollingTime + */ +const waitForTransactionConfirmation = async (_network, _tx, _pollingTime = 3000) => { + let transaction = null + await polling(async () => { + try { + transaction = await _makeInsightLiteApiCall(_network, 'GET', `/tx/${_tx}/`) + return transaction.confirmations > 0 + } catch (_err) { + return false + } + }, _pollingTime) + return transaction +} + +export { + broadcastTransaction, + isValidAddress, + getUtxoByAddress, + getTransactionHexById, + monitorUtxoByAddress, + waitForTransactionConfirmation +} diff --git a/packages/ptokens-utils/tests/ptokens-utils.eos.test.js b/packages/ptokens-utils/tests/ptokens-utils.eos.test.js index a8a536ba..00667272 100644 --- a/packages/ptokens-utils/tests/ptokens-utils.eos.test.js +++ b/packages/ptokens-utils/tests/ptokens-utils.eos.test.js @@ -1,23 +1,8 @@ import utils from '../src' import { expect } from 'chai' -import { JsSignatureProvider } from 'eosjs/dist/eosjs-jssig' -import { JsonRpc } from 'eosjs' -import fetch from 'node-fetch' - -const eosPrivateKey = '5JFPd8Kvhf7zSrxKCrMvhK22WKbh1jFw5TLeLjyPpp2yh4SvReS' -const eosProvider = 'https://pbtc-on-eos-jungle-3.ptokens.io' jest.setTimeout(30000) -test('Should get the correct EOS account name', async () => { - const signatureProvider = new JsSignatureProvider([eosPrivateKey]) - const rpc = new JsonRpc(eosProvider, { fetch }) - const expectedAccountName = 'all3manfr4di' - const publicKeys = await signatureProvider.getAvailableKeys() - const accountName = await utils.eos.getAccountName(rpc, publicKeys) - expect(accountName).to.be.equal(expectedAccountName) -}) - test('all3manfr3di should be a valid EOS account name', () => { const validEosAccountName = 'all3manfr3di' const isValid = utils.eos.isValidAccountName(validEosAccountName) diff --git a/packages/ptokens-utils/types/index.d.ts b/packages/ptokens-utils/types/index.d.ts index dcf6b1ca..bb967628 100644 --- a/packages/ptokens-utils/types/index.d.ts +++ b/packages/ptokens-utils/types/index.d.ts @@ -136,7 +136,6 @@ export const eth: EthUtils // eos export interface EosUtils { getApi(_privateKey: string, _rpc: string | JsonRpc, _signatureProvider: JsSignatureProvider | null): Api - getAccountName(_rpc: JsonRpc, _pubkeys: string[]): Promise getAvailablePublicKeys(_signatureProvider: JsSignatureProvider): Promise getAmountInEosFormat(_amount: number, _decimals: number): number isValidAccountName(_accountName: string): boolean @@ -184,7 +183,8 @@ export interface Blockchains { Dogecoin: string, BinanceSmartChain: string, Polygon: string, - Xdai: string + Xdai: string, + Ravencoin: string } export interface Networks { @@ -202,7 +202,8 @@ export interface Networks { DogecoinMainnet: string, BinanceSmartChainMainnet: string, PolygonMainnet: string, - XdaiMainnet: string + XdaiMainnet: string, + RavecoinMainnet: string } export interface pTokens { @@ -232,7 +233,16 @@ export interface pTokens { pDOGE: string, pEOS: string, IQ: string, - TLOS: string + TLOS: string, + pOPIUM: string, + pBCP: string, + pDEFIPlusPlus: string, + CGG: string, + pUSDC: string, + pUSDT: string, + pRVN: string, + pOPEN: string, + OCP: string } export interface EthereumMainnetTokens { @@ -256,7 +266,18 @@ export interface EthereumMainnetTokens { BAT: string, REP: string, ZRX: string, - PNK: string + PNK: string, + OPIUM: string, + BCP: string, + 'DEFI++': string, + CGG: string, + USDC: string, + USDT: string, + OPEN: string +} + +export interface BinanceSmartChainMainnetTokens { + OCP: string } export interface TelosMainnetTokens { @@ -280,10 +301,15 @@ export interface EosioTokens { mainnet: EosioMainnetTokens } +export interface BinanceSmartChainTokens { + mainnet: BinanceSmartChainMainnetTokens +} + export interface Tokens { ethereum: EthereumTokens, eosio: EosioTokens, - telos: TelosTokens + telos: TelosTokens, + 'binance-smart-chain': BinanceSmartChainTokens } export interface Constants { @@ -449,3 +475,91 @@ export interface DogeUtils { } export const doge: LtcUtils + +// ltc +export interface RavencoinUtxoList extends Array {} + +export interface RavencoinUtxo { + address: string, + txid: string, + vout: number + value: number, + scriptPubKey: string, + amount: number, + satoshis: number, + height: number, + confirmations: number +} + +export interface RavencoinBroadcastedTx { + txid: string +} + +export interface RavencoinVin { + addr: string, + doubleSpentTxID: string | null, + n: number, + scriptSig: { + asm: string, + hex: string, + }, + sequence: number + txid: string + value: number + valueSat: number + vout: number +} + +export interface RavencoinVout { + n: number + scriptPubKey: { + addresses: string[], + asm: string, + hex: string, + type: string, + } + spentHeight: number, + spentIndex: number, + spentTxId: string, + value: number, +} + +export interface RavencoinVinList extends Array {} + +export interface RavencoinVoutList extends Array {} + +export interface RavencoinTransactionReceipt { + blockhash: string, + blockheight: number, + blocktime: number, + confirmations: number, + fees: number, + locktime: number, + size: number, + time: number, + txid: string, + valueIn: number, + valueOut: number, + version: number, + vin: LitecoinVinList + vout: LitecoinVoutList +} + +export interface RvnUtils { + broadcastTransaction(_network: string, _tx: string): Promise + getUtxoByAddress(_network: string, _address: string): Promise + getTransactionHexById(_network: string, _txId: string): Promise + isValidAddress(_network: string, _address: string): boolean + monitorUtxoByAddress( + _network: string, + _address: string, + _eventEmitter: EventEmitter, + _pollingTime: number, + _broadcastEventName?: string, + _confirmationEventName?: string, + _confirmations?: number + ): Promise + waitForTransactionConfirmation(_network: string, _tx: string, _pollingTime: number, _broadcastEventName: string, _confirmationEventName: string): Promise +} + +export const rvn: RvnUtils diff --git a/packages/ptokens-utils/types/tests/ptokens-utils-test.ts b/packages/ptokens-utils/types/tests/ptokens-utils-test.ts index abe1e8da..feee057e 100644 --- a/packages/ptokens-utils/types/tests/ptokens-utils-test.ts +++ b/packages/ptokens-utils/types/tests/ptokens-utils-test.ts @@ -125,9 +125,6 @@ const eosApi = new Api({ // $ExpectType Api eos.getApi('private key', 'node endpoint', signatureProvider) -// $ExpectType Promise -eos.getAccountName(jsonRpc, ['pubK1, pubK2']) - // $ExpectType Promise eos.getAvailablePublicKeys(signatureProvider) diff --git a/packages/ptokens/package.json b/packages/ptokens/package.json index a1f663c0..c6571d5d 100644 --- a/packages/ptokens/package.json +++ b/packages/ptokens/package.json @@ -1,6 +1,6 @@ { "name": "ptokens", - "version": "0.10.0", + "version": "0.11.0", "description": "main ptokens package", "repository": "https://github.com/provable-things/ptokens.js/tree/master/packages/ptokens", "main": "dist/ptokens.cjs.js", @@ -21,22 +21,26 @@ "bitcoin", "pnetwork", "litecoin", + "ravencoin", "eos", "dogecoin", - "eos" + "eos", + "binance-smart-chain" ], "dependencies": { "@babel/runtime": "^7.3.1", "@types/node": "^12.6.1", "chai": "^4.2.0", - "ptokens-deposit-address": "^0.10.0", - "ptokens-pbtc": "^0.10.0", - "ptokens-pdoge": "^0.10.0", - "ptokens-peosio-token": "^0.10.0", - "ptokens-perc20": "^0.10.0", - "ptokens-pltc": "^0.10.0", - "ptokens-providers": "^0.10.0", - "ptokens-utils": "^0.10.0" + "ptokens-deposit-address": "^0.11.0", + "ptokens-pbep20": "^0.11.0", + "ptokens-pbtc": "^0.11.0", + "ptokens-pdoge": "^0.11.0", + "ptokens-peosio-token": "^0.11.0", + "ptokens-perc20": "^0.11.0", + "ptokens-pltc": "^0.11.0", + "ptokens-providers": "^0.11.0", + "ptokens-prvn": "^0.11.0", + "ptokens-utils": "^0.11.0" }, "devDependencies": { "dtslint": "0.4.2", diff --git a/packages/ptokens/rollup.config.js b/packages/ptokens/rollup.config.js index 5c9d49aa..cce10452 100644 --- a/packages/ptokens/rollup.config.js +++ b/packages/ptokens/rollup.config.js @@ -5,8 +5,10 @@ export default rollupConfig('pTokens', pkg.name, { 'ptokens-pbtc': 'ptokens-pbtc', 'ptokens-pdoge': 'ptokens-pdoge', 'ptokens-perc20': 'ptokens-perc20', + 'ptokens-pbep20': 'ptokens-pbep20', 'ptokens-peosio-token': 'ptokens-peosio-token', 'ptokens-pltc': 'ptokens-pltc', + 'ptokens-prvn': 'ptokens-prvn', 'ptokens-utils': 'ptokens-utils', 'ptokens-providers': 'ptokens-providers', 'ptokens-deposit-address': 'ptokens-deposit-address' diff --git a/packages/ptokens/src/index.js b/packages/ptokens/src/index.js index 71ae8d86..b041c50b 100644 --- a/packages/ptokens/src/index.js +++ b/packages/ptokens/src/index.js @@ -1,6 +1,8 @@ import { pBTC } from 'ptokens-pbtc' import { pLTC } from 'ptokens-pltc' +import { pRVN } from 'ptokens-prvn' import { pERC20 } from 'ptokens-perc20' +import { pBEP20 } from 'ptokens-pbep20' import { pEosioToken } from 'ptokens-peosio-token' import { pDOGE } from 'ptokens-pdoge' import utils from 'ptokens-utils' @@ -11,11 +13,13 @@ class pTokens { * @param {Object} _configs */ constructor(_configs) { - const { pbtc, pltc, perc20, pdoge, peosioToken } = _configs + const { pbtc, pltc, prvn, perc20, pbep20, pdoge, peosioToken } = _configs if (pbtc) this.pbtc = !Array.isArray(pbtc) ? new pBTC(pbtc) : pbtc.map(_el => new pBTC(_el)) if (pltc) this.pltc = !Array.isArray(pltc) ? new pLTC(pltc) : pltc.map(_el => new pLTC(_el)) + if (prvn) this.prvn = !Array.isArray(prvn) ? new pRVN(prvn) : prvn.map(_el => new pRVN(_el)) + if (pdoge) this.pdoge = !Array.isArray(pdoge) ? new pDOGE(pdoge) : pdoge.map(_el => new pDOGE(_el)) if (perc20) { @@ -28,6 +32,16 @@ class pTokens { } } + if (pbep20) { + if (Array.isArray(pbep20)) { + pbep20.forEach(_pbep20 => { + this[_pbep20.pToken.toLowerCase()] = new pBEP20(_pbep20) + }) + } else { + this[pbep20.pToken.toLowerCase()] = new pBEP20(pbep20) + } + } + if (peosioToken) { if (Array.isArray(peosioToken)) { peosioToken.forEach(_peostoken => { diff --git a/packages/ptokens/tests/ptokens.test.js b/packages/ptokens/tests/ptokens.test.js index 842f8dd1..02ad0336 100644 --- a/packages/ptokens/tests/ptokens.test.js +++ b/packages/ptokens/tests/ptokens.test.js @@ -1,6 +1,7 @@ import pTokens from '../src/index' import { pBTC } from 'ptokens-pbtc' import { pLTC } from 'ptokens-pltc' +import { pRVN } from 'ptokens-prvn' import { pERC20 } from 'ptokens-perc20' import { constants } from 'ptokens-utils' import { pEosioToken } from 'ptokens-peosio-token' @@ -60,6 +61,10 @@ test('Should init pTokens correctly with more ptokens instances', () => { blockchain: constants.blockchains.Ethereum, network: constants.networks.Testnet }, + prvn: { + blockchain: constants.blockchains.BinanceSmartChain, + network: constants.networks.Mainnet + }, perc20: [ { pToken: constants.pTokens.pWETH, @@ -94,6 +99,7 @@ test('Should init pTokens correctly with more ptokens instances', () => { }) expect(ptokens.pbtc).to.be.an.instanceof(pBTC) expect(ptokens.pltc).to.be.an.instanceof(pLTC) + expect(ptokens.prvn).to.be.an.instanceof(pRVN) expect(ptokens.pweth).to.be.an.instanceof(pERC20) expect(ptokens.peth).to.be.an.instanceof(pERC20) expect(ptokens.peos).to.be.an.instanceof(pEosioToken) diff --git a/packages/ptokens/types/index.d.ts b/packages/ptokens/types/index.d.ts index 8b0fd702..39482362 100644 --- a/packages/ptokens/types/index.d.ts +++ b/packages/ptokens/types/index.d.ts @@ -10,7 +10,9 @@ import { } from 'ptokens-utils' import { pBTCConfigs } from 'ptokens-pbtc' import { pLTCConfigs } from 'ptokens-pltc' +import { pRVNConfigs } from 'ptokens-prvn' import { pERC20Configs } from 'ptokens-perc20' +import { pBEP20Configs } from 'ptokens-pbep20' import { pEosioTokenConfigs } from 'ptokens-peosio-token' import { pDOGEConfigs} from 'ptokens-pdoge' import { HttpProvider } from 'ptokens-providers' @@ -18,7 +20,9 @@ import { HttpProvider } from 'ptokens-providers' export interface pTokensConfigs { pbtc?: pBTCConfigs | pBTCConfigs[], pltc?: pLTCConfigs | pLTCConfigs[], + prvn?: pRVNConfigs | pRVNConfigs[], perc20?: pERC20Configs | pERC20Configs[], + pbep20?: pBEP20Configs | pBEP20Configs[], pdoge?: pDOGEConfigs | pDOGEConfigs[], peosioToken?: pEosioTokenConfigs | pEosioTokenConfigs[] } diff --git a/packages/ptokens/types/tests/ptokens-test.ts b/packages/ptokens/types/tests/ptokens-test.ts index 536913b0..dc86be44 100644 --- a/packages/ptokens/types/tests/ptokens-test.ts +++ b/packages/ptokens/types/tests/ptokens-test.ts @@ -9,6 +9,10 @@ const ptokens = new pTokens({ pltc: [{ network: 'mainnet', blockchain: 'eth' + }], + prvn: [{ + network: 'mainnet', + blockchain: 'bsc' }] }) diff --git a/resources/docs/ptokens-utils.md b/resources/docs/ptokens-utils.md index db4f3f90..4b742f55 100644 --- a/resources/docs/ptokens-utils.md +++ b/resources/docs/ptokens-utils.md @@ -692,7 +692,6 @@ const tx = await utils.eth.waitForTransactionConfirmation(web3, '0x8cc2e8f07ac6a ## utils.eos * __`getApi`__ -* __`getAccountName`__ * __`getAmountInEosFormat`__ * __`isValidAccountName`__ * __`waitForTransactionConfirmation`__ @@ -724,30 +723,6 @@ const api = utils.eos.getApi('provate key', 'https://', null)   -## eos.getAccountName - -```js -utils.eos.getAccountName(api, publicKeys) -``` - -Returns an EOS account name given a list of public keys - -### Parameters - -- __`Api`__ - __`api`__: An EOS Api instance -- __`Array`__ - __`publicKeys`__: list of public keys - -### Returns - -- __`Promise`__ : when resolved returns the account name - -### Example -```js -const api = utils.eos.getAccountName(api, ['EOS5....']) -``` - -  - ## eos.getAmountInEosFormat ```js