updates and bug fixes
This commit is contained in:
parent
be8329e876
commit
ef327a3222
381
floBank.html
381
floBank.html
@ -2,7 +2,7 @@
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>FLO Standard Operators</title>
|
||||
<title>FLO Bank</title>
|
||||
|
||||
<script id="floGlobals">
|
||||
/* Constants for FLO blockchain operations !!Make sure to add this at begining!! */
|
||||
@ -13,9 +13,7 @@
|
||||
|
||||
//Required for blockchain API operators
|
||||
apiURL: {
|
||||
FLO: ['https://explorer.mediciland.com/', 'https://livenet.flocha.in/', 'https://flosight.duckdns.org/',
|
||||
'http://livenet-explorer.floexperiments.com/'
|
||||
],
|
||||
FLO: [ 'https://livenet.flocha.in/'],
|
||||
FLO_TEST: ['https://testnet-flosight.duckdns.org/', 'https://testnet.flocha.in/']
|
||||
},
|
||||
tokenURL: "https://ranchimallflo.duckdns.org/",
|
||||
@ -30,7 +28,7 @@
|
||||
|
||||
//for cloud apps
|
||||
subAdmins: [],
|
||||
application: "TEST_MODE",
|
||||
application: "bank",
|
||||
appObjects: {},
|
||||
generalData: {},
|
||||
lastVC: {}
|
||||
@ -43,6 +41,12 @@
|
||||
//floDapps.setAppObjectStores({sampleObs1:{}, sampleObs2:{options{autoIncrement:true, keyPath:'SampleKey'}, Indexes:{sampleIndex:{}}}})
|
||||
//floDapps.setCustomPrivKeyInput( () => { FUNCTION BODY *must resolve private key* } )
|
||||
|
||||
floDapps.setAppObjectStores({
|
||||
accounts: {},
|
||||
responses: {},
|
||||
requests: {},
|
||||
appendix: {}
|
||||
})
|
||||
floDapps.launchStartUp().then(result => {
|
||||
console.log(result)
|
||||
alert(`Welcome FLO_ID: ${myFloID}`)
|
||||
@ -6961,7 +6965,7 @@ Bitcoin.Util = {
|
||||
})();
|
||||
</script>
|
||||
|
||||
<script id="floCrypto" version="2.0.0">
|
||||
<script id="floCrypto" version="2.0.1">
|
||||
/* FLO Crypto Operators*/
|
||||
const floCrypto = {
|
||||
|
||||
@ -6970,6 +6974,8 @@ Bitcoin.Util = {
|
||||
|
||||
ecparams: EllipticCurve.getSECCurveByName("secp256k1"),
|
||||
|
||||
asciiAlternatives: `‘ '\n’ '\n“ "\n” "\n– --\n— ---\n≥ >=\n≤ <=\n≠ !=\n× *\n÷ /\n← <-\n→ ->\n↔ <->\n⇒ =>\n⇐ <=\n⇔ <=>`,
|
||||
|
||||
exponent1: function() {
|
||||
return this.p.add(BigInteger.ONE).divide(BigInteger("4"))
|
||||
},
|
||||
@ -6995,9 +7001,8 @@ Bitcoin.Util = {
|
||||
// verify y value
|
||||
let resultBigInt = y.mod(BigInteger("2"));
|
||||
let check = resultBigInt.toString() % 2;
|
||||
if (prefix_modulus !== check) {
|
||||
if (prefix_modulus !== check)
|
||||
yDecimalValue = y.negate().mod(p).toString();
|
||||
}
|
||||
return {
|
||||
x: xDecimalValue,
|
||||
y: yDecimalValue
|
||||
@ -7014,20 +7019,15 @@ Bitcoin.Util = {
|
||||
},
|
||||
|
||||
deriveSharedKeySender: function(receiverCompressedPublicKey, senderPrivateKey) {
|
||||
try {
|
||||
let receiverPublicKeyString = this.getUncompressedPublicKey(receiverCompressedPublicKey);
|
||||
var senderDerivedKey = ellipticCurveEncryption.senderSharedKeyDerivation(
|
||||
receiverPublicKeyString.x, receiverPublicKeyString.y, senderPrivateKey);
|
||||
return senderDerivedKey;
|
||||
} catch (error) {
|
||||
return new Error(error);
|
||||
}
|
||||
let receiverPublicKeyString = this.getUncompressedPublicKey(receiverCompressedPublicKey);
|
||||
var senderDerivedKey = ellipticCurveEncryption.senderSharedKeyDerivation(
|
||||
receiverPublicKeyString.x, receiverPublicKeyString.y, senderPrivateKey);
|
||||
return senderDerivedKey;
|
||||
},
|
||||
|
||||
deriveReceiverSharedKey: function(senderPublicKeyString, receiverPrivateKey) {
|
||||
return ellipticCurveEncryption.receiverSharedKeyDerivation(
|
||||
senderPublicKeyString.XValuePublicString, senderPublicKeyString.YValuePublicString,
|
||||
receiverPrivateKey);
|
||||
senderPublicKeyString.XValuePublicString, senderPublicKeyString.YValuePublicString, receiverPrivateKey);
|
||||
},
|
||||
|
||||
getReceiverPublicKeyString: function(privateKey) {
|
||||
@ -7035,14 +7035,8 @@ Bitcoin.Util = {
|
||||
},
|
||||
|
||||
deriveSharedKeyReceiver: function(senderPublicKeyString, receiverPrivateKey) {
|
||||
try {
|
||||
return ellipticCurveEncryption.receiverSharedKeyDerivation(senderPublicKeyString
|
||||
.XValuePublicString,
|
||||
senderPublicKeyString.YValuePublicString, receiverPrivateKey);
|
||||
|
||||
} catch (error) {
|
||||
return new Error(error);
|
||||
}
|
||||
return ellipticCurveEncryption.receiverSharedKeyDerivation(
|
||||
senderPublicKeyString.XValuePublicString, senderPublicKeyString.YValuePublicString, receiverPrivateKey);
|
||||
},
|
||||
|
||||
wifToDecimal: function(pk_wif, isPubKeyCompressed = false) {
|
||||
@ -7247,10 +7241,68 @@ Bitcoin.Util = {
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
validateASCII: function(string, bool = true) {
|
||||
if (typeof string !== "string")
|
||||
return null;
|
||||
if (bool) {
|
||||
let x;
|
||||
for (let i = 0; i < string.length; i++) {
|
||||
x = string.charCodeAt(i);
|
||||
if (x < 32 || x > 127)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
let x, invalids = {};
|
||||
for (let i = 0; i < string.length; i++) {
|
||||
x = string.charCodeAt(i);
|
||||
if (x < 32 || x > 127)
|
||||
if (x in invalids)
|
||||
invalids[string[i]].push(i)
|
||||
else
|
||||
invalids[string[i]] = [i];
|
||||
}
|
||||
if (Object.keys(invalids).length)
|
||||
return invalids;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
},
|
||||
|
||||
convertToASCII: function(string, mode = 'soft-remove') {
|
||||
let chars = this.validateASCII(string, false);
|
||||
if (chars === true)
|
||||
return string;
|
||||
else if (chars === null)
|
||||
return null;
|
||||
let convertor, result = string,
|
||||
refAlt = {};
|
||||
this.util.asciiAlternatives.split('\n').forEach(a => refAlt[a[0]] = a.slice(2));
|
||||
mode = mode.toLowerCase();
|
||||
if (mode === "hard-unicode")
|
||||
convertor = (c) => `\\u${('000'+c.charCodeAt().toString(16)).slice(-4)}`;
|
||||
else if (mode === "soft-unicode")
|
||||
convertor = (c) => refAlt[c] || `\\u${('000'+c.charCodeAt().toString(16)).slice(-4)}`;
|
||||
else if (mode === "hard-remove")
|
||||
convertor = c => "";
|
||||
else if (mode === "soft-remove")
|
||||
convertor = c => refAlt[c] || "";
|
||||
else
|
||||
return null;
|
||||
for (let c in chars)
|
||||
result = result.replaceAll(c, convertor(c));
|
||||
return result;
|
||||
},
|
||||
|
||||
revertUnicode: function(string) {
|
||||
return string.replace(/\\u[\dA-F]{4}/gi,
|
||||
m => String.fromCharCode(parseInt(m.replace(/\\u/g, ''), 16)));
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<script id="floBlockchainAPI" version="2.0.1">
|
||||
<script id="floBlockchainAPI" version="2.0.1a">
|
||||
/* FLO Blockchain Operator to send/receive data from blockchain using API calls*/
|
||||
const floBlockchainAPI = {
|
||||
|
||||
@ -7322,6 +7374,8 @@ Bitcoin.Util = {
|
||||
//Send Tx to blockchain
|
||||
sendTx: function(senderAddr, receiverAddr, sendAmt, privKey, floData = '') {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!floCrypto.validateASCII(floData))
|
||||
return reject("Invalid FLO_Data: only printable ASCII characters are allowed");
|
||||
if (!floCrypto.validateAddr(senderAddr))
|
||||
reject(`Invalid address : ${senderAddr}`);
|
||||
else if (!floCrypto.validateAddr(receiverAddr))
|
||||
@ -7368,6 +7422,8 @@ Bitcoin.Util = {
|
||||
return reject(`Invalid floID`);
|
||||
if (!floCrypto.verifyPrivKey(privKey, floID))
|
||||
return reject("Invalid Private Key")
|
||||
if (!floCrypto.validateASCII(floData))
|
||||
return reject("Invalid FLO_Data: only printable ASCII characters are allowed");
|
||||
|
||||
var trx = bitjs.transaction();
|
||||
var utxoAmt = 0.0;
|
||||
@ -7431,7 +7487,8 @@ Bitcoin.Util = {
|
||||
*/
|
||||
sendTxMultiple: function(senderPrivKeys, receivers, floData = '') {
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
if (!floCrypto.validateASCII(floData))
|
||||
return reject("Invalid FLO_Data: only printable ASCII characters are allowed");
|
||||
let senders = {},
|
||||
preserveRatio;
|
||||
//check for argument validations
|
||||
@ -7649,8 +7706,8 @@ Bitcoin.Util = {
|
||||
filter : custom filter funtion for floData (eg . filter: d => {return d[0] == '$'})
|
||||
*/
|
||||
readData: function(addr, options = {}) {
|
||||
options.limit = options.limit | 0
|
||||
options.ignoreOld = options.ignoreOld | 0
|
||||
options.limit = options.limit || 0
|
||||
options.ignoreOld = options.ignoreOld || 0
|
||||
return new Promise((resolve, reject) => {
|
||||
this.promisedAPI(`api/addrs/${addr}/txs?from=0&to=1`).then(response => {
|
||||
var newItems = response.totalItems - options.ignoreOld;
|
||||
@ -7661,22 +7718,18 @@ Bitcoin.Util = {
|
||||
var filteredData = [];
|
||||
for (i = 0; i < (response.totalItems - options.ignoreOld) &&
|
||||
filteredData.length < options.limit; i++) {
|
||||
if (options.sentOnly && response.items[i].vin[0].addr !==
|
||||
addr)
|
||||
if (options.sentOnly && response.items[i].vin[0].addr !== addr)
|
||||
continue;
|
||||
if (options.pattern) {
|
||||
try {
|
||||
let jsonContent = JSON.parse(response.items[i]
|
||||
.floData)
|
||||
if (!Object.keys(jsonContent).includes(options
|
||||
.pattern))
|
||||
let jsonContent = JSON.parse(response.items[i].floData)
|
||||
if (!Object.keys(jsonContent).includes(options.pattern))
|
||||
continue;
|
||||
} catch (error) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (options.filter && !options.filter(response.items[i]
|
||||
.floData))
|
||||
if (options.filter && !options.filter(response.items[i].floData))
|
||||
continue;
|
||||
filteredData.push(response.items[i].floData);
|
||||
}
|
||||
@ -9320,14 +9373,19 @@ Bitcoin.Util = {
|
||||
<script id="bank_app" version=0.5>
|
||||
const bank_app = {
|
||||
|
||||
launchApp: function(reqCallback, resCallback){
|
||||
launchApp: function(reqCallback, resCallback) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let models = ["I_b", "I_s"];
|
||||
models.forEach(m => this.model[m] = this.exParser(floGlobals.settings[m]));
|
||||
for (let x in floGlobals.settings)
|
||||
if (x.startsWith("constant-"))
|
||||
this.constants[x.substring("constant-".length)] = floGlobals.settings[x]
|
||||
let data = ["requests", "responses", "appendix"];
|
||||
Promise.all(data.map(d => readAllData(o))).then(results => {
|
||||
for(let i in results)
|
||||
Promise.all(data.map(d => compactIDB.readAllData(o))).then(results => {
|
||||
for (let i in results)
|
||||
this[data[i]] = results[i];
|
||||
this.refreshData(true).then(result => {
|
||||
setInterval(this.refreshData, this.util.refreshTime);
|
||||
setInterval(() => this.refreshData(), this.util.refreshTime);
|
||||
this.readDataFromCloud(myFloID === floGlobals.adminID, reqCallback, resCallback)
|
||||
.then(result => resolve(result))
|
||||
.catch(error => reject(error))
|
||||
@ -9340,26 +9398,36 @@ Bitcoin.Util = {
|
||||
myIndex: 0,
|
||||
lastUpdate: null,
|
||||
secInYr: new Decimal(31556952000),
|
||||
refreshTime: 5 * 60000, //min*millisec
|
||||
istr: floGlobals.application + '::'
|
||||
},
|
||||
|
||||
model: {},
|
||||
constants: {},
|
||||
accMap: {},
|
||||
accounts: [],
|
||||
rates: {},
|
||||
|
||||
refreshData: function(reset = false) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.readDataFromBlockchain().then(result => {
|
||||
if (reset) {
|
||||
compactIDB.readAllData('accounts').then(accounts => {
|
||||
console.info(this)
|
||||
this.util.lastUpdate = null;
|
||||
this.accMap = {};
|
||||
this.accounts = [];
|
||||
this.rates = {};
|
||||
for (let a in accounts)
|
||||
parseAccount(a);
|
||||
this.updateAccountNetValues();
|
||||
resolve("Data Refreshed");
|
||||
}).catch(error => reject(error))
|
||||
} else {
|
||||
try {
|
||||
for (let a in result)
|
||||
parseAccount(a);
|
||||
this.updateAccountNetValues();
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
this.refreshData(true)
|
||||
@ -9380,12 +9448,13 @@ Bitcoin.Util = {
|
||||
for (let y in d[x].message)
|
||||
r[x][y] = d[x].message[y];
|
||||
r[x].floID = d[x].sender;
|
||||
r[x].status = "pending";
|
||||
this.requests[x] = r[x];
|
||||
compactIDB.addData("requests", r[x], x);
|
||||
}
|
||||
this.appendix.lastRequest = Object.keys(this.requests).sort().pop();
|
||||
compactIDB.writeData("appendix", this.appendix.lastRequest, "lastRequest");
|
||||
if(reqCallback instanceof Function)
|
||||
if (reqCallback instanceof Function)
|
||||
reqCallback(r, e);
|
||||
}
|
||||
if (isAdmin)
|
||||
@ -9412,12 +9481,12 @@ Bitcoin.Util = {
|
||||
r[x] = {}
|
||||
for (let y in d[x].message)
|
||||
r[x][y] = d[x].message[y];
|
||||
this.response[x] = r[x];
|
||||
this.responses[x] = r[x];
|
||||
compactIDB.addData("responses", r[x], x);
|
||||
}
|
||||
this.appendix.lastResponse = Object.keys(this.response).sort().pop();
|
||||
this.appendix.lastResponse = Object.keys(this.responses).sort().pop();
|
||||
compactIDB.writeData("appendix", this.appendix.lastResponse, "lastResponse");
|
||||
if(resCallback instanceof Function)
|
||||
if (resCallback instanceof Function)
|
||||
resCallback(r, e);
|
||||
}
|
||||
});
|
||||
@ -9427,26 +9496,26 @@ Bitcoin.Util = {
|
||||
|
||||
readDataFromBlockchain: function() {
|
||||
return new Promise((resolve, reject) => {
|
||||
let options = {
|
||||
sentOnly: true,
|
||||
ignoreOld: this.appendix.lastTx,
|
||||
filter: d => d.startsWith(this.util.istr)
|
||||
}
|
||||
floBlockchainAPI.readData(floGlobals.adminID, options).then(result => {
|
||||
let accounts = {},
|
||||
promises = [];
|
||||
result.data.forEach(d => {
|
||||
let data = d.substring(this.util.istr.length).split('|');
|
||||
accounts[data[1]] = data;
|
||||
promises.push(compactIDB.addData('accounts', data, data[1]))
|
||||
});
|
||||
Promise.all(promises).then(result => {
|
||||
this.appendix.lastTx = result.totalTxs
|
||||
compactIDB.writeData('appendix', result.totalTxs, lastTx)
|
||||
.then(result => resolve(accounts))
|
||||
.catch(error => reject(error))
|
||||
}).catch(error => reject(error))
|
||||
let options = {
|
||||
sentOnly: true,
|
||||
ignoreOld: this.appendix.lastTx,
|
||||
filter: d => d.startsWith(this.util.istr)
|
||||
}
|
||||
floBlockchainAPI.readData(floGlobals.adminID, options).then(result => {
|
||||
let accounts = {},
|
||||
promises = [];
|
||||
result.data.forEach(d => {
|
||||
let data = d.substring(this.util.istr.length).split('|');
|
||||
accounts[data[1]] = data;
|
||||
promises.push(compactIDB.addData('accounts', data, data[1]))
|
||||
});
|
||||
Promise.all(promises).then(results => {
|
||||
this.appendix.lastTx = result.totalTxs
|
||||
compactIDB.writeData('appendix', result.totalTxs, "lastTx")
|
||||
.then(result => resolve(accounts))
|
||||
.catch(error => reject(error))
|
||||
}).catch(error => reject(error))
|
||||
}).catch(error => reject(error))
|
||||
})
|
||||
|
||||
},
|
||||
@ -9454,7 +9523,7 @@ Bitcoin.Util = {
|
||||
parseAccount: function(data) {
|
||||
switch (data[0]) {
|
||||
case "open-deposit":
|
||||
if (floCrypto.verifySign(`open#${data[3]}:deposit${data[4]}|${data[7]}`, data[6], data[5]))
|
||||
if (floCrypto.verifySign(this.istr + `open#${data[3]}:deposit${data[4]}|${data[7]}`, data[6], data[5]))
|
||||
this.addAccount(data[2], {
|
||||
floID: data[2],
|
||||
type: "deposit",
|
||||
@ -9465,11 +9534,11 @@ Bitcoin.Util = {
|
||||
}, data[1]);
|
||||
break;
|
||||
case "close-deposit":
|
||||
if (floCrypto.verifySign(`close-deposit#${data[3]}`, data[5], data[4]))
|
||||
if (floCrypto.verifySign(this.istr + `close-deposit#${data[3]}`, data[5], data[4]))
|
||||
this.closeAccount(data[2], data[3], data[1]);
|
||||
break;
|
||||
case "open-loan":
|
||||
if (floCrypto.verifySign(`open#${data[3]}:deposit${data[4]}|${data[7]}`, data[6], data[5]))
|
||||
if (floCrypto.verifySign(this.istr + `open#${data[3]}:loan${data[4]}`, data[6], data[5]))
|
||||
this.addAccount(data[2], {
|
||||
floID: data[2],
|
||||
type: "loan",
|
||||
@ -9480,7 +9549,7 @@ Bitcoin.Util = {
|
||||
}, data[1]);
|
||||
break;
|
||||
case "close-loan":
|
||||
if (floCrypto.verifySign(`close-loan#${data[3]}:${data[6]}`, data[5], data[4]))
|
||||
if (floCrypto.verifySign(this.istr + `close-loan#${data[3]}:${data[6]}`, data[5], data[4]))
|
||||
this.closeAccount(data[2], data[3], data[1]);
|
||||
break;
|
||||
}
|
||||
@ -9526,14 +9595,32 @@ Bitcoin.Util = {
|
||||
resolve(response)
|
||||
}).catch(error => reject(error))
|
||||
})
|
||||
},
|
||||
validateToken: function(tx, sender, receiver, amount = null, token = floGlobals.token) {
|
||||
return ((!sender || tx.sender === sender) &&
|
||||
(!receiver || tx.receiver === receiver) &&
|
||||
(amount === null || tx.amount === amount) &&
|
||||
(token === tx.token));
|
||||
},
|
||||
verifyToken: function(txid, sender, receiver, amount = null, token = floGlobals.token) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.getTx(tx).then(txn => {
|
||||
if (sender && txn.sender != sender)
|
||||
reject("Incorrect sender");
|
||||
else if (receiver && txn.receiver != receiver)
|
||||
reject("Incorrect receiver");
|
||||
else if (amount && txn.amount != amount)
|
||||
reject("Incorrect amount");
|
||||
else if (token != txn.token)
|
||||
reject("Incorrect token")
|
||||
else
|
||||
resolve(txn)
|
||||
}).catch(error => reject(error))
|
||||
})
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
accMap: {},
|
||||
accounts: [],
|
||||
rates: {},
|
||||
|
||||
addAccount: function(floID, account, time) {
|
||||
this.updateAccountNetValues(time);
|
||||
account.netAmt = account.amount;
|
||||
@ -9694,10 +9781,8 @@ Bitcoin.Util = {
|
||||
return accounts[mappedIndex];
|
||||
},
|
||||
|
||||
parser(expression) {
|
||||
console.info(expression)
|
||||
exParser(expression) {
|
||||
let infix = expression.replace(/\s/g, "").split(""); //tokenize
|
||||
console.info(infix)
|
||||
const p = ["-", "+", "*", "/", "^"]; //presedences order (low to high)
|
||||
var opStack = [],
|
||||
postfix = [];
|
||||
@ -9742,7 +9827,6 @@ Bitcoin.Util = {
|
||||
postfix.push(opStack.pop());
|
||||
else
|
||||
throw Error("Invalid expression: unpaired bracket");
|
||||
console.info(postfix)
|
||||
return postfix
|
||||
},
|
||||
|
||||
@ -9763,7 +9847,6 @@ Bitcoin.Util = {
|
||||
}
|
||||
}
|
||||
for (let token of model) {
|
||||
console.info(token)
|
||||
if (/^[\w.]+$/.test(token))
|
||||
result.push(token)
|
||||
else {
|
||||
@ -9787,7 +9870,6 @@ Bitcoin.Util = {
|
||||
},
|
||||
|
||||
makeDeposit: function(amount) {
|
||||
this.updateAccountNetValues()
|
||||
return new Promise(async (resolve, reject) => {
|
||||
try {
|
||||
let index = this.util.myIndex + 1
|
||||
@ -9795,13 +9877,15 @@ Bitcoin.Util = {
|
||||
let bal = await this.tokenAPI.getBalance(myFloID)
|
||||
if (bal < amount)
|
||||
throw Error('Insufficiant balance')
|
||||
//refresh data and update the account net values
|
||||
await this.refreshData();
|
||||
//send token to banker floID (using floBlockchain API)
|
||||
let txid = await floBlockchainAPI.writeData(myFloID, `send ${amount} ${floGlobals.token}# for open-deposit`, myPrivKey, floGlobals.adminID)
|
||||
let request = {
|
||||
rtype: "openDeposit",
|
||||
amount: amount,
|
||||
txid: txid,
|
||||
sign: floCrypto.signData(`open#${index}:deposit${amount}|${txid}`)
|
||||
sign: floCrypto.signData(this.istr + `open#${index}:deposit${amount}|${txid}`)
|
||||
}
|
||||
//send request to banker (floCloudAPI)
|
||||
floCloudAPI.sendApplicationData(request, "REQUEST")
|
||||
@ -9815,35 +9899,39 @@ Bitcoin.Util = {
|
||||
},
|
||||
|
||||
verifyDeposit: function(reqID) {
|
||||
this.updateAccountNetValues()
|
||||
return new Promise(async (resolve, reject) => {
|
||||
let req = this.requests[reqID];
|
||||
try {
|
||||
//verify the token tx
|
||||
let req = this.getRequest(reqID)
|
||||
if (req.rtype !== "openDeposit")
|
||||
throw Error('Invalid request: Request-type is not openDeposit')
|
||||
if (req.status !== "pending")
|
||||
throw Error("Request already processed");
|
||||
let tx = await this.tokenAPI.getTx(req.txid);
|
||||
if (tx.amount !== req.amount)
|
||||
throw Error("R>Invalid deposit: Token amount doesnot match")
|
||||
if (!this.tokenAPI.validateToken(tx, req.floID, floGlobals.adminID, req.amount))
|
||||
throw Error("R>Invalid deposit: Invalid token transaction");
|
||||
//verify the signature
|
||||
if (req.index != this.accMap[req.floID].length)
|
||||
throw Error(`R>Invalid index (correct index is ${this.accMap[req.floID].length})`);
|
||||
if (!floCrypto.verifySign(`open#${req.index}:deposit${req.amount}|${req.txid}`, req.sign, req.pubKey))
|
||||
throw Error("R>Invalid deposit signature: Re-signing required")
|
||||
if (!floCrypto.verifySign(this.istr + `open#${req.index}:deposit${req.amount}|${req.txid}`, req.sign, req.pubKey))
|
||||
throw Error("R>Invalid signature: Re-signing required")
|
||||
await this.refreshData()
|
||||
let timestamp = this.util.lastUpdate;
|
||||
//write deposit details in blockchain
|
||||
let data = ["open-deposit", tx.timestamp, req.floID, req.index, req.amount, req.pubKey, req.sign, req.txid].join('|')
|
||||
let txid = floBlockchainAPI.writeData(myFloID, data, myPrivKey, floGlobals.adminID)
|
||||
let data = ["open-deposit", timestamp, req.floID, req.index, req.amount, req.pubKey, req.sign, req.txid].join('|')
|
||||
let txid = floBlockchainAPI.writeData(myFloID, this.util.istr + data, myPrivKey, floGlobals.adminID)
|
||||
let response = {
|
||||
requestID: reqID,
|
||||
rtype: "openDeposit",
|
||||
status: "success",
|
||||
txid: txid
|
||||
}
|
||||
req.status = "completed";
|
||||
compactIDB.writeData("requests", req, reqID);
|
||||
//send response to client
|
||||
floCloudAPI.sendApplicationData(response, "RESPONSE", {
|
||||
receiverID: clientID
|
||||
})
|
||||
.then(result => resolve(response))
|
||||
}).then(result => resolve(response))
|
||||
.catch(error => reject(error))
|
||||
|
||||
} catch (error) {
|
||||
@ -9856,11 +9944,12 @@ Bitcoin.Util = {
|
||||
status: "failed",
|
||||
reason: error.message.substring(2)
|
||||
}
|
||||
req.status = `failed (${response.reason})`;
|
||||
compactIDB.writeData("requests", req, reqID);
|
||||
//send rejected response to client
|
||||
floCloudAPI.sendApplicationData(response, "RESPONSE", {
|
||||
receiverID: clientID
|
||||
})
|
||||
.then(result => resolve(response))
|
||||
}).then(result => resolve(response))
|
||||
.catch(error => reject(error))
|
||||
}
|
||||
}
|
||||
@ -9868,7 +9957,6 @@ Bitcoin.Util = {
|
||||
},
|
||||
|
||||
withdrawDeposit: function(index) {
|
||||
this.updateAccountNetValues()
|
||||
return new Promise(async (resolve, reject) => {
|
||||
try {
|
||||
//check for validity (ie no loans outstanding)
|
||||
@ -9880,10 +9968,11 @@ Bitcoin.Util = {
|
||||
throw Error(`Account#${index} is not active`)
|
||||
if (details.netTotal < acc.netAmt)
|
||||
throw Error(`Unable to withdraw deposit: Loan amount exceeds`)
|
||||
await this.refreshData()
|
||||
let request = {
|
||||
rtype: "closeDeposit",
|
||||
index: index,
|
||||
sign: floCrypto.signData(`close-deposit#${index}`, myPrivKey)
|
||||
sign: floCrypto.signData(this.istr + `close-deposit#${index}`, myPrivKey)
|
||||
}
|
||||
//send request to banker
|
||||
floCloudAPI.sendApplicationData(request, "REQUEST")
|
||||
@ -9896,12 +9985,15 @@ Bitcoin.Util = {
|
||||
},
|
||||
|
||||
closeDeposit: function(reqID) {
|
||||
this.updateAccountNetValues()
|
||||
return new Promise(async (resolve, reject) => {
|
||||
let req = this.requests[reqID];
|
||||
try {
|
||||
let req = this.getRequest(reqID)
|
||||
await this.refreshData()
|
||||
let timestamp = this.util.lastUpdate;
|
||||
if (req.rtype !== "closeDeposit")
|
||||
throw Error('Invalid request: Request-type is not closeDeposit')
|
||||
if (req.status !== "pending")
|
||||
throw Error("Request already processed");
|
||||
//check for validity (ie no loans outstanding)
|
||||
let details = this.getUserDetails(req.floID)
|
||||
let acc = details.accounts[req.index]
|
||||
@ -9912,17 +10004,17 @@ Bitcoin.Util = {
|
||||
if (details.netTotal < acc.netAmt)
|
||||
throw Error(`R>Unable to close deposit: Loan amount exceeds`)
|
||||
//check for signature in request
|
||||
if (floCrypto.verifySign(`close-deposit#${req.index}`, req.sign, req.pubKey))
|
||||
throw Error("R>Invalid deposit signature: Re-signing required")
|
||||
if (floCrypto.verifySign(this.istr + `close-deposit#${req.index}`, req.sign, req.pubKey))
|
||||
throw Error("R>Invalid signature: Re-signing required")
|
||||
//send tokens to user and close loan (via blockchain)
|
||||
let ttxid = await floBlockchainAPI.writeData(myFloID, `send ${acc.netAmt} ${floGlobals.token}# for close-deposit`, myPrivKey, req.floID)
|
||||
//verify token transfer
|
||||
let tx = await this.tokenAPI.getTx(ttxid)
|
||||
if (!valid(tx)) //Condition should be fixed
|
||||
throw Error('Token not valid')
|
||||
if (!this.tokenAPI.validateToken(tx, floGlobals.adminID, req.floID, acc.netAmt))
|
||||
throw Error('Token not valid');
|
||||
//write close-deposit in blockchain
|
||||
let data = ["close-deposit", timestamp, clientID, req.index, req.pubKey, req.sign, ttxid].join('|')
|
||||
let btxid = await floBlockchainAPI.writeData(myFloID, data, myPrivKey, floGlobals.adminID)
|
||||
let data = ["close-deposit", timestamp, req.floID, req.index, req.pubKey, req.sign, ttxid].join('|')
|
||||
let btxid = await floBlockchainAPI.writeData(myFloID, this.util.istr + data, myPrivKey, floGlobals.adminID)
|
||||
//send response to client
|
||||
let response = {
|
||||
requestID: reqID,
|
||||
@ -9931,6 +10023,8 @@ Bitcoin.Util = {
|
||||
token: ttxid,
|
||||
txid: btxid
|
||||
}
|
||||
req.status = "completed";
|
||||
compactIDB.writeData("requests", req, reqID);
|
||||
floCloudAPI.sendApplicationData(response, "RESPONSE", {
|
||||
receiverID: clientID
|
||||
}).then(result => resolve(response))
|
||||
@ -9945,6 +10039,8 @@ Bitcoin.Util = {
|
||||
status: "failed",
|
||||
reason: error.message.substring(2)
|
||||
}
|
||||
req.status = `failed (${response.reason})`;
|
||||
compactIDB.writeData("requests", req, reqID);
|
||||
//send rejected response to client
|
||||
floCloudAPI.sendApplicationData(response, "RESPONSE", {
|
||||
receiverID: clientID
|
||||
@ -9956,8 +10052,8 @@ Bitcoin.Util = {
|
||||
},
|
||||
|
||||
requestLoan: function(amount) {
|
||||
this.updateAccountNetValues()
|
||||
return new Promise((resolve, reject) => {
|
||||
await this.refreshData()
|
||||
let index = this.util.myIndex + 1;
|
||||
//check for validity of loan (ie, check if enough deposit is present)
|
||||
let user = this.getUserDetails(myFloID)
|
||||
@ -9967,7 +10063,7 @@ Bitcoin.Util = {
|
||||
rtype: "openLoan",
|
||||
index: index,
|
||||
amount: amount,
|
||||
sign: floCrypto.signData(`open#${index}:loan${amount}`, myPrivKey)
|
||||
sign: floCrypto.signData(this.istr + `open#${index}:loan${amount}`, myPrivKey)
|
||||
}
|
||||
//send request to banker
|
||||
floCloudAPI.sendApplicationData(request, "REQUEST")
|
||||
@ -9977,29 +10073,32 @@ Bitcoin.Util = {
|
||||
},
|
||||
|
||||
sendLoan: function(reqID) {
|
||||
this.updateAccountNetValues()
|
||||
return new Promise(async (resolve, reject) => {
|
||||
let req = this.requests[reqID];
|
||||
try {
|
||||
let req = this.getRequest(reqID);
|
||||
await this.refreshData()
|
||||
let timestamp = this.util.lastUpdate;
|
||||
if (req.rtype !== "openLoan")
|
||||
throw Error('Invalid request: Request-type is not openLoan');
|
||||
if (req.status !== "pending")
|
||||
throw Error("Request already processed");
|
||||
//verify the signature
|
||||
if (req.index != this.accMap[req.floID].length)
|
||||
throw Error(`R>Invalid index (correct index is ${this.accMap[req.floID].length})`);
|
||||
if (!floCrypto.verifySign(`open#${req.index}:loan${req.amount}`, req.sign, req.pubKey))
|
||||
throw Error("R>Invalid deposit signature: Re-signing required");
|
||||
if (!floCrypto.verifySign(this.istr + `open#${req.index}:loan${req.amount}`, req.sign, req.pubKey))
|
||||
throw Error("R>Invalid signature: Re-signing required");
|
||||
//check for validity of loan (ie, check if enough deposit is present)
|
||||
let user = this.getUserDetails(req.floID)
|
||||
if (user.netTotal <= amount)
|
||||
return reject("Deposit insufficient");
|
||||
if (user.netTotal <= req.amount)
|
||||
return reject("R>Deposit insufficient");
|
||||
//send token to user
|
||||
ttxid = await floBlockchainAPI.writeData(myFloID, `send ${amount} ${floGlobals.token}# for open-loan`, myPrivKey, clientID);
|
||||
ttxid = await floBlockchainAPI.writeData(myFloID, `send ${req.amount} ${floGlobals.token}# for open-loan`, myPrivKey, clientID);
|
||||
//verify token transfer
|
||||
let tx = await this.tokenAPI.getTx(ttxid)
|
||||
if (!valid(tx)) //Condition should be fixed
|
||||
if (!this.tokenAPI.validateToken(tx, floGlobals.adminID, req.floID, req.amount))
|
||||
throw Error('Token not valid');
|
||||
let data = ["open-loan", timestamp, clientID, sign, ttxid].join('|')
|
||||
let btxid = await floBlockchainAPI.writeData(myFloID, data, myPrivKey, floGlobals.adminID)
|
||||
let data = ["open-loan", timestamp, req.floID, req.index, req.amount, req.pubKey, req.sign, ttxid].join('|')
|
||||
let btxid = await floBlockchainAPI.writeData(myFloID, this.util.istr + data, myPrivKey, floGlobals.adminID)
|
||||
let response = {
|
||||
requestID: reqID,
|
||||
rtype: "openLoan",
|
||||
@ -10007,6 +10106,8 @@ Bitcoin.Util = {
|
||||
token: ttxid,
|
||||
txid: btxid
|
||||
}
|
||||
req.status = "completed";
|
||||
compactIDB.writeData("requests", req, reqID);
|
||||
floCloudAPI.sendApplicationData(response, "RESPONSE", {
|
||||
receiverID: clientID
|
||||
}).then(result => resolve(result))
|
||||
@ -10021,6 +10122,8 @@ Bitcoin.Util = {
|
||||
status: "failed",
|
||||
reason: error.message.substring(2)
|
||||
}
|
||||
req.status = `failed (${response.reason})`;
|
||||
compactIDB.writeData("requests", req, reqID);
|
||||
//send rejected response to client
|
||||
floCloudAPI.sendApplicationData(response, "RESPONSE", {
|
||||
receiverID: clientID
|
||||
@ -10032,9 +10135,9 @@ Bitcoin.Util = {
|
||||
},
|
||||
|
||||
repayLoan: function(index) {
|
||||
this.updateAccountNetValues()
|
||||
return new Promise((resolve, reject) => {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
try {
|
||||
this.refreshData();
|
||||
let details = this.getUserDetails(myFloID)
|
||||
let acc = details.accounts[index]
|
||||
if (acc.type !== "loan")
|
||||
@ -10051,7 +10154,7 @@ Bitcoin.Util = {
|
||||
rtype: "closeLoan",
|
||||
index: index,
|
||||
txid: txid,
|
||||
sign: floCrypto.signData(`close-loan#${index}:${txid}`)
|
||||
sign: floCrypto.signData(this.istr + `close-loan#${index}:${txid}`)
|
||||
}
|
||||
floCloudAPI.sendApplicationData(request, "REQUEST")
|
||||
.then(result => resolve(result))
|
||||
@ -10063,26 +10166,38 @@ Bitcoin.Util = {
|
||||
},
|
||||
|
||||
closeLoan: function(reqID) {
|
||||
this.updateAccountNetValues()
|
||||
return new Promise(async (resolve, reject) => {
|
||||
let req = this.requests[reqID];
|
||||
try {
|
||||
//verify token tx
|
||||
let req = this.getRequest(reqID)
|
||||
if (req.rtype !== "closeLoan")
|
||||
throw Error('Invalid request: Request-type is not closeLoan')
|
||||
throw Error('Invalid request: Request-type is not closeLoan');
|
||||
if (req.status !== "pending")
|
||||
throw Error("Request already processed");
|
||||
//verify signature
|
||||
if (!floCrypto.verifySign(this.istr + `close-loan#${req.index}:${req.txid}`, req.sign, req.pubKey))
|
||||
throw Error("R>Invalid signature: Re-signing required");
|
||||
//verify token tx
|
||||
let tx = await this.tokenAPI.getTx(req.txid);
|
||||
await this.refreshData()
|
||||
let acc = this.getAccount(req.floID, req.index);
|
||||
if (tx.amount !== acc.netAmt)
|
||||
throw Error("R>Invalid request: Token amount insufficient")
|
||||
if (acc.status !== "active")
|
||||
throw Error("Account already closed");
|
||||
if (tx.amount < acc.netAmt)
|
||||
throw Error("R>Invalid request: Token amount insufficient");
|
||||
if (!this.tokenAPI.validateToken(tx, req.floID, floGlobals.adminID))
|
||||
throw Error("R>Invalid request: Invalid token transaction")
|
||||
let timestamp = this.util.lastUpdate;
|
||||
//close loan via blockchain
|
||||
let data = ["close-loan", timestamp, req.floID, req.index, req.pubKey, req, sign, req.txid].join('|')
|
||||
txid = await floBlockchainAPI.writeData(myFloID, data, myPrivKey, floGlobals.adminID)
|
||||
txid = await floBlockchainAPI.writeData(myFloID, this.util.istr + data, myPrivKey, floGlobals.adminID)
|
||||
let response = {
|
||||
requestID: reqID,
|
||||
rtype: "closeLoan",
|
||||
status: "success",
|
||||
txid: txid
|
||||
}
|
||||
req.status = "completed";
|
||||
compactIDB.writeData("requests", req, reqID);
|
||||
floCloudAPI.sendApplicationData(response, "RESPONSE", {
|
||||
receiverID: clientID
|
||||
}).then(result => resolve(result))
|
||||
@ -10097,6 +10212,8 @@ Bitcoin.Util = {
|
||||
status: "failed",
|
||||
reason: error.message.substring(2)
|
||||
}
|
||||
req.status = `failed (${response.reason})`;
|
||||
compactIDB.writeData("requests", req, reqID);
|
||||
//send rejected response to client
|
||||
floCloudAPI.sendApplicationData(response, "RESPONSE", {
|
||||
receiverID: clientID
|
||||
@ -10105,6 +10222,22 @@ Bitcoin.Util = {
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
viewAllRequests: function(floID = null) {
|
||||
let requests = this.requests
|
||||
if (floID) {
|
||||
let result = {}
|
||||
for (let r in requests)
|
||||
if (requests[r].floID === floID)
|
||||
result[r] = requests[r];
|
||||
return result;
|
||||
} else
|
||||
return requests;
|
||||
},
|
||||
|
||||
viewAllResponses: function() {
|
||||
return this.responses;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user