UNPKG

@ducatus/ducatus-wallet-service-rev

Version:
289 lines 11.7 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); var lodash_1 = __importDefault(require("lodash")); var chain_1 = require("../chain"); var txproposal_legacy_1 = require("./txproposal_legacy"); var txproposalaction_1 = require("./txproposalaction"); var $ = require('preconditions').singleton(); var Uuid = require('uuid'); var log = require('npmlog'); log.debug = log.verbose; log.disableColor(); var Common = require('../common'); var Constants = Common.Constants, Defaults = Common.Defaults, Utils = Common.Utils; var SwapStatusesEnum; (function (SwapStatusesEnum) { SwapStatusesEnum["WaitingForValidation"] = "WAITING_FOR_VALIDATION"; SwapStatusesEnum["InsufficientAmount"] = "INSUFFICIENT_AMOUNT"; SwapStatusesEnum["WaitingFor_Relay"] = "WAITING_FOR_RELAY"; SwapStatusesEnum["InsufficientTokenBalance"] = "INSUFFICIENT_TOKEN_BALANCE"; SwapStatusesEnum["InsufficientBalance"] = "INSUFFICIENT_BALANCE"; SwapStatusesEnum["Pending"] = "PENDING"; SwapStatusesEnum["Success"] = "SUCCESS"; SwapStatusesEnum["Revert"] = "REVERT"; SwapStatusesEnum["Fail"] = "FAIL"; SwapStatusesEnum["WaitingForReturn"] = "WAITING_FOR_RETURN"; SwapStatusesEnum["PendingReturn"] = "PENDING_RETURN"; SwapStatusesEnum["Return"] = "RETURN"; })(SwapStatusesEnum || (SwapStatusesEnum = {})); var TxProposal = (function () { function TxProposal() { this.actions = []; } TxProposal.create = function (opts) { opts = opts || {}; $.checkArgument(Utils.checkValueInCollection(opts.coin, Constants.COINS)); $.checkArgument(Utils.checkValueInCollection(opts.network, Constants.NETWORKS)); var x = new TxProposal(); if (opts.version) { $.checkArgument(opts.version === 3); } x.version = opts.version || 4; var now = Date.now(); x.createdOn = Math.floor(now / 1000); x.id = opts.id || Uuid.v4(); x.walletId = opts.walletId; x.creatorId = opts.creatorId; x.coin = opts.coin; x.network = opts.network; x.message = opts.message; x.payProUrl = opts.payProUrl; x.changeAddress = opts.changeAddress; x.outputs = lodash_1.default.map(opts.outputs, function (output) { return lodash_1.default.pick(output, ['amount', 'toAddress', 'message', 'data', 'gasLimit', 'script']); }); x.outputOrder = lodash_1.default.range(x.outputs.length + 1); if (!opts.noShuffleOutputs) { x.outputOrder = lodash_1.default.shuffle(x.outputOrder); } x.walletM = opts.walletM; x.walletN = opts.walletN; x.requiredSignatures = x.walletM; (x.requiredRejections = Math.min(x.walletM, x.walletN - x.walletM + 1)), (x.status = 'temporary'); x.actions = []; x.feeLevel = opts.feeLevel; x.feePerKb = opts.feePerKb; x.excludeUnconfirmedUtxos = opts.excludeUnconfirmedUtxos; x.addressType = opts.addressType || (x.walletN > 1 ? Constants.SCRIPT_TYPES.P2SH : Constants.SCRIPT_TYPES.P2PKH); $.checkState(Utils.checkValueInCollection(x.addressType, Constants.SCRIPT_TYPES)); x.customData = opts.customData; x.amount = opts.amount ? opts.amount : x.getTotalAmount(); x.setInputs(opts.inputs); x.fee = opts.fee; x.gasPrice = opts.gasPrice; x.from = opts.from; x.nonce = opts.nonce; x.gasLimit = opts.gasLimit; x.data = opts.data; x.tokenAddress = opts.tokenAddress; x.tokenId = opts.tokenId; x.destinationTag = opts.destinationTag; x.invoiceID = opts.invoiceID; x.wDucxAddress = opts.wDucxAddress; x.swap = opts.swap; return x; }; TxProposal.fromObj = function (obj) { if (!(obj.version >= 3)) { return txproposal_legacy_1.TxProposalLegacy.fromObj(obj); } var x = new TxProposal(); x.version = obj.version; x.createdOn = obj.createdOn; x.id = obj.id; x.walletId = obj.walletId; x.creatorId = obj.creatorId; x.coin = obj.coin || Defaults.COIN; x.network = obj.network; x.outputs = obj.outputs; x.amount = obj.amount; x.message = obj.message; x.payProUrl = obj.payProUrl; x.changeAddress = obj.changeAddress; x.inputs = obj.inputs; x.walletM = obj.walletM; x.walletN = obj.walletN; x.requiredSignatures = obj.requiredSignatures; x.requiredRejections = obj.requiredRejections; x.status = obj.status; x.txid = obj.txid; x.broadcastedOn = obj.broadcastedOn; x.inputPaths = obj.inputPaths; x.actions = lodash_1.default.map(obj.actions, function (action) { return txproposalaction_1.TxProposalAction.fromObj(action); }); x.outputOrder = obj.outputOrder; x.fee = obj.fee; x.feeLevel = obj.feeLevel; x.feePerKb = obj.feePerKb; x.excludeUnconfirmedUtxos = obj.excludeUnconfirmedUtxos; x.addressType = obj.addressType; x.customData = obj.customData; x.proposalSignature = obj.proposalSignature; x.proposalSignaturePubKey = obj.proposalSignaturePubKey; x.proposalSignaturePubKeySig = obj.proposalSignaturePubKeySig; x.gasPrice = obj.gasPrice; x.from = obj.from; x.nonce = obj.nonce; x.gasLimit = obj.gasLimit; x.data = obj.data; x.tokenAddress = obj.tokenAddress; x.tokenId = obj.tokenId; x.destinationTag = obj.destinationTag; x.invoiceID = obj.invoiceID; x.wDucxAddress = obj.wDucxAddress; x.swap = obj.swap; if (x.status == 'broadcasted') { x.raw = obj.raw; } return x; }; TxProposal.prototype.toObject = function () { var x = lodash_1.default.cloneDeep(this); x.isPending = this.isPending(); return x; }; TxProposal.prototype.setInputs = function (inputs) { this.inputs = inputs || []; this.inputPaths = lodash_1.default.map(inputs, 'path') || []; }; TxProposal.prototype._updateStatus = function () { if (this.status != 'pending') return; if (this.isRejected()) { this.status = 'rejected'; } else if (this.isAccepted()) { this.status = 'accepted'; } }; TxProposal.prototype._buildTx = function () { $.checkState(Utils.checkValueInCollection(this.addressType, Constants.SCRIPT_TYPES)); return chain_1.ChainService.buildTx(this); }; TxProposal.prototype._getCurrentSignatures = function () { var acceptedActions = lodash_1.default.filter(this.actions, function (a) { return a.type == 'accept'; }); return lodash_1.default.map(acceptedActions, function (x) { return { signatures: x.signatures, xpub: x.xpub }; }); }; TxProposal.prototype.getBitcoreTx = function () { var _this = this; var t = this._buildTx(); var sigs = this._getCurrentSignatures(); lodash_1.default.each(sigs, function (x) { chain_1.ChainService.addSignaturesToBitcoreTx(_this.coin, t, _this.inputs, _this.inputPaths, x.signatures, x.xpub); }); return t; }; TxProposal.prototype.getRawTx = function () { var t = this.getBitcoreTx(); return t.uncheckedSerialize(); }; TxProposal.prototype.getEstimatedSizeForSingleInput = function () { switch (this.addressType) { case Constants.SCRIPT_TYPES.P2PKH: return 147; default: case Constants.SCRIPT_TYPES.P2SH: return this.requiredSignatures * 72 + this.walletN * 36 + 44; } }; TxProposal.prototype.getEstimatedSize = function () { var safetyMargin = 0.02; var overhead = 4 + 4 + 9 + 9; var inputSize = this.getEstimatedSizeForSingleInput(); var outputSize = 34; var nbInputs = this.inputs.length; var nbOutputs = (lodash_1.default.isArray(this.outputs) ? Math.max(1, this.outputs.length) : 1) + 1; var size = overhead + inputSize * nbInputs + outputSize * nbOutputs; return parseInt((size * (1 + safetyMargin)).toFixed(0)); }; TxProposal.prototype.getEstimatedFee = function () { $.checkState(lodash_1.default.isNumber(this.feePerKb)); var fee = (this.feePerKb * this.getEstimatedSize()) / 1000; return parseInt(fee.toFixed(0)); }; TxProposal.prototype.estimateFee = function () { this.fee = this.getEstimatedFee(); }; TxProposal.prototype.getTotalAmount = function () { return lodash_1.default.sumBy(this.outputs, 'amount'); }; TxProposal.prototype.getActors = function () { return lodash_1.default.map(this.actions, 'copayerId'); }; TxProposal.prototype.getApprovers = function () { return lodash_1.default.map(lodash_1.default.filter(this.actions, function (a) { return a.type == 'accept'; }), 'copayerId'); }; TxProposal.prototype.getActionBy = function (copayerId) { return lodash_1.default.find(this.actions, { copayerId: copayerId }); }; TxProposal.prototype.addAction = function (copayerId, type, comment, signatures, xpub) { var action = txproposalaction_1.TxProposalAction.create({ copayerId: copayerId, type: type, signatures: signatures, xpub: xpub, comment: comment }); this.actions.push(action); this._updateStatus(); }; TxProposal.prototype.sign = function (copayerId, signatures, xpub) { try { var tx = this.getBitcoreTx(); chain_1.ChainService.addSignaturesToBitcoreTx(this.coin, tx, this.inputs, this.inputPaths, signatures, xpub); this.addAction(copayerId, 'accept', null, signatures, xpub); if (this.status == 'accepted') { this.raw = tx.uncheckedSerialize(); this.txid = tx.id; } return true; } catch (e) { log.debug(e); return false; } }; TxProposal.prototype.reject = function (copayerId, reason) { this.addAction(copayerId, 'reject', reason); }; TxProposal.prototype.isTemporary = function () { return this.status == 'temporary'; }; TxProposal.prototype.isPending = function () { return !lodash_1.default.includes(['temporary', 'broadcasted', 'rejected'], this.status); }; TxProposal.prototype.isAccepted = function () { var votes = lodash_1.default.countBy(this.actions, 'type'); return votes['accept'] >= this.requiredSignatures; }; TxProposal.prototype.isRejected = function () { var votes = lodash_1.default.countBy(this.actions, 'type'); return votes['reject'] >= this.requiredRejections; }; TxProposal.prototype.isBroadcasted = function () { return this.status == 'broadcasted'; }; TxProposal.prototype.setBroadcasted = function () { $.checkState(this.txid); this.status = 'broadcasted'; this.broadcastedOn = Math.floor(Date.now() / 1000); }; return TxProposal; }()); exports.TxProposal = TxProposal; //# sourceMappingURL=txproposal.js.map