Fixed conflicts with 'master'.
Merge branch 'master' into feature/wallet Conflicts: copay.js
This commit is contained in:
commit
6b33f0425a
15 changed files with 3618 additions and 304 deletions
|
|
@ -2,4 +2,7 @@
|
|||
|
||||
var config = {
|
||||
networkName: 'testnet',
|
||||
p2pApiKey: 'lwjd5qra8257b9',
|
||||
p2pDebug: 3,
|
||||
maxPeers: 5,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -32,9 +32,12 @@ angular.module('copay.header').controller('HeaderController',
|
|||
};
|
||||
|
||||
$scope.signout = function() {
|
||||
$rootScope.isLogged = false;
|
||||
Network.disconnect(function() {
|
||||
$location.path('signin');
|
||||
});
|
||||
};
|
||||
|
||||
$scope.clearFlashMessage = function() {
|
||||
$rootScope.flashMessage = {};
|
||||
};
|
||||
});
|
||||
|
|
|
|||
|
|
@ -2,26 +2,52 @@
|
|||
|
||||
angular.module('copay.signin').controller('SigninController',
|
||||
function($scope, $rootScope, $location, Network, Storage) {
|
||||
var peerData = Storage.get('peerData');
|
||||
|
||||
var peerData = Storage.get($rootScope.walletId, 'peerData');
|
||||
|
||||
$scope.loading = false;
|
||||
$rootScope.peerId = peerData ? peerData.peerId : null;
|
||||
|
||||
$scope.listWalletIds = function() {
|
||||
return Storage.getWalletIds();
|
||||
};
|
||||
|
||||
$scope.create = function() {
|
||||
$scope.loading = true;
|
||||
|
||||
Network.createWallet();
|
||||
Network.init(function() {
|
||||
$location.path('peer');
|
||||
$rootScope.$digest();
|
||||
});
|
||||
};
|
||||
|
||||
$scope.open = function(walletId) {
|
||||
$scope.loading = true;
|
||||
|
||||
if (Network.openWallet(walletId)) {
|
||||
Network.init(function() {
|
||||
$location.path('peer');
|
||||
$rootScope.$digest();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
$scope.join = function(cid) {
|
||||
$scope.loading = true;
|
||||
|
||||
if (cid) {
|
||||
Network.init(function() {
|
||||
Network.connect(cid, function() {
|
||||
$location.path('peer');
|
||||
Network.connect(cid,
|
||||
function() {
|
||||
$location.path('peer');
|
||||
$rootScope.$digest();
|
||||
}, function() {
|
||||
|
||||
console.log('[signin.js.46] SETTING MESSAGE'); //TODO
|
||||
$rootScope.flashMessage = { message: 'Connection refussed', type: 'error'};
|
||||
$location.path('home');
|
||||
$rootScope.$digest();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
|||
2958
js/copayBundle.js
Normal file
2958
js/copayBundle.js
Normal file
File diff suppressed because it is too large
Load diff
284
js/models/CopayPeer.js
Normal file
284
js/models/CopayPeer.js
Normal file
|
|
@ -0,0 +1,284 @@
|
|||
|
||||
var imports = require('soop').imports();
|
||||
var EventEmitter= imports.EventEmitter || require('events').EventEmitter;
|
||||
|
||||
/*
|
||||
* Emits
|
||||
* 'networkChange'
|
||||
* when network layout has change (new/lost peers, etc)
|
||||
*
|
||||
* 'data'
|
||||
* when an unknown data type arrives
|
||||
*
|
||||
* Provides
|
||||
* send(toPeerIds, {data}, cb?)
|
||||
*
|
||||
*/
|
||||
|
||||
function CopayPeer(opts) {
|
||||
opts = opts || {};
|
||||
this.peerId = opts.peerId;
|
||||
this.apiKey = opts.apiKey || 'lwjd5qra8257b9';
|
||||
this.debug = opts.debug || 3;
|
||||
this.maxPeers = opts.maxPeers || 5;
|
||||
this.connectedPeers = [];
|
||||
}
|
||||
|
||||
CopayPeer.parent=EventEmitter;
|
||||
|
||||
// Array helpers
|
||||
CopayPeer._arrayDiff = function(a, b) {
|
||||
var seen = [];
|
||||
var diff = [];
|
||||
|
||||
for (var i = 0; i < b.length; i++)
|
||||
seen[b[i]] = true;
|
||||
|
||||
for (var j = 0; j < a.length; j++)
|
||||
if (!seen[a[j]])
|
||||
diff.push(a[j]);
|
||||
|
||||
return diff;
|
||||
};
|
||||
|
||||
CopayPeer._inArray = function(el, array) {
|
||||
return array.indexOf(el) > -1;
|
||||
};
|
||||
|
||||
CopayPeer._arrayPushOnce = function(el, array) {
|
||||
var ret = false;
|
||||
if (!CopayPeer._inArray(el, array)) {
|
||||
array.push(el);
|
||||
ret = true;
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
|
||||
CopayPeer._arrayRemove = function(el, array) {
|
||||
var pos = array.indexOf(el);
|
||||
if (pos >= 0) array.splice(pos, 1);
|
||||
|
||||
return array;
|
||||
};
|
||||
|
||||
// DEBUG
|
||||
CopayPeer.prototype._showConnectedPeers = function() {
|
||||
console.log("### CONNECTED PEERS", this.connectedPeers);
|
||||
};
|
||||
|
||||
CopayPeer.prototype._onClose = function(peerId) {
|
||||
this.connectedPeers = CopayPeer._arrayRemove(peerId, this.connectedPeers);
|
||||
this._notify();
|
||||
};
|
||||
|
||||
CopayPeer.prototype._connectToPeers = function(peerIds) {
|
||||
var self = this;
|
||||
var ret = false;
|
||||
var arrayDiff1= CopayPeer._arrayDiff(peerIds, this.connectedPeers);
|
||||
var arrayDiff = CopayPeer._arrayDiff(arrayDiff1, [this.peerId]);
|
||||
arrayDiff.forEach(function(peerId) {
|
||||
console.log('### CONNECTING TO:', peerId);
|
||||
self.connectTo(peerId);
|
||||
ret = true;
|
||||
});
|
||||
return ret;
|
||||
};
|
||||
|
||||
CopayPeer.prototype._onData = function(data, isInbound) {
|
||||
var obj;
|
||||
try {
|
||||
obj = JSON.parse(data);
|
||||
} catch (e) {
|
||||
console.log('### ERROR ON DATA: "%s" ', data, isInbound, e);
|
||||
return;
|
||||
};
|
||||
console.log('### RECEIVED TYPE: %s FROM %s', obj.data.type, obj.sender);
|
||||
|
||||
switch(obj.data.type) {
|
||||
case 'peerList':
|
||||
this._connectToPeers(obj.data.peers);
|
||||
this._notify();
|
||||
break;
|
||||
case 'disconnect':
|
||||
this._onClose(obj.sender);
|
||||
break;
|
||||
default:
|
||||
this.emit('data', obj.sender, obj.data, isInbound);
|
||||
}
|
||||
};
|
||||
|
||||
CopayPeer.prototype._sendPeers = function(peerIds) {
|
||||
console.log('#### SENDING PEER LIST: ', this.connectedPeers, ' TO ', peerIds?peerIds: 'ALL');
|
||||
this.send(peerIds, {
|
||||
type: 'peerList',
|
||||
peers: this.connectedPeers,
|
||||
});
|
||||
};
|
||||
|
||||
CopayPeer.prototype._addPeer = function(peerId, isInbound) {
|
||||
|
||||
var hasChanged = CopayPeer._arrayPushOnce(peerId, this.connectedPeers);
|
||||
|
||||
|
||||
if (isInbound && hasChanged) {
|
||||
this._sendPeers(); //broadcast peer list
|
||||
}
|
||||
else {
|
||||
if (isInbound) {
|
||||
this._sendPeers(peerId);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
CopayPeer.prototype._setupConnectionHandlers = function(
|
||||
dataConn, isInbound, openCallback, closeCallback) {
|
||||
|
||||
var self=this;
|
||||
|
||||
dataConn.on('open', function() {
|
||||
if (!CopayPeer._inArray(dataConn.peer, self.connectedPeers)) {
|
||||
|
||||
console.log('### DATA CONNECTION READY TO: ADDING PEER: %s (inbound: %s)',
|
||||
dataConn.peer, isInbound);
|
||||
|
||||
self._addPeer(dataConn.peer, isInbound);
|
||||
self._notify( isInbound ? dataConn.peer : null);
|
||||
if (typeof openCallback === 'function') openCallback();
|
||||
}
|
||||
});
|
||||
|
||||
dataConn.on('data', function(data) {
|
||||
self._onData(data, isInbound);
|
||||
});
|
||||
|
||||
dataConn.on('error', function(e) {
|
||||
console.log('### DATA ERROR',e ); //TODO
|
||||
});
|
||||
|
||||
dataConn.on('close', function() {
|
||||
console.log('### CLOSE RECV FROM:', dataConn.peer); //TODO
|
||||
self._onClose(dataConn.peer);
|
||||
if (typeof closeCallback === 'function') closeCallback();
|
||||
});
|
||||
};
|
||||
|
||||
CopayPeer.prototype._notify = function(newPeer) {
|
||||
this._showConnectedPeers();
|
||||
this.emit('networkChange', newPeer);
|
||||
};
|
||||
|
||||
CopayPeer.prototype._setupPeerHandlers = function(openCallback) {
|
||||
var self=this;
|
||||
var p = this.peer;
|
||||
|
||||
|
||||
p.on('open', function(peerId) {
|
||||
console.log('### PEER OPEN. I AM:' + peerId);
|
||||
self.peerId = peerId;
|
||||
self.connectedPeers = [peerId];
|
||||
self._notify();
|
||||
return openCallback(peerId);
|
||||
});
|
||||
|
||||
p.on('error', function(err) {
|
||||
console.log('### PEER ERROR:', err);
|
||||
});
|
||||
|
||||
p.on('connection', function(dataConn) {
|
||||
|
||||
console.log('### NEW INBOUND CONNECTION %d/%d', self.connectedPeers.length, self.maxPeers);
|
||||
if (self.connectedPeers.length >= self.maxPeers) {
|
||||
console.log('### PEER REJECTED. PEER MAX LIMIT REACHED');
|
||||
dataConn.on('open', function() {
|
||||
console.log('### CLOSING CONN FROM:' + dataConn.peer);
|
||||
dataConn.close();
|
||||
});
|
||||
}
|
||||
else {
|
||||
self._setupConnectionHandlers(dataConn, true);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
CopayPeer.prototype.start = function(openCallback) {
|
||||
// Start PeerJS Peer
|
||||
this.peer = new Peer(this.peerId, {
|
||||
key: this.apiKey, // TODO: we need our own PeerServer KEY (http://peerjs.com/peerserver)
|
||||
debug: this.debug,
|
||||
});
|
||||
|
||||
this._setupPeerHandlers(openCallback);
|
||||
};
|
||||
|
||||
CopayPeer.prototype._sendToOne = function(peerId, data, cb) {
|
||||
if (peerId !== this.peerId) {
|
||||
var conns = this.peer.connections[peerId];
|
||||
|
||||
if (conns) {
|
||||
var str = JSON.stringify({
|
||||
sender: this.peerId,
|
||||
data: data
|
||||
});
|
||||
|
||||
for (var i = 0; i < conns.length; i++) {
|
||||
var conn = conns[i];
|
||||
conn.send(str);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (typeof cb === 'function') cb();
|
||||
};
|
||||
|
||||
CopayPeer.prototype.send = function(peerIds, data, cb) {
|
||||
var self=this;
|
||||
|
||||
if (!peerIds) {
|
||||
peerIds = this.connectedPeers;
|
||||
data.isBroadcast = 1;
|
||||
}
|
||||
console.log('[CopayPeer.js.216:SENDD:]',data); //TODO
|
||||
|
||||
if (Array.isArray(peerIds)) {
|
||||
var l = peerIds.length;
|
||||
var i = 0;
|
||||
peerIds.forEach(function(peerId) {
|
||||
self._sendToOne(peerId, data, function () {
|
||||
if (++i === l && typeof cb === 'function') cb();
|
||||
});
|
||||
});
|
||||
}
|
||||
else if (typeof peerIds === 'string')
|
||||
self._sendToOne(peerIds, data, cb);
|
||||
};
|
||||
|
||||
CopayPeer.prototype.connectTo = function(peerId, openCallback, closeCallback ) {
|
||||
var self = this;
|
||||
|
||||
console.log('### STARTING TO CONNECT TO:' + peerId );
|
||||
|
||||
var dataConn = this.peer.connect(peerId, {
|
||||
// label: 'wallet',
|
||||
serialization: 'none',
|
||||
reliable: true,
|
||||
metadata: { message: 'hi copayer!' }
|
||||
});
|
||||
|
||||
self._setupConnectionHandlers(dataConn, false, openCallback, closeCallback);
|
||||
};
|
||||
|
||||
CopayPeer.prototype.disconnect = function(peerId, cb) {
|
||||
var self = this;
|
||||
|
||||
this.send(null, { type: 'disconnect' }, function() {
|
||||
self.connectedPeers = [];
|
||||
self.peerId = null;
|
||||
if (self.peer) {
|
||||
self.peer.disconnect();
|
||||
self.peer.destroy();
|
||||
self.peer = null;
|
||||
}
|
||||
if (typeof cb === 'function') cb();
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = require('soop')(CopayPeer);
|
||||
8
js/models/Peer.js
Normal file
8
js/models/Peer.js
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
|
||||
|
||||
function Peer(id) {
|
||||
this.id = id;
|
||||
};
|
||||
|
||||
|
||||
module.exports = require('soop')(Peer);
|
||||
|
|
@ -59,22 +59,8 @@ PublicKeyRing.encrypt = function (passphrase, payload) {
|
|||
return payload;
|
||||
};
|
||||
|
||||
PublicKeyRing.read = function (id, passphrase) {
|
||||
var encPayload = storage.get(id);
|
||||
if (!encPayload)
|
||||
throw new Error('Could not find wallet data');
|
||||
var data;
|
||||
try {
|
||||
data = JSON.parse( PublicKeyRing.decrypt( passphrase, encPayload ));
|
||||
} catch (e) {
|
||||
throw new Error('error in storage: '+ e.toString());
|
||||
return;
|
||||
};
|
||||
|
||||
if (data.id !== id)
|
||||
throw new Error('Wrong id in data');
|
||||
|
||||
var config = { networkName: data.networkName };
|
||||
PublicKeyRing.fromObj = function (data) {
|
||||
var config = { networkName: data.networkName || 'livenet' };
|
||||
|
||||
var w = new PublicKeyRing(config);
|
||||
|
||||
|
|
@ -93,6 +79,25 @@ PublicKeyRing.read = function (id, passphrase) {
|
|||
return w;
|
||||
};
|
||||
|
||||
PublicKeyRing.read = function (id, passphrase) {
|
||||
var encPayload = storage.get(id);
|
||||
if (!encPayload)
|
||||
throw new Error('Could not find wallet data');
|
||||
var data;
|
||||
try {
|
||||
data = JSON.parse( PublicKeyRing.decrypt( passphrase, encPayload ));
|
||||
} catch (e) {
|
||||
throw new Error('error in storage: '+ e.toString());
|
||||
return;
|
||||
};
|
||||
|
||||
if (data.id !== id)
|
||||
throw new Error('Wrong id in data');
|
||||
|
||||
|
||||
return PublicKeyRing.fromObj(data);
|
||||
};
|
||||
|
||||
PublicKeyRing.prototype.toObj = function() {
|
||||
return {
|
||||
id: this.id,
|
||||
|
|
|
|||
|
|
@ -7,12 +7,20 @@ function Storage() {
|
|||
}
|
||||
|
||||
Storage.prototype.get = function(k) {
|
||||
return this.data[k];
|
||||
return JSON.parse(localStorage.getItem(k));
|
||||
};
|
||||
|
||||
Storage.prototype.set = function(k,v) {
|
||||
this.data[k]=v;
|
||||
localStorage.setItem(k, JSON.stringify(v));
|
||||
};
|
||||
|
||||
Storage.prototype.remove = function(k) {
|
||||
localStorage.removeItem(k);
|
||||
};
|
||||
|
||||
|
||||
Storage.prototype.clearAll = function() {
|
||||
localStorage.clear();
|
||||
};
|
||||
|
||||
module.exports = require('soop')(Storage);
|
||||
|
|
|
|||
|
|
@ -3,274 +3,176 @@
|
|||
angular.module('copay.network')
|
||||
.factory('Network', function($rootScope, Storage) {
|
||||
var peer;
|
||||
$rootScope.connectedPeers = [];
|
||||
$rootScope.peerId = null;
|
||||
|
||||
// Array helpers
|
||||
var _arrayDiff = function(a, b) {
|
||||
var seen = [];
|
||||
var diff = [];
|
||||
|
||||
for (var i = 0; i < b.length; i++)
|
||||
seen[b[i]] = true;
|
||||
|
||||
for (var i = 0; i < a.length; i++)
|
||||
if (!seen[a[i]])
|
||||
diff.push(a[i]);
|
||||
|
||||
return diff;
|
||||
var _refreshUx = function() {
|
||||
var cp = $rootScope.cp;
|
||||
console.log('*** UPDATING UX'); //TODO
|
||||
$rootScope.peerId = cp.peerId;
|
||||
$rootScope.connectedPeers = cp.connectedPeers;
|
||||
$rootScope.$digest();
|
||||
};
|
||||
|
||||
var _inArray = function(el, array) {
|
||||
return array.indexOf(el) > -1;
|
||||
};
|
||||
|
||||
var _arrayPushOnce = function(el, array) {
|
||||
if (!_inArray(el, array)) array.push(el);
|
||||
};
|
||||
|
||||
var _arrayRemove = function(el, array) {
|
||||
var pos = array.indexOf(el);
|
||||
if (pos >= 0) array.splice(pos, 1);
|
||||
|
||||
return array;
|
||||
};
|
||||
|
||||
// General helpers
|
||||
var _saveDataStorage = function() {
|
||||
Storage.save('peerData', {
|
||||
var _store = function() {
|
||||
Storage.set($rootScope.walletId, 'peerData', {
|
||||
peerId: $rootScope.peerId,
|
||||
connectedPeers: $rootScope.connectedPeers
|
||||
});
|
||||
};
|
||||
|
||||
var _sendToOne = function(pid, data, cb) {
|
||||
if (pid !== $rootScope.peerId) {
|
||||
var conns = peer.connections[pid];
|
||||
|
||||
if (conns) {
|
||||
var str = JSON.stringify({
|
||||
sender: $rootScope.peerId,
|
||||
data: data
|
||||
});
|
||||
|
||||
for (var i = 0; i < conns.length; i++) {
|
||||
var conn = conns[i];
|
||||
conn.send(str);
|
||||
}
|
||||
|
||||
if (typeof cb === 'function') cb();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var _onData = function(data, isOutbound) {
|
||||
var obj = JSON.parse(data);
|
||||
console.log('### RECEIVED TYPE: %s FROM %s', obj.data.type, obj.sender);
|
||||
switch(obj.data.type) {
|
||||
case 'peerList':
|
||||
if (_connectToPeers(obj.data.peers)) {
|
||||
//TODO Remove log
|
||||
console.log('### BROADCASTING PEER LIST');
|
||||
_send( $rootScope.connectedPeers, {
|
||||
type: 'peerList',
|
||||
peers: $rootScope.connectedPeers,
|
||||
isBroadcast: 1,
|
||||
});
|
||||
$rootScope.$digest();
|
||||
}
|
||||
else if (!isOutbound && !obj.data.isBroadcast) {
|
||||
// replying always to connecting peer
|
||||
console.log('### REPLYING PEERLIST TO:', obj.sender );
|
||||
_send( obj.sender, {
|
||||
type: 'peerList',
|
||||
peers: $rootScope.connectedPeers
|
||||
});
|
||||
}
|
||||
break;
|
||||
case 'disconnect':
|
||||
_onClose(obj.sender);
|
||||
break;
|
||||
case 'publicKeyRing':
|
||||
console.log('### RECEIVED PKR FROM:', obj.sender);
|
||||
|
||||
if ($rootScope.publicKeyRing.merge(obj.data.publicKeyRing, true)) {
|
||||
//TODO Remove log
|
||||
console.log('### BROADCASTING PRK');
|
||||
_send( $rootScope.connectedPeers, {
|
||||
type: 'publicKeyRing',
|
||||
publicKeyRing: $rootScope.publicKeyRing.toObj(),
|
||||
isBroadcast: 1,
|
||||
});
|
||||
$rootScope.$digest();
|
||||
}
|
||||
else if (!isOutbound && !obj.data.isBroadcast) {
|
||||
// replying always to connecting peer
|
||||
console.log('### REPLYING PRK TO:', obj.sender );
|
||||
_send( obj.sender, {
|
||||
type: 'publicKeyRing',
|
||||
publicKeyRing: $rootScope.publicKeyRing.toObj(),
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
//TODO Remove log
|
||||
console.log('*** PRK:', $rootScope.publicKeyRing.toObj());
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
var _onClose = function(pid) {
|
||||
$rootScope.connectedPeers = _arrayRemove(pid, $rootScope.connectedPeers);
|
||||
_saveDataStorage();
|
||||
|
||||
$rootScope.$digest();
|
||||
};
|
||||
|
||||
var _connectToPeers = function(peers) {
|
||||
var ret = false;
|
||||
var arrayDiff1= _arrayDiff(peers, $rootScope.connectedPeers);
|
||||
var arrayDiff = _arrayDiff(arrayDiff1, [$rootScope.peerId]);
|
||||
arrayDiff.forEach(function(pid) {
|
||||
console.log('### CONNECTING TO:',pid);
|
||||
ret = true;
|
||||
connect(pid);
|
||||
// set new inbound connections
|
||||
var _setNewPeer = function(newPeer) {
|
||||
var cp = $rootScope.cp;
|
||||
console.log('#### SENDING PKR 1111 ');
|
||||
cp.send(newPeer, {
|
||||
type: 'publicKeyRing',
|
||||
publicKeyRing: $rootScope.publicKeyRing.toObj(),
|
||||
});
|
||||
};
|
||||
|
||||
var _handleNetworkChange = function(newPeer) {
|
||||
var cp = $rootScope.cp;
|
||||
|
||||
if (newPeer)
|
||||
_setNewPeer(newPeer);
|
||||
|
||||
_store();
|
||||
_refreshUx();
|
||||
};
|
||||
|
||||
// TODO -> probably not in network.js
|
||||
var createWallet = function(walletId) {
|
||||
console.log('### CREATING WALLET. ID:' + walletId);
|
||||
|
||||
//TODO create a wallet and WalletId, not only pkr
|
||||
var pkr = new copay.PublicKeyRing({
|
||||
network: config.networkName,
|
||||
id: walletId,
|
||||
});
|
||||
pkr.addCopayer();
|
||||
console.log('\t### PublicKeyRing Initialized:');
|
||||
Storage.addWalletId(pkr.id);
|
||||
Storage.set(pkr.id, 'publicKeyRing', pkr.toObj());
|
||||
|
||||
$rootScope.walletId = pkr.id;
|
||||
$rootScope.publicKeyRing = pkr;
|
||||
};
|
||||
|
||||
var openWallet = function (walletId) {
|
||||
var ret = false;
|
||||
var pkr = Storage.get(walletId, 'publicKeyRing');
|
||||
|
||||
if (pkr) {
|
||||
console.log('### WALLET OPENED:', walletId, pkr);
|
||||
$rootScope.walletId = walletId;
|
||||
$rootScope.publicKeyRing = new copay.PublicKeyRing.fromObj(pkr);
|
||||
ret = true;
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
|
||||
var closeWallet = function() {
|
||||
console.log('### CLOSING WALLET');
|
||||
$rootScope.walletId = null;
|
||||
$rootScope.publicKeyRing = null;
|
||||
//TODO
|
||||
};
|
||||
|
||||
var _checkWallet = function(walletId) {
|
||||
console.log('[network.js.79:_checkWallet:]',walletId); //TODO
|
||||
|
||||
if ($rootScope.walletId && $rootScope.walletId !== walletId)
|
||||
closeWallet();
|
||||
|
||||
if ($rootScope.walletId)
|
||||
return;
|
||||
|
||||
if (!openWallet(walletId)) {
|
||||
createWallet(walletId);
|
||||
}
|
||||
};
|
||||
|
||||
var _handleData = function(senderId, data, isInbound) {
|
||||
var cp = $rootScope.cp;
|
||||
|
||||
switch(data.type) {
|
||||
case 'publicKeyRing':
|
||||
_checkWallet(data.publicKeyRing.id);
|
||||
var shouldSend = false;
|
||||
|
||||
var recipients, pkr = $rootScope.publicKeyRing;
|
||||
if (pkr.merge(data.publicKeyRing, true) && !data.isBroadcast) {
|
||||
console.log('### BROADCASTING PKR');
|
||||
recipients = null;
|
||||
shouldSend = true;
|
||||
}
|
||||
else if (isInbound && !data.isBroadcast) {
|
||||
// always replying to connecting peer
|
||||
console.log('### REPLYING PKR TO:', senderId);
|
||||
recipients = senderId;
|
||||
shouldSend = true;
|
||||
}
|
||||
|
||||
if (shouldSend) {
|
||||
console.log('### SENDING PKR TO:', recipients);
|
||||
cp.send( recipients, {
|
||||
type: 'publicKeyRing',
|
||||
publicKeyRing: $rootScope.publicKeyRing.toObj(),
|
||||
});
|
||||
}
|
||||
|
||||
_refreshUx();
|
||||
break;
|
||||
}
|
||||
};
|
||||
var _setupHandlers = function () {
|
||||
var cp = $rootScope.cp;
|
||||
cp.on('networkChange', _handleNetworkChange);
|
||||
cp.on('data', _handleData);
|
||||
};
|
||||
|
||||
// public methods
|
||||
var init = function(cb) {
|
||||
peer = new Peer($rootScope.peerId, {
|
||||
key: 'lwjd5qra8257b9', // TODO: we need our own PeerServer KEY (http://peerjs.com/peerserver)
|
||||
debug: 3
|
||||
});
|
||||
|
||||
var cp = $rootScope.cp = new copay.CopayPeer({
|
||||
apiKey: config.p2pApiKey,
|
||||
debug: config.p2pDebug,
|
||||
maxPeers: config.maxPeers, // TODO: This should be on wallet configuration
|
||||
});
|
||||
_setupHandlers();
|
||||
|
||||
$rootScope.publicKeyRing = new copay.PublicKeyRing({
|
||||
network: config.networkName,
|
||||
});
|
||||
$rootScope.publicKeyRing.addCopayer();
|
||||
console.log('### PublicKeyRing Initialized');
|
||||
|
||||
|
||||
peer.on('open', function(pid) {
|
||||
console.log('### PEER OPEN. I AM:' + pid);
|
||||
$rootScope.peerId = pid;
|
||||
_saveDataStorage();
|
||||
|
||||
cb();
|
||||
$rootScope.$digest();
|
||||
});
|
||||
|
||||
peer.on('connection', function(dataConn) {
|
||||
if (dataConn.label === 'wallet') {
|
||||
console.log('### NEW INBOUND CONNECTION'); //TODO
|
||||
dataConn.on('open', function() {
|
||||
if (!_inArray(dataConn.peer, $rootScope.connectedPeers)) {
|
||||
console.log('### INBOUND DATA CONNECTION READY TO:' + dataConn.peer); //TODO
|
||||
_arrayPushOnce(dataConn.peer, $rootScope.connectedPeers);
|
||||
_saveDataStorage();
|
||||
|
||||
$rootScope.$digest();
|
||||
}
|
||||
});
|
||||
|
||||
dataConn.on('data', _onData);
|
||||
dataConn.on('error', function(e) {
|
||||
console.log('### ## INBOUND DATA ERROR',e ); //TODO
|
||||
_onClose(dataConn.peer);
|
||||
});
|
||||
dataConn.on('close', function() {
|
||||
_onClose(dataConn.peer);
|
||||
});
|
||||
}
|
||||
// inicia session
|
||||
cp.start(function(peerId) {
|
||||
return cb();
|
||||
});
|
||||
};
|
||||
|
||||
var connect = function(pid, cb) {
|
||||
if (pid !== $rootScope.peerId) {
|
||||
var disconnect = function() {
|
||||
if ($rootScope.cp) {
|
||||
$rootScope.cp.disconnect();
|
||||
}
|
||||
Storage.remove('peerData');
|
||||
$rootScope.isLogged = false;
|
||||
_refreshUx();
|
||||
};
|
||||
|
||||
console.log('### STARTING CONNECT TO:' + pid );
|
||||
|
||||
var dataConn = peer.connect(pid, {
|
||||
label: 'wallet',
|
||||
serialization: 'none',
|
||||
reliable: true,
|
||||
metadata: { message: 'hi copayer!' }
|
||||
});
|
||||
|
||||
dataConn.on('open', function() {
|
||||
|
||||
console.log('### OUTBOUND DATA CONN READY TO:' + pid );
|
||||
_arrayPushOnce(pid, $rootScope.connectedPeers);
|
||||
_saveDataStorage();
|
||||
|
||||
console.log('#### SENDING PEER LIST: ' +$rootScope.connectedPeers);
|
||||
_send(pid, {
|
||||
type: 'peerList',
|
||||
peers: $rootScope.connectedPeers
|
||||
});
|
||||
|
||||
|
||||
console.log('#### SENDING PKR ');
|
||||
_send(dataConn.peer, {
|
||||
type: 'publicKeyRing',
|
||||
publicKeyRing: $rootScope.publicKeyRing.toObj(),
|
||||
});
|
||||
|
||||
if (typeof cb === 'function') cb();
|
||||
|
||||
$rootScope.$digest();
|
||||
});
|
||||
|
||||
dataConn.on('data', function(data) {
|
||||
_onData(data,true);
|
||||
});
|
||||
|
||||
dataConn.on('error', function(e) {
|
||||
console.log('### ## INBOUND DATA ERROR',e ); //TODO
|
||||
_onClose(dataConn.peer);
|
||||
});
|
||||
|
||||
dataConn.on('close', function() {
|
||||
_onClose(dataConn.peer);
|
||||
var connect = function(peerId, openCallback, failCallBack) {
|
||||
if ($rootScope.cp) {
|
||||
$rootScope.cp.connectTo(peerId, openCallback, function () {
|
||||
disconnect();
|
||||
failCallBack();
|
||||
});
|
||||
}
|
||||
else
|
||||
return failCallBack();
|
||||
};
|
||||
|
||||
var _send = function(pids, data, cb) {
|
||||
if (Array.isArray(pids))
|
||||
pids.forEach(function(pid) {
|
||||
_sendToOne(pid, data, cb);
|
||||
});
|
||||
else if (typeof pids === 'string')
|
||||
_sendToOne(pids, data, cb);
|
||||
};
|
||||
|
||||
var disconnect = function(cb) {
|
||||
Storage.remove('peerData');
|
||||
var conns = $rootScope.connectedPeers.length;
|
||||
var i = 1;
|
||||
_send($rootScope.connectedPeers, { type: 'disconnect' }, function() {
|
||||
i += 1;
|
||||
|
||||
if (i === conns) {
|
||||
|
||||
$rootScope.connectedPeers = [];
|
||||
$rootScope.peerId = null;
|
||||
peer.disconnect();
|
||||
peer.destroy();
|
||||
if (typeof cb === 'function') cb();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
init: init,
|
||||
connect: connect,
|
||||
send: _send,
|
||||
disconnect: disconnect
|
||||
disconnect: disconnect,
|
||||
createWallet: createWallet,
|
||||
openWallet: openWallet,
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -2,21 +2,63 @@
|
|||
|
||||
angular.module('copay.storage')
|
||||
.factory('Storage', function($rootScope) {
|
||||
|
||||
|
||||
var _key = function(walletId, key) {
|
||||
return walletId + '::' + key;
|
||||
};
|
||||
|
||||
var _pushKey = function(walletId, key) {
|
||||
var keys = localStorage.getItem(walletId);
|
||||
localStorage.setItem(walletId, (keys?keys+',':'') +key);
|
||||
};
|
||||
|
||||
return {
|
||||
get: function(key) {
|
||||
getGlobal: function( key) {
|
||||
return JSON.parse(localStorage.getItem(key));
|
||||
},
|
||||
|
||||
set: function(key, data) {
|
||||
setGlobal: function( key, data) {
|
||||
localStorage.setItem(key, JSON.stringify(data));
|
||||
},
|
||||
|
||||
remove: function(key) {
|
||||
localStorage.removeItem(key);
|
||||
get: function(walletId, key) {
|
||||
if (!walletId) return;
|
||||
return JSON.parse(localStorage.getItem(_key(walletId,key)));
|
||||
},
|
||||
set: function(walletId, key, data) {
|
||||
if (!walletId) return;
|
||||
var k = _key(walletId,key);
|
||||
localStorage.setItem(k, JSON.stringify(data));
|
||||
_pushKey(walletId, k);
|
||||
},
|
||||
remove: function(walletId, key) {
|
||||
localStorage.removeItem(_key(walletId,key));
|
||||
},
|
||||
clearAll: function(walletId){
|
||||
var keys = localStorage.getItem(walletId);
|
||||
keys.split(',').forEach(function(k){
|
||||
localStorage.removeItem(key);
|
||||
});
|
||||
},
|
||||
addWalletId: function(walletId) {
|
||||
var ids = localStorage.getItem('walletIds');
|
||||
localStorage.setItem('walletIds', (ids?ids+',':'') + walletId);
|
||||
},
|
||||
delWalletId: function(walletId) {
|
||||
var ids = localStorage.getItem('walletIds');
|
||||
if (ids) {
|
||||
var is = ids.split(',');
|
||||
var newIds = [];
|
||||
is.forEach(function(i) {
|
||||
if (i != walletId) {
|
||||
newIds.push(i);
|
||||
}
|
||||
});
|
||||
localStorage.setItem('walletIds', newIds.join(',') );
|
||||
}
|
||||
},
|
||||
getWalletIds: function() {
|
||||
var ids = localStorage.getItem('walletIds');
|
||||
return ids ? ids.split(',') : [];
|
||||
},
|
||||
|
||||
clearAll: function() {
|
||||
localStorage.clear();
|
||||
}
|
||||
};
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue