From d8f12060c73fc63b61514758f0c052e972c13a19 Mon Sep 17 00:00:00 2001 From: bechi Date: Wed, 10 Sep 2014 15:56:36 -0300 Subject: [PATCH 001/191] fix column on send section --- views/send.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/views/send.html b/views/send.html index 9ce86aa5c..62cef3c17 100644 --- a/views/send.html +++ b/views/send.html @@ -53,7 +53,7 @@
-
+
-
+
From e992b976e0f073dd6424af0ed7477868836b59fb Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Wed, 3 Sep 2014 11:27:31 -0300 Subject: [PATCH 002/191] settings: refactor views --- js/controllers/more.js | 10 ++--- js/controllers/settings.js | 2 - views/more.html | 78 +++++++++++++++++++++++--------------- views/settings.html | 46 ++++++---------------- 4 files changed, 63 insertions(+), 73 deletions(-) diff --git a/js/controllers/more.js b/js/controllers/more.js index 87c76ebec..5e148c2a5 100644 --- a/js/controllers/more.js +++ b/js/controllers/more.js @@ -4,8 +4,8 @@ angular.module('copayApp.controllers').controller('MoreController', function($scope, $rootScope, $location, backupService, walletFactory, controllerUtils, notification) { var w = $rootScope.wallet; - $scope.hideAdv=true; - $scope.hidePriv=true; + $scope.hideAdv = true; + $scope.hidePriv = true; if (w) $scope.priv = w.privateKey.toObj().extendedPrivateKeyString; @@ -24,7 +24,7 @@ angular.module('copayApp.controllers').controller('MoreController', $scope.purge = function(deleteAll) { var w = $rootScope.wallet; var removed = w.purgeTxProposals(deleteAll); - if (removed){ + if (removed) { controllerUtils.updateBalance(); } notification.info('Tx Proposals Purged', removed + ' transaction proposal purged'); @@ -32,14 +32,14 @@ angular.module('copayApp.controllers').controller('MoreController', $scope.updateIndexes = function() { var w = $rootScope.wallet; - notification.info('Scaning for transactions','Using derived addresses from your wallet'); + notification.info('Scaning for transactions', 'Using derived addresses from your wallet'); w.updateIndexes(function(err) { notification.info('Scan Ended', 'Updating balance'); if (err) { notification.error('Error', 'Error updating indexes: ' + err); } controllerUtils.updateAddressList(); - controllerUtils.updateBalance(function(){ + controllerUtils.updateBalance(function() { notification.info('Finished', 'The balance is updated using the derived addresses'); w.sendIndexes(); }); diff --git a/js/controllers/settings.js b/js/controllers/settings.js index 4e3020666..578e6ac0d 100644 --- a/js/controllers/settings.js +++ b/js/controllers/settings.js @@ -4,11 +4,9 @@ angular.module('copayApp.controllers').controller('SettingsController', function controllerUtils.redirIfLogged(); $scope.title = 'Settings'; - $scope.networkName = config.networkName; $scope.insightHost = config.blockchain.host; $scope.insightPort = config.blockchain.port; $scope.insightSecure = config.blockchain.schema === 'https'; - $scope.forceNetwork = config.forceNetwork; $scope.defaultLanguage = config.defaultLanguage || 'en'; $scope.availableLanguages = [{ diff --git a/views/more.html b/views/more.html index 78943d5d8..cc993d32f 100644 --- a/views/more.html +++ b/views/more.html @@ -1,62 +1,79 @@

Settings

-
-

Backup

-

It's important to backup your wallet so that you can recover it in case of disaster

- +
+

Backup

+

It's important to backup your wallet so that you can recover it in case of disaster

+ -
+
+
+
+
+ Wallet Unit + +
+
+ Alternative Currency + +
+ +
+ +
+
+
-

- Delete Wallet

-

If all funds have been removed from your wallet and you do not wish to have the wallet data stored on your computer anymore, you can delete your wallet.

+

Delete Wallet

+

If all funds have been removed from your wallet and you do not wish to have the wallet data stored on your computer anymore, you can delete your wallet.

- - Show - Hide - advanced options - + + Show + Hide + advanced options + -

-
-

+
+
+

Master Private Key

Your master private key contains the information to sign any transaction on this wallet. Handle with care.

-
-
-

Scan Wallet Addresses

+
+
+

Scan Wallet Addresses

- This will scan the blockchain looking for addresses derived from your wallet, in case you have funds in addresses not yet generated (e.g.: you restored an old backup). This will also trigger a syncronization of addresses to other connected peers. + This will scan the blockchain looking for addresses derived from your wallet, in case you have funds in addresses not yet generated (e.g.: you restored an old backup). This will also trigger a syncronization of addresses to other connected peers.

-
-
-

Purge Pending Transaction Proposals

+
+
+

Purge Pending Transaction Proposals

- Pending Transactions Proposals will be discarted. This need to be done on ALL peers of a wallet, to prevent the old proposals to be resynced again. + Pending Transactions Proposals will be discarted. This need to be done on ALL peers of a wallet, to prevent the old proposals to be resynced again.

- diff --git a/views/settings.html b/views/settings.html index 0c4ceaf18..b9ce464ac 100644 --- a/views/settings.html +++ b/views/settings.html @@ -10,45 +10,22 @@
Language -
-
- Bitcoin Network - - -
- Network has been fixed to {{networkName}} in this setup. See copay.io for options to use Copay on both livenet and testnet. -
-
-
- Wallet Unit - -
-
- Alternative Currency - -
-
- Insight API server - - - - - - + Insight API server + + + + + + -

- Insight API server is open-source software. You can run your own instance, check Insight API Homepage

+

+ Insight API server is open-source software. You can run your own instance, check Insight API Homepage +

-
« Back

- From 921cb8dd90cedb8cb849cb2f6dfdba2f4efcecef Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Wed, 3 Sep 2014 11:33:45 -0300 Subject: [PATCH 003/191] settings: refactor controllers --- js/controllers/more.js | 47 +++++++++++++++++++++++++++++++++++ js/controllers/settings.js | 50 +------------------------------------- 2 files changed, 48 insertions(+), 49 deletions(-) diff --git a/js/controllers/more.js b/js/controllers/more.js index 5e148c2a5..7b972128f 100644 --- a/js/controllers/more.js +++ b/js/controllers/more.js @@ -4,6 +4,53 @@ angular.module('copayApp.controllers').controller('MoreController', function($scope, $rootScope, $location, backupService, walletFactory, controllerUtils, notification) { var w = $rootScope.wallet; + + $scope.unitOpts = [{ + name: 'Satoshis (100,000,000 satoshis = 1BTC)', + shortName: 'SAT', + value: 1, + decimals: 0 + }, { + name: 'bits (1,000,000 bits = 1BTC)', + shortName: 'bits', + value: 100, + decimals: 2 + }, { + name: 'mBTC (1,000 mBTC = 1BTC)', + shortName: 'mBTC', + value: 100000, + decimals: 5 + }, { + name: 'BTC', + shortName: 'BTC', + value: 100000000, + decimals: 8 + }]; + $scope.selectedAlternative = { + name: config.alternativeName, + isoCode: config.alternativeIsoCode + }; + $scope.alternativeOpts = rateService.isAvailable ? + rateService.listAlternatives() : [$scope.selectedAlternative]; + + rateService.whenAvailable(function() { + $scope.alternativeOpts = rateService.listAlternatives(); + for (var ii in $scope.alternativeOpts) { + if (config.alternativeIsoCode === $scope.alternativeOpts[ii].isoCode) { + $scope.selectedAlternative = $scope.alternativeOpts[ii]; + } + } + }); + + + for (var ii in $scope.unitOpts) { + if (config.unitName === $scope.unitOpts[ii].shortName) { + $scope.selectedUnit = $scope.unitOpts[ii]; + break; + } + } + + $scope.hideAdv = true; $scope.hidePriv = true; if (w) diff --git a/js/controllers/settings.js b/js/controllers/settings.js index 578e6ac0d..6d2ca9896 100644 --- a/js/controllers/settings.js +++ b/js/controllers/settings.js @@ -1,6 +1,6 @@ 'use strict'; -angular.module('copayApp.controllers').controller('SettingsController', function($scope, $rootScope, $window, $location, controllerUtils, rateService) { +angular.module('copayApp.controllers').controller('SettingsController', function($scope, $rootScope, $window, $location, controllerUtils) { controllerUtils.redirIfLogged(); $scope.title = 'Settings'; @@ -24,54 +24,6 @@ angular.module('copayApp.controllers').controller('SettingsController', function } } - $scope.unitOpts = [{ - name: 'Satoshis (100,000,000 satoshis = 1BTC)', - shortName: 'SAT', - value: 1, - decimals: 0 - }, { - name: 'bits (1,000,000 bits = 1BTC)', - shortName: 'bits', - value: 100, - decimals: 2 - }, { - name: 'mBTC (1,000 mBTC = 1BTC)', - shortName: 'mBTC', - value: 100000, - decimals: 5 - }, { - name: 'BTC', - shortName: 'BTC', - value: 100000000, - decimals: 8 - }]; - - $scope.selectedAlternative = { - name: config.alternativeName, - isoCode: config.alternativeIsoCode - }; - $scope.alternativeOpts = rateService.isAvailable ? - rateService.listAlternatives() : [$scope.selectedAlternative]; - - rateService.whenAvailable(function() { - $scope.alternativeOpts = rateService.listAlternatives(); - for (var ii in $scope.alternativeOpts) { - if (config.alternativeIsoCode === $scope.alternativeOpts[ii].isoCode) { - $scope.selectedAlternative = $scope.alternativeOpts[ii]; - } - } - }); - - for (var ii in $scope.unitOpts) { - if (config.unitName === $scope.unitOpts[ii].shortName) { - $scope.selectedUnit = $scope.unitOpts[ii]; - break; - } - } - - $scope.changeNetwork = function() { - $scope.insightHost = $scope.networkName !== 'testnet' ? 'test-insight.bitpay.com' : 'insight.bitpay.com'; - }; $scope.changeInsightSSL = function() { From d2861d9c2ad1d12346d7b26d292b8b96b8503f76 Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Wed, 3 Sep 2014 13:11:32 -0300 Subject: [PATCH 004/191] settings: create new model --- js/controllers/more.js | 16 ++++++++++------ js/controllers/settings.js | 24 ++++++++---------------- js/models/core/Settings.js | 12 ++++++++++++ js/models/core/Wallet.js | 2 ++ 4 files changed, 32 insertions(+), 22 deletions(-) create mode 100644 js/models/core/Settings.js diff --git a/js/controllers/more.js b/js/controllers/more.js index 7b972128f..8431f1634 100644 --- a/js/controllers/more.js +++ b/js/controllers/more.js @@ -1,10 +1,9 @@ 'use strict'; angular.module('copayApp.controllers').controller('MoreController', - function($scope, $rootScope, $location, backupService, walletFactory, controllerUtils, notification) { + function($scope, $rootScope, $location, backupService, walletFactory, controllerUtils, notification, rateService) { var w = $rootScope.wallet; - $scope.unitOpts = [{ name: 'Satoshis (100,000,000 satoshis = 1BTC)', shortName: 'SAT', @@ -49,6 +48,15 @@ angular.module('copayApp.controllers').controller('MoreController', break; } } + $scope.save = function() { + w.changeSettings({ + unitName: $scope.selectedUnit.shortName, + unitToSatoshi: $scope.selectedUnit.value, + unitDecimals: $scope.selectedUnit.decimals, + alternativeName: $scope.selectedAlternative.name, + alternativeIsoCode: $scope.selectedAlternative.isoCode, + }); + }; $scope.hideAdv = true; @@ -57,19 +65,16 @@ angular.module('copayApp.controllers').controller('MoreController', $scope.priv = w.privateKey.toObj().extendedPrivateKeyString; $scope.downloadBackup = function() { - var w = $rootScope.wallet; backupService.download(w); } $scope.deleteWallet = function() { - var w = $rootScope.wallet; walletFactory.delete(w.id, function() { controllerUtils.logout(); }); }; $scope.purge = function(deleteAll) { - var w = $rootScope.wallet; var removed = w.purgeTxProposals(deleteAll); if (removed) { controllerUtils.updateBalance(); @@ -78,7 +83,6 @@ angular.module('copayApp.controllers').controller('MoreController', }; $scope.updateIndexes = function() { - var w = $rootScope.wallet; notification.info('Scaning for transactions', 'Using derived addresses from your wallet'); w.updateIndexes(function(err) { notification.info('Scan Ended', 'Updating balance'); diff --git a/js/controllers/settings.js b/js/controllers/settings.js index 6d2ca9896..d4c3d1426 100644 --- a/js/controllers/settings.js +++ b/js/controllers/settings.js @@ -37,24 +37,16 @@ angular.module('copayApp.controllers').controller('SettingsController', function network.port = $scope.insightPort; network.schema = $scope.insightSecure ? 'https' : 'http'; + var insightSettings = { + host: $scope.insightHost, + port: $scope.insightPort, + schema: $scope.insightSecure ? 'https' : 'http', + } + localStorage.setItem('config', JSON.stringify({ - networkName: $scope.networkName, - blockchain: { - host: $scope.insightHost, - port: $scope.insightPort, - schema: $scope.insightSecure ? 'https' : 'http', - }, - socket: { - host: $scope.insightHost, - port: $scope.insightPort, - schema: $scope.insightSecure ? 'https' : 'http', - }, + blockchain: insightSettings, + socket: insightSettings, network: network, - unitName: $scope.selectedUnit.shortName, - unitToSatoshi: $scope.selectedUnit.value, - unitDecimals: $scope.selectedUnit.decimals, - alternativeName: $scope.selectedAlternative.name, - alternativeIsoCode: $scope.selectedAlternative.isoCode, version: copay.version, defaultLanguage: $scope.selectedLanguage.isoCode diff --git a/js/models/core/Settings.js b/js/models/core/Settings.js new file mode 100644 index 000000000..4d8cbc0de --- /dev/null +++ b/js/models/core/Settings.js @@ -0,0 +1,12 @@ +'use strict'; + +var preconditions = require('preconditions').singleton(); +var log = require('../../log'); + +var copayConfig = require('../../../config'); + +function Settings(opts) { + var self = this; +} + +module.exports = Settings; diff --git a/js/models/core/Wallet.js b/js/models/core/Wallet.js index f9af99d39..4ba28a149 100644 --- a/js/models/core/Wallet.js +++ b/js/models/core/Wallet.js @@ -25,6 +25,7 @@ var TxProposal = require('./TxProposal'); var TxProposals = require('./TxProposals'); var PrivateKey = require('./PrivateKey'); var WalletLock = require('./WalletLock'); +var Settings = require('./Settings'); var copayConfig = require('../../../config'); /** @@ -73,6 +74,7 @@ function Wallet(opts) { this.id = opts.id || Wallet.getRandomId(); this.secretNumber = opts.secretNumber || Wallet.getRandomNumber(); this.lock = new WalletLock(this.storage, this.id, opts.lockTimeOutMin); + this.settings = new Settings(opts.settings); this.name = opts.name; this.verbose = opts.verbose; From ecceb668e300a97ceaed1ccdbbe7f38f00f19c20 Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Wed, 3 Sep 2014 13:11:44 -0300 Subject: [PATCH 005/191] settings: nuke verbose --- js/models/core/Wallet.js | 1 - 1 file changed, 1 deletion(-) diff --git a/js/models/core/Wallet.js b/js/models/core/Wallet.js index 4ba28a149..daa985438 100644 --- a/js/models/core/Wallet.js +++ b/js/models/core/Wallet.js @@ -77,7 +77,6 @@ function Wallet(opts) { this.settings = new Settings(opts.settings); this.name = opts.name; - this.verbose = opts.verbose; this.publicKeyRing.walletId = this.id; this.txProposals.walletId = this.id; this.network.maxPeers = this.totalCopayers; From f9a31ce9aa6ad50dd0ea6eeba0e005c5987b20c0 Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Wed, 3 Sep 2014 13:17:59 -0300 Subject: [PATCH 006/191] settings: nuke verbose 2 --- config.js | 18 ++++++++---------- js/models/core/Settings.js | 6 ++++++ js/models/core/Wallet.js | 4 +++- js/models/core/WalletFactory.js | 2 -- test/test.PayPro.js | 1 - test/test.Wallet.js | 3 +-- test/test.WalletFactory.js | 2 -- 7 files changed, 18 insertions(+), 18 deletions(-) diff --git a/config.js b/config.js index 9c0ef9224..d84a3af9e 100644 --- a/config.js +++ b/config.js @@ -6,11 +6,6 @@ var defaultConfig = { forceNetwork: false, logLevel: 'info', - // DEFAULT unit: Bit - unitName: 'bits', - unitToSatoshi: 100, - alternativeName: 'US Dollar', - alternativeIsoCode: 'USD', // wallet limits limits: { @@ -30,10 +25,14 @@ var defaultConfig = { requiredCopayers: 2, totalCopayers: 3, spendUnconfirmed: true, - verbose: 1, - // will duplicate itself after each try reconnectDelay: 5000, - idleDurationMin: 4 + idleDurationMin: 4, + settings: { + unitName: 'bits', + unitToSatoshi: 100, + alternativeName: 'US Dollar', + alternativeIsoCode: 'USD', + } }, // blockchain service API config @@ -62,7 +61,6 @@ var defaultConfig = { updateFrequencySeconds: 60 * 60 }, - verbose: 1, }; if (typeof module !== 'undefined') - module.exports = defaultConfig; \ No newline at end of file + module.exports = defaultConfig; diff --git a/js/models/core/Settings.js b/js/models/core/Settings.js index 4d8cbc0de..8ec86fe53 100644 --- a/js/models/core/Settings.js +++ b/js/models/core/Settings.js @@ -9,4 +9,10 @@ function Settings(opts) { var self = this; } +Settings.prototype.toObj = function() { + return { + + } +}; + module.exports = Settings; diff --git a/js/models/core/Wallet.js b/js/models/core/Wallet.js index daa985438..66dd1fa13 100644 --- a/js/models/core/Wallet.js +++ b/js/models/core/Wallet.js @@ -799,6 +799,7 @@ Wallet.prototype.toObj = function() { var walletObj = { opts: optsObj, + settings: this.settings.toObj(); networkNonce: networkNonce, //yours networkNonces: networkNonces, //copayers publicKeyRing: this.publicKeyRing.toObj(), @@ -832,6 +833,7 @@ Wallet.fromObj = function(o, storage, network, blockchain) { var opts = JSON.parse(JSON.stringify(o.opts)); opts.addressBook = o.addressBook; + opts.settings = o.settings; if (o.privateKey) { opts.privateKey = PrivateKey.fromObj(o.privateKey); @@ -2523,4 +2525,4 @@ Wallet.request = function(options, callback) { return ret; }; -module.exports = Wallet; \ No newline at end of file +module.exports = Wallet; diff --git a/js/models/core/WalletFactory.js b/js/models/core/WalletFactory.js index 2df26a931..bde1f27e1 100644 --- a/js/models/core/WalletFactory.js +++ b/js/models/core/WalletFactory.js @@ -95,7 +95,6 @@ WalletFactory.prototype.fromObj = function(obj, skipFields) { var w = Wallet.fromObj(obj, this.storage, this.network, this.blockchain); if (!w) return false; - w.verbose = this.verbose; this._checkVersion(w.version); this._checkNetwork(w.getNetworkName()); return w; @@ -217,7 +216,6 @@ WalletFactory.prototype.create = function(opts) { opts.storage = this.storage; opts.network = this.network; opts.blockchain = this.blockchain; - opts.verbose = this.verbose; opts.spendUnconfirmed = opts.spendUnconfirmed || this.walletDefaults.spendUnconfirmed; opts.reconnectDelay = opts.reconnectDelay || this.walletDefaults.reconnectDelay; diff --git a/test/test.PayPro.js b/test/test.PayPro.js index fbbeaf7ef..77872c23e 100644 --- a/test/test.PayPro.js +++ b/test/test.PayPro.js @@ -86,7 +86,6 @@ describe('PayPro (in Wallet) model', function() { }; c.networkName = walletConfig.networkName; - c.verbose = walletConfig.verbose; c.version = '0.0.1'; return new Wallet(c); diff --git a/test/test.Wallet.js b/test/test.Wallet.js index d6b765b46..e32698b3e 100644 --- a/test/test.Wallet.js +++ b/test/test.Wallet.js @@ -102,7 +102,6 @@ describe('Wallet model', function() { }; c.networkName = walletConfig.networkName; - c.verbose = walletConfig.verbose; c.version = '0.0.1'; @@ -1533,4 +1532,4 @@ describe('Wallet model', function() { should.exist(n.networkNonce); }); -}); \ No newline at end of file +}); diff --git a/test/test.WalletFactory.js b/test/test.WalletFactory.js index b79bdcd5c..d6cd93ac0 100644 --- a/test/test.WalletFactory.js +++ b/test/test.WalletFactory.js @@ -290,7 +290,6 @@ describe('WalletFactory model', function() { "totalCopayers": 3, "reconnectDelay": 100, "spendUnconfirmed": 1, - "verbose": 0 }, "blockchain": { "host": "test.insight.is", @@ -300,7 +299,6 @@ describe('WalletFactory model', function() { "host": "test.insight.is", "port": 3001 }, - "verbose": 0, "themes": ["default"], }; var wf = new WalletFactory(sconfig, '0.0.1'); From f443843d491ce73b53c61b293dd40a4287057966 Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Wed, 3 Sep 2014 13:28:14 -0300 Subject: [PATCH 007/191] settings: change old settings controller --- js/controllers/more.js | 8 ++++---- js/controllers/settings.js | 16 +++++----------- js/models/core/Wallet.js | 2 +- 3 files changed, 10 insertions(+), 16 deletions(-) diff --git a/js/controllers/more.js b/js/controllers/more.js index 8431f1634..cf619b6a9 100644 --- a/js/controllers/more.js +++ b/js/controllers/more.js @@ -26,8 +26,8 @@ angular.module('copayApp.controllers').controller('MoreController', decimals: 8 }]; $scope.selectedAlternative = { - name: config.alternativeName, - isoCode: config.alternativeIsoCode + name: w.settings.alternativeName, + isoCode: w.settings.alternativeIsoCode }; $scope.alternativeOpts = rateService.isAvailable ? rateService.listAlternatives() : [$scope.selectedAlternative]; @@ -35,7 +35,7 @@ angular.module('copayApp.controllers').controller('MoreController', rateService.whenAvailable(function() { $scope.alternativeOpts = rateService.listAlternatives(); for (var ii in $scope.alternativeOpts) { - if (config.alternativeIsoCode === $scope.alternativeOpts[ii].isoCode) { + if (w.settings.alternativeIsoCode === $scope.alternativeOpts[ii].isoCode) { $scope.selectedAlternative = $scope.alternativeOpts[ii]; } } @@ -43,7 +43,7 @@ angular.module('copayApp.controllers').controller('MoreController', for (var ii in $scope.unitOpts) { - if (config.unitName === $scope.unitOpts[ii].shortName) { + if (w.settings.unitName === $scope.unitOpts[ii].shortName) { $scope.selectedUnit = $scope.unitOpts[ii]; break; } diff --git a/js/controllers/settings.js b/js/controllers/settings.js index d4c3d1426..3141d6d62 100644 --- a/js/controllers/settings.js +++ b/js/controllers/settings.js @@ -4,9 +4,9 @@ angular.module('copayApp.controllers').controller('SettingsController', function controllerUtils.redirIfLogged(); $scope.title = 'Settings'; - $scope.insightHost = config.blockchain.host; - $scope.insightPort = config.blockchain.port; - $scope.insightSecure = config.blockchain.schema === 'https'; + $scope.insightHost = config.network.host; + $scope.insightPort = config.network.port; + $scope.insightSecure = config.network.schema === 'https'; $scope.defaultLanguage = config.defaultLanguage || 'en'; $scope.availableLanguages = [{ @@ -33,9 +33,6 @@ angular.module('copayApp.controllers').controller('SettingsController', function $scope.save = function() { var network = config.network; - network.host = $scope.insightHost; - network.port = $scope.insightPort; - network.schema = $scope.insightSecure ? 'https' : 'http'; var insightSettings = { host: $scope.insightHost, @@ -44,11 +41,8 @@ angular.module('copayApp.controllers').controller('SettingsController', function } localStorage.setItem('config', JSON.stringify({ - blockchain: insightSettings, - socket: insightSettings, - network: network, - - version: copay.version, + network: insightSettings, + version: copay.version defaultLanguage: $scope.selectedLanguage.isoCode })); diff --git a/js/models/core/Wallet.js b/js/models/core/Wallet.js index 66dd1fa13..db38f95e2 100644 --- a/js/models/core/Wallet.js +++ b/js/models/core/Wallet.js @@ -799,7 +799,7 @@ Wallet.prototype.toObj = function() { var walletObj = { opts: optsObj, - settings: this.settings.toObj(); + settings: this.settings.toObj(), networkNonce: networkNonce, //yours networkNonces: networkNonces, //copayers publicKeyRing: this.publicKeyRing.toObj(), From cff9f567bbc5c6ec22152775331104bddfdea9c1 Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Wed, 3 Sep 2014 14:44:48 -0300 Subject: [PATCH 008/191] settings: no settings model after all --- js/controllers/settings.js | 2 -- js/models/core/Settings.js | 18 ------------------ js/models/core/Wallet.js | 9 +++------ 3 files changed, 3 insertions(+), 26 deletions(-) delete mode 100644 js/models/core/Settings.js diff --git a/js/controllers/settings.js b/js/controllers/settings.js index 3141d6d62..b8b5ed1a8 100644 --- a/js/controllers/settings.js +++ b/js/controllers/settings.js @@ -24,8 +24,6 @@ angular.module('copayApp.controllers').controller('SettingsController', function } } - - $scope.changeInsightSSL = function() { $scope.insightPort = $scope.insightSecure ? 80 : 443; }; diff --git a/js/models/core/Settings.js b/js/models/core/Settings.js deleted file mode 100644 index 8ec86fe53..000000000 --- a/js/models/core/Settings.js +++ /dev/null @@ -1,18 +0,0 @@ -'use strict'; - -var preconditions = require('preconditions').singleton(); -var log = require('../../log'); - -var copayConfig = require('../../../config'); - -function Settings(opts) { - var self = this; -} - -Settings.prototype.toObj = function() { - return { - - } -}; - -module.exports = Settings; diff --git a/js/models/core/Wallet.js b/js/models/core/Wallet.js index db38f95e2..98c1971e4 100644 --- a/js/models/core/Wallet.js +++ b/js/models/core/Wallet.js @@ -25,7 +25,6 @@ var TxProposal = require('./TxProposal'); var TxProposals = require('./TxProposals'); var PrivateKey = require('./PrivateKey'); var WalletLock = require('./WalletLock'); -var Settings = require('./Settings'); var copayConfig = require('../../../config'); /** @@ -74,7 +73,7 @@ function Wallet(opts) { this.id = opts.id || Wallet.getRandomId(); this.secretNumber = opts.secretNumber || Wallet.getRandomNumber(); this.lock = new WalletLock(this.storage, this.id, opts.lockTimeOutMin); - this.settings = new Settings(opts.settings); + this.settings = opts.settings || copayConfig.settings; this.name = opts.name; this.publicKeyRing.walletId = this.id; @@ -781,9 +780,7 @@ Wallet.prototype.keepAlive = function() { */ Wallet.prototype.store = function() { this.keepAlive(); - - var wallet = this.toObj(); - this.storage.setFromObj(this.id, wallet); + this.storage.setFromObj(this.id, this.toObj()); log.debug('Wallet stored'); }; @@ -799,7 +796,7 @@ Wallet.prototype.toObj = function() { var walletObj = { opts: optsObj, - settings: this.settings.toObj(), + settings: this.settings, networkNonce: networkNonce, //yours networkNonces: networkNonces, //copayers publicKeyRing: this.publicKeyRing.toObj(), From c9cb2aae578f4e96b35df033682343b4d83f083c Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Wed, 3 Sep 2014 14:45:35 -0300 Subject: [PATCH 009/191] settings: small refactor --- js/models/core/Wallet.js | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/js/models/core/Wallet.js b/js/models/core/Wallet.js index 98c1971e4..0e1f63737 100644 --- a/js/models/core/Wallet.js +++ b/js/models/core/Wallet.js @@ -791,14 +791,11 @@ Wallet.prototype.store = function() { Wallet.prototype.toObj = function() { var optsObj = this._optsToObj(); - var networkNonce = this.network.getHexNonce(); - var networkNonces = this.network.getHexNonces(); - var walletObj = { opts: optsObj, settings: this.settings, - networkNonce: networkNonce, //yours - networkNonces: networkNonces, //copayers + networkNonce: this.network.getHexNonce(), //yours + networkNonces: this.network.getHexNonces(), //copayers publicKeyRing: this.publicKeyRing.toObj(), txProposals: this.txProposals.toObj(), privateKey: this.privateKey ? this.privateKey.toObj() : undefined, From c1d8103374fdfdef487034f659c6bf462e8a1f16 Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Mon, 8 Sep 2014 16:26:58 -0700 Subject: [PATCH 010/191] fix settings.js --- config.js | 15 --------------- js/controllers/settings.js | 2 +- js/models/core/Wallet.js | 17 ++++++++++++++++- js/models/core/WalletFactory.js | 2 +- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/config.js b/config.js index d84a3af9e..f9ca1170d 100644 --- a/config.js +++ b/config.js @@ -35,21 +35,6 @@ var defaultConfig = { } }, - // blockchain service API config - blockchain: { - schema: 'https', - host: 'test-insight.bitpay.com', - port: 443, - retryDelay: 1000, - }, - // socket service API config - socket: { - schema: 'https', - host: 'test-insight.bitpay.com', - port: 443, - reconnectDelay: 1000, - }, - // local encryption/security config passphrase: { iterations: 100, diff --git a/js/controllers/settings.js b/js/controllers/settings.js index b8b5ed1a8..620a06e36 100644 --- a/js/controllers/settings.js +++ b/js/controllers/settings.js @@ -40,7 +40,7 @@ angular.module('copayApp.controllers').controller('SettingsController', function localStorage.setItem('config', JSON.stringify({ network: insightSettings, - version: copay.version + version: copay.version, defaultLanguage: $scope.selectedLanguage.isoCode })); diff --git a/js/models/core/Wallet.js b/js/models/core/Wallet.js index 0e1f63737..4f603da24 100644 --- a/js/models/core/Wallet.js +++ b/js/models/core/Wallet.js @@ -161,6 +161,22 @@ Wallet.prototype._onIndexes = function(senderId, data) { } }; +/** + * @desc + * Changes wallet settings. The settings format is: + * + * var settings = { + * unitName: 'bits', + * unitToSatoshi: 100, + * alternativeName: 'US Dollar', + * alternativeIsoCode: 'USD', + * }; + */ +Wallet.prototype.changeSettings = function(settings) { + console.log(settings); + this.settings = settings; +}; + /** * @desc * Handles a 'PUBLICKEYRING' message from senderId. @@ -893,7 +909,6 @@ Wallet.prototype.send = function(recipients, obj) { Wallet.prototype.sendAllTxProposals = function(recipients, sinceTs) { var ntxids = sinceTs ? this.txProposals.getNtxidsSince(sinceTs) : this.txProposals.getNtxids(); var self = this; - _.each(ntxids, function(ntxid, key) { self.sendTxProposal(ntxid, recipients); }); diff --git a/js/models/core/WalletFactory.js b/js/models/core/WalletFactory.js index bde1f27e1..9f052e8f6 100644 --- a/js/models/core/WalletFactory.js +++ b/js/models/core/WalletFactory.js @@ -42,7 +42,7 @@ function WalletFactory(config, version) { this.storage = new this.Storage(config.storage); this.network = new this.Network(config.network); - this.blockchain = new this.Blockchain(config.blockchain); + this.blockchain = new this.Blockchain(config.network); this.networkName = config.networkName; this.walletDefaults = config.wallet; From 3e9328f9514985de9adde669e1c677e554537e7e Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Wed, 3 Sep 2014 15:05:44 -0300 Subject: [PATCH 011/191] settings: Insight.js refactor --- js/models/blockchain/Insight.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/js/models/blockchain/Insight.js b/js/models/blockchain/Insight.js index 00a4dddba..d71ea79a7 100644 --- a/js/models/blockchain/Insight.js +++ b/js/models/blockchain/Insight.js @@ -45,6 +45,7 @@ var Insight = function(opts) { 'secure': opts.schema === 'https' }; + this.socket = this.getSocket(); } util.inherits(Insight, EventEmitter); @@ -105,7 +106,7 @@ Insight.prototype._setMainHandlers = function(url, opts) { /** @private */ -Insight.prototype.getSocket = function(url, opts) { +Insight.prototype.getSocket = function() { if (!this.socket) { this.socket = this._getSocketIO(this.url, this.opts); From 08db6831ce854c1aa972bfa67a99a13710ec1edd Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Wed, 3 Sep 2014 15:08:14 -0300 Subject: [PATCH 012/191] settings: Insight.js refactor 2 --- test/test.blockchain.Insight.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/test.blockchain.Insight.js b/test/test.blockchain.Insight.js index b43003ed6..730d837f6 100644 --- a/test/test.blockchain.Insight.js +++ b/test/test.blockchain.Insight.js @@ -348,7 +348,7 @@ describe('Insight model', function() { }); describe('Events', function() { - it('should emmit event on a new block', function(done) { + it('should emit event on a new block', function(done) { var blockchain = new Insight(FAKE_OPTS); var socket = blockchain.getSocket(); blockchain.on('connect', function() { @@ -362,7 +362,7 @@ describe('Insight model', function() { }); }); - it('should emmit event on a transaction for subscribed addresses', function(done) { + it('should emit event on a transaction for subscribed addresses', function(done) { var blockchain = new Insight(FAKE_OPTS); var socket = blockchain.getSocket(); blockchain.subscribe('2NFjCBFZSsxiwWAD7CKQ3hzWFtf9DcqTucY'); @@ -378,7 +378,7 @@ describe('Insight model', function() { }); }); - it('should\'t emmit event on a transaction for non subscribed addresses', function(done) { + it('should\'t emit event on a transaction for non subscribed addresses', function(done) { var blockchain = new Insight(FAKE_OPTS); var socket = blockchain.getSocket(); blockchain.on('connect', function() { @@ -392,7 +392,7 @@ describe('Insight model', function() { }); }); - it('should emmit event on connection', function(done) { + it('should emit event on connection', function(done) { var blockchain = new Insight(FAKE_OPTS); var socket = blockchain.getSocket(); blockchain.on('connect', function() { @@ -400,7 +400,7 @@ describe('Insight model', function() { }); }); - it('should emmit event on disconnection', function(done) { + it('should emit event on disconnection', function(done) { var blockchain = new Insight(FAKE_OPTS); var socket = blockchain.getSocket(); blockchain.on('connect', function() { From e3afce6a9f77117e90fbc2fefe32613b92051cdb Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Wed, 3 Sep 2014 15:09:06 -0300 Subject: [PATCH 013/191] settings: Insight.js refactor 3 --- js/models/blockchain/Insight.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/js/models/blockchain/Insight.js b/js/models/blockchain/Insight.js index d71ea79a7..2e6c4116c 100644 --- a/js/models/blockchain/Insight.js +++ b/js/models/blockchain/Insight.js @@ -29,15 +29,15 @@ var preconditions = require('preconditions').singleton(); */ var Insight = function(opts) { - this.status = this.STATUS.DISCONNECTED; - this.subscribed = {}; - this.listeningBlocks = false; - preconditions.checkArgument(opts).shouldBeObject(opts) .checkArgument(opts.host) .checkArgument(opts.port) .checkArgument(opts.schema); + this.status = this.STATUS.DISCONNECTED; + this.subscribed = {}; + this.listeningBlocks = false; + this.url = opts.schema + '://' + opts.host + ':' + opts.port; this.opts = { 'reconnection': opts.reconnection || true, From 3691bd5ee03a4457c9bc489de05634ea7fa17c70 Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Wed, 3 Sep 2014 15:55:02 -0300 Subject: [PATCH 014/191] settings: fix balance bug --- index.html | 6 +++--- js/services/controllerUtils.js | 1 - views/includes/sidebar-mobile.html | 31 ++++++++++++++++++++++++++++++ views/includes/sidebar.html | 4 ++-- 4 files changed, 36 insertions(+), 6 deletions(-) diff --git a/index.html b/index.html index e6f34fd00..40b22b4da 100644 --- a/index.html +++ b/index.html @@ -17,8 +17,8 @@ Network Error. Attempting to reconnect... -
+ +
+
+
+ Balance + + + + {{totalBalance || 0 + |noFractionNumber}} {{$root.unitName}} + +
+
+ Locked + + + + {{lockedBalance || 0|noFractionNumber}} {{$root.unitName}} +   +
+
+
+
diff --git a/views/includes/sidebar.html b/views/includes/sidebar.html index 9f68392e3..86c6f7a96 100644 --- a/views/includes/sidebar.html +++ b/views/includes/sidebar.html @@ -20,7 +20,7 @@ - - Date: Wed, 3 Sep 2014 16:03:31 -0300 Subject: [PATCH 015/191] settings: fix balance bug 2 --- js/filters.js | 6 +++--- js/models/core/Wallet.js | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/js/filters.js b/js/filters.js index a52237d1f..68f014027 100644 --- a/js/filters.js +++ b/js/filters.js @@ -45,12 +45,12 @@ angular.module('copayApp.filters', []) }; }) .filter('noFractionNumber', - [ '$filter', '$locale', - function(filter, locale) { + [ '$filter', '$locale', '$rootScope', + function(filter, locale, $rootScope) { var numberFilter = filter('number'); var formats = locale.NUMBER_FORMATS; return function(amount, n) { - var fractionSize = (typeof(n) != 'undefined') ? n : config.unitToSatoshi.toString().length - 1; + var fractionSize = (typeof(n) != 'undefined') ? n : $rootScope.wallet.settings.unitToSatoshi.toString().length - 1; var value = numberFilter(amount, fractionSize); var sep = value.indexOf(formats.DECIMAL_SEP); var group = value.indexOf(formats.GROUP_SEP); diff --git a/js/models/core/Wallet.js b/js/models/core/Wallet.js index 4f603da24..17f1d09cb 100644 --- a/js/models/core/Wallet.js +++ b/js/models/core/Wallet.js @@ -73,7 +73,7 @@ function Wallet(opts) { this.id = opts.id || Wallet.getRandomId(); this.secretNumber = opts.secretNumber || Wallet.getRandomNumber(); this.lock = new WalletLock(this.storage, this.id, opts.lockTimeOutMin); - this.settings = opts.settings || copayConfig.settings; + this.settings = opts.settings || copayConfig.wallet.settings; this.name = opts.name; this.publicKeyRing.walletId = this.id; From 0fe477863785e4fcacc99aa0a2bd30ae69359118 Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Wed, 3 Sep 2014 16:24:25 -0300 Subject: [PATCH 016/191] settings: fix references to unitName --- config.js | 1 + js/controllers/send.js | 32 +++++++------ js/filters.js | 73 +++++++++++++++--------------- views/addresses.html | 48 ++++++++++---------- views/includes/sidebar-mobile.html | 4 +- views/includes/sidebar.html | 4 +- views/includes/transaction.html | 31 ++++++------- views/modals/qr-address.html | 2 +- views/send.html | 8 ++-- views/transactions.html | 24 +++++----- 10 files changed, 113 insertions(+), 114 deletions(-) diff --git a/config.js b/config.js index f9ca1170d..ab1beb0a8 100644 --- a/config.js +++ b/config.js @@ -30,6 +30,7 @@ var defaultConfig = { settings: { unitName: 'bits', unitToSatoshi: 100, + unitDecimals: 2, alternativeName: 'US Dollar', alternativeIsoCode: 'USD', } diff --git a/js/controllers/send.js b/js/controllers/send.js index 788217edf..01e547ada 100644 --- a/js/controllers/send.js +++ b/js/controllers/send.js @@ -5,13 +5,13 @@ angular.module('copayApp.controllers').controller('SendController', function($scope, $rootScope, $window, $timeout, $anchorScroll, $modal, isMobile, notification, controllerUtils, rateService) { $scope.title = 'Send'; $scope.loading = false; - var satToUnit = 1 / config.unitToSatoshi; + var satToUnit = 1 / $rootScope.wallet.settings.unitToSatoshi; $scope.defaultFee = bitcore.TransactionBuilder.FEE_PER_1000B_SAT * satToUnit; - $scope.unitToBtc = config.unitToSatoshi / bitcore.util.COIN; - $scope.unitToSatoshi = config.unitToSatoshi; + $scope.unitToBtc = $rootScope.wallet.settings.unitToSatoshi / bitcore.util.COIN; + $scope.unitToSatoshi = $rootScope.wallet.settings.unitToSatoshi; - $scope.alternativeName = config.alternativeName; - $scope.alternativeIsoCode = config.alternativeIsoCode; + $scope.alternativeName = $rootScope.wallet.settings.alternativeName; + $scope.alternativeIsoCode = $rootScope.wallet.settings.alternativeIsoCode; $scope.isRateAvailable = false; $scope.rateService = rateService; @@ -36,7 +36,7 @@ angular.module('copayApp.controllers').controller('SendController', this._alternative = newValue; if (typeof(newValue) === 'number' && $scope.isRateAvailable) { this._amount = parseFloat( - (rateService.fromFiat(newValue, config.alternativeIsoCode) * satToUnit).toFixed(config.unitDecimals), 10); + (rateService.fromFiat(newValue, $rootScope.wallet.settings.alternativeIsoCode) * satToUnit).toFixed($rootScope.wallet.settings.unitDecimals), 10); } else { this._amount = 0; } @@ -53,7 +53,7 @@ angular.module('copayApp.controllers').controller('SendController', this._amount = newValue; if (typeof(newValue) === 'number' && $scope.isRateAvailable) { this._alternative = parseFloat( - (rateService.toFiat(newValue * config.unitToSatoshi, config.alternativeIsoCode)).toFixed(2), 10); + (rateService.toFiat(newValue * $rootScope.wallet.settings.unitToSatoshi, $rootScope.wallet.settings.alternativeIsoCode)).toFixed(2), 10); } else { this._alternative = 0; } @@ -91,7 +91,7 @@ angular.module('copayApp.controllers').controller('SendController', if ($rootScope.pendingPayment) { var pp = $rootScope.pendingPayment; $scope.address = pp.address + ''; - var amount = pp.data.amount / config.unitToSatoshi * 100000000; + var amount = pp.data.amount / $rootScope.wallet.settings.unitToSatoshi * 100000000; $scope.amount = amount; $scope.commentText = pp.data.message; } @@ -113,7 +113,7 @@ angular.module('copayApp.controllers').controller('SendController', $scope.loading = true; var address = form.address.$modelValue; - var amount = parseInt((form.amount.$modelValue * config.unitToSatoshi).toFixed(0)); + var amount = parseInt((form.amount.$modelValue * $rootScope.wallet.settings.unitToSatoshi).toFixed(0)); var commentText = form.comment.$modelValue; var w = $rootScope.wallet; @@ -403,7 +403,7 @@ angular.module('copayApp.controllers').controller('SendController', }; $scope.getAvailableAmount = function() { - var amount = ((($rootScope.availableBalance * config.unitToSatoshi).toFixed(0) - bitcore.TransactionBuilder.FEE_PER_1000B_SAT) / config.unitToSatoshi); + var amount = ((($rootScope.availableBalance * $rootScope.wallet.settings.unitToSatoshi).toFixed(0) - bitcore.TransactionBuilder.FEE_PER_1000B_SAT) / $rootScope.wallet.settings.unitToSatoshi); return amount > 0 ? amount : 0; }; @@ -497,7 +497,7 @@ angular.module('copayApp.controllers').controller('SendController', // Payment Protocol URI (BIP-72) scope.wallet.fetchPaymentTx(uri.merchant, function(err, merchantData) { var balance = $rootScope.availableBalance; - var available = +(balance * config.unitToSatoshi).toFixed(0); + var available = +(balance * $rootScope.wallet.settings.unitToSatoshi).toFixed(0); if (merchantData && available < +merchantData.total) { err = new Error('No unspent outputs available.'); @@ -508,7 +508,7 @@ angular.module('copayApp.controllers').controller('SendController', scope.sendForm.address.$isValid = false; if (err.amount) { - scope.sendForm.amount.$setViewValue(+err.amount / config.unitToSatoshi); + scope.sendForm.amount.$setViewValue(+err.amount / $rootScope.wallet.settings.unitToSatoshi); scope.sendForm.amount.$render(); scope.sendForm.amount.$isValid = false; scope.notEnoughAmount = true; @@ -538,7 +538,7 @@ angular.module('copayApp.controllers').controller('SendController', var url = merchantData.request_url; var domain = /^(?:https?)?:\/\/([^\/:]+).*$/.exec(url)[1]; - merchantData.unitTotal = (+merchantData.total / config.unitToSatoshi) + ''; + merchantData.unitTotal = (+merchantData.total / $rootScope.wallet.settings.unitToSatoshi) + ''; merchantData.expiration = new Date( merchantData.pr.pd.expires * 1000).toISOString(); merchantData.domain = domain; @@ -587,8 +587,10 @@ angular.module('copayApp.controllers').controller('SendController', } notification.info('Payment Request', - 'Server is requesting ' + merchantData.unitTotal + ' ' + config.unitName + '.' + ' Message: ' + merchantData.pr.pd.memo); + 'Server is requesting ' + merchantData.unitTotal + + ' ' + $rootScope.wallet.settings.unitName + + '.' + ' Message: ' + merchantData.pr.pd.memo); }); }; - }); \ No newline at end of file + }); diff --git a/js/filters.js b/js/filters.js index 68f014027..9ed43cd72 100644 --- a/js/filters.js +++ b/js/filters.js @@ -44,43 +44,42 @@ angular.module('copayApp.filters', []) return addrs; }; }) - .filter('noFractionNumber', - [ '$filter', '$locale', '$rootScope', - function(filter, locale, $rootScope) { - var numberFilter = filter('number'); - var formats = locale.NUMBER_FORMATS; - return function(amount, n) { - var fractionSize = (typeof(n) != 'undefined') ? n : $rootScope.wallet.settings.unitToSatoshi.toString().length - 1; - var value = numberFilter(amount, fractionSize); - var sep = value.indexOf(formats.DECIMAL_SEP); - var group = value.indexOf(formats.GROUP_SEP); - if(amount >= 0) { - if (group > 0) { - if (sep < 0) { + .filter('noFractionNumber', ['$filter', '$locale', '$rootScope', + function(filter, locale, $rootScope) { + var numberFilter = filter('number'); + var formats = locale.NUMBER_FORMATS; + return function(amount, n) { + var fractionSize = (typeof(n) !== 'undefined') ? + n : $rootScope.wallet.settings.unitToSatoshi.toString().length - 1; + var value = numberFilter(amount, fractionSize); + var sep = value.indexOf(formats.DECIMAL_SEP); + var group = value.indexOf(formats.GROUP_SEP); + if (amount >= 0) { + if (group > 0) { + if (sep < 0) { + return value; + } + var intValue = value.substring(0, sep); + var floatValue = parseFloat(value.substring(sep)); + if (floatValue === 0) { + floatValue = ''; + } else { + if (floatValue % 1 === 0) { + floatValue = floatValue.toFixed(0); + } + floatValue = floatValue.toString().substring(1); + } + var finalValue = intValue + floatValue; + return finalValue; + } else { + value = parseFloat(value); + if (value % 1 === 0) { + value = value.toFixed(0); + } return value; } - var intValue = value.substring(0, sep); - var floatValue = parseFloat(value.substring(sep)); - if (floatValue === 0) { - floatValue = ''; - } - else { - if(floatValue % 1 === 0) { - floatValue = floatValue.toFixed(0); - } - floatValue = floatValue.toString().substring(1); - } - var finalValue = intValue + floatValue; - return finalValue; } - else { - value = parseFloat(value); - if(value % 1 === 0) { - value = value.toFixed(0); - } - return value; - } - } - return 0; - }; - } ]); + return 0; + }; + } + ]); diff --git a/views/addresses.html b/views/addresses.html index 14f3d7cde..499306ea9 100644 --- a/views/addresses.html +++ b/views/addresses.html @@ -4,39 +4,39 @@ Addresses - +
-
-
-
-
-   - +
+
+
+
+   + - - change -
-
- -
- - - - - {{addr.balance || 0|noFractionNumber}} {{$root.unitName}} - + + change
- - Show all - Show less - +
+ + + + + {{addr.balance || 0|noFractionNumber}} {{$root.wallet.settings.unitName}} + +
+
+ + + + Show all + Show less +
- diff --git a/views/includes/sidebar-mobile.html b/views/includes/sidebar-mobile.html index acb540d3c..a77d6d841 100644 --- a/views/includes/sidebar-mobile.html +++ b/views/includes/sidebar-mobile.html @@ -19,7 +19,7 @@ tooltip="{{totalBalanceBTC |noFractionNumber:8}} BTC" tooltip-trigger="mouseenter" tooltip-placement="bottom">{{totalBalance || 0 - |noFractionNumber}} {{$root.unitName}} + |noFractionNumber}} {{$root.wallet.settings.unitName}}
@@ -31,7 +31,7 @@ data-options="disable_for_touch:true" tooltip="{{lockedBalanceBTC |noFractionNumber:8}} BTC" tooltip-trigger="mouseenter" - tooltip-placement="bottom">{{lockedBalance || 0|noFractionNumber}} {{$root.unitName}} + tooltip-placement="bottom">{{lockedBalance || 0|noFractionNumber}} {{$root.wallet.settings.unitName}}  
diff --git a/views/includes/sidebar.html b/views/includes/sidebar.html index 86c6f7a96..0bd5b8263 100644 --- a/views/includes/sidebar.html +++ b/views/includes/sidebar.html @@ -26,7 +26,7 @@ tooltip-popup-delay='500' tooltip="{{totalBalanceAlternative |noFractionNumber:2}} {{alternativeIsoCode}}" tooltip-trigger="mouseenter" - tooltip-placement="bottom">{{totalBalance || 0 |noFractionNumber}} {{$root.unitName}} + tooltip-placement="bottom">{{totalBalance || 0 |noFractionNumber}} {{$root.wallet.settings.unitName}}
Locked   @@ -39,7 +39,7 @@ tooltip-popup-delay='500' tooltip="{{lockedBalanceAlternative |noFractionNumber:2}} {{alternativeIsoCode}}" tooltip-trigger="mouseenter" - tooltip-placement="bottom">{{lockedBalance || 0|noFractionNumber}} {{$root.unitName}} + tooltip-placement="bottom">{{lockedBalance || 0|noFractionNumber}} {{$root.wallet.settings.unitName}}  
diff --git a/views/includes/transaction.html b/views/includes/transaction.html index 5c58a9416..016465c5e 100644 --- a/views/includes/transaction.html +++ b/views/includes/transaction.html @@ -8,20 +8,19 @@
-

- {{tx.comment}} - - {{$root.wallet.publicKeyRing.nicknameForCopayer(tx.creator)}} +

+ {{tx.comment}} - {{$root.wallet.publicKeyRing.nicknameForCopayer(tx.creator)}}

-

{{out.value | noFractionNumber}} {{$root.unitName}}

-

{{out.value | noFractionNumber}} {{$root.unitName}}

+

{{out.value | noFractionNumber}} {{$root.wallet.settings.unitName}}

+

{{out.value | noFractionNumber}} {{$root.wallet.settings.unitName}}

-
+
- +
@@ -37,25 +36,25 @@ @@ -100,7 +99,7 @@
- Sent + Sent
Transaction ID: @@ -110,12 +109,12 @@

- One signature missing + One signature missing

- {{tx.missingSignatures}} signatures missing

+ {{tx.missingSignatures}} signatures missing

- Fee: {{tx.fee|noFractionNumber}} {{$root.unitName}} + Fee: {{tx.fee|noFractionNumber}} {{$root.wallet.settings.unitName}} Proposal ID: {{tx.ntxid}}
diff --git a/views/modals/qr-address.html b/views/modals/qr-address.html index c30b86096..13d5635fc 100644 --- a/views/modals/qr-address.html +++ b/views/modals/qr-address.html @@ -7,7 +7,7 @@

- {{address.balance || 0|noFractionNumber}} {{$root.unitName}} + {{address.balance || 0|noFractionNumber}} {{$root.wallet.settings.unitName}}

- {{$root.unitName}} + {{$root.wallet.settings.unitName}}
@@ -138,13 +138,13 @@

Total amount for this transaction:

- {{amount + defaultFee |noFractionNumber}} {{$root.unitName}} + {{amount + defaultFee |noFractionNumber}} {{$root.wallet.settings.unitName}} {{ rateService.toFiat((amount + defaultFee) * unitToSatoshi, alternativeIsoCode) | noFractionNumber: 2 }} {{ alternativeIsoCode }}
- Including fee of {{defaultFee|noFractionNumber}} {{$root.unitName}} + Including fee of {{defaultFee|noFractionNumber}} {{$root.wallet.settings.unitName}}

diff --git a/views/transactions.html b/views/transactions.html index 63d00b175..f00f78df7 100644 --- a/views/transactions.html +++ b/views/transactions.html @@ -7,7 +7,8 @@
-

No transactions proposals yet.

+

No transactions proposals yet. +

@@ -20,10 +21,8 @@
@@ -52,9 +51,9 @@
- {{vin.value| noFractionNumber}} {{$root.unitName}} + {{vin.value| noFractionNumber}} {{$root.wallet.settings.unitName}}

- +

@@ -66,20 +65,20 @@
- {{vout.value| noFractionNumber}} {{$root.unitName}} + {{vout.value| noFractionNumber}} {{$root.wallet.settings.unitName}}

- +

@@ -87,4 +86,3 @@
- From 7c582f4bd5b0d22cf74b6cefef58e2fe329fcfd1 Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Thu, 4 Sep 2014 11:12:08 -0300 Subject: [PATCH 017/191] settings: fix references to unitToSatoshi --- js/controllers/transactions.js | 4 +++- js/directives.js | 5 +++-- js/services/controllerUtils.js | 4 ++-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/js/controllers/transactions.js b/js/controllers/transactions.js index 7f15c02df..7dd03f52b 100644 --- a/js/controllers/transactions.js +++ b/js/controllers/transactions.js @@ -4,6 +4,8 @@ var bitcore = require('bitcore'); angular.module('copayApp.controllers').controller('TransactionsController', function($scope, $rootScope, $timeout, controllerUtils, notification) { + var w = $rootScope.wallet; + $scope.title = 'Transactions'; $scope.loading = false; $scope.lastShowed = false; @@ -12,7 +14,7 @@ angular.module('copayApp.controllers').controller('TransactionsController', $scope.txpItemsPerPage = 4; $scope.blockchain_txs = []; - var satToUnit = 1 / config.unitToSatoshi; + var satToUnit = 1 / w.settings.unitToSatoshi; $scope.update = function() { $scope.loading = true; diff --git a/js/directives.js b/js/directives.js index e8024cab5..82704b104 100644 --- a/js/directives.js +++ b/js/directives.js @@ -47,13 +47,14 @@ angular.module('copayApp.directives') .directive('enoughAmount', ['$rootScope', function($rootScope) { var bitcore = require('bitcore'); + var w = $rootScope.wallet; var feeSat = Number(bitcore.TransactionBuilder.FEE_PER_1000B_SAT); return { require: 'ngModel', link: function(scope, element, attrs, ctrl) { var val = function(value) { - var availableBalanceNum = Number(($rootScope.availableBalance * config.unitToSatoshi).toFixed(0)); - var vNum = Number((value * config.unitToSatoshi).toFixed(0)); + var availableBalanceNum = Number(($rootScope.availableBalance * w.settings.unitToSatoshi).toFixed(0)); + var vNum = Number((value * w.settings.unitToSatoshi).toFixed(0)); if (typeof vNum == "number" && vNum > 0) { vNum = vNum + feeSat; diff --git a/js/services/controllerUtils.js b/js/services/controllerUtils.js index ba3b6da98..899348ed4 100644 --- a/js/services/controllerUtils.js +++ b/js/services/controllerUtils.js @@ -175,7 +175,7 @@ angular.module('copayApp.services') w.getBalance(function(err, balanceSat, balanceByAddrSat, safeBalanceSat) { if (err) throw err; - var satToUnit = 1 / config.unitToSatoshi; + var satToUnit = 1 / w.settings.unitToSatoshi; var COIN = bitcore.util.COIN; $rootScope.totalBalance = balanceSat * satToUnit; @@ -210,7 +210,7 @@ angular.module('copayApp.services') if (!w) return; opts = opts || $rootScope.txsOpts || {}; - var satToUnit = 1 / config.unitToSatoshi; + var satToUnit = 1 / w.settings.unitToSatoshi; var myCopayerId = w.getMyCopayerId(); var pendingForUs = 0; var inT = w.getTxProposals().sort(function(t1, t2) { From 09ec6f04bbe0b9d9f73759abe5b95e0dd50c562c Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Thu, 4 Sep 2014 11:19:12 -0300 Subject: [PATCH 018/191] settings: fix references to alternativeName --- test/mocks/FakeWallet.js | 1 + test/unit/controllers/controllersSpec.js | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/test/mocks/FakeWallet.js b/test/mocks/FakeWallet.js index ee2621a1e..e4a7bc8d7 100644 --- a/test/mocks/FakeWallet.js +++ b/test/mocks/FakeWallet.js @@ -42,6 +42,7 @@ var FakeWallet = function() { }; this.privateKey = new FakePrivateKey(); + this.settings = {}; }; FakeWallet.prototype.createTx = function(toAddress, amountSatStr, comment, opts, cb) { diff --git a/test/unit/controllers/controllersSpec.js b/test/unit/controllers/controllersSpec.js index abd154840..be9e9553d 100644 --- a/test/unit/controllers/controllersSpec.js +++ b/test/unit/controllers/controllersSpec.js @@ -139,8 +139,8 @@ describe("Unit: Controllers", function() { scope = $rootScope.$new(); scope.rateService = rateService; $rootScope.wallet = new FakeWallet(walletConfig); - config.alternativeName = 'lol currency'; - config.alternativeIsoCode = 'LOL'; + $rootScope.wallet.settings.alternativeName = 'lol currency'; + $rootScope.wallet.settings.alternativeIsoCode = 'LOL'; var element = angular.element( '' + '' + From a048f8eed5a8e7b9a805278a83c3320d88a3f23b Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Thu, 4 Sep 2014 11:59:26 -0300 Subject: [PATCH 019/191] settings: fix references to alternativeIsoCode --- js/services/controllerUtils.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/js/services/controllerUtils.js b/js/services/controllerUtils.js index 899348ed4..e5940d904 100644 --- a/js/services/controllerUtils.js +++ b/js/services/controllerUtils.js @@ -195,9 +195,9 @@ angular.module('copayApp.services') $rootScope.updatingBalance = false; rateService.whenAvailable(function() { - $rootScope.totalBalanceAlternative = rateService.toFiat(balanceSat, config.alternativeIsoCode); - $rootScope.alternativeIsoCode = config.alternativeIsoCode; - $rootScope.lockedBalanceAlternative = rateService.toFiat(balanceSat - safeBalanceSat, config.alternativeIsoCode); + $rootScope.totalBalanceAlternative = rateService.toFiat(balanceSat, w.settings.alternativeIsoCode); + $rootScope.alternativeIsoCode = w.settings.alternativeIsoCode; + $rootScope.lockedBalanceAlternative = rateService.toFiat(balanceSat - safeBalanceSat, w.settings.alternativeIsoCode); return cb ? cb() : null; From 3effa3d0b191da8cce0cbd8c99a1c65cf07fa8b0 Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Thu, 4 Sep 2014 16:13:30 -0300 Subject: [PATCH 020/191] settings: it works --- js/models/core/Wallet.js | 18 +++++++++++++++++ js/models/core/WalletFactory.js | 34 +++++++++++++++------------------ 2 files changed, 33 insertions(+), 19 deletions(-) diff --git a/js/models/core/Wallet.js b/js/models/core/Wallet.js index 17f1d09cb..eba2518c6 100644 --- a/js/models/core/Wallet.js +++ b/js/models/core/Wallet.js @@ -112,6 +112,21 @@ Wallet.builderOpts = { feeSat: undefined, }; +/** + * @desc static list with persisted properties of a wallet. + * These are the properties that get stored/read from localstorage + */ +Wallet.PERSISTED_PROPERTIES = [ + 'opts', + 'settings', + 'publicKeyRing', + 'txProposals', + 'privateKey', + 'addressBook', + 'backupOffered', + 'lastTimestamp', +]; + /** * @desc Retrieve a random id for the wallet * @TODO: Discuss changing to a UUID @@ -175,6 +190,7 @@ Wallet.prototype._onIndexes = function(senderId, data) { Wallet.prototype.changeSettings = function(settings) { console.log(settings); this.settings = settings; + this.store(); }; /** @@ -818,6 +834,8 @@ Wallet.prototype.toObj = function() { addressBook: this.addressBook, lastTimestamp: this.lastTimestamp, }; + console.dir(walletObj); + console.trace(); return walletObj; }; diff --git a/js/models/core/WalletFactory.js b/js/models/core/WalletFactory.js index 9f052e8f6..e205896e6 100644 --- a/js/models/core/WalletFactory.js +++ b/js/models/core/WalletFactory.js @@ -83,13 +83,13 @@ WalletFactory.prototype.fromObj = function(obj, skipFields) { obj.opts.reconnectDelay = this.walletDefaults.reconnectDelay; // this is only used if private key or public key ring is skipped - obj.opts.networkName = this.networkName; + obj.opts.networkName = this.networkName; skipFields = skipFields || []; - skipFields.forEach(function(k){ + skipFields.forEach(function(k) { if (obj[k]) { delete obj[k]; - } else + } else throw new Error('unknown field:' + k); }); @@ -146,13 +146,9 @@ WalletFactory.prototype.read = function(walletId, skipFields) { var s = this.storage; obj.id = walletId; - obj.opts = s.get(walletId, 'opts'); - obj.publicKeyRing = s.get(walletId, 'publicKeyRing'); - obj.txProposals = s.get(walletId, 'txProposals'); - obj.privateKey = s.get(walletId, 'privateKey'); - obj.addressBook = s.get(walletId, 'addressBook'); - obj.backupOffered = s.get(walletId, 'backupOffered'); - obj.lastTimestamp = s.get(walletId, 'lastTimestamp'); + _.each(Wallet.PERSISTED_PROPERTIES, function(value) { + obj[value] = s.get(walletId, value); + }); var w = this.fromObj(obj, skipFields); return w; @@ -185,7 +181,7 @@ WalletFactory.prototype.create = function(opts) { networkName: this.networkName, }; - if (opts.privateKeyHex && opts.privateKeyHex.length>1) { + if (opts.privateKeyHex && opts.privateKeyHex.length > 1) { privOpts.extendedPrivateKeyString = opts.privateKeyHex; } @@ -243,9 +239,9 @@ WalletFactory.prototype._checkVersion = function(inVersion) { //We only check for major version differences if (thisV0 < inV0) { throw new Error('Major difference in software versions' + - '. Received:' + inVersion + - '. Current version:' + this.version + - '. Aborting.'); + '. Received:' + inVersion + + '. Current version:' + this.version + + '. Aborting.'); } }; @@ -269,7 +265,7 @@ WalletFactory.prototype._checkNetwork = function(inNetworkName) { WalletFactory.prototype.open = function(walletId, passphrase) { this.storage._setPassphrase(passphrase); var w = this.read(walletId); - if (w) + if (w) w.store(); this.storage.setLastOpened(walletId); @@ -343,7 +339,7 @@ WalletFactory.prototype.joinCreateSession = function(secret, nickname, passphras networkName: this.networkName, }; - if (privateHex && privateHex.length>1) { + if (privateHex && privateHex.length > 1) { privOpts.extendedPrivateKeyString = privateHex; } @@ -354,7 +350,7 @@ WalletFactory.prototype.joinCreateSession = function(secret, nickname, passphras copayerId: privateKey.getId(), privkey: privateKey.getIdPriv(), key: privateKey.getIdKey(), - secretNumber : s.secretNumber, + secretNumber: s.secretNumber, }; self.network.cleanUp(); @@ -364,12 +360,12 @@ WalletFactory.prototype.joinCreateSession = function(secret, nickname, passphras connectedOnce = true; }); - self.network.on('serverError', function() { + self.network.on('serverError', function() { return cb('joinError'); }); self.network.start(opts, function() { - self.network.greet(s.pubKey,opts.secretNumber); + self.network.greet(s.pubKey, opts.secretNumber); self.network.on('data', function(sender, data) { if (data.type === 'walletId') { if (data.networkName !== self.networkName) { From 4dffcccf19eccee78cd47db16959a5845b3b7de7 Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Thu, 4 Sep 2014 16:57:07 -0300 Subject: [PATCH 021/191] settings: works with 2-3 wallet --- js/controllers/more.js | 1 + js/models/core/Wallet.js | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/js/controllers/more.js b/js/controllers/more.js index cf619b6a9..5bd705d90 100644 --- a/js/controllers/more.js +++ b/js/controllers/more.js @@ -56,6 +56,7 @@ angular.module('copayApp.controllers').controller('MoreController', alternativeName: $scope.selectedAlternative.name, alternativeIsoCode: $scope.selectedAlternative.isoCode, }); + controllerUtils.updateBalance(); }; diff --git a/js/models/core/Wallet.js b/js/models/core/Wallet.js index eba2518c6..5fe1611da 100644 --- a/js/models/core/Wallet.js +++ b/js/models/core/Wallet.js @@ -834,8 +834,6 @@ Wallet.prototype.toObj = function() { addressBook: this.addressBook, lastTimestamp: this.lastTimestamp, }; - console.dir(walletObj); - console.trace(); return walletObj; }; From 1d0f12f4cb0585b1ed8cdf0d538aef99129df2d0 Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Fri, 5 Sep 2014 14:15:10 -0300 Subject: [PATCH 022/191] settings: fix test 1 --- test/test.WalletFactory.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/test/test.WalletFactory.js b/test/test.WalletFactory.js index d6cd93ac0..59c6dd717 100644 --- a/test/test.WalletFactory.js +++ b/test/test.WalletFactory.js @@ -201,8 +201,8 @@ describe('WalletFactory model', function() { }); it('support old index schema: #fromObj #toObj round trip', function() { - var o = '{"opts":{"id":"dbfe10c3fae71cea","spendUnconfirmed":1,"requiredCopayers":3,"totalCopayers":5,"version":"0.0.5"},"networkNonce":"0000000000000001","networkNonces":[],"publicKeyRing":{"walletId":"dbfe10c3fae71cea","networkName":"testnet","requiredCopayers":3,"totalCopayers":5,"indexes":{"changeIndex":0,"receiveIndex":0},"copayersBackup":[],"copayersExtPubKeys":["tpubD6NzVbkrYhZ4YGK8ZhZ8WVeBXNAAoTYjjpw9twCPiNGrGQYFktP3iVQkKmZNiFnUcAFMJRxJVJF6Nq9MDv2kiRceExJaHFbxUCGUiRhmy97","tpubD6NzVbkrYhZ4YKGDJkzWdQsQV3AcFemaQKiwNhV4RL8FHnBFvinidGdQtP8RKj3h34E65RkdtxjrggZYqsEwJ8RhhN2zz9VrjLnrnwbXYNc","tpubD6NzVbkrYhZ4YkDiewjb32Pp3Sz9WK2jpp37KnL7RCrHAyPpnLfgdfRnTdpn6DTWmPS7niywfgWiT42aJb1J6CjWVNmkgsMCxuw7j9DaGKB","tpubD6NzVbkrYhZ4XEtUAz4UUTWbprewbLTaMhR8NUvSJUEAh4Sidxr6rRPFdqqVRR73btKf13wUjds2i8vVCNo8sbKrAnyoTr3o5Y6QSbboQjk","tpubD6NzVbkrYhZ4Yj9AAt6xUVuGPVd8jXCrEE6V2wp7U3PFh8jYYvVad31b4VUXEYXzSnkco4fktu8r4icBsB2t3pCR3WnhVLedY2hxGcPFLKD"],"nicknameFor":{}},"txProposals":{"txps":[],"walletId":"dbfe10c3fae71cea","networkName":"testnet"},"privateKey":{"extendedPrivateKeyString":"tprv8ZgxMBicQKsPeoHLg3tY75z4xLeEe8MqAXLNcRA6J6UTRvHV8VZTXznt9eoTmSk1fwSrwZtMhY3XkNsceJ14h6sCXHSWinRqMSSbY8tfhHi","networkName":"testnet"},"addressBook":{}}'; - var o2 = '{"opts":{"id":"dbfe10c3fae71cea","spendUnconfirmed":1,"requiredCopayers":3,"totalCopayers":5,"version":"0.0.5"},"networkNonce":"0000000000000001","networkNonces":[],"publicKeyRing":{"walletId":"dbfe10c3fae71cea","networkName":"testnet","requiredCopayers":3,"totalCopayers":5,"indexes":[{"copayerIndex":2147483647,"changeIndex":0,"receiveIndex":0},{"copayerIndex":0,"changeIndex":0,"receiveIndex":0},{"copayerIndex":1,"changeIndex":0,"receiveIndex":0},{"copayerIndex":2,"changeIndex":0,"receiveIndex":0},{"copayerIndex":3,"changeIndex":0,"receiveIndex":0},{"copayerIndex":4,"changeIndex":0,"receiveIndex":0}],"copayersBackup":[],"copayersExtPubKeys":["tpubD6NzVbkrYhZ4YGK8ZhZ8WVeBXNAAoTYjjpw9twCPiNGrGQYFktP3iVQkKmZNiFnUcAFMJRxJVJF6Nq9MDv2kiRceExJaHFbxUCGUiRhmy97","tpubD6NzVbkrYhZ4YKGDJkzWdQsQV3AcFemaQKiwNhV4RL8FHnBFvinidGdQtP8RKj3h34E65RkdtxjrggZYqsEwJ8RhhN2zz9VrjLnrnwbXYNc","tpubD6NzVbkrYhZ4YkDiewjb32Pp3Sz9WK2jpp37KnL7RCrHAyPpnLfgdfRnTdpn6DTWmPS7niywfgWiT42aJb1J6CjWVNmkgsMCxuw7j9DaGKB","tpubD6NzVbkrYhZ4XEtUAz4UUTWbprewbLTaMhR8NUvSJUEAh4Sidxr6rRPFdqqVRR73btKf13wUjds2i8vVCNo8sbKrAnyoTr3o5Y6QSbboQjk","tpubD6NzVbkrYhZ4Yj9AAt6xUVuGPVd8jXCrEE6V2wp7U3PFh8jYYvVad31b4VUXEYXzSnkco4fktu8r4icBsB2t3pCR3WnhVLedY2hxGcPFLKD"],"nicknameFor":{}},"txProposals":{"txps":[],"walletId":"dbfe10c3fae71cea","networkName":"testnet"},"privateKey":{"extendedPrivateKeyString":"tprv8ZgxMBicQKsPeoHLg3tY75z4xLeEe8MqAXLNcRA6J6UTRvHV8VZTXznt9eoTmSk1fwSrwZtMhY3XkNsceJ14h6sCXHSWinRqMSSbY8tfhHi","networkName":"testnet"},"addressBook":{}}'; + var o = '{"opts":{"id":"dbfe10c3fae71cea","spendUnconfirmed":1,"requiredCopayers":3,"totalCopayers":5,"version":"0.0.5"},"networkNonce":"0000000000000001","networkNonces":[],"publicKeyRing":{"walletId":"dbfe10c3fae71cea","networkName":"testnet","requiredCopayers":3,"totalCopayers":5,"indexes":{"changeIndex":0,"receiveIndex":0},"copayersBackup":[],"copayersExtPubKeys":["tpubD6NzVbkrYhZ4YGK8ZhZ8WVeBXNAAoTYjjpw9twCPiNGrGQYFktP3iVQkKmZNiFnUcAFMJRxJVJF6Nq9MDv2kiRceExJaHFbxUCGUiRhmy97","tpubD6NzVbkrYhZ4YKGDJkzWdQsQV3AcFemaQKiwNhV4RL8FHnBFvinidGdQtP8RKj3h34E65RkdtxjrggZYqsEwJ8RhhN2zz9VrjLnrnwbXYNc","tpubD6NzVbkrYhZ4YkDiewjb32Pp3Sz9WK2jpp37KnL7RCrHAyPpnLfgdfRnTdpn6DTWmPS7niywfgWiT42aJb1J6CjWVNmkgsMCxuw7j9DaGKB","tpubD6NzVbkrYhZ4XEtUAz4UUTWbprewbLTaMhR8NUvSJUEAh4Sidxr6rRPFdqqVRR73btKf13wUjds2i8vVCNo8sbKrAnyoTr3o5Y6QSbboQjk","tpubD6NzVbkrYhZ4Yj9AAt6xUVuGPVd8jXCrEE6V2wp7U3PFh8jYYvVad31b4VUXEYXzSnkco4fktu8r4icBsB2t3pCR3WnhVLedY2hxGcPFLKD"],"nicknameFor":{}},"txProposals":{"txps":[],"walletId":"dbfe10c3fae71cea","networkName":"testnet"},"privateKey":{"extendedPrivateKeyString":"tprv8ZgxMBicQKsPeoHLg3tY75z4xLeEe8MqAXLNcRA6J6UTRvHV8VZTXznt9eoTmSk1fwSrwZtMhY3XkNsceJ14h6sCXHSWinRqMSSbY8tfhHi","networkName":"testnet"},"addressBook":{},"settings":{"unitName":"BTC","unitToSatoshi":100000000,"unitDecimals":8,"alternativeName":"Argentine Peso","alternativeIsoCode":"ARS"}}'; + var o2 = '{"opts":{"id":"dbfe10c3fae71cea","spendUnconfirmed":1,"requiredCopayers":3,"totalCopayers":5,"version":"0.0.5"},"networkNonce":"0000000000000001","networkNonces":[],"publicKeyRing":{"walletId":"dbfe10c3fae71cea","networkName":"testnet","requiredCopayers":3,"totalCopayers":5,"indexes":[{"copayerIndex":2147483647,"changeIndex":0,"receiveIndex":0},{"copayerIndex":0,"changeIndex":0,"receiveIndex":0},{"copayerIndex":1,"changeIndex":0,"receiveIndex":0},{"copayerIndex":2,"changeIndex":0,"receiveIndex":0},{"copayerIndex":3,"changeIndex":0,"receiveIndex":0},{"copayerIndex":4,"changeIndex":0,"receiveIndex":0}],"copayersBackup":[],"copayersExtPubKeys":["tpubD6NzVbkrYhZ4YGK8ZhZ8WVeBXNAAoTYjjpw9twCPiNGrGQYFktP3iVQkKmZNiFnUcAFMJRxJVJF6Nq9MDv2kiRceExJaHFbxUCGUiRhmy97","tpubD6NzVbkrYhZ4YKGDJkzWdQsQV3AcFemaQKiwNhV4RL8FHnBFvinidGdQtP8RKj3h34E65RkdtxjrggZYqsEwJ8RhhN2zz9VrjLnrnwbXYNc","tpubD6NzVbkrYhZ4YkDiewjb32Pp3Sz9WK2jpp37KnL7RCrHAyPpnLfgdfRnTdpn6DTWmPS7niywfgWiT42aJb1J6CjWVNmkgsMCxuw7j9DaGKB","tpubD6NzVbkrYhZ4XEtUAz4UUTWbprewbLTaMhR8NUvSJUEAh4Sidxr6rRPFdqqVRR73btKf13wUjds2i8vVCNo8sbKrAnyoTr3o5Y6QSbboQjk","tpubD6NzVbkrYhZ4Yj9AAt6xUVuGPVd8jXCrEE6V2wp7U3PFh8jYYvVad31b4VUXEYXzSnkco4fktu8r4icBsB2t3pCR3WnhVLedY2hxGcPFLKD"],"nicknameFor":{}},"txProposals":{"txps":[],"walletId":"dbfe10c3fae71cea","networkName":"testnet"},"privateKey":{"extendedPrivateKeyString":"tprv8ZgxMBicQKsPeoHLg3tY75z4xLeEe8MqAXLNcRA6J6UTRvHV8VZTXznt9eoTmSk1fwSrwZtMhY3XkNsceJ14h6sCXHSWinRqMSSbY8tfhHi","networkName":"testnet"},"addressBook":{},"settings":{"unitName":"BTC","unitToSatoshi":100000000,"unitDecimals":8,"alternativeName":"Argentine Peso","alternativeIsoCode":"ARS"}}'; var wf = new WalletFactory(config, '0.0.5'); var w = wf.fromObj(JSON.parse(o)); @@ -213,7 +213,6 @@ describe('WalletFactory model', function() { should.exist(w.txProposals.toObj); should.exist(w.privateKey.toObj); - // var expected = JSON.parse(o2.replace(/cosigner/g, 'copayerIndex')); assertObjectEqual(w.toObj(), expected); }); From aba883ed2d7d4cf6a181c4901d776cde16015d7a Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Fri, 5 Sep 2014 14:19:06 -0300 Subject: [PATCH 023/191] settings: fix test spelling --- test/test.WalletFactory.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test.WalletFactory.js b/test/test.WalletFactory.js index 59c6dd717..7b4e9dbaf 100644 --- a/test/test.WalletFactory.js +++ b/test/test.WalletFactory.js @@ -78,7 +78,7 @@ function assertObjectEqual(a, b, msg) { var orderedA = reconstructObject(a, getKeys(a).sort()), orderedB = reconstructObject(b, getKeys(b).sort()); - // compare as strings for diff tolls to show us the difference + // compare as strings for diff tools to show us the difference JSON.stringify(orderedA).should.equal(JSON.stringify(orderedB), msg) } } From 6a9ad9c01e7044083ae767f175cdb0ba183d2780 Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Fri, 5 Sep 2014 14:25:43 -0300 Subject: [PATCH 024/191] settings: fix test 2 --- test/test.WalletFactory.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/test/test.WalletFactory.js b/test/test.WalletFactory.js index 7b4e9dbaf..4559a5361 100644 --- a/test/test.WalletFactory.js +++ b/test/test.WalletFactory.js @@ -201,11 +201,11 @@ describe('WalletFactory model', function() { }); it('support old index schema: #fromObj #toObj round trip', function() { - var o = '{"opts":{"id":"dbfe10c3fae71cea","spendUnconfirmed":1,"requiredCopayers":3,"totalCopayers":5,"version":"0.0.5"},"networkNonce":"0000000000000001","networkNonces":[],"publicKeyRing":{"walletId":"dbfe10c3fae71cea","networkName":"testnet","requiredCopayers":3,"totalCopayers":5,"indexes":{"changeIndex":0,"receiveIndex":0},"copayersBackup":[],"copayersExtPubKeys":["tpubD6NzVbkrYhZ4YGK8ZhZ8WVeBXNAAoTYjjpw9twCPiNGrGQYFktP3iVQkKmZNiFnUcAFMJRxJVJF6Nq9MDv2kiRceExJaHFbxUCGUiRhmy97","tpubD6NzVbkrYhZ4YKGDJkzWdQsQV3AcFemaQKiwNhV4RL8FHnBFvinidGdQtP8RKj3h34E65RkdtxjrggZYqsEwJ8RhhN2zz9VrjLnrnwbXYNc","tpubD6NzVbkrYhZ4YkDiewjb32Pp3Sz9WK2jpp37KnL7RCrHAyPpnLfgdfRnTdpn6DTWmPS7niywfgWiT42aJb1J6CjWVNmkgsMCxuw7j9DaGKB","tpubD6NzVbkrYhZ4XEtUAz4UUTWbprewbLTaMhR8NUvSJUEAh4Sidxr6rRPFdqqVRR73btKf13wUjds2i8vVCNo8sbKrAnyoTr3o5Y6QSbboQjk","tpubD6NzVbkrYhZ4Yj9AAt6xUVuGPVd8jXCrEE6V2wp7U3PFh8jYYvVad31b4VUXEYXzSnkco4fktu8r4icBsB2t3pCR3WnhVLedY2hxGcPFLKD"],"nicknameFor":{}},"txProposals":{"txps":[],"walletId":"dbfe10c3fae71cea","networkName":"testnet"},"privateKey":{"extendedPrivateKeyString":"tprv8ZgxMBicQKsPeoHLg3tY75z4xLeEe8MqAXLNcRA6J6UTRvHV8VZTXznt9eoTmSk1fwSrwZtMhY3XkNsceJ14h6sCXHSWinRqMSSbY8tfhHi","networkName":"testnet"},"addressBook":{},"settings":{"unitName":"BTC","unitToSatoshi":100000000,"unitDecimals":8,"alternativeName":"Argentine Peso","alternativeIsoCode":"ARS"}}'; - var o2 = '{"opts":{"id":"dbfe10c3fae71cea","spendUnconfirmed":1,"requiredCopayers":3,"totalCopayers":5,"version":"0.0.5"},"networkNonce":"0000000000000001","networkNonces":[],"publicKeyRing":{"walletId":"dbfe10c3fae71cea","networkName":"testnet","requiredCopayers":3,"totalCopayers":5,"indexes":[{"copayerIndex":2147483647,"changeIndex":0,"receiveIndex":0},{"copayerIndex":0,"changeIndex":0,"receiveIndex":0},{"copayerIndex":1,"changeIndex":0,"receiveIndex":0},{"copayerIndex":2,"changeIndex":0,"receiveIndex":0},{"copayerIndex":3,"changeIndex":0,"receiveIndex":0},{"copayerIndex":4,"changeIndex":0,"receiveIndex":0}],"copayersBackup":[],"copayersExtPubKeys":["tpubD6NzVbkrYhZ4YGK8ZhZ8WVeBXNAAoTYjjpw9twCPiNGrGQYFktP3iVQkKmZNiFnUcAFMJRxJVJF6Nq9MDv2kiRceExJaHFbxUCGUiRhmy97","tpubD6NzVbkrYhZ4YKGDJkzWdQsQV3AcFemaQKiwNhV4RL8FHnBFvinidGdQtP8RKj3h34E65RkdtxjrggZYqsEwJ8RhhN2zz9VrjLnrnwbXYNc","tpubD6NzVbkrYhZ4YkDiewjb32Pp3Sz9WK2jpp37KnL7RCrHAyPpnLfgdfRnTdpn6DTWmPS7niywfgWiT42aJb1J6CjWVNmkgsMCxuw7j9DaGKB","tpubD6NzVbkrYhZ4XEtUAz4UUTWbprewbLTaMhR8NUvSJUEAh4Sidxr6rRPFdqqVRR73btKf13wUjds2i8vVCNo8sbKrAnyoTr3o5Y6QSbboQjk","tpubD6NzVbkrYhZ4Yj9AAt6xUVuGPVd8jXCrEE6V2wp7U3PFh8jYYvVad31b4VUXEYXzSnkco4fktu8r4icBsB2t3pCR3WnhVLedY2hxGcPFLKD"],"nicknameFor":{}},"txProposals":{"txps":[],"walletId":"dbfe10c3fae71cea","networkName":"testnet"},"privateKey":{"extendedPrivateKeyString":"tprv8ZgxMBicQKsPeoHLg3tY75z4xLeEe8MqAXLNcRA6J6UTRvHV8VZTXznt9eoTmSk1fwSrwZtMhY3XkNsceJ14h6sCXHSWinRqMSSbY8tfhHi","networkName":"testnet"},"addressBook":{},"settings":{"unitName":"BTC","unitToSatoshi":100000000,"unitDecimals":8,"alternativeName":"Argentine Peso","alternativeIsoCode":"ARS"}}'; + var o3 = '{"opts":{"id":"dbfe10c3fae71cea","spendUnconfirmed":1,"requiredCopayers":3,"totalCopayers":5,"version":"0.0.5"},"networkNonce":"0000000000000001","networkNonces":[],"publicKeyRing":{"walletId":"dbfe10c3fae71cea","networkName":"testnet","requiredCopayers":3,"totalCopayers":5,"indexes":{"changeIndex":0,"receiveIndex":0},"copayersBackup":[],"copayersExtPubKeys":["tpubD6NzVbkrYhZ4YGK8ZhZ8WVeBXNAAoTYjjpw9twCPiNGrGQYFktP3iVQkKmZNiFnUcAFMJRxJVJF6Nq9MDv2kiRceExJaHFbxUCGUiRhmy97","tpubD6NzVbkrYhZ4YKGDJkzWdQsQV3AcFemaQKiwNhV4RL8FHnBFvinidGdQtP8RKj3h34E65RkdtxjrggZYqsEwJ8RhhN2zz9VrjLnrnwbXYNc","tpubD6NzVbkrYhZ4YkDiewjb32Pp3Sz9WK2jpp37KnL7RCrHAyPpnLfgdfRnTdpn6DTWmPS7niywfgWiT42aJb1J6CjWVNmkgsMCxuw7j9DaGKB","tpubD6NzVbkrYhZ4XEtUAz4UUTWbprewbLTaMhR8NUvSJUEAh4Sidxr6rRPFdqqVRR73btKf13wUjds2i8vVCNo8sbKrAnyoTr3o5Y6QSbboQjk","tpubD6NzVbkrYhZ4Yj9AAt6xUVuGPVd8jXCrEE6V2wp7U3PFh8jYYvVad31b4VUXEYXzSnkco4fktu8r4icBsB2t3pCR3WnhVLedY2hxGcPFLKD"],"nicknameFor":{}},"txProposals":{"txps":[],"walletId":"dbfe10c3fae71cea","networkName":"testnet"},"privateKey":{"extendedPrivateKeyString":"tprv8ZgxMBicQKsPeoHLg3tY75z4xLeEe8MqAXLNcRA6J6UTRvHV8VZTXznt9eoTmSk1fwSrwZtMhY3XkNsceJ14h6sCXHSWinRqMSSbY8tfhHi","networkName":"testnet"},"addressBook":{},"settings":{"unitName":"BTC","unitToSatoshi":100000000,"unitDecimals":8,"alternativeName":"Argentine Peso","alternativeIsoCode":"ARS"}}'; + var o4 = '{"opts":{"id":"dbfe10c3fae71cea","spendUnconfirmed":1,"requiredCopayers":3,"totalCopayers":5,"version":"0.0.5"},"networkNonce":"0000000000000001","networkNonces":[],"publicKeyRing":{"walletId":"dbfe10c3fae71cea","networkName":"testnet","requiredCopayers":3,"totalCopayers":5,"indexes":[{"copayerIndex":2147483647,"changeIndex":0,"receiveIndex":0},{"copayerIndex":0,"changeIndex":0,"receiveIndex":0},{"copayerIndex":1,"changeIndex":0,"receiveIndex":0},{"copayerIndex":2,"changeIndex":0,"receiveIndex":0},{"copayerIndex":3,"changeIndex":0,"receiveIndex":0},{"copayerIndex":4,"changeIndex":0,"receiveIndex":0}],"copayersBackup":[],"copayersExtPubKeys":["tpubD6NzVbkrYhZ4YGK8ZhZ8WVeBXNAAoTYjjpw9twCPiNGrGQYFktP3iVQkKmZNiFnUcAFMJRxJVJF6Nq9MDv2kiRceExJaHFbxUCGUiRhmy97","tpubD6NzVbkrYhZ4YKGDJkzWdQsQV3AcFemaQKiwNhV4RL8FHnBFvinidGdQtP8RKj3h34E65RkdtxjrggZYqsEwJ8RhhN2zz9VrjLnrnwbXYNc","tpubD6NzVbkrYhZ4YkDiewjb32Pp3Sz9WK2jpp37KnL7RCrHAyPpnLfgdfRnTdpn6DTWmPS7niywfgWiT42aJb1J6CjWVNmkgsMCxuw7j9DaGKB","tpubD6NzVbkrYhZ4XEtUAz4UUTWbprewbLTaMhR8NUvSJUEAh4Sidxr6rRPFdqqVRR73btKf13wUjds2i8vVCNo8sbKrAnyoTr3o5Y6QSbboQjk","tpubD6NzVbkrYhZ4Yj9AAt6xUVuGPVd8jXCrEE6V2wp7U3PFh8jYYvVad31b4VUXEYXzSnkco4fktu8r4icBsB2t3pCR3WnhVLedY2hxGcPFLKD"],"nicknameFor":{}},"txProposals":{"txps":[],"walletId":"dbfe10c3fae71cea","networkName":"testnet"},"privateKey":{"extendedPrivateKeyString":"tprv8ZgxMBicQKsPeoHLg3tY75z4xLeEe8MqAXLNcRA6J6UTRvHV8VZTXznt9eoTmSk1fwSrwZtMhY3XkNsceJ14h6sCXHSWinRqMSSbY8tfhHi","networkName":"testnet"},"addressBook":{},"settings":{"unitName":"BTC","unitToSatoshi":100000000,"unitDecimals":8,"alternativeName":"Argentine Peso","alternativeIsoCode":"ARS"}}'; var wf = new WalletFactory(config, '0.0.5'); - var w = wf.fromObj(JSON.parse(o)); + var w = wf.fromObj(JSON.parse(o3)); should.exist(w); w.id.should.equal("dbfe10c3fae71cea"); @@ -213,7 +213,7 @@ describe('WalletFactory model', function() { should.exist(w.txProposals.toObj); should.exist(w.privateKey.toObj); - var expected = JSON.parse(o2.replace(/cosigner/g, 'copayerIndex')); + var expected = JSON.parse(o4.replace(/cosigner/g, 'copayerIndex')); assertObjectEqual(w.toObj(), expected); }); @@ -485,7 +485,8 @@ describe('WalletFactory model', function() { }); -var o = '{"opts":{"id":"dbfe10c3fae71cea","spendUnconfirmed":1,"requiredCopayers":3,"totalCopayers":5,"version":"0.0.5"},"networkNonce":"0000000000000001","networkNonces":[],"publicKeyRing":{"walletId":"dbfe10c3fae71cea","networkName":"testnet","requiredCopayers":3,"totalCopayers":5,"indexes":[{"copayerIndex":2,"changeIndex":0,"receiveIndex":0}],"copayersBackup":[],"copayersExtPubKeys":["tpubD6NzVbkrYhZ4YGK8ZhZ8WVeBXNAAoTYjjpw9twCPiNGrGQYFktP3iVQkKmZNiFnUcAFMJRxJVJF6Nq9MDv2kiRceExJaHFbxUCGUiRhmy97","tpubD6NzVbkrYhZ4YKGDJkzWdQsQV3AcFemaQKiwNhV4RL8FHnBFvinidGdQtP8RKj3h34E65RkdtxjrggZYqsEwJ8RhhN2zz9VrjLnrnwbXYNc","tpubD6NzVbkrYhZ4YkDiewjb32Pp3Sz9WK2jpp37KnL7RCrHAyPpnLfgdfRnTdpn6DTWmPS7niywfgWiT42aJb1J6CjWVNmkgsMCxuw7j9DaGKB","tpubD6NzVbkrYhZ4XEtUAz4UUTWbprewbLTaMhR8NUvSJUEAh4Sidxr6rRPFdqqVRR73btKf13wUjds2i8vVCNo8sbKrAnyoTr3o5Y6QSbboQjk","tpubD6NzVbkrYhZ4Yj9AAt6xUVuGPVd8jXCrEE6V2wp7U3PFh8jYYvVad31b4VUXEYXzSnkco4fktu8r4icBsB2t3pCR3WnhVLedY2hxGcPFLKD"],"nicknameFor":{}},"txProposals":{"txps":[],"walletId":"dbfe10c3fae71cea","networkName":"testnet"},"privateKey":{"extendedPrivateKeyString":"tprv8ZgxMBicQKsPeoHLg3tY75z4xLeEe8MqAXLNcRA6J6UTRvHV8VZTXznt9eoTmSk1fwSrwZtMhY3XkNsceJ14h6sCXHSWinRqMSSbY8tfhHi","networkName":"testnet"},"addressBook":{}}'; +var o = '{"opts":{"id":"dbfe10c3fae71cea","spendUnconfirmed":1,"requiredCopayers":3,"totalCopayers":5,"version":"0.0.5"},"networkNonce":"0000000000000001","networkNonces":[],"publicKeyRing":{"walletId":"dbfe10c3fae71cea","networkName":"testnet","requiredCopayers":3,"totalCopayers":5,"indexes":[{"copayerIndex":2,"changeIndex":0,"receiveIndex":0}],"copayersBackup":[],"copayersExtPubKeys":["tpubD6NzVbkrYhZ4YGK8ZhZ8WVeBXNAAoTYjjpw9twCPiNGrGQYFktP3iVQkKmZNiFnUcAFMJRxJVJF6Nq9MDv2kiRceExJaHFbxUCGUiRhmy97","tpubD6NzVbkrYhZ4YKGDJkzWdQsQV3AcFemaQKiwNhV4RL8FHnBFvinidGdQtP8RKj3h34E65RkdtxjrggZYqsEwJ8RhhN2zz9VrjLnrnwbXYNc","tpubD6NzVbkrYhZ4YkDiewjb32Pp3Sz9WK2jpp37KnL7RCrHAyPpnLfgdfRnTdpn6DTWmPS7niywfgWiT42aJb1J6CjWVNmkgsMCxuw7j9DaGKB","tpubD6NzVbkrYhZ4XEtUAz4UUTWbprewbLTaMhR8NUvSJUEAh4Sidxr6rRPFdqqVRR73btKf13wUjds2i8vVCNo8sbKrAnyoTr3o5Y6QSbboQjk","tpubD6NzVbkrYhZ4Yj9AAt6xUVuGPVd8jXCrEE6V2wp7U3PFh8jYYvVad31b4VUXEYXzSnkco4fktu8r4icBsB2t3pCR3WnhVLedY2hxGcPFLKD"],"nicknameFor":{}},"txProposals":{"txps":[],"walletId":"dbfe10c3fae71cea","networkName":"testnet"},"privateKey":{"extendedPrivateKeyString":"tprv8ZgxMBicQKsPeoHLg3tY75z4xLeEe8MqAXLNcRA6J6UTRvHV8VZTXznt9eoTmSk1fwSrwZtMhY3XkNsceJ14h6sCXHSWinRqMSSbY8tfhHi","networkName":"testnet"},"addressBook":{},"settings":{"unitName":"BTC","un itToSatoshi":100000000,"unitDecimals":8,"alternativeName":"Argentine Peso","alternativeIsoCode":"ARS"}}'; +var o2 = '{"opts":{"id":"dbfe10c3fae71cea","spendUnconfirmed":1,"requiredCopayers":3,"totalCopayers":5,"version":"0.0.5"},"networkNonce":"0000000000000001","networkNonces":[],"publicKeyRing":{"walletId":"dbfe10c3fae71cea","networkName":"testnet","requiredCopayers":3,"totalCopayers":5,"indexes":[{"copayerIndex":2147483647,"changeIndex":0,"receiveIndex":0},{"copayerIndex":0,"changeIndex":0,"receiveIndex":0},{"copayerIndex":1,"changeIndex":0,"receiveIndex":0},{"copayerIndex":2,"changeIndex":0,"receiveIndex":0},{"copayerIndex":3,"changeIndex":0,"receiveIndex":0},{"copayerIndex":4,"changeIndex":0,"receiveIndex":0}],"copayersBackup":[],"copayersExtPubKeys":["tpubD6NzVbkrYhZ4YGK8ZhZ8WVeBXNAAoTYjjpw9twCPiNGrGQYFktP3iVQkKmZNiFnUcAFMJRxJVJF6Nq9MDv2kiRceExJaHFbxUCGUiRhmy97","tpubD6NzVbkrYhZ4YKGDJkzWdQsQV3AcFemaQKiwNhV4RL8FHnBFvinidGdQtP8RKj3h34E65RkdtxjrggZYqsEwJ8RhhN2zz9VrjLnrnwbXYNc","tpubD6NzVbkrYhZ4YkDiewjb32Pp3Sz9WK2jpp37KnL7RCrHAyPpnLfgdfRnTdpn6DTWmPS7niywfgWiT42aJb1J6CjWVNmkgsMCxuw7j9DaGKB","tpubD6NzVbkrYhZ4XEtUAz4UUTWbprewbLTaMhR8NUvSJUEAh4Sidxr6rRPFdqqVRR73btKf13wUjds2i8vVCNo8sbKrAnyoTr3o5Y6QSbboQjk","tpubD6NzVbkrYhZ4Yj9AAt6xUVuGPVd8jXCrEE6V2wp7U3PFh8jYYvVad31b4VUXEYXzSnkco4fktu8r4icBsB2t3pCR3WnhVLedY2hxGcPFLKD"],"nicknameFor":{}},"txProposals":{"txps":[],"walletId":"dbfe10c3fae71cea","networkName":"testnet"},"privateKey":{"extendedPrivateKeyString":"tprv8ZgxMBicQKsPeoHLg3tY75z4xLeEe8MqAXLNcRA6J6UTRvHV8VZTXznt9eoTmSk1fwSrwZtMhY3XkNsceJ14h6sCXHSWinRqMSSbY8tfhHi","networkName":"testnet"},"addressBook":{},"settings":{"unitName":"BTC","unitToSatoshi":100000000,"unitDecimals":8,"alternativeName":"Argentine Peso","alternativeIsoCode":"ARS"}}'; var legacyO = '{"opts":{"id":"55d4bd062d32f90a","spendUnconfirmed":true,"requiredCopayers":2,"totalCopayers":2,"name":"xcvzxcv","version":"0.3.2"},"networkNonce":"53d25e8600000009","networkNonces":[],"publicKeyRing":{"walletId":"55d4bd062d32f90a","networkName":"testnet","requiredCopayers":2,"totalCopayers":2,"indexes":[{"copayerIndex":2147483647,"changeIndex":0,"receiveIndex":0},{"copayerIndex":0,"changeIndex":4,"receiveIndex":2},{"copayerIndex":1,"changeIndex":5,"receiveIndex":2}],"copayersBackup":["02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba","02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5"],"copayersExtPubKeys":["tpubD94LTzAUiW99mpA59nyf6fAHh4xKGmnwbgCV4gU2bRpeN9CRiMSurqme22px5NmJAo6FdcdH883Zu98VbqyhesCJ86kUEjH3Zpufy5FfcaC","tpubDA2U9H6LkRHDRbRxHBp4VTbxPc7JqsvtcLxrE5QJF8z1iT6hMJ1pXSVf57GWRcxXutYvpoXRurDVGsscJauMtnJBkYAWBVExYmm91XQE2zz"],"nicknameFor":{"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":"asdf","02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":"qwerqw"},"publicKeysCache":{"m/0/0/0":["028a4b63f26253f3a8731577b8e1ee480950ad5833ebbf106fe3463bfc07cc3b90","0332efa054c08cb77506a35ee0762cb7156f244566703ec08e433568ec0397bec8"],"m/1/0/0":["0220ad514cf593d0c3905d3bb49bc5767a9410823bf9b77ea5ef2cf1d1016d77a8","02fd42cf66f1dbdc7bbb9ae09aecea72df479ffe5a0c4641301067e331d12e416d"],"m/1/0/1":["0315f7868eaf1f9b7127e3f7e0222c5e473eea003e34700f4758b6873c525d6723","02a2e8ed5e90dd39e3842fc790e06178997dbca319987f365317589e2a71a93658"],"m/0/1/0":["0244a25a0b97b26707fd855c15b046b901be85a3b70a781d0678608e633440eeca","0358cdcbc528ddfb7173b0dab283f702be82546ff031e4a832a7270080cb875959"],"m/0/1/1":["025c9b49bdf17d97bd82ea1b87793082f857247f0f9b999937a166ec994bb1b41f","020389327ee8ae7d0ee3f8187842d23a4070bdd8a27c0bcddd05d80ef39009253d"],"m/1/1/0":["02fd0e7c62b7b58d1ea7bb4cb84d53b019df99d3703a42aed73a2cfa15f3af5d08","0355a15912e76072ef50e6643376b8a9da8422ed4f8ea07b1d84d4989be5a39b2e"],"m/1/1/1":["03bc3e1f4db32efd8eb1fd44a1665938d59628429c67e1e8b7054ab5717f4e6750","03c4c817b633ac31f44f16f390af831d35f7d98744a52a0f23e9598967342255f8"],"m/1/1/2":["02826fe7e9da408480ddeb1d4414c5100b350f862ca718e27122681e1a0ca35077","02bd25af907bb3edbf6b2cd1ea90eaa92cc93ec47bea7d339af44c1d2c05708e99"],"m/0/1/2":["0337a1a70364b94745d6e26d2d28919cf528304f52765f12ef43e3d6da0a6c8dc0","039d83db9aa43e6e00e0304e6971b6079d79dc12d8d55ce2e6fc24a52ba8d41329"],"m/0/0/1":["0359c6d0d0d31f83301169901a6ffad9535f14014b5ab3b43561dbb2436a7b8138","037d06f713f13a11967fd5edca265ff4c77528693a712c482256505693e4890d93"],"m/1/1/3":["02600e5c41670773a213a4cb58c8f2fa3e83840784bc7f0b56925e1075e06632c2","036d01867af5f61371151ef7d9026fa0400a623f6924e404ee0b856625268972f9"],"m/0/1/3":["03e5a9b039b187ca8e065627df402e4a5b196b94198542da7036879de08be63d2d","0304f3e0b70f696d80e5785dc7747d6dcb55ba24c31f2d80bf184b4e582e6b47fc"],"m/1/1/4":["03741afa5bd50d6ba5801064c810fae84f6a4557d6a88ddc8591d0d4eb68a8fc41","0214dd6ce6073b05999fb887098ca6f7e1d0b4fdc0760557786907df353df90d1c"],"m/2147483647/1/0":["033e072a53ea835763a03c66e35c35384736210a1bb7d7ee6d9a3e109e82426b30","02e37b5570c053da8a8ee587be86fc629775c4db890aba2745ccc4e4dcc8c31041"],"m/2147483647/1/1":["0228a6de42ef421c263d1efd9f28d9a7d15a261995028a24eff6b9f1c3fc46e6bf","0226cff885cb0d607cc9cf69a7608316eb3fb2ec344c0c9956246ba776116fc396"],"m/2147483647/1/2":["034fe2a8f0b98445eb5810fe36572ad2f64ed9bf64dc9de624f99c0142cb07c682","02f2c5c758e32293f5c193fd69afadbba83abafb397db01e6f2b447690e900475a"],"m/2147483647/1/3":["02b25ef9434446c51f10678f787e4913de582e34d164bd3b06af7732c5476df1a8","025d51a1efd59bcff22ee2e0af61b21a7ba5f639e20dfdf25690e926005177dd0c"],"m/2147483647/1/4":["03e5734e1d29b2f684d0446b7a2ffbd0ba8952570a502d0d14b1efd8f24b61be53","0258fc28a324848d8d0154e8614815e35c668d274a8f01957bb99aab8dc8f386c0"],"m/2147483647/1/5":["021f9e775246765e1cfba0ae453b4eae6cd4ae5a57a09c319edbe89d4dbbf23be3","02857f66571a1c3eb9e72d22ae88e734c03d448bced4dcfd345c2059468124c741"],"m/2147483647/1/6":["02c072f329391a25255dc6452e5f5220966869dbf736ba8a8c3ae9d273a84bc3fd","030920a8b8e88c4db2871a7df0878a86cf0695f6d96bb50c701c3454f3df25176a"],"m/2147483647/1/7":["036bf329fc19bce10cf1999fae5bfa80290ff7b44776b49c7b0dc9eec6cffcfa21","03955a549875b4f7b9be28b9ff4bcd51ad2bc224430b1634baef890585885d5e1b"],"m/2147483647/1/8":["024879c9c9a261b3141ecfa1c79c4efc25278c844ecd1dcfcb95d9c19581fbdd25","03fb4a5fdb91239df3ccf7f61a5b99e7e72483101e21c9d1ee0d85544e9354c6c7"],"m/2147483647/1/9":["035928a107ec01f78cd586914d5a49710fd42e352b1312e3ad0eeb2c9666fdf8e7","03a54c03093797854829c75357f092356352a109042bbb83bdac20cb4e5eca27ea"],"m/2147483647/1/10":["021e7a3a7efe888c5e820b5cf0f03317b2b4bf438d8563449aeb7a77cade97f136","03ec0960b3d1df52ca3cc2c82b7d97063400da4dd051bba2f9bab6cb44aee01efa"],"m/2147483647/1/11":["035d70c26b7f429861f555f7c0d99947411b23b7f95303fb8d5de5b82a95aa30fc","038b922f7024f5446d6b48e5253643543b35c006d90fd37688105c6cefcd8adb8a"],"m/2147483647/1/12":["02158d6503891c6c65a606221dbf5c68d0832288975914007968419939588ecb24","0248264cb1763a3f4de9b34787b4bc5443ec92ef915927494bb9f1c1c0b498c7ca"],"m/2147483647/1/13":["0349965eea38a25ae0c061faeac4c4e57e648bc4c0f059d07b3b8b7962cbc0dde5","0352243d9269565ce2a1ffdd0b8e43a442c6dd1c9edda86eaaf2cba5a4a95c40f1"],"m/2147483647/1/14":["030fa6e3d0c5cedc0581955395c77cbe134c912a47971023b9695332df3f7bb200","03f2cf09e33326fb59bf3f13e6298d2d5d29c9eae3b872e5a851e8d8d77259c883"],"m/2147483647/1/15":["02bf0d45e41339f552df6f8baf4392142921fd38b0f2a4388a905ff6cbacbc278a","03fabe46bb6706a1b8edfd28c046a8891b4530bbe5305080b72b0d08ebdf7b8c0a"],"m/2147483647/1/16":["03a4e3146ed34d6a8af4e4379e6edcff32cb0373ba232b3d746af3052f674133ac","030311b73c6f5c46ddffc0cfce6e5ed0b671d94267d8e52cd8837f2a479916eb91"],"m/2147483647/1/17":["03233df93c762d2f06c7f5f388e4e0a8dbdb13302acba0d2d6995c487d8aec9f2f","024badfdcb7e772ac7fc1c46d3943b07500edbbece105cdeff3eb9e9fcc9f54782"],"m/2147483647/1/18":["0364035475a098e00eb010c500cad3c90af3e81a4bd613144bc9433a150f14718b","028223dc8142154e7477ce000b3dc13e1d15a901553d9b18864c8645b582b38fe6"],"m/2147483647/1/19":["03971b74b4ac4bdaadf636baa4caa82fe5355471ed6ea05a9cbe5fc6c9e4b9db76","0202ebffacd01f83849e5bc5c0e2c317bc5fb2fbcb2d6d4482a5235f9f1308b61a"],"m/0/1/4":["03005ee9ff028c98fd132e531023f2f2b61ff0d26022f979dd98088d2ba167b031","0345ea82e8dfe38277f0c3aee18d2dd93edb63e8663ac83328a7934d2ca57006f6"],"m/0/1/5":["0391bc4990b71d8a3f156ae7107929ed6372b0b4ba8a868253f71ba7189d1efa02","0312a74cf2e7c0dd41897d04fabfd8cc3187b84a28305cfc79315b24e6fe23a6b4"],"m/0/1/6":["021a38c492607ff9684a4fec445e47b5b7100d3ef9e9dc0d0b37c0a646d28d4f77","03ae0b46ab36f97447ebaa53f2b5c8f090f15395378785f2fd285eeba17fbf3f65"],"m/0/1/7":["0308cdec88c1ffe16edc98853d9c08dbd4ba2541ba566668ca17bda19d7eb3481f","02dd622267c2e68287287b8b61724f76fbe84096a56aa5054af92f8fe25380e2d1"],"m/0/1/8":["039647da9ad725836bcb28a3e0497659a28d7749d1416c421a0a01c62d237ee962","022e22aa61eafda0dd8820427f1a06314d352a15ea8645e7ab9b80920017084d82"],"m/0/1/9":["03a4ade946076c6962b70c70ac7fad3a87efb59a1d0a4e32bda13a6d47fe9df961","029a07235aba04ab69526e117d836d5b3fae5cfc8c5e72b10c6d1afd261ccc19f3"],"m/0/1/10":["03c78e9b6493b22790db1acea20df9444e0f9c424fc5756e7a32c290ae01783953","0254c130ee467a96570c9f5ebea89de04f0b1db1686b164f2694339bef8f25dd88"],"m/0/1/11":["03a762c43318ef8d4840fab04c8db73797dc648825fac60f2730b4c76678df1cf3","0212c684a4de8e750ad2dfe2b136370ab9803eca178ed9a27b3990c29b067de35c"],"m/0/1/12":["02702d221f9b15c5cf75ac2f497a6c63e60213087c3d2d3be46768e3ebd238e26e","03ed58580744deb357258e44548212038670769d8d51e385d4fb8414311fd01b52"],"m/0/1/13":["0320e0597b54c62768352f433389cee4725d6094d7bcb5c72265edcc0933829aff","02c5706f11b9a85f3176c572842b7c9812c2195058d24d945bc026b00312740e76"],"m/0/1/14":["02fe43077676b844226d3aaa62e8a86d237710d92f882366944acbde0c8992fcaf","039a6a8662abb8910741cf331320549665e9feb28ca94d1ab6a43c84fa330b94ee"],"m/0/1/15":["0369f99f72847af93d50ab8ee75b6e7e912d26e27be96f6d6b7215cf7daeff7ba5","02521700cc07c953ba5aa586fb0e4795a34dffc68c5fb43e038be3866e40f4daed"],"m/0/1/16":["02f67d1d89bd8fe2f91c5b973cbdacfb4ba440e7656bce284cf73d549625607347","035da9cfac5a803dcb2b283b02a2515a4a1bcbf3d19e0d180aee8fc30193bc0555"],"m/0/1/17":["02c024ec199d240e8d6c66276b94b91071f7cdf2bef540c29d6d18d25de7b1cf7c","02190865f9dafae3f7f05c093463be5632946422ddda0a6fef6904390792516067"],"m/0/1/18":["035ed504d7704ad984a333b8eb0fceb8be043da9284de31ed84d9e68d90c75507d","033303c415b50421732402df00f4baa219f334647a7eb5014b9f8079864d6ab558"],"m/0/1/19":["02ce49fe86b0eee73663b1ee867b16b97c876af26f12764c528a2e6d0eb55ad3d7","03ab969bc81796b88e44c340d854df955fc60ea17ea92db5d3115595d6dec890d8"],"m/0/1/20":["03e2fa915378cbdffa0d919b0fb50c7256ca731b9d571b3365e486893a1d43079c","038d058b895cf084dccfcc9367e4796a5cf4ddceed6c35f6885d75c80119613350"],"m/0/1/21":["02fcb1bf644446b5b42205272af72f0aeab9e92ca29aafa91c5fb69142764017aa","035c5fe5c8811603279a5b72b6c30735d702817db1eab937c622269e28192ffa90"],"m/0/1/22":["03b39d61dc9a504b13ae480049c140dcffa23a6cc9c09d12d6d1f332fee5e18ca5","022929f515c5cf967474322468c3bd945bb6f281225b2c884b465680ef3052c07e"],"m/0/1/23":["03f40b82fe8cacff08879f13c45f443a3dc3ea98e1d75d5f32a19f5e5a8f7a905b","028415ee458e4dcfd440ce969726f3b58ae74fb6cf3995ced099579211e7419844"],"m/1/1/5":["032748a6282e21f571b8c8dd49e775deb83c90fcf88dc4ba81d878536973709c3f","020837cd68f14ce571b335eecd1b6fa0af43e1576dd9721aaca2a8ab639ac6b7cd"],"m/1/1/6":["0337032efb013dc92bb8dccfbdda9f5c28f0039a9c60953d41003d095e9f9778af","03ceed2da6b9603297061dc8eb930112ba726b2ccf5eec67f4866a05ca4049a22b"],"m/1/1/7":["0383c96ac2af7d203f69133b2fab6b68366b5075ad6957fa06759df3b20fbfec70","0311385f79834cedaf2230a48c0f9dc8e794da1869fc595db2518d62debb85579a"],"m/1/1/8":["03efc649680280f4e4df96da923bc88330275004125ebe5483c2f3e05ca52e19a4","02803c02d197d780388259afbd001ae41fa3eb3e2bac9627aff540521c184c3b23"],"m/1/1/9":["03af2fe6aa027a76b42c1c4050a040bfd026ad2daec1bb96a5fe2d026a7df919de","02ce14163047c640228796fb1f72bbe3afb05819ad141598a4f021058a6f79dd3b"],"m/1/1/10":["033770378bd762cf0408e44e4e604bef77e336170428c506949b1a4f1f2963e574","02c58ed43946f699dbd3e36d3e9aab2714cadeb19ecd3a56e4328c50336b4a76cb"],"m/1/1/11":["02898a1545fa19bdca92adc498698d27b86529cd4c08946d9d29604734b86f31af","02b402767a045ede072600924401c0d720000b2ed59fa444bfdbef4a5f1cead745"],"m/1/1/12":["039b8659430be49913e2cd869aa8c99ccf49a13df35837370b792033dadb891483","03264e63df292257cc76babb15d15bef620d1c2f8c3bbc78d6ea02d127e5ee7386"],"m/1/1/13":["02381a559791b8e86bf546e2c718ae63cf24eed0518a58e4d4a4b310adf2cd38fa","02d7f8283a4418d912508901b4a3db0d2103206dfdd74b3c75648671e20ecfd445"],"m/1/1/14":["020376e8c550b7d9faa0b2da947a2a36fab22c6e8190b6f99460b6022017bb97d7","03fbc5299190e6628de28c92aaa12e3a131b21eb7266462c46fbedeb86fa878055"],"m/1/1/15":["027209fd3b0cf7368180a5dbb16b928c997d33fccb78505d48440c7d23eadf5460","03450bfb22858726cd7e228e6733f69457546978a95188565c53e0d1c0d6070ea8"],"m/1/1/16":["03cb355ba04f64293793855121bab5831f84a3a3edf7cd31fccaa6d67c407a4912","028bc897a39c1224610b765a80f4cd8ab79cb37776f58fec9c10ac6f649d1f3c72"],"m/1/1/17":["03f4cb0564d7e2c6b85673503b7954db22779f29a8f3374904573984e318a96bf1","037c11b6ee906d84aa7eed359d758d986d912b6f8e5cbb1acf0982a77b3ef812c4"],"m/1/1/18":["02d2e5798f33f6889472857744316f2d253f25f88379610063f40cfe5798d9858f","0253cefdfe9ca987cbf1c950b6246d5b7a194d8dfad47c3a78dbbc5c1d01511d97"],"m/1/1/19":["0336c325f5aed366ffc10d553f2bfd4d69e66cbe1688d77af14efc8827aea2e318","0378b1b9a6074f9f2ab4fa9ad1e14649c621b0c8124a1b148914d3c10e6ab390c6"],"m/1/1/20":["03ea55740a734689ce778a8c00df8ebf4274c8f66de7d05646fe5c927773ff7f2e","02275b558d49aef955b6dee51a3c0a53f4b076b97bb3f26abcc82540168ec87cac"],"m/1/1/21":["03c77869c9984664eac9c238f4b6d806c9f48ca8a736c48450f398834db2aa915c","02d984f548c7f60c09dad3287cfc48807bc8157123989636c713be61be6a2e9ced"],"m/1/1/22":["03ed7c6a3c854c1f9459891691cc32671402f9e47126919878251e568dbdf353f8","02a113dab22cd9e46967b3fd76b9b9ec1d227d88817a9300e42d332cca2a0877fd"],"m/1/1/23":["02ee186432dcf69fda50a6fdbd94651817d8a271c273a5b70cab3ec4ae77a3753b","02291370aad9de0dac676355ced64e268b0c431a51f42f12d13f5144940fce4285"],"m/1/1/24":["02bf71435e84e66547c8c583d5ba226a5ac4d935e0a9f9603ecd8925c3e847e91a","03578d8657d285a89d9d597632db662cfef9baccfb55c76b1e87948a94fc9de30d"],"m/2147483647/0/0":["02a8425bbe23426219065969f695a6c3e242b24e57226bffdd542be8fd6be968c9","03057a42fdb6569fb1615b173ccb702453db2eac5be4291b82d4511461eafbed87"],"m/2147483647/0/1":["0250c3d3e86e332010c5233c2ec3bc728026002f0037cb3382d6318409b0e70796","02cfac1e7c4c88191201080f8316af52d9faa6ba624a6e160279e9fac4d1cf79a9"],"m/2147483647/0/2":["02a8c266a5b92eb50c8be91f95e4d1ad968b2f57d527377fd642d63fb84474f61a","028cc954ab31bd179ff80b8a05f95430ae534e61b3ff35f5284fa2fbe1832ceccb"],"m/2147483647/0/3":["02f719e1a7ab00ea98611453fb03d44c1da04655bed74af392534d70099039b4c2","03bfa548bfd4718c50bfce173f780eadcfb679d9c0206c91a2fa1879a9cf7558b2"],"m/2147483647/0/4":["0362c0695d397ca26bf47f0e641bb3cfb06ff29ccac2e1d56ded3afcf88b1e688d","02f9d87b05bdb3b9e82f506b43f813041c0e403274adc23d11e5e1651e34b606c2"],"m/2147483647/0/5":["033731323032d4ee08e858fc71f93970444333e183a1d5052e1d08cfb511e262c8","023e12556cef67ade35b7758916b5e1a3ebe074ccd35c5d8eff6b01321f63eb495"],"m/2147483647/0/6":["025d11b90081972bc1c258c9d6f476dfc2f95b69f0e9935322bf9c21deb580ff64","02b065f56a378907354f0738a0ed74f10660c6b5dd68c9f992093b75ce3d7d8b72"],"m/2147483647/0/7":["0210e721e8a35db9d8c855a0d346f60c09208f3be80b39e03af2c29db777332c71","0277f352969fadb1f1835f9a0fa99c6a3c7b6c281be5b2794c88a708eb177ea33d"],"m/2147483647/0/8":["02998d8d41e4215cd2a961a415a3ed0b1f984f1627719a7b102a75864943c4d87b","03d8ed7fc8f68a77f68d3afd007b7aa4c89944195143630ce183f0fa5438f2b559"],"m/2147483647/0/9":["0324fa91737588e4f85937303ce65c3b91b5f2ae506a72d92b83e3f5f9aeeb3c6f","02a011be72c4a400319212228106af278823a97acfe0a67e1ecd866d446b315114"],"m/2147483647/0/10":["025886ba287922a904881c7315e6fcc410a7976741771a5937d3a1a01b529f21fd","0243bb91ceed9d29d0c2ca66a8ab77e82110bbcc023beb4106f787964f44a0b972"],"m/2147483647/0/11":["0369d21684894cc2d4b2f5e581ede3cac9e8db4161a08e7737c1be129bb673d3d5","03c9ef27e3cd3dadc078fdfd9936a7ad9bf7954747085cf8f8a2a5bb3431f68a9f"],"m/2147483647/0/12":["03a73b8fd859bf6acebffdfffa2597199091daedd2c011ac67fc3494d8a1a8ceb6","025a213f7771c8be03f43f2e7f469ad4ef2cf6907ea284b227a786d1f55dfa7144"],"m/2147483647/0/13":["03a09f7ca257e1ab263cd5e6b0addc3ff868b93df132321d98775ca3505efb576f","03454c715739164bc55f347a651439cdf3ec146b35d2927beb60e8290b3916e082"],"m/2147483647/0/14":["03a64b1f7bd94a6b1a6e84ea444e0ba04e9deb86460934ccc37c0615a134a8257b","02794f09210b1811a455f3e1c7bcd35c76dff2523190fef9615eb27e2376acac1c"],"m/2147483647/0/15":["0392dca2fd9a3bc2b2a7d90a848719069fbc5f22bff7327bb8186c032514085263","032ee8a33ea76d70c7ae839448ca6c5b1af89146f2922e23ba1822df42dbc7e66a"],"m/2147483647/0/16":["031a22a1a3c1abad7c4d782ef6ba3cc00f2e8fe549eb33e0732200aff6d3174831","03bdce9781289e0c31cf727f4c93fe46f7930dd8fd68f818ce241f1ede268e8e0e"],"m/2147483647/0/17":["03b12d27e9aea2c2ad598e54e40860a705ac2ca2427aa511b501b38ec368ea5c7d","03e60d35d84d4536cad895215256b312bb4879a8d417251c279995e58f25da3d54"],"m/2147483647/0/18":["0380266cc9a9673676ad6a1b2e7148766df9c25b4dce299e5edc4f65b72aa58e64","0329e2a8a48c06c0c45dfdd2ab33e6455551557d8ebaf8c12fdf7470f8c45f1d28"],"m/2147483647/0/19":["036fe62af85560d7eea7c7af55e60b32a97dca80134d0aedffb19eb2705b9d6e01","02381c2c30b9f81e2a53c69028fbe11803acad0420b267719b7a80870be0baaeb7"],"m/0/0/2":["027bf94b8fc4e9b42683af25fda125ccab8760040717d100270dd4afd032692daf","026382c6c9357250d96dc21e43c053857a64efeac1887fdcbc107fbe3ecfc6115a"],"m/0/0/3":["03fd203acbd9af3cbbfb709458f8952078234a36094f12d00372e4b2b14cfdf419","03f2e5db59aea5dc89f53ac2a9f4ef66d41265c45afc5d763e0ca61ab70c7c61ec"],"m/0/0/4":["02a1d7cf4fcdbbf4de4002b844c3bff1639073f1cd6e5c4a4e02596b45d3f518c2","03b5fba813294e6ae096ea158833453caa5a945609b0a554696091b9b152bb0f7d"],"m/0/0/5":["0261d37e3b56ef4e106c59753037f516a4b1c45e056b2a3e00f8b77f15aaa7f8a5","0256a55e66e0de1603f0d600c0eb5f5486cf3512a776a36f3ab0d1941fc0dc9b09"],"m/0/0/6":["031db2826af215fe6cbe3f6e121b0497840fc49be133cff0a4d4eab679d6b99d70","021dd722c3f35dd04fcdb57f09b76c723d521fb36751de03ffd08096ddf1dc1f86"],"m/0/0/7":["0354ea75bdd9eb5beae7262e4a5eeb58bd10103ee0185e85b749ea39f6615d0f62","03f2c8f3b6478c0501a8578d5caf5ac2974f8213fc5e699d62dd2af58fbe8781d4"],"m/0/0/8":["0282e67df3bcd1e1662469b4c3151fb50ee1e46b75d787d91184c16b9803131f82","02921a7054af1e425f4137a5eb6b34d1f2b9d81c2625230194bc30657bb4277e11"],"m/0/0/9":["033e7e387933983ceab37c8388bd8ebc5119760f493ffe6f083bef0e5dfe22891d","02d660d60cc55d80912e0745cb142a8596a4604fbf72f9aadec0599aa2ed62461a"],"m/0/0/10":["022ce5b2750ae34512199856eab9e912dc25281cd8b88e7688a46c3b9a389701cb","02f14aa1608fce3b6088148709eb5fe72b61699c931fa8d95a45fab1106859d1b0"],"m/0/0/11":["0288dbef3302c1bc5556028adb33e2f9e03c119dbad4f706befb8ce86cea459f2b","03f13ced465e2e0a3aaa8895f3185d5711e0bebdaf507610b7a669ac8fc82da8fe"],"m/0/0/12":["031ab4677885340d2f927ccc9747f4346b79e4eb6c750695095a8a2524610fa94a","038c881910fbd8b50d193db4e0c84f5b7840820397f92cf0718a8e06d027125503"],"m/0/0/13":["031b568452cba22eb7a88c6085489e53e35abd16068882e71a140e47e12dee9c61","020d09885ee362101d12d34ce0918d41593634db1b9413e5415c6755753b9330e8"],"m/0/0/14":["024177bc9aa03cfc72eda2dfddffd7fe9d0c2f007fc3ba1a48280feae2b9fb117a","03394ad321668440c08da76eb35475ba3a8c0e8cbe0ed81468673a8c72d38fe457"],"m/0/0/15":["02037b1cc696ffbe9eba3684edd53653386ef6cd7728401c40120037593a4c2ae2","020ab8d6900ec9c11ca5d96dfc0ce7cf0ee71653a7c45118e89abb4b113147e53a"],"m/0/0/16":["023bcbb8d4726a546087cdb83740adf0ace879b7195a572c652fa8ce4dbe195a04","0392721b230d5163d28b27fc7e059b875711f12b3da448eabe7229bde57530e637"],"m/0/0/17":["02498ee74e849d3e9261dd1863038caf83d6a3bc2eeebecf17055d4bab44dee77f","03d4dc104b2e0981693e8097437de9b05334a85e2c8edb02783897859bdbc93e32"],"m/0/0/18":["0218a9f524fe54abf8c3afd21314296cfd93eaa9227acbd457e6c9a742dc233cf4","03760f3d0c5db969bda698ff9352e3b7c332216c34825f4c6e857e39c9aee7cd35"],"m/0/0/19":["033dd51f7737f0e9db79f5c38e4298bf3396346904ef3933d290a22e5b77048d9e","0221b2eedccb9a37515263071550069b3b349a166f0f131d0028e8600d9a2251b9"],"m/0/0/20":["02cb6c39161f3244d7769f7ab96346cae2cf21cb6f4538f5e7382d363dc2f836c7","034f7bda4d1e9ed6a3774608a4d6cd8582ab59fe3187f8a7a7cf914d89426ebe28"],"m/0/0/21":["035490549d65f1360f10340037250b171470ff4c86966318a2b1eead6d8b969aea","03f6a04f6fcd07a4f32c82d53710ed30e0f54d43d41c67c661d158b3d0830c3ea2"],"m/1/0/2":["02972eae7e4302e319c266578e14a07839c1e788296a92906e6d66d938211dad5f","039ed6b488f1571ad6527acd6b6c5b8453eacf6665dc5cb7852e33d1c8ea73f9fe"],"m/1/0/3":["02bec4728888c2c045108353994bae5731ec7a7b41459023b0023e10b8d616bd30","03ce1efe16214c9eac595382e46a68143dd11a335b3f7c971ddd719ac544a5fc4b"],"m/1/0/4":["030e2df1d341568225d8dfbe5d07e98dae9f90e0f43e19dcc68c998a6ed7bcc1f0","0380f4c07dc84faf42d51779f104aa6e3b5c3ce2d7684b3cb76d49faeefc2b69d6"],"m/1/0/5":["029a54ddaa25f433b493f4b72df8c1d41be2c4d2963b8b61ee63cc86d16c12d066","021567c95e0317442e7367aa4e3378dd46c5bcef5860f789272fea83b917de0669"],"m/1/0/6":["03590320d80b61cc0874b579f467c9b5ccc50d9ef875bcf6bdd12e2d0c211e8973","03ee4677b6ee89a9d355851f2230506c6897ff219062c0df4ad9a85c60f3535f93"],"m/1/0/7":["03caf98ab1c9b79d1dc8029453a6137c08787b04043b79af3cb42d41d2d3f1338f","023f39ae4e2f4f3887d5fc58e0d3a0d7ee267dc04aa257c75b6b2d67d2f5580f81"],"m/1/0/8":["0352a2a3ea8209c9a2b633d788796ac2d16c08022440e04a77ab2835c7f971d266","0291bc248b3da997f35e8fae98a75a91fdac2819d74c4e270899338d48f7389e87"],"m/1/0/9":["02468d32d9c3c62418d506d4cd0da6cd2022d5bcafdb5f847cf7bde7a48ec6848b","032713d90d12eb6a072f3c1db6c0d3b680d3f78883016135fc0f78e8193d41d4b4"],"m/1/0/10":["034863cc6bab9b059be53413ba75c5fc286647c20d7f9e5512ef4754ea301dd1ce","03a33ab9c32a2264ee2464ebbb5892f0e34acf0fdede4f87395a89e9dacdd4930e"],"m/1/0/11":["031e19296695bfe8a96ba3bf58afa805ee1bd5471fddb3929b1678d69d442d69c9","0270feb33956fd9e937019d629523e26437493c0856514011e6aec88baf7721295"],"m/1/0/12":["03cce695d3c3843bf73e851b2446a77d7e235e5b80b4f4474f9946292eb8218742","039ea96c8822f0ec7ed28308d277f3e730480d7573579cd11b89aef4364cd9ffeb"],"m/1/0/13":["02ab4ac38eb405e822d12c0f0f354f04f9ee1d991dde887a5c1171096fe503158f","036809e60cae1203da8884ea1f85d4669ce6e053f8ba605d775e271b70ab4f6787"],"m/1/0/14":["039d61da23a8610fa0ee58eb37d7cea7ea9396c79153da97280ccf5e46718e3bac","03015c27bcc778682781fd6ad30aa6041db0b7e24270818cdceece0043ccc34b26"],"m/1/0/15":["03c088ed669132835d2728b0ecf294271c8388988c6ae264d43ca24f50e4005f81","03e2c118c9445a2ddc4c8afeb0ba49e21be3f818a483d346418b8922b8a371a2b7"],"m/1/0/16":["02bba7df9847f463c6b23eca37a4bd6efa3801a52b8ddfad804d902e783b70c81c","03764b657f23996e31c64a701facc1cbeb0c9edfdd605e2c1ed36cf48197565d45"],"m/1/0/17":["020445179c522295b89bf4bfd582eb03422e3fa20dcd29263925e9f44282d476d8","036e47bdd32f3061aed1c1f8c2a32b038c7b72391cb1f80ebfc150e58f88372766"],"m/1/0/18":["024d88c4bfcbba713d49e1edcd035234aaa1ee76ad7bcf75bf074a16658a6b0b6d","02b861e7a20d89f6875d2e44c78dbadb99503e282e5e60e9f65657af6fea81d425"],"m/1/0/19":["023a8ca9d5300181f157e1930d3b0800eebe7683d8df72e6cbf28834dbf1be5d60","026053c4f84c10d15890c0b254522972931bc2d5b7cdf9c1f9f3137c22edf3ecd3"],"m/1/0/20":["03137c66e9f3d61aba659f408d77a293fa0f3fea4ccb911074a681d6f61a55d023","0291aa1bbfbef59b16b0e37e185a706c589d448cb02e860c5df9c9d7242ecc739f"],"m/1/0/21":["03c08673e0cae55318bc9dcc4b5f11eb3ff71d42de04015e255dde3fd8cba7e09e","02423d4eab06cd5b26e71d145283523c011d58032700c517f00b328d2c90cf109f"]}},"txProposals":{"txps":[{"creator":"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5","createdTs":1405543144016,"seenBy":{"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543144016,"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543144645},"signedBy":{"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543144016},"rejectedBy":{"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543170040},"sentTs":null,"sentTxid":null,"inputChainPaths":["m/45\'/0/0/0"],"comment":"blablabla","builderObj":{"valueInSat":"29000000","valueOutSat":"8900000","feeSat":"10000","remainderSat":"20090000","hashToScriptMap":{"2NBtv6DdXj8HBunyGqpW9H8bUtW5x3rfVTj":"5221028a4b63f26253f3a8731577b8e1ee480950ad5833ebbf106fe3463bfc07cc3b90210332efa054c08cb77506a35ee0762cb7156f244566703ec08e433568ec0397bec852ae"},"selectedUtxos":[{"address":"2NBtv6DdXj8HBunyGqpW9H8bUtW5x3rfVTj","txid":"a9f4dda3f092e37244bc4e77ea921fed01d5b8ea49613dfdc0dc8afdd70190b5","vout":1,"ts":1405543855,"scriptPubKey":"a914cc93216398b77b5f8c451ca3a357bef961678be987","amount":0.29,"confirmations":0,"confirmationsFromCache":false}],"inputsSigned":0,"signaturesAdded":1,"signhash":1,"spendUnconfirmed":true,"tx":"0100000001b59001d7fd8adcc0fd3d6149eab8d501ed1f92ea774ebc4472e392f0a3ddf4a9010000009300493046022100ccbb8f398f74a76236629b8499ffc6f9518a2091f5a61a9a352c0a10f615961e022100b8f0769c76cf33bec3d7f81d9da2b74cf6e8a5e0a24ee5f48172854d8bcdbfa101475221028a4b63f26253f3a8731577b8e1ee480950ad5833ebbf106fe3463bfc07cc3b90210332efa054c08cb77506a35ee0762cb7156f244566703ec08e433568ec0397bec852aeffffffff02a0cd8700000000001976a91485eb47fe98f349065d6f044e27a4ac541af79ee288ac908c32010000000017a914560c292066792531164149c5ed63ad2793a61b928700000000"}},{"creator":"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5","createdTs":1405543188745,"seenBy":{"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543188745,"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543189341},"signedBy":{"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543188745,"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543206819},"rejectedBy":{},"sentTs":1405543207304,"sentTxid":"169bc92693dd2e27724eeba81e54210e842035bd3af6c52e6a6a5e908f1a4f66","inputChainPaths":["m/45\'/0/0/0"],"comment":"que parece","builderObj":{"valueInSat":"29000000","valueOutSat":"9000000","feeSat":"10000","remainderSat":"19990000","hashToScriptMap":{"2NBtv6DdXj8HBunyGqpW9H8bUtW5x3rfVTj":"5221028a4b63f26253f3a8731577b8e1ee480950ad5833ebbf106fe3463bfc07cc3b90210332efa054c08cb77506a35ee0762cb7156f244566703ec08e433568ec0397bec852ae"},"selectedUtxos":[{"address":"2NBtv6DdXj8HBunyGqpW9H8bUtW5x3rfVTj","txid":"a9f4dda3f092e37244bc4e77ea921fed01d5b8ea49613dfdc0dc8afdd70190b5","vout":1,"ts":1405543855,"scriptPubKey":"a914cc93216398b77b5f8c451ca3a357bef961678be987","amount":0.29,"confirmations":1,"confirmationsFromCache":false}],"inputsSigned":1,"signaturesAdded":2,"signhash":1,"spendUnconfirmed":true,"tx":"0100000001b59001d7fd8adcc0fd3d6149eab8d501ed1f92ea774ebc4472e392f0a3ddf4a901000000da00483045022035423cc74824ba904907678dda3b62a20a787b96d1b3e9f3e9546f9c57f4e45902210080a1ff1c39f458ac1642b9e948bd62fd70563b5252e749cc8fc642cd763ee830014730440220524a13f36cfb03caa246d7d84de634ec9386f2c39c19bfa926037f48da86262b022050e58a6503d105ad2805f86806810a1aa7f20d6271e1340b42fa91ab6a30f3e801475221028a4b63f26253f3a8731577b8e1ee480950ad5833ebbf106fe3463bfc07cc3b90210332efa054c08cb77506a35ee0762cb7156f244566703ec08e433568ec0397bec852aeffffffff0240548900000000001976a91485eb47fe98f349065d6f044e27a4ac541af79ee288acf00531010000000017a9146130a9d51f996b7a1b9d3e10c80930834251909d8700000000"}},{"creator":"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba","createdTs":1405543505848,"seenBy":{"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543505848,"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543590221},"signedBy":{"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543505848,"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543590221},"rejectedBy":{},"sentTs":1405543610315,"sentTxid":"6fe851b54b777a75fe80fa204dc674395e2af69efb1f7c0017e909eb82c3d914","inputChainPaths":["m/45\'/0/1/1"],"comment":"mandaaaaaaa","builderObj":{"valueInSat":"19990000","valueOutSat":"19980000","feeSat":"10000","remainderSat":"0","hashToScriptMap":{"2N277q5r8Ab6XLJNCjXXFdh5itDJRQCv9ts":"5221020389327ee8ae7d0ee3f8187842d23a4070bdd8a27c0bcddd05d80ef39009253d21025c9b49bdf17d97bd82ea1b87793082f857247f0f9b999937a166ec994bb1b41f52ae"},"selectedUtxos":[{"address":"2N277q5r8Ab6XLJNCjXXFdh5itDJRQCv9ts","txid":"169bc92693dd2e27724eeba81e54210e842035bd3af6c52e6a6a5e908f1a4f66","vout":1,"ts":1405543157,"scriptPubKey":"a9146130a9d51f996b7a1b9d3e10c80930834251909d87","amount":0.1999,"confirmationsFromCache":false}],"inputsSigned":1,"signaturesAdded":2,"signhash":1,"spendUnconfirmed":true,"tx":"0100000001664f1a8f905e6a6a2ec5f63abd3520840e21541ea8eb4e72272edd9326c99b1601000000db0048304502206b18b3dba2646c552469d8ef52d7656f6a65f563032530f622abdfd8bd4c5cee022100e804b406eddebbc827646141e74dc64c76a770ed4e35183ffd35d265ad9f7d3b01483045022100f6c013638ff0a316b1baa93dfffba6a98cf3033c133e8bd899e933c9c3e47ce10220530f40e7ea52ae58bec695edbec6d566d2ee8e7b5f33f95e33093ad1e29a125401475221020389327ee8ae7d0ee3f8187842d23a4070bdd8a27c0bcddd05d80ef39009253d21025c9b49bdf17d97bd82ea1b87793082f857247f0f9b999937a166ec994bb1b41f52aeffffffff01e0de3001000000001976a91485eb47fe98f349065d6f044e27a4ac541af79ee288ac00000000"}},{"creator":"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba","createdTs":1405543781381,"seenBy":{"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543781381,"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543782017},"signedBy":{"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543781381},"rejectedBy":{"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543794590},"sentTs":null,"sentTxid":null,"inputChainPaths":["m/45\'/0/0/1"],"comment":"1","builderObj":{"valueInSat":"29000000","valueOutSat":"1000000","feeSat":"10000","remainderSat":"27990000","hashToScriptMap":{"2N4eyXKikdnnUT4S74MRNAYqXChhUYmZ1Sb":"52210359c6d0d0d31f83301169901a6ffad9535f14014b5ab3b43561dbb2436a7b813821037d06f713f13a11967fd5edca265ff4c77528693a712c482256505693e4890d9352ae"},"selectedUtxos":[{"address":"2N4eyXKikdnnUT4S74MRNAYqXChhUYmZ1Sb","txid":"6c9da5b0da4bab0d576033325e987b10ccf2b9bf479d306b6aae36efeaa56892","vout":0,"ts":1405543698,"scriptPubKey":"a9147d274ac50968d7823b6cbc1b38770deb7157995387","amount":0.29,"confirmationsFromCache":false}],"inputsSigned":0,"signaturesAdded":1,"signhash":1,"spendUnconfirmed":true,"tx":"01000000019268a5eaef36ae6a6b309d47bfb9f2cc107b985e323360570dab4bdab0a59d6c000000009200483045022064d877bc5171fbaef909c2a1a924e0023b3ccc0b530cb46653f06ecb230283e8022100bc6658d60ad4f7120d9226c8f6eada87f3b0388f73c458011988bab36e78ba15014752210359c6d0d0d31f83301169901a6ffad9535f14014b5ab3b43561dbb2436a7b813821037d06f713f13a11967fd5edca265ff4c77528693a712c482256505693e4890d9352aeffffffff0240420f00000000001976a91485eb47fe98f349065d6f044e27a4ac541af79ee288acf017ab010000000017a91421c4a435d9ac263ec55b35a1a5ca95e979639b9b8700000000"}},{"creator":"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5","createdTs":1405543835343,"seenBy":{"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543835343,"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543835968},"signedBy":{"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543835343},"rejectedBy":{"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543850998},"sentTs":null,"sentTxid":null,"inputChainPaths":["m/45\'/0/0/1"],"comment":"2","builderObj":{"valueInSat":"29000000","valueOutSat":"1000000","feeSat":"10000","remainderSat":"27990000","hashToScriptMap":{"2N4eyXKikdnnUT4S74MRNAYqXChhUYmZ1Sb":"52210359c6d0d0d31f83301169901a6ffad9535f14014b5ab3b43561dbb2436a7b813821037d06f713f13a11967fd5edca265ff4c77528693a712c482256505693e4890d9352ae"},"selectedUtxos":[{"address":"2N4eyXKikdnnUT4S74MRNAYqXChhUYmZ1Sb","txid":"6c9da5b0da4bab0d576033325e987b10ccf2b9bf479d306b6aae36efeaa56892","vout":0,"ts":1405543698,"scriptPubKey":"a9147d274ac50968d7823b6cbc1b38770deb7157995387","amount":0.29,"confirmationsFromCache":false}],"inputsSigned":0,"signaturesAdded":1,"signhash":1,"spendUnconfirmed":true,"tx":"01000000019268a5eaef36ae6a6b309d47bfb9f2cc107b985e323360570dab4bdab0a59d6c0000000092004830450220302baae7de2e0f102bf3af2d5f450f673e51bd143020141a769ccdcdf16af188022100e7abc087c76050ed649e7139a5a136969e74e24a8d8f6223d3219ad033a26451014752210359c6d0d0d31f83301169901a6ffad9535f14014b5ab3b43561dbb2436a7b813821037d06f713f13a11967fd5edca265ff4c77528693a712c482256505693e4890d9352aeffffffff0240420f00000000001976a91485eb47fe98f349065d6f044e27a4ac541af79ee288acf017ab010000000017a9148b102abba0729fb0690c61cf7187064d692d43d78700000000"}},{"creator":"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba","createdTs":1405543869803,"seenBy":{"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543869803,"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543870411},"signedBy":{"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543869803,"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543890406},"rejectedBy":{},"sentTs":1405543890913,"sentTxid":"6a0f61574ad65e537e7e99298968db565f97b894b61f4c8f8fac8fcaedb83e2b","inputChainPaths":["m/45\'/0/0/1"],"comment":"3","builderObj":{"valueInSat":"29000000","valueOutSat":"1100000","feeSat":"10000","remainderSat":"27890000","hashToScriptMap":{"2N4eyXKikdnnUT4S74MRNAYqXChhUYmZ1Sb":"52210359c6d0d0d31f83301169901a6ffad9535f14014b5ab3b43561dbb2436a7b813821037d06f713f13a11967fd5edca265ff4c77528693a712c482256505693e4890d9352ae"},"selectedUtxos":[{"address":"2N4eyXKikdnnUT4S74MRNAYqXChhUYmZ1Sb","txid":"6c9da5b0da4bab0d576033325e987b10ccf2b9bf479d306b6aae36efeaa56892","vout":0,"ts":1405543698,"scriptPubKey":"a9147d274ac50968d7823b6cbc1b38770deb7157995387","amount":0.29,"confirmationsFromCache":false}],"inputsSigned":1,"signaturesAdded":2,"signhash":1,"spendUnconfirmed":true,"tx":"01000000019268a5eaef36ae6a6b309d47bfb9f2cc107b985e323360570dab4bdab0a59d6c00000000db00483045022100a8ce7907f9fd7dd41dd65c2dec425e008efea06ee7c80787c10c0e210fbf181302207712c0fdd1cb25836ac1fc2fd303c1e26b85e8980417719b9ed50e977a9693ec01483045022100d1780c4f028cd898920aca3eaceba352ed9306cd17f019ae2f634e8facad149a02203c84ab2093da8e22577e93f27a732f0728d4e6db0c749f3cd3d898d6a025152a014752210359c6d0d0d31f83301169901a6ffad9535f14014b5ab3b43561dbb2436a7b813821037d06f713f13a11967fd5edca265ff4c77528693a712c482256505693e4890d9352aeffffffff02e0c81000000000001976a91485eb47fe98f349065d6f044e27a4ac541af79ee288ac5091a9010000000017a914cc1cab78458b1a951b91c6dcd7eeeeb682f506388700000000"}}],"walletId":"55d4bd062d32f90a","networkName":"testnet"},"privateKey":{"extendedPrivateKeyString":"tprv8ZgxMBicQKsPdWUAmaaopPftevC72Jtiu19V8ee5XijL9JvogqfR95uVrL85f8yBdQMq3KyQtG3Q91yWQb3XDbWWpcdWFDAmJ7Xy2XWkGJu","networkName":"testnet","privateKeyCache":{"m/45\'/0/0/0":"b6fd8d1a079efd523da34f31ba81f544fc3d0a728a8a98299d8980682518e79c","m/45\'/0/1/1":"0f4d52d2a99e4c8c1c2edf09fef12407c3abd2304b961198c3f131a8c8443a13","m/45\'/0/0/1":"de5c191c343bd6017b98708c03344849624a14e2c167cfd6eb8dcb075d139293"}},"addressBook":{"msj42CCGruhRsFrGATiUuh25dtxYtnpbTx":{"hidden":false,"createdTs":1405543109222,"copayerId":"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba","label":"faucet","signature":"3045022067576e5b37f2707a8dc66e57511ad9b10a3125bd95193fff6f8f6402969c3bf3022100adff9f417db07d88face13b3d13f422740d4421440cade1a205684dfdc5d733a"}}}'; var encryptedLegacyO = 'U2FsdGVkX19yGM1uBAIzQa8Po/dvUicmxt1YyRk/S97PcZ6I6rHMp9dMagIrehg4Qd6JHn/ustmFHS7vmBYj0EBpf6rdXiQezaWnVAJS9/xYjAO36EFUbl+NmUanuwujAxgYdSP/sNssRLeInvExmZYW993EEclxkwL6YUyX66kKsxGQo2oWng0NreBJNhFmrbOEWeFje2PiWP57oUjKsurFzwpluAAarUTYSLud+nXeabC7opzOP5yqniWBMJz0Ou8gpNCWCMhG/P9F9ccVPY7juyd0Hf41FVse8nd2++axKB57+paozLdO+HRfV6zkMqC3h8gWY7LkS75j3bvqcTw9LhXmzE0Sz21n9yDnRpA4chiAvtwQvvBGgj1pFMKhNQU6Obac9ZwKYzUTgdDn3Uzg1UlDzgyOh9S89rbRTV84WB+hXwhuVluWzbNNYV3vXe5PFrocVktIrtS3xQh+k/7my4A6/gRRrzNYpKrUASJqDS/9u9WBkG35xD63J/qXjtG2M0YPwbI57BK1IK4K510b8V72lz5U2XQrIC4ldBwni1rpSavwCJV9xF6hUdOmNV8fZsVHP0NeN1PYlLkSb2QgfuoWnkcsJerwuFR7GZC/i6efrswtpO0wMEQr/J0CLbeXlHAru6xxjCBhWoJvZpMGw72zgnDLoyMNsEVglNhx/VlV9ZMYkkdaEYAxPOEIyZdQ5MS+2jEAlXf818n/xzJSVrniCn9be8EPePvkw35pivprvy09vbW4cKsWBKvgIyoT6A3OhUOCCS8E9cg0WAjjav2EymrbKmGWRHaiD+EoJqaDg6s20zhHn1YEa/YwvGGSB5+Hg8baLHD8ZASvxz4cFFAAVZrBUedRFgHzqwaMUlFXLgueivWUj7RXlIw6GuNhLoo1QkhZMacf23hrFxxQYvGBRw1hekBuDmcsGWljA28udBxBd5f9i+3gErttMLJ6IPaud590uvrxRIclu0Sz9R2EQX64YJxqDtLpMY0PjddSMu8vaDRpK9/ZSrnz/xrXsyabaafz4rE/ItFXjwFUFkvtmuauHTz6nmuKjVfxvNLNAiKb/gI7vQyUhnTbKIApe7XyJsjedNDtZqsPoJRIzdDmrZYxGStbAZ7HThqFJlSJ9NPNhH+E2jm3TwL5mwt0fFZ5h+p497lHMtIcKffESo7KNa2juSVNMDREk0NcyxGXGiVB2FWl4sLdvyhcsVq0I7tmW6OGZKRf8W49GCJXq6Ie69DJ9LB1DO67NV1jsYbsLx9uhE2yEmpWZ3jkoCV/Eas4grxt0CGN6EavzQ=='; var legacyPassword = '1'; From 296ddf3625060832da5f5a6ff925b23ce30d0f4b Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Fri, 5 Sep 2014 14:28:21 -0300 Subject: [PATCH 025/191] settings: fix test 3 --- js/models/blockchain/Insight.js | 4 ++-- test/test.WalletFactory.js | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/js/models/blockchain/Insight.js b/js/models/blockchain/Insight.js index 2e6c4116c..b4d928c4c 100644 --- a/js/models/blockchain/Insight.js +++ b/js/models/blockchain/Insight.js @@ -29,7 +29,8 @@ var preconditions = require('preconditions').singleton(); */ var Insight = function(opts) { - preconditions.checkArgument(opts).shouldBeObject(opts) + preconditions.checkArgument(opts) + .shouldBeObject(opts) .checkArgument(opts.host) .checkArgument(opts.port) .checkArgument(opts.schema); @@ -149,7 +150,6 @@ Insight.prototype.subscribe = function(addresses) { return function(txid) { // verify the address is still subscribed if (!self.subscribed[address]) return; - log.debug('insight tx event'); self.emit('tx', { diff --git a/test/test.WalletFactory.js b/test/test.WalletFactory.js index 4559a5361..ac473bb89 100644 --- a/test/test.WalletFactory.js +++ b/test/test.WalletFactory.js @@ -441,9 +441,10 @@ describe('WalletFactory model', function() { should.exist(w.privateKey.toObj()); }); - it('should be able to import simple 1-of-1 encrypted legacy testnet wallet', function(done) { + it.only('should be able to import simple 1-of-1 encrypted legacy testnet wallet', function(done) { var pp = new Passphrase(config.passphrase); var alternateConfig = JSON.parse(JSON.stringify(config)); + alternateConfig.Blockchain = FakeBlockchain; alternateConfig.Storage = LocalEncrypted; alternateConfig.storage = { localStorage: mockLocalStorage, From 69b70d7d2b1ac3651a8e0dfebfd03c62a0a7e3f3 Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Fri, 5 Sep 2014 14:28:54 -0300 Subject: [PATCH 026/191] settings: fix tests --- test/test.WalletFactory.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test.WalletFactory.js b/test/test.WalletFactory.js index ac473bb89..f683093e2 100644 --- a/test/test.WalletFactory.js +++ b/test/test.WalletFactory.js @@ -441,7 +441,7 @@ describe('WalletFactory model', function() { should.exist(w.privateKey.toObj()); }); - it.only('should be able to import simple 1-of-1 encrypted legacy testnet wallet', function(done) { + it('should be able to import simple 1-of-1 encrypted legacy testnet wallet', function(done) { var pp = new Passphrase(config.passphrase); var alternateConfig = JSON.parse(JSON.stringify(config)); alternateConfig.Blockchain = FakeBlockchain; From 6bdeaadb948f7067d74358423f76d6c00dc6e83b Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Fri, 5 Sep 2014 15:54:44 -0700 Subject: [PATCH 027/191] settings: fix angular test 1 --- js/directives.js | 16 +-- test/mocks/FakeWallet.js | 25 +++-- test/unit/directives/directivesSpec.js | 33 ++++--- test/unit/filters/filtersSpec.js | 131 ++++++++++++++----------- util/build.js | 20 ++-- 5 files changed, 131 insertions(+), 94 deletions(-) diff --git a/js/directives.js b/js/directives.js index 82704b104..555b78991 100644 --- a/js/directives.js +++ b/js/directives.js @@ -1,10 +1,12 @@ 'use strict'; +var bitcore = require('bitcore'); +var Address = bitcore.Address; +var bignum = bitcore.Bignum; +var preconditions = require('preconditions').singleton(); + angular.module('copayApp.directives') - .directive('validAddress', ['$rootScope', function($rootScope) { - var bitcore = require('bitcore'); - var Address = bitcore.Address; - var bignum = bitcore.Bignum; + irective('validAddress', ['$rootScope', function($rootScope) { return { require: 'ngModel', @@ -46,8 +48,10 @@ angular.module('copayApp.directives') }]) .directive('enoughAmount', ['$rootScope', function($rootScope) { - var bitcore = require('bitcore'); var w = $rootScope.wallet; + preconditions.checkState(w); + preconditions.checkState(w.settings.unitToSatoshi); + var feeSat = Number(bitcore.TransactionBuilder.FEE_PER_1000B_SAT); return { require: 'ngModel', @@ -271,7 +275,7 @@ angular.module('copayApp.directives') client.on('datarequested', function(client) { client.setText(scope.clipCopy); - } ); + }); client.on('complete', function(client, args) { elm.removeClass('btn-copy').addClass('btn-copied').html('Copied!'); diff --git a/test/mocks/FakeWallet.js b/test/mocks/FakeWallet.js index e4a7bc8d7..57aa5d2d2 100644 --- a/test/mocks/FakeWallet.js +++ b/test/mocks/FakeWallet.js @@ -6,11 +6,10 @@ if (is_browser) { } var Wallet = copay.Wallet; -var FakePrivateKey = function () { -}; +var FakePrivateKey = function() {}; FakePrivateKey.prototype.toObj = function() { - return extendedPublicKeyString = 'privHex'; + return extendedPublicKeyString = 'privHex'; }; var FakeWallet = function() { @@ -37,12 +36,20 @@ var FakeWallet = function() { } }; this.blockchain = { - getSubscriptions: function(){ return []; }, - subscribe: function(){} + getSubscriptions: function() { + return []; + }, + subscribe: function() {} }; this.privateKey = new FakePrivateKey(); - this.settings = {}; + this.settings = { + unitName: 'bits', + unitToSatoshi: 100, + unitDecimals: 2, + alternativeName: 'US Dollar', + alternativeIsoCode: 'USD', + }; }; FakeWallet.prototype.createTx = function(toAddress, amountSatStr, comment, opts, cb) { @@ -99,8 +106,7 @@ FakeWallet.prototype.getBalance = function(cb) { return cb(null, this.balance, this.balanceByAddr, this.safeBalance); }; -FakeWallet.prototype.removeTxWithSpentInputs = function (cb) { -}; +FakeWallet.prototype.removeTxWithSpentInputs = function(cb) {}; FakeWallet.prototype.setEnc = function(enc) { this.enc = enc; @@ -110,8 +116,7 @@ FakeWallet.prototype.toEncryptedObj = function() { return this.enc; }; -FakeWallet.prototype.close = function() { -}; +FakeWallet.prototype.close = function() {}; // TODO a try catch was here module.exports = FakeWallet; diff --git a/test/unit/directives/directivesSpec.js b/test/unit/directives/directivesSpec.js index e0a2b389e..87b8aab91 100644 --- a/test/unit/directives/directivesSpec.js +++ b/test/unit/directives/directivesSpec.js @@ -8,17 +8,23 @@ describe("Unit: Testing Directives", function() { beforeEach(module('copayApp.directives')); - beforeEach(function() { - config.unitToSatoshi = 100; - config.unitName = 'bits'; - }); + var walletConfig = { + requiredCopayers: 3, + totalCopayers: 5, + spendUnconfirmed: 1, + reconnectDelay: 100, + networkName: 'testnet', + alternativeName: 'lol currency', + alternativeIsoCode: 'LOL' + }; - describe('Check config', function() { - it('unit should be set to BITS in config.js', function() { - expect(config.unitToSatoshi).to.equal(100); - expect(config.unitName).to.equal('bits'); - }); - }); + + beforeEach(inject(function($rootScope) { + $rootScope.wallet = new FakeWallet(walletConfig); + var w = $rootScope.wallet; + w.settings.unitToSatoshi = 100; + w.settings.unitName = 'bits'; + })); describe('Validate Address', function() { beforeEach(inject(function($compile, $rootScope) { @@ -94,9 +100,12 @@ describe("Unit: Testing Directives", function() { describe('Unit: BTC', function() { beforeEach(inject(function($compile, $rootScope) { - config.unitToSatoshi = 100000000; - config.unitName = 'BTC'; $scope = $rootScope; + var w = new FakeWallet(walletConfig); + w.settings.unitToSatoshi = 100000000; + w.settings.unitName = 'BTC'; + $rootScope.wallet = w; + $rootScope.availableBalance = 0.04; var element = angular.element( '' + diff --git a/test/unit/filters/filtersSpec.js b/test/unit/filters/filtersSpec.js index 38a7dc442..1f2e52809 100644 --- a/test/unit/filters/filtersSpec.js +++ b/test/unit/filters/filtersSpec.js @@ -5,6 +5,15 @@ describe('Unit: Testing Filters', function() { beforeEach(module('copayApp.filters')); + var walletConfig = { + requiredCopayers: 3, + totalCopayers: 5, + spendUnconfirmed: 1, + reconnectDelay: 100, + networkName: 'testnet', + alternativeName: 'lol currency', + alternativeIsoCode: 'LOL' + }; describe('limitAddress', function() { @@ -103,68 +112,76 @@ describe('Unit: Testing Filters', function() { })); }); - describe('noFractionNumber bits', function() { - beforeEach(function() { - config.unitToSatoshi = 100; - config.unitName = 'bits'; + describe('noFractionNumber', function() { + describe('noFractionNumber bits', function() { + beforeEach(inject(function($rootScope) { + $rootScope.wallet = new FakeWallet(walletConfig); + var w = $rootScope.wallet; + w.settings.unitToSatoshi = 100; + w.settings.unitName = 'bits'; + })); + it('should format number to display correctly', inject(function($filter) { + var noFraction = $filter('noFractionNumber'); + expect(noFraction(3100)).to.equal('3,100'); + expect(noFraction(3100200)).to.equal('3,100,200'); + expect(noFraction(3)).to.equal('3'); + expect(noFraction(0.3)).to.equal(0.3); + expect(noFraction(0.30000000)).to.equal(0.3); + expect(noFraction(3200.01)).to.equal('3,200.01'); + expect(noFraction(3200890.010000)).to.equal('3,200,890.01'); + })); }); - it('should format number to display correctly', inject(function($filter) { - var noFraction = $filter('noFractionNumber'); - expect(noFraction(3100)).to.equal('3,100'); - expect(noFraction(3100200)).to.equal('3,100,200'); - expect(noFraction(3)).to.equal('3'); - expect(noFraction(0.3)).to.equal(0.3); - expect(noFraction(0.30000000)).to.equal(0.3); - expect(noFraction(3200.01)).to.equal('3,200.01'); - expect(noFraction(3200890.010000)).to.equal('3,200,890.01'); - })); - }); - describe('noFractionNumber BTC', function() { - beforeEach(function() { - config.unitToSatoshi = 100000000; - config.unitName = 'BTC'; + describe('noFractionNumber BTC', function() { + beforeEach(inject(function($rootScope) { + $rootScope.wallet = new FakeWallet(walletConfig); + var w = $rootScope.wallet; + w.settings.unitToSatoshi = 100000000; + w.settings.unitName = 'BTC'; + })); + it('should format number to display correctly', inject(function($filter) { + var noFraction = $filter('noFractionNumber'); + expect(noFraction(0.30000000)).to.equal(0.3); + expect(noFraction(0.00302000)).to.equal(0.00302); + expect(noFraction(1.00000001)).to.equal(1.00000001); + expect(noFraction(3.10000012)).to.equal(3.10000012); + expect(noFraction(0.00100000)).to.equal(0.001); + expect(noFraction(0.00100009)).to.equal(0.00100009); + expect(noFraction(2000.00312011)).to.equal('2,000.00312011'); + expect(noFraction(2000998.00312011)).to.equal('2,000,998.00312011'); + })); }); - it('should format number to display correctly', inject(function($filter) { - var noFraction = $filter('noFractionNumber'); - expect(noFraction(0.30000000)).to.equal(0.3); - expect(noFraction(0.00302000)).to.equal(0.00302); - expect(noFraction(1.00000001)).to.equal(1.00000001); - expect(noFraction(3.10000012)).to.equal(3.10000012); - expect(noFraction(0.00100000)).to.equal(0.001); - expect(noFraction(0.00100009)).to.equal(0.00100009); - expect(noFraction(2000.00312011)).to.equal('2,000.00312011'); - expect(noFraction(2000998.00312011)).to.equal('2,000,998.00312011'); - })); - }); - describe('noFractionNumber mBTC', function() { - beforeEach(function() { - config.unitToSatoshi = 100000; - config.unitName = 'mBTC'; + describe('noFractionNumber mBTC', function() { + beforeEach(inject(function($rootScope) { + $rootScope.wallet = new FakeWallet(walletConfig); + var w = $rootScope.wallet; + w.settings.unitToSatoshi = 100000; + w.settings.unitName = 'mBTC'; + })); + it('should format number to display correctly', inject(function($filter) { + var noFraction = $filter('noFractionNumber'); + expect(noFraction(0.30000)).to.equal(0.3); + expect(noFraction(0.00302)).to.equal(0.00302); + expect(noFraction(1.00001)).to.equal(1.00001); + expect(noFraction(3.10002)).to.equal(3.10002); + expect(noFraction(0.00100000)).to.equal(0.001); + expect(noFraction(0.00100009)).to.equal(0.001); + expect(noFraction(2000.00312)).to.equal('2,000.00312'); + expect(noFraction(2000998.00312)).to.equal('2,000,998.00312'); + })); }); - it('should format number to display correctly', inject(function($filter) { - var noFraction = $filter('noFractionNumber'); - expect(noFraction(0.30000)).to.equal(0.3); - expect(noFraction(0.00302)).to.equal(0.00302); - expect(noFraction(1.00001)).to.equal(1.00001); - expect(noFraction(3.10002)).to.equal(3.10002); - expect(noFraction(0.00100000)).to.equal(0.001); - expect(noFraction(0.00100009)).to.equal(0.001); - expect(noFraction(2000.00312)).to.equal('2,000.00312'); - expect(noFraction(2000998.00312)).to.equal('2,000,998.00312'); - })); - }); - describe('noFractionNumber:custom fractionSize', function() { - it('should format number to display correctly', inject(function($filter) { - var noFraction = $filter('noFractionNumber'); - expect(noFraction(0.30000, 0)).to.equal('0'); - expect(noFraction(1.00001, 0)).to.equal('1'); - expect(noFraction(3.10002, 0)).to.equal('3'); - expect(noFraction(2000.00312, 0)).to.equal('2,000'); - expect(noFraction(2000998.00312, 0)).to.equal('2,000,998'); - })); - }); + describe('noFractionNumber:custom fractionSize', function() { + it('should format number to display correctly', inject(function($filter) { + var noFraction = $filter('noFractionNumber'); + expect(noFraction(0.30000, 0)).to.equal('0'); + expect(noFraction(1.00001, 0)).to.equal('1'); + expect(noFraction(3.10002, 0)).to.equal('3'); + expect(noFraction(2000.00312, 0)).to.equal('2,000'); + expect(noFraction(2000998.00312, 0)).to.equal('2,000,998'); + })); + }); + }); }); diff --git a/util/build.js b/util/build.js index 6f15143ef..b60af799b 100644 --- a/util/build.js +++ b/util/build.js @@ -15,7 +15,9 @@ var getCommitHash = function() { //exec git command to get the hash of the current commit //git rev-parse HEAD - var hash = shell.exec('git rev-parse HEAD',{silent:true}).output.trim().substr(0,7); + var hash = shell.exec('git rev-parse HEAD', { + silent: true + }).output.trim().substr(0, 7); return hash; } @@ -23,7 +25,7 @@ var createVersion = function() { var json = JSON.parse(fs.readFileSync('./package.json', 'utf8')); var content = 'module.exports.version="' + json.version + '";'; - content = content + '\nmodule.exports.commitHash="' + getCommitHash() + '";'; + content = content + '\nmodule.exports.commitHash="' + getCommitHash() + '";'; fs.writeFileSync("./version.js", content); }; @@ -43,9 +45,9 @@ var createBundle = function(opts) { b.require('browser-request', { expose: 'request' }); - b.require('underscore', { - expose: 'underscore' - }); + b.require('underscore'); + b.require('assert'); + b.require('preconditions'); b.require('./copay', { expose: 'copay' @@ -130,10 +132,10 @@ if (require.main === module) { }; var program = require('commander'); program - .version('0.0.1') - .option('-d, --debug', 'Development. Don\'t minify the codem and include debug packages.') - .option('-o, --stdout', 'Specify output as stdout') - .parse(process.argv); + .version('0.0.1') + .option('-d, --debug', 'Development. Don\'t minify the codem and include debug packages.') + .option('-o, --stdout', 'Specify output as stdout') + .parse(process.argv); createVersion(); var copayBundle = createBundle(program); From 258ae5c79cd7949d646d8f60305752a0178ddca4 Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Fri, 5 Sep 2014 16:09:20 -0700 Subject: [PATCH 028/191] settings: fix angular test 2 --- test/unit/controllers/controllersSpec.js | 28 ++++++++++-------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/test/unit/controllers/controllersSpec.js b/test/unit/controllers/controllersSpec.js index be9e9553d..851776839 100644 --- a/test/unit/controllers/controllersSpec.js +++ b/test/unit/controllers/controllersSpec.js @@ -34,12 +34,6 @@ describe("Unit: Controllers", function() { alternativeIsoCode: 'LOL' }; - it('Copay config should be binded', function() { - should.exist(config); - should.exist(config.unitToSatoshi); - }); - - describe('More Controller', function() { var ctrl; beforeEach(inject(function($controller, $rootScope) { @@ -224,35 +218,35 @@ describe("Unit: Controllers", function() { sinon.assert.callCount(spy2, 0); sinon.assert.callCount(scope.loadTxs, 1); spy.getCall(0).args[0].should.equal('mkfTyEk7tfgV611Z4ESwDDSZwhsZdbMpVy'); - spy.getCall(0).args[1].should.equal(1000 * config.unitToSatoshi); + spy.getCall(0).args[1].should.equal(1000 * scope.wallet.settings.unitToSatoshi); (typeof spy.getCall(0).args[2]).should.equal('undefined'); }); it('should handle big values in 100 BTC', function() { - var old = config.unitToSatoshi; - config.unitToSatoshi = 100000000;; + var old = scope.wallet.settings.unitToSatoshi; + scope.wallet.settings.unitToSatoshi = 100000000;; sendForm.address.$setViewValue('mkfTyEk7tfgV611Z4ESwDDSZwhsZdbMpVy'); sendForm.amount.$setViewValue(100); var spy = sinon.spy(scope.wallet, 'createTx'); scope.loadTxs = sinon.spy(); scope.submitForm(sendForm); - spy.getCall(0).args[1].should.equal(100 * config.unitToSatoshi); - config.unitToSatoshi = old; + spy.getCall(0).args[1].should.equal(100 * scope.wallet.settings.unitToSatoshi); + scope.wallet.settings.unitToSatoshi = old; }); - it('should handle big values in 5000 BTC', function() { - var old = config.unitToSatoshi; - config.unitToSatoshi = 100000000;; + it('should handle big values in 5000 BTC', inject(function($rootScope) { + var old = $rootScope.wallet.settings.unitToSatoshi; + $rootScope.wallet.settings.unitToSatoshi = 100000000;; sendForm.address.$setViewValue('mkfTyEk7tfgV611Z4ESwDDSZwhsZdbMpVy'); sendForm.amount.$setViewValue(5000); var spy = sinon.spy(scope.wallet, 'createTx'); scope.loadTxs = sinon.spy(); scope.submitForm(sendForm); - spy.getCall(0).args[1].should.equal(5000 * config.unitToSatoshi); - config.unitToSatoshi = old; - }); + spy.getCall(0).args[1].should.equal(5000 * $rootScope.wallet.settings.unitToSatoshi); + $rootScope.wallet.settings.unitToSatoshi = old; + })); it('should convert bits amount to fiat', function(done) { scope.rateService.whenAvailable(function() { From 7277d29965e015ca2f5521117387239e423818a0 Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Fri, 5 Sep 2014 16:11:08 -0700 Subject: [PATCH 029/191] settings: fix angular test 3 --- test/unit/services/servicesSpec.js | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/test/unit/services/servicesSpec.js b/test/unit/services/servicesSpec.js index b430385fd..9c3279645 100644 --- a/test/unit/services/servicesSpec.js +++ b/test/unit/services/servicesSpec.js @@ -5,19 +5,6 @@ // var sinon = require('sinon'); -beforeEach(function() { - config.unitToSatoshi = 100; - config.unitName = 'bits'; -}); - -describe('Check config', function() { - - it('unit should be set to BITS in config.js', function() { - expect(config.unitToSatoshi).to.equal(100); - expect(config.unitName).to.equal('bits'); - }); -}); - describe("Unit: Walletfactory Service", function() { beforeEach(angular.mock.module('copayApp.services')); it('should contain a walletFactory service', inject(function(walletFactory) { From 2a976d2673c95009ca1c7943e4b969cedf61f552 Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Fri, 5 Sep 2014 16:16:06 -0700 Subject: [PATCH 030/191] settings: fix angular test 4 --- js/controllers/send.js | 47 +++++++++++++----------- test/unit/controllers/controllersSpec.js | 1 + test/unit/services/servicesSpec.js | 1 + 3 files changed, 28 insertions(+), 21 deletions(-) diff --git a/js/controllers/send.js b/js/controllers/send.js index 01e547ada..45386f1b1 100644 --- a/js/controllers/send.js +++ b/js/controllers/send.js @@ -1,17 +1,22 @@ 'use strict'; var bitcore = require('bitcore'); +var preconditions = require('preconditions').singleton(); angular.module('copayApp.controllers').controller('SendController', function($scope, $rootScope, $window, $timeout, $anchorScroll, $modal, isMobile, notification, controllerUtils, rateService) { + var w = $rootScope.wallet; + preconditions.checkState(w); + preconditions.checkState(w.settings.unitToSatoshi); + $scope.title = 'Send'; $scope.loading = false; - var satToUnit = 1 / $rootScope.wallet.settings.unitToSatoshi; + var satToUnit = 1 / w.settings.unitToSatoshi; $scope.defaultFee = bitcore.TransactionBuilder.FEE_PER_1000B_SAT * satToUnit; - $scope.unitToBtc = $rootScope.wallet.settings.unitToSatoshi / bitcore.util.COIN; - $scope.unitToSatoshi = $rootScope.wallet.settings.unitToSatoshi; + $scope.unitToBtc = w.settings.unitToSatoshi / bitcore.util.COIN; + $scope.unitToSatoshi = w.settings.unitToSatoshi; - $scope.alternativeName = $rootScope.wallet.settings.alternativeName; - $scope.alternativeIsoCode = $rootScope.wallet.settings.alternativeIsoCode; + $scope.alternativeName = w.settings.alternativeName; + $scope.alternativeIsoCode = w.settings.alternativeIsoCode; $scope.isRateAvailable = false; $scope.rateService = rateService; @@ -36,7 +41,7 @@ angular.module('copayApp.controllers').controller('SendController', this._alternative = newValue; if (typeof(newValue) === 'number' && $scope.isRateAvailable) { this._amount = parseFloat( - (rateService.fromFiat(newValue, $rootScope.wallet.settings.alternativeIsoCode) * satToUnit).toFixed($rootScope.wallet.settings.unitDecimals), 10); + (rateService.fromFiat(newValue, w.settings.alternativeIsoCode) * satToUnit).toFixed(w.settings.unitDecimals), 10); } else { this._amount = 0; } @@ -53,7 +58,7 @@ angular.module('copayApp.controllers').controller('SendController', this._amount = newValue; if (typeof(newValue) === 'number' && $scope.isRateAvailable) { this._alternative = parseFloat( - (rateService.toFiat(newValue * $rootScope.wallet.settings.unitToSatoshi, $rootScope.wallet.settings.alternativeIsoCode)).toFixed(2), 10); + (rateService.toFiat(newValue * w.settings.unitToSatoshi, w.settings.alternativeIsoCode)).toFixed(2), 10); } else { this._alternative = 0; } @@ -75,7 +80,7 @@ angular.module('copayApp.controllers').controller('SendController', } $scope.showAddressBook = function() { - var w = $rootScope.wallet; + var w = w; var flag; if (w) { for (var k in w.addressBook) { @@ -91,7 +96,7 @@ angular.module('copayApp.controllers').controller('SendController', if ($rootScope.pendingPayment) { var pp = $rootScope.pendingPayment; $scope.address = pp.address + ''; - var amount = pp.data.amount / $rootScope.wallet.settings.unitToSatoshi * 100000000; + var amount = pp.data.amount / w.settings.unitToSatoshi * 100000000; $scope.amount = amount; $scope.commentText = pp.data.message; } @@ -113,10 +118,10 @@ angular.module('copayApp.controllers').controller('SendController', $scope.loading = true; var address = form.address.$modelValue; - var amount = parseInt((form.amount.$modelValue * $rootScope.wallet.settings.unitToSatoshi).toFixed(0)); + var amount = parseInt((form.amount.$modelValue * w.settings.unitToSatoshi).toFixed(0)); var commentText = form.comment.$modelValue; - var w = $rootScope.wallet; + var w = w; function done(err, ntxid, merchantData) { if (err) { @@ -344,7 +349,7 @@ angular.module('copayApp.controllers').controller('SendController', } $scope.toggleAddressBookEntry = function(key) { - var w = $rootScope.wallet; + var w = w; w.toggleAddressBookEntry(key); }; @@ -379,7 +384,7 @@ angular.module('copayApp.controllers').controller('SendController', }); modalInstance.result.then(function(entry) { - var w = $rootScope.wallet; + var w = w; $timeout(function() { $scope.loading = false; @@ -403,7 +408,7 @@ angular.module('copayApp.controllers').controller('SendController', }; $scope.getAvailableAmount = function() { - var amount = ((($rootScope.availableBalance * $rootScope.wallet.settings.unitToSatoshi).toFixed(0) - bitcore.TransactionBuilder.FEE_PER_1000B_SAT) / $rootScope.wallet.settings.unitToSatoshi); + var amount = ((($rootScope.availableBalance * w.settings.unitToSatoshi).toFixed(0) - bitcore.TransactionBuilder.FEE_PER_1000B_SAT) / w.settings.unitToSatoshi); return amount > 0 ? amount : 0; }; @@ -416,7 +421,7 @@ angular.module('copayApp.controllers').controller('SendController', $scope.send = function(ntxid, cb) { $scope.loading = true; $rootScope.txAlertCount = 0; - var w = $rootScope.wallet; + var w = w; w.sendTx(ntxid, function(txid, merchantData) { if (!txid) { notification.error('Error', 'There was an error sending the transaction'); @@ -441,7 +446,7 @@ angular.module('copayApp.controllers').controller('SendController', $scope.sign = function(ntxid) { $scope.loading = true; - var w = $rootScope.wallet; + var w = w; w.sign(ntxid, function(ret) { if (!ret) { notification.error('Error', 'There was an error signing the transaction'); @@ -461,7 +466,7 @@ angular.module('copayApp.controllers').controller('SendController', $scope.reject = function(ntxid) { $scope.loading = true; $rootScope.txAlertCount = 0; - var w = $rootScope.wallet; + var w = w; w.reject(ntxid); notification.warning('Transaction rejected', 'You rejected the transaction successfully'); $scope.loading = false; @@ -497,7 +502,7 @@ angular.module('copayApp.controllers').controller('SendController', // Payment Protocol URI (BIP-72) scope.wallet.fetchPaymentTx(uri.merchant, function(err, merchantData) { var balance = $rootScope.availableBalance; - var available = +(balance * $rootScope.wallet.settings.unitToSatoshi).toFixed(0); + var available = +(balance * w.settings.unitToSatoshi).toFixed(0); if (merchantData && available < +merchantData.total) { err = new Error('No unspent outputs available.'); @@ -508,7 +513,7 @@ angular.module('copayApp.controllers').controller('SendController', scope.sendForm.address.$isValid = false; if (err.amount) { - scope.sendForm.amount.$setViewValue(+err.amount / $rootScope.wallet.settings.unitToSatoshi); + scope.sendForm.amount.$setViewValue(+err.amount / w.settings.unitToSatoshi); scope.sendForm.amount.$render(); scope.sendForm.amount.$isValid = false; scope.notEnoughAmount = true; @@ -538,7 +543,7 @@ angular.module('copayApp.controllers').controller('SendController', var url = merchantData.request_url; var domain = /^(?:https?)?:\/\/([^\/:]+).*$/.exec(url)[1]; - merchantData.unitTotal = (+merchantData.total / $rootScope.wallet.settings.unitToSatoshi) + ''; + merchantData.unitTotal = (+merchantData.total / w.settings.unitToSatoshi) + ''; merchantData.expiration = new Date( merchantData.pr.pd.expires * 1000).toISOString(); merchantData.domain = domain; @@ -588,7 +593,7 @@ angular.module('copayApp.controllers').controller('SendController', notification.info('Payment Request', 'Server is requesting ' + merchantData.unitTotal + - ' ' + $rootScope.wallet.settings.unitName + + ' ' + w.settings.unitName + '.' + ' Message: ' + merchantData.pr.pd.memo); }); }; diff --git a/test/unit/controllers/controllersSpec.js b/test/unit/controllers/controllersSpec.js index 851776839..95d0f0f8a 100644 --- a/test/unit/controllers/controllersSpec.js +++ b/test/unit/controllers/controllersSpec.js @@ -384,6 +384,7 @@ describe("Unit: Controllers", function() { beforeEach(inject(function($compile, $rootScope, $controller) { scope = $rootScope.$new(); $rootScope.availableBalance = 123456; + $rootScope.wallet = new FakeWallet(walletConfig); var element = angular.element( '' + diff --git a/test/unit/services/servicesSpec.js b/test/unit/services/servicesSpec.js index 9c3279645..7541c26fd 100644 --- a/test/unit/services/servicesSpec.js +++ b/test/unit/services/servicesSpec.js @@ -4,6 +4,7 @@ // // var sinon = require('sinon'); +var preconditions = require('preconditions').singleton(); describe("Unit: Walletfactory Service", function() { beforeEach(angular.mock.module('copayApp.services')); From 0a531a47f9660b0a468f3bf71ca2de15e5be6507 Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Fri, 5 Sep 2014 16:19:49 -0700 Subject: [PATCH 031/191] settings: fix angular test 5 --- test/unit/controllers/controllersSpec.js | 25 ++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/test/unit/controllers/controllersSpec.js b/test/unit/controllers/controllersSpec.js index 95d0f0f8a..cb48f2789 100644 --- a/test/unit/controllers/controllersSpec.js +++ b/test/unit/controllers/controllersSpec.js @@ -104,6 +104,7 @@ describe("Unit: Controllers", function() { var transactionsCtrl; beforeEach(inject(function($controller, $rootScope) { scope = $rootScope.$new(); + $rootScope.wallet = new FakeWallet(walletConfig); transactionsCtrl = $controller('TransactionsController', { $scope: scope, }); @@ -125,7 +126,11 @@ describe("Unit: Controllers", function() { beforeEach(module(function($provide) { $provide.value('request', { 'get': function(_, cb) { - cb(null, null, [{name: 'lol currency', code: 'LOL', rate: 2}]); + cb(null, null, [{ + name: 'lol currency', + code: 'LOL', + rate: 2 + }]); } }); })); @@ -299,15 +304,15 @@ describe("Unit: Controllers", function() { beforeEach(inject(function($controller, $injector) { $httpBackend = $injector.get('$httpBackend'); $httpBackend.when('GET', GH) - .respond([{ - name: "v100.1.6", - zipball_url: "https://api.github.com/repos/bitpay/copay/zipball/v0.0.6", - tarball_url: "https://api.github.com/repos/bitpay/copay/tarball/v0.0.6", - commit: { - sha: "ead7352bf2eca705de58d8b2f46650691f2bc2c7", - url: "https://api.github.com/repos/bitpay/copay/commits/ead7352bf2eca705de58d8b2f46650691f2bc2c7" - } - }]); + .respond([{ + name: "v100.1.6", + zipball_url: "https://api.github.com/repos/bitpay/copay/zipball/v0.0.6", + tarball_url: "https://api.github.com/repos/bitpay/copay/tarball/v0.0.6", + commit: { + sha: "ead7352bf2eca705de58d8b2f46650691f2bc2c7", + url: "https://api.github.com/repos/bitpay/copay/commits/ead7352bf2eca705de58d8b2f46650691f2bc2c7" + } + }]); })); var rootScope; From b36564fcb7ad6d1e1a9f4e0b07601bebc93785e0 Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Fri, 5 Sep 2014 16:42:57 -0700 Subject: [PATCH 032/191] settings: fix angular test 6 --- test/mocks/FakeBlockchain.js | 2 +- test/mocks/FakeWallet.js | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/test/mocks/FakeBlockchain.js b/test/mocks/FakeBlockchain.js index c6dd8ca4f..7de66350d 100644 --- a/test/mocks/FakeBlockchain.js +++ b/test/mocks/FakeBlockchain.js @@ -11,7 +11,7 @@ FakeBlockchain.prototype.getTransaction = function(txid, cb) { }; FakeBlockchain.prototype.getTransactions = function(addresses, cb) { - return cb(null, []); + cb(null, []); }; diff --git a/test/mocks/FakeWallet.js b/test/mocks/FakeWallet.js index 57aa5d2d2..a206f70ce 100644 --- a/test/mocks/FakeWallet.js +++ b/test/mocks/FakeWallet.js @@ -39,7 +39,8 @@ var FakeWallet = function() { getSubscriptions: function() { return []; }, - subscribe: function() {} + subscribe: function() {}, + getTransactions: function() {} }; this.privateKey = new FakePrivateKey(); @@ -60,6 +61,9 @@ FakeWallet.prototype.createTx = function(toAddress, amountSatStr, comment, opts, FakeWallet.prototype.sendTx = function(ntxid, cb) { cb(8); } +FakeWallet.prototype.getAddressesStr = function() { + return ['2Mw2YXxyMD7fhtPhHYY39X6BVWiBRaez5Zn']; +}; FakeWallet.prototype.set = function(balance, safeBalance, balanceByAddr) { this.balance = balance; From 75dcb73fed898e6dcfc4ff99fe2300beafe4d84a Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Mon, 8 Sep 2014 16:52:06 -0700 Subject: [PATCH 033/191] fix html --- views/settings.html | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/views/settings.html b/views/settings.html index b9ce464ac..aee27ab81 100644 --- a/views/settings.html +++ b/views/settings.html @@ -13,18 +13,18 @@ - Insight API server - - - - - - - -

- Insight API server is open-source software. You can run your own instance, check Insight API Homepage -

+
+ Insight API server + + + + + + +

+ Insight API server is open-source software. You can run your own instance, check Insight API Homepage +

« Back From 1da67489ea66e59bf05ab9de81d7feec2f47877b Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Mon, 8 Sep 2014 17:07:57 -0700 Subject: [PATCH 034/191] fix sidebar --- views/includes/sidebar-mobile.html | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/views/includes/sidebar-mobile.html b/views/includes/sidebar-mobile.html index a77d6d841..d313c1ab4 100644 --- a/views/includes/sidebar-mobile.html +++ b/views/includes/sidebar-mobile.html @@ -8,7 +8,8 @@
-
+
+
Balance @@ -39,7 +40,7 @@
-
+

{{$root.wallet.getName()}} {{$root.wallet.requiredCopayers}}-of-{{$root.wallet.totalCopayers}} @@ -51,7 +52,7 @@ {{totalBalance || 0 - |noFractionNumber}} {{$root.unitName}} + |noFractionNumber}} {{$root.wallet.settings.unitName}}

@@ -59,7 +60,7 @@ - {{lockedBalance || 0|noFractionNumber}} {{$root.unitName}} + {{lockedBalance || 0|noFractionNumber}} {{$root.wallet.settings.unitName}}  
From 3c38a20ac73bcbbdfe3cf8b9f3d78bfb64b2b0e3 Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Mon, 8 Sep 2014 17:44:12 -0700 Subject: [PATCH 035/191] fix style --- views/addresses.html | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/views/addresses.html b/views/addresses.html index 499306ea9..fb83cbfed 100644 --- a/views/addresses.html +++ b/views/addresses.html @@ -19,16 +19,16 @@ change
-
- -
- +
+ - + {{addr.balance || 0|noFractionNumber}} {{$root.wallet.settings.unitName}} +
+
From 7a86b1edf3b6936b4fa7b3e47baed1a7e718fd96 Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Mon, 8 Sep 2014 19:38:45 -0700 Subject: [PATCH 036/191] fix typo --- js/directives.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/directives.js b/js/directives.js index 555b78991..f6816d863 100644 --- a/js/directives.js +++ b/js/directives.js @@ -6,7 +6,7 @@ var bignum = bitcore.Bignum; var preconditions = require('preconditions').singleton(); angular.module('copayApp.directives') - irective('validAddress', ['$rootScope', function($rootScope) { + .directive('validAddress', ['$rootScope', function($rootScope) { return { require: 'ngModel', From 048664b4afafdc193f92adac4c4d6732d532fd84 Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Tue, 9 Sep 2014 11:23:21 -0700 Subject: [PATCH 037/191] fix some karma tests after rebase --- js/controllers/send.js | 8 -------- 1 file changed, 8 deletions(-) diff --git a/js/controllers/send.js b/js/controllers/send.js index 45386f1b1..683b6c71c 100644 --- a/js/controllers/send.js +++ b/js/controllers/send.js @@ -80,7 +80,6 @@ angular.module('copayApp.controllers').controller('SendController', } $scope.showAddressBook = function() { - var w = w; var flag; if (w) { for (var k in w.addressBook) { @@ -121,8 +120,6 @@ angular.module('copayApp.controllers').controller('SendController', var amount = parseInt((form.amount.$modelValue * w.settings.unitToSatoshi).toFixed(0)); var commentText = form.comment.$modelValue; - var w = w; - function done(err, ntxid, merchantData) { if (err) { var message = 'The transaction' + (w.isShared() ? ' proposal' : '') + ' could not be created'; @@ -349,7 +346,6 @@ angular.module('copayApp.controllers').controller('SendController', } $scope.toggleAddressBookEntry = function(key) { - var w = w; w.toggleAddressBookEntry(key); }; @@ -384,7 +380,6 @@ angular.module('copayApp.controllers').controller('SendController', }); modalInstance.result.then(function(entry) { - var w = w; $timeout(function() { $scope.loading = false; @@ -421,7 +416,6 @@ angular.module('copayApp.controllers').controller('SendController', $scope.send = function(ntxid, cb) { $scope.loading = true; $rootScope.txAlertCount = 0; - var w = w; w.sendTx(ntxid, function(txid, merchantData) { if (!txid) { notification.error('Error', 'There was an error sending the transaction'); @@ -446,7 +440,6 @@ angular.module('copayApp.controllers').controller('SendController', $scope.sign = function(ntxid) { $scope.loading = true; - var w = w; w.sign(ntxid, function(ret) { if (!ret) { notification.error('Error', 'There was an error signing the transaction'); @@ -466,7 +459,6 @@ angular.module('copayApp.controllers').controller('SendController', $scope.reject = function(ntxid) { $scope.loading = true; $rootScope.txAlertCount = 0; - var w = w; w.reject(ntxid); notification.warning('Transaction rejected', 'You rejected the transaction successfully'); $scope.loading = false; From fc1d098135e246b57883eaa83ccd9a437af4b4ea Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Tue, 9 Sep 2014 13:00:30 -0700 Subject: [PATCH 038/191] settings: start adding network config at create --- js/controllers/create.js | 1 + views/create.html | 52 +++++++++++++--------------------------- 2 files changed, 17 insertions(+), 36 deletions(-) diff --git a/js/controllers/create.js b/js/controllers/create.js index 81308f51d..341ca9f6a 100644 --- a/js/controllers/create.js +++ b/js/controllers/create.js @@ -41,6 +41,7 @@ angular.module('copayApp.controllers').controller('CreateController', $scope.walletPassword = $rootScope.walletPassword; $scope.isMobile = !!window.cordova; $scope.hideAdv = true; + $scope.networkName = config.networkName; // ng-repeat defined number of times instead of repeating over array? $scope.getNumber = function(num) { diff --git a/views/create.html b/views/create.html index ef54b8301..4479dcb9a 100644 --- a/views/create.html +++ b/views/create.html @@ -25,42 +25,26 @@
- - - + symbols" tooltip-trigger="focus" required tooltip-placement="top"> + +
- + Show Hide advanced options

- +

- +
@@ -78,24 +62,21 @@
- +

(*) The limits are imposed by the bitcoin network.

+
+ + +
- « Back - « Back + « Back + « Back - Next + Next
@@ -103,4 +84,3 @@ - From 520fd762ba080952833b8283fb7550a1f69a996c Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Tue, 9 Sep 2014 15:30:49 -0700 Subject: [PATCH 039/191] settings: added network to wallet secret --- js/models/core/Wallet.js | 10 ++++++++-- js/models/core/WalletFactory.js | 23 +++++++++-------------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/js/models/core/Wallet.js b/js/models/core/Wallet.js index 5fe1611da..56d216ab5 100644 --- a/js/models/core/Wallet.js +++ b/js/models/core/Wallet.js @@ -647,7 +647,11 @@ Wallet.prototype.getSecretNumber = function() { * @return {string} */ Wallet.prototype.getSecret = function() { - var buf = new Buffer(this.getMyCopayerId() + this.getSecretNumber(), 'hex'); + var buf = new Buffer( + this.getMyCopayerId() + + this.getSecretNumber() + + this.getNetworkName() === 'livenet' ? 'L' : 'T', + 'hex'); var str = Base58Check.encode(buf); return str; }; @@ -662,9 +666,11 @@ Wallet.decodeSecret = function(secretB) { var secret = Base58Check.decode(secretB); var pubKeyBuf = secret.slice(0, 33); var secretNumber = secret.slice(33, 38); + var networkName = secret.slice(38, 39) === 'L' ? 'livenet' : 'testnet'; return { pubKey: pubKeyBuf.toString('hex'), - secretNumber: secretNumber.toString('hex') + secretNumber: secretNumber.toString('hex'), + networkName: networkName, } }; diff --git a/js/models/core/WalletFactory.js b/js/models/core/WalletFactory.js index e205896e6..3902d6763 100644 --- a/js/models/core/WalletFactory.js +++ b/js/models/core/WalletFactory.js @@ -44,7 +44,6 @@ function WalletFactory(config, version) { this.network = new this.Network(config.network); this.blockchain = new this.Blockchain(config.network); - this.networkName = config.networkName; this.walletDefaults = config.wallet; this.version = version; }; @@ -82,9 +81,6 @@ WalletFactory.prototype.fromObj = function(obj, skipFields) { // not stored options obj.opts.reconnectDelay = this.walletDefaults.reconnectDelay; - // this is only used if private key or public key ring is skipped - obj.opts.networkName = this.networkName; - skipFields = skipFields || []; skipFields.forEach(function(k) { if (obj[k]) { @@ -178,7 +174,7 @@ WalletFactory.prototype.create = function(opts) { log.debug('### CREATING NEW WALLET.' + (opts.id ? ' USING ID: ' + opts.id : ' NEW ID') + (opts.privateKey ? ' USING PrivateKey: ' + opts.privateKey.getId() : ' NEW PrivateKey')); var privOpts = { - networkName: this.networkName, + networkName: opts.networkName, }; if (opts.privateKeyHex && opts.privateKeyHex.length > 1) { @@ -192,7 +188,7 @@ WalletFactory.prototype.create = function(opts) { opts.lockTimeoutMin = this.walletDefaults.idleDurationMin; opts.publicKeyRing = opts.publicKeyRing || new PublicKeyRing({ - networkName: this.networkName, + networkName: opts.networkName, requiredCopayers: requiredCopayers, totalCopayers: totalCopayers, }); @@ -203,7 +199,7 @@ WalletFactory.prototype.create = function(opts) { log.debug('\t### PublicKeyRing Initialized'); opts.txProposals = opts.txProposals || new TxProposals({ - networkName: this.networkName, + networkName: opts.networkName, }); log.debug('\t### TxProposals Initialized'); @@ -332,11 +328,11 @@ WalletFactory.prototype.decodeSecret = function(secret) { */ WalletFactory.prototype.joinCreateSession = function(secret, nickname, passphrase, privateHex, cb) { var self = this; - var s = self.decodeSecret(secret); - if (!s) return cb('badSecret'); + var decodedSecret = self.decodeSecret(secret); + if (!decodedSecret) return cb('badSecret'); var privOpts = { - networkName: this.networkName, + networkName: decodedSecret.networkName, }; if (privateHex && privateHex.length > 1) { @@ -350,7 +346,7 @@ WalletFactory.prototype.joinCreateSession = function(secret, nickname, passphras copayerId: privateKey.getId(), privkey: privateKey.getIdPriv(), key: privateKey.getIdKey(), - secretNumber: s.secretNumber, + secretNumber: decodedSecret.secretNumber, }; self.network.cleanUp(); @@ -365,7 +361,7 @@ WalletFactory.prototype.joinCreateSession = function(secret, nickname, passphras }); self.network.start(opts, function() { - self.network.greet(s.pubKey, opts.secretNumber); + self.network.greet(decodedSecret.pubKey, opts.secretNumber); self.network.on('data', function(sender, data) { if (data.type === 'walletId') { if (data.networkName !== self.networkName) { @@ -377,8 +373,7 @@ WalletFactory.prototype.joinCreateSession = function(secret, nickname, passphras data.opts.passphrase = passphrase; data.opts.id = data.walletId; var w = self.create(data.opts); - w.sendWalletReady(s.pubKey); - //w.seedCopayer(s.pubKey); + w.sendWalletReady(decodedSecret.pubKey); return cb(null, w); } else { return cb('walletFull', w); From 7159cdb7127fad5f4dd320393cb613a7bf408105 Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Tue, 9 Sep 2014 17:08:59 -0700 Subject: [PATCH 040/191] settings: added test for new secret scheme --- js/controllers/join.js | 2 +- js/models/core/Wallet.js | 4 ++-- js/models/core/WalletFactory.js | 2 +- test/test.Wallet.js | 11 +++++++++++ 4 files changed, 15 insertions(+), 4 deletions(-) diff --git a/js/controllers/join.js b/js/controllers/join.js index d94c24354..37fbf3a70 100644 --- a/js/controllers/join.js +++ b/js/controllers/join.js @@ -129,7 +129,7 @@ angular.module('copayApp.controllers').controller('JoinController', else if (err === 'walletFull') notification.error('The wallet is full'); else if (err === 'badNetwork') - notification.error('Network Error', 'The wallet your are trying to join uses a different Bitcoin Network. Check your settings.'); + notification.error('Network Error', 'Wallet network configuration missmatch'); else if (err === 'badSecret') notification.error('Bad secret', 'The secret string you entered is invalid'); else diff --git a/js/models/core/Wallet.js b/js/models/core/Wallet.js index 56d216ab5..36d70fef1 100644 --- a/js/models/core/Wallet.js +++ b/js/models/core/Wallet.js @@ -650,7 +650,7 @@ Wallet.prototype.getSecret = function() { var buf = new Buffer( this.getMyCopayerId() + this.getSecretNumber() + - this.getNetworkName() === 'livenet' ? 'L' : 'T', + (this.getNetworkName() === 'livenet' ? '00' : '01'), 'hex'); var str = Base58Check.encode(buf); return str; @@ -666,7 +666,7 @@ Wallet.decodeSecret = function(secretB) { var secret = Base58Check.decode(secretB); var pubKeyBuf = secret.slice(0, 33); var secretNumber = secret.slice(33, 38); - var networkName = secret.slice(38, 39) === 'L' ? 'livenet' : 'testnet'; + var networkName = secret.slice(38, 39).toString('hex') === '00' ? 'livenet' : 'testnet'; return { pubKey: pubKeyBuf.toString('hex'), secretNumber: secretNumber.toString('hex'), diff --git a/js/models/core/WalletFactory.js b/js/models/core/WalletFactory.js index 3902d6763..482b57c37 100644 --- a/js/models/core/WalletFactory.js +++ b/js/models/core/WalletFactory.js @@ -364,7 +364,7 @@ WalletFactory.prototype.joinCreateSession = function(secret, nickname, passphras self.network.greet(decodedSecret.pubKey, opts.secretNumber); self.network.on('data', function(sender, data) { if (data.type === 'walletId') { - if (data.networkName !== self.networkName) { + if (data.networkName !== decodedSecret.networkName) { return cb('badNetwork'); } diff --git a/test/test.Wallet.js b/test/test.Wallet.js index e32698b3e..26498c1e4 100644 --- a/test/test.Wallet.js +++ b/test/test.Wallet.js @@ -362,7 +362,18 @@ describe('Wallet model', function() { var s = Wallet.decodeSecret(sb); s.pubKey.should.equal(id); s.secretNumber.should.equal(secretNumber); + s.networkName.should.equal(w.getNetworkName()); + }); + it('#getSecret decodeSecret livenet', function() { + var w = cachedCreateW2(); + var stub = sinon.stub(w, 'getNetworkName'); + stub.returns('livenet'); + var sb = w.getSecret(); + should.exist(sb); + var s = Wallet.decodeSecret(sb); + s.networkName.should.equal('livenet'); + stub.restore(); }); From b2fb48683959bc954d1bba79beafec4445223ebe Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Tue, 9 Sep 2014 17:15:52 -0700 Subject: [PATCH 041/191] settings: remove _checkNetwork in WalletFactory --- js/controllers/create.js | 1 + js/models/core/WalletFactory.js | 13 ------------- 2 files changed, 1 insertion(+), 13 deletions(-) diff --git a/js/controllers/create.js b/js/controllers/create.js index 341ca9f6a..52db78e95 100644 --- a/js/controllers/create.js +++ b/js/controllers/create.js @@ -84,6 +84,7 @@ angular.module('copayApp.controllers').controller('CreateController', nickname: $scope.myNickname, passphrase: passphrase, privateKeyHex: $scope.private, + networkName: $scope.networkName, }; var w = walletFactory.create(opts); controllerUtils.startNetwork(w, $scope); diff --git a/js/models/core/WalletFactory.js b/js/models/core/WalletFactory.js index 482b57c37..9f0945b45 100644 --- a/js/models/core/WalletFactory.js +++ b/js/models/core/WalletFactory.js @@ -26,7 +26,6 @@ var StorageLocalEncrypted = module.exports.StorageLocalEncrypted = require('../s * @param {Object} config.network - the configuration to be sent to the Network constructor * @param {Blockchain} config.Blockchain - the class to instantiate to get information about the blockchain (Insight by default) * @param {Object} config.blockchain - the configuration to be sent to the Blockchain constructor - * @param {string} config.networkName - the name of the bitcoin network to use ('testnet' or 'livenet') * @TODO: Investigate what parameters go inside this object * @param {Object} config.wallet - default configuration for the wallet * @TODO: put `version` inside of the config object @@ -92,7 +91,6 @@ WalletFactory.prototype.fromObj = function(obj, skipFields) { var w = Wallet.fromObj(obj, this.storage, this.network, this.blockchain); if (!w) return false; this._checkVersion(w.version); - this._checkNetwork(w.getNetworkName()); return w; }; @@ -241,17 +239,6 @@ WalletFactory.prototype._checkVersion = function(inVersion) { } }; -/** - * @desc Throw an error if the network name is different to {@link WalletFactory#networkName} - * @param {string} inNetworkName - the network name to check - * @throws {Error} - */ -WalletFactory.prototype._checkNetwork = function(inNetworkName) { - if (this.networkName !== inNetworkName) { - throw new Error('This Wallet is configured for ' + inNetworkName + ' while currently Copay is configured for: ' + this.networkName + '. Check your settings.'); - } -}; - /** * @desc Retrieve a wallet from the storage * @param {string} walletId - the id of the wallet From a619970b489bedf3adc36c6242d060f151c02d97 Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Tue, 9 Sep 2014 17:49:53 -0700 Subject: [PATCH 042/191] settings: view refactor --- views/create.html | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/views/create.html b/views/create.html index 4479dcb9a..ddc4c6ce8 100644 --- a/views/create.html +++ b/views/create.html @@ -33,6 +33,11 @@ symbols" tooltip-trigger="focus" required tooltip-placement="top"> + +
+ + +
@@ -66,10 +71,6 @@

(*) The limits are imposed by the bitcoin network.

-
- - -
« Back « Back From 566b746ffd514eaecf428b8ed2ce3aa87b83d790 Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Tue, 9 Sep 2014 17:52:15 -0700 Subject: [PATCH 043/191] settings: one network config per bitcoin network --- config.js | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/config.js b/config.js index ab1beb0a8..7bc8ae06c 100644 --- a/config.js +++ b/config.js @@ -15,9 +15,16 @@ var defaultConfig = { // network layer config network: { - host: 'test-insight.bitpay.com', - port: 443, - schema: 'https' + testnet: { + host: 'test-insight.bitpay.com', + port: 443, + schema: 'https' + }, + livenet: { + host: 'insight.bitpay.com', + port: 443, + schema: 'https' + }, }, // wallet default config From 76f3b1c3211a958e280175d965a30085b5dba4b5 Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Wed, 10 Sep 2014 11:12:28 -0700 Subject: [PATCH 044/191] settings: maintain livenet and testnet simultainously --- js/controllers/open.js | 1 + js/models/core/Wallet.js | 1 + js/models/core/WalletFactory.js | 66 +++++++++++++++++++++++---------- 3 files changed, 49 insertions(+), 19 deletions(-) diff --git a/js/controllers/open.js b/js/controllers/open.js index 019932988..fb3c01ac4 100644 --- a/js/controllers/open.js +++ b/js/controllers/open.js @@ -37,6 +37,7 @@ angular.module('copayApp.controllers').controller('OpenController', function($sc try { w = walletFactory.open($scope.selectedWalletId, passphrase); } catch (e) { + throw e; errMsg = e.message; }; if (!w) { diff --git a/js/models/core/Wallet.js b/js/models/core/Wallet.js index 36d70fef1..056691994 100644 --- a/js/models/core/Wallet.js +++ b/js/models/core/Wallet.js @@ -602,6 +602,7 @@ Wallet.prototype._optsToObj = function() { totalCopayers: this.totalCopayers, name: this.name, version: this.version, + networkName: this.getNetworkName(), }; return obj; diff --git a/js/models/core/WalletFactory.js b/js/models/core/WalletFactory.js index 9f0945b45..818a40a63 100644 --- a/js/models/core/WalletFactory.js +++ b/js/models/core/WalletFactory.js @@ -23,9 +23,8 @@ var StorageLocalEncrypted = module.exports.StorageLocalEncrypted = require('../s * @param {Storage} config.Storage - the class to instantiate to store the wallet (StorageLocalEncrypted by default) * @param {Object} config.storage - the configuration to be sent to the Storage constructor * @param {Network} config.Network - the class to instantiate to make network requests to copayers (the Async module by default) - * @param {Object} config.network - the configuration to be sent to the Network constructor + * @param {Object} config.network - the configurations to be sent to the Network and Blockchain constructors * @param {Blockchain} config.Blockchain - the class to instantiate to get information about the blockchain (Insight by default) - * @param {Object} config.blockchain - the configuration to be sent to the Blockchain constructor * @TODO: Investigate what parameters go inside this object * @param {Object} config.wallet - default configuration for the wallet * @TODO: put `version` inside of the config object @@ -40,8 +39,14 @@ function WalletFactory(config, version) { this.Blockchain = config.Blockchain || Insight; this.storage = new this.Storage(config.storage); - this.network = new this.Network(config.network); - this.blockchain = new this.Blockchain(config.network); + this.networks = { + 'livenet': new this.Network(config.network.livenet), + 'testnet': new this.Network(config.network.testnet), + }; + this.blockchains = { + 'livenet': new this.Blockchain(config.network.livenet), + 'testnet': new this.Blockchain(config.network.testnet), + }; this.walletDefaults = config.wallet; this.version = version; @@ -69,15 +74,29 @@ WalletFactory.prototype._checkRead = function(walletId) { return !!ret; }; +/** + * @desc obtain network name from serialized wallet + * @param {Object} wallet object + * @return {string} network name + */ +WalletFactory.prototype.obtainNetworkName = function(obj) { + console.log(JSON.stringify(obj)); + return obj.networkName || + obj.opts.networkName || + obj.publicKeyRing.networkName || + obj.privateKey.networkName; +}; + /** * @desc Deserialize an object to a Wallet - * @param {Object} obj + * @param {Object} wallet object * @param {string[]} skipFields - fields to skip when importing * @return {Wallet} */ WalletFactory.prototype.fromObj = function(obj, skipFields) { + var networkName = this.obtainNetworkName(obj); + preconditions.checkState(networkName); - // not stored options obj.opts.reconnectDelay = this.walletDefaults.reconnectDelay; skipFields = skipFields || []; @@ -88,7 +107,9 @@ WalletFactory.prototype.fromObj = function(obj, skipFields) { throw new Error('unknown field:' + k); }); - var w = Wallet.fromObj(obj, this.storage, this.network, this.blockchain); + alert(networkName); + + var w = Wallet.fromObj(obj, this.storage, this.networks[networkName], this.blockchains[networkName]); if (!w) return false; this._checkVersion(w.version); return w; @@ -168,7 +189,9 @@ WalletFactory.prototype.read = function(walletId, skipFields) { * @return {Wallet} */ WalletFactory.prototype.create = function(opts) { - opts = opts || {}; + preconditions.checkArgument(opts); + preconditions.checkArgument(opts.networkName); + log.debug('### CREATING NEW WALLET.' + (opts.id ? ' USING ID: ' + opts.id : ' NEW ID') + (opts.privateKey ? ' USING PrivateKey: ' + opts.privateKey.getId() : ' NEW PrivateKey')); var privOpts = { @@ -204,8 +227,8 @@ WalletFactory.prototype.create = function(opts) { this.storage._setPassphrase(opts.passphrase); opts.storage = this.storage; - opts.network = this.network; - opts.blockchain = this.blockchain; + opts.network = this.networks[opts.networkName]; + opts.blockchain = this.blockchains[opts.networkName]; opts.spendUnconfirmed = opts.spendUnconfirmed || this.walletDefaults.spendUnconfirmed; opts.reconnectDelay = opts.reconnectDelay || this.walletDefaults.reconnectDelay; @@ -248,8 +271,9 @@ WalletFactory.prototype._checkVersion = function(inVersion) { WalletFactory.prototype.open = function(walletId, passphrase) { this.storage._setPassphrase(passphrase); var w = this.read(walletId); - if (w) + if (w) { w.store(); + } this.storage.setLastOpened(walletId); return w; @@ -315,8 +339,10 @@ WalletFactory.prototype.decodeSecret = function(secret) { */ WalletFactory.prototype.joinCreateSession = function(secret, nickname, passphrase, privateHex, cb) { var self = this; - var decodedSecret = self.decodeSecret(secret); - if (!decodedSecret) return cb('badSecret'); + var decodedSecret = this.decodeSecret(secret); + if (!decodedSecret || !decodedSecret.networkName || !decodedSecret.pubkey) { + return cb('badSecret'); + } var privOpts = { networkName: decodedSecret.networkName, @@ -335,21 +361,23 @@ WalletFactory.prototype.joinCreateSession = function(secret, nickname, passphras key: privateKey.getIdKey(), secretNumber: decodedSecret.secretNumber, }; - self.network.cleanUp(); + + var joinNetwork = this.networks[decodedSecret.networkName]; + joinNetwork.cleanUp(); // This is a hack to reconize if the connection was rejected or the peer wasn't there. var connectedOnce = false; - self.network.on('connected', function(sender, data) { + joinNetwork.on('connected', function(sender, data) { connectedOnce = true; }); - self.network.on('serverError', function() { + joinNetwork.on('serverError', function() { return cb('joinError'); }); - self.network.start(opts, function() { - self.network.greet(decodedSecret.pubKey, opts.secretNumber); - self.network.on('data', function(sender, data) { + joinNetwork.start(opts, function() { + joinNetwork.greet(decodedSecret.pubKey, opts.secretNumber); + joinNetwork.on('data', function(sender, data) { if (data.type === 'walletId') { if (data.networkName !== decodedSecret.networkName) { return cb('badNetwork'); From 4cfe87490fe078f2b2ca5c825b8398857a2cd31d Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Wed, 10 Sep 2014 11:47:41 -0700 Subject: [PATCH 045/191] settings: show wallet network on sidebar --- js/controllers/open.js | 1 - js/controllers/version.js | 6 ++++-- js/models/core/WalletFactory.js | 3 --- views/includes/version.html | 2 +- 4 files changed, 5 insertions(+), 7 deletions(-) diff --git a/js/controllers/open.js b/js/controllers/open.js index fb3c01ac4..019932988 100644 --- a/js/controllers/open.js +++ b/js/controllers/open.js @@ -37,7 +37,6 @@ angular.module('copayApp.controllers').controller('OpenController', function($sc try { w = walletFactory.open($scope.selectedWalletId, passphrase); } catch (e) { - throw e; errMsg = e.message; }; if (!w) { diff --git a/js/controllers/version.js b/js/controllers/version.js index f61e7af4b..5adfafd7a 100644 --- a/js/controllers/version.js +++ b/js/controllers/version.js @@ -3,9 +3,11 @@ angular.module('copayApp.controllers').controller('VersionController', function($scope, $rootScope, $http, notification) { + var w = $rootScope.wallet; + $scope.version = copay.version; $scope.commitHash = copay.commitHash; - $scope.networkName = config.networkName; + $scope.networkName = w ? w.getNetworkName() : ''; $scope.defaultLanguage = config.defaultLanguage; if (_.isUndefined($rootScope.checkVersion)) $rootScope.checkVersion = true; @@ -30,4 +32,4 @@ angular.module('copayApp.controllers').controller('VersionController', }); } - }); \ No newline at end of file + }); diff --git a/js/models/core/WalletFactory.js b/js/models/core/WalletFactory.js index 818a40a63..ab57dcea7 100644 --- a/js/models/core/WalletFactory.js +++ b/js/models/core/WalletFactory.js @@ -80,7 +80,6 @@ WalletFactory.prototype._checkRead = function(walletId) { * @return {string} network name */ WalletFactory.prototype.obtainNetworkName = function(obj) { - console.log(JSON.stringify(obj)); return obj.networkName || obj.opts.networkName || obj.publicKeyRing.networkName || @@ -107,8 +106,6 @@ WalletFactory.prototype.fromObj = function(obj, skipFields) { throw new Error('unknown field:' + k); }); - alert(networkName); - var w = Wallet.fromObj(obj, this.storage, this.networks[networkName], this.blockchains[networkName]); if (!w) return false; this._checkVersion(w.version); diff --git a/views/includes/version.html b/views/includes/version.html index a554d6bcf..55e19d99c 100644 --- a/views/includes/version.html +++ b/views/includes/version.html @@ -1,6 +1,6 @@
v{{version}} ({{defaultLanguage}}) #{{commitHash}} - [ {{networkName}} ] + [ {{networkName}} ]
From 2aa2d89f92d0617b5b649d52f553824ed6015c25 Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Wed, 10 Sep 2014 11:49:16 -0700 Subject: [PATCH 046/191] settings: simple insight config --- config.js | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/config.js b/config.js index 7bc8ae06c..39fa2cbbb 100644 --- a/config.js +++ b/config.js @@ -16,14 +16,10 @@ var defaultConfig = { // network layer config network: { testnet: { - host: 'test-insight.bitpay.com', - port: 443, - schema: 'https' + url: 'https://test-insight.bitpay.com:443' }, livenet: { - host: 'insight.bitpay.com', - port: 443, - schema: 'https' + url: 'https:insight.bitpay.com:443' }, }, From 423348f5ec2b86e528a5d3fa1dc028817698767b Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Wed, 10 Sep 2014 11:56:33 -0700 Subject: [PATCH 047/191] settings: simple insight config controller and view --- js/controllers/settings.js | 21 ++++++++------------- views/settings.html | 14 ++++++-------- 2 files changed, 14 insertions(+), 21 deletions(-) diff --git a/js/controllers/settings.js b/js/controllers/settings.js index 620a06e36..135b5ae34 100644 --- a/js/controllers/settings.js +++ b/js/controllers/settings.js @@ -4,10 +4,9 @@ angular.module('copayApp.controllers').controller('SettingsController', function controllerUtils.redirIfLogged(); $scope.title = 'Settings'; - $scope.insightHost = config.network.host; - $scope.insightPort = config.network.port; - $scope.insightSecure = config.network.schema === 'https'; $scope.defaultLanguage = config.defaultLanguage || 'en'; + $scope.insightLivenet = config.network.livenet.url; + $scope.insightTestnet = config.network.testnet.url; $scope.availableLanguages = [{ name: 'English', @@ -24,18 +23,14 @@ angular.module('copayApp.controllers').controller('SettingsController', function } } - $scope.changeInsightSSL = function() { - $scope.insightPort = $scope.insightSecure ? 80 : 443; - }; - - $scope.save = function() { - var network = config.network; - var insightSettings = { - host: $scope.insightHost, - port: $scope.insightPort, - schema: $scope.insightSecure ? 'https' : 'http', + livenet: { + url: $scope.insightLivenet, + }, + testnet: { + url: $scope.insightTestnet, + }, } localStorage.setItem('config', JSON.stringify({ diff --git a/views/settings.html b/views/settings.html index aee27ab81..b80b53707 100644 --- a/views/settings.html +++ b/views/settings.html @@ -14,16 +14,14 @@
- Insight API server - - - - - - + Insight API servers + + + +

- Insight API server is open-source software. You can run your own instance, check Insight API Homepage + Insight API server is open-source software. You can run your own instances, check Insight API Homepage

From 997c061b1a25ced69776669e647372fb896e37f8 Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Wed, 10 Sep 2014 12:36:33 -0700 Subject: [PATCH 048/191] settings: change Insight.js opts --- config.js | 2 +- js/models/blockchain/Insight.js | 13 +++++-------- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/config.js b/config.js index 39fa2cbbb..a22baad87 100644 --- a/config.js +++ b/config.js @@ -19,7 +19,7 @@ var defaultConfig = { url: 'https://test-insight.bitpay.com:443' }, livenet: { - url: 'https:insight.bitpay.com:443' + url: 'https://insight.bitpay.com:443' }, }, diff --git a/js/models/blockchain/Insight.js b/js/models/blockchain/Insight.js index b4d928c4c..aa53fb560 100644 --- a/js/models/blockchain/Insight.js +++ b/js/models/blockchain/Insight.js @@ -15,9 +15,7 @@ var preconditions = require('preconditions').singleton(); subscribing to transactions on adressess and blocks. Opts: - - host - - port - - schema + - url - reconnection (optional) - reconnectionDelay (optional) @@ -31,19 +29,18 @@ var preconditions = require('preconditions').singleton(); var Insight = function(opts) { preconditions.checkArgument(opts) .shouldBeObject(opts) - .checkArgument(opts.host) - .checkArgument(opts.port) - .checkArgument(opts.schema); + .checkArgument(opts.url) this.status = this.STATUS.DISCONNECTED; this.subscribed = {}; this.listeningBlocks = false; - this.url = opts.schema + '://' + opts.host + ':' + opts.port; + this.url = opts.url; + alert(this.url); this.opts = { 'reconnection': opts.reconnection || true, 'reconnectionDelay': opts.reconnectionDelay || 1000, - 'secure': opts.schema === 'https' + 'secure': opts.url.indexOf('https') > -1 }; this.socket = this.getSocket(); From 6152227668ef715da15efd991a3d6f7d60fd681f Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Wed, 10 Sep 2014 13:09:57 -0700 Subject: [PATCH 049/191] settings: change Async.js opts --- js/models/blockchain/Insight.js | 1 - js/models/network/Async.js | 22 +++++++++------------- 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/js/models/blockchain/Insight.js b/js/models/blockchain/Insight.js index aa53fb560..e7da834fc 100644 --- a/js/models/blockchain/Insight.js +++ b/js/models/blockchain/Insight.js @@ -36,7 +36,6 @@ var Insight = function(opts) { this.listeningBlocks = false; this.url = opts.url; - alert(this.url); this.opts = { 'reconnection': opts.reconnection || true, 'reconnectionDelay': opts.reconnectionDelay || 1000, diff --git a/js/models/network/Async.js b/js/models/network/Async.js index c6d001b7d..695e8ae78 100644 --- a/js/models/network/Async.js +++ b/js/models/network/Async.js @@ -14,9 +14,7 @@ function Network(opts) { var self = this; opts = opts || {}; this.maxPeers = opts.maxPeers || 12; - this.host = opts.host || 'localhost'; - this.port = opts.port || 3001; - this.schema = opts.schema || 'https'; + this.url = opts.url || 'http//localhost:30001'; this.secretNumber = opts.secretNumber; this.cleanUp(); } @@ -74,12 +72,12 @@ Network.prototype.connectedCopayers = function() { return ret; }; -Network.prototype._sendHello = function(copayerId,secretNumber) { +Network.prototype._sendHello = function(copayerId, secretNumber) { this.send(copayerId, { type: 'hello', copayerId: this.copayerId, - secretNumber : secretNumber + secretNumber: secretNumber }); }; @@ -197,11 +195,10 @@ Network.prototype._onMessage = function(enc) { var self = this; switch (payload.type) { case 'hello': - if (typeof payload.secretNumber === 'undefined' || payload.secretNumber !== this.secretNumber) - { + if (typeof payload.secretNumber === 'undefined' || payload.secretNumber !== this.secretNumber) { this._sendRejectConnection(sender); this._deletePeer(enc.pubkey, 'incorrect secret number'); - return; + return; } // if we locked allowed copayers, check if it belongs if (this.allowedCopayerIds && !this.allowedCopayerIds[payload.copayerId]) { @@ -274,8 +271,8 @@ Network.prototype._onError = function(err) { this.criticalError = err.message; }; -Network.prototype.greet = function(copayerId,secretNumber) { - this._sendHello(copayerId,secretNumber); +Network.prototype.greet = function(copayerId, secretNumber) { + this._sendHello(copayerId, secretNumber); var peerId = this.peerFromCopayer(copayerId); this._addCopayerMap(peerId, copayerId); }; @@ -326,11 +323,10 @@ Network.prototype.start = function(opts, openCallback) { }; Network.prototype.createSocket = function() { - var hostPort = this.schema + '://' + this.host + ':' + this.port; - return io.connect(hostPort, { + return io.connect(this.url, { reconnection: true, 'force new connection': true, - 'secure': this.schema === 'https', + 'secure': this.url.indexOf('https') > -1, }); }; From 4931f08b5fffa9251ccab6b775764fd97e7575ab Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Wed, 10 Sep 2014 13:10:10 -0700 Subject: [PATCH 050/191] settings: change default config --- config.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config.js b/config.js index a22baad87..cdcac0c01 100644 --- a/config.js +++ b/config.js @@ -16,10 +16,10 @@ var defaultConfig = { // network layer config network: { testnet: { - url: 'https://test-insight.bitpay.com:443' + url: 'https://test-insight.bitpay.com' }, livenet: { - url: 'https://insight.bitpay.com:443' + url: 'https://insight.bitpay.com' }, }, From 56db2bebcf0df0c60e30d65cb69da1d0a5ef72f0 Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Wed, 10 Sep 2014 13:15:19 -0700 Subject: [PATCH 051/191] settings: change default config --- config.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config.js b/config.js index cdcac0c01..a22baad87 100644 --- a/config.js +++ b/config.js @@ -16,10 +16,10 @@ var defaultConfig = { // network layer config network: { testnet: { - url: 'https://test-insight.bitpay.com' + url: 'https://test-insight.bitpay.com:443' }, livenet: { - url: 'https://insight.bitpay.com' + url: 'https://insight.bitpay.com:443' }, }, From 91033f3fcb0a5b8a25fa8f3d3169a9fa44a17f36 Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Wed, 10 Sep 2014 13:46:20 -0700 Subject: [PATCH 052/191] settings: fix tests 1 --- test/test.blockchain.Insight.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test/test.blockchain.Insight.js b/test/test.blockchain.Insight.js index 730d837f6..032725f18 100644 --- a/test/test.blockchain.Insight.js +++ b/test/test.blockchain.Insight.js @@ -40,9 +40,7 @@ var UNSPENT = [{ }]; var FAKE_OPTS = { - host: 'something.com', - port: 123, - schema: 'http' + url: 'http://something.com:123', } describe('Insight model', function() { From 28dff691fd6d6279fb2c44c8ef5c2b89e61ac1f4 Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Wed, 10 Sep 2014 13:56:49 -0700 Subject: [PATCH 053/191] settings: fix tests 2 --- js/models/core/WalletFactory.js | 6 ++++-- test/test.WalletFactory.js | 21 +++++++++++---------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/js/models/core/WalletFactory.js b/js/models/core/WalletFactory.js index ab57dcea7..767f5f290 100644 --- a/js/models/core/WalletFactory.js +++ b/js/models/core/WalletFactory.js @@ -9,6 +9,7 @@ var log = require('../../log'); var Async = module.exports.Async = require('../network/Async'); var Insight = module.exports.Insight = require('../blockchain/Insight'); var StorageLocalEncrypted = module.exports.StorageLocalEncrypted = require('../storage/LocalEncrypted'); +var preconditions = require('preconditions').singleton(); /** * @desc @@ -186,8 +187,9 @@ WalletFactory.prototype.read = function(walletId, skipFields) { * @return {Wallet} */ WalletFactory.prototype.create = function(opts) { - preconditions.checkArgument(opts); - preconditions.checkArgument(opts.networkName); + + opts = opts || {}; + opts.networkName = opts.networkName || 'testnet'; log.debug('### CREATING NEW WALLET.' + (opts.id ? ' USING ID: ' + opts.id : ' NEW ID') + (opts.privateKey ? ' USING PrivateKey: ' + opts.privateKey.getId() : ' NEW PrivateKey')); diff --git a/test/test.WalletFactory.js b/test/test.WalletFactory.js index f683093e2..1ed6b3bd1 100644 --- a/test/test.WalletFactory.js +++ b/test/test.WalletFactory.js @@ -94,12 +94,14 @@ describe('WalletFactory model', function() { totalCopayers: 5, spendUnconfirmed: 1, reconnectDelay: 100, - }, - blockchain: { - host: 'test.insight.is', - port: 80, - schema: 'https' + network: { + testnet: { + url: 'https://test-insight.bitpay.com:443' + }, + livenet: { + url: 'https://insight.bitpay.com:443' + }, }, networkName: 'testnet', passphrase: { @@ -111,7 +113,6 @@ describe('WalletFactory model', function() { it('should create the factory', function() { var wf = new WalletFactory(config, '0.0.1'); should.exist(wf); - wf.networkName.should.equal(config.networkName); wf.walletDefaults.should.deep.equal(config.wallet); wf.version.should.equal('0.0.1'); }); @@ -203,7 +204,7 @@ describe('WalletFactory model', function() { it('support old index schema: #fromObj #toObj round trip', function() { var o3 = '{"opts":{"id":"dbfe10c3fae71cea","spendUnconfirmed":1,"requiredCopayers":3,"totalCopayers":5,"version":"0.0.5"},"networkNonce":"0000000000000001","networkNonces":[],"publicKeyRing":{"walletId":"dbfe10c3fae71cea","networkName":"testnet","requiredCopayers":3,"totalCopayers":5,"indexes":{"changeIndex":0,"receiveIndex":0},"copayersBackup":[],"copayersExtPubKeys":["tpubD6NzVbkrYhZ4YGK8ZhZ8WVeBXNAAoTYjjpw9twCPiNGrGQYFktP3iVQkKmZNiFnUcAFMJRxJVJF6Nq9MDv2kiRceExJaHFbxUCGUiRhmy97","tpubD6NzVbkrYhZ4YKGDJkzWdQsQV3AcFemaQKiwNhV4RL8FHnBFvinidGdQtP8RKj3h34E65RkdtxjrggZYqsEwJ8RhhN2zz9VrjLnrnwbXYNc","tpubD6NzVbkrYhZ4YkDiewjb32Pp3Sz9WK2jpp37KnL7RCrHAyPpnLfgdfRnTdpn6DTWmPS7niywfgWiT42aJb1J6CjWVNmkgsMCxuw7j9DaGKB","tpubD6NzVbkrYhZ4XEtUAz4UUTWbprewbLTaMhR8NUvSJUEAh4Sidxr6rRPFdqqVRR73btKf13wUjds2i8vVCNo8sbKrAnyoTr3o5Y6QSbboQjk","tpubD6NzVbkrYhZ4Yj9AAt6xUVuGPVd8jXCrEE6V2wp7U3PFh8jYYvVad31b4VUXEYXzSnkco4fktu8r4icBsB2t3pCR3WnhVLedY2hxGcPFLKD"],"nicknameFor":{}},"txProposals":{"txps":[],"walletId":"dbfe10c3fae71cea","networkName":"testnet"},"privateKey":{"extendedPrivateKeyString":"tprv8ZgxMBicQKsPeoHLg3tY75z4xLeEe8MqAXLNcRA6J6UTRvHV8VZTXznt9eoTmSk1fwSrwZtMhY3XkNsceJ14h6sCXHSWinRqMSSbY8tfhHi","networkName":"testnet"},"addressBook":{},"settings":{"unitName":"BTC","unitToSatoshi":100000000,"unitDecimals":8,"alternativeName":"Argentine Peso","alternativeIsoCode":"ARS"}}'; - var o4 = '{"opts":{"id":"dbfe10c3fae71cea","spendUnconfirmed":1,"requiredCopayers":3,"totalCopayers":5,"version":"0.0.5"},"networkNonce":"0000000000000001","networkNonces":[],"publicKeyRing":{"walletId":"dbfe10c3fae71cea","networkName":"testnet","requiredCopayers":3,"totalCopayers":5,"indexes":[{"copayerIndex":2147483647,"changeIndex":0,"receiveIndex":0},{"copayerIndex":0,"changeIndex":0,"receiveIndex":0},{"copayerIndex":1,"changeIndex":0,"receiveIndex":0},{"copayerIndex":2,"changeIndex":0,"receiveIndex":0},{"copayerIndex":3,"changeIndex":0,"receiveIndex":0},{"copayerIndex":4,"changeIndex":0,"receiveIndex":0}],"copayersBackup":[],"copayersExtPubKeys":["tpubD6NzVbkrYhZ4YGK8ZhZ8WVeBXNAAoTYjjpw9twCPiNGrGQYFktP3iVQkKmZNiFnUcAFMJRxJVJF6Nq9MDv2kiRceExJaHFbxUCGUiRhmy97","tpubD6NzVbkrYhZ4YKGDJkzWdQsQV3AcFemaQKiwNhV4RL8FHnBFvinidGdQtP8RKj3h34E65RkdtxjrggZYqsEwJ8RhhN2zz9VrjLnrnwbXYNc","tpubD6NzVbkrYhZ4YkDiewjb32Pp3Sz9WK2jpp37KnL7RCrHAyPpnLfgdfRnTdpn6DTWmPS7niywfgWiT42aJb1J6CjWVNmkgsMCxuw7j9DaGKB","tpubD6NzVbkrYhZ4XEtUAz4UUTWbprewbLTaMhR8NUvSJUEAh4Sidxr6rRPFdqqVRR73btKf13wUjds2i8vVCNo8sbKrAnyoTr3o5Y6QSbboQjk","tpubD6NzVbkrYhZ4Yj9AAt6xUVuGPVd8jXCrEE6V2wp7U3PFh8jYYvVad31b4VUXEYXzSnkco4fktu8r4icBsB2t3pCR3WnhVLedY2hxGcPFLKD"],"nicknameFor":{}},"txProposals":{"txps":[],"walletId":"dbfe10c3fae71cea","networkName":"testnet"},"privateKey":{"extendedPrivateKeyString":"tprv8ZgxMBicQKsPeoHLg3tY75z4xLeEe8MqAXLNcRA6J6UTRvHV8VZTXznt9eoTmSk1fwSrwZtMhY3XkNsceJ14h6sCXHSWinRqMSSbY8tfhHi","networkName":"testnet"},"addressBook":{},"settings":{"unitName":"BTC","unitToSatoshi":100000000,"unitDecimals":8,"alternativeName":"Argentine Peso","alternativeIsoCode":"ARS"}}'; + var o4 = '{"opts":{"id":"dbfe10c3fae71cea","spendUnconfirmed":1,"requiredCopayers":3,"totalCopayers":5,"version":"0.0.5","networkName":"testnet"},"networkNonce":"0000000000000001","networkNonces":[],"publicKeyRing":{"walletId":"dbfe10c3fae71cea","networkName":"testnet","requiredCopayers":3,"totalCopayers":5,"indexes":[{"copayerIndex":2147483647,"changeIndex":0,"receiveIndex":0},{"copayerIndex":0,"changeIndex":0,"receiveIndex":0},{"copayerIndex":1,"changeIndex":0,"receiveIndex":0},{"copayerIndex":2,"changeIndex":0,"receiveIndex":0},{"copayerIndex":3,"changeIndex":0,"receiveIndex":0},{"copayerIndex":4,"changeIndex":0,"receiveIndex":0}],"copayersBackup":[],"copayersExtPubKeys":["tpubD6NzVbkrYhZ4YGK8ZhZ8WVeBXNAAoTYjjpw9twCPiNGrGQYFktP3iVQkKmZNiFnUcAFMJRxJVJF6Nq9MDv2kiRceExJaHFbxUCGUiRhmy97","tpubD6NzVbkrYhZ4YKGDJkzWdQsQV3AcFemaQKiwNhV4RL8FHnBFvinidGdQtP8RKj3h34E65RkdtxjrggZYqsEwJ8RhhN2zz9VrjLnrnwbXYNc","tpubD6NzVbkrYhZ4YkDiewjb32Pp3Sz9WK2jpp37KnL7RCrHAyPpnLfgdfRnTdpn6DTWmPS7niywfgWiT42aJb1J6CjWVNmkgsMCxuw7j9DaGKB","tpubD6NzVbkrYhZ4XEtUAz4UUTWbprewbLTaMhR8NUvSJUEAh4Sidxr6rRPFdqqVRR73btKf13wUjds2i8vVCNo8sbKrAnyoTr3o5Y6QSbboQjk","tpubD6NzVbkrYhZ4Yj9AAt6xUVuGPVd8jXCrEE6V2wp7U3PFh8jYYvVad31b4VUXEYXzSnkco4fktu8r4icBsB2t3pCR3WnhVLedY2hxGcPFLKD"],"nicknameFor":{}},"txProposals":{"txps":[],"walletId":"dbfe10c3fae71cea","networkName":"testnet"},"privateKey":{"extendedPrivateKeyString":"tprv8ZgxMBicQKsPeoHLg3tY75z4xLeEe8MqAXLNcRA6J6UTRvHV8VZTXznt9eoTmSk1fwSrwZtMhY3XkNsceJ14h6sCXHSWinRqMSSbY8tfhHi","networkName":"testnet"},"addressBook":{},"settings":{"unitName":"BTC","unitToSatoshi":100000000,"unitDecimals":8,"alternativeName":"Argentine Peso","alternativeIsoCode":"ARS"}}'; var wf = new WalletFactory(config, '0.0.5'); var w = wf.fromObj(JSON.parse(o3)); @@ -408,8 +409,8 @@ describe('WalletFactory model', function() { describe('#joinCreateSession', function() { it('should call network.start', function() { var wf = new WalletFactory(config, '0.0.1'); - wf.network.cleanUp = sinon.spy(); - wf.network.start = sinon.spy(); + wf.networks.testnet.cleanUp = sinon.spy(); + wf.networks.testnet.start = sinon.spy(); wf.joinCreateSession('8WtTuiFTkhP5ao7AF2QErSwV39Cbur6pdMebKzQXFqL59RscXM', 'test'); wf.network.start.calledOnce.should.equal(true); }); @@ -486,7 +487,7 @@ describe('WalletFactory model', function() { }); -var o = '{"opts":{"id":"dbfe10c3fae71cea","spendUnconfirmed":1,"requiredCopayers":3,"totalCopayers":5,"version":"0.0.5"},"networkNonce":"0000000000000001","networkNonces":[],"publicKeyRing":{"walletId":"dbfe10c3fae71cea","networkName":"testnet","requiredCopayers":3,"totalCopayers":5,"indexes":[{"copayerIndex":2,"changeIndex":0,"receiveIndex":0}],"copayersBackup":[],"copayersExtPubKeys":["tpubD6NzVbkrYhZ4YGK8ZhZ8WVeBXNAAoTYjjpw9twCPiNGrGQYFktP3iVQkKmZNiFnUcAFMJRxJVJF6Nq9MDv2kiRceExJaHFbxUCGUiRhmy97","tpubD6NzVbkrYhZ4YKGDJkzWdQsQV3AcFemaQKiwNhV4RL8FHnBFvinidGdQtP8RKj3h34E65RkdtxjrggZYqsEwJ8RhhN2zz9VrjLnrnwbXYNc","tpubD6NzVbkrYhZ4YkDiewjb32Pp3Sz9WK2jpp37KnL7RCrHAyPpnLfgdfRnTdpn6DTWmPS7niywfgWiT42aJb1J6CjWVNmkgsMCxuw7j9DaGKB","tpubD6NzVbkrYhZ4XEtUAz4UUTWbprewbLTaMhR8NUvSJUEAh4Sidxr6rRPFdqqVRR73btKf13wUjds2i8vVCNo8sbKrAnyoTr3o5Y6QSbboQjk","tpubD6NzVbkrYhZ4Yj9AAt6xUVuGPVd8jXCrEE6V2wp7U3PFh8jYYvVad31b4VUXEYXzSnkco4fktu8r4icBsB2t3pCR3WnhVLedY2hxGcPFLKD"],"nicknameFor":{}},"txProposals":{"txps":[],"walletId":"dbfe10c3fae71cea","networkName":"testnet"},"privateKey":{"extendedPrivateKeyString":"tprv8ZgxMBicQKsPeoHLg3tY75z4xLeEe8MqAXLNcRA6J6UTRvHV8VZTXznt9eoTmSk1fwSrwZtMhY3XkNsceJ14h6sCXHSWinRqMSSbY8tfhHi","networkName":"testnet"},"addressBook":{},"settings":{"unitName":"BTC","un itToSatoshi":100000000,"unitDecimals":8,"alternativeName":"Argentine Peso","alternativeIsoCode":"ARS"}}'; +var o = '{"opts":{"id":"dbfe10c3fae71cea","spendUnconfirmed":1,"requiredCopayers":3,"totalCopayers":5,"version":"0.0.5","networkName":"testnet"},"networkNonce":"0000000000000001","networkNonces":[],"publicKeyRing":{"walletId":"dbfe10c3fae71cea","networkName":"testnet","requiredCopayers":3,"totalCopayers":5,"indexes":[{"copayerIndex":2,"changeIndex":0,"receiveIndex":0}],"copayersBackup":[],"copayersExtPubKeys":["tpubD6NzVbkrYhZ4YGK8ZhZ8WVeBXNAAoTYjjpw9twCPiNGrGQYFktP3iVQkKmZNiFnUcAFMJRxJVJF6Nq9MDv2kiRceExJaHFbxUCGUiRhmy97","tpubD6NzVbkrYhZ4YKGDJkzWdQsQV3AcFemaQKiwNhV4RL8FHnBFvinidGdQtP8RKj3h34E65RkdtxjrggZYqsEwJ8RhhN2zz9VrjLnrnwbXYNc","tpubD6NzVbkrYhZ4YkDiewjb32Pp3Sz9WK2jpp37KnL7RCrHAyPpnLfgdfRnTdpn6DTWmPS7niywfgWiT42aJb1J6CjWVNmkgsMCxuw7j9DaGKB","tpubD6NzVbkrYhZ4XEtUAz4UUTWbprewbLTaMhR8NUvSJUEAh4Sidxr6rRPFdqqVRR73btKf13wUjds2i8vVCNo8sbKrAnyoTr3o5Y6QSbboQjk","tpubD6NzVbkrYhZ4Yj9AAt6xUVuGPVd8jXCrEE6V2wp7U3PFh8jYYvVad31b4VUXEYXzSnkco4fktu8r4icBsB2t3pCR3WnhVLedY2hxGcPFLKD"],"nicknameFor":{}},"txProposals":{"txps":[],"walletId":"dbfe10c3fae71cea","networkName":"testnet"},"privateKey":{"extendedPrivateKeyString":"tprv8ZgxMBicQKsPeoHLg3tY75z4xLeEe8MqAXLNcRA6J6UTRvHV8VZTXznt9eoTmSk1fwSrwZtMhY3XkNsceJ14h6sCXHSWinRqMSSbY8tfhHi","networkName":"testnet"},"addressBook":{},"settings":{"unitName":"BTC","un itToSatoshi":100000000,"unitDecimals":8,"alternativeName":"Argentine Peso","alternativeIsoCode":"ARS"}}'; var o2 = '{"opts":{"id":"dbfe10c3fae71cea","spendUnconfirmed":1,"requiredCopayers":3,"totalCopayers":5,"version":"0.0.5"},"networkNonce":"0000000000000001","networkNonces":[],"publicKeyRing":{"walletId":"dbfe10c3fae71cea","networkName":"testnet","requiredCopayers":3,"totalCopayers":5,"indexes":[{"copayerIndex":2147483647,"changeIndex":0,"receiveIndex":0},{"copayerIndex":0,"changeIndex":0,"receiveIndex":0},{"copayerIndex":1,"changeIndex":0,"receiveIndex":0},{"copayerIndex":2,"changeIndex":0,"receiveIndex":0},{"copayerIndex":3,"changeIndex":0,"receiveIndex":0},{"copayerIndex":4,"changeIndex":0,"receiveIndex":0}],"copayersBackup":[],"copayersExtPubKeys":["tpubD6NzVbkrYhZ4YGK8ZhZ8WVeBXNAAoTYjjpw9twCPiNGrGQYFktP3iVQkKmZNiFnUcAFMJRxJVJF6Nq9MDv2kiRceExJaHFbxUCGUiRhmy97","tpubD6NzVbkrYhZ4YKGDJkzWdQsQV3AcFemaQKiwNhV4RL8FHnBFvinidGdQtP8RKj3h34E65RkdtxjrggZYqsEwJ8RhhN2zz9VrjLnrnwbXYNc","tpubD6NzVbkrYhZ4YkDiewjb32Pp3Sz9WK2jpp37KnL7RCrHAyPpnLfgdfRnTdpn6DTWmPS7niywfgWiT42aJb1J6CjWVNmkgsMCxuw7j9DaGKB","tpubD6NzVbkrYhZ4XEtUAz4UUTWbprewbLTaMhR8NUvSJUEAh4Sidxr6rRPFdqqVRR73btKf13wUjds2i8vVCNo8sbKrAnyoTr3o5Y6QSbboQjk","tpubD6NzVbkrYhZ4Yj9AAt6xUVuGPVd8jXCrEE6V2wp7U3PFh8jYYvVad31b4VUXEYXzSnkco4fktu8r4icBsB2t3pCR3WnhVLedY2hxGcPFLKD"],"nicknameFor":{}},"txProposals":{"txps":[],"walletId":"dbfe10c3fae71cea","networkName":"testnet"},"privateKey":{"extendedPrivateKeyString":"tprv8ZgxMBicQKsPeoHLg3tY75z4xLeEe8MqAXLNcRA6J6UTRvHV8VZTXznt9eoTmSk1fwSrwZtMhY3XkNsceJ14h6sCXHSWinRqMSSbY8tfhHi","networkName":"testnet"},"addressBook":{},"settings":{"unitName":"BTC","unitToSatoshi":100000000,"unitDecimals":8,"alternativeName":"Argentine Peso","alternativeIsoCode":"ARS"}}'; var legacyO = '{"opts":{"id":"55d4bd062d32f90a","spendUnconfirmed":true,"requiredCopayers":2,"totalCopayers":2,"name":"xcvzxcv","version":"0.3.2"},"networkNonce":"53d25e8600000009","networkNonces":[],"publicKeyRing":{"walletId":"55d4bd062d32f90a","networkName":"testnet","requiredCopayers":2,"totalCopayers":2,"indexes":[{"copayerIndex":2147483647,"changeIndex":0,"receiveIndex":0},{"copayerIndex":0,"changeIndex":4,"receiveIndex":2},{"copayerIndex":1,"changeIndex":5,"receiveIndex":2}],"copayersBackup":["02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba","02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5"],"copayersExtPubKeys":["tpubD94LTzAUiW99mpA59nyf6fAHh4xKGmnwbgCV4gU2bRpeN9CRiMSurqme22px5NmJAo6FdcdH883Zu98VbqyhesCJ86kUEjH3Zpufy5FfcaC","tpubDA2U9H6LkRHDRbRxHBp4VTbxPc7JqsvtcLxrE5QJF8z1iT6hMJ1pXSVf57GWRcxXutYvpoXRurDVGsscJauMtnJBkYAWBVExYmm91XQE2zz"],"nicknameFor":{"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":"asdf","02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":"qwerqw"},"publicKeysCache":{"m/0/0/0":["028a4b63f26253f3a8731577b8e1ee480950ad5833ebbf106fe3463bfc07cc3b90","0332efa054c08cb77506a35ee0762cb7156f244566703ec08e433568ec0397bec8"],"m/1/0/0":["0220ad514cf593d0c3905d3bb49bc5767a9410823bf9b77ea5ef2cf1d1016d77a8","02fd42cf66f1dbdc7bbb9ae09aecea72df479ffe5a0c4641301067e331d12e416d"],"m/1/0/1":["0315f7868eaf1f9b7127e3f7e0222c5e473eea003e34700f4758b6873c525d6723","02a2e8ed5e90dd39e3842fc790e06178997dbca319987f365317589e2a71a93658"],"m/0/1/0":["0244a25a0b97b26707fd855c15b046b901be85a3b70a781d0678608e633440eeca","0358cdcbc528ddfb7173b0dab283f702be82546ff031e4a832a7270080cb875959"],"m/0/1/1":["025c9b49bdf17d97bd82ea1b87793082f857247f0f9b999937a166ec994bb1b41f","020389327ee8ae7d0ee3f8187842d23a4070bdd8a27c0bcddd05d80ef39009253d"],"m/1/1/0":["02fd0e7c62b7b58d1ea7bb4cb84d53b019df99d3703a42aed73a2cfa15f3af5d08","0355a15912e76072ef50e6643376b8a9da8422ed4f8ea07b1d84d4989be5a39b2e"],"m/1/1/1":["03bc3e1f4db32efd8eb1fd44a1665938d59628429c67e1e8b7054ab5717f4e6750","03c4c817b633ac31f44f16f390af831d35f7d98744a52a0f23e9598967342255f8"],"m/1/1/2":["02826fe7e9da408480ddeb1d4414c5100b350f862ca718e27122681e1a0ca35077","02bd25af907bb3edbf6b2cd1ea90eaa92cc93ec47bea7d339af44c1d2c05708e99"],"m/0/1/2":["0337a1a70364b94745d6e26d2d28919cf528304f52765f12ef43e3d6da0a6c8dc0","039d83db9aa43e6e00e0304e6971b6079d79dc12d8d55ce2e6fc24a52ba8d41329"],"m/0/0/1":["0359c6d0d0d31f83301169901a6ffad9535f14014b5ab3b43561dbb2436a7b8138","037d06f713f13a11967fd5edca265ff4c77528693a712c482256505693e4890d93"],"m/1/1/3":["02600e5c41670773a213a4cb58c8f2fa3e83840784bc7f0b56925e1075e06632c2","036d01867af5f61371151ef7d9026fa0400a623f6924e404ee0b856625268972f9"],"m/0/1/3":["03e5a9b039b187ca8e065627df402e4a5b196b94198542da7036879de08be63d2d","0304f3e0b70f696d80e5785dc7747d6dcb55ba24c31f2d80bf184b4e582e6b47fc"],"m/1/1/4":["03741afa5bd50d6ba5801064c810fae84f6a4557d6a88ddc8591d0d4eb68a8fc41","0214dd6ce6073b05999fb887098ca6f7e1d0b4fdc0760557786907df353df90d1c"],"m/2147483647/1/0":["033e072a53ea835763a03c66e35c35384736210a1bb7d7ee6d9a3e109e82426b30","02e37b5570c053da8a8ee587be86fc629775c4db890aba2745ccc4e4dcc8c31041"],"m/2147483647/1/1":["0228a6de42ef421c263d1efd9f28d9a7d15a261995028a24eff6b9f1c3fc46e6bf","0226cff885cb0d607cc9cf69a7608316eb3fb2ec344c0c9956246ba776116fc396"],"m/2147483647/1/2":["034fe2a8f0b98445eb5810fe36572ad2f64ed9bf64dc9de624f99c0142cb07c682","02f2c5c758e32293f5c193fd69afadbba83abafb397db01e6f2b447690e900475a"],"m/2147483647/1/3":["02b25ef9434446c51f10678f787e4913de582e34d164bd3b06af7732c5476df1a8","025d51a1efd59bcff22ee2e0af61b21a7ba5f639e20dfdf25690e926005177dd0c"],"m/2147483647/1/4":["03e5734e1d29b2f684d0446b7a2ffbd0ba8952570a502d0d14b1efd8f24b61be53","0258fc28a324848d8d0154e8614815e35c668d274a8f01957bb99aab8dc8f386c0"],"m/2147483647/1/5":["021f9e775246765e1cfba0ae453b4eae6cd4ae5a57a09c319edbe89d4dbbf23be3","02857f66571a1c3eb9e72d22ae88e734c03d448bced4dcfd345c2059468124c741"],"m/2147483647/1/6":["02c072f329391a25255dc6452e5f5220966869dbf736ba8a8c3ae9d273a84bc3fd","030920a8b8e88c4db2871a7df0878a86cf0695f6d96bb50c701c3454f3df25176a"],"m/2147483647/1/7":["036bf329fc19bce10cf1999fae5bfa80290ff7b44776b49c7b0dc9eec6cffcfa21","03955a549875b4f7b9be28b9ff4bcd51ad2bc224430b1634baef890585885d5e1b"],"m/2147483647/1/8":["024879c9c9a261b3141ecfa1c79c4efc25278c844ecd1dcfcb95d9c19581fbdd25","03fb4a5fdb91239df3ccf7f61a5b99e7e72483101e21c9d1ee0d85544e9354c6c7"],"m/2147483647/1/9":["035928a107ec01f78cd586914d5a49710fd42e352b1312e3ad0eeb2c9666fdf8e7","03a54c03093797854829c75357f092356352a109042bbb83bdac20cb4e5eca27ea"],"m/2147483647/1/10":["021e7a3a7efe888c5e820b5cf0f03317b2b4bf438d8563449aeb7a77cade97f136","03ec0960b3d1df52ca3cc2c82b7d97063400da4dd051bba2f9bab6cb44aee01efa"],"m/2147483647/1/11":["035d70c26b7f429861f555f7c0d99947411b23b7f95303fb8d5de5b82a95aa30fc","038b922f7024f5446d6b48e5253643543b35c006d90fd37688105c6cefcd8adb8a"],"m/2147483647/1/12":["02158d6503891c6c65a606221dbf5c68d0832288975914007968419939588ecb24","0248264cb1763a3f4de9b34787b4bc5443ec92ef915927494bb9f1c1c0b498c7ca"],"m/2147483647/1/13":["0349965eea38a25ae0c061faeac4c4e57e648bc4c0f059d07b3b8b7962cbc0dde5","0352243d9269565ce2a1ffdd0b8e43a442c6dd1c9edda86eaaf2cba5a4a95c40f1"],"m/2147483647/1/14":["030fa6e3d0c5cedc0581955395c77cbe134c912a47971023b9695332df3f7bb200","03f2cf09e33326fb59bf3f13e6298d2d5d29c9eae3b872e5a851e8d8d77259c883"],"m/2147483647/1/15":["02bf0d45e41339f552df6f8baf4392142921fd38b0f2a4388a905ff6cbacbc278a","03fabe46bb6706a1b8edfd28c046a8891b4530bbe5305080b72b0d08ebdf7b8c0a"],"m/2147483647/1/16":["03a4e3146ed34d6a8af4e4379e6edcff32cb0373ba232b3d746af3052f674133ac","030311b73c6f5c46ddffc0cfce6e5ed0b671d94267d8e52cd8837f2a479916eb91"],"m/2147483647/1/17":["03233df93c762d2f06c7f5f388e4e0a8dbdb13302acba0d2d6995c487d8aec9f2f","024badfdcb7e772ac7fc1c46d3943b07500edbbece105cdeff3eb9e9fcc9f54782"],"m/2147483647/1/18":["0364035475a098e00eb010c500cad3c90af3e81a4bd613144bc9433a150f14718b","028223dc8142154e7477ce000b3dc13e1d15a901553d9b18864c8645b582b38fe6"],"m/2147483647/1/19":["03971b74b4ac4bdaadf636baa4caa82fe5355471ed6ea05a9cbe5fc6c9e4b9db76","0202ebffacd01f83849e5bc5c0e2c317bc5fb2fbcb2d6d4482a5235f9f1308b61a"],"m/0/1/4":["03005ee9ff028c98fd132e531023f2f2b61ff0d26022f979dd98088d2ba167b031","0345ea82e8dfe38277f0c3aee18d2dd93edb63e8663ac83328a7934d2ca57006f6"],"m/0/1/5":["0391bc4990b71d8a3f156ae7107929ed6372b0b4ba8a868253f71ba7189d1efa02","0312a74cf2e7c0dd41897d04fabfd8cc3187b84a28305cfc79315b24e6fe23a6b4"],"m/0/1/6":["021a38c492607ff9684a4fec445e47b5b7100d3ef9e9dc0d0b37c0a646d28d4f77","03ae0b46ab36f97447ebaa53f2b5c8f090f15395378785f2fd285eeba17fbf3f65"],"m/0/1/7":["0308cdec88c1ffe16edc98853d9c08dbd4ba2541ba566668ca17bda19d7eb3481f","02dd622267c2e68287287b8b61724f76fbe84096a56aa5054af92f8fe25380e2d1"],"m/0/1/8":["039647da9ad725836bcb28a3e0497659a28d7749d1416c421a0a01c62d237ee962","022e22aa61eafda0dd8820427f1a06314d352a15ea8645e7ab9b80920017084d82"],"m/0/1/9":["03a4ade946076c6962b70c70ac7fad3a87efb59a1d0a4e32bda13a6d47fe9df961","029a07235aba04ab69526e117d836d5b3fae5cfc8c5e72b10c6d1afd261ccc19f3"],"m/0/1/10":["03c78e9b6493b22790db1acea20df9444e0f9c424fc5756e7a32c290ae01783953","0254c130ee467a96570c9f5ebea89de04f0b1db1686b164f2694339bef8f25dd88"],"m/0/1/11":["03a762c43318ef8d4840fab04c8db73797dc648825fac60f2730b4c76678df1cf3","0212c684a4de8e750ad2dfe2b136370ab9803eca178ed9a27b3990c29b067de35c"],"m/0/1/12":["02702d221f9b15c5cf75ac2f497a6c63e60213087c3d2d3be46768e3ebd238e26e","03ed58580744deb357258e44548212038670769d8d51e385d4fb8414311fd01b52"],"m/0/1/13":["0320e0597b54c62768352f433389cee4725d6094d7bcb5c72265edcc0933829aff","02c5706f11b9a85f3176c572842b7c9812c2195058d24d945bc026b00312740e76"],"m/0/1/14":["02fe43077676b844226d3aaa62e8a86d237710d92f882366944acbde0c8992fcaf","039a6a8662abb8910741cf331320549665e9feb28ca94d1ab6a43c84fa330b94ee"],"m/0/1/15":["0369f99f72847af93d50ab8ee75b6e7e912d26e27be96f6d6b7215cf7daeff7ba5","02521700cc07c953ba5aa586fb0e4795a34dffc68c5fb43e038be3866e40f4daed"],"m/0/1/16":["02f67d1d89bd8fe2f91c5b973cbdacfb4ba440e7656bce284cf73d549625607347","035da9cfac5a803dcb2b283b02a2515a4a1bcbf3d19e0d180aee8fc30193bc0555"],"m/0/1/17":["02c024ec199d240e8d6c66276b94b91071f7cdf2bef540c29d6d18d25de7b1cf7c","02190865f9dafae3f7f05c093463be5632946422ddda0a6fef6904390792516067"],"m/0/1/18":["035ed504d7704ad984a333b8eb0fceb8be043da9284de31ed84d9e68d90c75507d","033303c415b50421732402df00f4baa219f334647a7eb5014b9f8079864d6ab558"],"m/0/1/19":["02ce49fe86b0eee73663b1ee867b16b97c876af26f12764c528a2e6d0eb55ad3d7","03ab969bc81796b88e44c340d854df955fc60ea17ea92db5d3115595d6dec890d8"],"m/0/1/20":["03e2fa915378cbdffa0d919b0fb50c7256ca731b9d571b3365e486893a1d43079c","038d058b895cf084dccfcc9367e4796a5cf4ddceed6c35f6885d75c80119613350"],"m/0/1/21":["02fcb1bf644446b5b42205272af72f0aeab9e92ca29aafa91c5fb69142764017aa","035c5fe5c8811603279a5b72b6c30735d702817db1eab937c622269e28192ffa90"],"m/0/1/22":["03b39d61dc9a504b13ae480049c140dcffa23a6cc9c09d12d6d1f332fee5e18ca5","022929f515c5cf967474322468c3bd945bb6f281225b2c884b465680ef3052c07e"],"m/0/1/23":["03f40b82fe8cacff08879f13c45f443a3dc3ea98e1d75d5f32a19f5e5a8f7a905b","028415ee458e4dcfd440ce969726f3b58ae74fb6cf3995ced099579211e7419844"],"m/1/1/5":["032748a6282e21f571b8c8dd49e775deb83c90fcf88dc4ba81d878536973709c3f","020837cd68f14ce571b335eecd1b6fa0af43e1576dd9721aaca2a8ab639ac6b7cd"],"m/1/1/6":["0337032efb013dc92bb8dccfbdda9f5c28f0039a9c60953d41003d095e9f9778af","03ceed2da6b9603297061dc8eb930112ba726b2ccf5eec67f4866a05ca4049a22b"],"m/1/1/7":["0383c96ac2af7d203f69133b2fab6b68366b5075ad6957fa06759df3b20fbfec70","0311385f79834cedaf2230a48c0f9dc8e794da1869fc595db2518d62debb85579a"],"m/1/1/8":["03efc649680280f4e4df96da923bc88330275004125ebe5483c2f3e05ca52e19a4","02803c02d197d780388259afbd001ae41fa3eb3e2bac9627aff540521c184c3b23"],"m/1/1/9":["03af2fe6aa027a76b42c1c4050a040bfd026ad2daec1bb96a5fe2d026a7df919de","02ce14163047c640228796fb1f72bbe3afb05819ad141598a4f021058a6f79dd3b"],"m/1/1/10":["033770378bd762cf0408e44e4e604bef77e336170428c506949b1a4f1f2963e574","02c58ed43946f699dbd3e36d3e9aab2714cadeb19ecd3a56e4328c50336b4a76cb"],"m/1/1/11":["02898a1545fa19bdca92adc498698d27b86529cd4c08946d9d29604734b86f31af","02b402767a045ede072600924401c0d720000b2ed59fa444bfdbef4a5f1cead745"],"m/1/1/12":["039b8659430be49913e2cd869aa8c99ccf49a13df35837370b792033dadb891483","03264e63df292257cc76babb15d15bef620d1c2f8c3bbc78d6ea02d127e5ee7386"],"m/1/1/13":["02381a559791b8e86bf546e2c718ae63cf24eed0518a58e4d4a4b310adf2cd38fa","02d7f8283a4418d912508901b4a3db0d2103206dfdd74b3c75648671e20ecfd445"],"m/1/1/14":["020376e8c550b7d9faa0b2da947a2a36fab22c6e8190b6f99460b6022017bb97d7","03fbc5299190e6628de28c92aaa12e3a131b21eb7266462c46fbedeb86fa878055"],"m/1/1/15":["027209fd3b0cf7368180a5dbb16b928c997d33fccb78505d48440c7d23eadf5460","03450bfb22858726cd7e228e6733f69457546978a95188565c53e0d1c0d6070ea8"],"m/1/1/16":["03cb355ba04f64293793855121bab5831f84a3a3edf7cd31fccaa6d67c407a4912","028bc897a39c1224610b765a80f4cd8ab79cb37776f58fec9c10ac6f649d1f3c72"],"m/1/1/17":["03f4cb0564d7e2c6b85673503b7954db22779f29a8f3374904573984e318a96bf1","037c11b6ee906d84aa7eed359d758d986d912b6f8e5cbb1acf0982a77b3ef812c4"],"m/1/1/18":["02d2e5798f33f6889472857744316f2d253f25f88379610063f40cfe5798d9858f","0253cefdfe9ca987cbf1c950b6246d5b7a194d8dfad47c3a78dbbc5c1d01511d97"],"m/1/1/19":["0336c325f5aed366ffc10d553f2bfd4d69e66cbe1688d77af14efc8827aea2e318","0378b1b9a6074f9f2ab4fa9ad1e14649c621b0c8124a1b148914d3c10e6ab390c6"],"m/1/1/20":["03ea55740a734689ce778a8c00df8ebf4274c8f66de7d05646fe5c927773ff7f2e","02275b558d49aef955b6dee51a3c0a53f4b076b97bb3f26abcc82540168ec87cac"],"m/1/1/21":["03c77869c9984664eac9c238f4b6d806c9f48ca8a736c48450f398834db2aa915c","02d984f548c7f60c09dad3287cfc48807bc8157123989636c713be61be6a2e9ced"],"m/1/1/22":["03ed7c6a3c854c1f9459891691cc32671402f9e47126919878251e568dbdf353f8","02a113dab22cd9e46967b3fd76b9b9ec1d227d88817a9300e42d332cca2a0877fd"],"m/1/1/23":["02ee186432dcf69fda50a6fdbd94651817d8a271c273a5b70cab3ec4ae77a3753b","02291370aad9de0dac676355ced64e268b0c431a51f42f12d13f5144940fce4285"],"m/1/1/24":["02bf71435e84e66547c8c583d5ba226a5ac4d935e0a9f9603ecd8925c3e847e91a","03578d8657d285a89d9d597632db662cfef9baccfb55c76b1e87948a94fc9de30d"],"m/2147483647/0/0":["02a8425bbe23426219065969f695a6c3e242b24e57226bffdd542be8fd6be968c9","03057a42fdb6569fb1615b173ccb702453db2eac5be4291b82d4511461eafbed87"],"m/2147483647/0/1":["0250c3d3e86e332010c5233c2ec3bc728026002f0037cb3382d6318409b0e70796","02cfac1e7c4c88191201080f8316af52d9faa6ba624a6e160279e9fac4d1cf79a9"],"m/2147483647/0/2":["02a8c266a5b92eb50c8be91f95e4d1ad968b2f57d527377fd642d63fb84474f61a","028cc954ab31bd179ff80b8a05f95430ae534e61b3ff35f5284fa2fbe1832ceccb"],"m/2147483647/0/3":["02f719e1a7ab00ea98611453fb03d44c1da04655bed74af392534d70099039b4c2","03bfa548bfd4718c50bfce173f780eadcfb679d9c0206c91a2fa1879a9cf7558b2"],"m/2147483647/0/4":["0362c0695d397ca26bf47f0e641bb3cfb06ff29ccac2e1d56ded3afcf88b1e688d","02f9d87b05bdb3b9e82f506b43f813041c0e403274adc23d11e5e1651e34b606c2"],"m/2147483647/0/5":["033731323032d4ee08e858fc71f93970444333e183a1d5052e1d08cfb511e262c8","023e12556cef67ade35b7758916b5e1a3ebe074ccd35c5d8eff6b01321f63eb495"],"m/2147483647/0/6":["025d11b90081972bc1c258c9d6f476dfc2f95b69f0e9935322bf9c21deb580ff64","02b065f56a378907354f0738a0ed74f10660c6b5dd68c9f992093b75ce3d7d8b72"],"m/2147483647/0/7":["0210e721e8a35db9d8c855a0d346f60c09208f3be80b39e03af2c29db777332c71","0277f352969fadb1f1835f9a0fa99c6a3c7b6c281be5b2794c88a708eb177ea33d"],"m/2147483647/0/8":["02998d8d41e4215cd2a961a415a3ed0b1f984f1627719a7b102a75864943c4d87b","03d8ed7fc8f68a77f68d3afd007b7aa4c89944195143630ce183f0fa5438f2b559"],"m/2147483647/0/9":["0324fa91737588e4f85937303ce65c3b91b5f2ae506a72d92b83e3f5f9aeeb3c6f","02a011be72c4a400319212228106af278823a97acfe0a67e1ecd866d446b315114"],"m/2147483647/0/10":["025886ba287922a904881c7315e6fcc410a7976741771a5937d3a1a01b529f21fd","0243bb91ceed9d29d0c2ca66a8ab77e82110bbcc023beb4106f787964f44a0b972"],"m/2147483647/0/11":["0369d21684894cc2d4b2f5e581ede3cac9e8db4161a08e7737c1be129bb673d3d5","03c9ef27e3cd3dadc078fdfd9936a7ad9bf7954747085cf8f8a2a5bb3431f68a9f"],"m/2147483647/0/12":["03a73b8fd859bf6acebffdfffa2597199091daedd2c011ac67fc3494d8a1a8ceb6","025a213f7771c8be03f43f2e7f469ad4ef2cf6907ea284b227a786d1f55dfa7144"],"m/2147483647/0/13":["03a09f7ca257e1ab263cd5e6b0addc3ff868b93df132321d98775ca3505efb576f","03454c715739164bc55f347a651439cdf3ec146b35d2927beb60e8290b3916e082"],"m/2147483647/0/14":["03a64b1f7bd94a6b1a6e84ea444e0ba04e9deb86460934ccc37c0615a134a8257b","02794f09210b1811a455f3e1c7bcd35c76dff2523190fef9615eb27e2376acac1c"],"m/2147483647/0/15":["0392dca2fd9a3bc2b2a7d90a848719069fbc5f22bff7327bb8186c032514085263","032ee8a33ea76d70c7ae839448ca6c5b1af89146f2922e23ba1822df42dbc7e66a"],"m/2147483647/0/16":["031a22a1a3c1abad7c4d782ef6ba3cc00f2e8fe549eb33e0732200aff6d3174831","03bdce9781289e0c31cf727f4c93fe46f7930dd8fd68f818ce241f1ede268e8e0e"],"m/2147483647/0/17":["03b12d27e9aea2c2ad598e54e40860a705ac2ca2427aa511b501b38ec368ea5c7d","03e60d35d84d4536cad895215256b312bb4879a8d417251c279995e58f25da3d54"],"m/2147483647/0/18":["0380266cc9a9673676ad6a1b2e7148766df9c25b4dce299e5edc4f65b72aa58e64","0329e2a8a48c06c0c45dfdd2ab33e6455551557d8ebaf8c12fdf7470f8c45f1d28"],"m/2147483647/0/19":["036fe62af85560d7eea7c7af55e60b32a97dca80134d0aedffb19eb2705b9d6e01","02381c2c30b9f81e2a53c69028fbe11803acad0420b267719b7a80870be0baaeb7"],"m/0/0/2":["027bf94b8fc4e9b42683af25fda125ccab8760040717d100270dd4afd032692daf","026382c6c9357250d96dc21e43c053857a64efeac1887fdcbc107fbe3ecfc6115a"],"m/0/0/3":["03fd203acbd9af3cbbfb709458f8952078234a36094f12d00372e4b2b14cfdf419","03f2e5db59aea5dc89f53ac2a9f4ef66d41265c45afc5d763e0ca61ab70c7c61ec"],"m/0/0/4":["02a1d7cf4fcdbbf4de4002b844c3bff1639073f1cd6e5c4a4e02596b45d3f518c2","03b5fba813294e6ae096ea158833453caa5a945609b0a554696091b9b152bb0f7d"],"m/0/0/5":["0261d37e3b56ef4e106c59753037f516a4b1c45e056b2a3e00f8b77f15aaa7f8a5","0256a55e66e0de1603f0d600c0eb5f5486cf3512a776a36f3ab0d1941fc0dc9b09"],"m/0/0/6":["031db2826af215fe6cbe3f6e121b0497840fc49be133cff0a4d4eab679d6b99d70","021dd722c3f35dd04fcdb57f09b76c723d521fb36751de03ffd08096ddf1dc1f86"],"m/0/0/7":["0354ea75bdd9eb5beae7262e4a5eeb58bd10103ee0185e85b749ea39f6615d0f62","03f2c8f3b6478c0501a8578d5caf5ac2974f8213fc5e699d62dd2af58fbe8781d4"],"m/0/0/8":["0282e67df3bcd1e1662469b4c3151fb50ee1e46b75d787d91184c16b9803131f82","02921a7054af1e425f4137a5eb6b34d1f2b9d81c2625230194bc30657bb4277e11"],"m/0/0/9":["033e7e387933983ceab37c8388bd8ebc5119760f493ffe6f083bef0e5dfe22891d","02d660d60cc55d80912e0745cb142a8596a4604fbf72f9aadec0599aa2ed62461a"],"m/0/0/10":["022ce5b2750ae34512199856eab9e912dc25281cd8b88e7688a46c3b9a389701cb","02f14aa1608fce3b6088148709eb5fe72b61699c931fa8d95a45fab1106859d1b0"],"m/0/0/11":["0288dbef3302c1bc5556028adb33e2f9e03c119dbad4f706befb8ce86cea459f2b","03f13ced465e2e0a3aaa8895f3185d5711e0bebdaf507610b7a669ac8fc82da8fe"],"m/0/0/12":["031ab4677885340d2f927ccc9747f4346b79e4eb6c750695095a8a2524610fa94a","038c881910fbd8b50d193db4e0c84f5b7840820397f92cf0718a8e06d027125503"],"m/0/0/13":["031b568452cba22eb7a88c6085489e53e35abd16068882e71a140e47e12dee9c61","020d09885ee362101d12d34ce0918d41593634db1b9413e5415c6755753b9330e8"],"m/0/0/14":["024177bc9aa03cfc72eda2dfddffd7fe9d0c2f007fc3ba1a48280feae2b9fb117a","03394ad321668440c08da76eb35475ba3a8c0e8cbe0ed81468673a8c72d38fe457"],"m/0/0/15":["02037b1cc696ffbe9eba3684edd53653386ef6cd7728401c40120037593a4c2ae2","020ab8d6900ec9c11ca5d96dfc0ce7cf0ee71653a7c45118e89abb4b113147e53a"],"m/0/0/16":["023bcbb8d4726a546087cdb83740adf0ace879b7195a572c652fa8ce4dbe195a04","0392721b230d5163d28b27fc7e059b875711f12b3da448eabe7229bde57530e637"],"m/0/0/17":["02498ee74e849d3e9261dd1863038caf83d6a3bc2eeebecf17055d4bab44dee77f","03d4dc104b2e0981693e8097437de9b05334a85e2c8edb02783897859bdbc93e32"],"m/0/0/18":["0218a9f524fe54abf8c3afd21314296cfd93eaa9227acbd457e6c9a742dc233cf4","03760f3d0c5db969bda698ff9352e3b7c332216c34825f4c6e857e39c9aee7cd35"],"m/0/0/19":["033dd51f7737f0e9db79f5c38e4298bf3396346904ef3933d290a22e5b77048d9e","0221b2eedccb9a37515263071550069b3b349a166f0f131d0028e8600d9a2251b9"],"m/0/0/20":["02cb6c39161f3244d7769f7ab96346cae2cf21cb6f4538f5e7382d363dc2f836c7","034f7bda4d1e9ed6a3774608a4d6cd8582ab59fe3187f8a7a7cf914d89426ebe28"],"m/0/0/21":["035490549d65f1360f10340037250b171470ff4c86966318a2b1eead6d8b969aea","03f6a04f6fcd07a4f32c82d53710ed30e0f54d43d41c67c661d158b3d0830c3ea2"],"m/1/0/2":["02972eae7e4302e319c266578e14a07839c1e788296a92906e6d66d938211dad5f","039ed6b488f1571ad6527acd6b6c5b8453eacf6665dc5cb7852e33d1c8ea73f9fe"],"m/1/0/3":["02bec4728888c2c045108353994bae5731ec7a7b41459023b0023e10b8d616bd30","03ce1efe16214c9eac595382e46a68143dd11a335b3f7c971ddd719ac544a5fc4b"],"m/1/0/4":["030e2df1d341568225d8dfbe5d07e98dae9f90e0f43e19dcc68c998a6ed7bcc1f0","0380f4c07dc84faf42d51779f104aa6e3b5c3ce2d7684b3cb76d49faeefc2b69d6"],"m/1/0/5":["029a54ddaa25f433b493f4b72df8c1d41be2c4d2963b8b61ee63cc86d16c12d066","021567c95e0317442e7367aa4e3378dd46c5bcef5860f789272fea83b917de0669"],"m/1/0/6":["03590320d80b61cc0874b579f467c9b5ccc50d9ef875bcf6bdd12e2d0c211e8973","03ee4677b6ee89a9d355851f2230506c6897ff219062c0df4ad9a85c60f3535f93"],"m/1/0/7":["03caf98ab1c9b79d1dc8029453a6137c08787b04043b79af3cb42d41d2d3f1338f","023f39ae4e2f4f3887d5fc58e0d3a0d7ee267dc04aa257c75b6b2d67d2f5580f81"],"m/1/0/8":["0352a2a3ea8209c9a2b633d788796ac2d16c08022440e04a77ab2835c7f971d266","0291bc248b3da997f35e8fae98a75a91fdac2819d74c4e270899338d48f7389e87"],"m/1/0/9":["02468d32d9c3c62418d506d4cd0da6cd2022d5bcafdb5f847cf7bde7a48ec6848b","032713d90d12eb6a072f3c1db6c0d3b680d3f78883016135fc0f78e8193d41d4b4"],"m/1/0/10":["034863cc6bab9b059be53413ba75c5fc286647c20d7f9e5512ef4754ea301dd1ce","03a33ab9c32a2264ee2464ebbb5892f0e34acf0fdede4f87395a89e9dacdd4930e"],"m/1/0/11":["031e19296695bfe8a96ba3bf58afa805ee1bd5471fddb3929b1678d69d442d69c9","0270feb33956fd9e937019d629523e26437493c0856514011e6aec88baf7721295"],"m/1/0/12":["03cce695d3c3843bf73e851b2446a77d7e235e5b80b4f4474f9946292eb8218742","039ea96c8822f0ec7ed28308d277f3e730480d7573579cd11b89aef4364cd9ffeb"],"m/1/0/13":["02ab4ac38eb405e822d12c0f0f354f04f9ee1d991dde887a5c1171096fe503158f","036809e60cae1203da8884ea1f85d4669ce6e053f8ba605d775e271b70ab4f6787"],"m/1/0/14":["039d61da23a8610fa0ee58eb37d7cea7ea9396c79153da97280ccf5e46718e3bac","03015c27bcc778682781fd6ad30aa6041db0b7e24270818cdceece0043ccc34b26"],"m/1/0/15":["03c088ed669132835d2728b0ecf294271c8388988c6ae264d43ca24f50e4005f81","03e2c118c9445a2ddc4c8afeb0ba49e21be3f818a483d346418b8922b8a371a2b7"],"m/1/0/16":["02bba7df9847f463c6b23eca37a4bd6efa3801a52b8ddfad804d902e783b70c81c","03764b657f23996e31c64a701facc1cbeb0c9edfdd605e2c1ed36cf48197565d45"],"m/1/0/17":["020445179c522295b89bf4bfd582eb03422e3fa20dcd29263925e9f44282d476d8","036e47bdd32f3061aed1c1f8c2a32b038c7b72391cb1f80ebfc150e58f88372766"],"m/1/0/18":["024d88c4bfcbba713d49e1edcd035234aaa1ee76ad7bcf75bf074a16658a6b0b6d","02b861e7a20d89f6875d2e44c78dbadb99503e282e5e60e9f65657af6fea81d425"],"m/1/0/19":["023a8ca9d5300181f157e1930d3b0800eebe7683d8df72e6cbf28834dbf1be5d60","026053c4f84c10d15890c0b254522972931bc2d5b7cdf9c1f9f3137c22edf3ecd3"],"m/1/0/20":["03137c66e9f3d61aba659f408d77a293fa0f3fea4ccb911074a681d6f61a55d023","0291aa1bbfbef59b16b0e37e185a706c589d448cb02e860c5df9c9d7242ecc739f"],"m/1/0/21":["03c08673e0cae55318bc9dcc4b5f11eb3ff71d42de04015e255dde3fd8cba7e09e","02423d4eab06cd5b26e71d145283523c011d58032700c517f00b328d2c90cf109f"]}},"txProposals":{"txps":[{"creator":"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5","createdTs":1405543144016,"seenBy":{"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543144016,"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543144645},"signedBy":{"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543144016},"rejectedBy":{"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543170040},"sentTs":null,"sentTxid":null,"inputChainPaths":["m/45\'/0/0/0"],"comment":"blablabla","builderObj":{"valueInSat":"29000000","valueOutSat":"8900000","feeSat":"10000","remainderSat":"20090000","hashToScriptMap":{"2NBtv6DdXj8HBunyGqpW9H8bUtW5x3rfVTj":"5221028a4b63f26253f3a8731577b8e1ee480950ad5833ebbf106fe3463bfc07cc3b90210332efa054c08cb77506a35ee0762cb7156f244566703ec08e433568ec0397bec852ae"},"selectedUtxos":[{"address":"2NBtv6DdXj8HBunyGqpW9H8bUtW5x3rfVTj","txid":"a9f4dda3f092e37244bc4e77ea921fed01d5b8ea49613dfdc0dc8afdd70190b5","vout":1,"ts":1405543855,"scriptPubKey":"a914cc93216398b77b5f8c451ca3a357bef961678be987","amount":0.29,"confirmations":0,"confirmationsFromCache":false}],"inputsSigned":0,"signaturesAdded":1,"signhash":1,"spendUnconfirmed":true,"tx":"0100000001b59001d7fd8adcc0fd3d6149eab8d501ed1f92ea774ebc4472e392f0a3ddf4a9010000009300493046022100ccbb8f398f74a76236629b8499ffc6f9518a2091f5a61a9a352c0a10f615961e022100b8f0769c76cf33bec3d7f81d9da2b74cf6e8a5e0a24ee5f48172854d8bcdbfa101475221028a4b63f26253f3a8731577b8e1ee480950ad5833ebbf106fe3463bfc07cc3b90210332efa054c08cb77506a35ee0762cb7156f244566703ec08e433568ec0397bec852aeffffffff02a0cd8700000000001976a91485eb47fe98f349065d6f044e27a4ac541af79ee288ac908c32010000000017a914560c292066792531164149c5ed63ad2793a61b928700000000"}},{"creator":"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5","createdTs":1405543188745,"seenBy":{"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543188745,"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543189341},"signedBy":{"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543188745,"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543206819},"rejectedBy":{},"sentTs":1405543207304,"sentTxid":"169bc92693dd2e27724eeba81e54210e842035bd3af6c52e6a6a5e908f1a4f66","inputChainPaths":["m/45\'/0/0/0"],"comment":"que parece","builderObj":{"valueInSat":"29000000","valueOutSat":"9000000","feeSat":"10000","remainderSat":"19990000","hashToScriptMap":{"2NBtv6DdXj8HBunyGqpW9H8bUtW5x3rfVTj":"5221028a4b63f26253f3a8731577b8e1ee480950ad5833ebbf106fe3463bfc07cc3b90210332efa054c08cb77506a35ee0762cb7156f244566703ec08e433568ec0397bec852ae"},"selectedUtxos":[{"address":"2NBtv6DdXj8HBunyGqpW9H8bUtW5x3rfVTj","txid":"a9f4dda3f092e37244bc4e77ea921fed01d5b8ea49613dfdc0dc8afdd70190b5","vout":1,"ts":1405543855,"scriptPubKey":"a914cc93216398b77b5f8c451ca3a357bef961678be987","amount":0.29,"confirmations":1,"confirmationsFromCache":false}],"inputsSigned":1,"signaturesAdded":2,"signhash":1,"spendUnconfirmed":true,"tx":"0100000001b59001d7fd8adcc0fd3d6149eab8d501ed1f92ea774ebc4472e392f0a3ddf4a901000000da00483045022035423cc74824ba904907678dda3b62a20a787b96d1b3e9f3e9546f9c57f4e45902210080a1ff1c39f458ac1642b9e948bd62fd70563b5252e749cc8fc642cd763ee830014730440220524a13f36cfb03caa246d7d84de634ec9386f2c39c19bfa926037f48da86262b022050e58a6503d105ad2805f86806810a1aa7f20d6271e1340b42fa91ab6a30f3e801475221028a4b63f26253f3a8731577b8e1ee480950ad5833ebbf106fe3463bfc07cc3b90210332efa054c08cb77506a35ee0762cb7156f244566703ec08e433568ec0397bec852aeffffffff0240548900000000001976a91485eb47fe98f349065d6f044e27a4ac541af79ee288acf00531010000000017a9146130a9d51f996b7a1b9d3e10c80930834251909d8700000000"}},{"creator":"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba","createdTs":1405543505848,"seenBy":{"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543505848,"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543590221},"signedBy":{"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543505848,"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543590221},"rejectedBy":{},"sentTs":1405543610315,"sentTxid":"6fe851b54b777a75fe80fa204dc674395e2af69efb1f7c0017e909eb82c3d914","inputChainPaths":["m/45\'/0/1/1"],"comment":"mandaaaaaaa","builderObj":{"valueInSat":"19990000","valueOutSat":"19980000","feeSat":"10000","remainderSat":"0","hashToScriptMap":{"2N277q5r8Ab6XLJNCjXXFdh5itDJRQCv9ts":"5221020389327ee8ae7d0ee3f8187842d23a4070bdd8a27c0bcddd05d80ef39009253d21025c9b49bdf17d97bd82ea1b87793082f857247f0f9b999937a166ec994bb1b41f52ae"},"selectedUtxos":[{"address":"2N277q5r8Ab6XLJNCjXXFdh5itDJRQCv9ts","txid":"169bc92693dd2e27724eeba81e54210e842035bd3af6c52e6a6a5e908f1a4f66","vout":1,"ts":1405543157,"scriptPubKey":"a9146130a9d51f996b7a1b9d3e10c80930834251909d87","amount":0.1999,"confirmationsFromCache":false}],"inputsSigned":1,"signaturesAdded":2,"signhash":1,"spendUnconfirmed":true,"tx":"0100000001664f1a8f905e6a6a2ec5f63abd3520840e21541ea8eb4e72272edd9326c99b1601000000db0048304502206b18b3dba2646c552469d8ef52d7656f6a65f563032530f622abdfd8bd4c5cee022100e804b406eddebbc827646141e74dc64c76a770ed4e35183ffd35d265ad9f7d3b01483045022100f6c013638ff0a316b1baa93dfffba6a98cf3033c133e8bd899e933c9c3e47ce10220530f40e7ea52ae58bec695edbec6d566d2ee8e7b5f33f95e33093ad1e29a125401475221020389327ee8ae7d0ee3f8187842d23a4070bdd8a27c0bcddd05d80ef39009253d21025c9b49bdf17d97bd82ea1b87793082f857247f0f9b999937a166ec994bb1b41f52aeffffffff01e0de3001000000001976a91485eb47fe98f349065d6f044e27a4ac541af79ee288ac00000000"}},{"creator":"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba","createdTs":1405543781381,"seenBy":{"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543781381,"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543782017},"signedBy":{"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543781381},"rejectedBy":{"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543794590},"sentTs":null,"sentTxid":null,"inputChainPaths":["m/45\'/0/0/1"],"comment":"1","builderObj":{"valueInSat":"29000000","valueOutSat":"1000000","feeSat":"10000","remainderSat":"27990000","hashToScriptMap":{"2N4eyXKikdnnUT4S74MRNAYqXChhUYmZ1Sb":"52210359c6d0d0d31f83301169901a6ffad9535f14014b5ab3b43561dbb2436a7b813821037d06f713f13a11967fd5edca265ff4c77528693a712c482256505693e4890d9352ae"},"selectedUtxos":[{"address":"2N4eyXKikdnnUT4S74MRNAYqXChhUYmZ1Sb","txid":"6c9da5b0da4bab0d576033325e987b10ccf2b9bf479d306b6aae36efeaa56892","vout":0,"ts":1405543698,"scriptPubKey":"a9147d274ac50968d7823b6cbc1b38770deb7157995387","amount":0.29,"confirmationsFromCache":false}],"inputsSigned":0,"signaturesAdded":1,"signhash":1,"spendUnconfirmed":true,"tx":"01000000019268a5eaef36ae6a6b309d47bfb9f2cc107b985e323360570dab4bdab0a59d6c000000009200483045022064d877bc5171fbaef909c2a1a924e0023b3ccc0b530cb46653f06ecb230283e8022100bc6658d60ad4f7120d9226c8f6eada87f3b0388f73c458011988bab36e78ba15014752210359c6d0d0d31f83301169901a6ffad9535f14014b5ab3b43561dbb2436a7b813821037d06f713f13a11967fd5edca265ff4c77528693a712c482256505693e4890d9352aeffffffff0240420f00000000001976a91485eb47fe98f349065d6f044e27a4ac541af79ee288acf017ab010000000017a91421c4a435d9ac263ec55b35a1a5ca95e979639b9b8700000000"}},{"creator":"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5","createdTs":1405543835343,"seenBy":{"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543835343,"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543835968},"signedBy":{"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543835343},"rejectedBy":{"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543850998},"sentTs":null,"sentTxid":null,"inputChainPaths":["m/45\'/0/0/1"],"comment":"2","builderObj":{"valueInSat":"29000000","valueOutSat":"1000000","feeSat":"10000","remainderSat":"27990000","hashToScriptMap":{"2N4eyXKikdnnUT4S74MRNAYqXChhUYmZ1Sb":"52210359c6d0d0d31f83301169901a6ffad9535f14014b5ab3b43561dbb2436a7b813821037d06f713f13a11967fd5edca265ff4c77528693a712c482256505693e4890d9352ae"},"selectedUtxos":[{"address":"2N4eyXKikdnnUT4S74MRNAYqXChhUYmZ1Sb","txid":"6c9da5b0da4bab0d576033325e987b10ccf2b9bf479d306b6aae36efeaa56892","vout":0,"ts":1405543698,"scriptPubKey":"a9147d274ac50968d7823b6cbc1b38770deb7157995387","amount":0.29,"confirmationsFromCache":false}],"inputsSigned":0,"signaturesAdded":1,"signhash":1,"spendUnconfirmed":true,"tx":"01000000019268a5eaef36ae6a6b309d47bfb9f2cc107b985e323360570dab4bdab0a59d6c0000000092004830450220302baae7de2e0f102bf3af2d5f450f673e51bd143020141a769ccdcdf16af188022100e7abc087c76050ed649e7139a5a136969e74e24a8d8f6223d3219ad033a26451014752210359c6d0d0d31f83301169901a6ffad9535f14014b5ab3b43561dbb2436a7b813821037d06f713f13a11967fd5edca265ff4c77528693a712c482256505693e4890d9352aeffffffff0240420f00000000001976a91485eb47fe98f349065d6f044e27a4ac541af79ee288acf017ab010000000017a9148b102abba0729fb0690c61cf7187064d692d43d78700000000"}},{"creator":"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba","createdTs":1405543869803,"seenBy":{"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543869803,"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543870411},"signedBy":{"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543869803,"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543890406},"rejectedBy":{},"sentTs":1405543890913,"sentTxid":"6a0f61574ad65e537e7e99298968db565f97b894b61f4c8f8fac8fcaedb83e2b","inputChainPaths":["m/45\'/0/0/1"],"comment":"3","builderObj":{"valueInSat":"29000000","valueOutSat":"1100000","feeSat":"10000","remainderSat":"27890000","hashToScriptMap":{"2N4eyXKikdnnUT4S74MRNAYqXChhUYmZ1Sb":"52210359c6d0d0d31f83301169901a6ffad9535f14014b5ab3b43561dbb2436a7b813821037d06f713f13a11967fd5edca265ff4c77528693a712c482256505693e4890d9352ae"},"selectedUtxos":[{"address":"2N4eyXKikdnnUT4S74MRNAYqXChhUYmZ1Sb","txid":"6c9da5b0da4bab0d576033325e987b10ccf2b9bf479d306b6aae36efeaa56892","vout":0,"ts":1405543698,"scriptPubKey":"a9147d274ac50968d7823b6cbc1b38770deb7157995387","amount":0.29,"confirmationsFromCache":false}],"inputsSigned":1,"signaturesAdded":2,"signhash":1,"spendUnconfirmed":true,"tx":"01000000019268a5eaef36ae6a6b309d47bfb9f2cc107b985e323360570dab4bdab0a59d6c00000000db00483045022100a8ce7907f9fd7dd41dd65c2dec425e008efea06ee7c80787c10c0e210fbf181302207712c0fdd1cb25836ac1fc2fd303c1e26b85e8980417719b9ed50e977a9693ec01483045022100d1780c4f028cd898920aca3eaceba352ed9306cd17f019ae2f634e8facad149a02203c84ab2093da8e22577e93f27a732f0728d4e6db0c749f3cd3d898d6a025152a014752210359c6d0d0d31f83301169901a6ffad9535f14014b5ab3b43561dbb2436a7b813821037d06f713f13a11967fd5edca265ff4c77528693a712c482256505693e4890d9352aeffffffff02e0c81000000000001976a91485eb47fe98f349065d6f044e27a4ac541af79ee288ac5091a9010000000017a914cc1cab78458b1a951b91c6dcd7eeeeb682f506388700000000"}}],"walletId":"55d4bd062d32f90a","networkName":"testnet"},"privateKey":{"extendedPrivateKeyString":"tprv8ZgxMBicQKsPdWUAmaaopPftevC72Jtiu19V8ee5XijL9JvogqfR95uVrL85f8yBdQMq3KyQtG3Q91yWQb3XDbWWpcdWFDAmJ7Xy2XWkGJu","networkName":"testnet","privateKeyCache":{"m/45\'/0/0/0":"b6fd8d1a079efd523da34f31ba81f544fc3d0a728a8a98299d8980682518e79c","m/45\'/0/1/1":"0f4d52d2a99e4c8c1c2edf09fef12407c3abd2304b961198c3f131a8c8443a13","m/45\'/0/0/1":"de5c191c343bd6017b98708c03344849624a14e2c167cfd6eb8dcb075d139293"}},"addressBook":{"msj42CCGruhRsFrGATiUuh25dtxYtnpbTx":{"hidden":false,"createdTs":1405543109222,"copayerId":"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba","label":"faucet","signature":"3045022067576e5b37f2707a8dc66e57511ad9b10a3125bd95193fff6f8f6402969c3bf3022100adff9f417db07d88face13b3d13f422740d4421440cade1a205684dfdc5d733a"}}}'; var encryptedLegacyO = 'U2FsdGVkX19yGM1uBAIzQa8Po/dvUicmxt1YyRk/S97PcZ6I6rHMp9dMagIrehg4Qd6JHn/ustmFHS7vmBYj0EBpf6rdXiQezaWnVAJS9/xYjAO36EFUbl+NmUanuwujAxgYdSP/sNssRLeInvExmZYW993EEclxkwL6YUyX66kKsxGQo2oWng0NreBJNhFmrbOEWeFje2PiWP57oUjKsurFzwpluAAarUTYSLud+nXeabC7opzOP5yqniWBMJz0Ou8gpNCWCMhG/P9F9ccVPY7juyd0Hf41FVse8nd2++axKB57+paozLdO+HRfV6zkMqC3h8gWY7LkS75j3bvqcTw9LhXmzE0Sz21n9yDnRpA4chiAvtwQvvBGgj1pFMKhNQU6Obac9ZwKYzUTgdDn3Uzg1UlDzgyOh9S89rbRTV84WB+hXwhuVluWzbNNYV3vXe5PFrocVktIrtS3xQh+k/7my4A6/gRRrzNYpKrUASJqDS/9u9WBkG35xD63J/qXjtG2M0YPwbI57BK1IK4K510b8V72lz5U2XQrIC4ldBwni1rpSavwCJV9xF6hUdOmNV8fZsVHP0NeN1PYlLkSb2QgfuoWnkcsJerwuFR7GZC/i6efrswtpO0wMEQr/J0CLbeXlHAru6xxjCBhWoJvZpMGw72zgnDLoyMNsEVglNhx/VlV9ZMYkkdaEYAxPOEIyZdQ5MS+2jEAlXf818n/xzJSVrniCn9be8EPePvkw35pivprvy09vbW4cKsWBKvgIyoT6A3OhUOCCS8E9cg0WAjjav2EymrbKmGWRHaiD+EoJqaDg6s20zhHn1YEa/YwvGGSB5+Hg8baLHD8ZASvxz4cFFAAVZrBUedRFgHzqwaMUlFXLgueivWUj7RXlIw6GuNhLoo1QkhZMacf23hrFxxQYvGBRw1hekBuDmcsGWljA28udBxBd5f9i+3gErttMLJ6IPaud590uvrxRIclu0Sz9R2EQX64YJxqDtLpMY0PjddSMu8vaDRpK9/ZSrnz/xrXsyabaafz4rE/ItFXjwFUFkvtmuauHTz6nmuKjVfxvNLNAiKb/gI7vQyUhnTbKIApe7XyJsjedNDtZqsPoJRIzdDmrZYxGStbAZ7HThqFJlSJ9NPNhH+E2jm3TwL5mwt0fFZ5h+p497lHMtIcKffESo7KNa2juSVNMDREk0NcyxGXGiVB2FWl4sLdvyhcsVq0I7tmW6OGZKRf8W49GCJXq6Ie69DJ9LB1DO67NV1jsYbsLx9uhE2yEmpWZ3jkoCV/Eas4grxt0CGN6EavzQ=='; From d57e5e73e7feb94d5bf8fa083215d2360f82c456 Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Wed, 10 Sep 2014 14:01:10 -0700 Subject: [PATCH 054/191] settings: fix tests 3 --- js/models/core/WalletFactory.js | 2 +- test/test.WalletFactory.js | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/js/models/core/WalletFactory.js b/js/models/core/WalletFactory.js index 767f5f290..33d763451 100644 --- a/js/models/core/WalletFactory.js +++ b/js/models/core/WalletFactory.js @@ -339,7 +339,7 @@ WalletFactory.prototype.decodeSecret = function(secret) { WalletFactory.prototype.joinCreateSession = function(secret, nickname, passphrase, privateHex, cb) { var self = this; var decodedSecret = this.decodeSecret(secret); - if (!decodedSecret || !decodedSecret.networkName || !decodedSecret.pubkey) { + if (!decodedSecret || !decodedSecret.networkName || !decodedSecret.pubKey) { return cb('badSecret'); } diff --git a/test/test.WalletFactory.js b/test/test.WalletFactory.js index 1ed6b3bd1..e0f90281d 100644 --- a/test/test.WalletFactory.js +++ b/test/test.WalletFactory.js @@ -411,15 +411,15 @@ describe('WalletFactory model', function() { var wf = new WalletFactory(config, '0.0.1'); wf.networks.testnet.cleanUp = sinon.spy(); wf.networks.testnet.start = sinon.spy(); - wf.joinCreateSession('8WtTuiFTkhP5ao7AF2QErSwV39Cbur6pdMebKzQXFqL59RscXM', 'test'); - wf.network.start.calledOnce.should.equal(true); + wf.joinCreateSession('CA1e4HJpSmx9i97i2NigZ6j6F8C5pSaZX9XrAUwQERYAxNpQ4jsBEkr8iS', 'test'); + wf.networks.testnet.start.calledOnce.should.equal(true); }); it('should accept a priv key a input', function() { var wf = new WalletFactory(config, '0.0.1'); var privHex = 'tprv8ZgxMBicQKsPf7MCvCjnhnr4uiR2Z2gyNC27vgd9KUu98F9mM1tbaRrWMyddVju36GxLbeyntuSadBAttriwGGMWUkRgVmUUCg5nFioGZsd'; wf.network.cleanUp = sinon.spy(); wf.network.start = sinon.spy(); - wf.joinCreateSession('8WtTuiFTkhP5ao7AF2QErSwV39Cbur6pdMebKzQXFqL59RscXM', 'test', null, privHex); + wf.joinCreateSession('CA1e4HJpSmx9i97i2NigZ6j6F8C5pSaZX9XrAUwQERYAxNpQ4jsBEkr8iS', 'test', null, privHex); wf.network.start.getCall(0).args[0].privkey.should.equal('ddc2fa8c583a73c4b2a24630ec7c283df4e7c230a02c4e48bc36ec61687afd7d'); }); it('should call network.start with private key', function() { From d4f7401e231a63846e92f57ac66d0bf1da8bfd40 Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Wed, 10 Sep 2014 14:01:40 -0700 Subject: [PATCH 055/191] settings: fix tests 4 --- test/test.WalletFactory.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/test.WalletFactory.js b/test/test.WalletFactory.js index e0f90281d..9335adc4a 100644 --- a/test/test.WalletFactory.js +++ b/test/test.WalletFactory.js @@ -417,10 +417,10 @@ describe('WalletFactory model', function() { it('should accept a priv key a input', function() { var wf = new WalletFactory(config, '0.0.1'); var privHex = 'tprv8ZgxMBicQKsPf7MCvCjnhnr4uiR2Z2gyNC27vgd9KUu98F9mM1tbaRrWMyddVju36GxLbeyntuSadBAttriwGGMWUkRgVmUUCg5nFioGZsd'; - wf.network.cleanUp = sinon.spy(); - wf.network.start = sinon.spy(); + wf.networks.testnet.cleanUp = sinon.spy(); + wf.networks.testnet.start = sinon.spy(); wf.joinCreateSession('CA1e4HJpSmx9i97i2NigZ6j6F8C5pSaZX9XrAUwQERYAxNpQ4jsBEkr8iS', 'test', null, privHex); - wf.network.start.getCall(0).args[0].privkey.should.equal('ddc2fa8c583a73c4b2a24630ec7c283df4e7c230a02c4e48bc36ec61687afd7d'); + wf.networks.testnet.start.getCall(0).args[0].privkey.should.equal('ddc2fa8c583a73c4b2a24630ec7c283df4e7c230a02c4e48bc36ec61687afd7d'); }); it('should call network.start with private key', function() { var wf = new WalletFactory(config, '0.0.1'); From 85af5623503584d69f1b67fd456177d3e5130a7e Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Wed, 10 Sep 2014 14:02:11 -0700 Subject: [PATCH 056/191] settings: fix tests 5 --- test/test.WalletFactory.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/test.WalletFactory.js b/test/test.WalletFactory.js index 9335adc4a..8712c4121 100644 --- a/test/test.WalletFactory.js +++ b/test/test.WalletFactory.js @@ -424,10 +424,10 @@ describe('WalletFactory model', function() { }); it('should call network.start with private key', function() { var wf = new WalletFactory(config, '0.0.1'); - wf.network.cleanUp = sinon.spy(); - wf.network.start = sinon.spy(); + wf.networks.testnet.cleanUp = sinon.spy(); + wf.networks.testnet.start = sinon.spy(); wf.joinCreateSession('8WtTuiFTkhP5ao7AF2QErSwV39Cbur6pdMebKzQXFqL59RscXM', 'test', null, undefined); - wf.network.start.getCall(0).args[0].privkey.length.should.equal(64); //privkey is hex of private key buffer + wf.networks.testnet.start.getCall(0).args[0].privkey.length.should.equal(64); //privkey is hex of private key buffer }); }); describe('dont break backwards compatibility of wallets', function() { From f2f5179b0a167d36c2831830e95a4cbb4208ee44 Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Wed, 10 Sep 2014 14:06:54 -0700 Subject: [PATCH 057/191] settings: fix tests 6 --- js/controllers/join.js | 1 - test/unit/controllers/controllersSpec.js | 5 ----- 2 files changed, 6 deletions(-) diff --git a/js/controllers/join.js b/js/controllers/join.js index 37fbf3a70..2a9ee0c51 100644 --- a/js/controllers/join.js +++ b/js/controllers/join.js @@ -118,7 +118,6 @@ angular.module('copayApp.controllers').controller('JoinController', } $scope.loading = true; - walletFactory.network.on('badSecret', function() {}); Passphrase.getBase64Async($scope.joinPassword, function(passphrase) { walletFactory.joinCreateSession($scope.connectionId, $scope.nickname, passphrase, $scope.private, function(err, w) { diff --git a/test/unit/controllers/controllersSpec.js b/test/unit/controllers/controllersSpec.js index cb48f2789..38bd1f6a1 100644 --- a/test/unit/controllers/controllersSpec.js +++ b/test/unit/controllers/controllersSpec.js @@ -357,11 +357,6 @@ describe("Unit: Controllers", function() { scope.$apply(); }); - it('should return networkName', function() { - $httpBackend.flush(); // need flush - var networkName = scope.networkName; - expect(networkName).equal('testnet'); - }); }); describe("Unit: Sidebar Controller", function() { From 7618488bc3d680715f166926f3ca46db638fbab9 Mon Sep 17 00:00:00 2001 From: Matias Pando Date: Wed, 10 Sep 2014 15:28:13 -0300 Subject: [PATCH 058/191] Fixed --- js/controllers/copayers.js | 8 +++++++- views/copayers.html | 33 ++++++++++++++++++--------------- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/js/controllers/copayers.js b/js/controllers/copayers.js index fc140593b..cf3b880cc 100644 --- a/js/controllers/copayers.js +++ b/js/controllers/copayers.js @@ -5,6 +5,12 @@ angular.module('copayApp.controllers').controller('CopayersController', $scope.hideAdv = true; + + $scope.skipBackup = function() { + var w = $rootScope.wallet; + w.setBackupReady(); + }; + $scope.backup = function() { var w = $rootScope.wallet; w.setBackupReady(); @@ -37,4 +43,4 @@ angular.module('copayApp.controllers').controller('CopayersController', return $rootScope.wallet.publicKeyRing.isBackupReady(copayer.copayerId); } - }); + }); \ No newline at end of file diff --git a/views/copayers.html b/views/copayers.html index cbd00e805..ddd2a02a5 100644 --- a/views/copayers.html +++ b/views/copayers.html @@ -51,6 +51,7 @@
+ Creating and storing a backup will allow to restore funds of the wallet
@@ -75,21 +76,23 @@
-
- + + + + + Skip Backup + +
- - - From e8190730030b8a37e077eaccb865115ab83b965b Mon Sep 17 00:00:00 2001 From: Matias Pando Date: Thu, 11 Sep 2014 10:28:56 -0300 Subject: [PATCH 060/191] Conflicts solved --- js/models/core/Wallet.js | 2 +- test/test.Wallet.js | 19 ++++++++++++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/js/models/core/Wallet.js b/js/models/core/Wallet.js index 809c7aaa3..c2278b820 100644 --- a/js/models/core/Wallet.js +++ b/js/models/core/Wallet.js @@ -87,7 +87,7 @@ function Wallet(opts) { this.lastMessageFrom = {}; //to avoid confirmation of copayer's backups if is imported from a file - this.isImported = opts.isImported; + this.isImported = opts.isImported || false; this.paymentRequests = opts.paymentRequests || {}; diff --git a/test/test.Wallet.js b/test/test.Wallet.js index d6b765b46..983cfc076 100644 --- a/test/test.Wallet.js +++ b/test/test.Wallet.js @@ -829,6 +829,23 @@ describe('Wallet model', function() { }); }); + describe('#createTxSync', 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) { var w = cachedCreateW2(); @@ -1533,4 +1550,4 @@ describe('Wallet model', function() { should.exist(n.networkNonce); }); -}); \ No newline at end of file +}); From 2a4b054ba129fe462a930056e19026f269197d68 Mon Sep 17 00:00:00 2001 From: Matias Pando Date: Thu, 11 Sep 2014 11:30:55 -0300 Subject: [PATCH 061/191] Solving conflicts --- test/test.Wallet.js | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/test/test.Wallet.js b/test/test.Wallet.js index 983cfc076..e55128119 100644 --- a/test/test.Wallet.js +++ b/test/test.Wallet.js @@ -829,23 +829,6 @@ describe('Wallet model', function() { }); }); - describe('#createTxSync', 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) { var w = cachedCreateW2(); From 7de88f2cc813256b78f7b67c3f0535d446a91aa6 Mon Sep 17 00:00:00 2001 From: bechi Date: Thu, 11 Sep 2014 11:54:14 -0300 Subject: [PATCH 062/191] fix text color --- views/copayers.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/views/copayers.html b/views/copayers.html index a9c7427f9..1b7f82bdc 100644 --- a/views/copayers.html +++ b/views/copayers.html @@ -51,7 +51,7 @@
- Creating and storing a backup will allow to restore funds of the wallet +

Creating and storing a backup will allow to restore funds of the wallet

From 7095750d6fa1860ce0de57d2beae71f67e9acab7 Mon Sep 17 00:00:00 2001 From: bechi Date: Thu, 11 Sep 2014 13:01:22 -0300 Subject: [PATCH 063/191] fix style --- css/src/main.css | 2 +- views/copayers.html | 18 +++++++++--------- views/join.html | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/css/src/main.css b/css/src/main.css index bea1ac145..16d4d0d2a 100644 --- a/css/src/main.css +++ b/css/src/main.css @@ -1046,7 +1046,7 @@ a.text-warning:hover {color: #FD7262;} background: #2C3E50; -moz-box-shadow: 0px 0px 0px 0px rgba(255,255,255,0.09), inset 0px 0px 2px 0px rgba(0,0,0,0.20); box-shadow: 0px 0px 0px 0px rgba(255,255,255,0.09), inset 0px 0px 2px 0px rgba(0,0,0,0.20); - margin-bottom: 5px; + margin-bottom: 15px; } .box-setup-copay-required { diff --git a/views/copayers.html b/views/copayers.html index 1b7f82bdc..22f0749d3 100644 --- a/views/copayers.html +++ b/views/copayers.html @@ -51,7 +51,7 @@
-

Creating and storing a backup will allow to restore funds of the wallet

+

Creating and storing a backup will allow to restore funds of the wallet

@@ -75,14 +75,7 @@
-
- - Skip Backup - - - + + + Skip Backup + + +
+
-
-
- Wallet Unit - -
-
- Alternative Currency - -
- -
- -
-
-
+

Delete Wallet

If all funds have been removed from your wallet and you do not wish to have the wallet data stored on your computer anymore, you can delete your wallet.

From 4711558d76d7cb7a75a037b6a12ef2386337e1c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Ar=C3=A1oz?= Date: Thu, 11 Sep 2014 14:39:04 -0700 Subject: [PATCH 076/191] Revert "fix layout style" --- css/src/main.css | 6 ------ views/more.html | 51 ++++++++++++++++++++++++------------------------ 2 files changed, 25 insertions(+), 32 deletions(-) diff --git a/css/src/main.css b/css/src/main.css index 57158c6bc..bea1ac145 100644 --- a/css/src/main.css +++ b/css/src/main.css @@ -249,10 +249,6 @@ a:hover { font-weight: normal; } -fieldset legend { - background: transparent; -} - .import input[type="file"], .import label, .import label small, @@ -1152,8 +1148,6 @@ a.text-warning:hover {color: #FD7262;} display: none; } - - @media only screen and (min-width: 40.063em) { dialog.tiny, .reveal-modal.tiny { width: 50%; diff --git a/views/more.html b/views/more.html index caf1f8f62..cc993d32f 100644 --- a/views/more.html +++ b/views/more.html @@ -1,34 +1,33 @@

Settings

-
-
-
- Wallet Unit - -
-
- Alternative Currency - -
- -
- -
-
+
+

Backup

+

It's important to backup your wallet so that you can recover it in case of disaster

+
-
-
-

Backup

-

It's important to backup your wallet so that you can recover it in case of disaster

- +
+
+ Wallet Unit + +
+
+ Alternative Currency + +
+ +
+
+
+
+

Delete Wallet

If all funds have been removed from your wallet and you do not wish to have the wallet data stored on your computer anymore, you can delete your wallet.

From 187db9c49ba69853a6ab9e0399383658397b9cd9 Mon Sep 17 00:00:00 2001 From: bechi Date: Thu, 11 Sep 2014 18:52:56 -0300 Subject: [PATCH 077/191] fix with tony's feedback --- views/more.html | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/views/more.html b/views/more.html index cc993d32f..8fef9cf89 100644 --- a/views/more.html +++ b/views/more.html @@ -8,32 +8,32 @@
-
-
- Wallet Unit - -
-
- Alternative Currency - -
+
+ +
+ Wallet Unit + +
+
+ Alternative Currency + +
-
- -
- -
-
-
-

Delete Wallet

-

If all funds have been removed from your wallet and you do not wish to have the wallet data stored on your computer anymore, you can delete your wallet.

-
- Delete +
+
+ +
+
+
+

Delete Wallet

+

If all funds have been removed from your wallet and you do not wish to have the wallet data stored on your computer anymore, you can delete your wallet.

+

From d02a159f762a51e93c2dc3128336298b8eb989c7 Mon Sep 17 00:00:00 2001 From: Gustavo Maximiliano Cortez Date: Thu, 11 Sep 2014 22:02:31 -0300 Subject: [PATCH 078/191] Fix address list for small screen --- views/addresses.html | 44 ++++++++++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/views/addresses.html b/views/addresses.html index fb83cbfed..345b02a05 100644 --- a/views/addresses.html +++ b/views/addresses.html @@ -7,28 +7,35 @@

-
-
-
-
-   - - +
+
+
+
+   + + - - change + + change +
+
+ + + + change +
-
-
- - - - - {{addr.balance || 0|noFractionNumber}} {{$root.wallet.settings.unitName}} - +
+ + + + + {{addr.balance || 0|noFractionNumber}} {{$root.wallet.settings.unitName}} + +
-
@@ -40,3 +47,4 @@
+ From 6e5e0846d0cb911e6f1c3dec9d74e8345963d67d Mon Sep 17 00:00:00 2001 From: Gustavo Maximiliano Cortez Date: Thu, 11 Sep 2014 22:09:43 -0300 Subject: [PATCH 079/191] Fix indentation --- views/addresses.html | 47 ++++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/views/addresses.html b/views/addresses.html index 345b02a05..ac0ea08f0 100644 --- a/views/addresses.html +++ b/views/addresses.html @@ -7,44 +7,43 @@
-
-
-
-
-   - +
+
+
+
+   + - - change -
-
- + + change +
+
+ - change -
+ change
-
- +
+
+ - + {{addr.balance || 0|noFractionNumber}} {{$root.wallet.settings.unitName}} -
- - - - Show all - Show less -
+ + + + Show all + Show less +
+
From 1f83f851898fe7169428b0a876af60bf5c8440e2 Mon Sep 17 00:00:00 2001 From: Ivan Socolsky Date: Wed, 10 Sep 2014 18:03:31 -0300 Subject: [PATCH 080/191] separated subscribeToAddresses from getAddressesInfo --- js/models/core/Wallet.js | 17 ++++++----------- js/services/controllerUtils.js | 6 ++++-- test/test.Wallet.js | 17 +++++++++++++++++ 3 files changed, 27 insertions(+), 13 deletions(-) diff --git a/js/models/core/Wallet.js b/js/models/core/Wallet.js index a9f34c4aa..16f26f7c5 100644 --- a/js/models/core/Wallet.js +++ b/js/models/core/Wallet.js @@ -1925,21 +1925,16 @@ Wallet.prototype.getAddressesStr = function(opts) { }); }; +Wallet.prototype.subscribeToAddresses = function() { + var addrInfo = this.publicKeyRing.getAddressesInfo(); + this.blockchain.subscribe(_.pluck(addrInfo, 'addressStr')); +}; + /** * @desc Alias for {@link PublicKeyRing#getAddressesInfo} */ Wallet.prototype.getAddressesInfo = function(opts) { - var addrInfo = this.publicKeyRing.getAddressesInfo(opts, this.publicKey); - var currentAddrs = this.blockchain.getSubscriptions(); - - var newAddrs = []; - for (var i in addrInfo) { - var a = addrInfo[i]; - if (!currentAddrs[a.addressStr] && !a.isChange) - newAddrs.push(a.addressStr); - } - this.blockchain.subscribe(newAddrs); - return addrInfo; + return this.publicKeyRing.getAddressesInfo(opts, this.publicKey); }; /** * @desc Returns true if a given address was generated by deriving our master public key diff --git a/js/services/controllerUtils.js b/js/services/controllerUtils.js index 90fe1948f..8926fd877 100644 --- a/js/services/controllerUtils.js +++ b/js/services/controllerUtils.js @@ -107,7 +107,7 @@ angular.module('copayApp.services') }, 3000); }); w.on('txProposalEvent', function(e) { - + var user = w.publicKeyRing.nicknameForCopayer(e.cId); switch (e.type) { case 'signed': @@ -158,8 +158,10 @@ angular.module('copayApp.services') // TODO movie this to wallet root.updateAddressList = function() { var w = $rootScope.wallet; - if (w && w.isReady()) + if (w && w.isReady()) { + w.subscribeToAddresses(); $rootScope.addrInfos = w.getAddressesInfo(); + } }; root.updateBalance = function(cb) { diff --git a/test/test.Wallet.js b/test/test.Wallet.js index 26498c1e4..62a8f7445 100644 --- a/test/test.Wallet.js +++ b/test/test.Wallet.js @@ -1,5 +1,6 @@ 'use strict'; +var _ = require('underscore'); var chai = chai || require('chai'); var should = chai.should(); var sinon = require('sinon'); @@ -914,6 +915,22 @@ describe('Wallet model', function() { }); }); + describe('#subscribeToAddresses', function() { + it('should subscribe successfully', function() { + var w = cachedCreateW2(); + var addr1 = w.getAddresses()[0].toString(); + var addr2 = w.generateAddress().toString(); + var addr3 = w.generateAddress(true).toString(); + chai.expect(w.getAddresses().length).to.equal(3); + + w.blockchain.subscribe = sinon.spy(); + w.subscribeToAddresses(); + w.blockchain.subscribe.calledOnce.should.equal(true); + var arg = w.blockchain.subscribe.getCall(0).args[0]; + chai.expect(_.difference(arg, [addr1, addr2, addr3]).length).to.equal(0); + }); + }); + describe('#send', function() { it('should call this.network.send', function() { var w = cachedCreateW2(); From 19a8733a9ce3e0726495fb1dda2b83b6c436f50c Mon Sep 17 00:00:00 2001 From: Ivan Socolsky Date: Fri, 12 Sep 2014 10:28:16 -0300 Subject: [PATCH 081/191] resolved conflicts --- test/mocks/FakeWallet.js | 2 ++ test/unit/services/servicesSpec.js | 6 +++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/test/mocks/FakeWallet.js b/test/mocks/FakeWallet.js index 4ca6d3e2c..17be72584 100644 --- a/test/mocks/FakeWallet.js +++ b/test/mocks/FakeWallet.js @@ -84,6 +84,8 @@ FakeWallet.prototype.getAddressesInfo = function() { return ret; }; +FakeWallet.prototype.subscribeToAddresses = function() {}; + FakeWallet.prototype.isShared = function() { return this.totalCopayers > 1; } diff --git a/test/unit/services/servicesSpec.js b/test/unit/services/servicesSpec.js index 7541c26fd..9a5b73faf 100644 --- a/test/unit/services/servicesSpec.js +++ b/test/unit/services/servicesSpec.js @@ -113,7 +113,11 @@ describe('Unit: Rate Service', function() { beforeEach(module(function($provide) { $provide.value('request', { 'get': function(_, cb) { - cb(null, null, [{name: 'lol currency', code: 'LOL', rate: 2}]); + cb(null, null, [{ + name: 'lol currency', + code: 'LOL', + rate: 2 + }]); } }); })); From 81a73e6f2affbda51d191a30d4278d4baf5ef2ea Mon Sep 17 00:00:00 2001 From: Ivan Socolsky Date: Fri, 12 Sep 2014 10:40:47 -0300 Subject: [PATCH 082/191] resolved --- js/models/core/Wallet.js | 8 ++++++++ js/services/backupService.js | 16 ++++++++------- test/mocks/FakeWallet.js | 5 +++++ test/test.Wallet.js | 9 +++++++++ test/unit/controllers/controllersSpec.js | 25 +++++++++++++++++++----- 5 files changed, 51 insertions(+), 12 deletions(-) diff --git a/js/models/core/Wallet.js b/js/models/core/Wallet.js index 16f26f7c5..411c550d1 100644 --- a/js/models/core/Wallet.js +++ b/js/models/core/Wallet.js @@ -632,6 +632,14 @@ Wallet.prototype.getMyCopayerIdPriv = function() { return this.privateKey.getIdPriv(); //copayer idpriv is hex of a private key }; +/** + * @desc Get my own nickname + * @return {string} copayer nickname + */ +Wallet.prototype.getMyCopayerNickname = function() { + return this.publicKeyRing.nicknameForCopayer(this.getMyCopayerId()); +}; + /** * @desc Returns the secret value for other users to join this wallet * @return {string} my own pubkey, base58 encoded diff --git a/js/services/backupService.js b/js/services/backupService.js index dc915d632..eba8255c0 100644 --- a/js/services/backupService.js +++ b/js/services/backupService.js @@ -9,14 +9,17 @@ BackupService.prototype.getName = function(wallet) { return (wallet.name ? (wallet.name + '-') : '') + wallet.id; }; +BackupService.prototype.getCopayer = function(wallet) { + return wallet.getMyCopayerNickname(); +}; + BackupService.prototype.download = function(wallet) { var ew = wallet.toEncryptedObj(); - var partial = !wallet.publicKeyRing.isComplete(); - var walletName = this.getName(wallet) + (partial ? '-Partial' : ''); - var filename = walletName + '-keybackup.json.aes'; + var walletName = this.getName(wallet); + var copayerName = this.getCopayer(wallet); + var filename = copayerName + '-' + walletName + '-keybackup.json.aes'; - var notify = partial ? 'Partial backup created' : 'Backup created'; - this.notifications.success(notify, 'Encrypted backup file saved.'); + this.notifications.success('Backup created', 'Encrypted backup file saved.'); var blob = new Blob([ew], { type: 'text/plain;charset=utf-8' }); @@ -32,9 +35,8 @@ BackupService.prototype.download = function(wallet) { // throw an email intent if we are in the mobile version if (window.cordova) { var name = wallet.name ? wallet.name + ' ' : ''; - var partial = partial ? 'Partial ' : ''; return window.plugin.email.open({ - subject: 'Copay - ' + name + 'Wallet ' + partial + 'Backup', + subject: 'Copay - ' + name + 'Wallet ' + 'Backup', body: 'Here is the encrypted backup of the wallet ' + wallet.id, attachments: ['base64:' + filename + '//' + btoa(ew)] }); diff --git a/test/mocks/FakeWallet.js b/test/mocks/FakeWallet.js index 17be72584..bec56a931 100644 --- a/test/mocks/FakeWallet.js +++ b/test/mocks/FakeWallet.js @@ -23,6 +23,7 @@ var FakeWallet = function() { '1CjPR7Z5ZSyWk6WtXvSFgkptmpoi4UM9BC': 1000 }; this.name = 'myTESTwullet'; + this.nickname = 'myNickname'; this.addressBook = { '2NFR2kzH9NUdp8vsXTB4wWQtTtzhpKxsyoJ': { label: 'John', @@ -86,6 +87,10 @@ FakeWallet.prototype.getAddressesInfo = function() { FakeWallet.prototype.subscribeToAddresses = function() {}; +FakeWallet.prototype.getMyCopayerNickname = function() { + return this.nickname; +}; + FakeWallet.prototype.isShared = function() { return this.totalCopayers > 1; } diff --git a/test/test.Wallet.js b/test/test.Wallet.js index 62a8f7445..c8ae349e5 100644 --- a/test/test.Wallet.js +++ b/test/test.Wallet.js @@ -1221,6 +1221,15 @@ describe('Wallet model', function() { }); }); + describe('#getMyCopayerNickname', function() { + it('should call publicKeyRing.nicknameForCopayer', function() { + var w = cachedCreateW2(); + w.publicKeyRing.nicknameForCopayer = sinon.spy(); + w.getMyCopayerNickname(); + w.publicKeyRing.nicknameForCopayer.calledOnce.should.equal(true); + }); + }); + describe('#netStart', function() { it('should call Network.start', function() { var w = cachedCreateW2(); diff --git a/test/unit/controllers/controllersSpec.js b/test/unit/controllers/controllersSpec.js index 38bd1f6a1..bb836fb69 100644 --- a/test/unit/controllers/controllersSpec.js +++ b/test/unit/controllers/controllersSpec.js @@ -5,9 +5,11 @@ var sinon = require('sinon'); // Replace saveAs plugin -saveAsLastCall = null; -saveAs = function(o) { - saveAsLastCall = o; +saveAs = function(blob, filename) { + saveAsLastCall = { + blob: blob, + filename: filename + }; }; var startServer = require('../../mocks/FakePayProServer'); @@ -35,6 +37,11 @@ describe("Unit: Controllers", function() { }; describe('More Controller', function() { + it('Copay config should be binded', function() { + should.exist(config); + should.exist(config.unitToSatoshi); + }); + var ctrl; beforeEach(inject(function($controller, $rootScope) { scope = $rootScope.$new(); @@ -44,14 +51,22 @@ describe("Unit: Controllers", function() { $scope: scope, $modal: {}, }); + saveAsLastCall = null; })); it('Backup controller #download', function() { scope.wallet.setEnc('1234567'); expect(saveAsLastCall).equal(null); scope.downloadBackup(); - expect(saveAsLastCall.size).equal(7); - expect(saveAsLastCall.type).equal('text/plain;charset=utf-8'); + expect(saveAsLastCall.blob.size).equal(7); + expect(saveAsLastCall.blob.type).equal('text/plain;charset=utf-8'); + }); + + it('Backup controller should name backup correctly', function() { + scope.wallet.setEnc('1234567'); + expect(saveAsLastCall).equal(null); + scope.downloadBackup(); + expect(saveAsLastCall.filename).equal('myNickname-myTESTwullet-testID-keybackup.json.aes'); }); it('Backup controller #delete', function() { From 7cf2a474ddec0db169ad5d677691197fa48d2f36 Mon Sep 17 00:00:00 2001 From: Ivan Socolsky Date: Fri, 12 Sep 2014 10:37:11 -0300 Subject: [PATCH 083/191] removed old test --- test/unit/controllers/controllersSpec.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/test/unit/controllers/controllersSpec.js b/test/unit/controllers/controllersSpec.js index bb836fb69..0dd6b38a5 100644 --- a/test/unit/controllers/controllersSpec.js +++ b/test/unit/controllers/controllersSpec.js @@ -37,11 +37,6 @@ describe("Unit: Controllers", function() { }; describe('More Controller', function() { - it('Copay config should be binded', function() { - should.exist(config); - should.exist(config.unitToSatoshi); - }); - var ctrl; beforeEach(inject(function($controller, $rootScope) { scope = $rootScope.$new(); From 8d7e420524308674f58935b3aa321e8c38df6f8d Mon Sep 17 00:00:00 2001 From: Ivan Socolsky Date: Fri, 12 Sep 2014 11:10:45 -0300 Subject: [PATCH 084/191] No copayer nickname on 1-1 wallets --- js/services/backupService.js | 4 ++-- test/unit/controllers/controllersSpec.js | 10 +++++++++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/js/services/backupService.js b/js/services/backupService.js index eba8255c0..24f0763f4 100644 --- a/js/services/backupService.js +++ b/js/services/backupService.js @@ -10,14 +10,14 @@ BackupService.prototype.getName = function(wallet) { }; BackupService.prototype.getCopayer = function(wallet) { - return wallet.getMyCopayerNickname(); + return wallet.totalCopayers > 1 ? wallet.getMyCopayerNickname() : ''; }; BackupService.prototype.download = function(wallet) { var ew = wallet.toEncryptedObj(); var walletName = this.getName(wallet); var copayerName = this.getCopayer(wallet); - var filename = copayerName + '-' + walletName + '-keybackup.json.aes'; + var filename = (copayerName ? copayerName + '-' : '') + walletName + '-keybackup.json.aes'; this.notifications.success('Backup created', 'Encrypted backup file saved.'); var blob = new Blob([ew], { diff --git a/test/unit/controllers/controllersSpec.js b/test/unit/controllers/controllersSpec.js index 0dd6b38a5..48214a907 100644 --- a/test/unit/controllers/controllersSpec.js +++ b/test/unit/controllers/controllersSpec.js @@ -57,13 +57,21 @@ describe("Unit: Controllers", function() { expect(saveAsLastCall.blob.type).equal('text/plain;charset=utf-8'); }); - it('Backup controller should name backup correctly', function() { + it('Backup controller should name backup correctly for multiple copayers', function() { scope.wallet.setEnc('1234567'); expect(saveAsLastCall).equal(null); scope.downloadBackup(); expect(saveAsLastCall.filename).equal('myNickname-myTESTwullet-testID-keybackup.json.aes'); }); + it('Backup controller should name backup correctly for 1-1 wallet', function() { + scope.wallet.setEnc('1234567'); + expect(saveAsLastCall).equal(null); + scope.wallet.totalCopayers = 1; + scope.downloadBackup(); + expect(saveAsLastCall.filename).equal('myTESTwullet-testID-keybackup.json.aes'); + }); + it('Backup controller #delete', function() { expect(scope.wallet).not.equal(undefined); scope.deleteWallet(); From 84dbcb038a0fcd1cbed63441f8fe91269aa1cb37 Mon Sep 17 00:00:00 2001 From: Matias Pando Date: Wed, 10 Sep 2014 15:28:13 -0300 Subject: [PATCH 085/191] Fixed --- js/controllers/copayers.js | 8 +++++++- views/copayers.html | 33 ++++++++++++++++++--------------- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/js/controllers/copayers.js b/js/controllers/copayers.js index fc140593b..cf3b880cc 100644 --- a/js/controllers/copayers.js +++ b/js/controllers/copayers.js @@ -5,6 +5,12 @@ angular.module('copayApp.controllers').controller('CopayersController', $scope.hideAdv = true; + + $scope.skipBackup = function() { + var w = $rootScope.wallet; + w.setBackupReady(); + }; + $scope.backup = function() { var w = $rootScope.wallet; w.setBackupReady(); @@ -37,4 +43,4 @@ angular.module('copayApp.controllers').controller('CopayersController', return $rootScope.wallet.publicKeyRing.isBackupReady(copayer.copayerId); } - }); + }); \ No newline at end of file diff --git a/views/copayers.html b/views/copayers.html index cbd00e805..ddd2a02a5 100644 --- a/views/copayers.html +++ b/views/copayers.html @@ -51,6 +51,7 @@
+ Creating and storing a backup will allow to restore funds of the wallet
@@ -75,21 +76,23 @@
-
- + + + + + Skip Backup + +
- - - From 2b540264a5631ceab159b92bd240cf0852e8baab Mon Sep 17 00:00:00 2001 From: Matias Pando Date: Thu, 11 Sep 2014 10:28:56 -0300 Subject: [PATCH 087/191] Conflicts solved --- js/models/core/Wallet.js | 2 +- test/test.Wallet.js | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/js/models/core/Wallet.js b/js/models/core/Wallet.js index 358037fb7..06c2a08c5 100644 --- a/js/models/core/Wallet.js +++ b/js/models/core/Wallet.js @@ -87,7 +87,7 @@ function Wallet(opts) { this.lastMessageFrom = {}; //to avoid confirmation of copayer's backups if is imported from a file - this.isImported = opts.isImported; + this.isImported = opts.isImported || false; this.paymentRequests = opts.paymentRequests || {}; diff --git a/test/test.Wallet.js b/test/test.Wallet.js index c8ae349e5..94bef86f8 100644 --- a/test/test.Wallet.js +++ b/test/test.Wallet.js @@ -840,6 +840,23 @@ describe('Wallet model', function() { }); }); + describe('#createTxSync', 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) { var w = cachedCreateW2(); From db7d33682e3c97bc9d6947c71cf2c2ebd6504e25 Mon Sep 17 00:00:00 2001 From: Matias Pando Date: Thu, 11 Sep 2014 11:30:55 -0300 Subject: [PATCH 088/191] Solving conflicts --- test/test.Wallet.js | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/test/test.Wallet.js b/test/test.Wallet.js index 94bef86f8..c8ae349e5 100644 --- a/test/test.Wallet.js +++ b/test/test.Wallet.js @@ -840,23 +840,6 @@ describe('Wallet model', function() { }); }); - describe('#createTxSync', 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) { var w = cachedCreateW2(); From 778086ca1df38c5169926fcbaf169b9824c4ef3c Mon Sep 17 00:00:00 2001 From: bechi Date: Thu, 11 Sep 2014 11:54:14 -0300 Subject: [PATCH 089/191] fix text color --- views/copayers.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/views/copayers.html b/views/copayers.html index a9c7427f9..1b7f82bdc 100644 --- a/views/copayers.html +++ b/views/copayers.html @@ -51,7 +51,7 @@
- Creating and storing a backup will allow to restore funds of the wallet +

Creating and storing a backup will allow to restore funds of the wallet

From 7847cd5067eeff812810e8cf06bdf52eb74daa2d Mon Sep 17 00:00:00 2001 From: bechi Date: Thu, 11 Sep 2014 13:01:22 -0300 Subject: [PATCH 090/191] fix style --- css/src/main.css | 2 +- views/copayers.html | 18 +++++++++--------- views/join.html | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/css/src/main.css b/css/src/main.css index bea1ac145..16d4d0d2a 100644 --- a/css/src/main.css +++ b/css/src/main.css @@ -1046,7 +1046,7 @@ a.text-warning:hover {color: #FD7262;} background: #2C3E50; -moz-box-shadow: 0px 0px 0px 0px rgba(255,255,255,0.09), inset 0px 0px 2px 0px rgba(0,0,0,0.20); box-shadow: 0px 0px 0px 0px rgba(255,255,255,0.09), inset 0px 0px 2px 0px rgba(0,0,0,0.20); - margin-bottom: 5px; + margin-bottom: 15px; } .box-setup-copay-required { diff --git a/views/copayers.html b/views/copayers.html index 1b7f82bdc..22f0749d3 100644 --- a/views/copayers.html +++ b/views/copayers.html @@ -51,7 +51,7 @@
-

Creating and storing a backup will allow to restore funds of the wallet

+

Creating and storing a backup will allow to restore funds of the wallet

@@ -75,14 +75,7 @@
-
- - Skip Backup - - - + + + Skip Backup + +
-

Creating and storing a backup will allow to restore funds of the wallet

+

Creating and storing a backup will allow to restore funds of the wallet

From b7373367a18f431f9fa3b4e8aa9900775f7dde0a Mon Sep 17 00:00:00 2001 From: Matias Pando Date: Fri, 12 Sep 2014 13:25:52 -0300 Subject: [PATCH 092/191] Skip avoid waiting for other copayers --- js/controllers/copayers.js | 4 ++-- js/models/core/Wallet.js | 8 ++++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/js/controllers/copayers.js b/js/controllers/copayers.js index cf3b880cc..57573b4d0 100644 --- a/js/controllers/copayers.js +++ b/js/controllers/copayers.js @@ -8,7 +8,7 @@ angular.module('copayApp.controllers').controller('CopayersController', $scope.skipBackup = function() { var w = $rootScope.wallet; - w.setBackupReady(); + w.setBackupReady(true); }; $scope.backup = function() { @@ -43,4 +43,4 @@ angular.module('copayApp.controllers').controller('CopayersController', return $rootScope.wallet.publicKeyRing.isBackupReady(copayer.copayerId); } - }); \ No newline at end of file + }); diff --git a/js/models/core/Wallet.js b/js/models/core/Wallet.js index 06c2a08c5..c3508f539 100644 --- a/js/models/core/Wallet.js +++ b/js/models/core/Wallet.js @@ -89,6 +89,9 @@ function Wallet(opts) { //to avoid confirmation of copayer's backups if is imported from a file this.isImported = opts.isImported || false; + //to avoid waiting others copayers to make a backup and login immediatly + this.forcedLogin = opts.forcedLogin || false; + this.paymentRequests = opts.paymentRequests || {}; //network nonces are 8 byte buffers, representing a big endian number @@ -2430,7 +2433,7 @@ Wallet.prototype.isShared = function() { * @return {boolean} */ Wallet.prototype.isReady = function() { - var ret = this.publicKeyRing.isComplete() && (this.publicKeyRing.isFullyBackup() || this.isImported); + var ret = this.publicKeyRing.isComplete() && (this.publicKeyRing.isFullyBackup() || this.isImported || this.forcedLogin); return ret; }; @@ -2439,7 +2442,8 @@ Wallet.prototype.isReady = function() { * * Also backs up the wallet */ -Wallet.prototype.setBackupReady = function() { +Wallet.prototype.setBackupReady = function(forcedLogin) { + this.forcedLogin = forcedLogin; this.publicKeyRing.setBackupReady(); this.sendPublicKeyRing(); this.store(); From 0698c70cce5f3b2efec5fdb4a1ff907f74cbe826 Mon Sep 17 00:00:00 2001 From: Matias Pando Date: Fri, 12 Sep 2014 14:56:19 -0300 Subject: [PATCH 093/191] Conflicts fixed --- js/controllers/copayers.js | 4 ---- js/models/core/Wallet.js | 5 ++--- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/js/controllers/copayers.js b/js/controllers/copayers.js index 5703c751e..57573b4d0 100644 --- a/js/controllers/copayers.js +++ b/js/controllers/copayers.js @@ -8,11 +8,7 @@ angular.module('copayApp.controllers').controller('CopayersController', $scope.skipBackup = function() { var w = $rootScope.wallet; -<<<<<<< HEAD w.setBackupReady(true); -======= - w.setBackupReady(); ->>>>>>> 6703652ea9d7e9e8c9a137a735b2fc2fc6de2494 }; $scope.backup = function() { diff --git a/js/models/core/Wallet.js b/js/models/core/Wallet.js index 481719830..6b91a8b0d 100644 --- a/js/models/core/Wallet.js +++ b/js/models/core/Wallet.js @@ -2433,9 +2433,8 @@ Wallet.prototype.isShared = function() { * @desc Returns true if the keyring is complete and all users have backed up the wallet * @return {boolean} */ -Wallet.prototype.isReady = function() { << << << < HEAD - var ret = this.publicKeyRing.isComplete() && (this.publicKeyRing.isFullyBackup() || this.isImported || this.forcedLogin); === === = - var ret = this.publicKeyRing.isComplete() && (this.publicKeyRing.isFullyBackup() || this.isImported); >>> >>> > 6703652ea9d7e9e8c9a137a735b2fc2fc6de2494 +Wallet.prototype.isReady = function() { + var ret = this.publicKeyRing.isComplete() && (this.publicKeyRing.isFullyBackup() || this.isImported || this.forcedLogin); return ret; }; From ce975ed0ab6e1268e5692d33e5a9823d5d8516ed Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Fri, 12 Sep 2014 11:23:44 -0700 Subject: [PATCH 094/191] wording fix --- views/more.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/views/more.html b/views/more.html index 8fef9cf89..425b873c5 100644 --- a/views/more.html +++ b/views/more.html @@ -73,7 +73,7 @@

Purge Pending Transaction Proposals

- Pending Transactions Proposals will be discarted. This need to be done on ALL peers of a wallet, to prevent the old proposals to be resynced again. + Pending Transactions Proposals will be discarted. This needs to be done on ALL peers of a wallet, to prevent the old proposals to be resynced again.

-

Creating and storing a backup will allow to restore funds of the wallet

+

+ Creating and storing a backup will allow you to recover wallet funds +

From de43990882292ac911f7036947112dc9f2e86861 Mon Sep 17 00:00:00 2001 From: Matias Pando Date: Fri, 12 Sep 2014 10:24:27 -0300 Subject: [PATCH 097/191] Conflicts fixed --- js/directives.js | 12 +++++++----- views/create.html | 14 ++++++++++++++ views/join.html | 1 + 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/js/directives.js b/js/directives.js index 897757e39..27a4a131c 100644 --- a/js/directives.js +++ b/js/directives.js @@ -6,17 +6,16 @@ var bignum = bitcore.Bignum; var preconditions = require('preconditions').singleton(); angular.module('copayApp.directives') - .directive('validAddress', ['$rootScope', function($rootScope) { +.directive('validAddress', ['$rootScope', + function($rootScope) { return { require: 'ngModel', link: function(scope, elem, attrs, ctrl) { var validator = function(value) { // If we're setting the domain, ignore the change. - if ($rootScope.merchant - && $rootScope.merchant.domain - && value === $rootScope.merchant.domain) { + if ($rootScope.merchant && $rootScope.merchant.domain && value === $rootScope.merchant.domain) { ctrl.$setValidity('validAddress', true); return value; } @@ -27,6 +26,7 @@ angular.module('copayApp.directives') return value; } + // Bip21 uri if (/^bitcoin:/.test(value)) { var uri = new bitcore.BIP21(value); @@ -41,11 +41,13 @@ angular.module('copayApp.directives') return value; }; + ctrl.$parsers.unshift(validator); ctrl.$formatters.unshift(validator); } }; - }]) + } +]) .directive('enoughAmount', ['$rootScope', function($rootScope) { var w = $rootScope.wallet; diff --git a/views/create.html b/views/create.html index ddc4c6ce8..fca8cfb3c 100644 --- a/views/create.html +++ b/views/create.html @@ -30,6 +30,7 @@ @@ -38,6 +39,19 @@
+======= + symbols" + tooltip-trigger="focus" required + tooltip-placement="top"> + + Please enter the same password you entered above + +>>>>>>> Fixed
diff --git a/views/join.html b/views/join.html index 9f972d352..7e58dba5d 100644 --- a/views/join.html +++ b/views/join.html @@ -64,6 +64,7 @@ numbers and symbols" tooltip-trigger="focus" tooltip-placement="top" required> + Please enter the same password you entered above Date: Fri, 12 Sep 2014 10:33:28 -0300 Subject: [PATCH 098/191] Fixed --- views/create.html | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/views/create.html b/views/create.html index fca8cfb3c..ca7a897c1 100644 --- a/views/create.html +++ b/views/create.html @@ -30,28 +30,14 @@ - + Please enter the same password you entered above
-======= - symbols" - tooltip-trigger="focus" required - tooltip-placement="top"> - - Please enter the same password you entered above - ->>>>>>> Fixed
From 4de113fa19297bc63db8f3a7ab950dbcbbed1ad8 Mon Sep 17 00:00:00 2001 From: Matias Pando Date: Fri, 12 Sep 2014 12:52:34 -0300 Subject: [PATCH 099/191] Translation added --- po/es.po | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/po/es.po b/po/es.po index c3de76e45..038cb2993 100644 --- a/po/es.po +++ b/po/es.po @@ -738,3 +738,12 @@ msgstr "Faltan {{tx.missingSignatures}} firmas" #~ msgstr "" #~ "Nombre del\n" #~ " monedero" + +#: views/create.html +msgid "Please enter the same password you entered above" +msgstr "Por favor ingrese la misma contraseña ingresada arriba" + +#: views/join.html +msgid "Please enter the same password you entered above" +msgstr "Por favor ingrese la misma contraseña ingresada arriba" + From 2bb61501bb2aa97aa3ba99b4ce2dca48b0a67fb8 Mon Sep 17 00:00:00 2001 From: bechi Date: Fri, 12 Sep 2014 17:06:38 -0300 Subject: [PATCH 100/191] fix ui --- po/es.po | 10 ++++++---- views/create.html | 18 ++++++++++++------ views/join.html | 27 +++++++++++++++++++-------- 3 files changed, 37 insertions(+), 18 deletions(-) diff --git a/po/es.po b/po/es.po index 038cb2993..0e8aa2757 100644 --- a/po/es.po +++ b/po/es.po @@ -740,10 +740,12 @@ msgstr "Faltan {{tx.missingSignatures}} firmas" #~ " monedero" #: views/create.html -msgid "Please enter the same password you entered above" -msgstr "Por favor ingrese la misma contraseña ingresada arriba" +msgid "Passwords must match" +msgstr "Las contraseñas deben coincidir" #: views/join.html -msgid "Please enter the same password you entered above" -msgstr "Por favor ingrese la misma contraseña ingresada arriba" +msgid "Passwords must match" +msgstr "Las contraseñas deben coincidir" + + diff --git a/views/create.html b/views/create.html index ca7a897c1..f1a2f5178 100644 --- a/views/create.html +++ b/views/create.html @@ -24,17 +24,23 @@
-
+
diff --git a/views/join.html b/views/join.html index 7e58dba5d..d11b34edf 100644 --- a/views/join.html +++ b/views/join.html @@ -22,9 +22,13 @@
-
+
+ +
  @@ -64,13 +68,20 @@ numbers and symbols" tooltip-trigger="focus" tooltip-placement="top" required> - Please enter the same password you entered above - - +
+ + +

+ + {{'Passwords must match'|translate}} +

+
+ +
Show Hide advanced options From a599251b39ef2897ad9b4988c7d6996b9a71991e Mon Sep 17 00:00:00 2001 From: Matias Pando Date: Sat, 13 Sep 2014 08:46:55 -0300 Subject: [PATCH 101/191] Fixed --- js/controllers/join.js | 9 ++++----- views/create.html | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/js/controllers/join.js b/js/controllers/join.js index 2a9ee0c51..2de8fa49a 100644 --- a/js/controllers/join.js +++ b/js/controllers/join.js @@ -7,7 +7,7 @@ angular.module('copayApp.controllers').controller('JoinController', $scope.loading = false; $scope.isMobile = !!window.cordova; - // QR code Scanner + // QR code Scanner var cameraInput; var video; var canvas; @@ -15,14 +15,13 @@ angular.module('copayApp.controllers').controller('JoinController', var context; var localMediaStream; - $scope.hideAdv=true; - + $scope.hideAdv = true; navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia; - if (!window.cordova && !navigator.getUserMedia) - $scope.disableScanner =1; + if (!window.cordova && !navigator.getUserMedia) + $scope.disableScanner = 1; var _scan = function(evt) { if (localMediaStream) { diff --git a/views/create.html b/views/create.html index f1a2f5178..a22ba56b7 100644 --- a/views/create.html +++ b/views/create.html @@ -36,7 +36,7 @@

- Passwords must match + {{'Passwords must match'|translate}}

From 027043bd6f56cd34eaf025fd5bf5bad86d838acd Mon Sep 17 00:00:00 2001 From: Esteban Ordano Date: Mon, 8 Sep 2014 15:42:55 -0300 Subject: [PATCH 102/191] JSDocs generated by grunt --- .gitignore | 2 ++ Gruntfile.js | 37 ++++++++++++++++++++++----------- js/models/core/HDPath.js | 3 +-- js/models/core/PrivateKey.js | 1 + js/models/core/PublicKeyRing.js | 8 +++---- js/models/core/Wallet.js | 21 ++++++++++--------- js/models/core/WalletFactory.js | 3 ++- jsdoc.conf.json | 18 ++++++++++++++++ package.json | 3 ++- 9 files changed, 66 insertions(+), 30 deletions(-) create mode 100644 jsdoc.conf.json diff --git a/.gitignore b/.gitignore index 28fe0f592..f7555ecd4 100644 --- a/.gitignore +++ b/.gitignore @@ -77,3 +77,5 @@ dist/windows dist/*.dmg dist/*.tar.gz dist/*.exe + +doc/ diff --git a/Gruntfile.js b/Gruntfile.js index d78203f5e..090c67c91 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -9,6 +9,7 @@ module.exports = function(grunt) { grunt.loadNpmTasks('grunt-contrib-concat'); grunt.loadNpmTasks('grunt-contrib-uglify'); grunt.loadNpmTasks('grunt-angular-gettext'); + grunt.loadNpmTasks('grunt-jsdoc'); // Project Configuration grunt.initConfig({ @@ -16,7 +17,7 @@ module.exports = function(grunt) { prod: { options: { stdout: false, - stderr: false + stderr: false }, command: 'node ./util/build.js' }, @@ -52,12 +53,12 @@ module.exports = function(grunt) { main: { files: [ 'js/init.js', - 'js/app.js', - 'js/directives.js', - 'js/filters.js', - 'js/routes.js', + 'js/app.js', + 'js/directives.js', + 'js/filters.js', + 'js/routes.js', 'js/mobile.js', - 'js/services/*.js', + 'js/services/*.js', 'js/controllers/*.js' ], tasks: ['concat:main'] @@ -119,11 +120,11 @@ module.exports = function(grunt) { }, main: { src: [ - 'js/app.js', - 'js/directives.js', - 'js/filters.js', - 'js/routes.js', - 'js/services/*.js', + 'js/app.js', + 'js/directives.js', + 'js/filters.js', + 'js/routes.js', + 'js/services/*.js', 'js/controllers/*.js', 'js/translations.js', 'js/mobile.js', // PLACEHOLDER: CORDOVA SRIPT @@ -172,11 +173,23 @@ module.exports = function(grunt) { 'js/translations.js': ['po/*.po'] } }, + }, + jsdoc: { + dist : { + src: ['js/models/core/*.js'], + options: { + destination: 'doc', + configure: 'jsdoc.conf.json', + template: './node_modules/grunt-jsdoc/node_modules/ink-docstrap/template', + theme: 'flatly' + } + } } }); + grunt.registerTask('default', ['shell:dev', 'nggettext_compile', 'concat', 'cssmin']); grunt.registerTask('prod', ['shell:prod', 'nggettext_compile', 'concat', 'cssmin', 'uglify']); grunt.registerTask('translate', ['nggettext_extract']); - + grunt.registerTask('docs', ['jsdoc2md']); }; diff --git a/js/models/core/HDPath.js b/js/models/core/HDPath.js index 3960284bf..041912742 100644 --- a/js/models/core/HDPath.js +++ b/js/models/core/HDPath.js @@ -7,10 +7,9 @@ var _ = require('underscore'); /** * @namespace - * + * @desc * HDPath contains helper functions to handle BIP32 branches as * Copay uses them. - * * Based on https://github.com/maraoz/bips/blob/master/bip-NNNN.mediawiki *
  * m / purpose' / copayerIndex / change:boolean / addressIndex
diff --git a/js/models/core/PrivateKey.js b/js/models/core/PrivateKey.js
index 8df3325c7..e8dcd8737 100644
--- a/js/models/core/PrivateKey.js
+++ b/js/models/core/PrivateKey.js
@@ -21,6 +21,7 @@ var HDPath = require('./HDPath');
  * @param {string} opts.extendedPrivateKeyString if set, use this private key
  *                                               string, othewise create a new
  *                                               private key
+ * @constructor
  */
 function PrivateKey(opts) {
   opts = opts || {};
diff --git a/js/models/core/PublicKeyRing.js b/js/models/core/PublicKeyRing.js
index 0c22694aa..54fca0faf 100644
--- a/js/models/core/PublicKeyRing.js
+++ b/js/models/core/PublicKeyRing.js
@@ -12,7 +12,7 @@ var HDPath = require('./HDPath');
 var HDParams = require('./HDParams');
 
 /**
- * @desc
+ * @desc Represents a public key ring, the set of all public keys and the used indexes
  *
  * @constructor
  * @param {Object} opts
@@ -20,10 +20,10 @@ var HDParams = require('./HDParams');
  * @param {string} opts.network 'livenet' to signal the bitcoin main network, all others are testnet
  * @param {number=} opts.requiredCopayers - defaults to 3
  * @param {number=} opts.totalCopayers - defaults to 5
- * @param {Object[]=} opts.indexes - an array to be deserialized using {@link HDParams#fromList}
+ * @param {Object[]} [opts.indexes] - an array to be deserialized using {@link HDParams#fromList}
  *                                   (defaults to all indexes in zero)
  * @param {Object=} opts.nicknameFor - nicknames for other copayers
- * @param {boolean[]=} opts.copayersBackup - whether other copayers have backed up their wallets
+ * @param {boolean[]} [opts.copayersBackup] - whether other copayers have backed up their wallets
  */
 function PublicKeyRing(opts) {
   opts = opts || {};
@@ -527,7 +527,7 @@ PublicKeyRing.prototype.getForPath = function(path) {
  * @see PublicKeyRing#getForPath
  *
  * @param {string[]} paths - the BIP32 paths
- * @return {Buffer[][]} the public keys, in buffer format
+ * @return {Array[]} the public keys, in buffer format (matrix of Buffer, Buffer[][])
  */
 PublicKeyRing.prototype.getForPaths = function(paths) {
   preconditions.checkArgument(!_.isUndefined(paths));
diff --git a/js/models/core/Wallet.js b/js/models/core/Wallet.js
index 6b91a8b0d..61e81b137 100644
--- a/js/models/core/Wallet.js
+++ b/js/models/core/Wallet.js
@@ -53,6 +53,7 @@ var copayConfig = require('../../../config');
  * @TODO: figure out if reconnectDelay is set in milliseconds
  * @param {number} opts.reconnectDelay - amount of seconds to wait before
  *                                       attempting to reconnect
+ * @constructor
  */
 function Wallet(opts) {
   var self = this;
@@ -171,7 +172,7 @@ Wallet.prototype.seedCopayer = function(pubKey) {
  *
  * @param {string} senderId - the sender id
  * @param {Object} data - the data recived, {@see HDParams#fromList}
- * @emits {publicKeyRingUpdated}
+ * @emits publicKeyRingUpdated
  */
 Wallet.prototype._onIndexes = function(senderId, data) {
   log.debug('RECV INDEXES:', data);
@@ -216,8 +217,8 @@ Wallet.prototype.changeSettings = function(settings) {
  * @param {Object} data - the data recived, {@see HDParams#fromList}
  * @param {Object} data.publicKeyRing - data to be deserialized into a {@link PublicKeyRing}
  *                                      using {@link PublicKeyRing#fromObj}
- * @emits {publicKeyRingUpdated}
- * @emits {connectionError}
+ * @emits publicKeyRingUpdated
+ * @emits connectionError
  */
 Wallet.prototype._onPublicKeyRing = function(senderId, data) {
   log.debug('RECV PUBLICKEYRING:', data);
@@ -252,7 +253,7 @@ Wallet.prototype._onPublicKeyRing = function(senderId, data) {
  *
  * @param {string} senderId - the copayer that sent this event
  * @param {Object} m - the data received
- * @emits {txProposalEvent}
+ * @emits txProposalEvent
  */
 Wallet.prototype._processProposalEvents = function(senderId, m) {
   var ev;
@@ -955,7 +956,7 @@ Wallet.prototype.sendAllTxProposals = function(recipients, sinceTs) {
 /**
  * @desc Send a TxProposal identified by transaction id to a set of recipients
  * @param {string} ntxid - the transaction proposal id
- * @param {string[]=} recipients - the pubkeys of the recipients
+ * @param {string[]} [recipients] - the pubkeys of the recipients
  */
 Wallet.prototype.sendTxProposal = function(ntxid, recipients) {
   preconditions.checkArgument(ntxid);
@@ -997,7 +998,7 @@ Wallet.prototype.sendReject = function(ntxid) {
 
 /**
  * @desc Notify other peers that a wallet has been backed up and it's ready to be used
- * @param {string[]=} recipients - the pubkeys of the recipients
+ * @param {string[]} [recipients] - the pubkeys of the recipients
  */
 Wallet.prototype.sendWalletReady = function(recipients, sinceTs) {
   log.debug('### SENDING WalletReady TO:', recipients || 'All');
@@ -1012,7 +1013,7 @@ Wallet.prototype.sendWalletReady = function(recipients, sinceTs) {
 /**
  * @desc Notify other peers of the walletId
  * @TODO: Why is this needed? Can't everybody just calculate the walletId?
- * @param {string[]=} recipients - the pubkeys of the recipients
+ * @param {string[]} [recipients] - the pubkeys of the recipients
  */
 Wallet.prototype.sendWalletId = function(recipients) {
   log.debug('### SENDING walletId TO:', recipients || 'All', this.id);
@@ -1027,7 +1028,7 @@ Wallet.prototype.sendWalletId = function(recipients) {
 
 /**
  * @desc Send the current PublicKeyRing to other recipients
- * @param {string[]=} recipients - the pubkeys of the recipients
+ * @param {string[]} [recipients] - the pubkeys of the recipients
  */
 Wallet.prototype.sendPublicKeyRing = function(recipients) {
   log.debug('### SENDING publicKeyRing TO:', recipients || 'All', this.publicKeyRing.toObj());
@@ -1042,7 +1043,7 @@ Wallet.prototype.sendPublicKeyRing = function(recipients) {
 
 /**
  * @desc Send the current indexes of our public key ring to other peers
- * @param {string[]=} recipients - the pubkeys of the recipients
+ * @param {string[]} recipients - the pubkeys of the recipients
  */
 Wallet.prototype.sendIndexes = function(recipients) {
   var indexes = HDParams.serialize(this.publicKeyRing.indexes);
@@ -1057,7 +1058,7 @@ Wallet.prototype.sendIndexes = function(recipients) {
 
 /**
  * @desc Send our addressBook to other recipients
- * @param {string[]=} recipients - the pubkeys of the recipients
+ * @param {string[]} recipients - the pubkeys of the recipients
  */
 Wallet.prototype.sendAddressBook = function(recipients) {
   log.debug('### SENDING addressBook TO:', recipients || 'All', this.addressBook);
diff --git a/js/models/core/WalletFactory.js b/js/models/core/WalletFactory.js
index 33d763451..b91853657 100644
--- a/js/models/core/WalletFactory.js
+++ b/js/models/core/WalletFactory.js
@@ -30,6 +30,7 @@ var preconditions = require('preconditions').singleton();
  * @param {Object} config.wallet - default configuration for the wallet
  * @TODO: put `version` inside of the config object
  * @param {string} version - the version of copay for which this wallet was generated (for example, 0.4.7)
+ * @constructor
  */
 function WalletFactory(config, version) {
   var self = this;
@@ -318,7 +319,7 @@ WalletFactory.prototype.decodeSecret = function(secret) {
 
 /**
  * @callback walletCreationCallback
- * @param {?=} err - an error, if any, that happened during the wallet creation
+ * @param {?} err - an error, if any, that happened during the wallet creation
  * @param {Wallet=} wallet - the wallet created
  */
 
diff --git a/jsdoc.conf.json b/jsdoc.conf.json
new file mode 100644
index 000000000..5c5c11650
--- /dev/null
+++ b/jsdoc.conf.json
@@ -0,0 +1,18 @@
+{
+    "tags": {
+        "allowUnknownTags": true
+    },
+    "source": {
+        "includePattern": ".+\\.js(doc)?$",
+        "excludePattern": "(^|\\/|\\\\)_"
+    },
+    "plugins": [],
+    "templates": {
+        "cleverLinks": false,
+        "monospaceLinks": false,
+        "default": {
+            "outputSourceFiles": true
+        },
+        "theme": "flatly"
+    }
+}
diff --git a/package.json b/package.json
index dcf7345df..7248c5c0f 100644
--- a/package.json
+++ b/package.json
@@ -55,17 +55,18 @@
     "express": "4.0.0",
     "github-releases": "0.2.0",
     "grunt": "^0.4.5",
+    "grunt-angular-gettext": "^0.2.15",
     "grunt-browserify": "2.0.8",
     "grunt-cli": "^0.1.13",
     "grunt-contrib-concat": "0.5.0",
     "grunt-contrib-cssmin": "0.10.0",
     "grunt-contrib-uglify": "^0.5.1",
     "grunt-contrib-watch": "0.5.3",
+    "grunt-jsdoc": "^0.5.7",
     "grunt-markdown": "0.5.0",
     "bitcore": "0.1.36",
     "grunt-mocha-test": "0.8.2",
     "grunt-shell": "0.6.4",
-    "grunt-angular-gettext": "^0.2.15",
     "istanbul": "0.2.10",
     "karma": "0.12.9",
     "karma-chrome-launcher": "0.1.3",

From 313efa95031e5045fbd19e31d046d81558b28e1f Mon Sep 17 00:00:00 2001
From: Esteban Ordano 
Date: Wed, 10 Sep 2014 21:38:30 -0300
Subject: [PATCH 103/191] Fixes old version of grunt

---
 Gruntfile.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Gruntfile.js b/Gruntfile.js
index 090c67c91..8844d8e30 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -191,5 +191,5 @@ module.exports = function(grunt) {
   grunt.registerTask('default', ['shell:dev', 'nggettext_compile', 'concat', 'cssmin']);
   grunt.registerTask('prod', ['shell:prod', 'nggettext_compile', 'concat', 'cssmin', 'uglify']);
   grunt.registerTask('translate', ['nggettext_extract']);
-  grunt.registerTask('docs', ['jsdoc2md']);
+  grunt.registerTask('docs', ['jsdoc']);
 };

From d85fcbfe077d99a2c262ea9a16b802fdedac44b6 Mon Sep 17 00:00:00 2001
From: Gustavo Maximiliano Cortez 
Date: Mon, 15 Sep 2014 10:16:40 -0300
Subject: [PATCH 104/191] Remove forceNetwork

---
 config.js                | 1 -
 js/app.js                | 3 ---
 js/models/core/Wallet.js | 3 ---
 test/test.Wallet.js      | 9 ---------
 4 files changed, 16 deletions(-)

diff --git a/config.js b/config.js
index a22baad87..82dc4f1d6 100644
--- a/config.js
+++ b/config.js
@@ -3,7 +3,6 @@ var defaultConfig = {
   defaultLanguage: 'en',
   // DEFAULT network (livenet or testnet)
   networkName: 'testnet',
-  forceNetwork: false,
   logLevel: 'info',
 
 
diff --git a/js/app.js b/js/app.js
index 177755b2a..e3d6491c4 100644
--- a/js/app.js
+++ b/js/app.js
@@ -10,9 +10,6 @@ if (localConfig) {
   var lmv = localConfig.version ? localConfig.version.split('.')[1] : '-1';
   if (cmv === lmv) {
     _.each(localConfig, function(value, key) {
-      if (key === 'networkName' && config['forceNetwork']) {
-        return;
-      }
       config[key] = value;
     });
   }
diff --git a/js/models/core/Wallet.js b/js/models/core/Wallet.js
index 61e81b137..1db23d329 100644
--- a/js/models/core/Wallet.js
+++ b/js/models/core/Wallet.js
@@ -67,9 +67,6 @@ function Wallet(opts) {
     preconditions.checkArgument(!_.isUndefined(opts[k]), 'missing required option for Wallet: ' + k);
     self[k] = opts[k];
   });
-  preconditions.checkArgument(!copayConfig.forceNetwork || this.getNetworkName() === copayConfig.networkName,
-    'Network forced to ' + copayConfig.networkName +
-    ' and tried to create a Wallet with network ' + this.getNetworkName());
 
   this.id = opts.id || Wallet.getRandomId();
   this.secretNumber = opts.secretNumber || Wallet.getRandomNumber();
diff --git a/test/test.Wallet.js b/test/test.Wallet.js
index c8ae349e5..194252aee 100644
--- a/test/test.Wallet.js
+++ b/test/test.Wallet.js
@@ -1247,15 +1247,6 @@ describe('Wallet model', function() {
 
   });
 
-  describe('#forceNetwork in config', function() {
-    it('should throw if network is different', function() {
-      var backup = copayConfig.forceNetwork;
-      copayConfig.forceNetwork = true;
-      walletConfig.networkName = 'livenet';
-      createW2.should.throw(Error);
-      copayConfig.forceNetwork = backup;
-    });
-  });
   describe('_getKeymap', function() {
     var w = cachedCreateW();
 

From 3818044a2ea464d9ec1c878034be98c56e4bfa04 Mon Sep 17 00:00:00 2001
From: Matias Pando 
Date: Mon, 15 Sep 2014 10:50:06 -0300
Subject: [PATCH 105/191] Translations fixed

---
 po/es.po          | 142 +++++++++++++++++++++++++---------------------
 views/create.html |   2 +-
 views/join.html   |   5 +-
 3 files changed, 81 insertions(+), 68 deletions(-)

diff --git a/po/es.po b/po/es.po
index 0e8aa2757..69a693a3f 100644
--- a/po/es.po
+++ b/po/es.po
@@ -9,7 +9,7 @@ msgstr ""
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"X-Generator: Poedit 1.6.8\n"
+"X-Generator: Poedit 1.6.9\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
 #: views/create.html
@@ -17,8 +17,9 @@ msgid "(*) The limits are imposed by the bitcoin network."
 msgstr "(*) Los límites son impuestos por la red de bitcoin."
 
 #: views/more.html
+#, fuzzy
 msgid ""
-"ALL Transactions Proposals will be discarted. This need to be done on "
+"ALL Transactions Proposals will be discarted. This needs to be done on "
 "ALL peers of a wallet, to prevent the old proposals to be resynced "
 "again.\n"
 "        "
@@ -52,7 +53,7 @@ msgstr "Libreta de Direcciones"
 msgid "Addresses"
 msgstr "Direcciones"
 
-#: views/settings.html
+#: views/more.html
 msgid "Alternative Currency"
 msgstr "Moneda Alternativa"
 
@@ -93,9 +94,9 @@ msgstr "Balance"
 msgid "Balance locked in pending transaction proposals"
 msgstr "Balance bloqueado en las propuestas de transacción pendientes"
 
-#: views/settings.html
-msgid "Bitcoin Network"
-msgstr "Red Bitcoin"
+#: views/send.html
+msgid "Bitcoin address"
+msgstr "Dirección bitcoin"
 
 #: views/includes/transaction.html
 msgid "Broadcast Transaction"
@@ -113,11 +114,16 @@ msgstr "Cancelar"
 msgid "Certificate:"
 msgstr "Certificado:"
 
+#: views/create.html
+#, fuzzy
+msgid "Choose a password"
+msgstr "Escribe tu contraseña"
+
 #: views/import.html
 msgid "Choose backup file from your computer"
 msgstr "Seleccione el archivo backup de su computadora"
 
-#: views/create.html views/join.html
+#: views/join.html
 msgid "Choose your password"
 msgstr "Escribe tu contraseña"
 
@@ -161,6 +167,12 @@ msgstr "Crear nuevo monedero"
 msgid "Create {{requiredCopayers}}-of-{{totalCopayers}} wallet"
 msgstr "Crea monedero {{requiredCopayers}}-de-{{totalCopayers}}"
 
+#: views/copayers.html
+msgid "Creating and storing a backup will allow you to recover wallet funds"
+msgstr ""
+"Crear y guardar una copia de seguridad  le permitirá recuperar el dinero de "
+"su monedero"
+
 #: views/create.html
 msgid "Creating wallet..."
 msgstr "Creando monedero..."
@@ -181,10 +193,6 @@ msgstr "Eliminar"
 msgid "Delete Wallet"
 msgstr "Borrar Monedero"
 
-#: views/copayers.html
-msgid "Delete wallet"
-msgstr "Borrar monedero"
-
 #: views/copayers.html
 msgid "Download Backup"
 msgstr "Descargar Copia de Seguridad"
@@ -193,10 +201,6 @@ msgstr "Descargar Copia de Seguridad"
 msgid "Download File"
 msgstr "Descargar Archivo"
 
-#: views/copayers.html
-msgid "Download seed backup"
-msgstr "Descargar copia de seguridad"
-
 #: views/send.html
 msgid "Empty. Create an alias for your addresses"
 msgstr "Vacío. Crea una etiqueta para tus direcciones"
@@ -213,8 +217,8 @@ msgstr "Tasa"
 msgid "Get QR code"
 msgstr "Obtener código QR"
 
-#: views/copayers.html views/create.html views/import.html views/join.html
-#: views/more.html views/transactions.html
+#: views/create.html views/import.html views/join.html views/more.html
+#: views/transactions.html
 msgid "Hide"
 msgstr "Ocultar"
 
@@ -243,12 +247,9 @@ msgid "Including fee of"
 msgstr "Incluye tasa de"
 
 #: views/settings.html
-msgid "Insight API server"
-msgstr "Servidor API Insight"
-
-#: views/settings.html
+#, fuzzy
 msgid ""
-"Insight API server is open-source software.  You can run your own instance, "
+"Insight API server is open-source software. You can run your own instances, "
 "check Insight API Homepage"
 msgstr ""
@@ -256,6 +257,11 @@ msgstr ""
 "propia instancia en Insight "
 "API Homepage"
 
+#: views/settings.html
+#, fuzzy
+msgid "Insight API servers"
+msgstr "Servidor API Insight"
+
 #: views/send.html
 msgid "Insufficient funds"
 msgstr "Fondos insuficientes"
@@ -316,16 +322,6 @@ msgstr "Nombre"
 msgid "Network Error. Attempting to reconnect..."
 msgstr "Error de Red. Intentando reconectar..."
 
-#: views/settings.html
-msgid ""
-"Network has been fixed to {{networkName}} in this setup. "
-"See copay.io for options to use Copay on "
-"both livenet and testnet."
-msgstr ""
-"La red fue fijada a {{networkName}} para esta "
-"configuración. Ver copay.io para más "
-"opciones de uso de Copay en livenet y testnet."
-
 #: views/copayers.html
 msgid "New Wallet Created"
 msgstr "Nuevo Monedero Creado"
@@ -389,6 +385,10 @@ msgstr "Página no encontrada"
 msgid "Password"
 msgstr "Contraseña"
 
+#: views/create.html views/join.html
+msgid "Passwords must match"
+msgstr "Las contraseñas deben coincidir"
+
 #: views/join.html
 msgid "Paste wallet secret here"
 msgstr "Pegar código secreto del monedero aquí"
@@ -398,8 +398,9 @@ msgid "Payment Expiration:"
 msgstr "Vencimiento de Pago:"
 
 #: views/more.html
+#, fuzzy
 msgid ""
-"Pending Transactions Proposals will be discarted. This need to be done on "
+"Pending Transactions Proposals will be discarted. This needs to be done on "
 "ALL peers of a wallet, to prevent the old proposals to be resynced "
 "again.\n"
 "        "
@@ -409,10 +410,6 @@ msgstr ""
 "prevenir que viejas propuestas sean re sincronizadas de nuevo.\n"
 "        "
 
-#: views/settings.html
-msgid "Port"
-msgstr "Puerto"
-
 #: views/uri-payment.html
 msgid "Preparing payment..."
 msgstr "Preparando pago..."
@@ -457,11 +454,11 @@ msgstr "Rechazar"
 msgid "Repeat password"
 msgstr "Repite la contraseña"
 
-#: views/create.html views/import.html views/join.html
+#: views/import.html views/join.html
 msgid "Required"
 msgstr "Requerido"
 
-#: views/settings.html
+#: views/more.html views/settings.html
 msgid "Save"
 msgstr "Guardar"
 
@@ -513,8 +510,8 @@ msgstr "Configuración"
 msgid "Share this secret with your other copayers"
 msgstr "Compartir el código secreto con tus otros compañeros"
 
-#: views/copayers.html views/create.html views/import.html views/join.html
-#: views/more.html views/transactions.html
+#: views/create.html views/import.html views/join.html views/more.html
+#: views/transactions.html
 msgid "Show"
 msgstr "Mostrar"
 
@@ -530,6 +527,10 @@ msgstr "Ver menos"
 msgid "Sign"
 msgstr "Firmar"
 
+#: views/copayers.html
+msgid "Skip Backup"
+msgstr "Saltear Copia de Seguridad"
+
 #: views/import.html
 msgid "Skip public keys from peers"
 msgstr "Ignorar claves pública de los compañeros"
@@ -559,8 +560,8 @@ msgstr ""
 "sincronización de direcciones a los demás compañeros conectados."
 
 #: views/send.html
-msgid "To address"
-msgstr "Dirección"
+msgid "To:"
+msgstr "Para:"
 
 #: views/transactions.html
 msgid "Total"
@@ -582,10 +583,6 @@ msgstr "Propuestas de Transacción"
 msgid "Transaction finally rejected"
 msgstr "Transacción rechazada"
 
-#: views/settings.html
-msgid "Use SSL"
-msgstr "Usar SSL"
-
 #: views/send.html
 msgid "Use all funds"
 msgstr "Todos los fondos"
@@ -622,7 +619,7 @@ msgstr "Código Secreto del Monedero"
 msgid "Wallet Secret is not valid!"
 msgstr "¡El código secreto no es válido!"
 
-#: views/settings.html
+#: views/more.html
 msgid "Wallet Unit"
 msgstr "Unidad del monedero"
 
@@ -635,8 +632,9 @@ msgid "Warning!"
 msgstr "¡Advertencia!"
 
 #: views/create.html
-msgid "Your Wallet Password"
-msgstr "Contraseña de tu Monedero"
+#, fuzzy
+msgid "Your Password"
+msgstr "Tu contraseña"
 
 #: views/more.html
 msgid ""
@@ -662,8 +660,7 @@ msgstr "Tu contraseña"
 msgid "Your wallet password"
 msgstr "Contraseña de tu monedero"
 
-#: views/copayers.html views/create.html views/import.html views/join.html
-#: views/more.html
+#: views/create.html views/import.html views/join.html views/more.html
 msgid "advanced options"
 msgstr "opciones avanzadas"
 
@@ -676,7 +673,8 @@ msgid "first seen at"
 msgstr "Visto el"
 
 #: views/transactions.html
-msgid "mined at"
+#, fuzzy
+msgid "mined"
 msgstr "Minado el"
 
 #: views/send.html
@@ -719,6 +717,33 @@ msgstr "deben unirse"
 msgid "{{tx.missingSignatures}} signatures missing"
 msgstr "Faltan {{tx.missingSignatures}} firmas"
 
+#~ msgid "Bitcoin Network"
+#~ msgstr "Red Bitcoin"
+
+#~ msgid "Delete wallet"
+#~ msgstr "Borrar monedero"
+
+#~ msgid "Download seed backup"
+#~ msgstr "Descargar copia de seguridad"
+
+#~ msgid ""
+#~ "Network has been fixed to {{networkName}} in this setup. "
+#~ "See copay.io for options to use Copay on "
+#~ "both livenet and testnet."
+#~ msgstr ""
+#~ "La red fue fijada a {{networkName}} para esta "
+#~ "configuración. Ver copay.io para más "
+#~ "opciones de uso de Copay en livenet y testnet."
+
+#~ msgid "Port"
+#~ msgstr "Puerto"
+
+#~ msgid "Use SSL"
+#~ msgstr "Usar SSL"
+
+#~ msgid "Your Wallet Password"
+#~ msgstr "Contraseña de tu Monedero"
+
 #~ msgid "Send"
 #~ msgstr "Enviar"
 
@@ -738,14 +763,3 @@ msgstr "Faltan {{tx.missingSignatures}} firmas"
 #~ msgstr ""
 #~ "Nombre del\n"
 #~ "                monedero"
-
-#: views/create.html
-msgid "Passwords must match"
-msgstr "Las contraseñas deben coincidir"
-
-#: views/join.html
-msgid "Passwords must match"
-msgstr "Las contraseñas deben coincidir"
-
-
-
diff --git a/views/create.html b/views/create.html
index a22ba56b7..7d6c846f3 100644
--- a/views/create.html
+++ b/views/create.html
@@ -34,7 +34,7 @@
                 
-

+

{{'Passwords must match'|translate}}

diff --git a/views/join.html b/views/join.html index d11b34edf..3fe71ab36 100644 --- a/views/join.html +++ b/views/join.html @@ -25,8 +25,7 @@
- +
@@ -75,7 +74,7 @@ ng-model="joinPasswordConfirm" match="joinPassword" required> -

+

{{'Passwords must match'|translate}}

From feb40d7e3a89c0bfe73e0b78e635ce9150c57992 Mon Sep 17 00:00:00 2001 From: bechi Date: Mon, 15 Sep 2014 12:06:19 -0300 Subject: [PATCH 106/191] fix close button positioned --- index.html | 3 --- views/includes/sidebar-mobile.html | 31 ------------------------------ 2 files changed, 34 deletions(-) diff --git a/index.html b/index.html index 40b22b4da..9a79d3090 100644 --- a/index.html +++ b/index.html @@ -22,9 +22,6 @@
-
- -

diff --git a/views/includes/sidebar-mobile.html b/views/includes/sidebar-mobile.html index d313c1ab4..3e3834328 100644 --- a/views/includes/sidebar-mobile.html +++ b/views/includes/sidebar-mobile.html @@ -7,37 +7,6 @@

-
-
-
-
- Balance - - - - {{totalBalance || 0 - |noFractionNumber}} {{$root.wallet.settings.unitName}} - -
-
- Locked - - - - {{lockedBalance || 0|noFractionNumber}} {{$root.wallet.settings.unitName}} -   -
-
-
-
From 03eb6488ec515d254b3c738357cb96bbf615a114 Mon Sep 17 00:00:00 2001 From: Gustavo Maximiliano Cortez Date: Mon, 15 Sep 2014 13:04:44 -0300 Subject: [PATCH 107/191] typos: BIP32 master extended private key (hex) --- views/join.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/views/join.html b/views/join.html index 3fe71ab36..6528658e4 100644 --- a/views/join.html +++ b/views/join.html @@ -88,7 +88,7 @@

From 1ce3f82d0a88ab262fb8eaf8b9206a06ae8b0095 Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Mon, 1 Sep 2014 15:13:23 -0300 Subject: [PATCH 108/191] add angular-load --- Gruntfile.js | 1 + config.js | 9 +++++++++ js/app.js | 13 ++++++++++++- 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/Gruntfile.js b/Gruntfile.js index 8844d8e30..e4d0a51ef 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -115,6 +115,7 @@ module.exports = function(grunt) { 'lib/angular-foundation/mm-foundation.min.js', 'lib/angular-foundation/mm-foundation-tpls.min.js', 'lib/angular-gettext/dist/angular-gettext.min.js' + 'lib/angular-load/angular-load.min.js', ], dest: 'lib/angularjs-all.js' }, diff --git a/config.js b/config.js index a22baad87..fe4031e42 100644 --- a/config.js +++ b/config.js @@ -50,6 +50,15 @@ var defaultConfig = { updateFrequencySeconds: 60 * 60 }, + verbose: 1, + + plugins: { + googleDrive: true, + }, + + googleDrive: { + clientId: '1', + }, }; if (typeof module !== 'undefined') module.exports = defaultConfig; diff --git a/js/app.js b/js/app.js index 177755b2a..a5c169307 100644 --- a/js/app.js +++ b/js/app.js @@ -18,7 +18,13 @@ if (localConfig) { } } +var log = function() { + if (config.verbose) console.log(arguments); +} var copayApp = window.copayApp = angular.module('copayApp', [ + + +var modules = [ 'ngRoute', 'angularMoment', 'mm.foundation', @@ -29,7 +35,12 @@ var copayApp = window.copayApp = angular.module('copayApp', [ 'copayApp.services', 'copayApp.controllers', 'copayApp.directives', -]); +]; + +if (config.plugins.googleDrive) + modules.push('angularLoad'); + +var copayApp = window.copayApp = angular.module('copayApp', modules); copayApp.config(function($sceDelegateProvider) { $sceDelegateProvider.resourceUrlWhitelist([ From 2849f773e2df1c098b2de36355bf36e7220ef60a Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Mon, 1 Sep 2014 15:40:31 -0300 Subject: [PATCH 109/191] change name to Encrypted --- Gruntfile.js | 5 +- bower.json | 3 +- copay.js | 2 +- js/app.js | 10 +++- js/models/core/WalletFactory.js | 4 +- .../{LocalEncrypted.js => Encrypted.js} | 27 +++++---- ...st.LocalEncrypted.js => test.Encrypted.js} | 60 +++++++++---------- util/build.js | 4 ++ 8 files changed, 66 insertions(+), 49 deletions(-) rename js/models/storage/{LocalEncrypted.js => Encrypted.js} (89%) rename test/{test.LocalEncrypted.js => test.Encrypted.js} (84%) diff --git a/Gruntfile.js b/Gruntfile.js index e4d0a51ef..fc4b77dee 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -42,7 +42,8 @@ module.exports = function(grunt) { }, scripts: { files: [ - 'js/models/**/*.js' + 'js/models/**/*.js', + 'plugins/*.js', ], tasks: ['shell:dev'] }, @@ -129,7 +130,7 @@ module.exports = function(grunt) { 'js/controllers/*.js', 'js/translations.js', 'js/mobile.js', // PLACEHOLDER: CORDOVA SRIPT - 'js/init.js' + 'js/init.js', ], dest: 'js/copayMain.js' } diff --git a/bower.json b/bower.json index 9300e2b27..cccd15f07 100644 --- a/bower.json +++ b/bower.json @@ -24,7 +24,8 @@ "zeroclipboard": "~1.3.5", "ng-idle": "*", "underscore": "~1.7.0", - "inherits": "~0.0.1" + "inherits": "~0.0.1", + "angular-load": "0.2.0" }, "resolutions": { "angular": "=1.2.19" diff --git a/copay.js b/copay.js index 5f058d6ab..e821f7918 100644 --- a/copay.js +++ b/copay.js @@ -11,7 +11,7 @@ module.exports.HDParams = require('./js/models/core/HDParams'); // components var Async = module.exports.Async = require('./js/models/network/Async'); var Insight = module.exports.Insight = require('./js/models/blockchain/Insight'); -var StorageLocalEncrypted = module.exports.StorageLocalEncrypted = require('./js/models/storage/LocalEncrypted'); +var StorageEncrypted = module.exports.StorageEncrypted = require('./js/models/storage/Encrypted'); module.exports.WalletFactory = require('./js/models/core/WalletFactory'); module.exports.Wallet = require('./js/models/core/Wallet'); diff --git a/js/app.js b/js/app.js index a5c169307..e7b038516 100644 --- a/js/app.js +++ b/js/app.js @@ -37,9 +37,17 @@ var modules = [ 'copayApp.directives', ]; -if (config.plugins.googleDrive) +if (config.plugins.length) modules.push('angularLoad'); +if (config.plugins.googleDrive) { + var googleDrive = require('../plugins/googleDrive'); + var a = new googleDrive(); + a.init(); +console.log('[app.js.41:new:]',a); //TODO +} + + var copayApp = window.copayApp = angular.module('copayApp', modules); copayApp.config(function($sceDelegateProvider) { diff --git a/js/models/core/WalletFactory.js b/js/models/core/WalletFactory.js index b91853657..adf542ae1 100644 --- a/js/models/core/WalletFactory.js +++ b/js/models/core/WalletFactory.js @@ -8,7 +8,7 @@ var _ = require('underscore'); var log = require('../../log'); var Async = module.exports.Async = require('../network/Async'); var Insight = module.exports.Insight = require('../blockchain/Insight'); -var StorageLocalEncrypted = module.exports.StorageLocalEncrypted = require('../storage/LocalEncrypted'); +var StorageEncrypted = module.exports.StorageEncrypted = require('../storage/Encrypted'); var preconditions = require('preconditions').singleton(); /** @@ -36,7 +36,7 @@ function WalletFactory(config, version) { var self = this; config = config || {}; - this.Storage = config.Storage || StorageLocalEncrypted; + this.Storage = config.Storage || StorageEncrypted; this.Network = config.Network || Async; this.Blockchain = config.Blockchain || Insight; diff --git a/js/models/storage/LocalEncrypted.js b/js/models/storage/Encrypted.js similarity index 89% rename from js/models/storage/LocalEncrypted.js rename to js/models/storage/Encrypted.js index b093eaaa4..1997f7841 100644 --- a/js/models/storage/LocalEncrypted.js +++ b/js/models/storage/Encrypted.js @@ -13,9 +13,12 @@ function Storage(opts) { this._setPassphrase(opts.password); try { - this.localStorage = opts.localStorage || localStorage; + this.storage = opts.storage || localStorage; this.sessionStorage = opts.sessionStorage || sessionStorage; - } catch (e) {} + } catch (e) { + console.log('Error in storage:', e); //TODO + }; + preconditions.checkState(this.localStorage, 'No localstorage found'); preconditions.checkState(this.sessionStorage, 'No sessionStorage found'); } @@ -54,7 +57,7 @@ Storage.prototype._decrypt = function(base64) { Storage.prototype._read = function(k) { var ret; - ret = this.localStorage.getItem(k); + ret = this.storage.getItem(k); if (!ret) return null; ret = this._decrypt(ret); if (!ret) return null; @@ -67,23 +70,23 @@ Storage.prototype._write = function(k, v) { v = JSON.stringify(v); v = this._encrypt(v); - this.localStorage.setItem(k, v); + this.storage.setItem(k, v); }; // get value by key Storage.prototype.getGlobal = function(k) { - var item = this.localStorage.getItem(k); + var item = this.storage.getItem(k); return item == 'undefined' ? undefined : item; }; // set value for key Storage.prototype.setGlobal = function(k, v) { - this.localStorage.setItem(k, typeof v === 'object' ? JSON.stringify(v) : v); + this.storage.setItem(k, typeof v === 'object' ? JSON.stringify(v) : v); }; // remove value for key Storage.prototype.removeGlobal = function(k) { - this.localStorage.removeItem(k); + this.storage.removeItem(k); }; Storage.prototype.getSessionId = function() { @@ -127,8 +130,8 @@ Storage.prototype.getWalletIds = function() { var walletIds = []; var uniq = {}; - for (var i = 0; i < this.localStorage.length; i++) { - var key = this.localStorage.key(i); + for (var i = 0; i < this.storage.length; i++) { + var key = this.storage.key(i); var split = key.split('::'); if (split.length == 2) { var walletId = split[0]; @@ -162,8 +165,8 @@ Storage.prototype.deleteWallet = function(walletId) { var toDelete = {}; toDelete['nameFor::' + walletId] = 1; - for (var i = 0; i < this.localStorage.length; i++) { - var key = this.localStorage.key(i); + for (var i = 0; i < this.storage.length; i++) { + var key = this.storage.key(i); var split = key.split('::'); if (split.length == 2 && split[0] === walletId) { toDelete[key] = 1; @@ -192,7 +195,7 @@ Storage.prototype.setFromObj = function(walletId, obj) { // remove all values Storage.prototype.clearAll = function() { - this.localStorage.clear(); + this.storage.clear(); }; Storage.prototype.import = function(base64) { diff --git a/test/test.LocalEncrypted.js b/test/test.Encrypted.js similarity index 84% rename from test/test.LocalEncrypted.js rename to test/test.Encrypted.js index 32149e58f..bfe2fcd18 100644 --- a/test/test.LocalEncrypted.js +++ b/test/test.Encrypted.js @@ -3,7 +3,7 @@ var chai = chai || require('chai'); var should = chai.should(); var is_browser = typeof process == 'undefined' || typeof process.versions === 'undefined'; var copay = copay || require('../copay'); -var LocalEncrypted = copay.StorageLocalEncrypted; +var Encrypted = copay.StorageEncrypted; var fakeWallet = 'fake-wallet-id'; var timeStamp = Date.now(); @@ -11,23 +11,23 @@ var localMock = require('./mocks/FakeLocalStorage'); var sessionMock = require('./mocks/FakeLocalStorage'); -describe('Storage/LocalEncrypted model', function() { - var s = new LocalEncrypted({ - localStorage: localMock, +describe('Storage/Encrypted model', function() { + var s = new Encrypted({ + storage: localMock, sessionStorage: sessionMock, }); s._setPassphrase('mysupercoolpassword'); it('should create an instance', function() { - var s2 = new LocalEncrypted({ - localStorage: localMock, + var s2 = new Encrypted({ + storage: localMock, sessionStorage: sessionMock, }); should.exist(s2); }); it('should fail when encrypting without a password', function() { - var s2 = new LocalEncrypted({ - localStorage: localMock, + var s2 = new Encrypted({ + storage: localMock, sessionStorage: sessionMock, }); (function() { @@ -71,8 +71,8 @@ describe('Storage/LocalEncrypted model', function() { describe('#export', function() { it('should export the encrypted wallet', function() { - var storage = new LocalEncrypted({ - localStorage: localMock, + var storage = new Encrypted({ + storage: localMock, sessionStorage: sessionMock, password: 'password', }); @@ -89,8 +89,8 @@ describe('Storage/LocalEncrypted model', function() { describe('#remove', function() { it('should remove an item', function() { - var s = new LocalEncrypted({ - localStorage: localMock, + var s = new Encrypted({ + storage: localMock, sessionStorage: sessionMock, password: 'password' }); @@ -105,8 +105,8 @@ describe('Storage/LocalEncrypted model', function() { describe('#getWalletIds', function() { it('should get wallet ids', function() { - var s = new LocalEncrypted({ - localStorage: localMock, + var s = new Encrypted({ + storage: localMock, sessionStorage: sessionMock, password: 'password' }); @@ -118,8 +118,8 @@ describe('Storage/LocalEncrypted model', function() { describe('#getName #setName', function() { it('should get/set names', function() { - var s = new LocalEncrypted({ - localStorage: localMock, + var s = new Encrypted({ + storage: localMock, sessionStorage: sessionMock, password: 'password' }); @@ -130,8 +130,8 @@ describe('Storage/LocalEncrypted model', function() { describe('#getLastOpened #setLastOpened', function() { it('should get/set names', function() { - var s = new LocalEncrypted({ - localStorage: localMock, + var s = new Encrypted({ + storage: localMock, sessionStorage: sessionMock, password: 'password' }); @@ -143,8 +143,8 @@ describe('Storage/LocalEncrypted model', function() { if (is_browser) { describe('#getSessionId', function() { it('should get SessionId', function() { - var s = new LocalEncrypted({ - localStorage: localMock, + var s = new Encrypted({ + storage: localMock, sessionStorage: sessionMock, password: 'password' }); @@ -158,8 +158,8 @@ describe('Storage/LocalEncrypted model', function() { describe('#getWallets', function() { it('should retreive wallets from storage', function() { - var s = new LocalEncrypted({ - localStorage: localMock, + var s = new Encrypted({ + storage: localMock, sessionStorage: sessionMock, password: 'password' }); @@ -178,8 +178,8 @@ describe('Storage/LocalEncrypted model', function() { }); describe('#deleteWallet', function() { it('should delete a wallet', function() { - var s = new LocalEncrypted({ - localStorage: localMock, + var s = new Encrypted({ + storage: localMock, sessionStorage: sessionMock, password: 'password' }); @@ -198,8 +198,8 @@ describe('Storage/LocalEncrypted model', function() { describe('#setFromObj', function() { it('set localstorage from an object', function() { - var s = new LocalEncrypted({ - localStorage: localMock, + var s = new Encrypted({ + storage: localMock, sessionStorage: sessionMock, password: 'password' }); @@ -218,8 +218,8 @@ describe('Storage/LocalEncrypted model', function() { describe('#globals', function() { it('should set, get and remove keys', function() { - var s = new LocalEncrypted({ - localStorage: localMock, + var s = new Encrypted({ + storage: localMock, sessionStorage: sessionMock, password: 'password' }); @@ -237,8 +237,8 @@ describe('Storage/LocalEncrypted model', function() { describe('session storage', function() { it('should get a session ID', function() { - var s = new LocalEncrypted({ - localStorage: localMock, + var s = new Encrypted({ + storage: localMock, sessionStorage: sessionMock, password: 'password' }); diff --git a/util/build.js b/util/build.js index b60af799b..21e2afda8 100644 --- a/util/build.js +++ b/util/build.js @@ -83,6 +83,10 @@ var createBundle = function(opts) { b.require('./js/models/core/HDPath', { expose: '../js/models/core/HDPath' }); + b.require('./plugins/googleDrive', { + expose: '../plugins/googleDrive' + }); + b.require('./config', { expose: '../config' }); From c0360e7beb7915580f27c9bb761fe2464c92140f Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Mon, 1 Sep 2014 16:31:35 -0300 Subject: [PATCH 110/191] plugin system v0 --- Gruntfile.js | 1 + config.js | 4 +-- copay.js | 1 + js/app.js | 6 ----- js/controllers/home.js | 2 +- js/models/core/PluginManager.js | 46 +++++++++++++++++++++++++++++++++ js/services/pluginManager.js | 3 +++ plugins/googleDrive.js | 11 ++++++++ util/build.js | 10 +++++-- 9 files changed, 73 insertions(+), 11 deletions(-) create mode 100644 js/models/core/PluginManager.js create mode 100644 js/services/pluginManager.js create mode 100644 plugins/googleDrive.js diff --git a/Gruntfile.js b/Gruntfile.js index fc4b77dee..04078ba62 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -44,6 +44,7 @@ module.exports = function(grunt) { files: [ 'js/models/**/*.js', 'plugins/*.js', + 'copay.js' ], tasks: ['shell:dev'] }, diff --git a/config.js b/config.js index fe4031e42..6b7e5f30f 100644 --- a/config.js +++ b/config.js @@ -53,10 +53,10 @@ var defaultConfig = { verbose: 1, plugins: { - googleDrive: true, + GoogleDrive: true, }, - googleDrive: { + GoogleDrive: { clientId: '1', }, }; diff --git a/copay.js b/copay.js index e821f7918..2f0107816 100644 --- a/copay.js +++ b/copay.js @@ -16,6 +16,7 @@ var StorageEncrypted = module.exports.StorageEncrypted = require('./js/models/st module.exports.WalletFactory = require('./js/models/core/WalletFactory'); module.exports.Wallet = require('./js/models/core/Wallet'); module.exports.WalletLock = require('./js/models/core/WalletLock'); +module.exports.PluginManager = require('./js/models/core/PluginManager'); module.exports.version = require('./version').version; module.exports.commitHash = require('./version').commitHash; diff --git a/js/app.js b/js/app.js index e7b038516..e1a3826ee 100644 --- a/js/app.js +++ b/js/app.js @@ -40,12 +40,6 @@ var modules = [ if (config.plugins.length) modules.push('angularLoad'); -if (config.plugins.googleDrive) { - var googleDrive = require('../plugins/googleDrive'); - var a = new googleDrive(); - a.init(); -console.log('[app.js.41:new:]',a); //TODO -} var copayApp = window.copayApp = angular.module('copayApp', modules); diff --git a/js/controllers/home.js b/js/controllers/home.js index 2ac3e7381..a8d367d44 100644 --- a/js/controllers/home.js +++ b/js/controllers/home.js @@ -1,7 +1,7 @@ 'use strict'; angular.module('copayApp.controllers').controller('HomeController', - function($scope, $rootScope, $location, walletFactory, notification, controllerUtils) { + function($scope, $rootScope, $location, walletFactory, notification, controllerUtils, pluginManager) { controllerUtils.redirIfLogged(); diff --git a/js/models/core/PluginManager.js b/js/models/core/PluginManager.js new file mode 100644 index 000000000..995470481 --- /dev/null +++ b/js/models/core/PluginManager.js @@ -0,0 +1,46 @@ +'use strict'; +var preconditions = require('preconditions').singleton(); + +function PluginManager(config) { + this.registered = {}; + + for(var ii in config.plugins){ + var pluginName = ii; + + if (!config.plugins[pluginName]) + continue; + + console.log('Loading ' + pluginName); + var pluginClass = require('../plugins/' + pluginName); + var pluginObj = new pluginClass(); + pluginObj.init(); + this._register(pluginObj); + } +}; + +var KIND_UNIQUE = PluginManager.KIND_UNIQUE = 1; +var KIND_MULTIPLE = PluginManager.KIND_MULTIPLE = 2; + +PluginManager.TYPE = {}; +PluginManager.TYPE['STORAGE'] = KIND_UNIQUE; + +PluginManager.prototype._register = function(obj) { + preconditions.checkArgument(obj.type,'Plugin has not type'); + var type = obj.type; +console.log('[PluginManager.js.29:type:]',type); //TODO + + var kind = PluginManager.TYPE[type]; + preconditions.checkArgument(kind, 'Plugin has unkown type'); + preconditions.checkState(kind !== PluginManager.KIND_UNIQUE || !this.registered[type], 'Plugin kind already registered'); + + if (kind === PluginManager.KIND_UNIQUE) { + this.registered[type] = obj; + } else { + this.registered[type] = this.registered[type] || []; + this.registered[type].push(obj); + } +}; + +PluginManager.prototype.getOne = function(type) {}; + +module.exports = PluginManager; diff --git a/js/services/pluginManager.js b/js/services/pluginManager.js new file mode 100644 index 000000000..b3371c0cd --- /dev/null +++ b/js/services/pluginManager.js @@ -0,0 +1,3 @@ +'use strict'; + +angular.module('copayApp.services').value('pluginManager', new copay.PluginManager(config)); diff --git a/plugins/googleDrive.js b/plugins/googleDrive.js new file mode 100644 index 000000000..6be0c2c55 --- /dev/null +++ b/plugins/googleDrive.js @@ -0,0 +1,11 @@ +'use strict'; + +function GoogleDrive() { + this.type = 'STORAGE'; +}; + +GoogleDrive.prototype.init = function() { + console.log('[googleDrive.js.3] init'); //TODO +}; + +module.exports = GoogleDrive; diff --git a/util/build.js b/util/build.js index 21e2afda8..b9160cc7f 100644 --- a/util/build.js +++ b/util/build.js @@ -83,9 +83,15 @@ var createBundle = function(opts) { b.require('./js/models/core/HDPath', { expose: '../js/models/core/HDPath' }); - b.require('./plugins/googleDrive', { - expose: '../plugins/googleDrive' + b.require('./js/models/core/PluginManager', { + expose: '../js/models/core/PluginManager' }); + + if (!opts.disablePlugins) { + b.require('./plugins/GoogleDrive', { + expose: '../plugins/GoogleDrive' + }); + } b.require('./config', { expose: '../config' From b9881c114767f8c4e9f8c9e4ed0c7e2451232ff6 Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Mon, 1 Sep 2014 23:44:35 -0300 Subject: [PATCH 111/191] add LocalStorage plugin --- Gruntfile.js | 3 ++- config.js | 3 ++- js/controllers/home.js | 2 +- js/models/core/PluginManager.js | 18 +++++++------- js/models/core/WalletFactory.js | 6 +++-- js/models/storage/Encrypted.js | 2 ++ js/services/pluginManager.js | 4 +++- plugins/LocalStorage.js | 42 +++++++++++++++++++++++++++++++++ plugins/googleDrive.js | 33 +++++++++++++++++++++++++- util/build.js | 4 ++++ 10 files changed, 101 insertions(+), 16 deletions(-) create mode 100644 plugins/LocalStorage.js diff --git a/Gruntfile.js b/Gruntfile.js index 04078ba62..099cd23bd 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -44,7 +44,8 @@ module.exports = function(grunt) { files: [ 'js/models/**/*.js', 'plugins/*.js', - 'copay.js' + 'copay.js', + 'utils/*.js' ], tasks: ['shell:dev'] }, diff --git a/config.js b/config.js index 6b7e5f30f..10b5dafe7 100644 --- a/config.js +++ b/config.js @@ -53,7 +53,8 @@ var defaultConfig = { verbose: 1, plugins: { - GoogleDrive: true, + LocalStorage: true, + // GoogleDrive: true, }, GoogleDrive: { diff --git a/js/controllers/home.js b/js/controllers/home.js index a8d367d44..2ac3e7381 100644 --- a/js/controllers/home.js +++ b/js/controllers/home.js @@ -1,7 +1,7 @@ 'use strict'; angular.module('copayApp.controllers').controller('HomeController', - function($scope, $rootScope, $location, walletFactory, notification, controllerUtils, pluginManager) { + function($scope, $rootScope, $location, walletFactory, notification, controllerUtils) { controllerUtils.redirIfLogged(); diff --git a/js/models/core/PluginManager.js b/js/models/core/PluginManager.js index 995470481..23b3c2a77 100644 --- a/js/models/core/PluginManager.js +++ b/js/models/core/PluginManager.js @@ -10,11 +10,11 @@ function PluginManager(config) { if (!config.plugins[pluginName]) continue; - console.log('Loading ' + pluginName); + console.log('Loading plugin: ' + pluginName); var pluginClass = require('../plugins/' + pluginName); var pluginObj = new pluginClass(); pluginObj.init(); - this._register(pluginObj); + this._register(pluginObj, pluginName); } }; @@ -24,14 +24,12 @@ var KIND_MULTIPLE = PluginManager.KIND_MULTIPLE = 2; PluginManager.TYPE = {}; PluginManager.TYPE['STORAGE'] = KIND_UNIQUE; -PluginManager.prototype._register = function(obj) { - preconditions.checkArgument(obj.type,'Plugin has not type'); +PluginManager.prototype._register = function(obj, name) { + preconditions.checkArgument(obj.type,'Plugin has not type:' + name); var type = obj.type; -console.log('[PluginManager.js.29:type:]',type); //TODO - var kind = PluginManager.TYPE[type]; - preconditions.checkArgument(kind, 'Plugin has unkown type'); - preconditions.checkState(kind !== PluginManager.KIND_UNIQUE || !this.registered[type], 'Plugin kind already registered'); + preconditions.checkArgument(kind, 'Plugin has unkown type' + name); + preconditions.checkState(kind !== PluginManager.KIND_UNIQUE || !this.registered[type], 'Plugin kind already registered: ' + name); if (kind === PluginManager.KIND_UNIQUE) { this.registered[type] = obj; @@ -41,6 +39,8 @@ console.log('[PluginManager.js.29:type:]',type); //TODO } }; -PluginManager.prototype.getOne = function(type) {}; +PluginManager.prototype.get = function(type) { + return this.registered[type]; +}; module.exports = PluginManager; diff --git a/js/models/core/WalletFactory.js b/js/models/core/WalletFactory.js index adf542ae1..ef88b6a52 100644 --- a/js/models/core/WalletFactory.js +++ b/js/models/core/WalletFactory.js @@ -36,11 +36,13 @@ function WalletFactory(config, version) { var self = this; config = config || {}; - this.Storage = config.Storage || StorageEncrypted; + this.pluginManager = new copay.PluginManager(config); + + this.Storage = config.Storage || StorageEncrypted; this.Network = config.Network || Async; this.Blockchain = config.Blockchain || Insight; + this.storage = new this.Storage({storage: this.pluginManager.get('STORAGE')}); - this.storage = new this.Storage(config.storage); this.networks = { 'livenet': new this.Network(config.network.livenet), 'testnet': new this.Network(config.network.testnet), diff --git a/js/models/storage/Encrypted.js b/js/models/storage/Encrypted.js index 1997f7841..6a0c378e7 100644 --- a/js/models/storage/Encrypted.js +++ b/js/models/storage/Encrypted.js @@ -130,6 +130,8 @@ Storage.prototype.getWalletIds = function() { var walletIds = []; var uniq = {}; +console.log('[Encrypted.js.144]', this.storage); //TODO +console.log('[Encrypted.js.144]', this.storage.length); //TODO for (var i = 0; i < this.storage.length; i++) { var key = this.storage.key(i); var split = key.split('::'); diff --git a/js/services/pluginManager.js b/js/services/pluginManager.js index b3371c0cd..c67b16846 100644 --- a/js/services/pluginManager.js +++ b/js/services/pluginManager.js @@ -1,3 +1,5 @@ 'use strict'; -angular.module('copayApp.services').value('pluginManager', new copay.PluginManager(config)); +angular.module('copayApp.services').factory('pluginManager', function(angularLoad){ + return new copay.PluginManager(config); +}); diff --git a/plugins/LocalStorage.js b/plugins/LocalStorage.js new file mode 100644 index 000000000..3f050f64f --- /dev/null +++ b/plugins/LocalStorage.js @@ -0,0 +1,42 @@ +'use strict'; + +function LocalStorage() { + this.type = 'STORAGE'; +}; + +LocalStorage.prototype.init = function() { + console.log(' init LocalStorage'); //TODO +}; + + +LocalStorage.prototype.getItem = function(k) { + return localStorage.getItem(k); +}; + +LocalStorage.prototype.setItem = function(k,v) { + localStorage.setItem(k,v); +}; + +LocalStorage.prototype.removeItem = function(k) { + localStorage.removeItem(k); +}; + +LocalStorage.prototype.clear = function() { + localStorage.clear(); +}; + +delete LocalStorage.prototype.length; + +Object.defineProperty(LocalStorage.prototype, 'length', { + get: function() { + return localStorage.length; + } +}); + +LocalStorage.prototype.key = function(k) { + var v = localStorage.key(k); + return v; +}; + + +module.exports = LocalStorage; diff --git a/plugins/googleDrive.js b/plugins/googleDrive.js index 6be0c2c55..7d7544b79 100644 --- a/plugins/googleDrive.js +++ b/plugins/googleDrive.js @@ -5,7 +5,38 @@ function GoogleDrive() { }; GoogleDrive.prototype.init = function() { - console.log('[googleDrive.js.3] init'); //TODO + console.log('[googleDrive.js.3] init GoogleDrive'); //TODO }; + +GoogleDrive.prototype.getItem = function(k) { + return localStorage.getItem(k); +}; + +GoogleDrive.prototype.setItem = function(k,v) { + localStorage.setItem(k,v); +}; + +GoogleDrive.prototype.removeItem = function(k) { + localStorage.removeItem(k); +}; + +GoogleDrive.prototype.clear = function() { + localStorage.clear(); +}; + +delete GoogleDrive.prototype.length; + +Object.defineProperty(GoogleDrive.prototype, 'length', { + get: function() { + return localStorage.length; + } +}); + +GoogleDrive.prototype.key = function(k) { + var v = localStorage.key(k); + return v; +}; + + module.exports = GoogleDrive; diff --git a/util/build.js b/util/build.js index b9160cc7f..080c1e47e 100644 --- a/util/build.js +++ b/util/build.js @@ -91,6 +91,10 @@ var createBundle = function(opts) { b.require('./plugins/GoogleDrive', { expose: '../plugins/GoogleDrive' }); + b.require('./plugins/LocalStorage', { + expose: '../plugins/LocalStorage' + }); + } b.require('./config', { From bbd762a1fe3fd582b7a620b4f792b1de162a5aee Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Mon, 1 Sep 2014 23:49:13 -0300 Subject: [PATCH 112/191] rm encrypted to storage --- copay.js | 2 +- .../{storage/Encrypted.js => Storage.js} | 0 js/models/core/WalletFactory.js | 7 ++-- test/{test.Encrypted.js => test.Storage.js} | 32 +++++++++---------- util/build.js | 1 - 5 files changed, 21 insertions(+), 21 deletions(-) rename js/models/{storage/Encrypted.js => Storage.js} (100%) rename test/{test.Encrypted.js => test.Storage.js} (92%) diff --git a/copay.js b/copay.js index 2f0107816..6bba1b613 100644 --- a/copay.js +++ b/copay.js @@ -11,7 +11,7 @@ module.exports.HDParams = require('./js/models/core/HDParams'); // components var Async = module.exports.Async = require('./js/models/network/Async'); var Insight = module.exports.Insight = require('./js/models/blockchain/Insight'); -var StorageEncrypted = module.exports.StorageEncrypted = require('./js/models/storage/Encrypted'); +var Storage = module.exports.Storage = require('./js/models/Storage'); module.exports.WalletFactory = require('./js/models/core/WalletFactory'); module.exports.Wallet = require('./js/models/core/Wallet'); diff --git a/js/models/storage/Encrypted.js b/js/models/Storage.js similarity index 100% rename from js/models/storage/Encrypted.js rename to js/models/Storage.js diff --git a/js/models/core/WalletFactory.js b/js/models/core/WalletFactory.js index ef88b6a52..2efea81de 100644 --- a/js/models/core/WalletFactory.js +++ b/js/models/core/WalletFactory.js @@ -6,10 +6,11 @@ var PrivateKey = require('./PrivateKey'); var Wallet = require('./Wallet'); var _ = require('underscore'); var log = require('../../log'); +var PluginManager = require('./PluginManager'); var Async = module.exports.Async = require('../network/Async'); var Insight = module.exports.Insight = require('../blockchain/Insight'); -var StorageEncrypted = module.exports.StorageEncrypted = require('../storage/Encrypted'); var preconditions = require('preconditions').singleton(); +var Storage = module.exports.Storage = require('../Storage'); /** * @desc @@ -36,9 +37,9 @@ function WalletFactory(config, version) { var self = this; config = config || {}; - this.pluginManager = new copay.PluginManager(config); + this.pluginManager = new PluginManager(config); - this.Storage = config.Storage || StorageEncrypted; + this.Storage = config.Storage || Storage; this.Network = config.Network || Async; this.Blockchain = config.Blockchain || Insight; this.storage = new this.Storage({storage: this.pluginManager.get('STORAGE')}); diff --git a/test/test.Encrypted.js b/test/test.Storage.js similarity index 92% rename from test/test.Encrypted.js rename to test/test.Storage.js index bfe2fcd18..0ad668bff 100644 --- a/test/test.Encrypted.js +++ b/test/test.Storage.js @@ -3,7 +3,7 @@ var chai = chai || require('chai'); var should = chai.should(); var is_browser = typeof process == 'undefined' || typeof process.versions === 'undefined'; var copay = copay || require('../copay'); -var Encrypted = copay.StorageEncrypted; +var Storage = copay.Storage; var fakeWallet = 'fake-wallet-id'; var timeStamp = Date.now(); @@ -11,22 +11,22 @@ var localMock = require('./mocks/FakeLocalStorage'); var sessionMock = require('./mocks/FakeLocalStorage'); -describe('Storage/Encrypted model', function() { - var s = new Encrypted({ +describe('Storage model', function() { + var s = new Storage({ storage: localMock, sessionStorage: sessionMock, }); s._setPassphrase('mysupercoolpassword'); it('should create an instance', function() { - var s2 = new Encrypted({ + var s2 = new Storage({ storage: localMock, sessionStorage: sessionMock, }); should.exist(s2); }); it('should fail when encrypting without a password', function() { - var s2 = new Encrypted({ + var s2 = new Storage({ storage: localMock, sessionStorage: sessionMock, }); @@ -71,7 +71,7 @@ describe('Storage/Encrypted model', function() { describe('#export', function() { it('should export the encrypted wallet', function() { - var storage = new Encrypted({ + var storage = new Storage({ storage: localMock, sessionStorage: sessionMock, password: 'password', @@ -89,7 +89,7 @@ describe('Storage/Encrypted model', function() { describe('#remove', function() { it('should remove an item', function() { - var s = new Encrypted({ + var s = new Storage({ storage: localMock, sessionStorage: sessionMock, password: 'password' @@ -105,7 +105,7 @@ describe('Storage/Encrypted model', function() { describe('#getWalletIds', function() { it('should get wallet ids', function() { - var s = new Encrypted({ + var s = new Storage({ storage: localMock, sessionStorage: sessionMock, password: 'password' @@ -118,7 +118,7 @@ describe('Storage/Encrypted model', function() { describe('#getName #setName', function() { it('should get/set names', function() { - var s = new Encrypted({ + var s = new Storage({ storage: localMock, sessionStorage: sessionMock, password: 'password' @@ -130,7 +130,7 @@ describe('Storage/Encrypted model', function() { describe('#getLastOpened #setLastOpened', function() { it('should get/set names', function() { - var s = new Encrypted({ + var s = new Storage({ storage: localMock, sessionStorage: sessionMock, password: 'password' @@ -143,7 +143,7 @@ describe('Storage/Encrypted model', function() { if (is_browser) { describe('#getSessionId', function() { it('should get SessionId', function() { - var s = new Encrypted({ + var s = new Storage({ storage: localMock, sessionStorage: sessionMock, password: 'password' @@ -158,7 +158,7 @@ describe('Storage/Encrypted model', function() { describe('#getWallets', function() { it('should retreive wallets from storage', function() { - var s = new Encrypted({ + var s = new Storage({ storage: localMock, sessionStorage: sessionMock, password: 'password' @@ -178,7 +178,7 @@ describe('Storage/Encrypted model', function() { }); describe('#deleteWallet', function() { it('should delete a wallet', function() { - var s = new Encrypted({ + var s = new Storage({ storage: localMock, sessionStorage: sessionMock, password: 'password' @@ -198,7 +198,7 @@ describe('Storage/Encrypted model', function() { describe('#setFromObj', function() { it('set localstorage from an object', function() { - var s = new Encrypted({ + var s = new Storage({ storage: localMock, sessionStorage: sessionMock, password: 'password' @@ -218,7 +218,7 @@ describe('Storage/Encrypted model', function() { describe('#globals', function() { it('should set, get and remove keys', function() { - var s = new Encrypted({ + var s = new Storage({ storage: localMock, sessionStorage: sessionMock, password: 'password' @@ -237,7 +237,7 @@ describe('Storage/Encrypted model', function() { describe('session storage', function() { it('should get a session ID', function() { - var s = new Encrypted({ + var s = new Storage({ storage: localMock, sessionStorage: sessionMock, password: 'password' diff --git a/util/build.js b/util/build.js index 080c1e47e..2c078f458 100644 --- a/util/build.js +++ b/util/build.js @@ -94,7 +94,6 @@ var createBundle = function(opts) { b.require('./plugins/LocalStorage', { expose: '../plugins/LocalStorage' }); - } b.require('./config', { From 6efa4f86de7f14482fdcec586a1178439162c71d Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Wed, 3 Sep 2014 01:25:08 -0300 Subject: [PATCH 113/191] wallet listing working --- Gruntfile.js | 1 + config.js | 7 +- js/app.js | 3 +- js/controllers/home.js | 13 +- js/controllers/open.js | 34 ++--- js/models/Storage.js | 174 +++++++++++++++-------- js/models/core/PluginManager.js | 11 +- js/models/core/Wallet.js | 36 +++-- js/models/core/WalletFactory.js | 154 ++++++++++---------- js/models/core/WalletLock.js | 57 ++++---- js/services/pluginManager.js | 16 ++- js/services/walletFactory.js | 6 +- plugins/LocalStorage.js | 28 ++-- plugins/googleDrive.js | 242 ++++++++++++++++++++++++++++++-- 14 files changed, 540 insertions(+), 242 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index 099cd23bd..540a676b0 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -43,6 +43,7 @@ module.exports = function(grunt) { scripts: { files: [ 'js/models/**/*.js', + 'js/models/*.js', 'plugins/*.js', 'copay.js', 'utils/*.js' diff --git a/config.js b/config.js index 10b5dafe7..94dc2a829 100644 --- a/config.js +++ b/config.js @@ -53,12 +53,13 @@ var defaultConfig = { verbose: 1, plugins: { - LocalStorage: true, - // GoogleDrive: true, +// LocalStorage: true, + GoogleDrive: true, }, GoogleDrive: { - clientId: '1', + clientId: '232630733383-29u1khqf5i8qubhf0homhpb2m14b5lja.apps.googleusercontent.com', + home: 'copay' }, }; if (typeof module !== 'undefined') diff --git a/js/app.js b/js/app.js index e1a3826ee..216553f20 100644 --- a/js/app.js +++ b/js/app.js @@ -37,11 +37,10 @@ var modules = [ 'copayApp.directives', ]; -if (config.plugins.length) +if (Object.keys(config.plugins).length) modules.push('angularLoad'); - var copayApp = window.copayApp = angular.module('copayApp', modules); copayApp.config(function($sceDelegateProvider) { diff --git a/js/controllers/home.js b/js/controllers/home.js index 2ac3e7381..c8a73d862 100644 --- a/js/controllers/home.js +++ b/js/controllers/home.js @@ -1,10 +1,13 @@ 'use strict'; -angular.module('copayApp.controllers').controller('HomeController', - function($scope, $rootScope, $location, walletFactory, notification, controllerUtils) { - - controllerUtils.redirIfLogged(); +angular.module('copayApp.controllers').controller('HomeController', function($scope, $rootScope, $location, walletFactory, notification, controllerUtils) { + controllerUtils.redirIfLogged(); + + $scope.loading = true; + + walletFactory.getWallets(function(ret) { $scope.loading = false; - $scope.hasWallets = (walletFactory.getWallets() && walletFactory.getWallets().length > 0) ? true : false; + $scope.hasWallets = (ret && ret.length > 0) ? true : false; }); +}); diff --git a/js/controllers/open.js b/js/controllers/open.js index 019932988..005bba83d 100644 --- a/js/controllers/open.js +++ b/js/controllers/open.js @@ -14,12 +14,18 @@ angular.module('copayApp.controllers').controller('OpenController', function($sc }; $rootScope.fromSetup = false; $scope.loading = false; - $scope.wallets = walletFactory.getWallets().sort(cmp); - $scope.selectedWalletId = walletFactory.storage.getLastOpened() || ($scope.wallets[0] && $scope.wallets[0].id); + walletFactory.getWallets(function(wallets) { + $scope.wallets = wallets.sort(cmp); + }); + + walletFactory.storage.getLastOpened(function(ret) { + $scope.selectedWalletId = ret || ($scope.wallets[0] && $scope.wallets[0].id); + }); + $scope.openPassword = ''; $scope.isMobile = !!window.cordova; - if (!$scope.wallets.length){ + if (!$scope.wallets.length) { $location.path('/'); } @@ -34,19 +40,15 @@ angular.module('copayApp.controllers').controller('OpenController', function($sc Passphrase.getBase64Async(password, function(passphrase) { var w, errMsg; - try { - w = walletFactory.open($scope.selectedWalletId, passphrase); - } catch (e) { - errMsg = e.message; - }; - if (!w) { - $scope.loading = false; - notification.error('Error', errMsg || 'Wrong password'); - $rootScope.$digest(); - return; - } - $rootScope.updatingBalance = true; - controllerUtils.startNetwork(w, $scope); + walletFactory.open($scope.selectedWalletId, passphrase, function(err, w) { + if (!w) { + $scope.loading = false; + notification.error('Error', err.errMsg || 'Wrong password'); + $rootScope.$digest(); + } + $rootScope.updatingBalance = true; + controllerUtils.startNetwork(w, $scope); + }); }); }; diff --git a/js/models/Storage.js b/js/models/Storage.js index 6a0c378e7..17757192f 100644 --- a/js/models/Storage.js +++ b/js/models/Storage.js @@ -1,5 +1,5 @@ 'use strict'; - +var preconditions = require('preconditions').singleton(); var CryptoJS = require('node-cryptojs-aes').CryptoJS; var bitcore = require('bitcore'); var preconditions = require('preconditions').instance(); @@ -55,38 +55,50 @@ Storage.prototype._decrypt = function(base64) { }; -Storage.prototype._read = function(k) { - var ret; - ret = this.storage.getItem(k); - if (!ret) return null; - ret = this._decrypt(ret); - if (!ret) return null; - ret = ret.toString(CryptoJS.enc.Utf8); - ret = JSON.parse(ret); - return ret; +Storage.prototype._read = function(k, cb) { + preconditions.checkArgument(cb); + + var self = this; + this.storage.getItem(k, function(ret) { + if (!ret) return cb(null); + var ret = self._decrypt(ret); + if (!ret) return cb(null); + + ret = ret.toString(CryptoJS.enc.Utf8); + ret = JSON.parse(ret); + return cb(ret); + }); }; -Storage.prototype._write = function(k, v) { +Storage.prototype._write = function(k, v, cb) { + preconditions.checkArgument(cb); + v = JSON.stringify(v); v = this._encrypt(v); - - this.storage.setItem(k, v); + this.storage.setItem(k, v, cb); }; // get value by key -Storage.prototype.getGlobal = function(k) { - var item = this.storage.getItem(k); - return item == 'undefined' ? undefined : item; +Storage.prototype.getGlobal = function(k, cb) { + preconditions.checkArgument(cb); + + this.storage.getItem(k, function(item) { + cb(item == 'undefined' ? undefined : item); + }); }; // set value for key -Storage.prototype.setGlobal = function(k, v) { - this.storage.setItem(k, typeof v === 'object' ? JSON.stringify(v) : v); +Storage.prototype.setGlobal = function(k, v, cb) { + preconditions.checkArgument(cb); + + this.storage.setItem(k, typeof v === 'object' ? JSON.stringify(v) : v, cb); }; // remove value for key -Storage.prototype.removeGlobal = function(k) { - this.storage.removeItem(k); +Storage.prototype.removeGlobal = function(k, cb) { + preconditions.checkArgument(cb); + + this.storage.removeItem(k, cb); }; Storage.prototype.getSessionId = function() { @@ -102,23 +114,38 @@ Storage.prototype._key = function(walletId, k) { return walletId + '::' + k; }; // get value by key -Storage.prototype.get = function(walletId, k) { - var ret = this._read(this._key(walletId, k)); - return ret; +Storage.prototype.get = function(walletId, k, cb) { + this._read(this._key(walletId, k), cb); +}; + +Storage.prototype.getMany = function(walletId, keys, cb) { + preconditions.checkArgument(cb); + + var self = this; + var ret = {}; + + var l = keys.length - 1; + for (var ii in keys) { + var k = keys[ii]; + this._read(this._key(walletId, k), function(v) { + ret[k] = v; + if (ii == l) return cb(ret); + }); + } }; // set value for key -Storage.prototype.set = function(walletId, k, v) { - this._write(this._key(walletId, k), v); +Storage.prototype.set = function(walletId, k, v, cb) { + this._write(this._key(walletId, k), v, cb); }; // remove value for key -Storage.prototype.remove = function(walletId, k) { - this.removeGlobal(this._key(walletId, k)); +Storage.prototype.remove = function(walletId, k, cb) { + this.removeGlobal(this._key(walletId, k), cb); }; -Storage.prototype.setName = function(walletId, name) { - this.setGlobal('nameFor::' + walletId, name); +Storage.prototype.setName = function(walletId, name, cb) { + this.setGlobal('nameFor::' + walletId, name, cb); }; Storage.prototype.getName = function(walletId) { @@ -126,41 +153,54 @@ Storage.prototype.getName = function(walletId) { return ret; }; -Storage.prototype.getWalletIds = function() { +Storage.prototype.getWalletIds = function(cb) { var walletIds = []; var uniq = {}; -console.log('[Encrypted.js.144]', this.storage); //TODO -console.log('[Encrypted.js.144]', this.storage.length); //TODO - for (var i = 0; i < this.storage.length; i++) { - var key = this.storage.key(i); - var split = key.split('::'); - if (split.length == 2) { - var walletId = split[0]; + this.storage.allKeys(function(keys) { +console.log('[Storage.js.170:keys:]',keys); //TODO - if (!walletId || walletId === 'nameFor' || walletId === 'lock') - continue; + for (var ii in keys) { + var key = keys[ii]; +console.log('[Storage.js.174:key:]',key); //TODO + var split = key.split('::'); + if (split.length == 2) { + var walletId = split[0]; - if (typeof uniq[walletId] === 'undefined') { - walletIds.push(walletId); - uniq[walletId] = 1; + if (!walletId || walletId === 'nameFor' || walletId === 'lock') + continue; + + if (typeof uniq[walletId] === 'undefined') { + walletIds.push(walletId); + uniq[walletId] = 1; + } } } - } - return walletIds; + return cb(walletIds); + }); }; -Storage.prototype.getWallets = function() { +Storage.prototype.getWallets = function(cb) { var wallets = []; - var ids = this.getWalletIds(); + var self = this; - for (var i in ids) { - wallets.push({ - id: ids[i], - name: this.getName(ids[i]), - }); - } - return wallets; + this.getWalletIds(function(ids) { + var l = ids.length - 1; + if (!l) + return cb([]); + + for (var i in ids) { + self.getName(ids[i], function(name) { + wallets.push({ + id: ids[i], + name: name, + }); + if (i == l) { + return cb(wallets); + } + }) + } + }); }; Storage.prototype.deleteWallet = function(walletId) { @@ -179,25 +219,35 @@ Storage.prototype.deleteWallet = function(walletId) { } }; -Storage.prototype.setLastOpened = function(walletId) { - this.setGlobal('lastOpened', walletId); +Storage.prototype.setLastOpened = function(walletId, cb) { + this.setGlobal('lastOpened', walletId, cb); } -Storage.prototype.getLastOpened = function() { - return this.getGlobal('lastOpened'); +Storage.prototype.getLastOpened = function(cb) { + this.getGlobal('lastOpened', cb); } //obj contains keys to be set -Storage.prototype.setFromObj = function(walletId, obj) { +Storage.prototype.setFromObj = function(walletId, obj, cb) { + preconditions.checkArgument(cb); + var self = this; + + console.log('[Storage.js.241]'); //TODO + var l = Object.keys(obj).length, + i = 0; for (var k in obj) { - this.set(walletId, k, obj[k]); + console.log('[Storage.js.247]', k, i, l); //TODO + self.set(walletId, k, obj[k], function() { + if (++i == l) { + self.setName(walletId, obj.opts.name, cb); + } + }); } - this.setName(walletId, obj.opts.name); }; // remove all values -Storage.prototype.clearAll = function() { - this.storage.clear(); +Storage.prototype.clearAll = function(cb) { + this.storage.clear(cb); }; Storage.prototype.import = function(base64) { diff --git a/js/models/core/PluginManager.js b/js/models/core/PluginManager.js index 23b3c2a77..bce94e464 100644 --- a/js/models/core/PluginManager.js +++ b/js/models/core/PluginManager.js @@ -3,8 +3,9 @@ var preconditions = require('preconditions').singleton(); function PluginManager(config) { this.registered = {}; + this.scripts = []; - for(var ii in config.plugins){ + for (var ii in config.plugins) { var pluginName = ii; if (!config.plugins[pluginName]) @@ -12,7 +13,7 @@ function PluginManager(config) { console.log('Loading plugin: ' + pluginName); var pluginClass = require('../plugins/' + pluginName); - var pluginObj = new pluginClass(); + var pluginObj = new pluginClass(config[pluginName]); pluginObj.init(); this._register(pluginObj, pluginName); } @@ -25,9 +26,10 @@ PluginManager.TYPE = {}; PluginManager.TYPE['STORAGE'] = KIND_UNIQUE; PluginManager.prototype._register = function(obj, name) { - preconditions.checkArgument(obj.type,'Plugin has not type:' + name); + preconditions.checkArgument(obj.type, 'Plugin has not type:' + name); var type = obj.type; var kind = PluginManager.TYPE[type]; + preconditions.checkArgument(kind, 'Plugin has unkown type' + name); preconditions.checkState(kind !== PluginManager.KIND_UNIQUE || !this.registered[type], 'Plugin kind already registered: ' + name); @@ -37,8 +39,11 @@ PluginManager.prototype._register = function(obj, name) { this.registered[type] = this.registered[type] || []; this.registered[type].push(obj); } + + this.scripts = this.scripts.concat(obj.scripts || []); }; + PluginManager.prototype.get = function(type) { return this.registered[type]; }; diff --git a/js/models/core/Wallet.js b/js/models/core/Wallet.js index 61e81b137..6ab010c5a 100644 --- a/js/models/core/Wallet.js +++ b/js/models/core/Wallet.js @@ -821,21 +821,28 @@ Wallet.prototype.getRegisteredPeerIds = function() { * @emits locked - in case the wallet is opened in another instance */ Wallet.prototype.keepAlive = function() { - try { - this.lock.keepAlive(); - } catch (e) { - log.debug(e); - this.emit('locked', null, 'Wallet appears to be openned on other browser instance. Closing this one.'); - } + var self = this; + + this.lock.keepAlive(function(err) { + if (err) { + log.debug(err); + self.emit('locked', null, 'Wallet appears to be openned on other browser instance. Closing this one.'); + } + }); }; /** * @desc Store the wallet's state + * @param {function} callback (err) */ -Wallet.prototype.store = function() { +Wallet.prototype.store = function(cb) { + var self = this; this.keepAlive(); - this.storage.setFromObj(this.id, this.toObj()); - log.debug('Wallet stored'); + this.storage.setFromObj(this.id, this.toObj(), function(err) { + log.debug('Wallet stored'); + if (cb) + cb(err); + }); }; /** @@ -2339,11 +2346,14 @@ Wallet.prototype.indexDiscovery = function(start, change, copayerIndex, gap, cb) /** * @desc Closes the wallet and disconnects all services */ -Wallet.prototype.close = function() { +Wallet.prototype.close = function(cb) { + var self =this; log.debug('## CLOSING'); - this.lock.release(); - this.network.cleanUp(); - this.blockchain.destroy(); + this.lock.release(function() { + self.network.cleanUp(); + self.blockchain.destroy(); + if (cb) return cb(); + }); }; /** diff --git a/js/models/core/WalletFactory.js b/js/models/core/WalletFactory.js index 2efea81de..f164c533f 100644 --- a/js/models/core/WalletFactory.js +++ b/js/models/core/WalletFactory.js @@ -1,4 +1,5 @@ 'use strict'; +var preconditions = require('preconditions').singleton(); var TxProposals = require('./TxProposals'); var PublicKeyRing = require('./PublicKeyRing'); @@ -6,7 +7,7 @@ var PrivateKey = require('./PrivateKey'); var Wallet = require('./Wallet'); var _ = require('underscore'); var log = require('../../log'); -var PluginManager = require('./PluginManager'); +var PluginManager = require('./PluginManager'); var Async = module.exports.Async = require('../network/Async'); var Insight = module.exports.Insight = require('../blockchain/Insight'); var preconditions = require('preconditions').singleton(); @@ -33,16 +34,24 @@ var Storage = module.exports.Storage = require('../Storage'); * @param {string} version - the version of copay for which this wallet was generated (for example, 0.4.7) * @constructor */ -function WalletFactory(config, version) { + +function WalletFactory(config, version, pluginManager) { var self = this; config = config || {}; - this.pluginManager = new PluginManager(config); - - this.Storage = config.Storage || Storage; + this.Storage = config.Storage || Storage; this.Network = config.Network || Async; this.Blockchain = config.Blockchain || Insight; - this.storage = new this.Storage({storage: this.pluginManager.get('STORAGE')}); + + var storageOpts = {}; + + if (pluginManager) { + storageOpts = { + storage: pluginManager.get('STORAGE') + }; + } + + this.storage = new this.Storage(storageOpts); this.networks = { 'livenet': new this.Network(config.network.livenet), @@ -57,27 +66,6 @@ function WalletFactory(config, version) { this.version = version; }; -/** - * @desc - * Returns true if the storage instance can retrieve the following keys using a given walletId - *

    - *
  • publicKeyRing
  • - *
  • txProposals
  • - *
  • opts
  • - *
  • privateKey
  • - *
- * @param {string} walletId - * @return {boolean} true if all the keys are present in the storage instance - */ -WalletFactory.prototype._checkRead = function(walletId) { - var s = this.storage; - var ret = - s.get(walletId, 'publicKeyRing') && - s.get(walletId, 'txProposals') && - s.get(walletId, 'opts') && - s.get(walletId, 'privateKey'); - return !!ret; -}; /** * @desc obtain network name from serialized wallet @@ -100,9 +88,14 @@ WalletFactory.prototype.obtainNetworkName = function(obj) { WalletFactory.prototype.fromObj = function(obj, skipFields) { var networkName = this.obtainNetworkName(obj); preconditions.checkState(networkName); + preconditions.checkArgument(obj); + obj.opts.reconnectDelay = this.walletDefaults.reconnectDelay; + // this is only used if private key or public key ring is skipped + obj.opts.networkName = this.networkName; + skipFields = skipFields || []; skipFields.forEach(function(k) { if (obj[k]) { @@ -155,20 +148,17 @@ WalletFactory.prototype.import = function(base64, password, skipFields) { * @param {string[]} skipFields - parameters to ignore when importing * @return {Wallet} */ -WalletFactory.prototype.read = function(walletId, skipFields) { - if (!this._checkRead(walletId)) - return false; - +WalletFactory.prototype.read = function(walletId, skipFields, cb) { + var self = this; var obj = {}; - var s = this.storage; - obj.id = walletId; - _.each(Wallet.PERSISTED_PROPERTIES, function(value) { - obj[value] = s.get(walletId, value); - }); - var w = this.fromObj(obj, skipFields); - return w; + this.storage.getMany(walletId, Wallet.PERSISTED_PROPERTIES, function(ret) { + for (var ii in ret) { + obj[ii] = ret[ii]; + } + return cb(self.fromObj(obj, skipFields)); + }); }; /** @@ -269,29 +259,29 @@ WalletFactory.prototype._checkVersion = function(inVersion) { * @desc Retrieve a wallet from the storage * @param {string} walletId - the id of the wallet * @param {string} passphrase - the passphrase to decode it - * @return {Wallet} + * @param {function} callback (err, {Wallet}) + * @return */ -WalletFactory.prototype.open = function(walletId, passphrase) { - this.storage._setPassphrase(passphrase); - var w = this.read(walletId); - if (w) { - w.store(); - } - - this.storage.setLastOpened(walletId); - return w; +WalletFactory.prototype.open = function(walletId, passphrase, cb) { + var self = this, + err; + self.storage._setPassphrase(passphrase); + self.read(walletId, null, function(w) { + w.store(function() { + self.storage.setLastOpened(walletId, function() { + return cb(err, w); + }); + }); + }); }; -/** - * @desc Retrieve all wallets stored without encription in the storage instance - * @returns {Wallet[]} - */ -WalletFactory.prototype.getWallets = function() { - var ret = this.storage.getWallets(); - ret.forEach(function(i) { - i.show = i.name ? ((i.name + ' <' + i.id + '>')) : i.id; +WalletFactory.prototype.getWallets = function(cb) { + var ret = this.storage.getWallets(function(ret) { + ret.forEach(function(i) { + i.show = i.name ? ((i.name + ' <' + i.id + '>')) : i.id; + }); + return cb(ret); }); - return ret; }; /** @@ -374,30 +364,32 @@ WalletFactory.prototype.joinCreateSession = function(secret, nickname, passphras connectedOnce = true; }); - joinNetwork.on('serverError', function() { - return cb('joinError'); - }); + << << << < HEAD + joinNetwork.on('serverError', function() { === === = + self.network.on('serverError', function() { >>> >>> > wallet listing working + return cb('joinError'); + }); - joinNetwork.start(opts, function() { - joinNetwork.greet(decodedSecret.pubKey, opts.secretNumber); - joinNetwork.on('data', function(sender, data) { - if (data.type === 'walletId') { - if (data.networkName !== decodedSecret.networkName) { - return cb('badNetwork'); - } + joinNetwork.start(opts, function() { + joinNetwork.greet(decodedSecret.pubKey, opts.secretNumber); + joinNetwork.on('data', function(sender, data) { + if (data.type === 'walletId') { + if (data.networkName !== decodedSecret.networkName) { + return cb('badNetwork'); + } - data.opts.privateKey = privateKey; - data.opts.nickname = nickname; - data.opts.passphrase = passphrase; - data.opts.id = data.walletId; - var w = self.create(data.opts); - w.sendWalletReady(decodedSecret.pubKey); - return cb(null, w); - } else { - return cb('walletFull', w); - } - }); - }); -}; + data.opts.privateKey = privateKey; + data.opts.nickname = nickname; + data.opts.passphrase = passphrase; + data.opts.id = data.walletId; + var w = self.create(data.opts); + w.sendWalletReady(decodedSecret.pubKey); + return cb(null, w); + } else { + return cb('walletFull', w); + } + }); + }); + }; -module.exports = WalletFactory; + module.exports = WalletFactory; diff --git a/js/models/core/WalletLock.js b/js/models/core/WalletLock.js index edd2bf67d..ef33fa196 100644 --- a/js/models/core/WalletLock.js +++ b/js/models/core/WalletLock.js @@ -10,46 +10,51 @@ function WalletLock(storage, walletId, timeoutMin) { this.storage = storage; this.timeoutMin = timeoutMin || 5; this.key = WalletLock._keyFor(walletId); - this._setLock(); + this._setLock(function() {}); } WalletLock._keyFor = function(walletId) { return 'lock' + '::' + walletId; }; -WalletLock.prototype._isLockedByOther = function() { - var json = this.storage.getGlobal(this.key); - var wl = json ? JSON.parse(json) : null; - var t = wl ? (Date.now() - wl.expireTs) : false; - // is not locked? - if (!wl || t > 0 || wl.sessionId === this.sessionId) - return false; +WalletLock.prototype._isLockedByOther = function(cb) { + var self=this; + this.storage.getGlobal(this.key, function(json) { + var wl = json ? JSON.parse(json) : null; + var t = wl ? (Date.now() - wl.expireTs) : false; + // is not locked? + if (!wl || t > 0 || wl.sessionId === self.sessionId) + return cb(false); - // Seconds remainding - return parseInt(-t/1000.); -}; - - -WalletLock.prototype._setLock = function() { - this.storage.setGlobal(this.key, { - sessionId: this.sessionId, - expireTs: Date.now() + this.timeoutMin * 60 * 1000, + // Seconds remainding + return cb(parseInt(-t / 1000.)); }); }; -WalletLock.prototype.keepAlive = function() { - preconditions.checkState(this.sessionId); - - var t = this._isLockedByOther(); - if (t) - throw new Error('Wallet is already open. Close it to proceed or wait '+ t + ' seconds if you close it already' ); - this._setLock(); +WalletLock.prototype._setLock = function(cb) { + this.storage.setGlobal(this.key, { + sessionId: this.sessionId, + expireTs: Date.now() + this.timeoutMin * 60 * 1000, + }, cb); }; -WalletLock.prototype.release = function() { - this.storage.removeGlobal(this.key); +WalletLock.prototype.keepAlive = function(cb) { + preconditions.checkState(this.sessionId); + var self = this; + + this._isLockedByOther(function(t) { + if (t) + return cb(new Error('Wallet is already open. Close it to proceed or wait ' + t + ' seconds if you close it already')); + + self._setLock(cb); + }); +}; + + +WalletLock.prototype.release = function(cb) { + this.storage.removeGlobal(this.key, cb); }; diff --git a/js/services/pluginManager.js b/js/services/pluginManager.js index c67b16846..f5e6e165c 100644 --- a/js/services/pluginManager.js +++ b/js/services/pluginManager.js @@ -1,5 +1,19 @@ 'use strict'; angular.module('copayApp.services').factory('pluginManager', function(angularLoad){ - return new copay.PluginManager(config); + var pm = new copay.PluginManager(config); + + var scripts = pm.scripts; + + for(var ii in scripts){ + var src = scripts[ii].src; + + console.log('\tLoading ',src); //TODO + angularLoad.loadScript(src) + .then(scripts[ii].then || null) + .catch(function() { + throw new Error('Loading ' + src); + }) + } + return pm; }); diff --git a/js/services/walletFactory.js b/js/services/walletFactory.js index 16580af9d..7a6b96ea6 100644 --- a/js/services/walletFactory.js +++ b/js/services/walletFactory.js @@ -1,3 +1,7 @@ 'use strict'; +angular.module('copayApp.services').factory('walletFactory', function(pluginManager){ + +console.log('[walletFactory.js.3]'); //TODO + return new copay.WalletFactory(config, copay.version, pluginManager); +}); -angular.module('copayApp.services').value('walletFactory', new copay.WalletFactory(config, copay.version)); diff --git a/plugins/LocalStorage.js b/plugins/LocalStorage.js index 3f050f64f..a811cfcf4 100644 --- a/plugins/LocalStorage.js +++ b/plugins/LocalStorage.js @@ -9,33 +9,33 @@ LocalStorage.prototype.init = function() { }; -LocalStorage.prototype.getItem = function(k) { - return localStorage.getItem(k); +LocalStorage.prototype.getItem = function(k,cb) { + return cb(localStorage.getItem(k)); }; -LocalStorage.prototype.setItem = function(k,v) { +LocalStorage.prototype.setItem = function(k,v,cb) { localStorage.setItem(k,v); + return cb(); }; -LocalStorage.prototype.removeItem = function(k) { +LocalStorage.prototype.removeItem = function(k,cb) { localStorage.removeItem(k); + return cb(); }; -LocalStorage.prototype.clear = function() { +LocalStorage.prototype.clear = function(cb) { localStorage.clear(); + return cb(); }; -delete LocalStorage.prototype.length; +LocalStorage.prototype.allKeys = function(cb) { + var l = localStorage.length; + var ret = []; -Object.defineProperty(LocalStorage.prototype, 'length', { - get: function() { - return localStorage.length; - } -}); + for(var i=0; i Date: Wed, 3 Sep 2014 15:43:27 -0300 Subject: [PATCH 114/191] working! --- js/controllers/create.js | 5 +- js/controllers/open.js | 14 +-- js/models/Storage.js | 45 ++++++--- js/models/core/WalletFactory.js | 51 +++++----- js/models/core/WalletLock.js | 12 ++- js/routes.js | 4 +- plugins/googleDrive.js | 173 ++++++++++++++++++++++---------- 7 files changed, 201 insertions(+), 103 deletions(-) diff --git a/js/controllers/create.js b/js/controllers/create.js index 52db78e95..6631dcce9 100644 --- a/js/controllers/create.js +++ b/js/controllers/create.js @@ -86,8 +86,9 @@ angular.module('copayApp.controllers').controller('CreateController', privateKeyHex: $scope.private, networkName: $scope.networkName, }; - var w = walletFactory.create(opts); - controllerUtils.startNetwork(w, $scope); + walletFactory.create(opts, function(err, w) { + controllerUtils.startNetwork(w, $scope); + }); }); }; diff --git a/js/controllers/open.js b/js/controllers/open.js index 005bba83d..403f4f9fd 100644 --- a/js/controllers/open.js +++ b/js/controllers/open.js @@ -16,19 +16,19 @@ angular.module('copayApp.controllers').controller('OpenController', function($sc $scope.loading = false; walletFactory.getWallets(function(wallets) { $scope.wallets = wallets.sort(cmp); - }); - walletFactory.storage.getLastOpened(function(ret) { - $scope.selectedWalletId = ret || ($scope.wallets[0] && $scope.wallets[0].id); + if (!$scope.wallets.length) { + $location.path('/'); + } + + walletFactory.storage.getLastOpened(function(ret) { + $scope.selectedWalletId = ret || ($scope.wallets[0] && $scope.wallets[0].id); + }); }); $scope.openPassword = ''; $scope.isMobile = !!window.cordova; - if (!$scope.wallets.length) { - $location.path('/'); - } - $scope.open = function(form) { if (form && form.$invalid) { notification.error('Error', 'Please enter the required fields'); diff --git a/js/models/Storage.js b/js/models/Storage.js index 17757192f..e23ab530d 100644 --- a/js/models/Storage.js +++ b/js/models/Storage.js @@ -83,6 +83,7 @@ Storage.prototype.getGlobal = function(k, cb) { preconditions.checkArgument(cb); this.storage.getItem(k, function(item) { +console.log('[Storage.js.96:item:]',item); //TODO cb(item == 'undefined' ? undefined : item); }); }; @@ -118,18 +119,34 @@ Storage.prototype.get = function(walletId, k, cb) { this._read(this._key(walletId, k), cb); }; + +Storage.prototype._readHelper = function(walletId, k, cb) { +console.log('[Storage.js.134:walletId:]',walletId,k); //TODO + var wk = this._key(walletId, k); + + this._read(wk, function(v){ + return cb(v,k); + }); +}; + Storage.prototype.getMany = function(walletId, keys, cb) { preconditions.checkArgument(cb); var self = this; var ret = {}; +console.log('[Storage.js.142:keys:]',keys); //TODO + + var l = keys.length, i=0; - var l = keys.length - 1; for (var ii in keys) { - var k = keys[ii]; - this._read(this._key(walletId, k), function(v) { + this._readHelper(walletId, keys[ii], function(v, k) { ret[k] = v; - if (ii == l) return cb(ret); +console.log('[Storage.js.144:ret:]',k,i,l,v); //TODO + if (++i == l) { + +console.log('[Storage.js.157] LKIST', ret); //TODO + return cb(ret); + } }); } }; @@ -148,9 +165,8 @@ Storage.prototype.setName = function(walletId, name, cb) { this.setGlobal('nameFor::' + walletId, name, cb); }; -Storage.prototype.getName = function(walletId) { - var ret = this.getGlobal('nameFor::' + walletId); - return ret; +Storage.prototype.getName = function(walletId, cb) { + this.getGlobal('nameFor::' + walletId, cb); }; Storage.prototype.getWalletIds = function(cb) { @@ -185,17 +201,21 @@ Storage.prototype.getWallets = function(cb) { var self = this; this.getWalletIds(function(ids) { - var l = ids.length - 1; +console.log('[Storage.js.197:ids:]',ids); //TODO + var l = ids.length, i=0; if (!l) return cb([]); - for (var i in ids) { - self.getName(ids[i], function(name) { + for (var ii in ids) { + var id = ids[ii]; +console.log('[Storage.js.206:id:]',id); //TODO + self.getName(id, function(name) { wallets.push({ - id: ids[i], + id: id, name: name, }); - if (i == l) { +console.log('[Storage.js.208:wallets:]',wallets); //TODO + if (++i == l) { return cb(wallets); } }) @@ -232,7 +252,6 @@ Storage.prototype.setFromObj = function(walletId, obj, cb) { preconditions.checkArgument(cb); var self = this; - console.log('[Storage.js.241]'); //TODO var l = Object.keys(obj).length, i = 0; for (var k in obj) { diff --git a/js/models/core/WalletFactory.js b/js/models/core/WalletFactory.js index f164c533f..18d5ed063 100644 --- a/js/models/core/WalletFactory.js +++ b/js/models/core/WalletFactory.js @@ -178,10 +178,10 @@ WalletFactory.prototype.read = function(walletId, skipFields, cb) { * @TODO: Figure out in what unit is this reconnect delay. * @param {number} opts.reconnectDelay milliseconds? * @param {number=} opts.version + * @param {callback} opts.version * @return {Wallet} */ -WalletFactory.prototype.create = function(opts) { - +WalletFactory.prototype.create = function(opts, cb) { opts = opts || {}; opts.networkName = opts.networkName || 'testnet'; @@ -230,9 +230,12 @@ WalletFactory.prototype.create = function(opts) { opts.version = opts.version || this.version; var w = new Wallet(opts); - w.store(); - this.storage.setLastOpened(w.id); - return w; + var self = this; + w.store(function() { + self.storage.setLastOpened(w.id, function() { + return cb(null, w); + }); + }); }; /** @@ -364,15 +367,13 @@ WalletFactory.prototype.joinCreateSession = function(secret, nickname, passphras connectedOnce = true; }); - << << << < HEAD - joinNetwork.on('serverError', function() { === === = - self.network.on('serverError', function() { >>> >>> > wallet listing working - return cb('joinError'); - }); + joinNetwork.on('serverError', function() { + return cb('joinError'); + }); - joinNetwork.start(opts, function() { - joinNetwork.greet(decodedSecret.pubKey, opts.secretNumber); - joinNetwork.on('data', function(sender, data) { + joinNetwork.start(opts, function() { + joinNetwork.greet(decodedSecret.pubKey, opts.secretNumber); + joinNetwork.on('data', function(sender, data) { if (data.type === 'walletId') { if (data.networkName !== decodedSecret.networkName) { return cb('badNetwork'); @@ -382,14 +383,18 @@ WalletFactory.prototype.joinCreateSession = function(secret, nickname, passphras data.opts.nickname = nickname; data.opts.passphrase = passphrase; data.opts.id = data.walletId; - var w = self.create(data.opts); - w.sendWalletReady(decodedSecret.pubKey); - return cb(null, w); - } else { - return cb('walletFull', w); - } - }); - }); - }; + self.create(data.opts, function(err, w) { + if (!err & w) { + w.sendWalletReady(s.pubKey); + } else { + if (!err) err = 'walletFull'; + } + return cb(err, w); + }); - module.exports = WalletFactory; + }); + }); + }; +}; + +module.exports = WalletFactory; diff --git a/js/models/core/WalletLock.js b/js/models/core/WalletLock.js index ef33fa196..a8a1729b7 100644 --- a/js/models/core/WalletLock.js +++ b/js/models/core/WalletLock.js @@ -10,7 +10,7 @@ function WalletLock(storage, walletId, timeoutMin) { this.storage = storage; this.timeoutMin = timeoutMin || 5; this.key = WalletLock._keyFor(walletId); - this._setLock(function() {}); + // this._setLock(function() {}); } WalletLock._keyFor = function(walletId) { @@ -18,7 +18,9 @@ WalletLock._keyFor = function(walletId) { }; WalletLock.prototype._isLockedByOther = function(cb) { - var self=this; + var self = this; + + console.log('[WalletLock.js.22]'); //TODO this.storage.getGlobal(this.key, function(json) { var wl = json ? JSON.parse(json) : null; var t = wl ? (Date.now() - wl.expireTs) : false; @@ -33,10 +35,13 @@ WalletLock.prototype._isLockedByOther = function(cb) { WalletLock.prototype._setLock = function(cb) { + this.storage.setGlobal(this.key, { sessionId: this.sessionId, expireTs: Date.now() + this.timeoutMin * 60 * 1000, - }, cb); + }, function() { + cb(null); + }); }; @@ -45,6 +50,7 @@ WalletLock.prototype.keepAlive = function(cb) { var self = this; this._isLockedByOther(function(t) { + if (t) return cb(new Error('Wallet is already open. Close it to proceed or wait ' + t + ' seconds if you close it already')); diff --git a/js/routes.js b/js/routes.js index 02c036251..6f01ffc23 100644 --- a/js/routes.js +++ b/js/routes.js @@ -76,8 +76,8 @@ angular // IDLE timeout var timeout = config.wallet.idleDurationMin * 60 || 300; $idleProvider.idleDuration(timeout); // in seconds - $idleProvider.warningDuration(20); // in seconds - $keepaliveProvider.interval(2); // in seconds + $idleProvider.warningDuration(40); // in seconds + $keepaliveProvider.interval(30); // in seconds }) .run(function($rootScope, $location, $idle, gettextCatalog) { gettextCatalog.currentLanguage = config.defaultLanguage; diff --git a/plugins/googleDrive.js b/plugins/googleDrive.js index 7811640b9..8cf41d72e 100644 --- a/plugins/googleDrive.js +++ b/plugins/googleDrive.js @@ -25,7 +25,7 @@ function GoogleDrive(config) { window.InitGoogleDrive = function() { - console.log('[googleDrive.js.18] setting loaded'); //TODO + // console.log('[googleDrive.js.18] setting loaded'); //TODO loaded = 1; }; @@ -47,7 +47,7 @@ GoogleDrive.prototype.initLoaded = function() { */ GoogleDrive.prototype.checkAuth = function() { - console.log('\tChecking google Auth'); //TODO + console.log('\tChecking google Auth'); gapi.auth.authorize({ 'client_id': this.clientId, 'scope': SCOPES, @@ -61,7 +61,7 @@ GoogleDrive.prototype.checkAuth = function() { */ GoogleDrive.prototype.handleAuthResult = function(authResult) { var self = this; - console.log('[googleDrive.js.39:authResult:]', authResult); //TODO + // console.log('[googleDrive.js.39:authResult:]', authResult); //TODO if (authResult.error) { if (authResult.error) { @@ -81,61 +81,121 @@ GoogleDrive.prototype.checkReady = function() { throw new Error('goggle drive is not ready!'); }; -GoogleDrive.prototype.getItem = function(k) { - this.checkReady(); - throw new Error('getItem not implemented'); +GoogleDrive.prototype._httpGet = function(theUrl) { + var accessToken = gapi.auth.getToken().access_token; + var xmlHttp = null; + + xmlHttp = new XMLHttpRequest(); + xmlHttp.open("GET", theUrl, false); + xmlHttp.setRequestHeader('Authorization', 'Bearer ' + accessToken); + xmlHttp.send(null); + return xmlHttp.responseText; +} + +GoogleDrive.prototype.getItem = function(k, cb) { + console.log('[googleDrive.js.95:getItem:]', k); //TODO + var self = this; + + self.checkReady(); + self._idForName(k, function(kId) { + // console.log('[googleDrive.js.89:kId:]', kId); //TODO + if (!kId) + return cb(null); + + + var args = { + 'path': '/drive/v2/files/' + kId, + 'method': 'GET', + }; + // console.log('[googleDrive.js.95:args:]', args); //TODO + + var request = gapi.client.request(args); + request.execute(function(res) { + // console.log('[googleDrive.js.175:res:]', res); //TODO + if (!res || !res.downloadUrl) + return cb(null); + + return cb(self._httpGet(res.downloadUrl)); + }); + + }); }; GoogleDrive.prototype.setItem = function(k, v, cb) { + // console.log('[googleDrive.js.111:setItem:]', k, v); //TODO var self = this; - this.checkReady(); + self.checkReady(); + self._idForName(this.home, function(parentId) { + preconditions.checkState(parentId); + // console.log('[googleDrive.js.118:parentId:]', parentId); //TODO + self._idForName(k, function(kId) { - var parendId = self._idForName[this.home]; - preconditions.checkState(parentId); + // console.log('[googleDrive.js.105]', parentId, kId); //TODO - var boundary = '-------314159265358979323846'; - var delimiter = "\r\n--" + boundary + "\r\n"; - var close_delim = "\r\n--" + boundary + "--"; + var boundary = '-------314159265358979323846'; + var delimiter = "\r\n--" + boundary + "\r\n"; + var close_delim = "\r\n--" + boundary + "--"; - var metadata = { - 'title': k, - 'mimeType': 'application/octet-stream', - 'parents': [parentId], - }; + var metadata = { + 'title': k, + 'mimeType': 'application/octet-stream', + 'parents': [{ + 'id': parentId + }], + }; - var base64Data = btoa(v); - var multipartRequestBody = - delimiter + - 'Content-Type: application/json\r\n\r\n' + - JSON.stringify(metadata) + - delimiter + - 'Content-Type: application/octet-stream \r\n' + - 'Content-Transfer-Encoding: base64\r\n' + - '\r\n' + - base64Data + - close_delim; -console.log('[googleDrive.js.105:multipartRequestBody:]',multipartRequestBody); //TODO + var base64Data = btoa(v); + var multipartRequestBody = + delimiter + + 'Content-Type: application/json\r\n\r\n' + + JSON.stringify(metadata) + + delimiter + + 'Content-Type: application/octet-stream \r\n' + + 'Content-Transfer-Encoding: base64\r\n' + + '\r\n' + + base64Data + + close_delim; - var request = gapi.client.request({ - 'path': '/upload/drive/v2/files', - 'method': 'POST', - 'params': { - 'uploadType': 'multipart', - }, - 'headers': { - 'Content-Type': 'multipart/mixed; boundary="' + boundary + '"' - }, - 'body': multipartRequestBody + var args = { + 'path': '/upload/drive/v2/files' + (kId ? '/' + kId : ''), + 'method': kId ? 'PUT' : 'POST', + 'params': { + 'uploadType': 'multipart', + }, + 'headers': { + 'Content-Type': 'multipart/mixed; boundary="' + boundary + '"' + }, + 'body': multipartRequestBody + } + // console.log('[googleDrive.js.148:args:]', args); //TODO + + var request = gapi.client.request(args); + request.execute(cb); + }); }); - request.execute(cb); }; -GoogleDrive.prototype.removeItem = function(k) { - this.checkReady(); +GoogleDrive.prototype.removeItem = function(k, cb) { + var self = this; - throw new Error('removeItem not implemented'); + self.checkReady(); + self._idForName(this.home, function(parentId) { + preconditions.checkState(parentId); + self._idForName(k, function(kId) { + + var args = { + 'path': '/drive/v2/files/' + kId, + 'method': 'DELETE', + }; + var request = gapi.client.request(args); + request.execute(function() { + if (cb) + cb(); + }); + }); + }); }; GoogleDrive.prototype.clear = function() { @@ -158,13 +218,14 @@ GoogleDrive.prototype._mkdir = function(cb) { 'mimeType': "application/vnd.google-apps.folder", }), }); - request.execute(function(){ - self._idForName(this.home, cb); + request.execute(function() { + self._idForName(self.home, cb); }); }; GoogleDrive.prototype._idForName = function(name, cb) { + // console.log('[googleDrive.js.199:_idForName:]', name); //TODO preconditions.checkArgument(name); preconditions.checkArgument(cb); var self = this; @@ -174,17 +235,24 @@ GoogleDrive.prototype._idForName = function(name, cb) { self.ts = self.ts * 1.5; return setTimeout(self._idForName.bind(self, name, cb), self.ts); } -console.log('[googleDrive.js.178:name:]',name); //TODO + // console.log('[googleDrive.js.178:name:]', name); //TODO - if (self.idCache[name]) + if (self.idCache[name]) { + // console.log('[googleDrive.js.212:] FROM CACHE', name, self.idCache[name]); //TODO return cb(self.idCache[name]); + } console.log('Querying for: ', name); //TODO var args; - var idParent = name == this.home ? 'root' : self.idCache[this.home] ; + var idParent = name == this.home ? 'root' : self.idCache[this.home]; -console.log('[googleDrive.js.177:idParent:]',idParent); //TODO + if (!idParent) { + return self._mkdir(function() { + self._idForName(name, cb); + }); + } + // console.log('[googleDrive.js.177:idParent:]', idParent); //TODO preconditions.checkState(idParent); args = { @@ -195,13 +263,12 @@ console.log('[googleDrive.js.177:idParent:]',idParent); //TODO } }; - console.log('[googleDrive.js.196:args:]', args); //TODO var request = gapi.client.request(args); request.execute(function(res) { - console.log('[googleDrive.js.175:res:]', res); //TODO var i = res.items && res.items[0] ? res.items[0].id : false; if (i) self.idCache[name] = i; + // console.log('[googleDrive.js.238] CACHING ' + name + ':' + i); //TODO return cb(self.idCache[name]); }); }; @@ -232,13 +299,13 @@ GoogleDrive.prototype.allKeys = function(cb) { }, }); request.execute(function(res) { - console.log('[googleDrive.js.152:res:]', res); //TODO + // console.log('[googleDrive.js.152:res:]', res); //TODO if (res.error) throw new Error(res.error.message); var ret = []; for (var ii in res.items) { - ret.push(res[ii].id); + ret.push(res.items[ii].title); } return cb(ret); }); From da1266e5f9d4920209b8c9d78fec24d03ed00eac Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Wed, 3 Sep 2014 17:05:19 -0300 Subject: [PATCH 115/191] renamed foo to FOO --- plugins/{googleDrive.js => GoogleDrive.js} | 0 plugins/kk | 321 +++++++++++++++++++++ 2 files changed, 321 insertions(+) rename plugins/{googleDrive.js => GoogleDrive.js} (100%) create mode 100644 plugins/kk diff --git a/plugins/googleDrive.js b/plugins/GoogleDrive.js similarity index 100% rename from plugins/googleDrive.js rename to plugins/GoogleDrive.js diff --git a/plugins/kk b/plugins/kk new file mode 100644 index 000000000..8cf41d72e --- /dev/null +++ b/plugins/kk @@ -0,0 +1,321 @@ +'use strict'; + +var preconditions = require('preconditions').singleton(); +var loaded = 0; +var SCOPES = 'https://www.googleapis.com/auth/drive'; + +function GoogleDrive(config) { + preconditions.checkArgument(config && config.clientId, 'No clientId at GoogleDrive config'); + + this.clientId = config.clientId; + this.home = config.home || 'copay'; + this.idCache = {}; + + this.type = 'STORAGE'; + + this.scripts = [{ + then: this.initLoaded.bind(this), + src: 'https://apis.google.com/js/client.js?onload=InitGoogleDrive' + }]; + + this.isReady = false; + this.useImmediate = true; + this.ts = 100; +}; + +window.InitGoogleDrive = function() { + + // console.log('[googleDrive.js.18] setting loaded'); //TODO + loaded = 1; +}; + +GoogleDrive.prototype.init = function() {}; + +/** + * Called when the client library is loaded to start the auth flow. + */ +GoogleDrive.prototype.initLoaded = function() { + if (!loaded) { + window.setTimeout(this.initLoaded.bind(this), 500); + } else { + window.setTimeout(this.checkAuth.bind(this), 1); + } +} + +/** + * Check if the current user has authorized the application. + */ +GoogleDrive.prototype.checkAuth = function() { + + console.log('\tChecking google Auth'); + gapi.auth.authorize({ + 'client_id': this.clientId, + 'scope': SCOPES, + 'immediate': this.useImmediate, + }, + this.handleAuthResult.bind(this)); +}; + +/** + * Called when authorization server replies. + */ +GoogleDrive.prototype.handleAuthResult = function(authResult) { + var self = this; + // console.log('[googleDrive.js.39:authResult:]', authResult); //TODO + + if (authResult.error) { + if (authResult.error) { + self.useImmediate = false; + return this.checkAuth(); + }; + throw new Error(authResult.error); + } + + gapi.client.load('drive', 'v2', function() { + self.isReady = true; + }); +} + +GoogleDrive.prototype.checkReady = function() { + if (!this.isReady) + throw new Error('goggle drive is not ready!'); +}; + +GoogleDrive.prototype._httpGet = function(theUrl) { + var accessToken = gapi.auth.getToken().access_token; + var xmlHttp = null; + + xmlHttp = new XMLHttpRequest(); + xmlHttp.open("GET", theUrl, false); + xmlHttp.setRequestHeader('Authorization', 'Bearer ' + accessToken); + xmlHttp.send(null); + return xmlHttp.responseText; +} + +GoogleDrive.prototype.getItem = function(k, cb) { + console.log('[googleDrive.js.95:getItem:]', k); //TODO + var self = this; + + self.checkReady(); + self._idForName(k, function(kId) { + // console.log('[googleDrive.js.89:kId:]', kId); //TODO + if (!kId) + return cb(null); + + + var args = { + 'path': '/drive/v2/files/' + kId, + 'method': 'GET', + }; + // console.log('[googleDrive.js.95:args:]', args); //TODO + + var request = gapi.client.request(args); + request.execute(function(res) { + // console.log('[googleDrive.js.175:res:]', res); //TODO + if (!res || !res.downloadUrl) + return cb(null); + + return cb(self._httpGet(res.downloadUrl)); + }); + + }); +}; + +GoogleDrive.prototype.setItem = function(k, v, cb) { + // console.log('[googleDrive.js.111:setItem:]', k, v); //TODO + var self = this; + + self.checkReady(); + self._idForName(this.home, function(parentId) { + preconditions.checkState(parentId); + // console.log('[googleDrive.js.118:parentId:]', parentId); //TODO + self._idForName(k, function(kId) { + + // console.log('[googleDrive.js.105]', parentId, kId); //TODO + + + var boundary = '-------314159265358979323846'; + var delimiter = "\r\n--" + boundary + "\r\n"; + var close_delim = "\r\n--" + boundary + "--"; + + var metadata = { + 'title': k, + 'mimeType': 'application/octet-stream', + 'parents': [{ + 'id': parentId + }], + }; + + var base64Data = btoa(v); + var multipartRequestBody = + delimiter + + 'Content-Type: application/json\r\n\r\n' + + JSON.stringify(metadata) + + delimiter + + 'Content-Type: application/octet-stream \r\n' + + 'Content-Transfer-Encoding: base64\r\n' + + '\r\n' + + base64Data + + close_delim; + + var args = { + 'path': '/upload/drive/v2/files' + (kId ? '/' + kId : ''), + 'method': kId ? 'PUT' : 'POST', + 'params': { + 'uploadType': 'multipart', + }, + 'headers': { + 'Content-Type': 'multipart/mixed; boundary="' + boundary + '"' + }, + 'body': multipartRequestBody + } + // console.log('[googleDrive.js.148:args:]', args); //TODO + + var request = gapi.client.request(args); + request.execute(cb); + }); + }); +}; + +GoogleDrive.prototype.removeItem = function(k, cb) { + var self = this; + + self.checkReady(); + self._idForName(this.home, function(parentId) { + preconditions.checkState(parentId); + self._idForName(k, function(kId) { + + var args = { + 'path': '/drive/v2/files/' + kId, + 'method': 'DELETE', + }; + var request = gapi.client.request(args); + request.execute(function() { + if (cb) + cb(); + }); + }); + }); +}; + +GoogleDrive.prototype.clear = function() { + this.checkReady(); + throw new Error('clear not implemented'); +}; + + +GoogleDrive.prototype._mkdir = function(cb) { + preconditions.checkArgument(cb); + var self = this; + + console.log('Creating drive folder ' + this.home); + + var request = gapi.client.request({ + 'path': '/drive/v2/files', + 'method': 'POST', + 'body': JSON.stringify({ + 'title': this.home, + 'mimeType': "application/vnd.google-apps.folder", + }), + }); + request.execute(function() { + self._idForName(self.home, cb); + }); +}; + + +GoogleDrive.prototype._idForName = function(name, cb) { + // console.log('[googleDrive.js.199:_idForName:]', name); //TODO + preconditions.checkArgument(name); + preconditions.checkArgument(cb); + var self = this; + + if (!self.isReady) { + console.log('\tWaiting for Drive'); + self.ts = self.ts * 1.5; + return setTimeout(self._idForName.bind(self, name, cb), self.ts); + } + // console.log('[googleDrive.js.178:name:]', name); //TODO + + if (self.idCache[name]) { + // console.log('[googleDrive.js.212:] FROM CACHE', name, self.idCache[name]); //TODO + return cb(self.idCache[name]); + } + + console.log('Querying for: ', name); //TODO + var args; + + var idParent = name == this.home ? 'root' : self.idCache[this.home]; + + if (!idParent) { + return self._mkdir(function() { + self._idForName(name, cb); + }); + } + // console.log('[googleDrive.js.177:idParent:]', idParent); //TODO + preconditions.checkState(idParent); + + args = { + 'path': '/drive/v2/files', + 'method': 'GET', + 'params': { + 'q': "title='" + name + "' and trashed = false and '" + idParent + "' in parents", + } + }; + + var request = gapi.client.request(args); + request.execute(function(res) { + var i = res.items && res.items[0] ? res.items[0].id : false; + if (i) + self.idCache[name] = i; + // console.log('[googleDrive.js.238] CACHING ' + name + ':' + i); //TODO + return cb(self.idCache[name]); + }); +}; + +GoogleDrive.prototype._checkHomeDir = function(cb) { + var self = this; + + this._idForName(this.home, function(homeId) { + if (!homeId) + return self._mkdir(cb); + + return cb(homeId); + }); +}; + +GoogleDrive.prototype.allKeys = function(cb) { + var self = this; + + this._checkHomeDir(function(homeId) { + preconditions.checkState(homeId); + + var request = gapi.client.request({ + 'path': '/drive/v2/files', + 'method': 'GET', + 'params': { + 'q': "'" + homeId + "' in parents and trashed = false", + 'fields': 'items(id,title)' + }, + }); + request.execute(function(res) { + // console.log('[googleDrive.js.152:res:]', res); //TODO + if (res.error) + throw new Error(res.error.message); + + var ret = []; + for (var ii in res.items) { + ret.push(res.items[ii].title); + } + return cb(ret); + }); + }); +}; + +GoogleDrive.prototype.key = function(k) { + var v = localStorage.key(k); + return v; +}; + + +module.exports = GoogleDrive; From fe37bcc9e90599c0abe4415344fa1e93dd161d0d Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Wed, 3 Sep 2014 17:05:49 -0300 Subject: [PATCH 116/191] . --- plugins/kk | 321 ----------------------------------------------------- 1 file changed, 321 deletions(-) delete mode 100644 plugins/kk diff --git a/plugins/kk b/plugins/kk deleted file mode 100644 index 8cf41d72e..000000000 --- a/plugins/kk +++ /dev/null @@ -1,321 +0,0 @@ -'use strict'; - -var preconditions = require('preconditions').singleton(); -var loaded = 0; -var SCOPES = 'https://www.googleapis.com/auth/drive'; - -function GoogleDrive(config) { - preconditions.checkArgument(config && config.clientId, 'No clientId at GoogleDrive config'); - - this.clientId = config.clientId; - this.home = config.home || 'copay'; - this.idCache = {}; - - this.type = 'STORAGE'; - - this.scripts = [{ - then: this.initLoaded.bind(this), - src: 'https://apis.google.com/js/client.js?onload=InitGoogleDrive' - }]; - - this.isReady = false; - this.useImmediate = true; - this.ts = 100; -}; - -window.InitGoogleDrive = function() { - - // console.log('[googleDrive.js.18] setting loaded'); //TODO - loaded = 1; -}; - -GoogleDrive.prototype.init = function() {}; - -/** - * Called when the client library is loaded to start the auth flow. - */ -GoogleDrive.prototype.initLoaded = function() { - if (!loaded) { - window.setTimeout(this.initLoaded.bind(this), 500); - } else { - window.setTimeout(this.checkAuth.bind(this), 1); - } -} - -/** - * Check if the current user has authorized the application. - */ -GoogleDrive.prototype.checkAuth = function() { - - console.log('\tChecking google Auth'); - gapi.auth.authorize({ - 'client_id': this.clientId, - 'scope': SCOPES, - 'immediate': this.useImmediate, - }, - this.handleAuthResult.bind(this)); -}; - -/** - * Called when authorization server replies. - */ -GoogleDrive.prototype.handleAuthResult = function(authResult) { - var self = this; - // console.log('[googleDrive.js.39:authResult:]', authResult); //TODO - - if (authResult.error) { - if (authResult.error) { - self.useImmediate = false; - return this.checkAuth(); - }; - throw new Error(authResult.error); - } - - gapi.client.load('drive', 'v2', function() { - self.isReady = true; - }); -} - -GoogleDrive.prototype.checkReady = function() { - if (!this.isReady) - throw new Error('goggle drive is not ready!'); -}; - -GoogleDrive.prototype._httpGet = function(theUrl) { - var accessToken = gapi.auth.getToken().access_token; - var xmlHttp = null; - - xmlHttp = new XMLHttpRequest(); - xmlHttp.open("GET", theUrl, false); - xmlHttp.setRequestHeader('Authorization', 'Bearer ' + accessToken); - xmlHttp.send(null); - return xmlHttp.responseText; -} - -GoogleDrive.prototype.getItem = function(k, cb) { - console.log('[googleDrive.js.95:getItem:]', k); //TODO - var self = this; - - self.checkReady(); - self._idForName(k, function(kId) { - // console.log('[googleDrive.js.89:kId:]', kId); //TODO - if (!kId) - return cb(null); - - - var args = { - 'path': '/drive/v2/files/' + kId, - 'method': 'GET', - }; - // console.log('[googleDrive.js.95:args:]', args); //TODO - - var request = gapi.client.request(args); - request.execute(function(res) { - // console.log('[googleDrive.js.175:res:]', res); //TODO - if (!res || !res.downloadUrl) - return cb(null); - - return cb(self._httpGet(res.downloadUrl)); - }); - - }); -}; - -GoogleDrive.prototype.setItem = function(k, v, cb) { - // console.log('[googleDrive.js.111:setItem:]', k, v); //TODO - var self = this; - - self.checkReady(); - self._idForName(this.home, function(parentId) { - preconditions.checkState(parentId); - // console.log('[googleDrive.js.118:parentId:]', parentId); //TODO - self._idForName(k, function(kId) { - - // console.log('[googleDrive.js.105]', parentId, kId); //TODO - - - var boundary = '-------314159265358979323846'; - var delimiter = "\r\n--" + boundary + "\r\n"; - var close_delim = "\r\n--" + boundary + "--"; - - var metadata = { - 'title': k, - 'mimeType': 'application/octet-stream', - 'parents': [{ - 'id': parentId - }], - }; - - var base64Data = btoa(v); - var multipartRequestBody = - delimiter + - 'Content-Type: application/json\r\n\r\n' + - JSON.stringify(metadata) + - delimiter + - 'Content-Type: application/octet-stream \r\n' + - 'Content-Transfer-Encoding: base64\r\n' + - '\r\n' + - base64Data + - close_delim; - - var args = { - 'path': '/upload/drive/v2/files' + (kId ? '/' + kId : ''), - 'method': kId ? 'PUT' : 'POST', - 'params': { - 'uploadType': 'multipart', - }, - 'headers': { - 'Content-Type': 'multipart/mixed; boundary="' + boundary + '"' - }, - 'body': multipartRequestBody - } - // console.log('[googleDrive.js.148:args:]', args); //TODO - - var request = gapi.client.request(args); - request.execute(cb); - }); - }); -}; - -GoogleDrive.prototype.removeItem = function(k, cb) { - var self = this; - - self.checkReady(); - self._idForName(this.home, function(parentId) { - preconditions.checkState(parentId); - self._idForName(k, function(kId) { - - var args = { - 'path': '/drive/v2/files/' + kId, - 'method': 'DELETE', - }; - var request = gapi.client.request(args); - request.execute(function() { - if (cb) - cb(); - }); - }); - }); -}; - -GoogleDrive.prototype.clear = function() { - this.checkReady(); - throw new Error('clear not implemented'); -}; - - -GoogleDrive.prototype._mkdir = function(cb) { - preconditions.checkArgument(cb); - var self = this; - - console.log('Creating drive folder ' + this.home); - - var request = gapi.client.request({ - 'path': '/drive/v2/files', - 'method': 'POST', - 'body': JSON.stringify({ - 'title': this.home, - 'mimeType': "application/vnd.google-apps.folder", - }), - }); - request.execute(function() { - self._idForName(self.home, cb); - }); -}; - - -GoogleDrive.prototype._idForName = function(name, cb) { - // console.log('[googleDrive.js.199:_idForName:]', name); //TODO - preconditions.checkArgument(name); - preconditions.checkArgument(cb); - var self = this; - - if (!self.isReady) { - console.log('\tWaiting for Drive'); - self.ts = self.ts * 1.5; - return setTimeout(self._idForName.bind(self, name, cb), self.ts); - } - // console.log('[googleDrive.js.178:name:]', name); //TODO - - if (self.idCache[name]) { - // console.log('[googleDrive.js.212:] FROM CACHE', name, self.idCache[name]); //TODO - return cb(self.idCache[name]); - } - - console.log('Querying for: ', name); //TODO - var args; - - var idParent = name == this.home ? 'root' : self.idCache[this.home]; - - if (!idParent) { - return self._mkdir(function() { - self._idForName(name, cb); - }); - } - // console.log('[googleDrive.js.177:idParent:]', idParent); //TODO - preconditions.checkState(idParent); - - args = { - 'path': '/drive/v2/files', - 'method': 'GET', - 'params': { - 'q': "title='" + name + "' and trashed = false and '" + idParent + "' in parents", - } - }; - - var request = gapi.client.request(args); - request.execute(function(res) { - var i = res.items && res.items[0] ? res.items[0].id : false; - if (i) - self.idCache[name] = i; - // console.log('[googleDrive.js.238] CACHING ' + name + ':' + i); //TODO - return cb(self.idCache[name]); - }); -}; - -GoogleDrive.prototype._checkHomeDir = function(cb) { - var self = this; - - this._idForName(this.home, function(homeId) { - if (!homeId) - return self._mkdir(cb); - - return cb(homeId); - }); -}; - -GoogleDrive.prototype.allKeys = function(cb) { - var self = this; - - this._checkHomeDir(function(homeId) { - preconditions.checkState(homeId); - - var request = gapi.client.request({ - 'path': '/drive/v2/files', - 'method': 'GET', - 'params': { - 'q': "'" + homeId + "' in parents and trashed = false", - 'fields': 'items(id,title)' - }, - }); - request.execute(function(res) { - // console.log('[googleDrive.js.152:res:]', res); //TODO - if (res.error) - throw new Error(res.error.message); - - var ret = []; - for (var ii in res.items) { - ret.push(res.items[ii].title); - } - return cb(ret); - }); - }); -}; - -GoogleDrive.prototype.key = function(k) { - var v = localStorage.key(k); - return v; -}; - - -module.exports = GoogleDrive; From 9ad326cd30a281f9309ec0b378546d3e58e44885 Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Thu, 4 Sep 2014 16:23:37 -0300 Subject: [PATCH 117/191] working! --- config.js | 8 +++++--- js/controllers/home.js | 4 ++-- js/controllers/open.js | 2 ++ js/models/Storage.js | 11 ----------- js/services/walletFactory.js | 2 -- plugins/LocalStorage.js | 1 - views/home.html | 6 +++++- views/open.html | 8 ++++++-- 8 files changed, 20 insertions(+), 22 deletions(-) diff --git a/config.js b/config.js index 94dc2a829..7b67351bd 100644 --- a/config.js +++ b/config.js @@ -53,12 +53,14 @@ var defaultConfig = { verbose: 1, plugins: { -// LocalStorage: true, - GoogleDrive: true, + LocalStorage: true, + // GoogleDrive: true, }, GoogleDrive: { - clientId: '232630733383-29u1khqf5i8qubhf0homhpb2m14b5lja.apps.googleusercontent.com', + // for localhost: + clientId: '232630733383-a35gcnovnkgka94394i88gq60vtjb4af.apps.googleusercontent.com', + // clientId: '232630733383-29u1khqf5i8qubhf0homhpb2m14b5lja.apps.googleusercontent.com', home: 'copay' }, }; diff --git a/js/controllers/home.js b/js/controllers/home.js index c8a73d862..b0d325448 100644 --- a/js/controllers/home.js +++ b/js/controllers/home.js @@ -4,10 +4,10 @@ angular.module('copayApp.controllers').controller('HomeController', function($sc controllerUtils.redirIfLogged(); - $scope.loading = true; + $scope.retreiving = true; walletFactory.getWallets(function(ret) { - $scope.loading = false; + $scope.retreiving = false; $scope.hasWallets = (ret && ret.length > 0) ? true : false; }); }); diff --git a/js/controllers/open.js b/js/controllers/open.js index 403f4f9fd..e06519e1f 100644 --- a/js/controllers/open.js +++ b/js/controllers/open.js @@ -14,6 +14,7 @@ angular.module('copayApp.controllers').controller('OpenController', function($sc }; $rootScope.fromSetup = false; $scope.loading = false; + $scope.retreiving = true; walletFactory.getWallets(function(wallets) { $scope.wallets = wallets.sort(cmp); @@ -23,6 +24,7 @@ angular.module('copayApp.controllers').controller('OpenController', function($sc walletFactory.storage.getLastOpened(function(ret) { $scope.selectedWalletId = ret || ($scope.wallets[0] && $scope.wallets[0].id); + $scope.retreiving = false; }); }); diff --git a/js/models/Storage.js b/js/models/Storage.js index e23ab530d..f4e19a350 100644 --- a/js/models/Storage.js +++ b/js/models/Storage.js @@ -83,7 +83,6 @@ Storage.prototype.getGlobal = function(k, cb) { preconditions.checkArgument(cb); this.storage.getItem(k, function(item) { -console.log('[Storage.js.96:item:]',item); //TODO cb(item == 'undefined' ? undefined : item); }); }; @@ -121,9 +120,7 @@ Storage.prototype.get = function(walletId, k, cb) { Storage.prototype._readHelper = function(walletId, k, cb) { -console.log('[Storage.js.134:walletId:]',walletId,k); //TODO var wk = this._key(walletId, k); - this._read(wk, function(v){ return cb(v,k); }); @@ -141,10 +138,7 @@ console.log('[Storage.js.142:keys:]',keys); //TODO for (var ii in keys) { this._readHelper(walletId, keys[ii], function(v, k) { ret[k] = v; -console.log('[Storage.js.144:ret:]',k,i,l,v); //TODO if (++i == l) { - -console.log('[Storage.js.157] LKIST', ret); //TODO return cb(ret); } }); @@ -174,11 +168,9 @@ Storage.prototype.getWalletIds = function(cb) { var uniq = {}; this.storage.allKeys(function(keys) { -console.log('[Storage.js.170:keys:]',keys); //TODO for (var ii in keys) { var key = keys[ii]; -console.log('[Storage.js.174:key:]',key); //TODO var split = key.split('::'); if (split.length == 2) { var walletId = split[0]; @@ -201,20 +193,17 @@ Storage.prototype.getWallets = function(cb) { var self = this; this.getWalletIds(function(ids) { -console.log('[Storage.js.197:ids:]',ids); //TODO var l = ids.length, i=0; if (!l) return cb([]); for (var ii in ids) { var id = ids[ii]; -console.log('[Storage.js.206:id:]',id); //TODO self.getName(id, function(name) { wallets.push({ id: id, name: name, }); -console.log('[Storage.js.208:wallets:]',wallets); //TODO if (++i == l) { return cb(wallets); } diff --git a/js/services/walletFactory.js b/js/services/walletFactory.js index 7a6b96ea6..a592470d2 100644 --- a/js/services/walletFactory.js +++ b/js/services/walletFactory.js @@ -1,7 +1,5 @@ 'use strict'; angular.module('copayApp.services').factory('walletFactory', function(pluginManager){ - -console.log('[walletFactory.js.3]'); //TODO return new copay.WalletFactory(config, copay.version, pluginManager); }); diff --git a/plugins/LocalStorage.js b/plugins/LocalStorage.js index a811cfcf4..0035fc12b 100644 --- a/plugins/LocalStorage.js +++ b/plugins/LocalStorage.js @@ -5,7 +5,6 @@ function LocalStorage() { }; LocalStorage.prototype.init = function() { - console.log(' init LocalStorage'); //TODO }; diff --git a/views/home.html b/views/home.html index 972b2618c..7018435e9 100644 --- a/views/home.html +++ b/views/home.html @@ -1,5 +1,9 @@
-
+
+ + Retreiving information from storage... +
+
Copay
diff --git a/views/open.html b/views/open.html index 8cf125ff2..e7ca352a1 100644 --- a/views/open.html +++ b/views/open.html @@ -1,9 +1,13 @@
-
+
+ + Retreiving information from storage... +
+
Connecting...
-
+
Copay
From e0db19a40a787929a2ee5c214e336ba4f63bcf9b Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Thu, 4 Sep 2014 16:38:22 -0300 Subject: [PATCH 118/191] rebased --- js/models/Storage.js | 1 - 1 file changed, 1 deletion(-) diff --git a/js/models/Storage.js b/js/models/Storage.js index f4e19a350..b9cb9fa75 100644 --- a/js/models/Storage.js +++ b/js/models/Storage.js @@ -168,7 +168,6 @@ Storage.prototype.getWalletIds = function(cb) { var uniq = {}; this.storage.allKeys(function(keys) { - for (var ii in keys) { var key = keys[ii]; var split = key.split('::'); From b3ed2a2ea82a174dbd5e3997423585b956333387 Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Thu, 4 Sep 2014 18:07:09 -0300 Subject: [PATCH 119/191] start fixing tests --- js/models/Storage.js | 18 +++++- js/models/core/WalletLock.js | 1 - test/mocks/FakeLocalStorage.js | 17 +++--- test/test.Storage.js | 105 +++++++++++++++++++++------------ 4 files changed, 89 insertions(+), 52 deletions(-) diff --git a/js/models/Storage.js b/js/models/Storage.js index b9cb9fa75..4d24928f7 100644 --- a/js/models/Storage.js +++ b/js/models/Storage.js @@ -3,6 +3,8 @@ var preconditions = require('preconditions').singleton(); var CryptoJS = require('node-cryptojs-aes').CryptoJS; var bitcore = require('bitcore'); var preconditions = require('preconditions').instance(); +var _ = require('underscore'); + var id = 0; function Storage(opts) { @@ -19,14 +21,14 @@ function Storage(opts) { console.log('Error in storage:', e); //TODO }; - preconditions.checkState(this.localStorage, 'No localstorage found'); - preconditions.checkState(this.sessionStorage, 'No sessionStorage found'); + preconditions.checkState(this.storage, 'No storage defined'); + preconditions.checkState(this.sessionStorage, 'No sessionStorage defined'); } var pps = {}; Storage.prototype._getPassphrase = function() { if (!pps[this.__uniqueid]) - throw new Error('No passprase set'); + throw new Error('NOPASSPHRASE: No passphrase set'); return pps[this.__uniqueid]; } @@ -147,23 +149,29 @@ console.log('[Storage.js.142:keys:]',keys); //TODO // set value for key Storage.prototype.set = function(walletId, k, v, cb) { + preconditions.checkArgument(walletId && k && !_.isUndefined(v) && cb); + this._write(this._key(walletId, k), v, cb); }; // remove value for key Storage.prototype.remove = function(walletId, k, cb) { + preconditions.checkArgument(walletId && k && cb); this.removeGlobal(this._key(walletId, k), cb); }; Storage.prototype.setName = function(walletId, name, cb) { + preconditions.checkArgument(walletId && name && cb); this.setGlobal('nameFor::' + walletId, name, cb); }; Storage.prototype.getName = function(walletId, cb) { + preconditions.checkArgument(walletId && cb); this.getGlobal('nameFor::' + walletId, cb); }; Storage.prototype.getWalletIds = function(cb) { + preconditions.checkArgument(cb); var walletIds = []; var uniq = {}; @@ -188,6 +196,8 @@ Storage.prototype.getWalletIds = function(cb) { }; Storage.prototype.getWallets = function(cb) { + preconditions.checkArgument(cb); + var wallets = []; var self = this; @@ -212,6 +222,8 @@ Storage.prototype.getWallets = function(cb) { }; Storage.prototype.deleteWallet = function(walletId) { + preconditions.checkArgument(walletId); + var toDelete = {}; toDelete['nameFor::' + walletId] = 1; diff --git a/js/models/core/WalletLock.js b/js/models/core/WalletLock.js index a8a1729b7..66e2458d2 100644 --- a/js/models/core/WalletLock.js +++ b/js/models/core/WalletLock.js @@ -20,7 +20,6 @@ WalletLock._keyFor = function(walletId) { WalletLock.prototype._isLockedByOther = function(cb) { var self = this; - console.log('[WalletLock.js.22]'); //TODO this.storage.getGlobal(this.key, function(json) { var wl = json ? JSON.parse(json) : null; var t = wl ? (Date.now() - wl.expireTs) : false; diff --git a/test/mocks/FakeLocalStorage.js b/test/mocks/FakeLocalStorage.js index e39280719..a276abaec 100644 --- a/test/mocks/FakeLocalStorage.js +++ b/test/mocks/FakeLocalStorage.js @@ -1,27 +1,26 @@ //localstorage Mock ls = {}; -function LocalStorage(opts) {} +function LocalStorage(opts) { +} FakeLocalStorage = {}; FakeLocalStorage.length = 0; FakeLocalStorage.removeItem = function(key) { delete ls[key]; - this.length = Object.keys(ls).length; }; -FakeLocalStorage.getItem = function(k) { - return ls[k]; +FakeLocalStorage.getItem = function(k,cb) { + return cb(ls[k]); }; -FakeLocalStorage.key = function(i) { - return Object.keys(ls)[i]; +FakeLocalStorage.allKeys = function(cb) { + return cb(Object.keys(ls)); }; -FakeLocalStorage.setItem = function(k, v) { +FakeLocalStorage.setItem = function(k, v,cb) { ls[k] = v; - this.key[this.length] = k; - this.length = Object.keys(ls).length; + return cb(); }; module.exports = FakeLocalStorage; diff --git a/test/test.Storage.js b/test/test.Storage.js index 0ad668bff..fd03c8cee 100644 --- a/test/test.Storage.js +++ b/test/test.Storage.js @@ -26,22 +26,29 @@ describe('Storage model', function() { should.exist(s2); }); it('should fail when encrypting without a password', function() { + var s2 = new Storage({ storage: localMock, sessionStorage: sessionMock, }); (function() { - s2.set(fakeWallet, timeStamp, 1); - }).should.throw(); + s2.set(fakeWallet, timeStamp, 1, function() {}); + }).should.throw('NOPASSPHRASE'); }); - it('should be able to encrypt and decrypt', function() { - s._write(fakeWallet + timeStamp, 'value'); - s._read(fakeWallet + timeStamp).should.equal('value'); - localMock.removeItem(fakeWallet + timeStamp); + it('should be able to encrypt and decrypt', function(done) { + s._write(fakeWallet + timeStamp, 'value', function() { + s._read(fakeWallet + timeStamp, function(v) { + v.should.equal('value'); + localMock.removeItem(fakeWallet + timeStamp); + done(); + }); + }); }); - it('should be able to set a value', function() { - s.set(fakeWallet, timeStamp, 1); - localMock.removeItem(fakeWallet + '::' + timeStamp); + it('should be able to set a value', function(done) { + s.set(fakeWallet, timeStamp, 1, function() { + localMock.removeItem(fakeWallet + '::' + timeStamp); + done(); + }); }); var getSetData = [ 1, 1000, -15, -1000, @@ -62,81 +69,101 @@ describe('Storage model', function() { ]; getSetData.forEach(function(obj) { it('should be able to set a value and get it for ' + JSON.stringify(obj), function() { - s.set(fakeWallet, timeStamp, obj); - var obj2 = s.get(fakeWallet, timeStamp); - JSON.stringify(obj2).should.equal(JSON.stringify(obj)); - localMock.removeItem(fakeWallet + '::' + timeStamp); + s.set(fakeWallet, timeStamp, obj, function() { + s.get(fakeWallet, timeStamp, function(obj2) { + JSON.stringify(obj2).should.equal(JSON.stringify(obj)); + localMock.removeItem(fakeWallet + '::' + timeStamp); + }); + }); }); }); describe('#export', function() { - it('should export the encrypted wallet', function() { + it('should export the encrypted wallet', function(done) { var storage = new Storage({ storage: localMock, sessionStorage: sessionMock, password: 'password', }); - storage.set(fakeWallet, timeStamp, 'testval'); - var obj = { - test: 'testval' - }; - var encrypted = storage.export(obj); - encrypted.length.should.be.greaterThan(10); - localMock.removeItem(fakeWallet + '::' + timeStamp); - //encrypted.slice(0,6).should.equal("53616c"); + storage.set(fakeWallet, timeStamp, 'testval', function() { + var obj = { + test: 'testval' + }; + var encrypted = storage.export(obj); + encrypted.length.should.be.greaterThan(10); + localMock.removeItem(fakeWallet + '::' + timeStamp); + done(); + + }); }); }); - describe('#remove', function() { + describe('#remove', function(done) { it('should remove an item', function() { var s = new Storage({ storage: localMock, sessionStorage: sessionMock, password: 'password' }); - s.set('1', "hola", 'juan'); - s.get('1', 'hola').should.equal('juan'); - s.remove('1', 'hola'); - - should.not.exist(s.get('1', 'hola')); + s.set('1', "hola", 'juan', function() { + s.get('1', 'hola', function(v) { + v.should.equal('juan'); + s.remove('1', 'hola', function() { + should.not.exist(s.get('1', 'hola')); + done(); + }); + }) + }) }); }); describe('#getWalletIds', function() { - it('should get wallet ids', function() { + it('should get wallet ids', function(done) { var s = new Storage({ storage: localMock, sessionStorage: sessionMock, password: 'password' }); - s.set('1', "hola", 'juan'); - s.set('2', "hola", 'juan'); - s.getWalletIds().should.deep.equal(['1', '2']); + s.set('1', "hola", 'juan', function() { + s.set('2', "hola", 'juan', function() { + s.getWalletIds(function(v) { + v.should.deep.equal(['1', '2']); + done(); + }); + }); + }); }); }); describe('#getName #setName', function() { - it('should get/set names', function() { + it('should get/set names', function(done) { var s = new Storage({ storage: localMock, sessionStorage: sessionMock, password: 'password' }); - s.setName(1, 'hola'); - s.getName(1).should.equal('hola'); + s.setName(1, 'hola', function() { + s.getName(1, function(v) { + v.should.equal('hola'); + done(); + }); + }); }); }); describe('#getLastOpened #setLastOpened', function() { - it('should get/set names', function() { + it('should get/set last opened', function() { var s = new Storage({ storage: localMock, sessionStorage: sessionMock, password: 'password' }); - s.setLastOpened('hey'); - s.getLastOpened().should.equal('hey'); + s.setLastOpened('hey', function() { + s.getLastOpened(function(v) { + v.should.equal('hey'); + }); + }); }); }); @@ -243,7 +270,7 @@ describe('Storage model', function() { password: 'password' }); s.getSessionId().length.should.equal(16); - (new Buffer(s.getSessionId(),'hex')).length.should.equal(8); + (new Buffer(s.getSessionId(), 'hex')).length.should.equal(8); }); }); }); From f1e6d6cfc6d0c973afd8afbadfbb2774e7981968 Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Mon, 8 Sep 2014 10:46:57 -0300 Subject: [PATCH 120/191] fix walletLock test --- js/models/Storage.js | 58 ++++++++------ js/models/core/WalletFactory.js | 5 ++ js/models/core/WalletLock.js | 51 ++++++++++--- test/mocks/FakeLocalStorage.js | 3 +- test/mocks/FakeStorage.js | 62 ++++++++------- test/test.Storage.js | 130 +++++++++++++++++++------------- test/test.WalletFactory.js | 17 +++-- test/test.WalletLock.js | 102 ++++++++++++++++--------- 8 files changed, 272 insertions(+), 156 deletions(-) diff --git a/js/models/Storage.js b/js/models/Storage.js index 4d24928f7..4d842e431 100644 --- a/js/models/Storage.js +++ b/js/models/Storage.js @@ -99,17 +99,22 @@ Storage.prototype.setGlobal = function(k, v, cb) { // remove value for key Storage.prototype.removeGlobal = function(k, cb) { preconditions.checkArgument(cb); - this.storage.removeItem(k, cb); }; -Storage.prototype.getSessionId = function() { - var sessionId = this.sessionStorage.getItem('sessionId'); - if (!sessionId) { +Storage.prototype.getSessionId = function(cb) { + preconditions.checkArgument(cb); + var self = this; + + self.sessionStorage.getItem('sessionId', function(sessionId) { + if (sessionId) + return cb(sessionId); + sessionId = bitcore.SecureRandom.getRandomBuffer(8).toString('hex'); - this.sessionStorage.setItem('sessionId', sessionId); - } - return sessionId; + self.sessionStorage.setItem('sessionId', sessionId, function(){ + return cb(sessionId); + }); + }); }; Storage.prototype._key = function(walletId, k) { @@ -117,14 +122,15 @@ Storage.prototype._key = function(walletId, k) { }; // get value by key Storage.prototype.get = function(walletId, k, cb) { + preconditions.checkArgument(walletId, k, cb); this._read(this._key(walletId, k), cb); }; Storage.prototype._readHelper = function(walletId, k, cb) { var wk = this._key(walletId, k); - this._read(wk, function(v){ - return cb(v,k); + this._read(wk, function(v) { + return cb(v, k); }); }; @@ -133,15 +139,15 @@ Storage.prototype.getMany = function(walletId, keys, cb) { var self = this; var ret = {}; -console.log('[Storage.js.142:keys:]',keys); //TODO - var l = keys.length, i=0; + var l = keys.length, + i = 0; for (var ii in keys) { this._readHelper(walletId, keys[ii], function(v, k) { ret[k] = v; if (++i == l) { - return cb(ret); + return cb(ret); } }); } @@ -202,7 +208,8 @@ Storage.prototype.getWallets = function(cb) { var self = this; this.getWalletIds(function(ids) { - var l = ids.length, i=0; + var l = ids.length, + i = 0; if (!l) return cb([]); @@ -221,21 +228,29 @@ Storage.prototype.getWallets = function(cb) { }); }; -Storage.prototype.deleteWallet = function(walletId) { +Storage.prototype.deleteWallet = function(walletId, cb) { preconditions.checkArgument(walletId); + preconditions.checkArgument(cb); var toDelete = {}; toDelete['nameFor::' + walletId] = 1; - for (var i = 0; i < this.storage.length; i++) { - var key = this.storage.key(i); - var split = key.split('::'); - if (split.length == 2 && split[0] === walletId) { - toDelete[key] = 1; + this.storage.allKeys(function(allKeys) { + for (var key in allKeys) { + var split = key.split('::'); + if (split.length == 2 && split[0] === walletId) { + toDelete[key] = 1; + }; } - } + }); + + var l = toDelete.length, + i = 0; for (var i in toDelete) { - this.removeGlobal(i); + this.removeGlobal(i, function() { + if (++i == l) + return cb(); + }); } }; @@ -255,7 +270,6 @@ Storage.prototype.setFromObj = function(walletId, obj, cb) { var l = Object.keys(obj).length, i = 0; for (var k in obj) { - console.log('[Storage.js.247]', k, i, l); //TODO self.set(walletId, k, obj[k], function() { if (++i == l) { self.setName(walletId, obj.opts.name, cb); diff --git a/js/models/core/WalletFactory.js b/js/models/core/WalletFactory.js index 18d5ed063..eb0c432af 100644 --- a/js/models/core/WalletFactory.js +++ b/js/models/core/WalletFactory.js @@ -182,6 +182,8 @@ WalletFactory.prototype.read = function(walletId, skipFields, cb) { * @return {Wallet} */ WalletFactory.prototype.create = function(opts, cb) { + preconditions.checkArgument(cb); + opts = opts || {}; opts.networkName = opts.networkName || 'testnet'; @@ -229,6 +231,7 @@ WalletFactory.prototype.create = function(opts, cb) { opts.totalCopayers = totalCopayers; opts.version = opts.version || this.version; +console.log('[WalletFactory.js.165]'); //TODO var w = new Wallet(opts); var self = this; w.store(function() { @@ -266,6 +269,7 @@ WalletFactory.prototype._checkVersion = function(inVersion) { * @return */ WalletFactory.prototype.open = function(walletId, passphrase, cb) { + preconditions.checkArgument(cb); var self = this, err; self.storage._setPassphrase(passphrase); @@ -334,6 +338,7 @@ WalletFactory.prototype.decodeSecret = function(secret) { * @param {walletCreationCallback} cb - a callback */ WalletFactory.prototype.joinCreateSession = function(secret, nickname, passphrase, privateHex, cb) { + preconditions.checkArgument(cb); var self = this; var decodedSecret = this.decodeSecret(secret); if (!decodedSecret || !decodedSecret.networkName || !decodedSecret.pubKey) { diff --git a/js/models/core/WalletLock.js b/js/models/core/WalletLock.js index 66e2458d2..fa449b855 100644 --- a/js/models/core/WalletLock.js +++ b/js/models/core/WalletLock.js @@ -6,13 +6,24 @@ function WalletLock(storage, walletId, timeoutMin) { preconditions.checkArgument(storage); preconditions.checkArgument(walletId); - this.sessionId = storage.getSessionId(); this.storage = storage; this.timeoutMin = timeoutMin || 5; this.key = WalletLock._keyFor(walletId); - // this._setLock(function() {}); } + +WalletLock.prototype.init = function(cb) { + preconditions.checkArgument(cb); + var self = this; + + self.storage.getSessionId(function(sid) { + preconditions.checkState(sid); + + self.sessionId = sid; + cb(); + }); +}; + WalletLock._keyFor = function(walletId) { return 'lock' + '::' + walletId; }; @@ -22,18 +33,27 @@ WalletLock.prototype._isLockedByOther = function(cb) { this.storage.getGlobal(this.key, function(json) { var wl = json ? JSON.parse(json) : null; - var t = wl ? (Date.now() - wl.expireTs) : false; - // is not locked? - if (!wl || t > 0 || wl.sessionId === self.sessionId) + if (!wl || !wl.expireTs) + return cb(false); + + var expiredSince = Date.now() - wl.expireTs; + if (expiredSince >= 0) + return cb(false); + + var isMyself = wl.sessionId === self.sessionId; + + if (isMyself) return cb(false); // Seconds remainding - return cb(parseInt(-t / 1000.)); + return cb(parseInt(-expiredSince / 1000)); }); }; WalletLock.prototype._setLock = function(cb) { + preconditions.checkArgument(cb); + preconditions.checkState(this.sessionId); this.storage.setGlobal(this.key, { sessionId: this.sessionId, @@ -44,20 +64,33 @@ WalletLock.prototype._setLock = function(cb) { }; -WalletLock.prototype.keepAlive = function(cb) { +WalletLock.prototype._doKeepAlive = function(cb) { + preconditions.checkArgument(cb); preconditions.checkState(this.sessionId); + var self = this; this._isLockedByOther(function(t) { - if (t) - return cb(new Error('Wallet is already open. Close it to proceed or wait ' + t + ' seconds if you close it already')); + return cb(new Error('LOCKED: Wallet is locked for ' + t + ' srcs')); self._setLock(cb); }); }; + +WalletLock.prototype.keepAlive = function(cb) { + var self = this; + + if (!self.sessionId) { + return self.init(self._doKeepAlive.bind(self, cb)); + }; + + return this._doKeepAlive(cb); +}; + + WalletLock.prototype.release = function(cb) { this.storage.removeGlobal(this.key, cb); }; diff --git a/test/mocks/FakeLocalStorage.js b/test/mocks/FakeLocalStorage.js index a276abaec..fba5e7dfd 100644 --- a/test/mocks/FakeLocalStorage.js +++ b/test/mocks/FakeLocalStorage.js @@ -5,8 +5,9 @@ function LocalStorage(opts) { FakeLocalStorage = {}; FakeLocalStorage.length = 0; -FakeLocalStorage.removeItem = function(key) { +FakeLocalStorage.removeItem = function(key,cb) { delete ls[key]; + cb(); }; FakeLocalStorage.getItem = function(k,cb) { diff --git a/test/mocks/FakeStorage.js b/test/mocks/FakeStorage.js index 9aea4d2ea..39a4b2ade 100644 --- a/test/mocks/FakeStorage.js +++ b/test/mocks/FakeStorage.js @@ -11,57 +11,65 @@ FakeStorage.prototype._setPassphrase = function(password) { this.storage.passphrase = password; }; -FakeStorage.prototype.setGlobal = function(id, v) { +FakeStorage.prototype.setGlobal = function(id, v, cb) { this.storage[id] = typeof v === 'object' ? JSON.stringify(v) : v; + cb(); }; -FakeStorage.prototype.getGlobal = function(id) { - return this.storage[id]; +FakeStorage.prototype.getGlobal = function(id, cb) { + return cb(this.storage[id]); }; -FakeStorage.prototype.setLastOpened = function(val) { +FakeStorage.prototype.setLastOpened = function(val, cb) { this.storage['lastOpened'] = val; + return cb(); }; -FakeStorage.prototype.getLastOpened = function() { - return this.storage['lastOpened']; +FakeStorage.prototype.getLastOpened = function(cb) { + return cb(this.storage['lastOpened']); }; FakeStorage.prototype.setLock = function(id) { this.storage[id + '::lock'] = true; + return cb(); } -FakeStorage.prototype.getLock = function(id) { - return this.storage[id + '::lock']; +FakeStorage.prototype.getLock = function(id,cb) { + return cb(this.storage[id + '::lock']); } -FakeStorage.prototype.getSessionId = function() { - return this.sessionId || 'aSessionId'; +FakeStorage.prototype.getSessionId = function(cb) { + this.sessionId = this.sessionId || 'aSessionId'; + return cb(this.sessionId); }; -FakeStorage.prototype.removeLock = function(id) { +FakeStorage.prototype.removeLock = function(id,cb) { delete this.storage[id + '::lock']; + cb(); } -FakeStorage.prototype.removeGlobal = function(id) { +FakeStorage.prototype.removeGlobal = function(id,cb) { delete this.storage[id]; + cb(); }; -FakeStorage.prototype.set = function(wid, id, payload) { +FakeStorage.prototype.set = function(wid, id, payload, cb) { this.storage[wid + '::' + id] = payload; + if (cb) return cb(); }; -FakeStorage.prototype.get = function(wid, id) { - return this.storage[wid + '::' + id]; +FakeStorage.prototype.get = function(wid, id, cb) { + return cb(this.storage[wid + '::' + id]); }; -FakeStorage.prototype.clear = function() { +FakeStorage.prototype.clear = function(cb) { delete this['storage']; + cb(); }; -FakeStorage.prototype.getWalletIds = function() { +FakeStorage.prototype.getWalletIds = function(cb) { var walletIds = []; var uniq = {}; @@ -79,10 +87,10 @@ FakeStorage.prototype.getWalletIds = function() { } } } - return walletIds; + return cb(walletIds); }; -FakeStorage.prototype.deleteWallet = function(walletId) { +FakeStorage.prototype.deleteWallet = function(walletId, cb) { var toDelete = {}; toDelete['nameFor::' + walletId] = 1; @@ -98,17 +106,17 @@ FakeStorage.prototype.deleteWallet = function(walletId) { }; -FakeStorage.prototype.getName = function(walletId) { - return this.getGlobal('nameFor::' + walletId); +FakeStorage.prototype.getName = function(walletId,cb) { + return this.getGlobal('nameFor::' + walletId,cb); }; -FakeStorage.prototype.setName = function(walletId, name) { - this.setGlobal('nameFor::' + walletId, name); +FakeStorage.prototype.setName = function(walletId, name, cb) { + this.setGlobal('nameFor::' + walletId, name, cb); }; -FakeStorage.prototype.getWallets = function() { +FakeStorage.prototype.getWallets = function(cb) { var wallets = []; var ids = this.getWalletIds(); @@ -118,14 +126,14 @@ FakeStorage.prototype.getWallets = function() { name: this.getName(ids[i]), }); } - return wallets; + return cb(wallets); }; -FakeStorage.prototype.setFromObj = function(walletId, obj) { +FakeStorage.prototype.setFromObj = function(walletId, obj, cb) { for (var k in obj) { this.set(walletId, k, obj[k]); } - this.setName(walletId, obj.opts.name); + this.setName(walletId, obj.opts.name, cb); }; module.exports = FakeStorage; diff --git a/test/test.Storage.js b/test/test.Storage.js index fd03c8cee..0363108ab 100644 --- a/test/test.Storage.js +++ b/test/test.Storage.js @@ -39,15 +39,13 @@ describe('Storage model', function() { s._write(fakeWallet + timeStamp, 'value', function() { s._read(fakeWallet + timeStamp, function(v) { v.should.equal('value'); - localMock.removeItem(fakeWallet + timeStamp); - done(); + localMock.removeItem(fakeWallet + timeStamp, done); }); }); }); it('should be able to set a value', function(done) { s.set(fakeWallet, timeStamp, 1, function() { - localMock.removeItem(fakeWallet + '::' + timeStamp); - done(); + localMock.removeItem(fakeWallet + '::' + timeStamp, done); }); }); var getSetData = [ @@ -68,11 +66,11 @@ describe('Storage model', function() { null ]; getSetData.forEach(function(obj) { - it('should be able to set a value and get it for ' + JSON.stringify(obj), function() { + it('should be able to set a value and get it for ' + JSON.stringify(obj), function(done) { s.set(fakeWallet, timeStamp, obj, function() { s.get(fakeWallet, timeStamp, function(obj2) { JSON.stringify(obj2).should.equal(JSON.stringify(obj)); - localMock.removeItem(fakeWallet + '::' + timeStamp); + localMock.removeItem(fakeWallet + '::' + timeStamp, done); }); }); }); @@ -91,15 +89,13 @@ describe('Storage model', function() { }; var encrypted = storage.export(obj); encrypted.length.should.be.greaterThan(10); - localMock.removeItem(fakeWallet + '::' + timeStamp); - done(); - + localMock.removeItem(fakeWallet + '::' + timeStamp, done); }); }); }); - describe('#remove', function(done) { - it('should remove an item', function() { + describe('#remove', function() { + it('should remove an item', function(done) { var s = new Storage({ storage: localMock, sessionStorage: sessionMock, @@ -109,8 +105,10 @@ describe('Storage model', function() { s.get('1', 'hola', function(v) { v.should.equal('juan'); s.remove('1', 'hola', function() { - should.not.exist(s.get('1', 'hola')); - done(); + s.get('1', 'hola', function(v) { + should.not.exist(v); + done(); + }); }); }) }) @@ -169,62 +167,75 @@ describe('Storage model', function() { if (is_browser) { describe('#getSessionId', function() { - it('should get SessionId', function() { + it('should get SessionId', function(done) { var s = new Storage({ storage: localMock, sessionStorage: sessionMock, password: 'password' }); - var sid = s.getSessionId(); - should.exist(sid); - var sid2 = s.getSessionId(); - sid2.should.equal(sid); + s.getSessionId(function(sid) { + should.exist(sid); + s.getSessionId(function(sid2) { + sid2.should.equal(sid); + done(); + }); + }); }); }); } describe('#getWallets', function() { - it('should retreive wallets from storage', function() { + it('should retreive wallets from storage', function(done) { var s = new Storage({ storage: localMock, sessionStorage: sessionMock, password: 'password' }); - s.set('1', "hola", 'juan'); - s.set('2', "hola", 'juan'); - s.setName(1, 'hola'); - s.getWallets()[0].should.deep.equal({ - id: '1', - name: 'hola', - }); - s.getWallets()[1].should.deep.equal({ - id: '2', - name: undefined + s.set('1', "hola", 'juan', function() { + s.set('2', "hola", 'juan', function() { + s.setName(1, 'hola', function() { + s.getWallets(function(ws) { + ws[0].should.deep.equal({ + id: '1', + name: 'hola', + }); + ws[1].should.deep.equal({ + id: '2', + name: undefined + }); + done(); + }); + }); + }); }); }); }); - describe('#deleteWallet', function() { + describe('#deleteWallet', function(done) { it('should delete a wallet', function() { var s = new Storage({ storage: localMock, sessionStorage: sessionMock, password: 'password' }); - s.set('1', "hola", 'juan'); - s.set('2', "hola", 'juan'); - s.setName(1, 'hola'); - - s.deleteWallet('1'); - s.getWallets().length.should.equal(1); - s.getWallets()[0].should.deep.equal({ - id: '2', - name: undefined + s.set('1', "hola", 'juan', function() { + s.set('2', "hola", 'juan', function() { + s.deleteWallet('1', function() { + s.getWallets(function(ws) { + s.getWallets().length.should.equal(1); + ws[0].should.deep.equal({ + id: '2', + name: undefined + }); + done(); + }); + }); + }); }); }); }); describe('#setFromObj', function() { - it('set localstorage from an object', function() { + it('set localstorage from an object', function(done) { var s = new Storage({ storage: localMock, sessionStorage: sessionMock, @@ -235,42 +246,57 @@ describe('Storage model', function() { 'opts': { 'name': 'nameid1' }, + }, function() { + s.get('id1', 'key', function(v) { + v.should.equal('val'); + done(); + }); }); - - s.get('id1', 'key').should.equal('val'); - }); }); describe('#globals', function() { - it('should set, get and remove keys', function() { + it('should set, get and remove keys', function(done) { var s = new Storage({ storage: localMock, sessionStorage: sessionMock, password: 'password' }); + s.setGlobal('a', { b: 1 + }, function() { + s.getGlobal('a', function(v) { + + JSON.parse(v).should.deep.equal({ + b: 1 + }); + s.removeGlobal('a', function() { + s.getGlobal('a', function(v) { + should.not.exist(v); + done(); + }); + }); + }); }); - JSON.parse(s.getGlobal('a')).should.deep.equal({ - b: 1 - }); - s.removeGlobal('a'); - should.not.exist(s.getGlobal('a')); }); }); describe('session storage', function() { - it('should get a session ID', function() { + it('should get a session ID', function(done) { var s = new Storage({ storage: localMock, sessionStorage: sessionMock, password: 'password' }); - s.getSessionId().length.should.equal(16); - (new Buffer(s.getSessionId(), 'hex')).length.should.equal(8); + s.getSessionId(function(s) { + should.exist(s); + s.length.should.equal(16); + (new Buffer(s, 'hex')).length.should.equal(8); + done(); + }); }); }); }); diff --git a/test/test.WalletFactory.js b/test/test.WalletFactory.js index 8712c4121..f736c339f 100644 --- a/test/test.WalletFactory.js +++ b/test/test.WalletFactory.js @@ -117,16 +117,17 @@ describe('WalletFactory model', function() { wf.version.should.equal('0.0.1'); }); - it('#_checkRead should return false', function() { - var wf = new WalletFactory(config); - wf._checkRead('dummy').should.equal(false); - wf.read('dummy').should.equal(false); - }); - it('should be able to create wallets', function() { + it('should be able to create wallets', function(done) { var wf = new WalletFactory(config, '0.0.1'); - var w = wf.create(); - should.exist(w); + wf.create(null, function(err, w) { + +console.log('[test.WalletFactory.js.123]'); //TODO + should.not.exist(err); + should.exist(w); + w.should.be.instanceof('WalletFactory'); + done(); + }); }); it('should be able to create wallets with given pk', function() { diff --git a/test/test.WalletLock.js b/test/test.WalletLock.js index f3ccf051d..e8e418a96 100644 --- a/test/test.WalletLock.js +++ b/test/test.WalletLock.js @@ -15,8 +15,11 @@ var WalletLock = copay.WalletLock; var PrivateKey = copay.PrivateKey; var Storage = require('./mocks/FakeStorage'); +var storage; describe('WalletLock model', function() { - var storage = new Storage(); + beforeEach(function() { + storage = new Storage(); + }); it('should fail with missing args', function() { (function() { @@ -36,45 +39,70 @@ describe('WalletLock model', function() { should.exist(w); }); - it('should NOT fail if locked already', function() { - var w = new WalletLock(storage, 'walletId'); - storage.sessionId = 'xxx'; - var w2= new WalletLock(storage, 'walletId'); - should.exist(w2); + + it('should generate a sessionId with init', function(done) { + var w = new WalletLock(storage, 'id'); + var spy = sinon.spy(storage, 'getSessionId'); + w.init(function() { + spy.calledOnce.should.equal(true); + done(); + }); }); - it('should change status of previously openned wallet', function() { + it('#keepAlive should call getsessionId if not called before', function(done) { + var w = new WalletLock(storage, 'id'); + var spy = sinon.spy(storage, 'getSessionId'); + w.keepAlive(function() { + spy.calledOnce.should.equal(true); + done(); + }); + }); + + it('should NOT fail if locked already by me', function(done) { + var w = new WalletLock(storage, 'walletId2'); + w.keepAlive(function() { + var w2 = new WalletLock(storage, 'walletId2'); + w2.init(function() { + w2.keepAlive(function() { + w.sessionId.should.equal(w2.sessionId); + should.exist(w2); + done(); + }); + }); + }) + }); + + it('should FAIL if locked by someone else', function(done) { storage.sessionId = 'session1'; var w = new WalletLock(storage, 'walletId'); - storage.sessionId = 'xxx'; - var w2= new WalletLock(storage, 'walletId'); - w2.keepAlive(); - (function() {w.keepAlive();}).should.throw('already open'); - - }); - - - it('should not fail if locked by me', function() { - var s = new Storage(); - var w = new WalletLock(s, 'walletId'); - var w2 = new WalletLock(s, 'walletId') - w2.keepAlive(); - should.exist(w2); - }); - - it('should not fail if expired', function() { - var s = new Storage(); - var w = new WalletLock(s, 'walletId'); - var k = Object.keys(s.storage)[0]; - var v = JSON.parse(s.storage[k]); - v.expireTs = Date.now() - 60 * 6 * 1000; - s.storage[k] = JSON.stringify(v); - - s.sessionId = 'xxx'; - var w2 = new WalletLock(s, 'walletId') - should.exist(w2); - }); - - + w.keepAlive(function() { + storage.sessionId = 'session2'; + var w2 = new WalletLock(storage, 'walletId'); + w2.keepAlive(function(locked) { + w2.sessionId.should.equal('session2'); + should.exist(locked); + locked.message.should.contain('LOCKED'); + done(); + }); + }); + }) + it('should FAIL if locked by someone else but expired', function(done) { + storage.sessionId = 'session1'; + var w = new WalletLock(storage, 'walletId'); + w.keepAlive(function() { + storage.sessionId = 'session2'; + var json = JSON.parse(storage.storage['lock::walletId']); + json.expireTs -= 3600 * 1000; + storage.storage['lock::walletId'] = JSON.stringify(json); + var w2 = new WalletLock(storage, 'walletId'); + w2.keepAlive(function(locked) { + w2.sessionId.should.equal('session2'); + should.not.exist(locked); + done(); + }); + }); + }) }); + + From f48898033fd840fe238ee09230afbf5cf2860362 Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Mon, 8 Sep 2014 14:24:57 -0300 Subject: [PATCH 121/191] more tests fixes --- js/models/core/WalletFactory.js | 3 ++- test/mocks/FakeStorage.js | 25 +++++++++++++----- test/test.WalletFactory.js | 45 ++++++++++++++++++--------------- 3 files changed, 46 insertions(+), 27 deletions(-) diff --git a/js/models/core/WalletFactory.js b/js/models/core/WalletFactory.js index eb0c432af..4ba0ed31a 100644 --- a/js/models/core/WalletFactory.js +++ b/js/models/core/WalletFactory.js @@ -91,6 +91,8 @@ WalletFactory.prototype.fromObj = function(obj, skipFields) { preconditions.checkArgument(obj); + // not stored options + obj.opts = obj.opts || {}; obj.opts.reconnectDelay = this.walletDefaults.reconnectDelay; // this is only used if private key or public key ring is skipped @@ -231,7 +233,6 @@ WalletFactory.prototype.create = function(opts, cb) { opts.totalCopayers = totalCopayers; opts.version = opts.version || this.version; -console.log('[WalletFactory.js.165]'); //TODO var w = new Wallet(opts); var self = this; w.store(function() { diff --git a/test/mocks/FakeStorage.js b/test/mocks/FakeStorage.js index 39a4b2ade..ef8b33b3c 100644 --- a/test/mocks/FakeStorage.js +++ b/test/mocks/FakeStorage.js @@ -20,6 +20,19 @@ FakeStorage.prototype.getGlobal = function(id, cb) { return cb(this.storage[id]); }; +FakeStorage.prototype.getMany = function(wid, fields, cb) { + var self= this; + var ret = []; + for(var ii in fields){ + var k = fields[ii]; + ret[k] = this.storage[wid + '::' + k]; + } + + return cb(ret); +}; + + + FakeStorage.prototype.setLastOpened = function(val, cb) { this.storage['lastOpened'] = val; return cb(); @@ -34,7 +47,7 @@ FakeStorage.prototype.setLock = function(id) { return cb(); } -FakeStorage.prototype.getLock = function(id,cb) { +FakeStorage.prototype.getLock = function(id, cb) { return cb(this.storage[id + '::lock']); } @@ -44,12 +57,12 @@ FakeStorage.prototype.getSessionId = function(cb) { }; -FakeStorage.prototype.removeLock = function(id,cb) { +FakeStorage.prototype.removeLock = function(id, cb) { delete this.storage[id + '::lock']; cb(); } -FakeStorage.prototype.removeGlobal = function(id,cb) { +FakeStorage.prototype.removeGlobal = function(id, cb) { delete this.storage[id]; cb(); }; @@ -78,7 +91,7 @@ FakeStorage.prototype.getWalletIds = function(cb) { if (split.length == 2) { var walletId = split[0]; - if (!walletId || walletId === 'nameFor' || walletId ==='lock') + if (!walletId || walletId === 'nameFor' || walletId === 'lock') continue; if (typeof uniq[walletId] === 'undefined') { @@ -106,8 +119,8 @@ FakeStorage.prototype.deleteWallet = function(walletId, cb) { }; -FakeStorage.prototype.getName = function(walletId,cb) { - return this.getGlobal('nameFor::' + walletId,cb); +FakeStorage.prototype.getName = function(walletId, cb) { + return this.getGlobal('nameFor::' + walletId, cb); }; diff --git a/test/test.WalletFactory.js b/test/test.WalletFactory.js index f736c339f..5148734cf 100644 --- a/test/test.WalletFactory.js +++ b/test/test.WalletFactory.js @@ -85,6 +85,7 @@ function assertObjectEqual(a, b, msg) { describe('WalletFactory model', function() { + var config = { Network: FakeNetwork, Blockchain: FakeBlockchain, @@ -121,42 +122,46 @@ describe('WalletFactory model', function() { it('should be able to create wallets', function(done) { var wf = new WalletFactory(config, '0.0.1'); wf.create(null, function(err, w) { - -console.log('[test.WalletFactory.js.123]'); //TODO - should.not.exist(err); should.exist(w); - w.should.be.instanceof('WalletFactory'); + should.not.exist(err); done(); }); }); - it('should be able to create wallets with given pk', function() { + it('should be able to create wallets with given pk', function(done) { var wf = new WalletFactory(config, '0.0.1'); var priv = 'tprv8ZgxMBicQKsPdEqHcA7RjJTayxA3gSSqeRTttS1JjVbgmNDZdSk9EHZK5pc52GY5xFmwcakmUeKWUDzGoMLGAhrfr5b3MovMUZUTPqisL2m'; - var w = wf.create({ + wf.create({ privateKeyHex: priv, + }, function(err, w) { + w.privateKey.toObj().extendedPrivateKeyString.should.equal(priv); + should.not.exist(err); + done(); }); - w.privateKey.toObj().extendedPrivateKeyString.should.equal(priv); }); - it('should be able to create wallets with random pk', function() { + it('should be able to create wallets with random pk', function(done) { var wf = new WalletFactory(config, '0.0.1'); - var priv = 'tprv8ZgxMBicQKsPdEqHcA7RjJTayxA3gSSqeRTttS1JjVbgmNDZdSk9EHZK5pc52GY5xFmwcakmUeKWUDzGoMLGAhrfr5b3MovMUZUTPqisL2m'; - var w1 = wf.create(); - var w2 = wf.create(); - w1.privateKey.toObj().extendedPrivateKeyString.should.not.equal( - w2.privateKey.toObj().extendedPrivateKeyString - ); + wf.create(null, function(err, w1) { + wf.create(null, function(err, w2) { + w1.privateKey.toObj().extendedPrivateKeyString.should.not.equal( + w2.privateKey.toObj().extendedPrivateKeyString + ); + done(); + }); + }); }); - it('should be able to get wallets', function() { + it.only('should be able to get wallets', function(done) { var wf = new WalletFactory(config, '0.0.1'); - var w = wf.create(); - - var w2 = wf.read(w.id); - should.exist(w2); - w2.id.should.equal(w.id); + wf.create(null, function(err,w){ + wf.read(w.id, [], function(err, w2){ + should.exist(w2); + w2.id.should.equal(w.id); + done(); + }); + }); }); From 9f30c9ade5c7d70669849f69bc083fc6ce966420 Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Mon, 8 Sep 2014 14:58:23 -0300 Subject: [PATCH 122/191] fix more tests en wallet f --- js/models/core/WalletFactory.js | 13 +++++++------ test/test.WalletFactory.js | 11 +++++++---- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/js/models/core/WalletFactory.js b/js/models/core/WalletFactory.js index 4ba0ed31a..eca5e656b 100644 --- a/js/models/core/WalletFactory.js +++ b/js/models/core/WalletFactory.js @@ -151,7 +151,7 @@ WalletFactory.prototype.import = function(base64, password, skipFields) { * @return {Wallet} */ WalletFactory.prototype.read = function(walletId, skipFields, cb) { - var self = this; + var self = this, err; var obj = {}; obj.id = walletId; @@ -159,7 +159,7 @@ WalletFactory.prototype.read = function(walletId, skipFields, cb) { for (var ii in ret) { obj[ii] = ret[ii]; } - return cb(self.fromObj(obj, skipFields)); + return cb(err, self.fromObj(obj, skipFields)); }); }; @@ -271,11 +271,12 @@ WalletFactory.prototype._checkVersion = function(inVersion) { */ WalletFactory.prototype.open = function(walletId, passphrase, cb) { preconditions.checkArgument(cb); - var self = this, - err; + var self = this; self.storage._setPassphrase(passphrase); - self.read(walletId, null, function(w) { - w.store(function() { + self.read(err, walletId, null, function(w) { + if (err) return cb(err); + + w.store(function(err) { self.storage.setLastOpened(walletId, function() { return cb(err, w); }); diff --git a/test/test.WalletFactory.js b/test/test.WalletFactory.js index 5148734cf..36c032b80 100644 --- a/test/test.WalletFactory.js +++ b/test/test.WalletFactory.js @@ -153,7 +153,7 @@ describe('WalletFactory model', function() { }); - it.only('should be able to get wallets', function(done) { + it('should be able to get wallets', function(done) { var wf = new WalletFactory(config, '0.0.1'); wf.create(null, function(err,w){ wf.read(w.id, [], function(err, w2){ @@ -273,7 +273,7 @@ describe('WalletFactory model', function() { }).should.throw(); }); - it('BIP32 length problem', function() { + it('BIP32 length problem', function(done) { var sconfig = { Network: FakeNetwork, Blockchain: FakeBlockchain, @@ -312,8 +312,11 @@ describe('WalletFactory model', function() { 'requiredCopayers': 2, 'totalCopayers': 3 }; - var w = wf.create(opts); - + wf.create(opts, function(err,w){ + should.not.exist(err); + should.exist(w); + done(); + }); }); it('should be able to get current wallets', function() { From 90e8231aca54fad93f78db63b173a7c67f775121 Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Fri, 12 Sep 2014 15:29:20 -0300 Subject: [PATCH 123/191] fix grunt file --- Gruntfile.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index 540a676b0..a63da775d 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -118,8 +118,8 @@ module.exports = function(grunt) { 'lib/ng-idle/angular-idle.min.js', 'lib/angular-foundation/mm-foundation.min.js', 'lib/angular-foundation/mm-foundation-tpls.min.js', - 'lib/angular-gettext/dist/angular-gettext.min.js' - 'lib/angular-load/angular-load.min.js', + 'lib/angular-gettext/dist/angular-gettext.min.js', + 'lib/angular-load/angular-load.min.js' ], dest: 'lib/angularjs-all.js' }, From c3574ae57ffbfde8daf45f46a2d58607a7a921be Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Sat, 13 Sep 2014 10:25:13 -0300 Subject: [PATCH 124/191] refactor WalletFactory test to use sinon instead of mocks WIP --- .gitignore | 3 + js/app.js | 2 - js/models/Storage.js | 15 ++- js/models/core/PluginManager.js | 3 +- js/models/core/Wallet.js | 2 +- js/models/core/WalletFactory.js | 45 +++++-- package.json | 13 +- test/mocks/FakeStorage.js | 36 +++-- test/test.WalletFactory.js | 232 +++++++++++++++++++++----------- 9 files changed, 230 insertions(+), 121 deletions(-) diff --git a/.gitignore b/.gitignore index f7555ecd4..8aa3d8515 100644 --- a/.gitignore +++ b/.gitignore @@ -77,5 +77,8 @@ dist/windows dist/*.dmg dist/*.tar.gz dist/*.exe +<<<<<<< HEAD doc/ +/node_modules +/*-cov diff --git a/js/app.js b/js/app.js index 216553f20..a9e3c39f0 100644 --- a/js/app.js +++ b/js/app.js @@ -21,8 +21,6 @@ if (localConfig) { var log = function() { if (config.verbose) console.log(arguments); } -var copayApp = window.copayApp = angular.module('copayApp', [ - var modules = [ 'ngRoute', diff --git a/js/models/Storage.js b/js/models/Storage.js index 4d842e431..5750eb428 100644 --- a/js/models/Storage.js +++ b/js/models/Storage.js @@ -12,7 +12,7 @@ function Storage(opts) { this.__uniqueid = ++id; if (opts.password) - this._setPassphrase(opts.password); + this.setPassphrase(opts.password); try { this.storage = opts.storage || localStorage; @@ -33,7 +33,7 @@ Storage.prototype._getPassphrase = function() { return pps[this.__uniqueid]; } -Storage.prototype._setPassphrase = function(password) { +Storage.prototype.setPassphrase = function(password) { pps[this.__uniqueid] = password; } @@ -231,6 +231,7 @@ Storage.prototype.getWallets = function(cb) { Storage.prototype.deleteWallet = function(walletId, cb) { preconditions.checkArgument(walletId); preconditions.checkArgument(cb); + var err; var toDelete = {}; toDelete['nameFor::' + walletId] = 1; @@ -245,11 +246,15 @@ Storage.prototype.deleteWallet = function(walletId, cb) { }); var l = toDelete.length, - i = 0; + j = 0; + + if (!l) + return cb(new Error('WNOTFOUND: Wallet not found')); + for (var i in toDelete) { this.removeGlobal(i, function() { - if (++i == l) - return cb(); + if (++j == l) + return cb(err); }); } }; diff --git a/js/models/core/PluginManager.js b/js/models/core/PluginManager.js index bce94e464..7aced3b49 100644 --- a/js/models/core/PluginManager.js +++ b/js/models/core/PluginManager.js @@ -1,5 +1,6 @@ 'use strict'; var preconditions = require('preconditions').singleton(); +var log = require('../../log'); function PluginManager(config) { this.registered = {}; @@ -11,7 +12,7 @@ function PluginManager(config) { if (!config.plugins[pluginName]) continue; - console.log('Loading plugin: ' + pluginName); + log.info('Loading plugin: ' + pluginName); var pluginClass = require('../plugins/' + pluginName); var pluginObj = new pluginClass(config[pluginName]); pluginObj.init(); diff --git a/js/models/core/Wallet.js b/js/models/core/Wallet.js index 6ab010c5a..c14a568fe 100644 --- a/js/models/core/Wallet.js +++ b/js/models/core/Wallet.js @@ -64,7 +64,7 @@ function Wallet(opts) { 'publicKeyRing', 'txProposals', 'privateKey', 'version', 'reconnectDelay' ].forEach(function(k) { - preconditions.checkArgument(!_.isUndefined(opts[k]), 'missing required option for Wallet: ' + k); + preconditions.checkArgument(!_.isUndefined(opts[k]), 'MISSOPT: missing required option for Wallet: ' + k); self[k] = opts[k]; }); preconditions.checkArgument(!copayConfig.forceNetwork || this.getNetworkName() === copayConfig.networkName, diff --git a/js/models/core/WalletFactory.js b/js/models/core/WalletFactory.js index eca5e656b..15e4eee16 100644 --- a/js/models/core/WalletFactory.js +++ b/js/models/core/WalletFactory.js @@ -120,7 +120,7 @@ WalletFactory.prototype.fromObj = function(obj, skipFields) { * @return {Wallet} */ WalletFactory.prototype.fromEncryptedObj = function(base64, password, skipFields) { - this.storage._setPassphrase(password); + this.storage.setPassphrase(password); var walletObj = this.storage.import(base64); if (!walletObj) return false; var w = this.fromObj(walletObj, skipFields); @@ -148,18 +148,34 @@ WalletFactory.prototype.import = function(base64, password, skipFields) { * @desc Retrieve a wallet from storage * @param {string} walletId - the wallet id * @param {string[]} skipFields - parameters to ignore when importing - * @return {Wallet} + * @param {function} callback - {err, Wallet} */ WalletFactory.prototype.read = function(walletId, skipFields, cb) { - var self = this, err; + var self = this, + err; var obj = {}; - obj.id = walletId; this.storage.getMany(walletId, Wallet.PERSISTED_PROPERTIES, function(ret) { for (var ii in ret) { obj[ii] = ret[ii]; } - return cb(err, self.fromObj(obj, skipFields)); + + if (!_.any(_.values(obj))) + return cb(new Error('Wallet not found')); + + var w, err; + obj.id = walletId; + try { + w = self.fromObj(obj, skipFields); + } catch (e) { + if (e && e.message && e.message.indexOf('MISSOPTS')) { + err = new Error('Could not read: ' + walletId); + } else { + err = e; + } + w = null; + } + return cb(err, w); }); }; @@ -221,7 +237,7 @@ WalletFactory.prototype.create = function(opts, cb) { }); log.debug('\t### TxProposals Initialized'); - this.storage._setPassphrase(opts.passphrase); + this.storage.setPassphrase(opts.passphrase); opts.storage = this.storage; opts.network = this.networks[opts.networkName]; @@ -272,8 +288,8 @@ WalletFactory.prototype._checkVersion = function(inVersion) { WalletFactory.prototype.open = function(walletId, passphrase, cb) { preconditions.checkArgument(cb); var self = this; - self.storage._setPassphrase(passphrase); - self.read(err, walletId, null, function(w) { + self.storage.setPassphrase(passphrase); + self.read(walletId, null, function(err, w) { if (err) return cb(err); w.store(function(err) { @@ -285,11 +301,11 @@ WalletFactory.prototype.open = function(walletId, passphrase, cb) { }; WalletFactory.prototype.getWallets = function(cb) { - var ret = this.storage.getWallets(function(ret) { + this.storage.getWallets(function(ret) { ret.forEach(function(i) { i.show = i.name ? ((i.name + ' <' + i.id + '>')) : i.id; }); - return cb(ret); + return cb(null, ret); }); }; @@ -303,9 +319,12 @@ WalletFactory.prototype.getWallets = function(cb) { */ WalletFactory.prototype.delete = function(walletId, cb) { var s = this.storage; - s.deleteWallet(walletId); - s.setLastOpened(undefined); - return cb(); + s.deleteWallet(walletId, function(err) { + if (err) return cb(err); + s.setLastOpened(null, function(err) { + return cb(err); + }); + }); }; /** diff --git a/package.json b/package.json index 7248c5c0f..248cac974 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "dependencies": { "browser-request": "^0.3.2", "inherits": "^2.0.1", - "mocha": "^1.18.2", + "mocha": "^1.21.4", "mocha-lcov-reporter": "0.0.1", "optimist": "^0.6.1", "preconditions": "^1.0.7", @@ -27,12 +27,14 @@ "chrome": "source browser-extensions/chrome/build.sh", "setup-shell": "node shell/scripts/download-atom-shell.js", "start": "node server.js", - "coverage": "./node_modules/.bin/istanbul cover ./node_modules/.bin/_mocha -- --reporter spec test", - "test": "sh test/run.sh", + "coverage": "mochacoverage", + "test": "mocha --ui exports --reporter spec", "dist": "node shell/scripts/dist.js", "sign": "gpg -u 1112CFA1 --output browser-extensions/firefox/copay.xpi.sig --detach-sig browser-extensions/firefox/copay.xpi; gpg -u 1112CFA1 --output browser-extensions/chrome/copay-chrome-extension.zip.sig --detach-sig browser-extensions/chrome/copay-chrome-extension.zip", "verify": "gpg --verify browser-extensions/firefox/copay.xpi.sig browser-extensions/firefox/copay.xpi; gpg --verify browser-extensions/chrome/copay-chrome-extension.zip.sig browser-extensions/chrome/copay-chrome-extension.zip", - "postinstall": "./node_modules/.bin/grunt" + "postinstall": "./node_modules/.bin/grunt", + "monitor": "mocha --ui exports --reporter min --watch", + "debugtest": "mocha --debug-brk --ui exports --reporter spec" }, "keywords": [ "wallet", @@ -81,7 +83,8 @@ "shelljs": "0.3.0", "socket.io-client": "1.0.6", "travis-cov": "0.2.5", - "uglifyify": "1.2.3" + "uglifyify": "1.2.3", + "mochawrapper": "" }, "main": "app.js", "homepage": "https://github.com/bitpay/copay", diff --git a/test/mocks/FakeStorage.js b/test/mocks/FakeStorage.js index ef8b33b3c..ba64b382a 100644 --- a/test/mocks/FakeStorage.js +++ b/test/mocks/FakeStorage.js @@ -21,9 +21,9 @@ FakeStorage.prototype.getGlobal = function(id, cb) { }; FakeStorage.prototype.getMany = function(wid, fields, cb) { - var self= this; + var self = this; var ret = []; - for(var ii in fields){ + for (var ii in fields) { var k = fields[ii]; ret[k] = this.storage[wid + '::' + k]; } @@ -113,14 +113,23 @@ FakeStorage.prototype.deleteWallet = function(walletId, cb) { toDelete[key] = 1; } } + var l = toDelete.length, + j = 0; + + if (!l) + return cb(new Error('WNOTFOUND: Wallet not found')); + for (var i in toDelete) { - this.removeGlobal(i); + this.removeGlobal(i, cb); + if (++j == l) + return cb(err); + } }; FakeStorage.prototype.getName = function(walletId, cb) { - return this.getGlobal('nameFor::' + walletId, cb); + this.getGlobal('nameFor::' + walletId, cb); }; @@ -131,15 +140,16 @@ FakeStorage.prototype.setName = function(walletId, name, cb) { FakeStorage.prototype.getWallets = function(cb) { var wallets = []; - var ids = this.getWalletIds(); - - for (var i in ids) { - wallets.push({ - id: ids[i], - name: this.getName(ids[i]), - }); - } - return cb(wallets); + var self= this; + this.getWalletIds(function(ids) { + for (var i in ids) { + wallets.push({ + id: ids[i], + name: self.storage['nameFor::' + ids[i]], + }); + } + return cb(wallets); + }); }; FakeStorage.prototype.setFromObj = function(walletId, obj, cb) { diff --git a/test/test.WalletFactory.js b/test/test.WalletFactory.js index 36c032b80..be09931d6 100644 --- a/test/test.WalletFactory.js +++ b/test/test.WalletFactory.js @@ -155,8 +155,8 @@ describe('WalletFactory model', function() { it('should be able to get wallets', function(done) { var wf = new WalletFactory(config, '0.0.1'); - wf.create(null, function(err,w){ - wf.read(w.id, [], function(err, w2){ + wf.create(null, function(err, w) { + wf.read(w.id, [], function(err, w2) { should.exist(w2); w2.id.should.equal(w.id); done(); @@ -312,107 +312,177 @@ describe('WalletFactory model', function() { 'requiredCopayers': 2, 'totalCopayers': 3 }; - wf.create(opts, function(err,w){ + wf.create(opts, function(err, w) { should.not.exist(err); should.exist(w); done(); }); }); - it('should be able to get current wallets', function() { + it('should be able to get current wallets', function(done) { var wf = new WalletFactory(config, '0.0.1'); - var ws = wf.getWallets(); - - var w = wf.create({ + wf.create({ name: 'test wallet' - }); + }, function(err, ws) { + should.not.exist(err); - ws = wf.getWallets(); - ws.length.should.equal(1); - ws[0].name.should.equal('test wallet'); - }); - - it('should be able to delete wallet', function(done) { - var wf = new WalletFactory(config, '0.0.1'); - var w = wf.create({ - name: 'test wallet' - }); - var ws = wf.getWallets(); - ws.length.should.equal(1); - wf.delete(ws[0].id, function() { - ws = wf.getWallets(); - ws.length.should.equal(0); - done(); + wf.getWallets(function(err, ws) { + should.not.exist(err); + ws.length.should.equal(1); + ws[0].name.should.equal('test wallet'); + done(); + }); }); }); - it('should clean lastOpened on delete wallet', function(done) { - var wf = new WalletFactory(config, '0.0.1'); - var w = wf.create({ - name: 'test wallet' + describe('#delete', function() { + it('should call deleteWallet', function(done) { + var wf = new WalletFactory(config, '0.0.1'); + var s1 = sinon.spy(wf.storage, 'deleteWallet'); + + wf.delete('xxx', function() { + s1.getCall(0).args[0].should.equal('xxx'); + done(); + }); }); - wf.storage.setLastOpened(w.id); - wf.delete(w.id, function() { - var last = wf.storage.getLastOpened(); - should.equal(last, undefined); - done(); + it('should call lastOpened', function(done) { + var wf = new WalletFactory(config, '0.0.1'); + var s1 = sinon.stub(wf.storage, 'deleteWallet').yields(null); + var s2 = sinon.stub(wf.storage, 'setLastOpened').yields(null); + wf.delete('xxx', function() { + s2.calledOnce.should.equal(true); + should.not.exist(s2.getCall(0).args[0]); + done(); + }); }); }); - it('should return false if wallet does not exist', function() { + + describe('#read', function() { + it('should fail to read unexisting wallet', function(done) { + var wf = new WalletFactory(config, '0.0.1'); + wf.read('id', [], function(err, w) { + should.not.exist(w); + should.exist(err); + should.exist(err.message); + var m = err.message.toString(); + m.should.to.have.string('Wallet not found'); + done(); + }); + }); + it('should fail to read broken wallet', function(done) { + var wf = new WalletFactory(config, '0.0.1'); + wf.storage.getMany = sinon.stub().yields({ + 'opts': 1 + }); + wf.read('id', [], function(err, w) { + should.not.exist(w); + should.exist(err); + should.exist(err.message); + var m = err.message.toString(); + m.should.to.have.string('Could not read'); + done(); + }); + }); + it('should read existing wallet', function(done) { + var wf = new WalletFactory(config, '0.0.1'); + wf.storage.getMany = sinon.stub().yields({ + 'opts': 1 + }); + wf.fromObj = sinon.stub().returns('ok'); + wf.read('id', [], function(err, w) { + should.not.exist(err); + should.exist(w); + done(); + }); + }); + }); + + + describe('#open', function() { var opts = { - 'requiredCopayers': 2, - 'totalCopayers': 3 + 'requiredcopayers': 2, + 'totalcopayers': 3 }; - var wf = new WalletFactory(config, '0.0.1'); - var w = wf.open('dummy', opts); - should.exist(w); + it('should call setPassphrase', function(done) { + var wf = new WalletFactory(config, '0.0.1'); + wf.storage.setPassphrase = sinon.spy(); + + var s1 = sinon.stub(); + s1.store = sinon.stub().yields(null); + wf.read = sinon.stub().yields(null, s1); + wf.storage.setLastOpened = sinon.stub().yields(null); + + wf.open('dummy', 'xxx', function(err, w) { + wf.storage.setPassphrase.calledOnce.should.equal(true); + wf.storage.setPassphrase.getCall(0).args[0].should.equal('xxx'); + done(); + }); + }); + + it('should call return wallet', function(done) { + var wf = new WalletFactory(config, '0.0.1'); + wf.storage.setPassphrase = sinon.spy(); + + var s1 = sinon.stub(); + s1.store = sinon.stub().yields(null); + wf.read = sinon.stub().yields(null, s1); + wf.storage.setLastOpened = sinon.stub().yields(null); + + wf.open('dummy', 'xxx', function(err, w) { + w.should.equal(s1); + s1.store.calledOnce.should.equal(true); + done(); + }); + }); + + + it('should call #store', function(done) { + var wf = new WalletFactory(config, '0.0.1'); + wf.storage.setPassphrase = sinon.spy(); + + var s1 = sinon.stub(); + s1.store = sinon.stub().yields(null); + wf.read = sinon.stub().yields(null, s1); + wf.storage.setLastOpened = sinon.stub().yields(null); + + wf.open('dummy', 'xxx', function(err, w) { + s1.store.calledOnce.should.equal(true); + done(); + }); + }); + + it('should call #setLastOpened', function(done) { + var wf = new WalletFactory(config, '0.0.1'); + wf.storage.setPassphrase = sinon.spy(); + + var s1 = sinon.stub(); + s1.store = sinon.stub().yields(null); + wf.read = sinon.stub().yields(null, s1); + wf.storage.setLastOpened = sinon.stub().yields(null); + + wf.open('dummy', 'xxx', function(err, w) { + wf.storage.setLastOpened.calledOnce.should.equal(true); + wf.storage.setLastOpened.getCall(0).args[0].should.equal('dummy'); + done(); + }); + }); }); - it('should open a wallet', function() { - var opts = { - 'requiredCopayers': 2, - 'totalCopayers': 3 - }; - var wf = new WalletFactory(config, '0.0.1'); - var w = wf.create(opts); - var walletId = w.id; - - wf.read = sinon.stub().withArgs(walletId).returns(w); - var wo = wf.open(walletId, opts); - should.exist(wo); - wf.read.calledWith(walletId).should.be.true; - }); - - it('should save lastOpened on create/open a wallet', function() { - var opts = { - 'requiredCopayers': 2, - 'totalCopayers': 3 - }; - var wf = new WalletFactory(config, '0.0.1'); - var w = wf.create(opts); - var last = wf.storage.getLastOpened(); - should.equal(last, w.id); - - wf.storage.setLastOpened('other_id'); - - var wo = wf.open(w.id, opts); - last = wf.storage.getLastOpened(); - should.equal(last, w.id); - }); - - it('should return error if network are differents', function() { - var opts = { - 'requiredCopayers': 2, - 'totalCopayers': 3 - }; - var wf = new WalletFactory(config, '0.0.1'); - var w = wf.create(opts); - (function() { - wf._checkNetwork('livenet'); - }).should.throw(); + describe.only('#create', function() { + it('should return error if network are differents', function() { + var opts = { + 'requiredCopayers': 2, + 'totalCopayers': 3 + }; + var wf = new WalletFactory(config, '0.0.1'); + var w = wf.create(opts, function(err, w) { + err.should.to.have.string('Wallet not found'); + should.not.exist(w); + }); + }); }); describe('#joinCreateSession', function() { From ad22b24d83f226ab2bcd475f1a6d11c656b73752 Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Sun, 14 Sep 2014 13:52:43 -0300 Subject: [PATCH 125/191] more tests --- js/controllers/join.js | 7 +- js/models/core/WalletFactory.js | 46 ++- test/mocks/FakeStorage.js | 2 +- test/test.WalletFactory.js | 487 +++++++++++++++----------------- 4 files changed, 272 insertions(+), 270 deletions(-) diff --git a/js/controllers/join.js b/js/controllers/join.js index 2de8fa49a..3d54d59f0 100644 --- a/js/controllers/join.js +++ b/js/controllers/join.js @@ -119,7 +119,12 @@ angular.module('copayApp.controllers').controller('JoinController', $scope.loading = true; Passphrase.getBase64Async($scope.joinPassword, function(passphrase) { - walletFactory.joinCreateSession($scope.connectionId, $scope.nickname, passphrase, $scope.private, function(err, w) { + walletFactory.joinCreateSession({ + secret: $scope.connectionId, + nickname: $scope.nickname, + passphrase: passphrase, + privateHex: $scope.private, + }, function(err, w) { $scope.loading = false; if (err || !w) { if (err === 'joinError') diff --git a/js/models/core/WalletFactory.js b/js/models/core/WalletFactory.js index 15e4eee16..eacfeb48f 100644 --- a/js/models/core/WalletFactory.js +++ b/js/models/core/WalletFactory.js @@ -123,8 +123,7 @@ WalletFactory.prototype.fromEncryptedObj = function(base64, password, skipFields this.storage.setPassphrase(password); var walletObj = this.storage.import(base64); if (!walletObj) return false; - var w = this.fromObj(walletObj, skipFields); - return w; + return this.fromObj(walletObj, skipFields); }; /** @@ -179,8 +178,21 @@ WalletFactory.prototype.read = function(walletId, skipFields, cb) { }); }; + /** - * @desc This method instantiates a wallet + * @desc This method instantiates a wallet. Usefull for stubbing. + * + * @param {opts} opts, ready for new Wallet(opts) + * + */ + + +WalletFactory.prototype._getWallet = function(opts) { + return new Wallet(opts); +}; + +/** + * @desc This method prepares options for a new Wallet * * @param {Object} opts * @param {string} opts.id @@ -249,11 +261,12 @@ WalletFactory.prototype.create = function(opts, cb) { opts.totalCopayers = totalCopayers; opts.version = opts.version || this.version; - var w = new Wallet(opts); + var w = this._getWallet(opts); var self = this; - w.store(function() { - self.storage.setLastOpened(w.id, function() { - return cb(null, w); + w.store(function(err) { + if (err) return cb(err); + self.storage.setLastOpened(w.id, function(err) { + return cb(err, w); }); }); }; @@ -352,16 +365,21 @@ WalletFactory.prototype.decodeSecret = function(secret) { * information locally using passphrase. privateHex is the * private extended master key. cb has two params: error and wallet. * - * @param {string} secret - the wallet secret - * @param {string} nickname - a nickname for the current user - * @param {string} passphrase - a passphrase to use to encrypt the wallet for persistance - * @param {string} privateHex - the private extended master key + * @param {object} opts + * @param {string} opts.secret - the wallet secret + * @param {string} opts.passphrase - a passphrase to use to encrypt the wallet for persistance + * @param {string} opts.nickname - a nickname for the current user + * @param {string} opts.privateHex - the private extended master key * @param {walletCreationCallback} cb - a callback */ -WalletFactory.prototype.joinCreateSession = function(secret, nickname, passphrase, privateHex, cb) { +WalletFactory.prototype.joinCreateSession = function(opts, cb) { + preconditions.checkArgument(opts); + preconditions.checkArgument(opts.secret); + preconditions.checkArgument(opts.passphrase); + preconditions.checkArgument(opts.nickname); preconditions.checkArgument(cb); var self = this; - var decodedSecret = this.decodeSecret(secret); + var decodedSecret = this.decodeSecret(opts.secret); if (!decodedSecret || !decodedSecret.networkName || !decodedSecret.pubKey) { return cb('badSecret'); } @@ -370,7 +388,7 @@ WalletFactory.prototype.joinCreateSession = function(secret, nickname, passphras networkName: decodedSecret.networkName, }; - if (privateHex && privateHex.length > 1) { + if (opts.privateHex && opts.privateHex.length > 1) { privOpts.extendedPrivateKeyString = privateHex; } diff --git a/test/mocks/FakeStorage.js b/test/mocks/FakeStorage.js index ba64b382a..7bb9de7b6 100644 --- a/test/mocks/FakeStorage.js +++ b/test/mocks/FakeStorage.js @@ -7,7 +7,7 @@ FakeStorage.prototype.reset = function(password) { this.storage = {}; }; -FakeStorage.prototype._setPassphrase = function(password) { +FakeStorage.prototype.setPassphrase = function(password) { this.storage.passphrase = password; }; diff --git a/test/test.WalletFactory.js b/test/test.WalletFactory.js index be09931d6..78dca9aff 100644 --- a/test/test.WalletFactory.js +++ b/test/test.WalletFactory.js @@ -3,12 +3,11 @@ var chai = chai || require('chai'); var should = chai.should(); -var FakeStorage = require('./mocks/FakeLocalStorage'); var copay = copay || require('../copay'); var sinon = require('sinon'); var FakeNetwork = require('./mocks/FakeNetwork'); var FakeBlockchain = require('./mocks/FakeBlockchain'); -var FakeStorage = require('./mocks/FakeStorage'); +var FakeStorage = function FakeStorage() {}; var WalletFactory = require('../js/models/core/WalletFactory'); var Passphrase = require('../js/models/core/Passphrase'); var LocalEncrypted = copay.StorageLocalEncrypted; @@ -78,7 +77,7 @@ function assertObjectEqual(a, b, msg) { var orderedA = reconstructObject(a, getKeys(a).sort()), orderedB = reconstructObject(b, getKeys(b).sort()); - // compare as strings for diff tools to show us the difference + // compare as strings for diff tolls to show us the difference JSON.stringify(orderedA).should.equal(JSON.stringify(orderedB), msg) } } @@ -86,6 +85,31 @@ function assertObjectEqual(a, b, msg) { describe('WalletFactory model', function() { + var wf; + + beforeEach(function() { + wf = new WalletFactory(config, '0.0.1'); + wf.storage.setPassphrase = sinon.spy(); + wf.storage.getSessionId = sinon.spy(); + wf.storage.setFromObj = sinon.spy(); + wf.storage.setLastOpened = sinon.stub().yields(null); + + var w = sinon.stub(); + w.store = sinon.stub().yields(null); + + wf._getWallet = sinon.stub().returns(w); + + + wf.network.setHexNonce = sinon.spy(); + }); + + + afterEach(function() { + wf = undefined; + }); + + + var config = { Network: FakeNetwork, Blockchain: FakeBlockchain, @@ -95,14 +119,12 @@ describe('WalletFactory model', function() { totalCopayers: 5, spendUnconfirmed: 1, reconnectDelay: 100, + }, - network: { - testnet: { - url: 'https://test-insight.bitpay.com:443' - }, - livenet: { - url: 'https://insight.bitpay.com:443' - }, + blockchain: { + host: 'test.insight.is', + port: 80, + schema: 'https' }, networkName: 'testnet', passphrase: { @@ -111,225 +133,143 @@ describe('WalletFactory model', function() { }, }; - it('should create the factory', function() { - var wf = new WalletFactory(config, '0.0.1'); - should.exist(wf); - wf.walletDefaults.should.deep.equal(config.wallet); - wf.version.should.equal('0.0.1'); + describe('#constructor', function() { + it('should create the factory', function() { + var wf = new WalletFactory(config, '0.0.1'); + should.exist(wf); + wf.networkName.should.equal(config.networkName); + wf.walletDefaults.should.deep.equal(config.wallet); + wf.version.should.equal('0.0.1'); + }); }); + describe('#fromObj / #toObj', function() { + it('round trip', function() { + var w = wf.fromObj(JSON.parse(o)); - it('should be able to create wallets', function(done) { - var wf = new WalletFactory(config, '0.0.1'); - wf.create(null, function(err, w) { should.exist(w); - should.not.exist(err); - done(); + w.id.should.equal("dbfe10c3fae71cea"); + should.exist(w.publicKeyRing.getCopayerId); + should.exist(w.txProposals.toObj()); + should.exist(w.privateKey.toObj()); + + assertObjectEqual(w.toObj(), JSON.parse(o)); }); - }); - it('should be able to create wallets with given pk', function(done) { - var wf = new WalletFactory(config, '0.0.1'); - var priv = 'tprv8ZgxMBicQKsPdEqHcA7RjJTayxA3gSSqeRTttS1JjVbgmNDZdSk9EHZK5pc52GY5xFmwcakmUeKWUDzGoMLGAhrfr5b3MovMUZUTPqisL2m'; - wf.create({ - privateKeyHex: priv, - }, function(err, w) { - w.privateKey.toObj().extendedPrivateKeyString.should.equal(priv); - should.not.exist(err); - done(); - }); - }); + it('round trip, using old copayerIndex', function() { + var wf = new WalletFactory(config, '0.0.5'); + var w = wf.fromObj(JSON.parse(o)); - it('should be able to create wallets with random pk', function(done) { - var wf = new WalletFactory(config, '0.0.1'); - wf.create(null, function(err, w1) { - wf.create(null, function(err, w2) { - w1.privateKey.toObj().extendedPrivateKeyString.should.not.equal( - w2.privateKey.toObj().extendedPrivateKeyString - ); - done(); - }); - }); - }); - - - it('should be able to get wallets', function(done) { - var wf = new WalletFactory(config, '0.0.1'); - wf.create(null, function(err, w) { - wf.read(w.id, [], function(err, w2) { - should.exist(w2); - w2.id.should.equal(w.id); - done(); - }); - }); - }); - - - it('#fromObj #toObj round trip', function() { - var wf = new WalletFactory(config, '0.0.5'); - var w = wf.fromObj(JSON.parse(o)); - - should.exist(w); - w.id.should.equal("dbfe10c3fae71cea"); - should.exist(w.publicKeyRing.getCopayerId); - should.exist(w.txProposals.toObj()); - should.exist(w.privateKey.toObj()); - - assertObjectEqual(w.toObj(), JSON.parse(o)); - }); - - - - it('#fromObj #toObj round trip, using old copayerIndex', function() { - var wf = new WalletFactory(config, '0.0.5'); - var w = wf.fromObj(JSON.parse(o)); - - should.exist(w); - w.id.should.equal("dbfe10c3fae71cea"); - should.exist(w.publicKeyRing.getCopayerId); - should.exist(w.txProposals.toObj()); - should.exist(w.privateKey.toObj()); - assertObjectEqual(w.toObj(), JSON.parse(o)); - }); - - - it('#fromObj, skipping fields', function() { - var wf = new WalletFactory(config, '0.0.5'); - var w = wf.fromObj(JSON.parse(o), ['publicKeyRing']); - - should.exist(w); - w.id.should.equal("dbfe10c3fae71cea"); - should.exist(w.publicKeyRing.getCopayerId); - should.exist(w.txProposals.toObj()); - should.exist(w.privateKey.toObj()); - (function() { - assertObjectEqual(w.toObj(), JSON.parse(o)) - }).should.throw(); - }); - - it('support old index schema: #fromObj #toObj round trip', function() { - - var o3 = '{"opts":{"id":"dbfe10c3fae71cea","spendUnconfirmed":1,"requiredCopayers":3,"totalCopayers":5,"version":"0.0.5"},"networkNonce":"0000000000000001","networkNonces":[],"publicKeyRing":{"walletId":"dbfe10c3fae71cea","networkName":"testnet","requiredCopayers":3,"totalCopayers":5,"indexes":{"changeIndex":0,"receiveIndex":0},"copayersBackup":[],"copayersExtPubKeys":["tpubD6NzVbkrYhZ4YGK8ZhZ8WVeBXNAAoTYjjpw9twCPiNGrGQYFktP3iVQkKmZNiFnUcAFMJRxJVJF6Nq9MDv2kiRceExJaHFbxUCGUiRhmy97","tpubD6NzVbkrYhZ4YKGDJkzWdQsQV3AcFemaQKiwNhV4RL8FHnBFvinidGdQtP8RKj3h34E65RkdtxjrggZYqsEwJ8RhhN2zz9VrjLnrnwbXYNc","tpubD6NzVbkrYhZ4YkDiewjb32Pp3Sz9WK2jpp37KnL7RCrHAyPpnLfgdfRnTdpn6DTWmPS7niywfgWiT42aJb1J6CjWVNmkgsMCxuw7j9DaGKB","tpubD6NzVbkrYhZ4XEtUAz4UUTWbprewbLTaMhR8NUvSJUEAh4Sidxr6rRPFdqqVRR73btKf13wUjds2i8vVCNo8sbKrAnyoTr3o5Y6QSbboQjk","tpubD6NzVbkrYhZ4Yj9AAt6xUVuGPVd8jXCrEE6V2wp7U3PFh8jYYvVad31b4VUXEYXzSnkco4fktu8r4icBsB2t3pCR3WnhVLedY2hxGcPFLKD"],"nicknameFor":{}},"txProposals":{"txps":[],"walletId":"dbfe10c3fae71cea","networkName":"testnet"},"privateKey":{"extendedPrivateKeyString":"tprv8ZgxMBicQKsPeoHLg3tY75z4xLeEe8MqAXLNcRA6J6UTRvHV8VZTXznt9eoTmSk1fwSrwZtMhY3XkNsceJ14h6sCXHSWinRqMSSbY8tfhHi","networkName":"testnet"},"addressBook":{},"settings":{"unitName":"BTC","unitToSatoshi":100000000,"unitDecimals":8,"alternativeName":"Argentine Peso","alternativeIsoCode":"ARS"}}'; - var o4 = '{"opts":{"id":"dbfe10c3fae71cea","spendUnconfirmed":1,"requiredCopayers":3,"totalCopayers":5,"version":"0.0.5","networkName":"testnet"},"networkNonce":"0000000000000001","networkNonces":[],"publicKeyRing":{"walletId":"dbfe10c3fae71cea","networkName":"testnet","requiredCopayers":3,"totalCopayers":5,"indexes":[{"copayerIndex":2147483647,"changeIndex":0,"receiveIndex":0},{"copayerIndex":0,"changeIndex":0,"receiveIndex":0},{"copayerIndex":1,"changeIndex":0,"receiveIndex":0},{"copayerIndex":2,"changeIndex":0,"receiveIndex":0},{"copayerIndex":3,"changeIndex":0,"receiveIndex":0},{"copayerIndex":4,"changeIndex":0,"receiveIndex":0}],"copayersBackup":[],"copayersExtPubKeys":["tpubD6NzVbkrYhZ4YGK8ZhZ8WVeBXNAAoTYjjpw9twCPiNGrGQYFktP3iVQkKmZNiFnUcAFMJRxJVJF6Nq9MDv2kiRceExJaHFbxUCGUiRhmy97","tpubD6NzVbkrYhZ4YKGDJkzWdQsQV3AcFemaQKiwNhV4RL8FHnBFvinidGdQtP8RKj3h34E65RkdtxjrggZYqsEwJ8RhhN2zz9VrjLnrnwbXYNc","tpubD6NzVbkrYhZ4YkDiewjb32Pp3Sz9WK2jpp37KnL7RCrHAyPpnLfgdfRnTdpn6DTWmPS7niywfgWiT42aJb1J6CjWVNmkgsMCxuw7j9DaGKB","tpubD6NzVbkrYhZ4XEtUAz4UUTWbprewbLTaMhR8NUvSJUEAh4Sidxr6rRPFdqqVRR73btKf13wUjds2i8vVCNo8sbKrAnyoTr3o5Y6QSbboQjk","tpubD6NzVbkrYhZ4Yj9AAt6xUVuGPVd8jXCrEE6V2wp7U3PFh8jYYvVad31b4VUXEYXzSnkco4fktu8r4icBsB2t3pCR3WnhVLedY2hxGcPFLKD"],"nicknameFor":{}},"txProposals":{"txps":[],"walletId":"dbfe10c3fae71cea","networkName":"testnet"},"privateKey":{"extendedPrivateKeyString":"tprv8ZgxMBicQKsPeoHLg3tY75z4xLeEe8MqAXLNcRA6J6UTRvHV8VZTXznt9eoTmSk1fwSrwZtMhY3XkNsceJ14h6sCXHSWinRqMSSbY8tfhHi","networkName":"testnet"},"addressBook":{},"settings":{"unitName":"BTC","unitToSatoshi":100000000,"unitDecimals":8,"alternativeName":"Argentine Peso","alternativeIsoCode":"ARS"}}'; - var wf = new WalletFactory(config, '0.0.5'); - var w = wf.fromObj(JSON.parse(o3)); - - should.exist(w); - w.id.should.equal("dbfe10c3fae71cea"); - should.exist(w.publicKeyRing.getCopayerId); - should.exist(w.txProposals.toObj); - should.exist(w.privateKey.toObj); - - var expected = JSON.parse(o4.replace(/cosigner/g, 'copayerIndex')); - assertObjectEqual(w.toObj(), expected); - }); - - it('should create wallet from encrypted object', function() { - var wf = new WalletFactory(config, '0.0.1'); - var walletObj = JSON.parse(o); - wf.storage._setPassphrase = sinon.spy(); - wf.storage.import = sinon.stub().withArgs("encrypted object").returns(walletObj); - wf.fromObj = sinon.stub().withArgs(walletObj).returns(walletObj); - - var w = wf.fromEncryptedObj("encrypted object", "password"); - should.exist(w); - wf.storage._setPassphrase.called.should.be.true; - wf.storage.import.called.should.be.true; - wf.fromObj.calledWith(walletObj).should.be.true; - }); - - it('should return false if decrypted object is wrong', function() { - var wf = new WalletFactory(config, '0.0.1'); - var walletObj = JSON.parse(o); - wf.storage._setPassphrase = sinon.spy(); - wf.storage.import = sinon.spy(); - wf.fromObj = sinon.stub().withArgs(walletObj).returns(walletObj); - - var w = wf.fromEncryptedObj("encrypted object", "password"); - should.exist(w); - wf.storage._setPassphrase.called.should.be.true; - wf.storage.import.called.should.be.true; - wf.fromObj.calledWith(walletObj).should.be.false; - }); - - it('should import and update indexes', function() { - var wf = new WalletFactory(config, '0.0.1'); - var wallet = { - id: "fake wallet", - updateIndexes: function(cb) { - cb(); - } - }; - wf.fromEncryptedObj = sinon.stub().returns(wallet); - - var w = wf.import("encrypted", "password"); - - should.exist(w); - wallet.should.equal(w); - - wf.fromEncryptedObj = sinon.stub().returns(null); - (function() { - wf.import("encrypted", "password") - }).should.throw(); - }); - - it('BIP32 length problem', function(done) { - var sconfig = { - Network: FakeNetwork, - Blockchain: FakeBlockchain, - Storage: FakeStorage, - "networkName": "testnet", - "network": { - "key": "g23ihfh82h35rf", - "host": "162.242.219.26", - "port": 10009, - "path": "/", - "maxPeers": 15, - "debug": 3 - }, - "limits": { - "totalCopayers": 10, - "mPlusN": 15 - }, - "wallet": { - "requiredCopayers": 2, - "totalCopayers": 3, - "reconnectDelay": 100, - "spendUnconfirmed": 1, - }, - "blockchain": { - "host": "test.insight.is", - "port": 3001 - }, - "socket": { - "host": "test.insight.is", - "port": 3001 - }, - "themes": ["default"], - }; - var wf = new WalletFactory(sconfig, '0.0.1'); - var opts = { - 'requiredCopayers': 2, - 'totalCopayers': 3 - }; - wf.create(opts, function(err, w) { - should.not.exist(err); should.exist(w); - done(); + w.id.should.equal("dbfe10c3fae71cea"); + should.exist(w.publicKeyRing.getCopayerId); + should.exist(w.txProposals.toObj()); + should.exist(w.privateKey.toObj()); + assertObjectEqual(w.toObj(), JSON.parse(o)); + }); + + it('#fromObj, skipping fields', function() { + var wf = new WalletFactory(config, '0.0.5'); + var w = wf.fromObj(JSON.parse(o), ['publicKeyRing']); + + should.exist(w); + w.id.should.equal("dbfe10c3fae71cea"); + should.exist(w.publicKeyRing.getCopayerId); + should.exist(w.txProposals.toObj()); + should.exist(w.privateKey.toObj()); + (function() { + assertObjectEqual(w.toObj(), JSON.parse(o)) + }).should.throw(); + }); + + it('support old index schema: #fromObj #toObj round trip', function() { + var o = '{"opts":{"id":"dbfe10c3fae71cea","spendUnconfirmed":1,"requiredCopayers":3,"totalCopayers":5,"version":"0.0.5"},"networkNonce":"0000000000000001","networkNonces":[],"publicKeyRing":{"walletId":"dbfe10c3fae71cea","networkName":"testnet","requiredCopayers":3,"totalCopayers":5,"indexes":{"changeIndex":0,"receiveIndex":0},"copayersBackup":[],"copayersExtPubKeys":["tpubD6NzVbkrYhZ4YGK8ZhZ8WVeBXNAAoTYjjpw9twCPiNGrGQYFktP3iVQkKmZNiFnUcAFMJRxJVJF6Nq9MDv2kiRceExJaHFbxUCGUiRhmy97","tpubD6NzVbkrYhZ4YKGDJkzWdQsQV3AcFemaQKiwNhV4RL8FHnBFvinidGdQtP8RKj3h34E65RkdtxjrggZYqsEwJ8RhhN2zz9VrjLnrnwbXYNc","tpubD6NzVbkrYhZ4YkDiewjb32Pp3Sz9WK2jpp37KnL7RCrHAyPpnLfgdfRnTdpn6DTWmPS7niywfgWiT42aJb1J6CjWVNmkgsMCxuw7j9DaGKB","tpubD6NzVbkrYhZ4XEtUAz4UUTWbprewbLTaMhR8NUvSJUEAh4Sidxr6rRPFdqqVRR73btKf13wUjds2i8vVCNo8sbKrAnyoTr3o5Y6QSbboQjk","tpubD6NzVbkrYhZ4Yj9AAt6xUVuGPVd8jXCrEE6V2wp7U3PFh8jYYvVad31b4VUXEYXzSnkco4fktu8r4icBsB2t3pCR3WnhVLedY2hxGcPFLKD"],"nicknameFor":{}},"txProposals":{"txps":[],"walletId":"dbfe10c3fae71cea","networkName":"testnet"},"privateKey":{"extendedPrivateKeyString":"tprv8ZgxMBicQKsPeoHLg3tY75z4xLeEe8MqAXLNcRA6J6UTRvHV8VZTXznt9eoTmSk1fwSrwZtMhY3XkNsceJ14h6sCXHSWinRqMSSbY8tfhHi","networkName":"testnet"},"addressBook":{}}'; + var o2 = '{"opts":{"id":"dbfe10c3fae71cea","spendUnconfirmed":1,"requiredCopayers":3,"totalCopayers":5,"version":"0.0.5"},"networkNonce":"0000000000000001","networkNonces":[],"publicKeyRing":{"walletId":"dbfe10c3fae71cea","networkName":"testnet","requiredCopayers":3,"totalCopayers":5,"indexes":[{"copayerIndex":2147483647,"changeIndex":0,"receiveIndex":0},{"copayerIndex":0,"changeIndex":0,"receiveIndex":0},{"copayerIndex":1,"changeIndex":0,"receiveIndex":0},{"copayerIndex":2,"changeIndex":0,"receiveIndex":0},{"copayerIndex":3,"changeIndex":0,"receiveIndex":0},{"copayerIndex":4,"changeIndex":0,"receiveIndex":0}],"copayersBackup":[],"copayersExtPubKeys":["tpubD6NzVbkrYhZ4YGK8ZhZ8WVeBXNAAoTYjjpw9twCPiNGrGQYFktP3iVQkKmZNiFnUcAFMJRxJVJF6Nq9MDv2kiRceExJaHFbxUCGUiRhmy97","tpubD6NzVbkrYhZ4YKGDJkzWdQsQV3AcFemaQKiwNhV4RL8FHnBFvinidGdQtP8RKj3h34E65RkdtxjrggZYqsEwJ8RhhN2zz9VrjLnrnwbXYNc","tpubD6NzVbkrYhZ4YkDiewjb32Pp3Sz9WK2jpp37KnL7RCrHAyPpnLfgdfRnTdpn6DTWmPS7niywfgWiT42aJb1J6CjWVNmkgsMCxuw7j9DaGKB","tpubD6NzVbkrYhZ4XEtUAz4UUTWbprewbLTaMhR8NUvSJUEAh4Sidxr6rRPFdqqVRR73btKf13wUjds2i8vVCNo8sbKrAnyoTr3o5Y6QSbboQjk","tpubD6NzVbkrYhZ4Yj9AAt6xUVuGPVd8jXCrEE6V2wp7U3PFh8jYYvVad31b4VUXEYXzSnkco4fktu8r4icBsB2t3pCR3WnhVLedY2hxGcPFLKD"],"nicknameFor":{}},"txProposals":{"txps":[],"walletId":"dbfe10c3fae71cea","networkName":"testnet"},"privateKey":{"extendedPrivateKeyString":"tprv8ZgxMBicQKsPeoHLg3tY75z4xLeEe8MqAXLNcRA6J6UTRvHV8VZTXznt9eoTmSk1fwSrwZtMhY3XkNsceJ14h6sCXHSWinRqMSSbY8tfhHi","networkName":"testnet"},"addressBook":{}}'; + + var wf = new WalletFactory(config, '0.0.5'); + var w = wf.fromObj(JSON.parse(o)); + + should.exist(w); + w.id.should.equal("dbfe10c3fae71cea"); + should.exist(w.publicKeyRing.getCopayerId); + should.exist(w.txProposals.toObj); + should.exist(w.privateKey.toObj); + + // + var expected = JSON.parse(o2.replace(/cosigner/g, 'copayerIndex')); + assertObjectEqual(w.toObj(), expected); }); }); - it('should be able to get current wallets', function(done) { - var wf = new WalletFactory(config, '0.0.1'); - wf.create({ - name: 'test wallet' - }, function(err, ws) { - should.not.exist(err); + describe('#fromEncryptedObj', function() { + it('should create wallet from encrypted object', function() { + wf.storage.setPassphrase = sinon.spy(); + wf.storage.import = sinon.stub().withArgs('base64').returns('walletObj'); + wf.fromObj = sinon.stub().withArgs('walletObj').returns('ok'); + + var w = wf.fromEncryptedObj("encrypted object", "123"); + + w.should.equal('ok'); + wf.storage.setPassphrase.calledOnce.should.be.true; + wf.storage.setPassphrase.getCall(0).args[0].should.equal('123'); + wf.storage.import.calledOnce.should.be.true; + wf.fromObj.calledWith('walletObj').should.be.true; + }); + }); + + describe('#import', function() { + it('should import and update indexes', function() { + var wallet = { + id: "fake wallet", + updateIndexes: function(cb) { + cb(); + } + }; + wf.fromEncryptedObj = sinon.stub().returns(wallet); + + var w = wf.import("encrypted", "password"); + + should.exist(w); + wallet.should.equal(w); + + wf.fromEncryptedObj = sinon.stub().returns(null); + (function() { + wf.import("encrypted", "password") + }).should.throw(); + }); + }); + + describe('#getWallets', function() { + it('should return empty array if no wallets', function(done) { + wf.storage.getWallets = sinon.stub().yields([]); wf.getWallets(function(err, ws) { should.not.exist(err); - ws.length.should.equal(1); - ws[0].name.should.equal('test wallet'); + ws.should.deep.equal([]); + done(); + }); + }); + + it('should be able to get current wallets', function(done) { + wf.storage.getWallets = sinon.stub().yields([{ + name: 'w1', + id: 'id1', + }, { + name: 'w', + id: 'id2', + }]); + + wf.getWallets(function(err, ws) { + should.not.exist(err); + ws.should.deep.equal([{ + name: 'w1', + id: 'id1', + show: 'w1 ' + }, { + name: 'w', + id: 'id2', + show: 'w ' + }]); done(); }); }); @@ -337,22 +277,19 @@ describe('WalletFactory model', function() { describe('#delete', function() { it('should call deleteWallet', function(done) { - var wf = new WalletFactory(config, '0.0.1'); - var s1 = sinon.spy(wf.storage, 'deleteWallet'); - + wf.storage.deleteWallet = sinon.stub().yields(null); wf.delete('xxx', function() { - s1.getCall(0).args[0].should.equal('xxx'); + wf.storage.deleteWallet.getCall(0).args[0].should.equal('xxx'); done(); }); }); it('should call lastOpened', function(done) { - var wf = new WalletFactory(config, '0.0.1'); - var s1 = sinon.stub(wf.storage, 'deleteWallet').yields(null); - var s2 = sinon.stub(wf.storage, 'setLastOpened').yields(null); + wf.storage.deleteWallet = sinon.stub().yields(null); + wf.storage.setLastOpened = sinon.stub().yields(null); wf.delete('xxx', function() { - s2.calledOnce.should.equal(true); - should.not.exist(s2.getCall(0).args[0]); + wf.storage.setLastOpened.calledOnce.should.equal(true); + should.not.exist(wf.storage.setLastOpened.getCall(0).args[0]); done(); }); }); @@ -361,7 +298,8 @@ describe('WalletFactory model', function() { describe('#read', function() { it('should fail to read unexisting wallet', function(done) { - var wf = new WalletFactory(config, '0.0.1'); + wf.storage.getMany = sinon.stub().yields({}); + wf.read('id', [], function(err, w) { should.not.exist(w); should.exist(err); @@ -372,7 +310,6 @@ describe('WalletFactory model', function() { }); }); it('should fail to read broken wallet', function(done) { - var wf = new WalletFactory(config, '0.0.1'); wf.storage.getMany = sinon.stub().yields({ 'opts': 1 }); @@ -471,42 +408,86 @@ describe('WalletFactory model', function() { }); }); - describe.only('#create', function() { - it('should return error if network are differents', function() { - var opts = { - 'requiredCopayers': 2, - 'totalCopayers': 3 - }; - var wf = new WalletFactory(config, '0.0.1'); - var w = wf.create(opts, function(err, w) { - err.should.to.have.string('Wallet not found'); - should.not.exist(w); + describe('#create', function() { + it('should create wallet', function(done) { + wf.create(null, function(err, w) { + should.exist(w); + should.not.exist(err); + done(); + }); + }); + + it('should be able to create wallets with given pk', function(done) { + var priv = 'tprv8ZgxMBicQKsPdEqHcA7RjJTayxA3gSSqeRTttS1JjVbgmNDZdSk9EHZK5pc52GY5xFmwcakmUeKWUDzGoMLGAhrfr5b3MovMUZUTPqisL2m'; + wf.create({ + privateKeyHex: priv, + }, function(err, w) { + wf._getWallet.getCall(0).args[0].privateKey.toObj().extendedPrivateKeyString.should.equal(priv); + should.not.exist(err); + done(); + }); + }); + + it('should be able to create wallets with random pk', function(done) { + wf.create(null, function(err, w1) { + wf.create(null, function(err, w2) { + wf._getWallet.getCall(0).args[0].privateKey.toObj().extendedPrivateKeyString.should.not.equal( + wf._getWallet.getCall(1).args[0].privateKey.toObj().extendedPrivateKeyString + ); + done(); + }); }); }); }); describe('#joinCreateSession', function() { - it('should call network.start', function() { - var wf = new WalletFactory(config, '0.0.1'); - wf.networks.testnet.cleanUp = sinon.spy(); - wf.networks.testnet.start = sinon.spy(); - wf.joinCreateSession('CA1e4HJpSmx9i97i2NigZ6j6F8C5pSaZX9XrAUwQERYAxNpQ4jsBEkr8iS', 'test'); - wf.networks.testnet.start.calledOnce.should.equal(true); + var opts = { + secret: '8WtTuiFTkhP5ao7AF2QErSwV39Cbur6pdMebKzQXFqL59RscXM', + nickname: 'test', + passphrase: 'pass' + }; + it('should yield network error', function(done) { + opts.privHex = undefined; + wf.network.on = sinon.stub().withArgs('serverError').yields(null); + wf.joinCreateSession(opts, function(err, w) { + err.should.equal('joinError'); + done(); + }); }); + + + it('should call network.start', function(done) { + opts.privHex = undefined; + wf.network.cleanUp = sinon.spy(); + wf.network.greet = sinon.spy(); + wf.network.on = sinon.stub().withArgs('connected').yields(null); + + wf.network.start = sinon.stub().yields(null); + wf.joinCreateSession(opts, function(err, w) { + console.log('[test.WalletFactory.js.454:err:]', err); //TODO + wf.network.start.calledOnce.should.equal(true); + done(); + }); + + }); + it('should accept a priv key a input', function() { var wf = new WalletFactory(config, '0.0.1'); - var privHex = 'tprv8ZgxMBicQKsPf7MCvCjnhnr4uiR2Z2gyNC27vgd9KUu98F9mM1tbaRrWMyddVju36GxLbeyntuSadBAttriwGGMWUkRgVmUUCg5nFioGZsd'; - wf.networks.testnet.cleanUp = sinon.spy(); - wf.networks.testnet.start = sinon.spy(); - wf.joinCreateSession('CA1e4HJpSmx9i97i2NigZ6j6F8C5pSaZX9XrAUwQERYAxNpQ4jsBEkr8iS', 'test', null, privHex); - wf.networks.testnet.start.getCall(0).args[0].privkey.should.equal('ddc2fa8c583a73c4b2a24630ec7c283df4e7c230a02c4e48bc36ec61687afd7d'); + opts.privHex = 'tprv8ZgxMBicQKsPf7MCvCjnhnr4uiR2Z2gyNC27vgd9KUu98F9mM1tbaRrWMyddVju36GxLbeyntuSadBAttriwGGMWUkRgVmUUCg5nFioGZsd'; + wf.network.cleanUp = sinon.spy(); + wf.network.start = sinon.spy(); + wf.joinCreateSession(opts, function(err, w) { + wf.network.start.getCall(0).args[0].privkey.should.equal('ddc2fa8c583a73c4b2a24630ec7c283df4e7c230a02c4e48bc36ec61687afd7d'); + }); }); it('should call network.start with private key', function() { + opts.privHex = undefined; var wf = new WalletFactory(config, '0.0.1'); - wf.networks.testnet.cleanUp = sinon.spy(); - wf.networks.testnet.start = sinon.spy(); - wf.joinCreateSession('8WtTuiFTkhP5ao7AF2QErSwV39Cbur6pdMebKzQXFqL59RscXM', 'test', null, undefined); - wf.networks.testnet.start.getCall(0).args[0].privkey.length.should.equal(64); //privkey is hex of private key buffer + wf.network.cleanUp = sinon.spy(); + wf.network.start = sinon.spy(); + wf.joinCreateSession(opts, function(err, w) { + wf.network.start.getCall(0).args[0].privkey.length.should.equal(64); //privkey is hex of private key buffer + }); }); }); describe('dont break backwards compatibility of wallets', function() { @@ -524,7 +505,6 @@ describe('WalletFactory model', function() { it('should be able to import simple 1-of-1 encrypted legacy testnet wallet', function(done) { var pp = new Passphrase(config.passphrase); var alternateConfig = JSON.parse(JSON.stringify(config)); - alternateConfig.Blockchain = FakeBlockchain; alternateConfig.Storage = LocalEncrypted; alternateConfig.storage = { localStorage: mockLocalStorage, @@ -566,8 +546,7 @@ describe('WalletFactory model', function() { }); -var o = '{"opts":{"id":"dbfe10c3fae71cea","spendUnconfirmed":1,"requiredCopayers":3,"totalCopayers":5,"version":"0.0.5","networkName":"testnet"},"networkNonce":"0000000000000001","networkNonces":[],"publicKeyRing":{"walletId":"dbfe10c3fae71cea","networkName":"testnet","requiredCopayers":3,"totalCopayers":5,"indexes":[{"copayerIndex":2,"changeIndex":0,"receiveIndex":0}],"copayersBackup":[],"copayersExtPubKeys":["tpubD6NzVbkrYhZ4YGK8ZhZ8WVeBXNAAoTYjjpw9twCPiNGrGQYFktP3iVQkKmZNiFnUcAFMJRxJVJF6Nq9MDv2kiRceExJaHFbxUCGUiRhmy97","tpubD6NzVbkrYhZ4YKGDJkzWdQsQV3AcFemaQKiwNhV4RL8FHnBFvinidGdQtP8RKj3h34E65RkdtxjrggZYqsEwJ8RhhN2zz9VrjLnrnwbXYNc","tpubD6NzVbkrYhZ4YkDiewjb32Pp3Sz9WK2jpp37KnL7RCrHAyPpnLfgdfRnTdpn6DTWmPS7niywfgWiT42aJb1J6CjWVNmkgsMCxuw7j9DaGKB","tpubD6NzVbkrYhZ4XEtUAz4UUTWbprewbLTaMhR8NUvSJUEAh4Sidxr6rRPFdqqVRR73btKf13wUjds2i8vVCNo8sbKrAnyoTr3o5Y6QSbboQjk","tpubD6NzVbkrYhZ4Yj9AAt6xUVuGPVd8jXCrEE6V2wp7U3PFh8jYYvVad31b4VUXEYXzSnkco4fktu8r4icBsB2t3pCR3WnhVLedY2hxGcPFLKD"],"nicknameFor":{}},"txProposals":{"txps":[],"walletId":"dbfe10c3fae71cea","networkName":"testnet"},"privateKey":{"extendedPrivateKeyString":"tprv8ZgxMBicQKsPeoHLg3tY75z4xLeEe8MqAXLNcRA6J6UTRvHV8VZTXznt9eoTmSk1fwSrwZtMhY3XkNsceJ14h6sCXHSWinRqMSSbY8tfhHi","networkName":"testnet"},"addressBook":{},"settings":{"unitName":"BTC","un itToSatoshi":100000000,"unitDecimals":8,"alternativeName":"Argentine Peso","alternativeIsoCode":"ARS"}}'; -var o2 = '{"opts":{"id":"dbfe10c3fae71cea","spendUnconfirmed":1,"requiredCopayers":3,"totalCopayers":5,"version":"0.0.5"},"networkNonce":"0000000000000001","networkNonces":[],"publicKeyRing":{"walletId":"dbfe10c3fae71cea","networkName":"testnet","requiredCopayers":3,"totalCopayers":5,"indexes":[{"copayerIndex":2147483647,"changeIndex":0,"receiveIndex":0},{"copayerIndex":0,"changeIndex":0,"receiveIndex":0},{"copayerIndex":1,"changeIndex":0,"receiveIndex":0},{"copayerIndex":2,"changeIndex":0,"receiveIndex":0},{"copayerIndex":3,"changeIndex":0,"receiveIndex":0},{"copayerIndex":4,"changeIndex":0,"receiveIndex":0}],"copayersBackup":[],"copayersExtPubKeys":["tpubD6NzVbkrYhZ4YGK8ZhZ8WVeBXNAAoTYjjpw9twCPiNGrGQYFktP3iVQkKmZNiFnUcAFMJRxJVJF6Nq9MDv2kiRceExJaHFbxUCGUiRhmy97","tpubD6NzVbkrYhZ4YKGDJkzWdQsQV3AcFemaQKiwNhV4RL8FHnBFvinidGdQtP8RKj3h34E65RkdtxjrggZYqsEwJ8RhhN2zz9VrjLnrnwbXYNc","tpubD6NzVbkrYhZ4YkDiewjb32Pp3Sz9WK2jpp37KnL7RCrHAyPpnLfgdfRnTdpn6DTWmPS7niywfgWiT42aJb1J6CjWVNmkgsMCxuw7j9DaGKB","tpubD6NzVbkrYhZ4XEtUAz4UUTWbprewbLTaMhR8NUvSJUEAh4Sidxr6rRPFdqqVRR73btKf13wUjds2i8vVCNo8sbKrAnyoTr3o5Y6QSbboQjk","tpubD6NzVbkrYhZ4Yj9AAt6xUVuGPVd8jXCrEE6V2wp7U3PFh8jYYvVad31b4VUXEYXzSnkco4fktu8r4icBsB2t3pCR3WnhVLedY2hxGcPFLKD"],"nicknameFor":{}},"txProposals":{"txps":[],"walletId":"dbfe10c3fae71cea","networkName":"testnet"},"privateKey":{"extendedPrivateKeyString":"tprv8ZgxMBicQKsPeoHLg3tY75z4xLeEe8MqAXLNcRA6J6UTRvHV8VZTXznt9eoTmSk1fwSrwZtMhY3XkNsceJ14h6sCXHSWinRqMSSbY8tfhHi","networkName":"testnet"},"addressBook":{},"settings":{"unitName":"BTC","unitToSatoshi":100000000,"unitDecimals":8,"alternativeName":"Argentine Peso","alternativeIsoCode":"ARS"}}'; +var o = '{"opts":{"id":"dbfe10c3fae71cea","spendUnconfirmed":1,"requiredCopayers":3,"totalCopayers":5,"version":"0.0.5"},"networkNonce":"0000000000000001","networkNonces":[],"publicKeyRing":{"walletId":"dbfe10c3fae71cea","networkName":"testnet","requiredCopayers":3,"totalCopayers":5,"indexes":[{"copayerIndex":2,"changeIndex":0,"receiveIndex":0}],"copayersBackup":[],"copayersExtPubKeys":["tpubD6NzVbkrYhZ4YGK8ZhZ8WVeBXNAAoTYjjpw9twCPiNGrGQYFktP3iVQkKmZNiFnUcAFMJRxJVJF6Nq9MDv2kiRceExJaHFbxUCGUiRhmy97","tpubD6NzVbkrYhZ4YKGDJkzWdQsQV3AcFemaQKiwNhV4RL8FHnBFvinidGdQtP8RKj3h34E65RkdtxjrggZYqsEwJ8RhhN2zz9VrjLnrnwbXYNc","tpubD6NzVbkrYhZ4YkDiewjb32Pp3Sz9WK2jpp37KnL7RCrHAyPpnLfgdfRnTdpn6DTWmPS7niywfgWiT42aJb1J6CjWVNmkgsMCxuw7j9DaGKB","tpubD6NzVbkrYhZ4XEtUAz4UUTWbprewbLTaMhR8NUvSJUEAh4Sidxr6rRPFdqqVRR73btKf13wUjds2i8vVCNo8sbKrAnyoTr3o5Y6QSbboQjk","tpubD6NzVbkrYhZ4Yj9AAt6xUVuGPVd8jXCrEE6V2wp7U3PFh8jYYvVad31b4VUXEYXzSnkco4fktu8r4icBsB2t3pCR3WnhVLedY2hxGcPFLKD"],"nicknameFor":{}},"txProposals":{"txps":[],"walletId":"dbfe10c3fae71cea","networkName":"testnet"},"privateKey":{"extendedPrivateKeyString":"tprv8ZgxMBicQKsPeoHLg3tY75z4xLeEe8MqAXLNcRA6J6UTRvHV8VZTXznt9eoTmSk1fwSrwZtMhY3XkNsceJ14h6sCXHSWinRqMSSbY8tfhHi","networkName":"testnet"},"addressBook":{}}'; var legacyO = '{"opts":{"id":"55d4bd062d32f90a","spendUnconfirmed":true,"requiredCopayers":2,"totalCopayers":2,"name":"xcvzxcv","version":"0.3.2"},"networkNonce":"53d25e8600000009","networkNonces":[],"publicKeyRing":{"walletId":"55d4bd062d32f90a","networkName":"testnet","requiredCopayers":2,"totalCopayers":2,"indexes":[{"copayerIndex":2147483647,"changeIndex":0,"receiveIndex":0},{"copayerIndex":0,"changeIndex":4,"receiveIndex":2},{"copayerIndex":1,"changeIndex":5,"receiveIndex":2}],"copayersBackup":["02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba","02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5"],"copayersExtPubKeys":["tpubD94LTzAUiW99mpA59nyf6fAHh4xKGmnwbgCV4gU2bRpeN9CRiMSurqme22px5NmJAo6FdcdH883Zu98VbqyhesCJ86kUEjH3Zpufy5FfcaC","tpubDA2U9H6LkRHDRbRxHBp4VTbxPc7JqsvtcLxrE5QJF8z1iT6hMJ1pXSVf57GWRcxXutYvpoXRurDVGsscJauMtnJBkYAWBVExYmm91XQE2zz"],"nicknameFor":{"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":"asdf","02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":"qwerqw"},"publicKeysCache":{"m/0/0/0":["028a4b63f26253f3a8731577b8e1ee480950ad5833ebbf106fe3463bfc07cc3b90","0332efa054c08cb77506a35ee0762cb7156f244566703ec08e433568ec0397bec8"],"m/1/0/0":["0220ad514cf593d0c3905d3bb49bc5767a9410823bf9b77ea5ef2cf1d1016d77a8","02fd42cf66f1dbdc7bbb9ae09aecea72df479ffe5a0c4641301067e331d12e416d"],"m/1/0/1":["0315f7868eaf1f9b7127e3f7e0222c5e473eea003e34700f4758b6873c525d6723","02a2e8ed5e90dd39e3842fc790e06178997dbca319987f365317589e2a71a93658"],"m/0/1/0":["0244a25a0b97b26707fd855c15b046b901be85a3b70a781d0678608e633440eeca","0358cdcbc528ddfb7173b0dab283f702be82546ff031e4a832a7270080cb875959"],"m/0/1/1":["025c9b49bdf17d97bd82ea1b87793082f857247f0f9b999937a166ec994bb1b41f","020389327ee8ae7d0ee3f8187842d23a4070bdd8a27c0bcddd05d80ef39009253d"],"m/1/1/0":["02fd0e7c62b7b58d1ea7bb4cb84d53b019df99d3703a42aed73a2cfa15f3af5d08","0355a15912e76072ef50e6643376b8a9da8422ed4f8ea07b1d84d4989be5a39b2e"],"m/1/1/1":["03bc3e1f4db32efd8eb1fd44a1665938d59628429c67e1e8b7054ab5717f4e6750","03c4c817b633ac31f44f16f390af831d35f7d98744a52a0f23e9598967342255f8"],"m/1/1/2":["02826fe7e9da408480ddeb1d4414c5100b350f862ca718e27122681e1a0ca35077","02bd25af907bb3edbf6b2cd1ea90eaa92cc93ec47bea7d339af44c1d2c05708e99"],"m/0/1/2":["0337a1a70364b94745d6e26d2d28919cf528304f52765f12ef43e3d6da0a6c8dc0","039d83db9aa43e6e00e0304e6971b6079d79dc12d8d55ce2e6fc24a52ba8d41329"],"m/0/0/1":["0359c6d0d0d31f83301169901a6ffad9535f14014b5ab3b43561dbb2436a7b8138","037d06f713f13a11967fd5edca265ff4c77528693a712c482256505693e4890d93"],"m/1/1/3":["02600e5c41670773a213a4cb58c8f2fa3e83840784bc7f0b56925e1075e06632c2","036d01867af5f61371151ef7d9026fa0400a623f6924e404ee0b856625268972f9"],"m/0/1/3":["03e5a9b039b187ca8e065627df402e4a5b196b94198542da7036879de08be63d2d","0304f3e0b70f696d80e5785dc7747d6dcb55ba24c31f2d80bf184b4e582e6b47fc"],"m/1/1/4":["03741afa5bd50d6ba5801064c810fae84f6a4557d6a88ddc8591d0d4eb68a8fc41","0214dd6ce6073b05999fb887098ca6f7e1d0b4fdc0760557786907df353df90d1c"],"m/2147483647/1/0":["033e072a53ea835763a03c66e35c35384736210a1bb7d7ee6d9a3e109e82426b30","02e37b5570c053da8a8ee587be86fc629775c4db890aba2745ccc4e4dcc8c31041"],"m/2147483647/1/1":["0228a6de42ef421c263d1efd9f28d9a7d15a261995028a24eff6b9f1c3fc46e6bf","0226cff885cb0d607cc9cf69a7608316eb3fb2ec344c0c9956246ba776116fc396"],"m/2147483647/1/2":["034fe2a8f0b98445eb5810fe36572ad2f64ed9bf64dc9de624f99c0142cb07c682","02f2c5c758e32293f5c193fd69afadbba83abafb397db01e6f2b447690e900475a"],"m/2147483647/1/3":["02b25ef9434446c51f10678f787e4913de582e34d164bd3b06af7732c5476df1a8","025d51a1efd59bcff22ee2e0af61b21a7ba5f639e20dfdf25690e926005177dd0c"],"m/2147483647/1/4":["03e5734e1d29b2f684d0446b7a2ffbd0ba8952570a502d0d14b1efd8f24b61be53","0258fc28a324848d8d0154e8614815e35c668d274a8f01957bb99aab8dc8f386c0"],"m/2147483647/1/5":["021f9e775246765e1cfba0ae453b4eae6cd4ae5a57a09c319edbe89d4dbbf23be3","02857f66571a1c3eb9e72d22ae88e734c03d448bced4dcfd345c2059468124c741"],"m/2147483647/1/6":["02c072f329391a25255dc6452e5f5220966869dbf736ba8a8c3ae9d273a84bc3fd","030920a8b8e88c4db2871a7df0878a86cf0695f6d96bb50c701c3454f3df25176a"],"m/2147483647/1/7":["036bf329fc19bce10cf1999fae5bfa80290ff7b44776b49c7b0dc9eec6cffcfa21","03955a549875b4f7b9be28b9ff4bcd51ad2bc224430b1634baef890585885d5e1b"],"m/2147483647/1/8":["024879c9c9a261b3141ecfa1c79c4efc25278c844ecd1dcfcb95d9c19581fbdd25","03fb4a5fdb91239df3ccf7f61a5b99e7e72483101e21c9d1ee0d85544e9354c6c7"],"m/2147483647/1/9":["035928a107ec01f78cd586914d5a49710fd42e352b1312e3ad0eeb2c9666fdf8e7","03a54c03093797854829c75357f092356352a109042bbb83bdac20cb4e5eca27ea"],"m/2147483647/1/10":["021e7a3a7efe888c5e820b5cf0f03317b2b4bf438d8563449aeb7a77cade97f136","03ec0960b3d1df52ca3cc2c82b7d97063400da4dd051bba2f9bab6cb44aee01efa"],"m/2147483647/1/11":["035d70c26b7f429861f555f7c0d99947411b23b7f95303fb8d5de5b82a95aa30fc","038b922f7024f5446d6b48e5253643543b35c006d90fd37688105c6cefcd8adb8a"],"m/2147483647/1/12":["02158d6503891c6c65a606221dbf5c68d0832288975914007968419939588ecb24","0248264cb1763a3f4de9b34787b4bc5443ec92ef915927494bb9f1c1c0b498c7ca"],"m/2147483647/1/13":["0349965eea38a25ae0c061faeac4c4e57e648bc4c0f059d07b3b8b7962cbc0dde5","0352243d9269565ce2a1ffdd0b8e43a442c6dd1c9edda86eaaf2cba5a4a95c40f1"],"m/2147483647/1/14":["030fa6e3d0c5cedc0581955395c77cbe134c912a47971023b9695332df3f7bb200","03f2cf09e33326fb59bf3f13e6298d2d5d29c9eae3b872e5a851e8d8d77259c883"],"m/2147483647/1/15":["02bf0d45e41339f552df6f8baf4392142921fd38b0f2a4388a905ff6cbacbc278a","03fabe46bb6706a1b8edfd28c046a8891b4530bbe5305080b72b0d08ebdf7b8c0a"],"m/2147483647/1/16":["03a4e3146ed34d6a8af4e4379e6edcff32cb0373ba232b3d746af3052f674133ac","030311b73c6f5c46ddffc0cfce6e5ed0b671d94267d8e52cd8837f2a479916eb91"],"m/2147483647/1/17":["03233df93c762d2f06c7f5f388e4e0a8dbdb13302acba0d2d6995c487d8aec9f2f","024badfdcb7e772ac7fc1c46d3943b07500edbbece105cdeff3eb9e9fcc9f54782"],"m/2147483647/1/18":["0364035475a098e00eb010c500cad3c90af3e81a4bd613144bc9433a150f14718b","028223dc8142154e7477ce000b3dc13e1d15a901553d9b18864c8645b582b38fe6"],"m/2147483647/1/19":["03971b74b4ac4bdaadf636baa4caa82fe5355471ed6ea05a9cbe5fc6c9e4b9db76","0202ebffacd01f83849e5bc5c0e2c317bc5fb2fbcb2d6d4482a5235f9f1308b61a"],"m/0/1/4":["03005ee9ff028c98fd132e531023f2f2b61ff0d26022f979dd98088d2ba167b031","0345ea82e8dfe38277f0c3aee18d2dd93edb63e8663ac83328a7934d2ca57006f6"],"m/0/1/5":["0391bc4990b71d8a3f156ae7107929ed6372b0b4ba8a868253f71ba7189d1efa02","0312a74cf2e7c0dd41897d04fabfd8cc3187b84a28305cfc79315b24e6fe23a6b4"],"m/0/1/6":["021a38c492607ff9684a4fec445e47b5b7100d3ef9e9dc0d0b37c0a646d28d4f77","03ae0b46ab36f97447ebaa53f2b5c8f090f15395378785f2fd285eeba17fbf3f65"],"m/0/1/7":["0308cdec88c1ffe16edc98853d9c08dbd4ba2541ba566668ca17bda19d7eb3481f","02dd622267c2e68287287b8b61724f76fbe84096a56aa5054af92f8fe25380e2d1"],"m/0/1/8":["039647da9ad725836bcb28a3e0497659a28d7749d1416c421a0a01c62d237ee962","022e22aa61eafda0dd8820427f1a06314d352a15ea8645e7ab9b80920017084d82"],"m/0/1/9":["03a4ade946076c6962b70c70ac7fad3a87efb59a1d0a4e32bda13a6d47fe9df961","029a07235aba04ab69526e117d836d5b3fae5cfc8c5e72b10c6d1afd261ccc19f3"],"m/0/1/10":["03c78e9b6493b22790db1acea20df9444e0f9c424fc5756e7a32c290ae01783953","0254c130ee467a96570c9f5ebea89de04f0b1db1686b164f2694339bef8f25dd88"],"m/0/1/11":["03a762c43318ef8d4840fab04c8db73797dc648825fac60f2730b4c76678df1cf3","0212c684a4de8e750ad2dfe2b136370ab9803eca178ed9a27b3990c29b067de35c"],"m/0/1/12":["02702d221f9b15c5cf75ac2f497a6c63e60213087c3d2d3be46768e3ebd238e26e","03ed58580744deb357258e44548212038670769d8d51e385d4fb8414311fd01b52"],"m/0/1/13":["0320e0597b54c62768352f433389cee4725d6094d7bcb5c72265edcc0933829aff","02c5706f11b9a85f3176c572842b7c9812c2195058d24d945bc026b00312740e76"],"m/0/1/14":["02fe43077676b844226d3aaa62e8a86d237710d92f882366944acbde0c8992fcaf","039a6a8662abb8910741cf331320549665e9feb28ca94d1ab6a43c84fa330b94ee"],"m/0/1/15":["0369f99f72847af93d50ab8ee75b6e7e912d26e27be96f6d6b7215cf7daeff7ba5","02521700cc07c953ba5aa586fb0e4795a34dffc68c5fb43e038be3866e40f4daed"],"m/0/1/16":["02f67d1d89bd8fe2f91c5b973cbdacfb4ba440e7656bce284cf73d549625607347","035da9cfac5a803dcb2b283b02a2515a4a1bcbf3d19e0d180aee8fc30193bc0555"],"m/0/1/17":["02c024ec199d240e8d6c66276b94b91071f7cdf2bef540c29d6d18d25de7b1cf7c","02190865f9dafae3f7f05c093463be5632946422ddda0a6fef6904390792516067"],"m/0/1/18":["035ed504d7704ad984a333b8eb0fceb8be043da9284de31ed84d9e68d90c75507d","033303c415b50421732402df00f4baa219f334647a7eb5014b9f8079864d6ab558"],"m/0/1/19":["02ce49fe86b0eee73663b1ee867b16b97c876af26f12764c528a2e6d0eb55ad3d7","03ab969bc81796b88e44c340d854df955fc60ea17ea92db5d3115595d6dec890d8"],"m/0/1/20":["03e2fa915378cbdffa0d919b0fb50c7256ca731b9d571b3365e486893a1d43079c","038d058b895cf084dccfcc9367e4796a5cf4ddceed6c35f6885d75c80119613350"],"m/0/1/21":["02fcb1bf644446b5b42205272af72f0aeab9e92ca29aafa91c5fb69142764017aa","035c5fe5c8811603279a5b72b6c30735d702817db1eab937c622269e28192ffa90"],"m/0/1/22":["03b39d61dc9a504b13ae480049c140dcffa23a6cc9c09d12d6d1f332fee5e18ca5","022929f515c5cf967474322468c3bd945bb6f281225b2c884b465680ef3052c07e"],"m/0/1/23":["03f40b82fe8cacff08879f13c45f443a3dc3ea98e1d75d5f32a19f5e5a8f7a905b","028415ee458e4dcfd440ce969726f3b58ae74fb6cf3995ced099579211e7419844"],"m/1/1/5":["032748a6282e21f571b8c8dd49e775deb83c90fcf88dc4ba81d878536973709c3f","020837cd68f14ce571b335eecd1b6fa0af43e1576dd9721aaca2a8ab639ac6b7cd"],"m/1/1/6":["0337032efb013dc92bb8dccfbdda9f5c28f0039a9c60953d41003d095e9f9778af","03ceed2da6b9603297061dc8eb930112ba726b2ccf5eec67f4866a05ca4049a22b"],"m/1/1/7":["0383c96ac2af7d203f69133b2fab6b68366b5075ad6957fa06759df3b20fbfec70","0311385f79834cedaf2230a48c0f9dc8e794da1869fc595db2518d62debb85579a"],"m/1/1/8":["03efc649680280f4e4df96da923bc88330275004125ebe5483c2f3e05ca52e19a4","02803c02d197d780388259afbd001ae41fa3eb3e2bac9627aff540521c184c3b23"],"m/1/1/9":["03af2fe6aa027a76b42c1c4050a040bfd026ad2daec1bb96a5fe2d026a7df919de","02ce14163047c640228796fb1f72bbe3afb05819ad141598a4f021058a6f79dd3b"],"m/1/1/10":["033770378bd762cf0408e44e4e604bef77e336170428c506949b1a4f1f2963e574","02c58ed43946f699dbd3e36d3e9aab2714cadeb19ecd3a56e4328c50336b4a76cb"],"m/1/1/11":["02898a1545fa19bdca92adc498698d27b86529cd4c08946d9d29604734b86f31af","02b402767a045ede072600924401c0d720000b2ed59fa444bfdbef4a5f1cead745"],"m/1/1/12":["039b8659430be49913e2cd869aa8c99ccf49a13df35837370b792033dadb891483","03264e63df292257cc76babb15d15bef620d1c2f8c3bbc78d6ea02d127e5ee7386"],"m/1/1/13":["02381a559791b8e86bf546e2c718ae63cf24eed0518a58e4d4a4b310adf2cd38fa","02d7f8283a4418d912508901b4a3db0d2103206dfdd74b3c75648671e20ecfd445"],"m/1/1/14":["020376e8c550b7d9faa0b2da947a2a36fab22c6e8190b6f99460b6022017bb97d7","03fbc5299190e6628de28c92aaa12e3a131b21eb7266462c46fbedeb86fa878055"],"m/1/1/15":["027209fd3b0cf7368180a5dbb16b928c997d33fccb78505d48440c7d23eadf5460","03450bfb22858726cd7e228e6733f69457546978a95188565c53e0d1c0d6070ea8"],"m/1/1/16":["03cb355ba04f64293793855121bab5831f84a3a3edf7cd31fccaa6d67c407a4912","028bc897a39c1224610b765a80f4cd8ab79cb37776f58fec9c10ac6f649d1f3c72"],"m/1/1/17":["03f4cb0564d7e2c6b85673503b7954db22779f29a8f3374904573984e318a96bf1","037c11b6ee906d84aa7eed359d758d986d912b6f8e5cbb1acf0982a77b3ef812c4"],"m/1/1/18":["02d2e5798f33f6889472857744316f2d253f25f88379610063f40cfe5798d9858f","0253cefdfe9ca987cbf1c950b6246d5b7a194d8dfad47c3a78dbbc5c1d01511d97"],"m/1/1/19":["0336c325f5aed366ffc10d553f2bfd4d69e66cbe1688d77af14efc8827aea2e318","0378b1b9a6074f9f2ab4fa9ad1e14649c621b0c8124a1b148914d3c10e6ab390c6"],"m/1/1/20":["03ea55740a734689ce778a8c00df8ebf4274c8f66de7d05646fe5c927773ff7f2e","02275b558d49aef955b6dee51a3c0a53f4b076b97bb3f26abcc82540168ec87cac"],"m/1/1/21":["03c77869c9984664eac9c238f4b6d806c9f48ca8a736c48450f398834db2aa915c","02d984f548c7f60c09dad3287cfc48807bc8157123989636c713be61be6a2e9ced"],"m/1/1/22":["03ed7c6a3c854c1f9459891691cc32671402f9e47126919878251e568dbdf353f8","02a113dab22cd9e46967b3fd76b9b9ec1d227d88817a9300e42d332cca2a0877fd"],"m/1/1/23":["02ee186432dcf69fda50a6fdbd94651817d8a271c273a5b70cab3ec4ae77a3753b","02291370aad9de0dac676355ced64e268b0c431a51f42f12d13f5144940fce4285"],"m/1/1/24":["02bf71435e84e66547c8c583d5ba226a5ac4d935e0a9f9603ecd8925c3e847e91a","03578d8657d285a89d9d597632db662cfef9baccfb55c76b1e87948a94fc9de30d"],"m/2147483647/0/0":["02a8425bbe23426219065969f695a6c3e242b24e57226bffdd542be8fd6be968c9","03057a42fdb6569fb1615b173ccb702453db2eac5be4291b82d4511461eafbed87"],"m/2147483647/0/1":["0250c3d3e86e332010c5233c2ec3bc728026002f0037cb3382d6318409b0e70796","02cfac1e7c4c88191201080f8316af52d9faa6ba624a6e160279e9fac4d1cf79a9"],"m/2147483647/0/2":["02a8c266a5b92eb50c8be91f95e4d1ad968b2f57d527377fd642d63fb84474f61a","028cc954ab31bd179ff80b8a05f95430ae534e61b3ff35f5284fa2fbe1832ceccb"],"m/2147483647/0/3":["02f719e1a7ab00ea98611453fb03d44c1da04655bed74af392534d70099039b4c2","03bfa548bfd4718c50bfce173f780eadcfb679d9c0206c91a2fa1879a9cf7558b2"],"m/2147483647/0/4":["0362c0695d397ca26bf47f0e641bb3cfb06ff29ccac2e1d56ded3afcf88b1e688d","02f9d87b05bdb3b9e82f506b43f813041c0e403274adc23d11e5e1651e34b606c2"],"m/2147483647/0/5":["033731323032d4ee08e858fc71f93970444333e183a1d5052e1d08cfb511e262c8","023e12556cef67ade35b7758916b5e1a3ebe074ccd35c5d8eff6b01321f63eb495"],"m/2147483647/0/6":["025d11b90081972bc1c258c9d6f476dfc2f95b69f0e9935322bf9c21deb580ff64","02b065f56a378907354f0738a0ed74f10660c6b5dd68c9f992093b75ce3d7d8b72"],"m/2147483647/0/7":["0210e721e8a35db9d8c855a0d346f60c09208f3be80b39e03af2c29db777332c71","0277f352969fadb1f1835f9a0fa99c6a3c7b6c281be5b2794c88a708eb177ea33d"],"m/2147483647/0/8":["02998d8d41e4215cd2a961a415a3ed0b1f984f1627719a7b102a75864943c4d87b","03d8ed7fc8f68a77f68d3afd007b7aa4c89944195143630ce183f0fa5438f2b559"],"m/2147483647/0/9":["0324fa91737588e4f85937303ce65c3b91b5f2ae506a72d92b83e3f5f9aeeb3c6f","02a011be72c4a400319212228106af278823a97acfe0a67e1ecd866d446b315114"],"m/2147483647/0/10":["025886ba287922a904881c7315e6fcc410a7976741771a5937d3a1a01b529f21fd","0243bb91ceed9d29d0c2ca66a8ab77e82110bbcc023beb4106f787964f44a0b972"],"m/2147483647/0/11":["0369d21684894cc2d4b2f5e581ede3cac9e8db4161a08e7737c1be129bb673d3d5","03c9ef27e3cd3dadc078fdfd9936a7ad9bf7954747085cf8f8a2a5bb3431f68a9f"],"m/2147483647/0/12":["03a73b8fd859bf6acebffdfffa2597199091daedd2c011ac67fc3494d8a1a8ceb6","025a213f7771c8be03f43f2e7f469ad4ef2cf6907ea284b227a786d1f55dfa7144"],"m/2147483647/0/13":["03a09f7ca257e1ab263cd5e6b0addc3ff868b93df132321d98775ca3505efb576f","03454c715739164bc55f347a651439cdf3ec146b35d2927beb60e8290b3916e082"],"m/2147483647/0/14":["03a64b1f7bd94a6b1a6e84ea444e0ba04e9deb86460934ccc37c0615a134a8257b","02794f09210b1811a455f3e1c7bcd35c76dff2523190fef9615eb27e2376acac1c"],"m/2147483647/0/15":["0392dca2fd9a3bc2b2a7d90a848719069fbc5f22bff7327bb8186c032514085263","032ee8a33ea76d70c7ae839448ca6c5b1af89146f2922e23ba1822df42dbc7e66a"],"m/2147483647/0/16":["031a22a1a3c1abad7c4d782ef6ba3cc00f2e8fe549eb33e0732200aff6d3174831","03bdce9781289e0c31cf727f4c93fe46f7930dd8fd68f818ce241f1ede268e8e0e"],"m/2147483647/0/17":["03b12d27e9aea2c2ad598e54e40860a705ac2ca2427aa511b501b38ec368ea5c7d","03e60d35d84d4536cad895215256b312bb4879a8d417251c279995e58f25da3d54"],"m/2147483647/0/18":["0380266cc9a9673676ad6a1b2e7148766df9c25b4dce299e5edc4f65b72aa58e64","0329e2a8a48c06c0c45dfdd2ab33e6455551557d8ebaf8c12fdf7470f8c45f1d28"],"m/2147483647/0/19":["036fe62af85560d7eea7c7af55e60b32a97dca80134d0aedffb19eb2705b9d6e01","02381c2c30b9f81e2a53c69028fbe11803acad0420b267719b7a80870be0baaeb7"],"m/0/0/2":["027bf94b8fc4e9b42683af25fda125ccab8760040717d100270dd4afd032692daf","026382c6c9357250d96dc21e43c053857a64efeac1887fdcbc107fbe3ecfc6115a"],"m/0/0/3":["03fd203acbd9af3cbbfb709458f8952078234a36094f12d00372e4b2b14cfdf419","03f2e5db59aea5dc89f53ac2a9f4ef66d41265c45afc5d763e0ca61ab70c7c61ec"],"m/0/0/4":["02a1d7cf4fcdbbf4de4002b844c3bff1639073f1cd6e5c4a4e02596b45d3f518c2","03b5fba813294e6ae096ea158833453caa5a945609b0a554696091b9b152bb0f7d"],"m/0/0/5":["0261d37e3b56ef4e106c59753037f516a4b1c45e056b2a3e00f8b77f15aaa7f8a5","0256a55e66e0de1603f0d600c0eb5f5486cf3512a776a36f3ab0d1941fc0dc9b09"],"m/0/0/6":["031db2826af215fe6cbe3f6e121b0497840fc49be133cff0a4d4eab679d6b99d70","021dd722c3f35dd04fcdb57f09b76c723d521fb36751de03ffd08096ddf1dc1f86"],"m/0/0/7":["0354ea75bdd9eb5beae7262e4a5eeb58bd10103ee0185e85b749ea39f6615d0f62","03f2c8f3b6478c0501a8578d5caf5ac2974f8213fc5e699d62dd2af58fbe8781d4"],"m/0/0/8":["0282e67df3bcd1e1662469b4c3151fb50ee1e46b75d787d91184c16b9803131f82","02921a7054af1e425f4137a5eb6b34d1f2b9d81c2625230194bc30657bb4277e11"],"m/0/0/9":["033e7e387933983ceab37c8388bd8ebc5119760f493ffe6f083bef0e5dfe22891d","02d660d60cc55d80912e0745cb142a8596a4604fbf72f9aadec0599aa2ed62461a"],"m/0/0/10":["022ce5b2750ae34512199856eab9e912dc25281cd8b88e7688a46c3b9a389701cb","02f14aa1608fce3b6088148709eb5fe72b61699c931fa8d95a45fab1106859d1b0"],"m/0/0/11":["0288dbef3302c1bc5556028adb33e2f9e03c119dbad4f706befb8ce86cea459f2b","03f13ced465e2e0a3aaa8895f3185d5711e0bebdaf507610b7a669ac8fc82da8fe"],"m/0/0/12":["031ab4677885340d2f927ccc9747f4346b79e4eb6c750695095a8a2524610fa94a","038c881910fbd8b50d193db4e0c84f5b7840820397f92cf0718a8e06d027125503"],"m/0/0/13":["031b568452cba22eb7a88c6085489e53e35abd16068882e71a140e47e12dee9c61","020d09885ee362101d12d34ce0918d41593634db1b9413e5415c6755753b9330e8"],"m/0/0/14":["024177bc9aa03cfc72eda2dfddffd7fe9d0c2f007fc3ba1a48280feae2b9fb117a","03394ad321668440c08da76eb35475ba3a8c0e8cbe0ed81468673a8c72d38fe457"],"m/0/0/15":["02037b1cc696ffbe9eba3684edd53653386ef6cd7728401c40120037593a4c2ae2","020ab8d6900ec9c11ca5d96dfc0ce7cf0ee71653a7c45118e89abb4b113147e53a"],"m/0/0/16":["023bcbb8d4726a546087cdb83740adf0ace879b7195a572c652fa8ce4dbe195a04","0392721b230d5163d28b27fc7e059b875711f12b3da448eabe7229bde57530e637"],"m/0/0/17":["02498ee74e849d3e9261dd1863038caf83d6a3bc2eeebecf17055d4bab44dee77f","03d4dc104b2e0981693e8097437de9b05334a85e2c8edb02783897859bdbc93e32"],"m/0/0/18":["0218a9f524fe54abf8c3afd21314296cfd93eaa9227acbd457e6c9a742dc233cf4","03760f3d0c5db969bda698ff9352e3b7c332216c34825f4c6e857e39c9aee7cd35"],"m/0/0/19":["033dd51f7737f0e9db79f5c38e4298bf3396346904ef3933d290a22e5b77048d9e","0221b2eedccb9a37515263071550069b3b349a166f0f131d0028e8600d9a2251b9"],"m/0/0/20":["02cb6c39161f3244d7769f7ab96346cae2cf21cb6f4538f5e7382d363dc2f836c7","034f7bda4d1e9ed6a3774608a4d6cd8582ab59fe3187f8a7a7cf914d89426ebe28"],"m/0/0/21":["035490549d65f1360f10340037250b171470ff4c86966318a2b1eead6d8b969aea","03f6a04f6fcd07a4f32c82d53710ed30e0f54d43d41c67c661d158b3d0830c3ea2"],"m/1/0/2":["02972eae7e4302e319c266578e14a07839c1e788296a92906e6d66d938211dad5f","039ed6b488f1571ad6527acd6b6c5b8453eacf6665dc5cb7852e33d1c8ea73f9fe"],"m/1/0/3":["02bec4728888c2c045108353994bae5731ec7a7b41459023b0023e10b8d616bd30","03ce1efe16214c9eac595382e46a68143dd11a335b3f7c971ddd719ac544a5fc4b"],"m/1/0/4":["030e2df1d341568225d8dfbe5d07e98dae9f90e0f43e19dcc68c998a6ed7bcc1f0","0380f4c07dc84faf42d51779f104aa6e3b5c3ce2d7684b3cb76d49faeefc2b69d6"],"m/1/0/5":["029a54ddaa25f433b493f4b72df8c1d41be2c4d2963b8b61ee63cc86d16c12d066","021567c95e0317442e7367aa4e3378dd46c5bcef5860f789272fea83b917de0669"],"m/1/0/6":["03590320d80b61cc0874b579f467c9b5ccc50d9ef875bcf6bdd12e2d0c211e8973","03ee4677b6ee89a9d355851f2230506c6897ff219062c0df4ad9a85c60f3535f93"],"m/1/0/7":["03caf98ab1c9b79d1dc8029453a6137c08787b04043b79af3cb42d41d2d3f1338f","023f39ae4e2f4f3887d5fc58e0d3a0d7ee267dc04aa257c75b6b2d67d2f5580f81"],"m/1/0/8":["0352a2a3ea8209c9a2b633d788796ac2d16c08022440e04a77ab2835c7f971d266","0291bc248b3da997f35e8fae98a75a91fdac2819d74c4e270899338d48f7389e87"],"m/1/0/9":["02468d32d9c3c62418d506d4cd0da6cd2022d5bcafdb5f847cf7bde7a48ec6848b","032713d90d12eb6a072f3c1db6c0d3b680d3f78883016135fc0f78e8193d41d4b4"],"m/1/0/10":["034863cc6bab9b059be53413ba75c5fc286647c20d7f9e5512ef4754ea301dd1ce","03a33ab9c32a2264ee2464ebbb5892f0e34acf0fdede4f87395a89e9dacdd4930e"],"m/1/0/11":["031e19296695bfe8a96ba3bf58afa805ee1bd5471fddb3929b1678d69d442d69c9","0270feb33956fd9e937019d629523e26437493c0856514011e6aec88baf7721295"],"m/1/0/12":["03cce695d3c3843bf73e851b2446a77d7e235e5b80b4f4474f9946292eb8218742","039ea96c8822f0ec7ed28308d277f3e730480d7573579cd11b89aef4364cd9ffeb"],"m/1/0/13":["02ab4ac38eb405e822d12c0f0f354f04f9ee1d991dde887a5c1171096fe503158f","036809e60cae1203da8884ea1f85d4669ce6e053f8ba605d775e271b70ab4f6787"],"m/1/0/14":["039d61da23a8610fa0ee58eb37d7cea7ea9396c79153da97280ccf5e46718e3bac","03015c27bcc778682781fd6ad30aa6041db0b7e24270818cdceece0043ccc34b26"],"m/1/0/15":["03c088ed669132835d2728b0ecf294271c8388988c6ae264d43ca24f50e4005f81","03e2c118c9445a2ddc4c8afeb0ba49e21be3f818a483d346418b8922b8a371a2b7"],"m/1/0/16":["02bba7df9847f463c6b23eca37a4bd6efa3801a52b8ddfad804d902e783b70c81c","03764b657f23996e31c64a701facc1cbeb0c9edfdd605e2c1ed36cf48197565d45"],"m/1/0/17":["020445179c522295b89bf4bfd582eb03422e3fa20dcd29263925e9f44282d476d8","036e47bdd32f3061aed1c1f8c2a32b038c7b72391cb1f80ebfc150e58f88372766"],"m/1/0/18":["024d88c4bfcbba713d49e1edcd035234aaa1ee76ad7bcf75bf074a16658a6b0b6d","02b861e7a20d89f6875d2e44c78dbadb99503e282e5e60e9f65657af6fea81d425"],"m/1/0/19":["023a8ca9d5300181f157e1930d3b0800eebe7683d8df72e6cbf28834dbf1be5d60","026053c4f84c10d15890c0b254522972931bc2d5b7cdf9c1f9f3137c22edf3ecd3"],"m/1/0/20":["03137c66e9f3d61aba659f408d77a293fa0f3fea4ccb911074a681d6f61a55d023","0291aa1bbfbef59b16b0e37e185a706c589d448cb02e860c5df9c9d7242ecc739f"],"m/1/0/21":["03c08673e0cae55318bc9dcc4b5f11eb3ff71d42de04015e255dde3fd8cba7e09e","02423d4eab06cd5b26e71d145283523c011d58032700c517f00b328d2c90cf109f"]}},"txProposals":{"txps":[{"creator":"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5","createdTs":1405543144016,"seenBy":{"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543144016,"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543144645},"signedBy":{"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543144016},"rejectedBy":{"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543170040},"sentTs":null,"sentTxid":null,"inputChainPaths":["m/45\'/0/0/0"],"comment":"blablabla","builderObj":{"valueInSat":"29000000","valueOutSat":"8900000","feeSat":"10000","remainderSat":"20090000","hashToScriptMap":{"2NBtv6DdXj8HBunyGqpW9H8bUtW5x3rfVTj":"5221028a4b63f26253f3a8731577b8e1ee480950ad5833ebbf106fe3463bfc07cc3b90210332efa054c08cb77506a35ee0762cb7156f244566703ec08e433568ec0397bec852ae"},"selectedUtxos":[{"address":"2NBtv6DdXj8HBunyGqpW9H8bUtW5x3rfVTj","txid":"a9f4dda3f092e37244bc4e77ea921fed01d5b8ea49613dfdc0dc8afdd70190b5","vout":1,"ts":1405543855,"scriptPubKey":"a914cc93216398b77b5f8c451ca3a357bef961678be987","amount":0.29,"confirmations":0,"confirmationsFromCache":false}],"inputsSigned":0,"signaturesAdded":1,"signhash":1,"spendUnconfirmed":true,"tx":"0100000001b59001d7fd8adcc0fd3d6149eab8d501ed1f92ea774ebc4472e392f0a3ddf4a9010000009300493046022100ccbb8f398f74a76236629b8499ffc6f9518a2091f5a61a9a352c0a10f615961e022100b8f0769c76cf33bec3d7f81d9da2b74cf6e8a5e0a24ee5f48172854d8bcdbfa101475221028a4b63f26253f3a8731577b8e1ee480950ad5833ebbf106fe3463bfc07cc3b90210332efa054c08cb77506a35ee0762cb7156f244566703ec08e433568ec0397bec852aeffffffff02a0cd8700000000001976a91485eb47fe98f349065d6f044e27a4ac541af79ee288ac908c32010000000017a914560c292066792531164149c5ed63ad2793a61b928700000000"}},{"creator":"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5","createdTs":1405543188745,"seenBy":{"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543188745,"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543189341},"signedBy":{"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543188745,"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543206819},"rejectedBy":{},"sentTs":1405543207304,"sentTxid":"169bc92693dd2e27724eeba81e54210e842035bd3af6c52e6a6a5e908f1a4f66","inputChainPaths":["m/45\'/0/0/0"],"comment":"que parece","builderObj":{"valueInSat":"29000000","valueOutSat":"9000000","feeSat":"10000","remainderSat":"19990000","hashToScriptMap":{"2NBtv6DdXj8HBunyGqpW9H8bUtW5x3rfVTj":"5221028a4b63f26253f3a8731577b8e1ee480950ad5833ebbf106fe3463bfc07cc3b90210332efa054c08cb77506a35ee0762cb7156f244566703ec08e433568ec0397bec852ae"},"selectedUtxos":[{"address":"2NBtv6DdXj8HBunyGqpW9H8bUtW5x3rfVTj","txid":"a9f4dda3f092e37244bc4e77ea921fed01d5b8ea49613dfdc0dc8afdd70190b5","vout":1,"ts":1405543855,"scriptPubKey":"a914cc93216398b77b5f8c451ca3a357bef961678be987","amount":0.29,"confirmations":1,"confirmationsFromCache":false}],"inputsSigned":1,"signaturesAdded":2,"signhash":1,"spendUnconfirmed":true,"tx":"0100000001b59001d7fd8adcc0fd3d6149eab8d501ed1f92ea774ebc4472e392f0a3ddf4a901000000da00483045022035423cc74824ba904907678dda3b62a20a787b96d1b3e9f3e9546f9c57f4e45902210080a1ff1c39f458ac1642b9e948bd62fd70563b5252e749cc8fc642cd763ee830014730440220524a13f36cfb03caa246d7d84de634ec9386f2c39c19bfa926037f48da86262b022050e58a6503d105ad2805f86806810a1aa7f20d6271e1340b42fa91ab6a30f3e801475221028a4b63f26253f3a8731577b8e1ee480950ad5833ebbf106fe3463bfc07cc3b90210332efa054c08cb77506a35ee0762cb7156f244566703ec08e433568ec0397bec852aeffffffff0240548900000000001976a91485eb47fe98f349065d6f044e27a4ac541af79ee288acf00531010000000017a9146130a9d51f996b7a1b9d3e10c80930834251909d8700000000"}},{"creator":"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba","createdTs":1405543505848,"seenBy":{"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543505848,"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543590221},"signedBy":{"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543505848,"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543590221},"rejectedBy":{},"sentTs":1405543610315,"sentTxid":"6fe851b54b777a75fe80fa204dc674395e2af69efb1f7c0017e909eb82c3d914","inputChainPaths":["m/45\'/0/1/1"],"comment":"mandaaaaaaa","builderObj":{"valueInSat":"19990000","valueOutSat":"19980000","feeSat":"10000","remainderSat":"0","hashToScriptMap":{"2N277q5r8Ab6XLJNCjXXFdh5itDJRQCv9ts":"5221020389327ee8ae7d0ee3f8187842d23a4070bdd8a27c0bcddd05d80ef39009253d21025c9b49bdf17d97bd82ea1b87793082f857247f0f9b999937a166ec994bb1b41f52ae"},"selectedUtxos":[{"address":"2N277q5r8Ab6XLJNCjXXFdh5itDJRQCv9ts","txid":"169bc92693dd2e27724eeba81e54210e842035bd3af6c52e6a6a5e908f1a4f66","vout":1,"ts":1405543157,"scriptPubKey":"a9146130a9d51f996b7a1b9d3e10c80930834251909d87","amount":0.1999,"confirmationsFromCache":false}],"inputsSigned":1,"signaturesAdded":2,"signhash":1,"spendUnconfirmed":true,"tx":"0100000001664f1a8f905e6a6a2ec5f63abd3520840e21541ea8eb4e72272edd9326c99b1601000000db0048304502206b18b3dba2646c552469d8ef52d7656f6a65f563032530f622abdfd8bd4c5cee022100e804b406eddebbc827646141e74dc64c76a770ed4e35183ffd35d265ad9f7d3b01483045022100f6c013638ff0a316b1baa93dfffba6a98cf3033c133e8bd899e933c9c3e47ce10220530f40e7ea52ae58bec695edbec6d566d2ee8e7b5f33f95e33093ad1e29a125401475221020389327ee8ae7d0ee3f8187842d23a4070bdd8a27c0bcddd05d80ef39009253d21025c9b49bdf17d97bd82ea1b87793082f857247f0f9b999937a166ec994bb1b41f52aeffffffff01e0de3001000000001976a91485eb47fe98f349065d6f044e27a4ac541af79ee288ac00000000"}},{"creator":"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba","createdTs":1405543781381,"seenBy":{"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543781381,"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543782017},"signedBy":{"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543781381},"rejectedBy":{"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543794590},"sentTs":null,"sentTxid":null,"inputChainPaths":["m/45\'/0/0/1"],"comment":"1","builderObj":{"valueInSat":"29000000","valueOutSat":"1000000","feeSat":"10000","remainderSat":"27990000","hashToScriptMap":{"2N4eyXKikdnnUT4S74MRNAYqXChhUYmZ1Sb":"52210359c6d0d0d31f83301169901a6ffad9535f14014b5ab3b43561dbb2436a7b813821037d06f713f13a11967fd5edca265ff4c77528693a712c482256505693e4890d9352ae"},"selectedUtxos":[{"address":"2N4eyXKikdnnUT4S74MRNAYqXChhUYmZ1Sb","txid":"6c9da5b0da4bab0d576033325e987b10ccf2b9bf479d306b6aae36efeaa56892","vout":0,"ts":1405543698,"scriptPubKey":"a9147d274ac50968d7823b6cbc1b38770deb7157995387","amount":0.29,"confirmationsFromCache":false}],"inputsSigned":0,"signaturesAdded":1,"signhash":1,"spendUnconfirmed":true,"tx":"01000000019268a5eaef36ae6a6b309d47bfb9f2cc107b985e323360570dab4bdab0a59d6c000000009200483045022064d877bc5171fbaef909c2a1a924e0023b3ccc0b530cb46653f06ecb230283e8022100bc6658d60ad4f7120d9226c8f6eada87f3b0388f73c458011988bab36e78ba15014752210359c6d0d0d31f83301169901a6ffad9535f14014b5ab3b43561dbb2436a7b813821037d06f713f13a11967fd5edca265ff4c77528693a712c482256505693e4890d9352aeffffffff0240420f00000000001976a91485eb47fe98f349065d6f044e27a4ac541af79ee288acf017ab010000000017a91421c4a435d9ac263ec55b35a1a5ca95e979639b9b8700000000"}},{"creator":"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5","createdTs":1405543835343,"seenBy":{"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543835343,"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543835968},"signedBy":{"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543835343},"rejectedBy":{"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543850998},"sentTs":null,"sentTxid":null,"inputChainPaths":["m/45\'/0/0/1"],"comment":"2","builderObj":{"valueInSat":"29000000","valueOutSat":"1000000","feeSat":"10000","remainderSat":"27990000","hashToScriptMap":{"2N4eyXKikdnnUT4S74MRNAYqXChhUYmZ1Sb":"52210359c6d0d0d31f83301169901a6ffad9535f14014b5ab3b43561dbb2436a7b813821037d06f713f13a11967fd5edca265ff4c77528693a712c482256505693e4890d9352ae"},"selectedUtxos":[{"address":"2N4eyXKikdnnUT4S74MRNAYqXChhUYmZ1Sb","txid":"6c9da5b0da4bab0d576033325e987b10ccf2b9bf479d306b6aae36efeaa56892","vout":0,"ts":1405543698,"scriptPubKey":"a9147d274ac50968d7823b6cbc1b38770deb7157995387","amount":0.29,"confirmationsFromCache":false}],"inputsSigned":0,"signaturesAdded":1,"signhash":1,"spendUnconfirmed":true,"tx":"01000000019268a5eaef36ae6a6b309d47bfb9f2cc107b985e323360570dab4bdab0a59d6c0000000092004830450220302baae7de2e0f102bf3af2d5f450f673e51bd143020141a769ccdcdf16af188022100e7abc087c76050ed649e7139a5a136969e74e24a8d8f6223d3219ad033a26451014752210359c6d0d0d31f83301169901a6ffad9535f14014b5ab3b43561dbb2436a7b813821037d06f713f13a11967fd5edca265ff4c77528693a712c482256505693e4890d9352aeffffffff0240420f00000000001976a91485eb47fe98f349065d6f044e27a4ac541af79ee288acf017ab010000000017a9148b102abba0729fb0690c61cf7187064d692d43d78700000000"}},{"creator":"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba","createdTs":1405543869803,"seenBy":{"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543869803,"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543870411},"signedBy":{"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543869803,"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543890406},"rejectedBy":{},"sentTs":1405543890913,"sentTxid":"6a0f61574ad65e537e7e99298968db565f97b894b61f4c8f8fac8fcaedb83e2b","inputChainPaths":["m/45\'/0/0/1"],"comment":"3","builderObj":{"valueInSat":"29000000","valueOutSat":"1100000","feeSat":"10000","remainderSat":"27890000","hashToScriptMap":{"2N4eyXKikdnnUT4S74MRNAYqXChhUYmZ1Sb":"52210359c6d0d0d31f83301169901a6ffad9535f14014b5ab3b43561dbb2436a7b813821037d06f713f13a11967fd5edca265ff4c77528693a712c482256505693e4890d9352ae"},"selectedUtxos":[{"address":"2N4eyXKikdnnUT4S74MRNAYqXChhUYmZ1Sb","txid":"6c9da5b0da4bab0d576033325e987b10ccf2b9bf479d306b6aae36efeaa56892","vout":0,"ts":1405543698,"scriptPubKey":"a9147d274ac50968d7823b6cbc1b38770deb7157995387","amount":0.29,"confirmationsFromCache":false}],"inputsSigned":1,"signaturesAdded":2,"signhash":1,"spendUnconfirmed":true,"tx":"01000000019268a5eaef36ae6a6b309d47bfb9f2cc107b985e323360570dab4bdab0a59d6c00000000db00483045022100a8ce7907f9fd7dd41dd65c2dec425e008efea06ee7c80787c10c0e210fbf181302207712c0fdd1cb25836ac1fc2fd303c1e26b85e8980417719b9ed50e977a9693ec01483045022100d1780c4f028cd898920aca3eaceba352ed9306cd17f019ae2f634e8facad149a02203c84ab2093da8e22577e93f27a732f0728d4e6db0c749f3cd3d898d6a025152a014752210359c6d0d0d31f83301169901a6ffad9535f14014b5ab3b43561dbb2436a7b813821037d06f713f13a11967fd5edca265ff4c77528693a712c482256505693e4890d9352aeffffffff02e0c81000000000001976a91485eb47fe98f349065d6f044e27a4ac541af79ee288ac5091a9010000000017a914cc1cab78458b1a951b91c6dcd7eeeeb682f506388700000000"}}],"walletId":"55d4bd062d32f90a","networkName":"testnet"},"privateKey":{"extendedPrivateKeyString":"tprv8ZgxMBicQKsPdWUAmaaopPftevC72Jtiu19V8ee5XijL9JvogqfR95uVrL85f8yBdQMq3KyQtG3Q91yWQb3XDbWWpcdWFDAmJ7Xy2XWkGJu","networkName":"testnet","privateKeyCache":{"m/45\'/0/0/0":"b6fd8d1a079efd523da34f31ba81f544fc3d0a728a8a98299d8980682518e79c","m/45\'/0/1/1":"0f4d52d2a99e4c8c1c2edf09fef12407c3abd2304b961198c3f131a8c8443a13","m/45\'/0/0/1":"de5c191c343bd6017b98708c03344849624a14e2c167cfd6eb8dcb075d139293"}},"addressBook":{"msj42CCGruhRsFrGATiUuh25dtxYtnpbTx":{"hidden":false,"createdTs":1405543109222,"copayerId":"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba","label":"faucet","signature":"3045022067576e5b37f2707a8dc66e57511ad9b10a3125bd95193fff6f8f6402969c3bf3022100adff9f417db07d88face13b3d13f422740d4421440cade1a205684dfdc5d733a"}}}'; var encryptedLegacyO = 'U2FsdGVkX19yGM1uBAIzQa8Po/dvUicmxt1YyRk/S97PcZ6I6rHMp9dMagIrehg4Qd6JHn/ustmFHS7vmBYj0EBpf6rdXiQezaWnVAJS9/xYjAO36EFUbl+NmUanuwujAxgYdSP/sNssRLeInvExmZYW993EEclxkwL6YUyX66kKsxGQo2oWng0NreBJNhFmrbOEWeFje2PiWP57oUjKsurFzwpluAAarUTYSLud+nXeabC7opzOP5yqniWBMJz0Ou8gpNCWCMhG/P9F9ccVPY7juyd0Hf41FVse8nd2++axKB57+paozLdO+HRfV6zkMqC3h8gWY7LkS75j3bvqcTw9LhXmzE0Sz21n9yDnRpA4chiAvtwQvvBGgj1pFMKhNQU6Obac9ZwKYzUTgdDn3Uzg1UlDzgyOh9S89rbRTV84WB+hXwhuVluWzbNNYV3vXe5PFrocVktIrtS3xQh+k/7my4A6/gRRrzNYpKrUASJqDS/9u9WBkG35xD63J/qXjtG2M0YPwbI57BK1IK4K510b8V72lz5U2XQrIC4ldBwni1rpSavwCJV9xF6hUdOmNV8fZsVHP0NeN1PYlLkSb2QgfuoWnkcsJerwuFR7GZC/i6efrswtpO0wMEQr/J0CLbeXlHAru6xxjCBhWoJvZpMGw72zgnDLoyMNsEVglNhx/VlV9ZMYkkdaEYAxPOEIyZdQ5MS+2jEAlXf818n/xzJSVrniCn9be8EPePvkw35pivprvy09vbW4cKsWBKvgIyoT6A3OhUOCCS8E9cg0WAjjav2EymrbKmGWRHaiD+EoJqaDg6s20zhHn1YEa/YwvGGSB5+Hg8baLHD8ZASvxz4cFFAAVZrBUedRFgHzqwaMUlFXLgueivWUj7RXlIw6GuNhLoo1QkhZMacf23hrFxxQYvGBRw1hekBuDmcsGWljA28udBxBd5f9i+3gErttMLJ6IPaud590uvrxRIclu0Sz9R2EQX64YJxqDtLpMY0PjddSMu8vaDRpK9/ZSrnz/xrXsyabaafz4rE/ItFXjwFUFkvtmuauHTz6nmuKjVfxvNLNAiKb/gI7vQyUhnTbKIApe7XyJsjedNDtZqsPoJRIzdDmrZYxGStbAZ7HThqFJlSJ9NPNhH+E2jm3TwL5mwt0fFZ5h+p497lHMtIcKffESo7KNa2juSVNMDREk0NcyxGXGiVB2FWl4sLdvyhcsVq0I7tmW6OGZKRf8W49GCJXq6Ie69DJ9LB1DO67NV1jsYbsLx9uhE2yEmpWZ3jkoCV/Eas4grxt0CGN6EavzQ=='; var legacyPassword = '1'; From 5cf4fe0b665bba6c2c58de2b2ad8c99e28ef2731 Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Mon, 15 Sep 2014 13:56:38 -0300 Subject: [PATCH 126/191] ALL TEST PASSING!!! --- js/models/Storage.js | 33 ++++--- js/models/core/WalletFactory.js | 8 +- test/test.Passphrase.js | 1 - test/test.Storage.js | 66 ++++++++++++-- test/test.WalletFactory.js | 147 +++++++++++++++++++++----------- 5 files changed, 184 insertions(+), 71 deletions(-) diff --git a/js/models/Storage.js b/js/models/Storage.js index 5750eb428..3433589bf 100644 --- a/js/models/Storage.js +++ b/js/models/Storage.js @@ -111,7 +111,7 @@ Storage.prototype.getSessionId = function(cb) { return cb(sessionId); sessionId = bitcore.SecureRandom.getRandomBuffer(8).toString('hex'); - self.sessionStorage.setItem('sessionId', sessionId, function(){ + self.sessionStorage.setItem('sessionId', sessionId, function() { return cb(sessionId); }); }); @@ -232,31 +232,36 @@ Storage.prototype.deleteWallet = function(walletId, cb) { preconditions.checkArgument(walletId); preconditions.checkArgument(cb); var err; + var self = this; var toDelete = {}; - toDelete['nameFor::' + walletId] = 1; this.storage.allKeys(function(allKeys) { - for (var key in allKeys) { + for (var ii in allKeys) { + var key = allKeys[ii]; var split = key.split('::'); if (split.length == 2 && split[0] === walletId) { toDelete[key] = 1; }; } + var l = Object.keys(toDelete).length, + j = 0; + if (!l) + return cb(new Error('WNOTFOUND: Wallet not found')); + + toDelete['nameFor::' + walletId] = 1; + l++; + + for (var i in toDelete) { + self.removeGlobal(i, function() { + if (++j == l) + return cb(err); + }); + + } }); - var l = toDelete.length, - j = 0; - if (!l) - return cb(new Error('WNOTFOUND: Wallet not found')); - - for (var i in toDelete) { - this.removeGlobal(i, function() { - if (++j == l) - return cb(err); - }); - } }; Storage.prototype.setLastOpened = function(walletId, cb) { diff --git a/js/models/core/WalletFactory.js b/js/models/core/WalletFactory.js index eacfeb48f..48010d1c7 100644 --- a/js/models/core/WalletFactory.js +++ b/js/models/core/WalletFactory.js @@ -53,6 +53,7 @@ function WalletFactory(config, version, pluginManager) { this.storage = new this.Storage(storageOpts); +<<<<<<< HEAD this.networks = { 'livenet': new this.Network(config.network.livenet), 'testnet': new this.Network(config.network.testnet), @@ -63,6 +64,10 @@ function WalletFactory(config, version, pluginManager) { }; this.walletDefaults = config.wallet; +======= + this.networkName = config.networkName; + this.walletDefaults = config.wallet || {}; +>>>>>>> ALL TEST PASSING!!! this.version = version; }; @@ -90,7 +95,6 @@ WalletFactory.prototype.fromObj = function(obj, skipFields) { preconditions.checkState(networkName); preconditions.checkArgument(obj); - // not stored options obj.opts = obj.opts || {}; obj.opts.reconnectDelay = this.walletDefaults.reconnectDelay; @@ -418,7 +422,7 @@ WalletFactory.prototype.joinCreateSession = function(opts, cb) { joinNetwork.start(opts, function() { joinNetwork.greet(decodedSecret.pubKey, opts.secretNumber); joinNetwork.on('data', function(sender, data) { - if (data.type === 'walletId') { + if (data.type === 'walletId' && data.opts) { if (data.networkName !== decodedSecret.networkName) { return cb('badNetwork'); } diff --git a/test/test.Passphrase.js b/test/test.Passphrase.js index 75074108b..dd249f283 100644 --- a/test/test.Passphrase.js +++ b/test/test.Passphrase.js @@ -36,5 +36,4 @@ describe('Passphrase model', function() { done(); }); }); - }); diff --git a/test/test.Storage.js b/test/test.Storage.js index 0363108ab..170235f13 100644 --- a/test/test.Storage.js +++ b/test/test.Storage.js @@ -16,7 +16,7 @@ describe('Storage model', function() { storage: localMock, sessionStorage: sessionMock, }); - s._setPassphrase('mysupercoolpassword'); + s.setPassphrase('mysupercoolpassword'); it('should create an instance', function() { var s2 = new Storage({ @@ -210,8 +210,8 @@ describe('Storage model', function() { }); }); }); - describe('#deleteWallet', function(done) { - it('should delete a wallet', function() { + describe('#deleteWallet', function() { + it('should fail to delete a unexisting wallet', function(done) { var s = new Storage({ storage: localMock, sessionStorage: sessionMock, @@ -219,9 +219,26 @@ describe('Storage model', function() { }); s.set('1', "hola", 'juan', function() { s.set('2', "hola", 'juan', function() { - s.deleteWallet('1', function() { + s.deleteWallet('3', function(err) { + err.toString().should.include('WNOTFOUND'); + done(); + }); + }); + }); + }); + + it('should delete a wallet', function(done) { + var s = new Storage({ + storage: localMock, + sessionStorage: sessionMock, + password: 'password' + }); + s.set('1', "hola", 'juan', function() { + s.set('2', "hola", 'juan', function() { + s.deleteWallet('1', function(err) { + should.not.exist(err); s.getWallets(function(ws) { - s.getWallets().length.should.equal(1); + ws.length.should.equal(1); ws[0].should.deep.equal({ id: '2', name: undefined @@ -299,4 +316,43 @@ describe('Storage model', function() { }); }); }); + + describe('#import', function() { + it('should be able to decrypt an old backup', function() { + var s = new Storage({ + storage: localMock, + sessionStorage: sessionMock, + password: legacyPassword1 , + }); + var wo = s.import(encryptedLegacy1); + should.exist(wo); + wo.opts.id.should.equal('48ba2f1ffdfe9708'); + wo.opts.spendUnconfirmed.should.equal(true); + wo.opts.requiredCopayers.should.equal(1); + wo.opts.totalCopayers.should.equal(1); + wo.opts.name.should.equal('pepe wallet'); + wo.opts.version.should.equal('0.4.7'); + wo.publicKeyRing.walletId.should.equal('48ba2f1ffdfe9708'); + wo.publicKeyRing.networkName.should.equal('testnet'); + wo.publicKeyRing.requiredCopayers.should.equal(1); + wo.publicKeyRing.totalCopayers.should.equal(1); + wo.publicKeyRing.indexes.length.should.equal(2); + JSON.stringify(wo.publicKeyRing.indexes[0]).should.equal('{"copayerIndex":2147483647,"changeIndex":0,"receiveIndex":1}'); + JSON.stringify(wo.publicKeyRing.indexes[1]).should.equal('{"copayerIndex":0,"changeIndex":0,"receiveIndex":1}'); + wo.publicKeyRing.copayersBackup.length.should.equal(1); + wo.publicKeyRing.copayersBackup[0].should.equal('0298f65b2694c55f9048bc05f10368242727c7f9d2065cbd788c3ecde1ec57f33f'); + wo.publicKeyRing.copayersExtPubKeys.length.should.equal(1); + wo.publicKeyRing.copayersExtPubKeys[0].should.equal('tpubD9SGoP7CXsqSKTiQxCZSCpicDcophqnE4yuqjfw5M9tAR3fSjT9GDGwPEUFCN7SSmRKGDLZgKQePYFaLWyK32akeSan45TNTd8sgef9Ymh6'); + wo.privateKey.extendedPrivateKeyString.should.equal('tprv8ZgxMBicQKsPfQCscb7CtJKzixxcVSyrCVcfr3WCFbtT8kYTzNubhjQ5R7AuYJgPCcSH4R8T34YVxeohKGhAB9wbB4eFBbQFjUpjGCqptHm'); + wo.privateKey.networkName.should.equal('testnet'); + + + }); + }); + }); + +var legacyPassword1 = '1DUpLRbuVpgLkcEY8gY8iod/SmA7+OheGZJ9PtvmTlvNE0FkEWpCKW9STdzXYJqbn0wiAapE4ojHNYj2hjYYAQ=='; +var encryptedLegacy1 = 'U2FsdGVkX19yGM1uBAIzQa8Po/dvUicmxt1YyRk/S97PcZ6I6rHMp9dMagIrehg4Qd6JHn/ustmFHS7vmBYj0EBpf6rdXiQezaWnVAJS9/xYjAO36EFUbl+NmUanuwujAxgYdSP/sNssRLeInvExmZYW993EEclxkwL6YUyX66kKsxGQo2oWng0NreBJNhFmrbOEWeFje2PiWP57oUjKsurFzwpluAAarUTYSLud+nXeabC7opzOP5yqniWBMJz0Ou8gpNCWCMhG/P9F9ccVPY7juyd0Hf41FVse8nd2++axKB57+paozLdO+HRfV6zkMqC3h8gWY7LkS75j3bvqcTw9LhXmzE0Sz21n9yDnRpA4chiAvtwQvvBGgj1pFMKhNQU6Obac9ZwKYzUTgdDn3Uzg1UlDzgyOh9S89rbRTV84WB+hXwhuVluWzbNNYV3vXe5PFrocVktIrtS3xQh+k/7my4A6/gRRrzNYpKrUASJqDS/9u9WBkG35xD63J/qXjtG2M0YPwbI57BK1IK4K510b8V72lz5U2XQrIC4ldBwni1rpSavwCJV9xF6hUdOmNV8fZsVHP0NeN1PYlLkSb2QgfuoWnkcsJerwuFR7GZC/i6efrswtpO0wMEQr/J0CLbeXlHAru6xxjCBhWoJvZpMGw72zgnDLoyMNsEVglNhx/VlV9ZMYkkdaEYAxPOEIyZdQ5MS+2jEAlXf818n/xzJSVrniCn9be8EPePvkw35pivprvy09vbW4cKsWBKvgIyoT6A3OhUOCCS8E9cg0WAjjav2EymrbKmGWRHaiD+EoJqaDg6s20zhHn1YEa/YwvGGSB5+Hg8baLHD8ZASvxz4cFFAAVZrBUedRFgHzqwaMUlFXLgueivWUj7RXlIw6GuNhLoo1QkhZMacf23hrFxxQYvGBRw1hekBuDmcsGWljA28udBxBd5f9i+3gErttMLJ6IPaud590uvrxRIclu0Sz9R2EQX64YJxqDtLpMY0PjddSMu8vaDRpK9/ZSrnz/xrXsyabaafz4rE/ItFXjwFUFkvtmuauHTz6nmuKjVfxvNLNAiKb/gI7vQyUhnTbKIApe7XyJsjedNDtZqsPoJRIzdDmrZYxGStbAZ7HThqFJlSJ9NPNhH+E2jm3TwL5mwt0fFZ5h+p497lHMtIcKffESo7KNa2juSVNMDREk0NcyxGXGiVB2FWl4sLdvyhcsVq0I7tmW6OGZKRf8W49GCJXq6Ie69DJ9LB1DO67NV1jsYbsLx9uhE2yEmpWZ3jkoCV/Eas4grxt0CGN6EavzQ=='; + + diff --git a/test/test.WalletFactory.js b/test/test.WalletFactory.js index 78dca9aff..2ec67e64a 100644 --- a/test/test.WalletFactory.js +++ b/test/test.WalletFactory.js @@ -1,5 +1,6 @@ 'use strict'; + var chai = chai || require('chai'); var should = chai.should(); @@ -10,7 +11,6 @@ var FakeBlockchain = require('./mocks/FakeBlockchain'); var FakeStorage = function FakeStorage() {}; var WalletFactory = require('../js/models/core/WalletFactory'); var Passphrase = require('../js/models/core/Passphrase'); -var LocalEncrypted = copay.StorageLocalEncrypted; var mockLocalStorage = require('./mocks/FakeLocalStorage'); var mockSessionStorage = require('./mocks/FakeLocalStorage'); @@ -89,18 +89,18 @@ describe('WalletFactory model', function() { beforeEach(function() { wf = new WalletFactory(config, '0.0.1'); + wf.storage.setPassphrase = sinon.spy(); wf.storage.getSessionId = sinon.spy(); wf.storage.setFromObj = sinon.spy(); wf.storage.setLastOpened = sinon.stub().yields(null); + + var w = sinon.stub(); w.store = sinon.stub().yields(null); wf._getWallet = sinon.stub().returns(w); - - - wf.network.setHexNonce = sinon.spy(); }); @@ -145,6 +145,7 @@ describe('WalletFactory model', function() { describe('#fromObj / #toObj', function() { it('round trip', function() { + var wf = new WalletFactory(config, '0.0.5'); var w = wf.fromObj(JSON.parse(o)); should.exist(w); @@ -446,9 +447,32 @@ describe('WalletFactory model', function() { nickname: 'test', passphrase: 'pass' }; - it('should yield network error', function(done) { + + it('should yield bad network error', function(done) { + wf.network.greet = sinon.stub(); + wf.network.on = sinon.stub(); + wf.network.on.withArgs('data').yields('senderId', { + type: 'walletId', + networkName: 'aWeirdNetworkName', + opts: {}, + }); opts.privHex = undefined; - wf.network.on = sinon.stub().withArgs('serverError').yields(null); + wf.joinCreateSession(opts, function(err, w) { + err.should.equal('badNetwork'); + done(); + }); + }); + + + it('should yield to join error', function(done) { + opts.privHex = undefined; + wf.network.greet = sinon.stub(); + wf.network.on = sinon.stub(); + wf.network.on.withArgs('serverError').yields(null); + wf.network.on.withArgs('data').yields('senderId', { + type: 'walletId', + networkName: wf.networkName, + }); wf.joinCreateSession(opts, function(err, w) { err.should.equal('joinError'); done(); @@ -456,19 +480,45 @@ describe('WalletFactory model', function() { }); - it('should call network.start', function(done) { + it('should call network.start / create', function(done) { opts.privHex = undefined; wf.network.cleanUp = sinon.spy(); wf.network.greet = sinon.spy(); - wf.network.on = sinon.stub().withArgs('connected').yields(null); - wf.network.start = sinon.stub().yields(null); + + wf.network.on = sinon.stub(); + wf.network.on.withArgs('connected').yields(null); + wf.network.on.withArgs('data').yields('senderId', { + type: 'walletId', + networkName: wf.networkName, + opts: {}, + }); + wf.create = sinon.stub().yields(null, 'wallet'); wf.joinCreateSession(opts, function(err, w) { - console.log('[test.WalletFactory.js.454:err:]', err); //TODO wf.network.start.calledOnce.should.equal(true); + wf.create.calledOnce.should.equal(true); done(); }); + }); + it('should return walletFull', function(done) { + opts.privHex = undefined; + wf.network.cleanUp = sinon.spy(); + wf.network.greet = sinon.spy(); + wf.network.start = sinon.stub().yields(null); + + wf.network.on = sinon.stub(); + wf.network.on.withArgs('connected').yields(null); + wf.network.on.withArgs('data').yields('senderId', { + type: 'walletId', + networkName: wf.networkName, + opts: {}, + }); + wf.create = sinon.stub().yields(null, null); + wf.joinCreateSession(opts, function(err, w) { + err.should.equal('walletFull'); + done(); + }); }); it('should accept a priv key a input', function() { @@ -490,7 +540,9 @@ describe('WalletFactory model', function() { }); }); }); - describe('dont break backwards compatibility of wallets', function() { + + + describe('Backwards compatibility tests', function() { it('should be able to import unencrypted legacy wallet TxProposal: v0', function() { var wf = new WalletFactory(config, '0.0.5'); var w = wf.fromObj(JSON.parse(legacyO)); @@ -502,43 +554,38 @@ describe('WalletFactory model', function() { should.exist(w.privateKey.toObj()); }); - it('should be able to import simple 1-of-1 encrypted legacy testnet wallet', function(done) { - var pp = new Passphrase(config.passphrase); - var alternateConfig = JSON.parse(JSON.stringify(config)); - alternateConfig.Storage = LocalEncrypted; - alternateConfig.storage = { - localStorage: mockLocalStorage, - sessionStorage: mockSessionStorage - }; - var wf = new WalletFactory(alternateConfig, '0.4.7'); + it('should be able to import simple 1-of-1 encrypted legacy testnet wallet', function() { - pp.getBase64Async(legacyPassword, function(passphrase) { - var w, errMsg; - w = wf.import(encryptedLegacyO, passphrase); - should.exist(w); - w.isReady().should.equal(true); - var wo = w.toObj(); - wo.opts.id.should.equal('48ba2f1ffdfe9708'); - wo.opts.spendUnconfirmed.should.equal(true); - wo.opts.requiredCopayers.should.equal(1); - wo.opts.totalCopayers.should.equal(1); - wo.opts.name.should.equal('pepe wallet'); - wo.opts.version.should.equal('0.4.7'); - wo.publicKeyRing.walletId.should.equal('48ba2f1ffdfe9708'); - wo.publicKeyRing.networkName.should.equal('testnet'); - wo.publicKeyRing.requiredCopayers.should.equal(1); - wo.publicKeyRing.totalCopayers.should.equal(1); - wo.publicKeyRing.indexes.length.should.equal(2); - JSON.stringify(wo.publicKeyRing.indexes[0]).should.equal('{"copayerIndex":2147483647,"changeIndex":0,"receiveIndex":1}'); - JSON.stringify(wo.publicKeyRing.indexes[1]).should.equal('{"copayerIndex":0,"changeIndex":0,"receiveIndex":1}'); - wo.publicKeyRing.copayersBackup.length.should.equal(1); - wo.publicKeyRing.copayersBackup[0].should.equal('0298f65b2694c55f9048bc05f10368242727c7f9d2065cbd788c3ecde1ec57f33f'); - wo.publicKeyRing.copayersExtPubKeys.length.should.equal(1); - wo.publicKeyRing.copayersExtPubKeys[0].should.equal('tpubD9SGoP7CXsqSKTiQxCZSCpicDcophqnE4yuqjfw5M9tAR3fSjT9GDGwPEUFCN7SSmRKGDLZgKQePYFaLWyK32akeSan45TNTd8sgef9Ymh6'); - wo.privateKey.extendedPrivateKeyString.should.equal('tprv8ZgxMBicQKsPfQCscb7CtJKzixxcVSyrCVcfr3WCFbtT8kYTzNubhjQ5R7AuYJgPCcSH4R8T34YVxeohKGhAB9wbB4eFBbQFjUpjGCqptHm'); - wo.privateKey.networkName.should.equal('testnet'); - done(); - }); + wf.storage.import = sinon.stub(); + wf.storage.setPassphrase = sinon.spy(); + wf.storage.import.withArgs('dummy').returns(JSON.parse(legacy1)); + + var w = wf.import('dummy', 'xxx'); + should.exist(w); + wf.storage.setPassphrase.calledOnce.should.equal(true); + wf.storage.setPassphrase.getCall(0).args[0].should.equal('xxx'); + + w.isReady().should.equal(true); + var wo = w.toObj(); + wo.opts.id.should.equal('48ba2f1ffdfe9708'); + wo.opts.spendUnconfirmed.should.equal(true); + wo.opts.requiredCopayers.should.equal(1); + wo.opts.totalCopayers.should.equal(1); + wo.opts.name.should.equal('pepe wallet'); + wo.opts.version.should.equal('0.4.7'); + wo.publicKeyRing.walletId.should.equal('48ba2f1ffdfe9708'); + wo.publicKeyRing.networkName.should.equal('testnet'); + wo.publicKeyRing.requiredCopayers.should.equal(1); + wo.publicKeyRing.totalCopayers.should.equal(1); + wo.publicKeyRing.indexes.length.should.equal(2); + JSON.stringify(wo.publicKeyRing.indexes[0]).should.equal('{"copayerIndex":2147483647,"changeIndex":0,"receiveIndex":1}'); + JSON.stringify(wo.publicKeyRing.indexes[1]).should.equal('{"copayerIndex":0,"changeIndex":0,"receiveIndex":1}'); + wo.publicKeyRing.copayersBackup.length.should.equal(1); + wo.publicKeyRing.copayersBackup[0].should.equal('0298f65b2694c55f9048bc05f10368242727c7f9d2065cbd788c3ecde1ec57f33f'); + wo.publicKeyRing.copayersExtPubKeys.length.should.equal(1); + wo.publicKeyRing.copayersExtPubKeys[0].should.equal('tpubD9SGoP7CXsqSKTiQxCZSCpicDcophqnE4yuqjfw5M9tAR3fSjT9GDGwPEUFCN7SSmRKGDLZgKQePYFaLWyK32akeSan45TNTd8sgef9Ymh6'); + wo.privateKey.extendedPrivateKeyString.should.equal('tprv8ZgxMBicQKsPfQCscb7CtJKzixxcVSyrCVcfr3WCFbtT8kYTzNubhjQ5R7AuYJgPCcSH4R8T34YVxeohKGhAB9wbB4eFBbQFjUpjGCqptHm'); + wo.privateKey.networkName.should.equal('testnet'); }); }); @@ -548,5 +595,7 @@ describe('WalletFactory model', function() { var o = '{"opts":{"id":"dbfe10c3fae71cea","spendUnconfirmed":1,"requiredCopayers":3,"totalCopayers":5,"version":"0.0.5"},"networkNonce":"0000000000000001","networkNonces":[],"publicKeyRing":{"walletId":"dbfe10c3fae71cea","networkName":"testnet","requiredCopayers":3,"totalCopayers":5,"indexes":[{"copayerIndex":2,"changeIndex":0,"receiveIndex":0}],"copayersBackup":[],"copayersExtPubKeys":["tpubD6NzVbkrYhZ4YGK8ZhZ8WVeBXNAAoTYjjpw9twCPiNGrGQYFktP3iVQkKmZNiFnUcAFMJRxJVJF6Nq9MDv2kiRceExJaHFbxUCGUiRhmy97","tpubD6NzVbkrYhZ4YKGDJkzWdQsQV3AcFemaQKiwNhV4RL8FHnBFvinidGdQtP8RKj3h34E65RkdtxjrggZYqsEwJ8RhhN2zz9VrjLnrnwbXYNc","tpubD6NzVbkrYhZ4YkDiewjb32Pp3Sz9WK2jpp37KnL7RCrHAyPpnLfgdfRnTdpn6DTWmPS7niywfgWiT42aJb1J6CjWVNmkgsMCxuw7j9DaGKB","tpubD6NzVbkrYhZ4XEtUAz4UUTWbprewbLTaMhR8NUvSJUEAh4Sidxr6rRPFdqqVRR73btKf13wUjds2i8vVCNo8sbKrAnyoTr3o5Y6QSbboQjk","tpubD6NzVbkrYhZ4Yj9AAt6xUVuGPVd8jXCrEE6V2wp7U3PFh8jYYvVad31b4VUXEYXzSnkco4fktu8r4icBsB2t3pCR3WnhVLedY2hxGcPFLKD"],"nicknameFor":{}},"txProposals":{"txps":[],"walletId":"dbfe10c3fae71cea","networkName":"testnet"},"privateKey":{"extendedPrivateKeyString":"tprv8ZgxMBicQKsPeoHLg3tY75z4xLeEe8MqAXLNcRA6J6UTRvHV8VZTXznt9eoTmSk1fwSrwZtMhY3XkNsceJ14h6sCXHSWinRqMSSbY8tfhHi","networkName":"testnet"},"addressBook":{}}'; var legacyO = '{"opts":{"id":"55d4bd062d32f90a","spendUnconfirmed":true,"requiredCopayers":2,"totalCopayers":2,"name":"xcvzxcv","version":"0.3.2"},"networkNonce":"53d25e8600000009","networkNonces":[],"publicKeyRing":{"walletId":"55d4bd062d32f90a","networkName":"testnet","requiredCopayers":2,"totalCopayers":2,"indexes":[{"copayerIndex":2147483647,"changeIndex":0,"receiveIndex":0},{"copayerIndex":0,"changeIndex":4,"receiveIndex":2},{"copayerIndex":1,"changeIndex":5,"receiveIndex":2}],"copayersBackup":["02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba","02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5"],"copayersExtPubKeys":["tpubD94LTzAUiW99mpA59nyf6fAHh4xKGmnwbgCV4gU2bRpeN9CRiMSurqme22px5NmJAo6FdcdH883Zu98VbqyhesCJ86kUEjH3Zpufy5FfcaC","tpubDA2U9H6LkRHDRbRxHBp4VTbxPc7JqsvtcLxrE5QJF8z1iT6hMJ1pXSVf57GWRcxXutYvpoXRurDVGsscJauMtnJBkYAWBVExYmm91XQE2zz"],"nicknameFor":{"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":"asdf","02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":"qwerqw"},"publicKeysCache":{"m/0/0/0":["028a4b63f26253f3a8731577b8e1ee480950ad5833ebbf106fe3463bfc07cc3b90","0332efa054c08cb77506a35ee0762cb7156f244566703ec08e433568ec0397bec8"],"m/1/0/0":["0220ad514cf593d0c3905d3bb49bc5767a9410823bf9b77ea5ef2cf1d1016d77a8","02fd42cf66f1dbdc7bbb9ae09aecea72df479ffe5a0c4641301067e331d12e416d"],"m/1/0/1":["0315f7868eaf1f9b7127e3f7e0222c5e473eea003e34700f4758b6873c525d6723","02a2e8ed5e90dd39e3842fc790e06178997dbca319987f365317589e2a71a93658"],"m/0/1/0":["0244a25a0b97b26707fd855c15b046b901be85a3b70a781d0678608e633440eeca","0358cdcbc528ddfb7173b0dab283f702be82546ff031e4a832a7270080cb875959"],"m/0/1/1":["025c9b49bdf17d97bd82ea1b87793082f857247f0f9b999937a166ec994bb1b41f","020389327ee8ae7d0ee3f8187842d23a4070bdd8a27c0bcddd05d80ef39009253d"],"m/1/1/0":["02fd0e7c62b7b58d1ea7bb4cb84d53b019df99d3703a42aed73a2cfa15f3af5d08","0355a15912e76072ef50e6643376b8a9da8422ed4f8ea07b1d84d4989be5a39b2e"],"m/1/1/1":["03bc3e1f4db32efd8eb1fd44a1665938d59628429c67e1e8b7054ab5717f4e6750","03c4c817b633ac31f44f16f390af831d35f7d98744a52a0f23e9598967342255f8"],"m/1/1/2":["02826fe7e9da408480ddeb1d4414c5100b350f862ca718e27122681e1a0ca35077","02bd25af907bb3edbf6b2cd1ea90eaa92cc93ec47bea7d339af44c1d2c05708e99"],"m/0/1/2":["0337a1a70364b94745d6e26d2d28919cf528304f52765f12ef43e3d6da0a6c8dc0","039d83db9aa43e6e00e0304e6971b6079d79dc12d8d55ce2e6fc24a52ba8d41329"],"m/0/0/1":["0359c6d0d0d31f83301169901a6ffad9535f14014b5ab3b43561dbb2436a7b8138","037d06f713f13a11967fd5edca265ff4c77528693a712c482256505693e4890d93"],"m/1/1/3":["02600e5c41670773a213a4cb58c8f2fa3e83840784bc7f0b56925e1075e06632c2","036d01867af5f61371151ef7d9026fa0400a623f6924e404ee0b856625268972f9"],"m/0/1/3":["03e5a9b039b187ca8e065627df402e4a5b196b94198542da7036879de08be63d2d","0304f3e0b70f696d80e5785dc7747d6dcb55ba24c31f2d80bf184b4e582e6b47fc"],"m/1/1/4":["03741afa5bd50d6ba5801064c810fae84f6a4557d6a88ddc8591d0d4eb68a8fc41","0214dd6ce6073b05999fb887098ca6f7e1d0b4fdc0760557786907df353df90d1c"],"m/2147483647/1/0":["033e072a53ea835763a03c66e35c35384736210a1bb7d7ee6d9a3e109e82426b30","02e37b5570c053da8a8ee587be86fc629775c4db890aba2745ccc4e4dcc8c31041"],"m/2147483647/1/1":["0228a6de42ef421c263d1efd9f28d9a7d15a261995028a24eff6b9f1c3fc46e6bf","0226cff885cb0d607cc9cf69a7608316eb3fb2ec344c0c9956246ba776116fc396"],"m/2147483647/1/2":["034fe2a8f0b98445eb5810fe36572ad2f64ed9bf64dc9de624f99c0142cb07c682","02f2c5c758e32293f5c193fd69afadbba83abafb397db01e6f2b447690e900475a"],"m/2147483647/1/3":["02b25ef9434446c51f10678f787e4913de582e34d164bd3b06af7732c5476df1a8","025d51a1efd59bcff22ee2e0af61b21a7ba5f639e20dfdf25690e926005177dd0c"],"m/2147483647/1/4":["03e5734e1d29b2f684d0446b7a2ffbd0ba8952570a502d0d14b1efd8f24b61be53","0258fc28a324848d8d0154e8614815e35c668d274a8f01957bb99aab8dc8f386c0"],"m/2147483647/1/5":["021f9e775246765e1cfba0ae453b4eae6cd4ae5a57a09c319edbe89d4dbbf23be3","02857f66571a1c3eb9e72d22ae88e734c03d448bced4dcfd345c2059468124c741"],"m/2147483647/1/6":["02c072f329391a25255dc6452e5f5220966869dbf736ba8a8c3ae9d273a84bc3fd","030920a8b8e88c4db2871a7df0878a86cf0695f6d96bb50c701c3454f3df25176a"],"m/2147483647/1/7":["036bf329fc19bce10cf1999fae5bfa80290ff7b44776b49c7b0dc9eec6cffcfa21","03955a549875b4f7b9be28b9ff4bcd51ad2bc224430b1634baef890585885d5e1b"],"m/2147483647/1/8":["024879c9c9a261b3141ecfa1c79c4efc25278c844ecd1dcfcb95d9c19581fbdd25","03fb4a5fdb91239df3ccf7f61a5b99e7e72483101e21c9d1ee0d85544e9354c6c7"],"m/2147483647/1/9":["035928a107ec01f78cd586914d5a49710fd42e352b1312e3ad0eeb2c9666fdf8e7","03a54c03093797854829c75357f092356352a109042bbb83bdac20cb4e5eca27ea"],"m/2147483647/1/10":["021e7a3a7efe888c5e820b5cf0f03317b2b4bf438d8563449aeb7a77cade97f136","03ec0960b3d1df52ca3cc2c82b7d97063400da4dd051bba2f9bab6cb44aee01efa"],"m/2147483647/1/11":["035d70c26b7f429861f555f7c0d99947411b23b7f95303fb8d5de5b82a95aa30fc","038b922f7024f5446d6b48e5253643543b35c006d90fd37688105c6cefcd8adb8a"],"m/2147483647/1/12":["02158d6503891c6c65a606221dbf5c68d0832288975914007968419939588ecb24","0248264cb1763a3f4de9b34787b4bc5443ec92ef915927494bb9f1c1c0b498c7ca"],"m/2147483647/1/13":["0349965eea38a25ae0c061faeac4c4e57e648bc4c0f059d07b3b8b7962cbc0dde5","0352243d9269565ce2a1ffdd0b8e43a442c6dd1c9edda86eaaf2cba5a4a95c40f1"],"m/2147483647/1/14":["030fa6e3d0c5cedc0581955395c77cbe134c912a47971023b9695332df3f7bb200","03f2cf09e33326fb59bf3f13e6298d2d5d29c9eae3b872e5a851e8d8d77259c883"],"m/2147483647/1/15":["02bf0d45e41339f552df6f8baf4392142921fd38b0f2a4388a905ff6cbacbc278a","03fabe46bb6706a1b8edfd28c046a8891b4530bbe5305080b72b0d08ebdf7b8c0a"],"m/2147483647/1/16":["03a4e3146ed34d6a8af4e4379e6edcff32cb0373ba232b3d746af3052f674133ac","030311b73c6f5c46ddffc0cfce6e5ed0b671d94267d8e52cd8837f2a479916eb91"],"m/2147483647/1/17":["03233df93c762d2f06c7f5f388e4e0a8dbdb13302acba0d2d6995c487d8aec9f2f","024badfdcb7e772ac7fc1c46d3943b07500edbbece105cdeff3eb9e9fcc9f54782"],"m/2147483647/1/18":["0364035475a098e00eb010c500cad3c90af3e81a4bd613144bc9433a150f14718b","028223dc8142154e7477ce000b3dc13e1d15a901553d9b18864c8645b582b38fe6"],"m/2147483647/1/19":["03971b74b4ac4bdaadf636baa4caa82fe5355471ed6ea05a9cbe5fc6c9e4b9db76","0202ebffacd01f83849e5bc5c0e2c317bc5fb2fbcb2d6d4482a5235f9f1308b61a"],"m/0/1/4":["03005ee9ff028c98fd132e531023f2f2b61ff0d26022f979dd98088d2ba167b031","0345ea82e8dfe38277f0c3aee18d2dd93edb63e8663ac83328a7934d2ca57006f6"],"m/0/1/5":["0391bc4990b71d8a3f156ae7107929ed6372b0b4ba8a868253f71ba7189d1efa02","0312a74cf2e7c0dd41897d04fabfd8cc3187b84a28305cfc79315b24e6fe23a6b4"],"m/0/1/6":["021a38c492607ff9684a4fec445e47b5b7100d3ef9e9dc0d0b37c0a646d28d4f77","03ae0b46ab36f97447ebaa53f2b5c8f090f15395378785f2fd285eeba17fbf3f65"],"m/0/1/7":["0308cdec88c1ffe16edc98853d9c08dbd4ba2541ba566668ca17bda19d7eb3481f","02dd622267c2e68287287b8b61724f76fbe84096a56aa5054af92f8fe25380e2d1"],"m/0/1/8":["039647da9ad725836bcb28a3e0497659a28d7749d1416c421a0a01c62d237ee962","022e22aa61eafda0dd8820427f1a06314d352a15ea8645e7ab9b80920017084d82"],"m/0/1/9":["03a4ade946076c6962b70c70ac7fad3a87efb59a1d0a4e32bda13a6d47fe9df961","029a07235aba04ab69526e117d836d5b3fae5cfc8c5e72b10c6d1afd261ccc19f3"],"m/0/1/10":["03c78e9b6493b22790db1acea20df9444e0f9c424fc5756e7a32c290ae01783953","0254c130ee467a96570c9f5ebea89de04f0b1db1686b164f2694339bef8f25dd88"],"m/0/1/11":["03a762c43318ef8d4840fab04c8db73797dc648825fac60f2730b4c76678df1cf3","0212c684a4de8e750ad2dfe2b136370ab9803eca178ed9a27b3990c29b067de35c"],"m/0/1/12":["02702d221f9b15c5cf75ac2f497a6c63e60213087c3d2d3be46768e3ebd238e26e","03ed58580744deb357258e44548212038670769d8d51e385d4fb8414311fd01b52"],"m/0/1/13":["0320e0597b54c62768352f433389cee4725d6094d7bcb5c72265edcc0933829aff","02c5706f11b9a85f3176c572842b7c9812c2195058d24d945bc026b00312740e76"],"m/0/1/14":["02fe43077676b844226d3aaa62e8a86d237710d92f882366944acbde0c8992fcaf","039a6a8662abb8910741cf331320549665e9feb28ca94d1ab6a43c84fa330b94ee"],"m/0/1/15":["0369f99f72847af93d50ab8ee75b6e7e912d26e27be96f6d6b7215cf7daeff7ba5","02521700cc07c953ba5aa586fb0e4795a34dffc68c5fb43e038be3866e40f4daed"],"m/0/1/16":["02f67d1d89bd8fe2f91c5b973cbdacfb4ba440e7656bce284cf73d549625607347","035da9cfac5a803dcb2b283b02a2515a4a1bcbf3d19e0d180aee8fc30193bc0555"],"m/0/1/17":["02c024ec199d240e8d6c66276b94b91071f7cdf2bef540c29d6d18d25de7b1cf7c","02190865f9dafae3f7f05c093463be5632946422ddda0a6fef6904390792516067"],"m/0/1/18":["035ed504d7704ad984a333b8eb0fceb8be043da9284de31ed84d9e68d90c75507d","033303c415b50421732402df00f4baa219f334647a7eb5014b9f8079864d6ab558"],"m/0/1/19":["02ce49fe86b0eee73663b1ee867b16b97c876af26f12764c528a2e6d0eb55ad3d7","03ab969bc81796b88e44c340d854df955fc60ea17ea92db5d3115595d6dec890d8"],"m/0/1/20":["03e2fa915378cbdffa0d919b0fb50c7256ca731b9d571b3365e486893a1d43079c","038d058b895cf084dccfcc9367e4796a5cf4ddceed6c35f6885d75c80119613350"],"m/0/1/21":["02fcb1bf644446b5b42205272af72f0aeab9e92ca29aafa91c5fb69142764017aa","035c5fe5c8811603279a5b72b6c30735d702817db1eab937c622269e28192ffa90"],"m/0/1/22":["03b39d61dc9a504b13ae480049c140dcffa23a6cc9c09d12d6d1f332fee5e18ca5","022929f515c5cf967474322468c3bd945bb6f281225b2c884b465680ef3052c07e"],"m/0/1/23":["03f40b82fe8cacff08879f13c45f443a3dc3ea98e1d75d5f32a19f5e5a8f7a905b","028415ee458e4dcfd440ce969726f3b58ae74fb6cf3995ced099579211e7419844"],"m/1/1/5":["032748a6282e21f571b8c8dd49e775deb83c90fcf88dc4ba81d878536973709c3f","020837cd68f14ce571b335eecd1b6fa0af43e1576dd9721aaca2a8ab639ac6b7cd"],"m/1/1/6":["0337032efb013dc92bb8dccfbdda9f5c28f0039a9c60953d41003d095e9f9778af","03ceed2da6b9603297061dc8eb930112ba726b2ccf5eec67f4866a05ca4049a22b"],"m/1/1/7":["0383c96ac2af7d203f69133b2fab6b68366b5075ad6957fa06759df3b20fbfec70","0311385f79834cedaf2230a48c0f9dc8e794da1869fc595db2518d62debb85579a"],"m/1/1/8":["03efc649680280f4e4df96da923bc88330275004125ebe5483c2f3e05ca52e19a4","02803c02d197d780388259afbd001ae41fa3eb3e2bac9627aff540521c184c3b23"],"m/1/1/9":["03af2fe6aa027a76b42c1c4050a040bfd026ad2daec1bb96a5fe2d026a7df919de","02ce14163047c640228796fb1f72bbe3afb05819ad141598a4f021058a6f79dd3b"],"m/1/1/10":["033770378bd762cf0408e44e4e604bef77e336170428c506949b1a4f1f2963e574","02c58ed43946f699dbd3e36d3e9aab2714cadeb19ecd3a56e4328c50336b4a76cb"],"m/1/1/11":["02898a1545fa19bdca92adc498698d27b86529cd4c08946d9d29604734b86f31af","02b402767a045ede072600924401c0d720000b2ed59fa444bfdbef4a5f1cead745"],"m/1/1/12":["039b8659430be49913e2cd869aa8c99ccf49a13df35837370b792033dadb891483","03264e63df292257cc76babb15d15bef620d1c2f8c3bbc78d6ea02d127e5ee7386"],"m/1/1/13":["02381a559791b8e86bf546e2c718ae63cf24eed0518a58e4d4a4b310adf2cd38fa","02d7f8283a4418d912508901b4a3db0d2103206dfdd74b3c75648671e20ecfd445"],"m/1/1/14":["020376e8c550b7d9faa0b2da947a2a36fab22c6e8190b6f99460b6022017bb97d7","03fbc5299190e6628de28c92aaa12e3a131b21eb7266462c46fbedeb86fa878055"],"m/1/1/15":["027209fd3b0cf7368180a5dbb16b928c997d33fccb78505d48440c7d23eadf5460","03450bfb22858726cd7e228e6733f69457546978a95188565c53e0d1c0d6070ea8"],"m/1/1/16":["03cb355ba04f64293793855121bab5831f84a3a3edf7cd31fccaa6d67c407a4912","028bc897a39c1224610b765a80f4cd8ab79cb37776f58fec9c10ac6f649d1f3c72"],"m/1/1/17":["03f4cb0564d7e2c6b85673503b7954db22779f29a8f3374904573984e318a96bf1","037c11b6ee906d84aa7eed359d758d986d912b6f8e5cbb1acf0982a77b3ef812c4"],"m/1/1/18":["02d2e5798f33f6889472857744316f2d253f25f88379610063f40cfe5798d9858f","0253cefdfe9ca987cbf1c950b6246d5b7a194d8dfad47c3a78dbbc5c1d01511d97"],"m/1/1/19":["0336c325f5aed366ffc10d553f2bfd4d69e66cbe1688d77af14efc8827aea2e318","0378b1b9a6074f9f2ab4fa9ad1e14649c621b0c8124a1b148914d3c10e6ab390c6"],"m/1/1/20":["03ea55740a734689ce778a8c00df8ebf4274c8f66de7d05646fe5c927773ff7f2e","02275b558d49aef955b6dee51a3c0a53f4b076b97bb3f26abcc82540168ec87cac"],"m/1/1/21":["03c77869c9984664eac9c238f4b6d806c9f48ca8a736c48450f398834db2aa915c","02d984f548c7f60c09dad3287cfc48807bc8157123989636c713be61be6a2e9ced"],"m/1/1/22":["03ed7c6a3c854c1f9459891691cc32671402f9e47126919878251e568dbdf353f8","02a113dab22cd9e46967b3fd76b9b9ec1d227d88817a9300e42d332cca2a0877fd"],"m/1/1/23":["02ee186432dcf69fda50a6fdbd94651817d8a271c273a5b70cab3ec4ae77a3753b","02291370aad9de0dac676355ced64e268b0c431a51f42f12d13f5144940fce4285"],"m/1/1/24":["02bf71435e84e66547c8c583d5ba226a5ac4d935e0a9f9603ecd8925c3e847e91a","03578d8657d285a89d9d597632db662cfef9baccfb55c76b1e87948a94fc9de30d"],"m/2147483647/0/0":["02a8425bbe23426219065969f695a6c3e242b24e57226bffdd542be8fd6be968c9","03057a42fdb6569fb1615b173ccb702453db2eac5be4291b82d4511461eafbed87"],"m/2147483647/0/1":["0250c3d3e86e332010c5233c2ec3bc728026002f0037cb3382d6318409b0e70796","02cfac1e7c4c88191201080f8316af52d9faa6ba624a6e160279e9fac4d1cf79a9"],"m/2147483647/0/2":["02a8c266a5b92eb50c8be91f95e4d1ad968b2f57d527377fd642d63fb84474f61a","028cc954ab31bd179ff80b8a05f95430ae534e61b3ff35f5284fa2fbe1832ceccb"],"m/2147483647/0/3":["02f719e1a7ab00ea98611453fb03d44c1da04655bed74af392534d70099039b4c2","03bfa548bfd4718c50bfce173f780eadcfb679d9c0206c91a2fa1879a9cf7558b2"],"m/2147483647/0/4":["0362c0695d397ca26bf47f0e641bb3cfb06ff29ccac2e1d56ded3afcf88b1e688d","02f9d87b05bdb3b9e82f506b43f813041c0e403274adc23d11e5e1651e34b606c2"],"m/2147483647/0/5":["033731323032d4ee08e858fc71f93970444333e183a1d5052e1d08cfb511e262c8","023e12556cef67ade35b7758916b5e1a3ebe074ccd35c5d8eff6b01321f63eb495"],"m/2147483647/0/6":["025d11b90081972bc1c258c9d6f476dfc2f95b69f0e9935322bf9c21deb580ff64","02b065f56a378907354f0738a0ed74f10660c6b5dd68c9f992093b75ce3d7d8b72"],"m/2147483647/0/7":["0210e721e8a35db9d8c855a0d346f60c09208f3be80b39e03af2c29db777332c71","0277f352969fadb1f1835f9a0fa99c6a3c7b6c281be5b2794c88a708eb177ea33d"],"m/2147483647/0/8":["02998d8d41e4215cd2a961a415a3ed0b1f984f1627719a7b102a75864943c4d87b","03d8ed7fc8f68a77f68d3afd007b7aa4c89944195143630ce183f0fa5438f2b559"],"m/2147483647/0/9":["0324fa91737588e4f85937303ce65c3b91b5f2ae506a72d92b83e3f5f9aeeb3c6f","02a011be72c4a400319212228106af278823a97acfe0a67e1ecd866d446b315114"],"m/2147483647/0/10":["025886ba287922a904881c7315e6fcc410a7976741771a5937d3a1a01b529f21fd","0243bb91ceed9d29d0c2ca66a8ab77e82110bbcc023beb4106f787964f44a0b972"],"m/2147483647/0/11":["0369d21684894cc2d4b2f5e581ede3cac9e8db4161a08e7737c1be129bb673d3d5","03c9ef27e3cd3dadc078fdfd9936a7ad9bf7954747085cf8f8a2a5bb3431f68a9f"],"m/2147483647/0/12":["03a73b8fd859bf6acebffdfffa2597199091daedd2c011ac67fc3494d8a1a8ceb6","025a213f7771c8be03f43f2e7f469ad4ef2cf6907ea284b227a786d1f55dfa7144"],"m/2147483647/0/13":["03a09f7ca257e1ab263cd5e6b0addc3ff868b93df132321d98775ca3505efb576f","03454c715739164bc55f347a651439cdf3ec146b35d2927beb60e8290b3916e082"],"m/2147483647/0/14":["03a64b1f7bd94a6b1a6e84ea444e0ba04e9deb86460934ccc37c0615a134a8257b","02794f09210b1811a455f3e1c7bcd35c76dff2523190fef9615eb27e2376acac1c"],"m/2147483647/0/15":["0392dca2fd9a3bc2b2a7d90a848719069fbc5f22bff7327bb8186c032514085263","032ee8a33ea76d70c7ae839448ca6c5b1af89146f2922e23ba1822df42dbc7e66a"],"m/2147483647/0/16":["031a22a1a3c1abad7c4d782ef6ba3cc00f2e8fe549eb33e0732200aff6d3174831","03bdce9781289e0c31cf727f4c93fe46f7930dd8fd68f818ce241f1ede268e8e0e"],"m/2147483647/0/17":["03b12d27e9aea2c2ad598e54e40860a705ac2ca2427aa511b501b38ec368ea5c7d","03e60d35d84d4536cad895215256b312bb4879a8d417251c279995e58f25da3d54"],"m/2147483647/0/18":["0380266cc9a9673676ad6a1b2e7148766df9c25b4dce299e5edc4f65b72aa58e64","0329e2a8a48c06c0c45dfdd2ab33e6455551557d8ebaf8c12fdf7470f8c45f1d28"],"m/2147483647/0/19":["036fe62af85560d7eea7c7af55e60b32a97dca80134d0aedffb19eb2705b9d6e01","02381c2c30b9f81e2a53c69028fbe11803acad0420b267719b7a80870be0baaeb7"],"m/0/0/2":["027bf94b8fc4e9b42683af25fda125ccab8760040717d100270dd4afd032692daf","026382c6c9357250d96dc21e43c053857a64efeac1887fdcbc107fbe3ecfc6115a"],"m/0/0/3":["03fd203acbd9af3cbbfb709458f8952078234a36094f12d00372e4b2b14cfdf419","03f2e5db59aea5dc89f53ac2a9f4ef66d41265c45afc5d763e0ca61ab70c7c61ec"],"m/0/0/4":["02a1d7cf4fcdbbf4de4002b844c3bff1639073f1cd6e5c4a4e02596b45d3f518c2","03b5fba813294e6ae096ea158833453caa5a945609b0a554696091b9b152bb0f7d"],"m/0/0/5":["0261d37e3b56ef4e106c59753037f516a4b1c45e056b2a3e00f8b77f15aaa7f8a5","0256a55e66e0de1603f0d600c0eb5f5486cf3512a776a36f3ab0d1941fc0dc9b09"],"m/0/0/6":["031db2826af215fe6cbe3f6e121b0497840fc49be133cff0a4d4eab679d6b99d70","021dd722c3f35dd04fcdb57f09b76c723d521fb36751de03ffd08096ddf1dc1f86"],"m/0/0/7":["0354ea75bdd9eb5beae7262e4a5eeb58bd10103ee0185e85b749ea39f6615d0f62","03f2c8f3b6478c0501a8578d5caf5ac2974f8213fc5e699d62dd2af58fbe8781d4"],"m/0/0/8":["0282e67df3bcd1e1662469b4c3151fb50ee1e46b75d787d91184c16b9803131f82","02921a7054af1e425f4137a5eb6b34d1f2b9d81c2625230194bc30657bb4277e11"],"m/0/0/9":["033e7e387933983ceab37c8388bd8ebc5119760f493ffe6f083bef0e5dfe22891d","02d660d60cc55d80912e0745cb142a8596a4604fbf72f9aadec0599aa2ed62461a"],"m/0/0/10":["022ce5b2750ae34512199856eab9e912dc25281cd8b88e7688a46c3b9a389701cb","02f14aa1608fce3b6088148709eb5fe72b61699c931fa8d95a45fab1106859d1b0"],"m/0/0/11":["0288dbef3302c1bc5556028adb33e2f9e03c119dbad4f706befb8ce86cea459f2b","03f13ced465e2e0a3aaa8895f3185d5711e0bebdaf507610b7a669ac8fc82da8fe"],"m/0/0/12":["031ab4677885340d2f927ccc9747f4346b79e4eb6c750695095a8a2524610fa94a","038c881910fbd8b50d193db4e0c84f5b7840820397f92cf0718a8e06d027125503"],"m/0/0/13":["031b568452cba22eb7a88c6085489e53e35abd16068882e71a140e47e12dee9c61","020d09885ee362101d12d34ce0918d41593634db1b9413e5415c6755753b9330e8"],"m/0/0/14":["024177bc9aa03cfc72eda2dfddffd7fe9d0c2f007fc3ba1a48280feae2b9fb117a","03394ad321668440c08da76eb35475ba3a8c0e8cbe0ed81468673a8c72d38fe457"],"m/0/0/15":["02037b1cc696ffbe9eba3684edd53653386ef6cd7728401c40120037593a4c2ae2","020ab8d6900ec9c11ca5d96dfc0ce7cf0ee71653a7c45118e89abb4b113147e53a"],"m/0/0/16":["023bcbb8d4726a546087cdb83740adf0ace879b7195a572c652fa8ce4dbe195a04","0392721b230d5163d28b27fc7e059b875711f12b3da448eabe7229bde57530e637"],"m/0/0/17":["02498ee74e849d3e9261dd1863038caf83d6a3bc2eeebecf17055d4bab44dee77f","03d4dc104b2e0981693e8097437de9b05334a85e2c8edb02783897859bdbc93e32"],"m/0/0/18":["0218a9f524fe54abf8c3afd21314296cfd93eaa9227acbd457e6c9a742dc233cf4","03760f3d0c5db969bda698ff9352e3b7c332216c34825f4c6e857e39c9aee7cd35"],"m/0/0/19":["033dd51f7737f0e9db79f5c38e4298bf3396346904ef3933d290a22e5b77048d9e","0221b2eedccb9a37515263071550069b3b349a166f0f131d0028e8600d9a2251b9"],"m/0/0/20":["02cb6c39161f3244d7769f7ab96346cae2cf21cb6f4538f5e7382d363dc2f836c7","034f7bda4d1e9ed6a3774608a4d6cd8582ab59fe3187f8a7a7cf914d89426ebe28"],"m/0/0/21":["035490549d65f1360f10340037250b171470ff4c86966318a2b1eead6d8b969aea","03f6a04f6fcd07a4f32c82d53710ed30e0f54d43d41c67c661d158b3d0830c3ea2"],"m/1/0/2":["02972eae7e4302e319c266578e14a07839c1e788296a92906e6d66d938211dad5f","039ed6b488f1571ad6527acd6b6c5b8453eacf6665dc5cb7852e33d1c8ea73f9fe"],"m/1/0/3":["02bec4728888c2c045108353994bae5731ec7a7b41459023b0023e10b8d616bd30","03ce1efe16214c9eac595382e46a68143dd11a335b3f7c971ddd719ac544a5fc4b"],"m/1/0/4":["030e2df1d341568225d8dfbe5d07e98dae9f90e0f43e19dcc68c998a6ed7bcc1f0","0380f4c07dc84faf42d51779f104aa6e3b5c3ce2d7684b3cb76d49faeefc2b69d6"],"m/1/0/5":["029a54ddaa25f433b493f4b72df8c1d41be2c4d2963b8b61ee63cc86d16c12d066","021567c95e0317442e7367aa4e3378dd46c5bcef5860f789272fea83b917de0669"],"m/1/0/6":["03590320d80b61cc0874b579f467c9b5ccc50d9ef875bcf6bdd12e2d0c211e8973","03ee4677b6ee89a9d355851f2230506c6897ff219062c0df4ad9a85c60f3535f93"],"m/1/0/7":["03caf98ab1c9b79d1dc8029453a6137c08787b04043b79af3cb42d41d2d3f1338f","023f39ae4e2f4f3887d5fc58e0d3a0d7ee267dc04aa257c75b6b2d67d2f5580f81"],"m/1/0/8":["0352a2a3ea8209c9a2b633d788796ac2d16c08022440e04a77ab2835c7f971d266","0291bc248b3da997f35e8fae98a75a91fdac2819d74c4e270899338d48f7389e87"],"m/1/0/9":["02468d32d9c3c62418d506d4cd0da6cd2022d5bcafdb5f847cf7bde7a48ec6848b","032713d90d12eb6a072f3c1db6c0d3b680d3f78883016135fc0f78e8193d41d4b4"],"m/1/0/10":["034863cc6bab9b059be53413ba75c5fc286647c20d7f9e5512ef4754ea301dd1ce","03a33ab9c32a2264ee2464ebbb5892f0e34acf0fdede4f87395a89e9dacdd4930e"],"m/1/0/11":["031e19296695bfe8a96ba3bf58afa805ee1bd5471fddb3929b1678d69d442d69c9","0270feb33956fd9e937019d629523e26437493c0856514011e6aec88baf7721295"],"m/1/0/12":["03cce695d3c3843bf73e851b2446a77d7e235e5b80b4f4474f9946292eb8218742","039ea96c8822f0ec7ed28308d277f3e730480d7573579cd11b89aef4364cd9ffeb"],"m/1/0/13":["02ab4ac38eb405e822d12c0f0f354f04f9ee1d991dde887a5c1171096fe503158f","036809e60cae1203da8884ea1f85d4669ce6e053f8ba605d775e271b70ab4f6787"],"m/1/0/14":["039d61da23a8610fa0ee58eb37d7cea7ea9396c79153da97280ccf5e46718e3bac","03015c27bcc778682781fd6ad30aa6041db0b7e24270818cdceece0043ccc34b26"],"m/1/0/15":["03c088ed669132835d2728b0ecf294271c8388988c6ae264d43ca24f50e4005f81","03e2c118c9445a2ddc4c8afeb0ba49e21be3f818a483d346418b8922b8a371a2b7"],"m/1/0/16":["02bba7df9847f463c6b23eca37a4bd6efa3801a52b8ddfad804d902e783b70c81c","03764b657f23996e31c64a701facc1cbeb0c9edfdd605e2c1ed36cf48197565d45"],"m/1/0/17":["020445179c522295b89bf4bfd582eb03422e3fa20dcd29263925e9f44282d476d8","036e47bdd32f3061aed1c1f8c2a32b038c7b72391cb1f80ebfc150e58f88372766"],"m/1/0/18":["024d88c4bfcbba713d49e1edcd035234aaa1ee76ad7bcf75bf074a16658a6b0b6d","02b861e7a20d89f6875d2e44c78dbadb99503e282e5e60e9f65657af6fea81d425"],"m/1/0/19":["023a8ca9d5300181f157e1930d3b0800eebe7683d8df72e6cbf28834dbf1be5d60","026053c4f84c10d15890c0b254522972931bc2d5b7cdf9c1f9f3137c22edf3ecd3"],"m/1/0/20":["03137c66e9f3d61aba659f408d77a293fa0f3fea4ccb911074a681d6f61a55d023","0291aa1bbfbef59b16b0e37e185a706c589d448cb02e860c5df9c9d7242ecc739f"],"m/1/0/21":["03c08673e0cae55318bc9dcc4b5f11eb3ff71d42de04015e255dde3fd8cba7e09e","02423d4eab06cd5b26e71d145283523c011d58032700c517f00b328d2c90cf109f"]}},"txProposals":{"txps":[{"creator":"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5","createdTs":1405543144016,"seenBy":{"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543144016,"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543144645},"signedBy":{"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543144016},"rejectedBy":{"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543170040},"sentTs":null,"sentTxid":null,"inputChainPaths":["m/45\'/0/0/0"],"comment":"blablabla","builderObj":{"valueInSat":"29000000","valueOutSat":"8900000","feeSat":"10000","remainderSat":"20090000","hashToScriptMap":{"2NBtv6DdXj8HBunyGqpW9H8bUtW5x3rfVTj":"5221028a4b63f26253f3a8731577b8e1ee480950ad5833ebbf106fe3463bfc07cc3b90210332efa054c08cb77506a35ee0762cb7156f244566703ec08e433568ec0397bec852ae"},"selectedUtxos":[{"address":"2NBtv6DdXj8HBunyGqpW9H8bUtW5x3rfVTj","txid":"a9f4dda3f092e37244bc4e77ea921fed01d5b8ea49613dfdc0dc8afdd70190b5","vout":1,"ts":1405543855,"scriptPubKey":"a914cc93216398b77b5f8c451ca3a357bef961678be987","amount":0.29,"confirmations":0,"confirmationsFromCache":false}],"inputsSigned":0,"signaturesAdded":1,"signhash":1,"spendUnconfirmed":true,"tx":"0100000001b59001d7fd8adcc0fd3d6149eab8d501ed1f92ea774ebc4472e392f0a3ddf4a9010000009300493046022100ccbb8f398f74a76236629b8499ffc6f9518a2091f5a61a9a352c0a10f615961e022100b8f0769c76cf33bec3d7f81d9da2b74cf6e8a5e0a24ee5f48172854d8bcdbfa101475221028a4b63f26253f3a8731577b8e1ee480950ad5833ebbf106fe3463bfc07cc3b90210332efa054c08cb77506a35ee0762cb7156f244566703ec08e433568ec0397bec852aeffffffff02a0cd8700000000001976a91485eb47fe98f349065d6f044e27a4ac541af79ee288ac908c32010000000017a914560c292066792531164149c5ed63ad2793a61b928700000000"}},{"creator":"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5","createdTs":1405543188745,"seenBy":{"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543188745,"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543189341},"signedBy":{"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543188745,"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543206819},"rejectedBy":{},"sentTs":1405543207304,"sentTxid":"169bc92693dd2e27724eeba81e54210e842035bd3af6c52e6a6a5e908f1a4f66","inputChainPaths":["m/45\'/0/0/0"],"comment":"que parece","builderObj":{"valueInSat":"29000000","valueOutSat":"9000000","feeSat":"10000","remainderSat":"19990000","hashToScriptMap":{"2NBtv6DdXj8HBunyGqpW9H8bUtW5x3rfVTj":"5221028a4b63f26253f3a8731577b8e1ee480950ad5833ebbf106fe3463bfc07cc3b90210332efa054c08cb77506a35ee0762cb7156f244566703ec08e433568ec0397bec852ae"},"selectedUtxos":[{"address":"2NBtv6DdXj8HBunyGqpW9H8bUtW5x3rfVTj","txid":"a9f4dda3f092e37244bc4e77ea921fed01d5b8ea49613dfdc0dc8afdd70190b5","vout":1,"ts":1405543855,"scriptPubKey":"a914cc93216398b77b5f8c451ca3a357bef961678be987","amount":0.29,"confirmations":1,"confirmationsFromCache":false}],"inputsSigned":1,"signaturesAdded":2,"signhash":1,"spendUnconfirmed":true,"tx":"0100000001b59001d7fd8adcc0fd3d6149eab8d501ed1f92ea774ebc4472e392f0a3ddf4a901000000da00483045022035423cc74824ba904907678dda3b62a20a787b96d1b3e9f3e9546f9c57f4e45902210080a1ff1c39f458ac1642b9e948bd62fd70563b5252e749cc8fc642cd763ee830014730440220524a13f36cfb03caa246d7d84de634ec9386f2c39c19bfa926037f48da86262b022050e58a6503d105ad2805f86806810a1aa7f20d6271e1340b42fa91ab6a30f3e801475221028a4b63f26253f3a8731577b8e1ee480950ad5833ebbf106fe3463bfc07cc3b90210332efa054c08cb77506a35ee0762cb7156f244566703ec08e433568ec0397bec852aeffffffff0240548900000000001976a91485eb47fe98f349065d6f044e27a4ac541af79ee288acf00531010000000017a9146130a9d51f996b7a1b9d3e10c80930834251909d8700000000"}},{"creator":"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba","createdTs":1405543505848,"seenBy":{"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543505848,"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543590221},"signedBy":{"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543505848,"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543590221},"rejectedBy":{},"sentTs":1405543610315,"sentTxid":"6fe851b54b777a75fe80fa204dc674395e2af69efb1f7c0017e909eb82c3d914","inputChainPaths":["m/45\'/0/1/1"],"comment":"mandaaaaaaa","builderObj":{"valueInSat":"19990000","valueOutSat":"19980000","feeSat":"10000","remainderSat":"0","hashToScriptMap":{"2N277q5r8Ab6XLJNCjXXFdh5itDJRQCv9ts":"5221020389327ee8ae7d0ee3f8187842d23a4070bdd8a27c0bcddd05d80ef39009253d21025c9b49bdf17d97bd82ea1b87793082f857247f0f9b999937a166ec994bb1b41f52ae"},"selectedUtxos":[{"address":"2N277q5r8Ab6XLJNCjXXFdh5itDJRQCv9ts","txid":"169bc92693dd2e27724eeba81e54210e842035bd3af6c52e6a6a5e908f1a4f66","vout":1,"ts":1405543157,"scriptPubKey":"a9146130a9d51f996b7a1b9d3e10c80930834251909d87","amount":0.1999,"confirmationsFromCache":false}],"inputsSigned":1,"signaturesAdded":2,"signhash":1,"spendUnconfirmed":true,"tx":"0100000001664f1a8f905e6a6a2ec5f63abd3520840e21541ea8eb4e72272edd9326c99b1601000000db0048304502206b18b3dba2646c552469d8ef52d7656f6a65f563032530f622abdfd8bd4c5cee022100e804b406eddebbc827646141e74dc64c76a770ed4e35183ffd35d265ad9f7d3b01483045022100f6c013638ff0a316b1baa93dfffba6a98cf3033c133e8bd899e933c9c3e47ce10220530f40e7ea52ae58bec695edbec6d566d2ee8e7b5f33f95e33093ad1e29a125401475221020389327ee8ae7d0ee3f8187842d23a4070bdd8a27c0bcddd05d80ef39009253d21025c9b49bdf17d97bd82ea1b87793082f857247f0f9b999937a166ec994bb1b41f52aeffffffff01e0de3001000000001976a91485eb47fe98f349065d6f044e27a4ac541af79ee288ac00000000"}},{"creator":"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba","createdTs":1405543781381,"seenBy":{"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543781381,"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543782017},"signedBy":{"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543781381},"rejectedBy":{"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543794590},"sentTs":null,"sentTxid":null,"inputChainPaths":["m/45\'/0/0/1"],"comment":"1","builderObj":{"valueInSat":"29000000","valueOutSat":"1000000","feeSat":"10000","remainderSat":"27990000","hashToScriptMap":{"2N4eyXKikdnnUT4S74MRNAYqXChhUYmZ1Sb":"52210359c6d0d0d31f83301169901a6ffad9535f14014b5ab3b43561dbb2436a7b813821037d06f713f13a11967fd5edca265ff4c77528693a712c482256505693e4890d9352ae"},"selectedUtxos":[{"address":"2N4eyXKikdnnUT4S74MRNAYqXChhUYmZ1Sb","txid":"6c9da5b0da4bab0d576033325e987b10ccf2b9bf479d306b6aae36efeaa56892","vout":0,"ts":1405543698,"scriptPubKey":"a9147d274ac50968d7823b6cbc1b38770deb7157995387","amount":0.29,"confirmationsFromCache":false}],"inputsSigned":0,"signaturesAdded":1,"signhash":1,"spendUnconfirmed":true,"tx":"01000000019268a5eaef36ae6a6b309d47bfb9f2cc107b985e323360570dab4bdab0a59d6c000000009200483045022064d877bc5171fbaef909c2a1a924e0023b3ccc0b530cb46653f06ecb230283e8022100bc6658d60ad4f7120d9226c8f6eada87f3b0388f73c458011988bab36e78ba15014752210359c6d0d0d31f83301169901a6ffad9535f14014b5ab3b43561dbb2436a7b813821037d06f713f13a11967fd5edca265ff4c77528693a712c482256505693e4890d9352aeffffffff0240420f00000000001976a91485eb47fe98f349065d6f044e27a4ac541af79ee288acf017ab010000000017a91421c4a435d9ac263ec55b35a1a5ca95e979639b9b8700000000"}},{"creator":"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5","createdTs":1405543835343,"seenBy":{"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543835343,"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543835968},"signedBy":{"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543835343},"rejectedBy":{"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543850998},"sentTs":null,"sentTxid":null,"inputChainPaths":["m/45\'/0/0/1"],"comment":"2","builderObj":{"valueInSat":"29000000","valueOutSat":"1000000","feeSat":"10000","remainderSat":"27990000","hashToScriptMap":{"2N4eyXKikdnnUT4S74MRNAYqXChhUYmZ1Sb":"52210359c6d0d0d31f83301169901a6ffad9535f14014b5ab3b43561dbb2436a7b813821037d06f713f13a11967fd5edca265ff4c77528693a712c482256505693e4890d9352ae"},"selectedUtxos":[{"address":"2N4eyXKikdnnUT4S74MRNAYqXChhUYmZ1Sb","txid":"6c9da5b0da4bab0d576033325e987b10ccf2b9bf479d306b6aae36efeaa56892","vout":0,"ts":1405543698,"scriptPubKey":"a9147d274ac50968d7823b6cbc1b38770deb7157995387","amount":0.29,"confirmationsFromCache":false}],"inputsSigned":0,"signaturesAdded":1,"signhash":1,"spendUnconfirmed":true,"tx":"01000000019268a5eaef36ae6a6b309d47bfb9f2cc107b985e323360570dab4bdab0a59d6c0000000092004830450220302baae7de2e0f102bf3af2d5f450f673e51bd143020141a769ccdcdf16af188022100e7abc087c76050ed649e7139a5a136969e74e24a8d8f6223d3219ad033a26451014752210359c6d0d0d31f83301169901a6ffad9535f14014b5ab3b43561dbb2436a7b813821037d06f713f13a11967fd5edca265ff4c77528693a712c482256505693e4890d9352aeffffffff0240420f00000000001976a91485eb47fe98f349065d6f044e27a4ac541af79ee288acf017ab010000000017a9148b102abba0729fb0690c61cf7187064d692d43d78700000000"}},{"creator":"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba","createdTs":1405543869803,"seenBy":{"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543869803,"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543870411},"signedBy":{"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543869803,"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543890406},"rejectedBy":{},"sentTs":1405543890913,"sentTxid":"6a0f61574ad65e537e7e99298968db565f97b894b61f4c8f8fac8fcaedb83e2b","inputChainPaths":["m/45\'/0/0/1"],"comment":"3","builderObj":{"valueInSat":"29000000","valueOutSat":"1100000","feeSat":"10000","remainderSat":"27890000","hashToScriptMap":{"2N4eyXKikdnnUT4S74MRNAYqXChhUYmZ1Sb":"52210359c6d0d0d31f83301169901a6ffad9535f14014b5ab3b43561dbb2436a7b813821037d06f713f13a11967fd5edca265ff4c77528693a712c482256505693e4890d9352ae"},"selectedUtxos":[{"address":"2N4eyXKikdnnUT4S74MRNAYqXChhUYmZ1Sb","txid":"6c9da5b0da4bab0d576033325e987b10ccf2b9bf479d306b6aae36efeaa56892","vout":0,"ts":1405543698,"scriptPubKey":"a9147d274ac50968d7823b6cbc1b38770deb7157995387","amount":0.29,"confirmationsFromCache":false}],"inputsSigned":1,"signaturesAdded":2,"signhash":1,"spendUnconfirmed":true,"tx":"01000000019268a5eaef36ae6a6b309d47bfb9f2cc107b985e323360570dab4bdab0a59d6c00000000db00483045022100a8ce7907f9fd7dd41dd65c2dec425e008efea06ee7c80787c10c0e210fbf181302207712c0fdd1cb25836ac1fc2fd303c1e26b85e8980417719b9ed50e977a9693ec01483045022100d1780c4f028cd898920aca3eaceba352ed9306cd17f019ae2f634e8facad149a02203c84ab2093da8e22577e93f27a732f0728d4e6db0c749f3cd3d898d6a025152a014752210359c6d0d0d31f83301169901a6ffad9535f14014b5ab3b43561dbb2436a7b813821037d06f713f13a11967fd5edca265ff4c77528693a712c482256505693e4890d9352aeffffffff02e0c81000000000001976a91485eb47fe98f349065d6f044e27a4ac541af79ee288ac5091a9010000000017a914cc1cab78458b1a951b91c6dcd7eeeeb682f506388700000000"}}],"walletId":"55d4bd062d32f90a","networkName":"testnet"},"privateKey":{"extendedPrivateKeyString":"tprv8ZgxMBicQKsPdWUAmaaopPftevC72Jtiu19V8ee5XijL9JvogqfR95uVrL85f8yBdQMq3KyQtG3Q91yWQb3XDbWWpcdWFDAmJ7Xy2XWkGJu","networkName":"testnet","privateKeyCache":{"m/45\'/0/0/0":"b6fd8d1a079efd523da34f31ba81f544fc3d0a728a8a98299d8980682518e79c","m/45\'/0/1/1":"0f4d52d2a99e4c8c1c2edf09fef12407c3abd2304b961198c3f131a8c8443a13","m/45\'/0/0/1":"de5c191c343bd6017b98708c03344849624a14e2c167cfd6eb8dcb075d139293"}},"addressBook":{"msj42CCGruhRsFrGATiUuh25dtxYtnpbTx":{"hidden":false,"createdTs":1405543109222,"copayerId":"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba","label":"faucet","signature":"3045022067576e5b37f2707a8dc66e57511ad9b10a3125bd95193fff6f8f6402969c3bf3022100adff9f417db07d88face13b3d13f422740d4421440cade1a205684dfdc5d733a"}}}'; -var encryptedLegacyO = 'U2FsdGVkX19yGM1uBAIzQa8Po/dvUicmxt1YyRk/S97PcZ6I6rHMp9dMagIrehg4Qd6JHn/ustmFHS7vmBYj0EBpf6rdXiQezaWnVAJS9/xYjAO36EFUbl+NmUanuwujAxgYdSP/sNssRLeInvExmZYW993EEclxkwL6YUyX66kKsxGQo2oWng0NreBJNhFmrbOEWeFje2PiWP57oUjKsurFzwpluAAarUTYSLud+nXeabC7opzOP5yqniWBMJz0Ou8gpNCWCMhG/P9F9ccVPY7juyd0Hf41FVse8nd2++axKB57+paozLdO+HRfV6zkMqC3h8gWY7LkS75j3bvqcTw9LhXmzE0Sz21n9yDnRpA4chiAvtwQvvBGgj1pFMKhNQU6Obac9ZwKYzUTgdDn3Uzg1UlDzgyOh9S89rbRTV84WB+hXwhuVluWzbNNYV3vXe5PFrocVktIrtS3xQh+k/7my4A6/gRRrzNYpKrUASJqDS/9u9WBkG35xD63J/qXjtG2M0YPwbI57BK1IK4K510b8V72lz5U2XQrIC4ldBwni1rpSavwCJV9xF6hUdOmNV8fZsVHP0NeN1PYlLkSb2QgfuoWnkcsJerwuFR7GZC/i6efrswtpO0wMEQr/J0CLbeXlHAru6xxjCBhWoJvZpMGw72zgnDLoyMNsEVglNhx/VlV9ZMYkkdaEYAxPOEIyZdQ5MS+2jEAlXf818n/xzJSVrniCn9be8EPePvkw35pivprvy09vbW4cKsWBKvgIyoT6A3OhUOCCS8E9cg0WAjjav2EymrbKmGWRHaiD+EoJqaDg6s20zhHn1YEa/YwvGGSB5+Hg8baLHD8ZASvxz4cFFAAVZrBUedRFgHzqwaMUlFXLgueivWUj7RXlIw6GuNhLoo1QkhZMacf23hrFxxQYvGBRw1hekBuDmcsGWljA28udBxBd5f9i+3gErttMLJ6IPaud590uvrxRIclu0Sz9R2EQX64YJxqDtLpMY0PjddSMu8vaDRpK9/ZSrnz/xrXsyabaafz4rE/ItFXjwFUFkvtmuauHTz6nmuKjVfxvNLNAiKb/gI7vQyUhnTbKIApe7XyJsjedNDtZqsPoJRIzdDmrZYxGStbAZ7HThqFJlSJ9NPNhH+E2jm3TwL5mwt0fFZ5h+p497lHMtIcKffESo7KNa2juSVNMDREk0NcyxGXGiVB2FWl4sLdvyhcsVq0I7tmW6OGZKRf8W49GCJXq6Ie69DJ9LB1DO67NV1jsYbsLx9uhE2yEmpWZ3jkoCV/Eas4grxt0CGN6EavzQ=='; -var legacyPassword = '1'; + + + +var legacy1 = '{"opts":{"id":"48ba2f1ffdfe9708","spendUnconfirmed":true,"requiredCopayers":1,"totalCopayers":1,"name":"pepe wallet","version":"0.4.7"},"networkNonce":"5405f06b00000001","networkNonces":[],"publicKeyRing":{"walletId":"48ba2f1ffdfe9708","networkName":"testnet","requiredCopayers":1,"totalCopayers":1,"indexes":[{"copayerIndex":2147483647,"changeIndex":0,"receiveIndex":1},{"copayerIndex":0,"changeIndex":0,"receiveIndex":1}],"copayersBackup":["0298f65b2694c55f9048bc05f10368242727c7f9d2065cbd788c3ecde1ec57f33f"],"copayersExtPubKeys":["tpubD9SGoP7CXsqSKTiQxCZSCpicDcophqnE4yuqjfw5M9tAR3fSjT9GDGwPEUFCN7SSmRKGDLZgKQePYFaLWyK32akeSan45TNTd8sgef9Ymh6"],"nicknameFor":{}},"txProposals":{"txps":[],"walletId":"48ba2f1ffdfe9708","networkName":"testnet"},"privateKey":{"extendedPrivateKeyString":"tprv8ZgxMBicQKsPfQCscb7CtJKzixxcVSyrCVcfr3WCFbtT8kYTzNubhjQ5R7AuYJgPCcSH4R8T34YVxeohKGhAB9wbB4eFBbQFjUpjGCqptHm","networkName":"testnet"},"addressBook":{}}'; From 64072f83bc2d24f2db65376341830f0d99be9d13 Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Mon, 15 Sep 2014 14:25:09 -0300 Subject: [PATCH 127/191] rebased! --- js/models/core/WalletFactory.js | 52 +++++++++++++++------------------ 1 file changed, 23 insertions(+), 29 deletions(-) diff --git a/js/models/core/WalletFactory.js b/js/models/core/WalletFactory.js index 48010d1c7..c3c2b505b 100644 --- a/js/models/core/WalletFactory.js +++ b/js/models/core/WalletFactory.js @@ -53,7 +53,6 @@ function WalletFactory(config, version, pluginManager) { this.storage = new this.Storage(storageOpts); -<<<<<<< HEAD this.networks = { 'livenet': new this.Network(config.network.livenet), 'testnet': new this.Network(config.network.testnet), @@ -63,11 +62,7 @@ function WalletFactory(config, version, pluginManager) { 'testnet': new this.Blockchain(config.network.testnet), }; - this.walletDefaults = config.wallet; -======= - this.networkName = config.networkName; - this.walletDefaults = config.wallet || {}; ->>>>>>> ALL TEST PASSING!!! + this.walletDefaults = config.walle || {}; this.version = version; }; @@ -100,7 +95,7 @@ WalletFactory.prototype.fromObj = function(obj, skipFields) { obj.opts.reconnectDelay = this.walletDefaults.reconnectDelay; // this is only used if private key or public key ring is skipped - obj.opts.networkName = this.networkName; + obj.opts.networkName = networkName; skipFields = skipFields || []; skipFields.forEach(function(k) { @@ -420,29 +415,28 @@ WalletFactory.prototype.joinCreateSession = function(opts, cb) { }); joinNetwork.start(opts, function() { - joinNetwork.greet(decodedSecret.pubKey, opts.secretNumber); - joinNetwork.on('data', function(sender, data) { - if (data.type === 'walletId' && data.opts) { - if (data.networkName !== decodedSecret.networkName) { - return cb('badNetwork'); - } + joinNetwork.greet(decodedSecret.pubKey, opts.secretNumber); + joinNetwork.on('data', function(sender, data) { + if (data.type === 'walletId' && data.opts) { + if (data.networkName !== decodedSecret.networkName) { + return cb('badNetwork'); + } - data.opts.privateKey = privateKey; - data.opts.nickname = nickname; - data.opts.passphrase = passphrase; - data.opts.id = data.walletId; - self.create(data.opts, function(err, w) { - if (!err & w) { - w.sendWalletReady(s.pubKey); - } else { - if (!err) err = 'walletFull'; - } - return cb(err, w); - }); - - }); - }); - }; + data.opts.privateKey = privateKey; + data.opts.nickname = nickname; + data.opts.passphrase = passphrase; + data.opts.id = data.walletId; + self.create(data.opts, function(err, w) { + if (!err & w) { + w.sendWalletReady(s.pubKey); + } else { + if (!err) err = 'walletFull'; + } + return cb(err, w); + }); + } + }); + }); }; module.exports = WalletFactory; From 03c3eefd0d68ce49fce5b4d6259885b69b4de7a4 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Mon, 15 Sep 2014 11:42:12 -0700 Subject: [PATCH 128/191] paypro: fix xhr error messages. remove comments. --- js/models/core/Wallet.js | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/js/models/core/Wallet.js b/js/models/core/Wallet.js index 61e81b137..815ee3fa0 100644 --- a/js/models/core/Wallet.js +++ b/js/models/core/Wallet.js @@ -1295,7 +1295,7 @@ Wallet.prototype.createPaymentTx = function(options, cb) { return self.receivePaymentRequest(options, pr, cb); }) .error(function(data, status, headers, config) { - return cb(new Error('Status: ' + JSON.stringify(status))); + return cb(new Error('Status: ' + status)); }); }; @@ -1572,7 +1572,7 @@ Wallet.prototype.sendPaymentTx = function(ntxid, options, cb) { return self.receivePaymentRequestACK(ntxid, tx, txp, ack, cb); }) .error(function(data, status, headers, config) { - return cb(new Error('Status: ' + JSON.stringify(status))); + return cb(new Error('Status: ' + status)); }); }; @@ -2483,15 +2483,6 @@ Wallet.prototype.verifySignedJson = function(senderId, payload, signature) { return v; } -// NOTE: Angular $http module does not send ArrayBuffers correctly, so we're -// not going to use it. We'll have to write our own. Otherwise, we could -// hex-encoded our messages and decode them on the other side, but that -// deviates from BIP-70. - -// if (typeof angular !== 'undefined') { -// var $http = angular.bootstrap().get('$http'); -// } - /** * @desc Create a HTTP request * @TODO: This shouldn't be a wallet responsibility @@ -2557,7 +2548,13 @@ Wallet.request = function(options, callback) { }; xhr.onerror = function(event) { - return ret._error(null, new Error(event.message), null, options); + var status; + if (xhr.status === 0 || !xhr.statusText) { + status = 'HTTP Request Error: This endpoint likely does not support cross-origin requests.'; + } else { + status = xhr.statusText; + } + return ret._error(null, status, null, options); }; if (req.body) { From 52a8423df9a5a60b5670222806c1765ec796b1f5 Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Mon, 15 Sep 2014 16:11:26 -0300 Subject: [PATCH 129/191] trying to fix tests --- js/models/core/WalletFactory.js | 8 +++----- test/test.WalletFactory.js | 29 +++++++++++++++++++---------- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/js/models/core/WalletFactory.js b/js/models/core/WalletFactory.js index c3c2b505b..702ae499e 100644 --- a/js/models/core/WalletFactory.js +++ b/js/models/core/WalletFactory.js @@ -37,7 +37,8 @@ var Storage = module.exports.Storage = require('../Storage'); function WalletFactory(config, version, pluginManager) { var self = this; - config = config || {}; + preconditions.checkArgument(config); + preconditions.checkArgument(config.network); this.Storage = config.Storage || Storage; this.Network = config.Network || Async; @@ -62,7 +63,7 @@ function WalletFactory(config, version, pluginManager) { 'testnet': new this.Blockchain(config.network.testnet), }; - this.walletDefaults = config.walle || {}; + this.walletDefaults = config.wallet || {}; this.version = version; }; @@ -94,9 +95,6 @@ WalletFactory.prototype.fromObj = function(obj, skipFields) { obj.opts = obj.opts || {}; obj.opts.reconnectDelay = this.walletDefaults.reconnectDelay; - // this is only used if private key or public key ring is skipped - obj.opts.networkName = networkName; - skipFields = skipFields || []; skipFields.forEach(function(k) { if (obj[k]) { diff --git a/test/test.WalletFactory.js b/test/test.WalletFactory.js index 2ec67e64a..44d4fd517 100644 --- a/test/test.WalletFactory.js +++ b/test/test.WalletFactory.js @@ -131,30 +131,39 @@ describe('WalletFactory model', function() { iterations: 100, storageSalt: 'mjuBtGybi/4=', }, + + // network layer config + network: { + testnet: { + url: 'https://test-insight.bitpay.com:443' + }, + livenet: { + url: 'https://insight.bitpay.com:443' + }, + }, + }; describe('#constructor', function() { it('should create the factory', function() { var wf = new WalletFactory(config, '0.0.1'); should.exist(wf); - wf.networkName.should.equal(config.networkName); wf.walletDefaults.should.deep.equal(config.wallet); wf.version.should.equal('0.0.1'); }); }); describe('#fromObj / #toObj', function() { - it('round trip', function() { + it.only('round trip', function() { var wf = new WalletFactory(config, '0.0.5'); - var w = wf.fromObj(JSON.parse(o)); + var original = JSON.parse(o); + var o2 = wf.fromObj(original).toObj(); - should.exist(w); - w.id.should.equal("dbfe10c3fae71cea"); - should.exist(w.publicKeyRing.getCopayerId); - should.exist(w.txProposals.toObj()); - should.exist(w.privateKey.toObj()); - - assertObjectEqual(w.toObj(), JSON.parse(o)); +console.log('[test.WalletFactory.js.169]', original.opts); //TODO + ['addressBook', 'networkNonce','networkNonces', 'opts', 'privateKey','copayersExtPubKeys'].forEach(function(k){ + o2[k].should.be.deep.equal(original[k], k + ' differs'); + }) + //assertObjectEqual(w.toObj(), JSON.parse(o)); }); it('round trip, using old copayerIndex', function() { From 2562490b4d104bef82841e6185c150db1d72dc2a Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Mon, 15 Sep 2014 16:16:02 -0300 Subject: [PATCH 130/191] rm comment --- js/models/core/Wallet.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/models/core/Wallet.js b/js/models/core/Wallet.js index c14a568fe..873d14bf8 100644 --- a/js/models/core/Wallet.js +++ b/js/models/core/Wallet.js @@ -884,7 +884,7 @@ Wallet.prototype.toObj = function() { */ Wallet.fromObj = function(o, storage, network, blockchain) { - // TODO: What is this supposed to do? + // clone opts var opts = JSON.parse(JSON.stringify(o.opts)); opts.addressBook = o.addressBook; From b38c26fbd4e04de90d8caa6265229935c9fcd578 Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Mon, 15 Sep 2014 16:42:45 -0300 Subject: [PATCH 131/191] . --- test/test.WalletFactory.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/test.WalletFactory.js b/test/test.WalletFactory.js index 44d4fd517..eaaa526fc 100644 --- a/test/test.WalletFactory.js +++ b/test/test.WalletFactory.js @@ -161,7 +161,9 @@ describe('WalletFactory model', function() { console.log('[test.WalletFactory.js.169]', original.opts); //TODO ['addressBook', 'networkNonce','networkNonces', 'opts', 'privateKey','copayersExtPubKeys'].forEach(function(k){ +console.log('[test.WalletFactory.js.166:original:]',k,original[k]); //TODO o2[k].should.be.deep.equal(original[k], k + ' differs'); + }) //assertObjectEqual(w.toObj(), JSON.parse(o)); }); @@ -602,7 +604,7 @@ console.log('[test.WalletFactory.js.169]', original.opts); //TODO }); -var o = '{"opts":{"id":"dbfe10c3fae71cea","spendUnconfirmed":1,"requiredCopayers":3,"totalCopayers":5,"version":"0.0.5"},"networkNonce":"0000000000000001","networkNonces":[],"publicKeyRing":{"walletId":"dbfe10c3fae71cea","networkName":"testnet","requiredCopayers":3,"totalCopayers":5,"indexes":[{"copayerIndex":2,"changeIndex":0,"receiveIndex":0}],"copayersBackup":[],"copayersExtPubKeys":["tpubD6NzVbkrYhZ4YGK8ZhZ8WVeBXNAAoTYjjpw9twCPiNGrGQYFktP3iVQkKmZNiFnUcAFMJRxJVJF6Nq9MDv2kiRceExJaHFbxUCGUiRhmy97","tpubD6NzVbkrYhZ4YKGDJkzWdQsQV3AcFemaQKiwNhV4RL8FHnBFvinidGdQtP8RKj3h34E65RkdtxjrggZYqsEwJ8RhhN2zz9VrjLnrnwbXYNc","tpubD6NzVbkrYhZ4YkDiewjb32Pp3Sz9WK2jpp37KnL7RCrHAyPpnLfgdfRnTdpn6DTWmPS7niywfgWiT42aJb1J6CjWVNmkgsMCxuw7j9DaGKB","tpubD6NzVbkrYhZ4XEtUAz4UUTWbprewbLTaMhR8NUvSJUEAh4Sidxr6rRPFdqqVRR73btKf13wUjds2i8vVCNo8sbKrAnyoTr3o5Y6QSbboQjk","tpubD6NzVbkrYhZ4Yj9AAt6xUVuGPVd8jXCrEE6V2wp7U3PFh8jYYvVad31b4VUXEYXzSnkco4fktu8r4icBsB2t3pCR3WnhVLedY2hxGcPFLKD"],"nicknameFor":{}},"txProposals":{"txps":[],"walletId":"dbfe10c3fae71cea","networkName":"testnet"},"privateKey":{"extendedPrivateKeyString":"tprv8ZgxMBicQKsPeoHLg3tY75z4xLeEe8MqAXLNcRA6J6UTRvHV8VZTXznt9eoTmSk1fwSrwZtMhY3XkNsceJ14h6sCXHSWinRqMSSbY8tfhHi","networkName":"testnet"},"addressBook":{}}'; +var o = '{"opts":{"id":"dbfe10c3fae71cea","spendUnconfirmed":1,"requiredCopayers":3,"totalCopayers":5,"version":"0.0.5","networkName":"testnet"},"networkNonce":"0000000000000001","networkNonces":[],"publicKeyRing":{"walletId":"dbfe10c3fae71cea","networkName":"testnet","requiredCopayers":3,"totalCopayers":5,"indexes":[{"copayerIndex":2,"changeIndex":0,"receiveIndex":0}],"copayersBackup":[],"copayersExtPubKeys":["tpubD6NzVbkrYhZ4YGK8ZhZ8WVeBXNAAoTYjjpw9twCPiNGrGQYFktP3iVQkKmZNiFnUcAFMJRxJVJF6Nq9MDv2kiRceExJaHFbxUCGUiRhmy97","tpubD6NzVbkrYhZ4YKGDJkzWdQsQV3AcFemaQKiwNhV4RL8FHnBFvinidGdQtP8RKj3h34E65RkdtxjrggZYqsEwJ8RhhN2zz9VrjLnrnwbXYNc","tpubD6NzVbkrYhZ4YkDiewjb32Pp3Sz9WK2jpp37KnL7RCrHAyPpnLfgdfRnTdpn6DTWmPS7niywfgWiT42aJb1J6CjWVNmkgsMCxuw7j9DaGKB","tpubD6NzVbkrYhZ4XEtUAz4UUTWbprewbLTaMhR8NUvSJUEAh4Sidxr6rRPFdqqVRR73btKf13wUjds2i8vVCNo8sbKrAnyoTr3o5Y6QSbboQjk","tpubD6NzVbkrYhZ4Yj9AAt6xUVuGPVd8jXCrEE6V2wp7U3PFh8jYYvVad31b4VUXEYXzSnkco4fktu8r4icBsB2t3pCR3WnhVLedY2hxGcPFLKD"],"nicknameFor":{}},"txProposals":{"txps":[],"walletId":"dbfe10c3fae71cea","networkName":"testnet"},"privateKey":{"extendedPrivateKeyString":"tprv8ZgxMBicQKsPeoHLg3tY75z4xLeEe8MqAXLNcRA6J6UTRvHV8VZTXznt9eoTmSk1fwSrwZtMhY3XkNsceJ14h6sCXHSWinRqMSSbY8tfhHi","networkName":"testnet"},"addressBook":{}}'; var legacyO = '{"opts":{"id":"55d4bd062d32f90a","spendUnconfirmed":true,"requiredCopayers":2,"totalCopayers":2,"name":"xcvzxcv","version":"0.3.2"},"networkNonce":"53d25e8600000009","networkNonces":[],"publicKeyRing":{"walletId":"55d4bd062d32f90a","networkName":"testnet","requiredCopayers":2,"totalCopayers":2,"indexes":[{"copayerIndex":2147483647,"changeIndex":0,"receiveIndex":0},{"copayerIndex":0,"changeIndex":4,"receiveIndex":2},{"copayerIndex":1,"changeIndex":5,"receiveIndex":2}],"copayersBackup":["02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba","02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5"],"copayersExtPubKeys":["tpubD94LTzAUiW99mpA59nyf6fAHh4xKGmnwbgCV4gU2bRpeN9CRiMSurqme22px5NmJAo6FdcdH883Zu98VbqyhesCJ86kUEjH3Zpufy5FfcaC","tpubDA2U9H6LkRHDRbRxHBp4VTbxPc7JqsvtcLxrE5QJF8z1iT6hMJ1pXSVf57GWRcxXutYvpoXRurDVGsscJauMtnJBkYAWBVExYmm91XQE2zz"],"nicknameFor":{"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":"asdf","02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":"qwerqw"},"publicKeysCache":{"m/0/0/0":["028a4b63f26253f3a8731577b8e1ee480950ad5833ebbf106fe3463bfc07cc3b90","0332efa054c08cb77506a35ee0762cb7156f244566703ec08e433568ec0397bec8"],"m/1/0/0":["0220ad514cf593d0c3905d3bb49bc5767a9410823bf9b77ea5ef2cf1d1016d77a8","02fd42cf66f1dbdc7bbb9ae09aecea72df479ffe5a0c4641301067e331d12e416d"],"m/1/0/1":["0315f7868eaf1f9b7127e3f7e0222c5e473eea003e34700f4758b6873c525d6723","02a2e8ed5e90dd39e3842fc790e06178997dbca319987f365317589e2a71a93658"],"m/0/1/0":["0244a25a0b97b26707fd855c15b046b901be85a3b70a781d0678608e633440eeca","0358cdcbc528ddfb7173b0dab283f702be82546ff031e4a832a7270080cb875959"],"m/0/1/1":["025c9b49bdf17d97bd82ea1b87793082f857247f0f9b999937a166ec994bb1b41f","020389327ee8ae7d0ee3f8187842d23a4070bdd8a27c0bcddd05d80ef39009253d"],"m/1/1/0":["02fd0e7c62b7b58d1ea7bb4cb84d53b019df99d3703a42aed73a2cfa15f3af5d08","0355a15912e76072ef50e6643376b8a9da8422ed4f8ea07b1d84d4989be5a39b2e"],"m/1/1/1":["03bc3e1f4db32efd8eb1fd44a1665938d59628429c67e1e8b7054ab5717f4e6750","03c4c817b633ac31f44f16f390af831d35f7d98744a52a0f23e9598967342255f8"],"m/1/1/2":["02826fe7e9da408480ddeb1d4414c5100b350f862ca718e27122681e1a0ca35077","02bd25af907bb3edbf6b2cd1ea90eaa92cc93ec47bea7d339af44c1d2c05708e99"],"m/0/1/2":["0337a1a70364b94745d6e26d2d28919cf528304f52765f12ef43e3d6da0a6c8dc0","039d83db9aa43e6e00e0304e6971b6079d79dc12d8d55ce2e6fc24a52ba8d41329"],"m/0/0/1":["0359c6d0d0d31f83301169901a6ffad9535f14014b5ab3b43561dbb2436a7b8138","037d06f713f13a11967fd5edca265ff4c77528693a712c482256505693e4890d93"],"m/1/1/3":["02600e5c41670773a213a4cb58c8f2fa3e83840784bc7f0b56925e1075e06632c2","036d01867af5f61371151ef7d9026fa0400a623f6924e404ee0b856625268972f9"],"m/0/1/3":["03e5a9b039b187ca8e065627df402e4a5b196b94198542da7036879de08be63d2d","0304f3e0b70f696d80e5785dc7747d6dcb55ba24c31f2d80bf184b4e582e6b47fc"],"m/1/1/4":["03741afa5bd50d6ba5801064c810fae84f6a4557d6a88ddc8591d0d4eb68a8fc41","0214dd6ce6073b05999fb887098ca6f7e1d0b4fdc0760557786907df353df90d1c"],"m/2147483647/1/0":["033e072a53ea835763a03c66e35c35384736210a1bb7d7ee6d9a3e109e82426b30","02e37b5570c053da8a8ee587be86fc629775c4db890aba2745ccc4e4dcc8c31041"],"m/2147483647/1/1":["0228a6de42ef421c263d1efd9f28d9a7d15a261995028a24eff6b9f1c3fc46e6bf","0226cff885cb0d607cc9cf69a7608316eb3fb2ec344c0c9956246ba776116fc396"],"m/2147483647/1/2":["034fe2a8f0b98445eb5810fe36572ad2f64ed9bf64dc9de624f99c0142cb07c682","02f2c5c758e32293f5c193fd69afadbba83abafb397db01e6f2b447690e900475a"],"m/2147483647/1/3":["02b25ef9434446c51f10678f787e4913de582e34d164bd3b06af7732c5476df1a8","025d51a1efd59bcff22ee2e0af61b21a7ba5f639e20dfdf25690e926005177dd0c"],"m/2147483647/1/4":["03e5734e1d29b2f684d0446b7a2ffbd0ba8952570a502d0d14b1efd8f24b61be53","0258fc28a324848d8d0154e8614815e35c668d274a8f01957bb99aab8dc8f386c0"],"m/2147483647/1/5":["021f9e775246765e1cfba0ae453b4eae6cd4ae5a57a09c319edbe89d4dbbf23be3","02857f66571a1c3eb9e72d22ae88e734c03d448bced4dcfd345c2059468124c741"],"m/2147483647/1/6":["02c072f329391a25255dc6452e5f5220966869dbf736ba8a8c3ae9d273a84bc3fd","030920a8b8e88c4db2871a7df0878a86cf0695f6d96bb50c701c3454f3df25176a"],"m/2147483647/1/7":["036bf329fc19bce10cf1999fae5bfa80290ff7b44776b49c7b0dc9eec6cffcfa21","03955a549875b4f7b9be28b9ff4bcd51ad2bc224430b1634baef890585885d5e1b"],"m/2147483647/1/8":["024879c9c9a261b3141ecfa1c79c4efc25278c844ecd1dcfcb95d9c19581fbdd25","03fb4a5fdb91239df3ccf7f61a5b99e7e72483101e21c9d1ee0d85544e9354c6c7"],"m/2147483647/1/9":["035928a107ec01f78cd586914d5a49710fd42e352b1312e3ad0eeb2c9666fdf8e7","03a54c03093797854829c75357f092356352a109042bbb83bdac20cb4e5eca27ea"],"m/2147483647/1/10":["021e7a3a7efe888c5e820b5cf0f03317b2b4bf438d8563449aeb7a77cade97f136","03ec0960b3d1df52ca3cc2c82b7d97063400da4dd051bba2f9bab6cb44aee01efa"],"m/2147483647/1/11":["035d70c26b7f429861f555f7c0d99947411b23b7f95303fb8d5de5b82a95aa30fc","038b922f7024f5446d6b48e5253643543b35c006d90fd37688105c6cefcd8adb8a"],"m/2147483647/1/12":["02158d6503891c6c65a606221dbf5c68d0832288975914007968419939588ecb24","0248264cb1763a3f4de9b34787b4bc5443ec92ef915927494bb9f1c1c0b498c7ca"],"m/2147483647/1/13":["0349965eea38a25ae0c061faeac4c4e57e648bc4c0f059d07b3b8b7962cbc0dde5","0352243d9269565ce2a1ffdd0b8e43a442c6dd1c9edda86eaaf2cba5a4a95c40f1"],"m/2147483647/1/14":["030fa6e3d0c5cedc0581955395c77cbe134c912a47971023b9695332df3f7bb200","03f2cf09e33326fb59bf3f13e6298d2d5d29c9eae3b872e5a851e8d8d77259c883"],"m/2147483647/1/15":["02bf0d45e41339f552df6f8baf4392142921fd38b0f2a4388a905ff6cbacbc278a","03fabe46bb6706a1b8edfd28c046a8891b4530bbe5305080b72b0d08ebdf7b8c0a"],"m/2147483647/1/16":["03a4e3146ed34d6a8af4e4379e6edcff32cb0373ba232b3d746af3052f674133ac","030311b73c6f5c46ddffc0cfce6e5ed0b671d94267d8e52cd8837f2a479916eb91"],"m/2147483647/1/17":["03233df93c762d2f06c7f5f388e4e0a8dbdb13302acba0d2d6995c487d8aec9f2f","024badfdcb7e772ac7fc1c46d3943b07500edbbece105cdeff3eb9e9fcc9f54782"],"m/2147483647/1/18":["0364035475a098e00eb010c500cad3c90af3e81a4bd613144bc9433a150f14718b","028223dc8142154e7477ce000b3dc13e1d15a901553d9b18864c8645b582b38fe6"],"m/2147483647/1/19":["03971b74b4ac4bdaadf636baa4caa82fe5355471ed6ea05a9cbe5fc6c9e4b9db76","0202ebffacd01f83849e5bc5c0e2c317bc5fb2fbcb2d6d4482a5235f9f1308b61a"],"m/0/1/4":["03005ee9ff028c98fd132e531023f2f2b61ff0d26022f979dd98088d2ba167b031","0345ea82e8dfe38277f0c3aee18d2dd93edb63e8663ac83328a7934d2ca57006f6"],"m/0/1/5":["0391bc4990b71d8a3f156ae7107929ed6372b0b4ba8a868253f71ba7189d1efa02","0312a74cf2e7c0dd41897d04fabfd8cc3187b84a28305cfc79315b24e6fe23a6b4"],"m/0/1/6":["021a38c492607ff9684a4fec445e47b5b7100d3ef9e9dc0d0b37c0a646d28d4f77","03ae0b46ab36f97447ebaa53f2b5c8f090f15395378785f2fd285eeba17fbf3f65"],"m/0/1/7":["0308cdec88c1ffe16edc98853d9c08dbd4ba2541ba566668ca17bda19d7eb3481f","02dd622267c2e68287287b8b61724f76fbe84096a56aa5054af92f8fe25380e2d1"],"m/0/1/8":["039647da9ad725836bcb28a3e0497659a28d7749d1416c421a0a01c62d237ee962","022e22aa61eafda0dd8820427f1a06314d352a15ea8645e7ab9b80920017084d82"],"m/0/1/9":["03a4ade946076c6962b70c70ac7fad3a87efb59a1d0a4e32bda13a6d47fe9df961","029a07235aba04ab69526e117d836d5b3fae5cfc8c5e72b10c6d1afd261ccc19f3"],"m/0/1/10":["03c78e9b6493b22790db1acea20df9444e0f9c424fc5756e7a32c290ae01783953","0254c130ee467a96570c9f5ebea89de04f0b1db1686b164f2694339bef8f25dd88"],"m/0/1/11":["03a762c43318ef8d4840fab04c8db73797dc648825fac60f2730b4c76678df1cf3","0212c684a4de8e750ad2dfe2b136370ab9803eca178ed9a27b3990c29b067de35c"],"m/0/1/12":["02702d221f9b15c5cf75ac2f497a6c63e60213087c3d2d3be46768e3ebd238e26e","03ed58580744deb357258e44548212038670769d8d51e385d4fb8414311fd01b52"],"m/0/1/13":["0320e0597b54c62768352f433389cee4725d6094d7bcb5c72265edcc0933829aff","02c5706f11b9a85f3176c572842b7c9812c2195058d24d945bc026b00312740e76"],"m/0/1/14":["02fe43077676b844226d3aaa62e8a86d237710d92f882366944acbde0c8992fcaf","039a6a8662abb8910741cf331320549665e9feb28ca94d1ab6a43c84fa330b94ee"],"m/0/1/15":["0369f99f72847af93d50ab8ee75b6e7e912d26e27be96f6d6b7215cf7daeff7ba5","02521700cc07c953ba5aa586fb0e4795a34dffc68c5fb43e038be3866e40f4daed"],"m/0/1/16":["02f67d1d89bd8fe2f91c5b973cbdacfb4ba440e7656bce284cf73d549625607347","035da9cfac5a803dcb2b283b02a2515a4a1bcbf3d19e0d180aee8fc30193bc0555"],"m/0/1/17":["02c024ec199d240e8d6c66276b94b91071f7cdf2bef540c29d6d18d25de7b1cf7c","02190865f9dafae3f7f05c093463be5632946422ddda0a6fef6904390792516067"],"m/0/1/18":["035ed504d7704ad984a333b8eb0fceb8be043da9284de31ed84d9e68d90c75507d","033303c415b50421732402df00f4baa219f334647a7eb5014b9f8079864d6ab558"],"m/0/1/19":["02ce49fe86b0eee73663b1ee867b16b97c876af26f12764c528a2e6d0eb55ad3d7","03ab969bc81796b88e44c340d854df955fc60ea17ea92db5d3115595d6dec890d8"],"m/0/1/20":["03e2fa915378cbdffa0d919b0fb50c7256ca731b9d571b3365e486893a1d43079c","038d058b895cf084dccfcc9367e4796a5cf4ddceed6c35f6885d75c80119613350"],"m/0/1/21":["02fcb1bf644446b5b42205272af72f0aeab9e92ca29aafa91c5fb69142764017aa","035c5fe5c8811603279a5b72b6c30735d702817db1eab937c622269e28192ffa90"],"m/0/1/22":["03b39d61dc9a504b13ae480049c140dcffa23a6cc9c09d12d6d1f332fee5e18ca5","022929f515c5cf967474322468c3bd945bb6f281225b2c884b465680ef3052c07e"],"m/0/1/23":["03f40b82fe8cacff08879f13c45f443a3dc3ea98e1d75d5f32a19f5e5a8f7a905b","028415ee458e4dcfd440ce969726f3b58ae74fb6cf3995ced099579211e7419844"],"m/1/1/5":["032748a6282e21f571b8c8dd49e775deb83c90fcf88dc4ba81d878536973709c3f","020837cd68f14ce571b335eecd1b6fa0af43e1576dd9721aaca2a8ab639ac6b7cd"],"m/1/1/6":["0337032efb013dc92bb8dccfbdda9f5c28f0039a9c60953d41003d095e9f9778af","03ceed2da6b9603297061dc8eb930112ba726b2ccf5eec67f4866a05ca4049a22b"],"m/1/1/7":["0383c96ac2af7d203f69133b2fab6b68366b5075ad6957fa06759df3b20fbfec70","0311385f79834cedaf2230a48c0f9dc8e794da1869fc595db2518d62debb85579a"],"m/1/1/8":["03efc649680280f4e4df96da923bc88330275004125ebe5483c2f3e05ca52e19a4","02803c02d197d780388259afbd001ae41fa3eb3e2bac9627aff540521c184c3b23"],"m/1/1/9":["03af2fe6aa027a76b42c1c4050a040bfd026ad2daec1bb96a5fe2d026a7df919de","02ce14163047c640228796fb1f72bbe3afb05819ad141598a4f021058a6f79dd3b"],"m/1/1/10":["033770378bd762cf0408e44e4e604bef77e336170428c506949b1a4f1f2963e574","02c58ed43946f699dbd3e36d3e9aab2714cadeb19ecd3a56e4328c50336b4a76cb"],"m/1/1/11":["02898a1545fa19bdca92adc498698d27b86529cd4c08946d9d29604734b86f31af","02b402767a045ede072600924401c0d720000b2ed59fa444bfdbef4a5f1cead745"],"m/1/1/12":["039b8659430be49913e2cd869aa8c99ccf49a13df35837370b792033dadb891483","03264e63df292257cc76babb15d15bef620d1c2f8c3bbc78d6ea02d127e5ee7386"],"m/1/1/13":["02381a559791b8e86bf546e2c718ae63cf24eed0518a58e4d4a4b310adf2cd38fa","02d7f8283a4418d912508901b4a3db0d2103206dfdd74b3c75648671e20ecfd445"],"m/1/1/14":["020376e8c550b7d9faa0b2da947a2a36fab22c6e8190b6f99460b6022017bb97d7","03fbc5299190e6628de28c92aaa12e3a131b21eb7266462c46fbedeb86fa878055"],"m/1/1/15":["027209fd3b0cf7368180a5dbb16b928c997d33fccb78505d48440c7d23eadf5460","03450bfb22858726cd7e228e6733f69457546978a95188565c53e0d1c0d6070ea8"],"m/1/1/16":["03cb355ba04f64293793855121bab5831f84a3a3edf7cd31fccaa6d67c407a4912","028bc897a39c1224610b765a80f4cd8ab79cb37776f58fec9c10ac6f649d1f3c72"],"m/1/1/17":["03f4cb0564d7e2c6b85673503b7954db22779f29a8f3374904573984e318a96bf1","037c11b6ee906d84aa7eed359d758d986d912b6f8e5cbb1acf0982a77b3ef812c4"],"m/1/1/18":["02d2e5798f33f6889472857744316f2d253f25f88379610063f40cfe5798d9858f","0253cefdfe9ca987cbf1c950b6246d5b7a194d8dfad47c3a78dbbc5c1d01511d97"],"m/1/1/19":["0336c325f5aed366ffc10d553f2bfd4d69e66cbe1688d77af14efc8827aea2e318","0378b1b9a6074f9f2ab4fa9ad1e14649c621b0c8124a1b148914d3c10e6ab390c6"],"m/1/1/20":["03ea55740a734689ce778a8c00df8ebf4274c8f66de7d05646fe5c927773ff7f2e","02275b558d49aef955b6dee51a3c0a53f4b076b97bb3f26abcc82540168ec87cac"],"m/1/1/21":["03c77869c9984664eac9c238f4b6d806c9f48ca8a736c48450f398834db2aa915c","02d984f548c7f60c09dad3287cfc48807bc8157123989636c713be61be6a2e9ced"],"m/1/1/22":["03ed7c6a3c854c1f9459891691cc32671402f9e47126919878251e568dbdf353f8","02a113dab22cd9e46967b3fd76b9b9ec1d227d88817a9300e42d332cca2a0877fd"],"m/1/1/23":["02ee186432dcf69fda50a6fdbd94651817d8a271c273a5b70cab3ec4ae77a3753b","02291370aad9de0dac676355ced64e268b0c431a51f42f12d13f5144940fce4285"],"m/1/1/24":["02bf71435e84e66547c8c583d5ba226a5ac4d935e0a9f9603ecd8925c3e847e91a","03578d8657d285a89d9d597632db662cfef9baccfb55c76b1e87948a94fc9de30d"],"m/2147483647/0/0":["02a8425bbe23426219065969f695a6c3e242b24e57226bffdd542be8fd6be968c9","03057a42fdb6569fb1615b173ccb702453db2eac5be4291b82d4511461eafbed87"],"m/2147483647/0/1":["0250c3d3e86e332010c5233c2ec3bc728026002f0037cb3382d6318409b0e70796","02cfac1e7c4c88191201080f8316af52d9faa6ba624a6e160279e9fac4d1cf79a9"],"m/2147483647/0/2":["02a8c266a5b92eb50c8be91f95e4d1ad968b2f57d527377fd642d63fb84474f61a","028cc954ab31bd179ff80b8a05f95430ae534e61b3ff35f5284fa2fbe1832ceccb"],"m/2147483647/0/3":["02f719e1a7ab00ea98611453fb03d44c1da04655bed74af392534d70099039b4c2","03bfa548bfd4718c50bfce173f780eadcfb679d9c0206c91a2fa1879a9cf7558b2"],"m/2147483647/0/4":["0362c0695d397ca26bf47f0e641bb3cfb06ff29ccac2e1d56ded3afcf88b1e688d","02f9d87b05bdb3b9e82f506b43f813041c0e403274adc23d11e5e1651e34b606c2"],"m/2147483647/0/5":["033731323032d4ee08e858fc71f93970444333e183a1d5052e1d08cfb511e262c8","023e12556cef67ade35b7758916b5e1a3ebe074ccd35c5d8eff6b01321f63eb495"],"m/2147483647/0/6":["025d11b90081972bc1c258c9d6f476dfc2f95b69f0e9935322bf9c21deb580ff64","02b065f56a378907354f0738a0ed74f10660c6b5dd68c9f992093b75ce3d7d8b72"],"m/2147483647/0/7":["0210e721e8a35db9d8c855a0d346f60c09208f3be80b39e03af2c29db777332c71","0277f352969fadb1f1835f9a0fa99c6a3c7b6c281be5b2794c88a708eb177ea33d"],"m/2147483647/0/8":["02998d8d41e4215cd2a961a415a3ed0b1f984f1627719a7b102a75864943c4d87b","03d8ed7fc8f68a77f68d3afd007b7aa4c89944195143630ce183f0fa5438f2b559"],"m/2147483647/0/9":["0324fa91737588e4f85937303ce65c3b91b5f2ae506a72d92b83e3f5f9aeeb3c6f","02a011be72c4a400319212228106af278823a97acfe0a67e1ecd866d446b315114"],"m/2147483647/0/10":["025886ba287922a904881c7315e6fcc410a7976741771a5937d3a1a01b529f21fd","0243bb91ceed9d29d0c2ca66a8ab77e82110bbcc023beb4106f787964f44a0b972"],"m/2147483647/0/11":["0369d21684894cc2d4b2f5e581ede3cac9e8db4161a08e7737c1be129bb673d3d5","03c9ef27e3cd3dadc078fdfd9936a7ad9bf7954747085cf8f8a2a5bb3431f68a9f"],"m/2147483647/0/12":["03a73b8fd859bf6acebffdfffa2597199091daedd2c011ac67fc3494d8a1a8ceb6","025a213f7771c8be03f43f2e7f469ad4ef2cf6907ea284b227a786d1f55dfa7144"],"m/2147483647/0/13":["03a09f7ca257e1ab263cd5e6b0addc3ff868b93df132321d98775ca3505efb576f","03454c715739164bc55f347a651439cdf3ec146b35d2927beb60e8290b3916e082"],"m/2147483647/0/14":["03a64b1f7bd94a6b1a6e84ea444e0ba04e9deb86460934ccc37c0615a134a8257b","02794f09210b1811a455f3e1c7bcd35c76dff2523190fef9615eb27e2376acac1c"],"m/2147483647/0/15":["0392dca2fd9a3bc2b2a7d90a848719069fbc5f22bff7327bb8186c032514085263","032ee8a33ea76d70c7ae839448ca6c5b1af89146f2922e23ba1822df42dbc7e66a"],"m/2147483647/0/16":["031a22a1a3c1abad7c4d782ef6ba3cc00f2e8fe549eb33e0732200aff6d3174831","03bdce9781289e0c31cf727f4c93fe46f7930dd8fd68f818ce241f1ede268e8e0e"],"m/2147483647/0/17":["03b12d27e9aea2c2ad598e54e40860a705ac2ca2427aa511b501b38ec368ea5c7d","03e60d35d84d4536cad895215256b312bb4879a8d417251c279995e58f25da3d54"],"m/2147483647/0/18":["0380266cc9a9673676ad6a1b2e7148766df9c25b4dce299e5edc4f65b72aa58e64","0329e2a8a48c06c0c45dfdd2ab33e6455551557d8ebaf8c12fdf7470f8c45f1d28"],"m/2147483647/0/19":["036fe62af85560d7eea7c7af55e60b32a97dca80134d0aedffb19eb2705b9d6e01","02381c2c30b9f81e2a53c69028fbe11803acad0420b267719b7a80870be0baaeb7"],"m/0/0/2":["027bf94b8fc4e9b42683af25fda125ccab8760040717d100270dd4afd032692daf","026382c6c9357250d96dc21e43c053857a64efeac1887fdcbc107fbe3ecfc6115a"],"m/0/0/3":["03fd203acbd9af3cbbfb709458f8952078234a36094f12d00372e4b2b14cfdf419","03f2e5db59aea5dc89f53ac2a9f4ef66d41265c45afc5d763e0ca61ab70c7c61ec"],"m/0/0/4":["02a1d7cf4fcdbbf4de4002b844c3bff1639073f1cd6e5c4a4e02596b45d3f518c2","03b5fba813294e6ae096ea158833453caa5a945609b0a554696091b9b152bb0f7d"],"m/0/0/5":["0261d37e3b56ef4e106c59753037f516a4b1c45e056b2a3e00f8b77f15aaa7f8a5","0256a55e66e0de1603f0d600c0eb5f5486cf3512a776a36f3ab0d1941fc0dc9b09"],"m/0/0/6":["031db2826af215fe6cbe3f6e121b0497840fc49be133cff0a4d4eab679d6b99d70","021dd722c3f35dd04fcdb57f09b76c723d521fb36751de03ffd08096ddf1dc1f86"],"m/0/0/7":["0354ea75bdd9eb5beae7262e4a5eeb58bd10103ee0185e85b749ea39f6615d0f62","03f2c8f3b6478c0501a8578d5caf5ac2974f8213fc5e699d62dd2af58fbe8781d4"],"m/0/0/8":["0282e67df3bcd1e1662469b4c3151fb50ee1e46b75d787d91184c16b9803131f82","02921a7054af1e425f4137a5eb6b34d1f2b9d81c2625230194bc30657bb4277e11"],"m/0/0/9":["033e7e387933983ceab37c8388bd8ebc5119760f493ffe6f083bef0e5dfe22891d","02d660d60cc55d80912e0745cb142a8596a4604fbf72f9aadec0599aa2ed62461a"],"m/0/0/10":["022ce5b2750ae34512199856eab9e912dc25281cd8b88e7688a46c3b9a389701cb","02f14aa1608fce3b6088148709eb5fe72b61699c931fa8d95a45fab1106859d1b0"],"m/0/0/11":["0288dbef3302c1bc5556028adb33e2f9e03c119dbad4f706befb8ce86cea459f2b","03f13ced465e2e0a3aaa8895f3185d5711e0bebdaf507610b7a669ac8fc82da8fe"],"m/0/0/12":["031ab4677885340d2f927ccc9747f4346b79e4eb6c750695095a8a2524610fa94a","038c881910fbd8b50d193db4e0c84f5b7840820397f92cf0718a8e06d027125503"],"m/0/0/13":["031b568452cba22eb7a88c6085489e53e35abd16068882e71a140e47e12dee9c61","020d09885ee362101d12d34ce0918d41593634db1b9413e5415c6755753b9330e8"],"m/0/0/14":["024177bc9aa03cfc72eda2dfddffd7fe9d0c2f007fc3ba1a48280feae2b9fb117a","03394ad321668440c08da76eb35475ba3a8c0e8cbe0ed81468673a8c72d38fe457"],"m/0/0/15":["02037b1cc696ffbe9eba3684edd53653386ef6cd7728401c40120037593a4c2ae2","020ab8d6900ec9c11ca5d96dfc0ce7cf0ee71653a7c45118e89abb4b113147e53a"],"m/0/0/16":["023bcbb8d4726a546087cdb83740adf0ace879b7195a572c652fa8ce4dbe195a04","0392721b230d5163d28b27fc7e059b875711f12b3da448eabe7229bde57530e637"],"m/0/0/17":["02498ee74e849d3e9261dd1863038caf83d6a3bc2eeebecf17055d4bab44dee77f","03d4dc104b2e0981693e8097437de9b05334a85e2c8edb02783897859bdbc93e32"],"m/0/0/18":["0218a9f524fe54abf8c3afd21314296cfd93eaa9227acbd457e6c9a742dc233cf4","03760f3d0c5db969bda698ff9352e3b7c332216c34825f4c6e857e39c9aee7cd35"],"m/0/0/19":["033dd51f7737f0e9db79f5c38e4298bf3396346904ef3933d290a22e5b77048d9e","0221b2eedccb9a37515263071550069b3b349a166f0f131d0028e8600d9a2251b9"],"m/0/0/20":["02cb6c39161f3244d7769f7ab96346cae2cf21cb6f4538f5e7382d363dc2f836c7","034f7bda4d1e9ed6a3774608a4d6cd8582ab59fe3187f8a7a7cf914d89426ebe28"],"m/0/0/21":["035490549d65f1360f10340037250b171470ff4c86966318a2b1eead6d8b969aea","03f6a04f6fcd07a4f32c82d53710ed30e0f54d43d41c67c661d158b3d0830c3ea2"],"m/1/0/2":["02972eae7e4302e319c266578e14a07839c1e788296a92906e6d66d938211dad5f","039ed6b488f1571ad6527acd6b6c5b8453eacf6665dc5cb7852e33d1c8ea73f9fe"],"m/1/0/3":["02bec4728888c2c045108353994bae5731ec7a7b41459023b0023e10b8d616bd30","03ce1efe16214c9eac595382e46a68143dd11a335b3f7c971ddd719ac544a5fc4b"],"m/1/0/4":["030e2df1d341568225d8dfbe5d07e98dae9f90e0f43e19dcc68c998a6ed7bcc1f0","0380f4c07dc84faf42d51779f104aa6e3b5c3ce2d7684b3cb76d49faeefc2b69d6"],"m/1/0/5":["029a54ddaa25f433b493f4b72df8c1d41be2c4d2963b8b61ee63cc86d16c12d066","021567c95e0317442e7367aa4e3378dd46c5bcef5860f789272fea83b917de0669"],"m/1/0/6":["03590320d80b61cc0874b579f467c9b5ccc50d9ef875bcf6bdd12e2d0c211e8973","03ee4677b6ee89a9d355851f2230506c6897ff219062c0df4ad9a85c60f3535f93"],"m/1/0/7":["03caf98ab1c9b79d1dc8029453a6137c08787b04043b79af3cb42d41d2d3f1338f","023f39ae4e2f4f3887d5fc58e0d3a0d7ee267dc04aa257c75b6b2d67d2f5580f81"],"m/1/0/8":["0352a2a3ea8209c9a2b633d788796ac2d16c08022440e04a77ab2835c7f971d266","0291bc248b3da997f35e8fae98a75a91fdac2819d74c4e270899338d48f7389e87"],"m/1/0/9":["02468d32d9c3c62418d506d4cd0da6cd2022d5bcafdb5f847cf7bde7a48ec6848b","032713d90d12eb6a072f3c1db6c0d3b680d3f78883016135fc0f78e8193d41d4b4"],"m/1/0/10":["034863cc6bab9b059be53413ba75c5fc286647c20d7f9e5512ef4754ea301dd1ce","03a33ab9c32a2264ee2464ebbb5892f0e34acf0fdede4f87395a89e9dacdd4930e"],"m/1/0/11":["031e19296695bfe8a96ba3bf58afa805ee1bd5471fddb3929b1678d69d442d69c9","0270feb33956fd9e937019d629523e26437493c0856514011e6aec88baf7721295"],"m/1/0/12":["03cce695d3c3843bf73e851b2446a77d7e235e5b80b4f4474f9946292eb8218742","039ea96c8822f0ec7ed28308d277f3e730480d7573579cd11b89aef4364cd9ffeb"],"m/1/0/13":["02ab4ac38eb405e822d12c0f0f354f04f9ee1d991dde887a5c1171096fe503158f","036809e60cae1203da8884ea1f85d4669ce6e053f8ba605d775e271b70ab4f6787"],"m/1/0/14":["039d61da23a8610fa0ee58eb37d7cea7ea9396c79153da97280ccf5e46718e3bac","03015c27bcc778682781fd6ad30aa6041db0b7e24270818cdceece0043ccc34b26"],"m/1/0/15":["03c088ed669132835d2728b0ecf294271c8388988c6ae264d43ca24f50e4005f81","03e2c118c9445a2ddc4c8afeb0ba49e21be3f818a483d346418b8922b8a371a2b7"],"m/1/0/16":["02bba7df9847f463c6b23eca37a4bd6efa3801a52b8ddfad804d902e783b70c81c","03764b657f23996e31c64a701facc1cbeb0c9edfdd605e2c1ed36cf48197565d45"],"m/1/0/17":["020445179c522295b89bf4bfd582eb03422e3fa20dcd29263925e9f44282d476d8","036e47bdd32f3061aed1c1f8c2a32b038c7b72391cb1f80ebfc150e58f88372766"],"m/1/0/18":["024d88c4bfcbba713d49e1edcd035234aaa1ee76ad7bcf75bf074a16658a6b0b6d","02b861e7a20d89f6875d2e44c78dbadb99503e282e5e60e9f65657af6fea81d425"],"m/1/0/19":["023a8ca9d5300181f157e1930d3b0800eebe7683d8df72e6cbf28834dbf1be5d60","026053c4f84c10d15890c0b254522972931bc2d5b7cdf9c1f9f3137c22edf3ecd3"],"m/1/0/20":["03137c66e9f3d61aba659f408d77a293fa0f3fea4ccb911074a681d6f61a55d023","0291aa1bbfbef59b16b0e37e185a706c589d448cb02e860c5df9c9d7242ecc739f"],"m/1/0/21":["03c08673e0cae55318bc9dcc4b5f11eb3ff71d42de04015e255dde3fd8cba7e09e","02423d4eab06cd5b26e71d145283523c011d58032700c517f00b328d2c90cf109f"]}},"txProposals":{"txps":[{"creator":"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5","createdTs":1405543144016,"seenBy":{"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543144016,"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543144645},"signedBy":{"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543144016},"rejectedBy":{"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543170040},"sentTs":null,"sentTxid":null,"inputChainPaths":["m/45\'/0/0/0"],"comment":"blablabla","builderObj":{"valueInSat":"29000000","valueOutSat":"8900000","feeSat":"10000","remainderSat":"20090000","hashToScriptMap":{"2NBtv6DdXj8HBunyGqpW9H8bUtW5x3rfVTj":"5221028a4b63f26253f3a8731577b8e1ee480950ad5833ebbf106fe3463bfc07cc3b90210332efa054c08cb77506a35ee0762cb7156f244566703ec08e433568ec0397bec852ae"},"selectedUtxos":[{"address":"2NBtv6DdXj8HBunyGqpW9H8bUtW5x3rfVTj","txid":"a9f4dda3f092e37244bc4e77ea921fed01d5b8ea49613dfdc0dc8afdd70190b5","vout":1,"ts":1405543855,"scriptPubKey":"a914cc93216398b77b5f8c451ca3a357bef961678be987","amount":0.29,"confirmations":0,"confirmationsFromCache":false}],"inputsSigned":0,"signaturesAdded":1,"signhash":1,"spendUnconfirmed":true,"tx":"0100000001b59001d7fd8adcc0fd3d6149eab8d501ed1f92ea774ebc4472e392f0a3ddf4a9010000009300493046022100ccbb8f398f74a76236629b8499ffc6f9518a2091f5a61a9a352c0a10f615961e022100b8f0769c76cf33bec3d7f81d9da2b74cf6e8a5e0a24ee5f48172854d8bcdbfa101475221028a4b63f26253f3a8731577b8e1ee480950ad5833ebbf106fe3463bfc07cc3b90210332efa054c08cb77506a35ee0762cb7156f244566703ec08e433568ec0397bec852aeffffffff02a0cd8700000000001976a91485eb47fe98f349065d6f044e27a4ac541af79ee288ac908c32010000000017a914560c292066792531164149c5ed63ad2793a61b928700000000"}},{"creator":"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5","createdTs":1405543188745,"seenBy":{"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543188745,"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543189341},"signedBy":{"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543188745,"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543206819},"rejectedBy":{},"sentTs":1405543207304,"sentTxid":"169bc92693dd2e27724eeba81e54210e842035bd3af6c52e6a6a5e908f1a4f66","inputChainPaths":["m/45\'/0/0/0"],"comment":"que parece","builderObj":{"valueInSat":"29000000","valueOutSat":"9000000","feeSat":"10000","remainderSat":"19990000","hashToScriptMap":{"2NBtv6DdXj8HBunyGqpW9H8bUtW5x3rfVTj":"5221028a4b63f26253f3a8731577b8e1ee480950ad5833ebbf106fe3463bfc07cc3b90210332efa054c08cb77506a35ee0762cb7156f244566703ec08e433568ec0397bec852ae"},"selectedUtxos":[{"address":"2NBtv6DdXj8HBunyGqpW9H8bUtW5x3rfVTj","txid":"a9f4dda3f092e37244bc4e77ea921fed01d5b8ea49613dfdc0dc8afdd70190b5","vout":1,"ts":1405543855,"scriptPubKey":"a914cc93216398b77b5f8c451ca3a357bef961678be987","amount":0.29,"confirmations":1,"confirmationsFromCache":false}],"inputsSigned":1,"signaturesAdded":2,"signhash":1,"spendUnconfirmed":true,"tx":"0100000001b59001d7fd8adcc0fd3d6149eab8d501ed1f92ea774ebc4472e392f0a3ddf4a901000000da00483045022035423cc74824ba904907678dda3b62a20a787b96d1b3e9f3e9546f9c57f4e45902210080a1ff1c39f458ac1642b9e948bd62fd70563b5252e749cc8fc642cd763ee830014730440220524a13f36cfb03caa246d7d84de634ec9386f2c39c19bfa926037f48da86262b022050e58a6503d105ad2805f86806810a1aa7f20d6271e1340b42fa91ab6a30f3e801475221028a4b63f26253f3a8731577b8e1ee480950ad5833ebbf106fe3463bfc07cc3b90210332efa054c08cb77506a35ee0762cb7156f244566703ec08e433568ec0397bec852aeffffffff0240548900000000001976a91485eb47fe98f349065d6f044e27a4ac541af79ee288acf00531010000000017a9146130a9d51f996b7a1b9d3e10c80930834251909d8700000000"}},{"creator":"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba","createdTs":1405543505848,"seenBy":{"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543505848,"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543590221},"signedBy":{"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543505848,"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543590221},"rejectedBy":{},"sentTs":1405543610315,"sentTxid":"6fe851b54b777a75fe80fa204dc674395e2af69efb1f7c0017e909eb82c3d914","inputChainPaths":["m/45\'/0/1/1"],"comment":"mandaaaaaaa","builderObj":{"valueInSat":"19990000","valueOutSat":"19980000","feeSat":"10000","remainderSat":"0","hashToScriptMap":{"2N277q5r8Ab6XLJNCjXXFdh5itDJRQCv9ts":"5221020389327ee8ae7d0ee3f8187842d23a4070bdd8a27c0bcddd05d80ef39009253d21025c9b49bdf17d97bd82ea1b87793082f857247f0f9b999937a166ec994bb1b41f52ae"},"selectedUtxos":[{"address":"2N277q5r8Ab6XLJNCjXXFdh5itDJRQCv9ts","txid":"169bc92693dd2e27724eeba81e54210e842035bd3af6c52e6a6a5e908f1a4f66","vout":1,"ts":1405543157,"scriptPubKey":"a9146130a9d51f996b7a1b9d3e10c80930834251909d87","amount":0.1999,"confirmationsFromCache":false}],"inputsSigned":1,"signaturesAdded":2,"signhash":1,"spendUnconfirmed":true,"tx":"0100000001664f1a8f905e6a6a2ec5f63abd3520840e21541ea8eb4e72272edd9326c99b1601000000db0048304502206b18b3dba2646c552469d8ef52d7656f6a65f563032530f622abdfd8bd4c5cee022100e804b406eddebbc827646141e74dc64c76a770ed4e35183ffd35d265ad9f7d3b01483045022100f6c013638ff0a316b1baa93dfffba6a98cf3033c133e8bd899e933c9c3e47ce10220530f40e7ea52ae58bec695edbec6d566d2ee8e7b5f33f95e33093ad1e29a125401475221020389327ee8ae7d0ee3f8187842d23a4070bdd8a27c0bcddd05d80ef39009253d21025c9b49bdf17d97bd82ea1b87793082f857247f0f9b999937a166ec994bb1b41f52aeffffffff01e0de3001000000001976a91485eb47fe98f349065d6f044e27a4ac541af79ee288ac00000000"}},{"creator":"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba","createdTs":1405543781381,"seenBy":{"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543781381,"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543782017},"signedBy":{"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543781381},"rejectedBy":{"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543794590},"sentTs":null,"sentTxid":null,"inputChainPaths":["m/45\'/0/0/1"],"comment":"1","builderObj":{"valueInSat":"29000000","valueOutSat":"1000000","feeSat":"10000","remainderSat":"27990000","hashToScriptMap":{"2N4eyXKikdnnUT4S74MRNAYqXChhUYmZ1Sb":"52210359c6d0d0d31f83301169901a6ffad9535f14014b5ab3b43561dbb2436a7b813821037d06f713f13a11967fd5edca265ff4c77528693a712c482256505693e4890d9352ae"},"selectedUtxos":[{"address":"2N4eyXKikdnnUT4S74MRNAYqXChhUYmZ1Sb","txid":"6c9da5b0da4bab0d576033325e987b10ccf2b9bf479d306b6aae36efeaa56892","vout":0,"ts":1405543698,"scriptPubKey":"a9147d274ac50968d7823b6cbc1b38770deb7157995387","amount":0.29,"confirmationsFromCache":false}],"inputsSigned":0,"signaturesAdded":1,"signhash":1,"spendUnconfirmed":true,"tx":"01000000019268a5eaef36ae6a6b309d47bfb9f2cc107b985e323360570dab4bdab0a59d6c000000009200483045022064d877bc5171fbaef909c2a1a924e0023b3ccc0b530cb46653f06ecb230283e8022100bc6658d60ad4f7120d9226c8f6eada87f3b0388f73c458011988bab36e78ba15014752210359c6d0d0d31f83301169901a6ffad9535f14014b5ab3b43561dbb2436a7b813821037d06f713f13a11967fd5edca265ff4c77528693a712c482256505693e4890d9352aeffffffff0240420f00000000001976a91485eb47fe98f349065d6f044e27a4ac541af79ee288acf017ab010000000017a91421c4a435d9ac263ec55b35a1a5ca95e979639b9b8700000000"}},{"creator":"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5","createdTs":1405543835343,"seenBy":{"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543835343,"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543835968},"signedBy":{"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543835343},"rejectedBy":{"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543850998},"sentTs":null,"sentTxid":null,"inputChainPaths":["m/45\'/0/0/1"],"comment":"2","builderObj":{"valueInSat":"29000000","valueOutSat":"1000000","feeSat":"10000","remainderSat":"27990000","hashToScriptMap":{"2N4eyXKikdnnUT4S74MRNAYqXChhUYmZ1Sb":"52210359c6d0d0d31f83301169901a6ffad9535f14014b5ab3b43561dbb2436a7b813821037d06f713f13a11967fd5edca265ff4c77528693a712c482256505693e4890d9352ae"},"selectedUtxos":[{"address":"2N4eyXKikdnnUT4S74MRNAYqXChhUYmZ1Sb","txid":"6c9da5b0da4bab0d576033325e987b10ccf2b9bf479d306b6aae36efeaa56892","vout":0,"ts":1405543698,"scriptPubKey":"a9147d274ac50968d7823b6cbc1b38770deb7157995387","amount":0.29,"confirmationsFromCache":false}],"inputsSigned":0,"signaturesAdded":1,"signhash":1,"spendUnconfirmed":true,"tx":"01000000019268a5eaef36ae6a6b309d47bfb9f2cc107b985e323360570dab4bdab0a59d6c0000000092004830450220302baae7de2e0f102bf3af2d5f450f673e51bd143020141a769ccdcdf16af188022100e7abc087c76050ed649e7139a5a136969e74e24a8d8f6223d3219ad033a26451014752210359c6d0d0d31f83301169901a6ffad9535f14014b5ab3b43561dbb2436a7b813821037d06f713f13a11967fd5edca265ff4c77528693a712c482256505693e4890d9352aeffffffff0240420f00000000001976a91485eb47fe98f349065d6f044e27a4ac541af79ee288acf017ab010000000017a9148b102abba0729fb0690c61cf7187064d692d43d78700000000"}},{"creator":"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba","createdTs":1405543869803,"seenBy":{"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543869803,"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543870411},"signedBy":{"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543869803,"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543890406},"rejectedBy":{},"sentTs":1405543890913,"sentTxid":"6a0f61574ad65e537e7e99298968db565f97b894b61f4c8f8fac8fcaedb83e2b","inputChainPaths":["m/45\'/0/0/1"],"comment":"3","builderObj":{"valueInSat":"29000000","valueOutSat":"1100000","feeSat":"10000","remainderSat":"27890000","hashToScriptMap":{"2N4eyXKikdnnUT4S74MRNAYqXChhUYmZ1Sb":"52210359c6d0d0d31f83301169901a6ffad9535f14014b5ab3b43561dbb2436a7b813821037d06f713f13a11967fd5edca265ff4c77528693a712c482256505693e4890d9352ae"},"selectedUtxos":[{"address":"2N4eyXKikdnnUT4S74MRNAYqXChhUYmZ1Sb","txid":"6c9da5b0da4bab0d576033325e987b10ccf2b9bf479d306b6aae36efeaa56892","vout":0,"ts":1405543698,"scriptPubKey":"a9147d274ac50968d7823b6cbc1b38770deb7157995387","amount":0.29,"confirmationsFromCache":false}],"inputsSigned":1,"signaturesAdded":2,"signhash":1,"spendUnconfirmed":true,"tx":"01000000019268a5eaef36ae6a6b309d47bfb9f2cc107b985e323360570dab4bdab0a59d6c00000000db00483045022100a8ce7907f9fd7dd41dd65c2dec425e008efea06ee7c80787c10c0e210fbf181302207712c0fdd1cb25836ac1fc2fd303c1e26b85e8980417719b9ed50e977a9693ec01483045022100d1780c4f028cd898920aca3eaceba352ed9306cd17f019ae2f634e8facad149a02203c84ab2093da8e22577e93f27a732f0728d4e6db0c749f3cd3d898d6a025152a014752210359c6d0d0d31f83301169901a6ffad9535f14014b5ab3b43561dbb2436a7b813821037d06f713f13a11967fd5edca265ff4c77528693a712c482256505693e4890d9352aeffffffff02e0c81000000000001976a91485eb47fe98f349065d6f044e27a4ac541af79ee288ac5091a9010000000017a914cc1cab78458b1a951b91c6dcd7eeeeb682f506388700000000"}}],"walletId":"55d4bd062d32f90a","networkName":"testnet"},"privateKey":{"extendedPrivateKeyString":"tprv8ZgxMBicQKsPdWUAmaaopPftevC72Jtiu19V8ee5XijL9JvogqfR95uVrL85f8yBdQMq3KyQtG3Q91yWQb3XDbWWpcdWFDAmJ7Xy2XWkGJu","networkName":"testnet","privateKeyCache":{"m/45\'/0/0/0":"b6fd8d1a079efd523da34f31ba81f544fc3d0a728a8a98299d8980682518e79c","m/45\'/0/1/1":"0f4d52d2a99e4c8c1c2edf09fef12407c3abd2304b961198c3f131a8c8443a13","m/45\'/0/0/1":"de5c191c343bd6017b98708c03344849624a14e2c167cfd6eb8dcb075d139293"}},"addressBook":{"msj42CCGruhRsFrGATiUuh25dtxYtnpbTx":{"hidden":false,"createdTs":1405543109222,"copayerId":"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba","label":"faucet","signature":"3045022067576e5b37f2707a8dc66e57511ad9b10a3125bd95193fff6f8f6402969c3bf3022100adff9f417db07d88face13b3d13f422740d4421440cade1a205684dfdc5d733a"}}}'; From fd97b12c4deb58edbb3ddf014ac1765b5740a75b Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Mon, 15 Sep 2014 16:46:24 -0300 Subject: [PATCH 132/191] . --- test/test.WalletFactory.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test.WalletFactory.js b/test/test.WalletFactory.js index eaaa526fc..f759fd5cd 100644 --- a/test/test.WalletFactory.js +++ b/test/test.WalletFactory.js @@ -161,7 +161,7 @@ describe('WalletFactory model', function() { console.log('[test.WalletFactory.js.169]', original.opts); //TODO ['addressBook', 'networkNonce','networkNonces', 'opts', 'privateKey','copayersExtPubKeys'].forEach(function(k){ -console.log('[test.WalletFactory.js.166:original:]',k,original[k]); //TODO +console.log('[test.WalletFactory.js.166:original:]',k,original[k], o2[k]); //TODO o2[k].should.be.deep.equal(original[k], k + ' differs'); }) From 635579cf434d6ec837849dfca9834891dcf3b095 Mon Sep 17 00:00:00 2001 From: bechi Date: Mon, 15 Sep 2014 17:13:57 -0300 Subject: [PATCH 133/191] balance font in sidebar --- views/includes/sidebar.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/views/includes/sidebar.html b/views/includes/sidebar.html index 0bd5b8263..8a4e7d8e5 100644 --- a/views/includes/sidebar.html +++ b/views/includes/sidebar.html @@ -21,7 +21,7 @@ Date: Mon, 15 Sep 2014 17:45:06 -0300 Subject: [PATCH 134/191] all test passing, after rebasing --- js/models/core/WalletFactory.js | 12 +-- test/test.WalletFactory.js | 153 ++++++++++---------------------- 2 files changed, 55 insertions(+), 110 deletions(-) diff --git a/js/models/core/WalletFactory.js b/js/models/core/WalletFactory.js index 702ae499e..b1594937c 100644 --- a/js/models/core/WalletFactory.js +++ b/js/models/core/WalletFactory.js @@ -86,10 +86,12 @@ WalletFactory.prototype.obtainNetworkName = function(obj) { * @param {string[]} skipFields - fields to skip when importing * @return {Wallet} */ -WalletFactory.prototype.fromObj = function(obj, skipFields) { - var networkName = this.obtainNetworkName(obj); +WalletFactory.prototype.fromObj = function(inObj, skipFields) { + var networkName = this.obtainNetworkName(inObj); preconditions.checkState(networkName); - preconditions.checkArgument(obj); + preconditions.checkArgument(inObj); + + var obj = JSON.parse(JSON.stringify(inObj)); // not stored options obj.opts = obj.opts || {}; @@ -421,8 +423,8 @@ WalletFactory.prototype.joinCreateSession = function(opts, cb) { } data.opts.privateKey = privateKey; - data.opts.nickname = nickname; - data.opts.passphrase = passphrase; + data.opts.nickname = opts.nickname; + data.opts.passphrase = opts.passphrase; data.opts.id = data.walletId; self.create(data.opts, function(err, w) { if (!err & w) { diff --git a/test/test.WalletFactory.js b/test/test.WalletFactory.js index f759fd5cd..55f5239f6 100644 --- a/test/test.WalletFactory.js +++ b/test/test.WalletFactory.js @@ -1,6 +1,7 @@ 'use strict'; +var _ = require('underscore'); var chai = chai || require('chai'); var should = chai.should(); @@ -15,71 +16,14 @@ var mockLocalStorage = require('./mocks/FakeLocalStorage'); var mockSessionStorage = require('./mocks/FakeLocalStorage'); -/** - * A better way to compare two objects in Javascript - **/ -function getKeys(obj) { - var keys; - if (obj.keys) { - keys = obj.keys(); - } else { - keys = []; +var PERSISTED_PROPERTIES = require('../js/models/core/Wallet').PERSISTED_PROPERTIES; - for (var k in obj) { - if (Object.prototype.hasOwnProperty.call(obj, k)) { - keys.push(k); - } +function assertObjectEqual(a, b) { + PERSISTED_PROPERTIES.forEach(function(k) { + if (a[k] && b[k]) { + _.omit(a[k],'name').should.be.deep.equal(b[k], k + ' differs'); } - } - - return keys; -} - -/** - * Create a new object so the keys appear in the provided order. - * @param {Object} obj The object to be the base for the new object - * @param {Array} keys The order in which properties of the new object should appear - **/ -function reconstructObject(obj, keys) { - var result = {}; - for (var i = 0, l = keys.length; i < l; i++) { - if (Object.prototype.hasOwnProperty.call(obj, keys[i])) { - result[keys[i]] = obj[keys[i]]; - } - } - - return result; -} - -function assertObjectEqual(a, b, msg) { - msg = msg || ''; - if (Object.prototype.toString.call(a) === '[object Array]' && Object.prototype.toString.call(b) === '[object Array]') { - // special case: array of objects - if (a.filter(function(e) { - return Object.prototype.toString.call(e) === '[object Object]' - }).length > 0 || - b.filter(function(e) { - return Object.prototype.toString.call(e) === '[object Object]' - }).length > 0) { - - if (a.length !== b.length) { - JSON.stringify(a).should.equal(JSON.stringify(b), msg); - } else { - for (var i = 0, l = a.length; i < l; i++) { - assertObjectEqual(a[i], b[i], msg + '[elements at index ' + i + ' should be equal]'); - } - } - // simple array of primitives - } else { - JSON.stringify(a).should.equal(JSON.stringify(b), msg); - } - } else { - var orderedA = reconstructObject(a, getKeys(a).sort()), - orderedB = reconstructObject(b, getKeys(b).sort()); - - // compare as strings for diff tolls to show us the difference - JSON.stringify(orderedA).should.equal(JSON.stringify(orderedB), msg) - } + }) } @@ -153,19 +97,13 @@ describe('WalletFactory model', function() { }); }); + // TODO this is a WALLET TEST! not Wallet Factory. Move it. describe('#fromObj / #toObj', function() { - it.only('round trip', function() { + it('round trip', function() { var wf = new WalletFactory(config, '0.0.5'); var original = JSON.parse(o); var o2 = wf.fromObj(original).toObj(); - -console.log('[test.WalletFactory.js.169]', original.opts); //TODO - ['addressBook', 'networkNonce','networkNonces', 'opts', 'privateKey','copayersExtPubKeys'].forEach(function(k){ -console.log('[test.WalletFactory.js.166:original:]',k,original[k], o2[k]); //TODO - o2[k].should.be.deep.equal(original[k], k + ' differs'); - - }) - //assertObjectEqual(w.toObj(), JSON.parse(o)); + assertObjectEqual(o2, original); }); it('round trip, using old copayerIndex', function() { @@ -196,7 +134,7 @@ console.log('[test.WalletFactory.js.166:original:]',k,original[k], o2[k]); //TOD it('support old index schema: #fromObj #toObj round trip', function() { var o = '{"opts":{"id":"dbfe10c3fae71cea","spendUnconfirmed":1,"requiredCopayers":3,"totalCopayers":5,"version":"0.0.5"},"networkNonce":"0000000000000001","networkNonces":[],"publicKeyRing":{"walletId":"dbfe10c3fae71cea","networkName":"testnet","requiredCopayers":3,"totalCopayers":5,"indexes":{"changeIndex":0,"receiveIndex":0},"copayersBackup":[],"copayersExtPubKeys":["tpubD6NzVbkrYhZ4YGK8ZhZ8WVeBXNAAoTYjjpw9twCPiNGrGQYFktP3iVQkKmZNiFnUcAFMJRxJVJF6Nq9MDv2kiRceExJaHFbxUCGUiRhmy97","tpubD6NzVbkrYhZ4YKGDJkzWdQsQV3AcFemaQKiwNhV4RL8FHnBFvinidGdQtP8RKj3h34E65RkdtxjrggZYqsEwJ8RhhN2zz9VrjLnrnwbXYNc","tpubD6NzVbkrYhZ4YkDiewjb32Pp3Sz9WK2jpp37KnL7RCrHAyPpnLfgdfRnTdpn6DTWmPS7niywfgWiT42aJb1J6CjWVNmkgsMCxuw7j9DaGKB","tpubD6NzVbkrYhZ4XEtUAz4UUTWbprewbLTaMhR8NUvSJUEAh4Sidxr6rRPFdqqVRR73btKf13wUjds2i8vVCNo8sbKrAnyoTr3o5Y6QSbboQjk","tpubD6NzVbkrYhZ4Yj9AAt6xUVuGPVd8jXCrEE6V2wp7U3PFh8jYYvVad31b4VUXEYXzSnkco4fktu8r4icBsB2t3pCR3WnhVLedY2hxGcPFLKD"],"nicknameFor":{}},"txProposals":{"txps":[],"walletId":"dbfe10c3fae71cea","networkName":"testnet"},"privateKey":{"extendedPrivateKeyString":"tprv8ZgxMBicQKsPeoHLg3tY75z4xLeEe8MqAXLNcRA6J6UTRvHV8VZTXznt9eoTmSk1fwSrwZtMhY3XkNsceJ14h6sCXHSWinRqMSSbY8tfhHi","networkName":"testnet"},"addressBook":{}}'; - var o2 = '{"opts":{"id":"dbfe10c3fae71cea","spendUnconfirmed":1,"requiredCopayers":3,"totalCopayers":5,"version":"0.0.5"},"networkNonce":"0000000000000001","networkNonces":[],"publicKeyRing":{"walletId":"dbfe10c3fae71cea","networkName":"testnet","requiredCopayers":3,"totalCopayers":5,"indexes":[{"copayerIndex":2147483647,"changeIndex":0,"receiveIndex":0},{"copayerIndex":0,"changeIndex":0,"receiveIndex":0},{"copayerIndex":1,"changeIndex":0,"receiveIndex":0},{"copayerIndex":2,"changeIndex":0,"receiveIndex":0},{"copayerIndex":3,"changeIndex":0,"receiveIndex":0},{"copayerIndex":4,"changeIndex":0,"receiveIndex":0}],"copayersBackup":[],"copayersExtPubKeys":["tpubD6NzVbkrYhZ4YGK8ZhZ8WVeBXNAAoTYjjpw9twCPiNGrGQYFktP3iVQkKmZNiFnUcAFMJRxJVJF6Nq9MDv2kiRceExJaHFbxUCGUiRhmy97","tpubD6NzVbkrYhZ4YKGDJkzWdQsQV3AcFemaQKiwNhV4RL8FHnBFvinidGdQtP8RKj3h34E65RkdtxjrggZYqsEwJ8RhhN2zz9VrjLnrnwbXYNc","tpubD6NzVbkrYhZ4YkDiewjb32Pp3Sz9WK2jpp37KnL7RCrHAyPpnLfgdfRnTdpn6DTWmPS7niywfgWiT42aJb1J6CjWVNmkgsMCxuw7j9DaGKB","tpubD6NzVbkrYhZ4XEtUAz4UUTWbprewbLTaMhR8NUvSJUEAh4Sidxr6rRPFdqqVRR73btKf13wUjds2i8vVCNo8sbKrAnyoTr3o5Y6QSbboQjk","tpubD6NzVbkrYhZ4Yj9AAt6xUVuGPVd8jXCrEE6V2wp7U3PFh8jYYvVad31b4VUXEYXzSnkco4fktu8r4icBsB2t3pCR3WnhVLedY2hxGcPFLKD"],"nicknameFor":{}},"txProposals":{"txps":[],"walletId":"dbfe10c3fae71cea","networkName":"testnet"},"privateKey":{"extendedPrivateKeyString":"tprv8ZgxMBicQKsPeoHLg3tY75z4xLeEe8MqAXLNcRA6J6UTRvHV8VZTXznt9eoTmSk1fwSrwZtMhY3XkNsceJ14h6sCXHSWinRqMSSbY8tfhHi","networkName":"testnet"},"addressBook":{}}'; + var o2 = '{"opts":{"id":"dbfe10c3fae71cea","spendUnconfirmed":1,"requiredCopayers":3,"totalCopayers":5,"version":"0.0.5","networkName":"testnet"},"networkNonce":"0000000000000001","networkNonces":[],"publicKeyRing":{"walletId":"dbfe10c3fae71cea","networkName":"testnet","requiredCopayers":3,"totalCopayers":5,"indexes":[{"copayerIndex":2147483647,"changeIndex":0,"receiveIndex":0},{"copayerIndex":0,"changeIndex":0,"receiveIndex":0},{"copayerIndex":1,"changeIndex":0,"receiveIndex":0},{"copayerIndex":2,"changeIndex":0,"receiveIndex":0},{"copayerIndex":3,"changeIndex":0,"receiveIndex":0},{"copayerIndex":4,"changeIndex":0,"receiveIndex":0}],"copayersBackup":[],"copayersExtPubKeys":["tpubD6NzVbkrYhZ4YGK8ZhZ8WVeBXNAAoTYjjpw9twCPiNGrGQYFktP3iVQkKmZNiFnUcAFMJRxJVJF6Nq9MDv2kiRceExJaHFbxUCGUiRhmy97","tpubD6NzVbkrYhZ4YKGDJkzWdQsQV3AcFemaQKiwNhV4RL8FHnBFvinidGdQtP8RKj3h34E65RkdtxjrggZYqsEwJ8RhhN2zz9VrjLnrnwbXYNc","tpubD6NzVbkrYhZ4YkDiewjb32Pp3Sz9WK2jpp37KnL7RCrHAyPpnLfgdfRnTdpn6DTWmPS7niywfgWiT42aJb1J6CjWVNmkgsMCxuw7j9DaGKB","tpubD6NzVbkrYhZ4XEtUAz4UUTWbprewbLTaMhR8NUvSJUEAh4Sidxr6rRPFdqqVRR73btKf13wUjds2i8vVCNo8sbKrAnyoTr3o5Y6QSbboQjk","tpubD6NzVbkrYhZ4Yj9AAt6xUVuGPVd8jXCrEE6V2wp7U3PFh8jYYvVad31b4VUXEYXzSnkco4fktu8r4icBsB2t3pCR3WnhVLedY2hxGcPFLKD"],"nicknameFor":{}},"txProposals":{"txps":[],"walletId":"dbfe10c3fae71cea","networkName":"testnet"},"privateKey":{"extendedPrivateKeyString":"tprv8ZgxMBicQKsPeoHLg3tY75z4xLeEe8MqAXLNcRA6J6UTRvHV8VZTXznt9eoTmSk1fwSrwZtMhY3XkNsceJ14h6sCXHSWinRqMSSbY8tfhHi","networkName":"testnet"},"addressBook":{}}'; var wf = new WalletFactory(config, '0.0.5'); var w = wf.fromObj(JSON.parse(o)); @@ -207,9 +145,7 @@ console.log('[test.WalletFactory.js.166:original:]',k,original[k], o2[k]); //TOD should.exist(w.txProposals.toObj); should.exist(w.privateKey.toObj); - // - var expected = JSON.parse(o2.replace(/cosigner/g, 'copayerIndex')); - assertObjectEqual(w.toObj(), expected); + assertObjectEqual(w.toObj(), JSON.parse(o2)); }); }); @@ -460,9 +396,10 @@ console.log('[test.WalletFactory.js.166:original:]',k,original[k], o2[k]); //TOD }; it('should yield bad network error', function(done) { - wf.network.greet = sinon.stub(); - wf.network.on = sinon.stub(); - wf.network.on.withArgs('data').yields('senderId', { + var net = wf.networks['testnet']; + net.greet = sinon.stub(); + net.on = sinon.stub(); + net.on.withArgs('data').yields('senderId', { type: 'walletId', networkName: 'aWeirdNetworkName', opts: {}, @@ -477,10 +414,11 @@ console.log('[test.WalletFactory.js.166:original:]',k,original[k], o2[k]); //TOD it('should yield to join error', function(done) { opts.privHex = undefined; - wf.network.greet = sinon.stub(); - wf.network.on = sinon.stub(); - wf.network.on.withArgs('serverError').yields(null); - wf.network.on.withArgs('data').yields('senderId', { + var net = wf.networks['testnet']; + net.greet = sinon.stub(); + net.on = sinon.stub(); + net.on.withArgs('serverError').yields(null); + net.on.withArgs('data').yields('senderId', { type: 'walletId', networkName: wf.networkName, }); @@ -493,20 +431,21 @@ console.log('[test.WalletFactory.js.166:original:]',k,original[k], o2[k]); //TOD it('should call network.start / create', function(done) { opts.privHex = undefined; - wf.network.cleanUp = sinon.spy(); - wf.network.greet = sinon.spy(); - wf.network.start = sinon.stub().yields(null); + var net = wf.networks['testnet']; + net.cleanUp = sinon.spy(); + net.greet = sinon.spy(); + net.start = sinon.stub().yields(null); - wf.network.on = sinon.stub(); - wf.network.on.withArgs('connected').yields(null); - wf.network.on.withArgs('data').yields('senderId', { + net.on = sinon.stub(); + net.on.withArgs('connected').yields(null); + net.on.withArgs('data').yields('senderId', { type: 'walletId', - networkName: wf.networkName, + networkName: 'testnet', opts: {}, }); wf.create = sinon.stub().yields(null, 'wallet'); wf.joinCreateSession(opts, function(err, w) { - wf.network.start.calledOnce.should.equal(true); + net.start.calledOnce.should.equal(true); wf.create.calledOnce.should.equal(true); done(); }); @@ -514,15 +453,16 @@ console.log('[test.WalletFactory.js.166:original:]',k,original[k], o2[k]); //TOD it('should return walletFull', function(done) { opts.privHex = undefined; - wf.network.cleanUp = sinon.spy(); - wf.network.greet = sinon.spy(); - wf.network.start = sinon.stub().yields(null); + var net = wf.networks['testnet']; + net.cleanUp = sinon.spy(); + net.greet = sinon.spy(); + net.start = sinon.stub().yields(null); - wf.network.on = sinon.stub(); - wf.network.on.withArgs('connected').yields(null); - wf.network.on.withArgs('data').yields('senderId', { + net.on = sinon.stub(); + net.on.withArgs('connected').yields(null); + net.on.withArgs('data').yields('senderId', { type: 'walletId', - networkName: wf.networkName, + networkName: 'testnet', opts: {}, }); wf.create = sinon.stub().yields(null, null); @@ -535,19 +475,21 @@ console.log('[test.WalletFactory.js.166:original:]',k,original[k], o2[k]); //TOD it('should accept a priv key a input', function() { var wf = new WalletFactory(config, '0.0.1'); opts.privHex = 'tprv8ZgxMBicQKsPf7MCvCjnhnr4uiR2Z2gyNC27vgd9KUu98F9mM1tbaRrWMyddVju36GxLbeyntuSadBAttriwGGMWUkRgVmUUCg5nFioGZsd'; - wf.network.cleanUp = sinon.spy(); - wf.network.start = sinon.spy(); + var net = wf.networks['testnet']; + net.cleanUp = sinon.spy(); + net.start = sinon.spy(); wf.joinCreateSession(opts, function(err, w) { - wf.network.start.getCall(0).args[0].privkey.should.equal('ddc2fa8c583a73c4b2a24630ec7c283df4e7c230a02c4e48bc36ec61687afd7d'); + net.start.getCall(0).args[0].privkey.should.equal('ddc2fa8c583a73c4b2a24630ec7c283df4e7c230a02c4e48bc36ec61687afd7d'); }); }); it('should call network.start with private key', function() { opts.privHex = undefined; var wf = new WalletFactory(config, '0.0.1'); - wf.network.cleanUp = sinon.spy(); - wf.network.start = sinon.spy(); + var net = wf.networks['testnet']; + net.cleanUp = sinon.spy(); + net.start = sinon.spy(); wf.joinCreateSession(opts, function(err, w) { - wf.network.start.getCall(0).args[0].privkey.length.should.equal(64); //privkey is hex of private key buffer + net.start.getCall(0).args[0].privkey.length.should.equal(64); //privkey is hex of private key buffer }); }); }); @@ -604,7 +546,8 @@ console.log('[test.WalletFactory.js.166:original:]',k,original[k], o2[k]); //TOD }); -var o = '{"opts":{"id":"dbfe10c3fae71cea","spendUnconfirmed":1,"requiredCopayers":3,"totalCopayers":5,"version":"0.0.5","networkName":"testnet"},"networkNonce":"0000000000000001","networkNonces":[],"publicKeyRing":{"walletId":"dbfe10c3fae71cea","networkName":"testnet","requiredCopayers":3,"totalCopayers":5,"indexes":[{"copayerIndex":2,"changeIndex":0,"receiveIndex":0}],"copayersBackup":[],"copayersExtPubKeys":["tpubD6NzVbkrYhZ4YGK8ZhZ8WVeBXNAAoTYjjpw9twCPiNGrGQYFktP3iVQkKmZNiFnUcAFMJRxJVJF6Nq9MDv2kiRceExJaHFbxUCGUiRhmy97","tpubD6NzVbkrYhZ4YKGDJkzWdQsQV3AcFemaQKiwNhV4RL8FHnBFvinidGdQtP8RKj3h34E65RkdtxjrggZYqsEwJ8RhhN2zz9VrjLnrnwbXYNc","tpubD6NzVbkrYhZ4YkDiewjb32Pp3Sz9WK2jpp37KnL7RCrHAyPpnLfgdfRnTdpn6DTWmPS7niywfgWiT42aJb1J6CjWVNmkgsMCxuw7j9DaGKB","tpubD6NzVbkrYhZ4XEtUAz4UUTWbprewbLTaMhR8NUvSJUEAh4Sidxr6rRPFdqqVRR73btKf13wUjds2i8vVCNo8sbKrAnyoTr3o5Y6QSbboQjk","tpubD6NzVbkrYhZ4Yj9AAt6xUVuGPVd8jXCrEE6V2wp7U3PFh8jYYvVad31b4VUXEYXzSnkco4fktu8r4icBsB2t3pCR3WnhVLedY2hxGcPFLKD"],"nicknameFor":{}},"txProposals":{"txps":[],"walletId":"dbfe10c3fae71cea","networkName":"testnet"},"privateKey":{"extendedPrivateKeyString":"tprv8ZgxMBicQKsPeoHLg3tY75z4xLeEe8MqAXLNcRA6J6UTRvHV8VZTXznt9eoTmSk1fwSrwZtMhY3XkNsceJ14h6sCXHSWinRqMSSbY8tfhHi","networkName":"testnet"},"addressBook":{}}'; +var o = '{"opts":{"id":"dbfe10c3fae71cea", "spendUnconfirmed":1,"requiredCopayers":3,"totalCopayers":5,"version":"0.0.5","networkName":"testnet"},"networkNonce":"0000000000000001","networkNonces":[],"publicKeyRing":{"walletId":"dbfe10c3fae71cea","networkName":"testnet","requiredCopayers":3,"totalCopayers":5,"indexes":[{"copayerIndex":2,"changeIndex":0,"receiveIndex":0}],"copayersBackup":[],"copayersExtPubKeys":["tpubD6NzVbkrYhZ4YGK8ZhZ8WVeBXNAAoTYjjpw9twCPiNGrGQYFktP3iVQkKmZNiFnUcAFMJRxJVJF6Nq9MDv2kiRceExJaHFbxUCGUiRhmy97","tpubD6NzVbkrYhZ4YKGDJkzWdQsQV3AcFemaQKiwNhV4RL8FHnBFvinidGdQtP8RKj3h34E65RkdtxjrggZYqsEwJ8RhhN2zz9VrjLnrnwbXYNc","tpubD6NzVbkrYhZ4YkDiewjb32Pp3Sz9WK2jpp37KnL7RCrHAyPpnLfgdfRnTdpn6DTWmPS7niywfgWiT42aJb1J6CjWVNmkgsMCxuw7j9DaGKB","tpubD6NzVbkrYhZ4XEtUAz4UUTWbprewbLTaMhR8NUvSJUEAh4Sidxr6rRPFdqqVRR73btKf13wUjds2i8vVCNo8sbKrAnyoTr3o5Y6QSbboQjk","tpubD6NzVbkrYhZ4Yj9AAt6xUVuGPVd8jXCrEE6V2wp7U3PFh8jYYvVad31b4VUXEYXzSnkco4fktu8r4icBsB2t3pCR3WnhVLedY2hxGcPFLKD"],"nicknameFor":{}},"txProposals":{"txps":[],"walletId":"dbfe10c3fae71cea","networkName":"testnet"},"privateKey":{"extendedPrivateKeyString":"tprv8ZgxMBicQKsPeoHLg3tY75z4xLeEe8MqAXLNcRA6J6UTRvHV8VZTXznt9eoTmSk1fwSrwZtMhY3XkNsceJ14h6sCXHSWinRqMSSbY8tfhHi","networkName":"testnet"},"addressBook":{},"settings":{"unitName":"BTC","unitToSatoshi":100000000,"unitDecimals":8,"alternativeName":"Argentine Peso","alternativeIsoCode":"ARS"}}'; + var legacyO = '{"opts":{"id":"55d4bd062d32f90a","spendUnconfirmed":true,"requiredCopayers":2,"totalCopayers":2,"name":"xcvzxcv","version":"0.3.2"},"networkNonce":"53d25e8600000009","networkNonces":[],"publicKeyRing":{"walletId":"55d4bd062d32f90a","networkName":"testnet","requiredCopayers":2,"totalCopayers":2,"indexes":[{"copayerIndex":2147483647,"changeIndex":0,"receiveIndex":0},{"copayerIndex":0,"changeIndex":4,"receiveIndex":2},{"copayerIndex":1,"changeIndex":5,"receiveIndex":2}],"copayersBackup":["02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba","02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5"],"copayersExtPubKeys":["tpubD94LTzAUiW99mpA59nyf6fAHh4xKGmnwbgCV4gU2bRpeN9CRiMSurqme22px5NmJAo6FdcdH883Zu98VbqyhesCJ86kUEjH3Zpufy5FfcaC","tpubDA2U9H6LkRHDRbRxHBp4VTbxPc7JqsvtcLxrE5QJF8z1iT6hMJ1pXSVf57GWRcxXutYvpoXRurDVGsscJauMtnJBkYAWBVExYmm91XQE2zz"],"nicknameFor":{"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":"asdf","02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":"qwerqw"},"publicKeysCache":{"m/0/0/0":["028a4b63f26253f3a8731577b8e1ee480950ad5833ebbf106fe3463bfc07cc3b90","0332efa054c08cb77506a35ee0762cb7156f244566703ec08e433568ec0397bec8"],"m/1/0/0":["0220ad514cf593d0c3905d3bb49bc5767a9410823bf9b77ea5ef2cf1d1016d77a8","02fd42cf66f1dbdc7bbb9ae09aecea72df479ffe5a0c4641301067e331d12e416d"],"m/1/0/1":["0315f7868eaf1f9b7127e3f7e0222c5e473eea003e34700f4758b6873c525d6723","02a2e8ed5e90dd39e3842fc790e06178997dbca319987f365317589e2a71a93658"],"m/0/1/0":["0244a25a0b97b26707fd855c15b046b901be85a3b70a781d0678608e633440eeca","0358cdcbc528ddfb7173b0dab283f702be82546ff031e4a832a7270080cb875959"],"m/0/1/1":["025c9b49bdf17d97bd82ea1b87793082f857247f0f9b999937a166ec994bb1b41f","020389327ee8ae7d0ee3f8187842d23a4070bdd8a27c0bcddd05d80ef39009253d"],"m/1/1/0":["02fd0e7c62b7b58d1ea7bb4cb84d53b019df99d3703a42aed73a2cfa15f3af5d08","0355a15912e76072ef50e6643376b8a9da8422ed4f8ea07b1d84d4989be5a39b2e"],"m/1/1/1":["03bc3e1f4db32efd8eb1fd44a1665938d59628429c67e1e8b7054ab5717f4e6750","03c4c817b633ac31f44f16f390af831d35f7d98744a52a0f23e9598967342255f8"],"m/1/1/2":["02826fe7e9da408480ddeb1d4414c5100b350f862ca718e27122681e1a0ca35077","02bd25af907bb3edbf6b2cd1ea90eaa92cc93ec47bea7d339af44c1d2c05708e99"],"m/0/1/2":["0337a1a70364b94745d6e26d2d28919cf528304f52765f12ef43e3d6da0a6c8dc0","039d83db9aa43e6e00e0304e6971b6079d79dc12d8d55ce2e6fc24a52ba8d41329"],"m/0/0/1":["0359c6d0d0d31f83301169901a6ffad9535f14014b5ab3b43561dbb2436a7b8138","037d06f713f13a11967fd5edca265ff4c77528693a712c482256505693e4890d93"],"m/1/1/3":["02600e5c41670773a213a4cb58c8f2fa3e83840784bc7f0b56925e1075e06632c2","036d01867af5f61371151ef7d9026fa0400a623f6924e404ee0b856625268972f9"],"m/0/1/3":["03e5a9b039b187ca8e065627df402e4a5b196b94198542da7036879de08be63d2d","0304f3e0b70f696d80e5785dc7747d6dcb55ba24c31f2d80bf184b4e582e6b47fc"],"m/1/1/4":["03741afa5bd50d6ba5801064c810fae84f6a4557d6a88ddc8591d0d4eb68a8fc41","0214dd6ce6073b05999fb887098ca6f7e1d0b4fdc0760557786907df353df90d1c"],"m/2147483647/1/0":["033e072a53ea835763a03c66e35c35384736210a1bb7d7ee6d9a3e109e82426b30","02e37b5570c053da8a8ee587be86fc629775c4db890aba2745ccc4e4dcc8c31041"],"m/2147483647/1/1":["0228a6de42ef421c263d1efd9f28d9a7d15a261995028a24eff6b9f1c3fc46e6bf","0226cff885cb0d607cc9cf69a7608316eb3fb2ec344c0c9956246ba776116fc396"],"m/2147483647/1/2":["034fe2a8f0b98445eb5810fe36572ad2f64ed9bf64dc9de624f99c0142cb07c682","02f2c5c758e32293f5c193fd69afadbba83abafb397db01e6f2b447690e900475a"],"m/2147483647/1/3":["02b25ef9434446c51f10678f787e4913de582e34d164bd3b06af7732c5476df1a8","025d51a1efd59bcff22ee2e0af61b21a7ba5f639e20dfdf25690e926005177dd0c"],"m/2147483647/1/4":["03e5734e1d29b2f684d0446b7a2ffbd0ba8952570a502d0d14b1efd8f24b61be53","0258fc28a324848d8d0154e8614815e35c668d274a8f01957bb99aab8dc8f386c0"],"m/2147483647/1/5":["021f9e775246765e1cfba0ae453b4eae6cd4ae5a57a09c319edbe89d4dbbf23be3","02857f66571a1c3eb9e72d22ae88e734c03d448bced4dcfd345c2059468124c741"],"m/2147483647/1/6":["02c072f329391a25255dc6452e5f5220966869dbf736ba8a8c3ae9d273a84bc3fd","030920a8b8e88c4db2871a7df0878a86cf0695f6d96bb50c701c3454f3df25176a"],"m/2147483647/1/7":["036bf329fc19bce10cf1999fae5bfa80290ff7b44776b49c7b0dc9eec6cffcfa21","03955a549875b4f7b9be28b9ff4bcd51ad2bc224430b1634baef890585885d5e1b"],"m/2147483647/1/8":["024879c9c9a261b3141ecfa1c79c4efc25278c844ecd1dcfcb95d9c19581fbdd25","03fb4a5fdb91239df3ccf7f61a5b99e7e72483101e21c9d1ee0d85544e9354c6c7"],"m/2147483647/1/9":["035928a107ec01f78cd586914d5a49710fd42e352b1312e3ad0eeb2c9666fdf8e7","03a54c03093797854829c75357f092356352a109042bbb83bdac20cb4e5eca27ea"],"m/2147483647/1/10":["021e7a3a7efe888c5e820b5cf0f03317b2b4bf438d8563449aeb7a77cade97f136","03ec0960b3d1df52ca3cc2c82b7d97063400da4dd051bba2f9bab6cb44aee01efa"],"m/2147483647/1/11":["035d70c26b7f429861f555f7c0d99947411b23b7f95303fb8d5de5b82a95aa30fc","038b922f7024f5446d6b48e5253643543b35c006d90fd37688105c6cefcd8adb8a"],"m/2147483647/1/12":["02158d6503891c6c65a606221dbf5c68d0832288975914007968419939588ecb24","0248264cb1763a3f4de9b34787b4bc5443ec92ef915927494bb9f1c1c0b498c7ca"],"m/2147483647/1/13":["0349965eea38a25ae0c061faeac4c4e57e648bc4c0f059d07b3b8b7962cbc0dde5","0352243d9269565ce2a1ffdd0b8e43a442c6dd1c9edda86eaaf2cba5a4a95c40f1"],"m/2147483647/1/14":["030fa6e3d0c5cedc0581955395c77cbe134c912a47971023b9695332df3f7bb200","03f2cf09e33326fb59bf3f13e6298d2d5d29c9eae3b872e5a851e8d8d77259c883"],"m/2147483647/1/15":["02bf0d45e41339f552df6f8baf4392142921fd38b0f2a4388a905ff6cbacbc278a","03fabe46bb6706a1b8edfd28c046a8891b4530bbe5305080b72b0d08ebdf7b8c0a"],"m/2147483647/1/16":["03a4e3146ed34d6a8af4e4379e6edcff32cb0373ba232b3d746af3052f674133ac","030311b73c6f5c46ddffc0cfce6e5ed0b671d94267d8e52cd8837f2a479916eb91"],"m/2147483647/1/17":["03233df93c762d2f06c7f5f388e4e0a8dbdb13302acba0d2d6995c487d8aec9f2f","024badfdcb7e772ac7fc1c46d3943b07500edbbece105cdeff3eb9e9fcc9f54782"],"m/2147483647/1/18":["0364035475a098e00eb010c500cad3c90af3e81a4bd613144bc9433a150f14718b","028223dc8142154e7477ce000b3dc13e1d15a901553d9b18864c8645b582b38fe6"],"m/2147483647/1/19":["03971b74b4ac4bdaadf636baa4caa82fe5355471ed6ea05a9cbe5fc6c9e4b9db76","0202ebffacd01f83849e5bc5c0e2c317bc5fb2fbcb2d6d4482a5235f9f1308b61a"],"m/0/1/4":["03005ee9ff028c98fd132e531023f2f2b61ff0d26022f979dd98088d2ba167b031","0345ea82e8dfe38277f0c3aee18d2dd93edb63e8663ac83328a7934d2ca57006f6"],"m/0/1/5":["0391bc4990b71d8a3f156ae7107929ed6372b0b4ba8a868253f71ba7189d1efa02","0312a74cf2e7c0dd41897d04fabfd8cc3187b84a28305cfc79315b24e6fe23a6b4"],"m/0/1/6":["021a38c492607ff9684a4fec445e47b5b7100d3ef9e9dc0d0b37c0a646d28d4f77","03ae0b46ab36f97447ebaa53f2b5c8f090f15395378785f2fd285eeba17fbf3f65"],"m/0/1/7":["0308cdec88c1ffe16edc98853d9c08dbd4ba2541ba566668ca17bda19d7eb3481f","02dd622267c2e68287287b8b61724f76fbe84096a56aa5054af92f8fe25380e2d1"],"m/0/1/8":["039647da9ad725836bcb28a3e0497659a28d7749d1416c421a0a01c62d237ee962","022e22aa61eafda0dd8820427f1a06314d352a15ea8645e7ab9b80920017084d82"],"m/0/1/9":["03a4ade946076c6962b70c70ac7fad3a87efb59a1d0a4e32bda13a6d47fe9df961","029a07235aba04ab69526e117d836d5b3fae5cfc8c5e72b10c6d1afd261ccc19f3"],"m/0/1/10":["03c78e9b6493b22790db1acea20df9444e0f9c424fc5756e7a32c290ae01783953","0254c130ee467a96570c9f5ebea89de04f0b1db1686b164f2694339bef8f25dd88"],"m/0/1/11":["03a762c43318ef8d4840fab04c8db73797dc648825fac60f2730b4c76678df1cf3","0212c684a4de8e750ad2dfe2b136370ab9803eca178ed9a27b3990c29b067de35c"],"m/0/1/12":["02702d221f9b15c5cf75ac2f497a6c63e60213087c3d2d3be46768e3ebd238e26e","03ed58580744deb357258e44548212038670769d8d51e385d4fb8414311fd01b52"],"m/0/1/13":["0320e0597b54c62768352f433389cee4725d6094d7bcb5c72265edcc0933829aff","02c5706f11b9a85f3176c572842b7c9812c2195058d24d945bc026b00312740e76"],"m/0/1/14":["02fe43077676b844226d3aaa62e8a86d237710d92f882366944acbde0c8992fcaf","039a6a8662abb8910741cf331320549665e9feb28ca94d1ab6a43c84fa330b94ee"],"m/0/1/15":["0369f99f72847af93d50ab8ee75b6e7e912d26e27be96f6d6b7215cf7daeff7ba5","02521700cc07c953ba5aa586fb0e4795a34dffc68c5fb43e038be3866e40f4daed"],"m/0/1/16":["02f67d1d89bd8fe2f91c5b973cbdacfb4ba440e7656bce284cf73d549625607347","035da9cfac5a803dcb2b283b02a2515a4a1bcbf3d19e0d180aee8fc30193bc0555"],"m/0/1/17":["02c024ec199d240e8d6c66276b94b91071f7cdf2bef540c29d6d18d25de7b1cf7c","02190865f9dafae3f7f05c093463be5632946422ddda0a6fef6904390792516067"],"m/0/1/18":["035ed504d7704ad984a333b8eb0fceb8be043da9284de31ed84d9e68d90c75507d","033303c415b50421732402df00f4baa219f334647a7eb5014b9f8079864d6ab558"],"m/0/1/19":["02ce49fe86b0eee73663b1ee867b16b97c876af26f12764c528a2e6d0eb55ad3d7","03ab969bc81796b88e44c340d854df955fc60ea17ea92db5d3115595d6dec890d8"],"m/0/1/20":["03e2fa915378cbdffa0d919b0fb50c7256ca731b9d571b3365e486893a1d43079c","038d058b895cf084dccfcc9367e4796a5cf4ddceed6c35f6885d75c80119613350"],"m/0/1/21":["02fcb1bf644446b5b42205272af72f0aeab9e92ca29aafa91c5fb69142764017aa","035c5fe5c8811603279a5b72b6c30735d702817db1eab937c622269e28192ffa90"],"m/0/1/22":["03b39d61dc9a504b13ae480049c140dcffa23a6cc9c09d12d6d1f332fee5e18ca5","022929f515c5cf967474322468c3bd945bb6f281225b2c884b465680ef3052c07e"],"m/0/1/23":["03f40b82fe8cacff08879f13c45f443a3dc3ea98e1d75d5f32a19f5e5a8f7a905b","028415ee458e4dcfd440ce969726f3b58ae74fb6cf3995ced099579211e7419844"],"m/1/1/5":["032748a6282e21f571b8c8dd49e775deb83c90fcf88dc4ba81d878536973709c3f","020837cd68f14ce571b335eecd1b6fa0af43e1576dd9721aaca2a8ab639ac6b7cd"],"m/1/1/6":["0337032efb013dc92bb8dccfbdda9f5c28f0039a9c60953d41003d095e9f9778af","03ceed2da6b9603297061dc8eb930112ba726b2ccf5eec67f4866a05ca4049a22b"],"m/1/1/7":["0383c96ac2af7d203f69133b2fab6b68366b5075ad6957fa06759df3b20fbfec70","0311385f79834cedaf2230a48c0f9dc8e794da1869fc595db2518d62debb85579a"],"m/1/1/8":["03efc649680280f4e4df96da923bc88330275004125ebe5483c2f3e05ca52e19a4","02803c02d197d780388259afbd001ae41fa3eb3e2bac9627aff540521c184c3b23"],"m/1/1/9":["03af2fe6aa027a76b42c1c4050a040bfd026ad2daec1bb96a5fe2d026a7df919de","02ce14163047c640228796fb1f72bbe3afb05819ad141598a4f021058a6f79dd3b"],"m/1/1/10":["033770378bd762cf0408e44e4e604bef77e336170428c506949b1a4f1f2963e574","02c58ed43946f699dbd3e36d3e9aab2714cadeb19ecd3a56e4328c50336b4a76cb"],"m/1/1/11":["02898a1545fa19bdca92adc498698d27b86529cd4c08946d9d29604734b86f31af","02b402767a045ede072600924401c0d720000b2ed59fa444bfdbef4a5f1cead745"],"m/1/1/12":["039b8659430be49913e2cd869aa8c99ccf49a13df35837370b792033dadb891483","03264e63df292257cc76babb15d15bef620d1c2f8c3bbc78d6ea02d127e5ee7386"],"m/1/1/13":["02381a559791b8e86bf546e2c718ae63cf24eed0518a58e4d4a4b310adf2cd38fa","02d7f8283a4418d912508901b4a3db0d2103206dfdd74b3c75648671e20ecfd445"],"m/1/1/14":["020376e8c550b7d9faa0b2da947a2a36fab22c6e8190b6f99460b6022017bb97d7","03fbc5299190e6628de28c92aaa12e3a131b21eb7266462c46fbedeb86fa878055"],"m/1/1/15":["027209fd3b0cf7368180a5dbb16b928c997d33fccb78505d48440c7d23eadf5460","03450bfb22858726cd7e228e6733f69457546978a95188565c53e0d1c0d6070ea8"],"m/1/1/16":["03cb355ba04f64293793855121bab5831f84a3a3edf7cd31fccaa6d67c407a4912","028bc897a39c1224610b765a80f4cd8ab79cb37776f58fec9c10ac6f649d1f3c72"],"m/1/1/17":["03f4cb0564d7e2c6b85673503b7954db22779f29a8f3374904573984e318a96bf1","037c11b6ee906d84aa7eed359d758d986d912b6f8e5cbb1acf0982a77b3ef812c4"],"m/1/1/18":["02d2e5798f33f6889472857744316f2d253f25f88379610063f40cfe5798d9858f","0253cefdfe9ca987cbf1c950b6246d5b7a194d8dfad47c3a78dbbc5c1d01511d97"],"m/1/1/19":["0336c325f5aed366ffc10d553f2bfd4d69e66cbe1688d77af14efc8827aea2e318","0378b1b9a6074f9f2ab4fa9ad1e14649c621b0c8124a1b148914d3c10e6ab390c6"],"m/1/1/20":["03ea55740a734689ce778a8c00df8ebf4274c8f66de7d05646fe5c927773ff7f2e","02275b558d49aef955b6dee51a3c0a53f4b076b97bb3f26abcc82540168ec87cac"],"m/1/1/21":["03c77869c9984664eac9c238f4b6d806c9f48ca8a736c48450f398834db2aa915c","02d984f548c7f60c09dad3287cfc48807bc8157123989636c713be61be6a2e9ced"],"m/1/1/22":["03ed7c6a3c854c1f9459891691cc32671402f9e47126919878251e568dbdf353f8","02a113dab22cd9e46967b3fd76b9b9ec1d227d88817a9300e42d332cca2a0877fd"],"m/1/1/23":["02ee186432dcf69fda50a6fdbd94651817d8a271c273a5b70cab3ec4ae77a3753b","02291370aad9de0dac676355ced64e268b0c431a51f42f12d13f5144940fce4285"],"m/1/1/24":["02bf71435e84e66547c8c583d5ba226a5ac4d935e0a9f9603ecd8925c3e847e91a","03578d8657d285a89d9d597632db662cfef9baccfb55c76b1e87948a94fc9de30d"],"m/2147483647/0/0":["02a8425bbe23426219065969f695a6c3e242b24e57226bffdd542be8fd6be968c9","03057a42fdb6569fb1615b173ccb702453db2eac5be4291b82d4511461eafbed87"],"m/2147483647/0/1":["0250c3d3e86e332010c5233c2ec3bc728026002f0037cb3382d6318409b0e70796","02cfac1e7c4c88191201080f8316af52d9faa6ba624a6e160279e9fac4d1cf79a9"],"m/2147483647/0/2":["02a8c266a5b92eb50c8be91f95e4d1ad968b2f57d527377fd642d63fb84474f61a","028cc954ab31bd179ff80b8a05f95430ae534e61b3ff35f5284fa2fbe1832ceccb"],"m/2147483647/0/3":["02f719e1a7ab00ea98611453fb03d44c1da04655bed74af392534d70099039b4c2","03bfa548bfd4718c50bfce173f780eadcfb679d9c0206c91a2fa1879a9cf7558b2"],"m/2147483647/0/4":["0362c0695d397ca26bf47f0e641bb3cfb06ff29ccac2e1d56ded3afcf88b1e688d","02f9d87b05bdb3b9e82f506b43f813041c0e403274adc23d11e5e1651e34b606c2"],"m/2147483647/0/5":["033731323032d4ee08e858fc71f93970444333e183a1d5052e1d08cfb511e262c8","023e12556cef67ade35b7758916b5e1a3ebe074ccd35c5d8eff6b01321f63eb495"],"m/2147483647/0/6":["025d11b90081972bc1c258c9d6f476dfc2f95b69f0e9935322bf9c21deb580ff64","02b065f56a378907354f0738a0ed74f10660c6b5dd68c9f992093b75ce3d7d8b72"],"m/2147483647/0/7":["0210e721e8a35db9d8c855a0d346f60c09208f3be80b39e03af2c29db777332c71","0277f352969fadb1f1835f9a0fa99c6a3c7b6c281be5b2794c88a708eb177ea33d"],"m/2147483647/0/8":["02998d8d41e4215cd2a961a415a3ed0b1f984f1627719a7b102a75864943c4d87b","03d8ed7fc8f68a77f68d3afd007b7aa4c89944195143630ce183f0fa5438f2b559"],"m/2147483647/0/9":["0324fa91737588e4f85937303ce65c3b91b5f2ae506a72d92b83e3f5f9aeeb3c6f","02a011be72c4a400319212228106af278823a97acfe0a67e1ecd866d446b315114"],"m/2147483647/0/10":["025886ba287922a904881c7315e6fcc410a7976741771a5937d3a1a01b529f21fd","0243bb91ceed9d29d0c2ca66a8ab77e82110bbcc023beb4106f787964f44a0b972"],"m/2147483647/0/11":["0369d21684894cc2d4b2f5e581ede3cac9e8db4161a08e7737c1be129bb673d3d5","03c9ef27e3cd3dadc078fdfd9936a7ad9bf7954747085cf8f8a2a5bb3431f68a9f"],"m/2147483647/0/12":["03a73b8fd859bf6acebffdfffa2597199091daedd2c011ac67fc3494d8a1a8ceb6","025a213f7771c8be03f43f2e7f469ad4ef2cf6907ea284b227a786d1f55dfa7144"],"m/2147483647/0/13":["03a09f7ca257e1ab263cd5e6b0addc3ff868b93df132321d98775ca3505efb576f","03454c715739164bc55f347a651439cdf3ec146b35d2927beb60e8290b3916e082"],"m/2147483647/0/14":["03a64b1f7bd94a6b1a6e84ea444e0ba04e9deb86460934ccc37c0615a134a8257b","02794f09210b1811a455f3e1c7bcd35c76dff2523190fef9615eb27e2376acac1c"],"m/2147483647/0/15":["0392dca2fd9a3bc2b2a7d90a848719069fbc5f22bff7327bb8186c032514085263","032ee8a33ea76d70c7ae839448ca6c5b1af89146f2922e23ba1822df42dbc7e66a"],"m/2147483647/0/16":["031a22a1a3c1abad7c4d782ef6ba3cc00f2e8fe549eb33e0732200aff6d3174831","03bdce9781289e0c31cf727f4c93fe46f7930dd8fd68f818ce241f1ede268e8e0e"],"m/2147483647/0/17":["03b12d27e9aea2c2ad598e54e40860a705ac2ca2427aa511b501b38ec368ea5c7d","03e60d35d84d4536cad895215256b312bb4879a8d417251c279995e58f25da3d54"],"m/2147483647/0/18":["0380266cc9a9673676ad6a1b2e7148766df9c25b4dce299e5edc4f65b72aa58e64","0329e2a8a48c06c0c45dfdd2ab33e6455551557d8ebaf8c12fdf7470f8c45f1d28"],"m/2147483647/0/19":["036fe62af85560d7eea7c7af55e60b32a97dca80134d0aedffb19eb2705b9d6e01","02381c2c30b9f81e2a53c69028fbe11803acad0420b267719b7a80870be0baaeb7"],"m/0/0/2":["027bf94b8fc4e9b42683af25fda125ccab8760040717d100270dd4afd032692daf","026382c6c9357250d96dc21e43c053857a64efeac1887fdcbc107fbe3ecfc6115a"],"m/0/0/3":["03fd203acbd9af3cbbfb709458f8952078234a36094f12d00372e4b2b14cfdf419","03f2e5db59aea5dc89f53ac2a9f4ef66d41265c45afc5d763e0ca61ab70c7c61ec"],"m/0/0/4":["02a1d7cf4fcdbbf4de4002b844c3bff1639073f1cd6e5c4a4e02596b45d3f518c2","03b5fba813294e6ae096ea158833453caa5a945609b0a554696091b9b152bb0f7d"],"m/0/0/5":["0261d37e3b56ef4e106c59753037f516a4b1c45e056b2a3e00f8b77f15aaa7f8a5","0256a55e66e0de1603f0d600c0eb5f5486cf3512a776a36f3ab0d1941fc0dc9b09"],"m/0/0/6":["031db2826af215fe6cbe3f6e121b0497840fc49be133cff0a4d4eab679d6b99d70","021dd722c3f35dd04fcdb57f09b76c723d521fb36751de03ffd08096ddf1dc1f86"],"m/0/0/7":["0354ea75bdd9eb5beae7262e4a5eeb58bd10103ee0185e85b749ea39f6615d0f62","03f2c8f3b6478c0501a8578d5caf5ac2974f8213fc5e699d62dd2af58fbe8781d4"],"m/0/0/8":["0282e67df3bcd1e1662469b4c3151fb50ee1e46b75d787d91184c16b9803131f82","02921a7054af1e425f4137a5eb6b34d1f2b9d81c2625230194bc30657bb4277e11"],"m/0/0/9":["033e7e387933983ceab37c8388bd8ebc5119760f493ffe6f083bef0e5dfe22891d","02d660d60cc55d80912e0745cb142a8596a4604fbf72f9aadec0599aa2ed62461a"],"m/0/0/10":["022ce5b2750ae34512199856eab9e912dc25281cd8b88e7688a46c3b9a389701cb","02f14aa1608fce3b6088148709eb5fe72b61699c931fa8d95a45fab1106859d1b0"],"m/0/0/11":["0288dbef3302c1bc5556028adb33e2f9e03c119dbad4f706befb8ce86cea459f2b","03f13ced465e2e0a3aaa8895f3185d5711e0bebdaf507610b7a669ac8fc82da8fe"],"m/0/0/12":["031ab4677885340d2f927ccc9747f4346b79e4eb6c750695095a8a2524610fa94a","038c881910fbd8b50d193db4e0c84f5b7840820397f92cf0718a8e06d027125503"],"m/0/0/13":["031b568452cba22eb7a88c6085489e53e35abd16068882e71a140e47e12dee9c61","020d09885ee362101d12d34ce0918d41593634db1b9413e5415c6755753b9330e8"],"m/0/0/14":["024177bc9aa03cfc72eda2dfddffd7fe9d0c2f007fc3ba1a48280feae2b9fb117a","03394ad321668440c08da76eb35475ba3a8c0e8cbe0ed81468673a8c72d38fe457"],"m/0/0/15":["02037b1cc696ffbe9eba3684edd53653386ef6cd7728401c40120037593a4c2ae2","020ab8d6900ec9c11ca5d96dfc0ce7cf0ee71653a7c45118e89abb4b113147e53a"],"m/0/0/16":["023bcbb8d4726a546087cdb83740adf0ace879b7195a572c652fa8ce4dbe195a04","0392721b230d5163d28b27fc7e059b875711f12b3da448eabe7229bde57530e637"],"m/0/0/17":["02498ee74e849d3e9261dd1863038caf83d6a3bc2eeebecf17055d4bab44dee77f","03d4dc104b2e0981693e8097437de9b05334a85e2c8edb02783897859bdbc93e32"],"m/0/0/18":["0218a9f524fe54abf8c3afd21314296cfd93eaa9227acbd457e6c9a742dc233cf4","03760f3d0c5db969bda698ff9352e3b7c332216c34825f4c6e857e39c9aee7cd35"],"m/0/0/19":["033dd51f7737f0e9db79f5c38e4298bf3396346904ef3933d290a22e5b77048d9e","0221b2eedccb9a37515263071550069b3b349a166f0f131d0028e8600d9a2251b9"],"m/0/0/20":["02cb6c39161f3244d7769f7ab96346cae2cf21cb6f4538f5e7382d363dc2f836c7","034f7bda4d1e9ed6a3774608a4d6cd8582ab59fe3187f8a7a7cf914d89426ebe28"],"m/0/0/21":["035490549d65f1360f10340037250b171470ff4c86966318a2b1eead6d8b969aea","03f6a04f6fcd07a4f32c82d53710ed30e0f54d43d41c67c661d158b3d0830c3ea2"],"m/1/0/2":["02972eae7e4302e319c266578e14a07839c1e788296a92906e6d66d938211dad5f","039ed6b488f1571ad6527acd6b6c5b8453eacf6665dc5cb7852e33d1c8ea73f9fe"],"m/1/0/3":["02bec4728888c2c045108353994bae5731ec7a7b41459023b0023e10b8d616bd30","03ce1efe16214c9eac595382e46a68143dd11a335b3f7c971ddd719ac544a5fc4b"],"m/1/0/4":["030e2df1d341568225d8dfbe5d07e98dae9f90e0f43e19dcc68c998a6ed7bcc1f0","0380f4c07dc84faf42d51779f104aa6e3b5c3ce2d7684b3cb76d49faeefc2b69d6"],"m/1/0/5":["029a54ddaa25f433b493f4b72df8c1d41be2c4d2963b8b61ee63cc86d16c12d066","021567c95e0317442e7367aa4e3378dd46c5bcef5860f789272fea83b917de0669"],"m/1/0/6":["03590320d80b61cc0874b579f467c9b5ccc50d9ef875bcf6bdd12e2d0c211e8973","03ee4677b6ee89a9d355851f2230506c6897ff219062c0df4ad9a85c60f3535f93"],"m/1/0/7":["03caf98ab1c9b79d1dc8029453a6137c08787b04043b79af3cb42d41d2d3f1338f","023f39ae4e2f4f3887d5fc58e0d3a0d7ee267dc04aa257c75b6b2d67d2f5580f81"],"m/1/0/8":["0352a2a3ea8209c9a2b633d788796ac2d16c08022440e04a77ab2835c7f971d266","0291bc248b3da997f35e8fae98a75a91fdac2819d74c4e270899338d48f7389e87"],"m/1/0/9":["02468d32d9c3c62418d506d4cd0da6cd2022d5bcafdb5f847cf7bde7a48ec6848b","032713d90d12eb6a072f3c1db6c0d3b680d3f78883016135fc0f78e8193d41d4b4"],"m/1/0/10":["034863cc6bab9b059be53413ba75c5fc286647c20d7f9e5512ef4754ea301dd1ce","03a33ab9c32a2264ee2464ebbb5892f0e34acf0fdede4f87395a89e9dacdd4930e"],"m/1/0/11":["031e19296695bfe8a96ba3bf58afa805ee1bd5471fddb3929b1678d69d442d69c9","0270feb33956fd9e937019d629523e26437493c0856514011e6aec88baf7721295"],"m/1/0/12":["03cce695d3c3843bf73e851b2446a77d7e235e5b80b4f4474f9946292eb8218742","039ea96c8822f0ec7ed28308d277f3e730480d7573579cd11b89aef4364cd9ffeb"],"m/1/0/13":["02ab4ac38eb405e822d12c0f0f354f04f9ee1d991dde887a5c1171096fe503158f","036809e60cae1203da8884ea1f85d4669ce6e053f8ba605d775e271b70ab4f6787"],"m/1/0/14":["039d61da23a8610fa0ee58eb37d7cea7ea9396c79153da97280ccf5e46718e3bac","03015c27bcc778682781fd6ad30aa6041db0b7e24270818cdceece0043ccc34b26"],"m/1/0/15":["03c088ed669132835d2728b0ecf294271c8388988c6ae264d43ca24f50e4005f81","03e2c118c9445a2ddc4c8afeb0ba49e21be3f818a483d346418b8922b8a371a2b7"],"m/1/0/16":["02bba7df9847f463c6b23eca37a4bd6efa3801a52b8ddfad804d902e783b70c81c","03764b657f23996e31c64a701facc1cbeb0c9edfdd605e2c1ed36cf48197565d45"],"m/1/0/17":["020445179c522295b89bf4bfd582eb03422e3fa20dcd29263925e9f44282d476d8","036e47bdd32f3061aed1c1f8c2a32b038c7b72391cb1f80ebfc150e58f88372766"],"m/1/0/18":["024d88c4bfcbba713d49e1edcd035234aaa1ee76ad7bcf75bf074a16658a6b0b6d","02b861e7a20d89f6875d2e44c78dbadb99503e282e5e60e9f65657af6fea81d425"],"m/1/0/19":["023a8ca9d5300181f157e1930d3b0800eebe7683d8df72e6cbf28834dbf1be5d60","026053c4f84c10d15890c0b254522972931bc2d5b7cdf9c1f9f3137c22edf3ecd3"],"m/1/0/20":["03137c66e9f3d61aba659f408d77a293fa0f3fea4ccb911074a681d6f61a55d023","0291aa1bbfbef59b16b0e37e185a706c589d448cb02e860c5df9c9d7242ecc739f"],"m/1/0/21":["03c08673e0cae55318bc9dcc4b5f11eb3ff71d42de04015e255dde3fd8cba7e09e","02423d4eab06cd5b26e71d145283523c011d58032700c517f00b328d2c90cf109f"]}},"txProposals":{"txps":[{"creator":"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5","createdTs":1405543144016,"seenBy":{"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543144016,"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543144645},"signedBy":{"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543144016},"rejectedBy":{"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543170040},"sentTs":null,"sentTxid":null,"inputChainPaths":["m/45\'/0/0/0"],"comment":"blablabla","builderObj":{"valueInSat":"29000000","valueOutSat":"8900000","feeSat":"10000","remainderSat":"20090000","hashToScriptMap":{"2NBtv6DdXj8HBunyGqpW9H8bUtW5x3rfVTj":"5221028a4b63f26253f3a8731577b8e1ee480950ad5833ebbf106fe3463bfc07cc3b90210332efa054c08cb77506a35ee0762cb7156f244566703ec08e433568ec0397bec852ae"},"selectedUtxos":[{"address":"2NBtv6DdXj8HBunyGqpW9H8bUtW5x3rfVTj","txid":"a9f4dda3f092e37244bc4e77ea921fed01d5b8ea49613dfdc0dc8afdd70190b5","vout":1,"ts":1405543855,"scriptPubKey":"a914cc93216398b77b5f8c451ca3a357bef961678be987","amount":0.29,"confirmations":0,"confirmationsFromCache":false}],"inputsSigned":0,"signaturesAdded":1,"signhash":1,"spendUnconfirmed":true,"tx":"0100000001b59001d7fd8adcc0fd3d6149eab8d501ed1f92ea774ebc4472e392f0a3ddf4a9010000009300493046022100ccbb8f398f74a76236629b8499ffc6f9518a2091f5a61a9a352c0a10f615961e022100b8f0769c76cf33bec3d7f81d9da2b74cf6e8a5e0a24ee5f48172854d8bcdbfa101475221028a4b63f26253f3a8731577b8e1ee480950ad5833ebbf106fe3463bfc07cc3b90210332efa054c08cb77506a35ee0762cb7156f244566703ec08e433568ec0397bec852aeffffffff02a0cd8700000000001976a91485eb47fe98f349065d6f044e27a4ac541af79ee288ac908c32010000000017a914560c292066792531164149c5ed63ad2793a61b928700000000"}},{"creator":"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5","createdTs":1405543188745,"seenBy":{"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543188745,"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543189341},"signedBy":{"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543188745,"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543206819},"rejectedBy":{},"sentTs":1405543207304,"sentTxid":"169bc92693dd2e27724eeba81e54210e842035bd3af6c52e6a6a5e908f1a4f66","inputChainPaths":["m/45\'/0/0/0"],"comment":"que parece","builderObj":{"valueInSat":"29000000","valueOutSat":"9000000","feeSat":"10000","remainderSat":"19990000","hashToScriptMap":{"2NBtv6DdXj8HBunyGqpW9H8bUtW5x3rfVTj":"5221028a4b63f26253f3a8731577b8e1ee480950ad5833ebbf106fe3463bfc07cc3b90210332efa054c08cb77506a35ee0762cb7156f244566703ec08e433568ec0397bec852ae"},"selectedUtxos":[{"address":"2NBtv6DdXj8HBunyGqpW9H8bUtW5x3rfVTj","txid":"a9f4dda3f092e37244bc4e77ea921fed01d5b8ea49613dfdc0dc8afdd70190b5","vout":1,"ts":1405543855,"scriptPubKey":"a914cc93216398b77b5f8c451ca3a357bef961678be987","amount":0.29,"confirmations":1,"confirmationsFromCache":false}],"inputsSigned":1,"signaturesAdded":2,"signhash":1,"spendUnconfirmed":true,"tx":"0100000001b59001d7fd8adcc0fd3d6149eab8d501ed1f92ea774ebc4472e392f0a3ddf4a901000000da00483045022035423cc74824ba904907678dda3b62a20a787b96d1b3e9f3e9546f9c57f4e45902210080a1ff1c39f458ac1642b9e948bd62fd70563b5252e749cc8fc642cd763ee830014730440220524a13f36cfb03caa246d7d84de634ec9386f2c39c19bfa926037f48da86262b022050e58a6503d105ad2805f86806810a1aa7f20d6271e1340b42fa91ab6a30f3e801475221028a4b63f26253f3a8731577b8e1ee480950ad5833ebbf106fe3463bfc07cc3b90210332efa054c08cb77506a35ee0762cb7156f244566703ec08e433568ec0397bec852aeffffffff0240548900000000001976a91485eb47fe98f349065d6f044e27a4ac541af79ee288acf00531010000000017a9146130a9d51f996b7a1b9d3e10c80930834251909d8700000000"}},{"creator":"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba","createdTs":1405543505848,"seenBy":{"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543505848,"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543590221},"signedBy":{"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543505848,"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543590221},"rejectedBy":{},"sentTs":1405543610315,"sentTxid":"6fe851b54b777a75fe80fa204dc674395e2af69efb1f7c0017e909eb82c3d914","inputChainPaths":["m/45\'/0/1/1"],"comment":"mandaaaaaaa","builderObj":{"valueInSat":"19990000","valueOutSat":"19980000","feeSat":"10000","remainderSat":"0","hashToScriptMap":{"2N277q5r8Ab6XLJNCjXXFdh5itDJRQCv9ts":"5221020389327ee8ae7d0ee3f8187842d23a4070bdd8a27c0bcddd05d80ef39009253d21025c9b49bdf17d97bd82ea1b87793082f857247f0f9b999937a166ec994bb1b41f52ae"},"selectedUtxos":[{"address":"2N277q5r8Ab6XLJNCjXXFdh5itDJRQCv9ts","txid":"169bc92693dd2e27724eeba81e54210e842035bd3af6c52e6a6a5e908f1a4f66","vout":1,"ts":1405543157,"scriptPubKey":"a9146130a9d51f996b7a1b9d3e10c80930834251909d87","amount":0.1999,"confirmationsFromCache":false}],"inputsSigned":1,"signaturesAdded":2,"signhash":1,"spendUnconfirmed":true,"tx":"0100000001664f1a8f905e6a6a2ec5f63abd3520840e21541ea8eb4e72272edd9326c99b1601000000db0048304502206b18b3dba2646c552469d8ef52d7656f6a65f563032530f622abdfd8bd4c5cee022100e804b406eddebbc827646141e74dc64c76a770ed4e35183ffd35d265ad9f7d3b01483045022100f6c013638ff0a316b1baa93dfffba6a98cf3033c133e8bd899e933c9c3e47ce10220530f40e7ea52ae58bec695edbec6d566d2ee8e7b5f33f95e33093ad1e29a125401475221020389327ee8ae7d0ee3f8187842d23a4070bdd8a27c0bcddd05d80ef39009253d21025c9b49bdf17d97bd82ea1b87793082f857247f0f9b999937a166ec994bb1b41f52aeffffffff01e0de3001000000001976a91485eb47fe98f349065d6f044e27a4ac541af79ee288ac00000000"}},{"creator":"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba","createdTs":1405543781381,"seenBy":{"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543781381,"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543782017},"signedBy":{"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543781381},"rejectedBy":{"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543794590},"sentTs":null,"sentTxid":null,"inputChainPaths":["m/45\'/0/0/1"],"comment":"1","builderObj":{"valueInSat":"29000000","valueOutSat":"1000000","feeSat":"10000","remainderSat":"27990000","hashToScriptMap":{"2N4eyXKikdnnUT4S74MRNAYqXChhUYmZ1Sb":"52210359c6d0d0d31f83301169901a6ffad9535f14014b5ab3b43561dbb2436a7b813821037d06f713f13a11967fd5edca265ff4c77528693a712c482256505693e4890d9352ae"},"selectedUtxos":[{"address":"2N4eyXKikdnnUT4S74MRNAYqXChhUYmZ1Sb","txid":"6c9da5b0da4bab0d576033325e987b10ccf2b9bf479d306b6aae36efeaa56892","vout":0,"ts":1405543698,"scriptPubKey":"a9147d274ac50968d7823b6cbc1b38770deb7157995387","amount":0.29,"confirmationsFromCache":false}],"inputsSigned":0,"signaturesAdded":1,"signhash":1,"spendUnconfirmed":true,"tx":"01000000019268a5eaef36ae6a6b309d47bfb9f2cc107b985e323360570dab4bdab0a59d6c000000009200483045022064d877bc5171fbaef909c2a1a924e0023b3ccc0b530cb46653f06ecb230283e8022100bc6658d60ad4f7120d9226c8f6eada87f3b0388f73c458011988bab36e78ba15014752210359c6d0d0d31f83301169901a6ffad9535f14014b5ab3b43561dbb2436a7b813821037d06f713f13a11967fd5edca265ff4c77528693a712c482256505693e4890d9352aeffffffff0240420f00000000001976a91485eb47fe98f349065d6f044e27a4ac541af79ee288acf017ab010000000017a91421c4a435d9ac263ec55b35a1a5ca95e979639b9b8700000000"}},{"creator":"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5","createdTs":1405543835343,"seenBy":{"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543835343,"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543835968},"signedBy":{"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543835343},"rejectedBy":{"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543850998},"sentTs":null,"sentTxid":null,"inputChainPaths":["m/45\'/0/0/1"],"comment":"2","builderObj":{"valueInSat":"29000000","valueOutSat":"1000000","feeSat":"10000","remainderSat":"27990000","hashToScriptMap":{"2N4eyXKikdnnUT4S74MRNAYqXChhUYmZ1Sb":"52210359c6d0d0d31f83301169901a6ffad9535f14014b5ab3b43561dbb2436a7b813821037d06f713f13a11967fd5edca265ff4c77528693a712c482256505693e4890d9352ae"},"selectedUtxos":[{"address":"2N4eyXKikdnnUT4S74MRNAYqXChhUYmZ1Sb","txid":"6c9da5b0da4bab0d576033325e987b10ccf2b9bf479d306b6aae36efeaa56892","vout":0,"ts":1405543698,"scriptPubKey":"a9147d274ac50968d7823b6cbc1b38770deb7157995387","amount":0.29,"confirmationsFromCache":false}],"inputsSigned":0,"signaturesAdded":1,"signhash":1,"spendUnconfirmed":true,"tx":"01000000019268a5eaef36ae6a6b309d47bfb9f2cc107b985e323360570dab4bdab0a59d6c0000000092004830450220302baae7de2e0f102bf3af2d5f450f673e51bd143020141a769ccdcdf16af188022100e7abc087c76050ed649e7139a5a136969e74e24a8d8f6223d3219ad033a26451014752210359c6d0d0d31f83301169901a6ffad9535f14014b5ab3b43561dbb2436a7b813821037d06f713f13a11967fd5edca265ff4c77528693a712c482256505693e4890d9352aeffffffff0240420f00000000001976a91485eb47fe98f349065d6f044e27a4ac541af79ee288acf017ab010000000017a9148b102abba0729fb0690c61cf7187064d692d43d78700000000"}},{"creator":"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba","createdTs":1405543869803,"seenBy":{"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543869803,"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543870411},"signedBy":{"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba":1405543869803,"02b0c868a3889cd0cfc0e7fef9eaa6d85d7cf6f7573ae5c9d1d13645d22e2eb7e5":1405543890406},"rejectedBy":{},"sentTs":1405543890913,"sentTxid":"6a0f61574ad65e537e7e99298968db565f97b894b61f4c8f8fac8fcaedb83e2b","inputChainPaths":["m/45\'/0/0/1"],"comment":"3","builderObj":{"valueInSat":"29000000","valueOutSat":"1100000","feeSat":"10000","remainderSat":"27890000","hashToScriptMap":{"2N4eyXKikdnnUT4S74MRNAYqXChhUYmZ1Sb":"52210359c6d0d0d31f83301169901a6ffad9535f14014b5ab3b43561dbb2436a7b813821037d06f713f13a11967fd5edca265ff4c77528693a712c482256505693e4890d9352ae"},"selectedUtxos":[{"address":"2N4eyXKikdnnUT4S74MRNAYqXChhUYmZ1Sb","txid":"6c9da5b0da4bab0d576033325e987b10ccf2b9bf479d306b6aae36efeaa56892","vout":0,"ts":1405543698,"scriptPubKey":"a9147d274ac50968d7823b6cbc1b38770deb7157995387","amount":0.29,"confirmationsFromCache":false}],"inputsSigned":1,"signaturesAdded":2,"signhash":1,"spendUnconfirmed":true,"tx":"01000000019268a5eaef36ae6a6b309d47bfb9f2cc107b985e323360570dab4bdab0a59d6c00000000db00483045022100a8ce7907f9fd7dd41dd65c2dec425e008efea06ee7c80787c10c0e210fbf181302207712c0fdd1cb25836ac1fc2fd303c1e26b85e8980417719b9ed50e977a9693ec01483045022100d1780c4f028cd898920aca3eaceba352ed9306cd17f019ae2f634e8facad149a02203c84ab2093da8e22577e93f27a732f0728d4e6db0c749f3cd3d898d6a025152a014752210359c6d0d0d31f83301169901a6ffad9535f14014b5ab3b43561dbb2436a7b813821037d06f713f13a11967fd5edca265ff4c77528693a712c482256505693e4890d9352aeffffffff02e0c81000000000001976a91485eb47fe98f349065d6f044e27a4ac541af79ee288ac5091a9010000000017a914cc1cab78458b1a951b91c6dcd7eeeeb682f506388700000000"}}],"walletId":"55d4bd062d32f90a","networkName":"testnet"},"privateKey":{"extendedPrivateKeyString":"tprv8ZgxMBicQKsPdWUAmaaopPftevC72Jtiu19V8ee5XijL9JvogqfR95uVrL85f8yBdQMq3KyQtG3Q91yWQb3XDbWWpcdWFDAmJ7Xy2XWkGJu","networkName":"testnet","privateKeyCache":{"m/45\'/0/0/0":"b6fd8d1a079efd523da34f31ba81f544fc3d0a728a8a98299d8980682518e79c","m/45\'/0/1/1":"0f4d52d2a99e4c8c1c2edf09fef12407c3abd2304b961198c3f131a8c8443a13","m/45\'/0/0/1":"de5c191c343bd6017b98708c03344849624a14e2c167cfd6eb8dcb075d139293"}},"addressBook":{"msj42CCGruhRsFrGATiUuh25dtxYtnpbTx":{"hidden":false,"createdTs":1405543109222,"copayerId":"02c7b87033e4357d8afc6ab7fe31fff054772ea6251f0d9c8a835b1c1ac74f6fba","label":"faucet","signature":"3045022067576e5b37f2707a8dc66e57511ad9b10a3125bd95193fff6f8f6402969c3bf3022100adff9f417db07d88face13b3d13f422740d4421440cade1a205684dfdc5d733a"}}}'; From 7f17918ed93f0c51e4a65390e3e53464341d936e Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Mon, 15 Sep 2014 18:19:12 -0300 Subject: [PATCH 135/191] fix storage set --- js/models/Storage.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/js/models/Storage.js b/js/models/Storage.js index 3433589bf..103cb9a8d 100644 --- a/js/models/Storage.js +++ b/js/models/Storage.js @@ -155,7 +155,9 @@ Storage.prototype.getMany = function(walletId, keys, cb) { // set value for key Storage.prototype.set = function(walletId, k, v, cb) { - preconditions.checkArgument(walletId && k && !_.isUndefined(v) && cb); + preconditions.checkArgument(walletId && k && cb); + + if (_.isUndefined(v)) return cb(); this._write(this._key(walletId, k), v, cb); }; From 20bc1ecbb5d40bf83e70805c7e6d3eab83a9e74c Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Mon, 15 Sep 2014 15:49:52 -0700 Subject: [PATCH 136/191] paypro: fix $root.merchant clearing on tab change. see #1406 - gustavo's comment. --- js/controllers/send.js | 61 +++++++++++++++++++++++++----------------- 1 file changed, 36 insertions(+), 25 deletions(-) diff --git a/js/controllers/send.js b/js/controllers/send.js index 683b6c71c..d12868d40 100644 --- a/js/controllers/send.js +++ b/js/controllers/send.js @@ -465,6 +465,40 @@ angular.module('copayApp.controllers').controller('SendController', $scope.loadTxs(); }; + $scope.clearMerchant = function(callback) { + var scope = $scope; + // TODO: Find a better way of detecting + // whether we're in the Send scope or not. + if (!scope.sendForm || !scope.sendForm.address) { + delete $rootScope.merchant; + if (callback) callback(); + return; + } + var val = scope.sendForm.address.$viewValue || ''; + var uri; + // If we're setting the domain, ignore the change. + if ($rootScope.merchant && $rootScope.merchant.domain && val === $rootScope.merchant.domain) { + uri = { + merchant: $rootScope.merchant.request_url + }; + } + if (val.indexOf('bitcoin:') === 0) { + uri = new bitcore.BIP21(val).data; + } else if (/^https?:\/\//.test(val)) { + uri = { + merchant: val + }; + } + if (!uri || !uri.merchant) { + delete $rootScope.merchant; + scope.sendForm.amount.$setViewValue(''); + scope.sendForm.amount.$render(); + if (callback) callback(); + if ($rootScope.$$phase !== '$apply' && $rootScope.$$phase !== '$digest') { + $rootScope.$apply(); + } + } + }; $scope.onChanged = function() { var scope = $scope; @@ -552,31 +586,8 @@ angular.module('copayApp.controllers').controller('SendController', // If the address changes to a non-payment-protocol one, // delete the `merchant` property from the scope. - var unregister = scope.$watch('address', function() { - var val = scope.sendForm.address.$viewValue || ''; - var uri; - // If we're setting the domain, ignore the change. - if ($rootScope.merchant && $rootScope.merchant.domain && val === $rootScope.merchant.domain) { - uri = { - merchant: $rootScope.merchant.request_url - }; - } - if (val.indexOf('bitcoin:') === 0) { - uri = new bitcore.BIP21(val).data; - } else if (/^https?:\/\//.test(val)) { - uri = { - merchant: val - }; - } - if (!uri || !uri.merchant) { - delete $rootScope.merchant; - scope.sendForm.amount.$setViewValue(''); - scope.sendForm.amount.$render(); - unregister(); - if ($rootScope.$$phase !== '$apply' && $rootScope.$$phase !== '$digest') { - $rootScope.$apply(); - } - } + var unregister = $rootScope.$watch(function() { + $scope.clearMerchant(unregister); }); if ($rootScope.$$phase !== '$apply' && $rootScope.$$phase !== '$digest') { From aa5e90786b64ff4870c7f21e0b3f3c41b90adccb Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Mon, 15 Sep 2014 16:37:36 -0700 Subject: [PATCH 137/191] paypro: fix - check for merchant_data existence. --- js/models/core/Wallet.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/js/models/core/Wallet.js b/js/models/core/Wallet.js index 815ee3fa0..63ffebafa 100644 --- a/js/models/core/Wallet.js +++ b/js/models/core/Wallet.js @@ -1408,7 +1408,10 @@ Wallet.prototype.receivePaymentRequest = function(options, pr, cb) { expires: expires, memo: memo || 'This server would like some BTC from you.', payment_url: payment_url, - merchant_data: merchant_data.toString('hex') + merchant_data: merchant_data + ? merchant_data.toString('hex') + // : new Buffer('none', 'utf8').toString('hex') + : '00' }, signature: sig.toString('hex'), ca: trust.caName, From 62d6c0c8dfb541c8138f72f43fda8c59c7f3933d Mon Sep 17 00:00:00 2001 From: Mariano Rodriguez Date: Tue, 16 Sep 2014 11:39:30 -0300 Subject: [PATCH 138/191] Strong and italic to 'No transaction yet' msg --- views/transactions.html | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/views/transactions.html b/views/transactions.html index 4c92783f7..83210455e 100644 --- a/views/transactions.html +++ b/views/transactions.html @@ -27,8 +27,7 @@
- No transactions yet. -
+ No transactions yet.
From a7d5ca70d35ef624189d42583aee36095c3477fd Mon Sep 17 00:00:00 2001 From: bechi Date: Tue, 16 Sep 2014 12:04:21 -0300 Subject: [PATCH 139/191] fix address book mobile --- views/send.html | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/views/send.html b/views/send.html index 83e00d8f4..3208dce3b 100644 --- a/views/send.html +++ b/views/send.html @@ -181,9 +181,9 @@ Label Address - Creator - Date -   + Creator + Date +   @@ -191,10 +191,10 @@ ng-repeat="(addr, info) in $root.wallet.addressBook" ng-class="{'addressbook-disabled': info.hidden}"> {{info.label}} - {{addr}} - {{$root.wallet.publicKeyRing.nicknameForCopayer(info.copayerId)}} - - {{info.hidden ? + {{addr}} + {{$root.wallet.publicKeyRing.nicknameForCopayer(info.copayerId)}} + + {{info.hidden ? 'Enable' : 'Disable'}} From 0301ad0cf0152b0525a6e700e2516637ee2ac33c Mon Sep 17 00:00:00 2001 From: bechi Date: Tue, 16 Sep 2014 15:45:55 -0300 Subject: [PATCH 140/191] fix qr code's popup mobile --- css/src/mobile.css | 8 ++++---- views/modals/qr-address.html | 20 +++++++++++--------- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/css/src/mobile.css b/css/src/mobile.css index 9deb53219..f4f0bb509 100644 --- a/css/src/mobile.css +++ b/css/src/mobile.css @@ -122,13 +122,13 @@ display: block; float: none; margin: 0 auto; - width: 210px; - height: 210px; + width: 160px; + height: 160px; } .panel qrcode canvas { - width: 200px; - height: 200px; + width: 150px; + height: 150px; } .addresses .panel { diff --git a/views/modals/qr-address.html b/views/modals/qr-address.html index 13d5635fc..5f7d990c3 100644 --- a/views/modals/qr-address.html +++ b/views/modals/qr-address.html @@ -1,20 +1,22 @@
- +
-

{{address.address}}

+

{{address.address}}

-

+

{{address.balance || 0|noFractionNumber}} {{$root.wallet.settings.unitName}}

-

- +
+ + + Open in external application + +
× From a316d044740ab048b0c007c80dc79a7240350611 Mon Sep 17 00:00:00 2001 From: Matias Pando Date: Tue, 16 Sep 2014 15:58:23 -0300 Subject: [PATCH 141/191] Test added --- js/models/core/Wallet.js | 2 -- test/test.Wallet.js | 31 +++++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/js/models/core/Wallet.js b/js/models/core/Wallet.js index 61e81b137..ecd80db24 100644 --- a/js/models/core/Wallet.js +++ b/js/models/core/Wallet.js @@ -520,7 +520,6 @@ Wallet.prototype._onData = function(senderId, data, ts) { preconditions.checkArgument(data.type); preconditions.checkArgument(ts); preconditions.checkArgument(_.isNumber(ts)); - log.debug('RECV', senderId, data); if (data.type !== 'walletId' && this.id !== data.walletId) { @@ -529,7 +528,6 @@ Wallet.prototype._onData = function(senderId, data, ts) { return; } - switch (data.type) { // This handler is repeaded on WalletFactory (#join). TODO case 'walletId': diff --git a/test/test.Wallet.js b/test/test.Wallet.js index c8ae349e5..7e4090a55 100644 --- a/test/test.Wallet.js +++ b/test/test.Wallet.js @@ -402,6 +402,37 @@ describe('Wallet model', function() { }); + describe('#_onData', function() { + var w = cachedCreateW(); + var sender = '025c046aaf505a6d23203edd343132e9d4d21818b962d1e9a9c98573cc2031bfc9'; + var ts = 1410810974778246; + it('should fail on message unknown', function() { + var data = { + type: "xxx", + walletId: w.id + }; + + (function() { + w._onData(sender, data, ts); + }).should. + throw('unknown message type received: xxx from: 025c046aaf505a6d23203edd343132e9d4d21818b962d1e9a9c98573cc2031bfc9'); + + }); + + it('should call sendWalletReady', function() { + var data = { + type: "walletId", + walletId: w.id + }; + + var spy = sinon.spy(w, 'sendWalletReady'); + w._onData(sender, data, ts); + sinon.assert.callCount(spy, 1); + }); + + }); + + describe('#purgeTxProposals', function() { it('should delete all', function() { var w = cachedCreateW(); From 619611b0afeabc614a31ee23aba2ad1f968b583d Mon Sep 17 00:00:00 2001 From: bechi Date: Tue, 16 Sep 2014 17:01:52 -0300 Subject: [PATCH 142/191] fix address list mobile --- views/addresses.html | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/views/addresses.html b/views/addresses.html index ac0ea08f0..937dc186b 100644 --- a/views/addresses.html +++ b/views/addresses.html @@ -7,10 +7,10 @@
-
-
-
-
+
+
+
+
  @@ -18,22 +18,30 @@ change
-
- - - - change -
-
+
- - {{addr.balance || 0|noFractionNumber}} {{$root.wallet.settings.unitName}} - +

+ {{addr.balance || 0|noFractionNumber}} {{$root.wallet.settings.unitName}} +

-
+
+ +
+ + change +
+
+

+ +

+

+ {{addr.balance || 0|noFractionNumber}} {{$root.wallet.settings.unitName}} +

+
+
@@ -45,5 +53,4 @@
-
From 3e345fa60093b967dce5f011e33c7aec76221e69 Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Wed, 17 Sep 2014 06:33:26 -0300 Subject: [PATCH 143/191] fix gitignore --- .gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitignore b/.gitignore index 8aa3d8515..640ac6f20 100644 --- a/.gitignore +++ b/.gitignore @@ -77,7 +77,6 @@ dist/windows dist/*.dmg dist/*.tar.gz dist/*.exe -<<<<<<< HEAD doc/ /node_modules From 5886af5420cac7f70d0d8d57a0904aa7f47bd176 Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Wed, 17 Sep 2014 08:58:23 -0300 Subject: [PATCH 144/191] WIP karma tests --- test/test.Storage.js | 2 +- test/test.WalletFactory.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/test.Storage.js b/test/test.Storage.js index 170235f13..5a3032030 100644 --- a/test/test.Storage.js +++ b/test/test.Storage.js @@ -25,7 +25,7 @@ describe('Storage model', function() { }); should.exist(s2); }); - it('should fail when encrypting without a password', function() { + it.only('should fail when encrypting without a password', function() { var s2 = new Storage({ storage: localMock, diff --git a/test/test.WalletFactory.js b/test/test.WalletFactory.js index 55f5239f6..517bf44bd 100644 --- a/test/test.WalletFactory.js +++ b/test/test.WalletFactory.js @@ -16,7 +16,7 @@ var mockLocalStorage = require('./mocks/FakeLocalStorage'); var mockSessionStorage = require('./mocks/FakeLocalStorage'); -var PERSISTED_PROPERTIES = require('../js/models/core/Wallet').PERSISTED_PROPERTIES; +var PERSISTED_PROPERTIES = (copay.Wallet || require('../js/models/core/Wallet')).PERSISTED_PROPERTIES; function assertObjectEqual(a, b) { PERSISTED_PROPERTIES.forEach(function(k) { From 6fb1a9a4a35d85dac147c777dd72ab22d4976e86 Mon Sep 17 00:00:00 2001 From: Gustavo Maximiliano Cortez Date: Mon, 15 Sep 2014 11:49:53 -0300 Subject: [PATCH 145/191] Fixes typos and .po file --- po/es.po | 80 +++++++++++++++++----------------- views/create.html | 8 ++-- views/dummy-translations.html | 1 + views/modals/address-book.html | 4 +- views/more.html | 4 +- views/send.html | 4 +- 6 files changed, 50 insertions(+), 51 deletions(-) diff --git a/po/es.po b/po/es.po index 69a693a3f..78cedf7be 100644 --- a/po/es.po +++ b/po/es.po @@ -9,7 +9,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 1.6.9\n" +"X-Generator: Poedit 1.6.8\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: views/create.html @@ -17,35 +17,24 @@ msgid "(*) The limits are imposed by the bitcoin network." msgstr "(*) Los límites son impuestos por la red de bitcoin." #: views/more.html -#, fuzzy msgid "" "ALL Transactions Proposals will be discarted. This needs to be done on " -"ALL peers of a wallet, to prevent the old proposals to be resynced " -"again.\n" -" " +"ALL peers of a wallet, to prevent the old proposals to be resynced " +"again." msgstr "" "TODAS las Propuestas de Transacciones serán descartadas. Es necesario que lo " -"hagan TODOS los compañeros del monedero, para prevenir que las viejas " -"propuestas sean re sincronizadas de nuevo.\n" -" " +"hagan TODOS los compañeros del monedero, para prevenir que las viejas " +"propuestas sean re sincronizadas de nuevo." -#: views/modals/address-book.html -msgid "Add Address" -msgstr "Agregar Dirección" - -#: views/modals/address-book.html -msgid "Add Address Book Entry" -msgstr "Nueva entrada" - -#: views/send.html -msgid "Add New Entry" -msgstr "Nueva Entrada" +#: views/send.html views/modals/address-book.html +msgid "Add" +msgstr "Agregar" #: views/send.html views/modals/address-book.html msgid "Address" msgstr "Dirección" -#: views/send.html +#: views/send.html views/modals/address-book.html msgid "Address Book" msgstr "Libreta de Direcciones" @@ -115,9 +104,8 @@ msgid "Certificate:" msgstr "Certificado:" #: views/create.html -#, fuzzy msgid "Choose a password" -msgstr "Escribe tu contraseña" +msgstr "Escribe una contraseña" #: views/import.html msgid "Choose backup file from your computer" @@ -247,7 +235,6 @@ msgid "Including fee of" msgstr "Incluye tasa de" #: views/settings.html -#, fuzzy msgid "" "Insight API server is open-source software. You can run your own instances, " "check Insight API Homepage" #: views/settings.html -#, fuzzy msgid "Insight API servers" -msgstr "Servidor API Insight" +msgstr "Servidor Insight API" #: views/send.html msgid "Insufficient funds" @@ -398,23 +384,20 @@ msgid "Payment Expiration:" msgstr "Vencimiento de Pago:" #: views/more.html -#, fuzzy msgid "" "Pending Transactions Proposals will be discarted. This needs to be done on " -"ALL peers of a wallet, to prevent the old proposals to be resynced " -"again.\n" -" " +"ALL peers of a wallet, to prevent the old proposals to be resynced " +"again." msgstr "" "Las Propuestas de Transacciones Pendientes serán descartadas. Esto es " "necesario hacerlo con TODOS los compañeros del monedero, para " -"prevenir que viejas propuestas sean re sincronizadas de nuevo.\n" -" " +"prevenir que viejas propuestas sean re sincronizadas de nuevo." #: views/uri-payment.html msgid "Preparing payment..." msgstr "Preparando pago..." -#: views/create.html views/join.html +#: views/join.html msgid "Private Key (Hex)" msgstr "Clave Privada (Hex)" @@ -560,8 +543,8 @@ msgstr "" "sincronización de direcciones a los demás compañeros conectados." #: views/send.html -msgid "To:" -msgstr "Para:" +msgid "To" +msgstr "A" #: views/transactions.html msgid "Total" @@ -587,6 +570,10 @@ msgstr "Transacción rechazada" msgid "Use all funds" msgstr "Todos los fondos" +#: views/create.html +msgid "Use test network" +msgstr "Red de prueba" + #: views/join.html msgid "User information" msgstr "Información de Usuario" @@ -631,10 +618,9 @@ msgstr "Nombre del monedero" msgid "Warning!" msgstr "¡Advertencia!" -#: views/create.html -#, fuzzy -msgid "Your Password" -msgstr "Tu contraseña" +#: views/dummy-translations.html +msgid "Wrong password" +msgstr "Contraseña incorrecta" #: views/more.html msgid "" @@ -652,7 +638,7 @@ msgstr "Tu nombre" msgid "Your name (optional)" msgstr "Tu nombre (opcional)" -#: views/open.html +#: views/create.html views/open.html msgid "Your password" msgstr "Tu contraseña" @@ -673,9 +659,8 @@ msgid "first seen at" msgstr "Visto el" #: views/transactions.html -#, fuzzy msgid "mined" -msgstr "Minado el" +msgstr "minado el" #: views/send.html msgid "not valid" @@ -717,6 +702,19 @@ msgstr "deben unirse" msgid "{{tx.missingSignatures}} signatures missing" msgstr "Faltan {{tx.missingSignatures}} firmas" +#~ msgid "Add Address" +#~ msgstr "Agregar Dirección" + +#~ msgid "Add Address Book Entry" +#~ msgstr "Nueva entrada" + +#~ msgid "Add New Entry" +#~ msgstr "Nueva Entrada" + +#, fuzzy +#~ msgid "Your Password" +#~ msgstr "Tu contraseña" + #~ msgid "Bitcoin Network" #~ msgstr "Red Bitcoin" diff --git a/views/create.html b/views/create.html index 7d6c846f3..c9b099fe7 100644 --- a/views/create.html +++ b/views/create.html @@ -24,8 +24,8 @@
-
@@ -53,7 +53,7 @@

- +

diff --git a/views/dummy-translations.html b/views/dummy-translations.html index c87018b9a..fe7033c12 100644 --- a/views/dummy-translations.html +++ b/views/dummy-translations.html @@ -1,3 +1,4 @@ Receive History +Wrong password diff --git a/views/modals/address-book.html b/views/modals/address-book.html index 6dbda00db..e33cfee79 100644 --- a/views/modals/address-book.html +++ b/views/modals/address-book.html @@ -1,4 +1,4 @@ -

Add Address Book Entry

+

Address Book

- + Show Hide From fb73b8fb0bf32cd166fde6f15b589cac235f5d1f Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Mon, 22 Sep 2014 14:53:11 -0300 Subject: [PATCH 189/191] change network dflt --- config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.js b/config.js index df6a69641..35e3d9b14 100644 --- a/config.js +++ b/config.js @@ -2,7 +2,7 @@ var defaultConfig = { defaultLanguage: 'en', // DEFAULT network (livenet or testnet) - networkName: 'testnet', + networkName: 'livenet', logLevel: 'info', From 23b055c9e556b91680d06c7095fd8c1c3b850b06 Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Mon, 22 Sep 2014 14:54:18 -0300 Subject: [PATCH 190/191] New release v0.6.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3bea5238f..65773c273 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "bugs": { "url": "https://github.com/bitpay/copay/issues" }, - "version": "0.6.0", + "version": "0.6.1", "dependencies": { "browser-request": "^0.3.2", "inherits": "^2.0.1", From 59c9553a4e9fdbdb386f154e9969dd88ec2ef76e Mon Sep 17 00:00:00 2001 From: Esteban Ordano Date: Mon, 22 Sep 2014 15:50:19 -0300 Subject: [PATCH 191/191] Fixes test on rateService: github issue #1457 --- js/log.js | 1 - js/services/rate.js | 3 ++- test/unit/services/servicesSpec.js | 28 +++++++++++++++++----------- 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/js/log.js b/js/log.js index 8a011a665..6dc4305dd 100644 --- a/js/log.js +++ b/js/log.js @@ -101,5 +101,4 @@ Logger.prototype.setLevel = function(level) { var logger = new Logger('copay'); logger.setLevel(config.logLevel); -logger.log('Log level:' + config.logLevel); module.exports = logger; diff --git a/js/services/rate.js b/js/services/rate.js index 0c28ae046..68f96c313 100644 --- a/js/services/rate.js +++ b/js/services/rate.js @@ -4,6 +4,7 @@ var RateService = function(request) { this.isAvailable = false; this.UNAVAILABLE_ERROR = 'Service is not available - check for service.isAvailable or use service.whenAvailable'; this.SAT_TO_BTC = 1 / 1e8; + this.BTC_TO_SAT = 1e8; var MINS_IN_HOUR = 60; var MILLIS_IN_SECOND = 1000; var rateServiceConfig = config.rate; @@ -62,7 +63,7 @@ RateService.prototype.fromFiat = function(amount, code) { if (!this.isAvailable) { throw new Error(this.UNAVAILABLE_ERROR); } - return amount / this.rates[code] / this.SAT_TO_BTC; + return amount / this.rates[code] * this.BTC_TO_SAT; }; RateService.prototype.listAlternatives = function() { diff --git a/test/unit/services/servicesSpec.js b/test/unit/services/servicesSpec.js index 2d827c6fd..dd2805a96 100644 --- a/test/unit/services/servicesSpec.js +++ b/test/unit/services/servicesSpec.js @@ -26,7 +26,7 @@ describe("Unit: controllerUtils", function() { var Waddr = Object.keys($rootScope.wallet.balanceByAddr)[0]; var a = {}; a[Waddr] = 100; - //SATs + //SATs $rootScope.wallet.set(100000001, 90000002, a); //retuns values in DEFAULT UNIT(bits) @@ -124,17 +124,23 @@ describe('Unit: Rate Service', function() { }); })); it('should be possible to ask for conversion from fiat', - inject(function(rateService) { - rateService.whenAvailable(function() { - (1).should.equal(rateService.fromFiat(2, 'LOL')); - }); - }) + function(done) { + inject(function(rateService) { + rateService.whenAvailable(function() { + (1e8).should.equal(rateService.fromFiat(2, 'LOL')); + done(); + }); + }) + } ); it('should be possible to ask for conversion to fiat', - inject(function(rateService) { - rateService.whenAvailable(function() { - (2).should.equal(rateService.toFiat(1e8, 'LOL')); - }); - }) + function(done) { + inject(function(rateService) { + rateService.whenAvailable(function() { + (2).should.equal(rateService.toFiat(1e8, 'LOL')); + done(); + }); + }) + } ); });