UNPKG

ptokens-peosio-token

Version:

repo holding the code for interacting with pEosioToken

245 lines (241 loc) 8.91 kB
import Web3 from 'web3'; import Web3PromiEvent from 'web3-core-promievent'; import { NodeSelector } from 'ptokens-node-selector'; import { constants, helpers, eos, eth, abi, redeemFrom } from 'ptokens-utils'; import BigNumber from 'bignumber.js'; import Web3Utils from 'web3-utils'; var minimumAmounts = { [constants.pTokens.pEOS]: { issue: 0.0001, redeem: 1000000000 }, [constants.pTokens.IQ]: { issue: 0.001, redeem: 1000000000 }, [constants.pTokens.TLOS]: { issue: 0.0001, redeem: 1000000000 }, [constants.pTokens.EFX]: { issue: 0.001, redeem: 1000000000 }, [constants.pTokens.pSEEDS]: { issue: 0.0001, redeem: 1000000000 }, [constants.pTokens.NUCO]: { issue: 1, redeem: 1 }, [constants.pTokens.ORE]: { issue: 0.0001, redeem: 1000000000 } }; class pEosioToken extends NodeSelector { constructor(_configs) { const { hostBlockchain, hostNetwork, nativeBlockchain, nativeNetwork } = helpers.parseParams(_configs, constants.blockchains.Eosio); super({ pToken: _configs.pToken, hostBlockchain, hostNetwork, nativeBlockchain, nativeNetwork, defaultNode: _configs.defaultNode }); const { ethPrivateKey, ethProvider, bscPrivateKey, bscProvider, eosPrivateKey, eosRpc, eosSignatureProvider, telosPrivateKey, telosRpc, telosSignatureProvider, orePrivateKey, oreRpc, oreSignatureProvider } = _configs; if (eosSignatureProvider) { this.nativeApi = eos.getApi(null, eosRpc, eosSignatureProvider); } else if (eosPrivateKey && eosRpc) { this.nativeApi = eos.getApi(eosPrivateKey, eosRpc, null); this.nativePrivateKey = eosPrivateKey; } else if (!eosSignatureProvider && !eosPrivateKey && eosRpc) { this.nativeApi = eos.getApi(null, eosRpc, null); } if (telosSignatureProvider) { this.nativeApi = eos.getApi(null, telosRpc, telosSignatureProvider); } else if (telosPrivateKey && telosRpc) { this.nativeApi = eos.getApi(telosPrivateKey, telosRpc, null); this.nativePrivateKey = telosPrivateKey; } else if (!telosSignatureProvider && !telosPrivateKey && telosRpc) { this.nativeApi = eos.getApi(null, telosRpc, null); } if (oreSignatureProvider) { this.nativeApi = eos.getApi(null, oreRpc, oreSignatureProvider); } else if (orePrivateKey && oreRpc) { this.nativeApi = eos.getApi(orePrivateKey, oreRpc, null); this.nativePrivateKey = orePrivateKey; } else if (!oreSignatureProvider && !orePrivateKey && oreRpc) { this.nativeApi = eos.getApi(null, oreRpc, 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; } 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; } } issue(_amount, _hostAccount, _options) { const promiEvent = Web3PromiEvent(); const start = async () => { try { const { blocksBehind, expireSeconds, permission, actor } = _options; await this._loadData(); if (BigNumber(_amount).isLessThan(minimumAmounts[this.pToken.toLowerCase()].issue)) { promiEvent.reject(`Impossible to issue less than ${minimumAmounts[this.pToken.toLowerCase()].issue}`); return; } 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(); this.nativeApi.cachedAbis.set(this.nativeContractAddress, { abi: abi.EosioToken, rawAbi: null }); const nativeTxReceipt = await this.nativeApi.transact({ actions: [{ account: this.nativeContractAddress, name: 'transfer', authorization: [{ actor, permission }], data: { from: actor, to: this.nativeVaultAddress, quantity: eos.getAmountInEosFormat(_amount, this.pToken === constants.pTokens.IQ ? 3 : 4, this.pToken === constants.pTokens.IQ || this.pToken === constants.pTokens.TLOS || this.pToken === constants.pTokens.EFX ? this.pToken.toUpperCase() : this.pToken.slice(1).toUpperCase()), memo: _hostAccount } }] }, { blocksBehind, expireSeconds }); promiEvent.eventEmitter.emit('nativeTxConfirmed', nativeTxReceipt); const { broadcast_tx_hash } = await this.selectedNode.monitorIncomingTransaction(nativeTxReceipt.transaction_id, promiEvent.eventEmitter); const hostTxReceipt = await eth.waitForTransactionConfirmation(this.hostApi, broadcast_tx_hash); promiEvent.eventEmitter.emit('hostTxConfirmed', hostTxReceipt); promiEvent.resolve({ to: _hostAccount, nativeTx: nativeTxReceipt.transaction_id, hostTx: broadcast_tx_hash, amount: _amount }); } catch (_err) { promiEvent.reject(_err); } }; start(); return promiEvent.eventEmitter; } redeemWithMetadata(_amount, _account, _metadata, _options = {}) { return this._redeem(_amount, _account, _metadata, _options); } redeem(_amount, _account, _options = {}) { return this._redeem(_amount, _account, null, _options); } _redeem(_amount, _account, _metadata, _options = {}) { const promiEvent = Web3PromiEvent(); const { gas, gasPrice } = _options; const start = async () => { try { await this._loadData(); if (BigNumber(_amount).isLessThan(minimumAmounts[this.pToken.toLowerCase()].redeem)) { promiEvent.reject(`Impossible to redeem less than ${minimumAmounts[this.pToken.toLowerCase()].redeem}`); return; } if (!eos.isValidAccountName(_account)) { promiEvent.reject('Invalid native account'); return; } let hostTxHash = null; if (this.hostBlockchain === constants.blockchains.Ethereum || this.hostBlockchain === constants.blockchains.Polygon || this.hostBlockchain === constants.blockchains.BinanceSmartChain) { const hostTxReceipt = await redeemFrom.redeemFromEvmCompatible(this.hostApi, { privateKey: this.hostPrivateKey, gas, gasPrice, contractAddress: this.hostContractAddress, value: 0 }, _metadata ? [_amount, _metadata, _account] : [_amount, _account], promiEvent, 'hostTxBroadcasted'); promiEvent.eventEmitter.emit('hostTxConfirmed', hostTxReceipt); hostTxHash = hostTxReceipt.transactionHash; } const incomingTxReport = await this.selectedNode.monitorIncomingTransaction(hostTxHash, promiEvent.eventEmitter); const nativeTxReceipt = await eos.waitForTransactionConfirmation(this.nativeApi, incomingTxReport.broadcast_tx_hash); promiEvent.eventEmitter.emit('nativeTxConfirmed', nativeTxReceipt); promiEvent.resolve({ to: _account, nativeTx: nativeTxReceipt.transaction_id, 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.nativeVaultAddress = native_vault_address; this.nativeContractAddress = native_smart_contract_address; this.hostContractAddress = this.hostBlockchain === constants.blockchains.Ethereum ? eth.addHexPrefix(host_smart_contract_address) : host_smart_contract_address; } return this.nativeContractAddress; } catch (_err) { throw new Error(`Error during loading data: ${_err.message}`); } } } export { pEosioToken };