mirror of
https://github.com/Permissionless-Software-Foundation/bch-js.git
synced 2026-09-21 16:51:59 -07:00
Merge pull request #112 from Permissionless-Software-Foundation/ct-unstable
fix(decodeOpReturn): Switching to POST from GET to getRawTx call
This commit is contained in:
@@ -19,6 +19,7 @@
|
|||||||
"test:temp": "export RESTURL=http://localhost:3000/v4/ && mocha --timeout 30000 -g '#hydrateUtxos' test/integration/",
|
"test:temp": "export RESTURL=http://localhost:3000/v4/ && mocha --timeout 30000 -g '#hydrateUtxos' test/integration/",
|
||||||
"test:temp2": "mocha --timeout=30000 -g '#Util' test/unit/",
|
"test:temp2": "mocha --timeout=30000 -g '#Util' test/unit/",
|
||||||
"test:temp3": "export RESTURL=https://bchn.fullstack.cash/v4/ && mocha --timeout 30000 -g '#hydrateUtxos' test/integration/",
|
"test:temp3": "export RESTURL=https://bchn.fullstack.cash/v4/ && mocha --timeout 30000 -g '#hydrateUtxos' test/integration/",
|
||||||
|
"test:temp4": "export RESTURL=http://localhost:3000/v4/ && mocha --timeout 30000 -g '#decodeOpReturn' test/integration/",
|
||||||
"coverage": "nyc report --reporter=text-lcov | coveralls",
|
"coverage": "nyc report --reporter=text-lcov | coveralls",
|
||||||
"coverage:report": "nyc --reporter=html mocha --timeout 25000 test/unit/",
|
"coverage:report": "nyc --reporter=html mocha --timeout 25000 test/unit/",
|
||||||
"docs": "./node_modules/.bin/apidoc -i src/ -o docs",
|
"docs": "./node_modules/.bin/apidoc -i src/ -o docs",
|
||||||
|
|||||||
+36
-10
@@ -655,7 +655,7 @@ class Utils {
|
|||||||
|
|
||||||
// console.log(`txid: ${JSON.stringify(txid, null, 2)}`)
|
// console.log(`txid: ${JSON.stringify(txid, null, 2)}`)
|
||||||
// console.log(`path: ${JSON.stringify(path, null, 2)}`)
|
// console.log(`path: ${JSON.stringify(path, null, 2)}`)
|
||||||
console.log('ip: ', ip)
|
console.log('validateTxid3 ip: ', ip)
|
||||||
|
|
||||||
// Handle a single TXID or an array of TXIDs.
|
// Handle a single TXID or an array of TXIDs.
|
||||||
let txids
|
let txids
|
||||||
@@ -925,7 +925,7 @@ class Utils {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
// Reimplementation of decodeOpReturn() using slp-parser.
|
// Reimplementation of decodeOpReturn() using slp-parser.
|
||||||
async decodeOpReturn (txid, cache = null) {
|
async decodeOpReturn (txid, cache = null, ip = null) {
|
||||||
// The cache object is an in-memory cache (JS Object) that can be passed
|
// The cache object is an in-memory cache (JS Object) that can be passed
|
||||||
// into this function. It helps if multiple vouts from the same TXID are
|
// into this function. It helps if multiple vouts from the same TXID are
|
||||||
// being evaluated. In that case, it can significantly reduce the number
|
// being evaluated. In that case, it can significantly reduce the number
|
||||||
@@ -942,16 +942,32 @@ class Utils {
|
|||||||
if (cachedVal) return cachedVal
|
if (cachedVal) return cachedVal
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log(`decodeOpReturn ip: ${ip}`)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Validate the txid input.
|
// Validate the txid input.
|
||||||
if (!txid || txid === '' || typeof txid !== 'string') {
|
if (!txid || txid === '' || typeof txid !== 'string') {
|
||||||
throw new Error('txid string must be included.')
|
throw new Error('txid string must be included.')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CT: 2/24/21 Deprected GET in favor of POST, to pass IP address.
|
||||||
// Retrieve the transaction object from the full node.
|
// Retrieve the transaction object from the full node.
|
||||||
const path = `${this.restURL}rawtransactions/getRawTransaction/${txid}?verbose=true`
|
// const path = `${this.restURL}rawtransactions/getRawTransaction/${txid}?verbose=true`
|
||||||
const response = await _this.axios.get(path, _this.axiosOptions)
|
// const response = await _this.axios.get(path, _this.axiosOptions)
|
||||||
const txDetails = response.data
|
// const txDetails = response.data
|
||||||
|
|
||||||
|
const path = `${this.restURL}rawtransactions/getRawTransaction`
|
||||||
|
const response = await _this.axios.post(
|
||||||
|
path,
|
||||||
|
{
|
||||||
|
verbose: true,
|
||||||
|
txids: [txid],
|
||||||
|
ip
|
||||||
|
},
|
||||||
|
_this.axiosOptions
|
||||||
|
)
|
||||||
|
const txDetails = response.data[0]
|
||||||
|
|
||||||
// console.log(`txDetails: ${JSON.stringify(txDetails, null, 2)}`)
|
// console.log(`txDetails: ${JSON.stringify(txDetails, null, 2)}`)
|
||||||
|
|
||||||
// SLP spec expects OP_RETURN to be the first output of the transaction.
|
// SLP spec expects OP_RETURN to be the first output of the transaction.
|
||||||
@@ -1069,6 +1085,8 @@ class Utils {
|
|||||||
// Throw error if input is not an array.
|
// Throw error if input is not an array.
|
||||||
if (!Array.isArray(utxos)) throw new Error('Input must be an array.')
|
if (!Array.isArray(utxos)) throw new Error('Input must be an array.')
|
||||||
|
|
||||||
|
console.log(`tokenUtxoDetails ip: ${ip}`)
|
||||||
|
|
||||||
// Loop through each element in the array and validate the input before
|
// Loop through each element in the array and validate the input before
|
||||||
// further processing.
|
// further processing.
|
||||||
for (let i = 0; i < utxos.length; i++) {
|
for (let i = 0; i < utxos.length; i++) {
|
||||||
@@ -1100,7 +1118,7 @@ class Utils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Hydrate each UTXO with data from SLP OP_REUTRNs.
|
// Hydrate each UTXO with data from SLP OP_REUTRNs.
|
||||||
const outAry = await this._hydrateUtxo(utxos)
|
const outAry = await this._hydrateUtxo(utxos, ip)
|
||||||
// console.log(`outAry: ${JSON.stringify(outAry, null, 2)}`)
|
// console.log(`outAry: ${JSON.stringify(outAry, null, 2)}`)
|
||||||
|
|
||||||
// *After* each UTXO has been hydrated with SLP data,
|
// *After* each UTXO has been hydrated with SLP data,
|
||||||
@@ -1220,10 +1238,12 @@ class Utils {
|
|||||||
// This is a private function that is called by tokenUtxoDetails().
|
// This is a private function that is called by tokenUtxoDetails().
|
||||||
// It loops through an array of UTXOs and tries to hydrate them with SLP
|
// It loops through an array of UTXOs and tries to hydrate them with SLP
|
||||||
// token information from the OP_RETURN data.
|
// token information from the OP_RETURN data.
|
||||||
async _hydrateUtxo (utxos) {
|
async _hydrateUtxo (utxos, ip = null) {
|
||||||
try {
|
try {
|
||||||
const decodeOpReturnCache = {}
|
const decodeOpReturnCache = {}
|
||||||
|
|
||||||
|
console.log(`_hydrateUtxo ip: ${ip}`)
|
||||||
|
|
||||||
// Output Array
|
// Output Array
|
||||||
const outAry = []
|
const outAry = []
|
||||||
|
|
||||||
@@ -1236,7 +1256,11 @@ class Utils {
|
|||||||
// If there is no OP_RETURN, mark the UTXO as false.
|
// If there is no OP_RETURN, mark the UTXO as false.
|
||||||
let slpData = false
|
let slpData = false
|
||||||
try {
|
try {
|
||||||
slpData = await this.decodeOpReturn(utxo.txid, decodeOpReturnCache)
|
slpData = await this.decodeOpReturn(
|
||||||
|
utxo.txid,
|
||||||
|
decodeOpReturnCache,
|
||||||
|
ip
|
||||||
|
)
|
||||||
// console.log(`slpData: ${JSON.stringify(slpData, null, 2)}`)
|
// console.log(`slpData: ${JSON.stringify(slpData, null, 2)}`)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// console.log(`error from decodeOpReturn(${utxo.txid}): `, err)
|
// console.log(`error from decodeOpReturn(${utxo.txid}): `, err)
|
||||||
@@ -1326,7 +1350,8 @@ class Utils {
|
|||||||
|
|
||||||
const genesisData = await this.decodeOpReturn(
|
const genesisData = await this.decodeOpReturn(
|
||||||
slpData.tokenId,
|
slpData.tokenId,
|
||||||
decodeOpReturnCache
|
decodeOpReturnCache,
|
||||||
|
ip
|
||||||
)
|
)
|
||||||
// console.log(`genesisData: ${JSON.stringify(genesisData, null, 2)}`)
|
// console.log(`genesisData: ${JSON.stringify(genesisData, null, 2)}`)
|
||||||
|
|
||||||
@@ -1378,7 +1403,8 @@ class Utils {
|
|||||||
|
|
||||||
const genesisData = await this.decodeOpReturn(
|
const genesisData = await this.decodeOpReturn(
|
||||||
slpData.tokenId,
|
slpData.tokenId,
|
||||||
decodeOpReturnCache
|
decodeOpReturnCache,
|
||||||
|
ip
|
||||||
)
|
)
|
||||||
// console.log(`genesisData: ${JSON.stringify(genesisData, null, 2)}`)
|
// console.log(`genesisData: ${JSON.stringify(genesisData, null, 2)}`)
|
||||||
|
|
||||||
|
|||||||
+18
-18
@@ -273,8 +273,8 @@ describe('#SLP Utils', () => {
|
|||||||
try {
|
try {
|
||||||
// Mock the call to the REST API
|
// Mock the call to the REST API
|
||||||
sandbox
|
sandbox
|
||||||
.stub(uut.Utils.axios, 'get')
|
.stub(uut.Utils.axios, 'post')
|
||||||
.resolves({ data: mockData.nonSLPTxDetailsWithoutOpReturn })
|
.resolves({ data: [mockData.nonSLPTxDetailsWithoutOpReturn] })
|
||||||
|
|
||||||
const txid =
|
const txid =
|
||||||
'3793d4906654f648e659f384c0f40b19c8f10c1e9fb72232a9b8edd61abaa1ec'
|
'3793d4906654f648e659f384c0f40b19c8f10c1e9fb72232a9b8edd61abaa1ec'
|
||||||
@@ -292,8 +292,8 @@ describe('#SLP Utils', () => {
|
|||||||
try {
|
try {
|
||||||
// Mock the call to the REST API
|
// Mock the call to the REST API
|
||||||
sandbox
|
sandbox
|
||||||
.stub(uut.Utils.axios, 'get')
|
.stub(uut.Utils.axios, 'post')
|
||||||
.resolves({ data: mockData.nonSLPTxDetailsWithOpReturn })
|
.resolves({ data: [mockData.nonSLPTxDetailsWithOpReturn] })
|
||||||
|
|
||||||
const txid =
|
const txid =
|
||||||
'2ff74c48a5d657cf45f699601990bffbbe7a2a516d5480674cbf6c6a4497908f'
|
'2ff74c48a5d657cf45f699601990bffbbe7a2a516d5480674cbf6c6a4497908f'
|
||||||
@@ -310,8 +310,8 @@ describe('#SLP Utils', () => {
|
|||||||
it('should decode a genesis transaction', async () => {
|
it('should decode a genesis transaction', async () => {
|
||||||
// Mock the call to the REST API
|
// Mock the call to the REST API
|
||||||
sandbox
|
sandbox
|
||||||
.stub(uut.Utils.axios, 'get')
|
.stub(uut.Utils.axios, 'post')
|
||||||
.resolves({ data: mockData.txDetailsSLPGenesis })
|
.resolves({ data: [mockData.txDetailsSLPGenesis] })
|
||||||
|
|
||||||
const txid =
|
const txid =
|
||||||
'bd158c564dd4ef54305b14f44f8e94c44b649f246dab14bcb42fb0d0078b8a90'
|
'bd158c564dd4ef54305b14f44f8e94c44b649f246dab14bcb42fb0d0078b8a90'
|
||||||
@@ -336,8 +336,8 @@ describe('#SLP Utils', () => {
|
|||||||
it('should decode a mint transaction', async () => {
|
it('should decode a mint transaction', async () => {
|
||||||
// Mock the call to the REST API
|
// Mock the call to the REST API
|
||||||
sandbox
|
sandbox
|
||||||
.stub(uut.Utils.axios, 'get')
|
.stub(uut.Utils.axios, 'post')
|
||||||
.resolves({ data: mockData.txDetailsSLPMint })
|
.resolves({ data: [mockData.txDetailsSLPMint] })
|
||||||
|
|
||||||
const txid =
|
const txid =
|
||||||
'65f21bbfcd545e5eb515e38e861a9dfe2378aaa2c4e458eb9e59e4d40e38f3a4'
|
'65f21bbfcd545e5eb515e38e861a9dfe2378aaa2c4e458eb9e59e4d40e38f3a4'
|
||||||
@@ -357,8 +357,8 @@ describe('#SLP Utils', () => {
|
|||||||
it('should decode a send transaction', async () => {
|
it('should decode a send transaction', async () => {
|
||||||
// Mock the call to the REST API
|
// Mock the call to the REST API
|
||||||
sandbox
|
sandbox
|
||||||
.stub(uut.Utils.axios, 'get')
|
.stub(uut.Utils.axios, 'post')
|
||||||
.resolves({ data: mockData.txDetailsSLPSend })
|
.resolves({ data: [mockData.txDetailsSLPSend] })
|
||||||
|
|
||||||
const txid =
|
const txid =
|
||||||
'4f922565af664b6fdf0a1ba3924487344be721b3d8815c62cafc8a51e04a8afa'
|
'4f922565af664b6fdf0a1ba3924487344be721b3d8815c62cafc8a51e04a8afa'
|
||||||
@@ -372,8 +372,8 @@ describe('#SLP Utils', () => {
|
|||||||
it('should properly decode a Genesis transaction with no minting baton', async () => {
|
it('should properly decode a Genesis transaction with no minting baton', async () => {
|
||||||
// Mock the call to the REST API.
|
// Mock the call to the REST API.
|
||||||
sandbox
|
sandbox
|
||||||
.stub(uut.Utils.axios, 'get')
|
.stub(uut.Utils.axios, 'post')
|
||||||
.resolves({ data: mockData.txDetailsSLPGenesisNoBaton })
|
.resolves({ data: [mockData.txDetailsSLPGenesisNoBaton] })
|
||||||
|
|
||||||
const txid =
|
const txid =
|
||||||
'497291b8a1dfe69c8daea50677a3d31a5ef0e9484d8bebb610dac64bbc202fb7'
|
'497291b8a1dfe69c8daea50677a3d31a5ef0e9484d8bebb610dac64bbc202fb7'
|
||||||
@@ -387,8 +387,8 @@ describe('#SLP Utils', () => {
|
|||||||
it('should decode a send transaction with alternate encoding', async () => {
|
it('should decode a send transaction with alternate encoding', async () => {
|
||||||
// Mock the call to the REST API
|
// Mock the call to the REST API
|
||||||
sandbox
|
sandbox
|
||||||
.stub(uut.Utils.axios, 'get')
|
.stub(uut.Utils.axios, 'post')
|
||||||
.resolves({ data: mockData.txDetailsSLPSendAlt })
|
.resolves({ data: [mockData.txDetailsSLPSendAlt] })
|
||||||
|
|
||||||
const txid =
|
const txid =
|
||||||
'd94357179775425ebc59c93173bd6dc9854095f090a2eb9dcfe9797398bc8eae'
|
'd94357179775425ebc59c93173bd6dc9854095f090a2eb9dcfe9797398bc8eae'
|
||||||
@@ -411,8 +411,8 @@ describe('#SLP Utils', () => {
|
|||||||
try {
|
try {
|
||||||
// Mock the call to the REST API
|
// Mock the call to the REST API
|
||||||
sandbox
|
sandbox
|
||||||
.stub(uut.Utils.axios, 'get')
|
.stub(uut.Utils.axios, 'post')
|
||||||
.resolves({ data: mockData.mockInvalidSlpSend })
|
.resolves({ data: [mockData.mockInvalidSlpSend] })
|
||||||
|
|
||||||
const txid =
|
const txid =
|
||||||
'a60a522cc11ad7011b74e57fbabbd99296e4b9346bcb175dcf84efb737030415'
|
'a60a522cc11ad7011b74e57fbabbd99296e4b9346bcb175dcf84efb737030415'
|
||||||
@@ -428,8 +428,8 @@ describe('#SLP Utils', () => {
|
|||||||
it('should decode a NFT Parent transaction', async () => {
|
it('should decode a NFT Parent transaction', async () => {
|
||||||
// Mock the call to the REST API.
|
// Mock the call to the REST API.
|
||||||
sandbox
|
sandbox
|
||||||
.stub(uut.Utils.axios, 'get')
|
.stub(uut.Utils.axios, 'post')
|
||||||
.resolves({ data: mockData.txDetailsSLPNftGenesis })
|
.resolves({ data: [mockData.txDetailsSLPNftGenesis] })
|
||||||
|
|
||||||
const txid =
|
const txid =
|
||||||
'4ef6eb92950a13a69e97c2c02c7967d806aa874c0e2a6b5546a8880f2cd14bc4'
|
'4ef6eb92950a13a69e97c2c02c7967d806aa874c0e2a6b5546a8880f2cd14bc4'
|
||||||
|
|||||||
Reference in New Issue
Block a user