diff --git a/services/gunDB/contact-api/key.js b/services/gunDB/contact-api/key.js index 06aaa1fe..4aaf0174 100644 --- a/services/gunDB/contact-api/key.js +++ b/services/gunDB/contact-api/key.js @@ -67,3 +67,5 @@ exports.POSTS_NEW = 'posts' exports.COORDINATES = 'coordinates' exports.COORDINATE_INDEX = 'coordinateIndex' + +exports.TMP_CHAIN_COORDINATE = 'tmpChainCoordinate' diff --git a/services/schema/index.js b/services/schema/index.js index a8a52529..55ed70d4 100644 --- a/services/schema/index.js +++ b/services/schema/index.js @@ -283,6 +283,101 @@ class SchemaManager { const orderedOrders = orders.sort((a, b) => b.timestamp - a.timestamp) return orderedOrders } + + /** + * + * @param {string} address + * @param {CoordinateOrder} orderInfo + */ + //eslint-disable-next-line class-methods-use-this + async AddTmpChainOrder(address, orderInfo) { + const checkErr = checkOrderInfo(orderInfo) + if (checkErr) { + throw new Error(checkErr) + } + + /** + * @type {CoordinateOrder} + */ + const filteredOrder = { + fromLndPub: orderInfo.fromLndPub, + toLndPub: orderInfo.toLndPub, + fromGunPub: orderInfo.fromGunPub, + toGunPub: orderInfo.toGunPub, + inbound: orderInfo.inbound, + ownerGunPub: orderInfo.ownerGunPub, + coordinateIndex: orderInfo.coordinateIndex, + coordinateHash: orderInfo.coordinateHash, + type: orderInfo.type, + amount: orderInfo.amount, + description: orderInfo.description, + metadata: orderInfo.metadata, + + timestamp: orderInfo.timestamp || Date.now(), + } + const orderString = JSON.stringify(filteredOrder) + const mySecret = require('../gunDB/Mediator').getMySecret() + const encryptedOrderString = await SEA.encrypt(orderString, mySecret) + + const addressSHA256 = Crypto.createHash('SHA256') + .update(address) + .digest('hex') + + await new Promise((res, rej) => { + getGunUser() + .get(Key.TMP_CHAIN_COORDINATE) + .get(addressSHA256) + .put(encryptedOrderString, ack => { + if (ack.err && typeof ack.err !== 'number') { + rej( + new Error( + `Error saving tmp chain coordinate order to user-graph: ${ack}` + ) + ) + } else { + res(null) + } + }) + }) + } + + /** + * + * @param {string} address + * @returns {Promise} + */ + //eslint-disable-next-line class-methods-use-this + async isTmpChainOrder(address) { + if (typeof address !== 'string' || address === '') { + return false + } + const addressSHA256 = Crypto.createHash('SHA256') + .update(address) + .digest('hex') + + const maybeData = await getGunUser() + .get(Key.TMP_CHAIN_COORDINATE) + .get(addressSHA256) + .then() + + if (typeof maybeData !== 'string' || maybeData === '') { + return false + } + const mySecret = require('../gunDB/Mediator').getMySecret() + const decryptedString = await SEA.decrypt(maybeData, mySecret) + if (typeof decryptedString !== 'string' || decryptedString === '') { + return false + } + + const tmpOrder = JSON.parse(decryptedString) + const checkErr = checkOrderInfo(tmpOrder) + if (checkErr) { + return false + } + + return tmpOrder + + } } const Manager = new SchemaManager() diff --git a/src/sockets.js b/src/sockets.js index 54537af8..44c8b523 100644 --- a/src/sockets.js +++ b/src/sockets.js @@ -17,6 +17,7 @@ const { } = require('../services/gunDB/Mediator') const { deepDecryptIfNeeded } = require('../services/gunDB/rpc') const GunEvents = require('../services/gunDB/contact-api/events') +const SchemaManager = require('../services/schema') /** * @typedef {import('../services/gunDB/Mediator').SimpleSocket} SimpleSocket * @typedef {import('../services/gunDB/contact-api/SimpleGUN').ValidDataValue} ValidDataValue @@ -198,7 +199,18 @@ module.exports = ( logger.warn('Subscribing to transactions socket...' + subID) stream.on('data', data => { logger.info('[SOCKET] New transaction data:', data) - emitEncryptedEvent({ eventName: 'transaction:new', data, socket }) + + Promise.all(data.dest_addresses.map(SchemaManager.isTmpChainOrder)).then( + responses => { + const hasOrder = responses.some(res => res !== false) + if (hasOrder && data.num_confirmations > 0) { + //buddy needs to manage this + } else { + //business as usual + emitEncryptedEvent({ eventName: 'transaction:new', data, socket }) + } + } + ) }) stream.on('end', () => { logger.info('New transactions stream ended, starting a new one...')