- You
-
- {{peer}}
+ You
+ {{peer}}
diff --git a/js/controllers/transactions.js b/js/controllers/transactions.js
index f97d8785a..fed674948 100644
--- a/js/controllers/transactions.js
+++ b/js/controllers/transactions.js
@@ -59,8 +59,8 @@ angular.module('copay.transactions').controller('TransactionsController',
$rootScope.$digest();
return;
}
- var p = w.getTxProposal(ntxid);
- if (p.txp.builder.isFullySigned()) {
+ var p = w.txProposals.getTxProposal(ntxid);
+ if (p.builder.isFullySigned()) {
$scope.send(ntxid);
_updateTxs();
$rootScope.$digest();
diff --git a/js/models/core/PrivateKey.js b/js/models/core/PrivateKey.js
index 0e2d87631..6fdc21a44 100644
--- a/js/models/core/PrivateKey.js
+++ b/js/models/core/PrivateKey.js
@@ -18,15 +18,23 @@ function PrivateKey(opts) {
this.privateKeyCache = opts.privateKeyCache || {};
};
-PrivateKey.prototype.getId = function(prefix) {
- var buf = this.bip.extendedPublicKey;
- if (prefix) {
- buf = Buffer.concat([prefix, buf]);
+PrivateKey.prototype.getId = function() {
+ if (!this.id) {
+ var path = PublicKeyRing.SIGNING_BRANCH;
+ var bip32 = this.bip.derive(path);
+ this.id= bip32.eckey.public.toString('hex');
}
- var hash = util.sha256(buf).toString('hex');
- return hash.substring(0, hash.length/2);
+ return this.id;
};
+PrivateKey.prototype.getSigningKey = function() {
+ if (!this.sid) {
+ var path = PublicKeyRing.SIGNING_BRANCH;
+ var bip32 = this.bip.derive(path);
+ this.sid= bip32.eckey.private.toString('hex');
+ }
+ return this.sid;
+};
PrivateKey.fromObj = function(obj) {
return new PrivateKey(obj);
diff --git a/js/models/core/PublicKeyRing.js b/js/models/core/PublicKeyRing.js
index a9a1327d5..6d757671f 100644
--- a/js/models/core/PublicKeyRing.js
+++ b/js/models/core/PublicKeyRing.js
@@ -44,9 +44,12 @@ function PublicKeyRing(opts) {
*/
PublicKeyRing.Branch = function (index, isChange) {
- return 'm/'+(isChange?1:0)+'/'+index;
+ // first 0 is for future use: could be copayerId.
+ return 'm/0/'+(isChange?1:0)+'/'+index;
};
+PublicKeyRing.SIGNING_BRANCH = 'm/100/0/0';
+
PublicKeyRing.fromObj = function (data) {
if (data instanceof PublicKeyRing) {
throw new Error('bad data format: Did you use .toObj()?');
@@ -77,17 +80,20 @@ 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]);
+PublicKeyRing.prototype.getCopayerId = function(i) {
+ this.copayerIds = this.copayerIds || [];
+
+ if (!this.copayerIds[i]) {
+ var path = PublicKeyRing.SIGNING_BRANCH;
+ var bip32 = this.copayersBIP32[i].derive(path);
+ this.copayerIds[i]= bip32.eckey.public.toString('hex');
}
- var hash = util.sha256(buf).toString('hex');
- return hash.substring(0, hash.length/2);
+
+ return this.copayerIds[i];
};
-PublicKeyRing.prototype.myCopayerId = function(i, prefix) {
- return this.getCopayerId(0,prefix);
+PublicKeyRing.prototype.myCopayerId = function(i) {
+ return this.getCopayerId(0);
};
PublicKeyRing.prototype.registeredCopayers = function () {
diff --git a/js/models/core/Wallet.js b/js/models/core/Wallet.js
index b90b71040..fdbfe36ee 100644
--- a/js/models/core/Wallet.js
+++ b/js/models/core/Wallet.js
@@ -122,10 +122,10 @@ Wallet.prototype._handleData = function(senderId, data, isInbound) {
}
};
-Wallet.prototype._handleNetworkChange = function(newPeerId) {
- if (newPeerId) {
- this.log('#### Setting new PEER:', newPeerId);
- this.sendWalletId(newPeerId);
+Wallet.prototype._handleNetworkChange = function(newCopayerId) {
+ if (newCopayerId) {
+ this.log('#### Setting new PEER:', newCopayerId);
+ this.sendWalletId(newCopayerId);
}
this.emit('refresh');
};
@@ -143,13 +143,13 @@ Wallet.prototype._optsToObj = function () {
};
-Wallet.prototype.getPeerId = function(index) {
+Wallet.prototype.getCopayerId = function(index) {
return this.publicKeyRing.getCopayerId(index || 0);
};
-Wallet.prototype.getMyPeerId = function() {
- return this.getPeerId(0);
+Wallet.prototype.getMyCopayerId = function() {
+ return this.getCopayerId(0);
};
Wallet.prototype.netStart = function() {
@@ -167,22 +167,25 @@ Wallet.prototype.netStart = function() {
self.emit('close');
});
- var myPeerId = self.getMyPeerId();
+ var myId = self.getMyCopayerId();
var startOpts = {
- peerId: myPeerId
+ copayerId: myId,
+ signingKeyHex: self.privateKey.getSigningKey(),
};
- net.start(function() {
+ net.start(startOpts, function() {
self.emit('created');
for (var i=0; i %s', peerId, copayerId); //TODO
+ this.copayerForPeer[peerId]=copayerId;
+ }
+};
+
+Network.prototype.setCopayerId = function(copayerId) {
if (this.started) {
throw new Error ('network already started: can not change peerId')
}
- this.peerId = peerId;
+ this.copayerId = copayerId;
+ this.copayerIdBuf = new Buffer(copayerId,'hex');
+ this.peerId = this.peerFromCopayer(this.copayerId);
+ this._addCopayerMap(this.peerId,copayerId);
};
-Network.prototype.start = function(openCallback, opts) {
+Network.prototype.setSigningKey = function(keyHex) {
+ if (this.started || this.signingKey) {
+ throw new Error ('network already started or key assigned: can not change key')
+ }
+ var k = new Key();
+ k.private = new Buffer(keyHex,'hex');
+ k.regenerateSync();
+ this.signingKey = k;
+};
+
+Network.prototype.peerFromCopayer = function(hex) {
+ return util.sha256(new Buffer(hex,'hex')).toString('hex');
+};
+
+Network.prototype.start = function(opts, openCallback) {
opts = opts || {};
- // Start PeerJS Peer
var self = this;
-
if (this.started) return openCallback();
-
opts.connectedPeers = opts.connectedPeers || [];
- this.peerId = this.peerId || opts.peerId;
+
+ if (!this.copayerId)
+ this.setCopayerId(opts.copayerId);
+ if (!this.signingKey)
+ this.setSigningKey(opts.signingKeyHex);
this.peer = new Peer(this.peerId, this.opts);
this._setupPeerHandlers(openCallback);
@@ -238,57 +323,77 @@ Network.prototype.start = function(openCallback, opts) {
this.connectTo(otherPeerId);
}
this.started = true;
-
-console.log('[WebRTC.js.237] started TRUE'); //TODO
};
-Network.prototype._sendToOne = function(peerId, data, cb) {
+
+Network.prototype._sign = function(payload, copayerId) {
+ var ret='';
+ var str = JSON.stringify(payload);
+ if (payload.type ==='hello') {
+ ret = (
+ util.sha512hmac(
+ new Buffer(str),
+ new Buffer(copayerId,'hex')
+ )).toString('hex');
+ }
+ else {
+ if (!this.signingKey)
+ throw new Error ('no key to sign messages :(');
+ ret = bitcore.Message.sign(
+ str,
+ this.signingKey
+ ).toString('hex');
+ }
+ return ret;
+};
+
+Network.prototype._sendToOne = function(copayerId, payload, cb) {
+ var peerId = this.peerFromCopayer(copayerId);
if (peerId !== this.peerId) {
var dataConn = this.connections[peerId];
if (dataConn) {
var str = JSON.stringify({
- sender: this.peerId,
- data: data
+ sig: this._sign(payload, copayerId),
+ payload: payload
});
dataConn.send(str);
}
else {
-console.log('[WebRTC.js.255] WARN: NO CONNECTION TO:', peerId); //TODO
+ console.log('[WebRTC.js.255] WARN: NO CONNECTION TO:', peerId); //TODO
}
}
if (typeof cb === 'function') cb();
};
-Network.prototype.send = function(peerIds, data, cb) {
+Network.prototype.send = function(copayerIds, payload, cb) {
var self=this;
- if (!peerIds) {
- peerIds = this.connectedPeers;
- data.isBroadcast = 1;
+ if (!copayerIds) {
+ copayerIds = this.connectedCopayers();
+ payload.isBroadcast = 1;
}
- if (Array.isArray(peerIds)) {
- var l = peerIds.length;
+ if (Array.isArray(copayerIds)) {
+ var l = copayerIds.length;
var i = 0;
- peerIds.forEach(function(peerId) {
-console.log('[WebRTC.js.258:peerId:]',peerId); //TODO
- self._sendToOne(peerId, data, function () {
+ copayerIds.forEach(function(copayerId) {
+ self._sendToOne(copayerId, payload, function () {
if (++i === l && typeof cb === 'function') cb();
});
});
}
- else if (typeof peerIds === 'string')
- self._sendToOne(peerIds, data, cb);
+ else if (typeof copayerIds === 'string')
+ self._sendToOne(copayerIds, payload, cb);
};
-Network.prototype.connectTo = function(peerId) {
+Network.prototype.connectTo = function(copayerId) {
var self = this;
+ var peerId = this.peerFromCopayer(copayerId);
+ this._addCopayerMap(peerId,copayerId);
- console.log('### STARTING CONNECTION TO:' + peerId );
-
+ console.log('### STARTING CONNECTION TO:', peerId, copayerId);
var dataConn = this.peer.connect(peerId, {
serialization: 'none',
reliable: true,
- metadata: { message: 'hi copayer!' }
});
self._setupConnectionHandlers(dataConn, false);
diff --git a/test/test.PrivateKey.js b/test/test.PrivateKey.js
index 9eafd5794..71ae071be 100644
--- a/test/test.PrivateKey.js
+++ b/test/test.PrivateKey.js
@@ -70,7 +70,7 @@ describe('PrivateKey model', function() {
it('should calculate .id', function () {
var w1 = new PrivateKey(config);
should.exist(w1.getId());
- w1.getId().length.should.equal(32);
+ w1.getId().length.should.equal(66);
});
it('fromObj toObj roundtrip', function () {
var w1 = new PrivateKey(config);
diff --git a/test/test.PublicKeyRing.js b/test/test.PublicKeyRing.js
index c3701cb8b..76c0ff169 100644
--- a/test/test.PublicKeyRing.js
+++ b/test/test.PublicKeyRing.js
@@ -228,7 +228,7 @@ describe('PublicKeyRing model', function() {
networkName: 'livenet',
});
wx.addCopayer();
- (function() { w.merge(wx, true);}).should.throw();
+ (function() { w.merge(wx);}).should.throw();
});
|