UNPKG

ptokens-pbtc

Version:

repo holding the code for interacting with pBTC

352 lines (346 loc) 18.4 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } var _defineProperty = _interopDefault(require('@babel/runtime/helpers/defineProperty')); var _asyncToGenerator = _interopDefault(require('@babel/runtime/helpers/asyncToGenerator')); var _classCallCheck = _interopDefault(require('@babel/runtime/helpers/classCallCheck')); var _createClass = _interopDefault(require('@babel/runtime/helpers/createClass')); var _inherits = _interopDefault(require('@babel/runtime/helpers/inherits')); var _possibleConstructorReturn = _interopDefault(require('@babel/runtime/helpers/possibleConstructorReturn')); var _getPrototypeOf = _interopDefault(require('@babel/runtime/helpers/getPrototypeOf')); var _regeneratorRuntime = _interopDefault(require('@babel/runtime/regenerator')); var Web3 = _interopDefault(require('web3')); var Web3PromiEvent = _interopDefault(require('web3-core-promievent')); var ptokensNodeSelector = require('ptokens-node-selector'); var ptokensUtils = require('ptokens-utils'); var ptokensDepositAddress = require('ptokens-deposit-address'); var Web3Utils = _interopDefault(require('web3-utils')); function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } var MINIMUM_BTC_REDEEMABLE = 0.00005; var pBTC = function (_NodeSelector) { _inherits(pBTC, _NodeSelector); var _super = _createSuper(pBTC); function pBTC(_configs) { var _this; _classCallCheck(this, pBTC); var _helpers$parseParams = ptokensUtils.helpers.parseParams(_configs, _configs.nativeBlockchain || ptokensUtils.constants.blockchains.Bitcoin), hostBlockchain = _helpers$parseParams.hostBlockchain, hostNetwork = _helpers$parseParams.hostNetwork, nativeBlockchain = _helpers$parseParams.nativeBlockchain, nativeNetwork = _helpers$parseParams.nativeNetwork; _this = _super.call(this, { pToken: _configs.pToken || ptokensUtils.constants.pTokens.pBTC, hostBlockchain: hostBlockchain, hostNetwork: hostNetwork, nativeBlockchain: nativeBlockchain, nativeNetwork: nativeNetwork, defaultNode: _configs.defaultNode }); var ethPrivateKey = _configs.ethPrivateKey, ethProvider = _configs.ethProvider, eosPrivateKey = _configs.eosPrivateKey, eosRpc = _configs.eosRpc, eosSignatureProvider = _configs.eosSignatureProvider, algoProvider = _configs.algoProvider, algoClient = _configs.algoClient; if ((ethProvider || ethPrivateKey) && (eosSignatureProvider || eosPrivateKey)) throw new Error('Bad Initialization. Impossible to use both ETH and EOS'); if (ethProvider) _this.hostApi = new Web3(ethProvider); if (ethPrivateKey) { var account = _this.hostApi.eth.accounts.privateKeyToAccount(ptokensUtils.eth.addHexPrefix(ethPrivateKey)); _this.hostApi.eth.defaultAccount = account.address; _this.hostPrivateKey = ptokensUtils.eth.addHexPrefix(ethPrivateKey); } else { _this.hostPrivateKey = null; } if (eosSignatureProvider) { _this.hostApi = ptokensUtils.eos.getApi(null, eosRpc, eosSignatureProvider); } else if (eosPrivateKey && eosRpc) { _this.hostApi = ptokensUtils.eos.getApi(eosPrivateKey, eosRpc, null); _this.hostPrivateKey = eosPrivateKey; } else if (!eosSignatureProvider && !eosPrivateKey && eosRpc) { _this.hostApi = ptokensUtils.eos.getApi(null, eosRpc, null); } if (algoProvider) _this.hostApi = algoProvider; if (algoClient) _this.algoClient = algoClient; _this.contractAddress = null; _this.decimals = null; return _this; } _createClass(pBTC, [{ key: "getDepositAddress", value: function () { var _getDepositAddress = _asyncToGenerator( _regeneratorRuntime.mark(function _callee(_hostAddress) { var _isValidAddress; var isValidAddress, selectedNode, depositAddress; return _regeneratorRuntime.wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: isValidAddress = (_isValidAddress = {}, _defineProperty(_isValidAddress, ptokensUtils.constants.blockchains.Ethereum, function (_address) { return Web3Utils.isAddress(_address); }), _defineProperty(_isValidAddress, ptokensUtils.constants.blockchains.BinanceSmartChain, function (_address) { return Web3Utils.isAddress(_address); }), _defineProperty(_isValidAddress, ptokensUtils.constants.blockchains.Xdai, function (_address) { return Web3Utils.isAddress(_address); }), _defineProperty(_isValidAddress, ptokensUtils.constants.blockchains.Polygon, function (_address) { return Web3Utils.isAddress(_address); }), _defineProperty(_isValidAddress, ptokensUtils.constants.blockchains.Arbitrum, function (_address) { return Web3Utils.isAddress(_address); }), _defineProperty(_isValidAddress, ptokensUtils.constants.blockchains.Eosio, function (_address) { return ptokensUtils.eos.isValidAccountName(_address); }), _defineProperty(_isValidAddress, ptokensUtils.constants.blockchains.Telos, function (_address) { return ptokensUtils.eos.isValidAccountName(_address); }), _defineProperty(_isValidAddress, ptokensUtils.constants.blockchains.Algorand, function (_address) { return ptokensUtils.algo.isValidAddress(_address); }), _defineProperty(_isValidAddress, ptokensUtils.constants.blockchains.Libre, function (_address) { return ptokensUtils.eos.isValidAccountName(_address); }), _isValidAddress); if (isValidAddress[this.hostBlockchain](_hostAddress)) { _context.next = 3; break; } throw new Error('Invalid host account'); case 3: if (!this.selectedNode) { _context.next = 7; break; } _context.t0 = this.selectedNode; _context.next = 10; break; case 7: _context.next = 9; return this.select(); case 9: _context.t0 = _context.sent; case 10: selectedNode = _context.t0; if (selectedNode) { _context.next = 13; break; } throw new Error('No node selected. Impossible to generate a deposit Address.'); case 13: depositAddress = new ptokensDepositAddress.DepositAddress({ node: selectedNode, nativeBlockchain: this.nativeBlockchain, nativeNetwork: this.nativeNetwork, hostBlockchain: this.hostBlockchain, hostNetwork: this.hostNetwork, hostApi: this.hostApi }); _context.next = 16; return depositAddress.generate(_hostAddress); case 16: return _context.abrupt("return", depositAddress); case 17: case "end": return _context.stop(); } } }, _callee, this); })); function getDepositAddress(_x) { return _getDepositAddress.apply(this, arguments); } return getDepositAddress; }() }, { key: "redeem", value: function redeem(_amount, _btcAddress) { var _this2 = this; var _options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; var promiEvent = Web3PromiEvent(); var start = function () { var _ref = _asyncToGenerator( _regeneratorRuntime.mark(function _callee2() { var gas, gasPrice, blocksBehind, expireSeconds, permission, actor, from, swapInfo, redeemFromEvmCompatible, redeemFromEosio, redeemFromAlgorand, destinationChainId, hostTxHash, hostTxReceipt, eosTxReceipt, _hostTxReceipt, broadcastedBtcTxReport, broadcastedBtcTxReceipt; return _regeneratorRuntime.wrap(function _callee2$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: _context2.prev = 0; gas = _options.gas, gasPrice = _options.gasPrice, blocksBehind = _options.blocksBehind, expireSeconds = _options.expireSeconds, permission = _options.permission, actor = _options.actor, from = _options.from, swapInfo = _options.swapInfo; _context2.next = 4; return _this2._loadData(); case 4: if (!(_amount < MINIMUM_BTC_REDEEMABLE)) { _context2.next = 7; break; } promiEvent.reject("Impossible to burn less than ".concat(MINIMUM_BTC_REDEEMABLE, " pBTC")); return _context2.abrupt("return"); case 7: if (!(_this2.pToken === ptokensUtils.constants.pTokens.pBTC)) { _context2.next = 11; break; } if (ptokensUtils.btc.isValidAddress(_btcAddress)) { _context2.next = 11; break; } promiEvent.reject('Invalid Bitcoin address'); return _context2.abrupt("return"); case 11: if (_this2.selectedNode) { _context2.next = 14; break; } _context2.next = 14; return _this2.select(); case 14: redeemFromEvmCompatible = ptokensUtils.redeemFrom.redeemFromEvmCompatible, redeemFromEosio = ptokensUtils.redeemFrom.redeemFromEosio, redeemFromAlgorand = ptokensUtils.redeemFrom.redeemFromAlgorand; destinationChainId = _this2.version === 'v2' ? ptokensUtils.constants.chainIds[_this2.nativeBlockchain][_this2.nativeNetwork] : null; hostTxHash = null; if (!(_this2.hostBlockchain === ptokensUtils.constants.blockchains.Ethereum || _this2.hostBlockchain === ptokensUtils.constants.blockchains.BinanceSmartChain || _this2.hostBlockchain === ptokensUtils.constants.blockchains.Xdai || _this2.hostBlockchain === ptokensUtils.constants.blockchains.Polygon || _this2.hostBlockchain === ptokensUtils.constants.blockchains.Arbitrum)) { _context2.next = 24; break; } _context2.next = 20; return redeemFromEvmCompatible(_this2.hostApi, { privateKey: _this2.hostPrivateKey, gas: gas, gasPrice: gasPrice, contractAddress: _this2.contractAddress, value: 0 }, _this2.version === 'v1' ? [_amount, _btcAddress] : [_amount, _btcAddress, destinationChainId], promiEvent, 'hostTxBroadcasted', _this2.version || 'v1'); case 20: hostTxReceipt = _context2.sent; if (_this2.hostBlockchain === ptokensUtils.constants.blockchains.Ethereum) promiEvent.eventEmitter.emit('onEthTxConfirmed', hostTxReceipt); promiEvent.eventEmitter.emit('hostTxConfirmed', hostTxReceipt); hostTxHash = hostTxReceipt.transactionHash; case 24: if (!(_this2.hostBlockchain === ptokensUtils.constants.blockchains.Eosio || _this2.hostBlockchain === ptokensUtils.constants.blockchains.Telos || _this2.hostBlockchain === ptokensUtils.constants.blockchains.Libre)) { _context2.next = 31; break; } _context2.next = 27; return redeemFromEosio(_this2.hostApi, _amount, _btcAddress, _this2.version === 'v2' ? 9 : 8, _this2.contractAddress, ptokensUtils.constants.pTokens.pBTC, { blocksBehind: blocksBehind, expireSeconds: expireSeconds, permission: permission, actor: actor, version: _this2.version, destinationChainId: destinationChainId }); case 27: eosTxReceipt = _context2.sent; if (_this2.hostBlockchain === ptokensUtils.constants.blockchains.Eosio) { promiEvent.eventEmitter.emit('onEosTxConfirmed', eosTxReceipt); } promiEvent.eventEmitter.emit('hostTxConfirmed', eosTxReceipt); hostTxHash = eosTxReceipt.transaction_id; case 31: if (!(_this2.hostBlockchain === ptokensUtils.constants.blockchains.Algorand)) { _context2.next = 37; break; } _context2.next = 34; return redeemFromAlgorand({ provider: _this2.hostApi, client: _this2.algoClient, amount: _amount, to: _this2.hostIdentity, assetIndex: _this2.contractAddress, nativeAccount: _btcAddress, from: from, destinationChainId: destinationChainId, eventEmitter: promiEvent.eventEmitter, swapInfo: swapInfo }); case 34: _hostTxReceipt = _context2.sent; promiEvent.eventEmitter.emit('hostTxConfirmed', _hostTxReceipt); hostTxHash = _hostTxReceipt.txID().toString(); case 37: _context2.next = 39; return _this2.selectedNode.monitorIncomingTransaction(hostTxHash, promiEvent.eventEmitter); case 39: broadcastedBtcTxReport = _context2.sent; _context2.next = 42; return ptokensUtils.btc.waitForTransactionConfirmation(_this2.nativeNetwork, broadcastedBtcTxReport.broadcast_tx_hash, 5000); case 42: broadcastedBtcTxReceipt = _context2.sent; promiEvent.eventEmitter.emit('onBtcTxConfirmed', broadcastedBtcTxReceipt); promiEvent.eventEmitter.emit('nativeTxConfirmed', broadcastedBtcTxReceipt); promiEvent.resolve({ amount: _amount, hostTx: hostTxHash, nativeTx: broadcastedBtcTxReport.broadcast_tx_hash, to: _btcAddress }); _context2.next = 51; break; case 48: _context2.prev = 48; _context2.t0 = _context2["catch"](0); promiEvent.reject(_context2.t0); case 51: case "end": return _context2.stop(); } } }, _callee2, null, [[0, 48]]); })); return function start() { return _ref.apply(this, arguments); }; }(); start(); return promiEvent.eventEmitter; } }, { key: "_loadData", value: function () { var _loadData2 = _asyncToGenerator( _regeneratorRuntime.mark(function _callee3() { var _yield$this$selectedN, host_identity, smart_contract_address, host_smart_contract_address, versions; return _regeneratorRuntime.wrap(function _callee3$(_context3) { while (1) { switch (_context3.prev = _context3.next) { case 0: _context3.prev = 0; if (this.contractAddress) { _context3.next = 15; break; } if (this.selectedNode) { _context3.next = 5; break; } _context3.next = 5; return this.select(); case 5: _context3.next = 7; return this.selectedNode.getInfo(); case 7: _yield$this$selectedN = _context3.sent; host_identity = _yield$this$selectedN.host_identity; smart_contract_address = _yield$this$selectedN.smart_contract_address; host_smart_contract_address = _yield$this$selectedN.host_smart_contract_address; versions = _yield$this$selectedN.versions; this.contractAddress = smart_contract_address || host_smart_contract_address; this.version = versions && versions.network ? versions.network : 'v1'; this.hostIdentity = host_identity; case 15: _context3.next = 20; break; case 17: _context3.prev = 17; _context3.t0 = _context3["catch"](0); throw new Error("Error during getting contract address: ".concat(_context3.t0.message)); case 20: case "end": return _context3.stop(); } } }, _callee3, this, [[0, 17]]); })); function _loadData() { return _loadData2.apply(this, arguments); } return _loadData; }() }]); return pBTC; }(ptokensNodeSelector.NodeSelector); exports.pBTC = pBTC;