UNPKG

digibyte-js

Version:

A pure and powerful JavaScript DigiByte library.

154 lines (123 loc) 5.02 kB
const Base58Check = require("../encoding/base58check"); const crypto = require("crypto"); const Address = require("../address"); const Script = require("../script/script"); const Vote = require("./vote"); function Metadata(data) { if (data) this.data = (typeof data == "string") ? JSON.parse(data) : data; else this.data = {}; } Metadata.prototype.name = function (name) { if (typeof name != "string") throw "Incorrect type for asset name"; this.data.assetName = name; return this; } Metadata.prototype.description = function (description) { if (typeof description != "string") throw "Incorrect type for asset name"; this.data.description = description; return this; } Metadata.prototype.addUrl = function (name, url, mimeType) { if (typeof name != "string") throw "Incorrect type for url name"; if (typeof url != "string") throw "Incorrect type for url url"; if (typeof mimeType != "string") throw "Incorrect type for url mimeType"; if (!this.data.urls) this.data.urls = []; this.data.urls.push({ name, url, mimeType }); return this; } Metadata.prototype.addUrl = function (name, url, mimeType) { if (typeof name != "string") throw "Incorrect type for url name"; if (typeof url != "string") throw "Incorrect type for url url"; if (typeof mimeType != "string") throw "Incorrect type for url mimeType"; if (!this.data.urls) this.data.urls = []; this.data.urls.push({ name, url, mimeType }); return this; } Metadata.prototype.site = function (url, type = "web") { if (typeof url != "string") throw "Incorrect type for site url"; if (typeof type != "string") throw "Incorrect type for site type"; this.data.site = { url, type }; return this; } Metadata.prototype.issuer = function (issuer) { if (typeof issuer != "string") throw "Incorrect type for asset issuer"; this.data.issuer = issuer; return this; } /** * @param {Vote} vote * @returns */ Metadata.prototype.vote = function (vote) { if (this.votes) delete this.votes; this.votes = []; for (var n in vote.options) this.votes.push({ address: Vote.addresses[n], label: vote.options[n] }); return this; } /** * @param {string} hashData * @param {"locked"|"unlocked"} locked * @param {"aggregatable"|"hybrid"|"dispersed"} aggregation * @param {int} divisibility */ Metadata.prototype.assetId = function (hashData, locked, aggregation, divisibility) { if (typeof hashData != "string") throw "hashData type mismatch"; if (typeof locked != "string") throw "locked type mismatch"; if (typeof divisibility != "number") throw "divisibility type mismatch" if (locked == "locked") { var test = hashData.split(":"); if (test.length != 2) throw "For locked assets the hashing data must be 'TXID:VOUT' of the first UTXO"; if (!(test[0].match(/^[a-fA-F0-9]+$/) && test[0].length == 64)) throw "For locked assets, the first part of the hasing data must be the TXID of the first UTXO"; if (!test[1].match(/^[0-9]*$/)) throw "For locked assets, the second part of the hasing data must be the VOUT of the first UTXO"; } else if (locked == "unlocked") { if (Address.isValid(hashData)) hashData = Script.fromAddress(hashData).toHex(); if (!hashData.match(/^[a-fA-F0-9]+$/)) throw "For unlocked assets, hash the ScriptPubKey of the first UTXO"; hashData = Buffer.from(hashData, "hex"); } else { throw "Define locked or unlocked asset"; } locked = locked === "locked"; aggregation = (aggregation == "a" || aggregation == "aggregatable") ? 0 : (aggregation == "h" || aggregation == "hybrid") ? 1 : (aggregation == "d" || aggregation == "dispersed") ? 2 : null; if (aggregation === null) throw "Unknown aggregation"; const issuanceFlags = (divisibility << 5) | (locked ? 16 : 0) | (aggregation << 2); const header = (['2e37', '2e6b', '2e4e', false, '20ce', '2102', '20e4', false])[(issuanceFlags & 0x1c) >>> 2]; const hash256 = crypto.createHash('sha256').update(hashData).digest(); const hash160 = crypto.createHash('ripemd160').update(hash256).digest('hex'); this.data.assetId = Base58Check.encode(Buffer.from(header + hash160 + '000' + divisibility, 'hex')); return this; } Metadata.prototype.toHash = function (encoding = null) { var hash = crypto.createHash('sha256').update(JSON.stringify(this)).digest(); return (encoding == null) ? hash : hash.toString(encoding); } Metadata.prototype.toString = function () { return JSON.stringify(this); } module.exports = Metadata;