mirror of
https://github.com/Permissionless-Software-Foundation/bch-js.git
synced 2026-09-22 09:02:01 -07:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4a62ae64de | ||
|
|
78de9e390e | ||
|
|
656b0f6809 |
+1
-1
@@ -18,7 +18,7 @@
|
||||
"test:integration:local:abc": "export RESTURL=http://localhost:3000/v5/ && mocha --timeout 30000 test/integration && mocha --timeout 30000 test/integration/chains/abc/",
|
||||
"test:integration:local:bchn": "export RESTURL=http://localhost:3000/v5/ && mocha --timeout 30000 test/integration/ && mocha --timeout 30000 test/integration/chains/bchn/",
|
||||
"test:integration:local:testnet": "RESTURL=http://localhost:4000/v5/ mocha --timeout 30000 test/integration/chains/testnet",
|
||||
"test:integration:decatur:bchn": "export RESTURL=http://192.168.2.129:3000/v5/ && mocha --timeout 30000 test/integration/ && mocha --timeout 30000 test/integration/chains/bchn/",
|
||||
"test:integration:decatur:bchn": "export RESTURL=http://192.168.2.139:3000/v5/ && mocha --timeout 30000 test/integration/ && mocha --timeout 30000 test/integration/chains/bchn/",
|
||||
"test:integration:decatur:abc": "export RESTURL=http://192.168.2.141:3000/v5/ && mocha --timeout 30000 test/integration && mocha --timeout 30000 test/integration/chains/abc/",
|
||||
"test:integration:temp:bchn": "export RESTURL=http://157.90.174.219:3000/v5/ && mocha --timeout 30000 test/integration/",
|
||||
"test:temp": "export RESTURL=http://localhost:3000/v5/ && mocha --timeout 30000 -g '#Encryption' test/integration/",
|
||||
|
||||
+42
-2
@@ -1,10 +1,17 @@
|
||||
/*
|
||||
This library interacts with the PSF slp indexer REST API endpoints operated
|
||||
by FullStack.cash
|
||||
|
||||
TODO:
|
||||
- detect TXs from tokens in the blacklist.
|
||||
*/
|
||||
|
||||
// Public npm libraries
|
||||
const axios = require('axios')
|
||||
|
||||
// Local libraries
|
||||
const RawTransaction = require('./raw-transactions')
|
||||
|
||||
// let _this
|
||||
|
||||
class PsfSlpIndexer {
|
||||
@@ -29,6 +36,9 @@ class PsfSlpIndexer {
|
||||
}
|
||||
}
|
||||
|
||||
// Encapsulate dependencies
|
||||
this.rawTransaction = new RawTransaction(config)
|
||||
|
||||
// _this = this
|
||||
}
|
||||
|
||||
@@ -283,8 +293,38 @@ class PsfSlpIndexer {
|
||||
}
|
||||
throw new Error('Input txid must be a string.')
|
||||
} catch (error) {
|
||||
if (error.response && error.response.data) throw error.response.data
|
||||
else throw error
|
||||
// console.log('error: ', error)
|
||||
|
||||
// Case: txid is not stored in the psf-slp-indexer tx database.
|
||||
// Response: If it's not in the database, then it can be assumed the TX
|
||||
// is not a token TX?
|
||||
if (
|
||||
error.response &&
|
||||
error.response.data &&
|
||||
error.response.data.error &&
|
||||
error.response.data.error.includes('Key not found in database')
|
||||
) {
|
||||
// console.log(
|
||||
// 'TX not found in psf-slp-indexer. Retrieving from full node.'
|
||||
// )
|
||||
|
||||
// Get the TX Details from the full node.
|
||||
const txDetails = await this.rawTransaction.getTxData(txid)
|
||||
// console.log(`txDetails: ${JSON.stringify(txDetails, null, 2)}`)
|
||||
|
||||
// TODO: Run the TX through decodeOpReturn() to see if it has a tokenID
|
||||
// that is in the blacklist. If it is, then set isValidSlp = null to
|
||||
// signal that it's state can not be determined.
|
||||
|
||||
// Assumption: transaction is not a valid SLP UTXO.
|
||||
txDetails.isValidSlp = false
|
||||
|
||||
const outObj = {
|
||||
txData: txDetails
|
||||
}
|
||||
|
||||
return outObj
|
||||
} else throw error
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+11
-2
@@ -2,18 +2,27 @@
|
||||
High-level functions for working with Transactions
|
||||
*/
|
||||
|
||||
// Global npm libraries
|
||||
const BigNumber = require('bignumber.js')
|
||||
|
||||
// Local libraries
|
||||
const RawTransaction = require('./raw-transactions')
|
||||
const SlpUtils = require('./slp/utils')
|
||||
const Blockchain = require('./blockchain')
|
||||
const PsfSlpIndexer = require('./psf-slp-indexer')
|
||||
|
||||
class Transaction {
|
||||
constructor (config) {
|
||||
constructor (config = {}) {
|
||||
// Encapsulate dependencies
|
||||
this.slpUtils = new SlpUtils(config)
|
||||
this.rawTransaction = new RawTransaction(config)
|
||||
this.blockchain = new Blockchain(config)
|
||||
this.psfSlpIndexer = new PsfSlpIndexer(config)
|
||||
}
|
||||
|
||||
// Proxy the call to the psf-slp-indexer.
|
||||
async get (txid) {
|
||||
return await this.psfSlpIndexer.tx(txid)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -42,7 +51,7 @@ class Transaction {
|
||||
// CT 10/31/21: TODO: this function should be refactored to use get2(), but
|
||||
// add waterfall validation of the TX and its inputs.
|
||||
|
||||
async get (txid) {
|
||||
async getOld (txid) {
|
||||
try {
|
||||
if (typeof txid !== 'string') {
|
||||
throw new Error(
|
||||
|
||||
@@ -54,7 +54,7 @@ describe('#psf-slp-indexer', () => {
|
||||
})
|
||||
|
||||
describe('#tx', () => {
|
||||
it('should get hydrated tx data', async () => {
|
||||
it('should get hydrated tx data for an SLP transaction', async () => {
|
||||
const txid =
|
||||
'83361c34cac2ea7f9ca287fca57a96cc0763719f0cdf4850f9696c1e68eb635c'
|
||||
|
||||
@@ -64,6 +64,37 @@ describe('#psf-slp-indexer', () => {
|
||||
assert.property(result.txData, 'vin')
|
||||
assert.property(result.txData, 'vout')
|
||||
assert.property(result.txData, 'isValidSlp')
|
||||
assert.equal(result.txData.isValidSlp, true)
|
||||
})
|
||||
|
||||
it('should handle non-SLP transaction', async () => {
|
||||
const txid =
|
||||
'03d6e6b63647ce7b02ecc73dc6d41b485be14a3e20eed4474b8a840358ddf14e'
|
||||
|
||||
const result = await bchjs.PsfSlpIndexer.tx(txid)
|
||||
// console.log('result: ', result)
|
||||
|
||||
assert.property(result.txData, 'vin')
|
||||
assert.property(result.txData, 'vout')
|
||||
assert.property(result.txData, 'isValidSlp')
|
||||
assert.equal(result.txData.isValidSlp, false)
|
||||
})
|
||||
|
||||
// FlexUSD transactions
|
||||
// Currently FlexUSD UTXOs are reported as invalid SLP UTXOs, which means
|
||||
// the wallet will burn them. There is a TODO in the code. This test will
|
||||
// need to be changed when it is done.
|
||||
it('should handle a blacklisted token', async () => {
|
||||
const txid =
|
||||
'302113c11b90edc5f36c073d2f8a75e1e0eaf59b56235491a843d3819cd6a85f'
|
||||
|
||||
const result = await bchjs.PsfSlpIndexer.tx(txid)
|
||||
// console.log('result: ', result)
|
||||
|
||||
assert.property(result.txData, 'vin')
|
||||
assert.property(result.txData, 'vout')
|
||||
assert.property(result.txData, 'isValidSlp')
|
||||
assert.equal(result.txData.isValidSlp, false)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -11,12 +11,12 @@ describe('#Transaction', () => {
|
||||
if (process.env.IS_USING_FREE_TIER) await bchjs.Util.sleep(1000)
|
||||
})
|
||||
|
||||
describe('#get', () => {
|
||||
describe('#getOld', () => {
|
||||
it('should get details about a non-SLP transaction', async () => {
|
||||
const txid =
|
||||
'2b37bdb3b63dd0bca720437754a36671431a950e684b64c44ea910ea9d5297c7'
|
||||
|
||||
const result = await bchjs.Transaction.get(txid)
|
||||
const result = await bchjs.Transaction.getOld(txid)
|
||||
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
||||
|
||||
// Assert that there are stanardized properties.
|
||||
@@ -37,7 +37,7 @@ describe('#Transaction', () => {
|
||||
const txid =
|
||||
'266844d53e46bbd7dd37134688dffea6e54d944edff27a0add63dd0908839bc1'
|
||||
|
||||
const result = await bchjs.Transaction.get(txid)
|
||||
const result = await bchjs.Transaction.getOld(txid)
|
||||
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
||||
|
||||
// Assert that there are stanardized properties.
|
||||
@@ -69,9 +69,10 @@ describe('#Transaction', () => {
|
||||
// that is also a valid SLP tx, but is unrelated. Both TXs pass DAG validation,
|
||||
// but for separate tokens.
|
||||
it('should get problematic transaction', async () => {
|
||||
const txid = 'a19f2f395a8b0e15b6202944c56834367d128f1e3630486a4756de53424a46fe'
|
||||
const txid =
|
||||
'a19f2f395a8b0e15b6202944c56834367d128f1e3630486a4756de53424a46fe'
|
||||
|
||||
const result = await bchjs.Transaction.get(txid)
|
||||
const result = await bchjs.Transaction.getOld(txid)
|
||||
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
||||
|
||||
// The token ID should equal the txid for this Vin.
|
||||
|
||||
@@ -38,6 +38,7 @@ describe('#PsfSlpIndexer', () => {
|
||||
assert.include(err.message, 'test error')
|
||||
}
|
||||
})
|
||||
|
||||
it('should handle request error', async () => {
|
||||
try {
|
||||
// Stub the network call.
|
||||
@@ -239,20 +240,25 @@ describe('#PsfSlpIndexer', () => {
|
||||
assert.include(err.message, 'test error')
|
||||
}
|
||||
})
|
||||
it('should handle request error', async () => {
|
||||
try {
|
||||
// Stub the network call.
|
||||
const testErr = new Error()
|
||||
testErr.response = { data: { status: 422 } }
|
||||
sandbox.stub(axios, 'post').throws(testErr)
|
||||
|
||||
const txid =
|
||||
'a4fb5c2da1aa064e25018a43f9165040071d9e984ba190c222a7f59053af84b2'
|
||||
await bchjs.PsfSlpIndexer.tx(txid)
|
||||
assert.equal(true, false, 'Unexpected result!')
|
||||
} catch (err) {
|
||||
assert.equal(err.status, 422)
|
||||
it('should get tx from full node if not available from slp indexer', async () => {
|
||||
// Stub the call to the SLP indexer.
|
||||
const testErr = {
|
||||
response: { data: { error: 'Key not found in database' } }
|
||||
}
|
||||
sandbox.stub(axios, 'post').rejects(testErr)
|
||||
|
||||
// Stub the call to the full node
|
||||
sandbox
|
||||
.stub(bchjs.PsfSlpIndexer.rawTransaction, 'getTxData')
|
||||
.resolves({ txid: 'fakeTxid' })
|
||||
|
||||
const txid =
|
||||
'a4fb5c2da1aa064e25018a43f9165040071d9e984ba190c222a7f59053af84b2'
|
||||
const result = await bchjs.PsfSlpIndexer.tx(txid)
|
||||
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
||||
|
||||
assert.equal(result.txData.txid, 'fakeTxid')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -22,10 +22,10 @@ describe('#TransactionLib', () => {
|
||||
})
|
||||
afterEach(() => sandbox.restore())
|
||||
|
||||
describe('#get', () => {
|
||||
describe('#getOld', () => {
|
||||
it('should throw an error if txid is not specified', async () => {
|
||||
try {
|
||||
await bchjs.Transaction.get()
|
||||
await bchjs.Transaction.getOld()
|
||||
|
||||
assert.fail('Unexpected code path!')
|
||||
} catch (err) {
|
||||
@@ -45,7 +45,7 @@ describe('#TransactionLib', () => {
|
||||
.stub(bchjs.Transaction.rawTransaction, 'getTxData')
|
||||
.resolves(mockData.nonSlpTxDetails)
|
||||
|
||||
const result = await bchjs.Transaction.get(txid)
|
||||
const result = await bchjs.Transaction.getOld(txid)
|
||||
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
||||
|
||||
// Assert that there are stanardized properties.
|
||||
@@ -84,7 +84,7 @@ describe('#TransactionLib', () => {
|
||||
const txid =
|
||||
'266844d53e46bbd7dd37134688dffea6e54d944edff27a0add63dd0908839bc1'
|
||||
|
||||
const result = await bchjs.Transaction.get(txid)
|
||||
const result = await bchjs.Transaction.getOld(txid)
|
||||
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
||||
|
||||
// Assert that there are stanardized properties.
|
||||
@@ -114,7 +114,7 @@ describe('#TransactionLib', () => {
|
||||
.stub(bchjs.Transaction.rawTransaction, 'getTxData')
|
||||
.rejects(new Error('test error'))
|
||||
|
||||
await bchjs.Transaction.get(txid)
|
||||
await bchjs.Transaction.getOld(txid)
|
||||
|
||||
assert.fail('Unexpected code path')
|
||||
} catch (err) {
|
||||
@@ -147,7 +147,7 @@ describe('#TransactionLib', () => {
|
||||
const txid =
|
||||
'874306bda204d3a5dd15e03ea5732cccdca4c33a52df35162cdd64e30ea7f04e'
|
||||
|
||||
const result = await bchjs.Transaction.get(txid)
|
||||
const result = await bchjs.Transaction.getOld(txid)
|
||||
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
||||
|
||||
// Assert that there are stanardized properties.
|
||||
@@ -195,7 +195,7 @@ describe('#TransactionLib', () => {
|
||||
const txid =
|
||||
'4640a734063ea79fa587a3cac38a70a2f6f3db0011e23514024185982110d0fa'
|
||||
|
||||
const result = await bchjs.Transaction.get(txid)
|
||||
const result = await bchjs.Transaction.getOld(txid)
|
||||
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
||||
|
||||
// Assert that there are stanardized properties.
|
||||
@@ -246,7 +246,7 @@ describe('#TransactionLib', () => {
|
||||
const txid =
|
||||
'6bc111fbf5b118021d68355ca19a0e77fa358dd931f284b2550f79a51ab4792a'
|
||||
|
||||
const result = await bchjs.Transaction.get(txid)
|
||||
const result = await bchjs.Transaction.getOld(txid)
|
||||
// console.log(`result: ${JSON.stringify(result, null, 2)}`)
|
||||
|
||||
// Assert that there are stanardized properties.
|
||||
@@ -705,4 +705,15 @@ describe('#TransactionLib', () => {
|
||||
assert.equal(result.isSlpTx, true)
|
||||
})
|
||||
})
|
||||
|
||||
describe('#get', () => {
|
||||
it('should proxy psf-slp-indexer', async () => {
|
||||
// console.log('bchjs.Transaction: ', bchjs.Transaction)
|
||||
sandbox.stub(bchjs.Transaction.psfSlpIndexer, 'tx').resolves('test data')
|
||||
|
||||
const result = await bchjs.Transaction.get()
|
||||
|
||||
assert.equal(result, 'test data')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user