From d62dbeffcaff316bf1ee1137b5a662cd525cab1e Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Fri, 18 Apr 2014 14:40:16 -0300 Subject: [PATCH 01/15] WIP for automatic network join --- index.html | 5 ++-- js/config.js | 8 +++--- js/controllers/setup.js | 1 - js/controllers/signin.js | 6 +---- js/models/core/PrivateKey.js | 10 +++++--- js/models/core/Wallet.js | 20 +++++++++++---- js/models/core/WalletFactory.js | 44 +++------------------------------ js/models/network/Peer.js | 8 ------ js/models/network/WebRTC.js | 9 +++++-- test/mocks/FakeNetwork.js | 27 ++++++++++++++++++++ test/test.PrivateKey.js | 7 +++--- test/test.Walletfactory.js | 4 +-- 12 files changed, 73 insertions(+), 76 deletions(-) delete mode 100644 js/models/network/Peer.js create mode 100644 test/mocks/FakeNetwork.js diff --git a/index.html b/index.html index 90191c5c3..333f9c8b6 100644 --- a/index.html +++ b/index.html @@ -81,8 +81,9 @@
-

Join a Network Wallet

- +

Join Wallet Creation

+
diff --git a/js/config.js b/js/config.js index c5dde3556..1ee5a429b 100644 --- a/js/config.js +++ b/js/config.js @@ -23,12 +23,12 @@ var config = { verbose: 1, }, blockchain: { - host: 'localhost', - port: 3001 + host: 'test.insight.is', + port: 80 }, socket: { - host: 'localhost', - port: 3001 + host: 'test.insight.is', + port: 80 }, verbose: 1, }; diff --git a/js/controllers/setup.js b/js/controllers/setup.js index 58d5f158d..fc8545bc0 100644 --- a/js/controllers/setup.js +++ b/js/controllers/setup.js @@ -33,7 +33,6 @@ angular.module('copay.setup').controller('SetupController', }; var w = walletFactory.create(opts); controllerUtils.setupUxHandlers(w); - w.netStart(); }; }); diff --git a/js/controllers/signin.js b/js/controllers/signin.js index 260fbb07b..d977aa106 100644 --- a/js/controllers/signin.js +++ b/js/controllers/signin.js @@ -22,7 +22,6 @@ angular.module('copay.signin').controller('SigninController', var w = walletFactory.open(walletId); controllerUtils.setupUxHandlers(w); - w.netStart(); }; $scope.join = function(cid) { @@ -31,10 +30,7 @@ angular.module('copay.signin').controller('SigninController', controllerUtils.onError($scope); $rootScope.$digest(); }); - walletFactory.connectTo(cid, function(w) { - controllerUtils.setupUxHandlers(w); - w.netStart(); - }); + walletFactory.connectTo(cid, $scope.open.bind($scope)); }; diff --git a/js/models/core/PrivateKey.js b/js/models/core/PrivateKey.js index 9d9a7b009..c6e5d5c5f 100644 --- a/js/models/core/PrivateKey.js +++ b/js/models/core/PrivateKey.js @@ -16,13 +16,17 @@ function PrivateKey(opts) { var init = opts.extendedPrivateKeyString || this.network.name; this.bip = opts.BIP32 || new BIP32(init); this.privateKeyCache = opts.privateKeyCache || {}; - this._calcId(); }; -PrivateKey.prototype._calcId = function() { - this.id = util.ripe160(this.bip.extendedPublicKey).toString('hex'); +PrivateKey.prototype.getId = function(prefix) { + var buf = this.bip.extendedPublicKey; + if (prefix) { + buf = Buffer.concat([prefix, this.bip.extendedPublicKey]); + } + return util.ripe160(buf).toString('hex'); }; + PrivateKey.fromObj = function(obj) { return new PrivateKey(obj); }; diff --git a/js/models/core/Wallet.js b/js/models/core/Wallet.js index 97c4f74b4..254d4e6b1 100644 --- a/js/models/core/Wallet.js +++ b/js/models/core/Wallet.js @@ -133,6 +133,13 @@ Wallet.prototype._optsToObj = function () { return obj; }; + +Wallet.prototype.generatePeerId = function() { + var gen = this.privateKey.getId(new Buffer(this.id)); + console.log(gen); + return gen; +}; + Wallet.prototype.netStart = function() { var self = this; var net = this.network; @@ -147,9 +154,12 @@ Wallet.prototype.netStart = function() { net.on('close', function() { self.emit('close'); }); + var startOpts = { + peerId: this.generatePeerId() + } net.start(function(peerId) { self.emit('created'); - }); + }, startOpts); }; Wallet.prototype.store = function(isSync) { @@ -236,7 +246,7 @@ Wallet.prototype.getTxProposals = function() { self.txProposals.txps.forEach(function(txp) { var i = {txp:txp}; i.ntxid = txp.builder.build().getNormalizedHash(); - i.signedByUs = txp.signedBy[self.privateKey.id]?true:false; + i.signedByUs = txp.signedBy[self.privateKey.getId()]?true:false; ret.push(i); }); return ret; @@ -267,7 +277,7 @@ Wallet.prototype.sign = function(ntxid) { var ret = txp.builder.sign(keys); if (ret.signaturesAdded) { - txp.signedBy[this.privateKey.id] = Date.now(); + txp.signedBy[this.privateKey.getId()] = Date.now(); this.log('[Wallet.js.230:ret:]',ret); //TODO if (ret.isFullySigned) { this.log('[Wallet.js.231] BROADCASTING TX!!!'); //TODO @@ -294,8 +304,8 @@ Wallet.prototype.addSeenToTxProposals = function() { var self=this; this.txProposals.txps.forEach(function(txp) { - if (!txp.seenBy[self.privateKey.id]) { - txp.seenBy[self.privateKey.id] = Date.now(); + if (!txp.seenBy[self.privateKey.getId()]) { + txp.seenBy[self.privateKey.getId()] = Date.now(); ret = true; } }); diff --git a/js/models/core/WalletFactory.js b/js/models/core/WalletFactory.js index a3e0a4475..caad23826 100644 --- a/js/models/core/WalletFactory.js +++ b/js/models/core/WalletFactory.js @@ -75,6 +75,7 @@ WalletFactory.prototype.read = function(walletId) { this.log('NOT NECCESARY AN ERROR:', e); //TODO } this.log('### WALLET OPENED:', w.id); + w.netStart(); return w; }; @@ -112,10 +113,12 @@ WalletFactory.prototype.create = function(opts) { opts.totalCopayers = totalCopayers; var w = new Wallet(opts); w.store(); + w.netStart(); return w; }; WalletFactory.prototype.open = function(walletId) { + this.log('Opening walletId:' + walletId); var w = this.read(walletId) || this.create({ id: walletId, verbose: this.verbose, @@ -123,44 +126,6 @@ WalletFactory.prototype.open = function(walletId) { return w; }; -WalletFactory.prototype.openRemote = function(peedId) { - var s = WalletFactory.storage; - opts = opts || {}; - this.log('### CREATING NEW WALLET.' + (opts.id ? ' USING ID: ' + opts.id : ' NEW ID')); - - opts.privateKey = opts.privateKey || new PrivateKey({ networkName: this.networkName }); - this.log('\t### PrivateKey Initialized'); - - var requiredCopayers = opts.requiredCopayers || this.walletDefaults.requiredCopayers; - var totalCopayers = opts.totalCopayers || this.walletDefaults.totalCopayers; - - opts.publicKeyRing = opts.publicKeyRing || new PublicKeyRing({ - networkName: this.networkName, - requiredCopayers: requiredCopayers, - totalCopayers: totalCopayers, - }); - opts.publicKeyRing.addCopayer(opts.privateKey.getExtendedPublicKeyString()); - this.log('\t### PublicKeyRing Initialized'); - - opts.txProposals = opts.txProposals || new TxProposals({ - networkName: this.networkName, - }); - this.log('\t### TxProposals Initialized'); - - opts.storage = this.storage; - opts.network = this.network; - opts.blockchain = this.blockchain; - - opts.spendUnconfirmed = typeof opts.spendUnconfirmed === undefined - ?this.walletDefaults.spendUnconfirmed : opts.spendUnconfirmed; - - opts.requiredCopayers = requiredCopayers; - opts.totalCopayers = totalCopayers; - var w = new Wallet(opts); - w.store(); - return w; -}; - WalletFactory.prototype.getWalletIds = function() { return this.storage.getWalletIds(); } @@ -175,8 +140,7 @@ WalletFactory.prototype.connectTo = function(peerId, cb) { self.network.start(function() { self.network.connectTo(peerId) self.network.on('walletId', function(walletId) { - self.log('Opening walletId:' + walletId); - return cb(self.open(walletId)); + return cb(walletId); }); }); }; diff --git a/js/models/network/Peer.js b/js/models/network/Peer.js deleted file mode 100644 index 2d76a7d15..000000000 --- a/js/models/network/Peer.js +++ /dev/null @@ -1,8 +0,0 @@ - - -function Peer(id) { - this.id = id; -}; - - -module.exports = require('soop')(Peer); diff --git a/js/models/network/WebRTC.js b/js/models/network/WebRTC.js index d1a16ae03..7b4868567 100644 --- a/js/models/network/WebRTC.js +++ b/js/models/network/WebRTC.js @@ -29,6 +29,7 @@ function Network(opts) { if (opts[k]) self.opts[k]=opts[k]; }); this.connectedPeers = []; + this.started = false; } Network.parent=EventEmitter; @@ -215,12 +216,16 @@ Network.prototype._setupPeerHandlers = function(openCallback) { }); }; -Network.prototype.start = function(openCallback) { +Network.prototype.start = function(openCallback, opts) { // Start PeerJS Peer - if (this.peer) return openCallback(); // This is for connectTo-> peer is started before + if (this.started) return openCallback(); // This is for connectTo-> peer is started before + + opts = opts || {}; + this.peerId = this.peerId || opts.peerId; this.peer = new Peer(this.peerId, this.opts); this._setupPeerHandlers(openCallback); + this.started = true; }; Network.prototype._sendToOne = function(peerId, data, cb) { diff --git a/test/mocks/FakeNetwork.js b/test/mocks/FakeNetwork.js new file mode 100644 index 000000000..0245f5429 --- /dev/null +++ b/test/mocks/FakeNetwork.js @@ -0,0 +1,27 @@ + +var imports = require('soop').imports(); +var EventEmitter= imports.EventEmitter || require('events').EventEmitter; + +function Network(opts) { +} + +Network.parent=EventEmitter; + +Network.prototype.start = function(openCallback, opts) { + // start! :D +}; + +Network.prototype.send = function(peerIds, data, cb) { + // send! c: +}; + +Network.prototype.connectTo = function(peerId) { + // connect C: +}; + + +Network.prototype.disconnect = function(cb) { + // disconect :c +}; + +module.exports = require('soop')(Network); diff --git a/test/test.PrivateKey.js b/test/test.PrivateKey.js index 463f18054..a222ff71a 100644 --- a/test/test.PrivateKey.js +++ b/test/test.PrivateKey.js @@ -69,16 +69,15 @@ describe('PrivateKey model', function() { it('should calculate .id', function () { var w1 = new PrivateKey(config); - should.exist(w1.id); - w1.id.length.should.equal(40); + should.exist(w1.getId()); + w1.getId().length.should.equal(40); }); it('fromObj toObj roundtrip', function () { var w1 = new PrivateKey(config); var w2 = PrivateKey.fromObj(w1.toObj()); w2.toObj().extendedPrivateKeyString.should.equal(w1.toObj().extendedPrivateKeyString); - w2.id.should.equal(w1.id); - + w2.getId().should.equal(w1.getId()); JSON.stringify(w2.get(1,1).storeObj()).should .equal(JSON.stringify(w1.get(1,1).storeObj())); diff --git a/test/test.Walletfactory.js b/test/test.Walletfactory.js index 98157d952..944e55cb1 100644 --- a/test/test.Walletfactory.js +++ b/test/test.Walletfactory.js @@ -3,12 +3,12 @@ var chai = chai || require('chai'); var should = chai.should(); -var WebRTC = require('../js/models/network/WebRTC'); +var FakeNetwork = require('./mocks/FakeNetwork'); var Insight = require('../js/models/blockchain/Insight'); var FakeStorage = require('./mocks/FakeStorage'); var WalletFactory = typeof copay === 'undefined' ? require('soop').load('../js/models/core/WalletFactory',{ - Network: WebRTC, + Network: FakeNetwork, Blockchain: Insight, Storage: FakeStorage, }) : copay.WalletFactory; From 9246ae175fcb34c3657a5a0b96cbb9503f0cff8f Mon Sep 17 00:00:00 2001 From: "Ryan X. Charles" Date: Fri, 18 Apr 2014 17:35:32 -0300 Subject: [PATCH 02/15] encryption and decryption working for File --- js/models/storage/File.js | 44 ++++++++++++++++++++++------- js/models/storage/LocalEncrypted.js | 2 +- test/test.storage.File.js | 13 +++++---- 3 files changed, 43 insertions(+), 16 deletions(-) diff --git a/js/models/storage/File.js b/js/models/storage/File.js index 3fca9154a..50b44b6d9 100644 --- a/js/models/storage/File.js +++ b/js/models/storage/File.js @@ -2,7 +2,6 @@ var imports = require('soop').imports(); var fs = imports.fs || require('fs'); var parent = imports.parent || require('./Base'); -var crypto = imports.crypto || require('crypto'); var CryptoJS = require('node-cryptojs-aes').CryptoJS; var passwords = []; @@ -15,8 +14,33 @@ function Storage(opts) { } Storage.parent = parent; +Storage.prototype._encrypt = function(string) { + var encrypted = CryptoJS.AES.encrypt(string, passwords[0]); + var encryptedBase64 = encrypted.toString(); + return encryptedBase64; +}; + +Storage.prototype._encryptObj = function(obj) { + var string = JSON.stringify(obj); + return this._encrypt(string); +}; + +Storage.prototype._decrypt = function(base64) { + var decrypted = CryptoJS.AES.decrypt(base64, passwords[0]); + var decryptedStr = decrypted.toString(CryptoJS.enc.Utf8); + return decryptedStr; +}; + +Storage.prototype._decryptObj = function(base64) { + var decryptedStr = this._decrypt(base64); + return JSON.parse(decryptedStr); +}; + Storage.prototype.load = function(walletId, callback) { - fs.readFile(walletId, function(err, data) { + var self = this; + fs.readFile(walletId, function(err, base64) { + var data = self._decryptObj(base64); + if (err) return callback(err); try { @@ -32,10 +56,11 @@ Storage.prototype.load = function(walletId, callback) { }; Storage.prototype.save = function(walletId, callback) { - var data = JSON.stringify(this.data[walletId]); + var obj = this.data[walletId]; + var encryptedBase64 = this._encryptObj(obj); //TODO: update to use a queue to ensure that saves are made sequentially - fs.writeFile(walletId, data, function(err) { + fs.writeFile(walletId, encryptedBase64, function(err) { if (callback) return callback(err); }); @@ -105,16 +130,15 @@ Storage.prototype.setFromObj = function(walletId, obj, callback) { this.save(walletId, callback); }; -Storage.prototype.setFromEncryptedObj = function(walletId) { - //TODO: implement +Storage.prototype.setFromEncryptedObj = function(walletId, base64, callback) { + var obj = this._decryptObj(base64); + this.setFromObj(walletId, obj, callback); }; Storage.prototype.getEncryptedObj = function(walletId) { - var data = JSON.stringify(this.data[walletId]); - var encrypted = CryptoJS.AES.encrypt(data, passwords[0]); - var hex = CryptoJS.enc.Hex.stringify(CryptoJS.enc.Base64.parse(encrypted.toString())); + var encryptedBase64 = this._encryptObj(this.data[walletId]); - return hex; + return encryptedBase64; }; // remove all values diff --git a/js/models/storage/LocalEncrypted.js b/js/models/storage/LocalEncrypted.js index b730b7bce..cb4e378fe 100644 --- a/js/models/storage/LocalEncrypted.js +++ b/js/models/storage/LocalEncrypted.js @@ -54,7 +54,7 @@ Storage.prototype._write = function(k,v) { }; Storage.prototype.getEncryptedObj = function(walletId) { - var keys = this._getWalletKeys(); + var keys = this._getWalletKeys(walletId); var obj = {}; for (var i in keys) { var key = keys[0]; diff --git a/test/test.storage.File.js b/test/test.storage.File.js index 20da9cbba..97a33c9b0 100644 --- a/test/test.storage.File.js +++ b/test/test.storage.File.js @@ -17,7 +17,9 @@ describe('Storage/File', function() { var fs = {} fs.readFile = function(filename, callback) { filename.should.equal('myfilename'); - callback(); + var obj = {"test":"test"}; + var encryptedStr = CryptoJS.AES.encrypt(JSON.stringify(obj), "password").toString(); + callback(null, encryptedStr); }; var Storage = require('soop').load('../js/models/storage/File.js', {fs: fs}); var storage = new Storage({password: 'password'}); @@ -156,15 +158,16 @@ describe('Storage/File', function() { var obj = {test:'testval'}; var data = JSON.stringify(obj); var encrypted = CryptoJS.AES.encrypt(data, 'password'); - var hex = CryptoJS.enc.Hex.stringify(CryptoJS.enc.Base64.parse(encrypted.toString())); + var base64 = encrypted.toString(); var storage = new Storage({password: 'password'}); storage.data['walletId'] = obj; var enc = storage.getEncryptedObj('walletId'); - enc.length.should.equal(96); - enc.slice(0,10).should.equal(hex.slice(0,10)); - enc.slice(0,6).should.equal("53616c"); + //enc.length.should.equal(96); + enc.length.should.be.greaterThan(10); + enc.slice(0,10).should.equal(base64.slice(0,10)); + //enc.slice(0,6).should.equal("53616c"); }); }); From f599331351b942346eda77e7753cf4a6b0af6752 Mon Sep 17 00:00:00 2001 From: "Ryan X. Charles" Date: Fri, 18 Apr 2014 17:48:47 -0300 Subject: [PATCH 03/15] use base64 for export --- js/models/storage/LocalEncrypted.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/js/models/storage/LocalEncrypted.js b/js/models/storage/LocalEncrypted.js index cb4e378fe..95f4461a7 100644 --- a/js/models/storage/LocalEncrypted.js +++ b/js/models/storage/LocalEncrypted.js @@ -54,7 +54,7 @@ Storage.prototype._write = function(k,v) { }; Storage.prototype.getEncryptedObj = function(walletId) { - var keys = this._getWalletKeys(walletId); + var keys = this._getWalletKeys(); var obj = {}; for (var i in keys) { var key = keys[0]; @@ -62,9 +62,9 @@ Storage.prototype.getEncryptedObj = function(walletId) { } var str = JSON.stringify(obj); - var hex = CryptoJS.enc.Hex.stringify(CryptoJS.enc.Base64.parse(this._encrypt(str).toString())); + var base64 = this._encrypt(str).toString(); - return hex; + return base64; }; module.exports = require('soop')(Storage); From 4ba65dd4e1758ded22b0790c44a613b8e7e765bd Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Fri, 18 Apr 2014 18:25:51 -0300 Subject: [PATCH 04/15] automatic peer discovery --- index.html | 6 ++-- js/config.js | 12 ++++---- js/controllers/signin.js | 9 ++++-- js/models/core/PrivateKey.js | 2 +- js/models/core/PublicKeyRing.js | 13 +++++++-- js/models/core/Wallet.js | 35 +++++++++++++++++----- js/models/core/WalletFactory.js | 17 ++++++----- js/models/network/WebRTC.js | 51 ++++++++++++++++++++++++--------- js/services/controllerUtils.js | 2 ++ 9 files changed, 103 insertions(+), 44 deletions(-) diff --git a/index.html b/index.html index 333f9c8b6..ffcc2f018 100644 --- a/index.html +++ b/index.html @@ -61,7 +61,7 @@ One key is - missing. Ask your copayers to join your session: {{$root.wallet.network.peerId}} + missing. Share this secret with your other copayers for them to join your wallet: {{$root.wallet.network.peerId}}
@@ -82,7 +82,7 @@

Join Wallet Creation

-
@@ -110,7 +110,7 @@
-

Open a Existing Wallet

+

Open Existing Wallet

diff --git a/js/config.js b/js/config.js index 1ee5a429b..130c3f494 100644 --- a/js/config.js +++ b/js/config.js @@ -3,13 +3,13 @@ var config = { networkName: 'testnet', network: { - key: 'lwjd5qra8257b9', + // key: 'lwjd5qra8257b9', // This is for running local peerJs with params: ./peerjs -p 10009 -k 'sdfjhwefh' - // key: 'sdfjhwefh', - // host: 'localhost', - // port: 10009, - // path: '/', - maxPeers: 3, + key: 'sdfjhwefh', + host: '192.168.1.100', + port: 10009, + path: '/', + maxPeers: 10, debug: 3, }, limits: { diff --git a/js/controllers/signin.js b/js/controllers/signin.js index d977aa106..2607fd611 100644 --- a/js/controllers/signin.js +++ b/js/controllers/signin.js @@ -17,10 +17,11 @@ angular.module('copay.signin').controller('SigninController', $location.path('setup'); }; - $scope.open = function(walletId) { + $scope.open = function(walletId, opts) { $scope.loading = true; - var w = walletFactory.open(walletId); + console.log('OPENING!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!11 '+walletId+' opts '+opts); + var w = walletFactory.open(walletId, opts); controllerUtils.setupUxHandlers(w); }; @@ -30,7 +31,9 @@ angular.module('copay.signin').controller('SigninController', controllerUtils.onError($scope); $rootScope.$digest(); }); - walletFactory.connectTo(cid, $scope.open.bind($scope)); + walletFactory.connectTo(cid, function(data) { + $scope.open(data.walletId, data.opts); + }); }; diff --git a/js/models/core/PrivateKey.js b/js/models/core/PrivateKey.js index c6e5d5c5f..bf8cfa9de 100644 --- a/js/models/core/PrivateKey.js +++ b/js/models/core/PrivateKey.js @@ -21,7 +21,7 @@ function PrivateKey(opts) { PrivateKey.prototype.getId = function(prefix) { var buf = this.bip.extendedPublicKey; if (prefix) { - buf = Buffer.concat([prefix, this.bip.extendedPublicKey]); + buf = Buffer.concat([prefix, buf]); } return util.ripe160(buf).toString('hex'); }; diff --git a/js/models/core/PublicKeyRing.js b/js/models/core/PublicKeyRing.js index b55d7568b..122fb7da5 100644 --- a/js/models/core/PublicKeyRing.js +++ b/js/models/core/PublicKeyRing.js @@ -9,6 +9,7 @@ var Address = bitcore.Address; var Script = bitcore.Script; var coinUtil = bitcore.util; var Transaction = bitcore.Transaction; +var util = bitcore.util; var Storage = imports.Storage || require('../storage/Base.js'); var storage = Storage.default(); @@ -76,6 +77,14 @@ PublicKeyRing.prototype.serialize = function () { return JSON.stringify(this.toObj()); }; +PublicKeyRing.prototype.getCopayerId = function(i, prefix) { + var buf = this.copayersBIP32[i].extendedPublicKey; + if (prefix) { + buf = Buffer.concat([prefix, buf]); + } + return util.ripe160(buf).toString('hex'); +} + PublicKeyRing.prototype.registeredCopayers = function () { return this.copayersBIP32.length; @@ -225,12 +234,12 @@ PublicKeyRing.prototype._checkInPRK = function(inPKR, ignoreId) { if ( this.requiredCopayers && inPKR.requiredCopayers && (this.requiredCopayers !== inPKR.requiredCopayers)) - throw new Error('inPRK requiredCopayers mismatch'); + throw new Error('inPRK requiredCopayers mismatch '+this.requiredCopayers+'!='+inPKR.requiredCopayers); if ( this.totalCopayers && inPKR.totalCopayers && (this.totalCopayers !== inPKR.totalCopayers)) - throw new Error('inPRK requiredCopayers mismatch'); + throw new Error('inPRK totalCopayers mismatch'+this.totalCopayers+'!='+inPKR.requiredCopayers); }; diff --git a/js/models/core/Wallet.js b/js/models/core/Wallet.js index 254d4e6b1..376e95ebc 100644 --- a/js/models/core/Wallet.js +++ b/js/models/core/Wallet.js @@ -48,7 +48,9 @@ Wallet.prototype._handlePublicKeyRing = function(senderId, data, isInbound) { var shouldSend = false; var recipients, pkr = this.publicKeyRing; var inPKR = copay.PublicKeyRing.fromObj(data.publicKeyRing); - if (pkr.merge(inPKR, true) && !data.isBroadcast) { + + var hasChanged = pkr.merge(inPKR, true); + if (hasChanged && !data.isBroadcast) { this.log('### BROADCASTING PKR'); recipients = null; shouldSend = true; @@ -115,8 +117,11 @@ Wallet.prototype._handleData = function(senderId, data, isInbound) { Wallet.prototype._handleNetworkChange = function(newPeer) { if (newPeer) { this.log('#### Setting new PEER:', newPeer); + console.log('sending wallet id'); this.sendWalletId(newPeer); + console.log('sending pubkeyring'); this.sendPublicKeyRing(newPeer); + console.log('sending tx proposals'); this.sendTxProposals(newPeer); } this.emit('refresh'); @@ -134,10 +139,16 @@ Wallet.prototype._optsToObj = function () { }; -Wallet.prototype.generatePeerId = function() { - var gen = this.privateKey.getId(new Buffer(this.id)); - console.log(gen); - return gen; +Wallet.prototype.generatePeerId = function(index) { + var idBuf = new Buffer(this.id); + if (typeof index === 'undefined') { + // return my own peerId + var gen = this.privateKey.getId(idBuf); + return gen; + } + // return peer number 'index' peerId + return this.publicKeyRing.getCopayerId(index, idBuf); + }; Wallet.prototype.netStart = function() { @@ -148,17 +159,26 @@ Wallet.prototype.netStart = function() { net.on('data', self._handleData.bind(self) ); net.on('open', function() {}); // TODO net.on('openError', function() { - this.log('[Wallet.js.132:openError:] GOT openError'); //TODO + self.log('[Wallet.js.132:openError:] GOT openError'); //TODO self.emit('openError'); }); net.on('close', function() { self.emit('close'); }); var startOpts = { - peerId: this.generatePeerId() + peerId: self.generatePeerId() } + console.log('STARTING NETWORK WITH PEER ID: '+startOpts.peerId); net.start(function(peerId) { self.emit('created'); + console.log('CREATEEEEEEEEEEEEEEEEEEEEEEd'); + var myId = self.generatePeerId(); + for (var i=0; i= 0) array.splice(pos, 1); - return array; }; Network.prototype._onClose = function(peerId) { this.connectedPeers = Network._arrayRemove(peerId, this.connectedPeers); + console.log('on close peers:'+this.connectedPeers); this._notifyNetworkChange(); }; @@ -106,7 +106,7 @@ Network.prototype._onData = function(data, isInbound) { this._onClose(obj.sender); break; case 'walletId': - this.emit('walletId', obj.data.walletId); + this.emit('walletId', obj.data); break; default: this.emit('data', obj.sender, obj.data, isInbound); @@ -124,8 +124,6 @@ Network.prototype._sendPeers = function(peerIds) { Network.prototype._addPeer = function(peerId, isInbound) { var hasChanged = Network._arrayPushOnce(peerId, this.connectedPeers); - - if (isInbound && hasChanged) { this._sendPeers(); //broadcast peer list } @@ -186,17 +184,15 @@ Network.prototype._setupPeerHandlers = function(openCallback) { var p = this.peer; p.on('open', function(peerId) { + console.log('setup peer handlers open'+peerId); self.peerId = peerId; self.connectedPeers = [peerId]; - self._notifyNetworkChange(); return openCallback(peerId); }); p.on('error', function(err) { console.log('### PEER ERROR:', err); - self.peer.disconnect(); - self.peer.destroy(); - self.peer = null; + //self.disconnect(null, true); // force disconnect self._checkAnyPeer(); }); @@ -217,14 +213,36 @@ Network.prototype._setupPeerHandlers = function(openCallback) { }; Network.prototype.start = function(openCallback, opts) { + console.log('start start'); + opts = opts || {}; // Start PeerJS Peer - if (this.started) return openCallback(); // This is for connectTo-> peer is started before + var self = this; + if (this.started) { + // network already started, restarting network layer + console.log('Restarting network layer'); + opts.connectedPeers = this.connectedPeers; + Network._arrayRemove(this.peerId, opts.connectedPeers); + this.disconnect(function() { + console.log('restart disconnect finished'); + self.start(openCallback, opts); + }, true); // fast disconnect + return; + } + + opts = opts || {}; + opts.connectedPeers = opts.connectedPeers || []; this.peerId = this.peerId || opts.peerId; + console.log('setting up fresh network with id'+this.peerId); this.peer = new Peer(this.peerId, this.opts); this._setupPeerHandlers(openCallback); + console.log('connected peers'+opts.connectedPeers); + for (var i = 0; i Date: Fri, 18 Apr 2014 18:39:09 -0300 Subject: [PATCH 05/15] remove console.logs --- js/controllers/signin.js | 1 - js/models/core/Wallet.js | 5 ----- js/models/network/WebRTC.js | 8 -------- 3 files changed, 14 deletions(-) diff --git a/js/controllers/signin.js b/js/controllers/signin.js index 2607fd611..2a210b42a 100644 --- a/js/controllers/signin.js +++ b/js/controllers/signin.js @@ -20,7 +20,6 @@ angular.module('copay.signin').controller('SigninController', $scope.open = function(walletId, opts) { $scope.loading = true; - console.log('OPENING!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!11 '+walletId+' opts '+opts); var w = walletFactory.open(walletId, opts); controllerUtils.setupUxHandlers(w); }; diff --git a/js/models/core/Wallet.js b/js/models/core/Wallet.js index 376e95ebc..ed10587b0 100644 --- a/js/models/core/Wallet.js +++ b/js/models/core/Wallet.js @@ -117,11 +117,8 @@ Wallet.prototype._handleData = function(senderId, data, isInbound) { Wallet.prototype._handleNetworkChange = function(newPeer) { if (newPeer) { this.log('#### Setting new PEER:', newPeer); - console.log('sending wallet id'); this.sendWalletId(newPeer); - console.log('sending pubkeyring'); this.sendPublicKeyRing(newPeer); - console.log('sending tx proposals'); this.sendTxProposals(newPeer); } this.emit('refresh'); @@ -168,10 +165,8 @@ Wallet.prototype.netStart = function() { var startOpts = { peerId: self.generatePeerId() } - console.log('STARTING NETWORK WITH PEER ID: '+startOpts.peerId); net.start(function(peerId) { self.emit('created'); - console.log('CREATEEEEEEEEEEEEEEEEEEEEEEd'); var myId = self.generatePeerId(); for (var i=0; i Date: Fri, 18 Apr 2014 19:19:38 -0300 Subject: [PATCH 06/15] get LocalEncrypted working the same way as File --- js/models/storage/LocalEncrypted.js | 33 +++++++++++++++++++++++++---- test/test.storage.LocalEncrypted.js | 4 ++-- 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/js/models/storage/LocalEncrypted.js b/js/models/storage/LocalEncrypted.js index 95f4461a7..56922a1f2 100644 --- a/js/models/storage/LocalEncrypted.js +++ b/js/models/storage/LocalEncrypted.js @@ -25,12 +25,26 @@ Storage.prototype._setPassphrase = function(password) { pps[this.__uniqueid] = password; } -Storage.prototype._encrypt = function(data) { - return CryptoJS.AES.encrypt(data, this._getPassphrase()); +Storage.prototype._encrypt = function(string) { + var encrypted = CryptoJS.AES.encrypt(string, this._getPassphrase()); + var encryptedBase64 = encrypted.toString(); + return encryptedBase64; }; -Storage.prototype._decrypt = function(encrypted) { - return CryptoJS.AES.decrypt(encrypted, this._getPassphrase()); +Storage.prototype._encryptObj = function(obj) { + var string = JSON.stringify(obj); + return this._encrypt(string); +}; + +Storage.prototype._decrypt = function(base64) { + var decrypted = CryptoJS.AES.decrypt(base64, this._getPassphrase()); + var decryptedStr = decrypted.toString(CryptoJS.enc.Utf8); + return decryptedStr; +}; + +Storage.prototype._decryptObj = function(base64) { + var decryptedStr = this._decrypt(base64); + return JSON.parse(decryptedStr); }; Storage.prototype._read = function(k) { @@ -53,6 +67,17 @@ Storage.prototype._write = function(k,v) { localStorage.setItem(k, v); }; +Storage.prototype.setFromObj = function(walletId, obj) { + for (var i in keys) { + var key = keys[0]; + obj[key] = this.get(walletId, key); + } +}; + +Storage.prototype.setFromEncryptedObj = function(walletId, base64) { + +}; + Storage.prototype.getEncryptedObj = function(walletId) { var keys = this._getWalletKeys(); var obj = {}; diff --git a/test/test.storage.LocalEncrypted.js b/test/test.storage.LocalEncrypted.js index 80854b524..8e674a52f 100644 --- a/test/test.storage.LocalEncrypted.js +++ b/test/test.storage.LocalEncrypted.js @@ -53,8 +53,8 @@ if (typeof process === 'undefined' || !process.version) { storage.set('walletId', 'test', 'testval'); var obj = {test:'testval'}; var encrypted = storage.getEncryptedObj('walletId'); - encrypted.length.should.equal(96); - encrypted.slice(0,6).should.equal("53616c"); + encrypted.length.should.be.greaterThan(10); + //encrypted.slice(0,6).should.equal("53616c"); }); }); }); From 4fff1673cd272cce5cd8d3bf758b73a4aed25400 Mon Sep 17 00:00:00 2001 From: Gustavo Cortez Date: Sat, 19 Apr 2014 04:55:32 -0300 Subject: [PATCH 07/15] Send form: validation and functionality. Little issue in navbar was fixed. --- css/main.css | 17 ++++++++-- index.html | 71 +++++++++++++++++++++++++++++++----------- js/controllers/send.js | 27 ++++++++++++++++ 3 files changed, 93 insertions(+), 22 deletions(-) diff --git a/css/main.css b/css/main.css index e92211b0c..bedc96ff4 100644 --- a/css/main.css +++ b/css/main.css @@ -58,7 +58,6 @@ body { .header { background: #111; color: white; - overflow: hidden; margin-bottom: 30px; } @@ -71,6 +70,10 @@ body { color: #fff; } +.top-bar { + height: auto; +} + .panel { color: #333; background: #FFFFFF; @@ -164,7 +167,7 @@ span.panel-res { color: #FBE500; } -.alert-box.warning { +.alert-box.warning, .alert-box.error { background-color: #C0392A; border-color: #C0392A; color: #fff; @@ -174,6 +177,14 @@ span.panel-res { color:#C0392A; } +small.is-valid { + color: #04B404; +} + +small.has-error { + color: #f04124; +} + hr { margin: 2.25rem 0;} button.primary { background-color: #111; } @@ -203,4 +214,4 @@ button.secondary:hover { background-color: #FFDF00 !important;} .p20h {padding: 0 20px;} .m30v {margin: 30px 0;} .m30a {margin: 30px auto;} -.br100 {border-radius: 100%;} \ No newline at end of file +.br100 {border-radius: 100%;} diff --git a/index.html b/index.html index 91db24a0d..5c850d4e3 100644 --- a/index.html +++ b/index.html @@ -45,11 +45,14 @@
-
- {{$root.flashMessage.type}}: - {{$root.flashMessage.message}} - Dismiss +
+
+
+ {{$root.flashMessage.message}} + × +
+
@@ -68,7 +71,7 @@
-
+
@@ -296,21 +299,51 @@