committed by
GitHub
3 changed files with 202 additions and 17 deletions
@ -0,0 +1,176 @@ |
|||
'use strict'; |
|||
|
|||
var _ = require('lodash'); |
|||
var $ = require('preconditions').singleton(); |
|||
var log = require('npmlog'); |
|||
log.debug = log.verbose; |
|||
log.disableColor(); |
|||
|
|||
var Bitcore = require('bitcore-lib'); |
|||
|
|||
var Common = require('../common'); |
|||
var Constants = Common.Constants; |
|||
var Defaults = Common.Defaults; |
|||
|
|||
var TxProposalAction = require('./txproposalaction'); |
|||
|
|||
function TxProposal() {}; |
|||
|
|||
TxProposal.Types = { |
|||
SIMPLE: 'simple', |
|||
MULTIPLEOUTPUTS: 'multiple_outputs', |
|||
EXTERNAL: 'external' |
|||
}; |
|||
|
|||
TxProposal.fromObj = function(obj) { |
|||
var x = new TxProposal(); |
|||
|
|||
x.version = obj.version; |
|||
if (obj.version === '1.0.0') { |
|||
x.type = TxProposal.Types.SIMPLE; |
|||
} else { |
|||
x.type = obj.type; |
|||
} |
|||
x.createdOn = obj.createdOn; |
|||
x.id = obj.id; |
|||
x.walletId = obj.walletId; |
|||
x.creatorId = obj.creatorId; |
|||
x.outputs = obj.outputs; |
|||
x.toAddress = obj.toAddress; |
|||
x.amount = obj.amount; |
|||
x.message = obj.message; |
|||
x.payProUrl = obj.payProUrl; |
|||
x.proposalSignature = obj.proposalSignature; |
|||
x.changeAddress = obj.changeAddress; |
|||
x.inputs = obj.inputs; |
|||
x.requiredSignatures = obj.requiredSignatures; |
|||
x.requiredRejections = obj.requiredRejections; |
|||
x.walletN = obj.walletN; |
|||
x.status = obj.status; |
|||
x.txid = obj.txid; |
|||
x.broadcastedOn = obj.broadcastedOn; |
|||
x.inputPaths = obj.inputPaths; |
|||
x.actions = _.map(obj.actions, function(action) { |
|||
return TxProposalAction.fromObj(action); |
|||
}); |
|||
x.outputOrder = obj.outputOrder; |
|||
x.network = obj.network; |
|||
x.fee = obj.fee; |
|||
x.feePerKb = obj.feePerKb; |
|||
x.excludeUnconfirmedUtxos = obj.excludeUnconfirmedUtxos; |
|||
x.proposalSignaturePubKey = obj.proposalSignaturePubKey; |
|||
x.proposalSignaturePubKeySig = obj.proposalSignaturePubKeySig; |
|||
x.addressType = obj.addressType || Constants.SCRIPT_TYPES.P2SH; |
|||
x.derivationStrategy = obj.derivationStrategy || Constants.DERIVATION_STRATEGIES.BIP45; |
|||
x.customData = obj.customData; |
|||
|
|||
return x; |
|||
}; |
|||
|
|||
function throwUnsupportedError() { |
|||
var msg = 'Unsupported operation on this transaction proposal'; |
|||
log.warn('DEPRECATED: ' + msg); |
|||
throw new Error(msg); |
|||
}; |
|||
|
|||
TxProposal.prototype.toObject = function() { |
|||
var x = _.cloneDeep(this); |
|||
x.isPending = this.isPending(); |
|||
return x; |
|||
}; |
|||
|
|||
TxProposal.prototype._updateStatus = function() { |
|||
if (this.status != 'pending') return; |
|||
|
|||
if (this.isRejected()) { |
|||
this.status = 'rejected'; |
|||
} else if (this.isAccepted()) { |
|||
this.status = 'accepted'; |
|||
} |
|||
}; |
|||
|
|||
TxProposal.prototype.getBitcoreTx = function() { |
|||
throwUnsupportedError(); |
|||
}; |
|||
|
|||
TxProposal.prototype.getNetworkName = function() { |
|||
return Bitcore.Address(this.changeAddress.address).toObject().network; |
|||
}; |
|||
|
|||
TxProposal.prototype.getRawTx = function() { |
|||
throwUnsupportedError(); |
|||
}; |
|||
|
|||
TxProposal.prototype.getTotalAmount = function() { |
|||
if (this.type == TxProposal.Types.MULTIPLEOUTPUTS || this.type == TxProposal.Types.EXTERNAL) { |
|||
return _.pluck(this.outputs, 'amount') |
|||
.reduce(function(total, n) { |
|||
return total + n; |
|||
}, 0); |
|||
} else { |
|||
return this.amount; |
|||
} |
|||
}; |
|||
|
|||
TxProposal.prototype.getActors = function() { |
|||
return _.pluck(this.actions, 'copayerId'); |
|||
}; |
|||
|
|||
TxProposal.prototype.getApprovers = function() { |
|||
return _.pluck( |
|||
_.filter(this.actions, { |
|||
type: 'accept' |
|||
}), 'copayerId'); |
|||
}; |
|||
|
|||
TxProposal.prototype.getActionBy = function(copayerId) { |
|||
return _.find(this.actions, { |
|||
copayerId: copayerId |
|||
}); |
|||
}; |
|||
|
|||
TxProposal.prototype.addAction = function(copayerId, type, comment, signatures, xpub) { |
|||
var action = TxProposalAction.create({ |
|||
copayerId: copayerId, |
|||
type: type, |
|||
signatures: signatures, |
|||
xpub: xpub, |
|||
comment: comment, |
|||
}); |
|||
this.actions.push(action); |
|||
this._updateStatus(); |
|||
}; |
|||
|
|||
TxProposal.prototype.sign = function() { |
|||
throwUnsupportedError(); |
|||
}; |
|||
|
|||
TxProposal.prototype.reject = function(copayerId, reason) { |
|||
this.addAction(copayerId, 'reject', reason); |
|||
}; |
|||
|
|||
TxProposal.prototype.isPending = function() { |
|||
return !_.contains(['broadcasted', 'rejected'], this.status); |
|||
}; |
|||
|
|||
TxProposal.prototype.isAccepted = function() { |
|||
var votes = _.countBy(this.actions, 'type'); |
|||
return votes['accept'] >= this.requiredSignatures; |
|||
}; |
|||
|
|||
TxProposal.prototype.isRejected = function() { |
|||
var votes = _.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); |
|||
}; |
|||
|
|||
module.exports = TxProposal; |
Loading…
Reference in new issue