3eca1fff33945218ab8b4a250f1f221bf2e719b0c25c54c3b0f79cddeec2e2fc
{
  "bitpost": "code",
  "data": "const pixelMaker = require('pixel-sprite-generator-nodejs');\nconst canvas = require('canvas');\nconst bsv = require('bsv');\nconst Run = require('run-sdk');\nconst run = new Run({\n    owner: '',\n    purse: '',\n    trust: '*',\n    timeout: 60000,\n    api: 'run',\n});\nconst RelayNFTLocation = '84e20d29a122c6c3ad3776cc16c049d196fa28f9447b0745053d2b9ea9c0ff11_o1';\nconst OrderLockLocation = 'd6170025a62248d8df6dc14e3806e68b8df3d804c800c7bfb23b0b4232862505_o1';\nconst GenNFTLocation = '';\ngetRandomInt = max => { return Math.floor(Math.random() * max) + 1 } // generate random integer between 1 and 10\n\nconst berryTx = async(imageBuf, filename) => {\n    const bsvtx = new bsv.Transaction();\n    const utxos = await run.blockchain.utxos(run.purse.address);\n    bsvtx.from(utxos);\n    bsvtx.addSafeData(['19HxigV4QyBv3tHpQVcUEQyq1pzZVdoAut', imageBuf, 'image/png', 'binary', filename]);\n    bsvtx.change(run.purse.address);\n    bsvtx.sign(run.purse.privkey);\n    const txid = await run.blockchain.broadcast(bsvtx.toString());\n    console.log({txid})\n    return txid;\n}\nconst deploy = async() => {\n    const RelayNFT = await run.load(RelayNFTLocation);\n    const OrderLock = await run.load(OrderLockLocation);\n    class GenerativeNFT extends RelayNFT {\n        setMetadata(metadata) {\n            this.metadata = metadata;\n        }\n        setName(name) {\n            this.name = name;\n        }\n        setStats(stats) {\n            this.strength = stats.strength;\n            this.vitality = stats.vitality;\n            this.agility = stats.agility;\n            this.intelligence = stats.intelligence;\n        }\n    }\n    GenerativeNFT.metadata = {\n        emoji: '🧬',\n        description: \"Generative Art NFT\"\n    }\n    GenerativeNFT.interactive = false;\n    GenerativeNFT.friends = [Run.extra.B, OrderLock];\n    const tx = new Run.Transaction();\n    tx.update(() => {\n        run.deploy(GenerativeNFT);\n    })\n    const txid = await tx.publish();\n    console.log({txid})\n}\n//deploy();\nconst resize = (img, scale, removeWhite) => { // resize image, remove whitespace\n    var widthScaled  = img.width * scale;\n    var heightScaled = img.height * scale;\n    var origCtx = img.canvas.getContext('2d');\n    var origPixels = origCtx.getImageData(0, 0, img.width, img.height);\n    origPixels = img.pixels;\n    let pixel = img.pixels.data;\n    if (removeWhite) {\n        let r=0, g=1, b=2,a=3;\n        for (let p = 0; p < pixel.length; p+=4) {\n            if (pixel[p+r] == 255 &&\n                pixel[p+g] == 255 &&\n                pixel[p+b] == 255) // if white then change alpha to 0\n            { pixel[p+a] = 0 }\n        }\n    }\n    origPixels.data = pixel;\n    let scaled = canvas.createCanvas(widthScaled, heightScaled);\n    var scaledCtx    = scaled.getContext('2d');\n    var scaledPixels = scaledCtx.getImageData( 0, 0, widthScaled, heightScaled );\n    for( var y = 0; y < heightScaled; y++ ) {\n        for( var x = 0; x < widthScaled; x++ ) {\n            var index = (Math.floor(y / scale) * img.width + Math.floor(x / scale)) * 4;\n            var indexScaled = (y * widthScaled + x) * 4;\n            scaledPixels.data[ indexScaled ]   = origPixels.data[ index ];\n            scaledPixels.data[ indexScaled+1 ] = origPixels.data[ index+1 ];\n            scaledPixels.data[ indexScaled+2 ] = origPixels.data[ index+2 ];\n            scaledPixels.data[ indexScaled+3 ] = origPixels.data[ index+3 ];\n        }\n    }\n    scaledCtx.putImageData( scaledPixels, 0, 0 );\n    return scaled;\n}\ngenerate = () => { // create random dragon sprite\n    return new Promise((resolve, reject) => {\n        const sprite = pixelMaker.createCreature('./sprites/', n => {\n            console.log(`Created random creature: ${n}`);\n            const resized = resize(sprite, 16, true);\n            resolve({ imageBuf: resized.toBuffer(), filename: n })\n        }, pixelMaker.masks.dragon);\n    });\n}\nconst minting = async(name) => {\n    const img = await generate();\n    const berryTxid = await berryTx(img.imageBuf, img.filename);\n    const GenNFT = await run.load(GenNFTLocation);\n    await GenNFT.sync();\n    const image = await Run.extra.B.load(berryTxid);\n    const metadata = { image };\n    const stats = {\n        strength: getRandomInt(10),\n        vitality: getRandomInt(10),\n        agility: getRandomInt(10),\n        intelligence: getRandomInt(10)\n    }\n    const tx = new Run.Transaction();\n    tx.update(() => {\n        const dragon = GenNFT.mint();\n        dragon.setName(name);\n        dragon.setMetadata(metadata);\n        dragon.setStats(stats);\n    })\n    const t = await tx.publish();\n    console.log({t})\n}\nminting('Shua');",
  "opts": {
    "enc": "0",
    "pub": "1"
  },
  "signatures": {
    "child": {
      "hash": "0a9a74292e48f6369f0439bdec0fd175220b9bf0660bc024f69f1655ac864224",
      "pubkey": "1GMn5pR6mSWKoFMr7u1vsfbWxeh6RoJvQD",
      "signature": "Hwfi7ZLhj3Z5E7YIHeLfDifl8B7Lr/BnzAlGt4MxjHXCSd0W06MGANMGlDaRSN6rDdjMENWueoYv87TwkUIIAe0=",
      "timestamp": 1632517459,
      "verified": true
    },
    "parent": {
      "hash": "20929d4e215010de5907c96add42336dacec5b5dab1bd87ea1e8b8fd1b4693a7",
      "pubkey": "16RsNNjrxBXaBE5unPMpNSCrEPQ9Ffo9C8",
      "signature": "IIBjUKwuUdA4UEyOI2+Grp0+A7Jpiu9N2ZrWEkJiuk63CBZ8snnLdmujZ7GHqIc1peKKOdjfUKmdC25Yu4JAL8A=",
      "timestamp": 1632517459,
      "verified": true
    }
  },
  "title": "Generative Art NFT Code on RUN",
  "type": "text/javascript"
}
{
  "api_version": "1.3.0",
  "block_hash": "0000000000000000083b658dddef1e48c43c34d645dfc4fca5ea02ebb999d1f8",
  "block_height": 706221,
  "confirmations": 1,
  "miner_id": "030d1fe5c1b560efe196ba40540ce9017c20daa9504c4c4cec6184fc702d9f274e",
  "return_result": "success",
  "timestamp": "2021-09-24T21:24:48.4374909Z",
  "tx_second_mempool_expiry": 0,
  "txid": "3eca1fff33945218ab8b4a250f1f221bf2e719b0c25c54c3b0f79cddeec2e2fc",
  "verified": true
}