wire with orders
This commit is contained in:
parent
2079b4f984
commit
bd89766265
3 changed files with 94 additions and 49 deletions
|
|
@ -12,8 +12,9 @@ const {
|
||||||
Constants: { ErrorCode },
|
Constants: { ErrorCode },
|
||||||
Schema
|
Schema
|
||||||
} = Common
|
} = Common
|
||||||
|
const SchemaManager = require('../../../schema')
|
||||||
const LightningServices = require('../../../../utils/lightningServices')
|
const LightningServices = require('../../../../utils/lightningServices')
|
||||||
|
const LNDHealthManager = require('../../../../utils/lightningServices/errors')
|
||||||
|
|
||||||
const Key = require('../key')
|
const Key = require('../key')
|
||||||
const Utils = require('../utils')
|
const Utils = require('../utils')
|
||||||
|
|
@ -248,7 +249,7 @@ const listenerForAddr = (addr, SEA) => async (order, orderID) => {
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Common.Invoice} invoice
|
* @param {Common.Invoice & {r_hash:Buffer}} invoice
|
||||||
*/
|
*/
|
||||||
const invoiceSubCb = invoice => {
|
const invoiceSubCb = invoice => {
|
||||||
if (!invoice.settled) {
|
if (!invoice.settled) {
|
||||||
|
|
@ -260,14 +261,22 @@ const listenerForAddr = (addr, SEA) => async (order, orderID) => {
|
||||||
.get(maybePostId)
|
.get(maybePostId)
|
||||||
.set(null) // each item in the set is a tip
|
.set(null) // each item in the set is a tip
|
||||||
}
|
}
|
||||||
const coordinate = 'lnPub + invoiceIndex + payment hash(?)' //....
|
const myLndPub = LNDHealthManager.lndPub
|
||||||
const orderData = {
|
const myGunPub = getUser()._.sea.pub
|
||||||
someInfo: 'info '
|
if (!myLndPub) {
|
||||||
|
return //should never happen but just to be safe
|
||||||
}
|
}
|
||||||
getUser()
|
SchemaManager.AddOrder({
|
||||||
.get('orders')
|
amount: parseInt(invoice.amt_paid, 10),
|
||||||
.get(coordinate)
|
coordinateHash: invoice.r_hash.toString('hex'),
|
||||||
.set(orderData)
|
coordinateIndex: parseInt(invoice.add_index, 10),
|
||||||
|
toLndPub: myLndPub,
|
||||||
|
inbound: true,
|
||||||
|
type: 'other', //TODO better this
|
||||||
|
fromGunPub: order.from,
|
||||||
|
toGunPub: myGunPub,
|
||||||
|
invoiceMemo: invoice.memo
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
stream.on('data', invoiceSubCb)
|
stream.on('data', invoiceSubCb)
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,8 @@ const Key = require('../gunDB/contact-api/key')
|
||||||
*
|
*
|
||||||
* This represents a settled order only, unsettled orders have no coordinate
|
* This represents a settled order only, unsettled orders have no coordinate
|
||||||
* @typedef {object} CoordinateOrder
|
* @typedef {object} CoordinateOrder
|
||||||
* @prop {string} fromLndPub
|
* @prop {string=} fromLndPub can be unknown when inbound
|
||||||
* @prop {string} toLndPub
|
* @prop {string} toLndPub always known
|
||||||
* @prop {string=} fromGunPub can be optional, if the payment/invoice is not related to an order
|
* @prop {string=} fromGunPub can be optional, if the payment/invoice is not related to an order
|
||||||
* @prop {string=} toGunPub can be optional, if the payment/invoice is not related to an order
|
* @prop {string=} toGunPub can be optional, if the payment/invoice is not related to an order
|
||||||
* @prop {boolean} inbound
|
* @prop {boolean} inbound
|
||||||
|
|
@ -26,6 +26,7 @@ const Key = require('../gunDB/contact-api/key')
|
||||||
* @prop {OrderType} type
|
* @prop {OrderType} type
|
||||||
* @prop {number} amount
|
* @prop {number} amount
|
||||||
* @prop {string=} description
|
* @prop {string=} description
|
||||||
|
* @prop {string=} invoiceMemo
|
||||||
* @prop {string=} metadata JSON encoded string to store extra data for special use cases
|
* @prop {string=} metadata JSON encoded string to store extra data for special use cases
|
||||||
* @prop {number=} timestamp timestamp will be added at processing time if empty
|
* @prop {number=} timestamp timestamp will be added at processing time if empty
|
||||||
*
|
*
|
||||||
|
|
@ -34,7 +35,7 @@ const Key = require('../gunDB/contact-api/key')
|
||||||
/**
|
/**
|
||||||
* @param {CoordinateOrder} order
|
* @param {CoordinateOrder} order
|
||||||
*/
|
*/
|
||||||
const checkOrderInfo = (order = {}) => {
|
const checkOrderInfo = order => {
|
||||||
const {
|
const {
|
||||||
fromLndPub,
|
fromLndPub,
|
||||||
toLndPub,
|
toLndPub,
|
||||||
|
|
@ -47,23 +48,25 @@ const checkOrderInfo = (order = {}) => {
|
||||||
coordinateIndex,
|
coordinateIndex,
|
||||||
coordinateHash,
|
coordinateHash,
|
||||||
metadata,
|
metadata,
|
||||||
|
invoiceMemo
|
||||||
} = order
|
} = order
|
||||||
|
|
||||||
if (typeof fromLndPub !== 'string' || fromLndPub === '') {
|
if (fromLndPub && (typeof fromLndPub !== 'string' || fromLndPub === '')) {
|
||||||
return 'invalid or no "fromLndPub" field provided to order coordinate'
|
return 'invalid "fromLndPub" field provided to order coordinate'
|
||||||
}
|
}
|
||||||
if (typeof toLndPub !== 'string' || toLndPub === '') {
|
if (typeof toLndPub !== 'string' || toLndPub === '') {
|
||||||
return 'invalid or no "toLndPub" field provided to order coordinate'
|
return 'invalid or no "toLndPub" field provided to order coordinate'
|
||||||
}
|
}
|
||||||
if (fromGunPub && (typeof fromGunPub !== 'string' || fromGunPub === '')) {
|
if (fromGunPub && (typeof fromGunPub !== 'string' || fromGunPub === '')) {
|
||||||
return 'invalid or no "fromGunPub" field provided to order coordinate'
|
return 'invalid "fromGunPub" field provided to order coordinate'
|
||||||
}
|
}
|
||||||
if (toGunPub && (typeof toGunPub !== 'string' || toGunPub === '')) {
|
if (toGunPub && (typeof toGunPub !== 'string' || toGunPub === '')) {
|
||||||
return 'invalid or no "toGunPub" field provided to order coordinate'
|
return 'invalid "toGunPub" field provided to order coordinate'
|
||||||
}
|
}
|
||||||
if (typeof inbound !== 'boolean') {
|
if (typeof inbound !== 'boolean') {
|
||||||
return 'invalid or no "inbound" field provided to order coordinate'
|
return 'invalid or no "inbound" field provided to order coordinate'
|
||||||
}
|
}
|
||||||
|
//@ts-expect-error
|
||||||
if (typeof type !== 'string' || type === '') {
|
if (typeof type !== 'string' || type === '') {
|
||||||
return 'invalid or no "type" field provided to order coordinate'
|
return 'invalid or no "type" field provided to order coordinate'
|
||||||
}
|
}
|
||||||
|
|
@ -81,6 +84,9 @@ const checkOrderInfo = (order = {}) => {
|
||||||
if (description && (typeof description !== 'string' || description === '')) {
|
if (description && (typeof description !== 'string' || description === '')) {
|
||||||
return 'invalid "description" field provided to order coordinate'
|
return 'invalid "description" field provided to order coordinate'
|
||||||
}
|
}
|
||||||
|
if (invoiceMemo && (typeof invoiceMemo !== 'string' || invoiceMemo === '')) {
|
||||||
|
return 'invalid "invoiceMemo" field provided to order coordinate'
|
||||||
|
}
|
||||||
if (metadata && (typeof metadata !== 'string' || metadata === '')) {
|
if (metadata && (typeof metadata !== 'string' || metadata === '')) {
|
||||||
return 'invalid "metadata" field provided to order coordinate'
|
return 'invalid "metadata" field provided to order coordinate'
|
||||||
}
|
}
|
||||||
|
|
@ -90,7 +96,7 @@ const checkOrderInfo = (order = {}) => {
|
||||||
class SchemaManager {
|
class SchemaManager {
|
||||||
constructor({ memIndex = false }) {//config flag?
|
constructor({ memIndex = false }) {//config flag?
|
||||||
this.memIndex = memIndex
|
this.memIndex = memIndex
|
||||||
this.orderCreateIndexCallbacks.push(this.dateIndexCreateCb) //create more Cbs and p
|
this.orderCreateIndexCallbacks.push(this.dateIndexCreateCb) //create more Cbs and put them here for more indexes callbacks
|
||||||
}
|
}
|
||||||
|
|
||||||
dateIndexName = 'dateIndex'
|
dateIndexName = 'dateIndex'
|
||||||
|
|
@ -161,7 +167,7 @@ class SchemaManager {
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
res()
|
res(null)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
@ -179,7 +185,7 @@ class SchemaManager {
|
||||||
if (this.memIndex) {
|
if (this.memIndex) {
|
||||||
//update date memIndex
|
//update date memIndex
|
||||||
}
|
}
|
||||||
const date = new Date(orderInfo.timestamp)
|
const date = new Date(orderInfo.timestamp || 0)
|
||||||
//use UTC for consistency?
|
//use UTC for consistency?
|
||||||
const year = date.getUTCFullYear().toString()
|
const year = date.getUTCFullYear().toString()
|
||||||
const month = date.getUTCMonth().toString()
|
const month = date.getUTCMonth().toString()
|
||||||
|
|
@ -194,21 +200,23 @@ class SchemaManager {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* if not provided, assume current month and year
|
* if not provided, assume current month and year
|
||||||
* @param {number} year
|
* @param {number|null} year
|
||||||
* @param {number} month
|
* @param {number|null} month
|
||||||
*/
|
*/
|
||||||
async getMonthCoordinates(year = null, month = null) {
|
async getMonthCoordinates(year = null, month = null) {
|
||||||
const now = Date.now()
|
const now = Date.now()
|
||||||
|
//@ts-expect-error
|
||||||
const stringYear = year !== null ? year.toString() : now.getUTCFullYear().toString()
|
const stringYear = year !== null ? year.toString() : now.getUTCFullYear().toString()
|
||||||
|
//@ts-expect-error
|
||||||
const stringMonth = month !== null ? month.toString() : now.getUTCMonth().toString()
|
const stringMonth = month !== null ? month.toString() : now.getUTCMonth().toString()
|
||||||
|
|
||||||
const data = await new Promise((res, rej) => {
|
const data = await new Promise(res => {
|
||||||
getGunUser()
|
getGunUser()
|
||||||
.get(Key.COORDINATE_INDEX)
|
.get(Key.COORDINATE_INDEX)
|
||||||
.get(this.dateIndexName)
|
.get(this.dateIndexName)
|
||||||
.get(stringYear)
|
.get(stringYear)
|
||||||
.get(stringMonth)
|
.get(stringMonth)
|
||||||
.load()
|
.load(res)
|
||||||
})
|
})
|
||||||
const coordinatesArray = Object
|
const coordinatesArray = Object
|
||||||
.values(data)
|
.values(data)
|
||||||
|
|
@ -219,13 +227,15 @@ class SchemaManager {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* if not provided, assume current month and year
|
* if not provided, assume current month and year
|
||||||
* @param {number} year
|
* @param {number|null} year
|
||||||
* @param {number} month
|
* @param {number|null} month
|
||||||
* @returns {Promise<CoordinateOrder[]>} from newer to older
|
* @returns {Promise<CoordinateOrder[]>} from newer to older
|
||||||
*/
|
*/
|
||||||
async getMonthOrders(year = null, month = null) {
|
async getMonthOrders(year = null, month = null) {
|
||||||
const now = Date.now()
|
const now = Date.now()
|
||||||
|
//@ts-expect-error
|
||||||
const intYear = year !== null ? year : now.getUTCFullYear()
|
const intYear = year !== null ? year : now.getUTCFullYear()
|
||||||
|
//@ts-expect-error
|
||||||
const intMonth = month !== null ? month : now.getUTCMonth()
|
const intMonth = month !== null ? month : now.getUTCMonth()
|
||||||
|
|
||||||
let coordinates = null
|
let coordinates = null
|
||||||
|
|
@ -234,11 +244,21 @@ class SchemaManager {
|
||||||
} else {
|
} else {
|
||||||
coordinates = await this.getMonthCoordinates(intYear, intMonth)
|
coordinates = await this.getMonthCoordinates(intYear, intMonth)
|
||||||
}
|
}
|
||||||
const orders = await CommonUtils.asyncMap(coordinates, async coordinateSHA256 => {
|
/**
|
||||||
|
* @type {CoordinateOrder[]}
|
||||||
|
*/
|
||||||
|
const orders = []
|
||||||
|
if (!coordinates) {
|
||||||
|
return orders
|
||||||
|
}
|
||||||
|
await CommonUtils.asyncForEach(coordinates, async coordinateSHA256 => {
|
||||||
const encryptedOrderString = await getGunUser()
|
const encryptedOrderString = await getGunUser()
|
||||||
.get(Key.COORDINATES)
|
.get(Key.COORDINATES)
|
||||||
.get(coordinateSHA256)
|
.get(coordinateSHA256)
|
||||||
.then()
|
.then()
|
||||||
|
if (typeof encryptedOrderString !== 'string') {
|
||||||
|
return
|
||||||
|
}
|
||||||
const mySecret = require('../gunDB/Mediator').getMySecret()
|
const mySecret = require('../gunDB/Mediator').getMySecret()
|
||||||
const decryptedString = await SEA.decrypt(encryptedOrderString, mySecret)
|
const decryptedString = await SEA.decrypt(encryptedOrderString, mySecret)
|
||||||
|
|
||||||
|
|
@ -246,10 +266,14 @@ class SchemaManager {
|
||||||
* @type {CoordinateOrder}
|
* @type {CoordinateOrder}
|
||||||
*/
|
*/
|
||||||
const orderJSON = JSON.parse(decryptedString)
|
const orderJSON = JSON.parse(decryptedString)
|
||||||
return orderJSON
|
orders.push(orderJSON)
|
||||||
})
|
})
|
||||||
|
//@ts-expect-error
|
||||||
const orderedOrders = orders.sort((a, b) => b.timestamp - a.timestamp)
|
const orderedOrders = orders.sort((a, b) => b.timestamp - a.timestamp)
|
||||||
return orderedOrders
|
return orderedOrders
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Manager = new SchemaManager()
|
||||||
|
|
||||||
|
module.exports = Manager
|
||||||
|
|
@ -20,17 +20,26 @@ class LNDErrorManager {
|
||||||
*/
|
*/
|
||||||
_isCheckingHealth = false
|
_isCheckingHealth = false
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {string|null}
|
||||||
|
*/
|
||||||
|
_lndPub = null
|
||||||
|
|
||||||
|
get lndPub() {
|
||||||
|
return this._lndPub
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {HealthListener[]}
|
* @type {HealthListener[]}
|
||||||
*/
|
*/
|
||||||
_healthListeners = []
|
_healthListeners = []
|
||||||
|
|
||||||
//rejects if(err && err.code !== 12)
|
//rejects if(err && err.code !== 12)
|
||||||
getAvailableService(){
|
getAvailableService() {
|
||||||
|
|
||||||
//require('shock-common').Utils.makePromise((res, rej) => ...)
|
//require('shock-common').Utils.makePromise((res, rej) => ...)
|
||||||
return new Promise((res,rej)=>{
|
return new Promise((res, rej) => {
|
||||||
if(!this._isCheckingHealth){
|
if (!this._isCheckingHealth) {
|
||||||
this._isCheckingHealth = true
|
this._isCheckingHealth = true
|
||||||
this.getInfo()
|
this.getInfo()
|
||||||
}
|
}
|
||||||
|
|
@ -39,7 +48,7 @@ class LNDErrorManager {
|
||||||
* @param {LNDError} err
|
* @param {LNDError} err
|
||||||
* @param {object} response
|
* @param {object} response
|
||||||
*/
|
*/
|
||||||
const listener = (err,response)=>{
|
const listener = (err, response) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
if (err.code === 12) {
|
if (err.code === 12) {
|
||||||
res({
|
res({
|
||||||
|
|
@ -58,7 +67,7 @@ class LNDErrorManager {
|
||||||
walletStatus: 'unknown',
|
walletStatus: 'unknown',
|
||||||
success: false
|
success: false
|
||||||
})
|
})
|
||||||
} else if(err.code === 4){
|
} else if (err.code === 4) {
|
||||||
rej({
|
rej({
|
||||||
service: 'unknown',
|
service: 'unknown',
|
||||||
message:
|
message:
|
||||||
|
|
@ -77,7 +86,7 @@ class LNDErrorManager {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
res({
|
res({
|
||||||
service: 'lightning',
|
service: 'lightning',
|
||||||
message: response,
|
message: response,
|
||||||
|
|
@ -85,7 +94,7 @@ class LNDErrorManager {
|
||||||
walletStatus: 'unlocked',
|
walletStatus: 'unlocked',
|
||||||
success: true
|
success: true
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
this._healthListeners.push(listener)
|
this._healthListeners.push(listener)
|
||||||
})
|
})
|
||||||
|
|
@ -93,28 +102,31 @@ class LNDErrorManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
//private
|
//private
|
||||||
getInfo(){
|
getInfo() {
|
||||||
const { lightning } = LightningServices.services
|
const { lightning } = LightningServices.services
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {LNDError} err
|
* @param {LNDError} err
|
||||||
* @param {object} response
|
* @param {{identity_pubkey:string}} response
|
||||||
*/
|
*/
|
||||||
const callback = (err, response) => {
|
const callback = (err, response) => {
|
||||||
this._healthListeners.forEach(l =>{
|
if (response && response.identity_pubkey) {
|
||||||
l(err,response)
|
this._lndPub = response.identity_pubkey
|
||||||
|
}
|
||||||
|
this._healthListeners.forEach(l => {
|
||||||
|
l(err, response)
|
||||||
})
|
})
|
||||||
this._healthListeners.length = 0
|
this._healthListeners.length = 0
|
||||||
this._isCheckingHealth = false
|
this._isCheckingHealth = false
|
||||||
}
|
}
|
||||||
const deadline = Date.now() + 10000
|
const deadline = Date.now() + 10000
|
||||||
lightning.getInfo({},{deadline}, callback)
|
lightning.getInfo({}, { deadline }, callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {LNDError} e
|
* @param {LNDError} e
|
||||||
*/
|
*/
|
||||||
handleError(e){
|
handleError(e) {
|
||||||
return this.sanitizeLNDError(e)
|
return this.sanitizeLNDError(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -122,13 +134,13 @@ class LNDErrorManager {
|
||||||
* @param {LNDError} e
|
* @param {LNDError} e
|
||||||
*/
|
*/
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
sanitizeLNDError(e){
|
sanitizeLNDError(e) {
|
||||||
let eMessage = ''
|
let eMessage = ''
|
||||||
if(typeof e === 'string'){
|
if (typeof e === 'string') {
|
||||||
eMessage = e
|
eMessage = e
|
||||||
}else if(e.details){
|
} else if (e.details) {
|
||||||
eMessage = e.details
|
eMessage = e.details
|
||||||
} else if(e.message){
|
} else if (e.message) {
|
||||||
eMessage = e.message
|
eMessage = e.message
|
||||||
}
|
}
|
||||||
if (eMessage.toLowerCase().includes('unknown')) {
|
if (eMessage.toLowerCase().includes('unknown')) {
|
||||||
|
|
@ -137,13 +149,13 @@ class LNDErrorManager {
|
||||||
? splittedMessage.slice(1).join('')
|
? splittedMessage.slice(1).join('')
|
||||||
: splittedMessage.join('')
|
: splittedMessage.join('')
|
||||||
}
|
}
|
||||||
if(eMessage === ''){
|
if (eMessage === '') {
|
||||||
return 'unknown LND error'
|
return 'unknown LND error'
|
||||||
}
|
}
|
||||||
return eMessage
|
return eMessage
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue