gun-eth 1.3.6 → 1.4.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1 @@
1
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("gun"),require("ethers"),require("fs"),require("url"),require("path")):"function"==typeof define&&define.amd?define(["exports","gun","ethers","fs","url","path"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).GunEth={},e.Gun,e.ethers,e.fs,e.url,e.path$1)}(this,(function(e,t,r,n,o,a){"use strict";var i="undefined"!=typeof document?document.currentScript:null,s="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function c(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var u={exports:{}};!function(e){!function(){function t(e,r){return r?function(e){throw new Error('Could not dynamically require "'+e+'". Please configure the dynamicRequireTargets or/and ignoreDynamicRequires option of @rollup/plugin-commonjs appropriately for this require call to work.')}(e):e.slice?t[n(e)]:function(r,o){e(r={exports:{}}),t[n(o)]=r.exports};function n(e){return e.split("/").slice(-1).toString().replace(".js","")}}var r=e;t((function(e){"undefined"!=typeof self&&(e.window=self),"undefined"!=typeof window&&(e.window=window);var t=(e.window||e).SEA||{};(t.window=e.window)&&(t.window.SEA=t);try{undefined+""!=typeof r&&(r.exports=t)}catch(e){}e.exports=t}))(t,"./root"),t((function(e){var r=t("./root");try{r.window&&location.protocol.indexOf("s")<0&&location.host.indexOf("localhost")<0&&!/^127\.\d+\.\d+\.\d+$/.test(location.hostname)&&location.protocol.indexOf("file:")<0&&(console.warn("HTTPS needed for WebCrypto in SEA, redirecting..."),location.protocol="https:")}catch(e){}}))(t,"./https"),t((function(e){var r;if(r+""==typeof btoa){if(r+""==typeof Buffer)try{s.Buffer=t("buffer",1).Buffer}catch(e){console.log("Please `npm install buffer` or add it to your package.json !")}s.btoa=function(e){return Buffer.from(e,"binary").toString("base64")},s.atob=function(e){return Buffer.from(e,"base64").toString("binary")}}}))(t,"./base64"),t((function(e){function r(){}t("./base64"),Object.assign(r,{from:Array.from}),r.prototype=Object.create(Array.prototype),r.prototype.toString=function(e,t,r){e=e||"utf8",t=t||0;const n=this.length;if("hex"===e){const e=new Uint8Array(this);return[...Array((r&&r+1||n)-t).keys()].map((r=>e[r+t].toString(16).padStart(2,"0"))).join("")}return"utf8"===e?Array.from({length:(r||n)-t},((e,r)=>String.fromCharCode(this[r+t]))).join(""):"base64"===e?btoa(this):void 0},e.exports=r}))(t,"./array"),t((function(e){t("./base64");var r=t("./array");function n(...e){return console.warn("new SafeBuffer() is depreciated, please use SafeBuffer.from()"),n.from(...e)}n.prototype=Object.create(Array.prototype),Object.assign(n,{from(){if(!Object.keys(arguments).length||null==arguments[0])throw new TypeError("First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.");const e=arguments[0];let t;if("string"==typeof e){const n=arguments[1]||"utf8";if("hex"===n){const n=e.match(/([\da-fA-F]{2})/g).map((e=>parseInt(e,16)));if(!n||!n.length)throw new TypeError("Invalid first argument for type 'hex'.");t=r.from(n)}else if("utf8"===n||"binary"===n){const n=e.length,o=new Uint16Array(n);Array.from({length:n},((t,r)=>o[r]=e.charCodeAt(r))),t=r.from(o)}else if("base64"===n){const n=atob(e),o=n.length,a=new Uint8Array(o);Array.from({length:o},((e,t)=>a[t]=n.charCodeAt(t))),t=r.from(a)}else"binary"===n?t=r.from(e):console.info("SafeBuffer.from unknown encoding: "+n);return t}e.byteLength;if(e.byteLength?e.byteLength:e.length){let t;return e instanceof ArrayBuffer&&(t=new Uint8Array(e)),r.from(t||e)}},alloc:(e,t=0)=>r.from(new Uint8Array(Array.from({length:e},(()=>t)))),allocUnsafe:e=>r.from(new Uint8Array(Array.from({length:e}))),concat(e){if(!Array.isArray(e))throw new TypeError("First argument must be Array containing ArrayBuffer or Uint8Array instances.");return r.from(e.reduce(((e,t)=>e.concat(Array.from(t))),[]))}}),n.prototype.from=n.from,n.prototype.toString=r.prototype.toString,e.exports=n}))(t,"./buffer"),t((function(e){const n=t("./root"),o={Buffer:t("./buffer")};var a={};if(JSON.parseAsync=JSON.parseAsync||function(e,t,r){try{t(undefined,JSON.parse(e,r))}catch(e){t(e)}},JSON.stringifyAsync=JSON.stringifyAsync||function(e,t,r,n){try{t(undefined,JSON.stringify(e,r,n))}catch(e){t(e)}},o.parse=function(e,t){return new Promise((function(r,n){JSON.parseAsync(e,(function(e,t){e?n(e):r(t)}),t)}))},o.stringify=function(e,t,r){return new Promise((function(n,o){JSON.stringifyAsync(e,(function(e,t){e?o(e):n(t)}),t,r)}))},n.window&&(o.crypto=n.window.crypto||n.window.msCrypto,o.subtle=(o.crypto||a).subtle||(o.crypto||a).webkitSubtle,o.TextEncoder=n.window.TextEncoder,o.TextDecoder=n.window.TextDecoder,o.random=e=>o.Buffer.from(o.crypto.getRandomValues(new Uint8Array(o.Buffer.alloc(e))))),!o.TextDecoder){const{TextEncoder:e,TextDecoder:n}=t((undefined+""==typeof r?".":"")+"./lib/text-encoding",1);o.TextDecoder=n,o.TextEncoder=e}if(!o.crypto)try{var i=t("crypto",1);Object.assign(o,{crypto:i,random:e=>o.Buffer.from(i.randomBytes(e))});const{Crypto:e}=t("@peculiar/webcrypto",1);o.ossl=o.subtle=new e({directory:"ossl"}).subtle}catch(e){console.log("Please `npm install @peculiar/webcrypto` or add it to your package.json !")}e.exports=o}))(t,"./shim"),t((function(e){var r=t("./root"),n=t("./shim"),o={pbkdf2:{hash:{name:"SHA-256"},iter:1e5,ks:64},ecdsa:{pair:{name:"ECDSA",namedCurve:"P-256"},sign:{name:"ECDSA",hash:{name:"SHA-256"}}},ecdh:{name:"ECDH",namedCurve:"P-256"},jwk:function(e,t){var r={kty:"EC",crv:"P-256",x:(e=e.split("."))[0],y:e[1],ext:!0};return r.key_ops=t?["sign"]:["verify"],t&&(r.d=t),r},keyToJwk:function(e){return{kty:"oct",k:e.toString("base64").replace(/\+/g,"-").replace(/\//g,"_").replace(/\=/g,""),ext:!1,alg:"A256GCM"}},recall:{validity:43200,hook:function(e){return e}},check:function(e){return"string"==typeof e&&"SEA{"===e.slice(0,4)},parse:async function(e){try{var t="string"==typeof e;return t&&"SEA{"===e.slice(0,4)&&(e=e.slice(3)),t?await n.parse(e):e}catch(e){}return e}};r.opt=o,e.exports=o}))(t,"./settings"),t((function(e){var r=t("./shim");e.exports=async function(e,t){var n="string"==typeof e?e:await r.stringify(e),o=await r.subtle.digest({name:t||"SHA-256"},(new r.TextEncoder).encode(n));return r.Buffer.from(o)}}))(t,"./sha256"),t((function(e){const r=t("./shim"),n=r.subtle,o=r.ossl?r.ossl:n;e.exports=e=>o.digest({name:"SHA-1"},new ArrayBuffer(e))}))(t,"./sha1"),t((function(e){var r=t("./root"),n=t("./shim"),o=t("./settings"),a=t("./sha256");r.work=r.work||(async(e,t,i,s)=>{try{var c=(t||{}).epub||t;if(s=s||{},c instanceof Function&&(i=c,c=undefined),e="string"==typeof e?e:await n.stringify(e),"sha"===(s.name||"").toLowerCase().slice(0,3)){var u=n.Buffer.from(await a(e,s.name),"binary").toString(s.encode||"base64");if(i)try{i(u)}catch(e){console.log(e)}return u}c=c||n.random(9);var f=await(n.ossl||n.subtle).importKey("raw",(new n.TextEncoder).encode(e),{name:s.name||"PBKDF2"},!1,["deriveBits"]),p=await(n.ossl||n.subtle).deriveBits({name:s.name||"PBKDF2",iterations:s.iterations||o.pbkdf2.iter,salt:(new n.TextEncoder).encode(s.salt||c),hash:s.hash||o.pbkdf2.hash},f,s.length||8*o.pbkdf2.ks);e=n.random(e.length);var l=n.Buffer.from(p,"binary").toString(s.encode||"base64");if(i)try{i(l)}catch(e){console.log(e)}return l}catch(e){if(console.log(e),r.err=e,r.throw)throw e;return void(i&&i())}}),e.exports=r.work}))(t,"./work"),t((function(e){var r=t("./root"),n=t("./shim");t("./settings"),r.name=r.name||(async(e,t)=>{try{if(e)try{e()}catch(e){console.log(e)}return}catch(t){if(console.log(t),r.err=t,r.throw)throw t;return void(e&&e())}}),r.pair=r.pair||(async(e,t)=>{try{var o=n.ossl||n.subtle,a=await n.subtle.generateKey({name:"ECDSA",namedCurve:"P-256"},!0,["sign","verify"]).then((async e=>{var t={};t.priv=(await n.subtle.exportKey("jwk",e.privateKey)).d;var r=await n.subtle.exportKey("jwk",e.publicKey);return t.pub=r.x+"."+r.y,t}));try{var i=await o.generateKey({name:"ECDH",namedCurve:"P-256"},!0,["deriveKey"]).then((async e=>{var t={};t.epriv=(await o.exportKey("jwk",e.privateKey)).d;var r=await o.exportKey("jwk",e.publicKey);return t.epub=r.x+"."+r.y,t}))}catch(e){if(r.window)throw e;if("Error: ECDH is not a supported algorithm"!=e)throw e;console.log("Ignoring ECDH...")}i=i||{};var s={pub:a.pub,priv:a.priv,epub:i.epub,epriv:i.epriv};if(e)try{e(s)}catch(e){console.log(e)}return s}catch(t){if(console.log(t),r.err=t,r.throw)throw t;return void(e&&e())}}),e.exports=r.pair}))(t,"./pair"),t((function(e){var r,n=t("./root"),o=t("./shim"),a=t("./settings"),i=t("./sha256");n.sign=n.sign||(async(e,t,s,c)=>{try{if(c=c||{},!(t||c).priv){if(!n.I)throw"No signing key.";t=await n.I(null,{what:e,how:"sign",why:c.why})}if(r===e)throw"`undefined` not allowed.";var u=await a.parse(e),f=c.check=c.check||u;if(n.verify&&(n.opt.check(f)||f&&f.s&&f.m)&&r!==await n.verify(f,t)){var p=await a.parse(f);if(c.raw||(p="SEA"+await o.stringify(p)),s)try{s(p)}catch(e){console.log(e)}return p}var l=t.pub,y=t.priv,h=a.jwk(l,y),d=await i(u),g=await(o.ossl||o.subtle).importKey("jwk",h,{name:"ECDSA",namedCurve:"P-256"},!1,["sign"]).then((e=>(o.ossl||o.subtle).sign({name:"ECDSA",hash:{name:"SHA-256"}},e,new Uint8Array(d))));p={m:u,s:o.Buffer.from(g,"binary").toString(c.encode||"base64")};if(c.raw||(p="SEA"+await o.stringify(p)),s)try{s(p)}catch(e){console.log(e)}return p}catch(e){if(console.log(e),n.err=e,n.throw)throw e;return void(s&&s())}}),e.exports=n.sign}))(t,"./sign"),t((function(e){var r,n=t("./root"),o=t("./shim"),a=t("./settings"),i=t("./sha256");n.verify=n.verify||(async(e,t,s,c)=>{try{var u=await a.parse(e);if(!1===t){var f=await a.parse(u.m);if(s)try{s(f)}catch(e){console.log(e)}return f}c=c||{};var p,l,y,h=t.pub||t,d=n.opt.slow_leak?await n.opt.slow_leak(h):await(o.ossl||o.subtle).importKey("jwk",a.jwk(h),{name:"ECDSA",namedCurve:"P-256"},!1,["verify"]),g=await i(u.m);try{if(p=o.Buffer.from(u.s,c.encode||"base64"),l=new Uint8Array(p),!(y=await(o.ossl||o.subtle).verify({name:"ECDSA",hash:{name:"SHA-256"}},d,l,new Uint8Array(g))))throw"Signature did not match."}catch(r){if(n.opt.fallback)return await n.opt.fall_verify(e,t,s,c)}var w=y?await a.parse(u.m):r;if(s)try{s(w)}catch(e){console.log(e)}return w}catch(e){if(console.log(e),n.err=e,n.throw)throw e;return void(s&&s())}}),e.exports=n.verify;var s={};n.opt.slow_leak=e=>{if(s[e])return s[e];var t=a.jwk(e);return s[e]=(o.ossl||o.subtle).importKey("jwk",t,{name:"ECDSA",namedCurve:"P-256"},!1,["verify"]),s[e]};var c=n.opt;n.opt.fall_verify=async function(e,t,s,u,f){if(f===n.opt.fallback)throw"Signature did not match";f=f||1;var p=e||"";e=n.opt.unpack(e)||e;var l,y,h,d=await a.parse(e),g=t.pub||t,w=await n.opt.slow_leak(g),b=f<=n.opt.fallback?o.Buffer.from(await o.subtle.digest({name:"SHA-256"},(new o.TextEncoder).encode(await a.parse(d.m)))):await i(d.m);try{if(l=o.Buffer.from(d.s,u.encode||"base64"),y=new Uint8Array(l),!(h=await(o.ossl||o.subtle).verify({name:"ECDSA",hash:{name:"SHA-256"}},w,y,new Uint8Array(b))))throw"Signature did not match."}catch(e){try{l=o.Buffer.from(d.s,"utf8"),y=new Uint8Array(l),h=await(o.ossl||o.subtle).verify({name:"ECDSA",hash:{name:"SHA-256"}},w,y,new Uint8Array(b))}catch(e){if(!h)throw"Signature did not match."}}var m=h?await a.parse(d.m):r;if(c.fall_soul=p["#"],c.fall_key=p["."],c.fall_val=e,c.fall_state=p[">"],s)try{s(m)}catch(e){console.log(e)}return m},n.opt.fallback=2}))(t,"./verify"),t((function(e){var r=t("./shim"),n=t("./settings"),o=t("./sha256");e.exports=async(e,t,a)=>{const i=e+(t||r.random(8)).toString("utf8"),s=r.Buffer.from(await o(i),"binary"),c=n.keyToJwk(s);return await r.subtle.importKey("jwk",c,{name:"AES-GCM"},!1,["encrypt","decrypt"])}}))(t,"./aeskey"),t((function(e){var r=t("./root"),n=t("./shim");t("./settings");var o=t("./aeskey");r.encrypt=r.encrypt||(async(e,t,a,i)=>{try{i=i||{};var s=(t||i).epriv||t;if(undefined===e)throw"`undefined` not allowed.";if(!s){if(!r.I)throw"No encryption key.";s=(t=await r.I(null,{what:e,how:"encrypt",why:i.why})).epriv||t}var c="string"==typeof e?e:await n.stringify(e),u={s:n.random(9),iv:n.random(15)},f=await o(s,u.s,i).then((e=>n.subtle.encrypt({name:i.name||"AES-GCM",iv:new Uint8Array(u.iv)},e,(new n.TextEncoder).encode(c)))),p={ct:n.Buffer.from(f,"binary").toString(i.encode||"base64"),iv:u.iv.toString(i.encode||"base64"),s:u.s.toString(i.encode||"base64")};if(i.raw||(p="SEA"+await n.stringify(p)),a)try{a(p)}catch(e){console.log(e)}return p}catch(e){if(console.log(e),r.err=e,r.throw)throw e;return void(a&&a())}}),e.exports=r.encrypt}))(t,"./encrypt"),t((function(e){var r=t("./root"),n=t("./shim"),o=t("./settings"),a=t("./aeskey");r.decrypt=r.decrypt||(async(e,t,i,s)=>{try{s=s||{};var c=(t||s).epriv||t;if(!c){if(!r.I)throw"No decryption key.";c=(t=await r.I(null,{what:e,how:"decrypt",why:s.why})).epriv||t}var u,f,p,l=await o.parse(e);try{u=n.Buffer.from(l.s,s.encode||"base64"),f=n.Buffer.from(l.iv,s.encode||"base64"),p=n.Buffer.from(l.ct,s.encode||"base64");var y=await a(c,u,s).then((e=>n.subtle.decrypt({name:s.name||"AES-GCM",iv:new Uint8Array(f),tagLength:128},e,new Uint8Array(p))))}catch(n){if("utf8"===s.encode)throw"Could not decrypt";if(r.opt.fallback)return s.encode="utf8",await r.decrypt(e,t,i,s)}var h=await o.parse(new n.TextDecoder("utf8").decode(y));if(i)try{i(h)}catch(e){console.log(e)}return h}catch(e){if(console.log(e),r.err=e,r.throw)throw e;return void(i&&i())}}),e.exports=r.decrypt}))(t,"./decrypt"),t((function(e){var r=t("./root"),n=t("./shim");t("./settings"),r.secret=r.secret||(async(e,t,a,i)=>{try{if(i=i||{},!t||!t.epriv||!t.epub){if(!r.I)throw"No secret mix.";t=await r.I(null,{what:e,how:"secret",why:i.why})}var s=e.epub||e,c=t.epub,u=t.epriv,f=n.ossl||n.subtle,p=o(s),l=Object.assign({public:await f.importKey(...p,!0,[])},{name:"ECDH",namedCurve:"P-256"}),y=o(c,u),h=await f.importKey(...y,!1,["deriveBits"]).then((async e=>{var t=await f.deriveBits(l,e,256),r=new Uint8Array(t),n=await f.importKey("raw",r,{name:"AES-GCM",length:256},!0,["encrypt","decrypt"]);return f.exportKey("jwk",n).then((({k:e})=>e))}));if(a)try{a(h)}catch(e){console.log(e)}return h}catch(e){if(console.log(e),r.err=e,r.throw)throw e;return void(a&&a())}});var o=(e,t)=>{var[r,n]=e.split("."),o=t?{d:t}:{};return["jwk",Object.assign(o,{x:r,y:n,kty:"EC",crv:"P-256",ext:!0}),{name:"ECDH",namedCurve:"P-256"}]};e.exports=r.secret}))(t,"./secret"),t((function(e){var r=t("./root");r.certify=r.certify||(async(e,t={},n,o,a={})=>{try{if(console.log("SEA.certify() is an early experimental community supported method that may change API behavior without warning in any future version."),e=(()=>{var t=[];if(e){if(("string"==typeof e||Array.isArray(e))&&e.indexOf("*")>-1)return"*";if("string"==typeof e)return e;if(Array.isArray(e)){if(1===e.length&&e[0])return"object"==typeof e[0]&&e[0].pub?e[0].pub:"string"==typeof e[0]?e[0]:null;e.map((e=>{"string"==typeof e?t.push(e):"object"==typeof e&&e.pub&&t.push(e.pub)}))}return"object"==typeof e&&e.pub?e.pub:t.length>0?t:null}})(),!e)return console.log("No certificant found.");const s=!a.expiry||"number"!=typeof a.expiry&&"string"!=typeof a.expiry?null:parseFloat(a.expiry),c=(t||{}).read?t.read:null,u=(t||{}).write?t.write:"string"==typeof t||Array.isArray(t)||t["+"]||t["#"]||t["."]||t["="]||t["*"]||t[">"]||t["<"]?t:null,f=(a||{}).block||(a||{}).blacklist||(a||{}).ban||{},p=f.read&&("string"==typeof f.read||(f.read||{})["#"])?f.read:null,l="string"==typeof f?f:f.write&&("string"==typeof f.write||f.write["#"])?f.write:null;if(!c&&!u)return console.log("No policy found.");const y=JSON.stringify({c:e,...s?{e:s}:{},...c?{r:c}:{},...u?{w:u}:{},...p?{rb:p}:{},...l?{wb:l}:{}});var i=await r.sign(y,n,null,{raw:1});if(a.raw||(i="SEA"+JSON.stringify(i)),o)try{o(i)}catch(e){console.log(e)}return i}catch(e){if(r.err=e,r.throw)throw e;return void(o&&o())}}),e.exports=r.certify}))(t,"./certify"),t((function(e){var r=t("./shim"),n=t("./root");n.work=t("./work"),n.sign=t("./sign"),n.verify=t("./verify"),n.encrypt=t("./encrypt"),n.decrypt=t("./decrypt"),n.certify=t("./certify"),n.random=n.random||r.random,n.Buffer=n.Buffer||t("./buffer"),n.keyid=n.keyid||(async e=>{try{const t=r.Buffer.concat(e.replace(/-/g,"+").replace(/_/g,"/").split(".").map((e=>r.Buffer.from(e,"base64")))),n=r.Buffer.concat([r.Buffer.from([153,t.length/256,t.length%256]),t]),o=await sha1hash(n),a=r.Buffer.from(o,"binary");return a.toString("hex",a.length-8)}catch(e){throw console.log(e),e}}),((n.window||{}).GUN||{}).SEA=n,e.exports=n}))(t,"./sea"),t((function(e){var n,o=t("./sea");function a(e){this._={$:this}}function i(){return n.state().toString(36).replace(".","")}n=o.window?o.window.GUN||{chain:{}}:t((undefined+""==typeof r?".":"")+"./gun",1),o.GUN=n,a.prototype=function(){function e(){}return e.prototype=n.chain,new e}(),a.prototype.constructor=a,n.chain.user=function(e){var t,r=this.back(-1);if(e)return e=o.opt.pub((e._||"")["#"])||e,r.get("~"+e);if(t=r.back("user"))return t;var n=r=r._,s=n.opt.uuid||i;return(n=(t=n.user=this.chain(new a))._).opt={},n.opt.uuid=function(e){var t=s(),n=r.user;return n&&(n=n.is)&&(n=n.pub)?(t="~"+n+"/"+t,e&&e.call&&e(null,t),t):t},t},n.User=a,a.GUN=n,a.SEA=n.SEA=o,e.exports=a}))(t,"./user"),t((function(e){var n;(""+n!=typeof GUN?GUN||{chain:{}}:t((""+n==typeof r?".":"")+"./gun",1)).chain.then=function(e,t){var r=this,n=new Promise((function(e,n){r.once(e,t)}));return e?n.then(e):n}}))(t,"./then"),t((function(e){var r=t("./user"),n=r.SEA,o=r.GUN,a=function(){};r.prototype.create=function(...e){var t,r="object"==typeof e[0]&&(e[0].pub||e[0].epub)?e[0]:"object"==typeof e[1]&&(e[1].pub||e[1].epub)?e[1]:null,i=r&&(r.pub||r.epub)?r.pub:"string"==typeof e[0]?e[0]:null,s=r&&(r.pub||r.epub)?r:i&&"string"==typeof e[1]?e[1]:null,c=e.filter((e=>"function"==typeof e))[0]||null,u=e&&e.length>1&&"object"==typeof e[e.length-1]?e[e.length-1]:{},f=this,p=f._,l=f.back(-1);if((c=c||a,!1!==(u=u||{}).check)&&(i||(t="No user."),(s||"").length<8&&(t="Password too short!"),t))return c({err:o.log(t)}),f;if(p.ing)return(c||a)({err:o.log("User is already being created or authenticated!"),wait:!0}),f;p.ing=!0;var y={a:function(e){if(y.pubs=e,e&&!u.already){var t={err:o.log("User already created!")};return p.ing=!1,(c||a)(t),void f.leave()}y.salt=String.random(64),n.work(s,y.salt,y.b)},b:function(e){y.proof=e,r?y.c(r):n.pair(y.c)},c:function(e){var t;y.pair=e||{},(t=p.root.user)&&(t._.sea=e,t.is={pub:e.pub,epub:e.epub,alias:i}),y.data={pub:e.pub},y.d()},d:function(){y.data.alias=i,y.e()},e:function(){y.data.epub=y.pair.epub,n.encrypt({priv:y.pair.priv,epriv:y.pair.epriv},y.proof,y.f,{raw:1})},f:function(e){y.data.auth=JSON.stringify({ek:e,s:y.salt}),y.g(y.data.auth)},g:function(e){var t;y.data.auth=y.data.auth||e,l.get(t="~"+y.pair.pub).put(y.data).on(y.h);var r={};r[t]={"#":t},l.get("~@"+i).put(r).get(t).on(y.i)},h:function(e,t,r,n){n.off(),y.h.ok=1,y.i()},i:function(e,t,n,o){o&&(y.i.ok=1,o.off()),y.h.ok&&y.i.ok&&(p.ing=!1,c({ok:0,pub:y.pair.pub}),a===c&&(r?f.auth(r):f.auth(i,s)))}};return l.get("~@"+i).once(y.a),f},r.prototype.leave=function(e,t){var r=this.back(-1)._.user;if(r&&(delete r.is,delete r._.is,delete r._.sea),n.window)try{var o={};delete(o=n.window.sessionStorage).recall,delete o.pair}catch(e){}return this}}))(t,"./create"),t((function(e){var r=t("./user"),n=r.SEA,o=r.GUN,a=function(){};function i(e){if("string"!=typeof e)return e;try{e=JSON.parse(e)}catch(t){e={}}return e}r.prototype.auth=function(...e){var t="object"==typeof e[0]&&(e[0].pub||e[0].epub)?e[0]:"object"==typeof e[1]&&(e[1].pub||e[1].epub)?e[1]:null,r=t||"string"!=typeof e[0]?null:e[0],s=!r&&(!t||t.priv&&t.epriv)||"string"!=typeof e[1]?null:e[1],c=e.filter((e=>"function"==typeof e))[0]||null,u=e&&e.length>1&&"object"==typeof e[e.length-1]?e[e.length-1]:{},f=this,p=f._,l=f.back(-1);if(p.ing)return(c||a)({err:o.log("User is already being created or authenticated!"),wait:!0}),f;p.ing=!0;var y,h={},d=9;return h.a=function(e){if(!e)return h.b();if(!e.pub){var t=[];return Object.keys(e).forEach((function(r){"_"!=r&&t.push(e[r])})),h.b(t)}if(h.name)return h.f(e);h.c((h.data=e).auth)},h.b=function(e){var t=(h.list=(h.list||[]).concat(e||[])).shift();if(y===t)return h.name?h.err("Your user account is not published for dApps to access, please consider syncing it online, or allowing local access by adding your device as a peer."):r&&d--?void l.get("~@"+r).once(h.a):h.err("Wrong user or password.");l.get(t).once(h.a)},h.c=function(e){return y===e?h.b():"string"==typeof e?h.c(i(e)):void n.work(s,(h.auth=e).s,h.d,h.enc)},h.d=function(e){n.decrypt(h.auth.ek,e,h.e,h.enc)},h.e=function(e){if(y===e)return h.enc?(h.enc=null,h.b()):(h.enc={encode:"utf8"},h.c(h.auth));h.half=e,h.f(h.data)},h.f=function(e){var t=h.half||{},r=h.data||{};h.g(h.lol={pub:e.pub||r.pub,epub:e.epub||r.epub,priv:e.priv||t.priv,epriv:e.epriv||t.epriv})},h.g=function(e){if(!e||!e.pub||!e.epub)return h.b();h.pair=e;var t=l._.user,d=t._;d.tag;var g=d.opt;(d=t._=l.get("~"+e.pub)._).opt=g,t.is={pub:e.pub,epub:e.epub,alias:r||e.pub},d.sea=h.pair,p.ing=!1;try{s&&y==(i(p.root.graph["~"+e.pub].auth)||"")[":"]&&(u.shuffle=u.change=s)}catch(e){}if(u.change?h.z():(c||a)(d),n.window&&(f.back("user")._.opt||u).remember)try{var w={};(w=n.window.sessionStorage).recall=!0,w.pair=JSON.stringify(e)}catch(e){}try{l._.tag.auth?l._.on("auth",d):setTimeout((function(){l._.on("auth",d)}),1)}catch(e){o.log("Your 'auth' callback crashed with:",e)}},h.h=function(e){return e?((r=e.alias)||(r=e.alias="~"+t.pub),e.auth?(t=null,void h.c((h.data=e).auth)):h.g(t)):h.b()},h.z=function(){h.salt=String.random(64),n.work(u.change,h.salt,h.y)},h.y=function(e){n.encrypt({priv:h.pair.priv,epriv:h.pair.epriv},e,h.x,{raw:1})},h.x=function(e){h.w(JSON.stringify({ek:e,s:h.salt}))},h.w=function(e){if(u.shuffle){console.log("migrate core account from UTF8 & shuffle");var t={};Object.keys(h.data).forEach((function(e){t[e]=h.data[e]})),delete t._,t.auth=e,l.get("~"+h.pair.pub).put(t)}l.get("~"+h.pair.pub).get("auth").put(e,c||a)},h.err=function(e){var t={err:o.log(e||"User cannot be found!")};p.ing=!1,(c||a)(t)},h.plugin=function(e){if(!(h.name=e))return h.err();var t=[e];"~"!==e[0]&&(t[1]="~"+e,t[2]="~@"+e),h.b(t)},t?t.priv&&t.epriv?h.g(t):l.get("~"+t.pub).once(h.h):r?l.get("~@"+r).once(h.a):r||s||n.name(h.plugin),f}}))(t,"./auth"),t((function(e){var r=t("./user"),n=r.SEA;r.GUN,r.prototype.recall=function(e,t){var r=this,o=r.back(-1);if((e=e||{})&&e.sessionStorage){if(n.window)try{var a;(a=n.window.sessionStorage)&&(o._.opt.remember=!0,(r.back("user")._.opt||e).remember=!0,(a.recall||a.pair)&&o.user().auth(JSON.parse(a.pair),t))}catch(e){}return r}return r}}))(t,"./recall"),t((function(e){var r=t("./user"),n=r.SEA,o=r.GUN,a=function(){};r.prototype.pair=function(){var e,t=this;try{e=new Proxy({DANGER:"☠"},{get:function(e,r,n){if(t.is&&(t._||"").sea)return t._.sea[r]}})}catch(e){}return e},r.prototype.delete=async function(e,t,r){console.log("user.delete() IS DEPRECATED AND WILL BE MOVED TO A MODULE!!!");var n=this;n.back(-1);var i=n.back("user");try{i.auth(e,t,(function(e){(i.is||{}).pub;i.map().once((function(){this.put(null)})),i.leave(),(r||a)({ok:0})}))}catch(e){o.log("User.delete failed! Error:",e)}return n},r.prototype.alive=async function(){console.log("user.alive() IS DEPRECATED!!!");const e=this.back(-1);try{return await authRecall(e),e._.user._}catch(e){const t="No session!";throw o.log(t),{err:t}}},r.prototype.trust=async function(e){console.log("`.trust` API MAY BE DELETED OR CHANGED OR RENAMED, DO NOT USE!"),o.is(e)&&e.get("pub").get(((e,t)=>{console.log(e,t)})),e.get("trust").get(path).put(theirPubkey)},r.prototype.grant=function(e,t){console.log("`.grant` API MAY BE DELETED OR CHANGED OR RENAMED, DO NOT USE!");var r=this,o=r.back(-1).user(),a=o._.sea,i="";return r.back((function(e){e.is||(i+=e.get||"")})),async function(){var r,s=await o.get("grant").get(a.pub).get(i).then();(s=await n.decrypt(s,a))||(s=n.random(16).toString(),r=await n.encrypt(s,a),o.get("grant").get(a.pub).get(i).put(r));var c=e.get("pub").then(),u=e.get("epub").then();c=await c,u=await u;var f=await n.secret(u,a);r=await n.encrypt(s,f),o.get("grant").get(c).get(i).put(r,t)}(),r},r.prototype.secret=function(e,t){console.log("`.secret` API MAY BE DELETED OR CHANGED OR RENAMED, DO NOT USE!");var r=this,o=r.back(-1).user(),a=o.pair(),i="";return r.back((function(e){e.is||(i+=e.get||"")})),async function(){var s,c=await o.get("trust").get(a.pub).get(i).then();(c=await n.decrypt(c,a))||(c=n.random(16).toString(),s=await n.encrypt(c,a),o.get("trust").get(a.pub).get(i).put(s)),s=await n.encrypt(e,c),r.put(s,t)}(),r},e.exports=r}))(t,"./share"),t((function(e){var n,o=t("./sea"),a=t("./settings"),i=(o.window||"").GUN||t((""+n==typeof r?".":"")+"./gun",1);function s(e){var t,r=this,n=r.as,a=e.put,c=a["#"],u=a["."],f=a[":"],p=a[">"],l=e["#"];if(c&&u)if((e._||"").faith&&(n.opt||"").faith&&"function"==typeof e._)o.opt.pack(a,(function(t){o.verify(t,!1,(function(t){a["="]=o.opt.unpack(t),r.to.next(e)}))}));else{var y=function(t){n.on("in",{"@":l,err:e.err=t})};(e._||"").DBG&&((e._||"").DBG.c=+new Date),0<=c.indexOf("<?")&&(t=parseFloat(c.split("<?")[1]||""))&&p<i.state()-1e3*t?(t=e._)&&t.stun&&t.stun--:"~@"!==c?"~@"!==c.slice(0,2)?(t=o.opt.pub(c))?s.pub(r,e,f,u,c,n,y,n.user||"",t):0<=c.indexOf("#")?s.hash(r,e,f,u,c,n,y):s.any(r,e,f,u,c,n,y,n.user||""):s.pubs(r,e,f,u,c,n,y):s.alias(r,e,f,u,c,n,y)}}i.on("opt",(function(e){e.sea||(e.sea={own:{}},e.on("put",s,e)),this.to.next(e)})),s.hash=function(e,t,r,n,a,i,s){o.work(r,null,(function(r){return r&&r===n.split("#").slice(-1)[0]||r&&r===function(e){let t="";for(let r=0;r<e.length;r++)t+=r-1&1?"":String.fromCharCode(parseInt(e.substring(r-1,r+1),16));return btoa(t)}(n.split("#").slice(-1)[0])?e.to.next(t):void s("Data hash not same as hash!")}),{name:"SHA-256"})},s.alias=function(e,t,r,n,o,a,i){return r?"~@"+n===u(r)?e.to.next(t):void i("Alias not same!"):i("Data must exist!")},s.pubs=function(e,t,r,n,o,a,i){return r?n===u(r)?e.to.next(t):void i("Alias not same!"):i("Alias must exist!")},s.pub=async function(e,t,r,s,c,f,p,l,y){var h;const d=await a.parse(r)||{},g=(r,a,u)=>{if(r.m&&r.s&&a&&y)return o.verify(r,y,(r=>{if(n!==r&&n!==r.e&&t.put[">"]&&t.put[">"]>parseFloat(r.e))return p("Certificate expired.");if(n!==r&&r.c&&r.w&&(r.c===a||r.c.indexOf("*")>-1)){let t=c.indexOf("/")>-1?c.replace(c.substring(0,c.indexOf("/")+1),""):"";String.match=String.match||i.text.match;const n=Array.isArray(r.w)?r.w:"object"==typeof r.w||"string"==typeof r.w?[r.w]:[];for(const i of n)if(String.match(t,i["#"])&&String.match(s,i["."])||!i["."]&&String.match(t,i["#"])||!i["#"]&&String.match(s,i["."])||String.match(t?t+"/"+s:s,i["#"]||i)){if(i["+"]&&i["+"].indexOf("*")>-1&&t&&-1==t.indexOf(a)&&-1==s.indexOf(a))return p(`Path "${t}" or key "${s}" must contain string "${a}".`);if(r.wb&&("string"==typeof r.wb||(r.wb||{})["#"])){var o=e.as.root.$.back(-1);return"string"==typeof r.wb&&"~"!==r.wb.slice(0,1)&&(o=o.get("~"+y)),o.get(r.wb).get(a).once((e=>!e||1!==e&&!0!==e?u(r):p(`Certificant ${a} blocked.`)))}return u(r)}return p("Certificate verification fail.")}}))};if("pub"===s&&"~"+y===c)return r===y?e.to.next(t):p("Account not same!");(h=l.is)&&h.pub&&!d["*"]&&!d["+"]&&(y===h.pub||y!==h.pub&&((t._.msg||{}).opt||{}).cert)?o.opt.pack(t.put,(i=>{o.sign(i,l._.sea,(async function(i){if(n===i)return p(o.err||"Signature fail.");if(t.put[":"]={":":h=o.opt.unpack(i.m),"~":i.s},t.put["="]=h,y===l.is.pub)return(h=u(r))&&((f.sea.own[h]=f.sea.own[h]||{})[y]=1),void JSON.stringifyAsync(t.put[":"],(function(r,n){return r?p(r||"Stringify error."):(t.put[":"]=n,e.to.next(t))}));if(y!==l.is.pub&&((t._.msg||{}).opt||{}).cert){const r=await a.parse(t._.msg.opt.cert);r&&r.m&&r.s&&g(r,l.is.pub,(n=>{t.put[":"]["+"]=r,t.put[":"]["*"]=l.is.pub,JSON.stringifyAsync(t.put[":"],(function(r,n){return r?p(r||"Stringify error."):(t.put[":"]=n,e.to.next(t))}))}))}}),{raw:1})})):o.opt.pack(t.put,(r=>{o.verify(r,d["*"]||y,(function(r){var a;return r=o.opt.unpack(r),n===r?p("Unverified data."):((a=u(r))&&y===o.opt.pub(a)&&((f.sea.own[a]=f.sea.own[a]||{})[y]=1),d["+"]&&d["+"].m&&d["+"].s&&d["*"]?void g(d["+"],d["*"],(n=>(t.put["="]=r,e.to.next(t)))):(t.put["="]=r,e.to.next(t)))}))}))},s.any=function(e,t,r,n,o,a,i,s){if(a.opt.secure)return i("Soul missing public key at '"+n+"'.");a.on("secure",(function(t){if(this.off(),!a.opt.secure)return e.to.next(t);i("Data cannot be changed.")})).on.on("secure",t)};var c=i.valid,u=function(e,t){return"string"==typeof(t=c(e))&&t};(i.state||"").ify;var f=/[^\w_-]/;o.opt.pub=function(e){if(e&&(e=e.split("~"))&&(e=e[1])&&(e=e.split(f).slice(0,2))&&2==e.length&&"@"!==(e[0]||"")[0])return e=e.slice(0,2).join(".")},o.opt.stringy=function(e){},o.opt.pack=function(e,t,r,a,s){var c,u;if(o.opt.check(e))return t(e);e&&e["#"]&&e["."]&&e[">"]&&(c=e[":"],u=1),JSON.parseAsync(u?c:e,(function(o,c){var u=n!==(c||"")[":"]&&(c||"")["~"];t(u?{m:{"#":s||e["#"],".":r||e["."],":":(c||"")[":"],">":e[">"]||i.state.is(a,r)},s:u}:e)}))};var p=o.opt;o.opt.unpack=function(e,t,r){var a;if(n!==e){if(e&&n!==(a=e[":"]))return a;if(t=t||p.fall_key,!r&&p.fall_val&&((r={})[t]=p.fall_val),t&&r){if(e===r[t])return e;if(!o.opt.check(r[t]))return e;var s=r&&r._&&r._["#"]||p.fall_soul,c=i.state.is(r,t)||p.fall_state;return e&&4===e.length&&s===e[0]&&t===e[1]&&l(c)===l(e[3])?e[2]:c<o.opt.shuffle_attack?e:void 0}}},o.opt.shuffle_attack=15463296e5;var l=Math.floor}))(t,"./index")}()}(u);var f=c(u.exports);const p=o.fileURLToPath("undefined"==typeof document&&"undefined"==typeof location?require("url").pathToFileURL(p).href:"undefined"==typeof document?location.href:i&&"SCRIPT"===i.tagName.toUpperCase()&&i.src||new URL("gun-eth.min.js",document.baseURI).href),l=a.dirname(p);let y={PROOF_OF_INTEGRITY_ADDRESS:null,STEALTH_ANNOUNCER_ADDRESS:null};try{const e=n.readFileSync(a.join(l,"contract-address.json"),"utf8");y=JSON.parse(e),console.log("Loaded contract addresses:",y)}catch(e){console.warn("Warning: contract-address.json not found or invalid")}const h={PROOF_OF_INTEGRITY_ADDRESS:y.PROOF_OF_INTEGRITY_ADDRESS,STEALTH_ANNOUNCER_ADDRESS:y.STEALTH_ANNOUNCER_ADDRESS,RPC_URL:"http://127.0.0.1:8545",GUN_PEER:"http://localhost:8765/gun",CHAIN_ID:31337};process.env.NODE_ENV;const d="development"===process.env.NODE_ENV?h.PROOF_OF_INTEGRITY_ADDRESS:"0x...";process.env.NODE_ENV;const g=[{inputs:[{internalType:"bytes[]",name:"nodeIds",type:"bytes[]"},{internalType:"bytes32[]",name:"contentHashes",type:"bytes32[]"}],name:"batchUpdateData",outputs:[],stateMutability:"nonpayable",type:"function"},{anonymous:!1,inputs:[{indexed:!0,internalType:"bytes",name:"nodeId",type:"bytes"},{indexed:!1,internalType:"bytes32",name:"contentHash",type:"bytes32"},{indexed:!1,internalType:"address",name:"updater",type:"address"}],name:"DataUpdated",type:"event"},{inputs:[{internalType:"bytes",name:"nodeId",type:"bytes"}],name:"getLatestRecord",outputs:[{internalType:"bytes32",name:"",type:"bytes32"},{internalType:"uint256",name:"",type:"uint256"},{internalType:"address",name:"",type:"address"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"bytes",name:"nodeId",type:"bytes"},{internalType:"bytes32",name:"contentHash",type:"bytes32"}],name:"updateData",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[{internalType:"bytes",name:"nodeId",type:"bytes"},{internalType:"bytes32",name:"contentHash",type:"bytes32"}],name:"verifyData",outputs:[{internalType:"bool",name:"",type:"bool"},{internalType:"uint256",name:"",type:"uint256"},{internalType:"address",name:"",type:"address"}],stateMutability:"view",type:"function"}];let w,b="",m="";const v="Access GunDB with Ethereum";function S(e){try{const t=r.ethers.hexlify(e),n=r.ethers.keccak256(t);return console.log("Generated password:",n),n}catch(e){return console.error("Error generating password:",e),null}}function A(e){const t="0x"+(e=>{const t="=".repeat((4-e.length%4)%4),r=e.replace(/-/g,"+").replace(/_/g,"/")+t,n=atob(r);return Array.from(n,(e=>e.charCodeAt(0).toString(16).padStart(2,"0"))).join("")})(e),n=new r.ethers.Wallet(t);return{account:n,publicKey:n.address,privateKey:t}}const E=async()=>{if(b&&m){const e=new r.ethers.JsonRpcProvider(b,{chainId:h.CHAIN_ID,name:"localhost"});return new r.ethers.Wallet(m,e)}if("undefined"!=typeof window&&void 0!==window.ethereum){await window.ethereum.request({method:"eth_requestAccounts"});return new r.ethers.BrowserProvider(window.ethereum).getSigner()}throw new Error("No valid Ethereum provider found")};function k(e,t){try{const n=Buffer.from(e,"base64"),o=r.ethers.keccak256(r.ethers.concat([n,r.ethers.getBytes(t)])),a=new r.ethers.Wallet(o);return console.log("Debug deriveStealthAddress:",{sharedSecretHex:r.ethers.hexlify(n),spendingPublicKey:t,stealthPrivateKey:o,stealthAddress:a.address}),{stealthPrivateKey:o,stealthAddress:a.address,wallet:a}}catch(e){throw console.error("Error in deriveStealthAddress:",e),e}}t.chain.MESSAGE_TO_SIGN=v,t.chain.setSigner=function(e,t){return b=e,m=t,console.log("Standalone configuration set"),this},t.chain.verifySignature=async function(e,t){try{return r.ethers.verifyMessage(e,t)}catch(e){return console.error("Error verifying signature:",e),null}},t.chain.generatePassword=function(e){return S(e)},t.chain.createSignature=async function(e){try{if(e!==v)throw new Error("Invalid message, valid message is: "+v);const t=await E(),r=await t.signMessage(e);return console.log("Signature created:",r),r}catch(e){return console.error("Error creating signature:",e),null}},t.chain.createAndStoreEncryptedPair=async function(e,t){try{const r=this,n=await f.pair(),o=await f.pair(),a=await f.pair(),i=S(t),s=await f.encrypt(JSON.stringify(n),i),c=await f.encrypt(JSON.stringify(o),i),u=await f.encrypt(JSON.stringify(a),i),p=A(o.priv),l=A(a.priv);await r.get("gun-eth").get("users").get(e).put({pair:s,v_pair:c,s_pair:u,publicKeys:{viewingPublicKey:o.epub,viewingPublicKey:o.epub,spendingPublicKey:l.publicKey,ethViewingAddress:p.publicKey}}),console.log("Encrypted pairs and public keys stored for:",e)}catch(e){throw console.error("Error creating and storing encrypted pair:",e),e}},t.chain.getAndDecryptPair=async function(e,t){try{const r=this,n=await r.get("gun-eth").get("users").get(e).get("pair").then();if(!n)throw new Error("No encrypted data found for this address");const o=await f.decrypt(n,t);return console.log(o),o}catch(e){return console.error("Error retrieving and decrypting pair:",e),null}},t.chain.proof=function(e,t,n,o){if(console.log("Proof plugin called with:",{chain:e,nodeId:t,data:n}),"function"!=typeof o)return console.error("Callback must be a function"),this;const a=this;if("optimismSepolia"!==e&&"localhost"!==e)return o({err:"Chain not supported"}),this;if(w="development"===process.env.NODE_ENV?h.PROOF_OF_INTEGRITY_ADDRESS:d,console.log("Using contract address:",w),!w)return o({err:"Contract address not found. Did you deploy the contract?"}),this;if(t&&!n)a.get(t).once((async e=>{if(!e)return void(o&&o({err:"Node not found in GunDB"}));console.log("existingData",e);const n=e._contentHash;if(console.log("contentHash",n),n)try{const{isValid:e,timestamp:a,updater:i}=await(async(e,t)=>{console.log("Verifying on chain:",{nodeId:e,contentHash:t});const n=await E(),o=new r.ethers.Contract(w,g,n),[a,i,s]=await o.verifyData(r.ethers.toUtf8Bytes(e),t);return console.log("Verification result:",{isValid:a,timestamp:i,updater:s}),{isValid:a,timestamp:i,updater:s}})(t,n),s=await(async e=>{const t=await E(),n=new r.ethers.Contract(w,g,t),[o,a,i]=await n.getLatestRecord(r.ethers.toUtf8Bytes(e));return console.log("Latest record from blockchain:",{nodeId:e,contentHash:o,timestamp:a,updater:i}),{contentHash:o,timestamp:a,updater:i}})(t);e?o&&o({ok:!0,message:"Data verified on blockchain",timestamp:a,updater:i,latestRecord:s}):o&&o({ok:!1,message:"Data not verified on blockchain",latestRecord:s})}catch(e){o&&o({err:e.message})}else o&&o({err:"No content hash found for this node"})}));else if(n&&!t){const e=r.ethers.hexlify(r.ethers.randomBytes(32)).slice(2),t=JSON.stringify(n),i=r.ethers.keccak256(r.ethers.toUtf8Bytes(t));a.get(e).put({...n,_contentHash:i},(async t=>{if(console.log("ack",t),t.err)o&&o({err:"Error saving data to GunDB"});else try{const t=await(async(e,t)=>{console.log("Writing on chain:",{nodeId:e,contentHash:t});const n=await E(),o=new r.ethers.Contract(w,g,n),a=await o.updateData(r.ethers.toUtf8Bytes(e),t);console.log("Transaction sent:",a.hash);const i=await a.wait();return console.log("Transaction confirmed:",i),a})(e,i);o&&o({ok:!0,message:"Data written to GunDB and blockchain",nodeId:e,txHash:t.hash})}catch(e){o&&o({err:e.message})}}))}else o&&o({err:"Invalid input. Provide either nodeId or data, not both."});return a},t.chain.gunToEthAccount=function(e){return A(e)},t.chain.generateStealthAddress=async function(e,t){try{const r=this,n=await r.get("gun-eth").get("users").get(e).get("publicKeys").then();if(!n||!n.viewingPublicKey||!n.spendingPublicKey)throw new Error("Recipient's public keys not found");const o=await this.verifySignature(v,t),a=S(t),i=await r.get("gun-eth").get("users").get(o).then();if(!i||!i.s_pair)throw new Error("Sender's keys not found");let s;try{const e=await f.decrypt(i.s_pair,a);s="string"==typeof e?JSON.parse(e):e}catch(e){throw console.error("Error decrypting spending pair:",e),new Error("Unable to decrypt spending pair")}const c=await f.secret(n.viewingPublicKey,s);if(!c)throw new Error("Unable to generate shared secret");console.log("Generate shared secret:",c);const{stealthAddress:u}=k(c,n.spendingPublicKey);return{stealthAddress:u,senderPublicKey:s.epub,spendingPublicKey:n.spendingPublicKey}}catch(e){throw console.error("Error generating stealth address:",e),e}},t.chain.publishStealthKeys=async function(e){try{const t=this,r=await this.verifySignature(v,e),n=S(e),o=await t.get("gun-eth").get("users").get(r).then();if(!o||!o.v_pair||!o.s_pair)throw new Error("Keys not found");const a=JSON.parse(await f.decrypt(o.v_pair,n)),i=JSON.parse(await f.decrypt(o.s_pair,n)),s=A(a.priv),c=A(i.priv);await t.get("gun-eth").get("users").get(r).get("publicKeys").put({viewingPublicKey:s.publicKey,spendingPublicKey:c.publicKey}),console.log("Stealth public keys published successfully")}catch(e){throw console.error("Error publishing stealth keys:",e),e}},t.chain.recoverStealthFunds=async function(e,t,r,n){try{const o=this,a=S(r),i=await this.verifySignature(v,r),s=await o.get("gun-eth").get("users").get(i).then();if(!s||!s.v_pair||!s.s_pair)throw new Error("Keys not found");let c;try{const e=await f.decrypt(s.v_pair,a);c="string"==typeof e?JSON.parse(e):e}catch(e){throw console.error("Error decrypting keys:",e),new Error("Unable to decrypt keys")}const u=await f.secret(t,c);if(!u)throw new Error("Unable to generate shared secret");console.log("Recover shared secret:",u);const{wallet:p,stealthAddress:l}=k(u,n);if(l.toLowerCase()!==e.toLowerCase())throw console.error("Mismatch:",{recovered:l,expected:e,sharedSecret:u}),new Error("Recovered stealth address does not match");return{wallet:p,address:l}}catch(e){throw console.error("Error recovering stealth funds:",e),e}},t.chain.announceStealthPayment=async function(e,t,n,o,a={onChain:!1}){try{const i=this,s=await this.verifySignature(v,o);if(a.onChain){const o=await E(),a="development"===process.env.NODE_ENV?h.STEALTH_ANNOUNCER_ADDRESS:STEALTH_ANNOUNCER_ADDRESS;console.log("Using contract address:",a);const i=new r.ethers.Contract(a,STEALTH_ANNOUNCER_ABI,o),s=await i.devFee();console.log("Dev fee:",s.toString());const c=await i.announcePayment(t,n,e,{value:s});console.log("Transaction sent:",c.hash);const u=await c.wait();console.log("Transaction confirmed:",u.hash),console.log("Stealth payment announced on-chain (dev fee paid)")}else await i.get("gun-eth").get("stealth-payments").set({stealthAddress:e,senderAddress:s,senderPublicKey:t,spendingPublicKey:n,timestamp:Date.now()}),console.log("Stealth payment announced off-chain")}catch(e){throw console.error("Error announcing stealth payment:",e),console.error("Error details:",e.stack),e}},t.chain.getStealthPayments=async function(e,t={source:"both"}){try{const n=[];if("onChain"===t.source||"both"===t.source){const t=await E(),o="development"===process.env.NODE_ENV?h.STEALTH_ANNOUNCER_ADDRESS:STEALTH_ANNOUNCER_ADDRESS,a=new r.ethers.Contract(o,STEALTH_ANNOUNCER_ABI,t);try{const t=await a.getAnnouncementsCount(),r=Number(t.toString());if(console.log("Total on-chain announcements:",r),r>0){const t=100,o=r-1;for(let r=0;r<=o;r+=t){const i=Math.min(r+t-1,o),s=await a.getAnnouncementsInRange(r,i);for(const t of s)try{if(!(t&&t.stealthAddress&&t.senderPublicKey&&t.spendingPublicKey)){console.log("Invalid announcement:",t);continue}const r=await this.recoverStealthFunds(t.stealthAddress,t.senderPublicKey,e,t.spendingPublicKey);n.push({stealthAddress:t.stealthAddress,senderPublicKey:t.senderPublicKey,spendingPublicKey:t.spendingPublicKey,timestamp:Number(t.timestamp),source:"onChain",wallet:r})}catch(e){console.log(`Announcement not for us: ${t.stealthAddress}`);continue}}}}catch(e){console.error("Error retrieving on-chain announcements:",e)}}if("offChain"===t.source||"both"===t.source){const e=this,t=await new Promise((t=>{const r=[];e.get("gun-eth").get("stealth-payments").get(recipientAddress).map().once(((e,t)=>{e?.stealthAddress&&r.push({...e,id:t,source:"offChain"})})),setTimeout((()=>t(r)),2e3)}));n.push(...t)}return console.log(`Found ${n.length} stealth payments`),n}catch(e){throw console.error("Error retrieving stealth payments:",e),e}},t.chain.cleanStealthPayments=async function(e){try{const t=this,r=await t.get("gun-eth").get("stealth-payments").get(e).map().once().then();r&&Object.keys(r).forEach((async n=>{const o=r[n];o&&o.stealthAddress&&o.senderPublicKey&&o.spendingPublicKey||await t.get("gun-eth").get("stealth-payments").get(e).get(n).put(null)}))}catch(e){console.error("Error cleaning stealth payments:",e)}},e.default=t,e.MESSAGE_TO_SIGN=v,e.generatePassword=S,e.gunToEthAccount=A,Object.defineProperty(e,"__esModule",{value:!0})}));
package/package.json CHANGED
@@ -1,15 +1,51 @@
1
1
  {
2
2
  "name": "gun-eth",
3
- "version": "1.3.6",
3
+ "version": "1.4.1",
4
4
  "description": "A GunDB plugin for Ethereum, and Web3",
5
- "main": "./src/index.js",
5
+ "main": "dist/gun-eth.cjs.js",
6
+ "module": "dist/gun-eth.esm.js",
7
+ "browser": "dist/gun-eth.min.js",
8
+ "type": "module",
6
9
  "scripts": {
7
- "test": "echo \"Error: no test specified\" && exit 1"
10
+ "test": "echo \"Error: no test specified\" && exit 1",
11
+ "start-gun": "node startGun.js",
12
+ "compile": "hardhat compile",
13
+ "start-node": "hardhat node",
14
+ "deploy-local": "hardhat run scripts/start-local-node.cjs --network localhost",
15
+ "test-stealth": "cross-env NODE_ENV=development node --experimental-json-modules src/examples/stealth-example.js",
16
+ "test-proof": "cross-env NODE_ENV=development node --experimental-json-modules src/examples/proof-example.js",
17
+ "build": "rollup -c",
18
+ "build:watch": "rollup -c -w"
8
19
  },
9
20
  "dependencies": {
10
21
  "ethers": "^6.0.0",
22
+ "express": "^4.21.1",
11
23
  "gun": "^0.2020.1239"
12
24
  },
25
+ "devDependencies": {
26
+ "@nomicfoundation/hardhat-chai-matchers": "^2.0.0",
27
+ "@nomicfoundation/hardhat-ethers": "^3.0.0",
28
+ "@nomicfoundation/hardhat-network-helpers": "^1.0.0",
29
+ "@nomicfoundation/hardhat-toolbox": "^3.0.0",
30
+ "@nomicfoundation/hardhat-verify": "^1.0.0",
31
+ "@typechain/ethers-v6": "^0.4.0",
32
+ "@typechain/hardhat": "^8.0.0",
33
+ "@types/chai": "^4.2.0",
34
+ "@types/mocha": "^10.0.1",
35
+ "chai": "^4.2.0",
36
+ "cross-env": "^7.0.3",
37
+ "hardhat": "^2.17.0",
38
+ "hardhat-gas-reporter": "^1.0.8",
39
+ "solidity-coverage": "^0.8.1",
40
+ "ts-node": "^10.9.1",
41
+ "typechain": "^8.2.0",
42
+ "typescript": "^5.0.0",
43
+ "@rollup/plugin-commonjs": "^25.0.0",
44
+ "@rollup/plugin-node-resolve": "^15.0.0",
45
+ "@rollup/plugin-json": "^6.0.0",
46
+ "@rollup/plugin-terser": "^0.4.0",
47
+ "rollup": "^3.0.0"
48
+ },
13
49
  "author": "scobru",
14
50
  "repository": {
15
51
  "type": "git",
@@ -29,5 +65,8 @@
29
65
  "bugs": {
30
66
  "url": "https://github.com/scobru/gun-eth/issues"
31
67
  },
32
- "homepage": "https://github.com/scobru/gun-eth#readme"
68
+ "homepage": "https://github.com/scobru/gun-eth#readme",
69
+ "files": [
70
+ "dist"
71
+ ]
33
72
  }
package/TUTORIAL.md DELETED
@@ -1,103 +0,0 @@
1
- # Tutorial: Illuminating Your Data with SHINE in GunDB 🌟
2
-
3
- Hey there, GunDB aficionado! Ready to take your decentralized data game to the next level? Enter SHINE: your ticket to blockchain-verified data integrity. It's not just about storing data anymore; it's about making it cryptographically awesome!
4
-
5
- ## Step 0: Wallet Integration - Your Blockchain Passport
6
-
7
- Before we dive into the SHINE pool, remember: this plugin requires a browser-based wallet provider. Think of it as your blockchain passport. Here's how to check if you're ready to roll:
8
-
9
- ```javascript
10
- async function connectWallet() {
11
- if (typeof window.ethereum !== "undefined") {
12
- console.log("Ethereum object detected");
13
- try {
14
- await window.ethereum.request({ method: "eth_requestAccounts" });
15
- console.log("Wallet connected successfully");
16
- return true;
17
- } catch (error) {
18
- console.error("Wallet connection denied:", error);
19
- return false;
20
- }
21
- } else {
22
- console.log(
23
- "Please install MetaMask or another Ethereum-compatible wallet"
24
- );
25
- return false;
26
- }
27
- }
28
-
29
- // Make sure to call this before using SHINE
30
- await connectWallet();
31
- ```
32
-
33
- Pro tip: Always ensure your wallet is connected before invoking SHINE functions. No wallet, no blockchain magic!
34
-
35
- ## Step 1: Installation - Equipping Your Toolbelt
36
-
37
- Let's add SHINE to your development arsenal:
38
-
39
- ```bash
40
- npm install gun-eth
41
- ```
42
-
43
- If your terminal responds without errors, you're locked and loaded!
44
-
45
- ## Step 2: Import - Assembling the Pieces
46
-
47
- Time to bring Gun and SHINE into your JavaScript playground:
48
-
49
- ```javascript
50
- import Gun from "gun";
51
- import "gun-eth";
52
- const gun = Gun();
53
- ```
54
-
55
- ## Step 3: SHINE in Action - Blockchain Meets Database
56
-
57
- Let's say you've got some mission-critical data to store. Here's how you'd use SHINE to give it that blockchain-grade integrity:
58
-
59
- ```javascript
60
- const criticalData = {
61
- key1: "Encrypted message",
62
- key2: "Top secret algorithm",
63
- key3: "42",
64
- };
65
-
66
- gun.shine("optimismSepolia", null, criticalData, (ack) => {
67
- if (ack.ok) {
68
- console.log("Data successfully anchored to the blockchain");
69
- console.log("Node ID for future reference:", ack.nodeId);
70
- } else {
71
- console.error("Blockchain anchoring failed:", ack.err);
72
- }
73
- });
74
- ```
75
-
76
- Remember, your wallet needs to be ready to sign this transaction. It's like pushing code without commit access - it just won't fly!
77
-
78
- ## Step 4: Verification - Trust the Crypto, Not the Hearsay
79
-
80
- When it's time to verify your data's integrity:
81
-
82
- ```javascript
83
- const nodeId = "your-data-node-id";
84
- gun.shine("optimismSepolia", nodeId, null, (ack) => {
85
- if (ack.ok) {
86
- console.log("Data integrity verified on the blockchain");
87
- console.log("Timestamp:", ack.timestamp);
88
- console.log("Last updater:", ack.updater);
89
- } else {
90
- console.error("Integrity check failed:", ack.err);
91
- }
92
- });
93
- ```
94
-
95
- Again, wallet connection is crucial. No blockchain access, no verification!
96
-
97
- ## Step 5: Reap the Benefits
98
-
99
- Congratulations! You've just leveled up your data management game. Your data is now cryptographically verifiable, tamper-evident, and blockchain-secured.
100
-
101
- Remember: With SHINE, you're not just storing data; you're creating a cryptographic proof of its existence and integrity. Use this power wisely!
102
-
103
- P.S. SHINE responsibly. With great cryptographic power comes great responsibility. Happy coding, and may your data always maintain its integrity! 🚀🔐
@@ -1,262 +0,0 @@
1
- {
2
- "address": "0x43D838b683F772F08f321E5FA265ad3e333BE9C2",
3
- "abi": [
4
- {
5
- "anonymous": false,
6
- "inputs": [
7
- {
8
- "indexed": true,
9
- "internalType": "bytes",
10
- "name": "nodeId",
11
- "type": "bytes"
12
- },
13
- {
14
- "indexed": false,
15
- "internalType": "bytes32",
16
- "name": "contentHash",
17
- "type": "bytes32"
18
- },
19
- {
20
- "indexed": false,
21
- "internalType": "address",
22
- "name": "updater",
23
- "type": "address"
24
- }
25
- ],
26
- "name": "DataUpdated",
27
- "type": "event"
28
- },
29
- {
30
- "inputs": [
31
- {
32
- "internalType": "bytes[]",
33
- "name": "nodeIds",
34
- "type": "bytes[]"
35
- },
36
- {
37
- "internalType": "bytes32[]",
38
- "name": "contentHashes",
39
- "type": "bytes32[]"
40
- }
41
- ],
42
- "name": "batchUpdateData",
43
- "outputs": [],
44
- "stateMutability": "nonpayable",
45
- "type": "function"
46
- },
47
- {
48
- "inputs": [
49
- {
50
- "internalType": "bytes",
51
- "name": "nodeId",
52
- "type": "bytes"
53
- }
54
- ],
55
- "name": "getLatestRecord",
56
- "outputs": [
57
- {
58
- "internalType": "bytes32",
59
- "name": "",
60
- "type": "bytes32"
61
- },
62
- {
63
- "internalType": "uint256",
64
- "name": "",
65
- "type": "uint256"
66
- },
67
- {
68
- "internalType": "address",
69
- "name": "",
70
- "type": "address"
71
- }
72
- ],
73
- "stateMutability": "view",
74
- "type": "function"
75
- },
76
- {
77
- "inputs": [
78
- {
79
- "internalType": "bytes",
80
- "name": "",
81
- "type": "bytes"
82
- }
83
- ],
84
- "name": "nodeData",
85
- "outputs": [
86
- {
87
- "internalType": "bytes32",
88
- "name": "contentHash",
89
- "type": "bytes32"
90
- },
91
- {
92
- "internalType": "uint256",
93
- "name": "timestamp",
94
- "type": "uint256"
95
- },
96
- {
97
- "internalType": "address",
98
- "name": "updater",
99
- "type": "address"
100
- }
101
- ],
102
- "stateMutability": "view",
103
- "type": "function"
104
- },
105
- {
106
- "inputs": [
107
- {
108
- "internalType": "bytes",
109
- "name": "nodeId",
110
- "type": "bytes"
111
- },
112
- {
113
- "internalType": "bytes32",
114
- "name": "contentHash",
115
- "type": "bytes32"
116
- }
117
- ],
118
- "name": "updateData",
119
- "outputs": [],
120
- "stateMutability": "nonpayable",
121
- "type": "function"
122
- },
123
- {
124
- "inputs": [
125
- {
126
- "internalType": "bytes",
127
- "name": "nodeId",
128
- "type": "bytes"
129
- },
130
- {
131
- "internalType": "bytes32",
132
- "name": "contentHash",
133
- "type": "bytes32"
134
- }
135
- ],
136
- "name": "verifyData",
137
- "outputs": [
138
- {
139
- "internalType": "bool",
140
- "name": "",
141
- "type": "bool"
142
- },
143
- {
144
- "internalType": "uint256",
145
- "name": "",
146
- "type": "uint256"
147
- },
148
- {
149
- "internalType": "address",
150
- "name": "",
151
- "type": "address"
152
- }
153
- ],
154
- "stateMutability": "view",
155
- "type": "function"
156
- }
157
- ],
158
- "transactionHash": "0xc00b134812b2cb32d6a412fd1d1a4c9661777b0ee29ed0ff05b09c7c0b1f6f0d",
159
- "receipt": {
160
- "to": null,
161
- "from": "0x8aA5F726d9F868a21a8bd748E2f1E43bA31eb670",
162
- "contractAddress": "0x43D838b683F772F08f321E5FA265ad3e333BE9C2",
163
- "transactionIndex": 2,
164
- "gasUsed": "419514",
165
- "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
166
- "blockHash": "0xc8bd27a2f9bf4ec35e2c61c2c2e62b47b70aa10f587ea48d4802611c36116dd6",
167
- "transactionHash": "0xc00b134812b2cb32d6a412fd1d1a4c9661777b0ee29ed0ff05b09c7c0b1f6f0d",
168
- "logs": [],
169
- "blockNumber": 17723163,
170
- "cumulativeGasUsed": "551282",
171
- "status": 1,
172
- "byzantium": true
173
- },
174
- "args": [],
175
- "numDeployments": 4,
176
- "solcInputHash": "40cece70198a47ff2f958bd8d77d352d",
177
- "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes\",\"name\":\"nodeId\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"contentHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"updater\",\"type\":\"address\"}],\"name\":\"DataUpdated\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes[]\",\"name\":\"nodeIds\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"contentHashes\",\"type\":\"bytes32[]\"}],\"name\":\"batchUpdateData\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"nodeId\",\"type\":\"bytes\"}],\"name\":\"getLatestRecord\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"nodeData\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"contentHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"updater\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"nodeId\",\"type\":\"bytes\"},{\"internalType\":\"bytes32\",\"name\":\"contentHash\",\"type\":\"bytes32\"}],\"name\":\"updateData\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"nodeId\",\"type\":\"bytes\"},{\"internalType\":\"bytes32\",\"name\":\"contentHash\",\"type\":\"bytes32\"}],\"name\":\"verifyData\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/SHINE.sol\":\"SHINE\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/SHINE.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\npragma solidity ^0.8.0;\\r\\n\\r\\ncontract SHINE {\\r\\n\\tstruct DataRecord {\\r\\n\\t\\tbytes32 contentHash;\\r\\n\\t\\tuint256 timestamp;\\r\\n\\t\\taddress updater;\\r\\n\\t}\\r\\n\\r\\n\\tmapping(bytes => DataRecord) public nodeData;\\r\\n\\r\\n\\tevent DataUpdated(\\r\\n\\t\\tbytes indexed nodeId,\\r\\n\\t\\tbytes32 contentHash,\\r\\n\\t\\taddress updater\\r\\n\\t);\\r\\n\\r\\n\\tfunction updateData(bytes memory nodeId, bytes32 contentHash) public {\\r\\n\\t\\tnodeData[nodeId] = DataRecord(contentHash, block.timestamp, msg.sender);\\r\\n\\t\\temit DataUpdated(nodeId, contentHash, msg.sender);\\r\\n\\t}\\r\\n\\r\\n\\tfunction verifyData(\\r\\n\\t\\tbytes memory nodeId,\\r\\n\\t\\tbytes32 contentHash\\r\\n\\t) public view returns (bool, uint256, address) {\\r\\n\\t\\tDataRecord memory record = nodeData[nodeId];\\r\\n\\t\\tbool isValid = record.contentHash == contentHash;\\r\\n\\t\\treturn (isValid, record.timestamp, record.updater);\\r\\n\\t}\\r\\n\\r\\n\\tfunction getLatestRecord(\\r\\n\\t\\tbytes memory nodeId\\r\\n\\t) public view returns (bytes32, uint256, address) {\\r\\n\\t\\tDataRecord memory record = nodeData[nodeId];\\r\\n\\t\\treturn (record.contentHash, record.timestamp, record.updater);\\r\\n\\t}\\r\\n\\r\\n\\tfunction batchUpdateData(\\r\\n\\t\\tbytes[] memory nodeIds,\\r\\n\\t\\tbytes32[] memory contentHashes\\r\\n\\t) public {\\r\\n\\t\\trequire(\\r\\n\\t\\t\\tnodeIds.length == contentHashes.length,\\r\\n\\t\\t\\t\\\"Arrays length mismatch\\\"\\r\\n\\t\\t);\\r\\n\\t\\tfor (uint i = 0; i < nodeIds.length; i++) {\\r\\n\\t\\t\\tupdateData(nodeIds[i], contentHashes[i]);\\r\\n\\t\\t}\\r\\n\\t}\\r\\n}\\r\\n\",\"keccak256\":\"0x1ed77b1882586a77f3e6d5bf176009c5f00b9d91f71cfd6153ca2d57ef30831d\",\"license\":\"MIT\"}},\"version\":1}",
178
- "bytecode": "0x608060405234801561001057600080fd5b506106a0806100206000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c80630d36830e1461005c5780630f07e48514610071578063d236feda14610084578063d54193d7146100c2578063d58a3de3146100f9575b600080fd5b61006f61006a3660046104a8565b61013c565b005b61006f61007f36600461057c565b6101e9565b61009761009236600461057c565b6102a2565b60408051931515845260208401929092526001600160a01b0316908201526060015b60405180910390f35b6100d56100d03660046105c1565b610302565b6040805193845260208401929092526001600160a01b0316908201526060016100b9565b6100d56101073660046105c1565b80516020818301810180516000825292820191909301209152805460018201546002909201549091906001600160a01b031683565b805182511461018a5760405162461bcd60e51b8152602060048201526016602482015275082e4e4c2f2e640d8cadccee8d040dad2e6dac2e8c6d60531b604482015260640160405180910390fd5b60005b82518110156101e4576101d28382815181106101ab576101ab6105fe565b60200260200101518383815181106101c5576101c56105fe565b60200260200101516101e9565b806101dc81610614565b91505061018d565b505050565b604080516060810182528281524260208201523381830152905160009061021190859061063b565b908152604080516020928190038301812084518155928401516001840155920151600290910180546001600160a01b0319166001600160a01b0390921691909117905561025f90839061063b565b60408051918290038220838352336020840152917fac3d4f3cbf6818c9329b6b8c61e41d9dc52fc1cc580fff6af273be3ebc1d423f910160405180910390a25050565b6000806000806000866040516102b8919061063b565b9081526040805160209281900383018120606082018352805480835260018201549483018590526002909101546001600160a01b0316919092018190529614979096509350505050565b600080600080600085604051610318919061063b565b9081526040805160209281900383018120606082018352805480835260018201549483018590526002909101546001600160a01b0316919092018190529097919650945092505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff811182821017156103a1576103a1610362565b604052919050565b600067ffffffffffffffff8211156103c3576103c3610362565b5060051b60200190565b600082601f8301126103de57600080fd5b813567ffffffffffffffff8111156103f8576103f8610362565b61040b601f8201601f1916602001610378565b81815284602083860101111561042057600080fd5b816020850160208301376000918101602001919091529392505050565b600082601f83011261044e57600080fd5b8135602061046361045e836103a9565b610378565b82815260059290921b8401810191818101908684111561048257600080fd5b8286015b8481101561049d5780358352918301918301610486565b509695505050505050565b600080604083850312156104bb57600080fd5b823567ffffffffffffffff808211156104d357600080fd5b818501915085601f8301126104e757600080fd5b813560206104f761045e836103a9565b82815260059290921b8401810191818101908984111561051657600080fd5b8286015b8481101561054e578035868111156105325760008081fd5b6105408c86838b01016103cd565b84525091830191830161051a565b509650508601359250508082111561056557600080fd5b506105728582860161043d565b9150509250929050565b6000806040838503121561058f57600080fd5b823567ffffffffffffffff8111156105a657600080fd5b6105b2858286016103cd565b95602094909401359450505050565b6000602082840312156105d357600080fd5b813567ffffffffffffffff8111156105ea57600080fd5b6105f6848285016103cd565b949350505050565b634e487b7160e01b600052603260045260246000fd5b60006001820161063457634e487b7160e01b600052601160045260246000fd5b5060010190565b6000825160005b8181101561065c5760208186018101518583015201610642565b50600092019182525091905056fea2646970667358221220c3ea212644c861f0e892deb0129df945a7fa2af5971e51e4b97810c73fc547f764736f6c63430008110033",
179
- "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100575760003560e01c80630d36830e1461005c5780630f07e48514610071578063d236feda14610084578063d54193d7146100c2578063d58a3de3146100f9575b600080fd5b61006f61006a3660046104a8565b61013c565b005b61006f61007f36600461057c565b6101e9565b61009761009236600461057c565b6102a2565b60408051931515845260208401929092526001600160a01b0316908201526060015b60405180910390f35b6100d56100d03660046105c1565b610302565b6040805193845260208401929092526001600160a01b0316908201526060016100b9565b6100d56101073660046105c1565b80516020818301810180516000825292820191909301209152805460018201546002909201549091906001600160a01b031683565b805182511461018a5760405162461bcd60e51b8152602060048201526016602482015275082e4e4c2f2e640d8cadccee8d040dad2e6dac2e8c6d60531b604482015260640160405180910390fd5b60005b82518110156101e4576101d28382815181106101ab576101ab6105fe565b60200260200101518383815181106101c5576101c56105fe565b60200260200101516101e9565b806101dc81610614565b91505061018d565b505050565b604080516060810182528281524260208201523381830152905160009061021190859061063b565b908152604080516020928190038301812084518155928401516001840155920151600290910180546001600160a01b0319166001600160a01b0390921691909117905561025f90839061063b565b60408051918290038220838352336020840152917fac3d4f3cbf6818c9329b6b8c61e41d9dc52fc1cc580fff6af273be3ebc1d423f910160405180910390a25050565b6000806000806000866040516102b8919061063b565b9081526040805160209281900383018120606082018352805480835260018201549483018590526002909101546001600160a01b0316919092018190529614979096509350505050565b600080600080600085604051610318919061063b565b9081526040805160209281900383018120606082018352805480835260018201549483018590526002909101546001600160a01b0316919092018190529097919650945092505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff811182821017156103a1576103a1610362565b604052919050565b600067ffffffffffffffff8211156103c3576103c3610362565b5060051b60200190565b600082601f8301126103de57600080fd5b813567ffffffffffffffff8111156103f8576103f8610362565b61040b601f8201601f1916602001610378565b81815284602083860101111561042057600080fd5b816020850160208301376000918101602001919091529392505050565b600082601f83011261044e57600080fd5b8135602061046361045e836103a9565b610378565b82815260059290921b8401810191818101908684111561048257600080fd5b8286015b8481101561049d5780358352918301918301610486565b509695505050505050565b600080604083850312156104bb57600080fd5b823567ffffffffffffffff808211156104d357600080fd5b818501915085601f8301126104e757600080fd5b813560206104f761045e836103a9565b82815260059290921b8401810191818101908984111561051657600080fd5b8286015b8481101561054e578035868111156105325760008081fd5b6105408c86838b01016103cd565b84525091830191830161051a565b509650508601359250508082111561056557600080fd5b506105728582860161043d565b9150509250929050565b6000806040838503121561058f57600080fd5b823567ffffffffffffffff8111156105a657600080fd5b6105b2858286016103cd565b95602094909401359450505050565b6000602082840312156105d357600080fd5b813567ffffffffffffffff8111156105ea57600080fd5b6105f6848285016103cd565b949350505050565b634e487b7160e01b600052603260045260246000fd5b60006001820161063457634e487b7160e01b600052601160045260246000fd5b5060010190565b6000825160005b8181101561065c5760208186018101518583015201610642565b50600092019182525091905056fea2646970667358221220c3ea212644c861f0e892deb0129df945a7fa2af5971e51e4b97810c73fc547f764736f6c63430008110033",
180
- "devdoc": {
181
- "kind": "dev",
182
- "methods": {},
183
- "version": 1
184
- },
185
- "userdoc": {
186
- "kind": "user",
187
- "methods": {},
188
- "version": 1
189
- },
190
- "storageLayout": {
191
- "storage": [
192
- {
193
- "astId": 13,
194
- "contract": "contracts/SHINE.sol:SHINE",
195
- "label": "nodeData",
196
- "offset": 0,
197
- "slot": "0",
198
- "type": "t_mapping(t_bytes_memory_ptr,t_struct(DataRecord)8_storage)"
199
- }
200
- ],
201
- "types": {
202
- "t_address": {
203
- "encoding": "inplace",
204
- "label": "address",
205
- "numberOfBytes": "20"
206
- },
207
- "t_bytes32": {
208
- "encoding": "inplace",
209
- "label": "bytes32",
210
- "numberOfBytes": "32"
211
- },
212
- "t_bytes_memory_ptr": {
213
- "encoding": "bytes",
214
- "label": "bytes",
215
- "numberOfBytes": "32"
216
- },
217
- "t_mapping(t_bytes_memory_ptr,t_struct(DataRecord)8_storage)": {
218
- "encoding": "mapping",
219
- "key": "t_bytes_memory_ptr",
220
- "label": "mapping(bytes => struct SHINE.DataRecord)",
221
- "numberOfBytes": "32",
222
- "value": "t_struct(DataRecord)8_storage"
223
- },
224
- "t_struct(DataRecord)8_storage": {
225
- "encoding": "inplace",
226
- "label": "struct SHINE.DataRecord",
227
- "members": [
228
- {
229
- "astId": 3,
230
- "contract": "contracts/SHINE.sol:SHINE",
231
- "label": "contentHash",
232
- "offset": 0,
233
- "slot": "0",
234
- "type": "t_bytes32"
235
- },
236
- {
237
- "astId": 5,
238
- "contract": "contracts/SHINE.sol:SHINE",
239
- "label": "timestamp",
240
- "offset": 0,
241
- "slot": "1",
242
- "type": "t_uint256"
243
- },
244
- {
245
- "astId": 7,
246
- "contract": "contracts/SHINE.sol:SHINE",
247
- "label": "updater",
248
- "offset": 0,
249
- "slot": "2",
250
- "type": "t_address"
251
- }
252
- ],
253
- "numberOfBytes": "96"
254
- },
255
- "t_uint256": {
256
- "encoding": "inplace",
257
- "label": "uint256",
258
- "numberOfBytes": "32"
259
- }
260
- }
261
- }
262
- }
@@ -1,52 +0,0 @@
1
- // SPDX-License-Identifier: MIT
2
- pragma solidity ^0.8.0;
3
-
4
- contract SHINE {
5
- struct DataRecord {
6
- bytes32 contentHash;
7
- uint256 timestamp;
8
- address updater;
9
- }
10
-
11
- mapping(bytes => DataRecord) public nodeData;
12
-
13
- event DataUpdated(
14
- bytes indexed nodeId,
15
- bytes32 contentHash,
16
- address updater
17
- );
18
-
19
- function updateData(bytes memory nodeId, bytes32 contentHash) public {
20
- nodeData[nodeId] = DataRecord(contentHash, block.timestamp, msg.sender);
21
- emit DataUpdated(nodeId, contentHash, msg.sender);
22
- }
23
-
24
- function verifyData(
25
- bytes memory nodeId,
26
- bytes32 contentHash
27
- ) public view returns (bool, uint256, address) {
28
- DataRecord memory record = nodeData[nodeId];
29
- bool isValid = record.contentHash == contentHash;
30
- return (isValid, record.timestamp, record.updater);
31
- }
32
-
33
- function getLatestRecord(
34
- bytes memory nodeId
35
- ) public view returns (bytes32, uint256, address) {
36
- DataRecord memory record = nodeData[nodeId];
37
- return (record.contentHash, record.timestamp, record.updater);
38
- }
39
-
40
- function batchUpdateData(
41
- bytes[] memory nodeIds,
42
- bytes32[] memory contentHashes
43
- ) public {
44
- require(
45
- nodeIds.length == contentHashes.length,
46
- "Arrays length mismatch"
47
- );
48
- for (uint i = 0; i < nodeIds.length; i++) {
49
- updateData(nodeIds[i], contentHashes[i]);
50
- }
51
- }
52
- }