Skip to content

Commit

Permalink
Merge pull request #38 from christroutner/unstable
Browse files Browse the repository at this point in the history
NFT Prototypes
  • Loading branch information
christroutner committed Jun 5, 2020
2 parents 6a3d194 + 6daff04 commit d5ecacc
Show file tree
Hide file tree
Showing 8 changed files with 499 additions and 415 deletions.
126 changes: 126 additions & 0 deletions src/slp/nft1.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
/*
This library wraps the slp-mdm library to generate the OP_RETURN for NFT1 tokens.
NFT Group tokens (Parents) are generated and minted. They are like amorphous
NFTs; like stem cells that haven't specialized yet.
NFT 'Children' are the 'real' NFTs. They are created by burning an NFT Group
(Parent) token.
*/

const Address = require("./address")

const BigNumber = require("bignumber.js")
const slpMdm = require("slp-mdm")

// const addy = new Address()
let addy
const TransactionBuilder = require("../transaction-builder")

class TokenType1 {
constructor(config) {
this.restURL = config.restURL

addy = new Address(config)

// Instantiate the transaction builder.
TransactionBuilder.setAddress(addy)
}

// New NFT Group 'Parent'
newNFTGroupOpReturn(configObj) {
try {
// TODO: Add input validation.

// Prevent error if user fails to add the document hash.
if (!configObj.documentHash) configObj.documentHash = ""

// If mint baton is not specified, then replace it with null.
if (!configObj.mintBatonVout) configObj.mintBatonVout = null

const script = slpMdm.NFT1.Group.genesis(
configObj.ticker,
configObj.name,
configObj.documentUrl,
configObj.documentHash,
0,
configObj.mintBatonVout,
new slpMdm.BN("1")
)

return script
} catch (err) {
console.log(`Error in generateNFTParentOpReturn()`)
throw err
}
}

// Mint additional NFT Group 'Parent' tokens.
mintNFTGroupOpReturn(tokenUtxos, mintQty, destroyBaton = false) {
try {
// Throw error if input is not an array.
if (!Array.isArray(tokenUtxos))
throw new Error(`tokenUtxos must be an array.`)

// Loop through the tokenUtxos array and find the minting baton.
let mintBatonUtxo
for (let i = 0; i < tokenUtxos.length; i++) {
if (tokenUtxos[i].utxoType === "minting-baton")
mintBatonUtxo = tokenUtxos[i]
}

// Throw an error if the minting baton could not be found.
if (!mintBatonUtxo)
throw new Error(`Minting baton could not be found in tokenUtxos array.`)

const tokenId = mintBatonUtxo.tokenId

if (!tokenId)
throw new Error(`tokenId property not found in mint-baton UTXO.`)

// Signal that the baton should be passed or detroyed.
let batonVout = 2
if (destroyBaton) batonVout = null

const script = slpMdm.NFT1.Group.mint(
tokenId,
batonVout,
new slpMdm.BN(mintQty)
)

return script
} catch (err) {
// console.log(`Error in generateMintOpReturn()`)
throw err
}
}

generateNFTChildOpReturn(configObj) {
try {
// TODO: Add input validation.

// Prevent error if user fails to add the document hash.
if (!configObj.documentHash) configObj.documentHash = ""

// If mint baton is not specified, then replace it with null.
if (!configObj.mintBatonVout) configObj.mintBatonVout = null

const script = slpMdm.NFT1.Group.genesis(
configObj.ticker,
configObj.name,
configObj.documentUrl,
configObj.documentHash,
0,
configObj.mintBatonVout,
new slpMdm.BN("1")
)

return script
} catch (err) {
console.log(`Error in generateNFTChildOpReturn()`)
throw err
}
}
}

module.exports = TokenType1
2 changes: 2 additions & 0 deletions src/slp/slp.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const Address = require("./address")
const ECPair = require("./ecpair")
// const HDNode = require("./hdnode")
const TokenType1 = require("./tokentype1")
const NFT1 = require("./nft1")
const Utils = require("./utils")

// SLP is a superset of BITBOX
Expand All @@ -31,6 +32,7 @@ class SLP {
this.Address = new Address(tmp)
this.ECPair = ECPair
this.TokenType1 = new TokenType1(this.restURL)
this.NFT1 = new NFT1(this.restURL)
this.Utils = new Utils(tmp)
}
}
Expand Down
58 changes: 0 additions & 58 deletions src/slp/tokentype1.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
//const bchjs = new BCHJS()

const Address = require("./address")
const Script = require("../script")

const BigNumber = require("bignumber.js")
const slpMdm = require("slp-mdm")
Expand All @@ -15,8 +14,6 @@ class TokenType1 {
constructor(config) {
this.restURL = config.restURL

this.Script = new Script()

addy = new Address(config)

// Instantiate the transaction builder.
Expand Down Expand Up @@ -361,61 +358,6 @@ class TokenType1 {
throw err
}
}

// Parent NFT
generateNFTGenesisOpReturn(configObj) {
try {
// TODO: Add input validation.

// Prevent error if user fails to add the document hash.
if (!configObj.documentHash) configObj.documentHash = ""

// If mint baton is not specified, then replace it with null.
if (!configObj.mintBatonVout) configObj.mintBatonVout = null

const script = slpMdm.NFT1.Group.genesis(
configObj.ticker,
configObj.name,
configObj.documentUrl,
configObj.documentHash,
0,
configObj.mintBatonVout,
new slpMdm.BN("1")
)

return script
} catch (err) {
console.log(`Error in generateNFTGenesisOpReturn()`)
throw err
}
}

generateNFTChildOpReturn(configObj) {
try {
// TODO: Add input validation.

// Prevent error if user fails to add the document hash.
if (!configObj.documentHash) configObj.documentHash = ""

// If mint baton is not specified, then replace it with null.
if (!configObj.mintBatonVout) configObj.mintBatonVout = null

const script = slpMdm.NFT1.Group.genesis(
configObj.ticker,
configObj.name,
configObj.documentUrl,
configObj.documentHash,
0,
configObj.mintBatonVout,
new slpMdm.BN("1")
)

return script
} catch (err) {
console.log(`Error in generateNFTChildOpReturn()`)
throw err
}
}
}

module.exports = TokenType1
3 changes: 3 additions & 0 deletions src/slp/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -1167,6 +1167,7 @@ class Utils {
utxo.tokenDocumentUrl = slpData.documentUri
utxo.tokenDocumentHash = slpData.documentHash
utxo.decimals = slpData.decimals
utxo.tokenType = slpData.tokenType

// something
outAry[i] = utxo
Expand Down Expand Up @@ -1201,6 +1202,7 @@ class Utils {
// Hydrate the UTXO object with information about the SLP token.
utxo.transactionType = "mint"
utxo.tokenId = slpData.tokenId
utxo.tokenType = slpData.tokenType

utxo.tokenTicker = genesisData.ticker
utxo.tokenName = genesisData.name
Expand Down Expand Up @@ -1249,6 +1251,7 @@ class Utils {
utxo.tokenDocumentUrl = genesisData.documentUri
utxo.tokenDocumentHash = genesisData.documentHash
utxo.decimals = genesisData.decimals
utxo.tokenType = slpData.tokenType

// Calculate the real token quantity.
utxo.tokenQty = tokenQty / Math.pow(10, genesisData.decimals)
Expand Down
77 changes: 77 additions & 0 deletions test/unit/fixtures/slp/mock-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -1031,6 +1031,82 @@ const mockInvalidSlpSend = {
blocktime: 1535577007
}

const txDetailsSLPNftGenesis = {
txid: "4ef6eb92950a13a69e97c2c02c7967d806aa874c0e2a6b5546a8880f2cd14bc4",
hash: "4ef6eb92950a13a69e97c2c02c7967d806aa874c0e2a6b5546a8880f2cd14bc4",
version: 2,
size: 344,
locktime: 0,
vin: [
{
txid: "4041bc842554b796de1dbb625bbb6994379bc5132a47522677bef7323f3e5051",
vout: 2,
scriptSig: {
asm:
"3045022100f8d678e7cd6a2fc317fe4c0c8b633f5941aa40bceb6d7472559955908869544b02206d82e45a6658bb9b5ad39734aa93832b1de2d3c9650e1b59c2ee2f15aa26f3bb[ALL|FORKID] 029547345d63f86ea89ea92ea4ed26386c4493ff60c78d871cc7b38f517f3fd72c",
hex:
"483045022100f8d678e7cd6a2fc317fe4c0c8b633f5941aa40bceb6d7472559955908869544b02206d82e45a6658bb9b5ad39734aa93832b1de2d3c9650e1b59c2ee2f15aa26f3bb4121029547345d63f86ea89ea92ea4ed26386c4493ff60c78d871cc7b38f517f3fd72c"
},
sequence: 4294967295
}
],
vout: [
{
value: 0,
n: 0,
scriptPubKey: {
asm:
"OP_RETURN 5262419 -1 47454e45534953 4e46545454 4e4654205465737420546f6b656e 68747470733a2f2f46756c6c537461636b2e63617368 0 0 2 0000000000000001",
hex:
"6a04534c500001810747454e45534953054e465454540e4e4654205465737420546f6b656e1668747470733a2f2f46756c6c537461636b2e636173684c0001000102080000000000000001",
type: "nulldata"
}
},
{
value: 0.00000546,
n: 1,
scriptPubKey: {
asm:
"OP_DUP OP_HASH160 6011206cd60db8b634f85edf46da22a6d1351e54 OP_EQUALVERIFY OP_CHECKSIG",
hex: "76a9146011206cd60db8b634f85edf46da22a6d1351e5488ac",
reqSigs: 1,
type: "pubkeyhash",
addresses: ["bitcoincash:qpspzgrv6cxm3d35lp0d73k6y2ndzdg72s2304ttr8"]
}
},
{
value: 0.00000546,
n: 2,
scriptPubKey: {
asm:
"OP_DUP OP_HASH160 6011206cd60db8b634f85edf46da22a6d1351e54 OP_EQUALVERIFY OP_CHECKSIG",
hex: "76a9146011206cd60db8b634f85edf46da22a6d1351e5488ac",
reqSigs: 1,
type: "pubkeyhash",
addresses: ["bitcoincash:qpspzgrv6cxm3d35lp0d73k6y2ndzdg72s2304ttr8"]
}
},
{
value: 0.0001562,
n: 3,
scriptPubKey: {
asm:
"OP_DUP OP_HASH160 6011206cd60db8b634f85edf46da22a6d1351e54 OP_EQUALVERIFY OP_CHECKSIG",
hex: "76a9146011206cd60db8b634f85edf46da22a6d1351e5488ac",
reqSigs: 1,
type: "pubkeyhash",
addresses: ["bitcoincash:qpspzgrv6cxm3d35lp0d73k6y2ndzdg72s2304ttr8"]
}
}
],
hex:
"020000000151503e3f32f7be772652472a13c59b379469bb5b62bb1dde96b7542584bc4140020000006b483045022100f8d678e7cd6a2fc317fe4c0c8b633f5941aa40bceb6d7472559955908869544b02206d82e45a6658bb9b5ad39734aa93832b1de2d3c9650e1b59c2ee2f15aa26f3bb4121029547345d63f86ea89ea92ea4ed26386c4493ff60c78d871cc7b38f517f3fd72cffffffff0400000000000000004b6a04534c500001810747454e45534953054e465454540e4e4654205465737420546f6b656e1668747470733a2f2f46756c6c537461636b2e636173684c000100010208000000000000000122020000000000001976a9146011206cd60db8b634f85edf46da22a6d1351e5488ac22020000000000001976a9146011206cd60db8b634f85edf46da22a6d1351e5488ac043d0000000000001976a9146011206cd60db8b634f85edf46da22a6d1351e5488ac00000000",
blockhash: "000000000000000002405a44302888bc29bf0e9f4d99b97303038bcc83c15e33",
confirmations: 2,
time: 1591329189,
blocktime: 1591329189
}

module.exports = {
mockList,
mockToken,
Expand All @@ -1051,6 +1127,7 @@ module.exports = {
txDetailsSLPSend,
txDetailsSLPGenesisNoBaton,
txDetailsSLPSendAlt,
txDetailsSLPNftGenesis,
mockTxDetails,
mockDualValidation,
mockDualOpData,
Expand Down

0 comments on commit d5ecacc

Please sign in to comment.