update/fetch cashier's UPI (and some bug fixes)

- Cashiers can update their UPI where users need to send money for cash-to-token requests
- User fetches the UPI ID of cashier.
- findCashier only returns cashier that is online and has a UPI ID
- Fixed: check valid UPI/token tx not working correctly
- Changed console.info to console.warn for logging blockchain txid
- Fixed: Minor typo bugs  and syntax errors
This commit is contained in:
sairajzero 2022-03-09 00:52:42 +05:30
parent 9858038608
commit fbe1ad3992
4 changed files with 88 additions and 46 deletions

View File

@ -1,5 +1,6 @@
const TYPE_MONEY_REQUEST = "MoneyRequests",
TYPE_CASHIER_REQUEST = "CashierRequests";
TYPE_CASHIER_REQUEST = "CashierRequests",
TYPE_CASHIER_UPI = "CashierUPI";
const cashierUPI = {};
@ -37,24 +38,38 @@ User.init = function() {
callback: UI_RENDER_FN
}));
*/
promises.push(User.getCashierUPI());
Promise.all(promises)
.then(result => resolve(result))
.catch(error => reject(error))
})
}
Object.defineProperty(Cashier, 'cashierRequests', {
User.getCashierUPI = function() {
return new Promise((resolve) => {
Promise.allSettled(floGlobals.subAdmins.map(cashierID => floCloudAPI.requestApplicationData(TYPE_CASHIER_UPI, {
senderID: cashierID,
mostRecent: true
}))).then(result => {
for (let r of result)
if (r.status === "fulfilled" && r.value.length)
cashierUPI[r.value[0].senderID] = floCloudAPI.util.decodeMessage(r.value[0].message).upi;
resolve(cashierUPI);
})
})
}
Object.defineProperty(User, 'cashierRequests', {
get: function() {
let fk = floCloudAPI.util.filterKey(TYPE_CASHIER_REQUEST, {
senderID: myFloID,
receiverID: cashierID,
group: "Cashiers",
});
return floGlobals.generalData[fk];
}
});
Object.defineProperty(Cashier, 'moneyRequests', {
Object.defineProperty(User, 'moneyRequests', {
get: function() {
let fk = floCloudAPI.util.filterKey(TYPE_MONEY_REQUEST, {
receiverID: myFloID,
@ -66,7 +81,7 @@ Object.defineProperty(Cashier, 'moneyRequests', {
User.findCashier = function() {
let online = [];
for (let c in cashierStatus)
if (cashierStatus[c])
if (cashierStatus[c] && cashierUPI[c])
online.push(c);
if (!online.length)
return null;
@ -76,7 +91,7 @@ User.findCashier = function() {
User.cashToToken = function(cashier, amount, upiTxID) {
return new Promise((resolve, reject) => {
if (!floCloudAPI.subAdmins.includes(cashier))
if (!floGlobals.subAdmins.includes(cashier))
return reject("Invalid cashier");
floCloudAPI.sendGeneralData({
mode: "cash-to-token",
@ -91,7 +106,7 @@ User.cashToToken = function(cashier, amount, upiTxID) {
User.tokenToCash = function(cashier, amount, blkTxID, upiID) {
return new Promise((resolve, reject) => {
if (!floCloudAPI.subAdmins.includes(cashier))
if (!floGlobals.subAdmins.includes(cashier))
return reject("Invalid cashier");
floCloudAPI.sendGeneralData({
mode: "token-to-cash",
@ -138,7 +153,7 @@ const Cashier = {};
Cashier.init = function() {
return new Promise((resolve, reject) => {
let promises;
let promises = [];
//Requests from user to cashier(self) for token-cash exchange
promises.push(floCloudAPI.requestGeneralData(TYPE_CASHIER_REQUEST, {
receiverID: myFloID,
@ -157,11 +172,22 @@ Cashier.init = function() {
})
}
Cashier.updateUPI = function(upi_id) {
return new Promise((resolve, reject) => {
floCloudAPI.sendApplicationData({
upi: upi_id
}, TYPE_CASHIER_UPI)
.then(result => resolve(result))
.catch(error => reject(error))
})
}
Object.defineProperty(Cashier, 'Requests', {
get: function() {
let fk = floCloudAPI.util.filterKey(TYPE_CASHIER_REQUEST, {
receiver: myFloID
receiverID: myFloID
});
console.debug(fk, floGlobals.generalData[fk]);
return floGlobals.generalData[fk];
}
});
@ -192,8 +218,8 @@ Cashier.checkIfUpiTxIsValid = function(upiTxID) {
return new Promise((resolve, reject) => {
let requests = Cashier.Requests;
for (let r in requests)
if (requests[r].message.mode === "cash-to-token")
if (requests[r].note === upiTxID)
if (requests[r].message.mode === "cash-to-token" && requests[r].note)
if (requests[r].message.upi_txid === upiTxID)
return reject([true, "UPI transaction is already used for another request"]);
return resolve(true);
})
@ -203,8 +229,8 @@ Cashier.checkIfTokenTxIsValid = function(tokenTxID, sender, amount) {
return new Promise((resolve, reject) => {
let requests = Cashier.Requests;
for (let r in requests)
if (requests[r].message.mode === "token-to-cash")
if (requests[r].note === tokenTxID)
if (requests[r].message.mode === "token-to-cash" && requests[r].note)
if (requests[r].message.token_txid === tokenTxID)
return reject([true, "Token transaction is already used for another request"]);
tokenAPI.getTx(tokenTxID).then(tx => {
let parsedTxData = tokenAPI.util.parseTxData(tx);

View File

@ -4,7 +4,7 @@ userUI.requestTokenFromCashier = function() {
let cashier = User.findCashier();
if (!cashier)
return alert("No cashier online");
let amount = parseFloat(document.forms['request-cashier'][amount]);
let amount = parseFloat(document.forms['request-cashier']['amount'].value);
//get UPI txid from user
let upiTxID = prompt(`Send Rs. ${amount} to ${cashierUPI[cashier]} and enter UPI txid`);
if (!upiTxID)
@ -19,13 +19,13 @@ userUI.withdrawCashFromCashier = function() {
let cashier = User.findCashier();
if (!cashier)
return alert("No cashier online");
let amount = parseFloat(document.forms['request-cashier'][amount]);
let amount = parseFloat(document.forms['request-cashier']['amount'].value);
//get confirmation from user
let upiID = prompt(`${amount} ${floGlobals.currency}# will be sent to ${cashier}. Enter UPI ID`);
if (!upiID)
return alert("Cancelled");
User.sendToken(cashier, amount, 'for token-to-cash').then(txid => {
console.log("txid", txid);
console.warn(`Withdraw ${amount} from cashier ${cashier}`, txid);
User.tokenToCash(cashier, amount, txid, upiID).then(result => {
console.log(result);
alert("Requested cashier. please wait!");
@ -35,24 +35,24 @@ userUI.withdrawCashFromCashier = function() {
userUI.sendMoneyToUser = function() {
let form = document.forms['user-money'];
let floID = form['flo-id'],
amount = parseFloat(form['amount']),
remark = form['remark'];
let confirmation = prompt(`Do you want to SEND ${amount} to ${floID}?`);
let floID = form['flo-id'].value,
amount = parseFloat(form['amount'].value),
remark = form['remark'].value;
let confirmation = confirm(`Do you want to SEND ${amount} to ${floID}?`);
if (!confirmation)
return alert("Cancelled");
User.sendToken(floID, amount, remark).then(txid => {
console.info(`Sent ${amount} to ${floID}`, txid);
console.warn(`Sent ${amount} to ${floID}`, txid);
alert(`Sent ${amount} to ${floID}. It may take a few mins to reflect in their wallet`);
}).catch(error => console.error(error));
}
userUI.requestMoneyFromUser = function() {
let form = document.forms['user-money'];
let floID = form['flo-id'],
amount = parseFloat(form['amount']),
remark = form['remark'];
let confirmation = prompt(`Do you want to REQUEST ${amount} from ${floID}?`);
let floID = form['flo-id'].value,
amount = parseFloat(form['amount'].value),
remark = form['remark'].value;
let confirmation = confirm(`Do you want to REQUEST ${amount} from ${floID}?`);
if (!confirmation)
return alert("Cancelled");
User.requestToken(floID, amount, remark).then(result => {
@ -64,14 +64,14 @@ userUI.requestMoneyFromUser = function() {
userUI.renderCashierRequests = function(requests, error = null) {
if (error)
return console.error(error);
else if (typeof requests !== "object" || request === null)
else if (typeof requests !== "object" || requests === null)
return;
let table = document.getElementById('user-cashier-requests').getElementsByTagName('tbody')[0];
for (let r in requests) {
let oldCard = document.getElementById(r);
if (oldCard) oldCard.remove();
let row = table.insertRow();
renderUser_cashierRequestCard(request[r], row);
renderUser_cashierRequestCard(requests[r], row);
}
}
@ -80,21 +80,21 @@ function renderUser_cashierRequestCard(request, row) {
row.insertCell().textContent = request.time;
row.insertCell().textContent = request.receiverID;
row.insertCell().textContent = request.message.mode;
let status = request.tag ? (status = request.tag + ":" + request.note) : (request.note || "PENDING");
let status = request.tag ? (request.tag + ":" + request.note) : (request.note || "PENDING");
row.insertCell().textContent = status; //Status
}
userUI.renderMoneyRequests = function(requests, error = null) {
if (error)
return console.error(error);
else if (typeof requests !== "object" || request === null)
else if (typeof requests !== "object" || requests === null)
return;
let table = document.getElementById('user-money-requests').getElementsByTagName('tbody')[0];
for (let r in requests) {
let oldCard = document.getElementById(r);
if (oldCard) oldCard.remove();
let row = table.insertRow();
renderUser_moneyRequestCard(request[r], row);
renderUser_moneyRequestCard(requests[r], row);
}
}
@ -115,11 +115,11 @@ function renderUser_moneyRequestCard(request, row) {
userUI.payRequest = function(reqID) {
let request = User.moneyRequests[reqID];
let confirmation = prompt(`Do you want to SEND ${request.message. amount} to ${request.senderID}?`);
let confirmation = confirm(`Do you want to SEND ${request.message.amount} to ${request.senderID}?`);
if (!confirmation)
return alert("Cancelled");
User.sendToken(request.senderID, request.message.amount, request.message.remark).then(txid => {
console.info(`Sent ${request.message.amount} to ${request.senderID}`, txid);
console.warn(`Sent ${request.message.amount} to ${request.senderID}`, txid);
alert(`Sent ${request.message.amount} to ${request.senderID}. It may take a few mins to reflect in their wallet`);
User.decideRequest(request, 'PAID: ' + txid)
.then(result => console.log(result))
@ -141,14 +141,14 @@ const cashierUI = {};
cashierUI.renderRequests = function(requests, error = null) {
if (error)
return console.error(error);
else if (typeof requests !== "object" || request === null)
else if (typeof requests !== "object" || requests === null)
return;
let table = document.getElementById('cashier-request-list').getElementsByTagName('tbody')[0];
for (let r in requests) {
let oldCard = document.getElementById(r);
if (oldCard) oldCard.remove();
let row = table.insertRow();
renderRequestCard(request[r], row);
renderCashier_requestCard(requests[r], row);
}
}
@ -173,12 +173,12 @@ cashierUI.completeRequest = function(reqID) {
}
function completeCashToTokenRequest(request) {
Cashier.checkIfUpiTxIsValid(request.message.upiTxID).then(_ => {
let confirmation = prompt(`Check if you have received UPI transfer\ntxid:${request.message.upi_txid}\namount:${request.message.amount}`);
Cashier.checkIfUpiTxIsValid(request.message.upi_txid).then(_ => {
let confirmation = confirm(`Check if you have received UPI transfer\ntxid:${request.message.upi_txid}\namount:${request.message.amount}`);
if (!confirmation)
return alert("Cancelled");
User.sendToken(request.senderID, request.message.amount, 'for cash-to-token').then(txid => {
console.log("txid", txid);
console.warn(`${request.message.amount} cash-to-token for ${request.senderID}`, txid);
Cashier.finishRequest(request, txid).then(result => {
console.log(result);
console.info('Completed cash-to-token request:', request.vectorClock);

View File

@ -3,6 +3,13 @@
<head>
<title>RanchiMall Pay</title>
<style>
table,
th,
td {
border: 1px solid black;
}
</style>
<script id="floGlobals">
/* Constants for FLO blockchain operations !!Make sure to add this at begining!! */
const floGlobals = {
@ -56,6 +63,7 @@
userUI.renderMoneyRequests(User.moneyRequests);
User.init().then(result => {
console.log(result);
console.log("Cashiers:", cashierUPI);
document.getElementById('user').hidden = false;
}).catch(error => console.error(error))
}
@ -69,18 +77,24 @@
<div id="user-id"></div>
<div>
<form id="request-cashier">
Amount: <input type="number" name="amount" /><br />
<input type="button" value="request-token" onclick="userUI.requestTokenFromCashier()" />
<input type="button" value="withdraw-cash" onclick="userUI.withdrawCashFromCashier()" />
<fieldset>
<legend>Request Cashier</legend>
Amount: <input type="number" name="amount" /><br />
<input type="button" value="request-token" onclick="userUI.requestTokenFromCashier()" />
<input type="button" value="withdraw-cash" onclick="userUI.withdrawCashFromCashier()" />
</fieldset>
</form>
</div>
<div>
<form id="user-money">
FLO-ID<input type="text" name="flo-id" /><br />
Amount<input type="number" name="amount" /><br />
Remark<input type="text" name="remark" /><br />
<input type="button" value="send-money" onclick="userUI.sendMoneyToUser()" />
<input type="button" value="request-money" onclick="userUI.requestMoneyFromUser()" />
<fieldset>
<legend>Request Users</legend>
FLO-ID: <input type="text" name="flo-id" /><br />
Amount: <input type="number" name="amount" /><br />
Remark: <input type="text" name="remark" /><br />
<input type="button" value="send-money" onclick="userUI.sendMoneyToUser()" />
<input type="button" value="request-money" onclick="userUI.requestMoneyFromUser()" />
</fieldset>
</form>
</div>
<div>
@ -93,6 +107,7 @@
<td>Status</td>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
<div>
@ -106,6 +121,7 @@
<td>Status</td>
</tr>
</thead>
<tbody></tbody>
</table>
</div>

View File

@ -7451,7 +7451,7 @@
result[p] = tx.parsedFloData[p];
result.sender = tx.transactionDetails.vin[0].addr;
for (let vout of tx.transactionDetails.vout)
if (vout.scriptPubKey.addresses[0] !== sender)
if (vout.scriptPubKey.addresses[0] !== result.sender)
result.receiver = vout.scriptPubKey.addresses[0];
return result;
}