resolved conflict

This commit is contained in:
Ivan Socolsky 2014-09-10 15:09:11 -03:00
commit baf92d4c1b
5 changed files with 72 additions and 89 deletions

View file

@ -16,7 +16,6 @@ var defaultConfig = {
limits: { limits: {
totalCopayers: 12, totalCopayers: 12,
mPlusN: 100, mPlusN: 100,
minAmountSatoshi: 5400,
}, },
// network layer config // network layer config
@ -66,4 +65,4 @@ var defaultConfig = {
verbose: 1, verbose: 1,
}; };
if (typeof module !== 'undefined') if (typeof module !== 'undefined')
module.exports = defaultConfig; module.exports = defaultConfig;

View file

@ -9,7 +9,6 @@ angular.module('copayApp.controllers').controller('SendController',
$scope.defaultFee = bitcore.TransactionBuilder.FEE_PER_1000B_SAT * satToUnit; $scope.defaultFee = bitcore.TransactionBuilder.FEE_PER_1000B_SAT * satToUnit;
$scope.unitToBtc = config.unitToSatoshi / bitcore.util.COIN; $scope.unitToBtc = config.unitToSatoshi / bitcore.util.COIN;
$scope.unitToSatoshi = config.unitToSatoshi; $scope.unitToSatoshi = config.unitToSatoshi;
$scope.minAmount = config.limits.minAmountSatoshi * satToUnit;
$scope.alternativeName = config.alternativeName; $scope.alternativeName = config.alternativeName;
$scope.alternativeIsoCode = config.alternativeIsoCode; $scope.alternativeIsoCode = config.alternativeIsoCode;
@ -30,40 +29,38 @@ angular.module('copayApp.controllers').controller('SendController',
*/ */
Object.defineProperty($scope, Object.defineProperty($scope,
"alternative", { "alternative", {
get: function () { get: function() {
return this._alternative; return this._alternative;
}, },
set: function (newValue) { set: function(newValue) {
this._alternative = newValue; this._alternative = newValue;
if (typeof(newValue) === 'number' && $scope.isRateAvailable) { if (typeof(newValue) === 'number' && $scope.isRateAvailable) {
this._amount = parseFloat( this._amount = parseFloat(
(rateService.fromFiat(newValue, config.alternativeIsoCode) * satToUnit (rateService.fromFiat(newValue, config.alternativeIsoCode) * satToUnit).toFixed(config.unitDecimals), 10);
).toFixed(config.unitDecimals), 10); } else {
} else { this._amount = 0;
this._amount = 0; }
} },
}, enumerable: true,
enumerable: true, configurable: true
configurable: true });
});
Object.defineProperty($scope, Object.defineProperty($scope,
"amount", { "amount", {
get: function () { get: function() {
return this._amount; return this._amount;
}, },
set: function (newValue) { set: function(newValue) {
this._amount = newValue; this._amount = newValue;
if (typeof(newValue) === 'number' && $scope.isRateAvailable) { if (typeof(newValue) === 'number' && $scope.isRateAvailable) {
this._alternative = parseFloat( this._alternative = parseFloat(
(rateService.toFiat(newValue * config.unitToSatoshi, config.alternativeIsoCode) (rateService.toFiat(newValue * config.unitToSatoshi, config.alternativeIsoCode)).toFixed(2), 10);
).toFixed(2), 10); } else {
} else { this._alternative = 0;
this._alternative = 0; }
} },
}, enumerable: true,
enumerable: true, configurable: true
configurable: true });
});
$scope.loadTxs = function() { $scope.loadTxs = function() {
var opts = { var opts = {
@ -104,7 +101,7 @@ angular.module('copayApp.controllers').controller('SendController',
$scope.isMobile = isMobile.any(); $scope.isMobile = isMobile.any();
if (!window.cordova && !navigator.getUserMedia) if (!window.cordova && !navigator.getUserMedia)
$scope.disableScanner =1; $scope.disableScanner = 1;
$scope.submitForm = function(form) { $scope.submitForm = function(form) {
if (form.$invalid) { if (form.$invalid) {
@ -187,9 +184,7 @@ angular.module('copayApp.controllers').controller('SendController',
} }
// If we're setting the domain, ignore the change. // If we're setting the domain, ignore the change.
if ($rootScope.merchant if ($rootScope.merchant && $rootScope.merchant.domain && address === $rootScope.merchant.domain) {
&& $rootScope.merchant.domain
&& address === $rootScope.merchant.domain) {
uri = { uri = {
merchant: $rootScope.merchant.request_url merchant: $rootScope.merchant.request_url
}; };
@ -480,9 +475,7 @@ angular.module('copayApp.controllers').controller('SendController',
var uri; var uri;
// If we're setting the domain, ignore the change. // If we're setting the domain, ignore the change.
if ($rootScope.merchant if ($rootScope.merchant && $rootScope.merchant.domain && value === $rootScope.merchant.domain) {
&& $rootScope.merchant.domain
&& value === $rootScope.merchant.domain) {
return; return;
} }
@ -566,9 +559,7 @@ angular.module('copayApp.controllers').controller('SendController',
var val = scope.sendForm.address.$viewValue || ''; var val = scope.sendForm.address.$viewValue || '';
var uri; var uri;
// If we're setting the domain, ignore the change. // If we're setting the domain, ignore the change.
if ($rootScope.merchant if ($rootScope.merchant && $rootScope.merchant.domain && val === $rootScope.merchant.domain) {
&& $rootScope.merchant.domain
&& val === $rootScope.merchant.domain) {
uri = { uri = {
merchant: $rootScope.merchant.request_url merchant: $rootScope.merchant.request_url
}; };
@ -600,4 +591,4 @@ angular.module('copayApp.controllers').controller('SendController',
}); });
}; };
}); });

View file

@ -463,7 +463,7 @@ Wallet.prototype.updateTimestamp = function(ts) {
*/ */
Wallet.prototype._onNoMessages = function() { Wallet.prototype._onNoMessages = function() {
log.debug('No messages at the server. Requesting peer sync from: ' + this.lastTimestamp + 1); //TODO log.debug('No messages at the server. Requesting peer sync from: ' + this.lastTimestamp + 1); //TODO
this.sendWalletReady(null, parseInt((this.lastTimestamp + 1)/1000) ) ; this.sendWalletReady(null, parseInt((this.lastTimestamp + 1) / 1000));
}; };
/** /**
@ -498,7 +498,7 @@ Wallet.prototype._onData = function(senderId, data, ts) {
break; break;
case 'walletReady': case 'walletReady':
if (this.lastMessageFrom[senderId] !== 'walletReady') { if (this.lastMessageFrom[senderId] !== 'walletReady') {
log.debug('peer Sync received. since: ' + (data.sinceTs||0)); log.debug('peer Sync received. since: ' + (data.sinceTs || 0));
this.sendPublicKeyRing(senderId); this.sendPublicKeyRing(senderId);
this.sendAddressBook(senderId); this.sendAddressBook(senderId);
this.sendAllTxProposals(senderId, data.sinceTs); // send old txps this.sendAllTxProposals(senderId, data.sinceTs); // send old txps
@ -2114,7 +2114,6 @@ Wallet.prototype.createTxSync = function(toAddress, amountSatStr, comment, utxos
preconditions.checkArgument(new Address(toAddress).network().name === this.getNetworkName(), 'networkname mismatch'); preconditions.checkArgument(new Address(toAddress).network().name === this.getNetworkName(), 'networkname mismatch');
preconditions.checkState(pkr.isComplete(), 'pubkey ring incomplete'); preconditions.checkState(pkr.isComplete(), 'pubkey ring incomplete');
preconditions.checkState(priv, 'no private key'); preconditions.checkState(priv, 'no private key');
preconditions.checkArgument(bignum(amountSatStr, 10).cmp(copayConfig.limits.minAmountSatoshi) >= 0, 'invalid amount');
if (comment) preconditions.checkArgument(comment.length <= 100); if (comment) preconditions.checkArgument(comment.length <= 100);
if (!opts.remainderOut) { if (!opts.remainderOut) {
@ -2523,4 +2522,4 @@ Wallet.request = function(options, callback) {
return ret; return ret;
}; };
module.exports = Wallet; module.exports = Wallet;

View file

@ -219,7 +219,7 @@ describe('Wallet model', function() {
var t = w.txProposals; var t = w.txProposals;
var opts = JSON.parse(t.txps[ntxid].builder.vanilla.opts); var opts = JSON.parse(t.txps[ntxid].builder.vanilla.opts);
opts.signhash.should.equal(1); opts.signhash.should.equal(1);
(opts.lockTime===null).should.be.true; (opts.lockTime === null).should.be.true;
should.not.exist(opts.fee); should.not.exist(opts.fee);
should.not.exist(opts.feeSat); should.not.exist(opts.feeSat);
}); });
@ -377,7 +377,7 @@ describe('Wallet model', function() {
Wallet.decodeSecret('4fp61K187CsYmjoRQC5iAdC5eGmbCRsAAXfwEwetSQgHvZs27eWKaLaNHRoK'); Wallet.decodeSecret('4fp61K187CsYmjoRQC5iAdC5eGmbCRsAAXfwEwetSQgHvZs27eWKaLaNHRoK');
}).should. }).should.
throw(); throw();
(function() { (function() {
Wallet.decodeSecret('12345'); Wallet.decodeSecret('12345');
}).should. }).should.
@ -765,8 +765,12 @@ describe('Wallet model', function() {
var txp = w.txProposals.get(ntxid); var txp = w.txProposals.get(ntxid);
// Assign fake builder // Assign fake builder
txp.builder = new Builder(); txp.builder = new Builder();
sinon.stub(txp.builder, 'build').returns({ isComplete: function () { return false; }}); sinon.stub(txp.builder, 'build').returns({
(function () { isComplete: function() {
return false;
}
});
(function() {
w.sendTx(ntxid); w.sendTx(ntxid);
}).should.throw('Tx is not complete. Can not broadcast'); }).should.throw('Tx is not complete. Can not broadcast');
done(); done();
@ -777,9 +781,11 @@ describe('Wallet model', function() {
var utxo = createUTXO(w); var utxo = createUTXO(w);
w.blockchain.fixUnspent(utxo); w.blockchain.fixUnspent(utxo);
w.createTx(toAddress, amountSatStr, null, function(err, ntxid) { w.createTx(toAddress, amountSatStr, null, function(err, ntxid) {
sinon.stub(w.blockchain, 'broadcast').yields({statusCode: 303}); sinon.stub(w.blockchain, 'broadcast').yields({
statusCode: 303
});
var spyCheckSentTx = sinon.spy(w, '_checkSentTx'); var spyCheckSentTx = sinon.spy(w, '_checkSentTx');
w.sendTx(ntxid, function () {}); w.sendTx(ntxid, function() {});
chai.expect(spyCheckSentTx.calledOnce).to.be.true; chai.expect(spyCheckSentTx.calledOnce).to.be.true;
done(); done();
}); });
@ -810,37 +816,20 @@ describe('Wallet model', function() {
}); });
}); });
describe('#createTx', function () { describe('#createTx', function() {
it('should fail if insight server is down', function (done) { it('should fail if insight server is down', function(done) {
var w = cachedCreateW2(); var w = cachedCreateW2();
var utxo = createUTXO(w); var utxo = createUTXO(w);
w.blockchain.fixUnspent(utxo); w.blockchain.fixUnspent(utxo);
sinon.stub(w, 'getUnspent').yields('error', null); sinon.stub(w, 'getUnspent').yields('error', null);
w.createTx(toAddress, amountSatStr, null, function(err, ntxid) { w.createTx(toAddress, amountSatStr, null, function(err, ntxid) {
chai.expect(err.message).to.equal('Could not get list of UTXOs'); chai.expect(err.message).to.equal('Could not get list of UTXOs');
done(); done();
}); });
}); });
}); });
describe('#createTxSync', function() { describe('removeTxWithSpentInputs', function() {
it('should fail if amount below min value', function() {
var w = cachedCreateW2();
var utxo = createUTXO(w);
var badCreate = function() {
w.createTxSync(
'mgGJEugdPnvhmRuFdbdQcFfoFLc1XXeB79',
'123',
null,
utxo
);
}
chai.expect(badCreate).to.throw('invalid amount');
});
});
describe('removeTxWithSpentInputs', function () {
it('should remove pending TxProposal with spent inputs', function(done) { it('should remove pending TxProposal with spent inputs', function(done) {
var w = cachedCreateW2(); var w = cachedCreateW2();
var utxo = createUTXO(w); var utxo = createUTXO(w);
@ -849,7 +838,7 @@ describe('Wallet model', function() {
w.createTx(toAddress, amountSatStr, null, function(err, ntxid) { w.createTx(toAddress, amountSatStr, null, function(err, ntxid) {
w.sendTxProposal(ntxid); w.sendTxProposal(ntxid);
chai.expect(w.getTxProposals().length).to.equal(1); chai.expect(w.getTxProposals().length).to.equal(1);
// Inputs are still available, txp still valid // Inputs are still available, txp still valid
w.removeTxWithSpentInputs(); w.removeTxWithSpentInputs();
chai.expect(w.getTxProposals().length).to.equal(1); chai.expect(w.getTxProposals().length).to.equal(1);
@ -874,7 +863,7 @@ describe('Wallet model', function() {
w.createTx(toAddress, '100000', null, function(err, ntxid) { w.createTx(toAddress, '100000', null, function(err, ntxid) {
w.sendTxProposal(ntxid); w.sendTxProposal(ntxid);
chai.expect(w.getTxProposals().length).to.equal(1); chai.expect(w.getTxProposals().length).to.equal(1);
// Inputs are still available, txp still valid // Inputs are still available, txp still valid
w.removeTxWithSpentInputs(); w.removeTxWithSpentInputs();
chai.expect(w.getTxProposals().length).to.equal(1); chai.expect(w.getTxProposals().length).to.equal(1);
@ -896,7 +885,7 @@ describe('Wallet model', function() {
w.createTx(toAddress, amountSatStr, null, function(err, ntxid) { w.createTx(toAddress, amountSatStr, null, function(err, ntxid) {
w.sendTxProposal(ntxid); w.sendTxProposal(ntxid);
chai.expect(w.getTxProposals().length).to.equal(1); chai.expect(w.getTxProposals().length).to.equal(1);
// Inputs are still available, txp still valid // Inputs are still available, txp still valid
w.removeTxWithSpentInputs(); w.removeTxWithSpentInputs();
chai.expect(w.getTxProposals().length).to.equal(1); chai.expect(w.getTxProposals().length).to.equal(1);
@ -904,7 +893,9 @@ describe('Wallet model', function() {
// Simulate input spent. txp should be removed from txps list // Simulate input spent. txp should be removed from txps list
w.blockchain.fixUnspent([]); w.blockchain.fixUnspent([]);
var txp = w.txProposals.get(ntxid); var txp = w.txProposals.get(ntxid);
sinon.stub(txp, 'isPending', function () { return false; }) sinon.stub(txp, 'isPending', function() {
return false;
})
w.removeTxWithSpentInputs(); w.removeTxWithSpentInputs();
chai.expect(w.getTxProposals().length).to.equal(1); chai.expect(w.getTxProposals().length).to.equal(1);
@ -1402,17 +1393,21 @@ describe('Wallet model', function() {
}; };
var s1 = sinon.stub(w, '_getKeyMap', function() { var s1 = sinon.stub(w, '_getKeyMap', function() {
return {1:2}; return {
1: 2
};
}); });
var s2 = sinon.stub(w.txProposals, 'merge', function() { var s2 = sinon.stub(w.txProposals, 'merge', function() {
if (response == 0) if (response == 0)
throw new Error('test error'); throw new Error('test error');
return { return {
ntxid: 1, ntxid: 1,
txp: { txp: {
setCopayers: function() {return ['oeoe']; } , setCopayers: function() {
return ['oeoe'];
},
}, },
new: response == 1 new: response == 1
}; };
@ -1538,4 +1533,4 @@ describe('Wallet model', function() {
should.exist(n.networkNonce); should.exist(n.networkNonce);
}); });
}); });

View file

@ -70,9 +70,8 @@
<input type="number" id="amount" <input type="number" id="amount"
ng-disabled="loading || ($root.merchant && +$root.merchant.total > 0) || $root.merchantError" ng-disabled="loading || ($root.merchant && +$root.merchant.total > 0) || $root.merchantError"
name="amount" placeholder="{{'Amount'|translate}}" ng-model="amount" name="amount" placeholder="{{'Amount'|translate}}" ng-model="amount"
min="{{minAmount}}" max="10000000000" enough-amount required min="0.00000001" max="10000000000" enough-amount required
autocomplete="off" autocomplete="off">
>
<small class="icon-input" ng-show="!sendForm.amount.$invalid && amount"><i class="fi-check"></i></small> <small class="icon-input" ng-show="!sendForm.amount.$invalid && amount"><i class="fi-check"></i></small>
<small class="icon-input" ng-show="sendForm.amount.$invalid && !sendForm.amount.$pristine && !notEnoughAmount"><i class="fi-x"></i></small> <small class="icon-input" ng-show="sendForm.amount.$invalid && !sendForm.amount.$pristine && !notEnoughAmount"><i class="fi-x"></i></small>
<a class="small input-note" title="{{'Send all funds'|translate}}" <a class="small input-note" title="{{'Send all funds'|translate}}"