added code to handle connections between supernode and cashier
This commit is contained in:
parent
34d8c8d296
commit
a66b57c3cf
@ -2,7 +2,7 @@
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||||
<title>Handling Cash Payments For Localbitcoinplusplus</title>
|
<title>Handling Cash Payments For Localbitcoinplusplus</title>
|
||||||
<!-- Latest compiled and minified CSS -->
|
<!-- Latest compiled and minified CSS -->
|
||||||
@ -10,8 +10,50 @@
|
|||||||
|
|
||||||
<!-- Optional theme -->
|
<!-- Optional theme -->
|
||||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
|
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
|
||||||
|
<style>
|
||||||
|
.sidenav {
|
||||||
|
position: fixed;
|
||||||
|
z-index: 1;
|
||||||
|
top: 20px;
|
||||||
|
left: 10px;
|
||||||
|
background: #eee;
|
||||||
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar_div {
|
||||||
|
z-index: 1;
|
||||||
|
top: 20px;
|
||||||
|
left: 10px;
|
||||||
|
background: #eee;
|
||||||
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
|
<div class="sidenav">
|
||||||
|
<div class="w3-sidebar w3-bar-block" style="display:none" id="mySidebar">
|
||||||
|
<div onclick="closeMessage()" class="w3-bar-item w3-button w3-large bg-black">Close</div>
|
||||||
|
<pre id="log">Event information log
|
||||||
|
=====================
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
<div class="w3-button w3-teal w3-xlarge" onclick="displayMessages()">☰</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="supernode_seeds_div"></div>
|
||||||
|
<div id="flo_keys_div"></div>
|
||||||
|
|
||||||
|
<div id="action_buttons">
|
||||||
|
<button type="button" class="btn btn-outline-primary" id="fetch_deposits">Load Pending Deposits</button>
|
||||||
|
<button type="button" class="btn btn-outline-secondary">Secondary</button>
|
||||||
|
<button type="button" class="btn btn-outline-success">Success</button>
|
||||||
|
<button type="button" class="btn btn-outline-danger">Danger</button>
|
||||||
|
<button type="button" class="btn btn-outline-warning">Warning</button>
|
||||||
|
<button type="button" class="btn btn-outline-info">Info</button>
|
||||||
|
<button type="button" class="btn btn-outline-light">Light</button>
|
||||||
|
<button type="button" class="btn btn-outline-dark">Dark</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
//crypto-sha256-hmac.js
|
//crypto-sha256-hmac.js
|
||||||
@ -9092,6 +9134,183 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<!-- JSON RPC -->
|
||||||
|
<script>
|
||||||
|
var JSON_RPC = {};
|
||||||
|
|
||||||
|
var id = 0,
|
||||||
|
callbacks = {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new JSON-RPC Request
|
||||||
|
* @param method A String containing the name of the method to be invoked.
|
||||||
|
* @param params (optional) A Structured value that holds the parameter values to be used during the invocation of the method.
|
||||||
|
*/
|
||||||
|
JSON_RPC.Request = function (method, params, globalParams={}) {
|
||||||
|
this.jsonrpc = "2.0";
|
||||||
|
this.method = method;
|
||||||
|
if (typeof params !== "undefined") {
|
||||||
|
this.params = params;
|
||||||
|
}
|
||||||
|
this.globalParams = globalParams;
|
||||||
|
this.id = id++;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Implements getters and setters for the result of a JSON-RPC Request.
|
||||||
|
// The result may be an any Object or primitive
|
||||||
|
Object.defineProperty(JSON_RPC.Request.prototype, "result", {
|
||||||
|
get: function () {
|
||||||
|
return this._result;
|
||||||
|
},
|
||||||
|
set: function (result) {
|
||||||
|
delete this.method; // remove the method name
|
||||||
|
delete this.params; // remove the params
|
||||||
|
delete this.error; // remove error state if it exists
|
||||||
|
delete this.globalParams; // remove globalParams
|
||||||
|
this._result = result;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Implements getters and setters for the error state of a JSON-RPC Request.
|
||||||
|
// Error should be a JSON_RPC.Error object
|
||||||
|
Object.defineProperty(JSON_RPC.Request.prototype, "error", {
|
||||||
|
get: function () {
|
||||||
|
return this._error;
|
||||||
|
},
|
||||||
|
set: function (error) {
|
||||||
|
delete this.method; // remove the method name
|
||||||
|
delete this.params; // remove the params
|
||||||
|
delete this.result; // remove result state if it exists
|
||||||
|
delete this.globalParams; // remove globalParams if it exists
|
||||||
|
this._error = error;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a String representation of a JSON-RPC Request
|
||||||
|
* @returns A JSON String
|
||||||
|
*/
|
||||||
|
JSON_RPC.Request.prototype.toString = function () {
|
||||||
|
var rpc = {
|
||||||
|
jsonrpc: this.jsonrpc,
|
||||||
|
id: this.id
|
||||||
|
};
|
||||||
|
|
||||||
|
if (this.method !== undefined) rpc.method = this.method;
|
||||||
|
if (this.params !== undefined) rpc.params = this.params;
|
||||||
|
if (this.result !== undefined) rpc.result = this.result;
|
||||||
|
if (this.error !== undefined) rpc.error = this.error;
|
||||||
|
if (this.globalParams !== undefined) rpc.globalParams = this.globalParams;
|
||||||
|
|
||||||
|
return JSON.stringify(rpc);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new JSON-RPC Notification
|
||||||
|
* @param method A String containing the name of the method to be invoked.
|
||||||
|
* @param params (optional) A Structured value that holds the parameter values to be used during the invocation of the method.
|
||||||
|
*/
|
||||||
|
JSON_RPC.Notification = function (method, params, globalParams) {
|
||||||
|
this.jsonrpc = "2.0";
|
||||||
|
this.method = method;
|
||||||
|
if (typeof params !== "undefined") {
|
||||||
|
this.params = params;
|
||||||
|
}
|
||||||
|
if (typeof globalParams !== "undefined") {
|
||||||
|
this.globalParams = globalParams;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a String representation of a JSON-RPC Notification
|
||||||
|
* @returns A JSON String
|
||||||
|
*/
|
||||||
|
JSON_RPC.Notification.prototype.toString = function () {
|
||||||
|
var rpc = {
|
||||||
|
jsonrpc: this.jsonrpc,
|
||||||
|
method: this.method,
|
||||||
|
params: this.params,
|
||||||
|
globalParams: this.globalParams,
|
||||||
|
};
|
||||||
|
|
||||||
|
return JSON.stringify(rpc);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new JSON-RPC Errror object
|
||||||
|
* @params code A Number that indicates the error type that occurred. -32768 to -32000 are reserved.
|
||||||
|
* @param message (optional) A String providing a short description of the error.
|
||||||
|
* @param data (optional) A Primitive or Structured value that contains additional information about the error.
|
||||||
|
*/
|
||||||
|
JSON_RPC.Error = function (code, message, data) {
|
||||||
|
this.code = code;
|
||||||
|
if (typeof message == "string") this.message = message;
|
||||||
|
if (data !== undefined) this.data = data;
|
||||||
|
};
|
||||||
|
|
||||||
|
// stock errors
|
||||||
|
JSON_RPC.PARSE_ERROR = new JSON_RPC.Error(-32700,
|
||||||
|
"An error occurred on the server while parsing the JSON text.");
|
||||||
|
JSON_RPC.INVALID_REQUEST = new JSON_RPC.Error(-32600, "The JSON sent is not a valid Request object.");
|
||||||
|
JSON_RPC.METHOD_NOT_FOUND = new JSON_RPC.Error(-32601, "The method does not exist / is not available.");
|
||||||
|
JSON_RPC.INVALID_PARAMS = new JSON_RPC.Error(-32602, "Invalid method parameter(s).");
|
||||||
|
JSON_RPC.INTERNAL_ERROR = new JSON_RPC.Error(-32603, "Internal JSON-RPC error.");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses a JSON-RPC string and converts to a JSON-RPC object or an Array of such strings.
|
||||||
|
* @params rpc A String or Array to parse to a JSON-RPC object.
|
||||||
|
*/
|
||||||
|
JSON_RPC.parse = function (rpc) {
|
||||||
|
// batch?
|
||||||
|
if (rpc.constructor === Array) {
|
||||||
|
var arr = [];
|
||||||
|
rpc.forEach(function (el) {
|
||||||
|
arr.push(JSON_RPC.parse(el));
|
||||||
|
});
|
||||||
|
return arr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// parsable?
|
||||||
|
var rpc;
|
||||||
|
try {
|
||||||
|
rpc = JSON.parse(rpc);
|
||||||
|
} catch (err) {
|
||||||
|
var obj = new JSON_RPC.Request();
|
||||||
|
obj.result = JSON_RPC.PARSE_ERROR;
|
||||||
|
obj.id = null;
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2.0?
|
||||||
|
if (rpc.jsonrpc !== "2.0") {
|
||||||
|
var obj = new JSON_RPC.Request();
|
||||||
|
obj.result = JSON_RPC.INVALID_REQUEST;
|
||||||
|
obj.id = null;
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
// request or notification?
|
||||||
|
var obj = (rpc.id === undefined) ?
|
||||||
|
new JSON_RPC.Notification(rpc.method, rpc.params) :
|
||||||
|
new JSON_RPC.Request(rpc.method, rpc.params);
|
||||||
|
// have an ID?
|
||||||
|
if (rpc.id !== undefined) obj.id = rpc.id;
|
||||||
|
// is it a result?
|
||||||
|
if (rpc.result !== undefined) obj.result = rpc.result;
|
||||||
|
// is it a error?
|
||||||
|
if (rpc.error !== undefined) {
|
||||||
|
obj.error = new JSON_RPC.Error(
|
||||||
|
rpc.error.code,
|
||||||
|
rpc.error.message,
|
||||||
|
rpc.error.data
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// parsed :-)
|
||||||
|
return obj;
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
<!-- CASH PAYMENTS HANDLER SCRIPT START -->
|
<!-- CASH PAYMENTS HANDLER SCRIPT START -->
|
||||||
|
|
||||||
@ -9722,7 +9941,7 @@
|
|||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
manually_assign_my_private_key: function() {
|
manually_assign_my_private_key: function() {
|
||||||
readDB('localbitcoinUser', '00-01').then(usr=>{
|
readDB('paymentsHandlerDetails', '00-01').then(usr=>{
|
||||||
if (typeof usr=="object" && usr.myLocalFLOAddress.length>0) {
|
if (typeof usr=="object" && usr.myLocalFLOAddress.length>0) {
|
||||||
const RM_WALLET = new localbitcoinplusplus.wallets;
|
const RM_WALLET = new localbitcoinplusplus.wallets;
|
||||||
const pk_manual = prompt("Please enter your private key: ");
|
const pk_manual = prompt("Please enter your private key: ");
|
||||||
@ -9751,6 +9970,112 @@
|
|||||||
Promise.reject(mes);
|
Promise.reject(mes);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
reset_flo_keys: () => {
|
||||||
|
updateinDB('paymentsHandlerDetails', {
|
||||||
|
id: "00-01",
|
||||||
|
myLocalFLOAddress: "",
|
||||||
|
myLocalFLOPublicKey: "",
|
||||||
|
}, "00-01").then(() => true).catch(e => false);
|
||||||
|
return Promise.resolve(true);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/* CODE_JUNCTION: RPC */
|
||||||
|
|
||||||
|
var Rpc = localbitcoinplusplus.rpc = function () {
|
||||||
|
this.rpc_req_id;
|
||||||
|
this.valid_job = ["trade_buy", "trade_sell", "sync"];
|
||||||
|
}
|
||||||
|
Rpc.prototype = {
|
||||||
|
|
||||||
|
send_rpc(method, ...params) {
|
||||||
|
|
||||||
|
return new Promise((resolve, reject)=>{
|
||||||
|
var request = new JSON_RPC.Request(method, params);
|
||||||
|
var id = request.id;
|
||||||
|
this.rpc_req_id = id;
|
||||||
|
request.globalParams.rpc_protocol = '__FOR__CASHIER__';
|
||||||
|
|
||||||
|
(async function(request) {
|
||||||
|
|
||||||
|
if (typeof localbitcoinplusplus.wallets.my_local_flo_address == "string") {
|
||||||
|
request.globalParams.senderFloId = localbitcoinplusplus.wallets.my_local_flo_address;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof params[0].receiver_flo_address == "string") {
|
||||||
|
request.globalParams.receiverFloId = params[0].receiver_flo_address;
|
||||||
|
if (typeof request.globalParams.receiversList == "object") {
|
||||||
|
if(typeof request.globalParams["receiversList"] !== "object") request.globalParams["receiversList"] = [];
|
||||||
|
if (!request.globalParams.receiversList.includes(params[0].receiver_flo_address)) {
|
||||||
|
request.globalParams.receiversList.push(params[0].receiver_flo_address);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return resolve(request.toString());
|
||||||
|
|
||||||
|
})(request);
|
||||||
|
})
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
filter_legit_requests: function (flo_id=null, callback) {
|
||||||
|
if (typeof localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY === "string" &&
|
||||||
|
localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY.length > 0
|
||||||
|
) {
|
||||||
|
const RM_WALLET = new localbitcoinplusplus.wallets;
|
||||||
|
let user_keys = RM_WALLET.generateFloKeys(localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY);
|
||||||
|
if (typeof user_keys == "object" && typeof user_keys.pubKeyHex == "string") {
|
||||||
|
if (localbitcoinplusplus.master_configurations.supernodesPubKeys.includes(user_keys.pubKeyHex)) {
|
||||||
|
if (typeof flo_id !== null || typeof flo_id !== 'undefined') {
|
||||||
|
localbitcoinplusplus.kademlia.determineClosestSupernode(flo_id, 4)
|
||||||
|
.then(my_closest_su=>{
|
||||||
|
if (user_keys.address === my_closest_su[0].data.id) {
|
||||||
|
return callback(true);
|
||||||
|
} else {
|
||||||
|
let su_arr = my_closest_su.map(m=>m.data.id);
|
||||||
|
if(su_arr.includes(flo_id)) {
|
||||||
|
return callback(true);
|
||||||
|
} else {
|
||||||
|
return callback(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return callback(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return callback(false);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async receive_rpc_response(request) {
|
||||||
|
var request = JSON.parse(request);
|
||||||
|
var params = request.params[0];
|
||||||
|
var method = request.method;
|
||||||
|
|
||||||
|
if (typeof params == "object" && typeof method == "string") {
|
||||||
|
|
||||||
|
const RM_WALLET = new localbitcoinplusplus.wallets;
|
||||||
|
const RM_RPC = new localbitcoinplusplus.rpc;
|
||||||
|
|
||||||
|
let respective_trader_id = '';
|
||||||
|
if (typeof params.trader_flo_address == "string") respective_trader_id = params.trader_flo_address;
|
||||||
|
request.response = {};
|
||||||
|
let err_msg;
|
||||||
|
|
||||||
|
let recvr_flo_id = params.receiver_flo_address || request.globalParams.receiverFloId;
|
||||||
|
if (typeof recvr_flo_id == "string"
|
||||||
|
&& recvr_flo_id.length > 0
|
||||||
|
&& recvr_flo_id !== localbitcoinplusplus.wallets.my_local_flo_address) return;
|
||||||
|
|
||||||
|
console.log(request);
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// kbucket functions
|
// kbucket functions
|
||||||
@ -9762,22 +10087,21 @@
|
|||||||
k.splice(-4, 4)
|
k.splice(-4, 4)
|
||||||
return Crypto.util.bytesToHex(k)
|
return Crypto.util.bytesToHex(k)
|
||||||
},
|
},
|
||||||
launchSupernodesKBucket: function() {
|
launchKBucket: function() {
|
||||||
|
return new Promise((resolve, reject)=>{
|
||||||
localbitcoinplusplus.master_configurations.supernodesPubKeys.map(pubKey=>{
|
try {
|
||||||
return new Promise((resolve, reject)=>{
|
const master_flo_pubKey = localbitcoinplusplus.master_configurations.masterFLOPubKey;
|
||||||
try {
|
const master_flo_addr = bitjs.FLO_TEST.pubkey2address(master_flo_pubKey);
|
||||||
let flo_id = bitjs.FLO_TEST.pubkey2address(pubKey);
|
if(typeof master_flo_addr !== "string") return reject(false);
|
||||||
let kname = `SKBucket_${pubKey}`;
|
const SuKBucketId = localbitcoinplusplus.kademlia.floIdToKbucketId('FLO_TEST', master_flo_addr);
|
||||||
const KBucketId = localbitcoinplusplus.kademlia.floIdToKbucketId('FLO_TEST', flo_id);
|
const SukbOptions = { localNodeId: SuKBucketId }
|
||||||
const kbOptions = { localNodeId: KBucketId }
|
window.supernodeKBucket = new BuildKBucket(SukbOptions);
|
||||||
window[kname] = new BuildKBucket(kbOptions);
|
|
||||||
resolve(true);
|
resolve(true);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
reject(error);
|
reject(error);
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
})
|
|
||||||
},
|
},
|
||||||
addContact: function (id, data, KB=KBucket) {
|
addContact: function (id, data, KB=KBucket) {
|
||||||
const contact = {
|
const contact = {
|
||||||
@ -9843,7 +10167,10 @@
|
|||||||
if (typeof supernodeSeeds !== "object") reject("Failed to get supernode seeds.");
|
if (typeof supernodeSeeds !== "object") reject("Failed to get supernode seeds.");
|
||||||
let supernodeSeedsObj = JSON.parse(supernodeSeeds);
|
let supernodeSeedsObj = JSON.parse(supernodeSeeds);
|
||||||
nearestSupernodeAddresslist = Object.values(supernodeSeedsObj);
|
nearestSupernodeAddresslist = Object.values(supernodeSeedsObj);
|
||||||
nearestSupernodeAddresslist.map(m=>updateinDB('supernodesList', m));
|
nearestSupernodeAddresslist.map((m, i)=>{
|
||||||
|
m.id = i+1;
|
||||||
|
updateinDB('supernodesList', m).catch(e=>{throw new Error(e)});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
resolve(nearestSupernodeAddresslist);
|
resolve(nearestSupernodeAddresslist);
|
||||||
});
|
});
|
||||||
@ -9892,7 +10219,6 @@
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* CODE_JUNCTION: Indexed DB */
|
/* CODE_JUNCTION: Indexed DB */
|
||||||
@ -9938,6 +10264,8 @@
|
|||||||
unique: true
|
unique: true
|
||||||
});
|
});
|
||||||
objectStore.put({
|
objectStore.put({
|
||||||
|
id: "00-01",
|
||||||
|
myLocalFLOAddress: "",
|
||||||
myLocalFLOPublicKey: "",
|
myLocalFLOPublicKey: "",
|
||||||
upiID: "",
|
upiID: "",
|
||||||
last_tx_time: "",
|
last_tx_time: "",
|
||||||
@ -9982,7 +10310,7 @@
|
|||||||
var objectStore = db.createObjectStore("supernodesList", {
|
var objectStore = db.createObjectStore("supernodesList", {
|
||||||
keyPath: 'id'
|
keyPath: 'id'
|
||||||
});
|
});
|
||||||
objectStore.createIndex('trader_flo_address', 'trader_flo_address', {
|
objectStore.createIndex('kbucketId', 'kbucketId', {
|
||||||
unique: true
|
unique: true
|
||||||
});
|
});
|
||||||
objectStore.createIndex('ip', 'ip', {
|
objectStore.createIndex('ip', 'ip', {
|
||||||
@ -10179,6 +10507,14 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function onOpen(evt) {
|
function onOpen(evt) {
|
||||||
|
readAllDB('supernodesList').then(list=>{
|
||||||
|
list.some(m=>{
|
||||||
|
let ws_res = `ws://${m.ip}:${m.port}/`;
|
||||||
|
if(ws_res==websocket.url)
|
||||||
|
localbitcoinplusplus.CONNECTED_SUPERNODE_FLO_ADDRESS
|
||||||
|
= m.kbucketId;
|
||||||
|
});
|
||||||
|
});
|
||||||
console.info(`INFO: Connected succesfully to ${evt.srcElement.url}.`)
|
console.info(`INFO: Connected succesfully to ${evt.srcElement.url}.`)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -10192,14 +10528,147 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function onMessage(evt) {
|
async function onMessage(evt) {
|
||||||
console.log(evt);
|
var response = evt.data || evt;
|
||||||
|
console.log('RESPONSE: ' + response);
|
||||||
|
|
||||||
|
let is_message_for_cashier = response.search('__FOR__CASHIER__');
|
||||||
|
if (!is_message_for_cashier) return;
|
||||||
|
|
||||||
|
var res_pos = response.indexOf('{');
|
||||||
|
if (res_pos >= 0) {
|
||||||
|
var res = response.substr(res_pos);
|
||||||
|
try {
|
||||||
|
var res_obj = JSON.parse(res);
|
||||||
|
|
||||||
|
if (typeof res_obj.globalParams !== "object"
|
||||||
|
|| (localbitcoinplusplus.master_configurations.supernodesPubKeys
|
||||||
|
.includes(localbitcoinplusplus.wallets.my_local_flo_public_key)
|
||||||
|
&& typeof res_obj.globalParams.receiversList == "object"
|
||||||
|
&& !res_obj.globalParams.receiversList
|
||||||
|
.includes(localbitcoinplusplus.wallets.my_local_flo_address)
|
||||||
|
)) return;
|
||||||
|
|
||||||
|
if (typeof res_obj.globalParams.receiverFloId=="string"
|
||||||
|
&& res_obj.globalParams.receiverFloId !==
|
||||||
|
localbitcoinplusplus.wallets.my_local_flo_address) return;
|
||||||
|
|
||||||
|
const isIncomingMessageValid = await validateIncomingMessage(res);
|
||||||
|
console.log("isIncomingMessageValid: ", isIncomingMessageValid);
|
||||||
|
|
||||||
|
if (!isIncomingMessageValid) return;
|
||||||
|
|
||||||
|
if(typeof res_obj.globalParams.senderFloId !=="string")
|
||||||
|
throw new Error(`WARNING: The request did not contain sender FLO Id. Request Aborted.`);
|
||||||
|
|
||||||
|
if (typeof res_obj.method !== "undefined") {
|
||||||
|
let response_from_sever;
|
||||||
|
|
||||||
|
const RM_WALLET = new localbitcoinplusplus.wallets;
|
||||||
|
const RM_RPC = new localbitcoinplusplus.rpc;
|
||||||
|
|
||||||
|
switch (res_obj.method) {
|
||||||
|
case "":
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch(e) {
|
||||||
|
throw new Error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function onError(evt) {
|
function onError(evt) {
|
||||||
console.error(`ERROR: Websocket Connection to ${evt.srcElement.url} returned error.`);
|
console.error(`ERROR: Websocket Connection to ${evt.srcElement.url} returned error.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function doSend(message="") {
|
||||||
|
|
||||||
|
let finalMessage = message;
|
||||||
|
|
||||||
|
const msgObj = JSON.parse(message);
|
||||||
|
|
||||||
|
const RM_WALLET = new localbitcoinplusplus.wallets;
|
||||||
|
|
||||||
|
message = JSON.stringify(msgObj);
|
||||||
|
const message256hash = Crypto.SHA256(message);
|
||||||
|
|
||||||
|
if(typeof localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY !== "string")
|
||||||
|
throw new Error(`WARNING: Private key could not be found.`);
|
||||||
|
|
||||||
|
const nodeSignedMessage = RM_WALLET.sign(message256hash, localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY);
|
||||||
|
|
||||||
|
msgObj.nodeMessage256hash = message256hash;
|
||||||
|
msgObj.nodeSignedMessage = nodeSignedMessage;
|
||||||
|
msgObj.nodePubKey = localbitcoinplusplus.wallets.my_local_flo_public_key;
|
||||||
|
|
||||||
|
finalMessage = JSON.stringify(msgObj);
|
||||||
|
|
||||||
|
// The message is for usernodes and all backup supernodes
|
||||||
|
try {
|
||||||
|
websocket.send(finalMessage);
|
||||||
|
|
||||||
|
} catch(error) {
|
||||||
|
throw new Error(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("SENT: " + finalMessage);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function validateIncomingMessage(message) {
|
||||||
|
return new Promise((resolve, reject)=>{
|
||||||
|
if(message.length <1) {
|
||||||
|
showMessage(`WARNING: The incoming websocket message on was empty.`);
|
||||||
|
reject(false)};
|
||||||
|
const request_array = ['send_back_shamirs_secret_supernode_pvtkey',
|
||||||
|
'retrieve_shamirs_secret_supernode_pvtkey',
|
||||||
|
'store_shamirs_secret_pvtkey_shares'];
|
||||||
|
|
||||||
|
try {
|
||||||
|
const msgObj = JSON.parse(message);
|
||||||
|
|
||||||
|
if (request_array.includes(msgObj.method)) return resolve(true);
|
||||||
|
|
||||||
|
const getFloId = bitjs.FLO_TEST.pubkey2address(msgObj.nodePubKey);
|
||||||
|
|
||||||
|
// Check if the public key belongs to real sender
|
||||||
|
if (getFloId !== msgObj.globalParams.senderFloId) {
|
||||||
|
showMessage(`Sender FLO address did not match signer FLO address.`);
|
||||||
|
reject(false)
|
||||||
|
}
|
||||||
|
const initialMsgObj = {
|
||||||
|
jsonrpc:msgObj.jsonrpc,
|
||||||
|
id:msgObj.id,
|
||||||
|
method:msgObj.method,
|
||||||
|
params:msgObj.params,
|
||||||
|
globalParams:msgObj.globalParams,
|
||||||
|
}
|
||||||
|
|
||||||
|
const initialMsgObjStr = JSON.stringify(initialMsgObj);
|
||||||
|
|
||||||
|
const initialMsgObjStrHash = Crypto.SHA256(initialMsgObjStr);
|
||||||
|
|
||||||
|
const RM_WALLET = new localbitcoinplusplus.wallets;
|
||||||
|
if (RM_WALLET.verify(initialMsgObjStrHash, msgObj.nodeSignedMessage, msgObj.nodePubKey)) {
|
||||||
|
resolve(true);
|
||||||
|
} else {
|
||||||
|
showMessage(`WARNING: Incoming Websocket message verification failed.`)
|
||||||
|
reject(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
reject(error);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*CODE_JUNCTION: Random functions*/
|
/*CODE_JUNCTION: Random functions*/
|
||||||
|
|
||||||
// log event in the console
|
// log event in the console
|
||||||
@ -10211,11 +10680,12 @@
|
|||||||
|
|
||||||
function showMessage(msg='', t=10000) {
|
function showMessage(msg='', t=10000) {
|
||||||
if (msg.length>0) LogEvent(msg);
|
if (msg.length>0) LogEvent(msg);
|
||||||
displayMessages();
|
console.info(msg);
|
||||||
setTimeout(function(){
|
//displayMessages();
|
||||||
closeMessage();
|
// setTimeout(function(){
|
||||||
clearTimeout();
|
// closeMessage();
|
||||||
}, t);
|
// clearTimeout();
|
||||||
|
// }, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
function displayMessages() {
|
function displayMessages() {
|
||||||
@ -10273,8 +10743,10 @@
|
|||||||
try {
|
try {
|
||||||
var rm_configs = localbitcoinplusplus.actions.fetch_configs(async function (...fetch_configs_res) {
|
var rm_configs = localbitcoinplusplus.actions.fetch_configs(async function (...fetch_configs_res) {
|
||||||
localbitcoinplusplus.is_ui_loaded = false;
|
localbitcoinplusplus.is_ui_loaded = false;
|
||||||
showMessage(`Connecting to Supernode server. Please wait...`);
|
window.bitjs = []; // Launch bitjs
|
||||||
|
localbitcoinplusplus.master_configurations.tradableAsset1.map(asset => bitjslib(asset));
|
||||||
kickInit();
|
kickInit();
|
||||||
|
loadResetFloBtnUi();
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
showMessage(`WARNING: System failed to collect configurations.
|
showMessage(`WARNING: System failed to collect configurations.
|
||||||
@ -10291,22 +10763,113 @@
|
|||||||
console.info('Load pending withdrawals');
|
console.info('Load pending withdrawals');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Connect to Supernode
|
||||||
function loadSupernodesConnectUi() {
|
function loadSupernodesConnectUi() {
|
||||||
|
|
||||||
//wsUri = await localbitcoinplusplus.kademlia.getSupernodeSeed();
|
const supernodeSeeds = localbitcoinplusplus.master_configurations.supernodeSeeds;
|
||||||
|
if (typeof supernodeSeeds !== "object") return showMessage("Failed to get supernode list.");
|
||||||
|
let supernodeSeedsObj = JSON.parse(supernodeSeeds);
|
||||||
|
let supernodeSeedsArray = Object.values(supernodeSeedsObj);
|
||||||
|
|
||||||
// Connect with primary supernodes
|
let supernode_seedsInput = ``;
|
||||||
//await startWebSocket(`ws://${wsUri[0].ip}:${wsUri[0].port}`);
|
supernode_seedsInput += `<div class="input-group">
|
||||||
|
<select class="custom-select" id="supernode_seeds">
|
||||||
|
<option selected>Choose Suprnode...</option>`;
|
||||||
|
supernodeSeedsArray.map(wsUri=>{
|
||||||
|
supernode_seedsInput += `<option value="ws://${wsUri.ip}:${wsUri.port}">${wsUri.kbucketId}</option>`;
|
||||||
|
});
|
||||||
|
supernode_seedsInput += `</select>
|
||||||
|
<div class="input-group-append">
|
||||||
|
<button class="btn btn-outline-secondary" id="supn_conn_btn" type="button">Connect</button>
|
||||||
|
</div>
|
||||||
|
</div>`;
|
||||||
|
|
||||||
|
const supernode_seeds_div = document.getElementById('supernode_seeds_div');
|
||||||
|
supernode_seeds_div.innerHTML = supernode_seedsInput;
|
||||||
|
|
||||||
|
const supn_conn_btn = document.getElementById('supn_conn_btn');
|
||||||
|
supn_conn_btn.addEventListener("click", function(evt) {
|
||||||
|
const selected_su = document.getElementById('supernode_seeds');
|
||||||
|
if (typeof websocket == "object" && websocket.readyState === WebSocket.OPEN) {
|
||||||
|
if (websocket.url===`${selected_su.value}/`) {
|
||||||
|
showMessage(`INFO: Websocket already connected.`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
websocket.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
startWebSocket(selected_su.value);
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
showMessage('Error: '+error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// localbitcoinUser Database
|
// Ask Connected Supernode to give pending deposits/withdrawals
|
||||||
|
function AskSupernodeForLatestDepositsAndWithdrawalsData() {
|
||||||
|
|
||||||
|
const fetch_deposits_btn = document.getElementById('fetch_deposits');
|
||||||
|
fetch_deposits_btn.addEventListener("click", function(evt) {
|
||||||
|
|
||||||
|
console.log(localbitcoinplusplus);
|
||||||
|
console.log(localbitcoinplusplus.MY_UPI_ID);
|
||||||
|
console.log(localbitcoinplusplus.CONNECTED_SUPERNODE_FLO_ADDRESS);
|
||||||
|
|
||||||
|
if (localbitcoinplusplus.MY_UPI_ID.length < 1
|
||||||
|
|| localbitcoinplusplus.CONNECTED_SUPERNODE_FLO_ADDRESS.length < 1) {
|
||||||
|
showMessage(`WARNING: Your UPI Id or connected Supernode is not set.`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const RM_RPC = new localbitcoinplusplus.rpc;
|
||||||
|
RM_RPC
|
||||||
|
.send_rpc
|
||||||
|
.call(this, "give_cashier_latest_pending_cash_deposits", {
|
||||||
|
trader_flo_address: localbitcoinplusplus.wallets.my_local_flo_address,
|
||||||
|
cashier_pubKey: localbitcoinplusplus.wallets.my_local_flo_public_key,
|
||||||
|
cashier_upi: localbitcoinplusplus.MY_UPI_ID,
|
||||||
|
receiver_flo_address: localbitcoinplusplus.CONNECTED_SUPERNODE_FLO_ADDRESS,
|
||||||
|
}).then(resp=>doSend(resp));
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset Flo Id
|
||||||
|
function loadResetFloBtnUi() {
|
||||||
|
// RESET KEYS
|
||||||
|
const reset_flo_keys_div = document.getElementById('flo_keys_div');
|
||||||
|
const reset_flo_keys_btn = document.createElement('button');
|
||||||
|
reset_flo_keys_btn.className += ` button bg-purple mg-5 `;
|
||||||
|
const reset_flo_keys_btn_text = document.createTextNode(`Reset FLO Keys`);
|
||||||
|
reset_flo_keys_btn.appendChild(reset_flo_keys_btn_text);
|
||||||
|
reset_flo_keys_div.appendChild(reset_flo_keys_btn);
|
||||||
|
|
||||||
|
reset_flo_keys_btn.onclick = function () {
|
||||||
|
if (confirm(
|
||||||
|
`This will reset your old keys along with data associated with it. Are you sure you want to continue?`
|
||||||
|
)) {
|
||||||
|
const RM_WALLET = new localbitcoinplusplus.wallets;
|
||||||
|
RM_WALLET.reset_flo_keys().then(reset_success => {
|
||||||
|
if (reset_success) {
|
||||||
|
showMessage("INFO: FLO keys have been reset successfully.");
|
||||||
|
} else {
|
||||||
|
showMessage(`INFO: Failed to reset FLO keys.`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// paymentsHandlerDetails Database
|
||||||
const dataBaseUIOperations = async function () {
|
const dataBaseUIOperations = async function () {
|
||||||
|
|
||||||
localbitcoinplusplus.is_ui_loaded = true;
|
localbitcoinplusplus.is_ui_loaded = true;
|
||||||
|
|
||||||
const RM_WALLET = new localbitcoinplusplus.wallets;
|
const RM_WALLET = new localbitcoinplusplus.wallets;
|
||||||
const RM_TRADE = new localbitcoinplusplus.trade;
|
|
||||||
const RM_RPC = new localbitcoinplusplus.rpc;
|
const RM_RPC = new localbitcoinplusplus.rpc;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -10316,10 +10879,7 @@
|
|||||||
idbData.myLocalFLOAddress;
|
idbData.myLocalFLOAddress;
|
||||||
const MY_LOCAL_FLO_PUBLIC_KEY = localbitcoinplusplus.wallets.my_local_flo_public_key =
|
const MY_LOCAL_FLO_PUBLIC_KEY = localbitcoinplusplus.wallets.my_local_flo_public_key =
|
||||||
idbData.myLocalFLOPublicKey;
|
idbData.myLocalFLOPublicKey;
|
||||||
|
|
||||||
// Build Supernodes KBuckets
|
|
||||||
launchSupernodesKBuckects = await localbitcoinplusplus.kademlia.launchSupernodesKBucket();
|
|
||||||
|
|
||||||
// Load Supernodes Connection Select UI
|
// Load Supernodes Connection Select UI
|
||||||
loadSupernodesConnectUi();
|
loadSupernodesConnectUi();
|
||||||
|
|
||||||
@ -10329,14 +10889,17 @@
|
|||||||
// Load Pending Withdrawals UI
|
// Load Pending Withdrawals UI
|
||||||
loadPendingWithdrawals();
|
loadPendingWithdrawals();
|
||||||
|
|
||||||
|
// Fetch Deposits
|
||||||
|
AskSupernodeForLatestDepositsAndWithdrawalsData();
|
||||||
|
|
||||||
showMessage(`Connection successfull. Welocome to Local Bitcoin Plus Plus Cash Handling platform.`);
|
showMessage(`Connection successfull. Welocome to Local Bitcoin Plus Plus Cash Handling platform.`);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
showMessage("ERROR: Failed to initialise the localbitcoinUser database. You are unable to trade at the moment.");
|
showMessage("ERROR: Failed to initialise the paymentsHandlerDetails database. You are unable to trade at the moment.");
|
||||||
throw new Error(
|
throw new Error(
|
||||||
"ERROR: Failed to initialise the localbitcoinUser database. You are unable to trade at the moment."
|
"ERROR: Failed to initialise the paymentsHandlerDetails database. You are unable to trade at the moment."
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -10348,27 +10911,54 @@
|
|||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
|
|
||||||
readDB("paymentsHandlerDetails", "00-01").then(async function (idbData) {
|
readDB("paymentsHandlerDetails", "00-01").then(async function (idbData) {
|
||||||
|
let localbitcoinplusplusObj = {
|
||||||
|
id: "00-01",
|
||||||
|
myLocalFLOAddress: "",
|
||||||
|
myLocalFLOPublicKey: "",
|
||||||
|
upiID: "",
|
||||||
|
last_tx_time: "",
|
||||||
|
last_active_time: + new Date()
|
||||||
|
}
|
||||||
if (typeof idbData.myLocalFLOPublicKey == "undefined" || idbData.myLocalFLOPublicKey
|
if (typeof idbData.myLocalFLOPublicKey == "undefined" || idbData.myLocalFLOPublicKey
|
||||||
.trim() == '') {
|
.trim() == '') {
|
||||||
let user_pvt_key = prompt(
|
let user_pvt_key = prompt(
|
||||||
"Please Enter a valid FLO private key if you have any. Else leave blank."
|
"Please Enter a valid FLO private key if you have any. Else leave blank."
|
||||||
);
|
);
|
||||||
|
const user_upi = prompt("Please Enter a valid UPI id!");
|
||||||
|
|
||||||
if (user_pvt_key.trim() == "" || user_pvt_key.length < 1) user_pvt_key = null;
|
if (user_pvt_key.trim() == "" || user_pvt_key.length < 1) user_pvt_key = null;
|
||||||
|
if (user_upi.trim() == "" || user_upi.length < 1) return showMessage(`Warning: You must provide a valid UPI id.`);
|
||||||
|
|
||||||
let newKeys = RM_WALLET.generateFloKeys(user_pvt_key);
|
let newKeys = RM_WALLET.generateFloKeys(user_pvt_key);
|
||||||
if (typeof newKeys == 'object' && newKeys.privateKeyWIF.length > 0 &&
|
if (typeof newKeys == 'object' && newKeys.privateKeyWIF.length > 0 &&
|
||||||
newKeys.address.length > 0) {
|
newKeys.address.length > 0) {
|
||||||
localbitcoinplusplusObj.myLocalFLOAddress = newKeys.address;
|
|
||||||
localbitcoinplusplusObj.myLocalFLOPublicKey = newKeys.pubKeyHex;
|
|
||||||
localbitcoinplusplusObj.lastConnectedTime = + new Date();
|
|
||||||
|
|
||||||
await updateinDB("paymentsHandlerDetails", localbitcoinplusplusObj);
|
|
||||||
|
|
||||||
//wsUri = await localbitcoinplusplus.kademlia.getSupernodeSeed();
|
localbitcoinplusplusObj.myLocalFLOAddress= newKeys.address,
|
||||||
|
localbitcoinplusplusObj.myLocalFLOPublicKey= newKeys.pubKeyHex,
|
||||||
|
localbitcoinplusplusObj.upiID= user_upi,
|
||||||
|
localbitcoinplusplusObj.last_active_time= + new Date()
|
||||||
|
|
||||||
|
await updateinDB("paymentsHandlerDetails", localbitcoinplusplusObj);
|
||||||
|
|
||||||
//await startWebSocket(`ws://${wsUri[0].ip}:${wsUri[0].port}`);
|
Object.defineProperty(localbitcoinplusplus, "MY_UPI_ID", {
|
||||||
|
value: user_upi,
|
||||||
|
writable: false,
|
||||||
|
configurable: false,
|
||||||
|
enumerable: false
|
||||||
|
});
|
||||||
|
|
||||||
|
// launch KBuckets
|
||||||
|
launchKBuckects = await localbitcoinplusplus.kademlia.launchKBucket();
|
||||||
|
|
||||||
|
if (!launchKBuckects) {
|
||||||
|
const kmsg = `ERROR: Failed to build KBuckets. System cannot proceed further.`;
|
||||||
|
showMessage(kmsg);
|
||||||
|
throw new Error(kmsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
await localbitcoinplusplus.kademlia.restoreSupernodeKBucket();
|
||||||
|
|
||||||
|
await localbitcoinplusplus.kademlia.getSupernodeSeed();
|
||||||
|
|
||||||
if ((typeof localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY!=='string'
|
if ((typeof localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY!=='string'
|
||||||
|| localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY.length<1)
|
|| localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY.length<1)
|
||||||
@ -10390,12 +10980,30 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (typeof idbData.upiID !=="string" || idbData.upiID.length<1) {
|
||||||
|
showMessage(`ERROR: No UPI ID found.`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.defineProperty(localbitcoinplusplus, "MY_UPI_ID", {
|
||||||
|
value: idbData.upiID,
|
||||||
|
writable: false,
|
||||||
|
configurable: false,
|
||||||
|
enumerable: false
|
||||||
|
});
|
||||||
|
|
||||||
|
// launch KBuckets
|
||||||
|
launchKBuckects = await localbitcoinplusplus.kademlia.launchKBucket();
|
||||||
|
|
||||||
|
if (!launchKBuckects) {
|
||||||
|
const kmsg = `ERROR: Failed to build KBuckets. System cannot proceed further.`;
|
||||||
|
showMessage(kmsg);
|
||||||
|
throw new Error(kmsg);
|
||||||
|
}
|
||||||
|
|
||||||
await localbitcoinplusplus.kademlia.restoreSupernodeKBucket();
|
await localbitcoinplusplus.kademlia.restoreSupernodeKBucket();
|
||||||
|
|
||||||
//wsUri = await localbitcoinplusplus.kademlia.getSupernodeSeed();
|
await localbitcoinplusplus.kademlia.getSupernodeSeed();
|
||||||
|
|
||||||
// Connect with primary supernodes
|
|
||||||
//await startWebSocket(`ws://${wsUri[0].ip}:${wsUri[0].port}`);
|
|
||||||
|
|
||||||
if ((typeof localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY!=='string'
|
if ((typeof localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY!=='string'
|
||||||
|| localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY.length<1)
|
|| localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY.length<1)
|
||||||
@ -10415,10 +11023,8 @@
|
|||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<!-- Latest compiled and minified JavaScript -->
|
</script>
|
||||||
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
@ -10543,7 +10543,7 @@
|
|||||||
|
|
||||||
const master_flo_pubKey = localbitcoinplusplus.master_configurations.masterFLOPubKey;
|
const master_flo_pubKey = localbitcoinplusplus.master_configurations.masterFLOPubKey;
|
||||||
const master_flo_addr = bitjs.FLO_TEST.pubkey2address(master_flo_pubKey);
|
const master_flo_addr = bitjs.FLO_TEST.pubkey2address(master_flo_pubKey);
|
||||||
if(typeof master_flo_pubKey !== "string") return reject(false);
|
if(typeof master_flo_addr !== "string") return reject(false);
|
||||||
const SuKBucketId = localbitcoinplusplus.kademlia.floIdToKbucketId('FLO_TEST', master_flo_addr);
|
const SuKBucketId = localbitcoinplusplus.kademlia.floIdToKbucketId('FLO_TEST', master_flo_addr);
|
||||||
const SukbOptions = { localNodeId: SuKBucketId }
|
const SukbOptions = { localNodeId: SuKBucketId }
|
||||||
window.supernodeKBucket = new BuildKBucket(SukbOptions);
|
window.supernodeKBucket = new BuildKBucket(SukbOptions);
|
||||||
@ -10769,7 +10769,6 @@
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
addClosestSupernodeInDB: function(flo_addr, KB=supernodeKBucket) {
|
addClosestSupernodeInDB: function(flo_addr, KB=supernodeKBucket) {
|
||||||
return new Promise(async (resolve, reject)=>{
|
return new Promise(async (resolve, reject)=>{
|
||||||
const supernodeSeeds = localbitcoinplusplus.master_configurations.supernodeSeeds;
|
const supernodeSeeds = localbitcoinplusplus.master_configurations.supernodeSeeds;
|
||||||
@ -12496,6 +12495,8 @@
|
|||||||
.includes(parseFloat(params.depositing_amount))
|
.includes(parseFloat(params.depositing_amount))
|
||||||
&& typeof params.trader_flo_address == "string"
|
&& typeof params.trader_flo_address == "string"
|
||||||
&& params.trader_flo_address.length > 0
|
&& params.trader_flo_address.length > 0
|
||||||
|
&& typeof params.user_upi == "string"
|
||||||
|
&& params.user_upi.length > 0
|
||||||
) {
|
) {
|
||||||
|
|
||||||
params.id = helper_functions.unique_id();
|
params.id = helper_functions.unique_id();
|
||||||
@ -13677,6 +13678,8 @@
|
|||||||
.includes(parseFloat(params.depositing_amount))
|
.includes(parseFloat(params.depositing_amount))
|
||||||
&& typeof params.trader_flo_address == "string"
|
&& typeof params.trader_flo_address == "string"
|
||||||
&& params.trader_flo_address.length > 0
|
&& params.trader_flo_address.length > 0
|
||||||
|
&& typeof params.user_upi == "string"
|
||||||
|
&& params.user_upi.length > 0
|
||||||
) {
|
) {
|
||||||
|
|
||||||
params.id = helper_functions.unique_id();
|
params.id = helper_functions.unique_id();
|
||||||
@ -14729,7 +14732,7 @@
|
|||||||
"deposit_asset_request", deposit_request_object)
|
"deposit_asset_request", deposit_request_object)
|
||||||
.then(deposit_request=>doSend(deposit_request));
|
.then(deposit_request=>doSend(deposit_request));
|
||||||
},
|
},
|
||||||
depositCash(amount, currency, userFLOaddress) {
|
depositCash(amount, currency, userFLOaddress, user_upi) {
|
||||||
if (typeof localbitcoinplusplus.master_configurations.tradableAsset2 == 'undefined' ||
|
if (typeof localbitcoinplusplus.master_configurations.tradableAsset2 == 'undefined' ||
|
||||||
(!localbitcoinplusplus.master_configurations.tradableAsset2
|
(!localbitcoinplusplus.master_configurations.tradableAsset2
|
||||||
.includes(currency))) {
|
.includes(currency))) {
|
||||||
@ -14749,11 +14752,16 @@
|
|||||||
err_msg = "Error: Invalid deposit amount.";
|
err_msg = "Error: Invalid deposit amount.";
|
||||||
showMessage(err_msg);
|
showMessage(err_msg);
|
||||||
throw new Error(err_msg);
|
throw new Error(err_msg);
|
||||||
|
} else if (typeof user_upi!=="string" || user_upi.length<1) {
|
||||||
|
err_msg = "Error: Invalid UPI id.";
|
||||||
|
showMessage(err_msg);
|
||||||
|
throw new Error(err_msg);
|
||||||
}
|
}
|
||||||
let deposit_request_object = {
|
let deposit_request_object = {
|
||||||
trader_flo_address: userFLOaddress,
|
trader_flo_address: userFLOaddress,
|
||||||
depositing_amount: amount,
|
depositing_amount: amount,
|
||||||
currency: currency,
|
currency: currency,
|
||||||
|
user_upi: user_upi,
|
||||||
operation_type: "deposit_cash",
|
operation_type: "deposit_cash",
|
||||||
receiver_flo_address:localbitcoinplusplus.MY_SUPERNODE_FLO_ADDRESS,
|
receiver_flo_address:localbitcoinplusplus.MY_SUPERNODE_FLO_ADDRESS,
|
||||||
}
|
}
|
||||||
@ -16360,9 +16368,15 @@
|
|||||||
// If the message is about leaving of a node determine its FLO Id
|
// If the message is about leaving of a node determine its FLO Id
|
||||||
// and fire respective events
|
// and fire respective events
|
||||||
let isItANodeLeavingMessage = response.search(`\\-- left`);
|
let isItANodeLeavingMessage = response.search(`\\-- left`);
|
||||||
|
|
||||||
if(isItANodeLeavingMessage >= 0) {
|
if(isItANodeLeavingMessage >= 0) {
|
||||||
reactor.dispatchEvent('fireNodeGoodByeEvent', response);
|
reactor.dispatchEvent('fireNodeGoodByeEvent', response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const isMsgFromCashier = response.search('__FOR__CASHIER__');
|
||||||
|
if (isMsgFromCashier>=0) {
|
||||||
|
handleCashierMessages(response);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var res_pos = response.indexOf('{');
|
var res_pos = response.indexOf('{');
|
||||||
@ -16648,8 +16662,8 @@
|
|||||||
let counterTraderAccountAddress =
|
let counterTraderAccountAddress =
|
||||||
`Please pay the amount to following UPI ID:
|
`Please pay the amount to following UPI ID:
|
||||||
${resp.msg}`;
|
${resp.msg}`;
|
||||||
showMessage(counterTraderAccountAddress);
|
showMessage(counterTraderAccountAddress);
|
||||||
modalWindow(counterTraderAccountAddress);
|
modalWindow(counterTraderAccountAddress);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -19470,6 +19484,35 @@
|
|||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case "deposit_cash_request_response":
|
||||||
|
if (typeof res_obj.params !== "object"
|
||||||
|
|| typeof res_obj.params[0] !== "object") return;
|
||||||
|
let deposit_res_data = res_obj.params[0];
|
||||||
|
RM_RPC.filter_legit_backup_requests(deposit_res_data.trader_flo_address,
|
||||||
|
async function (is_valid_request) {
|
||||||
|
if(!is_valid_request) return false;
|
||||||
|
if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object"
|
||||||
|
&& typeof res_obj.params[0].data == "object") {
|
||||||
|
let resp = res_obj.params[0];
|
||||||
|
if (RM_WALLET
|
||||||
|
.verify(resp.data.depositDataHash, resp.data.order_validator_sign, resp.data.order_validator_public_key)
|
||||||
|
) {
|
||||||
|
let getPrimarySuObj = await localbitcoinplusplus.kademlia.determineClosestSupernode(resp.data.trader_flo_address);
|
||||||
|
const primarySupernode = getPrimarySuObj[0].data.id;
|
||||||
|
const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernode];
|
||||||
|
if(typeof backup_server_db_instance !== "object") {
|
||||||
|
let backup_db_error_msg = `WARNING: Unknown DB instance. DB Backup failed.`;
|
||||||
|
showMessage(backup_db_error_msg);
|
||||||
|
throw new Error(backup_db_error_msg);
|
||||||
|
};
|
||||||
|
|
||||||
|
backup_server_db_instance.backup_addDB('cash_deposits', resp.data);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
|
||||||
case "withdrawal_request_response":
|
case "withdrawal_request_response":
|
||||||
if (typeof res_obj.params !== "object"
|
if (typeof res_obj.params !== "object"
|
||||||
|| typeof res_obj.params[0] !== "object") return;
|
|| typeof res_obj.params[0] !== "object") return;
|
||||||
@ -20467,6 +20510,10 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function handleCashierMessages(response) {
|
||||||
|
console.log(response);
|
||||||
|
}
|
||||||
|
|
||||||
function onError(evt) {
|
function onError(evt) {
|
||||||
let msg = `ERROR: Websocket Connection to ${evt.srcElement.url} returned error.`;
|
let msg = `ERROR: Websocket Connection to ${evt.srcElement.url} returned error.`;
|
||||||
showMessage(msg);
|
showMessage(msg);
|
||||||
@ -22294,6 +22341,12 @@
|
|||||||
// asset_button_box.appendChild(withdrawAssetButton);
|
// asset_button_box.appendChild(withdrawAssetButton);
|
||||||
|
|
||||||
depositAssetButton.addEventListener('click', function () {
|
depositAssetButton.addEventListener('click', function () {
|
||||||
|
const user_upi = prompt('Please provide the UPI id you are paying from!');
|
||||||
|
if (typeof user_upi!=="string" || user_upi.length<1) {
|
||||||
|
err_msg = "Invalid or empty UPI id.";
|
||||||
|
showMessage(err_msg);
|
||||||
|
throw new Error(err_msg);
|
||||||
|
}
|
||||||
let asset_type = assetTypeInput.value;
|
let asset_type = assetTypeInput.value;
|
||||||
let tradeAmount = Number(tradeAmountSelect.value);
|
let tradeAmount = Number(tradeAmountSelect.value);
|
||||||
let fiatCurrency = currencySelect.value;
|
let fiatCurrency = currencySelect.value;
|
||||||
@ -22305,7 +22358,7 @@
|
|||||||
if (typeof localbitcoinplusplus.master_configurations.tradableAsset2 !== 'undefined' &&
|
if (typeof localbitcoinplusplus.master_configurations.tradableAsset2 !== 'undefined' &&
|
||||||
localbitcoinplusplus.master_configurations.tradableAsset2.includes(asset_type)
|
localbitcoinplusplus.master_configurations.tradableAsset2.includes(asset_type)
|
||||||
) {
|
) {
|
||||||
RM_TRADE.depositCash(tradeAmount, fiatCurrency, userFLOaddress);
|
RM_TRADE.depositCash(tradeAmount, fiatCurrency, userFLOaddress, user_upi);
|
||||||
} else {
|
} else {
|
||||||
err_msg = "Error while depositing your address.";
|
err_msg = "Error while depositing your address.";
|
||||||
showMessage(err_msg);
|
showMessage(err_msg);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user