Skip to content

Commit

Permalink
Merge pull request #46 from christroutner/unstable
Browse files Browse the repository at this point in the history
tokenUtxoDetails()
  • Loading branch information
christroutner authored Jun 14, 2020
2 parents 95c0b71 + a8c27e4 commit 11459ea
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 37 deletions.
7 changes: 3 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Here are two YouTube walk-through videos to help you get started:

### Quick Links
- [npm Library](https://www.npmjs.com/package/@chris.troutner/bch-js)
- [Documentation](https://bchjs.cash/bch-js/index.html)
- [Documentation](https://bchjs.fullstack.cash/)
- [Examples](https://github.com/Permissionless-Software-Foundation/bch-js-examples)
- [api.fullstack.cash](https://api.fullstack.cash) - The REST API this library talks to by default.
- [FullStack.cash Account](https://fullstack.cash/login) - Get your API key to unlock increased rate limits.
Expand Down Expand Up @@ -81,8 +81,7 @@ This library sets itself apart from BITBOX with the following features:
- [ECMAScript 2017 standard JavaScript](https://en.wikipedia.org/wiki/ECMAScript#8th_Edition_-_ECMAScript_2017) used instead of TypeScript. Works
natively with node.js v10 or higher.

- [slp-sdk](https://github.com/Bitcoin-com/slp-sdk) features are integrated
into this library too. Currently only simple token sending is supported. If you need SLP token functionality, you should use [slp-sdk](https://github.com/Bitcoin-com/slp-sdk), [slp-cli-wallet](https://www.npmjs.com/package/slp-cli-wallet).
- 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).

- [Semantic Release](https://github.com/semantic-release/semantic-release) for
continuous delivery using semantic versioning.
Expand All @@ -98,7 +97,7 @@ dependencies in case they are ever inaccessible from GitHub or npm.
## Documentation:

Full documentation for this library can be found here:
- [Documentation](https://bchjs.cash/bch-js/index.html)
- [Documentation](https://bchjs.fullstack.cash/)

Original documentation on BITBOX is available at:

Expand Down
29 changes: 17 additions & 12 deletions src/slp/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -838,10 +838,12 @@ class Utils {
* @apiDescription Hydrate a UTXO with SLP token metadata.
*
* Expects an array of UTXO objects as input. Returns an array of equal size.
* Returns UTXO data hydrated with token information.
* If the
* UTXO does not belong to a SLP transaction, it will return false.
* UTXO does not belong to a SLP transaction, it will return an `isValid` property
* set to false.
* If the UTXO is part of an SLP transaction, it will return the UTXO object
* with additional SLP information attached. An isValid property will be included.
* with additional SLP information attached. An `isValid` property will be included.
* If its value is true, the UTXO is a valid SLP UTXO. If the value is null,
* then SLPDB has not yet processed that txid and validity has not been confirmed.
*
Expand Down Expand Up @@ -948,7 +950,9 @@ class Utils {
// console.log(`error: `, err)
// An error will be thrown if the txid is not SLP.
// Mark as false and continue the loop.
outAry.push(false)
// outAry.push(false)
utxo.isValid = false
outAry.push(utxo)
continue
}

Expand All @@ -964,7 +968,9 @@ class Utils {
utxo.vout !== 1 // UTXO is not the reciever of the genesis or mint tokens.
) {
// Can safely be marked as false.
outAry[i] = false
// outAry[i] = false
utxo.isValid = false
outAry[i] = utxo
}

// If this is a valid SLP UTXO, then return the decoded OP_RETURN data.
Expand Down Expand Up @@ -999,7 +1005,9 @@ class Utils {
utxo.vout !== 1 // UTXO is not the reciever of the genesis or mint tokens.
) {
// Can safely be marked as false.
outAry[i] = false
// outAry[i] = false
utxo.isValid = false
outAry[i] = utxo
}

// If UTXO passes validation, then return formatted token data.
Expand Down Expand Up @@ -1040,17 +1048,14 @@ class Utils {
// const voutMatch = slpData.spendData.filter(x => utxo.vout === x.vout)
// console.log(`voutMatch: ${JSON.stringify(voutMatch, null, 2)}`)

// If there are no vout matches, the UTXO can safely be marked as false.
// if (voutMatch.length === 0) {
// outAry[i] = false
// }

// Figure out what token quantity is represented by this utxo.
const tokenQty = slpData.amounts[utxo.vout - 1]
// console.log(`tokenQty: `, tokenQty)

if (!tokenQty) {
outAry[i] = false
// outAry[i] = false
utxo.isValid = false
outAry[i] = utxo
}

// If UTXO passes validation, then return formatted token data.
Expand Down Expand Up @@ -1081,7 +1086,7 @@ class Utils {
}

// Finally, validate the SLP txid with SLPDB.
if (outAry[i]) {
if (outAry[i].tokenType) {
const isValid = await this.validateTxid(utxo.txid)
// console.log(`isValid: ${JSON.stringify(isValid, null, 2)}`)

Expand Down
10 changes: 5 additions & 5 deletions test/integration/slp.js
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ describe(`#SLP`, () => {
const data = await bchjs.SLP.Utils.tokenUtxoDetails(utxos)
// console.log(`data: ${JSON.stringify(data, null, 2)}`)

assert.equal(data[0], false, "Change UTXO marked as false.")
assert.equal(data[0].isValid, false, "Change UTXO marked as false.")

assert.property(data[1], "txid")
assert.property(data[1], "vout")
Expand Down Expand Up @@ -373,7 +373,7 @@ describe(`#SLP`, () => {

assert.isArray(result)
assert.equal(result.length, 2)
assert.equal(result[0], false)
assert.equal(result[0].isValid, false)
assert.equal(result[1].isValid, true)
})

Expand Down Expand Up @@ -404,7 +404,7 @@ describe(`#SLP`, () => {

assert.isArray(result)
assert.equal(result.length, 2)
assert.equal(result[0], false)
assert.equal(result[0].isValid, false)
assert.equal(result[1].isValid, true)
})

Expand Down Expand Up @@ -434,8 +434,8 @@ describe(`#SLP`, () => {
// console.log(`data: ${JSON.stringify(data, null, 2)}`)

assert.isArray(data)
assert.equal(false, data[0])
assert.equal(false, data[1])
assert.equal(data[0].isValid, false)
assert.equal(data[1].isValid, false)
})
})

Expand Down
101 changes: 85 additions & 16 deletions test/unit/slp-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -725,7 +725,15 @@ describe("#SLP Utils", () => {
const data = await slp.Utils.tokenUtxoDetails(utxos)
// console.log(`data: ${JSON.stringify(data, null, 2)}`)

assert2.equal(data[0], false, "Change UTXO marked as false.")
// assert2.equal(data[0], false, "Change UTXO marked as false.")
assert2.property(data[0], "txid")
assert2.property(data[0], "vout")
assert2.property(data[0], "amount")
assert2.property(data[0], "satoshis")
assert2.property(data[0], "height")
assert2.property(data[0], "confirmations")
assert2.property(data[0], "isValid")
assert2.equal(data[0].isValid, false)

assert2.property(data[1], "txid")
assert2.property(data[1], "vout")
Expand Down Expand Up @@ -953,8 +961,19 @@ describe("#SLP Utils", () => {

assert2.isArray(result)
assert2.equal(result.length, 2)
assert2.equal(result[0], false)

assert2.property(result[0], "txid")
assert2.property(result[0], "vout")
assert2.property(result[0], "value")
assert2.property(result[0], "satoshis")
assert2.property(result[0], "height")
assert2.property(result[0], "confirmations")
assert2.property(result[0], "isValid")
assert2.equal(result[0].isValid, false)

assert.equal(result[1].isValid, true)
assert.equal(result[1].utxoType, "token")
assert.equal(result[1].transactionType, "send")
})

it("should handle problematic utxos", async () => {
Expand Down Expand Up @@ -1022,11 +1041,22 @@ describe("#SLP Utils", () => {

assert2.isArray(result)
assert2.equal(result.length, 2)
assert2.equal(result[0], false)

assert2.property(result[0], "txid")
assert2.property(result[0], "vout")
assert2.property(result[0], "amount")
assert2.property(result[0], "satoshis")
assert2.property(result[0], "height")
assert2.property(result[0], "confirmations")
assert2.property(result[0], "isValid")
assert2.equal(result[0].isValid, false)

assert2.equal(result[1].isValid, true)
assert.equal(result[1].utxoType, "token")
assert.equal(result[1].transactionType, "send")
})

it("should return false for BCH-only UTXOs", async () => {
it("should return isValid=false for BCH-only UTXOs", async () => {
// Mock live network calls

sandbox
Expand Down Expand Up @@ -1054,12 +1084,26 @@ describe("#SLP Utils", () => {
}
]

const data = await slp.Utils.tokenUtxoDetails(utxos)
// console.log(`data: ${JSON.stringify(data, null, 2)}`)
const result = await slp.Utils.tokenUtxoDetails(utxos)
// console.log(`result: ${JSON.stringify(result, null, 2)}`)

assert2.isArray(data)
assert2.equal(false, data[0])
assert2.equal(false, data[1])
assert2.isArray(result)

assert2.property(result[0], "txid")
assert2.property(result[0], "vout")
assert2.property(result[0], "amount")
assert2.property(result[0], "satoshis")
assert2.property(result[0], "confirmations")
assert2.property(result[0], "isValid")
assert2.equal(result[0].isValid, false)

assert2.property(result[1], "txid")
assert2.property(result[1], "vout")
assert2.property(result[1], "amount")
assert2.property(result[1], "satoshis")
assert2.property(result[1], "confirmations")
assert2.property(result[1], "isValid")
assert2.equal(result[1].isValid, false)
})

it("should decode a Genesis transaction", async () => {
Expand Down Expand Up @@ -1121,10 +1165,17 @@ describe("#SLP Utils", () => {
// console.log(`data: ${JSON.stringify(data, null, 2)}`)

assert2.isArray(data)

assert2.equal(data[0].utxoType, "token")
assert2.equal(data[0].tokenQty, 100)
assert2.equal(data[0].isValid, true)
assert2.equal(data[0].tokenType, 1)

assert2.equal(data[1].utxoType, "minting-baton")
assert2.equal(false, data[2])
assert2.equal(data[1].isValid, true)
assert2.equal(data[1].tokenType, 1)

assert2.equal(data[2].isValid, false)
})

it("should decode a Mint transaction", async () => {
Expand Down Expand Up @@ -1212,10 +1263,17 @@ describe("#SLP Utils", () => {
// console.log(`data: ${JSON.stringify(data, null, 2)}`)

assert2.isArray(data)

assert2.equal(data[0].utxoType, "token")
assert2.equal(data[0].tokenQty, 100)
assert2.equal(data[0].isValid, true)
assert2.equal(data[0].tokenType, 1)

assert2.equal(data[1].utxoType, "minting-baton")
assert2.equal(false, data[2])
assert2.equal(data[1].isValid, true)
assert2.equal(data[1].tokenType, 1)

assert2.equal(data[2].isValid, false)
})

it("should decode a NFT Group Genesis transaction", async () => {
Expand Down Expand Up @@ -1299,13 +1357,16 @@ describe("#SLP Utils", () => {
// console.log(`data: ${JSON.stringify(data, null, 2)}`)

assert2.isArray(data)
assert2.equal(data[0], false)

assert2.equal(data[0].isValid, false)

assert2.equal(data[1].utxoType, "minting-baton")
assert2.equal(data[1].isValid, true)
assert2.equal(data[1].tokenType, 129)

assert2.equal(data[2].utxoType, "token")
assert2.equal(data[2].tokenType, 129)
assert2.equal(data[1].isValid, true)
})

it("should decode a NFT Group Mint transaction", async () => {
Expand Down Expand Up @@ -1398,13 +1459,16 @@ describe("#SLP Utils", () => {
// console.log(`data: ${JSON.stringify(data, null, 2)}`)

assert2.isArray(data)
assert2.equal(data[0], false)

assert2.equal(data[0].isValid, false)

assert2.equal(data[1].utxoType, "minting-baton")
assert2.equal(data[1].tokenType, 129)
assert2.equal(data[1].isValid, true)

assert2.equal(data[2].utxoType, "token")
assert2.equal(data[2].tokenType, 129)
assert2.equal(data[2].isValid, true)
})

it("should decode a NFT Child Genesis transaction", async () => {
Expand Down Expand Up @@ -1465,10 +1529,12 @@ describe("#SLP Utils", () => {
// console.log(`data: ${JSON.stringify(data, null, 2)}`)

assert2.isArray(data)
assert2.equal(data[1], false)

assert2.equal(data[0].utxoType, "token")
assert2.equal(data[0].tokenType, 65)
assert2.equal(data[0].isValid, true)

assert2.equal(data[1].isValid, false)
})

it("should decode an NFT Child Send transaction", async () => {
Expand Down Expand Up @@ -1543,8 +1609,9 @@ describe("#SLP Utils", () => {
assert2.equal(data[0].utxoType, "token")
assert2.equal(data[0].transactionType, "send")
assert2.equal(data[0].tokenType, 65)
assert2.equal(data[0].isValid, true)

assert2.equal(data[1], false)
assert2.equal(data[1].isValid, false)
})

it("should decode an NFT Group Send transaction", async () => {
Expand Down Expand Up @@ -1635,12 +1702,14 @@ describe("#SLP Utils", () => {
assert2.equal(data[0].utxoType, "token")
assert2.equal(data[0].transactionType, "send")
assert2.equal(data[0].tokenType, 129)
assert2.equal(data[0].isValid, true)

assert2.equal(data[1].utxoType, "token")
assert2.equal(data[1].transactionType, "send")
assert2.equal(data[1].tokenType, 129)
assert2.equal(data[1].isValid, true)

assert2.equal(data[2], false)
assert2.equal(data[2].isValid, false)
})
})

Expand Down

0 comments on commit 11459ea

Please sign in to comment.