@psf/bch-js 6.2.9 → 6.2.12

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/README.md CHANGED
@@ -5,7 +5,7 @@
5
5
  [![License](https://img.shields.io/npm/l/@psf/bch-js)](https://github.com/Permissionless-Software-Foundation/bch-js/blob/master/LICENSE.md)
6
6
  [![js-standard-style](https://img.shields.io/badge/javascript-standard%20code%20style-green.svg?style=flat-square)](https://github.com/feross/standard) [![Join the chat at https://gitter.im/Permissionless-Software-Foundation/bch-js](https://badges.gitter.im/Permissionless-Software-Foundation/bch-js.svg)](https://gitter.im/Permissionless-Software-Foundation/bch-js?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
7
7
 
8
- [bch-js](https://www.npmjs.com/package/@psf/bch-js) is a JavaScript npm library for creating web and mobile apps that can interact with the Bitcoin Cash (BCH) blockchains. It can be used for free, but requires an account on [FullStack.cash](https://fullstack.cash) for increased rate limits. Learn more from [this article](https://troutsblog.com/research/bitcoin-cash/how-to-bch-full-stack-developer) about Full Stack Bitcoin Cash development.
8
+ [bch-js](https://www.npmjs.com/package/@psf/bch-js) is a JavaScript npm library for creating web and mobile apps that can interact with the Bitcoin Cash (BCH) and eCash (XEC) blockchains. bch-js contains a toolbox of handy tools, and an easy API for talking with [bch-api REST API](https://github.com/Permissionless-Software-Foundation/bch-api). [FullStack.cash](https://fullstack.cash) offers paid cloud access to bch-api. You can run your own infrastructure by following documentation on [CashStack.info](https://cashstack.info).
9
9
 
10
10
  ### Quick Start Videos:
11
11
 
@@ -23,6 +23,7 @@ Here are two YouTube walk-through videos to help you get started:
23
23
  - [FullStack.cash](https://fullstack.cash) - cloud-based infrastructure for application developers.
24
24
  - [FullStack.cash Account](https://fullstack.cash/login) - Get your API key to unlock increased rate limits.
25
25
  - [Permissionless Software Foundation](https://psfoundation.cash) - The organization that maintains this library.
26
+ - [CashStack.info](https://cashstack.info) - bch-js is part of the Cash Stack, a JavaScript framework for writing web 2 and web 3 business applications.
26
27
 
27
28
  ### Quick Notes
28
29
 
@@ -42,10 +43,10 @@ the [bch-api](https://github.com/Permissionless-Software-Foundation/bch-api) RES
42
43
  - ABC Mainnet REST API server: https://abc.fullstack.cash/v5/
43
44
  - Check server status: https://metrics.fullstack.cash
44
45
 
45
- ### API Key
46
+ ### API Key (JWT Token)
46
47
 
47
48
  The [bch-api](https://github.com/Permissionless-Software-Foundation/bch-api) REST API hosted by [FullStack.cash](https://fullstack.cash) uses JWT tokens to pay for increased
48
- rate limits when interacting with the back end server. See [this article](https://troutsblog.com/research/bitcoin-cash/how-to-bch-full-stack-developer) if you want to understand the system-as-a-whole. The JWT token can be fed to bch-js _implicitly_ or _explicitly_.
49
+ rate limits when interacting with the back end server. See [this article](https://cashstack.info) if you want to understand the system-as-a-whole. The JWT token can be fed to bch-js _implicitly_ or _explicitly_.
49
50
 
50
51
  - Implicitly: bch-js will detect your JWT token if you set the `BCHJSTOKEN` environment variable.
51
52
  - Explicitly: You can directly feed in the JWT token with the `apiToken` property when instantiating the library. Here is an example:
@@ -58,38 +59,25 @@ let bchjs = new BCHJS({
58
59
  })
59
60
  ```
60
61
 
61
- ### Gatsby
62
+ ### Gatsby & Web Apps
62
63
 
63
- bch-js is included in this [gatsby-ipfs-template](https://github.com/Permissionless-Software-Foundation/gatsby-ipfs-template) for building uncensorable web apps that can interact with the blockchain. When building a Gatsby (or other front-end app that uses Webpack), you'll need to add these lines to your `gatsby-node.js` file, as per [this issue](https://github.com/gatsbyjs/gatsby/issues/564):
64
+ [minimal-slp-wallet](https://www.npmjs.com/package/minimal-slp-wallet) is a minimal wallet 'engine' that incorporates bch-js. It's compiled with Browserify for front end apps.
64
65
 
65
- ```
66
- exports.onCreateWebpackConfig = ({ actions }) => {
67
- actions.setWebpackConfig({
68
- node: {
69
- fs: 'empty'
70
- }
71
- })
72
- }
73
- ```
74
-
75
- This is because the new IPFS class in bch-js uses the fs library for uploading files, which is not supported by Gatsby.
66
+ [gatsby-theme-bch-wallet](https://github.com/Permissionless-Software-Foundation/gatsby-theme-bch-wallet) is a Gatsby Theme and [bch-wallet-starter](https://github.com/Permissionless-Software-Foundation/bch-wallet-starter) is a Gatsby Starter for building web wallets using minimal-slp-wallet.
76
67
 
77
- We also provide [minimal-slp-wallet-web](https://www.npmjs.com/package/minimal-slp-wallet-web) as a basic Bitcoin Cash wallet with SLP support, for front end projects. bch-js is encapsulated inside the instantiation of the library Class.
68
+ [This gist](https://gist.github.com/christroutner/6cb9d1b615f3f9363af79723157bc434) shows how to include minimal-slp-wallet into a basic web page without using a framework.
78
69
 
79
70
  ## Features
80
71
 
81
72
  - [ECMAScript 2017 standard JavaScript](https://en.wikipedia.org/wiki/ECMAScript#8th_Edition_-_ECMAScript_2017) used instead of TypeScript. Works
82
73
  natively with node.js v10 or higher.
83
74
 
84
- - Full SLP tokens support: bch-js has full support for all SLP token functionality, including send, mint, and genesis transactions. It also fully support all aspects of [non-fugible tokans (NFTs)](https://www.youtube.com/watch?v=vvlpYUx6HRs).
75
+ - Full SLP tokens support: bch-js has full support for all SLP token functionality, including send, mint, and genesis transactions. It also fully supports all aspects of [non-fugible tokans (NFTs)](https://www.youtube.com/watch?v=vvlpYUx6HRs).
85
76
 
86
77
  - [Semantic Release](https://github.com/semantic-release/semantic-release) for
87
78
  continuous delivery using semantic versioning.
88
79
 
89
- - [Greenkeeper](https://greenkeeper.io/) automatic dependency management for
90
- automatically maintaining the latest, most secure dependencies.
91
-
92
- - [IPFS uploads](https://ipfs.io) of all files and dependencies, to backup
80
+ - [IPFS](https://ipfs.io) and [Radicle](https://radicle.xyz) uploads of all files and dependencies, to backup
93
81
  dependencies in case they are ever inaccessible from GitHub or npm.
94
82
 
95
83
  ## Documentation:
@@ -109,14 +97,26 @@ live in the same repository. To generate the documentation:
109
97
  Have questions? Need help? Join our community support
110
98
  [Telegram channel](https://t.me/bch_js_toolkit)
111
99
 
112
- ## IPFS Releases
100
+ ## Donate
101
+
102
+ This open source software is developed and maintained by the [Permissionless Software Foundation](https://psfoundation.cash). If this library provides value to you, please consider making a donation to support the PSF developers:
103
+
104
+ <div align="center">
105
+ <img src="./img/donation-qr.png" />
106
+ <p>bitcoincash:qqsrke9lh257tqen99dkyy2emh4uty0vky9y0z0lsr</p>
107
+ </div>
108
+
109
+
110
+ ## IPFS & Radicle Releases
113
111
 
114
112
  Copies of this repository are also published on [IPFS](https://ipfs.io).
115
113
 
116
- - v4.5.4: QmWv3pxJy3MH8vU5nLUVyzqFxfNKXLQQEnz1rgStNuQijd
114
+ - v6.2.10: `bafybeifsioj3ba77u2763nsyuzq53gtbdxsnqpoipvdl4immj6ytznjaoy`
115
+ - (with dependencies, node v14.18.2 and npm v8.8.0): `bafybeihfendd4oj6uxvvecm7sluobwwhpb5wdcxhvhmx56e667nxdncd4a`
116
+
117
+ They are also posted to the Radicle:
118
+ - v6.2.10: `rad:git:hnrkkroqnbfwj6uxpfjuhspoxnfm4i8e6oqwy`
117
119
 
118
120
  ## License
119
121
 
120
122
  [MIT](LICENSE.md)
121
-
122
- test
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@psf/bch-js",
3
- "version": "6.2.9",
3
+ "version": "6.2.12",
4
4
  "description": "A JavaScript library for working with Bitcoin Cash, eCash, and SLP Tokens",
5
5
  "author": "Chris Troutner <chris.troutner@gmail.com>",
6
6
  "contributors": [
package/src/electrumx.js CHANGED
@@ -44,7 +44,7 @@ class ElectrumX {
44
44
  * @apiDescription Return a list of uxtos for an address.
45
45
  *
46
46
  * @apiExample Example usage:
47
- * (async () => {
47
+ * (async () => {
48
48
  * try {
49
49
  * let utxo = await bchjs.Electrumx.utxo('bitcoincash:qqh793x9au6ehvh7r2zflzguanlme760wuzehgzjh9');
50
50
  * console.log(utxo);
@@ -375,6 +375,9 @@ class TokenType1 {
375
375
  if (!Array.isArray(tokenUtxos)) {
376
376
  throw new Error('tokenUtxos must be an array.')
377
377
  }
378
+ if (!mintQty) {
379
+ throw new Error('mintQty must be a positive number.')
380
+ }
378
381
 
379
382
  // Loop through the tokenUtxos array and find the minting baton.
380
383
  let mintBatonUtxo
@@ -404,6 +407,8 @@ class TokenType1 {
404
407
  baseQty = Math.floor(baseQty)
405
408
  baseQty = baseQty.toString()
406
409
 
410
+ if (isNaN(baseQty)) throw new Error('baseQty is non a number!')
411
+
407
412
  // Signal that the baton should be passed or detroyed.
408
413
  let batonVout = 2
409
414
  if (destroyBaton) batonVout = null
package/src/utxo.js CHANGED
@@ -92,7 +92,7 @@ class UTXO {
92
92
  // Get SLP UTXOs from the psf-slp-indexer
93
93
  try {
94
94
  const slpUtxoData = await this.psfSlpIndexer.balance(addr)
95
- // console.log(`slpUtxoData: ${JSON.stringify(slpUtxoData, null, 2)}`)
95
+ console.log(`slpUtxoData: ${JSON.stringify(slpUtxoData, null, 2)}`)
96
96
 
97
97
  slpUtxos = slpUtxoData.balance.utxos
98
98
  } catch (err) {
@@ -125,6 +125,7 @@ class UTXO {
125
125
  thisUtxo.qty = thisSlpUtxo.qty
126
126
  thisUtxo.tokenId = thisSlpUtxo.tokenId
127
127
  thisUtxo.address = thisSlpUtxo.address
128
+ thisUtxo.tokenType = thisSlpUtxo.tokenType
128
129
 
129
130
  break
130
131
  }
@@ -151,19 +152,37 @@ class UTXO {
151
152
 
152
153
  // Get token UTXOs
153
154
  let type1TokenUtxos = utxos.filter(
154
- x => x.isSlp === true && x.type === 'token'
155
+ x => x.isSlp === true && x.type === 'token' && x.tokenType === 1
155
156
  )
156
157
 
157
158
  // Hydrate the UTXOs with additional token data.
158
159
  type1TokenUtxos = await this.hydrateTokenData(type1TokenUtxos)
159
160
 
160
- // Collect and hydrate any baton UTXOs
161
+ // Collect and hydrate any type1 baton UTXOs
161
162
  const bchUtxos = utxos.filter(x => x.isSlp === false)
162
163
  let type1BatonUtxos = utxos.filter(
163
- x => x.isSlp === true && x.type === 'baton'
164
+ x => x.isSlp === true && x.type === 'baton' && x.tokenType === 1
164
165
  )
165
166
  type1BatonUtxos = await this.hydrateTokenData(type1BatonUtxos)
166
167
 
168
+ // Collect and hydrate NFT Group tokens
169
+ let nftGroupTokenUtxos = utxos.filter(
170
+ x => x.isSlp === true && x.type === 'token' && x.tokenType === 129
171
+ )
172
+ nftGroupTokenUtxos = await this.hydrateTokenData(nftGroupTokenUtxos)
173
+
174
+ // Collect and hydrate any Group baton UTXOs
175
+ let groupBatonUtxos = utxos.filter(
176
+ x => x.isSlp === true && x.type === 'baton' && x.tokenType === 129
177
+ )
178
+ groupBatonUtxos = await this.hydrateTokenData(groupBatonUtxos)
179
+
180
+ // Collect and hydrate NFT child tokens
181
+ let nftChildTokenUtxos = utxos.filter(
182
+ x => x.isSlp === true && x.type === 'token' && x.tokenType === 65
183
+ )
184
+ nftChildTokenUtxos = await this.hydrateTokenData(nftChildTokenUtxos)
185
+
167
186
  // Isolate any UTXOs that are marked null by the SLP indexer.
168
187
  const nullUtxos = utxos.filter(x => x.isSlp === null)
169
188
 
@@ -175,7 +194,13 @@ class UTXO {
175
194
  tokens: type1TokenUtxos,
176
195
  mintBatons: type1BatonUtxos
177
196
  },
178
- nft: {} // Allocated for future support of NFT spec.
197
+ group: {
198
+ tokens: nftGroupTokenUtxos,
199
+ mintBatons: groupBatonUtxos
200
+ },
201
+ nft: {
202
+ tokens: nftChildTokenUtxos
203
+ }
179
204
  },
180
205
  nullUtxos
181
206
  }
@@ -229,14 +254,16 @@ class UTXO {
229
254
  thisUtxo.documentHash = genData[0].tokenData.documentHash
230
255
  thisUtxo.decimals = genData[0].tokenData.decimals
231
256
 
232
- // Calculate the real token quantity
233
- const qty = new BigNumber(thisUtxo.qty).dividedBy(
234
- 10 ** parseInt(thisUtxo.decimals)
235
- )
236
- thisUtxo.qtyStr = qty.toString()
257
+ if (thisUtxo.type !== 'baton') {
258
+ // Calculate the real token quantity
259
+ const qty = new BigNumber(thisUtxo.qty).dividedBy(
260
+ 10 ** parseInt(thisUtxo.decimals)
261
+ )
262
+ thisUtxo.qtyStr = qty.toString()
237
263
 
238
- // tokenQty is property expected by SLP.tokentype1.js library
239
- thisUtxo.tokenQty = thisUtxo.qtyStr
264
+ // tokenQty is property expected by SLP.tokentype1.js library
265
+ thisUtxo.tokenQty = thisUtxo.qtyStr
266
+ }
240
267
  }
241
268
 
242
269
  return utxoAry
@@ -83,13 +83,11 @@ describe('#UTXO', () => {
83
83
  assert.equal(result.slpUtxos.type1.mintBatons.length, 0)
84
84
  })
85
85
 
86
- // TODO: NFTs are currently not identified as different than normal BCH UTXOs.
87
- // The psf-slp-indexer needs to be updated to fix this issue.
88
- it('should handle minting batons', async () => {
89
- const addr = 'simpleledger:qrm0c67wwqh0w7wjxua2gdt2xggnm90xwsr5k22euj'
86
+ it('should handle Type1 minting batons', async () => {
87
+ const addr = 'simpleledger:qz5l5yzz9r09hw9aadcz53elp2knx6gyg5qk3s8md7'
90
88
 
91
89
  const result = await bchjs.Utxo.get(addr)
92
- // console.log(`result: ${JSON.stringify(result, null, 2)}`)
90
+ console.log(`result: ${JSON.stringify(result, null, 2)}`)
93
91
 
94
92
  // Assert that minting batons are correctly identified.
95
93
  assert.isAbove(result.slpUtxos.type1.mintBatons.length, 0)
@@ -105,14 +103,25 @@ describe('#UTXO', () => {
105
103
  assert.equal(result.slpUtxos.type1.tokens.length, 0)
106
104
  })
107
105
 
108
- it('should handle Group NFTs', async () => {
109
- const addr = 'bitcoincash:qrnghwrfgccf3s5e9wnglzxegcnhje9rkcwv2eka33'
106
+ it('should filter Group tokens and mint batons', async () => {
107
+ const addr = 'bitcoincash:qzeqcrpe5fcnslv8rfqjq4gh4gzdwytmdc4qmh0ztv'
110
108
 
111
109
  const result = await bchjs.Utxo.get(addr)
112
110
  // console.log(`result: ${JSON.stringify(result, null, 2)}`)
113
111
 
114
- assert.equal(result.nullUtxos.length, 0)
112
+ assert.isAbove(result.slpUtxos.group.tokens.length, 0)
113
+ assert.isAbove(result.slpUtxos.group.mintBatons.length, 0)
115
114
  })
115
+
116
+ // it('should filter NFTs', async () => {
117
+ // const addr = 'bitcoincash:qq7vp2kvejsql898a2760kuq6xz00h0a5vs4h72ysz'
118
+ //
119
+ // const result = await bchjs.Utxo.get(addr)
120
+ // console.log(`result: ${JSON.stringify(result, null, 2)}`)
121
+ //
122
+ // // assert.isAbove(result.slpUtxos.group.tokens.length, 0)
123
+ // // assert.isAbove(result.slpUtxos.group.mintBatons.length, 0)
124
+ // })
116
125
  })
117
126
  })
118
127