reject button working

This commit is contained in:
Matias Alejo Garcia 2014-04-23 02:01:54 -03:00
parent 3c7c24de49
commit b6280348e5
6 changed files with 99 additions and 49 deletions

View File

@ -244,7 +244,7 @@
<div class="transactions" data-ng-controller="TransactionsController">
<div class="row" ng-show='$root.wallet.publicKeyRing.isComplete()'>
<div class="large-12 columns">
<h4>Pending transactions <small>({{txs.length}})</small></h4>
<h4>Transactions proposals <small>({{txs.length}})</small></h4>
<div class="panel pending" ng-repeat="tx in txs | orderBy: 'createdTs':true">
<div class="txheader">
<div class="row">
@ -284,6 +284,7 @@
<span ng-if="action == 'create'" title="{{ts | date:'medium'}}" class="fi-page-add size-18 right m10h"></span>
<span ng-if="action == 'seen'" title="{{ts | date:'medium'}}" class="fi-eye size-18 right m10h"> </span>
<span ng-if="action == 'sign'" title="{{ts | date:'medium'}}" class="fi-check size-18 right m10h"> </span>
<span ng-if="action == 'rejected'" title="{{ts | date:'medium'}}" class="fi-x size-18 right m10h" style="color:red"> </span>
<a title="{{ts | date:'medium'}}"></a>
</span>
@ -301,16 +302,20 @@
<div ng-show="tx.signedByUs">
<i class="fi-check size-40"></i> Signed by you already
</div>
<div ng-show="!tx.signedByUs && tx.missingSignatures">
<div ng-show="!tx.signedByUs && !tx.rejectedByUs && !tx.finallyRejected && tx.missingSignatures">
<button class="secondary round" ng-click="sign(tx.ntxid)">
<i class="fi-check"></i> Sign
</button>
<button class="primary round">
<i class="fi-x"></i> Ignore
<button class="primary round" ng-click="reject(tx.ntxid)">
<i class="fi-x" ></i> Reject
</button>
</div>
</div>
<div class="large-6 columns text-right">
<span ng-show="tx.finallyRejected ">
Transaction finally rejected
</span>
<span ng-show="!tx.missingSignatures && !tx.sentTs">
Transaction ready.
<button class="secondary round" ng-click="send(tx.ntxid)">
@ -323,10 +328,10 @@
Sent at {{tx.sentTs | date:'medium'}}
TXID: {{tx.sentTxid}}
</span>
<span ng-show="tx.missingSignatures==1">
<span ng-show="!tx.finallyRejected && tx.missingSignatures==1">
One signature missing
</span>
<span ng-show="tx.missingSignatures>1">
<span ng-show="!tx.finallyRejected && tx.missingSignatures>1">
{{tx.missingSignatures}} signatures missing</span>
</div>
</div>

View File

@ -23,16 +23,15 @@ angular.module('copay.send').controller('SendController',
var w = $rootScope.wallet;
w.createTx( address, amount,function() {
// reset fields
$scope.address = null;
$scope.amount = null;
form.address.$pristine = true;
form.amount.$pristine = true;
$rootScope.flashMessage = { message: 'The transaction proposal has been created', type: 'success'};
$rootScope.$digest();
});
// reset fields
$scope.address = null;
$scope.amount = null;
form.address.$pristine = true;
form.amount.$pristine = true;
// TODO: check if createTx has an error.
$rootScope.flashMessage = { message: 'Your transaction proposal has been sent successfully', type: 'success'};
};
});

View File

@ -70,5 +70,14 @@ angular.module('copay.transactions').controller('TransactionsController',
}
};
$scope.reject = function (ntxid) {
var w = $rootScope.wallet;
w.reject(ntxid);
$rootScope.flashMessage = {type:'warning', message: 'Transaction rejected by you'};
_updateTxs();
$rootScope.$digest();
};
_updateTxs();
});

View File

@ -274,6 +274,8 @@ PublicKeyRing.prototype._mergePubkeys = function(inPKR) {
var self = this;
var hasChanged = false;
var l= self.copayersBIP32.length;
if (self.isComplete())
return;
inPKR.copayersBIP32.forEach( function(b) {
var haveIt = false;
@ -286,7 +288,6 @@ PublicKeyRing.prototype._mergePubkeys = function(inPKR) {
}
if (!haveIt) {
if (self.isComplete()) {
//console.log('[PublicKeyRing.js.318] REPEATED KEY', epk); //TODO
throw new Error('trying to add more pubkeys, when PKR isComplete at merge');
}
self.copayersBIP32.push(new BIP32(epk));

View File

@ -18,6 +18,7 @@ function TxProposal(opts) {
this.createdTs = opts.createdTs;
this.seenBy = opts.seenBy || {};
this.signedBy = opts.signedBy || {};
this.rejectedBy = opts.rejectedBy || {};
this.builder = opts.builder;
this.sentTs = opts.sentTs || null;
this.sentTxid = opts.sentTxid || null;
@ -120,6 +121,7 @@ TxProposals.prototype._startMerge = function(myTxps, theirTxps) {
};
};
// TODO add signatures.
TxProposals.prototype._mergeMetadata = function(myTxps, theirTxps, mergeInfo) {
var toMerge = mergeInfo.toMerge;
@ -130,7 +132,7 @@ TxProposals.prototype._mergeMetadata = function(myTxps, theirTxps, mergeInfo) {
var v1 = toMerge[hash];
Object.keys(v1.seenBy).forEach(function(k) {
if (!v0.seenBy[k] || v0.seenBy[k] !== v1.seenBy[k]) {
if (!v0.seenBy[k]) {
v0.seenBy[k] = v1.seenBy[k];
hasChanged++;
}
@ -143,6 +145,13 @@ TxProposals.prototype._mergeMetadata = function(myTxps, theirTxps, mergeInfo) {
}
});
Object.keys(v1.rejectedBy).forEach(function(k) {
if (!v0.rejectedBy[k]) {
v0.rejectedBy[k] = v1.rejectedBy[k];
hasChanged++;
}
});
if (!v0.sentTxid && v1.sentTxid) {
v0.sentTs = v1.sentTs;
v0.sentTxid = v1.sentTxid;
@ -181,10 +190,41 @@ TxProposals.prototype.setSent = function(ntxid,txid) {
this.txps[ntxid].setSent(txid);
};
TxProposals.prototype.getUsedUnspent = function() {
TxProposals.prototype.getTxProposal = function(ntxid) {
var txp = this.txps[ntxid];
var i = JSON.parse(JSON.stringify(txp));
i.builder = txp.builder;
i.ntxid = ntxid;
i.peerActions = {};
for(var p in txp.seenBy){
i.peerActions[p]={seen: txp.seenBy[p]};
}
for(var p in txp.signedBy){
i.peerActions[p]= i.peerActions[p] || {};
i.peerActions[p].sign = txp.signedBy[p];
}
var r=0;
for(var p in txp.rejectedBy){
i.peerActions[p]= i.peerActions[p] || {};
i.peerActions[p].rejected = txp.rejectedBy[p];
r++;
}
i.rejectCount=r;
var c = txp.creator;
i.peerActions[c] = i.peerActions[c] || {};
i.peerActions[c].create = txp.createdTs;
return i;
};
TxProposals.prototype.getUsedUnspent = function(maxRejectCount) {
var ret = [];
for(var i in this.txps) {
var u = this.txps[i].builder.getSelectedUnspent();
if (this.getTxProposal(i).rejectCount>maxRejectCount)
continue;
for (var j in u){
ret.push(u[j].txid);
}

View File

@ -274,46 +274,38 @@ Wallet.prototype.generateAddress = function(isChange) {
return addr;
};
// TODO : sort by time... / signed.
Wallet.prototype.getTxProposals = function() {
var ret = [];
for(var k in this.txProposals.txps) {
var txp = this.txProposals.txps[k];
var i = JSON.parse(JSON.stringify(txp));
i.builder = txp.builder;
i.ntxid = k;
i.signedByUs = txp.signedBy[this.getMyPeerId()]?true:false;
i.peerActions = {};
for(var p in txp.seenBy){
i.peerActions[p]={seen: txp.seenBy[p]};
}
for(var p in txp.signedBy){
i.peerActions[p]= i.peerActions[p] || {};
i.peerActions[p].sign = txp.signedBy[p];
}
var c = txp.creator;
i.peerActions[c] = i.peerActions[c] || {};
i.peerActions[c].create = txp.createdTs;
var i = this.txProposals.getTxProposal(k);
i.signedByUs = i.signedBy[this.getMyPeerId()]?true:false;
i.rejectedByUs = i.rejectedBy[this.getMyPeerId()]?true:false;
if (this.totalCopayers-i.rejectCount < this.requiredCopayers)
i.finallyRejected=true;
ret.push(i);
}
return ret;
};
Wallet.prototype.getTxProposal = function(ntxid) {
Wallet.prototype.reject = function(ntxid) {
var myId=this.getMyPeerId();
var txp = this.txProposals.txps[ntxid];
var i = {txp:txp};
i.ntxid = ntxid;
i.signedByUs = txp.signedBy[this.getMyPeerId()]?true:false;
return i;
if (!txp || txp.rejectedBy[myId] || txp.signedBy[myId]) return;
txp.rejectedBy[myId] = Date.now();
this.sendTxProposals();
this.store(true);
};
Wallet.prototype.sign = function(ntxid) {
var self = this;
var myId=this.getMyPeerId();
var txp = self.txProposals.txps[ntxid];
if (!txp) return;
if (!txp || txp.rejectedBy[myId] || txp.signedBy[myId]) return;
var pkr = self.publicKeyRing;
var keys = self.privateKey.getAll(pkr.addressIndex, pkr.changeAddressIndex);
@ -324,7 +316,7 @@ Wallet.prototype.sign = function(ntxid) {
var ret = false;
if (b.signaturesAdded > before) {
txp.signedBy[self.getMyPeerId()] = Date.now();
txp.signedBy[myId] = Date.now();
this.sendTxProposals();
this.store(true);
ret = true;
@ -371,7 +363,6 @@ Wallet.prototype.addSeenToTxProposals = function() {
return ret;
};
Wallet.prototype.getAddresses = function(onlyMain) {
return this.publicKeyRing.getAddresses(onlyMain);
};
@ -438,7 +429,8 @@ Wallet.prototype.getSafeUnspent = function(cb) {
this.blockchain.getUnspent(this.getAddressesStr(), function(unspentList) {
var ret=[];
var uu = self.txProposals.getUsedUnspent();
var maxRejectCount = self.totalCopayers - self.requiredCopayers;
var uu = self.txProposals.getUsedUnspent(maxRejectCount);
for(var i in unspentList){
if (uu.indexOf(unspentList[i].txid) === -1)
@ -497,21 +489,25 @@ Wallet.prototype.createTxSync = function(toAddress, amountSatStr, utxos, opts) {
if (priv) {
b.sign( priv.getAll(pkr.addressIndex, pkr.changeAddressIndex) );
}
var me = {};
var myId = this.getMyPeerId();
var now = Date.now();
if (priv) me[myId] = now;
var me = {};
if (priv && b.signaturesAdded) me[myId] = now;
var meSeen = {};
if (priv) meSeen[myId] = now;
var data = {
signedBy: (priv && b.signaturesAdded ? me : {}),
seenBy: (priv ? me : {}),
signedBy: me,
seenBy: meSeen,
creator: myId,
createdTs: now,
builder: b,
};
this.txProposals.add(data);
return true;
};
Wallet.prototype.connectTo = function(peerId) {