craft-nft

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

commit 44363b424cf7112b78565110f590dc20a4b46bb2
parent c1ac140331e36801539acec98979e5c969441f72
Author: lash <dev@holbrook.no>
Date:   Thu, 22 Dec 2022 08:58:50 +0000

WIP add image file dialogue

Diffstat:
MREADME.md | 12++++++++----
Mjs/index.html | 44++++++++++++++++++++++++++------------------
Mjs/manual_test_browser.js | 60+++++++++++++++++++++++++++++++++++++++++++++++++-----------
Mjs/src/common.js | 1-
4 files changed, 83 insertions(+), 34 deletions(-)

diff --git a/README.md b/README.md @@ -14,12 +14,17 @@ Version numbers in dependencies are not absolute, but only detail what has been * `python >= 3.7.x` * `node >= 19.2.x (npm >= 8.19.x)` * An `evm` service endpoint that speaks web3 JSON-RPC. Some examples for development are: - - ganache (probably the simplest to set up) - - A private network with `geth` - - An official `evm` testnet (e.g. Rinkeby or Ropsten) + - [ganache](https://trufflesuite.com/ganache/) (probably the simplest to set up) + - A private network with [geth](https://github.com/ethereum/go-ethereum) + - An `evm` network using valueless tokens (e.g. [Görli](https://blog.infura.io/post/infura-supports-goerli-and-sepolia-as-ethereums-long-lived-testnets) or [Bloxberg](https://bloxberg.org)) For `python` and `node` requirements, please consult the respective `*requirements.txt` and `package.json` files. +The example browser application currently only works with Metamask as wallet. The dependencies used in development are: + +* `chromium 108.0.5359.98` +* `metamask (chromium extension) 10.23.1` + To use the contract address storage service in the example browser application, you also need: * `rust >= 1.60 (cargo => 1.60)` @@ -199,4 +204,3 @@ See the `$REPO_ROOT/doc/latex/terminology.latex` document for a terminology over For more details on the chainlib/chaintool contents, please refer to the [chaintool documentation repository](https://git.defalsify.org/chaintool-doc). All chaintool related code repositories are hosted on [https://git.defalsify.org](https://git.defalsify.org) - diff --git a/js/index.html b/js/index.html @@ -10,10 +10,12 @@ <script src="src/wala.js"></script> <style type='text/css'> #detail { - visibility: hidden; + display: none; + /*visibility: hidden;*/ } #mint { - visibility: hidden; + display: none; + /*visibility: hidden;*/ } a { text-decoration: underline; @@ -26,29 +28,29 @@ label:after { content: '\a'; white-space: pre; } +dt { + font-weight: 900; +} </style> </head> <body> + <h1>Craft NFT Smart Contract</h1> <dl id=data"> - <dt>account</dt> + <dt>Signer account</dt> <dd id="data_account"></dd> - <dt>contract</dt> - <dd> - <dl> - <dt>address</dt> - <dd id="data_contract"></dd> - <dt>name</dt> - <dd id="data_name"></dd> - <dt>symbol</dt> - <dd id="data_symbol"></dd> - <dt>supply</dt> - <dd id="data_supply"></dd> - <dt>contract declaration</dt> - <dd id="data_declaration"></dd> - </dl> - </dd> + <dt>Contract address</dt> + <dd id="data_contract"></dd> + <dt>name</dt> + <dd id="data_name"></dd> + <dt>symbol</dt> + <dd id="data_symbol"></dd> + <dt>supply</dt> + <dd id="data_supply"></dd> + <dt>contract declaration</dt> + <dd id="data_declaration"></dd> </dl> <div id="interactive"> + <h2>Allocate token</h2> <form id="panel" action="#" onSubmit="return false;"> <input type="text" id="panel_title" name="title" /> <label for="panel_title">Title</label> @@ -56,10 +58,15 @@ label:after { <label for="panel_description">Description</label> <input type="text" id="panel_amount" name="amount" /> <label for="panel_amount">Batch size (0 or empty for unique work)</label> + <input type="file" id="panel_thumb" name="thumb" onChange='fileChange();'; /> + <label for="panel_thumb">Add image</label> + <ol id="panel_images_list"> + </ol> <button id="panel_submit" onClick='return false;'>allocate</button> </form> </div> <div id="detail"> + <h2>Token view</h2> <a id="back_link" onClick="uiCreateToken();">back</a> <dl> <dt>token id</dt> @@ -77,6 +84,7 @@ label:after { </dl> </div> <div id="mint"> + <h2>Mint allocated token</h2> <a id="back_link" onClick="uiCreateToken();">back</a> <dl> <dt>token id</dt> diff --git a/js/manual_test_browser.js b/js/manual_test_browser.js @@ -30,7 +30,12 @@ window.addEventListener('tokenBatch', async (e) => { const li = document.createElement('li'); const span = document.createElement('span'); li.setAttribute('id', 'token_' + e.detail.tokenId + ' _batch_' + e.detail.batch); - span.innerHTML = 'minted ' + e.detail.cursor + ' of ' + e.detail.count + ' '; + if (parseInt(e.detail.cursor, 10) >= parseInt(e.detail.count, 10)) { + span.innerHTML = 'all minted (' + e.detail.cursor + ' of ' + e.detail.count + ')'; + } else { + span.innerHTML = 'minted ' + e.detail.cursor + ' of ' + e.detail.count + ' '; + + } li.appendChild(span); const mintedTokenData = await window.craftnft.getMintedToken(session, e.detail.tokenId, e.detail.batch); @@ -133,7 +138,7 @@ async function generateMint() { composed: false, }); window.dispatchEvent(tokenRequestEvent); - //uiViewToken(tokenId); + uiViewToken(tokenId); } @@ -144,9 +149,10 @@ async function uiMintToken(tokenId, batch) { document.getElementById('token_mint_id').innerHTML = tokenId; document.getElementById('token_mint_batch').innerHTML = batch; - document.getElementById('interactive').style.visibility = 'hidden'; - document.getElementById('detail').style.visibility = 'hidden'; - document.getElementById('mint').style.visibility = 'visible' + document.getElementById('interactive').style.display = 'none'; + document.getElementById('detail').style.display = 'none'; + document.getElementById('mint').style.display = 'block'; + } @@ -234,9 +240,10 @@ async function uiViewToken(tokenId) { }); window.dispatchEvent(e); }); - document.getElementById('interactive').style.visibility = 'hidden'; - document.getElementById('detail').style.visibility = 'visible'; - document.getElementById('mint').style.visibility = 'hidden'; + document.getElementById('interactive').style.display = 'none'; + document.getElementById('detail').style.display = 'block'; + document.getElementById('mint').style.display = 'none'; + } @@ -244,9 +251,10 @@ async function uiViewToken(tokenId) { * Render the create token allocation view. */ async function uiCreateToken() { - document.getElementById('interactive').style.visibility = 'visible'; - document.getElementById('detail').style.visibility = 'hidden'; - document.getElementById('mint').style.visibility = 'hidden'; + document.getElementById('interactive').style.display ='block'; + document.getElementById('detail').style.display = 'none'; + document.getElementById('mint').style.display = 'none'; + } @@ -314,3 +322,33 @@ async function run(w3, generated_session) { window.dispatchEvent(e); }); } + + +async function renderFile(contents) { + //const sha_raw = new jsSHA("SHA-256", "BINARY", { encoding: "UTF8" }); + console.log('hexking', contents); + const sha_raw = new jsSHA("SHA-256", "ARRAYBUFFER"); + sha_raw.update(contents); + const digest = sha_raw.getHash("HEX"); + console.debug('digest', digest); + let li = document.createElement('li'); + li.innerHTML = 'sha256:' + digest; + document.getElementById('panel_images_list').appendChild(li); +} + +async function uploadFile(v) { + +} + +async function fileChange(e) { + let fileButton = document.getElementById("panel_thumb") + let file = fileButton.files[0]; + if (file) { + let f = new FileReader(); + f.onloadend = async (r) => { + renderFile(r.target.result); + uploadFile(r.target.result); + }; + f.readAsArrayBuffer(file); + } +} diff --git a/js/src/common.js b/js/src/common.js @@ -85,4 +85,3 @@ window.addEventListener('tokenRequest', (e) => { window.addEventListener('tokenMint', (e) => { window.craftnft.mintToken(session, e.detail.digest, e.detail.batch, e.detail.recipient, e.detail.index); }); -