UNPKG

bch-slpjs

Version:

Simple Ledger Protocol (SLP) JavaScript Library

261 lines (212 loc) 10.1 kB
import { Utils } from './utils'; import BigNumber from 'bignumber.js'; 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) { 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 let tokenVersionType = 0x01 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 !== null && typeof ticker !== 'string'){ throw Error("ticker must be a string") } else if (ticker === null || 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 !== null && typeof name !== 'string') { throw Error("name must be a string") } else if (name == null || 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 !== null && typeof documentUri !== 'string') { throw Error("documentUri must be a string") } else if (documentUri == null || 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 == null || 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 < 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) { [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[]) { 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 let tokenVersionType = 0x01 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"); } 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 } static buildMintOpReturn(tokenIdHex: string, batonVout: number|null, mintQuantity: BigNumber) { 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 let tokenVersionType = 0x01 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) { [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)) let encodedScript = Utils.encodeScript(script) if (encodedScript.length > 223) { throw Error("Script too long, must be less than 223 bytes.") } return encodedScript } }