diff --git a/public/fn.js b/public/fn.js index 07447c2..1781b72 100644 --- a/public/fn.js +++ b/public/fn.js @@ -1,5 +1,54 @@ //console.log(document.cookie.toString()); +const tokenAPI = { + fetch_api: function(apicall) { + return new Promise((resolve, reject) => { + console.log(floGlobals.tokenURL + apicall); + fetch(floGlobals.tokenURL + apicall).then(response => { + if (response.ok) + response.json().then(data => resolve(data)); + else + reject(response) + }).catch(error => reject(error)) + }) + }, + getBalance: function(floID, token = 'rupee') { + return new Promise((resolve, reject) => { + this.fetch_api(`api/v1.0/getFloAddressBalance?token=${token}&floAddress=${floID}`) + .then(result => resolve(result.balance || 0)) + .catch(error => reject(error)) + }) + }, + getTx: function(txID) { + return new Promise((resolve, reject) => { + this.fetch_api(`api/v1.0/getTransactionDetails/${txID}`).then(res => { + if (res.result === "error") + reject(res.description); + else if (!res.parsedFloData) + reject("Data piece (parsedFloData) missing"); + else if (!res.transactionDetails) + reject("Data piece (transactionDetails) missing"); + else + resolve(res); + }).catch(error => reject(error)) + }) + }, + sendToken: function(privKey, amount, message = "", receiverID = floGlobals.adminID, token = 'rupee') { + return new Promise((resolve, reject) => { + let senderID = floCrypto.getFloID(privKey); + if (typeof amount !== "number" || amount <= 0) + return reject("Invalid amount"); + this.getBalance(senderID, token).then(bal => { + if (amount > bal) + return reject("Insufficiant token balance"); + floBlockchainAPI.writeData(senderID, `send ${amount} ${token}# ${message}`, privKey, receiverID) + .then(txid => resolve(txid)) + .catch(error => reject(error)) + }).catch(error => reject(error)) + }); + } +} + function ResponseError(status, data) { if (this instanceof ResponseError) { this.data = data; @@ -65,47 +114,64 @@ function getTransactionList() { }); } +function signRequest(request, privKey) { + if (typeof request !== "object") + throw Error("Request is not an object"); + let req_str = Object.keys(request).sort().map(r => r + ":" + request[r]).join("|"); + return floCrypto.signData(req_str, privKey); +} + function signUp(privKey, sid) { return new Promise((resolve, reject) => { - let pubKey = floCrypto.getPubKeyHex(privKey); - let floID = floCrypto.getFloID(pubKey); - let sign = floCrypto.signData(sid, privKey); - console.log(privKey, pubKey, floID, sid) + let request = { + pubKey: floCrypto.getPubKeyHex(privKey), + floID: floCrypto.getFloID(privKey), + timestamp: Date.now() + }; + request.sign = signRequest({ + type: "create_account", + random: sid, + timestamp: request.timestamp + }, privKey); + console.debug(request); + fetch("/signup", { method: "POST", headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ - floID, - pubKey, - sign - }) + body: JSON.stringify(request) }).then(result => responseParse(result, false) .then(result => resolve(result)) .catch(error => reject(error))) .catch(error => reject(error)); - }) - + }); } -function login(privKey, sid, rememberMe = false) { +function login(privKey, proxyKey, sid, rememberMe = false) { return new Promise((resolve, reject) => { - let pubKey = floCrypto.getPubKeyHex(privKey); - let floID = floCrypto.getFloID(pubKey); - if (!floID || !floCrypto.verifyPrivKey(privKey, floID)) + let request = { + proxyKey: proxyKey, + floID: floCrypto.getFloID(privKey), + timestamp: Date.now(), + saveSession: rememberMe + }; + if (!privKey || !request.floID) return reject("Invalid Private key"); - let sign = floCrypto.signData(sid, privKey); + request.sign = signRequest({ + type: "login", + random: sid, + proxyKey: request.proxyKey, + timestamp: request.timestamp + }, privKey); + console.debug(request); + fetch("/login", { method: "POST", headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ - floID, - sign, - saveSession: rememberMe - }) + body: JSON.stringify(request) }).then(result => responseParse(result, false) .then(result => resolve(result)) .catch(error => reject(error))) @@ -123,21 +189,31 @@ function logout() { }) } -function buy(quantity, max_price) { +function buy(quantity, max_price, proxySecret) { return new Promise((resolve, reject) => { if (typeof quantity !== "number" || quantity <= 0) return reject(`Invalid quantity (${quantity})`); else if (typeof max_price !== "number" || max_price <= 0) return reject(`Invalid max_price (${max_price})`); + let request = { + quantity: quantity, + max_price: max_price, + timestamp: Date.now() + }; + request.sign = signRequest({ + type: "buy_order", + quantity: quantity, + max_price: max_price, + timestamp: request.timestamp + }, proxySecret); + console.debug(request); + fetch('/buy', { method: "POST", headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ - quantity, - max_price - }) + body: JSON.stringify(request) }).then(result => responseParse(result, false) .then(result => resolve(result)) .catch(error => reject(error))) @@ -146,21 +222,31 @@ function buy(quantity, max_price) { } -function sell(quantity, min_price) { +function sell(quantity, min_price, proxySecret) { return new Promise((resolve, reject) => { if (typeof quantity !== "number" || quantity <= 0) return reject(`Invalid quantity (${quantity})`); else if (typeof min_price !== "number" || min_price <= 0) return reject(`Invalid min_price (${min_price})`); + let request = { + quantity: quantity, + min_price: min_price, + timestamp: Date.now() + }; + request.sign = signRequest({ + type: "sell_order", + quantity: quantity, + min_price: min_price, + timestamp: request.timestamp + }, proxySecret); + console.debug(request); + fetch('/sell', { method: "POST", headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ - quantity, - min_price - }) + body: JSON.stringify(request) }).then(result => responseParse(result, false) .then(result => resolve(result)) .catch(error => reject(error))) @@ -169,19 +255,145 @@ function sell(quantity, min_price) { } -function cancelOrder(type, id) { +function cancelOrder(type, id, proxySecret) { return new Promise((resolve, reject) => { if (type !== "buy" && type !== "sell") return reject(`Invalid type (${type}): type should be sell (or) buy`); + let request = { + orderType: type, + orderID: id, + timestamp: Date.now() + }; + request.sign = signRequest({ + type: "cancel_order", + order: type, + id: id, + timestamp: data.timestamp + }, proxySecret); + console.debug(request); + fetch('/cancel', { method: "POST", headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ - orderType: type, - orderID: id - }) + body: JSON.stringify(request) + }).then(result => responseParse(result, false) + .then(result => resolve(result)) + .catch(error => reject(error))) + .catch(error => reject(error)) + }) +} + +function depositFLO(quantity, userID, privKey, proxySecret) { + return new Promise((resolve, reject) => { + if (typeof quantity !== "number" || quantity <= floGlobals.fee) + return reject(`Invalid quantity (${quantity})`); + floBlockchainAPI.sendTx(userID, floGlobals.adminID, quantity, privKey, 'Deposit FLO in market').then(result => { + if (!result.txid || !result.txid.result || result.txid.error) + return reject(result); + let request = { + txid: result.txid.result, + timestamp: Date.now() + }; + request.sign = signRequest({ + type: "deposit_FLO", + txid: request.txid, + timestamp: request.timestamp + }, proxySecret); + console.debug(request); + + fetch('/deposit-flo', { + method: "POST", + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify(request) + }).then(result => responseParse(result, false) + .then(result => resolve(result)) + .catch(error => reject(error))) + .catch(error => reject(error)) + }).catch(error => reject(error)) + }) +} + +function withdrawFLO(quantity, proxySecret) { + return new Promise((resolve, reject) => { + let request = { + amount: quantity, + timestamp: Date.now() + }; + request.sign = signRequest({ + type: "withdraw_FLO", + amount: request.amount, + timestamp: request.timestamp + }, proxySecret); + console.debug(request); + + fetch('/withdraw-flo', { + method: "POST", + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify(request) + }).then(result => responseParse(result, false) + .then(result => resolve(result)) + .catch(error => reject(error))) + .catch(error => reject(error)) + }) +} + +function depositRupee(quantity, userID, privKey, proxySecret) { + return new Promise((resolve, reject) => { + if (!floGlobals.verifyPrivKey(privKey, userID)) + return reject("Invalid Private Key"); + tokenAPI.sendToken(privKey, quantity, 'Deposit Rupee in market').then(result => { + if (!result.txid || !result.txid.result || result.txid.error) + return reject(result); + let request = { + txid: result.txid.result, + timestamp: Date.now() + }; + request.sign = signRequest({ + type: "deposit_Rupee", + txid: request.txid, + timestamp: request.timestamp + }, proxySecret); + console.debug(request); + + fetch('/deposit-rupee', { + method: "POST", + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify(request) + }).then(result => responseParse(result, false) + .then(result => resolve(result)) + .catch(error => reject(error))) + .catch(error => reject(error)) + }).catch(error => reject(error)) + }) +} + +function withdrawRupee(quantity, proxySecret) { + return new Promise((resolve, reject) => { + let request = { + amount: quantity, + timestamp: Date.now() + }; + request.sign = signRequest({ + type: "withdraw_Rupee", + amount: request.amount, + timestamp: request.timestamp + }, proxySecret); + console.debug(request); + + fetch('/withdraw-rupee', { + method: "POST", + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify(request) }).then(result => responseParse(result, false) .then(result => resolve(result)) .catch(error => reject(error))) diff --git a/public/home.html b/public/home.html index 77d1405..3eb7255 100644 --- a/public/home.html +++ b/public/home.html @@ -44,6 +44,16 @@ +