diff --git a/src/bip39.js b/src/bip39.js
index f12f5ec..f5cffeb 100644
--- a/src/bip39.js
+++ b/src/bip39.js
@@ -1,9 +1,9 @@
-var CryptoJS = require('crypto-js')
-var crypto = require('crypto')
+var CryptoJS = require('crypto-js');
+var crypto = require('crypto');
function BIP39(language) {
- language = language || 'en'
+ language = language || 'en';
this.wordlist = [
"abandon",
"ability",
@@ -2057,101 +2057,101 @@ function BIP39(language) {
}
BIP39.prototype.mnemonicToSeed = function(mnemonic, password) {
- var options = {iterations: 2048, hasher: CryptoJS.algo.SHA512, keySize: 512/32}
+ var options = {iterations: 2048, hasher: CryptoJS.algo.SHA512, keySize: 512/32};
return CryptoJS.PBKDF2(mnemonic, salt(password), options).toString(CryptoJS.enc.Hex)
-}
+};
BIP39.prototype.entropyToMnemonic = function(entropy) {
- var entropyBuffer = new Buffer(entropy, 'hex')
- var entropyBits = bytesToBinary([].slice.call(entropyBuffer))
- var checksum = checksumBits(entropyBuffer)
+ var entropyBuffer = new Buffer(entropy, 'hex');
+ var entropyBits = bytesToBinary([].slice.call(entropyBuffer));
+ var checksum = checksumBits(entropyBuffer);
- var bits = entropyBits + checksum
- var chunks = bits.match(/(.{1,11})/g)
+ var bits = entropyBits + checksum;
+ var chunks = bits.match(/(.{1,11})/g);
var words = chunks.map(function(binary) {
- var index = parseInt(binary, 2)
+ var index = parseInt(binary, 2);
return this.wordlist[index]
- }, this)
+ }, this);
return words.join(' ')
-}
+};
BIP39.prototype.mnemonicToHex = function (mnemonic) {
- var words = mnemonic.split(' ')
+ var words = mnemonic.split(' ');
- if (words.length % 3 !== 0) return false
+ if (words.length % 3 !== 0) return false;
- var wordlist = this.wordlist
+ var wordlist = this.wordlist;
var belongToList = words.every(function (word) {
return wordlist.indexOf(word) > -1
- })
+ });
- if (!belongToList) return false
+ if (!belongToList) return false;
// convert word indices to 11 bit binary strings
var bits = words.map(function (word) {
- var index = wordlist.indexOf(word)
+ var index = wordlist.indexOf(word);
return lpad(index.toString(2), '0', 11)
- }).join('')
+ }).join('');
// split the binary string into ENT/CS
- var dividerIndex = Math.floor(bits.length / 33) * 32
- var entropy = bits.slice(0, dividerIndex)
- var checksum = bits.slice(dividerIndex)
+ var dividerIndex = Math.floor(bits.length / 33) * 32;
+ var entropy = bits.slice(0, dividerIndex);
+ var checksum = bits.slice(dividerIndex);
// calculate the checksum and compare
var entropyBytes = entropy.match(/(.{1,8})/g).map(function (bin) {
return parseInt(bin, 2)
- })
- var entropyBuffer = new Buffer(entropyBytes)
+ });
+ var entropyBuffer = new Buffer(entropyBytes);
return entropyBuffer.toString('hex');
-}
+};
BIP39.prototype.validate = function(mnemonic) {
- var words = mnemonic.split(' ')
+ var words = mnemonic.split(' ');
- if (words.length % 3 !== 0) return false
+ if (words.length % 3 !== 0) return false;
- var wordlist = this.wordlist
+ var wordlist = this.wordlist;
var belongToList = words.every(function(word) {
return wordlist.indexOf(word) > -1
- })
+ });
- if (!belongToList) return false
+ if (!belongToList) return false;
// convert word indices to 11 bit binary strings
var bits = words.map(function(word) {
- var index = wordlist.indexOf(word)
+ var index = wordlist.indexOf(word);
return lpad(index.toString(2), '0', 11)
- }).join('')
+ }).join('');
// split the binary string into ENT/CS
- var dividerIndex = Math.floor(bits.length / 33) * 32
- var entropy = bits.slice(0, dividerIndex)
- var checksum = bits.slice(dividerIndex)
+ var dividerIndex = Math.floor(bits.length / 33) * 32;
+ var entropy = bits.slice(0, dividerIndex);
+ var checksum = bits.slice(dividerIndex);
// calculate the checksum and compare
var entropyBytes = entropy.match(/(.{1,8})/g).map(function(bin) {
return parseInt(bin, 2)
- })
- var entropyBuffer = new Buffer(entropyBytes)
- var newChecksum = checksumBits(entropyBuffer)
+ });
+ var entropyBuffer = new Buffer(entropyBytes);
+ var newChecksum = checksumBits(entropyBuffer);
return newChecksum === checksum
-}
+};
function checksumBits(entropyBuffer) {
- var hash = crypto.createHash('sha256').update(entropyBuffer).digest()
+ var hash = crypto.createHash('sha256').update(entropyBuffer).digest();
// Calculated constants from BIP39
- var ENT = entropyBuffer.length * 8
- var CS = ENT / 32
+ var ENT = entropyBuffer.length * 8;
+ var CS = ENT / 32;
return bytesToBinary([].slice.call(hash)).slice(0, CS)
}
@@ -2177,4 +2177,4 @@ function lpad(str, padString, length) {
return str;
}
-module.exports = BIP39
+module.exports = BIP39;
diff --git a/src/common.js b/src/common.js
index 3636450..019efa7 100644
--- a/src/common.js
+++ b/src/common.js
@@ -5,7 +5,7 @@ var assert = function(condition, message) {
if (!condition) {
throw message || "Assertion failed";
}
-}
+};
//Checks if GUID is valid. Only takes lowercase, non-bracketed GUIDs.
var isRealGuid = function(potentialGuidAsString){
@@ -13,10 +13,10 @@ var isRealGuid = function(potentialGuidAsString){
if (typeof potentialGuidAsString != 'string') return false;
if (potentialGuidAsString.length==0) return false;
- var guidRegex=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/
+ var guidRegex=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/;
var match = potentialGuidAsString.match(guidRegex);
return match ? true:false;
-}
+};
var encrypt = function (valueToEncrypt, passphrase) {
assert(valueToEncrypt, "valueToEncrypt invalid");
diff --git a/src/config.js b/src/config.js
index cea8c41..570a3b6 100644
--- a/src/config.js
+++ b/src/config.js
@@ -11,7 +11,7 @@ var config = {
port:"1111",
basePath:""
}
-}
+};
config.thisServer.baseUrl=config.thisServer.protocol+'://'+
config.thisServer.hostname+':'+config.thisServer.port+
diff --git a/src/index-mobile.js b/src/index-mobile.js
index 4cddf3b..a73a4ed 100644
--- a/src/index-mobile.js
+++ b/src/index-mobile.js
@@ -3,4 +3,4 @@ module.exports = {
API: require('./ninki-api'),
Engine: require('./ninki-engine'),
UI: require('./ninki-ui-mobile')
-}
+};
diff --git a/src/index.js b/src/index.js
index b8532ed..df00506 100644
--- a/src/index.js
+++ b/src/index.js
@@ -3,4 +3,4 @@ module.exports = {
API: require('./ninki-api'),
Engine: require('./ninki-engine'),
UI: require('./ninki-ui')
-}
+};
diff --git a/src/ninki-api.js b/src/ninki-api.js
index e0966cf..734ef9d 100644
--- a/src/ninki-api.js
+++ b/src/ninki-api.js
@@ -1,30 +1,29 @@
-var jQuery = require('jquery-browserify');
-var $ = require('jquery-browserify');
var sanitizer = require('sanitizer');
var common = require('./common');
var config = require('./config');
+var localStorage = require('browser-storage');
+var crypto = require('crypto');
+
+
function API() {
}
-//Implementing the GET and POST JQuery functions in a Node style.
+var apiToken = "";
-var CSRF_HEADER = 'X-CSRF-Token';
+API.registerToken = function registerToken(token) {
-var setCSRFToken = function (securityToken) {
- jQuery.ajaxPrefilter(function (options, _, xhr) {
- if (!xhr.crossDomain)
- xhr.setRequestHeader(CSRF_HEADER, securityToken);
- });
-};
+ apiToken = token;
+
+}
-//setCSRFToken($('meta[name="token"]').attr('content'));
API.get = function (url, querydata, callback) {
return this.get(url, querydata, callback);
-}
+};
+
function get(url, querydata, callback) {
@@ -40,21 +39,118 @@ function get(url, querydata, callback) {
});
}
+
API.post = function (url, postData, callback) {
return lpost(url, postData, callback);
-}
+};
function lpost(url, postData, callback) {
- var sessionToken = $('#API-Token').val();
- //
+ if (typeof window === 'undefined') { // Running in NodeJS
+
+ var tunnel = require('tunnel');
+ var querystring = require('querystring');
+
+ var tunnelingAgent = tunnel.httpsOverHttp({
+ proxy: {
+ host: '',
+ port: ''
+ }
+ });
+
+
+ }
+
+ if (typeof window === 'undefined') {
+
+ //call node
+ var data = querystring.stringify(postData);
+
+ var https = require('https');
+
+ var options = {
+ host: 'testnet.ninkip2p.com',
+ port: 443,
+ //agent: tunnelingAgent,
+ path: url,
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/x-www-form-urlencoded',
+ 'Content-Length': Buffer.byteLength(data),
+ 'api-token': apiToken
+ }
+ };
+
+ var req = https.request(options, function (res) {
+
+ var body = '';
+
+
+ res.on('data', function (chunk) {
+
+ body += chunk;
+
+ });
+
+ res.on('end', function () {
+
+ body = sanitizer.sanitize(body);
+
+ //console.log(body)
+ try {
+ body = JSON.parse(body);
+ body = JSON.parse(body);
+ } catch (err) {
+ console.log(err)
+ }
+
+ if ((typeof body === "string")) {
+ return callback(true, body);
+ }
+
+
+ if (body.error) {
+ return callback(true, body.message);
+ }
+ if (!(typeof body.message === "undefined")) {
+ return callback(false, body.message);
+ }
+
+ return callback(false, JSON.stringify(body));
+
+
+ });
+
+ req.on('error', function (e) {
+
+ console.log('problem with request: ' + e.message);
+
+ });
+
+ });
+
+ req.write(data);
+
+ req.end();
+
+
+
+ } else {
+
+
+
+ //https://10.0.1.42:1111
+
+ //https://testnet.ninkip2p.com:443
+
$.ajax({
url: "https://api.ninkip2p.com:443" + url,
type: "POST",
+ timeout: 10000,
data: JSON.stringify(postData),
contentType: "application/json; charset=utf-8",
dataType: "json",
- headers: { 'api-token': sessionToken },
+ headers: { 'api-token': apiToken },
success: function (data) {
data = sanitizer.sanitize(data);
@@ -65,8 +161,11 @@ function lpost(url, postData, callback) {
return callback(true, jdata.message);
}
if (!(typeof jdata.message === "undefined")) {
+
return callback(false, jdata.message);
+
}
+
return callback(false, JSON.stringify(jdata));
},
fail: function (data, textStatus) {
@@ -81,6 +180,12 @@ function lpost(url, postData, callback) {
},
error: function (data) {
+ if (data.statusText == "timeout") {
+
+ return callback(true, "Could not connect.");
+
+ }
+
if (data.status == 403) {
//session has been lost
@@ -117,6 +222,8 @@ function lpost(url, postData, callback) {
}
});
+
+ }
}
@@ -130,7 +237,7 @@ API.emailGUID = function (userName, callback) {
});
-}
+};
@@ -159,7 +266,7 @@ API.getMasterPublicKeyFromUpstreamServer = function (guid, callback) {
}
}
});
-}
+};
//function doesUsernameExist
//verifies that the requested username does not already exist on our database
@@ -174,7 +281,7 @@ API.doesAccountExist = function (username, email, callback) {
return callback(null, JSON.parse(response));
}
});
-}
+};
API.sendWelcomeDetails = function (guid, sharedid, callback) {
@@ -184,7 +291,7 @@ API.sendWelcomeDetails = function (guid, sharedid, callback) {
lpost("/api/1/sendwelcomedetails", postData, function (err, response) {
return callback(err, response);
});
-}
+};
API.getEmailValidation = function (guid, sharedid, token, callback) {
@@ -200,7 +307,7 @@ API.getEmailValidation = function (guid, sharedid, token, callback) {
});
-}
+};
API.getResetToken = function (guid, callback) {
@@ -211,7 +318,7 @@ API.getResetToken = function (guid, callback) {
callback(err, response);
});
-}
+};
API.validateSecret = function (guid, secret, callback) {
@@ -226,7 +333,7 @@ API.validateSecret = function (guid, secret, callback) {
return callback(err, data);
}
});
-}
+};
API.updateSecretPacket = function (guid, sharedid, vc, iv, callback) {
@@ -234,7 +341,7 @@ API.updateSecretPacket = function (guid, sharedid, vc, iv, callback) {
return lpost("/api/1/u/updatesecretpacket", postData, function (err, dataStr) {
return callback(err, dataStr);
});
-}
+};
API.unlockaccount = function (guid, token, callback) {
@@ -242,7 +349,7 @@ API.unlockaccount = function (guid, token, callback) {
return lpost("/api/1/u/unlockaccount", postData, function (err, dataStr) {
return callback(err, dataStr);
});
-}
+};
API.getWalletFromServer = function (guid, secret, twoFactorCode, rememberTwoFactor, callback) {
@@ -254,20 +361,13 @@ API.getWalletFromServer = function (guid, secret, twoFactorCode, rememberTwoFact
return callback(err, dataStr);
} else {
var data = JSON.parse(dataStr);
- var currentToken = $("#API-Token").val();
- //if (currentToken.length == 0) {
- if (data.SessionToken) {
- $("#API-Token").val(data.SessionToken);
- } else {
- $("#API-Token").val('');
- }
- //}
+ apiToken = data.SessionToken;
return callback(err, data);
}
});
-}
+};
//function getBalance gets the summary balance for all the account's outputs
@@ -281,7 +381,7 @@ API.getBalance = function (guid, sharedid, callback) {
return callback(err, data);
}
});
-}
+};
//function getBalance gets the summary balance for all the account's outputs
@@ -296,14 +396,14 @@ API.getusernetworkcategory = function (callback) {
return callback(err, data);
}
});
-}
+};
API.updateusernetworkcategory = function (guid, sharedid, username, category, callback) {
var postData = { guid: guid, sharedid: sharedid, username: username, category: category };
return lpost("/api/1/updateusernetworkcategory", postData, function (err, dataStr) {
return callback(err, dataStr);
});
-}
+};
@@ -314,7 +414,7 @@ API.getUnconfirmedBalance = function (guid, sharedid, callback) {
return lpost("/api/1/u/getunconfirmedbalance", postData, function (err, dataStr) {
return callback(err, dataStr);
});
-}
+};
//function for increased performance on login
API.getAccountData = function (guid, sharedid, callback) {
@@ -322,14 +422,14 @@ API.getAccountData = function (guid, sharedid, callback) {
return lpost("/api/1/u/getaccountdata", postData, function (err, dataStr) {
return callback(err, dataStr);
});
-}
+};
API.getUserData = function (guid, sharedid, callback) {
var postData = { guid: guid, sharedid: sharedid };
return lpost("/api/1/u/getuserdata", postData, function (err, dataStr) {
return callback(err, dataStr);
});
-}
+};
//gets the username associated with the wallet
@@ -338,21 +438,21 @@ API.getNickname = function (guid, sharedid, callback) {
return lpost("/api/1/u/getnickname", postData, function (err, dataStr) {
return callback(err, dataStr);
});
-}
+};
API.getUserProfile = function (guid, sharedid, callback) {
var postData = { guid: guid, sharedid: sharedid };
return lpost("/api/1/u/getuserprofile", postData, function (err, dataStr) {
return callback(err, dataStr);
});
-}
+};
API.updateUserProfile = function (guid, sharedid, profileImage, status, tax, callback) {
var postData = { guid: guid, sharedid: sharedid, profileImage: profileImage, status: status, tax: tax };
return lpost("/api/1/u/updateuserprofile", postData, function (err, dataStr) {
return callback(err, dataStr);
});
-}
+};
//function returns all outputs unspent by the wallet
@@ -367,7 +467,7 @@ API.getUnspentOutputs = function (guid, sharedid, callback) {
return callback(err, response);
}
});
-}
+};
//function returns all outputs unspent by the wallet
API.getCoinProfile = function (guid, sharedid, callback) {
@@ -381,7 +481,7 @@ API.getCoinProfile = function (guid, sharedid, callback) {
return callback(err, response);
}
});
-}
+};
API.getPrice = function (guid, ccy, callback) {
@@ -394,7 +494,7 @@ API.getPrice = function (guid, ccy, callback) {
return callback(err, response);
}
});
-}
+};
API.getPendingUserRequests = function (guid, sharedid, callback) {
@@ -408,7 +508,7 @@ API.getPendingUserRequests = function (guid, sharedid, callback) {
return callback(err, data);
}
});
-}
+};
API.getFriendRequests = function (guid, sharedid, callback) {
@@ -421,7 +521,7 @@ API.getFriendRequests = function (guid, sharedid, callback) {
return callback(err, dataStr);
}
});
-}
+};
API.getUserPacket = function (guid, sharedid, callback) {
@@ -434,7 +534,7 @@ API.getUserPacket = function (guid, sharedid, callback) {
return callback(err, dataStr);
}
});
-}
+};
API.isNetworkExist = function (guid, sharedid, username, callback) {
var postData = { guid: guid, sharedid: sharedid, username: username };
@@ -447,14 +547,14 @@ API.isNetworkExist = function (guid, sharedid, username, callback) {
}
});
-}
+};
API.rejectFriendRequest = function (guid, sharedid, username, callback) {
var postData = { guid: guid, sharedid: sharedid, username: username };
lpost("/api/1/u/rejectfriend", postData, function (err, result) {
return callback(err, result);
});
-}
+};
API.getTransactionRecords = function (guid, sharedid, callback) {
@@ -471,7 +571,7 @@ API.getTransactionRecords = function (guid, sharedid, callback) {
});
-}
+};
API.getInvoiceList = function (guid, sharedid, callback) {
@@ -489,7 +589,7 @@ API.getInvoiceList = function (guid, sharedid, callback) {
});
-}
+};
API.getInvoiceByUserList = function (guid, sharedid, callback) {
@@ -506,7 +606,7 @@ API.getInvoiceByUserList = function (guid, sharedid, callback) {
});
-}
+};
@@ -515,42 +615,42 @@ API.updateInvoice = function (guid, sharedid, username, invoiceId, transactionId
return lpost("/api/1/u/updateinvoice", postData, function (err, dataStr) {
return callback(err, dataStr);
});
-}
+};
API.getVersion = function (callback) {
var postData = {};
return lpost("/api/1/u/getversion", postData, function (err, dataStr) {
return callback(err, dataStr);
});
-}
+};
API.registerDevice = function (guid, deviceName, deviceId, deviceModel, devicePIN, regToken, secret, callback) {
var postData = { guid: guid, deviceName: deviceName, deviceId: deviceId, deviceModel: deviceModel, devicePIN: devicePIN, regToken: regToken, secret: secret };
return lpost("/api/1/u/registerdevice", postData, function (err, dataStr) {
return callback(err, dataStr);
});
-}
+};
API.getDeviceKey = function (guid, devicePIN, regToken, callback) {
var postData = { guid: guid, devicePIN: devicePIN, regToken: regToken };
return lpost("/api/1/u/getdevicekey", postData, function (err, dataStr) {
return callback(err, dataStr);
});
-}
+};
API.destroyDevice = function (guid, regToken, callback) {
var postData = { guid: guid, regToken: regToken };
return lpost("/api/1/u/destroydevice", postData, function (err, dataStr) {
return callback(err, dataStr);
});
-}
+};
API.destroyDevice2fa = function (guid, sharedid, deviceName, twoFactorCode, callback) {
var postData = { guid: guid, sharedid: sharedid, deviceName: deviceName, twoFactorCode: twoFactorCode };
return lpost("/api/1/u/destroydevice2fa", postData, function (err, dataStr) {
return callback(err, dataStr);
});
-}
+};
@@ -559,7 +659,7 @@ API.createDevice = function (guid, sharedid, deviceName, callback) {
return lpost("/api/1/u/createdevice", postData, function (err, dataStr) {
return callback(err, dataStr);
});
-}
+};
API.getDevices = function (guid, sharedid, callback) {
@@ -572,14 +672,14 @@ API.getDevices = function (guid, sharedid, callback) {
return callback(err, dataStr);
}
});
-}
+};
API.getDeviceToken = function (guid, sharedid, deviceName, twoFactorCode, callback) {
var postData = { guid: guid, sharedid: sharedid, deviceName: deviceName, twoFactorCode: twoFactorCode };
return lpost("/api/1/u/getdevicetoken", postData, function (err, dataStr) {
return callback(err, dataStr);
});
-}
+};
@@ -588,6 +688,21 @@ API.getRecoveryPacket = function (guid, callback) {
return lpost("/api/1/getrecoverypacket", postData, function (err, dataStr) {
return callback(err, dataStr);
});
-}
+};
+
+API.getLimitStatus = function (guid, sharedid, callback) {
+ var postData = { guid: guid, sharedid: sharedid };
+ return lpost("/api/1/u/getlimitstatus", postData, function (err, dataStr) {
+ return callback(err, dataStr);
+ });
+};
+
+API.createBackupCodes = function (guid, sharedid, twoFactorCode, callback) {
+ var postData = { guid: guid, sharedid: sharedid, twoFactorCode: twoFactorCode };
+ return lpost("/api/1/u/createbackupcodes", postData, function (err, dataStr) {
+ return callback(err, dataStr);
+ });
+};
+
module.exports = API;
\ No newline at end of file
diff --git a/src/ninki-device.js b/src/ninki-device.js
new file mode 100644
index 0000000..d2e8411
--- /dev/null
+++ b/src/ninki-device.js
@@ -0,0 +1,159 @@
+var localStorage = require('browser-storage');
+
+function Device() {
+
+
+ this.isChromeApp = isChromeApp;
+ function isChromeApp() {
+
+
+ if (typeof window === 'undefined') {
+
+ return false;
+
+ }
+
+ if (isCordova()) {
+ return false;
+ }
+
+ var is_chrome = navigator.userAgent.toLowerCase().indexOf('chrome') > -1;
+ if (is_chrome) {
+ if (chrome) {
+ if (chrome.app) {
+ if (chrome.app.runtime) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ this.isNode = isNode;
+ function isNode() {
+
+ if (typeof window === 'undefined') {
+
+ return true;
+
+ } else {
+ return false;
+ }
+
+ }
+
+ this.isCordova = isCordova;
+ function isCordova() {
+
+ if (typeof window === 'undefined') {
+ return false;
+ } else {
+ if (typeof window.cordova === 'undefined') {
+ return false;
+ }
+ else {
+ return true;
+ }
+ }
+
+ }
+
+ this.isBrowser = isBrowser;
+ function isBrowser() {
+
+ if (typeof window === 'undefined') {
+
+ return false;
+
+ } else {
+
+ if (typeof window.cordova === 'undefined') {
+
+ return true;
+
+ } else {
+
+ return false;
+ }
+
+ }
+
+ }
+
+ this.getStorageItem = getStorageItem;
+ function getStorageItem(cname, callback) {
+
+
+ if (isChromeApp()) {
+
+ chrome.storage.local.get(cname, function (result) {
+
+ if (result[cname]) {
+ result = result[cname];
+ } else {
+ result = "";
+ }
+
+ return callback(result);
+
+ });
+
+ } else {
+
+ if (localStorage.getItem(cname)) {
+ return callback(localStorage.getItem(cname));
+ } else {
+ return callback('');
+ }
+
+ }
+
+ }
+
+ this.setStorageItem = setStorageItem;
+ function setStorageItem(cname, cvalue) {
+
+
+ if (isChromeApp()) {
+
+ var obj = {};
+ obj[cname] = cvalue;
+ chrome.storage.local.set(obj, function () {
+
+ console.log("saved");
+
+ });
+
+ }
+ else {
+
+ localStorage.setItem(cname, cvalue);
+
+ }
+
+
+ }
+
+ this.deleteStorageItem = deleteStorageItem;
+ function deleteStorageItem(cname) {
+
+
+ if (isChromeApp()) {
+
+ chrome.storage.local.remove(cname, function () {
+
+ console.log("deleted");
+
+ });
+
+ } else {
+
+ localStorage.removeItem(cname);
+
+ }
+ }
+
+}
+
+module.exports = Device;
diff --git a/src/ninki-engine.js b/src/ninki-engine.js
index e7cba68..3b850bb 100644
--- a/src/ninki-engine.js
+++ b/src/ninki-engine.js
@@ -4,14 +4,16 @@ var Bitcoin = require('bitcoinjs-lib');
var openpgp = require('openpgp');
var CryptoJS = require('crypto-js');
var API = require('./ninki-api');
+var device = require('./ninki-device');
var BIP39 = require('./bip39');
var uuid = require('node-uuid');
var sjcl = require('sjcl');
var sanitizer = require('sanitizer');
-
+var crypto = require('crypto');
function Engine() {
+ this.m_network = "mainnet";
this.m_walletinfo = {};
this.m_sharedid = '';
this.m_twoFactorOnLogin = false;
@@ -33,74 +35,31 @@ function Engine() {
this.m_appInitialised = false;
this.m_watchOnly = false;
- m_this = this;
-
-
- this.appHasLoaded = appHasLoaded;
- function appHasLoaded() {
- // m_this.m_password = '';
+ m_this = this;
- }
+ this.Device = new device();
- function isChromeApp() {
+ this.appHasInit = appHasInit;
+ function appHasInit() {
- if (window.cordova) {
+ if (m_this.m_sharedid.length > 0) {
+ return true;
+ } else {
return false;
}
- var is_chrome = navigator.userAgent.toLowerCase().indexOf('chrome') > -1;
- if (is_chrome) {
- if (chrome) {
- if (chrome.app) {
- if (chrome.app.runtime) {
- return true;
- }
- }
- }
- }
- return false;
}
- function isBrowser() {
+ this.appHasLoaded = appHasLoaded;
+ function appHasLoaded() {
- if (window.cordova) {
- return false;
- }
+ // m_this.m_password = '';
- return !isChromeApp();
}
- function getCookie(cname, callback) {
-
-
- if (isChromeApp()) {
-
- chrome.storage.local.get(cname, function (result) {
-
- if (result[cname]) {
- result = result[cname];
- } else {
- result = "";
- }
-
- return callback(result);
-
- });
-
- } else {
-
- if (localStorage[cname]) {
- return callback(localStorage[cname]);
- } else {
- return callback('');
- }
-
- }
-
- }
this.isRealGuid = isRealGuid;
//Checks if GUID is valid. Only takes lowercase, non-bracketed GUIDs.
@@ -110,7 +69,7 @@ function Engine() {
if (typeof potentialGuidAsString != 'string') return false;
if (potentialGuidAsString.length == 0) return false;
- var guidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/
+ var guidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/;
var match = potentialGuidAsString.match(guidRegex);
return match ? true : false;
}
@@ -130,6 +89,32 @@ function Engine() {
}
+ function getRandomValues(b) {
+
+ var rng = new Uint8Array(b);
+ if (typeof window === 'undefined') {
+
+ try {
+ var buf = crypto.randomBytes(256);
+
+ rng = new Uint8Array(buf);
+
+ } catch (ex) {
+ // handle error
+ // most likely, entropy sources are drained
+
+ console.log(ex);
+ }
+
+ } else {
+
+ window.crypto.getRandomValues(rng);
+ }
+
+ return rng;
+ }
+
+
this.encrypt = encrypt;
function encrypt(valueToEncrypt, passphrase) {
@@ -137,9 +122,9 @@ function Engine() {
var key = CryptoJS.enc.Hex.parse(passphrase);
- var iv = new Uint8Array(32);
+ var iv = getRandomValues(32);
+
var ivbytes = [];
- window.crypto.getRandomValues(iv);
for (var i = 0; i < iv.length; ++i) {
ivbytes[i] = iv[i];
}
@@ -159,9 +144,10 @@ function Engine() {
var key = CryptoJS.enc.Hex.parse(passphrase);
- var iv = new Uint8Array(32);
+ var iv = getRandomValues(32);
+
+
var ivbytes = [];
- window.crypto.getRandomValues(iv);
for (var i = 0; i < iv.length; ++i) {
ivbytes[i] = iv[i];
}
@@ -198,7 +184,6 @@ function Engine() {
return decrypthex;
};
-
var hmac = function (key) {
var hasher = new sjcl.misc.hmac(key, sjcl.hash.sha1);
this.encrypt = function () {
@@ -228,40 +213,32 @@ function Engine() {
this.getEncHotHash = getEncHotHash;
function getEncHotHash(callback) {
- var isWeb = isBrowser();
- if (isChromeApp()) {
+ m_this.Device.getStorageItem("hk" + m_this.m_guid, function (hk) {
- chrome.storage.local.get("hk" + m_this.m_guid, function (result) {
-
- if (result["hk" + m_this.m_guid]) {
+ if (hk) {
- var hk = result["hk" + m_this.m_guid];
+ m_this.Device.getStorageItem("hkiv" + m_this.m_guid, function (hkiv) {
- chrome.storage.local.get("hkiv" + m_this.m_guid, function (resultiv) {
+ if (hkiv) {
- if (resultiv["hkiv" + m_this.m_guid]) {
+ var data = "{\"enc\":\"" + hk + "\", \"iv\":\"" + hkiv + "\"}";
- var hkiv = resultiv["hkiv" + m_this.m_guid];
+ return callback(false, data);
- var data = "{\"enc\":\"" + hk + "\", \"iv\":\"" + hkiv + "\"}";
- return callback(false, data);
- } else {
- return callback(true, "ErrMissing");
- }
+ } else {
- });
+ return callback(true, "ErrMissing");
+ }
- } else {
- return callback(true, "ErrMissing");
- }
+ });
- });
+ } else {
- } else {
+ return callback(true, "ErrMissing");
- return callback(true, "ErrInvalid");
- }
+ }
+ });
}
@@ -271,12 +248,10 @@ function Engine() {
function restoreHotHash(hothash, callback) {
-
-
//validate against loaded hot public key
var validseed = true;
try {
- var bipHot = Bitcoin.HDWallet.fromSeedHex(hothash);
+ var bipHot = Bitcoin.HDWallet.fromSeedHex(hothash, m_this.m_network);
if (m_this.m_walletinfo.hotPub != bipHot.toString()) {
validseed = false;
}
@@ -304,186 +279,135 @@ function Engine() {
}
-
-
}
this.getHotHash = getHotHash;
function getHotHash(key, callback) {
- var isWeb = isBrowser();
//to do: validate key against stored public key
//needs to be done incase user changed their password on a different machine
- if (isChromeApp()) {
-
- chrome.storage.local.get("hk" + m_this.m_guid, function (result) {
-
- if (result["hk" + m_this.m_guid]) {
- var hk = result["hk" + m_this.m_guid];
-
- chrome.storage.local.get("hkiv" + m_this.m_guid, function (resultiv) {
-
- if (resultiv["hkiv" + m_this.m_guid]) {
- var hkiv = resultiv["hkiv" + m_this.m_guid];
- var hothash = '';
- var iserror = false;
- try {
- hothash = decryptNp(hk, m_this.m_password, hkiv);
- } catch (error) {
- iserror = true;
- }
- if (!iserror) {
-
- //validate against loaded hot public key
- var validseed = true;
- try {
- var bipHot = Bitcoin.HDWallet.fromSeedHex(hothash);
- if (m_this.m_walletinfo.hotPub != bipHot.toString()) {
- validseed = false;
- }
- } catch (error) {
+ if (m_this.Device.isChromeApp() || m_this.Device.isBrowser() || m_this.Device.isNode()) {
- validseed = false;
- }
+ m_this.Device.getStorageItem("hk" + m_this.m_guid, function (result) {
- if (validseed) {
+ var hk = result;
- return callback(false, hothash);
+ m_this.Device.getStorageItem("hkiv" + m_this.m_guid, function (resultiv) {
- } else {
+ var hkiv = resultiv
- return callback(true, "invalid");
+ var hothash = '';
- }
+ var iserror = false;
+ try {
+ hothash = decryptNp(hk, m_this.m_password, hkiv);
+ } catch (error) {
+ iserror = true;
+ }
- } else {
+ if (!iserror) {
- return callback(true, "missing");
+ //validate against loaded hot public key
+ var validseed = true;
+ try {
+ var bipHot = Bitcoin.HDWallet.fromSeedHex(hothash, m_this.m_network);
+ if (m_this.m_walletinfo.hotPub != bipHot.toString()) {
+ validseed = false;
}
+ } catch (error) {
- } else {
-
- return callback(true, "missing");
+ validseed = false;
}
- });
-
- } else {
- return callback(true, "missing");
- }
-
- });
-
- } else if (isWeb) {
+ if (validseed) {
- var hk = localStorage["hk" + m_this.m_guid];
- var hkiv = localStorage["hkiv" + m_this.m_guid];
+ return callback(false, hothash);
- var hothash = '';
- var iserror = false;
- try {
- hothash = decryptNp(hk, m_this.m_password, hkiv);
- } catch (error) {
- iserror = true;
- }
- if (!iserror) {
+ } else {
- //validate against loaded hot public key
- var validseed = true;
- try {
- var bipHot = Bitcoin.HDWallet.fromSeedHex(hothash);
- if (m_this.m_walletinfo.hotPub != bipHot.toString()) {
- validseed = false;
- }
- } catch (error) {
+ return callback(true, "invalid");
- validseed = false;
- }
+ }
- if (validseed) {
- return callback(false, hothash);
+ } else {
- } else {
+ return callback(true, "missing");
+ }
- return callback(true, "invalid");
+ });
- }
- } else {
- return callback(true, "missing");
- }
+ });
} else {
- //not using the chrome app so must be mobile
-
- //use html5 localstorage
+ m_this.Device.getStorageItem("ninki_h", function (hk) {
- // localStorage
- var hk = localStorage["ninki_h"];
+ if (hk) {
+ var hothash = '';
+ var iserror = false;
+ try {
- if (hk) {
-
- var hothash = '';
- var iserror = false;
- try {
+ var enc = JSON.parse(hk);
+ hothash = decryptNp(enc.ct, key, enc.iv);
- var enc = JSON.parse(hk);
- hothash = decryptNp(enc.ct, key, enc.iv);
+ } catch (error) {
+ iserror = true;
+ }
+ if (!iserror) {
- } catch (error) {
- iserror = true;
- }
- if (!iserror) {
+ //validate against loaded hot public key
+ var validseed = true;
+ try {
+ var bipHot = Bitcoin.HDWallet.fromSeedHex(hothash, m_this.m_network);
+ if (m_this.m_walletinfo.hotPub != bipHot.toString()) {
+ validseed = false;
+ }
+ } catch (error) {
- //validate against loaded hot public key
- var validseed = true;
- try {
- var bipHot = Bitcoin.HDWallet.fromSeedHex(hothash);
- if (m_this.m_walletinfo.hotPub != bipHot.toString()) {
validseed = false;
}
- } catch (error) {
- validseed = false;
- }
+ if (validseed) {
+
+ //get the two factor code also
- if (validseed) {
+ m_this.Device.getStorageItem("ninki_rem", function (tft) {
+ var jtft = JSON.parse(tft);
- //get the two factor code also
+ var fatoken = decryptNp(jtft.ct, key, jtft.iv);
- var tft = localStorage["ninki_rem"];
- var jtft = JSON.parse(tft);
+ return callback(false, hothash, fatoken);
- var fatoken = decryptNp(jtft.ct, key, jtft.iv);
+ });
+
+ } else {
- return callback(false, hothash, fatoken);
+ return callback(true, "invalid");
- } else {
+ }
- return callback(true, "invalid");
+ } else {
+ return callback(true, "missing");
}
} else {
return callback(true, "missing");
- }
-
- } else {
- return callback(true, "missing");
+ }
- }
+ });
}
@@ -492,45 +416,25 @@ function Engine() {
this.saveHotHash = saveHotHash;
function saveHotHash(hotHash, callback) {
-
//before we encrypt validate the hash matches the logged in public key
var validseed = true;
try {
- var bipHot = Bitcoin.HDWallet.fromSeedHex(hotHash);
+ var bipHot = Bitcoin.HDWallet.fromSeedHex(hotHash, m_this.m_network);
if (m_this.m_walletinfo.hotPub != bipHot.toString()) {
validseed = false;
}
} catch (error) {
-
validseed = false;
}
if (validseed) {
var encHotHash = encryptNp(hotHash, m_this.m_password);
- var objhk = {};
-
- if (isChromeApp()) {
- objhk['hk' + m_this.m_guid] = encHotHash.toString();
- chrome.storage.local.set(objhk, function () {
- //console.log("saved");
- var objhkiv = {};
- objhkiv['hkiv' + m_this.m_guid] = encHotHash.iv.toString();
- chrome.storage.local.set(objhkiv, function () {
- //console.log("saved");
- callback(false, "ok");
- });
- });
- } else {
-
-
- localStorage.setItem('hk' + m_this.m_guid, encHotHash.toString());
- localStorage.setItem('hkiv' + m_this.m_guid, encHotHash.iv.toString());
-
- callback(false, "ok");
- }
+ m_this.Device.setStorageItem('hk' + m_this.m_guid, encHotHash.toString());
+ m_this.Device.setStorageItem('hkiv' + m_this.m_guid, encHotHash.iv.toString());
+ callback(false, "ok");
} else {
@@ -554,11 +458,6 @@ function Engine() {
}
- // createprog
- // textMessageCreate
- // createprogstatus
-
-
//create wallet
//create a new wallet and save to the server
this.createWallet = createWallet;
@@ -589,7 +488,7 @@ function Engine() {
}
else {
- $('#textMessageCreate').text('stretching password...');
+ //$('#textMessageCreate').text('stretching password...');
setTimeout(function () {
@@ -623,7 +522,7 @@ function Engine() {
walletInformation.wallet.recPacketIV = recpacket.iv.toString();
//save the wallet to the server
- $('#textMessageCreate').text('saving data...');
+ //$('#textMessageCreate').text('saving data...');
setTimeout(function () {
@@ -662,7 +561,7 @@ function Engine() {
//rename this function
setTimeout(function () {
- $('#textMessageCreate').text('creating account...');
+ //$('#textMessageCreate').text('creating account...');
API.getMasterPublicKeyFromUpstreamServer(m_this.m_oguid, function (err, ninkiPubKey, userToken, secret) {
if (err) {
@@ -670,7 +569,7 @@ function Engine() {
} else {
makeNewWalletPacket(nickname, email, ninkiPubKey, userToken, secret, function (err, walletInformation) {
if (err) {
- return callback(err, response);
+ return callback(err, walletInformation);
} else {
return callback(err, walletInformation, userToken);
}
@@ -684,15 +583,14 @@ function Engine() {
function makeNewWalletPacket(nickname, emailAddress, ninkiPubKey, userToken, secret, callback) {
- var network = "mainnet";
+ //$('#textMessageCreate').text('getting entropy...');
+ setTimeout(function () {
- $('#textMessageCreate').text('getting entropy...');
- setTimeout(function () {
- //get some random data for the cold key
- var rngcold = new Uint8Array(32);
- window.crypto.getRandomValues(rngcold);
+ //what to do if running in node
+ // crypto provider module
+ var rngcold = getRandomValues(32);
var coldKeyBytes = [];
for (var i = 0; i < rngcold.length; ++i) {
@@ -700,8 +598,7 @@ function Engine() {
}
//get some random data for the hot key
- var rnghot = new Uint8Array(32);
- window.crypto.getRandomValues(rnghot);
+ var rnghot = getRandomValues(32);
var hotKeyBytes = [];
for (var i = 0; i < rnghot.length; ++i) {
@@ -714,7 +611,7 @@ function Engine() {
//var seedtest = bip39.mnemonicToSeed(hotmnem, '');
- $('#textMessageCreate').text('creating cold keys...');
+ //$('#textMessageCreate').text('creating cold keys...');
setTimeout(function () {
@@ -722,12 +619,12 @@ function Engine() {
//Cold key space
var coldHash = Bitcoin.Crypto.SHA256(Bitcoin.convert.bytesToWordArray(coldKeyBytes)).toString();
- var coldWallet = Bitcoin.HDWallet.fromSeedHex(coldHash);
+ var coldWallet = Bitcoin.HDWallet.fromSeedHex(coldHash, m_this.m_network);
//get the keys as strings
var coldPriv = coldWallet.toString(" ");
var coldPub = coldWallet.toString();
- $('#textMessageCreate').text('creating hot keys...');
+ //$('#textMessageCreate').text('creating hot keys...');
setTimeout(function () {
@@ -736,7 +633,7 @@ function Engine() {
//Hot key space
var hotHash = Bitcoin.Crypto.SHA256(Bitcoin.convert.bytesToWordArray(hotKeyBytes)).toString();
- var hotWallet = Bitcoin.HDWallet.fromSeedHex(hotHash);
+ var hotWallet = Bitcoin.HDWallet.fromSeedHex(hotHash, m_this.m_network);
//get the keys as strings
var hotPriv = hotWallet.toString(" ");
var hotPub = hotWallet.toString();
@@ -750,7 +647,7 @@ function Engine() {
var hcbkey = Bitcoin.convert.hexToBytes(hckey);
var hchkey = Bitcoin.Crypto.SHA256(Bitcoin.convert.bytesToWordArray(hcbkey)).toString();
- $('#textMessageCreate').text('creating pgp keys...');
+ //$('#textMessageCreate').text('creating pgp keys...');
setTimeout(function () {
@@ -767,7 +664,7 @@ function Engine() {
setTimeout(function () {
- $('#textMessageCreate').text('encrypting data...');
+ //$('#textMessageCreate').text('encrypting data...');
//save the wallet keys and user token in an encrypted packet
//AES256 using PBKDF2 on the password and a unique salt
@@ -844,7 +741,7 @@ function Engine() {
hotWalletPhrase: bip39.entropyToMnemonic(hotHash),
sharedid: userToken,
hckey: hchkey
- }
+ };
//console.log(coldHash, hotHash);
@@ -945,7 +842,13 @@ function Engine() {
var packet = encrypt(walletInformation, m_this.m_password);
//now save the packet back to the server
- var postData = { twoFactorCode: twoFactCode, guid: m_this.m_guid, sharedid: walletInformation.userToken, accountPacket: packet.toString(), IVA: packet.iv.toString() };
+ var postData = {
+ twoFactorCode: twoFactCode,
+ guid: m_this.m_guid,
+ sharedid: walletInformation.userToken,
+ accountPacket: packet.toString(),
+ IVA: packet.iv.toString()
+ };
API.post("/api/1/u/migratepacket", postData, function (err, dataStr) {
return callback(false, "ok");
@@ -1077,7 +980,6 @@ function Engine() {
});
-
}
@@ -1175,7 +1077,7 @@ function Engine() {
//walletInformation.hotHash = '';
//walletInformation.hchkey = '';
-
+ m_this.m_APIToken = wallet.SessionToken;
m_this.m_twoFactorOnLogin = wallet.TwoFactorOnLogin;
m_this.m_walletinfo = walletInformation;
m_this.m_sharedid = walletInformation.userToken;
@@ -1192,6 +1094,10 @@ function Engine() {
} else {
+ m_this.m_settings = {};
+ m_this.m_settings.BackupIndex = secvalid.BackupIndex;
+ m_this.m_settings.HasBackupCodes = secvalid.HasBackupCodes;
+
//is a migrated account with 2fa enabled
//return to get the user to enter the 2fa code
return callback(err, secvalid);
@@ -1365,7 +1271,6 @@ function Engine() {
}
-
function deriveChild(path, hdwallet) {
var e = path.split('/');
@@ -1394,8 +1299,6 @@ function Engine() {
}
-
-
//function aMultiSigHashForSigning
//TODO: rename
function aMultiSigHashForSigning3(publickey1, publickey2, publickey3, index, outputsToSpend, outputsToSend, addressToSend) {
@@ -1561,35 +1464,96 @@ function Engine() {
return addrValid;
}
- this.sendTransaction = sendTransaction;
- function sendTransaction(sendType, friendUserName, addressTo, amount, twoFactorCode, callback) {
+ var corNodesDone = 0;
+ var corNodesToProcess = 0;
+ function deriveKeys(mpk, nodes, cdcallback) {
- //setup handles to report back progress
- var progressel = '';
- var messel = '';
- var progresselnum = ''
+ if (m_this.Device.isCordova()) {
- if (sendType == 'friend') {
- messel = '#textMessageSend';
- progressel = '#sendfriendprogstatus';
- progresselnum = '#sendstdprognum';
- }
+ var mkpder = [];
+
+ corNodesToProcess = nodes.length;
+ cordovaDeriveKey(mpk, nodes, mkpder, function (result) {
+
+ console.log(mkpder);
+
+ return cdcallback(mkpder);
+
+ });
+ } else {
+
+ var ret = [];
+ for (var i = 0; i < nodes.length; i++) {
+ ret.push(deriveChild(nodes[i], mpk).priv);
+ }
+ return cdcallback(ret);
- if (sendType == 'standard') {
- messel = '#textMessageSendStd';
- progressel = '#sendstdprogstatus';
- progresselnum = '#sendstdprognum';
}
- if (sendType == 'invoice') {
- messel = '#textMessageSendInv';
- progressel = '#sendinvprogstatus';
- progresselnum = '#sendstdprognum';
+ }
+
+ function cordovaDeriveKey(mpk, nodes, mkpder, derfinished) {
+
+ console.log("entered cordoveDeriveKey...");
+ console.log(mkpder);
+
+ if (corNodesDone == corNodesToProcess) {
+
+ console.log("returning...");
+ return derfinished(mkpder)
+
+ } else {
+
+
+ var nls = nodes[corNodesDone].split("/");
+ var tnode = nls[2] * 1;
+ var leaf = nls[3] * 1;
+
+
+ console.log("calling exec...");
+
+ cordova.exec(
+ function callback(data) {
+
+
+ corNodesDone++;
+
+ console.log("pushing data...");
+
+ mkpder.push(data);
+
+ console.log(mkpder);
+
+ console.log("key added...");
+
+ cordovaDeriveKey(mpk, nodes, mkpder, derfinished);
+
+
+ },
+ function errorHandler(err) {
+ //alert('Error');
+ console.log("error");
+ },
+ 'ECPlugin',
+ 'cordovaECDerKey',
+ [mpk.toString(" "), tnode, leaf]
+ );
}
+
+ }
+
+
+ this.sendTransaction = sendTransaction;
+ function sendTransaction(sendType, friendUserName, addressTo, amount, twoFactorCode, callback, statuscallback) {
+
+ var debug = true;
+ var debugtime = 5;
+ corNodesDone = 0;
+ corNodesToProcess = 0;
var minersFee = 10000;
- //??
+
amount = Math.round(amount);
if (m_this.m_settings.MinersFee) {
@@ -1600,16 +1564,23 @@ function Engine() {
//in the case of mobile the twoFactorCode is actually the device key
//and will return a twofactor override code
+
+
getHotHash(twoFactorCode, function (err, hothash, twoFactorOverride) {
if (twoFactorOverride) {
twoFactorCode = twoFactorOverride;
}
+
+
+
//initialise the hot private key space
- var bipHot = Bitcoin.HDWallet.fromSeedHex(hothash);
+ var bipHot = Bitcoin.HDWallet.fromSeedHex(hothash, m_this.m_network);
+
+ //
+
- //initialise the 3 public keys
var bipHotPub = Bitcoin.HDWallet.fromBase58(m_this.m_walletinfo.hotPub);
var bipCold = Bitcoin.HDWallet.fromBase58(m_this.m_walletinfo.coldPub);
var bipNinki = Bitcoin.HDWallet.fromBase58(m_this.m_walletinfo.ninkiPubKey);
@@ -1617,15 +1588,19 @@ function Engine() {
var pdata = { guid: m_this.m_guid, sharedid: m_this.m_sharedid };
-
- $(messel).text('Getting unspent outputs...');
-
+ statuscallback('Preparing transaction...', '10%');
API.post("/api/1/u/getunspentoutputs", pdata, function (err, outputs) {
if (!err) {
+
+ if (debug) {
+ console.log('getunspentoutputs...success');
+ }
+
+
var outputs = JSON.parse(outputs);
var outputsToSpend = [];
var amountsToSend = [];
@@ -1634,14 +1609,18 @@ function Engine() {
var nodeLevels = [];
var publicKeys = [];
- var packet = { addressToSend: addressToSend, amountsToSend: amountsToSend, outputsToSpend: outputsToSpend, userHotPrivKeys: userHotPrivKeys, guid: m_this.m_guid, paths: nodeLevels, publicKeys: publicKeys };
+ var packet = {
+ addressToSend: addressToSend,
+ amountsToSend: amountsToSend,
+ outputsToSpend: outputsToSpend,
+ userHotPrivKeys: userHotPrivKeys,
+ guid: m_this.m_guid,
+ paths: nodeLevels,
+ publicKeys: publicKeys
+ };
//get outputs to spend, calculate change amount minus miners fee
- $(progressel).width('20%');
- if ($(progresselnum)) {
- $(progresselnum).text('20%');
- }
//iterate the unspent outputs and select the first n that equal the amount to spend
//TO DO: do this before doing any key derivation
@@ -1649,14 +1628,23 @@ function Engine() {
for (var i = 0; i < outputs.length; i++) {
var pitem = outputs[i];
- var pout = { transactionId: pitem.TransactionId, outputIndex: pitem.OutputIndex, amount: pitem.Amount, address: pitem.Address }
+ var pout = {
+ transactionId: pitem.TransactionId,
+ outputIndex: pitem.OutputIndex,
+ amount: pitem.Amount,
+ address: pitem.Address
+ };
nodeLevels.push(pitem.NodeLevel);
outputsToSpend.push(pout);
//derive the private key to use for signing
- userHotPrivKeys.push(deriveChild(pitem.NodeLevel, bipHot).priv);
+
+ if (debug) {
+ console.log('derive the private key to use for signing ' + i);
+ }
+
//derive the public keys to use for script generation
//this could be cached on the server as no privacy or hand-off issue that I can see
@@ -1665,14 +1653,23 @@ function Engine() {
var dbipColdPub = "";
var dbipNinkiPub = "";
+
if (pitem.PK1.length > 0) {
+ if (debug) {
+ console.log('using cached public key ' + i);
+ }
+
dbipHotPub = Bitcoin.convert.hexToBytes(pitem.PK1);
dbipColdPub = Bitcoin.convert.hexToBytes(pitem.PK2);
dbipNinkiPub = Bitcoin.convert.hexToBytes(pitem.PK3);
} else {
+ if (debug) {
+ console.log('no cache - deriving ' + i);
+ }
+
dbipHotPub = deriveChild(pitem.NodeLevel, bipHotPub).pub.toBytes();
dbipColdPub = deriveChild(pitem.NodeLevel, bipCold).pub.toBytes();
dbipNinkiPub = deriveChild(pitem.NodeLevel, bipNinki).pub.toBytes();
@@ -1690,6 +1687,11 @@ function Engine() {
}
+
+ console.log("resume now...");
+ //call to cordova plugin for private key derivation
+
+
amountsToSend.push(amount);
//now create the change
@@ -1707,274 +1709,370 @@ function Engine() {
amountsToSend.push(changeAmount);
}
- //create a new address for my change to be sent back to me
+ if (debug) {
+ console.log('change amount...' + changeAmount);
+ }
+
+ //create a new address for my change to be sent back to me
+ statuscallback('Preparing transaction...', '20%');
//if we are sending money to a contact or paying an invoice
//we need to derive addresses on their behalf
- if (sendType == 'friend' || sendType == 'invoice') {
- var params = { guid: m_this.m_guid, sharedid: m_this.m_sharedid, username: friendUserName, amount: amount };
+ console.log(nodeLevels);
- //generate the address for the contact
- //this must be done on the client
- $(messel).text('Creating address...');
- createAddressForFriend(friendUserName, function (err, address) {
- if (!err) {
+ deriveKeys(bipHot, nodeLevels, function (ret) {
- $(progressel).width('40%');
- if ($(progresselnum)) {
- $(progresselnum).text('40%');
- }
+ console.log("got here...");
+ console.log(ret);
- addressToSend.push(address);
+ if (m_this.Device.isCordova()) {
+ console.log("is cordova...");
+ for (var i = 0; i < ret.length; i++) {
+ console.log("new key...");
+ var nkey = new Bitcoin.ECKey(ret[i]);
+ console.log(nkey);
+ userHotPrivKeys.push(nkey);
+ console.log(userHotPrivKeys);
+ }
- //create the change address, this must be done on the client
- $(messel).text('Creating change address...');
+ } else {
- createAddress('m/0/1', changeAmount, function (err, changeaddress) {
+ packet.userHotPrivKeys = ret;
+ }
- if (!err) {
- $(progressel).width('60%');
- if ($(progresselnum)) {
- $(progresselnum).text('60%');
- }
+ console.log(userHotPrivKeys);
- if (changeAmount > 0) {
- addressToSend.push(changeaddress);
- }
- //now get the transaction data
- $(messel).text('Creating transaction...');
- aGetTransactionData(packet, function (err, hashesForSigning, rawTransaction) {
- $(progressel).width('80%');
- if ($(progresselnum)) {
- $(progresselnum).text('80%');
- }
+ if (sendType == 'friend' || sendType == 'invoice') {
+ var params = {
+ guid: m_this.m_guid,
+ sharedid: m_this.m_sharedid,
+ username: friendUserName,
+ amount: amount
+ };
+ //generate the address for the contact
+ //this must be done on the client
- var jsonSend = { guid: m_this.m_guid, hashesForSigning: hashesForSigning, rawTransaction: rawTransaction, pathsToSignWith: nodeLevels }
- var jsonp1 = { guid: m_this.m_guid, jsonPacket: JSON.stringify(jsonSend), sharedid: m_this.m_sharedid, twoFactorCode: twoFactorCode, userName: friendUserName };
- $(messel).text('Counter-signing transaction...');
+ console.log('Creating address...');
+ statuscallback('creating address...', '30%');
+ createAddressForFriend(friendUserName, function (err, address) {
- //send the transaction to the service for countersigning and broadcast to the network
+ if (!err) {
- //requires 2 factor authentication
+ //statuscallback(null, '40%');
- API.post("/api/1/u/sendtransaction", jsonp1, function (err, result) {
+ addressToSend.push(address);
- if (!err) {
- $(progressel).width('100%');
- if ($(progresselnum)) {
- $(progresselnum).text('100%');
- }
+ //create the change address, this must be done on the client
+ statuscallback('Creating change address...', '40%');
+ console.log("start create address..");
+ createAddress('m/0/1', changeAmount, function (err, changeaddress) {
- $(messel).text('Transaction broadcast...');
- //error handling?
+ if (!err) {
+ console.log("end create address...");
- //we have a transaction id so lets make a note of the transaction in the database
- var params = { guid: m_this.m_guid, sharedid: m_this.m_sharedid, username: friendUserName, transactionid: result, address: address, amount: amount };
- API.post("/api/1/u/createtransactionrecord", params, function (err, result) {
- return callback(err, params.transactionid);
- });
- } else {
- //handle error messages returned from the server
- if (result == 'ErrSingleTransactionLimit') {
- $(progressel).width('100%');
- $(messel).text('Transaction Failed: Single limit exceeded');
- return callback(err, result);
- }
+ if (changeAmount > 0) {
+ addressToSend.push(changeaddress);
+ }
- if (result == 'ErrDailyTransactionLimit') {
- $(progressel).width('100%');
- $(messel).text('Transaction Failed: Daily limit exceeded');
- return callback(err, result);
- }
+ //now get the transaction data
+ statuscallback('Building transaction...', '60%');
+ setTimeout(function () {
+ aGetTransactionData(packet, function (err, hashesForSigning, rawTransaction) {
- if (result == 'ErrTransactionsPerDayLimit') {
- $(progressel).width('100%');
- $(messel).text('Transaction Failed: Daily number limit exceeded');
- return callback(err, result);
- }
+ if (!err) {
- if (result == 'ErrTransactionsPerHourLimit') {
- $(progressel).width('100%');
- $(messel).text('Transaction Failed: Hourly number limit exceeded');
- return callback(err, result);
- }
+ statuscallback(null, '80%');
- if (result == 'ErrInvalidRequest') {
- $(progressel).width('100%');
- $(messel).text('Transaction Failed: Invalid request');
- return callback(err, result);
- }
+ var jsonSend = {
+ guid: m_this.m_guid,
+ hashesForSigning: hashesForSigning,
+ rawTransaction: rawTransaction,
+ pathsToSignWith: nodeLevels
+ };
+ var jsonp1 = {
+ guid: m_this.m_guid,
+ jsonPacket: JSON.stringify(jsonSend),
+ sharedid: m_this.m_sharedid,
+ twoFactorCode: twoFactorCode,
+ userName: friendUserName
+ };
- if (result == 'ErrLocked') {
- $(progressel).width('100%');
- $(messel).text('Transaction Failed: Account is unavailable');
- return callback(err, result);
- }
+ statuscallback('Counter-signing transaction...', '80%');
- if (result == 'ErrBroadcastFailed') {
- $(progressel).width('100%');
- $(messel).text('Transaction Failed: Not accepted');
- return callback(err, result);
- }
+ //send the transaction to the service for countersigning and broadcast to the network
+
+
+ //requires 2 factor authentication
+
+ API.post("/api/1/u/sendtransaction", jsonp1, function (err, result) {
+
+ if (!err) {
+
+
+ statuscallback('Transaction broadcast...', '100%');
+
+ return callback(err, result);
+
+
+ } else {
+
+ //handle error messages returned from the server
+ if (result == 'ErrSingleTransactionLimit') {
+
+ statuscallback('Transaction Failed: Single limit exceeded', '0%');
+
+ return callback(err, result);
+
+ }
+
+ if (result == 'ErrDailyTransactionLimit') {
+
+ statuscallback('Transaction Failed: Daily limit exceeded', '0%');
+
+ return callback(err, result);
+ }
+
+ if (result == 'ErrTransactionsPerDayLimit') {
+
+ statuscallback('Transaction Failed: Daily number limit exceeded', '0%');
+
+ return callback(err, result);
+ }
+
+ if (result == 'ErrTransactionsPerHourLimit') {
+
+ statuscallback('Transaction Failed: Hourly number limit exceeded', '0%');
+
+ return callback(err, result);
+ }
+
+ if (result == 'ErrInvalidRequest') {
+
+ statuscallback('Transaction Failed: Invalid request', '0%');
+
+ return callback(err, result);
+ }
+
+
+ if (result == 'ErrBroadcastFailed') {
+
+ statuscallback('Transaction Failed: Not accepted', '0%');
+
+ return callback(err, result);
+ }
+
+ if (result == "Invalid two factor code") {
+
+ statuscallback("Invalid two factor code", '0%');
+
+ return callback(err, result);
+ }
+
+ if (result == "ErrInsufficientFunds") {
+ statuscallback("Transaction Failed: Insufficient funds", '0%');
+
+ return callback(err, result);
+ }
+
+ if (result == "ErrLocked") {
+
+ statuscallback("Contact account is unavailable", '0%');
+
+ return callback(err, result);
+ }
+
+ statuscallback('Transaction Failed:' + result, '0%');
+
+ return callback(err, result);
+
+ }
+ });
- if (result == "Invalid two factor code") {
- $(progressel).width('100%');
- $(messel).text("Invalid two factor code");
- return callback(err, result);
}
- }
- });
- });
- } else {
- //create address error
- if (changeaddress == 'ErrInvalidRequest') {
- $(progressel).width('100%');
- $(messel).text('Transaction Failed: Invalid request');
+
+ });
+ }, debugtime);
+ } else {
+ //create address error
+
+ statuscallback(changeaddress, '0%');
return callback(err, changeaddress);
+
}
- }
- });
- } else {
+ });
+ } else {
+
- if (address == 'ErrInvalidRequest') {
- $(progressel).width('100%');
- $(messel).text('Transaction Failed: Invalid request');
+ statuscallback(address, '0%');
return callback(err, address);
+
+
}
+ });
+ } else {
+
+ statuscallback('Creating change address...', '20%');
+ addressToSend.push(addressTo);
+
+ if (debug) {
+ console.log("start creating change address");
}
- });
- } else {
+ //create the change address, this must be done on the client
+ createAddress('m/0/1', changeAmount, function (err, changeaddress) {
+ if (!err) {
- $(messel).text('Creating address...');
+ if (debug) {
+ console.log("finished creating change address");
+ }
- addressToSend.push(addressTo);
- //create the change address, this must be done on the client
- createAddress('m/0/1', changeAmount, function (err, changeaddress) {
+ if (changeAmount > 0) {
+ addressToSend.push(changeaddress);
+ }
- if (!err) {
+ //now get the transaction
- $(progressel).width('40%');
+ statuscallback('Creating transaction...', '40%');
+ setTimeout(function () {
- if ($(progresselnum)) {
- $(progresselnum).text('40%');
- }
+ aGetTransactionData(packet, function (err, hashesForSigning, rawTransaction) {
- if (changeAmount > 0) {
- addressToSend.push(changeaddress);
- }
+ if (!err) {
- //now get the transaction
- $(messel).text('Creating transaction...');
- aGetTransactionData(packet, function (err, hashesForSigning, rawTransaction) {
- $(progressel).width('60%');
+ statuscallback('Counter-signing transaction...', '60%');
- if ($(progresselnum)) {
- $(progresselnum).text('60%');
- }
+ var jsonSend = {
+ guid: m_this.m_guid,
+ hashesForSigning: hashesForSigning,
+ rawTransaction: rawTransaction,
+ pathsToSignWith: nodeLevels
+ };
+ var jsonp1 = {
+ guid: m_this.m_guid,
+ jsonPacket: JSON.stringify(jsonSend),
+ sharedid: m_this.m_sharedid,
+ twoFactorCode: twoFactorCode,
+ userName: ''
+ };
- var jsonSend = { guid: m_this.m_guid, hashesForSigning: hashesForSigning, rawTransaction: rawTransaction, pathsToSignWith: nodeLevels }
- var jsonp1 = { guid: m_this.m_guid, jsonPacket: JSON.stringify(jsonSend), sharedid: m_this.m_sharedid, twoFactorCode: twoFactorCode, userName: '' };
- $(messel).text('Counter-signing transaction...');
- API.post("/api/1/u/sendtransaction", jsonp1, function (err, result) {
- $(progressel).width('80%');
+ API.post("/api/1/u/sendtransaction", jsonp1, function (err, result) {
- if ($(progresselnum)) {
- $(progresselnum).text('80%');
- }
+ statuscallback(null, '80%');
+ if (!err) {
- if (!err) {
+ statuscallback('Transaction broadcast', '100%');
+ return callback(err, result);
- if ($(progresselnum)) {
- $(progresselnum).text('100%');
- }
- $(progressel).width('100%');
- $(messel).text('Transaction broadcast...');
+ } else {
- //we have a transaction id so lets make a note of the transaction in the database
- var params = { guid: m_this.m_guid, sharedid: m_this.m_sharedid, username: 'External', transactionid: result, address: addressTo, amount: amount };
- API.post("/api/1/u/createtransactionrecord", params, function (err, result) {
- return callback(err, result);
- });
- } else {
- if (result == 'ErrSingleTransactionLimit') {
- $(progressel).width('100%');
- $(messel).text('Transaction Failed: Single limit exceeded');
- return callback(err, result);
- }
+ if (result == 'ErrSingleTransactionLimit') {
- if (result == 'ErrDailyTransactionLimit') {
- $(progressel).width('100%');
- $(messel).text('Transaction Failed: Daily limit exceeded');
- return callback(err, result);
- }
+ statuscallback('Transaction Failed: Single limit exceeded', '0%');
- if (result == 'ErrTransactionsPerDayLimit') {
- $(progressel).width('100%');
- $(messel).text('Transaction Failed: Daily number limit exceeded');
- return callback(err, result);
- }
+ return callback(err, result);
- if (result == 'ErrTransactionsPerHourLimit') {
- $(progressel).width('100%');
- $(messel).text('Transaction Failed: Hourly number limit exceeded');
- return callback(err, result);
- }
+ }
- if (result == 'ErrInvalidRequest') {
- $(progressel).width('100%');
- $(messel).text('Transaction Failed: Invalid request');
- return callback(err, result);
- }
+ if (result == 'ErrDailyTransactionLimit') {
+ statuscallback('Transaction Failed: Daily limit exceeded', '0%');
- if (result == 'ErrBroadcastFailed') {
- $(progressel).width('100%');
- $(messel).text('Transaction Failed: Not accepted');
- return callback(err, result);
- }
+ return callback(err, result);
+ }
+
+ if (result == 'ErrTransactionsPerDayLimit') {
+
+ statuscallback('Transaction Failed: Daily number limit exceeded', '0%');
+
+ return callback(err, result);
+ }
+
+ if (result == 'ErrTransactionsPerHourLimit') {
+
+ statuscallback('Transaction Failed: Hourly number limit exceeded', '0%');
+
+ return callback(err, result);
+ }
+
+ if (result == 'ErrInvalidRequest') {
+
+ statuscallback('Transaction Failed: Invalid request', '0%');
+
+ return callback(err, result);
+ }
+
+
+ if (result == 'ErrBroadcastFailed') {
+
+ statuscallback('Transaction Failed: Not accepted', '0%');
+
+ return callback(err, result);
+ }
+
+ if (result == "Invalid two factor code") {
+
+ statuscallback("Invalid two factor code", '0%');
+
+ return callback(err, result);
+ }
+
+ if (result == "ErrInsufficientFunds") {
+
+ statuscallback("Transaction Failed: Insufficient funds", '0%');
+
+ return callback(err, result);
+ }
+
+ statuscallback('Transaction Failed:' + result, '0%');
+
+ return callback(err, result);
+
+ }
+ });
+
+ } else {
+
+ statuscallback('error creating transaction', '0%');
+
+ return callback(err, 'error creating transaction');
- if (result == "Invalid two factor code") {
- $(progressel).width('100%');
- $(messel).text("Invalid two factor code");
- return callback(err, result);
}
+ });
+ }, 50);
+ } else {
- }
- });
- });
- } else {
+ //create address error
+
+ statuscallback(changeaddress, '0%');
- //create address error
- if (changeaddress == 'ErrInvalidRequest') {
- $(progressel).width('100%');
- $(messel).text('Transaction Failed: Invalid request');
return callback(err, changeaddress);
- }
- }
- });
- }
+ }
+ });
+ }
+ });
} else {
+ statuscallback(outputs, '0%');
+
return callback(err, outputs);
}
@@ -1984,64 +2082,196 @@ function Engine() {
});
+
}
//function createAddress
//this function creates an address for the user
this.createAddress = createAddress;
- function createAddress(nodePath, changeamount, callback) {
+ function createAddress(nodePath, changeamount, cacallback) {
if (changeamount > 0) {
+
+ var snode = nodePath.split('/');
+
var postData = { guid: m_this.m_guid, sharedid: m_this.m_sharedid, pathToUse: nodePath };
//get the next leaf from the user's node space
API.post("/api/1/u/getnextleaf", postData, function (err, leaf) {
- var path = nodePath + '/' + leaf;
+ if (!err) {
- //derive the 3 public keys for the new address
- //TODO: possible to use an encrypted cache for performance improvements
+ var path = nodePath + '/' + leaf;
- var bipHot = Bitcoin.HDWallet.fromBase58(m_this.m_walletinfo.hotPub);
- var bipCold = Bitcoin.HDWallet.fromBase58(m_this.m_walletinfo.coldPub);
- var bipNinki = Bitcoin.HDWallet.fromBase58(m_this.m_walletinfo.ninkiPubKey);
- var hotKey = deriveChild(path, bipHot);
- var coldKey = deriveChild(path, bipCold);
- var ninkiKey = deriveChild(path, bipNinki);
-
- //now create the multisig address
- var script = [0x52];
- script.push(33);
- script = script.concat(hotKey.pub.toBytes());
- script.push(33);
- script = script.concat(coldKey.pub.toBytes());
- script.push(33);
- script = script.concat(ninkiKey.pub.toBytes());
- script.push(0x53);
- script.push(0xae);
- var address = multiSig(script);
-
- //post the address back to the server
- //this allows the server to monitor for balances etc.
- var postData = { guid: m_this.m_guid, sharedid: m_this.m_sharedid, path: path, address: address, pk1: hotKey.pub.toString(), pk2: coldKey.pub.toString(), pk3: ninkiKey.pub.toString() };
- API.post("/api/1/u/createaddress", postData, function (err, result) {
- if (!err) {
- return callback(err, address);
+ if (m_this.Device.isCordova()) {
+
+ var tnode = snode[2] * 1;
+
+ var hotKey = [];
+ var coldKey = [];
+ var ninkiKey = [];
+
+ var hhotKey = '';
+ var hcoldKey = '';
+ var hninkiKey = '';
+
+ cordova.exec(
+ function callback(data) {
+
+ hhotKey = data;
+ console.log("hot key=" + data);
+
+ hotKey = Bitcoin.convert.hexToBytes(data);
+
+
+ cordova.exec(
+ function callback(data) {
+
+ hcoldKey = data;
+ console.log("cold key=" + data);
+
+ coldKey = Bitcoin.convert.hexToBytes(data);
+
+ cordova.exec(
+ function callback(data) {
+
+ hninkiKey = data;
+
+ console.log("ninki key=" + data);
+
+ ninkiKey = Bitcoin.convert.hexToBytes(data);
+
+
+ var script = [0x52];
+
+ script.push(33);
+ script = script.concat(hotKey);
+ script.push(33);
+ script = script.concat(coldKey);
+ script.push(33);
+ script = script.concat(ninkiKey);
+ script.push(0x53);
+ script.push(0xae);
+
+ var address = multiSig(script);
+
+ //post the address back to the server
+ //this allows the server to monitor for balances etc.
+ var postData = {
+ guid: m_this.m_guid,
+ sharedid: m_this.m_sharedid,
+ path: path,
+ address: address,
+ pk1: hhotKey,
+ pk2: hcoldKey,
+ pk3: hninkiKey
+ };
+ API.post("/api/1/u/createaddress", postData, function (err, result) {
+ console.log(result);
+ if (!err) {
+ return cacallback(err, address);
+ } else {
+ return cacallback(err, result);
+ }
+
+ });
+
+ },
+ function errorHandler(err) {
+ //alert('Error');
+ },
+ 'ECPlugin',
+ 'cordovaECMult',
+ [m_this.m_walletinfo.ninkiPubKey, tnode, leaf]
+ );
+
+ },
+ function errorHandler(err) {
+ //alert('Error');
+ },
+ 'ECPlugin',
+ 'cordovaECMult',
+ [m_this.m_walletinfo.coldPub, tnode, leaf]
+ );
+
+ },
+ function errorHandler(err) {
+ //alert('Error');
+ },
+ 'ECPlugin',
+ 'cordovaECMult',
+ [m_this.m_walletinfo.hotPub, tnode, leaf]
+ );
+
} else {
- return callback(err, result);
+
+
+ //derive the 3 public keys for the new address
+ //TODO: possible to use an encrypted cache for performance improvements
+
+ var bipHot = Bitcoin.HDWallet.fromBase58(m_this.m_walletinfo.hotPub);
+ var bipCold = Bitcoin.HDWallet.fromBase58(m_this.m_walletinfo.coldPub);
+ var bipNinki = Bitcoin.HDWallet.fromBase58(m_this.m_walletinfo.ninkiPubKey);
+
+ console.log("deriving hot");
+ var hotKey = deriveChild(path, bipHot);
+ console.log("deriving cold");
+ var coldKey = deriveChild(path, bipCold);
+ console.log("deriving ninki");
+ var ninkiKey = deriveChild(path, bipNinki);
+ console.log("keys derived");
+ //now create the multisig address
+ var script = [0x52];
+
+ script.push(33);
+ script = script.concat(hotKey.pub.toBytes());
+ script.push(33);
+ script = script.concat(coldKey.pub.toBytes());
+ script.push(33);
+ script = script.concat(ninkiKey.pub.toBytes());
+ script.push(0x53);
+ script.push(0xae);
+
+ var address = multiSig(script);
+
+ //post the address back to the server
+ //this allows the server to monitor for balances etc.
+ var postData = {
+ guid: m_this.m_guid,
+ sharedid: m_this.m_sharedid,
+ path: path,
+ address: address,
+ pk1: hotKey.pub.toString(),
+ pk2: coldKey.pub.toString(),
+ pk3: ninkiKey.pub.toString()
+ };
+ API.post("/api/1/u/createaddress", postData, function (err, result) {
+
+ if (!err) {
+ return cacallback(err, address);
+ } else {
+ return cacallback(err, result);
+ }
+
+ });
+
}
- });
+ } else {
+
+ return cacallback(err, leaf);
+
+ }
//now update the address to the server
});
} else {
- return callback(false, "skipped");
+ return cacallback(false, "skipped");
}
}
@@ -2049,7 +2279,7 @@ function Engine() {
//function createAddress
//this function creates an address on behalf of a user's contact
this.createAddressForFriend = createAddressForFriend;
- function createAddressForFriend(username, callback) {
+ function createAddressForFriend(username, cacallback) {
var postData = { guid: m_this.m_guid, sharedid: m_this.m_sharedid, username: username };
@@ -2069,56 +2299,185 @@ function Engine() {
//only allow address to be created if the packet has been validated
if (pubkeys.validated) {
//get the next leaf on the contacts address space node assigned to this user
+
API.post("/api/1/u/getnextleafforfriend", postData, function (err, leaf) {
- //derive the public keys
- var path = 'm/' + leaf;
+ if (!err) {
- var bipHot = Bitcoin.HDWallet.fromBase58(pubkeys.hotPub);
- var bipCold = Bitcoin.HDWallet.fromBase58(pubkeys.coldPub);
- var bipNinki = Bitcoin.HDWallet.fromBase58(pubkeys.ninkiPub);
+ //derive the public keys
+ var path = 'm/' + leaf;
- var hotKey = deriveChild(path, bipHot);
- var coldKey = deriveChild(path, bipCold);
- var ninkiKey = deriveChild(path, bipNinki);
- //now create the multisig address
- var script = [0x52];
- script.push(33);
- script = script.concat(hotKey.pub.toBytes());
- script.push(33);
- script = script.concat(coldKey.pub.toBytes());
- script.push(33);
- script = script.concat(ninkiKey.pub.toBytes());
- script.push(0x53);
- script.push(0xae);
- var address = multiSig(script);
+ if (m_this.Device.isCordova()) {
+
+
+ var nleaf = leaf * 1;
+
+ var hotKey = [];
+ var coldKey = [];
+ var ninkiKey = [];
+
+ var hhotKey = '';
+ var hcoldKey = '';
+ var hninkiKey = '';
+
+ cordova.exec(
+ function callback(data) {
+
+ hhotKey = data;
+ console.log("hot key=" + data);
+
+ hotKey = Bitcoin.convert.hexToBytes(data);
+
+
+ cordova.exec(
+ function callback(data) {
+
+ hcoldKey = data;
+ console.log("cold key=" + data);
+
+ coldKey = Bitcoin.convert.hexToBytes(data);
+
+ cordova.exec(
+ function callback(data) {
+
+ hninkiKey = data;
+
+ console.log("ninki key=" + data);
+
+ ninkiKey = Bitcoin.convert.hexToBytes(data);
+
+
+ var script = [0x52];
+
+ script.push(33);
+ script = script.concat(hotKey);
+ script.push(33);
+ script = script.concat(coldKey);
+ script.push(33);
+ script = script.concat(ninkiKey);
+ script.push(0x53);
+ script.push(0xae);
+
+ var address = multiSig(script);
+
+ //post the address back to the server
+ //this allows the server to monitor for balances etc.
+ //register the address with the server
+ var postData = {
+ guid: m_this.m_guid,
+ sharedid: m_this.m_sharedid,
+ username: username,
+ address: address,
+ leaf: leaf,
+ pk1: hhotKey,
+ pk2: hcoldKey,
+ pk3: hninkiKey
+ };
+ API.post("/api/1/u/createaddressforfriend", postData, function (err, result) {
+
+ if (!err) {
+ return cacallback(err, address);
+ } else {
+ return cacallback(err, result);
+ }
+
+ });
+
+ },
+ function errorHandler(err) {
+ //alert('Error');
+ },
+ 'ECPlugin',
+ 'cordovaECMultCached',
+ [pubkeys.ninkiPub, nleaf]
+ );
+
+ },
+ function errorHandler(err) {
+ //alert('Error');
+ },
+ 'ECPlugin',
+ 'cordovaECMultCached',
+ [pubkeys.coldPub, nleaf]
+ );
+
+ },
+ function errorHandler(err) {
+ //alert('Error');
+ },
+ 'ECPlugin',
+ 'cordovaECMultCached',
+ [pubkeys.hotPub, nleaf]
+ );
- //register the address with the server
- var postData = { guid: m_this.m_guid, sharedid: m_this.m_sharedid, username: username, address: address, leaf: leaf, pk1: hotKey.pub.toString(), pk2: coldKey.pub.toString(), pk3: ninkiKey.pub.toString() };
- API.post("/api/1/u/createaddressforfriend", postData, function (err, result) {
- if (!err) {
- return callback(err, address);
} else {
- return callback(err, result);
+
+
+ var bipHot = Bitcoin.HDWallet.fromBase58(pubkeys.hotPub);
+ var bipCold = Bitcoin.HDWallet.fromBase58(pubkeys.coldPub);
+ var bipNinki = Bitcoin.HDWallet.fromBase58(pubkeys.ninkiPub);
+
+ var hotKey = deriveChild(path, bipHot);
+ var coldKey = deriveChild(path, bipCold);
+ var ninkiKey = deriveChild(path, bipNinki);
+
+ //now create the multisig address
+ var script = [0x52];
+ script.push(33);
+ script = script.concat(hotKey.pub.toBytes());
+ script.push(33);
+ script = script.concat(coldKey.pub.toBytes());
+ script.push(33);
+ script = script.concat(ninkiKey.pub.toBytes());
+ script.push(0x53);
+ script.push(0xae);
+ var address = multiSig(script);
+
+ //register the address with the server
+ var postData = {
+ guid: m_this.m_guid,
+ sharedid: m_this.m_sharedid,
+ username: username,
+ address: address,
+ leaf: leaf,
+ pk1: hotKey.pub.toString(),
+ pk2: coldKey.pub.toString(),
+ pk3: ninkiKey.pub.toString()
+ };
+ API.post("/api/1/u/createaddressforfriend", postData, function (err, result) {
+
+ if (!err) {
+ return cacallback(err, address);
+ } else {
+ return cacallback(err, result);
+ }
+
+ });
}
- });
+ } else {
+
+ return cacallback(err, leaf);
+
+ }
//now update the address to the server
- });
+ });
+
+
} else {
//something very bad has happened
//attempting to derive an address for a non validated contact
- return callback(true, "ErrInvalid");
+ return cacallback(true, "ErrInvalid");
}
} else {
- return callback(true, "ErrInvalid");
+ return cacallback(true, "ErrInvalid");
}
@@ -2130,7 +2489,11 @@ function Engine() {
function multiSig(rs) {
var x = Bitcoin.Crypto.RIPEMD160(Bitcoin.Crypto.SHA256(Bitcoin.convert.bytesToWordArray(rs)));
x = Bitcoin.convert.wordArrayToBytes(x);
- x.unshift(0x5);
+ if (m_this.m_network == "testnet") {
+ x.unshift(196);
+ } else {
+ x.unshift(0x5);
+ }
var r = x;
r = Bitcoin.Crypto.SHA256(Bitcoin.Crypto.SHA256(Bitcoin.convert.bytesToWordArray(r)));
var checksum = Bitcoin.convert.wordArrayToBytes(r).slice(0, 4);
@@ -2139,8 +2502,6 @@ function Engine() {
}
-
-
this.signMessage = signMessage;
function signMessage(key, guid, callback) {
@@ -2154,7 +2515,7 @@ function Engine() {
}
var message = Bitcoin.Crypto.SHA256(Bitcoin.convert.bytesToWordArray(bytes)).toString();
- var skey = Bitcoin.HDWallet.fromSeedHex(mkey);
+ var skey = Bitcoin.HDWallet.fromSeedHex(mkey, m_this.m_network);
var sig = Bitcoin.convert.bytesToHex(skey.priv.sign(Bitcoin.convert.hexToBytes(message)));
@@ -2233,82 +2594,211 @@ function Engine() {
this.createFriend = createFriend;
- function createFriend(username, uimessage, callback) {
+ function createFriend(username, uimessage, cbcallback) {
//get the next friend node
var node = "";
var postData = { guid: m_this.m_guid, sharedid: m_this.m_sharedid, username: username };
- if ($(uimessage)) {
- $(uimessage).text('Assigning node...');
- }
-
API.post("/api/1/u/getnextnodeforfriend", postData, function (err, node) {
- var bipHot = Bitcoin.HDWallet.fromBase58(m_this.m_walletinfo.hotPub);
+ if (m_this.Device.isCordova()) {
- var bipCold = Bitcoin.HDWallet.fromBase58(m_this.m_walletinfo.coldPub);
+ var nls = node.split("/");
+ var tnode = nls[2] * 1;
- var bipNinki = Bitcoin.HDWallet.fromBase58(m_this.m_walletinfo.ninkiPubKey);
- setTimeout(function () {
+ var hotKey = '';
+ var coldKey = '';
+ var ninkiKey = '';
- var hotKey = deriveChild(node, bipHot).toString();
+ cordova.exec(function callback(data) {
- if ($(uimessage)) {
- $(uimessage).text('Deriving address.');
- }
+ hotKey = Bitcoin.HDWallet.fromHex(data).toString();
- setTimeout(function () {
+ console.log(hotKey);
- var coldKey = deriveChild(node, bipCold).toString();
- if ($(uimessage)) {
- $(uimessage).text('Deriving address..');
- }
+ cordova.exec(function callback(data) {
- setTimeout(function () {
+ coldKey = Bitcoin.HDWallet.fromHex(data).toString();
- var ninkiKey = deriveChild(node, bipNinki).toString();
- if ($(uimessage)) {
- $(uimessage).text('Deriving address...');
- }
- //get the friends public RSA key
- var rsaKey = '';
+ console.log(coldKey);
- $(uimessage).text('Get PGP keys...');
- API.post("/api/1/u/getrsakey", postData, function (err, rsaKey) {
+ cordova.exec(function callback(data) {
- var publicKeys = openpgp.key.readArmored(rsaKey);
- if ($(uimessage)) {
- $(uimessage).text('Encrypting data...');
- }
+ ninkiKey = Bitcoin.HDWallet.fromHex(data).toString();
- var pubKey = publicKeys.keys[0];
+ console.log(ninkiKey);
- var message = hotKey + coldKey + ninkiKey;
+ console.log("getting rsa key");
- var encrypted = openpgp.signAndEncryptMessage([pubKey], m_this.m_privKey, message);
+ API.post("/api/1/u/getrsakey", postData, function (err, rsaKey) {
- var result = "";
+ console.log("got rsa key");
- var postFriendData = { guid: m_this.m_guid, sharedid: m_this.m_sharedid, username: username, node: node, packetForFriend: encrypted, validationHash: '' };
- API.post("/api/1/u/createfriend", postFriendData, function (err, result) {
+ var publicKeys = openpgp.key.readArmored(rsaKey);
- return callback(err, result);
+ var pubKey = publicKeys.keys[0];
+
+ var message = hotKey + coldKey + ninkiKey;
+
+ console.log("encrypting");
+
+ var encrypted = openpgp.signAndEncryptMessage([pubKey], m_this.m_privKey, message);
+
+ console.log("encrypting done");
+
+ var result = "";
+
+ var postFriendData = {
+ guid: m_this.m_guid,
+ sharedid: m_this.m_sharedid,
+ username: username,
+ node: node,
+ packetForFriend: encrypted,
+ validationHash: ''
+ };
+
+ console.log(postFriendData);
+
+ console.log("calling createfriend");
+
+ API.post("/api/1/u/createfriend", postFriendData, function (err, result) {
+
+ console.log("done");
+
+ console.log(err);
+ console.log(result);
+
+ return cbcallback(err, result);
+
+ });
});
+ },
+ function errorHandler(err) {
+ alert(err);
+ },
+ 'ECPlugin',
+ 'cordovaDerMPK',
+ [m_this.m_walletinfo.ninkiPubKey, tnode]
+ );
+
+ }, function errorHandler(err) {
+ alert(err);
+ },
+ 'ECPlugin',
+ 'cordovaDerMPK',
+ [m_this.m_walletinfo.coldPub, tnode]
+ );
+
+ }, function errorHandler(err) {
+ alert(err);
+ },
+ 'ECPlugin',
+ 'cordovaDerMPK',
+ [m_this.m_walletinfo.hotPub, tnode]
+ );
+
+
+ } else {
+
+
+ var bipHot = Bitcoin.HDWallet.fromBase58(m_this.m_walletinfo.hotPub);
+
+ var bipCold = Bitcoin.HDWallet.fromBase58(m_this.m_walletinfo.coldPub);
+
+ var bipNinki = Bitcoin.HDWallet.fromBase58(m_this.m_walletinfo.ninkiPubKey);
+
+ var hotKey = deriveChild(node, bipHot).toString();
+
+ var coldKey = deriveChild(node, bipCold).toString();
+
+ var ninkiKey = deriveChild(node, bipNinki).toString();
+
+ //get the friends public RSA key
+ var rsaKey = '';
+
+ API.post("/api/1/u/getrsakey", postData, function (err, rsaKey) {
+
+ var publicKeys = openpgp.key.readArmored(rsaKey);
+
+ var pubKey = publicKeys.keys[0];
+
+ var message = hotKey + coldKey + ninkiKey;
+
+ var encrypted = openpgp.signAndEncryptMessage([pubKey], m_this.m_privKey, message);
+
+ var result = "";
+
+ var postFriendData = {
+ guid: m_this.m_guid,
+ sharedid: m_this.m_sharedid,
+ username: username,
+ node: node,
+ packetForFriend: encrypted,
+ validationHash: ''
+ };
+ API.post("/api/1/u/createfriend", postFriendData, function (err, result) {
+
+ return cbcallback(err, result);
+
+ });
+
+ });
+
+ }
+
+ });
+ }
+
+
+ this.acceptFriend = acceptFriend;
+ function acceptFriend(username, callback) {
+
+
+ //need to add error handling and messages here
+
+ m_this.acceptFriendRequest(username, function (err, secret) {
+
+ if (err) {
+
+ return callback(err, secret);
+
+ } else {
+
+ m_this.isNetworkExist(username, function (err, result) {
+
+ if (!result) {
+
+ m_this.createFriend(username, '', function (err, result) {
+
+ if (err) {
+
+ return callback(err, result);
+ } else {
+
+ return callback(err, result);
+ }
});
- }, 50);
- }, 50);
- }, 50);
+ } else {
+
+ return callback(err, result);
+ }
+ });
+ }
});
+
+
}
+
+
this.acceptFriendRequest = acceptFriendRequest;
function acceptFriendRequest(username, callback) {
@@ -2356,7 +2846,13 @@ function Engine() {
var encrypted = openpgp.signAndEncryptMessage([m_this.m_pubKey], m_this.m_privKey, JSON.stringify(packet));
- postData = { guid: m_this.m_guid, sharedid: m_this.m_sharedid, username: username, packet: encrypted, validationHash: '' };
+ postData = {
+ guid: m_this.m_guid,
+ sharedid: m_this.m_sharedid,
+ username: username,
+ packet: encrypted,
+ validationHash: ''
+ };
API.post("/api/1/u/updatefriend", postData, function (err, result) {
return callback(err, result);
@@ -2369,8 +2865,6 @@ function Engine() {
}
-
-
this.getFingerPrint = getFingerPrint;
function getFingerPrint(callback) {
@@ -2390,11 +2884,6 @@ function Engine() {
var postData = { guid: m_this.m_guid, sharedid: m_this.m_sharedid, username: username };
API.post("/api/1/u/getfriendpacket", postData, function (err, packet) {
-
- //this is set to a fixed value, i wanted it to be set as blank as we encrypt these keys aes256 anyway
- //there was no easy way to change this password in the library so i opted to go with a fixed password
- //instead of a blank one
-
if (!err) {
var msg = openpgp.message.readArmored(packet);
@@ -2420,7 +2909,13 @@ function Engine() {
var encryptedPayload = openpgp.signAndEncryptMessage([m_this.m_pubKey], m_this.m_privKey, JSON.stringify(reencrypt));
- postData = { guid: m_this.m_guid, sharedid: m_this.m_sharedid, username: username, packet: encryptedPayload, validationHash: code };
+ postData = {
+ guid: m_this.m_guid,
+ sharedid: m_this.m_sharedid,
+ username: username,
+ packet: encryptedPayload,
+ validationHash: code
+ };
API.post("/api/1/u/updatefriend", postData, function (err, result) {
@@ -2429,7 +2924,6 @@ function Engine() {
});
-
} else {
return callback(err, false);
@@ -2439,15 +2933,15 @@ function Engine() {
}
} else {
- return callback(err, result);
+ return callback(err, packet);
}
+
});
}
-
//status
//0 pending
//1 paid
@@ -2491,7 +2985,13 @@ function Engine() {
var result = "";
- var pdata = { guid: m_this.m_guid, sharedid: m_this.m_sharedid, userName: username, packetForMe: packetForMe, packetForThem: encrypted };
+ var pdata = {
+ guid: m_this.m_guid,
+ sharedid: m_this.m_sharedid,
+ userName: username,
+ packetForMe: packetForMe,
+ packetForThem: encrypted
+ };
API.post("/api/1/u/createinvoice", pdata, function (err, invoiceid) {
return callback(err, invoiceid);
@@ -2559,7 +3059,6 @@ function Engine() {
});
-
}
@@ -2578,18 +3077,10 @@ function Engine() {
if (!err) {
- var bytes = [];
- for (var i = 0; i < m_this.m_sharedid.length; ++i) {
- bytes.push(m_this.m_sharedid.charCodeAt(i));
- }
-
- var dpacket = Bitcoin.Crypto.SHA256(Bitcoin.convert.bytesToWordArray(bytes)).toString();
-
- API.post("/api/1/verifyrecoverpacket", { guid: m_this.m_oguid, token: dpacket }, function (err, response) {
+ API.registerToken(result);
+ m_this.m_APIToken = result;
- callback(err, response);
-
- });
+ callback(false, result);
} else {
@@ -2601,7 +3092,7 @@ function Engine() {
}
- this.SetupTwoFactor = SaveTwoFactor;
+ this.SetupTwoFactor = SetupTwoFactor;
function SetupTwoFactor(twoFactorCode, callback) {
var postData = {
@@ -2613,7 +3104,7 @@ function Engine() {
API.post("/api/1/u/updatetwofactor", postData, function (err, result) {
- $('#API-Token').val(result);
+ API.registerToken(result);
callback(err, result);
@@ -2671,9 +3162,8 @@ function Engine() {
}
-
this.ChangePassword = ChangePassword;
- function ChangePassword(twoFactorCode, oldpassword, newpassword, progbar, progmess, reset, message1, message2, callback) {
+ function ChangePassword(twoFactorCode, oldpassword, newpassword, callback, statusUpdate) {
API.getWalletFromServer(m_this.m_guid, m_this.m_secret, twoFactorCode, false, function (err, wallet) {
@@ -2687,8 +3177,10 @@ function Engine() {
getHotHash("", function (err, hothash) {
- $(progbar).width('40%');
- $(progmess).text('Securing password...');
+
+ statusUpdate('Securing password...', '20%');
+
+
setTimeout(function () {
//if password reset do not pbkdf the password
@@ -2696,11 +3188,9 @@ function Engine() {
oldpassword = pbkdf2(oldpassword, m_this.m_oguid);
//get the two packets
- $(progbar).width('40%');
- $(progmess).text('Getting packets...');
- // $("#chngpwdprogbar").width('50%');
- //$("#chngpwdprogmess").text('Decrypting account packet...');
+ statusUpdate('Getting packets...', '40%');
+
//decrypt with the old password
var decryptedWithOld = true;
var decryptedPayload = '';
@@ -2712,8 +3202,9 @@ function Engine() {
if (decryptedWithOld) {
- $(progbar).width('80%');
- $(progmess).text('Securing new password...');
+
+ statusUpdate('Securing new password...', '80%');
+
API.getUserPacket(m_this.m_guid, m_this.m_sharedid, function (err, encpacket) {
var decryptedUsrWithOld = true;
@@ -2757,8 +3248,8 @@ function Engine() {
newpassword = pbkdf2(newpassword, m_this.m_oguid);
- $(progbar).width('80%');
- $(progmess).text('Encrypting account packet...');
+ statusUpdate('Encrypting account packet...', '80%');
+
var newpayloadsuccess = true;
var newpayload = '';
@@ -2768,7 +3259,7 @@ function Engine() {
var newAIV = '';
var newUIV = '';
var newRIV = '';
- var newPIV = ''
+ var newPIV = '';
try {
newpayload = encrypt(decryptedPayload, newpassword);
@@ -2819,9 +3310,8 @@ function Engine() {
if (testsuccess) {
//save to the server
- $(progbar).width('95%');
- $(progmess).text('Saving...');
+ statusUpdate('Saving...', '95%');
//TO DO:
//add in the re-encryption of the verification
@@ -2831,12 +3321,23 @@ function Engine() {
//if reset password then provide signed message and call reset function
-
//need to add two factor here
//so 1. add two factor
//2. add way to save only the main packet
- var postData = { twoFactorCode: twoFactorCode, guid: m_this.m_guid, sharedid: m_this.m_sharedid, accountPacket: newpayload.toString(), userPacket: newusrpayload.toString(), verifyPacket: newveripacket.toString(), passPacket: newpasspacket.toString(), IVA: newAIV, IVU: newUIV, IVR: newRIV, PIV: newPIV };
+ var postData = {
+ twoFactorCode: twoFactorCode,
+ guid: m_this.m_guid,
+ sharedid: m_this.m_sharedid,
+ accountPacket: newpayload.toString(),
+ userPacket: newusrpayload.toString(),
+ verifyPacket: newveripacket.toString(),
+ passPacket: newpasspacket.toString(),
+ IVA: newAIV,
+ IVU: newUIV,
+ IVR: newRIV,
+ PIV: newPIV
+ };
API.post("/api/1/u/updatepackets", postData, function (err, dataStr) {
if (err) {
callback(true, "Error: Password not changed");
@@ -2844,19 +3345,45 @@ function Engine() {
if (dataStr == "ok") {
- m_this.m_password = newpassword;
- //if something goes wrong here
- //the worst case scenario is the
- //user has to reenter their hot key
- saveHotHash(hothash, function (err, result) {
+ m_this.Device.getStorageItem("tfso" + m_this.m_guid, function (tfso) {
+
+ if (tfso != "") {
+ var enc = JSON.parse(tfso);
+ var token = decryptNp(enc.ct, m_this.m_password, enc.iv);
+ tfso = encryptNp(token, newpassword);
+
+ var ctok = {};
+ ctok.ct = tfso.toString();
+ ctok.iv = tfso.iv.toString();
+ m_this.Device.setStorageItem("tfso" + m_this.m_guid, JSON.stringify(ctok));
+
+ }
+
+ m_this.m_password = newpassword;
+
+ //if something goes wrong here
+ //the worst case scenario is the
+ //user has to reenter their hot key
+
+ saveHotHash(hothash, function (err, result) {
- callback(false, '');
+ callback(false, '');
+
+ });
});
+
+
+
+
+
+
+
+
} else {
callback(true, "Error: Password not changed");
@@ -2866,7 +3393,6 @@ function Engine() {
});
-
} else {
callback(true, "Error: Password not changed");
@@ -2990,8 +3516,6 @@ function Engine() {
$(progmess).text('Getting packets...');
-
-
// $("#chngpwdprogbar").width('50%');
//$("#chngpwdprogmess").text('Decrypting account packet...');
//decrypt with the old password
@@ -3061,7 +3585,7 @@ function Engine() {
var newAIV = '';
var newUIV = '';
var newRIV = '';
- var newPIV = ''
+ var newPIV = '';
try {
newpayload = encrypt(decryptedPayload, newpassword);
@@ -3115,7 +3639,18 @@ function Engine() {
//if reset password then provide signed message and call reset function
- var postData = { guid: guid, sharedid: sharedid, accountPacket: newpayload.toString(), userPacket: newusrpayload.toString(), verifyPacket: newveripacket.toString(), passPacket: newpasspacket.toString(), IVA: newAIV, IVU: newUIV, IVR: newRIV, PIV: newPIV };
+ var postData = {
+ guid: guid,
+ sharedid: sharedid,
+ accountPacket: newpayload.toString(),
+ userPacket: newusrpayload.toString(),
+ verifyPacket: newveripacket.toString(),
+ passPacket: newpasspacket.toString(),
+ IVA: newAIV,
+ IVU: newUIV,
+ IVR: newRIV,
+ PIV: newPIV
+ };
API.post("/api/1/u/updatepackets", postData, function (err, dataStr) {
if (err) {
callback(true, "Error: Password not changed");
@@ -3136,7 +3671,6 @@ function Engine() {
});
-
} else {
callback(true, "Error: Password not changed");
@@ -3192,7 +3726,6 @@ function Engine() {
}
-
////////////////////////////////////////////////////////////////////////////////////////////
this.EmailValidationForTwoFactor = EmailValidationForTwoFactor;
@@ -3223,40 +3756,61 @@ function Engine() {
}
this.updateAccountSettings = updateAccountSettings;
- function updateAccountSettings(jsonPacket, twoFactorCode, callback) {
+ function updateAccountSettings(jsonPacket, twoFactorCode, twoFactorSend, callback) {
+
+
+
+ //only request a new token
+
var postdata = {
guid: m_this.m_guid,
sharedid: m_this.m_sharedid,
jsonPacket: JSON.stringify(jsonPacket),
- twoFactorCode: twoFactorCode
+ twoFactorCode: twoFactorCode,
+ twoFactorSend: twoFactorSend
};
- API.post("/api/1/u/updateaccountsettings", postdata
- , function (err, response) {
+ API.post("/api/2/u/updateaccountsettings", postdata
+ , function (err, response) {
- if (!err) {
+ if (!err) {
- getAccountSettings(function (err, res) {
+ if (response != "ok") {
- if (!err) {
+ var ret = JSON.parse(response);
- var settingsObject = JSON.parse(res);
- m_this.m_settings = settingsObject;
- callback(err, response);
- } else {
+ if (ret.Token) {
+
+ var enc = encryptNp(ret.Token, m_this.m_password);
+ var ctok = {};
+ ctok.ct = enc.toString();
+ ctok.iv = enc.iv.toString();
+ m_this.Device.setStorageItem("tfso" + m_this.m_guid, JSON.stringify(ctok));
- callback(err, res);
+ }
}
- });
+ getAccountSettings(function (err, res) {
- } else {
- callback(err, response);
- }
+ if (!err) {
+ var settingsObject = JSON.parse(res);
+ m_this.m_settings = settingsObject;
+ callback(err, response);
+ } else {
- });
+ callback(err, res);
+ }
+
+ });
+
+ } else {
+ callback(err, response);
+ }
+
+
+ });
}
@@ -3277,6 +3831,23 @@ function Engine() {
}
+ this.getNewTwoFactorImg = getNewTwoFactorImg;
+ function getNewTwoFactorImg(twoFactorCode, callback) {
+
+ var postData = {
+ guid: m_this.m_guid,
+ sharedid: m_this.m_sharedid,
+ twoFactorCode: twoFactorCode
+ };
+
+ API.post("/api/1/getnewtwofactorimg", postData, function (err, twoFactorQrImgUrl) {
+
+ callback(err, twoFactorQrImgUrl)
+
+ });
+
+ }
+
this.getBackup = getBackup;
function getBackup(twoFactorCode, callback) {
@@ -3504,7 +4075,7 @@ function Engine() {
function getDeviceKey(devicePIN, callback) {
var deviceid = "DEVICE123456789";
- if (window.cordova) {
+ if (m_this.Device.isCordova()) {
deviceid = window.device.uuid;
}
@@ -3517,7 +4088,7 @@ function Engine() {
pinhash = Bitcoin.Crypto.SHA256(Bitcoin.convert.bytesToWordArray(bytes)).toString();
- getCookie("ninki_reg", function (regToken) {
+ m_this.Device.getStorageItem("ninki_reg", function (regToken) {
API.getDeviceKey(m_this.m_guid, pinhash, regToken, function (err, ekey) {
@@ -3526,7 +4097,14 @@ function Engine() {
if (jekey.DeviceKey.length > 0) {
- callback(err, jekey);
+
+ if (jekey.SessionToken) {
+ API.registerToken(jekey.SessionToken);
+ m_this.m_APIToken = jekey.SessionToken;
+ callback(err, jekey);
+ }
+
+
} else {
@@ -3546,7 +4124,7 @@ function Engine() {
this.destroyDevice = destroyDevice;
function destroyDevice(callback) {
- getCookie("ninki_reg", function (regToken) {
+ m_this.Device.getStorageItem("ninki_reg", function (regToken) {
API.destroyDevice(m_this.m_guid, regToken, function (err, ekey) {
@@ -3585,6 +4163,103 @@ function Engine() {
function getDeviceToken(deviceName, twoFactorCode, callback) {
API.getDeviceToken(m_this.m_guid, m_this.m_sharedid, deviceName, twoFactorCode, callback);
}
+
+ this.getLimitStatus = getLimitStatus;
+ function getLimitStatus(callback) {
+ API.getLimitStatus(m_this.m_guid, m_this.m_sharedid, function (err, res) {
+
+ if (!err) {
+ var jlimits = JSON.parse(res);
+ return callback(err, jlimits);
+
+ } else {
+ return callback(err, res);
+ }
+
+ });
+ }
+
+
+ this.createBackupCodes = createBackupCodes;
+ function createBackupCodes(twoFactorCode, callback) {
+ API.createBackupCodes(m_this.m_guid, m_this.m_sharedid, twoFactorCode, function (err, res) {
+
+ if (!err) {
+ var jcodes = JSON.parse(res);
+ return callback(err, jcodes);
+
+ } else {
+ return callback(err, res);
+ }
+
+ });
+ }
+
+
+
+
+ this.get2faOverride = get2faOverride;
+ function get2faOverride(amount, callback) {
+
+ m_this.Device.getStorageItem("tfso" + m_this.m_guid, function (res) {
+
+ if (res == "") {
+
+ return callback(false,"");
+
+ }
+
+ getLimitStatus(function (err, limits) {
+
+ if (!err) {
+
+ var twofareq = false;
+ if ((limits.No24hr + 1) > limits.NoOfTransactionsPerDay) {
+ twofareq = true;
+ }
+ if ((limits.No1hr + 1) > limits.NoOfTransactionsPerHour) {
+ twofareq = true;
+ }
+
+ if ((amount) > limits.SingleTransactionLimit) {
+ twofareq = true;
+ }
+ if ((limits.TotalAmount24hr + amount) > limits.DailyTransactionLimit) {
+ twofareq = true;
+ }
+
+ if (twofareq) {
+
+ callback(err, "");
+
+ } else {
+
+ if (res.length > 0) {
+ var enc = JSON.parse(res);
+ twoFactorCode = decryptNp(enc.ct, m_this.m_password, enc.iv);
+ callback(err, twoFactorCode);
+
+ } else {
+
+ callback(err, "");
+ }
+
+ }
+ } else {
+
+ callback(err, limits);
+
+ }
+
+
+ });
+
+ });
+
+
+ }
+
}
-module.exports = Engine
\ No newline at end of file
+module.exports = Engine;
+
diff --git a/src/ninki-ui-mobile.js b/src/ninki-ui-mobile.js
index 5e242da..e9d936a 100644
--- a/src/ninki-ui-mobile.js
+++ b/src/ninki-ui-mobile.js
@@ -8,16 +8,7 @@ function UI() {
var Engine = new Ninki.Engine();
- // var WALLETINFORMATION = {};
- // var SHAREDID = '';
-
- // var TWOFACTORONLOGIN = false;
- // var NICKNAME = '';
- // var guid = '';
- // var oguid = '';
- // var password = '';
-
-
+ var currentBalance = 0;
var FRIENDSLIST = {};
var COINUNIT = 'BTC';
var price = 0;
@@ -55,10 +46,15 @@ function UI() {
var contactPhraseCache = {};
+ var isPairing = false;
+
var ua = window.navigator.userAgent;
var msie = ua.indexOf("MSIE");
+ var pintaps = 0;
+ var prevpin = '';
+
if (msie > 0 || !!navigator.userAgent.match(/Trident.*rv\:11\./)) {
@@ -95,7 +91,7 @@ function UI() {
var match = r.exec(url);
if (!match) return null;
- var parsed = { url: url }
+ var parsed = { url: url };
if (match[2]) {
var queries = match[2].split('&');
@@ -111,96 +107,6 @@ function UI() {
return parsed;
}
- function setCookie(cname, cvalue) {
-
-
- if (isChromeApp()) {
-
- var obj = {};
- obj[cname] = cvalue;
- chrome.storage.local.set(obj, function () {
-
- console.log("saved");
-
- });
-
- }
- else {
-
- localStorage[cname] = cvalue;
-
- }
-
-
- }
-
- function isChromeApp() {
-
- if (window.cordova) {
- return false;
- }
-
-
- var is_chrome = navigator.userAgent.toLowerCase().indexOf('chrome') > -1;
- if (is_chrome) {
- if (chrome) {
- if (chrome.app) {
- if (chrome.app.runtime) {
- return true;
- }
- }
- }
- }
- return false;
- }
-
-
- function getCookie(cname, callback) {
-
-
- if (isChromeApp()) {
-
- chrome.storage.local.get(cname, function (result) {
-
- if (result[cname]) {
- result = result[cname];
- } else {
- result = "";
- }
-
- return callback(result);
-
- });
-
- } else {
-
- if (localStorage[cname]) {
- return callback(localStorage[cname]);
- } else {
- return callback('');
- }
-
- }
-
- }
-
- function deleteCookie(cname) {
-
-
- if (isChromeApp()) {
-
- chrome.storage.local.remove(cname, function () {
-
- console.log("deleted");
-
- });
-
- } else {
-
- localStorage.removeItem(cname);
-
- }
- }
function getLocalTime(datetime) {
@@ -225,6 +131,7 @@ function UI() {
}
+ var pinlock = false;
function loginPIN() {
@@ -232,9 +139,11 @@ function UI() {
$("#enterpinalert").hide();
- if (pin.length == 4) {
+ if (pin.length == 4 && !pinlock) {
- getCookie("guid", function (guid) {
+ pinlock = true;
+
+ Engine.Device.getStorageItem("guid", function (guid) {
if (!Engine.m_appInitialised) {
@@ -255,46 +164,70 @@ function UI() {
if (!err) {
-
if (Engine.m_appInitialised) {
$('.numdone').attr("style", "background-color:white");
- if (ekeyv.SessionToken) {
- $("#API-Token").val(ekeyv.SessionToken);
- }
-
-
//check state and display correct headers
-
- //set new session key
$("#paddel").hide();
$('.numdone').attr("style", "background-color:white");
$("#loginpin").hide();
+ $("#pinloginmessage").text("Enter your PIN number");
$("#nonlogin").show();
- $(".footer").show();
+
$("#loginpinno").val('');
+ pinlock = false;
+
+ //do we show the footer or not?
+
+ if ($("#footermode").val() == 1) {
+ $(".footer").show();
+ } else {
+ $(".footer").hide();
+ }
+
+ //double check footer
+ //bug workaround
+
+ if (menustate == "profile" && profilepagestate == "") {
+
+ $(".footer").show();
+
+ }
+
+
+
+ $("#isactive").val(1);
- //initialiseDashboard();
setTimeout(updateUI(), 200);
} else {
- $("#pinspinner").show();
- var target = document.getElementById('pinspinner');
+ $("#pairspinner").show();
+ var target = document.getElementById('pairspinner');
var spinner = new Spinner(spinneropts).spin(target);
- getCookie("ninki_p", function (result) {
+ $("#pinspinner").hide();
+ $('.numdone').attr("style", "background-color:white");
+ $("#loginpin").hide();
+ $("#loginpinno").val('');
+ pinlock = false;
+ $("#paddel").hide();
+ $("#pinloginmessage").text("Enter your PIN number");
+
+
+
+ Engine.Device.getStorageItem("ninki_p", function (result) {
var enc = JSON.parse(result);
result = '';
Engine.setStretchPass(Engine.decryptNp(enc.ct, ekeyv.DeviceKey, enc.iv));
- getCookie("ninki_rem", function (res) {
+ Engine.Device.getStorageItem("ninki_rem", function (res) {
if (res.length > 0) {
var enc = JSON.parse(res);
@@ -310,22 +243,31 @@ function UI() {
if (result.TwoFactorOnLogin) {
- $("#pinspinner").hide();
+ $("#pairspinner").hide();
$("#loginpinno").val('');
- $("#enterpinalert").show();
- $("#enterpinalertmessage").text('Token has expired');
+ pinlock = false;
+ //$("#enterpinalert").show();
+ //$("#enterpinalertmessage").text('Token has expired');
+ bootbox.alert("Your token has expired. Please repair your device", function () {
+
+ Engine.Device.deleteStorageItem("ninki_reg");
+ Engine.Device.deleteStorageItem("ninki_p");
+ Engine.Device.deleteStorageItem("ninki_rem");
+ Engine.Device.deleteStorageItem("guid");
+
+ location.reload();
+
+ });
} else {
- $("#pinspinner").hide();
- $('.numdone').attr("style", "background-color:white");
- $("#loginpin").hide();
- $("#loginpinno").val('');
- $("#paddel").hide();
- getCookie("currency", function (res) {
+ $("#footermode").val(1);
+ $(".footer").show();
+
+ Engine.Device.getStorageItem("currency", function (res) {
if (res) {
@@ -333,16 +275,20 @@ function UI() {
} else {
- setCookie("currency", Engine.m_settings.LocalCurrency);
+ Engine.Device.setStorageItem("currency", Engine.m_settings.LocalCurrency);
}
+ console.log(Engine.m_settings.LocalCurrency);
+ console.log(Engine.m_settings.CoinUnit);
+
var t = Engine.m_settings.LocalCurrency;
+
$('.sccy').filter(function () {
return $(this).text().trim() == t;
}).find("label").html('');
- getCookie("coinunit", function (res) {
+ Engine.Device.getStorageItem("coinunit", function (res) {
if (res) {
@@ -350,7 +296,7 @@ function UI() {
} else {
- setCookie("coinunit", Engine.m_settings.CoinUnit);
+ Engine.Device.setStorageItem("coinunit", Engine.m_settings.CoinUnit);
}
@@ -364,14 +310,50 @@ function UI() {
});
- initialiseDashboard();
- Engine.m_appInitialised = true;
+
+ initialiseDashboard(function () {
+
+
+ Engine.m_appInitialised = true;
+ $("#isactive").val(1);
+
+ $("#pairspinner").hide();
+
+ $('#dashboard').show();
+ $('#dashheader').show();
+
+ $("#mainWallet").show();
+ $(".footer").show();
+
+ $("#nonlogin").show();
+
+
+ });
+
+
}
} else {
- $("#pinspinner").hide();
+
+ if (result == "ErrLocked") {
+
+ bootbox.alert("Your account is locked. Please unlock your account using the Chrome App");
+
+ } else {
+
+ bootbox.alert(result);
+
+ }
+
+
+ $("#pairspinner").hide();
$('.numdone').attr("style", "background-color:white");
+ $("#loginpin").show();
+ $("#loginpinno").val('');
+ pinlock = false;
+ $("#paddel").hide();
+ $("#pinloginmessage").text("Enter your PIN number");
}
@@ -391,22 +373,44 @@ function UI() {
if (ekeyv == "ErrDeviceDestroyed") {
- deleteCookie("ninki_reg");
- deleteCookie("ninki_p");
- deleteCookie("ninki_rem");
- deleteCookie("guid");
- $("#loginpin").hide();
- $("#mainWallet").hide();
- $("#pairDevice").show();
+ Engine.Device.deleteStorageItem("ninki_reg");
+ Engine.Device.deleteStorageItem("ninki_p");
+ Engine.Device.deleteStorageItem("ninki_rem");
+ Engine.Device.deleteStorageItem("guid");
- location.reload();
- }
+ bootbox.alert("Too many failed attempts. The device has been unpaired.", function () {
+
+ $("#loginpin").hide();
+ $("#mainWallet").hide();
+ $("#pairDevice").show();
+
+ location.reload();
+
+ });
- $("#loginpinno").val('');
- $("#enterpinalert").show();
- $("#enterpinalertmessage").text(ekeyv);
+ } else {
+
+ $("#loginpinno").val('');
+ pinlock = false;
+ $('.numdone').attr("style", "background-color:white");
+ $("#paddel").hide();
+
+ if (ekeyv.substring(0, 6) == "ErrPIN") {
+
+ var attempts = ekeyv.substring(7, 8);
+
+ $("#pinloginmessage").text("Incorrect PIN " + attempts + "/3 attempts");
- $('.numdone').attr("style", "background-color:white");
+ $("#pincounter").effect("shake");
+
+ } else {
+
+ bootbox.alert(ekeyv);
+
+ }
+
+
+ }
}
@@ -424,2735 +428,3160 @@ function UI() {
- function closeSendNet() {
+ //device paring
+ var deviceName = '';
+ var regToken = '';
+ var secret = '';
+ var enck = '';
+ var iv = '';
- //$("#dashprofile").show();
- $("#dashsend").hide();
- $("#dashsendamt").hide();
- $("#mainWallet").show();
- if (sendmode == "net") {
- $("#friendheader").show();
- }
+ function pairDevice() {
- $(".footer").show();
- $("#dashreceive").hide();
- $("#dashcontact").hide();
+ var blob = $('#pairdeviceblob').val();
+ var pwd = $('#pairpwd').val();
- $("#pinconfirm").hide();
+ var splitBlob = blob.split('|');
- $("#btnStdSndDone").hide();
+ console.log(splitBlob.length);
+ if (splitBlob.length == 5) {
- $('#toAddress').val('');
- $('#amount').text('');
+ var guid = splitBlob[2];
- updateStdAmount();
+ enck = splitBlob[0];
+ iv = splitBlob[1];
+ deviceName = splitBlob[3];
+ regToken = splitBlob[4];
- }
+ Engine.setPass(pwd, guid);
+ var bytes = [];
+ for (var i = 0; i < guid.length; ++i) {
+ bytes.push(guid.charCodeAt(i));
+ }
- function closeSendStd() {
+ var hashguid = Bitcoin.Crypto.SHA256(Bitcoin.convert.bytesToWordArray(bytes)).toString();
- //$("#dashprofile").show();
- $("#dashsend").hide();
- $("#dashsendamt").hide();
- $("#dashheader").show();
- $("#mainWallet").show();
- $(".footer").show();
- $("#dashreceive").hide();
- $("#dashcontact").hide();
+ Engine.m_guid = hashguid;
+ Engine.m_oguid = guid;
- $("#pinconfirm").hide();
+ //first validate the password with the secret
- $("#addrfade").hide();
+ Engine.getRecoveryPacket(function (err, response) {
- $("#btnStdSndDone").hide();
+ if (err) {
+ bootbox.alert("There was an error, please try again.");
- //profilepagestate = "send";
- //menustate = "profile"
- $('#toAddress').val('');
- $('#amount').text('');
- updateStdAmount();
+ } else {
- }
+ //decrypt packet
- var stdAmountConvCoin = true;
- var netAmountConvCoin = true;
+ var jpacket = JSON.parse(response);
- function convertToLocalCurrency(amount) {
+ secret = Engine.decryptNp(jpacket.packet, Engine.m_password, jpacket.IV);
- var conv = amount;
- conv = conv * 1.0;
+ Engine.validateSecret(secret, function (err, secvalid) {
- var sats = convertToSatoshis(conv, COINUNIT);
- var btc = convertFromSatoshis(sats, "BTC");
+ if (!err) {
- var cbtc = btc * price;
+ if (secvalid) {
+ //show pin screen
+ $('#pairDevice').hide();
+ $('#loginpin').show();
- var loc = "en-US";
- var ires = cbtc;
+ }
+
+ } else {
+
+ if (secvalid == "ErrAccount") {
+ bootbox.alert("Password not correct");
+ } else if (secvalid == "ErrLocked") {
+ bootbox.alert("The account is locked");
+ } else {
+ bootbox.alert("There was an error, please try again");
+ }
+
+ }
+
+ });
+
+ }
+
+ });
- if (Engine.m_settings.LocalCurrency == "JPY") {
- ires = (cbtc * 1.0).toFixed(0) * 1.0;
} else {
- ires = (cbtc * 1.0).toFixed(2) * 1.0;
+
+ bootbox.alert("There was a pairing error, please try again.");
+
+ // $('#pairdevicealertmessage').text("There was a pairing error");
+ //$('#pairdevicealert').show();
}
+ }
- var cprc = ires.toLocaleString(loc, { style: "currency", currency: Engine.m_settings.LocalCurrency });
- return cprc;
+ function regPIN() {
- }
- function convertFromLocalCurrency(amount) {
+ $("#pairspinner").show();
+ var target = document.getElementById('pairspinner');
+ var spinner = new Spinner(spinneropts).spin(target);
- var conv = amount;
- conv = conv * 1.0;
+ $('#loginpin').hide();
- //convert to bitcoin
- if (price > 0) {
- var cbtc = conv / price;
- var sats = convertToSatoshis(cbtc, "BTC");
- var btc = convertFromSatoshis(sats, COINUNIT);
- return btc;
- } else {
- return 0;
+ //hash the pin and device id
+ var deviceid = "DEVICE123456789";
+ if (window.cordova) {
+ deviceid = window.device.uuid;
}
- }
- function updateStdAmount() {
+ var pin = $("#loginpinno").val();
- var asamt = $('#amount').text();
- if (asamt == '' || asamt == '.') {
- asamt = 0;
+ var pinhash = deviceid + pin;
+ bytes = [];
+ for (var i = 0; i < pinhash.length; ++i) {
+ bytes.push(pinhash.charCodeAt(i));
}
- if (stdAmountConvCoin) {
- $('#ccystdamt').text(convertToLocalCurrency(asamt));
- $('#hdamount').val(asamt);
- }
- else {
- var amt = convertFromLocalCurrency(asamt);
- $('#hdamount').val(amt);
- $('#ccystdamt').text(amt + ' ' + COINUNIT);
- }
+ pinhash = Bitcoin.Crypto.SHA256(Bitcoin.convert.bytesToWordArray(bytes)).toString();
- }
+ //new register device
- var profilepagestate = '';
- var networkpagestate = '';
- var friendpagestate = '';
- var menustate = '';
- var cl = '';
+ //enter password
+ //stretch
+ //get validate
+ //if valid
+ //choose a PIN
+ //register
- jQuery(document).ready(function () {
- var $body = jQuery('body');
+ var devplatform = "platform";
+ var devmodel = "model";
+ if (window.cordova) {
+ devplatform = window.device.platform;
+ devmodel = window.device.model;
+ }
- //guid
- //ninki_reg
- //if device is paired then
+ Engine.registerDevice(Engine.m_guid, deviceName, devplatform, devmodel, pinhash, regToken, secret, function (err, result) {
+ if (!err) {
- getCookie("ninki_reg", function (reg) {
+ var dk = JSON.parse(result);
- if (reg) {
- $("#loginpin").show();
- } else {
- $("#pairDevice").show();
- }
+ if (dk.DeviceKey.length > 0) {
- });
+ var decblob = Engine.decryptNp(enck, dk.DeviceKey, iv);
+ //slice it up
+ //64 64 64
+ var hk = decblob.substring(0, 64);
+ var fatoken = decblob.substring(64, 128);
- $("#mainWallet").hide();
- $("#dashreceive").hide();
- $("#dashcontact").hide();
+ var encp = Engine.encryptNp(Engine.m_password, dk.DeviceKey);
+ result = '';
+ var ptok = {};
+ ptok.ct = encp.toString();
+ ptok.iv = encp.iv.toString();
+ var ptoken = JSON.stringify(ptok);
- $("#addcontactmodal").hide();
+ var enc = Engine.encryptNp(fatoken, dk.DeviceKey);
+ var ctok = {};
+ ctok.ct = enc.toString();
+ ctok.iv = enc.iv.toString();
- $('#stdselcu').click(function () {
+ var ctoken = JSON.stringify(ctok);
- var amttarget = '#amount';
- $('#stdselunit').text(COINUNIT);
- stdAmountConvCoin = true;
- $(amttarget).text('');
- updateStdAmount();
+ var ench = Engine.encryptNp(hk, dk.DeviceKey);
+ var htok = {};
+ htok.ct = ench.toString();
+ htok.iv = ench.iv.toString();
- });
+ var hkey = JSON.stringify(htok);
- $('#stdsellc').click(function () {
+ dk.DeviceKey = '';
+ //login using the credentials
+ //get a session
+ //then call register PIN
+ //this will return the encryption key
+ //encrypt the password and store in local storage
- var amttarget = '#amount';
+ Engine.Device.setStorageItem("guid", Engine.m_oguid);
- $('#stdselunit').text(Engine.m_settings.LocalCurrency);
- stdAmountConvCoin = false;
- $(amttarget).text('');
- updateStdAmount();
+ Engine.openWallet(Engine.m_oguid, fatoken, function (err, result) {
+ if (!err) {
- });
+ if (!result.TwoFactorOnLogin) {
+ Engine.Device.setStorageItem("ninki_rem", ctoken);
+ Engine.Device.setStorageItem("ninki_p", ptoken);
+ Engine.Device.setStorageItem("ninki_reg", regToken);
+ Engine.Device.setStorageItem("ninki_h", hkey);
- // $('.numc').bind('touchstart', function () {
- // $(this).removeClass('numtapoff');
+ $("#loginpinno").val('');
+ pinlock = false;
+ $("#paddel").hide();
+ $('.numdone').attr("style", "background-color:white");
- // cl = 'b' + (Math.floor(Math.random() * 6) + 1) + '';
- // //alert(cl);
- // $(this).addClass(cl);
+ var t = Engine.m_settings.LocalCurrency;
- // });
+ $('.sccy').filter(function () {
+ return $(this).text().trim() == t;
+ }).find("label").html('');
+ var tc = Engine.m_settings.CoinUnit;
+ $('.scoinunit').filter(function () {
+ return $(this).text().trim() == tc;
+ }).find("label").html('');
- $('.scoinunit').bind('click', function () {
- $('.scoinunit').find("label").html('');
+ isPairing = false;
- $(this).find("label").html('');
+ //callback here before displaying
- var sel = $.trim($(this).text());
- setCookie("coinunit", sel);
- Engine.m_settings.CoinUnit = sel;
+ initialiseDashboard(function () {
- COINUNIT = sel;
+ Engine.m_appInitialised = true;
- updateUI();
+ $("#pairspinner").hide();
+ $('#dashboard').show();
+ $('#dashheader').show();
- });
+ $("#footermode").val(1);
+ $("#mainWallet").show();
+ $(".footer").show();
+ });
+ } else {
+ $("#pairspinner").hide();
+ bootbox.alert("Could not pair", function () {
+ location.reload();
+ });
- $('.sccy').bind('click', function () {
+ }
- $('.sccy').find("label").html('');
+ } else {
+ $("#pairspinner").hide();
+ bootbox.alert(result, function () {
- $(this).find("label").html('');
+ location.reload();
- var sel = $.trim($(this).text());
+ });
- setCookie("currency", sel);
+ }
- Engine.m_settings.LocalCurrency = sel;
+ });
+ } else {
+ $("#pairspinner").hide();
+ bootbox.alert("The pairing token has expired", function () {
- updateUI();
+ location.reload();
- });
+ });
+ }
- $('.numc').bind('touchend', function () {
+ } else {
- var num = $(this);
- var text = $.trim(num.find('.txt').clone().children().remove().end().text());
+ $("#pairspinner").hide();
+ bootbox.alert(result, function () {
- var amttarget = '#amount';
+ location.reload();
- var amt = $(amttarget).text();
+ });
- if (!(amt.indexOf(".") > -1 && text == '.')) {
+ }
- var prev = amt.substring(0, amt.length - 1);
+ });
- if (text.length > 0) {
- $(amttarget).text($(amttarget).text() + text);
- } else {
- $(amttarget).text(prev);
- }
+ secret = '';
- updateStdAmount();
+ }
- }
- });
- var pintaps = 0;
- var prevpin = '';
- //touchend
- $('#loginpin .num').bind('touchstart', function () {
+ function closeSendNet() {
- var num = $(this);
- var text = $.trim(num.find('.txt').clone().children().remove().end().text());
- if (text.length > 0) {
- pintaps++;
+ $("#dashsend").addClass("invis");
+ $("#dashsend").removeClass("slideUp");
- if (pintaps == 1) {
- $('#loginpin #pin1').attr("style", "background-color:Gray");
+ $("#dashsendamt").addClass("invis");
+ $("#dashsendamt").removeClass("slideUp");
+ $("#dashsendamt").hide();
- }
+ $("#mainWallet").show();
- if (pintaps == 2) {
+ if (sendmode == "net" || sendmode == "inv") {
+ $("#friendheader").show();
+ } else {
+ $('#dashboard').show();
+ $('#dashheader').show();
- $('#loginpin #pin2').attr("style", "background-color:Gray");
+ }
- }
+ $(".footer").show();
- if (pintaps == 3) {
- $('#loginpin #pin3').attr("style", "background-color:Gray");
+ $("#dashreceive").addClass("invis");
+ $("#dashreceive").removeClass("slideUp");
- }
+ $("#dashcontact").addClass("invis");
+ $("#dashcontact").removeClass("slideUp");
- if (pintaps == 4) {
+ //$("#dashreceive").hide();
+ //$("#dashcontact").hide();
- $('#loginpin #pin4').attr("style", "background-color:Gray");
+ $("#pinconfirm").hide();
- }
+ $("#btnStdSndDone").hide();
- }
+ $('#toAddress').val('');
+ sendAmount = '';
+ updateStdAmount();
- var loginpinno = $('#loginpinno');
- var lpin = loginpinno.val();
- prevpin = lpin.substring(0, lpin.length - 1)
+ }
- if (text.length > 0) {
- $('#paddel').show();
+ function closeSendStd() {
+ $("#dashsend").removeClass("slideUp");
+ $("#dashsend").addClass("invis");
- $(loginpinno).val(loginpinno.val() + text);
+ $("#dashsendamt").removeClass("slideUp");
+ $("#dashsendamt").addClass("invis");
+ $("#dashsendamt").hide();
- if (pintaps == 4) {
+ $('#dashboard').show();
+ $('#dashheader').show();
- pintaps = 0;
+ $("#mainWallet").show();
+ $(".footer").show();
- loginPIN();
- //only if fail
+ $("#dashreceive").removeClass("slideUp");
+ $("#dashreceive").addClass("invis");
- }
+ $("#dashcontact").removeClass("slideUp");
+ $("#dashcontact").addClass("invis");
+ //$("#dashreceive").hide();
- } else {
+ //$("#dashcontact").hide();
+ $("#pinconfirm").hide();
+ $("#addrfade").hide();
- if (pintaps == 1) {
+ $("#btnStdSndDone").hide();
- $('#loginpin #pin1').attr("style", "background-color:White");
- $('#loginpin #paddel').hide();
- }
+ //profilepagestate = "send";
+ //menustate = "profile"
- if (pintaps == 2) {
+ $('#toAddress').val('');
- $('#loginpin #pin2').attr("style", "background-color:White");
+ sendAmount = '';
- }
+ updateStdAmount();
- if (pintaps == 3) {
+ }
- $('#loginpin #pin3').attr("style", "background-color:White");
+ var stdAmountConvCoin = true;
+ var netAmountConvCoin = true;
- }
+ function convertToLocalCurrency(amount) {
- if (pintaps == 4) {
+ var conv = amount;
+ conv = conv * 1.0;
- $('#loginpin #pin4').attr("style", "background-color:White");
+ var sats = convertToSatoshis(conv, COINUNIT);
+ var btc = convertFromSatoshis(sats, "BTC");
- }
+ var cbtc = btc * price;
- $(loginpinno).val(prevpin);
+ var loc = "en-US";
+ var ires = cbtc;
- if (pintaps > 0) {
- pintaps--;
- }
+ if (Engine.m_settings.LocalCurrency == "JPY") {
+ ires = (cbtc * 1.0).toFixed(0) * 1.0;
+ } else {
+ ires = (cbtc * 1.0).toFixed(2) * 1.0;
+ }
- }
+ var loc = "en-US";
+ var cprc = "";
+ if (Engine.m_settings.LocalCurrency == "JPY" || Engine.m_settings.LocalCurrency == "CNY") {
+ cprc = accounting.formatMoney(ires, "¥", 0);
+ } else if (Engine.m_settings.LocalCurrency == "GBP") {
+ cprc = accounting.formatMoney(ires, "£", 2);
+ } else if (Engine.m_settings.LocalCurrency == "EUR") {
+ cprc = accounting.formatMoney(ires, "€", 2);
+ } else if (Engine.m_settings.LocalCurrency == "USD") {
+ cprc = accounting.formatMoney(ires, "$", 2);
+ } else if (Engine.m_settings.LocalCurrency == "CNY") {
+ cprc = accounting.formatMoney(ires, "¥", 2);
+ }
+ return cprc;
- });
+ }
- $('#pinconfirm .num').bind('touchend', function () {
+ function convertFromLocalCurrency(amount, format) {
- var num = $(this);
- var text = $.trim(num.find('.txt').clone().children().remove().end().text());
- var loginpinno = $('#sendstdpin');
- var lpin = loginpinno.val();
- prevpin = lpin.substring(0, lpin.length - 1)
+ var conv = amount;
+ conv = conv * 1.0;
- if (text.length > 0) {
- $('#paddelconf').show();
- pintaps++;
- if (pintaps == 1) {
+ //convert to bitcoin
+ if (price > 0) {
+ var cbtc = conv / price;
- $('#pinconfirm #cpin1').attr("style", "background-color:Gray");
+ var sats = convertToSatoshis(cbtc, "BTC");
- }
+ var dp = 4;
+ if (sats > 0 && sats < 10000) {
+ dp = 8;
+ }
- if (pintaps == 2) {
- $('#pinconfirm #cpin2').attr("style", "background-color:Gray");
+ var btc = convertFromSatoshis(sats, COINUNIT);
- }
- if (pintaps == 3) {
+ if (format) {
+ if (COINUNIT == "BTC") {
- $('#pinconfirm #cpin3').attr("style", "background-color:Gray");
+ btc = accounting.formatMoney(btc, "", dp);
}
- if (pintaps == 4) {
+ if (COINUNIT == "Bits") {
- $('#pinconfirm #cpin4').attr("style", "background-color:Gray");
+ btc = accounting.formatMoney(btc, "", 0);
}
+ } else {
+ if (COINUNIT == "BTC") {
+ var dpr = 4;
+ if (sats > 0 && sats < 10000) {
+ dpr = 8;
+ }
- $(loginpinno).val(loginpinno.val() + text);
+ btc = accounting.toFixed(btc, dpr);
+ }
- if (pintaps == 4) {
+ if (COINUNIT == "Bits") {
+ var dpr = 0;
+ if (sats > 0 && sats < 10000) {
+ dpr = 2;
+ }
+ btc = accounting.toFixed(btc, dpr);
+ }
+ }
- pintaps = 0;
+ return btc;
- if (sendmode == 'std') {
+ } else {
- sendMoneyStd();
+ return 0;
- } else if (sendmode == 'net') {
+ }
- sendMoney(SELECTEDFRIEND, 0);
- } else if (sendmode == 'inv') {
+ }
- payInvoice(selectedInvoiceUserName, selectedInvoiceAmount, selectedInvoiceId);
- }
+ var sendAmount = '';
+ function updateStdAmount() {
+ //vamout will track the value
+ //hdamount.val is the value actually used as an
+ // input to the transaction
- //only if fail
- }
+ //if the input value is decimal . or empty
+ //set to 0
+
+ var vAmount = 0;
+ if (sendAmount == '' || sendAmount == '.') {
+ vAmount = 0;
+ } else {
+ vAmount = sendAmount;
+ }
+ vAmount = vAmount * 1;
+ if (sendAmount == '') {
+
+ //default entry box and actual value in the case of no input
+ $('#amount').text('Enter amount');
+ if (stdAmountConvCoin) {
+ $('#ccystdamt').html(convertToLocalCurrency(0));
} else {
+ $('#ccystdamt').html(convertFromLocalCurrency(0) + ' ' + COINUNIT);
+ }
+ $('#hdamount').val('0');
+ } else {
+ if (stdAmountConvCoin) {
- if (pintaps == 1) {
+ //amounts are being input in a Bitcoin denomination
+ //so we convert to local currenct
- $('#pinconfirm #cpin1').attr("style", "background-color:White");
- $('#pinconfirm #paddelconf').hide();
+ $('#ccystdamt').html(convertToLocalCurrency(vAmount));
+ //convert bitcoin amount to number
+ $('#hdamount').val(vAmount * 1.0);
- }
+ var cprc = 0;
+ if (COINUNIT == "Bits") {
- if (pintaps == 2) {
+ //default bits to 0 decimal places
+ cprc = accounting.formatMoney(sendAmount, "", 0);
- $('#pinconfirm #cpin2').attr("style", "background-color:White");
+ } else {
- }
- if (pintaps == 3) {
+ var indot = sendAmount.indexOf('.');
- $('#pinconfirm #cpin3').attr("style", "background-color:White");
+ //if the input is the beginning of input entry
+ //apply no formatting
+ if (sendAmount == '.' || sendAmount == '0.' || sendAmount == '0') {
- }
+ cprc = sendAmount;
- if (pintaps == 4) {
+ }
+ else if (indot == sendAmount.length - 1) {
+ //if the user has just enetered a decimal point
+ //format the number and add on the decimal for display
+ cprc = accounting.formatMoney(sendAmount, "", 0) + '.';
+ }
+ else {
+ //if there is no decimal point apply formatting
+ //with 0 dp
+ if (indot == -1) {
+
+ cprc = accounting.formatMoney(sendAmount, "", 0);
+
+ } else {
+
+ //allow bitcoin entry up to 6 decimal places
+ var ramt = Math.min(sendAmount.length - indot, 6);
+ ramt = ramt - 1;
+ cprc = accounting.formatMoney(sendAmount, "", ramt);
+ }
+
+ }
- $('#pinconfirm #cpin4').attr("style", "background-color:White");
}
- $(loginpinno).val(prevpin);
+ var fee = convertFromSatoshis(Engine.m_settings.MinersFee, COINUNIT);
+ if (currentBalance >= (vAmount + fee) && vAmount > 0) {
- if (pintaps > 0) {
- pintaps--;
+ $('#btnsendmoneystd').removeClass("disabled");
+
+ } else {
+
+ $('#btnsendmoneystd').removeClass("disabled");
+ $('#btnsendmoneystd').addClass("disabled");
}
+ $('#amount').text(cprc);
}
+ else {
- });
+ //entry is in local currency
+ //so we need to convert to coin units and also format
+ //the currency input
+
+ var amt = convertFromLocalCurrency(vAmount);
+ var amtfmt = convertFromLocalCurrency(vAmount, true);
+ amt = amt * 1.0;
+
+ $('#hdamount').val(amt);
+
+ $('#ccystdamt').text(amtfmt + ' ' + COINUNIT);
+
+ var symb = '';
+ if (Engine.m_settings.LocalCurrency == "JPY" || Engine.m_settings.LocalCurrency == "CNY") {
+ symb = "¥";
+ } else if (Engine.m_settings.LocalCurrency == "GBP") {
+ symb = "£";
+ } else if (Engine.m_settings.LocalCurrency == "EUR") {
+ symb = "€";
+ } else if (Engine.m_settings.LocalCurrency == "USD") {
+ symb = "$";
+ } else if (Engine.m_settings.LocalCurrency == "CNY") {
+ symb = "¥";
+ }
- $("#btnmenuprofile").bind('touchstart', function () {
+ var cprc = '';
- displayProfile();
+ var indot = sendAmount.indexOf('.');
- });
+ if (sendAmount == '.' || sendAmount == '0.' || sendAmount == '0') {
+ cprc = symb + sendAmount;
+ }
+ else if (indot == sendAmount.length - 1) {
- function displayProfile() {
+ cprc = accounting.formatMoney(sendAmount, symb, 0) + '.';
+ }
+ else {
+ if (indot == -1) {
- if (menustate != 'profile') {
- menustate = 'profile';
- $("#settings").hide();
- $("#settingsheader").hide();
+ cprc = accounting.formatMoney(sendAmount, symb, 0);
+ } else {
- $("#network").hide();
- $("#networklistheader").hide();
- $("#friendheader").hide();
- $("#dashboard").show();
+ var ramt = Math.min(sendAmount.length - indot, 2);
- $('#dashheader').show();
- //$("#invoices").hide();
+ cprc = symb + sendAmount
- } else {
- profilehome();
- }
+ }
- $("#btnmenusettings").attr('style', 'background-color:#ffffff');
- $("#btnmenunetwork").attr('style', 'background-color:#ffffff');
- $("#btnmenuprofile").attr('style', 'background-color:#eaeef1');
+ }
- }
+ var fee = convertFromSatoshis(Engine.m_settings.MinersFee, COINUNIT);
+ if (currentBalance >= (amt + fee) && amt > 0) {
- var hastouched = false;
- $("#btnmenunetwork").bind('touchstart', function () {
+ $('#btnsendmoneystd').removeClass("disabled");
- if (!hastouched) {
+ } else {
- hastouched = true;
+ $('#btnsendmoneystd').removeClass("disabled");
+ $('#btnsendmoneystd').addClass("disabled");
+ }
- var target = document.getElementById('myfrndspin');
- var spinner = new Spinner(spinneropts).spin(target);
- $("#myfrndspin").show();
- updateFriends(function (err, res) {
- $("#myfrndspin").hide();
+ $('#amount').html(cprc);
+ }
+ }
- });
+ }
- loadInvoices();
- }
+ var profilepagestate = '';
+ var networkpagestate = '';
+ var friendpagestate = '';
+ var menustate = '';
- displayNetwork();
+ var cl = '';
+ var scrolling = false;
+ var scrollingnettran = false;
+ var scrollingnetlist = false;
- });
+ jQuery(document).ready(function () {
+ var $body = jQuery('body');
- function displayNetwork() {
- if (menustate != "network") {
+ $("#dashboard").on("scroll", function () {
+ scrolling = true;
+ });
- menustate = "network";
- $("#settings").hide();
- $("#settingsheader").hide();
- $("#dashboard").hide();
- $('#dashheader').hide();
- //$("#pnlfriend").hide();
- $("#network").show();
+ $("#dashboard").on("touchstart", function () {
+ scrolling = false;
- if ($("#networklist").is(':visible')) {
- $("#networklistheader").show();
- }
+ });
- if ($("#pnlfriend").is(':visible')) {
- $("#friendheader").show();
- }
+ $("#pnlfriend").on("scroll", function () {
+ scrollingnettran = true;
+ });
- //$("#networklist").show();
+ $("#pnlfriend").on("touchstart", function () {
- if (networkpagestate == "invoice") {
+ scrollingnettran = false;
+ });
- //$("#invoices").show();
- }
+ $("#networklist").on("scroll", function () {
+ scrollingnetlist = true;
+ });
- } else {
+ $("#networklist").on("touchstart", function () {
- networkhome();
- }
+ scrollingnetlist = false;
- $("#btnmenusettings").attr('style', 'background-color:#ffffff');
- $("#btnmenuprofile").attr('style', 'background-color:#ffffff');
- $("#btnmenunetwork").attr('style', 'background-color:#eaeef1');
- }
+ });
- $("#invformelink").hammer(null).bind("tap", function () {
+ bootbox.setDefaults({ 'backdrop': false, 'animate': true });
- sendmode = "inv";
- $("#invformetab").show();
- $("#invbymetab").hide();
- $("#liby").removeClass('active');
- $("#lifor").addClass('active');
- });
+ //guid
+ //ninki_reg
- $("#invbymelink").hammer(null).bind("tap", function () {
- $("#invbymetab").show();
- $("#invformetab").hide();
- $("#lifor").removeClass('active');
- $("#liby").addClass('active');
- });
+ //if device is paired then
- //tapsendfriend
- //tapinvoicefriend
+ Engine.Device.getStorageItem("ninki_reg", function (reg) {
- //tapnetpayments
+ if (reg) {
+ isPairing = false;
+ $("#loginpin").show();
+ $("#pinimage").show();
- $("#tapnetpayments").hammer(null).bind("tap", function () {
- $("#pnlfriendinv").hide();
- $("#networkpayments").show();
- $("#networksend").hide();
- networkpagestate = "friend";
- friendpagestate = "payments";
+ } else {
+ isPairing = true;
+ $("#pairDevice").show();
+ $("#pinpair").show();
+ }
});
- $("#tapinvoicefriend").hammer(null).bind("tap", function () {
+ $("#mainWallet").hide();
- $("#pnlfriendinv").show();
- $("#networkpayments").hide();
- $("#networksend").hide();
- networkpagestate = "friend";
- friendpagestate = "invoice";
+ //$("#dashreceive").hide();
+ //$("#dashcontact").hide();
- });
- function networkhome() {
- if (networkpagestate == "invoice") {
+ $("#addcontactmodal").hide();
- $('#network').show();
- $("#pnlfriend").show();
- $("#friendheader").show();
- $('#invoices').hide();
- networkpagestate = "friend";
- friendpagestate = "invoice";
+ $('#stdselcu').click(function () {
- } else {
+ sendAmount = '';
- $("#pnlfriend").hide();
- $("#friendheader").hide();
- $("#network").show();
- $("#networklist").show();
- $("#networklistheader").show();
+ $('#stdselunit').text(COINUNIT);
- networkpagestate = "";
- }
- }
+ stdAmountConvCoin = true;
- function profilehome() {
+ updateStdAmount();
+ });
- $("#dashprofile").show();
- $("#dashsend").hide();
- $("#dashreceive").hide();
- $("#dashcontact").hide();
- $('#invoices').hide();
- $("#dashboard").show();
- $('#dashheader').show();
- $("#network").hide();
- profilepagestate = "";
- }
+ $('#stdsellc').click(function () {
- $("#btnmenusettings").bind('touchstart', function () {
+ sendAmount = '';
- menustate = "settings";
+ $('#stdselunit').text(Engine.m_settings.LocalCurrency);
+ stdAmountConvCoin = false;
+
+ updateStdAmount();
- $("#settings").show();
- $("#settingsheader").show();
- $("#network").hide();
- $("#dashboard").hide();
- $('#dashheader').hide();
- $('#friendheader').hide();
- $('#networklistheader').hide();
- $("#btnmenusettings").attr('style', 'background-color:#eaeef1');
- $("#btnmenuprofile").attr('style', 'background-color:#ffffff');
- $("#btnmenunetwork").attr('style', 'background-color:#ffffff');
});
- $('#toAddress').change(function () {
+ // $('.numc').bind('touchstart', function () {
+ // $(this).removeClass('numtapoff');
- //if a valid bitcoin address then
- //next stage
- var addr = $('#toAddress').val();
+ // cl = 'b' + (Math.floor(Math.random() * 6) + 1) + '';
+ // //alert(cl);
+ // $(this).addClass(cl);
- var paddr = parseBitcoinURL(addr);
+ // });
- if (addr.length > 25) {
- if (Engine.isAddressValid(paddr.address)) {
- //next stage
- //if amount is included in the URL set the amount and go straight to the
- //pay screen
- $('#toAddress').val(paddr.address)
+ $('.scoinunit').bind('click', function () {
- $("#dashsend").hide();
- $("#addrfade").hide();
- $("#dashsendamt").show();
+ $('.scoinunit').find("label").html('');
+ $(this).find("label").html('');
- }
- }
- });
+ var sel = $.trim($(this).text());
+ Engine.Device.setStorageItem("coinunit", sel);
- $("#btnCloseContact").bind('touchstart', function () {
+ Engine.m_settings.CoinUnit = sel;
- //closeSendStd();
- $("#dashcontact").hide();
- $("#mainWallet").show();
- $("#networklistheader").show();
- $(".footer").show();
+ COINUNIT = sel;
- });
+ prevtransfeed = -1;
+ prevNetworkTransCount = -1;
+ updateUI();
- $("#btnAddContactDone").bind('touchstart', function () {
+ });
- $("#addcontactmodal").hide();
- $("#dashcontact").show();
- });
- $("#btnCloseStdSndAmt").bind('touchstart', function () {
- closeSendNet();
+ $('.sccy').bind('click', function () {
- });
+ $('.sccy').find("label").html('');
- $("#btnCloseStdSndPIN").bind('touchstart', function () {
+ $(this).find("label").html('');
- if (sendmode == "std") {
- closeSendStd();
- } else {
- closeSendNet();
- }
+ var sel = $.trim($(this).text());
- });
+ Engine.Device.setStorageItem("currency", sel);
- $("#btnCloseStdSnd").bind('touchstart', function () {
+ Engine.m_settings.LocalCurrency = sel;
- closeSendStd();
+ updateUI();
});
- $("#btnCloseRec").bind('touchstart', function () {
-
- closeSendStd();
- });
+ $('.numc').bind('touchend', function () {
- $("#btnStdSndDone").bind('touchstart', function () {
+ var num = $(this);
+ var text = $.trim(num.find('.txt').clone().children().remove().end().text());
- $('#sendprogress').hide();
+ //check the number of decimal places and if more than 8 for btc
+ if (text.length > 0) {
- if (sendmode == "std") {
- closeSendStd();
- } else {
- closeSendNet();
- }
+ if (stdAmountConvCoin) {
- });
+ if (sendAmount.indexOf(".") > -1) {
- //$("#btnStdSndDone")
+ var ind = sendAmount.indexOf(".");
- $("#btnsendmoneystd").bind('touchstart', function () {
+ if (COINUNIT == "BTC") {
+ if ((sendAmount.length - ind) == 7) {
- if (sendmode == 'std') {
- $("#sendstds2add").text($('#toAddress').val());
- } else if (sendmode == 'net') {
- $("#sendstds2add").text(SELECTEDFRIEND);
- }
- $("#sendstds2amt").text($("#hdamount").val() + ' ' + COINUNIT);
+ return;
- $("#dashsend").hide();
- $("#dashsendamt").hide();
- $("#pinconfirm").show();
+ }
+ }
- //sendMoneyStd();
+ }
- });
+ } else {
+ if (sendAmount.indexOf(".") > -1) {
+ var ind = sendAmount.indexOf(".");
- $("#btnCloseValidate").bind('touchstart', function () {
+ if ((sendAmount.length - ind) == 3) {
- $("#friendheader").show();
- $("#mainWallet").show();
- $(".footer").show();
- $("#networkvalidate").hide();
+ return;
- });
+ }
- $("#tapvalidatefriend").bind('touchstart', function () {
- $("#friendheader").hide();
- $("#mainWallet").hide();
- $(".footer").hide();
- $("#networkvalidate").show();
+ }
- });
+ }
- $("#tapsendfriend").bind('touchstart', function () {
- sendmode = "net";
+ }
- $("#sendsubheading").text("send to " + SELECTEDFRIEND);
- $("#btnStdSndDone").hide();
- $("#dashsend").hide();
- $("#addrfade").hide();
+ if (!(sendAmount.indexOf(".") > -1 && text == '.')) {
- $("#friendheader").hide();
- $("#dashsendamt").show();
+ var prev = sendAmount.substring(0, sendAmount.length - 1);
+ if (text.length > 0) {
+ sendAmount = (sendAmount + '' + text);
+ } else {
+ sendAmount = prev;
+ }
- $("#mainWallet").hide();
- $(".footer").hide();
+ updateStdAmount();
+ }
- networkpagestate = "friend";
- friendpagestate = "send";
});
- $("#tapsend").bind('touchstart', function () {
-
- sendmode = "std"
-
- $("#dashheader").hide();
- $("#dashprofile").hide();
- $("#dashsend").show();
-
-
- setTimeout(function () {
- $("#addrfade").fadeIn(500);
- }, 500);
- $("#dashsendamt").hide();
- $("#mainWallet").hide();
- $(".footer").hide();
+ window.resetPin = function () {
- $("#dashreceive").hide();
- $("#dashcontact").hide();
- $("#toAddress").blur();
- $("#qr").focus();
- $("#btnStdSndDone").hide();
+ pintaps = 0;
+ prevpin = '';
- profilepagestate = "send";
- menustate = "profile"
+ };
+ window.hasSession = function () {
- });
+ if (Engine.m_APIToken.length > 0) {
- $("#tapreceive").bind('touchstart', function () {
+ return true;
+ }
+ return false;
- //dashreceive
- $("#dashheader").hide();
- $("#dashprofile").hide();
- $("#dashsend").hide();
- $("#mainWallet").hide();
- $("#dashreceive").show();
- $(".footer").hide();
- $("#dashcontact").hide();
- profilepagestate = "receive";
- menustate = "profile"
+ };
- });
- $("#taprequest").bind('touchstart', function () {
- //$("#dashprofile").hide();
- //$("#dashsend").hide();
- //$("#dashreceive").hide();
- $("#mainWallet").hide();
- $("#networklistheader").hide();
- $("#dashcontact").show();
- $(".footer").hide();
- //checkAndValidateTimer = setInterval(function () { checkAndValidateFriendRequests() }, 2000);
- //profilepagestate = "contact";
- //menustate = "profile"
- });
+ //touchend
+ $('#loginpin .num').bind('touchstart', function () {
- $('#imgProfileContainer').show();
- $("#dropzone").hide();
- $("#btnSaveProfile").hide();
- $("#btnCancelProfile").hide();
- $("#statusedit").hide();
- $("#imgreset").hide();
+ if (!pinlock) {
- $("#btnEditProfile").bind('touchstart', function () {
+ if (pintaps < 4) {
- key = '';
+ var num = $(this);
+ var text = $.trim(num.find('.txt').clone().children().remove().end().text());
- $('#imgProfileContainer').hide();
- $("#dropzone").show();
- $("#btnSaveProfile").show();
- $("#btnCancelProfile").show();
- $("#btnEditProfile").hide();
- $("#statusedit").show();
- $("#profnmests").hide();
- $("#imgreset").show();
- $("#txtStatusText").val(Engine.m_statusText);
+ if (text.length > 0) {
- });
+ pintaps++;
- $("#imgreset").bind('touchstart', function () {
+ if (pintaps == 1) {
- Engine.m_profileImage = "";
- imgReset = true;
+ $('#loginpin #pin1').attr("style", "background-color:Gray");
- var imageSrc = "images/avatar/256px/Avatar-" + pad(Engine.m_nickname.length) + ".png";
+ }
- document.getElementById('imgProfile').src = imageSrc;
- $('#imgProfileContainer').show();
- $('#dropzone').hide();
- $('progressNumber').text('');
- $("#imgreset").hide();
+ if (pintaps == 2) {
- });
+ $('#loginpin #pin2').attr("style", "background-color:Gray");
- var imgReset = false;
- $("#btnSaveProfile").bind('touchstart', function () {
+ }
- //updateUserProfile
+ if (pintaps == 3) {
- var statusText = $("#txtStatusText").val();
+ $('#loginpin #pin3').attr("style", "background-color:Gray");
- if (key == '' && !imgReset) {
- key = Engine.m_profileImage;
- }
+ }
- Engine.updateUserProfile(key, statusText, Engine.m_invoiceTax, function (err, result) {
+ if (pintaps == 4) {
- if (!err) {
+ $('#loginpin #pin4').attr("style", "background-color:Gray");
- var imageSrc = "images/avatar/256px/Avatar-" + pad(Engine.m_nickname.length) + ".png";
- var imageSrcSmall = "images/avatar/64px/Avatar-" + pad(Engine.m_nickname.length) + ".png";
+ }
- if (key != '' && !imgReset) {
- imageSrc = "https://ninkip2p.imgix.net/" + key + "?crop=faces&fit=crop&h=256&w=256&mask=ellipse&border=1,d0d0d0";
- imageSrcSmall = "https://ninkip2p.imgix.net/" + key + "?crop=faces&fit=crop&h=64&w=64&mask=ellipse&border=1,d0d0d0";
}
- $("#imgProfile").attr("src", imageSrc);
- $("#imgtoprightprofile").attr("src", imageSrcSmall);
-
- $('#imgProfileContainer').show();
- $("#dropzone").hide();
- $("#btnSaveProfile").hide();
- $("#btnCancelProfile").hide();
- $("#btnEditProfile").show();
- $("#statusedit").hide();
- $("#mystatus").text(statusText);
- $("#txtStatusText").val(statusText);
- $("#profnmests").show();
- $("#imgreset").hide();
- imgReset = false;
- $("#profileimgfile").val('');
- $("#progressNumber").val('');
-
- }
-
- });
- });
- $("#btnCancelProfile").bind('touchstart', function () {
- $('#imgProfileContainer').show();
- $("#dropzone").hide();
- $("#btnSaveProfile").hide();
- $("#btnCancelProfile").hide();
- $("#btnEditProfile").show();
+ var loginpinno = $('#loginpinno');
+ var lpin = loginpinno.val();
+ prevpin = lpin.substring(0, lpin.length - 1);
- //reset profile image
+ //if not delete
+ if (text.length > 0) {
- var imageSrc = "images/avatar/256px/Avatar-" + pad(Engine.m_nickname.length) + ".png";
+ $('#paddel').show();
- if (Engine.m_profileImage != '') {
- imageSrc = "https://ninkip2p.imgix.net/" + Engine.m_profileImage + "?crop=faces&fit=crop&h=256&w=256&mask=ellipse&border=1,d0d0d0";
- }
+ $(loginpinno).val(loginpinno.val() + text);
- $("#imgProfile").attr("src", imageSrc);
+ if (pintaps == 4) {
- $("#statusedit").hide();
- $("#profnmests").show();
- $("#imgreset").hide();
- });
+ pintaps = 0;
- var obj = $("#dropzone");
+ if (!isPairing) {
+ loginPIN();
+ } else {
+ regPIN();
+ }
- obj.click(function () {
- $("#profileimgfile").click();
- });
+ //only if fail
- $("#profileimgfile").change(function (e) {
+ }
- var control = document.getElementById("profileimgfile");
- var files = control.files;
- //alert(files[0]);
- //We need to send dropped files to Server
- handleFileUpload(files, obj);
- });
+ } else {
- obj.on('dragenter', function (e) {
- e.stopPropagation();
- e.preventDefault();
- $(this).css('border', '2px solid #0B85A1');
- });
- obj.on('dragover', function (e) {
- e.stopPropagation();
- e.preventDefault();
- });
- obj.on('drop', function (e) {
+ if (pintaps == 1) {
- $(this).addClass("b-dashed");
- $(this).addClass("b-light");
- e.preventDefault();
- var files = e.originalEvent.dataTransfer.files;
- //alert(files[0]);
- //We need to send dropped files to Server
- handleFileUpload(files, obj);
- });
+ $('#loginpin #pin1').attr("style", "background-color:White");
+ $('#loginpin #paddel').hide();
+ }
- $(document).on('dragenter', function (e) {
- e.stopPropagation();
- e.preventDefault();
- });
+ if (pintaps == 2) {
- $(document).on('dragover', function (e) {
- e.stopPropagation();
- e.preventDefault();
- obj.css('border', '2px dotted #0B85A1');
- });
+ $('#loginpin #pin2').attr("style", "background-color:White");
- $(document).on('drop', function (e) {
- e.stopPropagation();
- e.preventDefault();
- });
+ }
- var key = '';
- function handleFileUpload(files, obj) {
+ if (pintaps == 3) {
- if (files.length > 0) {
- var file = files[0];
- var fd = new FormData();
+ $('#loginpin #pin3').attr("style", "background-color:White");
- key = "images\/" + Engine.m_nickname + '_' + (new Date).getTime()
+ }
- Ninki.API.post("/api/1/u/createS3Policy", { test: 'test' }, function (err, result) {
+ if (pintaps == 4) {
- var policy = JSON.parse(result);
+ $('#loginpin #pin4').attr("style", "background-color:White");
- fd.append('key', key);
- fd.append('acl', 'public-read');
- fd.append('Content-Type', file.type);
- fd.append('bucket', 'ninkip2pimgstore');
- fd.append('AWSAccessKeyId', 'AKIAINOU56ATQFS3CLFQ');
- fd.append('policy', policy.s3Policy);
- fd.append('signature', policy.s3Signature);
- fd.append("file", file);
- //fd.append("success_action_redirect", "https://localhost:1111/ok");
+ }
+ $(loginpinno).val(prevpin);
- var xhr = new XMLHttpRequest();
+ if (pintaps > 0) {
+ pintaps--;
+ }
- xhr.upload.addEventListener("progress", uploadProgress, false);
- xhr.addEventListener("load", uploadComplete, false);
- xhr.addEventListener("error", uploadFailed, false);
- xhr.addEventListener("abort", uploadCanceled, false);
+ }
+ }
- xhr.open('POST', 'https://ninkip2pimgstore.s3-us-west-1.amazonaws.com/', true); //MUST BE LAST LINE BEFORE YOU SEND
+ }
+ });
- xhr.send(fd);
- });
- }
- }
+ $('#pinconfirm .num').bind('touchend', function () {
- function uploadProgress(evt) {
- if (evt.lengthComputable) {
- var percentComplete = Math.round(evt.loaded * 100 / evt.total);
- document.getElementById('progressNumber').innerHTML = percentComplete.toString() + '%';
- }
- else {
- document.getElementById('progressNumber').innerHTML = 'unable to compute';
- }
- }
+ //;
- function uploadComplete(evt) {
- /* This event is raised when the server send back a response */
- //alert("Done - " + evt.target.responseText);
- document.getElementById('imgProfile').src = 'https://ninkip2p.imgix.net/' + key + "?fit=crop&crop=faces&h=128&w=128&mask=ellipse&border=1,d0d0d0";
- $('#imgProfileContainer').show();
- $('#dropzone').hide();
- $('progressNumber').text('');
- $("#imgreset").hide();
- }
+ var num = $(this);
- function uploadFailed(evt) {
- alert("There was an error attempting to upload the file." + evt);
- }
+ var text = $.trim(num.find('.txt').clone().children().remove().end().text());
+ var loginpinno = $('#sendstdpin');
+ var lpin = loginpinno.val();
+ prevpin = lpin.substring(0, lpin.length - 1);
- function uploadCanceled(evt) {
- alert("The upload has been canceled by the user or the browser dropped the connection.");
- }
+ if (text.length > 0) {
- });
+ $('#paddelconf').show();
+ pintaps++;
+ if (pintaps == 1) {
- $(document).ready(function () {
+ $('#pinconfirm #cpin1').attr("style", "background-color:Gray");
+ }
- $("#pairdeviceblob").change(function () {
+ if (pintaps == 2) {
- $("#loginpin").hide();
- $("#pairstep1").hide();
- $("#pairstep2").show();
+ $('#pinconfirm #cpin2').attr("style", "background-color:Gray");
+ }
- });
+ if (pintaps == 3) {
+ $('#pinconfirm #cpin3').attr("style", "background-color:Gray");
- $("#btnUnpair").click(function () {
+ }
- //return;
- getCookie("guid", function (guid) {
+ if (pintaps == 4) {
- Engine.m_oguid = guid;
+ $('#pinconfirm #cpin4').attr("style", "background-color:Gray");
- var bytes = [];
- for (var i = 0; i < guid.length; ++i) {
- bytes.push(guid.charCodeAt(i));
}
- Engine.m_guid = Bitcoin.Crypto.SHA256(Bitcoin.convert.bytesToWordArray(bytes)).toString();
+ $(loginpinno).val(loginpinno.val() + text);
- Engine.destroyDevice(function (err, res) {
-
- deleteCookie("ninki_rem");
- deleteCookie("ninki_p");
- deleteCookie("ninki_reg");
- deleteCookie("ninki_h");
+ if (pintaps == 4) {
- //call to server
- location.reload();
- });
+ pintaps = 0;
- });
+ if (sendmode == 'std') {
+ sendMoneyStd();
- });
+ } else if (sendmode == 'net') {
+ sendMoney(SELECTEDFRIEND, 0);
- $("#btnPairDevice").bind('click', function () {
+ } else if (sendmode == 'inv') {
- var deviceid = "DEVICE123456789";
+ payInvoice(selectedInvoiceUserName, selectedInvoiceAmount, selectedInvoiceId);
- if (window.cordova) {
- deviceid = window.device.uuid;
- }
+ }
- var blob = $('#pairdeviceblob').val();
- var pin = $('#pairdevicepinnumber').val();
- var pwd = $('#pairpwd').val();
+ //only if fail
- var splitBlob = blob.split('|');
+ }
- var enck = splitBlob[0];
- var iv = splitBlob[1];
- var guid = splitBlob[2];
- var deviceName = splitBlob[3];
- var regToken = splitBlob[4];
+ } else {
- Engine.setPass(pwd, guid);
- pwd = Engine.m_password;
- var bytes = [];
- for (var i = 0; i < guid.length; ++i) {
- bytes.push(guid.charCodeAt(i));
- }
+ if (pintaps == 1) {
- var hashguid = Bitcoin.Crypto.SHA256(Bitcoin.convert.bytesToWordArray(bytes)).toString();
+ $('#pinconfirm #cpin1').attr("style", "background-color:White");
+ $('#pinconfirm #paddelconf').hide();
+ }
- Engine.m_guid = hashguid;
- Engine.m_oguid = guid;
+ if (pintaps == 2) {
- //first validate the password with the secret
- Engine.getRecoveryPacket(function (err, response) {
+ $('#pinconfirm #cpin2').attr("style", "background-color:White");
- if (err) {
+ }
- $('#pairdevicealertmessage').text(response);
+ if (pintaps == 3) {
- } else {
+ $('#pinconfirm #cpin3').attr("style", "background-color:White");
- //decrypt packet
+ }
- var jpacket = JSON.parse(response);
+ if (pintaps == 4) {
- var secret = Engine.decryptNp(jpacket.packet, pwd, jpacket.IV);
+ $('#pinconfirm #cpin4').attr("style", "background-color:White");
- Engine.validateSecret(secret, function (err, secvalid) {
+ }
- if (!err) {
+ $(loginpinno).val(prevpin);
+ if (pintaps > 0) {
+ pintaps--;
+ }
- //hash the pin and device id
- var pinhash = deviceid + pin;
- bytes = [];
- for (var i = 0; i < pinhash.length; ++i) {
- bytes.push(pinhash.charCodeAt(i));
- }
+ }
- pinhash = Bitcoin.Crypto.SHA256(Bitcoin.convert.bytesToWordArray(bytes)).toString();
+ });
- //new register device
+ $("#btnmenuprofile").bind('touchstart', function () {
+ displayProfile();
- //enter password
- //stretch
- //get validate
- //if valid
- //choose a PIN
- //register
+ });
- var devplatform = "platform";
- var devmodel = "model";
- if (window.cordova) {
- devplatform = window.device.platform;
- devmodel = window.device.model;
- }
+ function displayProfile() {
- Engine.registerDevice(hashguid, deviceName, devplatform, devmodel, pinhash, regToken, secret, function (err, result) {
+ if (menustate != 'profile') {
+ menustate = 'profile';
+ $("#settings").hide();
+ $("#settingsheader").hide();
- if (!err) {
- var dk = JSON.parse(result);
+ $("#network").hide();
+ $("#networklistheader").hide();
+ $("#friendheader").hide();
+ $("#dashboard").show();
- if (dk.DeviceKey.length > 0) {
+ $('#dashheader').show();
+ //$("#invoices").hide();
- var decblob = Engine.decryptNp(enck, dk.DeviceKey, iv);
+ } else {
+ profilehome();
+ }
- //slice it up
- //64 64 64
- var hk = decblob.substring(0, 64);
- var fatoken = decblob.substring(64, 128);
+ $("#btnmenusettings").attr('style', 'background-color:#ffffff');
+ $("#btnmenunetwork").attr('style', 'background-color:#ffffff');
+ $("#btnmenuprofile").attr('style', 'background-color:#eaeef1');
- var encp = Engine.encryptNp(pwd, dk.DeviceKey);
- result = '';
+ }
- var ptok = {};
- ptok.ct = encp.toString();
- ptok.iv = encp.iv.toString();
- var ptoken = JSON.stringify(ptok);
+ var hastouched = false;
+ $("#btnmenunetwork").bind('touchstart', function () {
- var enc = Engine.encryptNp(fatoken, dk.DeviceKey);
- var ctok = {};
- ctok.ct = enc.toString();
- ctok.iv = enc.iv.toString();
+ if (!hastouched) {
- var ctoken = JSON.stringify(ctok);
+ hastouched = true;
+ var target = document.getElementById('myfrndspin');
+ var spinner = new Spinner(spinneropts).spin(target);
+ $("#myfrndspin").show();
+ updateFriends(function (err, res) {
- var ench = Engine.encryptNp(hk, dk.DeviceKey);
- var htok = {};
- htok.ct = ench.toString();
- htok.iv = ench.iv.toString();
+ $("#myfrndspin").hide();
- var hkey = JSON.stringify(htok);
+ });
- dk.DeviceKey = '';
+ loadInvoices();
- //login using the credentials
- //get a session
- //then call register PIN
- //this will return the encryption key
- //encrypt the password and store in local storage
+ }
- setCookie("guid", guid);
+ displayNetwork();
- Engine.openWallet(guid, fatoken, function (err, result) {
- if (!err) {
+ });
- if (!result.TwoFactorOnLogin) {
- setCookie("ninki_rem", ctoken);
- setCookie("ninki_p", ptoken);
- setCookie("ninki_reg", regToken);
- setCookie("ninki_h", hkey);
+ function displayNetwork() {
- $('#pairDevice').hide();
+ if (menustate != "network") {
- initialiseDashboard();
+ menustate = "network";
+ $("#settings").hide();
+ $("#settingsheader").hide();
+ $("#dashboard").hide();
+ $('#dashheader').hide();
+ //$("#pnlfriend").hide();
+ $("#network").show();
- } else {
+ if ($("#networklist").is(':visible')) {
+ $("#networklistheader").show();
+ }
- $('#pairdevicealertmessage').text("could not pair");
- $('#pairdevicealert').show();
- }
+ if ($("#pnlfriend").is(':visible')) {
+ $("#friendheader").show();
+ }
+ //$("#networklist").show();
- } else {
+ if (networkpagestate == "invoice") {
- $('#pairdevicealertmessage').text(result);
- $('#pairdevicealert').show();
- }
- });
- } else {
+ //$("#invoices").show();
+ }
- $('#pairdevicealertmessage').text("The pairing token has expired");
- $('#pairdevicealert').show();
- }
+ } else {
+ networkhome();
+ }
- } else {
+ $("#btnmenusettings").attr('style', 'background-color:#ffffff');
+ $("#btnmenuprofile").attr('style', 'background-color:#ffffff');
+ $("#btnmenunetwork").attr('style', 'background-color:#eaeef1');
+ }
- $('#pairdevicealertmessage').text(result);
- $('#pairdevicealert').show();
- }
+ $("#invformelink").hammer(null).bind("tap", function () {
- });
+ sendmode = "inv";
+ $("#invformetab").show();
+ $("#invbymetab").hide();
+ $("#liby").removeClass('active');
+ $("#lifor").addClass('active');
+ });
- } else {
+ $("#invbymelink").hammer(null).bind("tap", function () {
+ $("#invbymetab").show();
+ $("#invformetab").hide();
+ $("#lifor").removeClass('active');
+ $("#liby").addClass('active');
+ });
- $('#pairdevicealertmessage').text(secvalid);
- $('#pairdevicealert').show();
- }
+ $("#tapnetpayments").hammer(null).bind("tap", function () {
+ $("#pnlfriendinv").hide();
+ $("#networkpayments").show();
+ $("#networksend").hide();
+ networkpagestate = "friend";
+ friendpagestate = "payments";
- });
+ });
- }
- });
+ $("#tapinvoicefriend").hammer(null).bind("tap", function () {
+ $("#pnlfriendinv").show();
+ $("#networkpayments").hide();
+ $("#networksend").hide();
+ networkpagestate = "friend";
+ friendpagestate = "invoice";
});
+ function networkhome() {
+ if (networkpagestate == "invoice") {
- $("#btnaddfriend").bind('touchstart', function () {
+ $('#network').show();
+ $("#pnlfriend").show();
+ $("#friendheader").show();
+ $('#invoices').hide();
+ networkpagestate = "friend";
+ friendpagestate = "invoice";
- addFriend($('input#friend').val());
- });
+ } else {
- $("#btngenaddr").bind('touchstart', function () {
+ $("#pnlfriend").hide();
+ $("#friendheader").hide();
+ $("#network").show();
+ $("#networklist").show();
+ $("#networklistheader").show();
- generateAddressClient();
+ networkpagestate = "";
+ }
- });
+ }
+ function profilehome() {
- //wallet security wizard
+ $("#dashprofile").show();
- //$("#balance").text("... BTC");
+ $("#dashsend").addClass("invis");
+ $("#dashsend").removeClass("slideUp");
- $("#btnSendToFriend").bind('touchstart', function () {
+ $("#dashreceive").addClass("invis");
+ $("#dashreceive").removeClass("slideUp");
- sendMoney(SELECTEDFRIEND, 0);
+ $("#dashcontact").addClass("invis");
+ $("#dashcontact").removeClass("slideUp");
+ //$("#dashreceive").hide();
+ //$("#dashcontact").hide();
- });
+ $('#invoices').hide();
+ $("#dashboard").show();
+ $('#dashheader').show();
+ $("#network").hide();
+ profilepagestate = "";
- $("#sendfriendprog").hide();
+ }
- $("#hdvalcontact").change(function () {
+ $("#btnmenusettings").bind('touchstart', function () {
- console.log('caught event...');
+ menustate = "settings";
- var res = $("#hdvalcontact").val();
- var sres = res.split(',');
- var phrase = sres[0];
- var username = sres[1];
+ $("#settings").show();
+ $("#settingsheader").show();
+ $("#network").hide();
+ $("#dashboard").hide();
+ $('#dashheader').hide();
+ $('#friendheader').hide();
+ $('#networklistheader').hide();
+ $("#btnmenusettings").attr('style', 'background-color:#eaeef1');
+ $("#btnmenuprofile").attr('style', 'background-color:#ffffff');
+ $("#btnmenunetwork").attr('style', 'background-color:#ffffff');
+ });
- $("#netvalidprognum").text('30%');
- $("#netvalidprogmess").text('Validating contact...');
- $("#netvalidprog").width('30%');
- setTimeout(function () {
- var bip39 = new BIP39();
- code = bip39.mnemonicToHex(phrase);
+ $('#toAddress').change(function () {
- console.log(code);
+ //if a valid bitcoin address then
+ //next stage
+ var addr = $('#toAddress').val();
+ if (addr.indexOf('bitcoin:') == -1) {
+ addr = 'bitcoin:' + addr;
+ }
- if (code.length != 40) {
+ var paddr = parseBitcoinURL(addr);
- return;
- }
+ if (addr.length > 25) {
+ if (Engine.isAddressValid(paddr.address)) {
+ //next stage
+ //if amount is included in the URL set the amount and go straight to the
+ //pay screen
- //console.log(SELECTEDFRIEND);
- //console.log(username);
+ $('#toAddress').val(paddr.address);
- if (SELECTEDFRIEND == username) {
+ $("#dashsend").addClass("invis");
+ $("#dashsend").removeClass("slideUp");
- $("#netvalidp2").show();
- $("#netvalidp1").hide();
+ $("#addrfade").hide();
- $("#netvalidprognum").text('50%');
- $("#netvalidprogmess").text('Validating contact...');
- $("#netvalidprog").width('50%');
+ $("#dashsendamt").show();
+ $("#dashsendamt").removeClass("invis");
+ $("#dashsendamt").addClass("slideUp");
- setTimeout(function () {
- Engine.verifyFriendData(SELECTEDFRIEND, code, function (err, result) {
+ }
+ }
+ });
- console.log(result);
- if (result) {
- $("#netvalidprognum").text('100%');
- $("#netvalidprogmess").text('Contact validated');
- $("#netvalidprog").width('100%');
+ $("#btnCloseTran").bind('touchstart', function () {
- //$("#validateform").hide();
- //$("#validatesuccess").show();
- $("#txtCode").val('');
- selectedFriend.validated = true;
- FRIENDSLIST[selectedFriend.userName].validated = true;
- updateSelectedFriend();
- $("#networkvalidate").hide();
- $("#friendheader").show();
- $("#mainWallet").show();
- $(".footer").show();
+ $("#transview").removeClass("slideUp");
+ $("#transview").addClass("invis");
- $("#netvalidp2").hide();
- $("#netvalidp1").show();
- //update list also
+ $("#mainWallet").show();
+ $(".footer").show();
- //find friend in list and update the validated icon
- $("#myfriends #seltarget" + selectedFriend.userName).html('
');
+ if (transactionDetailMode == 'dashboard') {
+ $('#dashboard').show();
+ $('#dashheader').show();
+ } else {
+ $("#friendheader").show();
+ }
+ });
- } else {
- $("#netvalidp2").hide();
- $("#netvalidp1").show();
- $("#validatefail").show();
- }
+ $("#btnCloseContact").bind('touchstart', function () {
- });
+ //closeSendStd();
- }, 100);
- }
+ //$("#dashcontact").hide();
+ $("#dashcontact").removeClass("slideUp");
+ $("#dashcontact").addClass("invis");
- }, 100);
+ $("#mainWallet").show();
+ $("#networklistheader").show();
+ $(".footer").show();
});
- $("#btnVerify").bind('touchstart', function () {
+ $("#btnAddContactDone").bind('touchstart', function () {
- var code = $("#txtCode").val();
+ $("#addcontactmodal").hide();
+ $("#dashcontact").show();
- $("#txtCode").css("border-color", "#ccc");
- $("#validatefail").hide();
- $("#validatesuccess").hide();
- var bip39 = new BIP39();
- code = bip39.mnemonicToHex(code);
+ });
- if (code.length != 40) {
- $("#txtCode").css("border-color", "#ffaaaa");
- return;
- }
+ $("#btnCloseStdSndAmt").bind('touchstart', function () {
- //get the hash to validate against
- //this will confirm that my friend has the same keys
- //i orginally packaged for him
+ closeSendNet();
- Engine.verifyFriendData(SELECTEDFRIEND, code, function (err, result) {
+ });
- if (result) {
+ $("#btnCloseStdSndPIN").bind('touchstart', function () {
- $("#txtCode").val('');
- selectedFriend.validated = true;
- FRIENDSLIST[selectedFriend.userName].validated = true;
- updateSelectedFriend();
- $("#networkvalidate").hide();
- $("#friendheader").show();
- $("#mainWallet").show();
- $(".footer").show();
- //update list also
+ if (sendmode == "std") {
+ closeSendStd();
+ } else if (sendmode == "net") {
+ closeSendNet();
+ } else {
+ $("#pinconfirm").hide();
+ $("#invoices").show();
+ }
- //find friend in list and update the validated icon
- $("#myfriends #seltarget" + selectedFriend.userName).html('
');
+ });
+ $("#btnCloseStdSnd").bind('touchstart', function () {
- } else {
- $("#validatefail").show();
- }
+ closeSendStd();
- });
});
+ $("#btnCloseRec").bind('touchstart', function () {
- //INVOICE STUFF START------------------------------------------
+ closeSendStd();
- $("#friendselector").hide();
- $("#invoice").hide();
- $("#invoicedisplay").hide();
+ });
- $("#btnpayinvoice").bind('touchstart', function () {
+ $("#btnStdSndDone").bind('touchstart', function () {
+ $('#sendprogress').hide();
- $(".footer").hide();
+ $('#textMessageSendStd').text('');
+ $('#textMessageSendStd').hide();
+ $('#sendstdprogstatus').width('0');
+ $('#sendstdprognum').text('0%');
+ $('#sendstdprog').hide();
- $("#sendstds2add").text(SELECTEDFRIEND);
+ if (sendmode == "std") {
+ closeSendStd();
+ } else if (sendmode == "net") {
+ closeSendNet();
+ } else {
+ $("#mainWallet").show();
+ $("#invoices").hide();
+ $("#network").show();
+ $("#pnlfriend").show();
+ $("#friendheader").show();
+ $(".footer").show();
+ }
- $("#sendstds2amt").text(convertFromSatoshis(selectedInvoiceAmount, COINUNIT) + ' ' + COINUNIT);
+ });
- sendmode = 'inv';
- $("#mainWallet").hide();
+ $("#btnsendmoneystd").bind('touchstart', function () {
+
+
+ $('#paddelconf').hide();
+
+ $("#dashsendamt").hide();
$("#pinconfirm").show();
+ if (sendmode == 'std') {
+ $("#sendstds2add").text($('#toAddress').val());
+ } else if (sendmode == 'net') {
+ $("#sendstds2add").text(SELECTEDFRIEND);
+ }
- });
+ if (COINUNIT == "BTC") {
+ $("#sendstds2amt").text(accounting.formatNumber($("#hdamount").val(), 8, ",", ".") + ' ' + COINUNIT);
+ } else {
+ $("#sendstds2amt").text(accounting.formatNumber($("#hdamount").val(), 2, ",", ".") + ' ' + COINUNIT);
+ }
- $("#btnrejectinvoice").bind('touchstart', function () {
- Engine.updateInvoice(selectedInvoiceUserName, selectedInvoiceId, '', 2, function (err, result) {
- loadInvoices(function (err, res) {
+ $("#dashsend").addClass("invis");
+ $("#dashsend").removeClass("slideUp");
- lastInvoiceToPayCount = 0;
- showInvoiceListNetwork();
+ $("#dashsendamt").addClass("invis");
+ $("#dashsendamt").removeClass("slideUp");
- $("#invoicedisplay").hide();
- $("#invoicestopay").show();
- $("#createinv").show();
- updateSelectedFriend();
- });
- });
+ //sendMoneyStd();
});
- $("#payinvoicecancel").bind('touchstart', function () {
-
+ $("#btnCloseValidate").bind('touchstart', function () {
- $("#invoices").hide();
- $("#network").show();
- $("#pnlfriend").show();
$("#friendheader").show();
- //if (uiInvoiceReturnToNetwork) {
- //$("#hnetwork").click();
- //uiInvoiceReturnToNetwork = false;
- //}
+ $("#mainWallet").show();
+ $(".footer").show();
+ $("#networkvalidate").hide();
+
+ });
+
+ $("#tapvalidatefriend").bind('touchstart', function () {
+ $("#friendheader").hide();
+ $("#mainWallet").hide();
+ $(".footer").hide();
+ $("#networkvalidate").show();
});
- });
+ $("#tapsendfriend").bind('touchstart', function () {
+ sendmode = "net";
- var lastInvoiceToPayNetCount = 0;
- var uiInvoiceReturnToNetwork = false;
+ $("#sendsubheading").text("send to " + SELECTEDFRIEND);
- var cachedInvoices = [];
- var cachedInvoicesByUser = [];
+ $("#btnStdSndDone").hide();
+ $("#dashsend").addClass("invis");
+ $("#dashsend").removeClass("slideUp");
- function showInvoiceListNetwork() {
+ $("#addrfade").hide();
- var invoices = _.filter(cachedInvoices, function (inv) { return inv.InvoiceFrom == SELECTEDFRIEND; });
+ $("#friendheader").hide();
+ $("#dashsendamt").show();
+ $("#dashsendamt").removeClass("invis");
+ $("#dashsendamt").addClass("slideUp");
- if (invoices.length == 0) {
- $('#invfornet').empty();
- $('#invfornet').hide();
- }
- //if (lastInvoiceToPayNetCount < invoices.length) {
+ $("#mainWallet").hide();
+ $(".footer").hide();
- lastInvoiceToPayNetCount = invoices.length;
- var s = '';
- $('#invfornet').empty();
+ networkpagestate = "friend";
+ friendpagestate = "send";
- for (var i = 0; i < invoices.length; i++) {
+ updateStdAmount();
- var invdate = new Date(invoices[i].InvoiceDate.match(/\d+/)[0] * 1);
+ });
- var timeLabel = prettydate.format(invdate);
+ $("#tapsend").bind('touchstart', function () {
- var statusbox = '';
- if (invoices[i].InvoiceStatus == 0) {
- statusbox = ' Pending';
- }
- else if (invoices[i].InvoiceStatus == 1) {
- statusbox = ' Paid';
- }
- else if (invoices[i].InvoiceStatus == 2) {
- statusbox = ' Rejected';
- }
-
- s += "" + _.escape(timeLabel) + "
" +
- "" + statusbox + "
";
- }
-
- $('#invfornet').append(s);
-
- for (var i = 0; i < invoices.length; i++) {
-
- $("#invfornet #viewinvoicenetfrom" + invoices[i].InvoiceFrom + invoices[i].InvoiceId).hammer(null).bind("tap", {
- index: invoices[i].InvoiceId, username: invoices[i].InvoiceFrom
- }, function (event) {
-
- $("#invtapspinner").show();
- var target = document.getElementById('invtapspinner');
- var spinner = new Spinner(spinneropts).spin(target);
+ sendmode = "std";
+ $("#sendsubheading").text('');
+ $("#dashheader").hide();
+ $("#dashprofile").hide();
+ $("#dashboard").hide();
- displayInvoice(event.data.index, event.data.username, 'forme', function (err, res) {
- uiInvoiceReturnToNetwork = true;
+ $("#dashsend").addClass("slideUp");
- networkpagestate = "invoice";
- friendpagestate = "invoice";
+ //$("#dashsend").removeClass("invis");
- $("#invtapspinner").hide();
- $('#pnlfriend').hide();
- $("#friendheader").hide();
- $('#invoices').show();
- });
- });
- }
+ setTimeout(function () {
+ $("#addrfade").fadeIn(500);
- $('#invfornet').show();
+ }, 500);
- //}
+ $("#dashsendamt").addClass("invis");
+ $("#dashsendamt").removeClass("slideUp");
+ $("#dashsendamt").hide();
- // $('#pnlfriendinv').show();
+ $("#mainWallet").hide();
+ $(".footer").hide();
+ //$("#dashreceive").hide();
+ //$("#dashcontact").hide();
- }
+ $("#toAddress").blur();
+ $("#qr").focus();
+ $("#btnStdSndDone").hide();
- var lastInvoiceByMeNetCount = 0;
- function showInvoiceByMeListNetwork() {
+ profilepagestate = "send";
+ menustate = "profile"
- var invoices = _.filter(cachedInvoicesByUser, function (inv) { return inv.InvoiceFrom == SELECTEDFRIEND; });
- if (invoices.length == 0) {
- $('#invbynet').empty();
- $('#invbynet').hide();
- }
+ });
+ $("#tapreceive").bind('touchstart', function () {
- if (lastInvoiceByMeNetCount < invoices.length) {
- lastInvoiceByMeNetCount = invoices.length;
- var s = '';
- $('#invbynet').empty();
+ //dashreceive
+ $("#dashheader").hide();
+ $("#dashprofile").hide();
- for (var i = 0; i < invoices.length; i++) {
- var invdate = new Date(invoices[i].InvoiceDate.match(/\d+/)[0] * 1);
+ $("#mainWallet").hide();
- var timeLabel = prettydate.format(invdate);
+ $("#dashreceive").addClass("slideUp");
+ $(".footer").hide();
- var statusbox = '';
- if (invoices[i].InvoiceStatus == 0) {
- statusbox = ' Pending';
- }
- else if (invoices[i].InvoiceStatus == 1) {
- statusbox = ' Paid';
- }
- else if (invoices[i].InvoiceStatus == 2) {
- statusbox = ' Rejected';
- }
+ profilepagestate = "receive";
+ menustate = "profile"
- s += "" + _.escape(timeLabel) + "
" +
- "" + statusbox + "
";
- }
+ setTimeout(generateAddressClient(), 1000);
- $('#invbynet').append(s);
- for (var i = 0; i < invoices.length; i++) {
+ });
- $("#invbynet #viewinvoicenetby" + invoices[i].InvoiceFrom + invoices[i].InvoiceId).hammer(null).bind("tap", {
- index: invoices[i].InvoiceId, username: invoices[i].InvoiceFrom
- }, function (event) {
+ $("#taprequest").bind('touchstart', function () {
+ $("#mainWallet").hide();
+ $("#networklistheader").hide();
- $("#invtapspinner").show();
- var target = document.getElementById('invtapspinner');
- var spinner = new Spinner(spinneropts).spin(target);
+ $("#dashcontact").addClass("slideUp");
- displayInvoice(event.data.index, event.data.username, 'byme', function (err, res) {
+ //$("#dashcontact").show();
- networkpagestate = "invoice";
- friendpagestate = "invoice";
- $("#invtapspinner").hide();
- $('#pnlfriend').hide();
- $("#friendheader").hide();
- $('#invoices').show();
+ $(".footer").hide();
- });
- });
- }
+ //checkAndValidateTimer = setInterval(function () { checkAndValidateFriendRequests() }, 2000);
- $('#invbynet').show();
+ //profilepagestate = "contact";
+ //menustate = "profile"
+ });
- }
+ });
- // $('#pnlfriendinv').show();
+ $(document).ready(function () {
- }
+ $("#pairdeviceblob").change(function () {
+ if ($("#pairdeviceblob").val().length > 10) {
- var selectedInvoiceAmount = 0;
- var selectedInvoiceId = 0;
- var selectedInvoiceUserName = '';
+ var check = $("#pairdeviceblob").val().split('|');
+ $("#pairdevicealert").hide();
- function displayInvoiceDetails(invoice, json, invtype, callback) {
+ if (check.length == 5) {
+ $("#loginpin").hide();
+ $("#pairstep1").hide();
- var invdate = new Date(invoice.InvoiceDate.match(/\d+/)[0] * 1).toLocaleString();
- $("#createinv").hide();
- $("#invoicestopay").hide();
+ $("#pairstep2").show();
+ $("#pairpwd").focus();
- $('#tblinvdisplay tbody').empty();
- var s = '';
- for (var i = 0; i < json.invoicelines.length; i++) {
- s += "" + _.escape(json.invoicelines[i].description) + " | " + _.escape(json.invoicelines[i].quantity) + " | " + _.escape(convertFromSatoshis(json.invoicelines[i].amount, COINUNIT)) + " | " + _.escape(convertFromSatoshis(json.invoicelines[i].amount, COINUNIT) * json.invoicelines[i].quantity) + " |
";
- }
+ } else {
- $('#tblinvdisplay tbody').append(s);
+ bootbox.alert("There was a pairing error, please try again.");
- if (invtype == 'forme') {
- $("#dinvusername").text('Invoice from ' + invoice.InvoiceFrom);
- } else {
- $("#dinvusername").text('Invoice to ' + invoice.InvoiceFrom);
- }
+ }
+ } else {
- $("#dinvdate").text(invdate);
- $("#tblinvdisplay tfoot th #dsubtotal").text(convertFromSatoshis(json.summary.subtotal, COINUNIT));
- $("#tblinvdisplay tfoot th #dtax").text(convertFromSatoshis(json.summary.tax, COINUNIT));
- $("#tblinvdisplay tfoot th #dtotal").text(convertFromSatoshis(json.summary.total, COINUNIT));
+ bootbox.alert("There was a pairing error, please try again.");
- selectedInvoiceAmount = convertFromSatoshis(json.summary.total);
- selectedInvoiceId = invoice.InvoiceId;
- selectedInvoiceUserName = invoice.InvoiceFrom;
+ }
- $("#sendinvprog").hide();
- $("#textMessageSendInv").hide();
- $("#btnokinvoice").hide();
- $("#invvalmess").hide();
- if (invtype == 'forme') {
- if (invoice.InvoiceStatus == 0) {
- $("#payinvoicecancel").show();
- $("#btnpayinvoice").show();
- $("#btnrejectinvoice").show();
+ });
- if (!FRIENDSLIST[invoice.InvoiceFrom].validated) {
- $("#btnpayinvoice").addClass("disabled");
- $("#invvalt").text(invoice.InvoiceFrom);
- $("#invvalmess").show();
- } else {
- $("#btnpayinvoice").removeClass("disabled");
- $("#invvalmess").hide();
- }
- }
+ $("#btnUnpair").click(function () {
- if (invoice.InvoiceStatus == 1 || invoice.InvoiceStatus == 2) {
- $("#btnokinvoice").show();
- $("#payinvoicecancel").hide();
- $("#btnpayinvoice").hide();
- $("#btnrejectinvoice").hide();
- }
- } else {
- $("#btnokinvoice").show();
- $("#payinvoicecancel").hide();
- $("#btnpayinvoice").hide();
- $("#btnrejectinvoice").hide();
- }
+ bootbox.confirm("Are you sure?", function (result) {
- var statusbox = '';
- if (invoice.InvoiceStatus == 0) {
- statusbox = ' Pending';
- }
- else if (invoice.InvoiceStatus == 1) {
- statusbox = ' Paid';
- }
- else if (invoice.InvoiceStatus == 2) {
- statusbox = ' Rejected';
- }
+ if (result) {
- $("#invdisstatus").html(statusbox);
- $("#invdisid").text(invoice.InvoiceFrom.toUpperCase() + invoice.InvoiceId);
+ Engine.Device.getStorageItem("guid", function (guid) {
+ Engine.m_oguid = guid;
- $("#invoicedisplay").show();
+ var bytes = [];
+ for (var i = 0; i < guid.length; ++i) {
+ bytes.push(guid.charCodeAt(i));
+ }
- return callback(false, "ok");
- }
+ Engine.m_guid = Bitcoin.Crypto.SHA256(Bitcoin.convert.bytesToWordArray(bytes)).toString();
- function displayInvoiceByUser(invoiceid, username, invtype, callback) {
+ Engine.destroyDevice(function (err, res) {
- var invoice = _.find(cachedInvoicesByUser, function (inv) { return inv.InvoiceId == invoiceid; });
+ //call to server
+ location.reload();
- //here decrypt the invoice with my private key
+ });
- Engine.UnpackInvoiceByMe(invoice, username, function (err, unpacked) {
+ //always destroy locally
+ Engine.Device.deleteStorageItem("ninki_rem");
+ Engine.Device.deleteStorageItem("ninki_p");
+ Engine.Device.deleteStorageItem("ninki_reg");
+ Engine.Device.deleteStorageItem("ninki_h");
+ Engine.Device.deleteStorageItem("guid");
+ Engine.Device.deleteStorageItem("coinunit");
+ Engine.Device.deleteStorageItem("currency");
- displayInvoiceDetails(invoice, unpacked, invtype, function (err, res) {
+ });
- callback(false, "ok");
+ }
});
});
- }
-
+ $("#btnPairDevice").bind('touchstart', function () {
+ $("#pairpwd").blur();
- function displayInvoice(invoiceid, username, invtype, callback) {
+ pairDevice();
- var invoice;
- //find by invoicefrom and invoice id
+ });
- if (invtype == 'forme') {
- invoice = _.find(cachedInvoices, function (inv) { return inv.InvoiceFrom == username && inv.InvoiceId == invoiceid; });
- } else {
- invoice = _.find(cachedInvoicesByUser, function (inv) { return inv.InvoiceFrom == username && inv.InvoiceId == invoiceid; });
- }
+ $("#btnaddfriend").bind('touchstart', function () {
- Engine.UnpackInvoiceForMe(invoice, username, invtype, function (err, unpacked) {
+ addFriend($('input#friend').val());
- displayInvoiceDetails(invoice, unpacked, invtype, function (err, res) {
+ });
- callback(false, "ok");
+ $("#btngenaddr").bind('touchstart', function () {
- });
+ generateAddressClient();
});
- }
+ $("#btnSendToFriend").bind('touchstart', function () {
- function payInvoice(friend, amount, invoiceNumber) {
+ sendMoney(SELECTEDFRIEND, 0);
- var pin = $('#sendstdpin').val();
- Engine.getDeviceKey(pin, function (err, ekey) {
+ });
- if (!err) {
+ $("#sendfriendprog").hide();
- $('#sendprogress').show();
- $('#pinconfirm').hide();
+ $("#btnVerify").bind('touchstart', function () {
+ var code = $("#txtCode").val();
- $('#textMessageSendStd').text('Creating transaction...');
- $('#textMessageSendStd').show();
- $('#sendstdprogstatus').width('3%')
- $('#sendstdprog').show();
- $('#sendstdprogstatus').width('10%');
+ $("#txtCode").css("border-color", "#ccc");
+ $("#validatefail").hide();
+ $("#validatesuccess").hide();
- $('#sendstdprognum').text('10%');
+ var bip39 = new BIP39();
+ code = bip39.mnemonicToHex(code);
+ if (code.length != 40) {
+ $("#txtCode").css("border-color", "#ffaaaa");
+ return;
+ }
- Engine.sendTransaction('invoice', friend, '', amount, ekey.DeviceKey, function (err, transactionid) {
+ //get the hash to validate against
+ //this will confirm that my friend has the same keys
+ //i orginally packaged for him
- if (!err) {
+ Engine.verifyFriendData(SELECTEDFRIEND, code, function (err, result) {
- Engine.updateInvoice(friend, invoiceNumber, transactionid, 1, function (err, result) {
+ if (result) {
- if (!err) {
+ $("#txtCode").val('');
+ selectedFriend.validated = true;
+ FRIENDSLIST[selectedFriend.userName].validated = true;
+ updateSelectedFriend();
+ $("#networkvalidate").hide();
+ $("#friendheader").show();
+ $("#mainWallet").show();
+ $(".footer").show();
+ //update list also
- $('#textMessageSend').text('You paid invoice: ' + friend.toUpperCase() + invoiceNumber);
- $('input#amount').text('');
+ //find friend in list and update the validated icon
+ $("#myfriends #seltarget" + selectedFriend.userName).html('
');
- updateStdAmount();
- setTimeout(function () {
- $("#btnStdSndDone").show();
- }, 100);
+ } else {
+ $("#validatefail").show();
+ }
- $("#sendstdpin").val('');
- $('.numdone').attr("style", "background-color:white");
+ });
+ });
- updateBalance();
+ //INVOICE STUFF START------------------------------------------
+
+ $("#friendselector").hide();
+ $("#invoice").hide();
+ $("#invoicedisplay").hide();
+ $("#btnpayinvoice").bind('touchstart', function () {
- //change status
- var statusbox = ' Paid';
- $("#invdisstatus").html(statusbox);
+ $(".footer").hide();
- //hide buttons
- $("#payinvoicecancel").hide();
- $("#btnpayinvoice").hide();
- $("#btnrejectinvoice").hide();
- }
+ $("#sendstds2add").text(SELECTEDFRIEND);
- });
+ $("#sendstds2amt").text(convertFromSatoshis(selectedInvoiceAmount, COINUNIT) + ' ' + COINUNIT);
+ sendmode = 'inv';
- } else {
+ $('.numdone').attr("style", "background-color:white");
+ $("#sendstdpin").val('');
+ pintaps = 0;
+ prevpin = '';
- $('#textMessageSend').addClass('alert alert-danger');
- $('#sendstdprogstatus').width('0%')
+ $("#invoices").hide();
+ $("#mainWallet").hide();
+ $("#pinconfirm").show();
- if (transactionid == "ErrInsufficientFunds") {
- $('#textMessageSend').text('Transaction Failed: Waiting for funds to clear');
- }
- }
+ });
- });
+ $("#btnrejectinvoice").bind('touchstart', function () {
- } else {
+ Engine.updateInvoice(selectedInvoiceUserName, selectedInvoiceId, '', 2, function (err, result) {
- //display pin error
- $('.numdone').attr("style", "background-color:white");
- $("#sendstdpin").val('');
- $('#confpinalert').show();
- $('#confpinalertmess').text(ekey);
+ loadInvoices(function (err, res) {
- }
+ lastInvoiceToPayCount = 0;
+
+ showInvoiceListNetwork();
+
+ $("#invoices").hide();
+ $("#mainWallet").show();
+ $("#network").show();
+ $("#pnlfriend").show();
+ $("#friendheader").show();
+ $(".footer").show();
+
+ updateSelectedFriend();
+
+ });
+ });
});
- }
+ $("#payinvoicecancel").bind('touchstart', function () {
- //INVOICE FUNCTIONS END------------------------------------------
+ $("#invoices").hide();
+ $("#mainWallet").show();
+ $("#network").show();
+ $("#pnlfriend").show();
+ $("#friendheader").show();
+ $(".footer").show();
+ //if (uiInvoiceReturnToNetwork) {
+ //$("#hnetwork").click();
+ //uiInvoiceReturnToNetwork = false;
+ //}
- function initialiseDashboard() {
- $("#dashsend").hide();
- $("#dashreceive").hide();
- $("#dashcontact").hide();
- $('#invoices').hide();
- $('#network').hide();
- $('#networklist').hide();
- $("#networklistheader").hide();
- $('#settings').hide();
- $("#settingsheader").hide();
+ });
- var length = Engine.m_nickname.length;
- if (length > 20) {
- length = 20;
- }
+ });
- COINUNIT = Engine.m_settings.CoinUnit;
- $("#mynickname").text(Engine.m_nickname);
- $("#usernameProfile").text(Engine.m_nickname);
- $("#mystatus").text(Engine.m_statusText);
+ var lastInvoiceToPayNetCount = 0;
+ var uiInvoiceReturnToNetwork = false;
+
+ var cachedInvoices = [];
+ var cachedInvoicesByUser = [];
+ function showInvoiceListNetwork() {
- var imageSrc = "images/avatar/128px/Avatar-" + pad(length) + ".png";
- var imageSrcSmall = "images/avatar/64px/Avatar-" + pad(length) + ".png";
+ var invoices = _.filter(cachedInvoices, function (inv) { return inv.InvoiceFrom == SELECTEDFRIEND; });
- if (Engine.m_profileImage != '') {
- imageSrc = "https://ninkip2p.imgix.net/" + Engine.m_profileImage + "?crop=faces&fit=crop&h=128&w=128&mask=ellipse&border=1,d0d0d0";
- imageSrcSmall = "https://ninkip2p.imgix.net/" + Engine.m_profileImage + "?crop=faces&fit=crop&h=64&w=64&mask=ellipse&border=1,d0d0d0";
+
+ if (invoices.length == 0) {
+ $('#invfornet').empty();
+ $('#invfornet').hide();
}
- $("#imgProfile").attr("src", imageSrc);
- $("#imgtoprightprofile").attr("src", imageSrcSmall);
+ //if (lastInvoiceToPayNetCount < invoices.length) {
- $("#codeForFriend").text(Engine.m_fingerprint);
+ lastInvoiceToPayNetCount = invoices.length;
+ var s = '';
+ $('#invfornet').empty();
- Engine.getUserNetwork(function (err, friends) {
+ for (var i = 0; i < invoices.length; i++) {
- FRIENDSLIST = {};
+ var invdate = new Date(invoices[i].InvoiceDate.match(/\d+/)[0] * 1);
- for (var i = 0; i < friends.length; i++) {
- FRIENDSLIST[friends[i].userName] = friends[i];
+ var timeLabel = prettydate.format(invdate);
+
+ var statusbox = '';
+ if (invoices[i].InvoiceStatus == 0) {
+ statusbox = ' Pending';
+ }
+ else if (invoices[i].InvoiceStatus == 1) {
+ statusbox = ' Paid';
+ }
+ else if (invoices[i].InvoiceStatus == 2) {
+ statusbox = ' Rejected';
}
- //prep the network tab
- $("#networklist").show();
- //$("#networklistheader").show();
+ s += "" + _.escape(timeLabel) + "
" +
+ "" + statusbox + "
";
+ }
- showTransactionFeed(function (err, res) {
+ $('#invfornet').append(s);
- $('#dashboard').show();
- $('#dashheader').show();
+ for (var i = 0; i < invoices.length; i++) {
- $("#mainWallet").show();
- $(".footer").show();
+ $("#invfornet #viewinvoicenetfrom" + invoices[i].InvoiceFrom + invoices[i].InvoiceId).hammer(null).bind("tap", {
+ index: invoices[i].InvoiceId, username: invoices[i].InvoiceFrom
+ }, function (event) {
- updateUI();
+ $("#invtapspinner").show();
+ var target = document.getElementById('invtapspinner');
+ var spinner = new Spinner(spinneropts).spin(target);
- var data = Engine.m_fingerprint + ',' + Engine.m_nickname;
- var options = { text: data, width: 172, height: 172 };
+ displayInvoice(event.data.index, event.data.username, 'forme', function (err, res) {
+ uiInvoiceReturnToNetwork = true;
- $('#fingerprintqr').text('');
- $('#fingerprintqr').qrcode(options);
+ networkpagestate = "invoice";
+ friendpagestate = "invoice";
+ $("#invtapspinner").hide();
+ $('#pnlfriend').hide();
+ $("#friendheader").hide();
+ $(".footer").hide();
+ $('#invoices').show();
- setInterval(function () {
- updateUI();
+ });
+ });
+ }
- }, 10000);
+ $('#invfornet').show();
- });
+ //}
- });
+ // $('#pnlfriendinv').show();
}
+ var lastInvoiceByMeNetCount = 0;
+ function showInvoiceByMeListNetwork() {
- function loadInvoices(callback) {
+ var invoices = _.filter(cachedInvoicesByUser, function (inv) { return inv.InvoiceFrom == SELECTEDFRIEND; });
- //load the invoices into the cache
- cachedInvoices = [];
+ if (invoices.length == 0) {
+ $('#invbynet').empty();
+ $('#invbynet').hide();
+ }
- Engine.getInvoiceList(function (err, invoices) {
+ if (lastInvoiceByMeNetCount < invoices.length) {
- for (var i = 0; i < invoices.length; i++) {
- var d1 = new Date(invoices[i].InvoiceDate);
- invoices[i].JsDate = d1;
- }
+ lastInvoiceByMeNetCount = invoices.length;
- invoices = _.sortBy(invoices, function (inv) { return -inv.JsDate; });
- for (var i = 0; i < invoices.length; i++) {
+ var s = '';
+ $('#invbynet').empty();
- cachedInvoices.push(invoices[i]);
+ for (var i = 0; i < invoices.length; i++) {
- }
+ var invdate = new Date(invoices[i].InvoiceDate.match(/\d+/)[0] * 1);
- cachedInvoicesByUser = [];
+ var timeLabel = prettydate.format(invdate);
- Engine.getInvoiceByUserList(function (err, invoices) {
- for (var i = 0; i < invoices.length; i++) {
- var d1 = new Date(invoices[i].InvoiceDate);
- invoices[i].JsDate = d1;
+ var statusbox = '';
+ if (invoices[i].InvoiceStatus == 0) {
+ statusbox = ' Pending';
+ }
+ else if (invoices[i].InvoiceStatus == 1) {
+ statusbox = ' Paid';
+ }
+ else if (invoices[i].InvoiceStatus == 2) {
+ statusbox = ' Rejected';
}
- invoices = _.sortBy(invoices, function (inv) { return -inv.JsDate; });
+ s += "" + _.escape(timeLabel) + "
" +
+ "" + statusbox + "
";
+ }
- for (var i = 0; i < invoices.length; i++) {
- cachedInvoicesByUser.push(invoices[i]);
- }
+ $('#invbynet').append(s);
- if (callback) {
- return callback(false, "ok");
- }
+ for (var i = 0; i < invoices.length; i++) {
- });
+ $("#invbynet #viewinvoicenetby" + invoices[i].InvoiceFrom + invoices[i].InvoiceId).hammer(null).bind("tap", {
+ index: invoices[i].InvoiceId, username: invoices[i].InvoiceFrom
+ }, function (event) {
- });
- }
+ $("#invtapspinner").show();
+ var target = document.getElementById('invtapspinner');
+ var spinner = new Spinner(spinneropts).spin(target);
+ displayInvoice(event.data.index, event.data.username, 'byme', function (err, res) {
- function initialiseUI() {
+ networkpagestate = "invoice";
+ friendpagestate = "invoice";
+
+ $("#invtapspinner").hide();
+ $('#pnlfriend').hide();
+ $("#friendheader").hide();
+ $('.footer').hide();
+ $('#invoices').show();
+
+ });
+ });
+ }
+ $('#invbynet').show();
- //updateFriends(function (err, res) {
+ }
+ // $('#pnlfriendinv').show();
- //});
}
+ var selectedInvoiceAmount = 0;
+ var selectedInvoiceId = 0;
+ var selectedInvoiceUserName = '';
+ function displayInvoiceDetails(invoice, json, invtype, callback) {
- //OPEN/CREATE WALLET FUNCTIONS END---------------------------------------------
+ var invdate = new Date(invoice.InvoiceDate.match(/\d+/)[0] * 1).toString("yyyy-MM-dd HH:mm tt");
- function pad(n) {
- return (n < 10) ? ("0" + n) : n;
- }
-
- function logout() {
- location.reload();
- }
- UI.updateUITimer = function () {
- updateUI();
- }
- var prevBlock = 0;
+ $("#createinv").hide();
+ $("#invoicestopay").hide();
- function updateUI(callback) {
+ $('#tblinvdisplay tbody').empty();
+ var dp = 4;
- //All background UI activity controlled from here
- //The focus is on minimizing any activity
+ if (COINUNIT == "Bits") {
+ if (json.summary.total < 10000) {
+ dp = 2;
+ } else {
+ dp = 0;
+ }
+ }
- //get version
- //checks all infra
- //if error we have a problem
+ if (COINUNIT == "BTC") {
- var newBlock = false;
+ if (json.summary.total < 10000) {
+ dp = 8;
+ } else {
+ dp = 4;
+ }
+ }
- Engine.getVersion(function (err, res) {
+ var s = '';
+ for (var i = 0; i < json.invoicelines.length; i++) {
+ if (COINUNIT == "Bits") {
+ s += "" + _.escape(json.invoicelines[i].description) + " | " + _.escape(json.invoicelines[i].quantity) + " | " + _.escape(accounting.formatNumber(convertFromSatoshis(json.invoicelines[i].amount, COINUNIT), dp, ",", ".")) + " | " + _.escape(accounting.formatNumber(convertFromSatoshis(json.invoicelines[i].amount, COINUNIT) * json.invoicelines[i].quantity, dp, ",", ".")) + " |
";
+ } else {
+ s += "" + _.escape(json.invoicelines[i].description) + " | " + _.escape(json.invoicelines[i].quantity) + " | " + _.escape(accounting.formatNumber(convertFromSatoshis(json.invoicelines[i].amount, COINUNIT), dp, ",", ".")) + " | " + _.escape(accounting.formatNumber(convertFromSatoshis(json.invoicelines[i].amount, COINUNIT) * json.invoicelines[i].quantity, dp, ",", ".")) + " |
";
+ }
+ }
- if (!err) {
+ $('#tblinvdisplay tbody').append(s);
- var stats = JSON.parse(res);
+ if (invtype == 'forme') {
+ $("#dinvusername").text('Invoice from ' + invoice.InvoiceFrom);
+ } else {
+ $("#dinvusername").text('Invoice to ' + invoice.InvoiceFrom);
+ }
- if (prevBlock != stats.BlockNumber) {
- newBlock = true;
- }
+ $("#dinvdate").text(invdate);
- prevBlock = stats.BlockNumber;
- //Always
+ $("#tblinvdisplay tfoot th #dsubtotal").text(accounting.formatNumber(convertFromSatoshis(json.summary.subtotal, COINUNIT), dp, ",", "."));
+ $("#tblinvdisplay tfoot th #dtax").text(accounting.formatNumber(convertFromSatoshis(json.summary.tax, COINUNIT), dp, ",", "."));
+ $("#tblinvdisplay tfoot th #dtotal").text(accounting.formatNumber(convertFromSatoshis(json.summary.total, COINUNIT), dp, ",", "."));
- updateBalance(function (err, hasChanged) {
- //do we need to update transactions
- //1. is our balance different from the last request?
- //if it is immediately update transactions
- //2. do we have a new block?
- //if so then call updatetransactions
- //if (hasChanged || newBlock) {
+ selectedInvoiceAmount = convertFromSatoshis(json.summary.total);
+ selectedInvoiceId = invoice.InvoiceId;
+ selectedInvoiceUserName = invoice.InvoiceFrom;
- //update transactions?
+ $("#sendinvprog").hide();
+ $("#textMessageSendInv").hide();
+ $("#btnokinvoice").hide();
+ $("#invvalmess").hide();
- showTransactionFeed(function (err, result) {
+ if (invtype == 'forme') {
+ if (invoice.InvoiceStatus == 0) {
- loadInvoices(function (err, result) {
+ $("#payinvoicecancel").show();
+ $("#btnpayinvoice").show();
+ $("#btnrejectinvoice").show();
- updateSelectedFriend();
+ if (!FRIENDSLIST[invoice.InvoiceFrom].validated) {
+ $("#btnpayinvoice").addClass("disabled");
+ $("#invvalt").text(invoice.InvoiceFrom);
+ $("#invvalmess").show();
+ } else {
+ $("#btnpayinvoice").removeClass("disabled");
+ $("#invvalmess").hide();
+ }
- });
+ }
+ if (invoice.InvoiceStatus == 1 || invoice.InvoiceStatus == 2) {
+ $("#btnokinvoice").show();
+ //$("#payinvoicecancel").hide();
+ $("#btnpayinvoice").hide();
+ $("#btnrejectinvoice").hide();
+ }
+ } else {
+ $("#btnokinvoice").show();
+ //$("#payinvoicecancel").hide();
+ $("#btnpayinvoice").hide();
+ $("#btnrejectinvoice").hide();
+ }
+ var statusbox = '';
+ if (invoice.InvoiceStatus == 0) {
+ statusbox = ' Pending';
+ }
+ else if (invoice.InvoiceStatus == 1) {
+ statusbox = ' Paid';
+ }
+ else if (invoice.InvoiceStatus == 2) {
+ statusbox = ' Rejected';
+ }
- });
+ $("#invdisstatus").html(statusbox);
+ $("#invdisid").text(invoice.InvoiceFrom.toUpperCase() + invoice.InvoiceId);
- updateFriendRequests(function (err, res) {
+ $("#invoicedisplay").show();
+ return callback(false, "ok");
+ }
+ function displayInvoiceByUser(invoiceid, username, invtype, callback) {
- });
+ var invoice = _.find(cachedInvoicesByUser, function (inv) { return inv.InvoiceId == invoiceid; });
+ //here decrypt the invoice with my private key
- updateFriends(function (err, res) {
+ Engine.UnpackInvoiceByMe(invoice, username, function (err, unpacked) {
+ displayInvoiceDetails(invoice, unpacked, invtype, function (err, res) {
+ callback(false, "ok");
- });
+ });
+ });
+ }
- //update selected friend transactions also
- //}
+ function displayInvoice(invoiceid, username, invtype, callback) {
- });
+ var invoice;
+ //find by invoicefrom and invoice id
+ if (invtype == 'forme') {
+ invoice = _.find(cachedInvoices, function (inv) { return inv.InvoiceFrom == username && inv.InvoiceId == invoiceid; });
+ } else {
+ invoice = _.find(cachedInvoicesByUser, function (inv) { return inv.InvoiceFrom == username && inv.InvoiceId == invoiceid; });
+ }
+ if (invoice) {
- //Always
- Ninki.API.getPrice(Engine.m_guid, Engine.m_settings.LocalCurrency, function (err, result) {
-
-
- result = _.escape(result);
- price = result * 1.0;
-
- var loc = "en-US";
- var cprc = "";
- if (Engine.m_settings.LocalCurrency == "JPY" || Engine.m_settings.LocalCurrency == "CNY") {
- cprc = accounting.formatMoney(result, "¥", 0);
- } else if (Engine.m_settings.LocalCurrency == "GBP") {
- cprc = accounting.formatMoney(result, "£", 2);
- } else if (Engine.m_settings.LocalCurrency == "EUR") {
- cprc = accounting.formatMoney(result, "€", 2);
- } else if (Engine.m_settings.LocalCurrency == "USD") {
- cprc = accounting.formatMoney(result, "$", 2);
- } else if (Engine.m_settings.LocalCurrency == "CNY") {
- cprc = accounting.formatMoney(result, "¥", 2);
- }
+ Engine.UnpackInvoiceForMe(invoice, username, invtype, function (err, unpacked) {
+ displayInvoiceDetails(invoice, unpacked, invtype, function (err, res) {
+ callback(false, "ok");
+ });
- $('#homeprice').html(cprc);
+ });
+ } else {
- // + ' / BTC'
+ $("#invtapspinner").hide();
- });
+ }
- }
+ }
- });
+ function payInvoice(friend, amount, invoiceNumber) {
+ var pin = $('#sendstdpin').val();
+ Engine.getDeviceKey(pin, function (err, ekey) {
- }
+ if (!err) {
- function convertFromSatoshis(amount, toUnit) {
+ $("#btnStdSndDone").hide();
- if (toUnit == 'BTC') {
- amount = amount / 100000000;
- }
+ $('#sendprogress').show();
+ $('#pinconfirm').hide();
+ $('#invoices').hide();
- if (toUnit == 'mBTC') {
- amount = amount / 100000;
- }
+ $('#textMessageSendStd').text('Creating transaction...');
+ $('#textMessageSendStd').show();
+ $('#sendstdprogstatus').width('3%');
+ $('#sendstdprog').show();
+ $('#sendstdprogstatus').width('10%');
- if (toUnit == 'uBTC') {
- amount = amount / 100;
- }
+ $('#sendstdprognum').text('10%');
- if (toUnit == 'Bits') {
- amount = amount / 100;
- }
+ setTimeout(function () {
+ Engine.sendTransaction('invoice', friend, '', amount, ekey.DeviceKey, function (err, transactionid) {
- return amount;
- }
-
- function convertToSatoshis(amount, fromUnit) {
+ if (!err) {
- if (fromUnit == 'BTC') {
- amount = amount * 100000000;
- }
+ Engine.updateInvoice(friend, invoiceNumber, transactionid, 1, function (err, result) {
- if (fromUnit == 'mBTC') {
- amount = amount * 100000;
- }
+ if (!err) {
- if (fromUnit == 'uBTC') {
- amount = amount * 100;
- }
+ $('#textMessageSendStd').text('You paid invoice: ' + friend.toUpperCase() + invoiceNumber);
- if (fromUnit == 'Bits') {
- amount = amount * 100;
- }
+ updateStdAmount();
- amount = Math.round(amount)
- return amount;
- }
+ setTimeout(function () {
+ $("#btnStdSndDone").show();
+ }, 100);
+ $("#sendstdpin").val('');
+ $('.numdone').attr("style", "background-color:white");
+ pintaps = 0;
+ prevpin = '';
- var previousBalance = 0;
+ updateBalance();
- function updateBalance(callback) {
- Engine.getBalance(function (err, result) {
+ //change status
+ var statusbox = ' Paid';
+ $("#invdisstatus").html(statusbox);
- if (!err) {
- //get in BTC units
- var balance = convertFromSatoshis(result.TotalBalance, COINUNIT);
+ //hide buttons
+ //$("#payinvoicecancel").hide();
+ $("#btnpayinvoice").hide();
+ $("#btnrejectinvoice").hide();
- $("#homebalance").text(balance);
- $("#homecoinunit").text(COINUNIT);
- $("#calcbalance").text(balance);
- $("#calccoinunit").text(COINUNIT);
+ }
- var template = '';
- if (result.UnconfirmedBalance > 0) {
- template += '';
- } else {
- template += '';
- }
+ });
- var templatecalc = '';
- if (result.UnconfirmedBalance > 0) {
- templatecalc += '';
- } else {
- templatecalc += '';
- }
- $("#hometimer").html(template);
- $("#calctimer").html(templatecalc);
+ } else {
+ $('#sendstdprogstatus').width('0%');
+ $('#sendstdprognum').text('0%');
- if (previousBalance != result.TotalBalance || result.UnconfirmedBalance > 0) {
+ if (transactionid == "ErrInsufficientFunds") {
+ $('#textMessageSendStd').text('Transaction Failed: Waiting for funds to clear');
+ }
- previousBalance = result.TotalBalance;
+ //return to send screen
+ setTimeout(function () {
+ $("#btnStdSndDone").show();
+ }, 100);
- if (callback) {
- callback(err, true);
- }
+ }
- } else {
+ }, function (message, progress) {
- if (result.UnconfirmedBalance == 0) {
- if (callback) {
- callback(err, false);
+ if (message) {
+ $('#textMessageSendStd').text(message);
}
- } else {
- if (callback) {
- callback(err, true);
+
+ if (progress) {
+ $('#sendstdprogstatus').width(progress);
+ $('#sendstdprognum').text(progress);
}
- }
- }
+ });
+ }, 50);
} else {
- callback(true, "Error");
+ //display pin error
+ $('.numdone').attr("style", "background-color:white");
+ $("#sendstdpin").val('');
+ pintaps = 0;
+ prevpin = '';
+
+ $('#confpinalert').show();
+ $('#confpinalertmess').text(ekey);
}
});
-
-
}
- function updateNetwork() {
- // getNewFriends();
- //updateFriendRequests();
- getNewFriends();
- }
+ //INVOICE FUNCTIONS END------------------------------------------
+ function initialiseDashboard(callback) {
+ $("#dashsend").addClass("invis");
+ $("#dashsend").removeClass("slideUp");
- var previousReqByMe = 0;
- function updateRequestsMadeByMe(callback) {
+ $("#dashreceive").addClass("invis");
+ $("#dashreceive").removeClass("slideUp");
- Engine.getPendingUserRequests(function (err, friends) {
+ $("#dashcontact").addClass("invis");
+ $("#dashcontact").removeClass("slideUp");
+ //$("#dashreceive").hide();
+ //$("#dashcontact").hide();
- if (friends.length != previousReqByMe) {
- previousReqByMe = friends.length;
- $("#requestssent").text('');
- for (var i = 0; i < friends.length; i++) {
- var length = friends[i].userName.length;
- if (length > 20) {
- length = 20;
- }
+ $('#invoices').hide();
+ $('#network').hide();
+ $('#networklist').hide();
+ $("#networklistheader").hide();
+ $('#settings').hide();
+ $("#settingsheader").hide();
- var template = '' +
- '' +
- '';
+ var length = Engine.m_nickname.length;
+ if (length > 20) {
+ length = 20;
+ }
- $("#requestssent").append(template);
- }
- }
+ COINUNIT = Engine.m_settings.CoinUnit;
- if (friends.length > 0) {
- $("#requestsentpanel").show();
- } else {
- $("#requestsentpanel").hide();
- }
+ $("#mynickname").text(Engine.m_nickname);
+ $("#usernameProfile").text(Engine.m_nickname);
+ $("#mystatus").text(Engine.m_statusText);
- if (callback) {
- callback();
+ var imageSrc = "images/avatar/128px/Avatar-" + pad(length) + ".png";
+ var imageSrcSmall = "images/avatar/64px/Avatar-" + pad(length) + ".png";
- }
+ if (Engine.m_profileImage != '') {
+ imageSrc = "https://ninkip2p.imgix.net/" + Engine.m_profileImage + "?crop=faces&fit=crop&h=128&w=128&mask=ellipse&border=1,d0d0d0";
+ imageSrcSmall = "https://ninkip2p.imgix.net/" + Engine.m_profileImage + "?crop=faces&fit=crop&h=64&w=64&mask=ellipse&border=1,d0d0d0";
+ }
- });
+ $("#imgProfile").attr("src", imageSrc);
+ $("#imgtoprightprofile").attr("src", imageSrcSmall);
+ $("#codeForFriend").text(Engine.m_fingerprint);
- }
+ Engine.getUserNetwork(function (err, friends) {
+ FRIENDSLIST = {};
- var lastNoOfFriends = 0;
- var invoiceSelectedUser = '';
- var invoiceSelectedAmount = 0;
- var selectedFriend = null;
+ for (var i = 0; i < friends.length; i++) {
+ FRIENDSLIST[friends[i].userName] = friends[i];
+ }
- function updateFriends(callback) {
+ //prep the network tab
+ $("#networklist").show();
+ //$("#networklistheader").show();
- if (!noAlert == true) {
+ showTransactionFeed(function (err, res) {
- Engine.getUserNetwork(function (err, friends) {
+ updateBalance(function (err, hasChanged) {
- //$("#nfriends").text(friends.length);
+ updatePrice(function () {
- if (friends.length > lastNoOfFriends) {
+ if (callback) {
- lastNoOfFriends = friends.length;
+ callback();
- FRIENDSLIST = {};
+ }
- for (var i = 0; i < friends.length; i++) {
- FRIENDSLIST[friends[i].userName] = friends[i];
- }
+ });
+
+ });
- //if selected friend is not isend and isreceive
- //then find in list and update
- // if (selectedFriend != null) {
+ updateUI();
- // if (!selectedFriend.ICanSend || !selectedFriend.ICanReceive) {
- // selectedFriend = FRIENDSLIST[selectedFriend.userName];
- // updateSelectedFriend();
- // }
+ var data = Engine.m_fingerprint + ',' + Engine.m_nickname;
+ var options = { text: data, width: 172, height: 172 };
- // }
+ $('#fingerprintqr').text('');
+ $('#fingerprintqr').qrcode(options);
+ $('#qrcontscan').text('');
+ $('#qrcontscan').qrcode(options);
- $("#nfriends").text(friends.length);
- $("#myfriends").text('');
+ setInterval(function () {
- var grouptemplate = '';
+ updateUI();
- var friendsgroup = _.groupBy(friends, function (item) { return item.category; })
+ }, 10000);
- grouptemplate += '';
- var k = 0;
- var g = 1;
- for (var key in friendsgroup) {
+ });
- friends = friendsgroup[key];
+ });
- grouptemplate += '
';
- grouptemplate += '
';
- grouptemplate += '
';
+ }
- for (var i = 0; i < friendsgroup[key].length; i++) {
+ function loadInvoices(callback) {
- var frnd = FRIENDSLIST[friends[i].userName];
+ //load the invoices into the cache
+ //cachedInvoices = [];
- var length = frnd.userName.length;
- if (length > 20) {
- length = 20;
- }
+ var tmpCachedInvoices = [];
+ Engine.getInvoiceList(function (err, invoices) {
- var imageSrc = "images/avatar/64px/Avatar-" + pad(length) + ".png";
+ for (var i = 0; i < invoices.length; i++) {
+ var d1 = new Date(invoices[i].InvoiceDate);
+ invoices[i].JsDate = d1;
+ }
- if (frnd.profileImage != '') {
- imageSrc = "https://ninkip2p.imgix.net/" + _.escape(frnd.profileImage) + "?crop=faces&fit=crop&h=256&w=256&mask=ellipse&border=1,d0d0d0";
- imageSrcSmall = "https://ninkip2p.imgix.net/" + _.escape(frnd.profileImage) + "?crop=faces&fit=crop&h=128&w=128&mask=ellipse&border=1,d0d0d0";
- }
+ invoices = _.sortBy(invoices, function (inv) { return -inv.JsDate; });
+ for (var i = 0; i < invoices.length; i++) {
+ tmpCachedInvoices.push(invoices[i]);
- var template = '
';
+ var tmpCachedInvoicesByUser = [];
- grouptemplate += template;
+ Engine.getInvoiceByUserList(function (err, invoices) {
+
+ for (var i = 0; i < invoices.length; i++) {
+ var d1 = new Date(invoices[i].InvoiceDate);
+ invoices[i].JsDate = d1;
+ }
+ invoices = _.sortBy(invoices, function (inv) { return -inv.JsDate; });
+ for (var i = 0; i < invoices.length; i++) {
+ tmpCachedInvoicesByUser.push(invoices[i]);
+ }
- k++;
- }
+ cachedInvoicesByUser = tmpCachedInvoicesByUser;
+ if (callback) {
+ return callback(false, "ok");
+ }
- grouptemplate += '
';
- grouptemplate += '
';
- g++;
- }
+ });
- grouptemplate += '
';
+ });
- $("#myfriends").html(grouptemplate);
+ }
+ function initialiseUI() {
- $('#myfriends #accordion2').on('touchstart.collapse.data-api', '[data-toggle=collapse]', function (e) {
- var $this = $(this);
+ //updateFriends(function (err, res) {
- $this.click();
- //href, target = $this.attr('data-target') || e.preventDefault() || (href = $this.attr('href')) //strip for ie7
- //,
- //option = $(target).data('collapse') ? 'show' : $this.data()
- //$(target).collapse(option)
- });
+ //});
+ }
- var k = 0;
- var g = 1;
- for (var key in friendsgroup) {
- friends = friendsgroup[key];
- for (var i = 0; i < friendsgroup[key].length; i++) {
+ //OPEN/CREATE WALLET FUNCTIONS END---------------------------------------------
- friends = friendsgroup[key];
+ function pad(n) {
+ return (n < 10) ? ("0" + n) : n;
+ }
+ function logout() {
+ location.reload();
+ }
- //var btnfriend = $("#myfriends #friend" + k).get();
- //var hammertime = new Hammer(btnfriend[0]);
+ UI.updateUITimer = function () {
+ updateUI();
+ };
- $("#myfriends #friend" + k).hammer(null).bind("tap", { userName: friends[i].userName }, function (ev) {
- SELECTEDFRIEND = ev.data.userName;
- selectedFriend = FRIENDSLIST[ev.data.userName];
- prevNetworkTransCount = 0;
+ var prevBlock = 0;
- networkpagestate = "friend";
- friendpagestate = "send"
- $("#networklistheader").hide();
- $("#friendheader").show();
- $("#pnlfriend").show();
+ function updateUI(callback) {
- $('#netpayfeed').html('');
- $("#networkpayments").show();
- $("#networklist").hide();
+ //All background UI activity controlled from here
+ //The focus is on minimizing any activity
- $("#pnlfriendinv").hide();
- window.scrollTo(0, 0);
+ //get version
+ //checks all infra
+ //if error we have a problem
- updateSelectedFriend();
+ var newBlock = false;
- });
+ Engine.getVersion(function (err, res) {
- //console.log("added click " + k + " for " + friends[i].userName);
+ if (!err) {
- k++;
- }
- g++;
- }
+ var stats = JSON.parse(res);
+ if (prevBlock != stats.BlockNumber) {
+ newBlock = true;
}
- if (callback) {
- return callback(false, "done");
+
+ prevBlock = stats.BlockNumber;
+
+
+
+ if (stdAmountConvCoin) {
+ $('#stdselunit').text(COINUNIT);
+ } else {
+ $('#stdselunit').text(Engine.m_settings.LocalCurrency);
}
- });
- }
- }
- function showSecret() {
+ $('#stdsendcunit').text(COINUNIT);
- }
+ $('#stdsendlcurr').text(Engine.m_settings.LocalCurrency);
- function refreshSelectedFriend(callback) {
- if (SELECTEDFRIEND.length > 0) {
+ //Always
- Engine.getFriend(SELECTEDFRIEND, function (err, friend) {
- if (!norefresh) {
- if (SELECTEDFRIEND == friend.userName) {
- selectedFriend = friend;
- FRIENDSLIST[SELECTEDFRIEND] = friend;
+ updateBalance(function (err, hasChanged) {
- if (selectedFriend.ICanSend) {
- $("#issend").show();
- //$("#networksend").show();
- } else {
- $("#issend").hide();
- //$("#networksend").hide();
- }
- if (selectedFriend.ICanReceive) {
- $("#isreceive").show();
- } else {
- $("#isreceive").hide();
- }
- var imageSrc = "images/avatar/256px/Avatar-" + pad(SELECTEDFRIEND.length) + ".png";
+ //do we need to update transactions
+ //1. is our balance different from the last request?
+ //if it is immediately update transactions
- if (selectedFriend.profileImage != '') {
- imageSrc = "https://ninkip2p.imgix.net/" + selectedFriend.profileImage + "?crop=faces&fit=crop&h=256&w=256&mask=ellipse&border=1,d0d0d0";
- }
- if (selectedFriend.status != '') {
- $("#friendSelectedStatus").text(selectedFriend.status);
- }
+ //2. do we have a new block?
+ //if so then call updatetransactions
- $("#imgSelectedFriend").attr("src", imageSrc);
+ //if (hasChanged || newBlock) {
+ //update transactions?
+ showTransactionFeed(function (err, result) {
+ loadInvoices(function (err, result) {
- callback(err, friend);
+ updateSelectedFriend();
- //updateSelectedFriend(function (err, res) {
- // selFriendBkgUpdate = false;
- // callback(err, res);
- //});
- }
- }
- });
+ });
- }
- }
+ });
+ updateFriendRequests(function (err, res) {
- function updateSelectedFriend(callback) {
- //can optimise futher
- norefresh = true;
- if (SELECTEDFRIEND.length > 0) {
+
+ });
- $('input#friendAmount').val('');
+ updateFriends(function (err, res) {
+
+
+
+ });
+
+
+
+ //update selected friend transactions also
+ //}
+
+ });
+
+
+ updatePrice();
+
- var length = selectedFriend.userName.length;
- if (length > 20) {
- length = 20;
}
- //$("#nselnetcat").val(selectedFriend.category);
+ });
- $('#friendempty').hide();
- //$('#textMessageSend').removeClass('alert alert-danger');
+ }
- $('#textMessageSend').hide();
- $('#sendfriendprog').hide();
+ function updatePrice(callback) {
+ //Always
+ Ninki.API.getPrice(Engine.m_guid, Engine.m_settings.LocalCurrency, function (err, result) {
- $("#friendSelectedName").text(selectedFriend.userName);
- $("#friendSelectedNameTo").text(selectedFriend.userName);
- $("#validateusername2").text(selectedFriend.userName);
+
+ result = _.escape(result);
+ price = result * 1.0;
+
+ var loc = "en-US";
+ var cprc = "";
+ if (Engine.m_settings.LocalCurrency == "JPY" || Engine.m_settings.LocalCurrency == "CNY") {
+ cprc = accounting.formatMoney(result, "¥", 0);
+ } else if (Engine.m_settings.LocalCurrency == "GBP") {
+ cprc = accounting.formatMoney(result, "£", 2);
+ } else if (Engine.m_settings.LocalCurrency == "EUR") {
+ cprc = accounting.formatMoney(result, "€", 2);
+ } else if (Engine.m_settings.LocalCurrency == "USD") {
+ cprc = accounting.formatMoney(result, "$", 2);
+ } else if (Engine.m_settings.LocalCurrency == "CNY") {
+ cprc = accounting.formatMoney(result, "¥", 2);
+ }
+
+ $('#homeprice').html(cprc);
+
+ if (callback) {
+ callback();
+ }
+
+ // + ' / BTC'
+
+ });
+
+
+ }
+
+ function convertFromSatoshis(amount, toUnit) {
+
+ if (toUnit == 'BTC') {
+ amount = amount / 100000000;
+ }
+
+ if (toUnit == 'mBTC') {
+ amount = amount / 100000;
+ }
+
+ if (toUnit == 'uBTC') {
+ amount = amount / 100;
+ }
+
+ if (toUnit == 'Bits') {
+ amount = amount / 100;
+ }
+
+
+ return amount;
+ }
+
+ function convertToSatoshis(amount, fromUnit) {
+
+ if (fromUnit == 'BTC') {
+ amount = amount * 100000000;
+ }
+
+ if (fromUnit == 'mBTC') {
+ amount = amount * 100000;
+ }
+
+ if (fromUnit == 'uBTC') {
+ amount = amount * 100;
+ }
+
+ if (fromUnit == 'Bits') {
+ amount = amount * 100;
+ }
+
+ amount = Math.round(amount);
+ return amount;
+ }
+
+
+ var previousBalance = 0;
+
+ function updateBalance(callback) {
+
+ Engine.getBalance(function (err, result) {
+
+ if (!err) {
+
+ //get in BTC units
+ var balance = convertFromSatoshis(result.TotalBalance, COINUNIT);
+
+ currentBalance = balance;
+
+ var fbal = '';
+ if (COINUNIT == "BTC") {
+ fbal = accounting.formatMoney(balance, "", 4);
+ } else if (COINUNIT == "Bits") {
+ fbal = accounting.formatMoney(balance, "", 0);
+ } else {
+ fbal = accounting.formatMoney(balance, "", 2);
+ }
+
+ $("#homebalance").text(fbal);
+ $("#homecoinunit").text(COINUNIT);
+
+ $("#calcbalance").text(fbal);
+ $("#calccoinunit").text(COINUNIT);
+
+ var template = '';
+ if (result.UnconfirmedBalance > 0) {
+ template += '';
+ } else {
+ template += '';
+ }
+
+ var templatecalc = '';
+ if (result.UnconfirmedBalance > 0) {
+ templatecalc += '';
+ } else {
+ templatecalc += '';
+ }
+
+ $("#hometimer").html(template);
+ $("#calctimer").html(templatecalc);
+
+
+ if (previousBalance != result.TotalBalance || result.UnconfirmedBalance > 0) {
+
+ previousBalance = result.TotalBalance;
+
+ if (callback) {
+ callback(err, true);
+ }
+
+ } else {
+
+ if (result.UnconfirmedBalance == 0) {
+ if (callback) {
+ callback(err, false);
+ }
+ } else {
+ if (callback) {
+ callback(err, true);
+ }
+ }
+
+ }
+
+ } else {
+
+ callback(true, "Error");
+
+ }
+
+ });
+
+
+
+ }
+
+ function updateNetwork() {
+
+ // getNewFriends();
+ //updateFriendRequests();
+ getNewFriends();
+ }
+
+
+ var previousReqByMe = 0;
+ function updateRequestsMadeByMe(callback) {
+
+
+ Engine.getPendingUserRequests(function (err, friends) {
+
+
+ if (friends.length != previousReqByMe) {
+ previousReqByMe = friends.length;
+ $("#requestssent").text('');
+ for (var i = 0; i < friends.length; i++) {
+
+ var length = friends[i].userName.length;
+ if (length > 20) {
+ length = 20;
+ }
+
+ var template = '' +
+ '' +
+ '';
+
+ $("#requestssent").append(template);
+ }
+ }
+
+ if (friends.length > 0) {
+ $("#requestsentpanel").show();
+ } else {
+ $("#requestsentpanel").hide();
+ }
+
+ if (callback) {
+
+ callback();
+
+ }
+
+ });
+
+
+
+
+ }
+
+
+ var lastNoOfFriends = 0;
+ var invoiceSelectedUser = '';
+ var invoiceSelectedAmount = 0;
+ var selectedFriend = null;
+
+ function updateFriends(callback) {
+
+ if (!noAlert == true) {
+
+
+ Engine.getUserNetwork(function (err, friends) {
+
+
+ if (!err) {
+
+ //$("#nfriends").text(friends.length);
+
+ if (friends.length > lastNoOfFriends) {
+
+ lastNoOfFriends = friends.length;
+
+ FRIENDSLIST = {};
+
+ for (var i = 0; i < friends.length; i++) {
+ FRIENDSLIST[friends[i].userName] = friends[i];
+ }
+
+ //if selected friend is not isend and isreceive
+ //then find in list and update
+
+ // if (selectedFriend != null) {
+
+ // if (!selectedFriend.ICanSend || !selectedFriend.ICanReceive) {
+ // selectedFriend = FRIENDSLIST[selectedFriend.userName];
+ // updateSelectedFriend();
+ // }
+
+ // }
+
+
+ $("#nfriends").text(friends.length);
+ $("#myfriends").text('');
+
+
+ var grouptemplate = '';
+
+ var friendsgroup = _.groupBy(friends, function (item) { return item.category; });
+
+ grouptemplate += '';
+
+ var k = 0;
+ var g = 1;
+ for (var key in friendsgroup) {
+
+ friends = friendsgroup[key];
+
+ grouptemplate += '
';
+ grouptemplate += '
';
+ grouptemplate += '
';
+
+
+ for (var i = 0; i < friendsgroup[key].length; i++) {
+
+ var frnd = FRIENDSLIST[friends[i].userName];
+
+ var length = frnd.userName.length;
+ if (length > 20) {
+ length = 20;
+ }
+
+
+ var imageSrc = "images/avatar/64px/Avatar-" + pad(length) + ".png";
+
+ if (frnd.profileImage != '') {
+ imageSrc = "https://ninkip2p.imgix.net/" + _.escape(frnd.profileImage) + "?crop=faces&fit=crop&h=256&w=256&mask=ellipse&border=1,d0d0d0";
+ imageSrcSmall = "https://ninkip2p.imgix.net/" + _.escape(frnd.profileImage) + "?crop=faces&fit=crop&h=128&w=128&mask=ellipse&border=1,d0d0d0";
+ }
+
+
+ var template = '
';
+
+
+ grouptemplate += template;
+
+
+
+ k++;
+ }
+
+
+ grouptemplate += '
';
+ grouptemplate += '
';
+ g++;
+ }
+
+ grouptemplate += '
';
+
+ $("#myfriends").html(grouptemplate);
+
+
+
+ $('#myfriends #accordion2').on('touchstart.collapse.data-api', '[data-toggle=collapse]', function (e) {
+ var $this = $(this);
+
+ $this.click();
+
+ //href, target = $this.attr('data-target') || e.preventDefault() || (href = $this.attr('href')) //strip for ie7
+ //,
+ //option = $(target).data('collapse') ? 'show' : $this.data()
+ //$(target).collapse(option)
+ });
+
+
+
+ var k = 0;
+ var g = 1;
+ for (var key in friendsgroup) {
+
+ friends = friendsgroup[key];
+ for (var i = 0; i < friendsgroup[key].length; i++) {
+
+ friends = friendsgroup[key];
+
+
+ //var btnfriend = $("#myfriends #friend" + k).get();
+ //var hammertime = new Hammer(btnfriend[0]);
+
+ $("#myfriends #friend" + k).hammer(null).bind("tap", { userName: friends[i].userName }, function (ev) {
+
+
+ if (!scrollingnetlist) {
+
+ SELECTEDFRIEND = ev.data.userName;
+ selectedFriend = FRIENDSLIST[ev.data.userName];
+ prevNetworkTransCount = 0;
+
+ networkpagestate = "friend";
+ friendpagestate = "send";
+ $("#networklistheader").hide();
+ $("#friendheader").show();
+ $("#pnlfriend").show();
+
+ $('#netpayfeed').html('');
+ $("#networkpayments").show();
+ $("#networklist").hide();
+
+ $("#pnlfriendinv").hide();
+
+ //window.scrollTo(0, 0);
+
+ updateSelectedFriend();
+
+ }
+
+ });
+
+ //console.log("added click " + k + " for " + friends[i].userName);
+
+ k++;
+ }
+ g++;
+ }
+
+ }
+
+ if (callback) {
+ return callback(false, "done");
+ }
+
+ } else {
+
+ if (callback) {
+ return callback(true, "done");
+ }
+
+ }
+ });
+ }
+
+ }
+
+ function showSecret() {
+
+
+ }
+
+ function refreshSelectedFriend(callback) {
+
+ if (SELECTEDFRIEND.length > 0) {
+
+ Engine.getFriend(SELECTEDFRIEND, function (err, friend) {
+ if (!norefresh) {
+ if (SELECTEDFRIEND == friend.userName) {
+ selectedFriend = friend;
+ FRIENDSLIST[SELECTEDFRIEND] = friend;
+
+ if (selectedFriend.ICanSend) {
+ $("#issend").show();
+ //$("#networksend").show();
+ } else {
+ $("#issend").hide();
+ //$("#networksend").hide();
+ }
+ if (selectedFriend.ICanReceive) {
+ $("#isreceive").show();
+ } else {
+ $("#isreceive").hide();
+ }
+
+ var imageSrc = "images/avatar/256px/Avatar-" + pad(SELECTEDFRIEND.length) + ".png";
+
+ if (selectedFriend.profileImage != '') {
+ imageSrc = "https://ninkip2p.imgix.net/" + selectedFriend.profileImage + "?crop=faces&fit=crop&h=256&w=256&mask=ellipse&border=1,d0d0d0";
+ }
+ if (selectedFriend.status != '') {
+ $("#friendSelectedStatus").text(selectedFriend.status);
+ }
+
+ $("#imgSelectedFriend").attr("src", imageSrc);
+
+
+
+
+ callback(err, friend);
+
+ //updateSelectedFriend(function (err, res) {
+ // selFriendBkgUpdate = false;
+ // callback(err, res);
+ //});
+ }
+ }
+ });
+
+ }
+
+ }
+
+ function updateSelectedFriend(callback) {
+
+ //can optimise futher
+ norefresh = true;
+ if (SELECTEDFRIEND.length > 0) {
+
+
+ $('input#friendAmount').val('');
+
+
+ var length = selectedFriend.userName.length;
+ if (length > 20) {
+ length = 20;
+ }
+
+ //$("#nselnetcat").val(selectedFriend.category);
+
+ $('#friendempty').hide();
+
+ //$('#textMessageSend').removeClass('alert alert-danger');
+
+
+
+ $('#textMessageSend').hide();
+ $('#sendfriendprog').hide();
+
+
+ $("#friendSelectedName").text(selectedFriend.userName);
+ $("#friendSelectedNameTo").text(selectedFriend.userName);
+ $("#validateusername2").text(selectedFriend.userName);
$("#validateusername3").text(selectedFriend.userName);
$("#validateusername4").text(selectedFriend.userName);
$("#validateusername5").text(selectedFriend.userName);
@@ -3160,788 +3589,1071 @@ function UI() {
$("#validatefail").hide();
- var imageSrc = "images/avatar/256px/Avatar-" + pad(length) + ".png";
+ var imageSrc = "images/avatar/256px/Avatar-" + pad(length) + ".png";
+
+ if (selectedFriend.profileImage != '') {
+ imageSrc = "https://ninkip2p.imgix.net/" + selectedFriend.profileImage + "?crop=faces&fit=crop&h=256&w=256&mask=ellipse&border=1,d0d0d0";
+ }
+ $("#friendSelectedStatus").text('');
+ if (selectedFriend.status != '') {
+ $("#friendSelectedStatus").text(selectedFriend.status);
+ }
+
+ $("#imgSelectedFriend").attr("src", imageSrc);
+
+
+ if (selectedFriend.validated) {
+
+ $("#tapvalidatefriend").hide();
+ $("#tapsendfriend").show();
+
+ } else {
+
+ $("#tapvalidatefriend").show();
+ $("#tapsendfriend").hide();
+ }
+
+ $('#tblnetinvbyme tbody').empty();
+ $('#tblnetinvforme tbody').empty();
+
+
+
+
+ lastInvoiceToPayNetCount = 0;
+ lastInvoiceByMeNetCount = 0;
+
+ showInvoiceListNetwork();
+ showInvoiceByMeListNetwork();
+
+ showTransactionNetwork();
+
+ //$("#pnlfriend").show();
+ //$("#friendheader").show();
+
+
+ }
+
+ norefresh = false;
+
+
+
+
+ if (callback) {
+ callback(false, "ok");
+ }
+
+ }
+
+ var lastNoOfFriendsReq = 0;
+ var selectedFriendRequest = '';
+
+ function updateFriendRequests(callback) {
+
+ //if there are any new friends
+ //fade in the button
+
+ //to do, move to handlebars templates
+ Engine.getFriendRequests(function (err, ofriends) {
+
+
+ //if origin of friend request is qrcode
+ //and no phrase cache
+ //delay for 60 seconds
+ //add accept with scan button
+ //then return to standard after 5 minutes
+
+ var friends = [];
+ for (var i = 0; i < ofriends.length; i++) {
+
+ if (contactPhraseCache[ofriends[i].userName]) {
+ //acceptAndValidateFriend(ofriends[i].userName);
+ } else {
+ friends.push(ofriends[i]);
+ }
+
+ }
+
+
+ if (friends.length > 0) {
+ $("#dashrequests").show();
+
+ } else {
+ $("#dashrequests").hide();
+ }
+
+ //$("#notifications").text(friends.length);
+ //$("#notificationsright").text(friends.length);
+ //$("#nfriendreq").text(friends.length);
+
+
+ if (lastNoOfFriendsReq != friends.length || friends.length == 0) {
+
+ lastNoOfFriendsReq = friends.length;
+
+ if (friends.length > 0) {
+ $("#notifications").attr("class", "badge bg-danger pull-right");
+ } else {
+ $("#notifications").attr("class", "badge pull-right");
+ }
+ $("#nfriendreq").text(friends.length);
+ $("#friendreq").text('');
+ for (var i = 0; i < friends.length; i++) {
+
+ var length = friends[i].userName.length;
+ if (length > 20) {
+ length = 20;
+ }
+
+ var template = '' +
+ '' +
+ '' +
+ '';
+
+ $("#friendreq").append(template);
+
+ }
+
+ for (var i = 0; i < friends.length; i++) {
+
+ $("#friendreq #tapfriendreq" + i).hammer(null).bind("tap", { userName: friends[i].userName }, function (ev) {
+
+ selectedFriendRequest = ev.data.userName;
+
+ $("#friendrequestusername").text(selectedFriendRequest);
+
+
+ $("#mainWallet").hide();
+ $("#networklistheader").hide();
+ $(".footer").hide();
+ $("#contactrequest").show();
+
+
+ });
+
+ }
+
+ }
+ if (callback) {
+ callback(false, "done");
+ }
+ });
+
+ }
+
+ $('#btnContactRequestClose').bind('touchstart', function () {
+
+ $("#contactrequest").hide();
+ $("#mainWallet").show();
+ $("#networklistheader").show();
+ $(".footer").show();
+ $("#friendrequestp1").show();
+ $("#friendrequestp2").hide();
+
+ });
+
+
+ $('#btnAcceptContactDone').bind('touchstart', function () {
+
+ $("#contactrequest").hide();
+ $("#mainWallet").show();
+ $("#networklistheader").show();
+ $(".footer").show();
+ $("#friendrequestp1").show();
+ $("#friendrequestp2").hide();
+
+ });
+
+
+ $('#btnContactReject').bind('touchstart', function () {
+
+ rejectFriend(event.data.userName, function (err, res) {
+
+ if (!err) {
+
+ selectedFriendRequest = '';
+ updateFriendRequests();
+
+ $("#friendrequestusername").text('');
+ $("#contactrequest").hide();
+ $("#mainWallet").show();
+ $("#networklistheader").show();
+ $(".footer").show();
+ }
+
+ });
+
+ });
+
+
+
+ var prevtransfeed = -1;
+ var transactionCache = [];
+
+ function showTransactionFeed(callback) {
+
+ Engine.getTransactionRecords(function (err, transactions) {
+
+
+ allTransactions = transactions;
+ transactionCache = transactions;
+
+ if (transactions.length != prevtransfeed) {
+
+
+ for (var i = 0; i < allTransactions.length; i++) {
+ var d1 = new Date(allTransactions[i].TransDateTime);
+ allTransactions[i].JsDate = new Date(transactions[i].TransDateTime.match(/\d+/)[0] * 1);
+ transactionIndex[allTransactions[i].TransactionId] = i;
+ }
+
+
+
+ prevtransfeed = transactions.length;
+
+ $('#transfeed').empty();
+
+ var template = '';
+
+ for (var i = 0; i < transactions.length && i < 51; i++) {
+
+ var length = transactions[i].UserName.length;
+ if (length > 20) {
+ length = 20;
+ }
+
+ var imageSrcSmall = "images/avatar/32px/Avatar-" + pad(length) + ".png";
+
+ if (transactions[i].UserName != 'External') {
+ if (FRIENDSLIST[transactions[i].UserName]) {
+ if (FRIENDSLIST[transactions[i].UserName].profileImage != '') {
+ imageSrcSmall = "https://ninkip2p.imgix.net/" + _.escape(FRIENDSLIST[transactions[i].UserName].profileImage) + "?crop=faces&fit=crop&h=128&w=128&mask=ellipse&border=1,d0d0d0";
+ }
+ }
+ }
+
+ var amountLabel = "";
+ var friendLabel = "";
+
+ if (transactions[i].TransType == 'S') {
+ amountLabel = "sent " + convertFromSatoshis(transactions[i].Amount, COINUNIT) + " " + _.escape(COINUNIT);
+ friendLabel = "to " + _.escape(transactions[i].UserName);
+ }
+
+ if (transactions[i].TransType == 'R') {
+ amountLabel = "received " + convertFromSatoshis(transactions[i].Amount, COINUNIT) + " " + _.escape(COINUNIT);
+ friendLabel = "from " + _.escape(transactions[i].UserName);
+ }
+
+
+ var trdate = new Date(transactions[i].TransDateTime.match(/\d+/)[0] * 1);
+ var timeLabel = prettydate.format(trdate);
+
+ template += '';
+ template += '';
+ template += '';
+
+ template += '';
+ template += '';
+ template += ''
+ template += amountLabel;
+ template += '';
+
+ template += '';
+ template += '';
+ template += timeLabel;
+ template += '
';
+ template += '';
+
+ template += '';
+ template += '';
+ if (transactions[i].Confirmations < 6) {
+ template += '';
+ template += transactions[i].Confirmations;
+ template += '';
+ }
+ template += '
';
+ template += '';
+ template += friendLabel;
+ template += '';
+ template += '';
+ template += '';
+
+ }
+
+ $('#transfeed').html(template);
+
+ for (var i = 0; i < transactions.length && i < 51; i++) {
+
+
+ $('#dtran' + i).hammer(null).bind("tap", {
+ index: i
+ }, function (event) {
+
+ if (!scrolling) {
+
+ displayTransactionDetails(transactions[event.data.index], "dashboard");
+
+
+ }
+
+ });
+ }
+
+
+ } else {
+
+ //optimise
+
+ $('#transfeed .conf').each(function (index, elem) {
+
+ var tran = allTransactions[transactionIndex[transactions[index].TransactionId]];
+
+ var template = '';
+ if (tran.Confirmations < 6) {
+ template += '';
+ template += _.escape(tran.Confirmations);
+ template += '';
+ }
+
+ $(elem).html(template);
+
+ });
+
+ $('#transfeed .trntime').each(function (index, elem) {
+
+ var tran = allTransactions[transactionIndex[transactions[index].TransactionId]];
+
+ var trdate = new Date(tran.TransDateTime.match(/\d+/)[0] * 1);
+
+ var timeLabel = prettydate.format(trdate);
- if (selectedFriend.profileImage != '') {
- imageSrc = "https://ninkip2p.imgix.net/" + selectedFriend.profileImage + "?crop=faces&fit=crop&h=256&w=256&mask=ellipse&border=1,d0d0d0";
- }
- $("#friendSelectedStatus").text('');
- if (selectedFriend.status != '') {
- $("#friendSelectedStatus").text(selectedFriend.status);
- }
+ $(elem).html(timeLabel);
- $("#imgSelectedFriend").attr("src", imageSrc);
+ });
+ }
- if (selectedFriend.validated) {
+ return callback(err, "ok");
- $("#tapvalidatefriend").hide();
- $("#tapsendfriend").show();
+ });
- } else {
+ }
- $("#tapvalidatefriend").show();
- $("#tapsendfriend").hide();
- }
- $('#tblnetinvbyme tbody').empty();
- $('#tblnetinvforme tbody').empty();
+ var prevNetworkTransCount = 0;
+ function showTransactionNetwork(callback) {
+ var transactions = _.filter(transactionCache, function (tran) { return tran.UserName == SELECTEDFRIEND; });
+ if (prevNetworkTransCount < transactions.length) {
- lastInvoiceToPayNetCount = 0;
- lastInvoiceByMeNetCount = 0;
+ prevNetworkTransCount = transactions.length;
- showInvoiceListNetwork();
- showInvoiceByMeListNetwork();
+ var template = '';
- showTransactionNetwork();
+ for (var i = 0; i < transactions.length; i++) {
- //$("#pnlfriend").show();
- //$("#friendheader").show();
+ var amountLabel = "";
+ var friendLabel = "";
+ if (transactions[i].TransType == 'S') {
+ amountLabel = "sent " + convertFromSatoshis(transactions[i].Amount, COINUNIT) + " " + _.escape(COINUNIT);
+ friendLabel = "to " + _.escape(transactions[i].UserName);
+ }
- }
+ if (transactions[i].TransType == 'R') {
+ amountLabel = "received " + convertFromSatoshis(transactions[i].Amount, COINUNIT) + " " + _.escape(COINUNIT);
+ friendLabel = "from " + _.escape(transactions[i].UserName);
+ }
- norefresh = false;
+ var trdate = new Date(transactions[i].TransDateTime.match(/\d+/)[0] * 1);
+ var timeLabel = prettydate.format(trdate);
+ template += '';
+ template += '';
+ template += '';
+ template += amountLabel;
+ template += '';
- if (callback) {
- callback(false, "ok");
- }
+ template += '';
+ template += '';
+ template += timeLabel;
+ template += '
';
+ template += '';
- }
+ template += '';
+ template += '';
+ if (transactions[i].Confirmations < 6) {
+ template += '';
+ template += transactions[i].Confirmations;
+ template += '';
+ }
+ template += '
';
+ template += '';
+ template += friendLabel;
+ template += '';
+ template += '';
+ template += '';
+ }
+ $('#netpayfeed').html(template);
+ for (var i = 0; i < transactions.length && i < 51; i++) {
+ $('#ntran' + i).hammer(null).bind("tap", {
+ index: i
+ }, function (event) {
- var lastNoOfFriendsReq = 0;
- var selectedFriendRequest = '';
+ if (!scrollingnettran) {
- function updateFriendRequests(callback) {
+ displayTransactionDetails(transactions[event.data.index], "network");
- //if there are any new friends
- //fade in the button
+ }
- //to do, move to handlebars templates
- Engine.getFriendRequests(function (err, ofriends) {
+ });
+ }
+ } else {
- //if origin of friend request is qrcode
- //and no phrase cache
- //delay for 60 seconds
- //add accept with scan button
- //then return to standard after 5 minutes
- var friends = [];
- for (var i = 0; i < ofriends.length; i++) {
+ $('#netpayfeed .conf').each(function (index, elem) {
- if (contactPhraseCache[ofriends[i].userName]) {
- //acceptAndValidateFriend(ofriends[i].userName);
- } else {
- friends.push(ofriends[i]);
+ var tran = allTransactions[transactionIndex[transactions[index].TransactionId]];
+
+ var template = '';
+ if (tran.Confirmations < 6) {
+ template += '';
+ template += _.escape(tran.Confirmations);
+ template += '';
}
- }
+ $(elem).html(template);
+ console.log('updating 1');
- if (friends.length > 0) {
- $("#dashrequests").show();
+ });
- } else {
- $("#dashrequests").hide();
- }
+ $('#netpayfeed .trntime').each(function (index, elem) {
- //$("#notifications").text(friends.length);
- //$("#notificationsright").text(friends.length);
- //$("#nfriendreq").text(friends.length);
+ var tran = allTransactions[transactionIndex[transactions[index].TransactionId]];
+
+ var trdate = new Date(tran.TransDateTime.match(/\d+/)[0] * 1);
+ var timeLabel = prettydate.format(trdate);
+ $(elem).html(timeLabel);
+ console.log('updating 2');
- if (lastNoOfFriendsReq != friends.length || friends.length == 0) {
+ });
- lastNoOfFriendsReq = friends.length;
+ }
- if (friends.length > 0) {
- $("#notifications").attr("class", "badge bg-danger pull-right");
- } else {
- $("#notifications").attr("class", "badge pull-right");
- }
- $("#nfriendreq").text(friends.length);
- $("#friendreq").text('');
- for (var i = 0; i < friends.length; i++) {
+ }
- var length = friends[i].userName.length;
- if (length > 20) {
- length = 20;
- }
- var template = '' +
- '' +
- '' +
- '';
+ var transactionDetailMode = 'dashboard';
- $("#friendreq").append(template);
+ function displayTransactionDetails(tran, mode) {
- }
+ transactionDetailMode = mode;
- for (var i = 0; i < friends.length; i++) {
+ var trdate = new Date(tran.TransDateTime.match(/\d+/)[0] * 1).toString("yyyy-MM-dd HH:mm tt");
- $("#friendreq #tapfriendreq" + i).hammer(null).bind("tap", { userName: friends[i].userName }, function (ev) {
- selectedFriendRequest = ev.data.userName;
+ var tranhtml = '';
- $("#friendrequestusername").text(selectedFriendRequest);
- $("#mainWallet").hide();
- $("#networklistheader").hide();
- $(".footer").hide();
- $("#contactrequest").show();
+ tranhtml += 'Date:';
+ tranhtml += '
';
+ tranhtml += '';
+ tranhtml += _.escape(trdate);
+ tranhtml += '
';
+ tranhtml += '';
+ tranhtml += '
Transaction Id:
';
+ tranhtml += '
';
- });
+ tranhtml += '';
+ tranhtml += _.escape(tran.TransactionId);
+ tranhtml += '
';
- }
- }
- if (callback) {
- callback(false, "done");
- }
- });
+ tranhtml += '';
+ tranhtml += '
Address:
';
+ tranhtml += '
';
- }
+ tranhtml += '';
+ tranhtml += _.escape(tran.Address);
+ tranhtml += '
';
+ tranhtml += 'Amount:'
+ tranhtml += '
';
+ tranhtml += '';
+ tranhtml += convertFromSatoshis(tran.Amount, COINUNIT) + ' ' + COINUNIT;
+ tranhtml += '
';
+ tranhtml += '';
+ tranhtml += 'Send/Receive:'
+ tranhtml += '
';
- $('#btnContactRequestClose').bind('touchstart', function () {
+ tranhtml += '';
+ tranhtml += _.escape(tran.TransType);
+ tranhtml += '
';
- $("#contactrequest").hide();
- $("#mainWallet").show();
- $("#networklistheader").show();
- $(".footer").show();
- $("friendrequestp1").show();
- $("friendrequestp2").hide();
- });
+ if (transactionDetailMode == 'dashboard') {
+ $("#dashheader").hide();
+ } else {
+ $("#friendheader").hide();
+ }
- $('#btnAcceptContactDone').bind('touchstart', function () {
+ $("#mainWallet").hide();
+ $(".footer").hide();
+ $("#transview").addClass("slideUp");
+ $('#transdets').html(tranhtml);
- $("#contactrequest").hide();
- $("#mainWallet").show();
- $("#networklistheader").show();
- $(".footer").show();
- $("friendrequestp1").show();
- $("friendrequestp2").hide();
+ }
- });
+ function generateAddressClient() {
- $('#btnContactReject').bind('touchstart', function () {
- rejectFriend(event.data.userName, function (err, res) {
+ $("#newaddrspinner").show();
+ var target = document.getElementById('newaddrspinner');
+ var spinner = new Spinner(spinneropts).spin(target);
+
+ Engine.createAddress('m/0/0', 1, function (err, newAddress, path) {
if (!err) {
- selectedFriendRequest = '';
- updateFriendRequests();
+ var options = { text: newAddress, width: 172, height: 172 };
- $("#friendrequestusername").text('');
- $("#contactrequest").hide();
- $("#mainWallet").show();
- $("#networklistheader").show();
- $(".footer").show();
- }
+ $('#requestaddressqr').show();
+ $('#requestaddressqr').text('');
+ $('#requestaddressqr').qrcode(options);
- });
+ $('#requestaddresstxt').text(newAddress);
- });
+ //$('#requestaddress').text(tempate);
+ $("#newaddrspinner").hide();
+ $('#requestaddress').show();
- function acceptAndValidateFriend(username, message, callback) {
+ } else {
+ $('#requestaddressqr').hide();
+ $('#requestaddress').show();
+ $("#newaddrspinner").hide();
+ $('#requestaddresstxt').text(newAddress);
+ }
+ });
- if ($(message)) {
- $(message).text('Accepting friend request...');
- }
+ }
- acceptFriend(username, message, function (err, res) {
- //handle here instead
+ function sendMoney(friend, index) {
- console.log('accept contact');
+ $('#textMessageSend').removeClass('alert alert-danger');
- console.log(contactPhraseCache[username]);
- console.log(err);
+ if (friend == null) {
+ return;
+ }
- if (!err) {
+ var pin = $('#sendstdpin').val();
- console.log('accepted request');
+ var amount = $('#hdamount').val();
- lastNoOfFriendsReq = 0;
- updateFriendRequests();
+ amount = convertToSatoshis(amount, COINUNIT);
- //$("#imgrequestwaiting").hide();
+ if (amount > 0) {
- if (contactPhraseCache[username]) {
- if ($(message)) {
- $(message).text('Validating contact...');
- }
+ Engine.getDeviceKey(pin, function (err, ekey) {
- console.log('found phrase');
+ if (!err) {
- console.log('found phrase');
- console.log(contactPhraseCache[username])
- var code = contactPhraseCache[username];
- var bip39 = new BIP39();
- code = bip39.mnemonicToHex(code);
+ $('#sendprogress').show();
+ $('#pinconfirm').hide();
- if (code.length == 40) {
+ $('.numdone').attr("style", "background-color:white");
+ $("#sendstdpin").val('');
+ pintaps = 0;
+ prevpin = '';
- Engine.verifyFriendData(username, code, function (err, result) {
- if (result) {
+ $('#textMessageSendStd').text('Creating transaction...');
+ $('#textMessageSendStd').show();
+ $('#sendstdprogstatus').width('10%');
+ $('#sendstdprognum').text('10%');
+ $('#sendstdprog').show();
- if ($(message)) {
- $(message).text('Validated...');
- }
- console.log('verified');
- console.log(result);
- lastNoOfFriends = 0;
- updateFriends();
+ setTimeout(function () {
- if (callback) {
+ Engine.sendTransaction('friend', friend, "", amount, ekey.DeviceKey, function (err, transactionid) {
- callback(false, "ok");
+ if (!err) {
- }
+ $('#textMessageSendStd').text('You sent ' + convertFromSatoshis(amount, COINUNIT) + ' ' + COINUNIT + ' to ' + friend);
- //updateSelectedFriend();
- //update list also
+ updateUI();
- //find friend in list and update the validated icon
- //$("#myfriends #seltarget" + selectedFriend.userName).text('
');
+ sendAmount = '';
- }
+ updateStdAmount();
- });
+ setTimeout(function () {
+ $("#btnStdSndDone").show();
+ }, 100);
- }
+ $("#sendstdpin").val('');
+ $('.numdone').attr("style", "background-color:white");
+ pintaps = 0;
+ prevpin = '';
- //get the hash to validate against
- //this will confirm that my friend has the same keys
- //i orginally packaged for him
+ } else {
- } else {
+ $('#sendstdprogstatus').width('0%');
+ $('#sendstdprognum').text('0%');
- if (callback) {
+ if (transactionid == "ErrInsufficientFunds") {
+ $('#textMessageSendStd').text('Transaction Failed: Waiting for funds to clear');
+ }
- callback(false, "ok");
+ //return to send screen
+ setTimeout(function () {
+ $("#btnStdSndDone").show();
+ }, 100);
- }
+ }
+ // alert(transactionid);
+ }, function (message, progress) {
- }
+ if (message) {
+ $('#textMessageSendStd').text(message);
+ }
- }
+ if (progress) {
+ $('#sendstdprogstatus').width(progress);
+ $('#sendstdprognum').text(progress);
+ }
+ });
+ }, 50);
- });
- }
+ } else {
- var prevtransfeed = -1;
- var transactionCache = [];
- function showTransactionFeed(callback) {
+ $('.numdone').attr("style", "background-color:white");
- Engine.getTransactionRecords(function (err, transactions) {
+ $("#sendstdpin").val('');
+ pintaps = 0;
+ prevpin = '';
- allTransactions = transactions;
- transactionCache = transactions;
+ if (ekey.substring(0, 6) == "ErrPIN") {
- if (transactions.length != prevtransfeed) {
+ var attempts = ekey.substring(7, 8);
+ //$("#pinconfmessage").text("Incorrect PIN " + attempts + "/3 attempts");
- for (var i = 0; i < allTransactions.length; i++) {
- var d1 = new Date(allTransactions[i].TransDateTime);
- allTransactions[i].JsDate = new Date(transactions[i].TransDateTime.match(/\d+/)[0] * 1);
- transactionIndex[allTransactions[i].TransactionId] = i;
- }
+ $("#pinconfcount").effect("shake");
+ } else {
+ bootbox.alert(ekey);
- prevtransfeed = transactions.length;
+ }
- $('#transfeed').empty();
+ }
- var template = '';
+ });
- for (var i = 0; i < transactions.length && i < 11; i++) {
+ } else {
+ $('input#friendAmount').css("border-color", "#ffaaaa");
+ }
- var length = transactions[i].UserName.length;
- if (length > 20) {
- length = 20;
- }
- var imageSrcSmall = "images/avatar/32px/Avatar-" + pad(length) + ".png";
+ }
- if (transactions[i].UserName != 'External') {
- if (FRIENDSLIST[transactions[i].UserName]) {
- if (FRIENDSLIST[transactions[i].UserName].profileImage != '') {
- imageSrcSmall = "https://ninkip2p.imgix.net/" + _.escape(FRIENDSLIST[transactions[i].UserName].profileImage) + "?crop=faces&fit=crop&h=128&w=128&mask=ellipse&border=1,d0d0d0";
- }
- }
- }
- var amountLabel = "";
- var friendLabel = "";
- if (transactions[i].TransType == 'S') {
- amountLabel = "sent " + convertFromSatoshis(transactions[i].Amount, COINUNIT) + " " + _.escape(COINUNIT);
- friendLabel = "to " + _.escape(transactions[i].UserName);
- }
- if (transactions[i].TransType == 'R') {
- amountLabel = "received " + convertFromSatoshis(transactions[i].Amount, COINUNIT) + " " + _.escape(COINUNIT);
- friendLabel = "from " + _.escape(transactions[i].UserName);
- }
+ function sendMoneyStd() {
- var trdate = new Date(transactions[i].TransDateTime.match(/\d+/)[0] * 1);
- var timeLabel = prettydate.format(trdate);
- template += '';
- template += '';
- template += '';
+ //get pin from user
+ //get device key
+ //pass the device key as the 2fa code
- template += '';
- template += '';
- template += '';
- template += amountLabel;
- template += '';
+ var amount = $('#hdamount').val();
+ amount = convertToSatoshis(amount, COINUNIT);
- template += '';
- template += ''
- template += timeLabel;
- template += '
';
- template += '';
+ var address = $('input#toAddress').val();
- template += '';
- template += '';
- if (transactions[i].Confirmations < 6) {
- template += '';
- template += transactions[i].Confirmations;
- template += '';
- }
- template += '
';
- template += '';
- template += friendLabel;
- template += '';
- template += '';
- template += '';
+ //$('#textMessageSendStd').removeClass('alert alert-danger');
+ //check for valid bitcoin address
- }
+ var allok = true;
- $('#transfeed').html(template);
+ var pin = $('#sendstdpin').val();
- } else {
+ if (allok) {
- //optimise
+ Engine.getDeviceKey(pin, function (err, ekey) {
- $('#transfeed .conf').each(function (index, elem) {
+ if (!err) {
- var tran = allTransactions[transactionIndex[transactions[index].TransactionId]];
+ $('#sendprogress').show();
+ $('#pinconfirm').hide();
- var template = ''
- if (tran.Confirmations < 6) {
- template += '';
- template += _.escape(tran.Confirmations);
- template += '';
- }
- $(elem).html(template);
+ $('#textMessageSendStd').text('Creating transaction...');
+ $('#textMessageSendStd').show();
+ $('#sendstdprogstatus').width('3%');
+ $('#sendstdprog').show();
+ $('#sendstdprogstatus').width('10%');
- });
+ $('#sendstdprognum').text('10%');
- $('#transfeed .trntime').each(function (index, elem) {
+ setTimeout(function () {
- var tran = allTransactions[transactionIndex[transactions[index].TransactionId]];
+ Engine.sendTransaction('standard', '', address, amount, ekey.DeviceKey, function (err, transactionid) {
- var trdate = new Date(tran.TransDateTime.match(/\d+/)[0] * 1);
+ if (!err) {
- var timeLabel = prettydate.format(trdate);
+ $('#textMessageSendStd').html('You sent ' + _.escape(convertFromSatoshis(amount, COINUNIT)) + ' ' + _.escape(COINUNIT) + ' to ' + address + '');
- $(elem).html(timeLabel);
+ updateUI();
- });
+ sendAmount = '';
+ updateStdAmount();
- }
+ setTimeout(function () {
+ $("#btnStdSndDone").show();
+ }, 100);
- return callback(err, "ok");
+ $("#sendstdpin").val('');
+ $('.numdone').attr("style", "background-color:white");
- });
+ pintaps = 0;
+ prevpin = '';
- }
+ } else {
+ $('#sendstdprogstatus').width('0%');
+ $('#sendstdprognum').text('0%');
- //
+ if (transactionid == "ErrInsufficientFunds") {
+ $('#textMessageSendStd').text('Transaction Failed: Waiting for funds to clear');
+ }
- var prevNetworkTransCount = 0;
+ setTimeout(function () {
+ $("#btnStdSndDone").show();
+ }, 100);
- function showTransactionNetwork(callback) {
+ $("#sendstdpin").val('');
+ $('.numdone').attr("style", "background-color:white");
- var transactions = _.filter(transactionCache, function (tran) { return tran.UserName == SELECTEDFRIEND; });
+ pintaps = 0;
+ prevpin = '';
- if (prevNetworkTransCount < transactions.length) {
+ }
- prevNetworkTransCount = transactions.length;
+ }, function (message, progress) {
- var template = '';
+ if (message) {
+ $('#textMessageSendStd').text(message);
+ }
- for (var i = 0; i < transactions.length; i++) {
+ if (progress) {
+ $('#sendstdprogstatus').width(progress);
+ $('#sendstdprognum').text(progress);
+ }
- var amountLabel = "";
- var friendLabel = "";
+ });
- if (transactions[i].TransType == 'S') {
- amountLabel = "sent " + convertFromSatoshis(transactions[i].Amount, COINUNIT) + " " + _.escape(COINUNIT);
- friendLabel = "to " + _.escape(transactions[i].UserName);
- }
+ }, 50);
- if (transactions[i].TransType == 'R') {
- amountLabel = "received " + convertFromSatoshis(transactions[i].Amount, COINUNIT) + " " + _.escape(COINUNIT);
- friendLabel = "from " + _.escape(transactions[i].UserName);
- }
+ } else {
- var trdate = new Date(transactions[i].TransDateTime.match(/\d+/)[0] * 1);
- var timeLabel = prettydate.format(trdate);
- template += '';
- template += '';
+ $('.numdone').attr("style", "background-color:white");
- template += '';
- template += amountLabel;
- template += '';
+ $("#sendstdpin").val('');
- template += '';
- template += ''
- template += timeLabel;
- template += '
';
- template += '';
+ pintaps = 0;
+ prevpin = '';
- template += '';
- template += '';
- if (transactions[i].Confirmations < 6) {
- template += '';
- template += transactions[i].Confirmations;
- template += '';
- }
- template += '
';
- template += '';
- template += friendLabel;
- template += '';
- template += '';
- template += '';
- }
+ if (ekey.substring(0, 6) == "ErrPIN") {
- $('#netpayfeed').html(template);
+ var attempts = ekey.substring(7, 8);
- } else {
+ //$("#pinconfmessage").text("Incorrect PIN " + attempts + "/3 attempts");
+ $("#pinconfcount").effect("shake");
- $('#netpayfeed .conf').each(function (index, elem) {
+ } else {
- var tran = allTransactions[transactionIndex[transactions[index].TransactionId]];
+ bootbox.alert(ekey);
- var template = ''
- if (tran.Confirmations < 6) {
- template += '';
- template += _.escape(tran.Confirmations);
- template += '';
+ }
}
- $(elem).html(template);
- console.log('updating 1');
});
+ }
- $('#netpayfeed .trntime').each(function (index, elem) {
-
- var tran = allTransactions[transactionIndex[transactions[index].TransactionId]];
-
- var trdate = new Date(tran.TransDateTime.match(/\d+/)[0] * 1);
+ }
- var timeLabel = prettydate.format(trdate);
- $(elem).html(timeLabel);
+ function acceptAndValidateFriend(username, message, callback) {
- console.log('updating 2');
+ var needToAccept = false;
+ if (FRIENDSLIST[username]) {
- });
+ if (!FRIENDSLIST[username].ICanSend) {
+ needToAccept = true;
+ }
+ } else {
+ needToAccept = true;
}
+ if (needToAccept) {
+ acceptFriend(username, message, function (err, res) {
- }
-
-
- function generateAddressClient() {
+ if (!err) {
- $("#newaddrspinner").show();
- var target = document.getElementById('newaddrspinner');
- var spinner = new Spinner(spinneropts).spin(target);
+ lastNoOfFriendsReq = 0;
+ updateFriendRequests();
- Engine.createAddress('m/0/0', 1, function (err, newAddress, path) {
+ if (contactPhraseCache[username]) {
- var options = { text: newAddress, width: 172, height: 172 };
+ message("ValidateContact");
- $('#requestaddressqr').text('');
- $('#requestaddressqr').qrcode(options);
+ var code = contactPhraseCache[username];
- $('#requestaddresstxt').text(newAddress);
+ validateContact(username, code, function (err, result) {
- //$('#requestaddress').text(tempate);
- $("#newaddrspinner").hide();
- $('#requestaddress').show();
+ lastNoOfFriends = 0;
+ updateFriends(function (err, result) {
+ return callback(err, result);
- });
+ });
- }
+ });
+ } else {
- function sendMoney(friend, index) {
+ if (callback) {
- $('#textMessageSend').removeClass('alert alert-danger');
+ return callback(false, "ok");
- if (friend == null) {
- return;
- }
+ }
- var pin = $('#sendstdpin').val();
- var amount = $('#amount').text();
- amount = convertToSatoshis(amount, COINUNIT);
+ }
- if (amount > 0) {
+ }
+ });
- Engine.getDeviceKey(pin, function (err, ekey) {
+ } else {
- if (!err) {
+ if (contactPhraseCache[username]) {
+ message("ValidateContact");
- $('#sendprogress').show();
- $('#pinconfirm').hide();
+ var code = contactPhraseCache[username];
+ validateContact(username, code, function (err, result) {
- $('#textMessageSendStd').text('Creating transaction...');
- $('#textMessageSendStd').show();
- $('#sendstdprogstatus').width('3%')
- $('#sendstdprog').show();
- $('#sendstdprogstatus').width('10%');
+ return callback(err, result);
- $('#sendstdprognum').text('10%');
+ });
+ } else {
+ if (callback) {
- Engine.sendTransaction('friend', friend, "", amount, ekey.DeviceKey, function (err, transactionid) {
+ return callback(false, "ok");
- if (!err) {
+ }
- $('#textMessageSend').text('You sent ' + convertFromSatoshis(amount, COINUNIT) + ' ' + COINUNIT + ' to ' + friend);
- $('input#amount').text('');
+ }
- updateUI();
- updateStdAmount();
+ }
+ }
- setTimeout(function () {
- $("#btnStdSndDone").show();
- }, 100);
+ function registerCode(username, phrase) {
- $("#sendstdpin").val('');
- $('.numdone').attr("style", "background-color:white");
+ var bip39 = new BIP39();
+ var code = bip39.mnemonicToHex(phrase);
+ contactPhraseCache[username] = code;
- } else {
- $('#textMessageSend').addClass('alert alert-danger');
- $('#sendfriendprogstatus').width('0%')
+ }
- if (transactionid == "ErrInsufficientFunds") {
- $('#textMessageSend').text('Transaction Failed: Waiting for funds to clear');
- }
- }
- // alert(transactionid);
- });
+ function validateContact(username, code, callback) {
- } else {
+ if (code.length == 40) {
- $('.numdone').attr("style", "background-color:white");
- $("#sendstdpin").val('');
- $('#confpinalert').show();
- $('#confpinalertmess').text(ekey)
+ Engine.verifyFriendData(username, code, function (err, result) {
- }
+ callback(err, result);
});
} else {
- $('input#friendAmount').css("border-color", "#ffaaaa");
- }
-
-
- }
+ callback(true, "invalid code");
- function sendMoneyStd() {
+ }
+ }
- //get pin from user
- //get device key
- //pass the device key as the 2fa code
- var amount = $('#amount').text();
- amount = convertToSatoshis(amount, COINUNIT);
- var address = $('input#toAddress').val();
+ var checkAndValidateTimer = null;
- $('#textMessageSendStd').removeClass('alert alert-danger');
- //check for valid bitcoin address
- var allok = true;
- if (Engine.isAddressValid(address)) {
- $('input#toAddress').css("border-color", "#ccc");
- } else {
- $('input#toAddress').css("border-color", "#ffaaaa");
- allok = false;
- }
- if (amount > 0) {
- $('#amount').css("border-color", "#ccc");
- } else {
- $('#amount').css("border-color", "#ffaaaa");
- allok = false;
- }
+ function clearCheckAndValidateTimer() {
+ console.log('clearing timer');
+ clearInterval(checkAndValidateTimer);
+ }
- var pin = $('#sendstdpin').val();
- if (allok) {
+ function checkAndValidateFriendRequests() {
- Engine.getDeviceKey(pin, function (err, ekey) {
+ console.log('checking...');
- if (!err) {
+ $("#textAddContact").text('Verifying request...');
+ $("#addcontactprognum").text("10%");
+ $("#addcontactprogstatus").width("10%");
+ Engine.getFriendRequests(function (err, ofriends) {
- $('#sendprogress').show();
- $('#pinconfirm').hide();
+ console.log('found ' + ofriends.length);
+ if (ofriends.length > 0) {
+ $("#contaddprog").show();
+ $("#contaddscan").hide();
+ }
- $('#textMessageSendStd').text('Creating transaction...');
- $('#textMessageSendStd').show();
- $('#sendstdprogstatus').width('3%')
- $('#sendstdprog').show();
- $('#sendstdprogstatus').width('10%');
+ var targetFriend = null;
- $('#sendstdprognum').text('10%');
+ var friends = [];
+ for (var i = 0; i < ofriends.length; i++) {
- Engine.sendTransaction('standard', '', address, amount, ekey.DeviceKey, function (err, transactionid) {
+ if (ofriends[i].userName == currentContactExchange) {
+ targetFriend = ofriends[i];
+ }
+ }
- if (!err) {
+ if (targetFriend) {
- $('#textMessageSendStd').html('You sent ' + _.escape(convertFromSatoshis(amount, COINUNIT)) + ' ' + _.escape(COINUNIT) + ' to ' + address + '');
- $('input#amount').text('');
+ if (contactPhraseCache[targetFriend.userName]) {
- updateUI();
- updateStdAmount();
+ clearCheckAndValidateTimer();
- setTimeout(function () {
- $("#btnStdSndDone").show();
- }, 100);
+ $("#addcontactprognum").text("20%");
+ $("#addcontactprogstatus").width("20%");
- $("#sendstdpin").val('');
- $('.numdone').attr("style", "background-color:white");
+ acceptAndValidateFriend(targetFriend.userName,
- } else {
+ function (message) {
- if (transactionid == "ErrInsufficientFunds") {
- $('#textMessageSendStd').text('Transaction Failed: Waiting for funds to clear');
- }
+ var prog = "";
+ var mess = "";
- $('#sendstdprogstatus').width('0%')
- $('#textMessageSendStd').addClass('alert alert-danger');
- $("#sendstdpin").val('');
+ if (message == "AcceptFriendRequest") {
+ mess = "Accepting request...";
+ prog = "50%";
}
- });
+ if (message == "CreateFriend") {
+ mess = "Creating contact...";
+ prog = "60%";
+ }
+ if (message == "ValidateContact") {
+ mess = "Validating contact...";
+ prog = "80%";
+ }
- } else {
+ $("#addcontactprognum").text(prog);
+ $("#addcontactprogstatus").width(prog);
+ $("#textAddContact").text(mess)
- //display pin error
- $('.numdone').attr("style", "background-color:white");
- $("#sendstdpin").val('');
- $('#confpinalert').show();
- $('#confpinalertmess').text(ekey);
- }
+ }
+ , function (err, result) {
+ if (!err) {
- });
- }
+ $("#addcontactprognum").text("100%");
+ $("#addcontactprogstatus").width("100%");
- }
+ setTimeout(function () {
+ $("#addcontactmodal").hide();
- var checkAndValidateTimer = null;
+ $("#dashcontact").addClass("invis");
+ $("#dashcontact").removeClass("slideUp");
+ $("#contactrequest").hide();
- function clearCheckAndValidateTimer() {
- clearInterval(checkAndValidateTimer);
- }
+ $("#mainWallet").show();
+ $("#networklistheader").show();
+ $(".footer").show();
+ $("#friendrequestp1").show();
+ $("#friendrequestp2").hide();
+ }, 1000);
- function checkAndValidateFriendRequests() {
- Engine.getFriendRequests(function (err, ofriends) {
- var friends = [];
- for (var i = 0; i < ofriends.length; i++) {
- if (contactPhraseCache[ofriends[i].userName]) {
+ } else {
- clearCheckAndValidateTimer();
+ $("#textAddContact").text(result);
+ }
- console.log('found request...accepting and validating');
- acceptAndValidateFriend(ofriends[i].userName);
+ });
- return;
}
+
}
+
+
});
}
@@ -3951,23 +4663,43 @@ function UI() {
$("#btnAcceptContactDone").hide();
$("#friendrequestp1").hide();
$("#friendrequestp2").show();
- $("#acceptcontactprognum").text('10%');
- $("#acceptcontactprog").width('10%');
+ $("#acceptcontactprognum").text('5%');
+ $("#acceptcontactprog").width('5%');
+ acceptAndValidateFriend(selectedFriendRequest, function (message) {
- acceptAndValidateFriend(selectedFriendRequest, "#acceptcontactprogmess", function (err, result) {
+ var prog = "";
+ var mess = "";
- if (!err) {
+ if (message == "AcceptFriendRequest") {
+ mess = "Accepting request...";
+ prog = "20%";
+ }
+
+ if (message == "CreateFriend") {
+ mess = "Creating contact...";
+ prog = "70%";
+ }
+
+ if (message == "ValidateContact") {
+ mess = "Validating contact...";
+ prog = "90%";
+ }
+
+ $("#acceptcontactprognum").text(prog);
+ $("#acceptcontactprog").width(prog);
+ $("#acceptcontactprogmess").text(mess)
+ }, function (err, result) {
+
+ if (!err) {
- $("#acceptcontactprognum").text('70%');
- $("#acceptcontactprog").width('70%');
updateFriendRequests(function (err, result) {
- $("#acceptcontactprognum").text('80%');
- $("#acceptcontactprog").width('80%');
+ $("#acceptcontactprognum").text('90%');
+ $("#acceptcontactprog").width('90%');
updateFriends(function (err, result) {
@@ -3996,6 +4728,8 @@ function UI() {
});
+ var currentContactExchange = '';
+
//function when connecting from main add contact screen
$("#hdqrcontact").change(function () {
@@ -4010,10 +4744,14 @@ function UI() {
console.log(phrase);
console.log(username);
- contactPhraseCache[username] = phrase;
+ currentContactExchange = username;
+
+ registerCode(username, phrase);
$("#addcontactmodal").show();
- $("#dashcontact").hide();
+
+ $("#dashcontact").addClass("invis");
+ $("#dashcontact").removeClass("slideUp");
//$("#imgaddcontactwaiting").show();
@@ -4054,13 +4792,16 @@ function UI() {
Engine.getFriendRequests(function (err, ofriends) {
- var friends = _.filter(ofriends, function (frn) { return frn.UserName == username; });
+ console.log("logging friend request filter...");
+ console.log(ofriends);
- if (friends.length == 0) {
+ var friends = _.filter(ofriends, function (frn) { return frn.userName == username; });
- console.log('network not exists');
+ console.log(friends);
+ if (friends.length == 0) {
+ console.log('friend request does not exist');
//if network doesnt exist create friend
@@ -4071,11 +4812,14 @@ function UI() {
if (!result) {
+ console.log('network does not exist');
+
$("#textAddContact").text('Deriving addresses...');
$("#addcontactprognum").text("60%");
$("#addcontactprogstatus").width("60%");
+ console.log('creating friend...');
Engine.createFriend(username, "#qrcontactmess", function (err, result) {
@@ -4092,110 +4836,184 @@ function UI() {
} else {
+
+ //if there is a pending friend request
+ //skip this bit
+
console.log('added timer for check and validate');
//here we go to - now you friend should scan this code
- checkAndValidateTimer = setInterval(function () { checkAndValidateFriendRequests() }, 2000);
+ checkAndValidateTimer = setInterval(function () {
+ checkAndValidateFriendRequests();
+ }
+ , 2000);
//listen for 2 minutes
- setTimeout(clearCheckAndValidateTimer(), 120000);
+ setTimeout(function () {
+ clearCheckAndValidateTimer();
+
+ //timed out so return the user to screen
+
+
+ $("#addcontactmodal").hide();
+
+ $("#dashcontact").addClass("invis");
+ $("#dashcontact").removeClass("slideUp");
+
+ $("#contactrequest").hide();
+
+ $("#mainWallet").show();
+ $("#networklistheader").show();
+ $(".footer").show();
+ $("#friendrequestp1").show();
+ $("#friendrequestp2").hide();
+
+
+ }, 60000);
$("#addcontactprognum").text("100%");
$("#addcontactprogstatus").width("100%");
//$("#imgaddcontactwaiting").hide();
//$("#addcontactmodal").hide();
- $("#textAddContact").text("Successfully added " + username + " as a contact");
- }
- });
- } else {
+ setTimeout(function () {
- $("#textAddContact").text('validating...');
+ $("#contaddprog").hide();
+ $("#contaddscan").show();
- $("#addcontactprognum").text("80%");
- $("#addcontactprogstatus").width("80%");
+ $("#scancontqrmess").text("Now ask " + username + " to scan the QR code below:");
+ }, 1000);
+
+ //$("#textAddContact").text("Now scan the QR code from " + username);
+ }
+ });
+ } else {
- //if already accepted validate only
+ acceptAndValidateFriend(username, function (message) {
- var needToAccept = false;
- if (FRIENDSLIST[username]) {
+ var prog = "";
+ var mess = "";
- if (!FRIENDSLIST[username].ICanSend) {
- needToAccept = true;
+ if (message == "AcceptFriendRequest") {
+ mess = "Accepting request...";
+ prog = "50%";
}
- } else {
- needToAccept = true;
- }
-
+ if (message == "CreateFriend") {
+ mess = "Creating contact...";
+ prog = "60%";
+ }
- if (needToAccept) {
+ if (message == "ValidateContact") {
+ mess = "Validating contact...";
+ prog = "80%";
+ }
- acceptAndValidateFriend(username, "", function (err, result) {
+ $("#addcontactprognum").text(prog);
+ $("#addcontactprogstatus").width(prog);
+ $("#textAddContact").text(mess)
- if (!err) {
+ }, function (err, result) {
- $("#addcontactprognum").text("100%");
- $("#addcontactprogstatus").width("100%");
- $("#textAddContact").text("Successfully added " + username + " as a contact");
- }
+ if (!err) {
+ setTimeout(function () {
+ $("#addcontactmodal").hide();
- });
+ $("#dashcontact").addClass("invis");
+ $("#dashcontact").removeClass("slideUp");
+ $("#contactrequest").hide();
- } else {
+ $("#mainWallet").show();
+ $("#networklistheader").show();
+ $(".footer").show();
+ $("#friendrequestp1").show();
+ $("#friendrequestp2").hide();
- console.log('caught event...');
+ }, 1000);
- var bip39 = new BIP39();
- code = bip39.mnemonicToHex(phrase);
- console.log(code);
+ } else {
- if (code.length != 40) {
+ $("#textAddContact").text(result);
+ $("#btnAddContactDone").show();
- return;
}
- Engine.verifyFriendData(username, code, function (err, result) {
+ });
- $("#addcontactprognum").text("100%");
- $("#addcontactprogstatus").width("100%");
+ }
- $("#textAddContact").text("Successfully verified " + username + " as a contact");
+ }
- //update contact list
- updateFriends();
+ });
- });
+ } else if (friends.length == 1) {
- }
+ //validate using the fingerprint
+ acceptAndValidateFriend(username, function (message) {
- }
+ var prog = "";
+ var mess = "";
+ if (message == "AcceptFriendRequest") {
+ mess = "Accepting request...";
+ prog = "50%";
}
- });
+ if (message == "CreateFriend") {
+ mess = "Creating contact...";
+ prog = "60%";
+ }
- } else if (friends.length == 1) {
+ if (message == "ValidateContact") {
+ mess = "Validating contact...";
+ prog = "80%";
+ }
+ $("#addcontactprognum").text(prog);
+ $("#addcontactprogstatus").width(prog);
+ $("#textAddContact").text(mess)
- //validate using the fingerprint
- acceptAndValidateFriend(username, "#textAddContact", function (err, result) {
+
+ }, function (err, result) {
if (!err) {
$("#addcontactprognum").text("100%");
$("#addcontactprogstatus").width("100%");
- $("#textAddContact").text("Successfully added " + username + " as a contact");
+ setTimeout(function () {
+
+ $("#addcontactmodal").hide();
+
+ $("#dashcontact").addClass("invis");
+ $("#dashcontact").removeClass("slideUp");
+
+ $("#contactrequest").hide();
+
+ $("#mainWallet").show();
+ $("#networklistheader").show();
+ $(".footer").show();
+ $("#friendrequestp1").show();
+ $("#friendrequestp2").hide();
+
+ }, 1000);
+
+
+
+ } else {
+
+ $("#textAddContact").text(result);
+ $("#btnAddContactDone").show();
+
}
@@ -4212,9 +5030,90 @@ function UI() {
}
});
+ });
+
+
+
+ $("#hdvalcontact").change(function () {
+
+ console.log('caught event...');
+
+ var res = $("#hdvalcontact").val();
+ var sres = res.split(',');
+ var phrase = sres[0];
+ var username = sres[1];
+
+ $("#netvalidp2").show();
+ $("#netvalidp1").hide();
+
+
+ registerCode(username, phrase);
+
+ acceptAndValidateFriend(username, function (message) {
+ var prog = "";
+ var mess = "";
+ if (message == "AcceptFriendRequest") {
+ mess = "Accepting request...";
+ prog = "30%";
+ }
+
+ if (message == "CreateFriend") {
+ mess = "Creating contact...";
+ prog = "60%";
+ }
+
+ if (message == "ValidateContact") {
+ mess = "Validating contact...";
+ prog = "80%";
+ }
+
+ $("#netvalidprognum").text(prog);
+ $("#netvalidprog").width(prog);
+ $("#netvalidprogmess").text(mess)
+
+
+ }, function (err, result) {
+
+ if (!err) {
+
+ selectedFriend.validated = true;
+ FRIENDSLIST[selectedFriend.userName].validated = true;
+ updateSelectedFriend();
+
+ $("#netvalidprognum").text('100%');
+ $("#netvalidprogmess").text('Contact validated');
+ $("#netvalidprog").width('100%');
+
+ setTimeout(function () {
+
+ //$("#validateform").hide();
+ //$("#validatesuccess").show();
+ $("#txtCode").val('');
+
+ $("#networkvalidate").hide();
+ $("#friendheader").show();
+ $("#mainWallet").show();
+ $(".footer").show();
+
+ $("#netvalidp2").hide();
+ $("#netvalidp1").show();
+ //update list also
+
+ //find friend in list and update the validated icon
+ $("#myfriends #seltarget" + selectedFriend.userName).html('
');
+
+ }, 1000);
+
+ } else {
+ $("#netvalidprogmess").text(result);
+ $("#btnNetValidDone").show();
+
+ }
+
+ });
});
@@ -4251,8 +5150,9 @@ function UI() {
if (!result) {
$("#addcontactmodal").show();
- $("#dashcontact").hide();
+ $("#dashcontact").addClass("invis");
+ $("#dashcontact").removeClass("slideUp");
//$("#imgaddcontactwaiting").show();
//var target = document.getElementById('imgaddcontactwaiting');
@@ -4273,38 +5173,51 @@ function UI() {
$("#textAddContact").text('Deriving addresses...');
+ Engine.createFriend(username, "", function (err, result) {
- Engine.createFriend(username, "#textAddContact", function (err, result) {
if (err) {
- //$("#friend").css("border-color", "#ffaaaa");
+ $("#friend").css("border-color", "#ffaaaa");
- //$("#addcontactalert").show();
- //$("#addcontactalertmessage").text("Error adding contact");
- //$("#imgaddcontactwaiting").hide();
+ $("#addcontactalert").show();
+ $("#addcontactalertmessage").text("Error adding contact");
+ $("#imgaddcontactwaiting").hide();
} else {
$("#addcontactprognum").text("100%");
$("#addcontactprogstatus").width("100%");
-
- //$("#addcontactmodal").hide();
$("#friend").val('');
- //$("#imgaddcontactwaiting").hide();
- //$("#addcontactsuccess").show();
$("#textAddContact").text("You requested " + username + " as a contact");
- //$("#addcontactsuccess").fadeOut(5000);
+
+ setTimeout(function () {
+ $("#addcontactmodal").hide();
+
+ $("#dashcontact").addClass("invis");
+ $("#dashcontact").removeClass("slideUp");
+
+ $("#contactrequest").hide();
+
+ $("#mainWallet").show();
+ $("#networklistheader").show();
+ $(".footer").show();
+ $("#friendrequestp1").show();
+ $("#friendrequestp2").hide();
+
+ }, 2000);
//updateRequestsMadeByMe();
}
+
+
});
} else {
$("#friend").css("border-color", "#ffaaaa");
$("#addcontactalert").show();
- $("#textAddContact").text("You have already requested " + username + " as a contact");
+ $("#addcontactalertmessage").text("You have already requested " + username + " as a contact");
//$("#imgaddcontactwaiting").hide();
}
@@ -4323,7 +5236,6 @@ function UI() {
}
-
function rejectFriend(username) {
Engine.rejectFriendRequest(username, function (err, result) {
@@ -4336,36 +5248,44 @@ function UI() {
function acceptFriend(username, message, callback) {
- console.log('calling accept acceptFriend');
+ message("AcceptFriendRequest");
- // $("#imgrequestwaiting").show();
- //var target = document.getElementById('imgrequestwaiting');
- // var spinner = new Spinner(spinneropts).spin(target);
+ Engine.acceptFriendRequest(username, function (err, result) {
- //$('#friendreq').fadeOut(1000);
- Engine.acceptFriendRequest(username, function (err, secret) {
if (err) {
- //alert("Wallet could not be opened.\n\n" + err);
+
+ return callback(err, result);
+
} else {
- console.log('accepted');
+
+
Engine.isNetworkExist(username, function (err, result) {
- if (!result) {
+ if (!err) {
- Engine.createFriend(username, message, function (err, result) {
+ if (!result) {
- if (err) {
+ message("CreateFriend");
- } else {
+ Engine.createFriend(username, message, function (err, result) {
- return callback(err, result);
- }
- });
+ if (err) {
+
+ } else {
+
+ return callback(err, result);
+ }
+ });
+
+ } else {
+
+ return callback(err, result);
+
+ }
} else {
return callback(err, result);
-
}
});
diff --git a/src/ninki-ui.js b/src/ninki-ui.js
index 9a5a5e6..b10a1a7 100644
--- a/src/ninki-ui.js
+++ b/src/ninki-ui.js
@@ -1,20 +1,13 @@
var Bitcoin = require('bitcoinjs-lib');
var BIP39 = require('./bip39');
-function UI() {
- var Engine = new Ninki.Engine();
+function UI() {
- // var WALLETINFORMATION = {};
- // var SHAREDID = '';
+ var Engine = new Ninki.Engine();
- // var TWOFACTORONLOGIN = false;
- // var NICKNAME = '';
- // var guid = '';
- // var oguid = '';
- // var password = '';
var FRIENDSLIST = {};
var COINUNIT = 'BTC';
@@ -85,97 +78,6 @@ function UI() {
};
-
- function setCookie(cname, cvalue) {
-
-
- if (isChromeApp()) {
-
- var obj = {};
- obj[cname] = cvalue;
- chrome.storage.local.set(obj, function () {
-
- console.log("saved");
-
- });
-
- }
- else {
-
- localStorage[cname] = cvalue;
-
- }
-
-
- }
-
- function isChromeApp() {
-
- var is_chrome = navigator.userAgent.toLowerCase().indexOf('chrome') > -1;
- if (is_chrome) {
- if (chrome) {
- if (chrome.app) {
- if (chrome.app.runtime) {
- return true;
- }
- }
- }
- }
- return false;
- }
-
-
- function getCookie(cname, callback) {
-
-
- if (isChromeApp()) {
-
- chrome.storage.local.get(cname, function (result) {
-
- if (result[cname]) {
- result = result[cname];
- } else {
- result = "";
- }
-
- return callback(result);
-
- });
-
- } else {
-
- if (localStorage[cname]) {
- return callback(localStorage[cname]);
- } else {
- return callback('');
- }
-
- }
-
- }
-
- function deleteCookie(cname) {
-
-
- if (isChromeApp()) {
-
- chrome.storage.local.remove(cname, function () {
-
- console.log("deleted");
-
- });
-
- } else {
-
- localStorage.removeItem(cname);
-
- }
- }
-
-
-
-
-
function getLocalTime(datetime) {
var timestamp = datetime,
@@ -233,6 +135,48 @@ function UI() {
jQuery(document).ready(function () {
+
+
+ $("#btnBackupCodes").click(function () {
+
+ $("#txt2faForBackupError").hide();
+
+ var twoFactorCode = $("#txt2faForBackup").val();
+
+ var codes = Engine.createBackupCodes(twoFactorCode, function (err, codes) {
+
+ if (!err) {
+
+ for (var i = 0; i < codes.length; i++) {
+
+ $("#bc" + (i + 1)).text(codes[i].Code.substring(0, 5) + ' ' + codes[i].Code.substring(5, 8));
+ }
+
+ Engine.m_settings.BackupIndex = 1;
+
+ $("#pnlBackupCodes").show();
+ $("#btnPrintCodes").show();
+ $("#btnBackupCodes").addClass('disabled');
+
+ } else {
+
+ $("#txt2faForBackupError").show();
+
+ }
+ });
+
+ });
+
+ $("#btnPairUseBackups").click(function () {
+
+ $("#pairerror").hide();
+ $("#pairqr2fa").hide();
+ $("#pairusebackup").show();
+
+ });
+
+
+
$("#btnBackupBeta").click(function () {
backupHotKey('#errbackupbeta');
@@ -242,7 +186,7 @@ function UI() {
$('#openWalletStart input#password').focus();
- var fatokk = getCookie("ninki_rem", function (res) {
+ var fatokk = Engine.Device.getStorageItem("ninki_rem", function (res) {
if (res.length > 0) {
$('#twofacenable').show();
@@ -252,8 +196,8 @@ function UI() {
var tmpContent = {};
$("#btnBrowseRestore").click(function () {
-
- chrome.fileSystem.chooseEntry({ type: 'openFile', accepts: [{ extensions: ['json']}] }, function (readOnlyEntry) {
+ //, accepts: [{ extensions: ['json']}]
+ chrome.fileSystem.chooseEntry({ type: 'openFile' }, function (readOnlyEntry) {
readOnlyEntry.file(function (file) {
var reader = new FileReader();
@@ -266,7 +210,7 @@ function UI() {
if (e.target.result) {
var json = JSON.parse(e.target.result);
tmpContent = json;
- restoreFromFile(m_this.m_password, json);
+ restoreFromFile(Engine.m_password, json);
} else {
$("#restoreerror").text('The file was empty');
}
@@ -384,7 +328,7 @@ function UI() {
$("#hunlock").click(function () {
- if (isChromeApp()) {
+ if (Engine.Device.isChromeApp()) {
chrome.app.window.create('recover_v1.html', {
'state': 'maximized'
});
@@ -406,7 +350,7 @@ function UI() {
$("#twofacenable").click(function () {
- deleteCookie("ninki_rem");
+ Engine.Device.deleteStorageItem("ninki_rem");
$('#twofacenable').hide();
});
@@ -442,7 +386,7 @@ function UI() {
var imageSrc = "images/avatar/256px/Avatar-" + pad(Engine.m_nickname.length) + ".png";
- if (isChromeApp()) {
+ if (Engine.Device.isChromeApp()) {
var xhrsm = new XMLHttpRequest();
xhrsm.open('GET', imageSrc, true);
xhrsm.responseType = 'blob';
@@ -487,7 +431,7 @@ function UI() {
}
- if (isChromeApp()) {
+ if (Engine.Device.isChromeApp()) {
var xhrsm = new XMLHttpRequest();
xhrsm.open('GET', imageSrc, true);
xhrsm.responseType = 'blob';
@@ -545,7 +489,7 @@ function UI() {
imageSrc = "https://ninkip2p.imgix.net/" + _.escape(Engine.m_profileImage) + "?crop=faces&fit=crop&h=256&w=256&mask=ellipse&border=1,d0d0d0";
}
- if (isChromeApp()) {
+ if (Engine.Device.isChromeApp()) {
var xhrsm = new XMLHttpRequest();
xhrsm.open('GET', imageSrc, true);
xhrsm.responseType = 'blob';
@@ -625,7 +569,7 @@ function UI() {
var file = files[0];
var fd = new FormData();
- key = "images\/" + Engine.m_nickname + '_' + (new Date).getTime()
+ key = "images\/" + Engine.m_nickname + '_' + (new Date).getTime();
Engine.createS3Policy(function (err, result) {
@@ -653,7 +597,7 @@ function UI() {
xhr.open('POST', 'https://ninkip2pimgstore.s3-us-west-1.amazonaws.com/', true); //MUST BE LAST LINE BEFORE YOU SEND
xhr.send(fd);
- }
+ }
});
}
@@ -678,7 +622,7 @@ function UI() {
var imageSrc = 'https://ninkip2p.imgix.net/' + _.escape(key) + "?fit=crop&crop=faces&h=128&w=128&mask=ellipse&border=1,d0d0d0";
- if (isChromeApp()) {
+ if (Engine.Device.isChromeApp()) {
var xhrsm = new XMLHttpRequest();
xhrsm.open('GET', imageSrc, true);
xhrsm.responseType = 'blob';
@@ -1038,7 +982,7 @@ function UI() {
var data = encdata.toString() + '|' + encdata.iv.toString() + '|' + Engine.m_oguid + '|' + currentDevice.DeviceName + '|' + jresult.RegToken;
- var options = { text: data, width: 256, height: 256 };
+ var options = { text: data, width: 256, height: 256, ecLevel: 'H' };
$('#qrdevice').text(data);
$('#qrdevice').qrcode(options);
@@ -1107,11 +1051,71 @@ function UI() {
$("#pairdevicemodal").modal('hide');
$("#pairdeviceqr").hide();
+
+ });
+
+ $("#btnUnpairBackupCancel").click(function () {
+ $("#pairdevicemodal").modal('hide');
+ $("#pairdeviceqr").hide();
+ $("#unpairbackupcode").val();
+ $("#pairerror").hide();
+ $("#pairqr2fa").show();
+ $("#pairusebackup").hide();
+ });
+
+
+ $("#btnUnpairBackupDone").click(function () {
+
+
+ $("#pairerror").hide();
+
+ var backupCode = $("#unpairbackupcode").val();
+
+
+ if (backupCode.length == 8) {
+
+ Engine.destroyDevice2fa(currentDevice.DeviceName, backupCode, function (err, result) {
+
+ if (!err) {
+
+ $('#upb' + Engine.m_settings.BackupIndex).removeAttr("style");
+
+ Engine.m_settings.BackupIndex = Engine.m_settings.BackupIndex + 1;
+
+ lastNoOfDevices = 0;
+ updateDeviceList();
+
+ $("#pairdevicemodal").modal('hide');
+ $("#pairdeviceqr").hide();
+
+ $("#pairerror").hide();
+ $("#pairqr2fa").show();
+ $("#pairusebackup").hide();
+
+
+ } else {
+
+ $('#pairerror').show();
+ $('#pairerrormess').text(result);
+
+ $('#upb' + Engine.m_settings.BackupIndex).removeAttr("style");
+
+ Engine.m_settings.BackupIndex = Engine.m_settings.BackupIndex + 1;
+
+ $('#upb' + Engine.m_settings.BackupIndex).attr("style", "border-color:red");
+
+ }
+
+ });
+
+ }
+
});
+
$("#btnLogin").click(function () {
if (!ensureOpenWalletGuidAndPasswordValid()) return;
@@ -1131,14 +1135,14 @@ function UI() {
Engine.setPass(password, guid);
- getCookie("ninki_rem", function (res) {
+ Engine.Device.getStorageItem("ninki_rem", function (res) {
if (res.length > 0) {
var enc = JSON.parse(res);
twoFactorCode = Engine.decryptNp(enc.ct, Engine.m_password, enc.iv);
}
- setCookie('guid', guid);
+ Engine.Device.setStorageItem('guid', guid);
@@ -1154,35 +1158,42 @@ function UI() {
$("#openwalletalert").hide();
+ if (!Engine.m_settings.HasBackupCodes) {
+ $("#btnPairUseBackups").hide();
+ $("#btnBackupCode2fa").hide();
+ $("#lost2fa").hide();
+ } else {
+ $("#lost2fa").show();
+ $("#btnPairUseBackups").show();
+ $("#btnBackupCode2fa").show();
+ }
+
if (result.TwoFactorOnLogin) {
//delete any old 2 factor tokens
- deleteCookie("ninki_rem");
+ Engine.Device.deleteStorageItem("ninki_rem");
if (!result.Beta12fa) {
$('#openWalletStart input#password').val('');
- if (result.TwoFactorOnLogin) {
-
- $("#siguid").hide();
- $("#silguid").hide();
- $("#sipwd").hide();
- $("#si2fa").show();
- $("#sib1").hide();
- $("#sib2").show();
- $("#signdiff").hide();
- $("#crwallet").hide();
+ $("#siguid").hide();
+ $("#silguid").hide();
+ $("#sipwd").hide();
+ $("#si2fa").show();
+ $("#sib1").hide();
+ $("#sib2").show();
+ $("#signdiff").hide();
+ $("#crwallet").hide();
+ $('#openWalletStart input#twoFactorCode').focus();
- $('#openWalletStart input#twoFactorCode').focus();
+ $("#btnLogin").prop('disabled', false);
+ $("#btnLogin").removeClass('disabled');
+ $("#imgopenwaiting").hide();
- $("#btnLogin").prop('disabled', false);
- $("#btnLogin").removeClass('disabled');
- $("#imgopenwaiting").hide();
- }
} else {
@@ -1204,13 +1215,13 @@ function UI() {
//initiate 2fa setup modal
- if (!m_this.m_twoFactorOnLogin) {
+ if (!Engine.m_twoFactorOnLogin) {
$("#twofactorsettings").show();
$("#2famodal").modal('show');
$("#twofactorsettings").show();
- $("#btnSetupTwoFactor").hide();
+ //$("#btnSetupTwoFactor").hide();
$("#savetwofactorerror").hide();
$("#setup2faemail").hide();
$("#setup2faqr").show();
@@ -1218,7 +1229,9 @@ function UI() {
$("#btnLogin").removeClass('disabled');
$("#imgopenwaiting").hide();
- showSettingsTwoFactorQr();
+
+
+ showMissingTwoFactorQr();
} else {
@@ -1227,8 +1240,8 @@ function UI() {
initialiseUI(function (err, result) {
- setCookie("user", Engine.m_nickname);
- setCookie("userimg", Engine.m_profileImage);
+ Engine.Device.setStorageItem("user", Engine.m_nickname);
+ Engine.Device.setStorageItem("userimg", Engine.m_profileImage);
$("#btnLogin").prop('disabled', false);
$("#btnLogin").removeClass('disabled');
@@ -1364,19 +1377,20 @@ function UI() {
$("#openwalletalertmessage").text(result);
$("#btn2faLogin").prop('disabled', false);
$("#btn2faLogin").removeClass('disabled');
+
} else {
if (result.CookieToken) {
- setCookie("ninki_rem", result.CookieToken);
+ Engine.Device.setStorageItem("ninki_rem", result.CookieToken);
}
if (Engine.m_walletinfo.hotHash == '') {
initialiseUI(function (err, result) {
- setCookie("user", Engine.m_nickname);
- setCookie("userimg", Engine.m_profileImage);
+ Engine.Device.setStorageItem("user", Engine.m_nickname);
+ Engine.Device.setStorageItem("userimg", Engine.m_profileImage);
});
@@ -1411,6 +1425,52 @@ function UI() {
});
+ $("#btnLoginBackupDone").click(function () {
+
+
+
+ var twoFactorCode = $('#txtLoginBackupCode').val();
+
+ if (twoFactorCode.length == 8) {
+
+ Engine.openWallet2fa(twoFactorCode, false, function (err, result) {
+
+ if (err) {
+
+ $('#log' + Engine.m_settings.BackupIndex).removeAttr("style");
+
+ Engine.m_settings.BackupIndex = Engine.m_settings.BackupIndex + 1;
+
+ $('#log' + Engine.m_settings.BackupIndex).attr("style", "border-color:red");
+
+ } else {
+
+ initialiseUI(function (err, result) {
+
+ $("#loginbackup").hide();
+
+ Engine.Device.setStorageItem("user", Engine.m_nickname);
+ Engine.Device.setStorageItem("userimg", Engine.m_profileImage);
+
+ $('#log' + Engine.m_settings.BackupIndex).removeAttr("style");
+
+ //increment not required as login will update settings
+
+ });
+
+ }
+
+ });
+
+ } else {
+
+ }
+
+
+
+ });
+
+
$("#btnEmailGuid").click(function () {
@@ -1506,13 +1566,73 @@ function UI() {
if (allok) {
- $('#sendstds2amt').text($('#hdamount').val() + ' ' + COINUNIT);
- $('#sendstds2add').text($('#toAddress').val());
+ Engine.Device.getStorageItem("tfso" + Engine.m_guid, function (res) {
+
+ if (res == "") {
+ //get the current limit status from the server
+ //and determine if we need 2fa or not
+
+ $('#sendstds2amt').text($('#hdamount').val() + ' ' + COINUNIT);
+ $('#sendstds2add').text($('#toAddress').val());
+
+ //$("#sendstds1").hide();
+ $("#sendstds3").hide();
+ $("#sendstds2").show();
+ $("#sendstdmodal").modal('show');
+
+ } else {
+
+ Engine.getLimitStatus(function (err, limits) {
+
+ var twofareq = false;
+ if ((limits.No24hr + 1) > limits.NoOfTransactionsPerDay) {
+ twofareq = true;
+ }
+ if ((limits.No1hr + 1) > limits.NoOfTransactionsPerHour) {
+ twofareq = true;
+ }
+
+ var amount = convertToSatoshis($('#hdamount').val(), COINUNIT);
+
+ if ((amount) > limits.SingleTransactionLimit) {
+ twofareq = true;
+ }
+ if ((limits.TotalAmount24hr + amount) > limits.DailyTransactionLimit) {
+ twofareq = true;
+ }
+
+ if (twofareq) {
+
+
+ $('#twofactreq').show();
+ $('#sendstds2amt').text($('#hdamount').val() + ' ' + COINUNIT);
+ $('#sendstds2add').text($('#toAddress').val());
+
+ //$("#sendstds1").hide();
+ $("#sendstds3").hide();
+ $("#sendstds2").show();
+ $("#sendstdmodal").modal('show');
+
+ } else {
+
+
+ $('#twofactreq').hide();
+ $('#sendstds2amt').text($('#hdamount').val() + ' ' + COINUNIT);
+ $('#sendstds2add').text($('#toAddress').val());
- //$("#sendstds1").hide();
- $("#sendstds3").hide();
- $("#sendstds2").show();
- $("#sendstdmodal").modal('show');
+ //$("#sendstds1").hide();
+ $("#sendstds3").hide();
+ $("#sendstds2").show();
+ $("#sendstdmodal").modal('show');
+
+ }
+
+
+ });
+
+ }
+
+ });
}
});
@@ -1561,13 +1681,79 @@ function UI() {
allok = false;
}
if (allok) {
- $('#sendnets2amt').text($('#hdfriendAmount').val() + ' ' + COINUNIT);
- $('#sendnets2add').text(SELECTEDFRIEND);
- //$("#networksend").hide();
- $("#sendnets3").hide();
- $("#sendnetmodal").modal('show');
- $("#sendnets2").show();
+ Engine.Device.getStorageItem("tfso" + Engine.m_guid, function (res) {
+
+ if (res == "") {
+
+
+ $('#sendnets2amt').text($('#hdfriendAmount').val() + ' ' + COINUNIT);
+ $('#sendnets2add').text(SELECTEDFRIEND);
+
+ //$("#networksend").hide();
+ $("#sendnets3").hide();
+ $("#sendnetmodal").modal('show');
+ $("#sendnets2").show();
+
+ $("#twofactreqnet").show();
+
+ } else {
+
+ Engine.getLimitStatus(function (err, limits) {
+
+ var twofareq = false;
+ if ((limits.No24hr + 1) > limits.NoOfTransactionsPerDay) {
+ twofareq = true;
+ }
+ if ((limits.No1hr + 1) > limits.NoOfTransactionsPerHour) {
+ twofareq = true;
+ }
+
+ var amount = convertToSatoshis($('#hdfriendAmount').val(), COINUNIT);
+
+ if ((amount) > limits.SingleTransactionLimit) {
+ twofareq = true;
+ }
+ if ((limits.TotalAmount24hr + amount) > limits.DailyTransactionLimit) {
+ twofareq = true;
+ }
+
+ if (twofareq) {
+
+
+ $('#sendnets2amt').text($('#hdfriendAmount').val() + ' ' + COINUNIT);
+ $('#sendnets2add').text(SELECTEDFRIEND);
+
+ //$("#networksend").hide();
+ $("#sendnets3").hide();
+ $("#sendnetmodal").modal('show');
+ $("#sendnets2").show();
+
+ $("#twofactreqnet").show();
+
+ } else {
+
+
+ $('#sendnets2amt').text($('#hdfriendAmount').val() + ' ' + COINUNIT);
+ $('#sendnets2add').text(SELECTEDFRIEND);
+
+ //$("#networksend").hide();
+ $("#sendnets3").hide();
+ $("#sendnetmodal").modal('show');
+ $("#sendnets2").show();
+
+ $("#twofactreqnet").hide();
+
+
+ }
+
+ });
+
+ }
+
+ });
+
+
}
});
@@ -1730,7 +1916,7 @@ function UI() {
$("#imgphrasewaiting").show();
- setCookie('guid', Engine.m_oguid);
+ Engine.Device.setStorageItem('guid', Engine.m_oguid);
Engine.openWalletAfterCreate(twoFactorCodeChk, function (err, result) {
@@ -1756,8 +1942,8 @@ function UI() {
$(".next").hide();
$(".previous").hide();
- setCookie("user", Engine.m_nickname);
- setCookie("userimg", Engine.m_profileImage);
+ Engine.Device.setStorageItem("user", Engine.m_nickname);
+ Engine.Device.setStorageItem("userimg", Engine.m_profileImage);
}
@@ -2267,7 +2453,7 @@ function UI() {
});
- getCookie('guid', function (res) {
+ Engine.Device.getStorageItem('guid', function (res) {
$("#openWalletStart #guid").val(res);
@@ -2276,14 +2462,14 @@ function UI() {
$("#guidsec").hide();
- if (isChromeApp()) {
+ if (Engine.Device.isChromeApp()) {
- getCookie('user', function (uname) {
+ Engine.Device.getStorageItem('user', function (uname) {
//console.write(res);
$("#loginuser").text(uname);
- getCookie('userimg', function (res) {
+ Engine.Device.getStorageItem('userimg', function (res) {
var imageSrcSmall = "images/avatar/64px/Avatar-" + pad(uname.length) + ".png";
@@ -2335,8 +2521,8 @@ function UI() {
// $("#coldWalletPhrase").printElement();
chrome.app.window.create('printwindow.html', { 'bounds': {
- 'width': Math.round(window.screen.availWidth * 0.8),
- 'height': Math.round(window.screen.availHeight * 0.8)
+ 'width': Math.round(window.screen.availWidth * 0.25),
+ 'height': Math.round(window.screen.availHeight * 0.25)
}
},
function (createdWindow) {
@@ -2351,8 +2537,28 @@ function UI() {
});
- $("#btnCreateInit").click(function () {
- $("#introduction").hide();
+ $("#btnPrintCodes").click(function () {
+ // $("#coldWalletPhrase").printElement();
+
+ chrome.app.window.create('printwindow.html', { 'bounds': {
+ 'width': Math.round(window.screen.availWidth * 0.2),
+ 'height': Math.round(window.screen.availHeight * 0.5)
+ }
+ },
+ function (createdWindow) {
+ var win = createdWindow.contentWindow;
+ win.onload = function () {
+ win.document.querySelector('#content').innerHTML = $("#codeprintarea").html();
+ win.print();
+ }
+ }
+ );
+
+ });
+
+
+ $("#btnCreateInit").click(function () {
+ $("#introduction").hide();
showCreateWalletStart();
});
@@ -2431,14 +2637,24 @@ function UI() {
$("#hlost2fa").click(function () {
- $("#createWalletStart").hide();
+ $("#logusebackup").show();
$("#openWalletStart").hide();
- $("#lostguid").hide();
- $("#reset2fa").show();
+ $("#loginbackup").show();
+
+ $('#log' + Engine.m_settings.BackupIndex).attr("style", "border-color:red");
+
+ });
+
+ $("#btnLoginBackupCancel").click(function () {
+
+ $("#logusebackup").hide();
+ $("#openWalletStart").show();
+ $("#loginbackup").hide();
});
+
$("#emailresend").click(function () {
Engine.sendWelcomeDetails(function (err, result) {
@@ -2500,7 +2716,7 @@ function UI() {
setTimeout(function () {
- Engine.ChangePassword(twoFactorCode, oldpassword, newpassword, "#chngpwdprogbar", "#chngpwdprogmess", false, '', '', function (err, results) {
+ Engine.ChangePassword(twoFactorCode, oldpassword, newpassword, function (err, results) {
if (err) {
$("#chngpwerr").show();
@@ -2512,24 +2728,6 @@ function UI() {
password = results;
-
- // Engine.getEncHotHash(function (err, data) {
-
- // var bb = new Blob([data], { type: 'text/plain' });
-
- // var a = document.getElementById('btnSaveBackupP');
-
- // var d = new Date();
- // var fdate = "" + (d.getDate()) + (d.getMonth() + 1) + (d.getFullYear());
-
- // a.download = "ninki_backup_" + _.escape(Engine.m_nickname) + "_" + fdate + ".json";
- // a.href = window.URL.createObjectURL(bb);
-
- // a.dataset.downloadurl = ['text/plain', a.download, a.href].join(':');
-
- // });
-
-
$("#pwdchangemain").hide();
$("#chngpwerr").hide();
@@ -2546,6 +2744,11 @@ function UI() {
}
+ }, function (message, progress) {
+
+ $("#chngpwdprogmess").text(message);
+ $("#chngpwdprogbar").width(progress);
+
});
@@ -2553,6 +2756,7 @@ function UI() {
}
} else {
+
$("#chngpwerr").show();
$("#chngpwerrmess").text("Passwords are the same. Password not updated");
$("#chngpwdprogmess").hide();
@@ -2664,18 +2868,41 @@ function UI() {
});
+
+ $("#btnBackupCode2fa").click(function () {
+
+ $('#fab' + Engine.m_settings.BackupIndex).attr("style", "border-color:red");
+
+ $("#tfausebackup").show();
+ $("#tfamove").hide();
+
+ });
+
+ $("#btn2faBackupCancel").click(function () {
+
+ $("#tfausebackup").hide();
+ $("#tfamove").show();
+
+ });
+
+
+
$("#btnSetupTwoFactor").click(function () {
- $("#twofactorsettings").show();
- $("#btnSetupTwoFactor").hide();
- $("#savetwofactorerror").hide();
- $("#setup2faemail").hide();
- $("#setup2faqr").show();
+
showSettingsTwoFactorQr();
});
+ $("#btn2faBackupDone").click(function () {
+
+
+ showSettingsBackupTwoFactorQr();
+
+ });
+
+
$("#btnSaveTwoFactor").click(function () {
//validate authenticator code
@@ -2691,7 +2918,13 @@ function UI() {
if (!err) {
//ok
- logout();
+ //logout();
+
+ $("#twofactorsettings").hide();
+ $("#2famodal").modal('hide');
+
+ $("#twoFactorCodeFor2fa").val('');
+ $("#txtsettings2fa").val('');
} else {
@@ -2804,15 +3037,82 @@ function UI() {
$("#btnpayinvoice").click(function () {
- $('input#txtInvoice2FA').css("border-color", "#ccc");
- $('input#txtInvoice2FA').val('');
- $("#sendinvprog").hide();
- $("#textMessageSendInv").hide();
+ Engine.Device.getStorageItem("tfso" + Engine.m_guid, function (res) {
+
+ if (res == "") {
+
+ $('input#txtInvoice2FA').css("border-color", "#ccc");
+ $('input#txtInvoice2FA').val('');
+
+ $("#sendinvprog").hide();
+ $("#textMessageSendInv").hide();
+
+ $("#sendinvs2").hide();
+ $("#sendinvs2").show();
+ $("#invmodal").modal('show');
+
+ $("#twofactreqinv").show();
+
+ } else {
+
+
+ Engine.getLimitStatus(function (err, limits) {
+
+ var twofareq = false;
+ if ((limits.No24hr + 1) > limits.NoOfTransactionsPerDay) {
+ twofareq = true;
+ }
+ if ((limits.No1hr + 1) > limits.NoOfTransactionsPerHour) {
+ twofareq = true;
+ }
+
+ var amount = selectedInvoiceAmount;
+
+ if ((amount) > limits.SingleTransactionLimit) {
+ twofareq = true;
+ }
+ if ((limits.TotalAmount24hr + amount) > limits.DailyTransactionLimit) {
+ twofareq = true;
+ }
+
+ if (twofareq) {
+
+ $('input#txtInvoice2FA').css("border-color", "#ccc");
+ $('input#txtInvoice2FA').val('');
+
+ $("#sendinvprog").hide();
+ $("#textMessageSendInv").hide();
+
+ $("#sendinvs2").hide();
+ $("#sendinvs2").show();
+ $("#invmodal").modal('show');
+
+ $("#twofactreqinv").show();
+
+
+ } else {
+
+ $('input#txtInvoice2FA').css("border-color", "#ccc");
+ $('input#txtInvoice2FA').val('');
+
+ $("#sendinvprog").hide();
+ $("#textMessageSendInv").hide();
+
+ $("#sendinvs2").hide();
+ $("#sendinvs2").show();
+ $("#invmodal").modal('show');
- $("#sendinvs2").hide();
- $("#sendinvs2").show();
- $("#invmodal").modal('show');
+ $("#twofactreqinv").hide();
+
+ }
+
+ });
+
+
+ }
+
+ });
});
@@ -2822,35 +3122,48 @@ function UI() {
var allok = true;
var twoFactorCode = $('#txtInvoice2FA').val();
- if (twoFactorCode.length == 6) {
- $('input#txtInvoice2FA').css("border-color", "#ccc");
- } else {
- $('input#txtInvoice2FA').css("border-color", "#ffaaaa");
- allok = false;
- }
+ Engine.get2faOverride(amount, function (err, result) {
- if (allok) {
+ if (result == "") {
+ if (twoFactorCode.length == 6) {
+ $('input#txtSendTwoFactor').css("border-color", "#ccc");
+ } else {
+ $('input#txtSendTwoFactor').css("border-color", "#ffaaaa");
+ allok = false;
+ }
+ } else {
+ twoFactorCode = result;
- $('#textMessageSendInv').removeClass('alert alert-danger');
- $('#textMessageSendInv').text('Creating transaction...');
- $('#textMessageSendInv').show();
- $('#sendinvprogstatus').width('3%')
- $('#sendinvprog').show();
- $('#sendinvprogstatus').width('10%');
+ }
- payInvoice(selectedInvoiceUserName, selectedInvoiceAmount, selectedInvoiceId, twoFactorCode, function (err, result) {
+ if (allok) {
- if (!err) {
+ $('#textMessageSendInv').removeClass('alert alert-danger');
+ $('#textMessageSendInv').text('Creating transaction...');
+ $('#textMessageSendInv').show();
+ $('#sendinvprogstatus').width('3%');
+ $('#sendinvprog').show();
+ $('#sendinvprogstatus').width('10%');
- $("#sendinvs2").hide();
- $("#sendinvs3").show();
- }
+ payInvoice(selectedInvoiceUserName, selectedInvoiceAmount, selectedInvoiceId, twoFactorCode, function (err, result) {
+ if (!err) {
+
+ $("#sendinvs2").hide();
+ $("#sendinvs3").show();
+ }
+
+
+ });
+
+ }
+
+
+
+ });
- });
- }
});
@@ -2997,7 +3310,7 @@ function UI() {
$("#invoicedisplay").hide();
uiInvoiceReturnToNetwork = true;
invoiceSelectedUser = SELECTEDFRIEND;
- lineCount = 0
+ lineCount = 0;
$("#createinvoiceforlabel").text('Create an Invoice for ' + SELECTEDFRIEND);
$("#tblinvoice tbody").empty();
@@ -3132,8 +3445,7 @@ function UI() {
$("#tax").text((subTotal * tax).toFixed(4));
$("#total").text((subTotal + (subTotal * tax)).toFixed(4));
- };
-
+ }
function validateInvoice() {
var subTotal = 0;
@@ -3228,10 +3540,7 @@ function UI() {
return isValid;
- };
-
-
-
+ }
var lineCount = 0;
function getRowTempate() {
var template = '' +
@@ -3394,7 +3703,7 @@ function UI() {
}
- if (isChromeApp()) {
+ if (Engine.Device.isChromeApp()) {
var xhrsm = new XMLHttpRequest();
xhrsm.open('GET', imageSrcSmall, true);
xhrsm.responseType = 'blob';
@@ -3688,7 +3997,7 @@ function UI() {
- if (isChromeApp()) {
+ if (Engine.Device.isChromeApp()) {
var xhrsm = new XMLHttpRequest();
xhrsm.open('GET', imageSrcSmall, true);
xhrsm.responseType = 'blob';
@@ -3795,7 +4104,7 @@ function UI() {
$("#tblinvdisplay tfoot th #dtax").text(convertFromSatoshis(json.summary.tax, COINUNIT));
$("#tblinvdisplay tfoot th #dtotal").text(convertFromSatoshis(json.summary.total, COINUNIT));
- selectedInvoiceAmount = convertFromSatoshis(json.summary.total);
+ selectedInvoiceAmount = json.summary.total;
selectedInvoiceId = invoice.InvoiceId;
selectedInvoiceUserName = invoice.InvoiceFrom;
@@ -3918,8 +4227,6 @@ function UI() {
function payInvoice(friend, amount, invoiceNumber, twoFactorCode, callback) {
-
-
Engine.sendTransaction('invoice', friend, '', amount, twoFactorCode, function (err, transactionid) {
if (!err) {
@@ -3964,8 +4271,10 @@ function UI() {
} else {
+
+
$('#textMessageSendInv').addClass('alert alert-danger');
- $('#sendinvprogstatus').width('0%')
+ $('#sendinvprogstatus').width('0%');
if (transactionid == "ErrInsufficientFunds") {
$('#textMessageSendInv').text('Transaction Failed: Not enough funds are currently available to send this transaction');
@@ -3979,6 +4288,16 @@ function UI() {
+ }, function (message, progress) {
+
+ if (message) {
+ $('#textMessageSendInv').text(message);
+ }
+
+ if (progress) {
+ $('#sendinvprogstatus').width(progress);
+ }
+
});
@@ -4042,7 +4361,7 @@ function UI() {
imageSrcSmall = "https://ninkip2p.imgix.net/" + _.escape(Engine.m_profileImage) + "?crop=faces&fit=crop&h=64&w=64&mask=ellipse&border=1,d0d0d0";
}
- if (isChromeApp()) {
+ if (Engine.Device.isChromeApp()) {
var xhr = new XMLHttpRequest();
xhr.open('GET', imageSrc, true);
@@ -4107,7 +4426,7 @@ function UI() {
if (!err) {
- document.onAway = function () { logout(); }
+ document.onAway = function () { logout(); };
setInterval(function () {
updateUI();
@@ -4117,7 +4436,7 @@ function UI() {
refreshSelectedFriend();
}, 30000);
-
+
$('#showPhrases').hide();
@@ -4202,7 +4521,7 @@ function UI() {
UI.updateUITimer = function () {
updateUI();
- }
+ };
@@ -4320,22 +4639,125 @@ function UI() {
function showSettingsTwoFactorQr() {
- $("#setup2faqr").show();
- $("#setting2fa").show();
- $("#settings2fa").show();
- $("#btnSetupTwoFactor").hide();
+ $("#twoFactorCodeFor2faError").hide();
+
+ var twoFactorCode = $("#twoFactorCodeFor2fa").val();
+
+ if (twoFactorCode.length == 6) {
+
+ Engine.getNewTwoFactorImg(twoFactorCode, function (err, twoFASecret) {
+
+ if (!err) {
+
+ var data = "otpauth://totp/Ninki:" + Engine.m_nickname + "?secret=" + twoFASecret + "&issuer=Ninki";
+ var options = { text: data, width: 172, height: 172 };
+
+ $('#imgsettings2fa').text('');
+ $('#imgsettings2fa').qrcode(options);
+
+ $("#setup2faqr").show();
+ $("#twofactorsettings").show();
+ $("#2famodal").modal('show');
+
+ $("#savetwofactorerror").hide();
+ $("#setup2faemail").hide();
+
+ } else {
+
+ $("#twoFactorCodeFor2faError").show();
+
+ }
+ });
+
+ } else {
+
+ $("#twoFactorCodeFor2faError").show();
+
+ }
+
+
+ }
+
+ function showSettingsBackupTwoFactorQr() {
+
+ //$("#twoFactorCodeFor2faError").hide();
+
+ var twoFactorCode = $("#txtTFABackupCode").val();
+
+ if (twoFactorCode.length == 8) {
+ Engine.getNewTwoFactorImg(twoFactorCode, function (err, twoFASecret) {
+
+ if (!err) {
+
+ var data = "otpauth://totp/Ninki:" + Engine.m_nickname + "?secret=" + twoFASecret + "&issuer=Ninki";
+ var options = { text: data, width: 172, height: 172 };
+
+ $('#imgsettings2fa').text('');
+ $('#imgsettings2fa').qrcode(options);
+
+ $("#setup2faqr").show();
+ $("#twofactorsettings").show();
+ $("#2famodal").modal('show');
+
+ //$("#savetwofactorerror").hide();
+ $("#setup2faemail").hide();
+
+ $("#tfausebackup").hide();
+ $("#tfamove").show();
+
+ $('#fab' + Engine.m_settings.BackupIndex).removeAttr("style");
+
+ Engine.m_settings.BackupIndex = Engine.m_settings.BackupIndex + 1;
+
+ } else {
+
+ $('#fab' + Engine.m_settings.BackupIndex).removeAttr("style");
+
+ Engine.m_settings.BackupIndex = Engine.m_settings.BackupIndex + 1;
+
+ $('#fab' + Engine.m_settings.BackupIndex).attr("style", "border-color:red");
+
+ //$("#twoFactorCodeFor2faError").show();
+
+ }
+ });
+
+ } else {
+
+ // $("#twoFactorCodeFor2faError").show();
+
+ }
+ }
+ function showMissingTwoFactorQr() {
+
Engine.getTwoFactorImg(function (err, twoFASecret) {
- var data = "otpauth://totp/Ninki:" + Engine.m_nickname + "?secret=" + twoFASecret + "&issuer=Ninki";
- var options = { text: data, width: 172, height: 172 };
+ if (!err) {
+
+ var data = "otpauth://totp/Ninki:" + Engine.m_nickname + "?secret=" + twoFASecret + "&issuer=Ninki";
+ var options = { text: data, width: 172, height: 172 };
+
+ $('#imgsettings2fa').text('');
+ $('#imgsettings2fa').qrcode(options);
+
+ $("#setup2faqr").show();
+ $("#twofactorsettings").show();
+ $("#2famodal").modal('show');
+
+ $("#savetwofactorerror").hide();
+ $("#setup2faemail").hide();
+
+ } else {
+
+ $("#twoFactorCodeFor2faError").show();
+
+ }
- $('#imgsettings2fa').text('');
- $('#imgsettings2fa').qrcode(options);
- });
+ });
}
@@ -4353,7 +4775,7 @@ function UI() {
$("#SingleTransactionLimit").prop('disabled', false);
$("#NoOfTransactionsPerDay").prop('disabled', false);
$("#NoOfTransactionsPerHour").prop('disabled', false);
- $("#btnSetupTwoFactor").hide();
+ //$("#btnSetupTwoFactor").hide();
} else {
$("#settings2faok").hide();
@@ -4421,12 +4843,52 @@ function UI() {
$('#lcCNY').prop('checked', true);
}
+ Engine.Device.getStorageItem("tfso" + Engine.m_guid, function (res) {
+
+ if (res == "") {
+
+ $('#chkTwoFactorLimits').prop('checked', false);
+
+ } else {
+
+ $('#chkTwoFactorLimits').prop('checked', true);
+ }
+
+ });
+
+
+ $('#pnlBackupCodes').hide();
+ if (!settingsObject.HasBackupCodes) {
+ $('#pnlBackupBtn').show();
+ $('#pnlBackupIsSetup').hide();
+ $('#libackupcodes').show();
+ } else {
+
+ if (settingsObject.BackupIndex > 7) {
+ $('#pnlBackupBtn').show();
+ $('#pnlBackupIsSetup').hide();
+ $('#libackupcodes').show();
+ } else {
+
+ $('#pnlBackupBtn').show();
+ $('#pnlBackupIsSetup').show();
+ $('#libackupcodes').hide();
+ }
+ }
+
+
+
}
});
}
function saveAccountSettingsToServer() {
+
+
+ $("#savesettingssuccess").hide();
+ $("#savesettingserror").hide();
+
var jsonPacket = {
guid: Engine.m_guid
};
@@ -4461,68 +4923,88 @@ function UI() {
$("#amount").val('');
}
+ var twoFactorSend = false;
- Engine.updateAccountSettings(jsonPacket, $("#txtTwoFactorCodeForSettings").val(), function (err, response) {
- if (err) {
- $("#savesettingserror").show();
- $("#savesettingssuccess").hide();
- $("#savesettingserrormessage").text(response);
- } else {
+ Engine.Device.getStorageItem("tfso" + Engine.m_guid, function (res) {
- var stdcoinunitsel = false;
- if ($("#stdselunit").text() == COINUNIT) {
- stdcoinunitsel = true;
- }
+ if (res == "" && $('#chkTwoFactorLimits')[0].checked) {
- var netcoinunitsel = false;
- if ($("#netselunit").text() == COINUNIT) {
- netcoinunitsel = true;
- }
+ twoFactorSend = true;
- if (jsonPacket['CoinUnit'] != COINUNIT) {
- COINUNIT = jsonPacket['CoinUnit'];
- lastNoOfTrans = -1;
- readAccountSettings();
- $("#stdsendcunit").text(COINUNIT);
- $("#amount").val('');
- $("#friendAmount").val('');
- }
+ }
- $("#stdsendlcurr").text(Engine.m_settings.LocalCurrency);
+ if (res.length > 0 && !$('#chkTwoFactorLimits')[0].checked) {
+
+ Engine.Device.deleteStorageItem("tfso" + Engine.m_guid);
+
+ }
- if (stdcoinunitsel) {
+ Engine.updateAccountSettings(jsonPacket, $("#txtTwoFactorCodeForSettings").val(), twoFactorSend, function (err, response) {
- $("#stdselunit").text(COINUNIT);
+ if (err) {
+ $("#savesettingserror").show();
+ $("#savesettingssuccess").hide();
+ $("#savesettingserrormessage").text(response);
} else {
- $("#stdselunit").text(Engine.m_settings.LocalCurrency);
- }
+ var stdcoinunitsel = false;
+ if ($("#stdselunit").text() == COINUNIT) {
+ stdcoinunitsel = true;
+ }
- if (netcoinunitsel) {
+ var netcoinunitsel = false;
+ if ($("#netselunit").text() == COINUNIT) {
+ netcoinunitsel = true;
+ }
- $("#netselunit").text(COINUNIT);
+ if (jsonPacket['CoinUnit'] != COINUNIT) {
+ COINUNIT = jsonPacket['CoinUnit'];
+ lastNoOfTrans = -1;
+ readAccountSettings();
+ $("#stdsendcunit").text(COINUNIT);
+ $("#amount").val('');
+ $("#friendAmount").val('');
+ }
- } else {
+ $("#stdsendlcurr").text(Engine.m_settings.LocalCurrency);
- $("#netselunit").text(Engine.m_settings.LocalCurrency);
+ if (stdcoinunitsel) {
- }
+ $("#stdselunit").text(COINUNIT);
- $("#amount").keyup();
- $("#friendAmount").keyup();
+ } else {
+ $("#stdselunit").text(Engine.m_settings.LocalCurrency);
- updateUI();
+ }
- $("#savesettingssuccess").show();
- $("#savesettingserror").hide();
- $("#savesettingssuccessmessage").text("Settings saved successfully");
+ if (netcoinunitsel) {
+
+ $("#netselunit").text(COINUNIT);
+
+ } else {
+
+ $("#netselunit").text(Engine.m_settings.LocalCurrency);
+
+ }
+
+ $("#amount").keyup();
+ $("#friendAmount").keyup();
+
+
+ updateUI();
+
+ $("#savesettingssuccess").show();
+ $("#savesettingserror").hide();
+ $("#savesettingssuccessmessage").text("Settings saved successfully");
+
+ //alert(response.body);
+ }
+ });
- //alert(response.body);
- }
});
} else {
@@ -4575,7 +5057,7 @@ function UI() {
amount = amount * 100;
}
- amount = Math.round(amount)
+ amount = Math.round(amount);
return amount;
}
@@ -4756,14 +5238,17 @@ function UI() {
$('#qrdevice').text('');
-
+ $('#pairerror').hide();
if (!event.data.device.IsPaired) {
+
$('#pairqrscan').hide();
$("#pairdevicemodal").modal('show');
$("#pairdeviceqr").show();
$('#pairqr2fa').show();
$("#pairheading").text("Pair " + event.data.device.DeviceName);
+ $("#btnShowPairQr").text("Pair");
+ $('#btnPairUseBackups').hide();
} else {
@@ -4773,6 +5258,12 @@ function UI() {
$("#pairheading").text("Unpair " + event.data.device.DeviceName);
$("#btnShowPairQr").text("Unpair");
$('#qrdevice').text('');
+ $('#btnPairUseBackups').show();
+
+
+ $('#upb' + Engine.m_settings.BackupIndex).attr("style", "border-color:red");
+
+
//$('#qrdevice').qrcode('');
}
@@ -4836,12 +5327,11 @@ function UI() {
}
});
+ }
- }
-
var lastNoOfFriends = 0;
var invoiceSelectedUser = '';
@@ -4855,156 +5345,165 @@ function UI() {
Engine.getUserNetwork(function (err, friends) {
- $("#nfriends").text(friends.length);
- if (friends.length > lastNoOfFriends) {
+ if (!err) {
- lastNoOfFriends = friends.length;
- FRIENDSLIST = {};
+ $("#nfriends").text(friends.length);
- for (var i = 0; i < friends.length; i++) {
- FRIENDSLIST[friends[i].userName] = friends[i];
- }
+ if (friends.length > lastNoOfFriends) {
- //if selected friend is not isend and isreceive
- //then find in list and update
+ lastNoOfFriends = friends.length;
- if (selectedFriend != null) {
+ FRIENDSLIST = {};
- if (!selectedFriend.ICanSend || !selectedFriend.ICanReceive) {
- selectedFriend = FRIENDSLIST[selectedFriend.userName];
- updateSelectedFriend();
+ for (var i = 0; i < friends.length; i++) {
+ FRIENDSLIST[friends[i].userName] = friends[i];
}
- }
+ //if selected friend is not isend and isreceive
+ //then find in list and update
+ if (selectedFriend != null) {
- $("#nfriends").text(friends.length);
- $("#myfriends").text('');
+ if (!selectedFriend.ICanSend || !selectedFriend.ICanReceive) {
+ selectedFriend = FRIENDSLIST[selectedFriend.userName];
+ updateSelectedFriend();
+ }
+ }
- var grouptemplate = '';
- var friendsgroup = _.groupBy(friends, function (item) { return item.category; })
+ $("#nfriends").text(friends.length);
+ $("#myfriends").text('');
- grouptemplate += '';
- var k = 0;
- var g = 1;
- for (var key in friendsgroup) {
+ var grouptemplate = '';
- friends = friendsgroup[key];
+ var friendsgroup = _.groupBy(friends, function (item) { return item.category; });
- grouptemplate += '
';
- grouptemplate += '
';
- grouptemplate += '
';
- grouptemplate += '
';
+ grouptemplate += '
';
+
+ var k = 0;
+ var g = 1;
+ for (var key in friendsgroup) {
+
+ friends = friendsgroup[key];
+
+ grouptemplate += '
';
+ grouptemplate += '
';
+ grouptemplate += '
';
- grouptemplate += '
';
- grouptemplate += '
';
- g++;
- }
-
- grouptemplate += '
';
-
- $("#myfriends").html(grouptemplate);
+ $("#myfriends").html(grouptemplate);
- var k = 0;
- var g = 1;
- for (var key in friendsgroup) {
- friends = friendsgroup[key];
- for (var i = 0; i < friendsgroup[key].length; i++) {
+ var k = 0;
+ var g = 1;
+ for (var key in friendsgroup) {
friends = friendsgroup[key];
+ for (var i = 0; i < friendsgroup[key].length; i++) {
+ friends = friendsgroup[key];
- var length = friends[i].userName.length;
- if (length > 20) {
- length = 20;
- }
- var imageSrc = "images/avatar/64px/Avatar-" + pad(length) + ".png";
+ var length = friends[i].userName.length;
+ if (length > 20) {
+ length = 20;
+ }
- if (friends[i].profileImage != '') {
- imageSrc = "https://ninkip2p.imgix.net/" + _.escape(friends[i].profileImage) + "?crop=faces&fit=crop&h=256&w=256&mask=ellipse&border=1,d0d0d0";
- imageSrcSmall = "https://ninkip2p.imgix.net/" + _.escape(friends[i].profileImage) + "?crop=faces&fit=crop&h=64&w=64&mask=ellipse&border=1,d0d0d0";
- }
+ var imageSrc = "images/avatar/64px/Avatar-" + pad(length) + ".png";
- //$("#myfriends #imgfriend" + k)
-
- if (isChromeApp()) {
- var xhrsm = new XMLHttpRequest();
- xhrsm.open('GET', imageSrc, true);
- xhrsm.responseType = 'blob';
- xhrsm.index = k;
- xhrsm.onload = function (e) {
- $("#myfriends #imgfriend" + this.index).attr("src", window.URL.createObjectURL(this.response));
- };
- xhrsm.send();
- } else {
- $("#myfriends #imgfriend" + k).attr("src", imageSrc);
- }
+ if (friends[i].profileImage != '') {
+ imageSrc = "https://ninkip2p.imgix.net/" + _.escape(friends[i].profileImage) + "?crop=faces&fit=crop&h=256&w=256&mask=ellipse&border=1,d0d0d0";
+ imageSrcSmall = "https://ninkip2p.imgix.net/" + _.escape(friends[i].profileImage) + "?crop=faces&fit=crop&h=64&w=64&mask=ellipse&border=1,d0d0d0";
+ }
+ //$("#myfriends #imgfriend" + k)
+
+ if (Engine.Device.isChromeApp()) {
+ var xhrsm = new XMLHttpRequest();
+ xhrsm.open('GET', imageSrc, true);
+ xhrsm.responseType = 'blob';
+ xhrsm.index = k;
+ xhrsm.onload = function (e) {
+ $("#myfriends #imgfriend" + this.index).attr("src", window.URL.createObjectURL(this.response));
+ };
+ xhrsm.send();
+ } else {
+ $("#myfriends #imgfriend" + k).attr("src", imageSrc);
+ }
- $("#myfriends #friend" + k).click({ userName: friends[i].userName }, function (event) {
- SELECTEDFRIEND = event.data.userName;
- selectedFriend = FRIENDSLIST[event.data.userName];
+ $("#myfriends #friend" + k).click({ userName: friends[i].userName }, function (event) {
- //depreciate
+ SELECTEDFRIEND = event.data.userName;
+ selectedFriend = FRIENDSLIST[event.data.userName];
+ //depreciate
- updateSelectedFriend();
- $("#friendAmount").keyup();
+ updateSelectedFriend();
+ $("#friendAmount").keyup();
- });
- console.log("added click " + k + " for " + friends[i].userName);
- k++;
+ });
+ console.log("added click " + k + " for " + friends[i].userName);
+
+ k++;
+ }
+ g++;
}
- g++;
+
}
- }
+ return callback(false, "done");
- return callback(false, "done");
+ } else {
+
+ return callback(true, "done");
+ }
});
}
@@ -5044,7 +5543,7 @@ function UI() {
imageSrc = "https://ninkip2p.imgix.net/" + _.escape(selectedFriend.profileImage) + "?crop=faces&fit=crop&h=256&w=256&mask=ellipse&border=1,d0d0d0";
}
- if (isChromeApp()) {
+ if (Engine.Device.isChromeApp()) {
var xhrsm = new XMLHttpRequest();
xhrsm.open('GET', imageSrc, true);
xhrsm.responseType = 'blob';
@@ -5168,7 +5667,7 @@ function UI() {
$("#friendSelectedStatus").text(selectedFriend.status);
//}
- if (isChromeApp()) {
+ if (Engine.Device.isChromeApp()) {
var xhrsm = new XMLHttpRequest();
xhrsm.open('GET', imageSrc, true);
xhrsm.responseType = 'blob';
@@ -5550,7 +6049,7 @@ function UI() {
imageSrcSmall = "https://ninkip2p.imgix.net/" + _.escape(FRIENDSLIST[transactions[i].UserName].profileImage) + "?crop=faces&fit=crop&h=64&w=64&mask=ellipse&border=1,d0d0d0";
}
}
- if (isChromeApp()) {
+ if (Engine.Device.isChromeApp()) {
var xhrsm = new XMLHttpRequest();
xhrsm.open('GET', imageSrcSmall, true);
xhrsm.responseType = 'blob';
@@ -5582,6 +6081,7 @@ function UI() {
function generateAddressClient() {
+
Engine.createAddress('m/0/0', 1, function (err, newAddress, path) {
var options = { text: newAddress, width: 172, height: 172 };
@@ -5621,54 +6121,77 @@ function UI() {
allok = false;
}
- if (twoFactorCode.length == 6) {
- $('input#txtFriendSend2FA').css("border-color", "#ccc");
- } else {
- $('input#txtFriendSend2FA').css("border-color", "#ffaaaa");
- allok = false;
- }
- if (allok) {
- $('input#friendAmount').css("border-color", "#ccc");
- $('#textMessageSend').text('Creating transaction...');
- $('#textMessageSend').show();
- $('#sendfriendprogstatus').width('3%')
- $('#sendfriendprog').show();
- $('#sendfriendprogstatus').width('10%');
- Engine.sendTransaction('friend', friend, '', amount, twoFactorCode, function (err, transactionid) {
+ Engine.get2faOverride(amount, function (err, result) {
- if (!err) {
- updateBalance();
- $('#textCompleteSendNet').text('You sent ' + convertFromSatoshis(amount, COINUNIT) + ' ' + COINUNIT + ' to ' + friend);
- $('input#friendAmount').val('');
+ if (result == "") {
+
+ if (twoFactorCode.length == 6) {
+ $('input#txtSendTwoFactor').css("border-color", "#ccc");
+ } else {
+ $('input#txtSendTwoFactor').css("border-color", "#ffaaaa");
+ allok = false;
+ }
+ } else {
+
+ twoFactorCode = result;
+
+ }
+ if (allok) {
+ $('input#friendAmount').css("border-color", "#ccc");
+ $('#textMessageSend').text('Creating transaction...');
+ $('#textMessageSend').show();
+ $('#sendfriendprogstatus').width('3%');
+ $('#sendfriendprog').show();
+ $('#sendfriendprogstatus').width('10%');
+ Engine.sendTransaction('friend', friend, '', amount, twoFactorCode, function (err, transactionid) {
- $("#sendnets2").hide();
- $("#sendnets3").show();
+ if (!err) {
+ updateBalance();
+ $('#textCompleteSendNet').text('You sent ' + convertFromSatoshis(amount, COINUNIT) + ' ' + COINUNIT + ' to ' + friend);
+ $('input#friendAmount').val('');
- //$('#textMessageSend').fadeOut(5000);
- //$('#sendfriendprog').fadeOut(5000);
- } else {
- $('#textMessageSend').addClass('alert alert-danger');
- $('#sendfriendprogstatus').width('0%')
+ $("#sendnets2").hide();
+ $("#sendnets3").show();
+
+
+ //$('#textMessageSend').fadeOut(5000);
+ //$('#sendfriendprog').fadeOut(5000);
- if (transactionid == "ErrInsufficientFunds") {
- $('#textMessageSend').text('Transaction Failed: Not enough funds are currently available to send this transaction');
- } else if (result == 'ErrLocked') {
- $('#textMessageSend').text('Transaction Failed: Account is unavailable');
} else {
- $('#textMessageSend').text(transactionid);
+ $('#textMessageSend').addClass('alert alert-danger');
+ $('#sendfriendprogstatus').width('0%');
+
+ if (transactionid == "ErrInsufficientFunds") {
+ $('#textMessageSend').text('Transaction Failed: Not enough funds are currently available to send this transaction');
+ } else if (result == 'ErrLocked') {
+ $('#textMessageSend').text('Transaction Failed: Account is unavailable');
+ } else {
+ $('#textMessageSend').text(transactionid);
+ }
+
+
}
+ // alert(transactionid);
+ }, function (message, progress) {
+ if (message) {
+ $('#textMessageSend').text(message);
+ }
- }
- // alert(transactionid);
- });
+ if (progress) {
+ $('#sendfriendprogstatus').width(progress);
+ }
- }
+ });
+
+ }
+
+ });
}
@@ -5700,52 +6223,72 @@ function UI() {
allok = false;
}
- if (twoFactorCode.length == 6) {
- $('input#txtSendTwoFactor').css("border-color", "#ccc");
- } else {
- $('input#txtSendTwoFactor').css("border-color", "#ffaaaa");
- allok = false;
- }
+ Engine.get2faOverride(amount, function (err, result) {
+ if (result == "") {
+
+ if (twoFactorCode.length == 6) {
+ $('input#txtSendTwoFactor').css("border-color", "#ccc");
+ } else {
+ $('input#txtSendTwoFactor').css("border-color", "#ffaaaa");
+ allok = false;
+ }
+ } else {
+ twoFactorCode = result;
- if (allok) {
+ }
- $('#textMessageSendStd').text('Creating transaction...');
- $('#textMessageSendStd').show();
- $('#sendstdprogstatus').width('3%')
- $('#sendstdprog').show();
- $('#sendstdprogstatus').width('10%');
+ if (allok) {
+ $('#textMessageSendStd').text('Creating transaction...');
+ $('#textMessageSendStd').show();
+ $('#sendstdprogstatus').width('3%');
+ $('#sendstdprog').show();
+ $('#sendstdprogstatus').width('10%');
- Engine.sendTransaction('standard', '', address, amount, twoFactorCode, function (err, transactionid) {
- if (!err) {
+ Engine.sendTransaction('standard', '', address, amount, twoFactorCode, function (err, transactionid) {
- var confmess = 'You sent ' + _.escape(convertFromSatoshis(amount, COINUNIT)) + ' ' + _.escape(COINUNIT) + ' to
' + _.escape(address) + '';
+ if (!err) {
- $('#textCompleteSendStd').html(confmess);
- $('input#amount').val('');
- $('input#toAddress').val('');
- //$('#textMessageSendStd').fadeOut(5000);
- //$('#sendstdprog').fadeOut(5000);
+ var confmess = 'You sent ' + _.escape(convertFromSatoshis(amount, COINUNIT)) + ' ' + _.escape(COINUNIT) + ' to
' + _.escape(address) + '';
- $('#sendstds2').hide();
- $('#sendstds3').show();
+ $('#textCompleteSendStd').html(confmess);
+ $('input#amount').val('');
+ $('input#toAddress').val('');
+ //$('#textMessageSendStd').fadeOut(5000);
+ //$('#sendstdprog').fadeOut(5000);
- } else {
+ $('#sendstds2').hide();
+ $('#sendstds3').show();
- if (transactionid == "ErrInsufficientFunds") {
- $('#textMessageSendStd').text('Transaction Failed: Not enough funds are currently available to send this transaction');
} else {
- $('#textMessageSendStd').text(transactionid)
+
+ if (transactionid == "ErrInsufficientFunds") {
+ $('#textMessageSendStd').text('Transaction Failed: Not enough funds are currently available to send this transaction');
+ } else {
+ $('#textMessageSendStd').text(transactionid)
+ }
+
+ $('#sendstdprogstatus').width('0%');
+ $('#textMessageSendStd').addClass('alert alert-danger');
}
+ }, function (message, progress) {
+
+ if (message) {
+ $('#textMessageSendStd').text(message);
+ }
+
+ if (progress) {
+ $('#sendstdprogstatus').width(progress);
+ }
+
+ });
+ }
+
+ });
- $('#sendstdprogstatus').width('0%')
- $('#textMessageSendStd').addClass('alert alert-danger');
- }
- });
- }
}
@@ -5909,6 +6452,7 @@ function UI() {
}
+
function ensureOpenWalletGuidAndPasswordValid() {
if (Engine.isRealGuid($("#openWalletStart input#guid").val())) {
diff --git a/tests/test-accept-contact-request-1.js b/tests/test-accept-contact-request-1.js
new file mode 100644
index 0000000..21b37a1
--- /dev/null
+++ b/tests/test-accept-contact-request-1.js
@@ -0,0 +1,133 @@
+var request = require('superagent');
+var expect = require('expect.js');
+var Engine = require('../src/ninki-engine');
+var API = require('../src/ninki-api');
+var BIP39 = require('../src/bip39.js');
+var speakeasy = require('speakeasy');
+var bs = require('browser-storage');
+
+var engine = new Engine();
+
+var guid = bs.getItem("testguid2");
+var guid2 = bs.getItem("testguid");
+
+var phrase = bs.getItem("fp" + guid2);
+
+
+var username2 = guid2.substring(0, 7);
+
+var password = "12345678";
+var FASecret = bs.getItem("tfasec2");
+
+console.log(guid);
+console.log(FASecret);
+
+
+describe('Account Utilities', function () {
+
+
+ describe('Login Functions', function () {
+
+
+ describe('openWallet', function () {
+
+
+ this.timeout(10000);
+
+ it("Verifies the users login details", function (done) {
+
+
+ engine.setPass(password, guid);
+
+
+ console.log(guid);
+
+ engine.openWallet(guid, "", function (err, result) {
+
+
+ console.log(result);
+
+ expect(err).to.equal(false);
+ expect(result).to.exist;
+
+ var twoFactorCode = speakeasy.totp({ key: FASecret, encoding: 'base32' });
+
+ console.log(twoFactorCode);
+
+ console.log("calling openWallet2fa");
+
+
+ engine.openWallet2fa(twoFactorCode, true, function (err, result) {
+
+ console.log(result);
+
+ expect(err).to.equal(false);
+ expect(result).to.exist;
+
+ done();
+
+ });
+
+
+ });
+
+ });
+
+ });
+
+ });
+
+
+ describe('User Functions', function () {
+
+ describe('accept contact request', function () {
+
+ this.timeout(5000);
+
+ it("Adds a contact", function (done) {
+
+ console.log(username2);
+
+ engine.acceptFriendRequest(username2, function (err, result) {
+
+ console.log(result);
+
+ var bip39 = new BIP39();
+ var code = bip39.mnemonicToHex(phrase);
+
+ engine.verifyFriendData(username2, code, function (err, result) {
+
+ engine.isNetworkExist(username2, function (err, result) {
+
+ console.log(result);
+
+ if (!result) {
+
+ engine.createFriend(username2, '', function (err, result) {
+
+ expect(err).to.equal(false);
+ expect(result).to.exist;
+
+ done();
+
+
+ });
+
+ }
+
+ });
+
+
+ });
+
+ });
+
+ });
+
+ });
+
+
+ });
+
+
+});
diff --git a/tests/test-accept-contact-request-2.js b/tests/test-accept-contact-request-2.js
new file mode 100644
index 0000000..abdc0fb
--- /dev/null
+++ b/tests/test-accept-contact-request-2.js
@@ -0,0 +1,121 @@
+var request = require('superagent');
+var expect = require('expect.js');
+var Engine = require('../src/ninki-engine');
+var API = require('../src/ninki-api');
+var speakeasy = require('speakeasy');
+var bs = require('browser-storage');
+
+var BIP39 = require('../src/bip39.js');
+
+var engine = new Engine();
+
+var guid = bs.getItem("testguid");
+var guid2 = bs.getItem("testguid2");
+
+var phrase = bs.getItem("fp" + guid2);
+
+
+var username2 = guid2.substring(0, 7);
+
+var password = "12345678";
+var FASecret = bs.getItem("tfasec");
+
+console.log(guid);
+console.log(FASecret);
+
+
+describe('Account Utilities', function () {
+
+
+ describe('Login Functions', function () {
+
+
+ describe('openWallet', function () {
+
+
+ this.timeout(10000);
+
+ it("Verifies the users login details", function (done) {
+
+
+ engine.setPass(password, guid);
+
+
+ console.log(guid);
+
+ engine.openWallet(guid, "", function (err, result) {
+
+
+ console.log(result);
+
+ expect(err).to.equal(false);
+ expect(result).to.exist;
+
+ var twoFactorCode = speakeasy.totp({ key: FASecret, encoding: 'base32' });
+
+ console.log(twoFactorCode);
+
+ console.log("calling openWallet2fa");
+
+
+ engine.openWallet2fa(twoFactorCode, true, function (err, result) {
+
+ console.log(result);
+
+ expect(err).to.equal(false);
+ expect(result).to.exist;
+
+ done();
+
+ });
+
+
+ });
+
+ });
+
+ });
+
+ });
+
+
+ describe('User Functions', function () {
+
+ describe('accept contact request', function () {
+
+ this.timeout(5000);
+
+ it("Adds a contact", function (done) {
+
+ console.log(username2);
+
+
+ engine.acceptFriendRequest(username2, function (err, result) {
+
+ var bip39 = new BIP39();
+ var code = bip39.mnemonicToHex(phrase);
+
+ engine.verifyFriendData(username2, code, function (err, result) {
+
+ console.log(result);
+
+ expect(err).to.equal(false);
+ expect(result).to.exist;
+
+ done();
+
+ });
+
+
+
+ });
+
+ });
+
+ });
+
+
+ });
+
+
+});
diff --git a/tests/test-add-contact.js b/tests/test-add-contact.js
new file mode 100644
index 0000000..f73a9d3
--- /dev/null
+++ b/tests/test-add-contact.js
@@ -0,0 +1,111 @@
+var request = require('superagent');
+var expect = require('expect.js');
+var Engine = require('../src/ninki-engine');
+var API = require('../src/ninki-api');
+var speakeasy = require('speakeasy');
+var bs = require('browser-storage');
+
+var engine = new Engine();
+
+var guid = bs.getItem("testguid");
+var guid2 = bs.getItem("testguid2");
+
+
+var username2 = guid2.substring(0, 7);
+
+var password = "12345678";
+var FASecret = bs.getItem("tfasec");
+
+console.log(guid);
+console.log(FASecret);
+
+
+describe('Account Utilities', function () {
+
+
+ describe('Login Functions', function () {
+
+
+ describe('openWallet', function () {
+
+
+ this.timeout(10000);
+
+ it("Verifies the users login details", function (done) {
+
+
+ engine.setPass(password, guid);
+
+
+ console.log(guid);
+
+ engine.openWallet(guid, "", function (err, result) {
+
+
+ console.log(result);
+
+ expect(err).to.equal(false);
+ expect(result).to.exist;
+
+ var twoFactorCode = speakeasy.totp({ key: FASecret, encoding: 'base32' });
+
+ console.log(twoFactorCode);
+
+ console.log("calling openWallet2fa");
+
+
+ engine.openWallet2fa(twoFactorCode, true, function (err, result) {
+
+ console.log(result);
+
+ expect(err).to.equal(false);
+ expect(result).to.exist;
+
+ done();
+
+ });
+
+
+ });
+
+ });
+
+ });
+
+ });
+
+
+ describe('User Functions', function () {
+
+ describe('add contact', function () {
+
+ this.timeout(5000);
+
+ it("Adds a contact", function (done) {
+
+ console.log(username2);
+
+
+ engine.createFriend(username2, "", function (err, result) {
+
+
+ console.log(result);
+
+ expect(err).to.equal(false);
+ expect(result).to.exist;
+
+ done();
+
+
+
+ });
+
+ });
+
+ });
+
+
+ });
+
+
+});
diff --git a/tests/test-change-password.js b/tests/test-change-password.js
new file mode 100644
index 0000000..10ea808
--- /dev/null
+++ b/tests/test-change-password.js
@@ -0,0 +1,127 @@
+var request = require('superagent');
+var expect = require('expect.js');
+var Engine = require('../src/ninki-engine');
+var API = require('../src/ninki-api');
+var speakeasy = require('speakeasy');
+var bs = require('browser-storage');
+
+var engine = new Engine();
+
+var guid = bs.getItem("testguid");
+var password = "12345678";
+var FASecret = bs.getItem("tfasec");
+
+console.log(guid);
+console.log(FASecret);
+
+
+describe('Account Utilities', function () {
+
+
+ describe('Login Functions', function () {
+
+
+ describe('openWallet', function () {
+
+
+ this.timeout(10000);
+
+ it("Verifies the users login details", function (done) {
+
+
+ engine.setPass(password, guid);
+
+
+ console.log(guid);
+
+ engine.openWallet(guid, "", function (err, result) {
+
+
+ console.log(result);
+
+ expect(err).to.equal(false);
+ expect(result).to.exist;
+
+ var twoFactorCode = speakeasy.totp({ key: FASecret, encoding: 'base32' });
+
+ console.log(twoFactorCode);
+
+ console.log("calling openWallet2fa");
+
+
+ engine.openWallet2fa(twoFactorCode, true, function (err, result) {
+
+ console.log(result);
+
+ bs.setItem('fp' + guid, engine.m_fingerprint);
+
+ expect(err).to.equal(false);
+ expect(result).to.exist;
+
+ done();
+
+ });
+
+
+ });
+
+ });
+
+ });
+
+ });
+
+ describe('User Functions', function () {
+
+ describe('Change Password', function () {
+
+ this.timeout(10000);
+
+ it("Changes the user's password", function (done) {
+
+ var twoFactorCode = speakeasy.totp({ key: FASecret, encoding: 'base32' });
+
+
+ engine.ChangePassword(twoFactorCode, password, "123456789", function (err, result) {
+
+
+ expect(err).to.equal(false);
+ expect(result).to.exist;
+ //console.log(result);
+
+ engine.ChangePassword(twoFactorCode, password, "12345678", function (err, result) {
+
+
+ expect(err).to.equal(false);
+ expect(result).to.exist;
+ //console.log(result);
+
+ done();
+
+
+ }, function (message, progress) {
+
+
+ console.log(message + '(' + progress + ')');
+
+
+ });
+
+
+ }, function (message, progress) {
+
+
+ console.log(message + '(' + progress + ')');
+
+
+ });
+
+ });
+
+ });
+
+
+ });
+
+
+});
diff --git a/tests/test-create-account-1.js b/tests/test-create-account-1.js
new file mode 100644
index 0000000..66a66fe
--- /dev/null
+++ b/tests/test-create-account-1.js
@@ -0,0 +1,254 @@
+var request = require('superagent');
+var expect = require('expect.js');
+var Engine = require('../src/ninki-engine');
+var API = require('../src/ninki-api');
+var speakeasy = require('speakeasy');
+var bs = require('browser-storage');
+var engine = new Engine();
+
+
+var guid = engine.getguid();
+var password = "12345678";
+var username = guid.substring(0,7);
+var emailAddress = guid + '@ninkip2p.com';
+var FASecret = '';
+
+bs.setItem('testguid', guid);
+
+describe('Account Utilities', function () {
+
+ describe('doesUsernameExist', function () {
+
+ it("username=testnet", function (done) {
+ engine.doesUsernameExist("testnet", function (err, res) {
+ expect(res).to.equal(true);
+ done();
+ });
+ });
+
+ it("username=xyxyxyxy", function (done) {
+ engine.doesUsernameExist("xyxyxyxy", function (err, res) {
+ expect(res).to.equal(false);
+ done();
+ });
+ });
+
+ });
+
+ describe('doesAccountExist', function () {
+ it("username=testnet,emailAddress=testnet@ninkip2p.com", function (done) {
+ API.doesAccountExist("testnet", "testnet@ninkip2p.com", function (err, accExists) {
+
+ expect(accExists.UserExists).to.equal(true);
+ expect(accExists.EmailExists).to.equal(true);
+ done();
+
+ });
+ });
+ it("username=gobxysgydu,emailAddress=ojihygjgrj@ninkip2p.com", function (done) {
+ API.doesAccountExist("gobxysgydu", "ojihygjgrj@ninkip2p.com", function (err, accExists) {
+
+ expect(accExists.UserExists).to.equal(false);
+ expect(accExists.EmailExists).to.equal(false);
+ done();
+
+ });
+ });
+
+ it("username=gobxysgydu,emailAddress=testnet@ninkip2p.com", function (done) {
+ API.doesAccountExist("gobxysgydu", "testnet@ninkip2p.com", function (err, accExists) {
+
+ expect(accExists.UserExists).to.equal(false);
+ expect(accExists.EmailExists).to.equal(true);
+ done();
+
+ });
+ });
+
+ it("username=testnet,emailAddress=ojihygjgrj@ninkip2p.com", function (done) {
+ API.doesAccountExist("testnet", "ojihygjgrj@ninkip2p.com", function (err, accExists) {
+
+ expect(accExists.UserExists).to.equal(true);
+ expect(accExists.EmailExists).to.equal(false);
+ done();
+
+ });
+ });
+
+ });
+
+
+ describe('Create Account Function', function () {
+
+
+ describe('createWallet', function () {
+
+ this.timeout(10000);
+
+ it("Creates a new account", function (done) {
+
+
+ engine.createWallet(guid, password, username, emailAddress, function (err, result) {
+
+
+ expect(err).to.equal(false);
+ expect(result.wallet).to.exist;
+
+
+ engine.getTwoFactorImg(function (err, twoFASecret) {
+
+
+ FASecret = twoFASecret;
+
+ bs.setItem('tfasec', twoFASecret);
+
+ console.log(twoFASecret);
+
+ expect(err).to.equal(false);
+ expect(twoFASecret).to.exist;
+
+ //generate an opt code from the secret
+ var twoFactorCode = speakeasy.totp({ key: twoFASecret, encoding: 'base32' });
+
+
+ bs["tfasec"] = twoFASecret;
+
+ console.log(twoFactorCode);
+
+ engine.SetupTwoFactor(twoFactorCode, function (err, result) {
+
+ console.log(result);
+
+ expect(err).to.equal(false);
+ expect(result).to.exist;
+
+ var token = "test";
+
+ engine.getEmailValidation(token, function (err, response) {
+
+ console.log(response);
+
+ expect(err).to.equal(true);
+ expect(response).to.exist;
+
+ done();
+
+ });
+
+
+
+ });
+
+
+ });
+
+
+ });
+
+ });
+
+ });
+
+ });
+
+});
+
+
+guid = bs.getItem("testguid");
+var password = "12345678";
+FASecret = bs.getItem("tfasec");
+
+console.log(guid);
+console.log(FASecret);
+
+
+describe('Account Utilities', function () {
+
+
+ describe('Login Functions', function () {
+
+
+ describe('openWallet', function () {
+
+
+ this.timeout(10000);
+
+ it("Verifies the users login details", function (done) {
+
+
+ engine.setPass(password, guid);
+
+
+ console.log(guid);
+
+ engine.openWallet(guid, "", function (err, result) {
+
+
+ console.log(result);
+
+ expect(err).to.equal(false);
+ expect(result).to.exist;
+
+ var twoFactorCode = speakeasy.totp({ key: FASecret, encoding: 'base32' });
+
+ console.log(twoFactorCode);
+
+ console.log("calling openWallet2fa");
+
+
+ engine.openWallet2fa(twoFactorCode, true, function (err, result) {
+
+ console.log(result);
+
+ bs.setItem('fp' + guid, engine.m_fingerprint);
+
+ expect(err).to.equal(false);
+ expect(result).to.exist;
+
+ done();
+
+ });
+
+
+ });
+
+ });
+
+ });
+
+ });
+
+
+
+ describe('User Functions', function () {
+
+ describe('createAddress', function () {
+
+ this.timeout(5000);
+
+ it("Creates a receive address", function (done) {
+
+ engine.createAddress('m/0/0', 1, function (err, newAddress, path) {
+
+
+ console.log("Send 2* 0.01 Testnet coins to :" + newAddress);
+
+ expect(err).to.equal(false);
+ expect(newAddress).to.exist;
+ expect(path).to.exist;
+
+ done();
+
+
+
+ });
+
+ });
+
+ });
+
+
+ });
+
+
+});
diff --git a/tests/test-create-account-2.js b/tests/test-create-account-2.js
new file mode 100644
index 0000000..6398c59
--- /dev/null
+++ b/tests/test-create-account-2.js
@@ -0,0 +1,189 @@
+var request = require('superagent');
+var expect = require('expect.js');
+var Engine = require('../src/ninki-engine');
+var API = require('../src/ninki-api');
+var speakeasy = require('speakeasy');
+var bs = require('browser-storage');
+var engine = new Engine();
+
+
+var guid = engine.getguid();
+var password = "12345678";
+var username = guid.substring(0,7);
+var emailAddress = guid + '@ninkip2p.com';
+var FASecret = '';
+
+bs.setItem('testguid2', guid);
+
+
+describe('Create Account Function', function () {
+
+
+ describe('createWallet', function () {
+
+ this.timeout(10000);
+
+ it("Creates a new account", function (done) {
+
+ engine.createWallet(guid, password, username, emailAddress, function (err, result) {
+
+
+ expect(err).to.equal(false);
+ expect(result.wallet).to.exist;
+
+
+ engine.getTwoFactorImg(function (err, twoFASecret) {
+
+
+ FASecret = twoFASecret;
+
+ bs.setItem('tfasec2', twoFASecret);
+
+ console.log(twoFASecret);
+
+ expect(err).to.equal(false);
+ expect(twoFASecret).to.exist;
+
+ //generate an opt code from the secret
+ var twoFactorCode = speakeasy.totp({ key: twoFASecret, encoding: 'base32' });
+
+
+ bs["tfasec2"] = twoFASecret;
+
+ console.log(twoFactorCode);
+
+ engine.SetupTwoFactor(twoFactorCode, function (err, result) {
+
+ console.log(result);
+
+ expect(err).to.equal(false);
+ expect(result).to.exist;
+
+ var token = "test";
+
+ engine.getEmailValidation(token, function (err, response) {
+
+ console.log(response);
+
+ expect(err).to.equal(true);
+ expect(response).to.exist;
+
+ done();
+
+ });
+
+
+
+ });
+
+
+ });
+
+
+ });
+
+ });
+
+ });
+
+});
+
+
+guid = bs.getItem("testguid2");
+password = "12345678";
+FASecret = bs.getItem("tfasec2");
+
+console.log(guid);
+console.log(FASecret);
+
+
+describe('Account Utilities', function () {
+
+
+ describe('Login Functions', function () {
+
+
+ describe('openWallet', function () {
+
+
+ this.timeout(10000);
+
+ it("Verifies the users login details", function (done) {
+
+
+ engine.setPass(password, guid);
+
+
+ console.log(guid);
+
+ engine.openWallet(guid, "", function (err, result) {
+
+
+ console.log(result);
+
+ expect(err).to.equal(false);
+ expect(result).to.exist;
+
+ var twoFactorCode = speakeasy.totp({ key: FASecret, encoding: 'base32' });
+
+ console.log(twoFactorCode);
+
+ console.log("calling openWallet2fa");
+
+
+ engine.openWallet2fa(twoFactorCode, true, function (err, result) {
+
+ console.log(result);
+
+ bs.setItem('fp' + guid, engine.m_fingerprint);
+
+ expect(err).to.equal(false);
+ expect(result).to.exist;
+
+ done();
+
+ });
+
+
+ });
+
+ });
+
+ });
+
+ });
+
+
+
+ describe('User Functions', function () {
+
+ describe('createAddress', function () {
+
+ this.timeout(5000);
+
+ it("Creates a receive address", function (done) {
+
+ engine.createAddress('m/0/0', 1, function (err, newAddress, path) {
+
+
+ console.log("Send 2* 0.01 Testnet coins to :" + newAddress);
+
+ expect(err).to.equal(false);
+ expect(newAddress).to.exist;
+ expect(path).to.exist;
+
+ done();
+
+
+
+ });
+
+ });
+
+ });
+
+
+ });
+
+
+});
diff --git a/tests/test-create-address-for-contact.js b/tests/test-create-address-for-contact.js
new file mode 100644
index 0000000..fe03ce1
--- /dev/null
+++ b/tests/test-create-address-for-contact.js
@@ -0,0 +1,105 @@
+var request = require('superagent');
+var expect = require('expect.js');
+var Engine = require('../src/ninki-engine');
+var API = require('../src/ninki-api');
+var speakeasy = require('speakeasy');
+var bs = require('browser-storage');
+
+var engine = new Engine();
+
+var guid = bs.getItem("testguid");
+var guid2 = bs.getItem("testguid2");
+var password = "12345678";
+var FASecret = bs.getItem("tfasec");
+
+var username2 = guid2.substring(0, 7);
+
+console.log(guid);
+console.log(FASecret);
+
+
+describe('Account Utilities', function () {
+
+
+ describe('Login Functions', function () {
+
+
+ describe('openWallet', function () {
+
+
+ this.timeout(10000);
+
+ it("Verifies the users login details", function (done) {
+
+
+ engine.setPass(password, guid);
+
+
+ console.log(guid);
+
+ engine.openWallet(guid, "", function (err, result) {
+
+
+ console.log(result);
+
+ expect(err).to.equal(false);
+ expect(result).to.exist;
+
+ var twoFactorCode = speakeasy.totp({ key: FASecret, encoding: 'base32' });
+
+ console.log(twoFactorCode);
+
+ console.log("calling openWallet2fa");
+
+
+ engine.openWallet2fa(twoFactorCode, true, function (err, result) {
+
+ console.log(result);
+
+ expect(err).to.equal(false);
+ expect(result).to.exist;
+
+ done();
+
+ });
+
+
+ });
+
+ });
+
+ });
+
+ });
+
+
+ describe('User Functions', function () {
+
+ describe('createAddressForContact', function () {
+
+ this.timeout(5000);
+
+ it("Creates a receive address for contact", function (done) {
+
+ engine.createAddressForFriend(username2, function (err, newAddress) {
+
+
+ console.log("Send 2* 0.01 Testnet coins to :" + newAddress);
+
+ expect(err).to.equal(false);
+ expect(newAddress).to.exist;
+ done();
+
+
+
+ });
+
+ });
+
+ });
+
+
+ });
+
+
+});
diff --git a/tests/test-open-wallet.js b/tests/test-open-wallet.js
new file mode 100644
index 0000000..9ae3fee
--- /dev/null
+++ b/tests/test-open-wallet.js
@@ -0,0 +1,107 @@
+var request = require('superagent');
+var expect = require('expect.js');
+var Engine = require('../src/ninki-engine');
+var API = require('../src/ninki-api');
+var speakeasy = require('speakeasy');
+var bs = require('browser-storage');
+
+var engine = new Engine();
+
+var guid = bs.getItem("testguid");
+var password = "12345678";
+var FASecret = bs.getItem("tfasec");
+
+console.log(guid);
+console.log(FASecret);
+
+
+describe('Account Utilities', function () {
+
+
+ describe('Login Functions', function () {
+
+
+ describe('openWallet', function () {
+
+
+ this.timeout(10000);
+
+ it("Verifies the users login details", function (done) {
+
+
+ engine.setPass(password, guid);
+
+
+ console.log(guid);
+
+ engine.openWallet(guid, "", function (err, result) {
+
+
+ console.log(result);
+
+ expect(err).to.equal(false);
+ expect(result).to.exist;
+
+ var twoFactorCode = speakeasy.totp({ key: FASecret, encoding: 'base32' });
+
+ console.log(twoFactorCode);
+
+ console.log("calling openWallet2fa");
+
+
+ engine.openWallet2fa(twoFactorCode, true, function (err, result) {
+
+ console.log(result);
+
+ bs.setItem('fp' + guid, engine.m_fingerprint);
+
+ expect(err).to.equal(false);
+ expect(result).to.exist;
+
+ done();
+
+ });
+
+
+ });
+
+ });
+
+ });
+
+ });
+
+
+
+ describe('User Functions', function () {
+
+ describe('createAddress', function () {
+
+ this.timeout(5000);
+
+ it("Creates a receive address", function (done) {
+
+ engine.createAddress('m/0/0', 1, function (err, newAddress, path) {
+
+
+ console.log("Send 2* 0.01 Testnet coins to :" + newAddress);
+
+ expect(err).to.equal(false);
+ expect(newAddress).to.exist;
+ expect(path).to.exist;
+
+ done();
+
+
+
+ });
+
+ });
+
+ });
+
+
+ });
+
+
+});
diff --git a/tests/test-send-transaction-contact.js b/tests/test-send-transaction-contact.js
new file mode 100644
index 0000000..7ba59b5
--- /dev/null
+++ b/tests/test-send-transaction-contact.js
@@ -0,0 +1,106 @@
+var request = require('superagent');
+var expect = require('expect.js');
+var Engine = require('../src/ninki-engine');
+var API = require('../src/ninki-api');
+var speakeasy = require('speakeasy');
+var bs = require('browser-storage');
+
+var engine = new Engine();
+
+var guid = bs.getItem("testguid");
+var guid2 = bs.getItem("testguid2");
+
+var password = "12345678";
+var FASecret = bs.getItem("tfasec");
+
+var username2 = guid2.substring(0,7);
+
+console.log(guid);
+console.log(FASecret);
+
+
+describe('Account Utilities', function () {
+
+
+ describe('Login Functions', function () {
+
+
+ describe('openWallet', function () {
+
+
+ this.timeout(10000);
+
+ it("Verifies the users login details", function (done) {
+
+
+ engine.setPass(password, guid);
+
+
+ console.log(guid);
+
+ engine.openWallet(guid, "", function (err, result) {
+
+
+ console.log(result);
+
+ expect(err).to.equal(false);
+ expect(result).to.exist;
+
+ var twoFactorCode = speakeasy.totp({ key: FASecret, encoding: 'base32' });
+
+ console.log(twoFactorCode);
+
+ console.log("calling openWallet2fa");
+
+
+ engine.openWallet2fa(twoFactorCode, true, function (err, result) {
+
+ console.log(result);
+
+ expect(err).to.equal(false);
+ expect(result).to.exist;
+
+ done();
+
+ });
+
+
+ });
+
+ });
+
+ });
+
+ });
+
+
+ describe('User Functions', function () {
+
+ describe('sendTransaction to contact', function () {
+
+ this.timeout(20000);
+
+ it("Sends transaction to contact amount <= sum(outputs)-miners fee", function (done) {
+
+ var twoFactorCode = speakeasy.totp({ key: FASecret, encoding: 'base32' });
+
+ engine.sendTransaction("friend", username2, "", 90000, twoFactorCode, function (err, transactionid) {
+
+ console.log(transactionid);
+
+ expect(err).to.equal(false);
+ expect(transactionid).to.exist;
+
+ done();
+
+ });
+
+ });
+
+ });
+
+
+ });
+
+
+});
diff --git a/tests/test-send-transaction.js b/tests/test-send-transaction.js
new file mode 100644
index 0000000..80072c0
--- /dev/null
+++ b/tests/test-send-transaction.js
@@ -0,0 +1,137 @@
+var request = require('superagent');
+var expect = require('expect.js');
+var Engine = require('../src/ninki-engine');
+var API = require('../src/ninki-api');
+var speakeasy = require('speakeasy');
+var bs = require('browser-storage');
+
+var engine = new Engine();
+
+var guid = bs.getItem("testguid");
+var password = "12345678";
+var FASecret = bs.getItem("tfasec");
+
+console.log(guid);
+console.log(FASecret);
+
+
+describe('Account Utilities', function () {
+
+
+ describe('Login Functions', function () {
+
+
+ describe('openWallet', function () {
+
+
+ this.timeout(10000);
+
+ it("Verifies the users login details", function (done) {
+
+
+ engine.setPass(password, guid);
+
+
+ console.log(guid);
+
+ engine.openWallet(guid, "", function (err, result) {
+
+
+ console.log(result);
+
+ expect(err).to.equal(false);
+ expect(result).to.exist;
+
+ var twoFactorCode = speakeasy.totp({ key: FASecret, encoding: 'base32' });
+
+ console.log(twoFactorCode);
+
+ console.log("calling openWallet2fa");
+
+
+ engine.openWallet2fa(twoFactorCode, true, function (err, result) {
+
+ console.log(result);
+
+ expect(err).to.equal(false);
+ expect(result).to.exist;
+
+ done();
+
+ });
+
+
+ });
+
+ });
+
+ });
+
+ });
+
+
+ describe('User Functions', function () {
+
+ describe('sendTransaction', function () {
+
+ this.timeout(5000);
+
+ it("Sends transaction to address amount > sum(outputs)-miners fee", function (done) {
+
+ var twoFactorCode = speakeasy.totp({ key: FASecret, encoding: 'base32' });
+
+ engine.sendTransaction("standard", "", "mkLqdjeJy5iQDyzFHESNYdb25c5ePLJqgM", 200000, twoFactorCode, function (err, transactionid) {
+
+ console.log(transactionid);
+
+ expect(err).to.equal(true);
+ expect(transactionid).to.equal("ErrInsufficientFunds");
+
+ done();
+
+ },
+
+ function (status, progress) {
+
+ console.log(progress);
+
+ });
+
+ });
+
+ });
+
+ describe('sendTransaction', function () {
+
+ this.timeout(20000);
+
+ it("Sends transaction to address amount <= sum(outputs)-miners fee", function (done) {
+
+ var twoFactorCode = speakeasy.totp({ key: FASecret, encoding: 'base32' });
+
+ engine.sendTransaction("standard", "", "mkLqdjeJy5iQDyzFHESNYdb25c5ePLJqgM", 70000, twoFactorCode, function (err, transactionid) {
+
+ console.log(transactionid);
+
+ expect(err).to.equal(false);
+ expect(transactionid).to.exist;
+
+ done();
+
+ },
+
+ function (status, progress) {
+
+ console.log(progress);
+
+ });
+
+ });
+
+ });
+
+
+ });
+
+
+});
diff --git a/tests/test-update-settings.js b/tests/test-update-settings.js
new file mode 100644
index 0000000..1e70c63
--- /dev/null
+++ b/tests/test-update-settings.js
@@ -0,0 +1,116 @@
+var request = require('superagent');
+var expect = require('expect.js');
+var Engine = require('../src/ninki-engine');
+var API = require('../src/ninki-api');
+var speakeasy = require('speakeasy');
+var bs = require('browser-storage');
+
+var engine = new Engine();
+
+var guid = bs.getItem("testguid");
+var password = "12345678";
+var FASecret = bs.getItem("tfasec");
+
+console.log(guid);
+console.log(FASecret);
+
+
+describe('Account Utilities', function () {
+
+
+ describe('Login Functions', function () {
+
+
+ describe('openWallet', function () {
+
+
+ this.timeout(10000);
+
+ it("Verifies the users login details", function (done) {
+
+ engine.setPass(password, guid);
+
+ console.log(guid);
+
+ engine.openWallet(guid, "", function (err, result) {
+
+
+ console.log(result);
+
+ expect(err).to.equal(false);
+ expect(result).to.exist;
+
+ var twoFactorCode = speakeasy.totp({ key: FASecret, encoding: 'base32' });
+
+ console.log(twoFactorCode);
+
+ console.log("calling openWallet2fa");
+
+
+ engine.openWallet2fa(twoFactorCode, true, function (err, result) {
+
+ console.log(result);
+
+ expect(err).to.equal(false);
+ expect(result).to.exist;
+
+ done();
+
+ });
+
+
+ });
+
+ });
+
+ });
+
+ });
+
+
+ describe('User Functions', function () {
+
+ describe('updateAccountSettings', function () {
+
+ this.timeout(5000);
+
+ it("updates account settings", function (done) {
+
+ var jsonPacket = {
+ guid: Engine.m_guid
+ };
+
+ jsonPacket['DailyTransactionLimit'] = 10000000;
+ jsonPacket['SingleTransactionLimit'] = 1000000;
+ jsonPacket['NoOfTransactionsPerDay'] = 4;
+ jsonPacket['NoOfTransactionsPerHour'] = 2;
+ jsonPacket['Inactivity'] = 10;
+ jsonPacket['MinersFee'] = 10000;
+ jsonPacket['CoinUnit'] = "BTC";
+ jsonPacket['Email'] = "isthislive@ninkip2p.com";
+ jsonPacket['EmailNotification'] = true;
+ jsonPacket['LocalCurrency'] = "USD"
+
+ var twoFactorCode = speakeasy.totp({ key: FASecret, encoding: 'base32' });
+
+ engine.updateAccountSettings(jsonPacket, twoFactorCode, function (err, res) {
+
+ console.log(res);
+
+ expect(err).to.equal(false);
+ expect(res).to.equal('ok');
+
+ done();
+
+
+ });
+
+ });
+
+ });
+
+
+ });
+
+
+});
diff --git a/tests/test-user-details.js b/tests/test-user-details.js
new file mode 100644
index 0000000..2e451c0
--- /dev/null
+++ b/tests/test-user-details.js
@@ -0,0 +1,124 @@
+var request = require('superagent');
+var expect = require('expect.js');
+var Engine = require('../src/ninki-engine');
+var API = require('../src/ninki-api');
+var speakeasy = require('speakeasy');
+var bs = require('browser-storage');
+
+var engine = new Engine();
+
+var guid = bs.getItem("testguid");
+var password = "12345678";
+var FASecret = bs.getItem("tfasec");
+
+console.log(guid);
+console.log(FASecret);
+
+
+describe('Account Utilities', function () {
+
+
+ describe('Login Functions', function () {
+
+
+ describe('openWallet', function () {
+
+
+ this.timeout(10000);
+
+ it("Verifies the users login details", function (done) {
+
+
+ engine.setPass(password, guid);
+
+
+ console.log(guid);
+
+ engine.openWallet(guid, "", function (err, result) {
+
+
+ console.log(result);
+
+ expect(err).to.equal(false);
+ expect(result).to.exist;
+
+ var twoFactorCode = speakeasy.totp({ key: FASecret, encoding: 'base32' });
+
+ console.log(twoFactorCode);
+
+ console.log("calling openWallet2fa");
+
+
+ engine.openWallet2fa(twoFactorCode, true, function (err, result) {
+
+ console.log(result);
+
+ expect(err).to.equal(false);
+ expect(result).to.exist;
+
+ done();
+
+ });
+
+
+ });
+
+ });
+
+ });
+
+ });
+
+
+ describe('User Functions', function () {
+
+ describe('getBalance', function () {
+
+ this.timeout(5000);
+
+ it("Get's users balance", function (done) {
+
+ engine.getBalance(function (err, result) {
+
+ console.log(result.ConfirmedBalance);
+ console.log(result.UnconfirmedBalance);
+ console.log(result.TotalBalance);
+
+ expect(err).to.equal(false);
+
+ expect(result).to.exist;
+ expect(result.ConfirmedBalance).to.exist;
+ expect(result.UnconfirmedBalance).to.exist;
+ expect(result.TotalBalance).to.exist;
+
+ done();
+
+ });
+
+ });
+
+
+ it("Get's users transactions", function (done) {
+
+ engine.getTransactionRecords(function (err, transactions) {
+
+ console.log(transactions);
+
+ expect(err).to.equal(false);
+
+ expect(transactions).to.exist;
+
+
+ done();
+
+ });
+
+ });
+
+ });
+
+
+ });
+
+
+});