@psf/bch-js 4.22.1 → 5.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@psf/bch-js",
3
- "version": "4.22.1",
3
+ "version": "5.1.0",
4
4
  "description": "The FullStack.cash JavaScript library for Bitcoin Cash and SLP Tokens",
5
5
  "author": "Chris Troutner <chris.troutner@gmail.com>",
6
6
  "contributors": [
@@ -18,7 +18,7 @@
18
18
  "test:integration:local:abc": "export RESTURL=http://localhost:3000/v5/ && mocha --timeout 30000 test/integration && mocha --timeout 30000 test/integration/chains/abc/",
19
19
  "test:integration:local:bchn": "export RESTURL=http://localhost:3000/v5/ && mocha --timeout 30000 test/integration/ && mocha --timeout 30000 test/integration/chains/bchn/",
20
20
  "test:integration:local:testnet": "RESTURL=http://localhost:4000/v5/ mocha --timeout 30000 test/integration/chains/testnet",
21
- "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/",
21
+ "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/",
22
22
  "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/",
23
23
  "test:integration:temp:bchn": "export RESTURL=http://157.90.174.219:3000/v5/ && mocha --timeout 30000 test/integration/",
24
24
  "test:temp": "export RESTURL=http://localhost:3000/v5/ && mocha --timeout 30000 -g '#Encryption' test/integration/",
@@ -1,10 +1,17 @@
1
1
  /*
2
2
  This library interacts with the PSF slp indexer REST API endpoints operated
3
3
  by FullStack.cash
4
+
5
+ TODO:
6
+ - detect TXs from tokens in the blacklist.
4
7
  */
8
+
5
9
  // Public npm libraries
6
10
  const axios = require('axios')
7
11
 
12
+ // Local libraries
13
+ const RawTransaction = require('./raw-transactions')
14
+
8
15
  // let _this
9
16
 
10
17
  class PsfSlpIndexer {
@@ -29,6 +36,9 @@ class PsfSlpIndexer {
29
36
  }
30
37
  }
31
38
 
39
+ // Encapsulate dependencies
40
+ this.rawTransaction = new RawTransaction(config)
41
+
32
42
  // _this = this
33
43
  }
34
44
 
@@ -283,8 +293,38 @@ class PsfSlpIndexer {
283
293
  }
284
294
  throw new Error('Input txid must be a string.')
285
295
  } catch (error) {
286
- if (error.response && error.response.data) throw error.response.data
287
- else throw error
296
+ // console.log('error: ', error)
297
+
298
+ // Case: txid is not stored in the psf-slp-indexer tx database.
299
+ // Response: If it's not in the database, then it can be assumed the TX
300
+ // is not a token TX?
301
+ if (
302
+ error.response &&
303
+ error.response.data &&
304
+ error.response.data.error &&
305
+ error.response.data.error.includes('Key not found in database')
306
+ ) {
307
+ // console.log(
308
+ // 'TX not found in psf-slp-indexer. Retrieving from full node.'
309
+ // )
310
+
311
+ // Get the TX Details from the full node.
312
+ const txDetails = await this.rawTransaction.getTxData(txid)
313
+ // console.log(`txDetails: ${JSON.stringify(txDetails, null, 2)}`)
314
+
315
+ // TODO: Run the TX through decodeOpReturn() to see if it has a tokenID
316
+ // that is in the blacklist. If it is, then set isValidSlp = null to
317
+ // signal that it's state can not be determined.
318
+
319
+ // Assumption: transaction is not a valid SLP UTXO.
320
+ txDetails.isValidSlp = false
321
+
322
+ const outObj = {
323
+ txData: txDetails
324
+ }
325
+
326
+ return outObj
327
+ } else throw error
288
328
  }
289
329
  }
290
330
  }
@@ -2,18 +2,27 @@
2
2
  High-level functions for working with Transactions
3
3
  */
4
4
 
5
+ // Global npm libraries
5
6
  const BigNumber = require('bignumber.js')
6
7
 
8
+ // Local libraries
7
9
  const RawTransaction = require('./raw-transactions')
8
10
  const SlpUtils = require('./slp/utils')
9
11
  const Blockchain = require('./blockchain')
12
+ const PsfSlpIndexer = require('./psf-slp-indexer')
10
13
 
11
14
  class Transaction {
12
- constructor (config) {
15
+ constructor (config = {}) {
13
16
  // Encapsulate dependencies
14
17
  this.slpUtils = new SlpUtils(config)
15
18
  this.rawTransaction = new RawTransaction(config)
16
19
  this.blockchain = new Blockchain(config)
20
+ this.psfSlpIndexer = new PsfSlpIndexer(config)
21
+ }
22
+
23
+ // Proxy the call to the psf-slp-indexer.
24
+ async get (txid) {
25
+ return await this.psfSlpIndexer.tx(txid)
17
26
  }
18
27
 
19
28
  /**
@@ -42,7 +51,7 @@ class Transaction {
42
51
  // CT 10/31/21: TODO: this function should be refactored to use get2(), but
43
52
  // add waterfall validation of the TX and its inputs.
44
53
 
45
- async get (txid) {
54
+ async getOld (txid) {
46
55
  try {
47
56
  if (typeof txid !== 'string') {
48
57
  throw new Error(
@@ -54,7 +54,7 @@ describe('#psf-slp-indexer', () => {
54
54
  })
55
55
 
56
56
  describe('#tx', () => {
57
- it('should get hydrated tx data', async () => {
57
+ it('should get hydrated tx data for an SLP transaction', async () => {
58
58
  const txid =
59
59
  '83361c34cac2ea7f9ca287fca57a96cc0763719f0cdf4850f9696c1e68eb635c'
60
60
 
@@ -64,6 +64,37 @@ describe('#psf-slp-indexer', () => {
64
64
  assert.property(result.txData, 'vin')
65
65
  assert.property(result.txData, 'vout')
66
66
  assert.property(result.txData, 'isValidSlp')
67
+ assert.equal(result.txData.isValidSlp, true)
68
+ })
69
+
70
+ it('should handle non-SLP transaction', async () => {
71
+ const txid =
72
+ '03d6e6b63647ce7b02ecc73dc6d41b485be14a3e20eed4474b8a840358ddf14e'
73
+
74
+ const result = await bchjs.PsfSlpIndexer.tx(txid)
75
+ // console.log('result: ', result)
76
+
77
+ assert.property(result.txData, 'vin')
78
+ assert.property(result.txData, 'vout')
79
+ assert.property(result.txData, 'isValidSlp')
80
+ assert.equal(result.txData.isValidSlp, false)
81
+ })
82
+
83
+ // FlexUSD transactions
84
+ // Currently FlexUSD UTXOs are reported as invalid SLP UTXOs, which means
85
+ // the wallet will burn them. There is a TODO in the code. This test will
86
+ // need to be changed when it is done.
87
+ it('should handle a blacklisted token', async () => {
88
+ const txid =
89
+ '302113c11b90edc5f36c073d2f8a75e1e0eaf59b56235491a843d3819cd6a85f'
90
+
91
+ const result = await bchjs.PsfSlpIndexer.tx(txid)
92
+ // console.log('result: ', result)
93
+
94
+ assert.property(result.txData, 'vin')
95
+ assert.property(result.txData, 'vout')
96
+ assert.property(result.txData, 'isValidSlp')
97
+ assert.equal(result.txData.isValidSlp, false)
67
98
  })
68
99
  })
69
100
  })
@@ -11,12 +11,12 @@ describe('#Transaction', () => {
11
11
  if (process.env.IS_USING_FREE_TIER) await bchjs.Util.sleep(1000)
12
12
  })
13
13
 
14
- describe('#get', () => {
14
+ describe('#getOld', () => {
15
15
  it('should get details about a non-SLP transaction', async () => {
16
16
  const txid =
17
17
  '2b37bdb3b63dd0bca720437754a36671431a950e684b64c44ea910ea9d5297c7'
18
18
 
19
- const result = await bchjs.Transaction.get(txid)
19
+ const result = await bchjs.Transaction.getOld(txid)
20
20
  // console.log(`result: ${JSON.stringify(result, null, 2)}`)
21
21
 
22
22
  // Assert that there are stanardized properties.
@@ -37,7 +37,7 @@ describe('#Transaction', () => {
37
37
  const txid =
38
38
  '266844d53e46bbd7dd37134688dffea6e54d944edff27a0add63dd0908839bc1'
39
39
 
40
- const result = await bchjs.Transaction.get(txid)
40
+ const result = await bchjs.Transaction.getOld(txid)
41
41
  // console.log(`result: ${JSON.stringify(result, null, 2)}`)
42
42
 
43
43
  // Assert that there are stanardized properties.
@@ -69,9 +69,10 @@ describe('#Transaction', () => {
69
69
  // that is also a valid SLP tx, but is unrelated. Both TXs pass DAG validation,
70
70
  // but for separate tokens.
71
71
  it('should get problematic transaction', async () => {
72
- const txid = 'a19f2f395a8b0e15b6202944c56834367d128f1e3630486a4756de53424a46fe'
72
+ const txid =
73
+ 'a19f2f395a8b0e15b6202944c56834367d128f1e3630486a4756de53424a46fe'
73
74
 
74
- const result = await bchjs.Transaction.get(txid)
75
+ const result = await bchjs.Transaction.getOld(txid)
75
76
  // console.log(`result: ${JSON.stringify(result, null, 2)}`)
76
77
 
77
78
  // The token ID should equal the txid for this Vin.
@@ -38,6 +38,7 @@ describe('#PsfSlpIndexer', () => {
38
38
  assert.include(err.message, 'test error')
39
39
  }
40
40
  })
41
+
41
42
  it('should handle request error', async () => {
42
43
  try {
43
44
  // Stub the network call.
@@ -239,20 +240,25 @@ describe('#PsfSlpIndexer', () => {
239
240
  assert.include(err.message, 'test error')
240
241
  }
241
242
  })
242
- it('should handle request error', async () => {
243
- try {
244
- // Stub the network call.
245
- const testErr = new Error()
246
- testErr.response = { data: { status: 422 } }
247
- sandbox.stub(axios, 'post').throws(testErr)
248
243
 
249
- const txid =
250
- 'a4fb5c2da1aa064e25018a43f9165040071d9e984ba190c222a7f59053af84b2'
251
- await bchjs.PsfSlpIndexer.tx(txid)
252
- assert.equal(true, false, 'Unexpected result!')
253
- } catch (err) {
254
- assert.equal(err.status, 422)
244
+ it('should get tx from full node if not available from slp indexer', async () => {
245
+ // Stub the call to the SLP indexer.
246
+ const testErr = {
247
+ response: { data: { error: 'Key not found in database' } }
255
248
  }
249
+ sandbox.stub(axios, 'post').rejects(testErr)
250
+
251
+ // Stub the call to the full node
252
+ sandbox
253
+ .stub(bchjs.PsfSlpIndexer.rawTransaction, 'getTxData')
254
+ .resolves({ txid: 'fakeTxid' })
255
+
256
+ const txid =
257
+ 'a4fb5c2da1aa064e25018a43f9165040071d9e984ba190c222a7f59053af84b2'
258
+ const result = await bchjs.PsfSlpIndexer.tx(txid)
259
+ // console.log(`result: ${JSON.stringify(result, null, 2)}`)
260
+
261
+ assert.equal(result.txData.txid, 'fakeTxid')
256
262
  })
257
263
  })
258
264
  })
@@ -22,10 +22,10 @@ describe('#TransactionLib', () => {
22
22
  })
23
23
  afterEach(() => sandbox.restore())
24
24
 
25
- describe('#get', () => {
25
+ describe('#getOld', () => {
26
26
  it('should throw an error if txid is not specified', async () => {
27
27
  try {
28
- await bchjs.Transaction.get()
28
+ await bchjs.Transaction.getOld()
29
29
 
30
30
  assert.fail('Unexpected code path!')
31
31
  } catch (err) {
@@ -45,7 +45,7 @@ describe('#TransactionLib', () => {
45
45
  .stub(bchjs.Transaction.rawTransaction, 'getTxData')
46
46
  .resolves(mockData.nonSlpTxDetails)
47
47
 
48
- const result = await bchjs.Transaction.get(txid)
48
+ const result = await bchjs.Transaction.getOld(txid)
49
49
  // console.log(`result: ${JSON.stringify(result, null, 2)}`)
50
50
 
51
51
  // Assert that there are stanardized properties.
@@ -84,7 +84,7 @@ describe('#TransactionLib', () => {
84
84
  const txid =
85
85
  '266844d53e46bbd7dd37134688dffea6e54d944edff27a0add63dd0908839bc1'
86
86
 
87
- const result = await bchjs.Transaction.get(txid)
87
+ const result = await bchjs.Transaction.getOld(txid)
88
88
  // console.log(`result: ${JSON.stringify(result, null, 2)}`)
89
89
 
90
90
  // Assert that there are stanardized properties.
@@ -114,7 +114,7 @@ describe('#TransactionLib', () => {
114
114
  .stub(bchjs.Transaction.rawTransaction, 'getTxData')
115
115
  .rejects(new Error('test error'))
116
116
 
117
- await bchjs.Transaction.get(txid)
117
+ await bchjs.Transaction.getOld(txid)
118
118
 
119
119
  assert.fail('Unexpected code path')
120
120
  } catch (err) {
@@ -147,7 +147,7 @@ describe('#TransactionLib', () => {
147
147
  const txid =
148
148
  '874306bda204d3a5dd15e03ea5732cccdca4c33a52df35162cdd64e30ea7f04e'
149
149
 
150
- const result = await bchjs.Transaction.get(txid)
150
+ const result = await bchjs.Transaction.getOld(txid)
151
151
  // console.log(`result: ${JSON.stringify(result, null, 2)}`)
152
152
 
153
153
  // Assert that there are stanardized properties.
@@ -195,7 +195,7 @@ describe('#TransactionLib', () => {
195
195
  const txid =
196
196
  '4640a734063ea79fa587a3cac38a70a2f6f3db0011e23514024185982110d0fa'
197
197
 
198
- const result = await bchjs.Transaction.get(txid)
198
+ const result = await bchjs.Transaction.getOld(txid)
199
199
  // console.log(`result: ${JSON.stringify(result, null, 2)}`)
200
200
 
201
201
  // Assert that there are stanardized properties.
@@ -246,7 +246,7 @@ describe('#TransactionLib', () => {
246
246
  const txid =
247
247
  '6bc111fbf5b118021d68355ca19a0e77fa358dd931f284b2550f79a51ab4792a'
248
248
 
249
- const result = await bchjs.Transaction.get(txid)
249
+ const result = await bchjs.Transaction.getOld(txid)
250
250
  // console.log(`result: ${JSON.stringify(result, null, 2)}`)
251
251
 
252
252
  // Assert that there are stanardized properties.
@@ -705,4 +705,15 @@ describe('#TransactionLib', () => {
705
705
  assert.equal(result.isSlpTx, true)
706
706
  })
707
707
  })
708
+
709
+ describe('#get', () => {
710
+ it('should proxy psf-slp-indexer', async () => {
711
+ // console.log('bchjs.Transaction: ', bchjs.Transaction)
712
+ sandbox.stub(bchjs.Transaction.psfSlpIndexer, 'tx').resolves('test data')
713
+
714
+ const result = await bchjs.Transaction.get()
715
+
716
+ assert.equal(result, 'test data')
717
+ })
718
+ })
708
719
  })