From 93960e93172eff9177e41cb1435911be41420a7f Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Mon, 13 Jan 2020 16:03:36 -0400 Subject: [PATCH] onOrders job --- services/gunDB/contact-api/jobs/index.js | 18 ++++ .../{jobs.js => jobs/onAcceptedRequests.js} | 29 ++----- services/gunDB/contact-api/jobs/onOrders.js | 82 +++++++++++++++++++ 3 files changed, 109 insertions(+), 20 deletions(-) create mode 100644 services/gunDB/contact-api/jobs/index.js rename services/gunDB/contact-api/{jobs.js => jobs/onAcceptedRequests.js} (80%) create mode 100644 services/gunDB/contact-api/jobs/onOrders.js diff --git a/services/gunDB/contact-api/jobs/index.js b/services/gunDB/contact-api/jobs/index.js new file mode 100644 index 00000000..55c993e1 --- /dev/null +++ b/services/gunDB/contact-api/jobs/index.js @@ -0,0 +1,18 @@ +/** + * @format + * Jobs are subscriptions to events that perform actions (write to GUN) on + * response to certain ways events can happen. These tasks need to be fired up + * at app launch otherwise certain features won't work as intended. Tasks should + * ideally be idempotent, that is, if they were to be fired up after a certain + * amount of time after app launch, everything should work as intended. For this + * to work, special care has to be put into how these respond to events. These + * tasks accept factories that are homonymous to the events on this same module. + */ + +const onAcceptedRequests = require('./onAcceptedRequests') +const onOrders = require('./onOrders') + +module.exports = { + onAcceptedRequests, + onOrders +} diff --git a/services/gunDB/contact-api/jobs.js b/services/gunDB/contact-api/jobs/onAcceptedRequests.js similarity index 80% rename from services/gunDB/contact-api/jobs.js rename to services/gunDB/contact-api/jobs/onAcceptedRequests.js index a6ec48dd..34888ca9 100644 --- a/services/gunDB/contact-api/jobs.js +++ b/services/gunDB/contact-api/jobs/onAcceptedRequests.js @@ -1,24 +1,15 @@ /** - * @prettier - * Taks are subscriptions to events that perform actions (write to GUN) on - * response to certain ways events can happen. These tasks need to be fired up - * at app launch otherwise certain features won't work as intended. Tasks should - * ideally be idempotent, that is, if they were to be fired up after a certain - * amount of time after app launch, everything should work as intended. For this - * to work, special care has to be put into how these respond to events. These - * tasks could be hardcoded inside events but then they wouldn't be easily - * auto-testable. These tasks accept factories that are homonymous to the events - * on the same + * @format */ -const ErrorCode = require('./errorCode') -const Key = require('./key') -const Schema = require('./schema') -const Utils = require('./utils') +const ErrorCode = require('../errorCode') +const Key = require('../key') +const Schema = require('../schema') +const Utils = require('../utils') /** - * @typedef {import('./SimpleGUN').GUNNode} GUNNode - * @typedef {import('./SimpleGUN').ISEA} ISEA - * @typedef {import('./SimpleGUN').UserGUNNode} UserGUNNode + * @typedef {import('../SimpleGUN').GUNNode} GUNNode + * @typedef {import('../SimpleGUN').ISEA} ISEA + * @typedef {import('../SimpleGUN').UserGUNNode} UserGUNNode */ /** @@ -148,6 +139,4 @@ const onAcceptedRequests = async (user, SEA) => { }) } -module.exports = { - onAcceptedRequests -} +module.exports = onAcceptedRequests diff --git a/services/gunDB/contact-api/jobs/onOrders.js b/services/gunDB/contact-api/jobs/onOrders.js new file mode 100644 index 00000000..95043e34 --- /dev/null +++ b/services/gunDB/contact-api/jobs/onOrders.js @@ -0,0 +1,82 @@ +/** + * @format + */ +const ErrorCode = require('../errorCode') +const Key = require('../key') +const Schema = require('../schema') +const Utils = require('../utils') + +/** + * @typedef {import('../SimpleGUN').GUNNode} GUNNode + * @typedef {import('../SimpleGUN').ListenerData} ListenerData + * @typedef {import('../SimpleGUN').ISEA} ISEA + * @typedef {import('../SimpleGUN').UserGUNNode} UserGUNNode + */ + +let currentOrderAddr = '' + +/** + * @param {string} addr + * @param {UserGUNNode} user + * @param {ISEA} SEA + * @returns {(order: ListenerData, orderID: string) => void} + */ +const listenerForAddr = (addr, user, SEA) => async (order, orderID) => { + if (addr !== currentOrderAddr) { + return + } + + if (!Schema.isOrder(order)) { + throw new Error(`Expected an order instead got: ${JSON.stringify(order)}`) + } + + const senderEpub = await Utils.pubToEpub(order.from) + const secret = await SEA.secret(senderEpub, user._.sea) + + const amount = Number(await SEA.decrypt(order.amount, secret)) + const memo = await SEA.decrypt(order.memo, secret) + + // create invoice here.. + + const invoice = `INVOICE_${amount}_${memo}` + + const encInvoice = await SEA.encrypt(invoice, secret) + + user + .get(Key.ORDER_TO_RESPONSE) + .get(orderID) + .put(encInvoice, ack => { + if (ack.err) { + console.error(`error saving order response: ${ack.err}`) + } + }) +} + +/** + * @param {UserGUNNode} user + * @param {GUNNode} gun + * @param {ISEA} SEA + * @throws {Error} NOT_AUTH + * @returns {void} + */ +const onOrders = (user, gun, SEA) => { + if (!user.is) { + throw new Error(ErrorCode.NOT_AUTH) + } + + user.get(Key.CURRENT_ORDER_ADDRESS).on(addr => { + if (typeof addr !== 'string') { + throw new TypeError('Expected current order address to be an string') + } + + currentOrderAddr = addr + + gun + .get(Key.ORDER_NODES) + .get(addr) + .map() + .on(listenerForAddr(currentOrderAddr, user, SEA)) + }) +} + +module.exports = onOrders