Skip to content

Commit

Permalink
Merge pull request #53 from christroutner/unstable
Browse files Browse the repository at this point in the history
fix(getHexOpReturn): Adding SLP.TokenType1.getHexOpReturn()
  • Loading branch information
christroutner authored Jul 19, 2020
2 parents 22539fd + 264cc1b commit 11ff2c6
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 223 deletions.
19 changes: 0 additions & 19 deletions greenkeeper.json

This file was deleted.

2 changes: 1 addition & 1 deletion src/slp/slp.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class SLP {

this.Address = new Address(tmp)
this.ECPair = ECPair
this.TokenType1 = new TokenType1(this.restURL)
this.TokenType1 = new TokenType1(tmp)
this.NFT1 = new NFT1(this.restURL)
this.Utils = new Utils(tmp)
}
Expand Down
154 changes: 70 additions & 84 deletions src/slp/tokentype1.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,34 @@ const Script = require("../script")

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

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

let _this // local global

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

addy = new Address(config)
this.Script = new Script()

this.axios = axios
// Add JWT token to the authorization header.
this.axiosOptions = {
headers: {
authorization: `Token ${this.apiToken}`
}
}

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

_this = this
}

/**
Expand Down Expand Up @@ -125,90 +139,6 @@ class TokenType1 {
}
}

/**
* @api SLP.TokenType1.generateSendOpReturnWeb() generateSendOpReturnWeb() - Web-friendly OP_RETURN code for SLP Send tx
* @apiName generateSendOpReturnWeb
* @apiGroup SLP
* @apiDescription Generate the OP_RETURN value needed to create an SLP Send transaction.
* It's assumed all elements in the tokenUtxos array belong to the same token.
* Returns an object with two properties:
* - script: an array of Bufers that is ready to fed into bchjs.Script.encode2() to be turned into a transaction output.
* - outputs: an integer with a value of 1 or 2. If 2, indicates there needs to be an extra output to send token change.
*/
generateSendOpReturnWeb(tokenUtxos, sendQty) {
try {
const tokenId = tokenUtxos[0].tokenId
const decimals = tokenUtxos[0].decimals

// Calculate the total amount of tokens owned by the wallet.
let totalTokens = 0
for (let i = 0; i < tokenUtxos.length; i++)
totalTokens += tokenUtxos[i].tokenQty

const change = totalTokens - sendQty
// console.log(`change: ${change}`)

let script
let outputs = 1

// The normal case, when there is token change to return to sender.
if (change > 0) {
outputs = 2

let baseQty = new BigNumber(sendQty).times(10 ** decimals)
baseQty = baseQty.absoluteValue()
baseQty = Math.floor(baseQty)
let baseQtyHex = baseQty.toString(16)
baseQtyHex = baseQtyHex.padStart(16, "0")

let baseChange = new BigNumber(change).times(10 ** decimals)
baseChange = baseChange.absoluteValue()
baseChange = Math.floor(baseChange)
// console.log(`baseChange: ${baseChange.toString()}`)

let baseChangeHex = baseChange.toString(16)
baseChangeHex = baseChangeHex.padStart(16, "0")
// console.log(`baseChangeHex padded: ${baseChangeHex}`)

script = [
this.Script.opcodes.OP_RETURN,
Buffer.from("534c5000", "hex"),
//BITBOX.Script.opcodes.OP_1,
Buffer.from("01", "hex"),
Buffer.from(`SEND`),
Buffer.from(tokenId, "hex"),
Buffer.from(baseQtyHex, "hex"),
Buffer.from(baseChangeHex, "hex")
]
} else {
// Corner case, when there is no token change to send back.

let baseQty = new BigNumber(sendQty).times(10 ** decimals)
baseQty = baseQty.absoluteValue()
baseQty = Math.floor(baseQty)
let baseQtyHex = baseQty.toString(16)
baseQtyHex = baseQtyHex.padStart(16, "0")

// console.log(`baseQty: ${baseQty.toString()}`)

script = [
this.Script.opcodes.OP_RETURN,
Buffer.from("534c5000", "hex"),
//BITBOX.Script.opcodes.OP_1,
Buffer.from("01", "hex"),
Buffer.from(`SEND`),
Buffer.from(tokenId, "hex"),
Buffer.from(baseQtyHex, "hex")
]
}

return { script, outputs }
} catch (err) {
console.log(`Error in generateSendOpReturnWeb()`)
throw err
}
}

/**
* @api SLP.TokenType1.generateBurnOpReturn() generateBurnOpReturn()
* @apiName generateBurnOpReturn
Expand Down Expand Up @@ -444,6 +374,62 @@ class TokenType1 {
throw err
}
}

/**
* @api SLP.TokenType1.getHexOpReturn() getHexOpReturn()
* @apiName getHexOpReturn
* @apiGroup SLP TokenType1
* @apiDescription Get hex representation of an SLP OP_RETURN
* This command returns a hex encoded OP_RETURN for SLP Send (Token Type 1)
* transactions. Rather than computing it directly, it calls bch-api to do
* the heavy lifting. This is easier and lighter weight for web apps.
*
* @apiExample Example usage:
*
* const tokenUtxos = [{
* tokenId: "0a321bff9761f28e06a268b14711274bb77617410a16807bd0437ef234a072b1",
* decimals: 0,
* tokenQty: 2
* }]
*
* const sendQty = 1.5
*
* const result = await bchjs.SLP.TokenType1.getHexOpReturn(tokenUtxos, sendQty)
*
* // result:
* {
* "script": "6a04534c500001010453454e44200a321bff9761f28e06a268b14711274bb77617410a16807bd0437ef234a072b1080000000000000001080000000000000000",
* "outputs": 2
* }
*/
async getHexOpReturn(tokenUtxos, sendQty) {
try {
// TODO: Add input filtering.

const data = {
tokenUtxos,
sendQty
}

const result = await _this.axios.post(
`${this.restURL}slp/generatesendopreturn`,
data,
_this.axiosOptions
)

const slpSendObj = result.data

// const script = _this.Buffer.from(slpSendObj.script)
//
// slpSendObj.script = script
// return slpSendObj

return slpSendObj
} catch (err) {
console.log(err)
throw err
}
}
}

module.exports = TokenType1
28 changes: 28 additions & 0 deletions test/integration/slp.js
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,34 @@ describe(`#SLP`, () => {
})
})
})

describe("#tokentype1", () => {
describe("#getHexOpReturn", () => {
it("should return OP_RETURN object ", async () => {
const tokenUtxos = [
{
tokenId:
"0a321bff9761f28e06a268b14711274bb77617410a16807bd0437ef234a072b1",
decimals: 0,
tokenQty: 2
}
]
const sendQty = 1.5

const result = await bchjs.SLP.TokenType1.getHexOpReturn(
tokenUtxos,
sendQty
)
// console.log(`result: ${JSON.stringify(result, null, 2)}`)

assert.property(result, "script")
assert.isString(result.script)

assert.property(result, "outputs")
assert.isNumber(result.outputs)
})
})
})
})

// Promise-based sleep function
Expand Down
Loading

0 comments on commit 11ff2c6

Please sign in to comment.