-
Notifications
You must be signed in to change notification settings - Fork 45
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Utilizing simpleledger/slp-mdm package, update associated unit tests - Update BigNumber library
- Loading branch information
Showing
8 changed files
with
153 additions
and
430 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,267 +1,42 @@ | ||
import { Utils } from './utils'; | ||
import BigNumber from 'bignumber.js'; | ||
import BigNumber from "bignumber.js"; | ||
import { TokenType1 } from "slp-mdm"; | ||
|
||
export class SlpTokenType1 { | ||
static get lokadIdHex() { return "534c5000" } | ||
|
||
static buildGenesisOpReturn(ticker: string|null, name: string|null, documentUri:string|null, documentHashHex: string|null, decimals: number, batonVout:number|null, initialQuantity:BigNumber, type=0x01) { | ||
let script: (number|number[])[] = []; | ||
|
||
// OP Return Prefix | ||
script.push(0x6a) | ||
|
||
// Lokad Id | ||
let lokadId = Buffer.from(this.lokadIdHex, 'hex') | ||
script.push(Utils.getPushDataOpcode(lokadId)) | ||
lokadId.forEach((item) => script.push(item)) | ||
|
||
// Token Version/Type | ||
if(![0x01, 0x41, 0x81].includes(type)) | ||
throw Error("Unable to create Genesis for this token type.") | ||
let tokenVersionType = type; | ||
script.push(Utils.getPushDataOpcode([tokenVersionType])) | ||
script.push(tokenVersionType) | ||
|
||
// Transaction Type | ||
let transactionType = Buffer.from('GENESIS') | ||
script.push(Utils.getPushDataOpcode(transactionType)) | ||
transactionType.forEach((item) => script.push(item)) | ||
|
||
// Ticker | ||
if (ticker && typeof ticker !== 'string'){ | ||
throw Error("ticker must be a string") | ||
} else if (!ticker || ticker.length === 0) { | ||
[0x4c, 0x00].forEach((item) => script.push(item)) | ||
} else { | ||
let tickerBuf = Buffer.from(ticker, 'utf8') | ||
script.push(Utils.getPushDataOpcode(tickerBuf)) | ||
tickerBuf.forEach((item) => script.push(item)) | ||
} | ||
|
||
// Name | ||
if (name && typeof name !== 'string') { | ||
throw Error("name must be a string") | ||
} else if (!name || name.length === 0) { | ||
[0x4c, 0x00].forEach((item) => script.push(item)) | ||
} else { | ||
let nameBuf = Buffer.from(name, 'utf8') | ||
script.push(Utils.getPushDataOpcode(nameBuf)) | ||
nameBuf.forEach((item) => script.push(item)) | ||
} | ||
|
||
// Document URL | ||
if (documentUri && typeof documentUri !== 'string') { | ||
throw Error("documentUri must be a string") | ||
} else if (!documentUri || documentUri.length === 0) { | ||
[0x4c, 0x00].forEach((item) => script.push(item)) | ||
} else { | ||
let documentUriBuf = Buffer.from(documentUri, 'ascii') | ||
script.push(Utils.getPushDataOpcode(documentUriBuf)) | ||
documentUriBuf.forEach((item) => script.push(item)) | ||
} | ||
|
||
// check Token Document Hash should be hexademical chracters. | ||
var re = /^[0-9a-fA-F]+$/; | ||
|
||
// Document Hash | ||
if (!documentHashHex || documentHashHex.length === 0) { | ||
[0x4c, 0x00].forEach((item) => script.push(item)) | ||
} else if (documentHashHex.length === 64 && re.test(documentHashHex)) { | ||
let documentHashBuf = Buffer.from(documentHashHex, 'hex') | ||
script.push(Utils.getPushDataOpcode(documentHashBuf)) | ||
documentHashBuf.forEach((item) => script.push(item)) | ||
} else { | ||
throw Error("Document hash must be provided as a 64 character hex string") | ||
} | ||
|
||
// Decimals | ||
if (decimals === null || decimals === undefined || decimals < 0 || decimals > 9) { | ||
throw Error("Decimals property must be in range 0 to 9") | ||
} else { | ||
script.push(Utils.getPushDataOpcode([decimals])) | ||
script.push(decimals) | ||
} | ||
|
||
// Baton Vout | ||
if (batonVout === null || batonVout === undefined) { | ||
[0x4c, 0x00].forEach((item) => script.push(item)) | ||
} else { | ||
if (batonVout < 2 || batonVout > 255 || !(typeof batonVout == 'number')) | ||
throw Error("Baton vout must a number and greater than 1 and less than 256.") | ||
|
||
script.push(Utils.getPushDataOpcode([batonVout])) | ||
script.push(batonVout) | ||
} | ||
|
||
// Initial Quantity | ||
let MAX_QTY = new BigNumber('18446744073709551615'); | ||
|
||
try { | ||
initialQuantity.absoluteValue() | ||
} catch(_) { | ||
throw Error("Amount must be an instance of BigNumber"); | ||
} | ||
|
||
if (initialQuantity.isGreaterThan(MAX_QTY)) | ||
throw new Error("Maximum genesis value exceeded. Reduce input quantity below 18446744073709551615."); | ||
|
||
if (initialQuantity.isLessThan(0)) | ||
throw Error("Genesis quantity must be greater than 0."); | ||
|
||
if (!initialQuantity.modulo(1).isEqualTo(new BigNumber(0))) | ||
throw Error("Genesis quantity must be a whole number."); | ||
|
||
let initialQuantityBuf = Utils.int2FixedBuffer(initialQuantity) | ||
script.push(Utils.getPushDataOpcode(initialQuantityBuf)) | ||
initialQuantityBuf.forEach((item) => script.push(item)) | ||
|
||
let encodedScript = Utils.encodeScript(script) | ||
if (encodedScript.length > 223) { | ||
throw Error("Script too long, must be less than 223 bytes.") | ||
} | ||
return encodedScript | ||
} | ||
|
||
static buildSendOpReturn(tokenIdHex: string, outputQtyArray: BigNumber[], type=0x01) { | ||
let script: (number|number[])[] = []; | ||
|
||
// OP Return Prefix | ||
script.push(0x6a) | ||
|
||
// Lokad Id | ||
let lokadId = Buffer.from(this.lokadIdHex, 'hex') | ||
script.push(Utils.getPushDataOpcode(lokadId)) | ||
lokadId.forEach((item) => script.push(item)) | ||
|
||
// Token Version/Type | ||
if(![0x01, 0x41, 0x81].includes(type)) | ||
throw Error("Unable to create Genesis for this token type.") | ||
let tokenVersionType = type | ||
script.push(Utils.getPushDataOpcode([tokenVersionType])) | ||
script.push(tokenVersionType) | ||
|
||
// Transaction Type | ||
let transactionType = Buffer.from('SEND') | ||
script.push(Utils.getPushDataOpcode(transactionType)) | ||
transactionType.forEach((item) => script.push(item)) | ||
|
||
// Token Id | ||
// check Token Id should be hexademical chracters. | ||
let re = /^([A-Fa-f0-9]{2}){32,32}$/; | ||
if (typeof tokenIdHex !== 'string' || !re.test(tokenIdHex)) { | ||
throw Error("TokenIdHex must be provided as a 64 character hex string.") | ||
} | ||
let tokenId = Buffer.from(tokenIdHex, 'hex') | ||
script.push(Utils.getPushDataOpcode(tokenId)) | ||
tokenId.forEach((item) => script.push(item)) | ||
|
||
// Output Quantities | ||
if (outputQtyArray.length > 19) { | ||
throw Error("Cannot have more than 19 SLP token outputs.") | ||
} | ||
if (outputQtyArray.length < 1) { | ||
throw Error("Cannot have less than 1 SLP token output.") | ||
} | ||
outputQtyArray.forEach((outputQty) => { | ||
try { | ||
outputQty.absoluteValue() | ||
} catch(_) { | ||
throw Error("Amount must be an instance of BigNumber"); | ||
static get lokadIdHex() { return "534c5000"; } | ||
|
||
public static buildGenesisOpReturn( | ||
ticker: string|null, | ||
name: string|null, | ||
documentUrl: string|null, | ||
documentHashHex: string|null, | ||
decimals: number, | ||
batonVout: number|null, | ||
initialQuantity: BigNumber, | ||
type= 0x01, | ||
) { | ||
if (decimals === null || decimals === undefined) { | ||
throw Error("Decimals property must be in range 0 to 9"); | ||
} | ||
|
||
let MAX_QTY = new BigNumber('18446744073709551615'); | ||
|
||
if (outputQty.isGreaterThan(MAX_QTY)) | ||
throw new Error("Maximum value exceeded. Reduce input quantity below 18446744073709551615."); | ||
|
||
if (outputQty.isLessThan(0)) | ||
throw Error("All Send outputs must be greater than 0."); | ||
|
||
if (!outputQty.modulo(1).isEqualTo(new BigNumber(0))) | ||
throw Error("All Send outputs must be a whole number."); | ||
|
||
let qtyBuffer = Utils.int2FixedBuffer(outputQty) | ||
script.push(Utils.getPushDataOpcode(qtyBuffer)) | ||
qtyBuffer.forEach((item) => script.push(item)) | ||
}) | ||
|
||
let encodedScript = Utils.encodeScript(script) | ||
if (encodedScript.length > 223) { | ||
throw Error("Script too long, must be less than 223 bytes.") | ||
} | ||
return encodedScript | ||
if (ticker !== null && typeof ticker !== "string") { | ||
throw Error("ticker must be a string"); | ||
} | ||
if (name !== null && typeof name !== "string") { | ||
throw Error("name must be a string"); | ||
} | ||
let res = TokenType1.genesis( | ||
ticker || "", name || "", documentUrl || "", | ||
documentHashHex || "", decimals || 0, batonVout, initialQuantity); | ||
if (res.length > 223) { | ||
throw Error("Script too long, must be less than or equal to 223 bytes."); | ||
} | ||
return res; | ||
} | ||
|
||
static buildMintOpReturn(tokenIdHex: string, batonVout: number|null, mintQuantity: BigNumber, type=0x01) { | ||
let script: (number|number[])[] = []; | ||
|
||
// OP Return Prefix | ||
script.push(0x6a) | ||
|
||
// Lokad Id | ||
let lokadId = Buffer.from(this.lokadIdHex, 'hex') | ||
script.push(Utils.getPushDataOpcode(lokadId)) | ||
lokadId.forEach((item) => script.push(item)) | ||
|
||
// Token Version/Type | ||
if(![0x01, 0x81].includes(type)) | ||
throw Error("Unable to create Genesis for this token type.") | ||
let tokenVersionType = type | ||
script.push(Utils.getPushDataOpcode([tokenVersionType])) | ||
script.push(tokenVersionType) | ||
|
||
// Transaction Type | ||
let transactionType = Buffer.from('MINT') | ||
script.push(Utils.getPushDataOpcode(transactionType)) | ||
transactionType.forEach((item) => script.push(item)) | ||
|
||
// Token Id | ||
// check Token Id should be hexademical chracters. | ||
let re = /^([A-Fa-f0-9]{2}){32,32}$/; | ||
if (typeof tokenIdHex !== 'string' || !re.test(tokenIdHex)) { | ||
throw Error("TokenIdHex must be provided as a 64 character hex string.") | ||
} | ||
let tokenId = Buffer.from(tokenIdHex, 'hex') | ||
script.push(Utils.getPushDataOpcode(tokenId)) | ||
tokenId.forEach((item) => script.push(item)) | ||
|
||
// Baton Vout | ||
if (batonVout === null || batonVout === undefined) { | ||
[0x4c, 0x00].forEach((item) => script.push(item)) | ||
} else { | ||
if (batonVout < 2 || batonVout > 255 || !(typeof batonVout == 'number')) | ||
throw Error("Baton vout must a number and greater than 1 and less than 256.") | ||
|
||
script.push(Utils.getPushDataOpcode([batonVout])) | ||
script.push(batonVout) | ||
} | ||
|
||
// Initial Quantity | ||
let MAX_QTY = new BigNumber('18446744073709551615'); | ||
|
||
try { | ||
mintQuantity.absoluteValue() | ||
} catch(_) { | ||
throw Error("Amount must be an instance of BigNumber"); | ||
} | ||
|
||
if (mintQuantity.isGreaterThan(MAX_QTY)) | ||
throw new Error("Maximum mint value exceeded. Reduce input quantity below 18446744073709551615."); | ||
|
||
if (mintQuantity.isLessThan(0)) | ||
throw Error("Mint quantity must be greater than 0."); | ||
|
||
if (!mintQuantity.modulo(1).isEqualTo(new BigNumber(0))) | ||
throw Error("Mint quantity must be a whole number."); | ||
|
||
let initialQuantityBuf = Utils.int2FixedBuffer(mintQuantity) | ||
script.push(Utils.getPushDataOpcode(initialQuantityBuf)) | ||
initialQuantityBuf.forEach((item) => script.push(item)) | ||
public static buildSendOpReturn(tokenIdHex: string, outputQtyArray: BigNumber[], type= 0x01) { | ||
return TokenType1.send(tokenIdHex, outputQtyArray); | ||
} | ||
|
||
let encodedScript = Utils.encodeScript(script) | ||
if (encodedScript.length > 223) { | ||
throw Error("Script too long, must be less than 223 bytes.") | ||
} | ||
return encodedScript | ||
public static buildMintOpReturn(tokenIdHex: string, batonVout: number|null, mintQuantity: BigNumber, type= 0x01) { | ||
return TokenType1.mint(tokenIdHex, batonVout, mintQuantity); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.