UNPKG

js-oip

Version:

A Javascript Library to fully interact with the Open Index Protocol

1,629 lines (1,343 loc) 39.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; require("core-js/modules/web.dom.iterable"); require("core-js/modules/es6.regexp.split"); var _files = require("../../files"); var _oipRecord = _interopRequireDefault(require("../oip-record")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } const DEFAULT_NETWORK = 'IPFS'; const SUPPORTED_TYPES = ['Audio', 'Video', 'Image', 'Text', 'Software', 'Web', 'Research', 'Property']; /** * @typedef {Object} StatusObject * @property {Boolean} success - If the attempt was successful * @property {string} error - The error text (if there was an error) */ /** * An Artifact contains metadata about a file/piece of content, * along with a location on a network to find that file, * and optionally payment information. * * Create a new Artifact * This function is an es5 constructor that returns a new Artifact class based on the version of the artifact/record * ##### Examples * Create a blank Artifact * ``` * import { Artifact } from 'oip-index' * * let artifact = Artifact() * ``` * Create an Artifact from JSON * ``` * import { Artifact } from 'oip-index' * * let artifact = Artifact({ "artifact": { "publisher": "FPkvwEHjddvva2smpYwQ4trgudwFcrXJ1X", "payment": { "addresses": [], "retailer": 15, "sugTip": [], "fiat": "USD", "scale": "1000:1", "promoter": 15, "maxdisc": 30 }, "storage": { "files": [ { "fname": "headshot.jpg", "fsize": 100677, "type": "Image" } ], "location": "QmUjSCcBda9YdEUKVLPQomHzSatwytPqQPAh4fdMiRV8bp", "network": "IPFS" }, "type": "Image-Basic", "info": { "title": "Headshot", "extraInfo": { "artist": "David Vasandani", "genre": "People" } }, "timestamp": 1531065099 }, "meta": { "block_hash": "a2ca4c3f06032dc4f9df7eca829b42b91da9595dbe9f4623a1c7f92a5508cfb9", "txid": "5f399eef8f93c03502efbd51691350cbacbf3c16eba228409bf7453ffff78207", "block": 2832215, "time": 1531065167, "type": "oip041" } }) * ``` * Create an Artifact from a JSON string * ``` * import { Artifact } from 'oip-index' * * let artifact = new Artifact("{"artifact":{"publisher":"FPkvwEHjddvva2smpYwQ4trgudwFcrXJ1X","payment":{"addresses":[],"retailer":15,"sugTip":[],"fiat":"USD","scale":"1000:1","promoter":15,"maxdisc":30},"storage":{"files":[{"fname":"headshot.jpg","fsize":100677,"type":"Image"}],"location":"QmUjSCcBda9YdEUKVLPQomHzSatwytPqQPAh4fdMiRV8bp","network":"IPFS"},"type":"Image-Basic","info":{"title":"Headshot","extraInfo":{"artist":"David Vasandani","genre":"People"}},"timestamp":1531065099},"meta":{"block_hash":"a2ca4c3f06032dc4f9df7eca829b42b91da9595dbe9f4623a1c7f92a5508cfb9","txid":"5f399eef8f93c03502efbd51691350cbacbf3c16eba228409bf7453ffff78207","block":2832215,"time":1531065167,"type":"oip041"}}") * ``` * @class Artifact * @param {Array<Multipart>|string|Object} input - Pass in either an array of Multiparts, an Artifact JSON string, or an Artifact JSON object to be loaded from * @return {Artifact} */ class Artifact extends _oipRecord.default { constructor(input) { super(input); this.artifact = { floAddress: '', info: {}, details: {}, storage: { network: DEFAULT_NETWORK, files: [] }, payment: {}, type: undefined, subtype: undefined, signature: undefined, timestamp: undefined }; this.meta = { block: undefined, block_hash: undefined, deactivated: false, signature: undefined, time: undefined, tx: undefined, txid: undefined, originalTxid: undefined, version: undefined, type: undefined }; this.FileObjects = []; // constructor if (input) { if (typeof input === 'string') { if (input.startsWith('json:')) { input = input.slice(5); } try { this.fromJSON(JSON.parse(input)); } catch (e) { console.error('Error parsing input in Artifact constructor', e); } } else if (typeof input === 'object') { this.fromJSON(input); } } } /** * Returns the Artifact Type (to be used before class initialization) * @returns {string} */ static getArtifactType() { return 'artifact'; } /** * Return the Artifact Subtype (to be used before class initialization) * @returns {string} */ static getArtifactSubtype() { return ''; } // /** // * Returns the original data fed to the constructor // * @returns {*} // */ // _getSource() { // return this._source // } // /** // * Set source data (DANGEROUS!!). Resets the original data fed into the constructor // * @param data // * @private // */ // _setSourceData(data) { // this._source = data // } /** * Set TXID * @param txid */ setTXID(txid) { this.meta.txid = txid; if (!this.getOriginalTXID) { this.setOriginalTXID(this.getTXID); } } /** * Get TXID * @return {string} txid */ getTXID() { return this.meta.txid; } /** * Set the Original Record TXID (setTXID will be different if edits have been performed) * @param {string} originalTxid */ setOriginalTXID(originalTxid) { this.meta.originalTxid = originalTxid; } /** * Get the Original Record TXID (getTXID will be different if edits have been performed) * @return {String} originalTxid */ getOriginalTXID() { return this.meta.originalTxid; } /** * Set the Publisher name String, please note that this does not set it when you publish to the blockchain! * @param {string} publisherName - The Publisher Name you wish to set the Artifact to * @example * artifact.setPublisherName("My Publisher Name") */ setPublisherName(pubName) { this.publisherName = pubName; } /** * Get the Publisher Name for the Artifact * @example * let pubName = artifact.getPublisherName() * @return {string} Returns the Publisher Name if defined, or the Main Address if the publisher name is undefined */ getPublisherName() { return this.publisherName || this.getPubAddress(); } /** * Set the Main Address that you will be signing the Artifact with * @example * artifact.setPubAddress("FLZXRaHzVPxJJfaoM32CWT4GZHuj2rx63k") * @param {string} address - The Main Address that will be signing the Artifact */ setPubAddress(address) { this.artifact.floAddress = address; } /** * Get the Main Address that the Artifact is signed with * @example * let mainAddress = artifact.getPubAddress() * @return {string} */ getPubAddress() { return this.artifact.floAddress; } /** * Set publish/signature timestamp for the Artifact * @example * artifact.setTimestamp(Date.now()) * @param {number} time - The Timestamp you wish to set the Artifact to */ setTimestamp(time) { if (typeof time === 'number') { this.artifact.timestamp = time; } } /** * Get the publish/signature timestamp for the Artifact * @example * let timestamp = artifact.getTimestamp() * @return {number} Returns `undefined` if timestamp is not yet set */ getTimestamp() { return this.artifact.timestamp; } /** * Set the Artifact Title * @example * artifact.setTitle("Example Title") * @param {string} title - The desired Title you wish to set the Artifact to */ setTitle(title) { this.artifact.info.title = title; } /** * Get the Artifact Title * @example * let title = artifact.getTitle() * @return {string} */ getTitle() { return this.artifact.info.title || ''; } /** * Set the Description of the Artifact * @example * artifact.setDescription("My Description") * @param {string} description - The Description you wish to set */ setDescription(description) { this.artifact.info.description = description; } /** * Get the Description of the Artifact * @example * let description = artifact.getDescription() * @return {string} */ getDescription() { return this.artifact.info.description || ''; } /** * Set the Type of the Artifact * @example * artifact.setType("Video") * @param {string} type - Must be one of the following supported Artifact Main Types ["Audio", "Video", "Image", "Text", "Software", "Web", "Research", "Property"] */ setType(type) { type = this.capitalizeFirstLetter(type); if (SUPPORTED_TYPES.indexOf(type) === -1) { return 'Type Not Supported!'; } this.artifact.type = type; } /** * Get the Type of the Artifact * @example * let type = artifact.getType() * @return {string} */ getType() { return this.artifact.type; } /** * Set the Subtype of the Artifact * @example * artifact.setSubtype("Album") * @param {string} subtype - The desired Subtype for the Artifact */ setSubtype(subtype) { subtype = this.capitalizeFirstLetter(subtype); this.artifact.subtype = subtype; } /** * Get the Subtype of the Artifact * @example * let subtype = artifact.getSubtype() * @return {string} */ getSubtype() { return this.artifact.subtype; } /** * Set the Year that the content was originally published * @example * artifact.setYear(2018) * @param {number} year - The Year that the content was originally published */ setYear(year) { if (typeof year === 'number') { this.artifact.info.year = year; } } /** * Get the Year that the content was originally published * @example * let year = artifact.getYear() * @return {number} */ getYear() { return this.artifact.info.year; } /** * Set if the Artifact is NSFW * @example * artifact.setNSFW(true) * @param {Boolean} nsfwToggle - `true` or `false` depending on the content of the Artifact */ setNSFW(nsfwToggle) { this.artifact.info.nsfw = nsfwToggle; } /** * Get if the Artifact is marked NSFW * @example * let nsfw = artifact.getNSFW() * @return {Boolean} */ getNSFW() { return this.artifact.info.nsfw || false; } /** * Set the Tags for the Artifact * @example * artifact.setTags(["Tag 1", "Tag 2", "Tag 3"]) * @param {Array.<string>} tags - Pass in an Array of tags */ setTags(tags) { if (Array.isArray(tags)) { this.artifact.info.tags = tags; } else { if (tags.split(', ').length > 1) { this.artifact.info.tags = tags.split(', '); } else { this.artifact.info.tags = [tags]; } } } /** * Get the Tags for the Artifact * @example * let tags = artifact.getTags() * @return {Array.<string>} */ getTags() { return this.artifact.info.tags || []; } /** * Set a specific Detail on the Artifact * @param {string} detail - Where should we place this detail (i.e. "artist") * @example * artifact.setDetail("artist", "Artist Name") * @param {Object} info - The item you wish to set to the detail node */ setDetail(detail, info) { this.artifact.details[detail] = info; } /** * Get a specific Detail back from the Artifact * @param {string} detail - The detail you want pack (i.e. "artist") * @example * let artist = artifact.getDetail("artist") * @return {Object} */ getDetail(detail) { return this.artifact.details[detail]; } /** * Set the Signature of the Artifact * @example * artifact.setSignature("IO0i5yhuwDy5p93VdNvEAna6vsH3UmIert53RedinQV+ScLzESIX8+QrL4vsquCjaCY0ms0ZlaSeTyqRDXC3Iw4=") * @param {string} signature - The signature of the Artifact */ setSignature(signature) { this.artifact.signature = signature; } /** * Get the Signature of the Artifact * @example * let signature = artifact.getSignature() * @return {string} Returns `undefined` if signature is not set */ getSignature() { return this.artifact.signature; } /** * Set the Storage Network of the Artifact * @example <caption>Set Network to IPFS</caption * artifact.setNetwork("IPFS") * @example <caption>Set Network to Storj (Support coming Soon)</caption * artifact.setNetwork("Storj") * @param {string} network - The Storage Network where we can find the file at Location */ setNetwork(network) { if (network === 'ipfs') { network = 'IPFS'; } this.artifact.storage.network = network; } /** * Get the Storage Network for the Artifact * @example * let mainAddress = artifact.getPubAddress() * @return {string} */ getNetwork() { return this.artifact.storage.network; } /** * Set the Storage Location * @example * artifact.setLocation("QmNmVHfXuh5Tub76H1fog7wSM8of4Njfm2j1oTg8ZYUBZm") * @param {string} location - The Location of the files on the Storage Network */ setLocation(location) { this.artifact.storage.location = location; } /** * Get the Storage Location * @example * let location = artifact.getLocation() * @return {string} */ getLocation() { return this.artifact.storage.location; } /** * Set the Fiat to be used in Payment Calculations. Only "usd" is supported right now. * @example * artifact.setPaymentFiat("usd") * @param {string} fiat - The Fiat type you wish to accept */ setPaymentFiat(fiat) { this.artifact.payment.fiat = fiat; } /** * Get the Fiat type to be used in Payment Calculations * @example * let fiat = artifact.getPaymentFiat() * @return {string} Returns undefined if no fiat is set */ getPaymentFiat() { return this.artifact.payment.fiat; } /** * Set the Payment Scale to use in Payment Calculations * @example * artifact.setPaymentScale(1000) * @param {number} newScale - The new Scale that should be used */ setPaymentScale(newScale) { this.artifact.payment.scale = newScale; } /** * Get the payment scale for use in Payment Calculations * @example * let scale = artifact.getPaymentScale() * @return {number} Returns 1 if no payment scale is set (aka, 1:1 scale) */ getPaymentScale() { // Check if scale is a string // If so, check if the string is a number, or represented as a ratio // return the parsed number or ratio bound if (this.artifact.payment.scale) { if (typeof this.artifact.payment.scale === 'string') { if (isNaN(this.artifact.payment.scale) && this.artifact.payment.scale.split(':').length === 2) { return parseInt(this.artifact.payment.scale.split(':')[0]); } else if (!isNaN(this.artifact.payment.scale)) { return parseInt(this.artifact.payment.scale); } } return this.artifact.payment.scale; } else { // Return 1:1 scale if undefined! The user should ALWAYS set scale ON PUBLISH if they are using a scale! return 1; } } /** * Set suggested tip values to use. These tip values are the fiat value, divided by the scale you set. * @example * artifact.setSuggestedTip([10, 100, 1000]) * @param {Array<number>} suggestedTipArray - The Suggested Tips you wish to define */ setSuggestedTip(suggestedTipArray) { this.artifact.payment.tips = suggestedTipArray; } /** * Get what the user has defined as their suggested tip values * @example * let tips = artifact.getSuggestedTip() * @return {Array<number>} */ getSuggestedTip() { return this.artifact.payment.tips || []; } /** * !!! NOT YET IMPLEMENTED !!! * Add Token Rule to the Artifact * @param {TokenRule} tokenRule - The Token Rule to add to the Artifact */ addTokenRule(tokenRule) { this.artifact.payment.tokens.push(tokenRule); } /** * !!! NOT YET IMPLEMENTED !!! * Get Token Rules from the Artifact * @return {Array.<TokenRule>} */ getTokenRules() { return this.artifact.payment.tokens; } /** * Accept Payments for a specific coin * @param {string} coin - The string coin ticker * @param {string} address - Base58 Public Key to send payments */ addSinglePaymentAddress(coin, address) { if (!this.artifact.payment.addresses) { this.artifact.payment.addresses = {}; } let tmpObj = {}; tmpObj[coin.toLowerCase()] = address; this.artifact.payment.addresses = _objectSpread({}, this.artifact.payment.addresses, tmpObj); } /** * Get the Address(es) to send Payments to for specific coins * @param {(string|Array.<string>)} coins - A string or an array of strings of the coins you wish to fetch the addresses for * @example * let address = artifact.getPaymentAddress(["btc", "ltc"]) * { btc: "19HuaNprtc8MpG6bmiPoZigjaEu9xccxps", ltc: "LbpjYYPwYBjoPQ44PrNZr7nTq7HkYgcoXN"} * @return {Object} - keyValue => [string][string] === [coin][address] */ getPaymentAddress(coins) { if ((!this.artifact.payment.addresses || this.artifact.payment.addresses === {}) && this.getPubAddress() && this.getPubAddress() !== '') { return { flo: this.getPubAddress() }; } let tmpObj = {}; if (Array.isArray(coins)) { for (let coin of coins) { for (let _coin in this.artifact.payment.addresses) { if (coin === _coin) { tmpObj[coin] = this.artifact.payment.addresses[coin]; } } } } else if (typeof coins === 'string') { tmpObj[coins] = this.artifact.payment.addresses[coins]; } return tmpObj; } /** * Get the Addresses to send Payment to * @example * let addresses = artifact.getPaymentAddresses() * @return {Object} - keyValue => [string][string] === [coin][address] */ getPaymentAddresses(coins) { if ((!this.artifact.payment.addresses || this.artifact.payment.addresses === {}) && this.getPubAddress() && this.getPubAddress() !== '') { return { flo: this.getPubAddress() }; } let tmpObj = {}; if (coins) { if (Array.isArray(coins)) { for (let _coin in this.artifact.payment.addresses) { for (let coin of coins) { if (coin === _coin) { tmpObj[coin] = this.artifact.payment.addresses[coin]; } } } return tmpObj; } else if (typeof coins === 'string') { tmpObj[coins] = this.artifact.payment.addresses[coins]; return tmpObj; } } return this.artifact.payment.addresses || {}; } /** * Get the supported payment coins * @param {(string|Array.<String>)} [coins] - coins you want to check against * @example * let supportedCoins = artifact.getSupportedCoins() * @return {(String|Array.<String>)} */ getSupportedCoins(coins) { let coinCheck = coins || undefined; let supportedCoins = []; let addrs = this.getPaymentAddresses(); if (typeof addrs === 'object') { for (let coin in addrs) { supportedCoins.push(coin); } } else { throw new Error('Invalid parameter. Expecting an Array of Objects: [{[coin][addr]},]'); } if (coinCheck) { if (Array.isArray(coinCheck)) { let _coins = []; for (let myCoin of coinCheck) { for (let supCoin of supportedCoins) { if (myCoin === supCoin) { _coins.push(myCoin); } } } return _coins; } else if (typeof coinCheck === 'string') { if (supportedCoins.includes(coinCheck)) { return coinCheck; } else { return ''; } } } return supportedCoins; } /** * Get the Addresses to send Tips to * @example * let addresses = artifact.getPaymentAddresses() * @return {Object} - keyValue => [string][string] === [coin][address] */ getTipAddresses() { return this.getPaymentAddresses(); } /** * Set the cut you want to send to Retailers for selling your content * @example * artifact.setRetailerCut(10) * @param {number} newCut - The new cut you want sent to Retailers */ setRetailerCut(newCut) { if (typeof newCut === 'number') { this.artifact.payment.retailer = newCut; } } /** * Get the cut that the user wants to send to Retailers for selling their content * @example * let retailerCut = artifact.getRetailerCut() * @return {number} */ getRetailerCut() { return this.artifact.payment.retailer || 0; } /** * Set the cut you want to send to Promoters for sharing your content * @example * artifact.setPromoterCut(10) * @param {number} newCut - The new cut you want sent to Retailers */ setPromoterCut(newCut) { if (typeof newCut === 'number') { this.artifact.payment.promoter = newCut; } } /** * Get the cut that the user wants to send to Promoters for sharing their content * @example * let promoterCut = artifact.getPromoterCut() * @return {number} */ getPromoterCut() { return this.artifact.payment.promoter || 0; } /** * Set the maximum discount percent that Retailers can discount your content by during a sale * @example * artifact.setMaxDiscount(20) * @param {number} newMax - The new maximim discount percentage */ setMaxDiscount(newMax) { if (typeof newMax === 'number') { this.artifact.payment.maxdisc = newMax; } } /** * Get the maximum discount percent that Retailers can discount the content by during a sale * @example * let maxDiscount = artifact.getMaxDiscount() * @return {number} */ getMaxDiscount() { return this.artifact.payment.maxdisc || 0; } /** * Add a File to the Artifact * @param {ArtifactFile} file - The file you wish to add */ addFile(file) { if (file instanceof _files.ArtifactFile) { this.FileObjects.push(new _files.ArtifactFile(file.toJSON(), this)); } else if (typeof file === 'object' || typeof file === 'string') { this.FileObjects.push(new _files.ArtifactFile(file, this)); } } /** * Get all the Files on the Artifact * @return {Array.<ArtifactFile>} */ getFiles() { return this.FileObjects; } /** * Get the Thumbnail file if it exists * @return {ArtifactFile} Returns undefined if no file is matched */ getThumbnail() { for (let file of this.getFiles()) { if (file.getType() === 'Image' && file.getSubtype() === 'Thumbnail' && file.getSuggestedPlayCost() === 0) { return file; } } for (let file of this.getFiles()) { if (file.getType() === 'Image' && file.getSuggestedPlayCost() === 0) { return file; } } return undefined; } /** * Get the "simple" Duration of the Artifact. * This gets the duration of the first file that has a duration. * @return {number} Returns undefined if there is no match to a duration */ getDuration() { for (let file of this.getFiles()) { if (!isNaN(file.getDuration())) { return file.getDuration(); } } return undefined; } /** * Check if an Artifact is Valid and has all the required fields to be Published * @return {StatusObject} */ isValid() { if (!this.artifact.info.title || this.artifact.info.title === '') { return { success: false, error: 'Artifact Title is a Required Field' }; } if (!this.artifact.floAddress || this.artifact.floAddress === '') { return { success: false, error: 'floAddress is a Required Field!' }; } return { success: true }; } /** * Check if the Artifact is Paid. An Artifact is defined as paid if any files have a cost. * @return {Boolean} */ isPaid() { let files = this.getFiles(); if (files) { for (let file of files) { if (file.isPaid()) { return true; } } } return false; } /** * Set block [height] */ setBlock(block) { this.meta.block = block; } /** * Get block [height] */ getBlock() { return this.meta.block; } /** * Set block hash * @param blockHash */ setBlockHash(blockHash) { this.meta.block_hash = blockHash; } /** * Get block hash */ getBlockHash() { return this.meta.block_hash; } /** * Set deactivation status * @param {boolean} status */ setDeactivated(status) { this.meta.deactivated = status; } /** * Get deactivation status * @returns {boolean} */ getDeactivated() { return this.meta.deactivated; } /** * Set time (unix timestamp of block creation) * @param time */ setTime(time) { this.meta.time = time; } /** * Get the unix timestamp of the block creation) * @returns {undefined|*} */ getTime() { return this.meta.time; } /** * Set Artifact Version * @param version - 'alexandria-media', 'oip041', or 'oip042' */ setVersion(version) { this.meta.type = version; } /** * Set Record Edit Version * @param editTxid - The txid of the Edit Record */ setEditVersion(editTxid) { this.meta.version = editTxid; } /** * Get Record Edit Version * @returns The txid of the Edit Record */ getEditVersion() { return this.meta.version; } /** * Get Artifact Version type */ getVersion() { return this.meta.type; } /** * Get the Artifact object * @return {Object} */ getArtifact() { return this.artifact; } /** * Get the Meta Object * @return {Object} */ getMeta() { return this.meta; } /** * Get the Artifact JSON. This is the "Dehydrated" version of this class. * @return {Object} */ toJSON() { this.artifact.storage.files = []; for (let file of this.FileObjects) { this.artifact.storage.files.push(file.toJSON()); } let artifact = this.getArtifact(); let meta = this.getMeta(); let artJSON = { artifact, meta }; let cloneJSON = JSON.parse(JSON.stringify(artJSON)); // OIPd will not accept artifacts that have storage defined without any files if (this.artifact.storage.files.length === 0) { delete cloneJSON.artifact.storage; } return cloneJSON; } /** * Load the Artifact from JSON. This "Hydrates" this class with the "Dehydrated" info. * @param {Object} artifact - The specific Artifact JSON * @return {StatusObject} */ fromJSON(artifact) { if (artifact) { if (!artifact.meta) { if (artifact['media-data']) { if (artifact['media-data']['alexandria-media']) { this.setVersion('alexandria-media'); return this.importAlexandriaMedia(artifact['media-data']['alexandria-media']); } else { return { success: false, error: 'No Artifact_DEPRECATED under Version!' }; } } else if (artifact['oip-041']) { this.setVersion('oip041'); if (artifact['oip-041'].signature) { this.setSignature(artifact['oip-041'].signature); } if (artifact['oip-041'].artifact) { return this.import041(artifact['oip-041'].artifact); } else { return { success: false, error: 'No Artifact_DEPRECATED under Version!' }; } } else if (artifact.oip042) { if (artifact.oip042.signature) { this.setSignature(artifact.oip042.signature); } if (artifact.oip042.artifact) { this.setVersion('oip042'); return this.import042(artifact.oip042.artifact); } else if (artifact.oip042.publish && artifact.oip042.publish.artifact) { return this.import042(artifact.oip042.publish.artifact); } else { return { success: false, error: 'No Artifact_DEPRECATED under Version!' }; } } } else { this.setBlock(artifact.meta.block); this.setBlockHash(artifact.meta.block_hash); this.setDeactivated(artifact.meta.deactivated || false); this.setSignature(artifact.meta.signature); this.setTXID(artifact.meta.txid); this.setOriginalTXID(artifact.meta.originalTxid); this.setTime(artifact.meta.time); this.setVersion(artifact.meta.type); switch (artifact.meta.type) { case 'alexandria-media': this.importAlexandriaMedia(artifact.artifact); break; case 'oip041': this.import041(artifact.artifact); break; case 'oip042': this.import042(artifact.artifact); break; default: return { success: false, error: 'Unsupported media type. Check artifact.meta.type', detail: artifact }; } } } else { return { success: false, error: 'Artifact Not Provided!' }; } } /** * Returns a string version of the .toJSON() function * @return {string} */ toString() { return JSON.stringify(this.toJSON()); } /** * Hydrate an alexandria-media JSON object * @param artifact */ importAlexandriaMedia(artifact) { if (artifact.publisher) { this.setPubAddress(artifact.publisher); } if (artifact.timestamp) { this.setTimestamp(artifact.timestamp); } if (artifact.type) { let type = artifact.type; if (type === 'music') { type = 'Audio'; } if (type === 'book') { type = 'Text'; this.setSubtype('Book'); } if (type === 'thing') { type = 'Web'; } this.setType(type); } if (artifact.torrent) { this.setLocation(artifact.torrent); if (artifact.torrent.split(':')[0] === 'btih') { this.setNetwork('bittorrent'); } } if (artifact.info) { if (artifact.info.title) { this.setTitle(artifact.info.title); } if (artifact.info.description) { this.setDescription(artifact.info.description); } if (artifact.info.year) { this.setYear(artifact.info.year); } if (artifact.info['extra-info']) { let tmpFiles = []; let hadFiles = false; for (let key in artifact.info['extra-info']) { if (artifact.info['extra-info'].hasOwnProperty(key)) { switch (key) { case 'tags': this.setTags(artifact.info['extra-info'][key]); break; case 'Bitcoin Address': this.addSinglePaymentAddress('btc', artifact.info['extra-info'][key]); break; case 'DHT Hash': let hash = artifact.info['extra-info'][key]; this.setLocation(hash); break; case 'filename': if (artifact.info['extra-info'][key] !== 'none') { tmpFiles.push({ fname: artifact.info['extra-info'][key] }); } break; case 'posterFrame': tmpFiles.push({ fname: artifact.info['extra-info'][key], type: 'Image', subtype: 'Thumbnail' }); break; case 'runtime': this.setDetail('duration', artifact.info['extra-info'][key]); break; case 'files': let fileList = artifact.info['extra-info'][key]; for (let file of fileList) { this.addFile(file); } if (this.FileObjects.length > 0) { hadFiles = true; } break; default: this.setDetail(key, artifact.info['extra-info'][key]); } } } if (!hadFiles) { for (let file of tmpFiles) { this.addFile(file); } } } } if (artifact.payment) {// toDo // if (artifact.payment.type && artifact.payment.type === "tip"){ // this.setPaymentFiat(artifact.payment.fiat); // } // if (artifact.payment.scale){ // this.setPaymentScale(artifact.payment.scale); // } // if (artifact.payment.sugTip){ // this.setSuggestedTip(artifact.payment.sugTip) // } } } /** * Hydrate an oip041 JSON object * @param artifact */ import041(artifact) { if (artifact.publisher) { this.setPubAddress(artifact.publisher); } if (artifact.timestamp) { this.setTimestamp(artifact.timestamp); } if (artifact.type) { if (artifact.type.split('-').length === 2) { let type = artifact.type.split('-')[0]; let subtype = artifact.type.split('-')[1]; this.setType(type); this.setSubtype(subtype); } else if (artifact.type.split('-').length === 1) { this.setType(artifact.type); } } if (artifact.info) { if (artifact.info.title) { this.setTitle(artifact.info.title); } if (artifact.info.description) { this.setDescription(artifact.info.description); } if (artifact.info.year) { this.setYear(artifact.info.year); } if (artifact.info.tags) { this.setTags(artifact.info.tags); } if (artifact.info.nsfw) { this.setNSFW(artifact.info.nsfw); } if (artifact.info.extraInfo) { for (let key in artifact.info.extraInfo) { if (artifact.info.extraInfo.hasOwnProperty(key)) { this.setDetail(key, artifact.info.extraInfo[key]); } } } } if (artifact.storage) { if (artifact.storage.network) { this.setNetwork(artifact.storage.network); } if (artifact.storage.location) { this.setLocation(artifact.storage.location); } if (artifact.storage.files) { for (let file of artifact.storage.files) { this.addFile(file); } } } if (artifact.payment) { if (artifact.payment.fiat) { this.setPaymentFiat(artifact.payment.fiat); } if (artifact.payment.scale) { this.setPaymentScale(artifact.payment.scale); } if (artifact.payment.sugTip) { this.setSuggestedTip(artifact.payment.sugTip); } if (artifact.payment.tokens && Array.isArray(artifact.payment.tokens)) { for (let token of artifact.payment.tokens) { this.addTokenRule(token); } } if (artifact.payment.addresses) { for (let address of artifact.payment.addresses) { this.addSinglePaymentAddress(address.token, address.address); } } if (artifact.payment.retailer) { this.setRetailerCut(artifact.payment.retailer); } if (artifact.payment.promoter) { this.setPromoterCut(artifact.payment.promoter); } if (artifact.payment.maxdisc) { this.setMaxDiscount(artifact.payment.maxdisc); } } } /** * Hydrate an oip042 JSON object * @param artifact */ import042(artifact) { if (artifact.floAddress) { this.setPubAddress(artifact.floAddress); } if (artifact.timestamp) { this.setTimestamp(artifact.timestamp); } if (artifact.type) { this.setType(artifact.type); } if (artifact.subtype) { this.setSubtype(artifact.subtype); } if (artifact.signature) { this.setSignature(artifact.signature); } if (artifact.info) { if (artifact.info.title) { this.setTitle(artifact.info.title); } if (artifact.info.description) { this.setDescription(artifact.info.description); } if (artifact.info.year) { this.setYear(artifact.info.year); } if (artifact.info.tags) { this.setTags(artifact.info.tags); } if (artifact.info.nsfw) { this.setNSFW(artifact.info.nsfw); } } if (artifact.details) { for (let key in artifact.details) { if (artifact.details.hasOwnProperty(key)) { this.setDetail(key, artifact.details[key]); } } } if (artifact.storage) { if (artifact.storage.network) { this.setNetwork(artifact.storage.network); } if (artifact.storage.location) { this.setLocation(artifact.storage.location); } if (artifact.storage.files) { for (let file of artifact.storage.files) { this.addFile(file); } } } if (artifact.payment) { if (artifact.payment.fiat) { this.setPaymentFiat(artifact.payment.fiat); } if (artifact.payment.scale) { this.setPaymentScale(artifact.payment.scale); } if (artifact.payment.sugTip) { this.setSuggestedTip(artifact.payment.sugTip); } if (artifact.payment.tokens && Array.isArray(artifact.payment.tokens)) { for (let token of artifact.payment.tokens) { this.addTokenRule(token); } } if (artifact.payment.addresses) { for (let coin in artifact.payment.addresses) { this.addSinglePaymentAddress(coin, artifact.payment.addresses[coin]); } } if (artifact.payment.retailer) { this.setRetailerCut(artifact.payment.retailer); } if (artifact.payment.promoter) { this.setPromoterCut(artifact.payment.promoter); } if (artifact.payment.maxdisc) { this.setMaxDiscount(artifact.payment.maxdisc); } } } capitalizeFirstLetter(string) { return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase(); } /** * Get the Class Name. * This is used to check the passed object in ArtifactFile (since InstanceOf could not be done). * @return {string} Returns "Artifact" */ getClassName() { return 'Artifact'; } /** * Create message to use for signature * @return {string} */ createPreimage() { if (!this.getTimestamp()) { this.setTimestamp(Date.now()); } let preimage = `${this.getLocation() || ''}-${this.getPubAddress()}-${this.getTimestamp()}`; this.preimage = preimage; return preimage; } serialize(method) { // convert this to json and extract artifact let artJSON = this.toJSON(); let art = artJSON.artifact; // setup initial object let pubMessage = { oip042: {} // insert method type }; pubMessage['oip042'][method] = { artifact: art // add json prefix }; return 'json:' + JSON.stringify(pubMessage); } } var _default = Artifact; exports.default = _default;