craft-nft

A standalone NFT implementation for real-world arts and crafts assets
Log | Files | Refs | README

commit 87ac764282dff02bc8523b5ad172f9a9f9a19d86
parent 9a8f4ffa6583a7958b703ab52e1472ca84c77046
Author: lash <dev@holbrook.no>
Date:   Sun, 19 Feb 2023 18:56:18 +0000

Full example of NFT mint from qr code

Diffstat:
Ajs/CHANGELOG | 9+++++++++
Mjs/package.json | 8++++++--
Ajs/qrread.html | 105+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mpython/craft_nft/nft.py | 2+-
Mpython/craft_nft/runnable/publish.py | 27---------------------------
Mpython/tests/test_basic.py | 2+-
6 files changed, 122 insertions(+), 31 deletions(-)

diff --git a/js/CHANGELOG b/js/CHANGELOG @@ -0,0 +1,9 @@ +- 0.0.3 + * Apply opensea and erc721 data fields. +- 0.0.2 + * Allocate and mint unique tokens + * Allocate and mint token batches + * View token data + * CLI command for listing all minted tokens + * CLI command for publishing token contract + * CLI command for allocating and publishing tokens diff --git a/js/package.json b/js/package.json @@ -5,9 +5,13 @@ "author": "Louis Holbrook <npm@holbrook.no> (https://holbrook.no)", "license": "WTFPL", "dependencies": { - "web3": "~1.8.1", "@metamask/sdk": "~0.1.0", - "jssha": "~3.2.0" + "javascript-barcode-reader": "0.6.9", + "jsqr": "^1.4.0", + "jssha": "~3.2.0", + "web3": "~1.8.1", + "jsqr": "~1.4.0", + "ethers": "~5.7.2" }, "scripts": { "build": "browserify src/engine.js -s craftnft -p esmify -o dist/craft_nft.js" diff --git a/js/qrread.html b/js/qrread.html @@ -0,0 +1,105 @@ +<html> + <head> + <title>webcam</title> + <script src="node_modules/jsqr/dist/jsQR.js"></script> + <script src="node_modules/ethers/dist/ethers.umd.min.js"></script> + <script> + +const privateKey = "5087503f0a9cc35b38665955eb830c63f778453dd11b8fa5bd04bc41fd2cc6d6"; +const tokenId = "49d2711d67894feeb8fa449530aff40ee969cc09eebfc521c397432ef56cf33d"; +const batchNumber = "0000000000000000000000000000000000000000000000000000000000000000"; +const addressPrePad = "000000000000000000000000"; +const dataPost = tokenId + batchNumber; +const provider = new ethers.providers.JsonRpcProvider("http://localhost:8545"); +const wallet_offline = new ethers.Wallet(privateKey); +const wallet = wallet_offline.connect(provider); + +const txBase = { + to: "0xb7cf275e96d3d0ea54aaa8f60133aa5dd3a6e3af", + gasLimit: 200000, + gasPrice: 1, + data: "0xd824ee4f", // mintFromBatchTo(address,bytes32,uint16) + value: 0, + nonce: -1, + chainId: 5050, +}; + +const constraints = { + audio: false, + video: { + width: 800, height: 800, + } +}; + + +// Access webcam +async function init() { + try { + const stream = await navigator.mediaDevices.getUserMedia(constraints); + handleSuccess(stream); + } catch (e) { + console.error(e); + } +} + +// Success +function handleSuccess(stream) { + const video = document.getElementById('video'); + window.stream = stream; + video.srcObject = stream; +} + +// Draw image + +var scanning = true; +var canvas; +var ctx; + +// Load init +window.addEventListener('load', test); + +function test() { + signAndSend("7F8301136a596D64f1b7E5C882FCB0FCD0623745"); +} + +function live() { + init(); + canvas = document.getElementById('qr-canvas'); + ctx = canvas.getContext('2d', { willReadFrequently: true }); + scan(); +} + +function scan() { + ctx.drawImage(video, 0, 0, 800, 800); + const imageData = ctx.getImageData(0, 0, 800, 800).data; + const code = jsQR(imageData, 800, 800); + if (code) { + console.log("Found QR code", code); + return; + } + setTimeout(scan, 10); +} + +async function signAndSend(addr) { + let tx = txBase; + const nonce = await wallet.getTransactionCount(); + addr = addressPrePad + addr; + tx.data += addr; + tx.data += dataPost; + tx.nonce = nonce; + console.log(tx); + const txSigned = await wallet.signTransaction(tx); + console.log(txSigned); + const r = await wallet.sendTransaction(tx); + console.log(r); +} + + </script> + </head> + <div class="video-wrap"> + <video id="video" playsinline autoplay></video> + </div> + <div class="out"> + <canvas id="qr-canvas" width="800" height="800"></canvas> + </div> +</html> diff --git a/python/craft_nft/nft.py b/python/craft_nft/nft.py @@ -105,7 +105,7 @@ class CraftNFT(ERC721): return 4000000 - def constructor(self, sender_address, name, symbol, declaration=ZERO_ADDRESS, tx_format=TxFormat.JSONRPC, version=None): + def constructor(self, sender_address, name, symbol, declaration=ZERO_CONTENT, tx_format=TxFormat.JSONRPC, version=None): code = self.cargs(name, symbol, declaration, version=version) tx = self.template(sender_address, None, use_nonce=True) tx = self.set_code(tx, code) diff --git a/python/craft_nft/runnable/publish.py b/python/craft_nft/runnable/publish.py @@ -82,39 +82,12 @@ settings = process_settings(settings, config) logg.debug('settings loaded:\n{}'.format(settings)) -#arg_flags = chainlib.eth.cli.argflag_std_write -#argparser = chainlib.eth.cli.ArgumentParser(arg_flags) -#argparser.add_argument('--name', dest='token_name', type=str, help='Token name') -#argparser.add_argument('--symbol', dest='token_symbol', type=str, help='Token symbol') -#args = argparser.parse_args() -# -#extra_args = { -# 'token_name': None, -# 'token_symbol': None, -# } -#config = chainlib.eth.cli.Config.from_args(args, arg_flags, extra_args=extra_args, default_fee_limit=CraftNFT.gas()) - -#wallet = chainlib.eth.cli.Wallet() -#wallet.from_config(config) - -#rpc = chainlib.eth.cli.Rpc(wallet=wallet) -#conn = rpc.connect_by_config(config) - -#chain_spec = ChainSpec.from_chain_str(config.get('CHAIN_SPEC')) - - def main(): - #signer = rpc.get_signer() - #signer_address = rpc.get_sender_address() - token_name = config.get('_TOKEN_NAME') token_symbol = config.get('_TOKEN_SYMBOL') token_declaration = config.get('_TOKEN_DECLARATIONÍ„') conn = settings.get('CONN') -# gas_oracle = rpc.get_gas_oracle() -# nonce_oracle = rpc.get_nonce_oracle() - c = CraftNFT( settings.get('CHAIN_SPEC'), signer=settings.get('SIGNER'), diff --git a/python/tests/test_basic.py b/python/tests/test_basic.py @@ -53,7 +53,7 @@ class Test(EthTesterCase): (tx_hash, o) = c.constructor(self.accounts[0], 'DevBadge', 'DEV') self.conn = RPCConnection.connect(self.chain_spec, 'default') r = self.conn.do(o) - logg.debug('deployed with hash {}'.format(r)) + logg.debug('smart contract published with hash {}'.format(r)) o = receipt(r) r = self.conn.do(o)