mirror of
https://github.com/Permissionless-Software-Foundation/bch-dex.git
synced 2026-09-21 16:52:00 -07:00
Debugging counter-offer
This commit is contained in:
Generated
+12
-12
@@ -26,7 +26,7 @@
|
||||
"@psf/bch-js": "6.7.3",
|
||||
"axios": "0.27.2",
|
||||
"bch-message-lib": "2.2.1",
|
||||
"bch-nostr": "1.3.2",
|
||||
"bch-nostr": "1.3.3",
|
||||
"bch-token-sweep": "2.2.1",
|
||||
"bcryptjs": "2.4.3",
|
||||
"bitcoincashjs-lib": "3.3.3",
|
||||
@@ -53,7 +53,7 @@
|
||||
"koa2-ratelimit": "0.9.1",
|
||||
"libp2p": "1.9.1",
|
||||
"line-reader": "0.4.0",
|
||||
"minimal-slp-wallet": "5.12.0",
|
||||
"minimal-slp-wallet": "5.12.1",
|
||||
"mongoose": "5.13.14",
|
||||
"node-fetch": "npm:@achingbrain/node-fetch@2.6.7",
|
||||
"nodemailer": "6.7.5",
|
||||
@@ -7420,9 +7420,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/bch-consumer": {
|
||||
"version": "1.6.1",
|
||||
"resolved": "http://94.130.170.209:4873/bch-consumer/-/bch-consumer-1.6.1.tgz",
|
||||
"integrity": "sha512-ZhyZ54kgF6f3sB7J4ylMBJHSoBXozUdM2bvsm2nTz31515LFfHra9d9w4Ommlmy5BvuDkdX4lUeGSLRvggXnFg==",
|
||||
"version": "1.5.1",
|
||||
"resolved": "http://94.130.170.209:4873/bch-consumer/-/bch-consumer-1.5.1.tgz",
|
||||
"integrity": "sha512-tEmds6Mk7g074+fGflm0d9At2ZV8DFhWErEN0nUzzW4vG5Ega9+yjREY16P/QuwwykzodnleQqOsNwcmvvgnAg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@psf/bch-js": "6.7.3",
|
||||
@@ -7597,9 +7597,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/bch-nostr": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "http://94.130.170.209:4873/bch-nostr/-/bch-nostr-1.3.2.tgz",
|
||||
"integrity": "sha512-MdbuuTns1MhEd205uabl7Y8X+caphnb6ZgHs574bet+cSE0aw4QoMr6hpc+EmLtuKK90r5Eqob1peuQ9jzVlIg==",
|
||||
"version": "1.3.3",
|
||||
"resolved": "http://94.130.170.209:4873/bch-nostr/-/bch-nostr-1.3.3.tgz",
|
||||
"integrity": "sha512-2Mod/PEDr/GJzQq20oSJKwJDtiXYm/Qj5KxIvFqsvBY1SYsHGyDu1FMBQ1UvOhY3ZP5fgiVLbIGvMRuWXqS4oQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"apidoc": "0.53.0",
|
||||
@@ -17185,15 +17185,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/minimal-slp-wallet": {
|
||||
"version": "5.12.0",
|
||||
"resolved": "http://94.130.170.209:4873/minimal-slp-wallet/-/minimal-slp-wallet-5.12.0.tgz",
|
||||
"integrity": "sha512-zSJcBLF/tt7NH0xkuukTJ4BxnC2GIR8kjUJRWW91/LwhI6c2K9qNVV/G5E7SjYx125aHkGk5lq3pjGePsJ18rA==",
|
||||
"version": "5.12.1",
|
||||
"resolved": "http://94.130.170.209:4873/minimal-slp-wallet/-/minimal-slp-wallet-5.12.1.tgz",
|
||||
"integrity": "sha512-DnggKv1KC/Y6qxT6GiplrxfKPgBOdYbu7uK4bWVO+6RgTtcgMxrd4pxCFh4kHV3nV7vKBpE1wsmVZgtZ3x9qcg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@chris.troutner/retry-queue-commonjs": "1.0.8",
|
||||
"@psf/bch-js": "6.8.0",
|
||||
"apidoc": "0.51.0",
|
||||
"bch-consumer": "1.6.1",
|
||||
"bch-consumer": "1.5.1",
|
||||
"bch-donation": "1.1.2",
|
||||
"crypto-js": "4.0.0"
|
||||
}
|
||||
|
||||
+2
-2
@@ -45,7 +45,7 @@
|
||||
"@psf/bch-js": "6.7.3",
|
||||
"axios": "0.27.2",
|
||||
"bch-message-lib": "2.2.1",
|
||||
"bch-nostr": "1.3.2",
|
||||
"bch-nostr": "1.3.3",
|
||||
"bch-token-sweep": "2.2.1",
|
||||
"bcryptjs": "2.4.3",
|
||||
"bitcoincashjs-lib": "3.3.3",
|
||||
@@ -72,7 +72,7 @@
|
||||
"koa2-ratelimit": "0.9.1",
|
||||
"libp2p": "1.9.1",
|
||||
"line-reader": "0.4.0",
|
||||
"minimal-slp-wallet": "5.12.0",
|
||||
"minimal-slp-wallet": "5.12.1",
|
||||
"mongoose": "5.13.14",
|
||||
"node-fetch": "npm:@achingbrain/node-fetch@2.6.7",
|
||||
"nodemailer": "6.7.5",
|
||||
|
||||
@@ -2,8 +2,10 @@
|
||||
Adapter library for working with Nostr.
|
||||
*/
|
||||
|
||||
// Global npm libraries
|
||||
import BchNostr from 'bch-nostr'
|
||||
import { RelayPool } from 'nostr'
|
||||
import RetryQueue from '@chris.troutner/retry-queue'
|
||||
|
||||
class NostrAdapter {
|
||||
constructor (localConfig = { nostrRelay: '', nostrTopic: '' }) {
|
||||
@@ -25,6 +27,11 @@ class NostrAdapter {
|
||||
// Encapsulate dependencies
|
||||
this.bchNostr = new BchNostr()
|
||||
this.RelayPool = RelayPool
|
||||
this.retryQueue = new RetryQueue({
|
||||
concurrency: 1,
|
||||
attempts: 5,
|
||||
retryPeriod: 1000
|
||||
})
|
||||
|
||||
// Bind the 'this' object
|
||||
this.start = this.start.bind(this)
|
||||
@@ -71,7 +78,7 @@ class NostrAdapter {
|
||||
msg,
|
||||
tags: [['t', this.topic]]
|
||||
}
|
||||
const eventId = await this.bchNostr.post.uploadToNostr(inObj)
|
||||
const eventId = await this.retryQueue.addToQueue(this.bchNostr.post.uploadToNostr, inObj)
|
||||
return eventId
|
||||
} catch (error) {
|
||||
console.log(`Error in nostr.js/post() ${error.message} `)
|
||||
|
||||
+10
-4
@@ -5,12 +5,11 @@
|
||||
// Public npm libraries
|
||||
import BchWallet from 'minimal-slp-wallet'
|
||||
import BchTokenSweep from 'bch-token-sweep/index.js'
|
||||
|
||||
import bitcoinJs from 'bitcoincashjs-lib'
|
||||
import RetryQueue from '@chris.troutner/retry-queue'
|
||||
|
||||
// Local libraries
|
||||
import JsonFiles from './json-files.js'
|
||||
|
||||
import config from '../../config/index.js'
|
||||
|
||||
// Hack to get __dirname back.
|
||||
@@ -35,6 +34,11 @@ class WalletAdapter {
|
||||
this.BchWallet = BchWallet
|
||||
this.bchWallet = {} // Will be replaced when initialized.
|
||||
// this.advancedConfig = localConfig.advancedConfig
|
||||
this.retryQueue = new RetryQueue({
|
||||
concurrency: 1,
|
||||
attempts: 5,
|
||||
retryPeriod: 5000
|
||||
})
|
||||
|
||||
// Bind the 'this' object
|
||||
this.moveTokens = this.moveTokens.bind(this)
|
||||
@@ -441,7 +445,7 @@ class WalletAdapter {
|
||||
|
||||
return txObj2
|
||||
} catch (err) {
|
||||
console.error('Error in wallet.js/deserializePartialTx()')
|
||||
console.error('Error in wallet.js/deserializeTx()')
|
||||
throw err
|
||||
}
|
||||
}
|
||||
@@ -508,7 +512,9 @@ class WalletAdapter {
|
||||
// return csTxHex
|
||||
|
||||
// Broadcast transaction to the network
|
||||
const txid = await this.bchWallet.ar.sendTx(csTxHex)
|
||||
// const txid = await this.bchWallet.ar.sendTx(csTxHex)
|
||||
const txid = await this.retryQueue.addToQueue(this.bchWallet.broadcast, { hex: csTxHex })
|
||||
console.log('completeTx() txid: ', txid)
|
||||
|
||||
return txid
|
||||
} catch (err) {
|
||||
|
||||
@@ -17,7 +17,7 @@ class OfferEntity {
|
||||
)
|
||||
}
|
||||
|
||||
console.log('offer entity validate() offerData: ', offerData)
|
||||
// console.log('offer entity validate() offerData: ', offerData)
|
||||
|
||||
const {
|
||||
messageType,
|
||||
@@ -105,7 +105,7 @@ class OfferEntity {
|
||||
tokenType,
|
||||
nostrEventId
|
||||
}
|
||||
console.log('offer entity validatedOfferData: ', validatedOfferData)
|
||||
// console.log('offer entity validatedOfferData: ', validatedOfferData)
|
||||
|
||||
return validatedOfferData
|
||||
}
|
||||
|
||||
@@ -94,7 +94,7 @@ class OfferUseCases {
|
||||
}
|
||||
// const utxoStatus = await this.adapters.wallet.bchWallet.utxoIsValid(utxo)
|
||||
const utxoStatus = await this.retryQueue.addToQueue(this.adapters.wallet.bchWallet.utxoIsValid, utxo)
|
||||
console.log('utxoStatus: ', utxoStatus)
|
||||
// console.log('utxoStatus: ', utxoStatus)
|
||||
// if (utxoStatus === null) return false
|
||||
if (!utxoStatus) return false
|
||||
|
||||
@@ -175,7 +175,7 @@ class OfferUseCases {
|
||||
const nsfwSetTrue = mutableData.nsfw === true
|
||||
const nsfwStringTrue = mutableData.nsfw === 'true'
|
||||
const nsfwDetected = hasNsfw && (nsfwSetTrue || nsfwStringTrue)
|
||||
console.log(`hasNsfw: ${hasNsfw}, nsfwSetTrue: ${nsfwSetTrue}, nsfwStringTrue: ${nsfwStringTrue}, nsfwDetected: ${nsfwDetected}`)
|
||||
// console.log(`hasNsfw: ${hasNsfw}, nsfwSetTrue: ${nsfwSetTrue}, nsfwStringTrue: ${nsfwStringTrue}, nsfwDetected: ${nsfwDetected}`)
|
||||
|
||||
if (nsfwDetected) {
|
||||
console.log('NSFW flag set as true')
|
||||
@@ -318,7 +318,7 @@ class OfferUseCases {
|
||||
|
||||
// Note : should be added to retry-queue?
|
||||
const utxoStatus = await this.adapters.wallet.bchWallet.utxoIsValid(utxo)
|
||||
console.log('utxoStatus: ', utxoStatus)
|
||||
// console.log('utxoStatus: ', utxoStatus)
|
||||
if (!utxoStatus) {
|
||||
console.log(`utxo txid: ${offerInfo.utxoTxid}, vout: ${offerInfo.utxoVout}`)
|
||||
|
||||
@@ -377,11 +377,11 @@ class OfferUseCases {
|
||||
data: takenOfferInfo,
|
||||
appId: this.config.p2wdbAppId
|
||||
}
|
||||
const resultEventId = await this.adapters.nostr.post(nostrData)
|
||||
const resultEventId = await this.adapters.nostr.post(JSON.stringify(nostrData))
|
||||
|
||||
// Delete the Offer from the database, so that the user doesn't attempt
|
||||
// to take the offer more than once.
|
||||
offerInfo.remove()
|
||||
// offerInfo.remove()
|
||||
|
||||
// Return the P2WDB CID
|
||||
return resultEventId
|
||||
@@ -472,27 +472,27 @@ class OfferUseCases {
|
||||
}
|
||||
|
||||
async findOfferByTxid (utxoTxid) {
|
||||
try {
|
||||
// try {
|
||||
if (typeof utxoTxid !== 'string' || !utxoTxid) {
|
||||
throw new Error('utxoTxid must be a string')
|
||||
}
|
||||
|
||||
const offer = await this.OfferModel.findOne({ utxoTxid })
|
||||
|
||||
// TODO: Offer should be found by TXID, then if there is more than one
|
||||
// result, they should be filtered by the vout property. That will leave
|
||||
// one remaining UTXO.
|
||||
|
||||
if (!offer) {
|
||||
throw new Error('offer not found')
|
||||
}
|
||||
|
||||
return offer
|
||||
} catch (error) {
|
||||
console.error('Error in use-cases/offer/findOfferByTxid(): ', error.message)
|
||||
throw error
|
||||
// try {
|
||||
// try {
|
||||
if (typeof utxoTxid !== 'string' || !utxoTxid) {
|
||||
throw new Error('utxoTxid must be a string')
|
||||
}
|
||||
|
||||
const offer = await this.OfferModel.findOne({ utxoTxid })
|
||||
|
||||
// TODO: Offer should be found by TXID, then if there is more than one
|
||||
// result, they should be filtered by the vout property. That will leave
|
||||
// one remaining UTXO.
|
||||
|
||||
if (!offer) {
|
||||
throw new Error('offer not found')
|
||||
}
|
||||
|
||||
return offer
|
||||
// } catch (error) {
|
||||
// // console.error('Error in use-cases/offer/findOfferByTxid(): ', error.message)
|
||||
// throw error
|
||||
// }
|
||||
}
|
||||
|
||||
// This function is called by the P2WDB webhook REST API handler. When a
|
||||
@@ -505,17 +505,18 @@ class OfferUseCases {
|
||||
|
||||
// See if this instance of bch-dex is managing the Order associated with
|
||||
// the incoming Counter Offer.
|
||||
|
||||
// Note : this should be handle by nostrEvent id or UtxoId?
|
||||
const orderHash = offerData.data.nostrEventId
|
||||
console.log('ping11')
|
||||
// Note : this should be handled by nostrEvent id or UtxoId?
|
||||
// const orderHash = offerData.data.nostrEventId
|
||||
let orderData = {}
|
||||
try {
|
||||
orderData = await this.orderUseCase.findOrderByEvent(orderHash)
|
||||
orderData = await this.orderUseCase.findOrderByUtxo(offerData)
|
||||
console.log(`orderData: ${JSON.stringify(orderData, null, 2)}`)
|
||||
} catch (err) {
|
||||
console.log('Order matching this Counter Offer is not managed by this instance of bch-dex. Exiting.')
|
||||
console.log('Order matching this Counter Offer is not managed by this instance of bch-dex. Skipping.')
|
||||
return 'N/A'
|
||||
}
|
||||
console.log('ping12')
|
||||
|
||||
// Deserialize the partially signed transaction.
|
||||
const txHex = offerData.data.partialTxHex
|
||||
@@ -549,7 +550,7 @@ class OfferUseCases {
|
||||
|
||||
return txid
|
||||
} catch (err) {
|
||||
console.error('Error in acceptCounterOffer()')
|
||||
console.error('Error in acceptCounterOffer(): ', err)
|
||||
throw err
|
||||
}
|
||||
}
|
||||
@@ -637,7 +638,7 @@ class OfferUseCases {
|
||||
|
||||
// If the Offer UTXO is spent, delete the Offer model.
|
||||
if (utxoStatus === false) {
|
||||
console.log('utxoStatus: ', utxoStatus)
|
||||
// console.log('utxoStatus: ', utxoStatus)
|
||||
console.log(`Spent UTXO detected. Deleting this Offer: ${JSON.stringify(thisOffer, null, 2)}`)
|
||||
await thisOffer.remove()
|
||||
}
|
||||
@@ -698,7 +699,7 @@ class OfferUseCases {
|
||||
try {
|
||||
// Retrieve offers array.
|
||||
const offers = await this.adapters.nostr.read()
|
||||
console.log('offers: ', offers)
|
||||
// console.log('offers: ', offers)
|
||||
|
||||
for (let i = 0; i < offers.length; i++) {
|
||||
try {
|
||||
@@ -709,9 +710,19 @@ class OfferUseCases {
|
||||
|
||||
// Append the Nostr Event ID to the offer object
|
||||
offerObj.data.nostrEventId = offer.eventId
|
||||
// console.log('loadOffers() offerObj: ', offerObj)
|
||||
|
||||
// Try to create new offer
|
||||
await this.createOffer(offerObj)
|
||||
if (offerObj.data.dataType === 'offer') {
|
||||
// Try to create new offer
|
||||
await this.createOffer(offerObj)
|
||||
}
|
||||
|
||||
if (offerObj.data.dataType === 'counter-offer') {
|
||||
console.log('Counter offer detected: ', offerObj)
|
||||
await this.acceptCounterOffer(offerObj)
|
||||
}
|
||||
|
||||
// Ignore the post if it doesn't fit the above filters.
|
||||
} catch (error) {
|
||||
/* exit quietly */
|
||||
}
|
||||
|
||||
+45
-2
@@ -31,6 +31,8 @@ class OrderLib {
|
||||
|
||||
// Bind subfunctions to the 'this' object.
|
||||
this.ensureFunds = this.ensureFunds.bind(this)
|
||||
this.createOrder = this.createOrder.bind(this)
|
||||
this.findOrderByUtxo = this.findOrderByUtxo.bind(this)
|
||||
}
|
||||
|
||||
// Create a new order model and add it to the Mongo database.
|
||||
@@ -191,6 +193,47 @@ class OrderLib {
|
||||
}
|
||||
}
|
||||
|
||||
// Retrieve an Order model from the database. Find it by its UTXO (TXID & Vout)
|
||||
async findOrderByUtxo (offerData = {}) {
|
||||
try {
|
||||
console.log('findOrderByUtxo() offerData: ', offerData)
|
||||
|
||||
// if (typeof nostrEventId !== 'string' || !nostrEventId) {
|
||||
// throw new Error('nostrEventId must be a string')
|
||||
// }
|
||||
|
||||
console.log('ping01')
|
||||
|
||||
// const allOrders = await this.OrderModel.find({})
|
||||
// console.log('allOrders: ', allOrders)
|
||||
|
||||
console.log('ping02')
|
||||
|
||||
// const order = await this.OrderModel.findOne({ nostrEventId })
|
||||
const order = await this.OrderModel.findOne({ utxoTxid: offerData.data.utxoTxid, utxoVout: offerData.data.utxoVout })
|
||||
// const order = await this.OrderModel.findOne({ utxoTxid: offerData.data.utxoTxid })
|
||||
// const order = await this.OrderModel.findOne({ tokenId: offerData.data.tokenId })
|
||||
console.log('findOrderByUtxo() order: ', order)
|
||||
|
||||
console.log('ping03')
|
||||
|
||||
if (!order) {
|
||||
throw new Error('order not found')
|
||||
}
|
||||
if (!order.nostrEventId) {
|
||||
throw new Error('order not found')
|
||||
}
|
||||
|
||||
const orderObject = order.toObject()
|
||||
// return this.offerEntity.validateFromModel(offerObject)
|
||||
|
||||
return orderObject
|
||||
} catch (err) {
|
||||
console.error('Error in findOrderByUtxo(): ', err)
|
||||
throw err
|
||||
}
|
||||
}
|
||||
|
||||
// This function is called by the garbage collection timer controller. It
|
||||
// checks the UTXO associated with each Order in the database. If the UTXO
|
||||
// has been spent, the Order is deleted from the database.
|
||||
@@ -201,7 +244,7 @@ class OrderLib {
|
||||
|
||||
// Get all Orders in the database.
|
||||
const orders = await this.OrderModel.find({})
|
||||
console.log('orders: ', orders)
|
||||
// console.log('orders: ', orders)
|
||||
|
||||
// Loop through each Order and ensure the UTXO is still valid.
|
||||
for (let i = 0; i < orders.length; i++) {
|
||||
@@ -239,7 +282,7 @@ class OrderLib {
|
||||
|
||||
// If the Order UTXO is spent, delete the Order model.
|
||||
if (utxoStatus === false) {
|
||||
console.log('utxoStatus: ', utxoStatus)
|
||||
// console.log('utxoStatus: ', utxoStatus)
|
||||
console.log(`Spent UTXO detected. Deleting this Order: ${JSON.stringify(thisOrder, null, 2)}`)
|
||||
await thisOrder.remove()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user