diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..44a2420 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,5 @@ +docs +README.md +banani-browser.js +package.json +package-lock.json diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..5f0677f --- /dev/null +++ b/.prettierrc @@ -0,0 +1,9 @@ +{ + "printWidth": 999, + "tabWidth": 2, + "semi": true, + "trailingComma": "es5", + "arrowParens": "always", + "endOfLine": "lf", + "useTabs": false +} diff --git a/README.md b/README.md index 6ad881d..b6f93a6 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ npm install banani ``` Embedding in the browser is easy to - just download and add `banani-browser.js` to your website: + ```html ``` @@ -21,23 +22,25 @@ Embedding in the browser is easy to - just download and add `banani-browser.js` Take a look in `browser_test/index.html` for an example. ## Documentation + The docs are hosted at https://banani.prussia.dev (can also be accessed at https://stjet.github.io/banani/). ## Examples + Banani allows you to send, receive, and change representative. If you are using Banani on the web, replace `banani` with `window.banani`. ```js -let rpc = new banani.RPC("https://kaliumapi.appditto.com/api"); +const rpc = new banani.RPC("https://kaliumapi.appditto.com/api"); console.log(await rpc.get_block_count()); -let wallet = new banani.Wallet(rpc, process.env.seed); +const wallet = new banani.Wallet(rpc, process.env.seed); -let zero_index_address = wallet.address; +const zero_index_address = wallet.address; wallet.index = 1; -let send_hash = await wallet.send(zero_index_address, "1"); //send 1 banano +const send_hash = await wallet.send(zero_index_address, "1"); //send 1 banano wallet.index = 0; @@ -47,15 +50,17 @@ await wallet.change_rep("placeholder"); ``` Banani also comes with some useful utilities, and message signing: + ```js -let rpc = new banani.RPC("https://kaliumapi.appditto.com/api"); -let random_wallet = banani.Wallet.gen_random_wallet(rpc); +const rpc = new banani.RPC("https://kaliumapi.appditto.com/api"); +const random_wallet = banani.Wallet.gen_random_wallet(rpc); console.log(banani.whole_to_raw("4.20069") === 420069000000000000000000000000n); console.log(random_wallet.sign_message("test message\ntest test")); ``` ## Contributing + ``` git clone https://github.com/stjet/banani.git cd banani @@ -70,18 +75,22 @@ Then commit and push your changes. In most cases, you will only need to touch the typescript (`.ts`) files. ## Work Generation + Though Kalium's public work will generate work for you, it is suggested that you generate your own work for the following reasons: + - it is relatively "easy" (in terms of computation) to do - if Boompow goes offline (as it has done in the past), many Banano services will go down, which is not great for users and is not a very decentralized or resilient way to make your thing Unrelated, do remember that Nano has harder work thresholds than Banano. ## Using for Nano instead of Banano + The main differences between Nano and Banano; or at least those relevant to a library like this, are the different amount of decimals. So, when creating a `Wallet` with banani, make sure to do `my_rpc.DECIMALS = 31` otherwise your sends will be off by two magnitudes which is bad. Also, a different preamble should be used for message signing. ## Dependencies + Banani has two external dependencies, tweetnacl and blake2b. Blake2b probably has its own dependencies, but I haven't checked. Tweetnacl is not listed as a dependency in the package.json because it has been modified to use blake2b for the hashing algorithm. So, a modified version of it is distributed directly along with the package (see `tweetnacl_mod.js`). Clone the repo and run `npm run cryptodiff` to see the changes made from regular tweetnacl. @@ -89,6 +98,6 @@ Tweetnacl is not listed as a dependency in the package.json because it has been Banani also has many dev dependencies for contributing/developing the package (see the "Contributing" section), but they are not needed for regular users of the package. ## Todo + - More extensive testing - Example work generating function - diff --git a/banani-browser.js b/banani-browser.js index 3f873f3..46c7822 100644 --- a/banani-browser.js +++ b/banani-browser.js @@ -1,4 +1,4 @@ -(()=>{var un=Object.create;var Le=Object.defineProperty;var ln=Object.getOwnPropertyDescriptor;var yn=Object.getOwnPropertyNames;var En=Object.getPrototypeOf,wn=Object.prototype.hasOwnProperty;var g=(e,r)=>Le(e,"name",{value:r,configurable:!0}),tr=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(r,t)=>(typeof require<"u"?require:r)[t]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var M=(e,r)=>()=>(r||e((r={exports:{}}).exports,r),r.exports),Me=(e,r)=>{for(var t in r)Le(e,t,{get:r[t],enumerable:!0})},Bn=(e,r,t,i)=>{if(r&&typeof r=="object"||typeof r=="function")for(let c of yn(r))!wn.call(e,c)&&c!==t&&Le(e,c,{get:()=>r[c],enumerable:!(i=ln(r,c))||i.enumerable});return e};var rr=(e,r,t)=>(t=e!=null?un(En(e)):{},Bn(r||!e||!e.__esModule?Le(t,"default",{value:e,enumerable:!0}):t,e));var lt=M((Di,ir)=>{ir.exports=nr;var Ve=class extends Error{static{g(this,"AssertionError")}};Ve.prototype.name="AssertionError";function nr(e,r){if(!e){var t=new Ve(r);throw Error.captureStackTrace&&Error.captureStackTrace(t,nr),t}}g(nr,"assert")});var Ir=M((mi,or)=>{function Ar(e){return e.length}g(Ar,"byteLength");function xn(e){let r=e.byteLength,t="";for(let i=0;i{var ge="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",Z=new Uint8Array(256);for(let e=0;e1&&e.charCodeAt(r-1)===61&&r--,r*3>>>2}g(ar,"byteLength");function dn(e){let r=e.byteLength,t="";for(let i=0;i>2]+ge[(e[i]&3)<<4|e[i+1]>>4]+ge[(e[i+1]&15)<<2|e[i+2]>>6]+ge[e[i+2]&63];return r%3===2?t=t.substring(0,t.length-1)+"=":r%3===1&&(t=t.substring(0,t.length-2)+"=="),t}g(dn,"toString");function bn(e,r,t=0,i=ar(r)){let c=Math.min(i,e.byteLength-t);for(let f=0,y=0;y>4,e[y++]=(x&15)<<4|b>>2,e[y++]=(b&3)<<6|_&63}return c}g(bn,"write");gr.exports={byteLength:ar,toString:dn,write:bn}});var Cr=M((Ki,fr)=>{function hr(e){return e.length>>>1}g(hr,"byteLength");function _n(e){let r=e.byteLength;e=new DataView(e.buffer,e.byteOffset,r);let t="",i=0;for(let c=r-r%4;i=48&&e<=57)return e-48;if(e>=65&&e<=70)return e-65+10;if(e>=97&&e<=102)return e-97+10}g(sr,"hexValue")});var lr=M((Yi,ur)=>{function yt(e){let r=0;for(let t=0,i=e.length;t=55296&&c<=56319&&t+1=56320&&f<=57343){r+=4,t++;continue}}c<=127?r+=1:c<=2047?r+=2:r+=3}return r}g(yt,"byteLength");var Et;if(typeof TextDecoder<"u"){let e=new TextDecoder;Et=g(function(t){return e.decode(t)},"toString")}else Et=g(function(r){let t=r.byteLength,i="",c=0;for(;c0){let x=0;for(;x>b,b-=6;b>=0;)r[w++]=128|x>>b&63,b-=6;y+=x>=65536?2:1}return f},"write");ur.exports={byteLength:yt,toString:Et,write:wt}});var wr=M((Hi,Er)=>{function yr(e){return e.length*2}g(yr,"byteLength");function Sn(e){let r=e.byteLength,t="";for(let i=0;i>8,b=w%256;e[t+y*2]=b,e[t+y*2+1]=x}return c}g(Dn,"write");Er.exports={byteLength:yr,toString:Sn,write:Dn}});var br=M((xt,dr)=>{var Un=Ir(),mn=cr(),vn=Cr(),Fn=lr(),Pn=wr(),Ge=new Uint8Array(Uint16Array.of(255).buffer)[0]===255;function xe(e){switch(e){case"ascii":return Un;case"base64":return mn;case"hex":return vn;case"utf8":case"utf-8":case void 0:return Fn;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return Pn;default:throw new Error(`Unknown encoding: ${e}`)}}g(xe,"codecFor");function Br(e){return e instanceof Uint8Array}g(Br,"isBuffer");function Kn(e){try{return xe(e),!0}catch{return!1}}g(Kn,"isEncoding");function kn(e,r,t){let i=new Uint8Array(e);return r!==void 0&&xt.fill(i,r,0,i.byteLength,t),i}g(kn,"alloc");function Yn(e){return new Uint8Array(e)}g(Yn,"allocUnsafe");function Rn(e){return new Uint8Array(e)}g(Rn,"allocUnsafeSlow");function Hn(e,r){return xe(r).byteLength(e)}g(Hn,"byteLength");function Ln(e,r){if(e===r)return 0;let t=Math.min(e.byteLength,r.byteLength);e=new DataView(e.buffer,e.byteOffset,e.byteLength),r=new DataView(r.buffer,r.byteOffset,r.byteLength);let i=0;for(let c=t-t%4;if)return 1}return e.byteLength>r.byteLength?1:e.byteLengthc+f.byteLength,0));let t=new Uint8Array(r),i=0;for(let c of e){if(i+c.byteLength>t.byteLength){let f=c.subarray(0,t.byteLength-i);return t.set(f,i),t}t.set(c,i),i+=c.byteLength}return t}g(Mn,"concat");function Vn(e,r,t=0,i=0,c=e.byteLength){if(c>0&&c=e.byteLength)throw new RangeError("sourceStart is out of range");if(c<0)throw new RangeError("sourceEnd is out of range");t>=r.byteLength&&(t=r.byteLength),c>e.byteLength&&(c=e.byteLength),r.byteLength-t=e.byteLength){if(c)return-1;t=e.byteLength-1}else if(t<0)if(c)t=0;else return-1;if(typeof r=="string")r=Bt(r,i);else if(typeof r=="number")return r=r&255,c?e.indexOf(r,t):e.lastIndexOf(r,t);if(r.byteLength===0)return-1;if(c){let f=-1;for(let y=t;ye.byteLength&&(t=e.byteLength-r.byteLength);for(let f=t;f>=0;f--){let y=!0;for(let w=0;w=c||i<=t?"":(t<0&&(t=0),i>c&&(i=c),(t!==0||i{var ci=g((e,r)=>g(function(){return r||(0,e[Object.keys(e)[0]])((r={exports:{}}).exports,r),r.exports},"__require"),"__commonJS"),si=(()=>{for(var e=new Uint8Array(128),r=0;r<64;r++)e[r<26?r+65:r<52?r+71:r<62?r-4:r*4-205]=r;return t=>{for(var i=t.length,c=new Uint8Array((i-(t[i-1]=="=")-(t[i-2]=="="))*3/4|0),f=0,y=0;f>4,c[y++]=x<<4|b>>2,c[y++]=b<<6|_}return c}})(),hi=ci({"wasm-binary:./blake2b.wat"(e,r){r.exports=si("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")}}),fi=hi(),Ci=WebAssembly.compile(fi);_r.exports=async e=>(await WebAssembly.instantiate(await Ci,e)).exports});var Kr=M((Oi,G)=>{var K=lt(),ui=br(),J=null,Sr=typeof WebAssembly<"u"&&pr()().then(e=>{J=e}),O=64,Ne=[];G.exports=v;var Dr=G.exports.BYTES_MIN=16,Ur=G.exports.BYTES_MAX=64,Ni=G.exports.BYTES=32,mr=G.exports.KEYBYTES_MIN=16,vr=G.exports.KEYBYTES_MAX=64,Ti=G.exports.KEYBYTES=32,Fr=G.exports.SALTBYTES=16,Pr=G.exports.PERSONALBYTES=16;function v(e,r,t,i,c){if(!(this instanceof v))return new v(e,r,t,i,c);if(!J)throw new Error("WASM not loaded. Wait for Blake2b.ready(cb)");e||(e=32),c!==!0&&(K(e>=Dr,"digestLength must be at least "+Dr+", was given "+e),K(e<=Ur,"digestLength must be at most "+Ur+", was given "+e),r!=null&&(K(r instanceof Uint8Array,"key must be Uint8Array or Buffer"),K(r.length>=mr,"key must be at least "+mr+", was given "+r.length),K(r.length<=vr,"key must be at least "+vr+", was given "+r.length)),t!=null&&(K(t instanceof Uint8Array,"salt must be Uint8Array or Buffer"),K(t.length===Fr,"salt must be exactly "+Fr+", was given "+t.length)),i!=null&&(K(i instanceof Uint8Array,"personal must be Uint8Array or Buffer"),K(i.length===Pr,"personal must be exactly "+Pr+", was given "+i.length))),Ne.length||(Ne.push(O),O+=216),this.digestLength=e,this.finalized=!1,this.pointer=Ne.pop(),this._memory=new Uint8Array(J.memory.buffer),this._memory.fill(0,0,64),this._memory[0]=this.digestLength,this._memory[1]=r?r.length:0,this._memory[2]=1,this._memory[3]=1,t&&this._memory.set(t,32),i&&this._memory.set(i,48),this.pointer+216>this._memory.length&&this._realloc(this.pointer+216),J.blake2b_init(this.pointer,this.digestLength),r&&(this.update(r),this._memory.fill(0,O,O+r.length),this._memory[this.pointer+200]=128)}g(v,"Blake2b");v.prototype._realloc=function(e){J.memory.grow(Math.max(0,Math.ceil(Math.abs(e-this._memory.length)/65536))),this._memory=new Uint8Array(J.memory.buffer)};v.prototype.update=function(e){return K(this.finalized===!1,"Hash instance finalized"),K(e instanceof Uint8Array,"input must be Uint8Array or Buffer"),O+e.length>this._memory.length&&this._realloc(O+e.length),this._memory.set(e,O),J.blake2b_update(this.pointer,O,O+e.length),this};v.prototype.digest=function(e){if(K(this.finalized===!1,"Hash instance finalized"),this.finalized=!0,Ne.push(this.pointer),J.blake2b_final(this.pointer),!e||e==="binary")return this._memory.slice(this.pointer+128,this.pointer+128+this.digestLength);if(typeof e=="string")return ui.toString(this._memory,e,this.pointer+128,this.pointer+128+this.digestLength);K(e instanceof Uint8Array&&e.length>=this.digestLength,"input must be Uint8Array or Buffer");for(var r=0;re(),e):e(new Error("WebAssembly not supported"))};v.prototype.ready=v.ready;v.prototype.getPartialHash=function(){return this._memory.slice(this.pointer,this.pointer+216)};v.prototype.setPartialHash=function(e){this._memory.set(e,this.pointer)};function li(){}g(li,"noop")});var Qt=M((qi,F)=>{var Y=lt(),de=Kr();function Te(e,r,t){var i=e[r]+e[t],c=e[r+1]+e[t+1];i>=4294967296&&c++,e[r]=i,e[r+1]=c}g(Te,"ADD64AA");function kr(e,r,t,i){var c=e[r]+t;t<0&&(c+=4294967296);var f=e[r+1]+i;c>=4294967296&&f++,e[r]=c,e[r+1]=f}g(kr,"ADD64AC");function Gr(e,r){return e[r]^e[r+1]<<8^e[r+2]<<16^e[r+3]<<24}g(Gr,"B2B_GET32");function q(e,r,t,i,c,f){var y=Qe[c],w=Qe[c+1],x=Qe[f],b=Qe[f+1];Te(B,e,r),kr(B,e,y,w);var _=B[i]^B[e],S=B[i+1]^B[e+1];B[i]=S,B[i+1]=_,Te(B,t,i),_=B[r]^B[t],S=B[r+1]^B[t+1],B[r]=_>>>24^S<<8,B[r+1]=S>>>24^_<<8,Te(B,e,r),kr(B,e,x,b),_=B[i]^B[e],S=B[i+1]^B[e+1],B[i]=_>>>16^S<<16,B[i+1]=S>>>16^_<<16,Te(B,t,i),_=B[r]^B[t],S=B[r+1]^B[t+1],B[r]=S>>>31^_<<1,B[r+1]=_>>>31^S<<1}g(q,"B2B_G");var Nr=new Uint32Array([4089235720,1779033703,2227873595,3144134277,4271175723,1013904242,1595750129,2773480762,2917565137,1359893119,725511199,2600822924,4215389547,528734635,327033209,1541459225]),yi=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,14,10,4,8,9,15,13,6,1,12,0,2,11,7,5,3,11,8,12,0,5,2,15,13,10,14,3,6,7,1,9,4,7,9,3,1,13,12,11,14,2,6,5,10,4,0,15,8,9,0,5,7,2,4,10,15,14,1,11,12,6,8,3,13,2,12,6,10,0,11,8,3,4,13,7,5,15,14,1,9,12,5,1,15,14,13,4,10,0,7,6,3,9,2,8,11,13,11,7,14,12,1,3,9,5,0,15,4,8,6,2,10,6,15,14,9,11,3,0,8,12,2,13,7,1,4,10,5,10,2,8,4,7,6,1,5,15,11,9,14,3,12,13,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,14,10,4,8,9,15,13,6,1,12,0,2,11,7,5,3],U=new Uint8Array(yi.map(function(e){return e*2})),B=new Uint32Array(32),Qe=new Uint32Array(32);function Tr(e,r){var t=0;for(t=0;t<16;t++)B[t]=e.h[t],B[t+16]=Nr[t];for(B[24]=B[24]^e.t,B[25]=B[25]^e.t/4294967296,r&&(B[28]=~B[28],B[29]=~B[29]),t=0;t<32;t++)Qe[t]=Gr(e.b,4*t);for(t=0;t<12;t++)q(0,8,16,24,U[t*16+0],U[t*16+1]),q(2,10,18,26,U[t*16+2],U[t*16+3]),q(4,12,20,28,U[t*16+4],U[t*16+5]),q(6,14,22,30,U[t*16+6],U[t*16+7]),q(0,10,20,30,U[t*16+8],U[t*16+9]),q(2,12,22,24,U[t*16+10],U[t*16+11]),q(4,14,16,26,U[t*16+12],U[t*16+13]),q(6,8,18,28,U[t*16+14],U[t*16+15]);for(t=0;t<16;t++)e.h[t]=e.h[t]^B[t]^B[t+16]}g(Tr,"blake2bCompress");var W=new Uint8Array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]);function ce(e,r,t,i){W.fill(0),this.b=new Uint8Array(128),this.h=new Uint32Array(16),this.t=0,this.c=0,this.outlen=e,W[0]=e,r&&(W[1]=r.length),W[2]=1,W[3]=1,t&&W.set(t,32),i&&W.set(i,48);for(var c=0;c<16;c++)this.h[c]=Nr[c]^Gr(W,c*4);r&&(Or(this,r),this.c=128)}g(ce,"Blake2b");ce.prototype.update=function(e){return Y(e instanceof Uint8Array,"input must be Uint8Array or Buffer"),Or(this,e),this};ce.prototype.digest=function(e){var r=!e||e==="binary"||e==="hex"?new Uint8Array(this.outlen):e;return Y(r instanceof Uint8Array,'out must be "binary", "hex", Uint8Array, or Buffer'),Y(r.length>=this.outlen,"out must have at least outlen bytes of space"),Ei(this,r),e==="hex"?wi(r):r};ce.prototype.final=ce.prototype.digest;ce.ready=function(e){de.ready(function(){e()})};function Or(e,r){for(var t=0;t>2]>>8*(t&3);return r}g(Ei,"blake2bFinal");function wi(e){for(var r="",t=0;t=Yr,"outlen must be at least "+Yr+", was given "+r),Y(r<=Rr,"outlen must be at most "+Rr+", was given "+r),t!=null&&(Y(t instanceof Uint8Array,"key must be Uint8Array or Buffer"),Y(t.length>=Hr,"key must be at least "+Hr+", was given "+t.length),Y(t.length<=Lr,"key must be at most "+Lr+", was given "+t.length)),i!=null&&(Y(i instanceof Uint8Array,"salt must be Uint8Array or Buffer"),Y(i.length===Mr,"salt must be exactly "+Mr+", was given "+i.length)),c!=null&&(Y(c instanceof Uint8Array,"personal must be Uint8Array or Buffer"),Y(c.length===Vr,"personal must be exactly "+Vr+", was given "+c.length))),new xi(r,t,i,c)},"createHash");F.exports.ready=function(e){de.ready(function(){e()})};F.exports.WASM_SUPPORTED=de.SUPPORTED;F.exports.WASM_LOADED=!1;var Yr=F.exports.BYTES_MIN=16,Rr=F.exports.BYTES_MAX=64,ji=F.exports.BYTES=32,Hr=F.exports.KEYBYTES_MIN=16,Lr=F.exports.KEYBYTES_MAX=64,Xi=F.exports.KEYBYTES=32,Mr=F.exports.SALTBYTES=16,Vr=F.exports.PERSONALBYTES=16;de.ready(function(e){e||(F.exports.WASM_LOADED=!0,F.exports=de)})});var Jr=M((zi,Oe)=>{(function(e){"use strict";let r=Qt();var t=g(function(n,o){this.hi=n|0,this.lo=o|0},"u64"),i=g(function(n){var o,A=new Float64Array(16);if(n)for(o=0;o>>32-o}g(X,"L32");function ne(n,o){var A=n[o+3]&255;return A=A<<8|n[o+2]&255,A=A<<8|n[o+1]&255,A<<8|n[o+0]&255}g(ne,"ld32");function Pt(n,o){var A=n[o]<<24|n[o+1]<<16|n[o+2]<<8|n[o+3],I=n[o+4]<<24|n[o+5]<<16|n[o+6]<<8|n[o+7];return new t(A,I)}g(Pt,"dl64");function We(n,o,A){var I;for(I=0;I<4;I++)n[o+I]=A&255,A>>>=8}g(We,"st32");function Kt(n,o,A){n[o]=A.hi>>24&255,n[o+1]=A.hi>>16&255,n[o+2]=A.hi>>8&255,n[o+3]=A.hi&255,n[o+4]=A.lo>>24&255,n[o+5]=A.lo>>16&255,n[o+6]=A.lo>>8&255,n[o+7]=A.lo&255}g(Kt,"ts64");function ze(n,o,A,I,a){var s,u=0;for(s=0;s>>8)-1}g(ze,"vn");function kt(n,o,A,I){return ze(n,o,A,I,16)}g(kt,"crypto_verify_16");function Ze(n,o,A,I){return ze(n,o,A,I,32)}g(Ze,"crypto_verify_32");function Yt(n,o,A,I,a){var s=new Uint32Array(16),u=new Uint32Array(16),l=new Uint32Array(16),h=new Uint32Array(4),C,E,d;for(C=0;C<4;C++)u[5*C]=ne(I,4*C),u[1+C]=ne(A,4*C),u[6+C]=ne(o,4*C),u[11+C]=ne(A,16+4*C);for(C=0;C<16;C++)l[C]=u[C];for(C=0;C<20;C++){for(E=0;E<4;E++){for(d=0;d<4;d++)h[d]=u[(5*E+4*d)%16];for(h[1]^=X(h[0]+h[3]|0,7),h[2]^=X(h[1]+h[0]|0,9),h[3]^=X(h[2]+h[1]|0,13),h[0]^=X(h[3]+h[2]|0,18),d=0;d<4;d++)s[4*E+(E+d)%4]=h[d]}for(d=0;d<16;d++)u[d]=s[d]}if(a){for(C=0;C<16;C++)u[C]=u[C]+l[C]|0;for(C=0;C<4;C++)u[5*C]=u[5*C]-ne(I,4*C)|0,u[6+C]=u[6+C]-ne(o,4*C)|0;for(C=0;C<4;C++)We(n,4*C,u[5*C]),We(n,16+4*C,u[6+C])}else for(C=0;C<16;C++)We(n,4*C,u[C]+l[C]|0)}g(Yt,"core");function Rt(n,o,A,I){return Yt(n,o,A,I,!1),0}g(Rt,"crypto_core_salsa20");function Ue(n,o,A,I){return Yt(n,o,A,I,!0),0}g(Ue,"crypto_core_hsalsa20");var he=new Uint8Array([101,120,112,97,110,100,32,51,50,45,98,121,116,101,32,107]);function $e(n,o,A,I,a,s,u){var l=new Uint8Array(16),h=new Uint8Array(64),C,E;if(!a)return 0;for(E=0;E<16;E++)l[E]=0;for(E=0;E<8;E++)l[E]=s[E];for(;a>=64;){for(Rt(h,l,u,he),E=0;E<64;E++)n[o+E]=(A?A[I+E]:0)^h[E];for(C=1,E=8;E<16;E++)C=C+(l[E]&255)|0,l[E]=C&255,C>>>=8;a-=64,o+=64,A&&(I+=64)}if(a>0)for(Rt(h,l,u,he),E=0;E>>=8}g(tt,"add1305");var Zr=new Uint32Array([5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,252]);function rt(n,o,A,I,a,s){var u,l,h,C,E=new Uint32Array(17),d=new Uint32Array(17),p=new Uint32Array(17),L=new Uint32Array(17),ae=new Uint32Array(17);for(h=0;h<17;h++)d[h]=p[h]=0;for(h=0;h<16;h++)d[h]=s[h];for(d[3]&=15,d[4]&=252,d[7]&=15,d[8]&=252,d[11]&=15,d[12]&=252,d[15]&=15;a>0;){for(h=0;h<17;h++)L[h]=0;for(h=0;h<16&&h>>=8;for(C=C+p[16]|0,p[16]=C&3,C=5*(C>>>2)|0,h=0;h<16;h++)C=C+p[h]|0,p[h]=C&255,C>>>=8;C=C+p[16]|0,p[16]=C}for(h=0;h<17;h++)ae[h]=p[h];for(tt(p,Zr),u=-(p[16]>>>7)|0,h=0;h<17;h++)p[h]^=u&(ae[h]^p[h]);for(h=0;h<16;h++)L[h]=s[h+16];for(L[16]=0,tt(p,L),h=0;h<16;h++)n[o+h]=p[h];return 0}g(rt,"crypto_onetimeauth");function Mt(n,o,A,I,a,s){var u=new Uint8Array(16);return rt(u,0,A,I,a,s),kt(n,o,u,0)}g(Mt,"crypto_onetimeauth_verify");function nt(n,o,A,I,a){var s;if(A<32)return-1;for(et(n,0,o,0,A,I,a),rt(n,16,n,32,A-32,n),s=0;s<16;s++)n[s]=0;return 0}g(nt,"crypto_secretbox");function it(n,o,A,I,a){var s,u=new Uint8Array(32);if(A<32||(Lt(u,0,32,I,a),Mt(o,16,o,32,A-32,u)!==0))return-1;for(et(n,0,o,0,A,I,a),s=0;s<32;s++)n[s]=0;return 0}g(it,"crypto_secretbox_open");function N(n,o){var A;for(A=0;A<16;A++)n[A]=o[A]|0}g(N,"set25519");function fe(n){var o,A;for(A=0;A<16;A++)n[A]+=65536,o=Math.floor(n[A]/65536),n[(A+1)*(A<15?1:0)]+=o-1+37*(o-1)*(A===15?1:0),n[A]-=o*65536}g(fe,"car25519");function ie(n,o,A){for(var I,a=~(A-1),s=0;s<16;s++)I=a&(n[s]^o[s]),n[s]^=I,o[s]^=I}g(ie,"sel25519");function Ae(n,o){var A,I,a,s=i(),u=i();for(A=0;A<16;A++)u[A]=o[A];for(fe(u),fe(u),fe(u),I=0;I<2;I++){for(s[0]=u[0]-65517,A=1;A<15;A++)s[A]=u[A]-65535-(s[A-1]>>16&1),s[A-1]&=65535;s[15]=u[15]-32767-(s[14]>>16&1),a=s[15]>>16&1,s[14]&=65535,ie(u,s,1-a)}for(A=0;A<16;A++)n[2*A]=u[A]&255,n[2*A+1]=u[A]>>8}g(Ae,"pack25519");function Vt(n,o){var A=new Uint8Array(32),I=new Uint8Array(32);return Ae(A,n),Ae(I,o),Ze(A,0,I,0)}g(Vt,"neq25519");function Gt(n){var o=new Uint8Array(32);return Ae(o,n),o[0]&1}g(Gt,"par25519");function At(n,o){var A;for(A=0;A<16;A++)n[A]=o[2*A]+(o[2*A+1]<<8);n[15]&=32767}g(At,"unpack25519");function R(n,o,A){var I;for(I=0;I<16;I++)n[I]=o[I]+A[I]|0}g(R,"A");function H(n,o,A){var I;for(I=0;I<16;I++)n[I]=o[I]-A[I]|0}g(H,"Z");function Q(n,o,A){var I,a,s=new Float64Array(31);for(I=0;I<31;I++)s[I]=0;for(I=0;I<16;I++)for(a=0;a<16;a++)s[I+a]+=o[I]*A[a];for(I=0;I<15;I++)s[I]+=38*s[I+16];for(I=0;I<16;I++)n[I]=s[I];fe(n),fe(n)}g(Q,"M");function k(n,o){Q(n,o,o)}g(k,"S");function Nt(n,o){var A=i(),I;for(I=0;I<16;I++)A[I]=o[I];for(I=253;I>=0;I--)k(A,A),I!==2&&I!==4&&Q(A,A,o);for(I=0;I<16;I++)n[I]=A[I]}g(Nt,"inv25519");function Tt(n,o){var A=i(),I;for(I=0;I<16;I++)A[I]=o[I];for(I=250;I>=0;I--)k(A,A),I!==1&&Q(A,A,o);for(I=0;I<16;I++)n[I]=A[I]}g(Tt,"pow2523");function me(n,o,A){var I=new Uint8Array(32),a=new Float64Array(80),s,u,l=i(),h=i(),C=i(),E=i(),d=i(),p=i();for(u=0;u<31;u++)I[u]=o[u];for(I[31]=o[31]&127|64,I[0]&=248,At(a,A),u=0;u<16;u++)h[u]=a[u],E[u]=l[u]=C[u]=0;for(l[0]=E[0]=1,u=254;u>=0;--u)s=I[u>>>3]>>>(u&7)&1,ie(l,h,s),ie(C,E,s),R(d,l,C),H(l,l,C),R(C,h,E),H(h,h,E),k(E,d),k(p,l),Q(l,C,l),Q(C,h,d),R(d,l,C),H(l,l,C),k(h,l),H(C,E,p),Q(l,C,b),R(l,l,E),Q(C,C,l),Q(l,E,p),Q(E,h,a),k(h,d),ie(l,h,s),ie(C,E,s);for(u=0;u<16;u++)a[u+16]=l[u],a[u+32]=C[u],a[u+48]=h[u],a[u+64]=E[u];var L=a.subarray(32),ae=a.subarray(16);return Nt(L,L),Q(ae,ae,L),Ae(n,ae),0}g(me,"crypto_scalarmult");function ve(n,o){return me(n,o,y)}g(ve,"crypto_scalarmult_base");function Ot(n,o){return c(o,32),ve(n,o)}g(Ot,"crypto_box_keypair");function Fe(n,o,A){var I=new Uint8Array(32);return me(I,A,o),Ue(n,f,I,he)}g(Fe,"crypto_box_beforenm");var Jt=nt,$r=it;function en(n,o,A,I,a,s){var u=new Uint8Array(32);return Fe(u,a,s),Jt(n,o,A,I,u)}g(en,"crypto_box");function tn(n,o,A,I,a,s){var u=new Uint8Array(32);return Fe(u,a,s),$r(n,o,A,I,u)}g(tn,"crypto_box_open");function Ce(){var n=0,o=0,A=0,I=0,a=65535,s,u,l;for(l=0;l>>16,A+=u&a,I+=u>>>16;return o+=n>>>16,A+=o>>>16,I+=A>>>16,new t(A&a|I<<16,n&a|o<<16)}g(Ce,"add64");function jt(n,o){return new t(n.hi>>>o,n.lo>>>o|n.hi<<32-o)}g(jt,"shr64");function Pe(){var n=0,o=0,A;for(A=0;A>>o|n.lo<>>o|n.hi<>>o|n.hi<>>o|n.lo<=128;){for(h=0;h<16;h++)u[h]=Pt(o,8*h+E);for(h=0;h<80;h++){for(C=0;C<8;C++)a[C]=s[C];for(l=Ce(s[7],on(s[4]),rn(s[4],s[5],s[6]),gn[h],u[h%16]),a[7]=Ce(l,An(s[0]),nn(s[0],s[1],s[2])),a[3]=Ce(a[3],l),C=0;C<8;C++)s[(C+1)%8]=a[C];if(h%16===15)for(C=0;C<16;C++)u[C]=Ce(u[C],u[(C+9)%16],In(u[(C+1)%16]),an(u[(C+14)%16]))}for(h=0;h<8;h++)s[h]=Ce(s[h],I[h]),I[h]=s[h];E+=128,A-=128}for(h=0;h<8;h++)Kt(n,8*h,I[h]);return A}g(Xt,"crypto_hashblocks");let ue=g((n,o)=>r(o).update(n).digest(),"crypto_hash_blake2b");var cn=new Uint8Array([106,9,230,103,243,188,201,8,187,103,174,133,132,202,167,59,60,110,243,114,254,148,248,43,165,79,245,58,95,29,54,241,81,14,82,127,173,230,130,209,155,5,104,140,43,62,108,31,31,131,217,171,251,65,189,107,91,224,205,25,19,126,33,121]);function ot(n,o,A){var I=new Uint8Array(64),a=new Uint8Array(256),s,u=A;for(s=0;s<64;s++)I[s]=cn[s];for(Xt(I,o,A),A%=128,s=0;s<256;s++)a[s]=0;for(s=0;s=0;--a)I=A[a/8|0]>>(a&7)&1,qt(n,o,I),Ke(o,n),Ke(n,n),qt(n,o,I)}g(It,"scalarmult");function le(n,o){var A=[i(),i(),i(),i()];N(A[0],m),N(A[1],j),N(A[2],x),Q(A[3],m,j),It(n,A,o)}g(le,"scalarbase");function at(n,o,A){var I=new Uint8Array(64),a=[i(),i(),i(),i()],s;A||c(o,32);I=ue(o,64),I[0]&=248,I[31]&=127,I[31]|=64,le(a,I),ke(n,a);return 0}g(at,"crypto_sign_keypair");var Ye=new Float64Array([237,211,245,92,26,99,18,88,214,156,247,162,222,249,222,20,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16]);function gt(n,o){var A,I,a,s;for(I=63;I>=32;--I){for(A=0,a=I-32,s=I-12;a>4)*Ye[a],A=o[a]>>8,o[a]&=255;for(a=0;a<32;a++)o[a]-=A*Ye[a];for(I=0;I<32;I++)o[I+1]+=o[I]>>8,n[I]=o[I]&255}g(gt,"modL");function ct(n){var o=new Float64Array(64),A;for(A=0;A<64;A++)o[A]=n[A];for(A=0;A<64;A++)n[A]=0;gt(n,o)}g(ct,"reduce");function Wt(n,o,A,I){var a=new Uint8Array(64),s=new Uint8Array(64),u=new Uint8Array(64),l,h,C=new Float64Array(64),E=[i(),i(),i(),i()];let d=er(I);a=ue(I,64),a[0]&=248,a[31]&=127,a[31]|=64;var p=A+64;for(l=0;l>7&&H(n[0],w,n[0]),Q(n[3],n[0],n[1]),0)}g(sn,"unpackneg");function st(n,o,A,I){var a,s=new Uint8Array(32),u=new Uint8Array(64),l=[i(),i(),i(),i()],h=[i(),i(),i(),i()];if(A<64||sn(h,I))return-1;for(a=0;a=0};function er(n){let o=new Uint8Array(64),A=[i(),i(),i(),i()],I,a=new Uint8Array(32);return o=ue(n,64),o[0]&=248,o[31]&=127,o[31]|=64,le(A,o),ke(a,A),a}g(er,"derivePublicFromSecret"),e.sign.keyPair=function(){var n=new Uint8Array(z),o=new Uint8Array(Ie);return at(n,o),{publicKey:n,secretKey:o}},e.sign.keyPair.fromSecretKey=function(n){if(P(n),n.length!==Ie)throw new Error("bad secret key size");var o=new Uint8Array(z);return o=er(n),{publicKey:o,secretKey:new Uint8Array(n)}},e.sign.keyPair.fromSeed=function(n){if(P(n),n.length!==Ct)throw new Error("bad seed size");for(var o=new Uint8Array(z),A=new Uint8Array(Ie),I=0;I<32;I++)A[I]=n[I];return at(o,A,!0),{publicKey:o,secretKey:A}},e.sign.publicKeyLength=z,e.sign.secretKeyLength=Ie,e.sign.seedLength=Ct,e.sign.signatureLength=T,e.hash=function(n){P(n);var o=new Uint8Array(ut);return ot(o,n,n.length),o},e.hash.hashLength=ut,e.verify=function(n,o){return P(n,o),n.length===0||o.length===0||n.length!==o.length?!1:ze(n,0,o,0,n.length)===0},e.setPRNG=function(n){c=n},function(){var n=typeof self<"u"?self.crypto||self.msCrypto:null;if(n&&n.getRandomValues){var o=65536;e.setPRNG(function(A,I){var a,s=new Uint8Array(I);for(a=0;aqr,get_address_from_public_key:()=>_e,get_private_key_from_seed:()=>_t,get_public_key_from_address:()=>pe,get_public_key_from_private_key:()=>je,hash_block:()=>te,hex_to_uint8array:()=>D,int_to_uint8array:()=>jr,raw_to_whole:()=>bt,sign_block_hash:()=>re,sign_message:()=>pt,uint8array_to_base32:()=>dt,uint8array_to_hex:()=>ee,utf8_to_uint8array:()=>Wr,verify_block_hash:()=>pi,whole_to_raw:()=>De});var Je=rr(Jr()),Se=rr(Qt());var Qi="0000000000000000000000000000000000000000000000000000000000000006",di="62616E616E6F6D73672D",be=["0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"];function ee(e){let r="";for(let t=0;t0;f--)c-=t[r-f]*16**(2*(f-1));t[r-i]=Math.floor(c/16**(2*(i-1)))}return t}g(jr,"int_to_uint8array");var Xr=["1","3","4","5","6","7","8","9","a","b","c","d","e","f","g","h","i","j","k","m","n","o","p","q","r","s","t","u","w","x","y","z"];function dt(e){let r="";for(let t=0;t=5)y=e[c]>>w-5&31;else{let x=5-w;y=(e[c]<>8-x&2**(8-x)-1)}r+=Xr[y]}return r}g(dt,"uint8array_to_base32");function bi(e,r){let t="",i=e;for(let c=0;c=2**(r-1-c)?(t+="1",i-=2**(r-1-c)):t+="0";return t}g(bi,"int_to_binary");function _i(e){let r=0;for(let t=0;tbi(Xr.indexOf(i),5)).join(""),t=new Uint8Array(Math.ceil(e.length*5/8));for(let i=0;ir-i[1].length)throw Error(`Too many decimals, cannot exceed ${r}`);t=BigInt(i[0])*BigInt(10)**BigInt(r)+BigInt(i[1])*BigInt(10)**BigInt(r-i[1].length)}else t=BigInt(e)*BigInt(10)**BigInt(r);return t}g(De,"whole_to_raw");function bt(e,r=zr){let t=e.toString(),i;if(t.length>r)i=t.slice(0,-r)+"."+t.slice(-r);else{let f=r-t.length;i="0."+"0".repeat(f>0?f:0)+t}let c=i.length;for(let f=0;fqe,RPCWithBackup:()=>St});var qe=class{constructor(r,t=!1){this.DECIMALS=void 0;this.debug=!1;this.rpc_url=r,this.use_pending=t}static{g(this,"RPC")}async call(r){this.debug&&console.log(JSON.stringify(r));let t=await fetch(this.rpc_url,{method:"POST",headers:this.headers??{"Content-Type":"application/json"},body:JSON.stringify(r)});if(!t.ok&&this.debug&&console.log(await t.text()),!t.ok)throw Error(`Request to RPC node failed with status code ${t.status}`);let i=await t.json();if(i.error)throw Error(`RPC node response: ${i.error}`);return i}async get_block_count(){return await this.call({action:"block_count"})}async get_block_info(r){return await this.call({action:"block_info",hash:r,json_block:!0})}async get_blocks(r){return await this.call({action:"blocks",hashes:r,json_block:!0})}async get_blocks_info(r){return await this.call({action:"blocks_info",hashes:r,json_block:!0})}async get_representatives(){return await this.call({action:"representatives"})}async get_representatives_online(r){return await this.call({action:"representatives_online",weight:r?"true":void 0})}async get_account_history(r,t,i,c,f,y,w){return await this.call({action:"account_history",account:r,count:`${t}`,raw:i?"true":void 0,head:c,offset:f?`${f}`:void 0,reverse:y?"true":void 0,account_filter:w})}async get_account_info(r,t,i,c,f){return await this.call({action:"account_info",account:r,representative:i?"true":void 0,weight:c?"true":void 0,pending:f?"true":void 0})}async get_account_balance(r){return await this.call({action:"account_balance",account:r})}async get_accounts_balances(r){return await this.call({action:"accounts_balances",accounts:r})}async get_account_representative(r){return await this.call({action:"account_representative",account:r})}async get_accounts_representatives(r){return await this.call({action:"accounts_representatives",account:r})}async get_account_weight(r){return await this.call({action:"account_weight",account:r})}async get_account_receivable(r,t,i,c){return await this.call({action:this.use_pending?"pending":"receivable",account:r,count:t?`${t}`:void 0,threshold:i?De(i,this.DECIMALS).toString():void 0,source:c?"true":void 0})}async get_delegators(r,t,i,c){return await this.call({action:"delegators",account:r,threshold:t?`${t}`:void 0,count:i?`${i}`:void 0,start:c})}async get_delegators_count(r){return await this.call({action:"account_weight",account:r})}},St=class extends qe{static{g(this,"RPCWithBackup")}constructor(r,t,i=!1){if(r.length<2)throw Error("Must provide at least two RPC URLs");super(r[0],i),this.rpc_urls=r}async call(r){let t=0;for(;;)try{let i=await fetch(this.rpc_urls[t],{method:"POST",headers:this.headers??{"Content-Type":"application/json"},body:JSON.stringify(r),signal:AbortSignal.timeout(this.timeout)});if(!i.ok)throw Error(`Request to RPC node failed with status code ${i.status}`);let c=await i.json();if(c.error)throw Error(`RPC node response: ${c.error}`);return c}catch(i){if(!this.rpc_urls[++t])throw Error(i)}}};var mt={};Me(mt,{Wallet:()=>Ut});var Ut=class e{constructor(r,t,i=0,c=!1,f){this.add_do_work=!0;if(this.rpc=r,typeof t!="string"||t?.length!==64)throw Error("Seed needs to be 64 character (hex) string");this.seed=t,this.index=i,this.work_function=f}static{g(this,"Wallet")}static gen_random_wallet(r){let t=new Uint8Array(32);crypto.getRandomValues(t);let i=ee(t);return new e(r,i)}get private_key(){return _t(this.seed,this.index)}get public_key(){return je(this.private_key)}get address(){return _e(this.public_key)}async send_process(r,t){return(await this.rpc.call({action:"process",json_block:"true",subtype:t,block:r,do_work:!r.work&&this.add_do_work?!0:void 0})).hash}async send(r,t,i,c,f){let y=De(t,this.rpc.DECIMALS),w=f??await this.get_account_info(void 0,!0),x=pe(r);c||(c=w.representative);let b=BigInt(w.balance),_=b-y;if(_<0n)throw Error(`Insufficient funds to send. Cannot send more than balance; ie, Before balance (raw: ${b}) less than send amount (raw: ${y})`);let S={type:"state",account:this.address,previous:w.frontier,representative:c,balance:_.toString(),link:x,link_as_account:r},m=te(S),j;i&&(j=await this.work_function(m));let se=re(this.private_key,m),X={...S,signature:se,work:j};return await this.send_process(X,"send")}async send_all(r,t,i){let c=await this.get_account_info(void 0,!0);return await this.send(r,bt(BigInt(c.balance),this.rpc.DECIMALS),t,i,c)}async receive(r,t,i){let c=await this.rpc.get_block_info(r),f=0n;i||(i=this.address);let y;try{let m=await this.get_account_info(void 0,!0);y=m.frontier,i=m.representative,f=BigInt(m.balance)}catch{y="0".repeat(64)}let w={type:"state",account:this.address,previous:y,representative:i,balance:(f+BigInt(c.amount)).toString(),link:r},x=te(w),b;t&&(b=await this.work_function(x));let _=re(this.private_key,x),S={...w,signature:_,work:b};return await this.send_process(S,"receive")}async receive_all(r=20,t,i){let c=(await this.get_account_receivable(r,t,!0)).blocks,f,y,w;try{let b=await this.get_account_info(void 0,!0);f=b.frontier,y=b.representative,w=BigInt(b.balance)}catch{f="0".repeat(64),y=this.address,w=BigInt(0)}let x=[];for(let b of Object.keys(c)){let _=(w+BigInt(c[b].amount)).toString(),S={type:"state",account:this.address,previous:f,representative:y,balance:_,link:b},m=te(S),j;i&&(j=await this.work_function(m));let se=re(this.private_key,m),X={...S,signature:se,work:j};await this.send_process(X,"receive"),x.push(m),f=m,w=BigInt(_)}return x}async change_representative(r,t){let i=await this.get_account_info(),c={type:"state",account:this.address,previous:i.frontier,representative:r,balance:i.balance,link:"0".repeat(64)},f=te(c),y;t&&(y=await this.work_function(f));let w=re(this.private_key,f),x={...c,signature:w,work:y};return await this.send_process(x,"change")}async change_rep(r,t){return await this.change_representative(r,t)}async get_account_info(r,t,i,c){return await this.rpc.get_account_info(this.address,r,t,i,c)}async get_account_receivable(r,t,i){return await this.rpc.get_account_receivable(this.address,r,t,i)}sign_message(r){return pt(this.private_key,r)}};var Ft={};Me(Ft,{RPCWorkProvider:()=>vt});var vt=class{constructor(r){this.extra_payload={};this.rpc=r}static{g(this,"RPCWorkProvider")}async request_work(r){return(await this.rpc.call({action:"work_generate",hash:r,...this.extra_payload})).work}};window.banani={...Xe,...Dt,...mt,...Ft};})(); +(()=>{var ur=Object.create;var Le=Object.defineProperty;var lr=Object.getOwnPropertyDescriptor;var yr=Object.getOwnPropertyNames;var Er=Object.getPrototypeOf,wr=Object.prototype.hasOwnProperty;var c=(e,n)=>Le(e,"name",{value:n,configurable:!0}),tn=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(n,t)=>(typeof require<"u"?require:n)[t]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var M=(e,n)=>()=>(n||e((n={exports:{}}).exports,n),n.exports),Me=(e,n)=>{for(var t in n)Le(e,t,{get:n[t],enumerable:!0})},Br=(e,n,t,i)=>{if(n&&typeof n=="object"||typeof n=="function")for(let g of yr(n))!wr.call(e,g)&&g!==t&&Le(e,g,{get:()=>n[g],enumerable:!(i=lr(n,g))||i.enumerable});return e};var nn=(e,n,t)=>(t=e!=null?ur(Er(e)):{},Br(n||!e||!e.__esModule?Le(t,"default",{value:e,enumerable:!0}):t,e));var lt=M((Di,An)=>{An.exports=rn;var Ve=class extends Error{static{c(this,"AssertionError")}};Ve.prototype.name="AssertionError";function rn(e,n){if(!e){var t=new Ve(n);throw Error.captureStackTrace&&Error.captureStackTrace(t,rn),t}}c(rn,"assert")});var an=M((mi,In)=>{function on(e){return e.length}c(on,"byteLength");function xr(e){let n=e.byteLength,t="";for(let i=0;i{var ce="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",Z=new Uint8Array(256);for(let e=0;e1&&e.charCodeAt(n-1)===61&&n--,n*3>>>2}c(cn,"byteLength");function dr(e){let n=e.byteLength,t="";for(let i=0;i>2]+ce[(e[i]&3)<<4|e[i+1]>>4]+ce[(e[i+1]&15)<<2|e[i+2]>>6]+ce[e[i+2]&63];return n%3===2?t=t.substring(0,t.length-1)+"=":n%3===1&&(t=t.substring(0,t.length-2)+"=="),t}c(dr,"toString");function br(e,n,t=0,i=cn(n)){let g=Math.min(i,e.byteLength-t);for(let f=0,y=0;y>4,e[y++]=(x&15)<<4|b>>2,e[y++]=(b&3)<<6|_&63}return g}c(br,"write");gn.exports={byteLength:cn,toString:dr,write:br}});var un=M((Ki,Cn)=>{function fn(e){return e.length>>>1}c(fn,"byteLength");function _r(e){let n=e.byteLength;e=new DataView(e.buffer,e.byteOffset,n);let t="",i=0;for(let g=n-n%4;i=48&&e<=57)return e-48;if(e>=65&&e<=70)return e-65+10;if(e>=97&&e<=102)return e-97+10}c(hn,"hexValue")});var yn=M((Yi,ln)=>{function yt(e){let n=0;for(let t=0,i=e.length;t=55296&&g<=56319&&t+1=56320&&f<=57343){n+=4,t++;continue}}g<=127?n+=1:g<=2047?n+=2:n+=3}return n}c(yt,"byteLength");var Et;if(typeof TextDecoder<"u"){let e=new TextDecoder;Et=c(function(t){return e.decode(t)},"toString")}else Et=c(function(n){let t=n.byteLength,i="",g=0;for(;g0){let x=0;for(;x>b,b-=6;b>=0;)n[w++]=128|x>>b&63,b-=6;y+=x>=65536?2:1}return f},"write");ln.exports={byteLength:yt,toString:Et,write:wt}});var Bn=M((Hi,wn)=>{function En(e){return e.length*2}c(En,"byteLength");function Sr(e){let n=e.byteLength,t="";for(let i=0;i>8,b=w%256;e[t+y*2]=b,e[t+y*2+1]=x}return g}c(Dr,"write");wn.exports={byteLength:En,toString:Sr,write:Dr}});var _n=M((xt,bn)=>{var Ur=an(),mr=sn(),vr=un(),Fr=yn(),Pr=Bn(),Ge=new Uint8Array(Uint16Array.of(255).buffer)[0]===255;function xe(e){switch(e){case"ascii":return Ur;case"base64":return mr;case"hex":return vr;case"utf8":case"utf-8":case void 0:return Fr;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return Pr;default:throw new Error(`Unknown encoding: ${e}`)}}c(xe,"codecFor");function xn(e){return e instanceof Uint8Array}c(xn,"isBuffer");function Kr(e){try{return xe(e),!0}catch{return!1}}c(Kr,"isEncoding");function kr(e,n,t){let i=new Uint8Array(e);return n!==void 0&&xt.fill(i,n,0,i.byteLength,t),i}c(kr,"alloc");function Yr(e){return new Uint8Array(e)}c(Yr,"allocUnsafe");function Rr(e){return new Uint8Array(e)}c(Rr,"allocUnsafeSlow");function Hr(e,n){return xe(n).byteLength(e)}c(Hr,"byteLength");function Lr(e,n){if(e===n)return 0;let t=Math.min(e.byteLength,n.byteLength);e=new DataView(e.buffer,e.byteOffset,e.byteLength),n=new DataView(n.buffer,n.byteOffset,n.byteLength);let i=0;for(let g=t-t%4;if)return 1}return e.byteLength>n.byteLength?1:e.byteLengthg+f.byteLength,0));let t=new Uint8Array(n),i=0;for(let g of e){if(i+g.byteLength>t.byteLength){let f=g.subarray(0,t.byteLength-i);return t.set(f,i),t}t.set(g,i),i+=g.byteLength}return t}c(Mr,"concat");function Vr(e,n,t=0,i=0,g=e.byteLength){if(g>0&&g=e.byteLength)throw new RangeError("sourceStart is out of range");if(g<0)throw new RangeError("sourceEnd is out of range");t>=n.byteLength&&(t=n.byteLength),g>e.byteLength&&(g=e.byteLength),n.byteLength-t=e.byteLength){if(g)return-1;t=e.byteLength-1}else if(t<0)if(g)t=0;else return-1;if(typeof n=="string")n=Bt(n,i);else if(typeof n=="number")return n=n&255,g?e.indexOf(n,t):e.lastIndexOf(n,t);if(n.byteLength===0)return-1;if(g){let f=-1;for(let y=t;ye.byteLength&&(t=e.byteLength-n.byteLength);for(let f=t;f>=0;f--){let y=!0;for(let w=0;w=g||i<=t?"":(t<0&&(t=0),i>g&&(i=g),(t!==0||i{var gi=c((e,n)=>c(function(){return n||(0,e[Object.keys(e)[0]])((n={exports:{}}).exports,n),n.exports},"__require"),"__commonJS"),si=(()=>{for(var e=new Uint8Array(128),n=0;n<64;n++)e[n<26?n+65:n<52?n+71:n<62?n-4:n*4-205]=n;return t=>{for(var i=t.length,g=new Uint8Array((i-(t[i-1]=="=")-(t[i-2]=="="))*3/4|0),f=0,y=0;f>4,g[y++]=x<<4|b>>2,g[y++]=b<<6|_}return g}})(),hi=gi({"wasm-binary:./blake2b.wat"(e,n){n.exports=si("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")}}),fi=hi(),Ci=WebAssembly.compile(fi);pn.exports=async e=>(await WebAssembly.instantiate(await Ci,e)).exports});var kn=M((Oi,G)=>{var K=lt(),ui=_n(),J=null,Dn=typeof WebAssembly<"u"&&Sn()().then(e=>{J=e}),O=64,Ne=[];G.exports=v;var Un=G.exports.BYTES_MIN=16,mn=G.exports.BYTES_MAX=64,Ni=G.exports.BYTES=32,vn=G.exports.KEYBYTES_MIN=16,Fn=G.exports.KEYBYTES_MAX=64,Ti=G.exports.KEYBYTES=32,Pn=G.exports.SALTBYTES=16,Kn=G.exports.PERSONALBYTES=16;function v(e,n,t,i,g){if(!(this instanceof v))return new v(e,n,t,i,g);if(!J)throw new Error("WASM not loaded. Wait for Blake2b.ready(cb)");e||(e=32),g!==!0&&(K(e>=Un,"digestLength must be at least "+Un+", was given "+e),K(e<=mn,"digestLength must be at most "+mn+", was given "+e),n!=null&&(K(n instanceof Uint8Array,"key must be Uint8Array or Buffer"),K(n.length>=vn,"key must be at least "+vn+", was given "+n.length),K(n.length<=Fn,"key must be at least "+Fn+", was given "+n.length)),t!=null&&(K(t instanceof Uint8Array,"salt must be Uint8Array or Buffer"),K(t.length===Pn,"salt must be exactly "+Pn+", was given "+t.length)),i!=null&&(K(i instanceof Uint8Array,"personal must be Uint8Array or Buffer"),K(i.length===Kn,"personal must be exactly "+Kn+", was given "+i.length))),Ne.length||(Ne.push(O),O+=216),this.digestLength=e,this.finalized=!1,this.pointer=Ne.pop(),this._memory=new Uint8Array(J.memory.buffer),this._memory.fill(0,0,64),this._memory[0]=this.digestLength,this._memory[1]=n?n.length:0,this._memory[2]=1,this._memory[3]=1,t&&this._memory.set(t,32),i&&this._memory.set(i,48),this.pointer+216>this._memory.length&&this._realloc(this.pointer+216),J.blake2b_init(this.pointer,this.digestLength),n&&(this.update(n),this._memory.fill(0,O,O+n.length),this._memory[this.pointer+200]=128)}c(v,"Blake2b");v.prototype._realloc=function(e){J.memory.grow(Math.max(0,Math.ceil(Math.abs(e-this._memory.length)/65536))),this._memory=new Uint8Array(J.memory.buffer)};v.prototype.update=function(e){return K(this.finalized===!1,"Hash instance finalized"),K(e instanceof Uint8Array,"input must be Uint8Array or Buffer"),O+e.length>this._memory.length&&this._realloc(O+e.length),this._memory.set(e,O),J.blake2b_update(this.pointer,O,O+e.length),this};v.prototype.digest=function(e){if(K(this.finalized===!1,"Hash instance finalized"),this.finalized=!0,Ne.push(this.pointer),J.blake2b_final(this.pointer),!e||e==="binary")return this._memory.slice(this.pointer+128,this.pointer+128+this.digestLength);if(typeof e=="string")return ui.toString(this._memory,e,this.pointer+128,this.pointer+128+this.digestLength);K(e instanceof Uint8Array&&e.length>=this.digestLength,"input must be Uint8Array or Buffer");for(var n=0;ne(),e):e(new Error("WebAssembly not supported"))};v.prototype.ready=v.ready;v.prototype.getPartialHash=function(){return this._memory.slice(this.pointer,this.pointer+216)};v.prototype.setPartialHash=function(e){this._memory.set(e,this.pointer)};function li(){}c(li,"noop")});var Qt=M((qi,F)=>{var Y=lt(),de=kn();function Te(e,n,t){var i=e[n]+e[t],g=e[n+1]+e[t+1];i>=4294967296&&g++,e[n]=i,e[n+1]=g}c(Te,"ADD64AA");function Yn(e,n,t,i){var g=e[n]+t;t<0&&(g+=4294967296);var f=e[n+1]+i;g>=4294967296&&f++,e[n]=g,e[n+1]=f}c(Yn,"ADD64AC");function Nn(e,n){return e[n]^e[n+1]<<8^e[n+2]<<16^e[n+3]<<24}c(Nn,"B2B_GET32");function q(e,n,t,i,g,f){var y=Qe[g],w=Qe[g+1],x=Qe[f],b=Qe[f+1];Te(B,e,n),Yn(B,e,y,w);var _=B[i]^B[e],S=B[i+1]^B[e+1];B[i]=S,B[i+1]=_,Te(B,t,i),_=B[n]^B[t],S=B[n+1]^B[t+1],B[n]=_>>>24^S<<8,B[n+1]=S>>>24^_<<8,Te(B,e,n),Yn(B,e,x,b),_=B[i]^B[e],S=B[i+1]^B[e+1],B[i]=_>>>16^S<<16,B[i+1]=S>>>16^_<<16,Te(B,t,i),_=B[n]^B[t],S=B[n+1]^B[t+1],B[n]=S>>>31^_<<1,B[n+1]=_>>>31^S<<1}c(q,"B2B_G");var Tn=new Uint32Array([4089235720,1779033703,2227873595,3144134277,4271175723,1013904242,1595750129,2773480762,2917565137,1359893119,725511199,2600822924,4215389547,528734635,327033209,1541459225]),yi=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,14,10,4,8,9,15,13,6,1,12,0,2,11,7,5,3,11,8,12,0,5,2,15,13,10,14,3,6,7,1,9,4,7,9,3,1,13,12,11,14,2,6,5,10,4,0,15,8,9,0,5,7,2,4,10,15,14,1,11,12,6,8,3,13,2,12,6,10,0,11,8,3,4,13,7,5,15,14,1,9,12,5,1,15,14,13,4,10,0,7,6,3,9,2,8,11,13,11,7,14,12,1,3,9,5,0,15,4,8,6,2,10,6,15,14,9,11,3,0,8,12,2,13,7,1,4,10,5,10,2,8,4,7,6,1,5,15,11,9,14,3,12,13,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,14,10,4,8,9,15,13,6,1,12,0,2,11,7,5,3],U=new Uint8Array(yi.map(function(e){return e*2})),B=new Uint32Array(32),Qe=new Uint32Array(32);function On(e,n){var t=0;for(t=0;t<16;t++)B[t]=e.h[t],B[t+16]=Tn[t];for(B[24]=B[24]^e.t,B[25]=B[25]^e.t/4294967296,n&&(B[28]=~B[28],B[29]=~B[29]),t=0;t<32;t++)Qe[t]=Nn(e.b,4*t);for(t=0;t<12;t++)q(0,8,16,24,U[t*16+0],U[t*16+1]),q(2,10,18,26,U[t*16+2],U[t*16+3]),q(4,12,20,28,U[t*16+4],U[t*16+5]),q(6,14,22,30,U[t*16+6],U[t*16+7]),q(0,10,20,30,U[t*16+8],U[t*16+9]),q(2,12,22,24,U[t*16+10],U[t*16+11]),q(4,14,16,26,U[t*16+12],U[t*16+13]),q(6,8,18,28,U[t*16+14],U[t*16+15]);for(t=0;t<16;t++)e.h[t]=e.h[t]^B[t]^B[t+16]}c(On,"blake2bCompress");var W=new Uint8Array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]);function ge(e,n,t,i){W.fill(0),this.b=new Uint8Array(128),this.h=new Uint32Array(16),this.t=0,this.c=0,this.outlen=e,W[0]=e,n&&(W[1]=n.length),W[2]=1,W[3]=1,t&&W.set(t,32),i&&W.set(i,48);for(var g=0;g<16;g++)this.h[g]=Tn[g]^Nn(W,g*4);n&&(Jn(this,n),this.c=128)}c(ge,"Blake2b");ge.prototype.update=function(e){return Y(e instanceof Uint8Array,"input must be Uint8Array or Buffer"),Jn(this,e),this};ge.prototype.digest=function(e){var n=!e||e==="binary"||e==="hex"?new Uint8Array(this.outlen):e;return Y(n instanceof Uint8Array,'out must be "binary", "hex", Uint8Array, or Buffer'),Y(n.length>=this.outlen,"out must have at least outlen bytes of space"),Ei(this,n),e==="hex"?wi(n):n};ge.prototype.final=ge.prototype.digest;ge.ready=function(e){de.ready(function(){e()})};function Jn(e,n){for(var t=0;t>2]>>8*(t&3);return n}c(Ei,"blake2bFinal");function wi(e){for(var n="",t=0;t=Rn,"outlen must be at least "+Rn+", was given "+n),Y(n<=Hn,"outlen must be at most "+Hn+", was given "+n),t!=null&&(Y(t instanceof Uint8Array,"key must be Uint8Array or Buffer"),Y(t.length>=Ln,"key must be at least "+Ln+", was given "+t.length),Y(t.length<=Mn,"key must be at most "+Mn+", was given "+t.length)),i!=null&&(Y(i instanceof Uint8Array,"salt must be Uint8Array or Buffer"),Y(i.length===Vn,"salt must be exactly "+Vn+", was given "+i.length)),g!=null&&(Y(g instanceof Uint8Array,"personal must be Uint8Array or Buffer"),Y(g.length===Gn,"personal must be exactly "+Gn+", was given "+g.length))),new xi(n,t,i,g)},"createHash");F.exports.ready=function(e){de.ready(function(){e()})};F.exports.WASM_SUPPORTED=de.SUPPORTED;F.exports.WASM_LOADED=!1;var Rn=F.exports.BYTES_MIN=16,Hn=F.exports.BYTES_MAX=64,ji=F.exports.BYTES=32,Ln=F.exports.KEYBYTES_MIN=16,Mn=F.exports.KEYBYTES_MAX=64,Xi=F.exports.KEYBYTES=32,Vn=F.exports.SALTBYTES=16,Gn=F.exports.PERSONALBYTES=16;de.ready(function(e){e||(F.exports.WASM_LOADED=!0,F.exports=de)})});var jn=M((zi,Oe)=>{(function(e){"use strict";let n=Qt();var t=c(function(r,o){this.hi=r|0,this.lo=o|0},"u64"),i=c(function(r){var o,A=new Float64Array(16);if(r)for(o=0;o>>32-o}c(X,"L32");function re(r,o){var A=r[o+3]&255;return A=A<<8|r[o+2]&255,A=A<<8|r[o+1]&255,A<<8|r[o+0]&255}c(re,"ld32");function Pt(r,o){var A=r[o]<<24|r[o+1]<<16|r[o+2]<<8|r[o+3],I=r[o+4]<<24|r[o+5]<<16|r[o+6]<<8|r[o+7];return new t(A,I)}c(Pt,"dl64");function We(r,o,A){var I;for(I=0;I<4;I++)r[o+I]=A&255,A>>>=8}c(We,"st32");function Kt(r,o,A){r[o]=A.hi>>24&255,r[o+1]=A.hi>>16&255,r[o+2]=A.hi>>8&255,r[o+3]=A.hi&255,r[o+4]=A.lo>>24&255,r[o+5]=A.lo>>16&255,r[o+6]=A.lo>>8&255,r[o+7]=A.lo&255}c(Kt,"ts64");function ze(r,o,A,I,a){var s,u=0;for(s=0;s>>8)-1}c(ze,"vn");function kt(r,o,A,I){return ze(r,o,A,I,16)}c(kt,"crypto_verify_16");function Ze(r,o,A,I){return ze(r,o,A,I,32)}c(Ze,"crypto_verify_32");function Yt(r,o,A,I,a){var s=new Uint32Array(16),u=new Uint32Array(16),l=new Uint32Array(16),h=new Uint32Array(4),C,E,d;for(C=0;C<4;C++)u[5*C]=re(I,4*C),u[1+C]=re(A,4*C),u[6+C]=re(o,4*C),u[11+C]=re(A,16+4*C);for(C=0;C<16;C++)l[C]=u[C];for(C=0;C<20;C++){for(E=0;E<4;E++){for(d=0;d<4;d++)h[d]=u[(5*E+4*d)%16];for(h[1]^=X(h[0]+h[3]|0,7),h[2]^=X(h[1]+h[0]|0,9),h[3]^=X(h[2]+h[1]|0,13),h[0]^=X(h[3]+h[2]|0,18),d=0;d<4;d++)s[4*E+(E+d)%4]=h[d]}for(d=0;d<16;d++)u[d]=s[d]}if(a){for(C=0;C<16;C++)u[C]=u[C]+l[C]|0;for(C=0;C<4;C++)u[5*C]=u[5*C]-re(I,4*C)|0,u[6+C]=u[6+C]-re(o,4*C)|0;for(C=0;C<4;C++)We(r,4*C,u[5*C]),We(r,16+4*C,u[6+C])}else for(C=0;C<16;C++)We(r,4*C,u[C]+l[C]|0)}c(Yt,"core");function Rt(r,o,A,I){return Yt(r,o,A,I,!1),0}c(Rt,"crypto_core_salsa20");function Ue(r,o,A,I){return Yt(r,o,A,I,!0),0}c(Ue,"crypto_core_hsalsa20");var he=new Uint8Array([101,120,112,97,110,100,32,51,50,45,98,121,116,101,32,107]);function $e(r,o,A,I,a,s,u){var l=new Uint8Array(16),h=new Uint8Array(64),C,E;if(!a)return 0;for(E=0;E<16;E++)l[E]=0;for(E=0;E<8;E++)l[E]=s[E];for(;a>=64;){for(Rt(h,l,u,he),E=0;E<64;E++)r[o+E]=(A?A[I+E]:0)^h[E];for(C=1,E=8;E<16;E++)C=C+(l[E]&255)|0,l[E]=C&255,C>>>=8;a-=64,o+=64,A&&(I+=64)}if(a>0)for(Rt(h,l,u,he),E=0;E>>=8}c(tt,"add1305");var $n=new Uint32Array([5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,252]);function nt(r,o,A,I,a,s){var u,l,h,C,E=new Uint32Array(17),d=new Uint32Array(17),p=new Uint32Array(17),L=new Uint32Array(17),ae=new Uint32Array(17);for(h=0;h<17;h++)d[h]=p[h]=0;for(h=0;h<16;h++)d[h]=s[h];for(d[3]&=15,d[4]&=252,d[7]&=15,d[8]&=252,d[11]&=15,d[12]&=252,d[15]&=15;a>0;){for(h=0;h<17;h++)L[h]=0;for(h=0;h<16&&h>>=8;for(C=C+p[16]|0,p[16]=C&3,C=5*(C>>>2)|0,h=0;h<16;h++)C=C+p[h]|0,p[h]=C&255,C>>>=8;C=C+p[16]|0,p[16]=C}for(h=0;h<17;h++)ae[h]=p[h];for(tt(p,$n),u=-(p[16]>>>7)|0,h=0;h<17;h++)p[h]^=u&(ae[h]^p[h]);for(h=0;h<16;h++)L[h]=s[h+16];for(L[16]=0,tt(p,L),h=0;h<16;h++)r[o+h]=p[h];return 0}c(nt,"crypto_onetimeauth");function Mt(r,o,A,I,a,s){var u=new Uint8Array(16);return nt(u,0,A,I,a,s),kt(r,o,u,0)}c(Mt,"crypto_onetimeauth_verify");function rt(r,o,A,I,a){var s;if(A<32)return-1;for(et(r,0,o,0,A,I,a),nt(r,16,r,32,A-32,r),s=0;s<16;s++)r[s]=0;return 0}c(rt,"crypto_secretbox");function it(r,o,A,I,a){var s,u=new Uint8Array(32);if(A<32||(Lt(u,0,32,I,a),Mt(o,16,o,32,A-32,u)!==0))return-1;for(et(r,0,o,0,A,I,a),s=0;s<32;s++)r[s]=0;return 0}c(it,"crypto_secretbox_open");function N(r,o){var A;for(A=0;A<16;A++)r[A]=o[A]|0}c(N,"set25519");function fe(r){var o,A;for(A=0;A<16;A++)r[A]+=65536,o=Math.floor(r[A]/65536),r[(A+1)*(A<15?1:0)]+=o-1+37*(o-1)*(A===15?1:0),r[A]-=o*65536}c(fe,"car25519");function ie(r,o,A){for(var I,a=~(A-1),s=0;s<16;s++)I=a&(r[s]^o[s]),r[s]^=I,o[s]^=I}c(ie,"sel25519");function Ae(r,o){var A,I,a,s=i(),u=i();for(A=0;A<16;A++)u[A]=o[A];for(fe(u),fe(u),fe(u),I=0;I<2;I++){for(s[0]=u[0]-65517,A=1;A<15;A++)s[A]=u[A]-65535-(s[A-1]>>16&1),s[A-1]&=65535;s[15]=u[15]-32767-(s[14]>>16&1),a=s[15]>>16&1,s[14]&=65535,ie(u,s,1-a)}for(A=0;A<16;A++)r[2*A]=u[A]&255,r[2*A+1]=u[A]>>8}c(Ae,"pack25519");function Vt(r,o){var A=new Uint8Array(32),I=new Uint8Array(32);return Ae(A,r),Ae(I,o),Ze(A,0,I,0)}c(Vt,"neq25519");function Gt(r){var o=new Uint8Array(32);return Ae(o,r),o[0]&1}c(Gt,"par25519");function At(r,o){var A;for(A=0;A<16;A++)r[A]=o[2*A]+(o[2*A+1]<<8);r[15]&=32767}c(At,"unpack25519");function R(r,o,A){var I;for(I=0;I<16;I++)r[I]=o[I]+A[I]|0}c(R,"A");function H(r,o,A){var I;for(I=0;I<16;I++)r[I]=o[I]-A[I]|0}c(H,"Z");function Q(r,o,A){var I,a,s=new Float64Array(31);for(I=0;I<31;I++)s[I]=0;for(I=0;I<16;I++)for(a=0;a<16;a++)s[I+a]+=o[I]*A[a];for(I=0;I<15;I++)s[I]+=38*s[I+16];for(I=0;I<16;I++)r[I]=s[I];fe(r),fe(r)}c(Q,"M");function k(r,o){Q(r,o,o)}c(k,"S");function Nt(r,o){var A=i(),I;for(I=0;I<16;I++)A[I]=o[I];for(I=253;I>=0;I--)k(A,A),I!==2&&I!==4&&Q(A,A,o);for(I=0;I<16;I++)r[I]=A[I]}c(Nt,"inv25519");function Tt(r,o){var A=i(),I;for(I=0;I<16;I++)A[I]=o[I];for(I=250;I>=0;I--)k(A,A),I!==1&&Q(A,A,o);for(I=0;I<16;I++)r[I]=A[I]}c(Tt,"pow2523");function me(r,o,A){var I=new Uint8Array(32),a=new Float64Array(80),s,u,l=i(),h=i(),C=i(),E=i(),d=i(),p=i();for(u=0;u<31;u++)I[u]=o[u];for(I[31]=o[31]&127|64,I[0]&=248,At(a,A),u=0;u<16;u++)h[u]=a[u],E[u]=l[u]=C[u]=0;for(l[0]=E[0]=1,u=254;u>=0;--u)s=I[u>>>3]>>>(u&7)&1,ie(l,h,s),ie(C,E,s),R(d,l,C),H(l,l,C),R(C,h,E),H(h,h,E),k(E,d),k(p,l),Q(l,C,l),Q(C,h,d),R(d,l,C),H(l,l,C),k(h,l),H(C,E,p),Q(l,C,b),R(l,l,E),Q(C,C,l),Q(l,E,p),Q(E,h,a),k(h,d),ie(l,h,s),ie(C,E,s);for(u=0;u<16;u++)a[u+16]=l[u],a[u+32]=C[u],a[u+48]=h[u],a[u+64]=E[u];var L=a.subarray(32),ae=a.subarray(16);return Nt(L,L),Q(ae,ae,L),Ae(r,ae),0}c(me,"crypto_scalarmult");function ve(r,o){return me(r,o,y)}c(ve,"crypto_scalarmult_base");function Ot(r,o){return g(o,32),ve(r,o)}c(Ot,"crypto_box_keypair");function Fe(r,o,A){var I=new Uint8Array(32);return me(I,A,o),Ue(r,f,I,he)}c(Fe,"crypto_box_beforenm");var Jt=rt,er=it;function tr(r,o,A,I,a,s){var u=new Uint8Array(32);return Fe(u,a,s),Jt(r,o,A,I,u)}c(tr,"crypto_box");function nr(r,o,A,I,a,s){var u=new Uint8Array(32);return Fe(u,a,s),er(r,o,A,I,u)}c(nr,"crypto_box_open");function Ce(){var r=0,o=0,A=0,I=0,a=65535,s,u,l;for(l=0;l>>16,A+=u&a,I+=u>>>16;return o+=r>>>16,A+=o>>>16,I+=A>>>16,new t(A&a|I<<16,r&a|o<<16)}c(Ce,"add64");function jt(r,o){return new t(r.hi>>>o,r.lo>>>o|r.hi<<32-o)}c(jt,"shr64");function Pe(){var r=0,o=0,A;for(A=0;A>>o|r.lo<>>o|r.hi<>>o|r.hi<>>o|r.lo<=128;){for(h=0;h<16;h++)u[h]=Pt(o,8*h+E);for(h=0;h<80;h++){for(C=0;C<8;C++)a[C]=s[C];for(l=Ce(s[7],or(s[4]),rr(s[4],s[5],s[6]),cr[h],u[h%16]),a[7]=Ce(l,Ar(s[0]),ir(s[0],s[1],s[2])),a[3]=Ce(a[3],l),C=0;C<8;C++)s[(C+1)%8]=a[C];if(h%16===15)for(C=0;C<16;C++)u[C]=Ce(u[C],u[(C+9)%16],Ir(u[(C+1)%16]),ar(u[(C+14)%16]))}for(h=0;h<8;h++)s[h]=Ce(s[h],I[h]),I[h]=s[h];E+=128,A-=128}for(h=0;h<8;h++)Kt(r,8*h,I[h]);return A}c(Xt,"crypto_hashblocks");let ue=c((r,o)=>n(o).update(r).digest(),"crypto_hash_blake2b");var gr=new Uint8Array([106,9,230,103,243,188,201,8,187,103,174,133,132,202,167,59,60,110,243,114,254,148,248,43,165,79,245,58,95,29,54,241,81,14,82,127,173,230,130,209,155,5,104,140,43,62,108,31,31,131,217,171,251,65,189,107,91,224,205,25,19,126,33,121]);function ot(r,o,A){var I=new Uint8Array(64),a=new Uint8Array(256),s,u=A;for(s=0;s<64;s++)I[s]=gr[s];for(Xt(I,o,A),A%=128,s=0;s<256;s++)a[s]=0;for(s=0;s=0;--a)I=A[a/8|0]>>(a&7)&1,qt(r,o,I),Ke(o,r),Ke(r,r),qt(r,o,I)}c(It,"scalarmult");function le(r,o){var A=[i(),i(),i(),i()];N(A[0],m),N(A[1],j),N(A[2],x),Q(A[3],m,j),It(r,A,o)}c(le,"scalarbase");function at(r,o,A){var I=new Uint8Array(64),a=[i(),i(),i(),i()],s;A||g(o,32);I=ue(o,64),I[0]&=248,I[31]&=127,I[31]|=64,le(a,I),ke(r,a);return 0}c(at,"crypto_sign_keypair");var Ye=new Float64Array([237,211,245,92,26,99,18,88,214,156,247,162,222,249,222,20,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16]);function ct(r,o){var A,I,a,s;for(I=63;I>=32;--I){for(A=0,a=I-32,s=I-12;a>4)*Ye[a],A=o[a]>>8,o[a]&=255;for(a=0;a<32;a++)o[a]-=A*Ye[a];for(I=0;I<32;I++)o[I+1]+=o[I]>>8,r[I]=o[I]&255}c(ct,"modL");function gt(r){var o=new Float64Array(64),A;for(A=0;A<64;A++)o[A]=r[A];for(A=0;A<64;A++)r[A]=0;ct(r,o)}c(gt,"reduce");function Wt(r,o,A,I){var a=new Uint8Array(64),s=new Uint8Array(64),u=new Uint8Array(64),l,h,C=new Float64Array(64),E=[i(),i(),i(),i()];let d=en(I);a=ue(I,64),a[0]&=248,a[31]&=127,a[31]|=64;var p=A+64;for(l=0;l>7&&H(r[0],w,r[0]),Q(r[3],r[0],r[1]),0)}c(sr,"unpackneg");function st(r,o,A,I){var a,s=new Uint8Array(32),u=new Uint8Array(64),l=[i(),i(),i(),i()],h=[i(),i(),i(),i()];if(A<64||sr(h,I))return-1;for(a=0;a=0};function en(r){let o=new Uint8Array(64),A=[i(),i(),i(),i()],I,a=new Uint8Array(32);return o=ue(r,64),o[0]&=248,o[31]&=127,o[31]|=64,le(A,o),ke(a,A),a}c(en,"derivePublicFromSecret"),e.sign.keyPair=function(){var r=new Uint8Array(z),o=new Uint8Array(Ie);return at(r,o),{publicKey:r,secretKey:o}},e.sign.keyPair.fromSecretKey=function(r){if(P(r),r.length!==Ie)throw new Error("bad secret key size");var o=new Uint8Array(z);return o=en(r),{publicKey:o,secretKey:new Uint8Array(r)}},e.sign.keyPair.fromSeed=function(r){if(P(r),r.length!==Ct)throw new Error("bad seed size");for(var o=new Uint8Array(z),A=new Uint8Array(Ie),I=0;I<32;I++)A[I]=r[I];return at(o,A,!0),{publicKey:o,secretKey:A}},e.sign.publicKeyLength=z,e.sign.secretKeyLength=Ie,e.sign.seedLength=Ct,e.sign.signatureLength=T,e.hash=function(r){P(r);var o=new Uint8Array(ut);return ot(o,r,r.length),o},e.hash.hashLength=ut,e.verify=function(r,o){return P(r,o),r.length===0||o.length===0||r.length!==o.length?!1:ze(r,0,o,0,r.length)===0},e.setPRNG=function(r){g=r},function(){var r=typeof self<"u"?self.crypto||self.msCrypto:null;if(r&&r.getRandomValues){var o=65536;e.setPRNG(function(A,I){var a,s=new Uint8Array(I);for(a=0;aWn,get_address_from_public_key:()=>_e,get_private_key_from_seed:()=>_t,get_public_key_from_address:()=>pe,get_public_key_from_private_key:()=>je,hash_block:()=>te,hex_to_uint8array:()=>D,int_to_uint8array:()=>Xn,raw_to_whole:()=>bt,sign_block_hash:()=>ne,sign_message:()=>pt,uint8array_to_base32:()=>dt,uint8array_to_hex:()=>ee,utf8_to_uint8array:()=>zn,verify_block_hash:()=>pi,whole_to_raw:()=>De});var Je=nn(jn()),Se=nn(Qt());var Qi="0000000000000000000000000000000000000000000000000000000000000006",di="62616E616E6F6D73672D",be=["0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"];function ee(e){let n="";for(let t=0;t0;f--)g-=t[n-f]*16**(2*(f-1));t[n-i]=Math.floor(g/16**(2*(i-1)))}return t}c(Xn,"int_to_uint8array");var qn=["1","3","4","5","6","7","8","9","a","b","c","d","e","f","g","h","i","j","k","m","n","o","p","q","r","s","t","u","w","x","y","z"];function dt(e){let n="";for(let t=0;t=5)y=e[g]>>w-5&31;else{let x=5-w;y=(e[g]<>8-x&2**(8-x)-1)}n+=qn[y]}return n}c(dt,"uint8array_to_base32");function bi(e,n){let t="",i=e;for(let g=0;g=2**(n-1-g)?(t+="1",i-=2**(n-1-g)):t+="0";return t}c(bi,"int_to_binary");function _i(e){let n=0;for(let t=0;tbi(qn.indexOf(i),5)).join(""),t=new Uint8Array(Math.ceil(e.length*5/8));for(let i=0;in-i[1].length)throw Error(`Too many decimals, cannot exceed ${n}`);t=BigInt(i[0])*BigInt(10)**BigInt(n)+BigInt(i[1])*BigInt(10)**BigInt(n-i[1].length)}else t=BigInt(e)*BigInt(10)**BigInt(n);return t}c(De,"whole_to_raw");function bt(e,n=Zn){let t=e.toString(),i;if(t.length>n)i=t.slice(0,-n)+"."+t.slice(-n);else{let f=n-t.length;i="0."+"0".repeat(f>0?f:0)+t}let g=i.length;for(let f=0;fqe,RPCWithBackup:()=>St});var qe=class{constructor(n,t=!1){this.DECIMALS=void 0;this.debug=!1;this.rpc_url=n,this.use_pending=t}static{c(this,"RPC")}async call(n){this.debug&&console.log(JSON.stringify(n));let t=await fetch(this.rpc_url,{method:"POST",headers:this.headers??{"Content-Type":"application/json"},body:JSON.stringify(n)});if(!t.ok&&this.debug&&console.log(await t.text()),!t.ok)throw Error(`Request to RPC node failed with status code ${t.status}`);let i=await t.json();if(i.error)throw Error(`RPC node response: ${i.error}`);return i}async get_block_count(){return await this.call({action:"block_count"})}async get_block_info(n){return await this.call({action:"block_info",hash:n,json_block:!0})}async get_blocks(n){return await this.call({action:"blocks",hashes:n,json_block:!0})}async get_blocks_info(n){return await this.call({action:"blocks_info",hashes:n,json_block:!0})}async get_representatives(){return await this.call({action:"representatives"})}async get_representatives_online(n){return await this.call({action:"representatives_online",weight:n?"true":void 0})}async get_account_history(n,t,i,g,f,y,w){return await this.call({action:"account_history",account:n,count:`${t}`,raw:i?"true":void 0,head:g,offset:f?`${f}`:void 0,reverse:y?"true":void 0,account_filter:w})}async get_account_info(n,t,i,g,f){return await this.call({action:"account_info",account:n,representative:i?"true":void 0,weight:g?"true":void 0,pending:f?"true":void 0})}async get_account_balance(n){return await this.call({action:"account_balance",account:n})}async get_accounts_balances(n){return await this.call({action:"accounts_balances",accounts:n})}async get_account_representative(n){return await this.call({action:"account_representative",account:n})}async get_accounts_representatives(n){return await this.call({action:"accounts_representatives",account:n})}async get_account_weight(n){return await this.call({action:"account_weight",account:n})}async get_account_receivable(n,t,i,g){return await this.call({action:this.use_pending?"pending":"receivable",account:n,count:t?`${t}`:void 0,threshold:i?De(i,this.DECIMALS).toString():void 0,source:g?"true":void 0})}async get_delegators(n,t,i,g){return await this.call({action:"delegators",account:n,threshold:t?`${t}`:void 0,count:i?`${i}`:void 0,start:g})}async get_delegators_count(n){return await this.call({action:"account_weight",account:n})}},St=class extends qe{static{c(this,"RPCWithBackup")}constructor(n,t,i=!1){if(n.length<2)throw Error("Must provide at least two RPC URLs");super(n[0],i),this.rpc_urls=n}async call(n){let t=0;for(;;)try{let i=await fetch(this.rpc_urls[t],{method:"POST",headers:this.headers??{"Content-Type":"application/json"},body:JSON.stringify(n),signal:AbortSignal.timeout(this.timeout)});if(!i.ok)throw Error(`Request to RPC node failed with status code ${i.status}`);let g=await i.json();if(g.error)throw Error(`RPC node response: ${g.error}`);return g}catch(i){if(!this.rpc_urls[++t])throw Error(i)}}};var mt={};Me(mt,{Wallet:()=>Ut});var Ut=class e{constructor(n,t,i=0,g=!1,f){this.add_do_work=!0;if(this.rpc=n,typeof t!="string"||t?.length!==64)throw Error("Seed needs to be 64 character (hex) string");this.seed=t,this.index=i,this.work_function=f}static{c(this,"Wallet")}static gen_random_wallet(n){let t=new Uint8Array(32);crypto.getRandomValues(t);let i=ee(t);return new e(n,i)}get private_key(){return _t(this.seed,this.index)}get public_key(){return je(this.private_key)}get address(){return _e(this.public_key)}async send_process(n,t){return(await this.rpc.call({action:"process",json_block:"true",subtype:t,block:n,do_work:!n.work&&this.add_do_work?!0:void 0})).hash}async send(n,t,i,g,f){let y=De(t,this.rpc.DECIMALS),w=f??await this.get_account_info(void 0,!0),x=pe(n);g||(g=w.representative);let b=BigInt(w.balance),_=b-y;if(_<0n)throw Error(`Insufficient funds to send. Cannot send more than balance; ie, Before balance (raw: ${b}) less than send amount (raw: ${y})`);let S={type:"state",account:this.address,previous:w.frontier,representative:g,balance:_.toString(),link:x,link_as_account:n},m=te(S),j;i&&(j=await this.work_function(m));let se=ne(this.private_key,m),X={...S,signature:se,work:j};return await this.send_process(X,"send")}async send_all(n,t,i){let g=await this.get_account_info(void 0,!0);return await this.send(n,bt(BigInt(g.balance),this.rpc.DECIMALS),t,i,g)}async receive(n,t,i){let g=await this.rpc.get_block_info(n),f=0n;i||(i=this.address);let y;try{let m=await this.get_account_info(void 0,!0);y=m.frontier,i=m.representative,f=BigInt(m.balance)}catch{y="0".repeat(64)}let w={type:"state",account:this.address,previous:y,representative:i,balance:(f+BigInt(g.amount)).toString(),link:n},x=te(w),b;t&&(b=await this.work_function(x));let _=ne(this.private_key,x),S={...w,signature:_,work:b};return await this.send_process(S,"receive")}async receive_all(n=20,t,i){let g=(await this.get_account_receivable(n,t,!0)).blocks,f,y,w;try{let b=await this.get_account_info(void 0,!0);f=b.frontier,y=b.representative,w=BigInt(b.balance)}catch{f="0".repeat(64),y=this.address,w=BigInt(0)}let x=[];for(let b of Object.keys(g)){let _=(w+BigInt(g[b].amount)).toString(),S={type:"state",account:this.address,previous:f,representative:y,balance:_,link:b},m=te(S),j;i&&(j=await this.work_function(m));let se=ne(this.private_key,m),X={...S,signature:se,work:j};await this.send_process(X,"receive"),x.push(m),f=m,w=BigInt(_)}return x}async change_representative(n,t){let i=await this.get_account_info(),g={type:"state",account:this.address,previous:i.frontier,representative:n,balance:i.balance,link:"0".repeat(64)},f=te(g),y;t&&(y=await this.work_function(f));let w=ne(this.private_key,f),x={...g,signature:w,work:y};return await this.send_process(x,"change")}async change_rep(n,t){return await this.change_representative(n,t)}async get_account_info(n,t,i,g){return await this.rpc.get_account_info(this.address,n,t,i,g)}async get_account_receivable(n,t,i){return await this.rpc.get_account_receivable(this.address,n,t,i)}sign_message(n){return pt(this.private_key,n)}};var Ft={};Me(Ft,{RPCWorkProvider:()=>vt});var vt=class{constructor(n){this.extra_payload={};this.rpc=n}static{c(this,"RPCWorkProvider")}async request_work(n){return(await this.rpc.call({action:"work_generate",hash:n,...this.extra_payload})).work}};window.banani={...Xe,...Dt,...mt,...Ft};})(); //!!! BANANO CHANGE: we are replacing the below line with blake2b //!!! BANANO CHANGE: below line commented out //!!! BANANO CHANGE: Changed hashing to blake2b, and the derive pk thing diff --git a/browser-main.ts b/browser-main.ts index 1435826..c547d3a 100644 --- a/browser-main.ts +++ b/browser-main.ts @@ -5,4 +5,3 @@ import * as work from "./work"; //for browsers or whatever window.banani = { ...util, ...rpc, ...wallet, ...work }; - diff --git a/browser_test/index.html b/browser_test/index.html index 0544f6f..9f8a071 100644 --- a/browser_test/index.html +++ b/browser_test/index.html @@ -1,4 +1,4 @@ - + @@ -19,7 +19,7 @@ document.getElementById("block-count").textContent = JSON.stringify(await rpc.get_block_count()); })(); function unit_calc(event) { - const raw = window.banani.whole_to_raw(event.target.value) + const raw = window.banani.whole_to_raw(event.target.value); document.getElementById("units").textContent = raw + "\n" + window.banani.raw_to_whole(raw); } let random_wallet = window.banani.Wallet.gen_random_wallet(rpc); @@ -28,9 +28,9 @@ console.log("privkey", prk); let puk = window.banani.get_public_key_from_private_key(prk); console.log("pubkey", puk); - let address = window.banani.get_address_from_public_key(puk); + let address = window.banani.get_address_from_public_key(puk); console.log(address); - console.log(window.banani.get_public_key_from_address(address)) + console.log(window.banani.get_public_key_from_address(address)); console.log("pubkey matches (to/from)", window.banani.get_public_key_from_address(address) === puk); console.log("message signature", random_wallet.sign_message("test message\ntest test")); diff --git a/docs/assets/highlight.css b/docs/assets/highlight.css index ad81803..5337699 100644 --- a/docs/assets/highlight.css +++ b/docs/assets/highlight.css @@ -15,20 +15,22 @@ --dark-hl-6: #CE9178; --light-hl-7: #0000FF; --dark-hl-7: #569CD6; - --light-hl-8: #795E26; - --dark-hl-8: #DCDCAA; - --light-hl-9: #A31515; - --dark-hl-9: #CE9178; - --light-hl-10: #AF00DB; - --dark-hl-10: #C586C0; - --light-hl-11: #098658; - --dark-hl-11: #B5CEA8; - --light-hl-12: #008000; - --dark-hl-12: #6A9955; - --light-hl-13: #EE0000; - --dark-hl-13: #D7BA7D; - --light-hl-14: #000000; - --dark-hl-14: #C8C8C8; + --light-hl-8: #0070C1; + --dark-hl-8: #4FC1FF; + --light-hl-9: #795E26; + --dark-hl-9: #DCDCAA; + --light-hl-10: #A31515; + --dark-hl-10: #CE9178; + --light-hl-11: #AF00DB; + --dark-hl-11: #C586C0; + --light-hl-12: #098658; + --dark-hl-12: #B5CEA8; + --light-hl-13: #008000; + --dark-hl-13: #6A9955; + --light-hl-14: #EE0000; + --dark-hl-14: #D7BA7D; + --light-hl-15: #000000; + --dark-hl-15: #C8C8C8; --light-code-background: #FFFFFF; --dark-code-background: #1E1E1E; } @@ -49,6 +51,7 @@ --hl-12: var(--light-hl-12); --hl-13: var(--light-hl-13); --hl-14: var(--light-hl-14); + --hl-15: var(--light-hl-15); --code-background: var(--light-code-background); } } @@ -68,6 +71,7 @@ --hl-12: var(--dark-hl-12); --hl-13: var(--dark-hl-13); --hl-14: var(--dark-hl-14); + --hl-15: var(--dark-hl-15); --code-background: var(--dark-code-background); } } @@ -87,6 +91,7 @@ --hl-12: var(--light-hl-12); --hl-13: var(--light-hl-13); --hl-14: var(--light-hl-14); + --hl-15: var(--light-hl-15); --code-background: var(--light-code-background); } @@ -106,6 +111,7 @@ --hl-12: var(--dark-hl-12); --hl-13: var(--dark-hl-13); --hl-14: var(--dark-hl-14); + --hl-15: var(--dark-hl-15); --code-background: var(--dark-code-background); } @@ -124,4 +130,5 @@ .hl-12 { color: var(--hl-12); } .hl-13 { color: var(--hl-13); } .hl-14 { color: var(--hl-14); } +.hl-15 { color: var(--hl-15); } pre, code { background: var(--code-background); } diff --git a/docs/classes/RPC.html b/docs/classes/RPC.html index 07e7838..7088d52 100644 --- a/docs/classes/RPC.html +++ b/docs/classes/RPC.html @@ -1,5 +1,5 @@ RPC | banani

Class RPC

Sends RPC requests to the RPC node, also has wrappers for actions that only read the network (write actions are handled by the Wallet class)

-

Hierarchy (view full)

Implements

Constructors

Hierarchy (view full)

Implements

Constructors

  • Parameters

    • rpc_url: string
    • Optional use_pending: boolean = false

      If true, uses "pending" instead of "receivable" in RPC action names, for compatibility with older versions of the node

      -

    Returns RPC

Properties

DECIMALS: any = undefined
debug: boolean = false
headers: Record<string, string>

HTTP headers to send with any RPC requests, defaults to { "Content-Type": "application/json" }

-
rpc_url: string
use_pending: boolean

Methods

  • The function that sends the RPC POST request

    -

    Parameters

    • payload: Record<string, any>

    Returns Promise<Record<string, any>>

\ No newline at end of file +

Returns RPC

Properties

DECIMALS: any = undefined
debug: boolean = false
headers: Record<string, string>

HTTP headers to send with any RPC requests, defaults to { "Content-Type": "application/json" }

+
rpc_url: string
use_pending: boolean

Methods

  • The function that sends the RPC POST request

    +

    Parameters

    • payload: Record<string, any>

    Returns Promise<Record<string, any>>

\ No newline at end of file diff --git a/docs/classes/RPCWithBackup.html b/docs/classes/RPCWithBackup.html index fb27ac6..dcdac71 100644 --- a/docs/classes/RPCWithBackup.html +++ b/docs/classes/RPCWithBackup.html @@ -1,5 +1,5 @@ RPCWithBackup | banani

Class RPCWithBackup

Sends RPC requests to the RPC node, also has wrappers for actions that only read the network (write actions are handled by the Wallet class)

-

Hierarchy (view full)

  • RPC
    • RPCWithBackup

Constructors

Hierarchy (view full)

  • RPC
    • RPCWithBackup

Constructors

  • Parameters

    • rpc_urls: string[]
    • Optional timeout: number

      Request to RPC timeout, in milliseconds. If RPC request fails or timeouts, tries the next RPC

      -
    • use_pending: boolean = false

    Returns RPCWithBackup

Properties

DECIMALS: any = undefined
debug: boolean = false
headers: Record<string, string>

HTTP headers to send with any RPC requests, defaults to { "Content-Type": "application/json" }

-
rpc_url: string
rpc_urls: string[]
timeout: number
use_pending: boolean

Methods

  • The function that sends the RPC POST request

    -

    Parameters

    • payload: Record<string, any>

    Returns Promise<Record<string, any>>

\ No newline at end of file +
  • use_pending: boolean = false
  • Returns RPCWithBackup

    Properties

    DECIMALS: any = undefined
    debug: boolean = false
    headers: Record<string, string>

    HTTP headers to send with any RPC requests, defaults to { "Content-Type": "application/json" }

    +
    rpc_url: string
    rpc_urls: string[]
    timeout: number
    use_pending: boolean

    Methods

    • The function that sends the RPC POST request

      +

      Parameters

      • payload: Record<string, any>

      Returns Promise<Record<string, any>>

    \ No newline at end of file diff --git a/docs/classes/RPCWorkProvider.html b/docs/classes/RPCWorkProvider.html index 38ad68b..b0cf6d2 100644 --- a/docs/classes/RPCWorkProvider.html +++ b/docs/classes/RPCWorkProvider.html @@ -1,6 +1,6 @@ -RPCWorkProvider | banani

    Class RPCWorkProvider

    Constructors

    constructor +RPCWorkProvider | banani

    Class RPCWorkProvider

    Constructors

    Properties

    Methods

    Constructors

    Properties

    extra_payload: Record<string, any> = {}

    Extra json to send with the rpc payload. Needed for rpc.nano.to's work_generate, unfortunately

    -
    rpc: RPC

    Methods

    • Parameters

      • block_hash: string

      Returns Promise<string>

    \ No newline at end of file +

    Constructors

    Properties

    extra_payload: Record<string, any> = {}

    Extra json to send with the rpc payload. Needed for rpc.nano.to's work_generate, unfortunately

    +
    rpc: RPC

    Methods

    • Parameters

      • block_hash: string

      Returns Promise<string>

    \ No newline at end of file diff --git a/docs/classes/Wallet.html b/docs/classes/Wallet.html index 3b60b11..52b1f4e 100644 --- a/docs/classes/Wallet.html +++ b/docs/classes/Wallet.html @@ -1,5 +1,5 @@ Wallet | banani

    Class Wallet

    Wallets are created from seeds, so they can have multiple addresses by changing the index. Use Wallets to "write" (send, receive, change rep) to the network

    -

    Constructors

    Constructors

    Properties

    Constructors

    • Parameters

      • rpc: RPCInterface
      • Optional seed: string

        Seed for the wallet from which private keys are derived. 64 character hex string (32 bytes)

        -
      • index: number = 0
      • try_work: boolean = false
      • Optional work_function: WorkFunction

      Returns Wallet

    Properties

    add_do_work: boolean = true
    index: number

    Seed index. Seeds can have multiple private keys and addresses

    -
    seed: string
    try_work: boolean
    work_function?: WorkFunction

    Accessors

    • get address(): `ban_${string}` | `nano_${string}`
    • Returns `ban_${string}` | `nano_${string}`

    • get private_key(): string
    • Returns string

    • get public_key(): string
    • Returns string

    Methods

    • Parameters

      • new_representative: `ban_${string}` | `nano_${string}`
      • Optional work: boolean

      Returns Promise<string>

    • Parameters

      • Optional new_representative: `ban_${string}` | `nano_${string}`

        banano address to change representative to

        +
      • index: number = 0
      • try_work: boolean = false
      • Optional work_function: WorkFunction

      Returns Wallet

    Properties

    add_do_work: boolean = true
    index: number

    Seed index. Seeds can have multiple private keys and addresses

    +
    seed: string
    try_work: boolean
    work_function?: WorkFunction

    Accessors

    • get address(): `ban_${string}` | `nano_${string}`
    • Returns `ban_${string}` | `nano_${string}`

    • get private_key(): string
    • Returns string

    • get public_key(): string
    • Returns string

    Methods

    • Parameters

      • new_representative: `ban_${string}` | `nano_${string}`
      • Optional work: boolean

      Returns Promise<string>

    • Parameters

      • Optional new_representative: `ban_${string}` | `nano_${string}`

        banano address to change representative to

      • Optional gen_work: boolean

        whether or not to call work function to generate work

        -

      Returns Promise<string>

    • Parameters

      • Optional include_confirmed: boolean
      • Optional representative: boolean
      • Optional weight: boolean
      • Optional pending: boolean

      Returns Promise<AccountInfoRPC>

    • Parameters

      • Optional block_hash: string

        send block to receive

        +

      Returns Promise<string>

    • Parameters

      • Optional include_confirmed: boolean
      • Optional representative: boolean
      • Optional weight: boolean
      • Optional pending: boolean

      Returns Promise<AccountInfoRPC>

    • Parameters

      • Optional block_hash: string

        send block to receive

      • Optional gen_work: boolean

        whether or not to call work function to generate work

      • Optional representative: `ban_${string}` | `nano_${string}`

        optionally provide a representative if you do not want to use the current representative receive bananos from a specific send block

        -

      Returns Promise<string>

    • Parameters

      • Optional count: number = 20

        Max amount of blocks to receive +

      Returns Promise<string>

    • Parameters

      • Optional count: number = 20

        Max amount of blocks to receive receive all (up to count and exceeding threshold if applicable) receivable blocks

      • Optional threshold: `${number}`

        Min amount of Banano to receive in whole

      • Optional gen_work: boolean

        whether or not to call work function to generate work Receive all receivable transactions (up to count, and over threshold

        -

      Returns Promise<string[]>

    • Parameters

      • Optional to: `ban_${string}` | `nano_${string}`

        address to send to

        +

      Returns Promise<string[]>

    • Parameters

      • Optional to: `ban_${string}` | `nano_${string}`

        address to send to

      • Optional amount: `${number}`

        amount in whole bananos to send

      • Optional gen_work: boolean

        whether or not to call work function to generate work

      • Optional representative: `ban_${string}` | `nano_${string}`

        optionally provide a representative if you do not want to use the current representative

      • Optional cached_account_info: AccountInfoRPC

        can save one rpc call in some cases. Mostly for internal use. Make sure that in the RPC call, "representative" is "true" Send Bananos

        -

      Returns Promise<string>

    • Parameters

      • to: `ban_${string}` | `nano_${string}`
      • Optional work: boolean
      • Optional representative: `ban_${string}` | `nano_${string}`

      Returns Promise<string>

    • Parameters

      • message: string

      Returns string

    \ No newline at end of file +

    Returns Promise<string>

    • Parameters

      • to: `ban_${string}` | `nano_${string}`
      • Optional work: boolean
      • Optional representative: `ban_${string}` | `nano_${string}`

      Returns Promise<string>

    • Parameters

      • message: string

      Returns string

    \ No newline at end of file diff --git a/docs/functions/base32_to_uint8array.html b/docs/functions/base32_to_uint8array.html index 4ace6ad..9806235 100644 --- a/docs/functions/base32_to_uint8array.html +++ b/docs/functions/base32_to_uint8array.html @@ -1 +1 @@ -base32_to_uint8array | banani

    Function base32_to_uint8array

    • Parameters

      • base32: string

      Returns Uint8Array

    \ No newline at end of file +base32_to_uint8array | banani

    Function base32_to_uint8array

    • Parameters

      • base32: string

      Returns Uint8Array

    \ No newline at end of file diff --git a/docs/functions/get_address_from_public_key.html b/docs/functions/get_address_from_public_key.html index df4923c..5c1f631 100644 --- a/docs/functions/get_address_from_public_key.html +++ b/docs/functions/get_address_from_public_key.html @@ -1 +1 @@ -get_address_from_public_key | banani

    Function get_address_from_public_key

    \ No newline at end of file +get_address_from_public_key | banani

    Function get_address_from_public_key

    \ No newline at end of file diff --git a/docs/functions/get_private_key_from_seed.html b/docs/functions/get_private_key_from_seed.html index 1e75e77..f27a4df 100644 --- a/docs/functions/get_private_key_from_seed.html +++ b/docs/functions/get_private_key_from_seed.html @@ -1 +1 @@ -get_private_key_from_seed | banani

    Function get_private_key_from_seed

    • Parameters

      • seed: string
      • index: number

      Returns string

    \ No newline at end of file +get_private_key_from_seed | banani

    Function get_private_key_from_seed

    • Parameters

      • seed: string
      • index: number

      Returns string

    \ No newline at end of file diff --git a/docs/functions/get_public_key_from_address.html b/docs/functions/get_public_key_from_address.html index 6f5ef1c..f0d1416 100644 --- a/docs/functions/get_public_key_from_address.html +++ b/docs/functions/get_public_key_from_address.html @@ -1 +1 @@ -get_public_key_from_address | banani

    Function get_public_key_from_address

    • Parameters

      • address: `ban_${string}` | `nano_${string}`

      Returns string

    \ No newline at end of file +get_public_key_from_address | banani

    Function get_public_key_from_address

    • Parameters

      • address: `ban_${string}` | `nano_${string}`

      Returns string

    \ No newline at end of file diff --git a/docs/functions/get_public_key_from_private_key.html b/docs/functions/get_public_key_from_private_key.html index 5157bcb..2e8514a 100644 --- a/docs/functions/get_public_key_from_private_key.html +++ b/docs/functions/get_public_key_from_private_key.html @@ -1 +1 @@ -get_public_key_from_private_key | banani

    Function get_public_key_from_private_key

    • Parameters

      • private_key: string

      Returns string

    \ No newline at end of file +get_public_key_from_private_key | banani

    Function get_public_key_from_private_key

    • Parameters

      • private_key: string

      Returns string

    \ No newline at end of file diff --git a/docs/functions/hash_block.html b/docs/functions/hash_block.html index 3b5e8d7..78fe6a3 100644 --- a/docs/functions/hash_block.html +++ b/docs/functions/hash_block.html @@ -1 +1 @@ -hash_block | banani

    Function hash_block

    \ No newline at end of file +hash_block | banani

    Function hash_block

    \ No newline at end of file diff --git a/docs/functions/hex_to_uint8array.html b/docs/functions/hex_to_uint8array.html index ee0b2c3..ff40236 100644 --- a/docs/functions/hex_to_uint8array.html +++ b/docs/functions/hex_to_uint8array.html @@ -1 +1 @@ -hex_to_uint8array | banani

    Function hex_to_uint8array

    • Parameters

      • hex: string

      Returns Uint8Array

    \ No newline at end of file +hex_to_uint8array | banani

    Function hex_to_uint8array

    • Parameters

      • hex: string

      Returns Uint8Array

    \ No newline at end of file diff --git a/docs/functions/int_to_uint8array.html b/docs/functions/int_to_uint8array.html index 1fb41a7..2085738 100644 --- a/docs/functions/int_to_uint8array.html +++ b/docs/functions/int_to_uint8array.html @@ -1 +1 @@ -int_to_uint8array | banani

    Function int_to_uint8array

    • Parameters

      • int: number
      • len: number

      Returns Uint8Array

    \ No newline at end of file +int_to_uint8array | banani

    Function int_to_uint8array

    • Parameters

      • int: number
      • len: number

      Returns Uint8Array

    \ No newline at end of file diff --git a/docs/functions/raw_to_whole.html b/docs/functions/raw_to_whole.html index 5879dec..93fa658 100644 --- a/docs/functions/raw_to_whole.html +++ b/docs/functions/raw_to_whole.html @@ -1,2 +1,2 @@ raw_to_whole | banani

    Function raw_to_whole

    • Turn raw Bananos (bigint) into whole Bananos (string)

      -

      Parameters

      • raw: bigint
      • decimals: number = BANANO_DECIMALS

      Returns Whole

    \ No newline at end of file +

    Parameters

    • raw: bigint
    • decimals: number = BANANO_DECIMALS

    Returns Whole

    \ No newline at end of file diff --git a/docs/functions/sign_block_hash.html b/docs/functions/sign_block_hash.html index 873a15a..e3c998c 100644 --- a/docs/functions/sign_block_hash.html +++ b/docs/functions/sign_block_hash.html @@ -1 +1 @@ -sign_block_hash | banani

    Function sign_block_hash

    • Parameters

      • private_key: string
      • block_hash: string

      Returns string

    \ No newline at end of file +sign_block_hash | banani

    Function sign_block_hash

    • Parameters

      • private_key: string
      • block_hash: string

      Returns string

    \ No newline at end of file diff --git a/docs/functions/sign_message.html b/docs/functions/sign_message.html index 9a7e64e..1eaa0f1 100644 --- a/docs/functions/sign_message.html +++ b/docs/functions/sign_message.html @@ -1,3 +1,3 @@ sign_message | banani

    Function sign_message

    • sign message by constructing a dummy block with the message (why not just sign the message itself instead of putting it in a dummy block? ledger support). This is already the standard across Banano services and wallets which support signing so please don't invent your own scheme

      Parameters

      • private_key: string
      • message: string
      • preamble: string = MESSAGE_PREAMBLE

      Returns string

      The signature in hex

      -
    \ No newline at end of file +
    \ No newline at end of file diff --git a/docs/functions/uint8array_to_base32.html b/docs/functions/uint8array_to_base32.html index 2eff9e2..270922f 100644 --- a/docs/functions/uint8array_to_base32.html +++ b/docs/functions/uint8array_to_base32.html @@ -1 +1 @@ -uint8array_to_base32 | banani

    Function uint8array_to_base32

    • Parameters

      • uint8array: Uint8Array

      Returns string

    \ No newline at end of file +uint8array_to_base32 | banani

    Function uint8array_to_base32

    • Parameters

      • uint8array: Uint8Array

      Returns string

    \ No newline at end of file diff --git a/docs/functions/uint8array_to_hex.html b/docs/functions/uint8array_to_hex.html index aadf419..7ad5656 100644 --- a/docs/functions/uint8array_to_hex.html +++ b/docs/functions/uint8array_to_hex.html @@ -1 +1 @@ -uint8array_to_hex | banani

    Function uint8array_to_hex

    • Parameters

      • uint8array: Uint8Array

      Returns string

    \ No newline at end of file +uint8array_to_hex | banani

    Function uint8array_to_hex

    • Parameters

      • uint8array: Uint8Array

      Returns string

    \ No newline at end of file diff --git a/docs/functions/utf8_to_uint8array.html b/docs/functions/utf8_to_uint8array.html index ccd6b38..58625cd 100644 --- a/docs/functions/utf8_to_uint8array.html +++ b/docs/functions/utf8_to_uint8array.html @@ -1 +1 @@ -utf8_to_uint8array | banani

    Function utf8_to_uint8array

    • Parameters

      • utf8: string

      Returns Uint8Array

    \ No newline at end of file +utf8_to_uint8array | banani

    Function utf8_to_uint8array

    • Parameters

      • utf8: string

      Returns Uint8Array

    \ No newline at end of file diff --git a/docs/functions/verify_block_hash.html b/docs/functions/verify_block_hash.html index 384de13..7b27122 100644 --- a/docs/functions/verify_block_hash.html +++ b/docs/functions/verify_block_hash.html @@ -1,2 +1,2 @@ verify_block_hash | banani

    Function verify_block_hash

    • Make sure the alleged signature for a block hash is valid

      -

      Parameters

      • public_key: string
      • signature: string
      • block_hash: string

      Returns boolean

    \ No newline at end of file +

    Parameters

    • public_key: string
    • signature: string
    • block_hash: string

    Returns boolean

    \ No newline at end of file diff --git a/docs/functions/whole_to_raw.html b/docs/functions/whole_to_raw.html index 748a380..5bbbfd3 100644 --- a/docs/functions/whole_to_raw.html +++ b/docs/functions/whole_to_raw.html @@ -1,2 +1,2 @@ whole_to_raw | banani

    Function whole_to_raw

    • Turn whole Bananos (string) into raw Bananos (bigint)

      -

      Parameters

      • whole: `${number}`
      • decimals: number = BANANO_DECIMALS

      Returns bigint

    \ No newline at end of file +

    Parameters

    • whole: `${number}`
    • decimals: number = BANANO_DECIMALS

    Returns bigint

    \ No newline at end of file diff --git a/docs/index.html b/docs/index.html index 6ef02a8..5eb0a8e 100644 --- a/docs/index.html +++ b/docs/index.html @@ -12,12 +12,12 @@ how to install banani on react.js

    Take a look in browser_test/index.html for an example.

    Documentation

    The docs are hosted at https://banani.prussia.dev (can also be accessed at https://stjet.github.io/banani/).

    Examples

    Banani allows you to send, receive, and change representative. If you are using Banani on the web, replace banani with window.banani.

    -
    let rpc = new banani.RPC("https://kaliumapi.appditto.com/api");

    console.log(await rpc.get_block_count());

    let wallet = new banani.Wallet(rpc, process.env.seed);

    let zero_index_address = wallet.address;

    wallet.index = 1;

    let send_hash = await wallet.send(zero_index_address, "1"); //send 1 banano

    wallet.index = 0;

    await wallet.receive(send_hash); //receive the bananos we just send (can also do `await wallet.receive_all()`)

    await wallet.change_rep("placeholder"); +
    const rpc = new banani.RPC("https://kaliumapi.appditto.com/api");

    console.log(await rpc.get_block_count());

    const wallet = new banani.Wallet(rpc, process.env.seed);

    const zero_index_address = wallet.address;

    wallet.index = 1;

    const send_hash = await wallet.send(zero_index_address, "1"); //send 1 banano

    wallet.index = 0;

    await wallet.receive(send_hash); //receive the bananos we just send (can also do `await wallet.receive_all()`)

    await wallet.change_rep("placeholder");

    Banani also comes with some useful utilities, and message signing:

    -
    let rpc = new banani.RPC("https://kaliumapi.appditto.com/api");
    let random_wallet = banani.Wallet.gen_random_wallet(rpc);

    console.log(banani.whole_to_raw("4.20069") === 420069000000000000000000000000n);
    console.log(random_wallet.sign_message("test message\ntest test")); +
    const rpc = new banani.RPC("https://kaliumapi.appditto.com/api");
    const random_wallet = banani.Wallet.gen_random_wallet(rpc);

    console.log(banani.whole_to_raw("4.20069") === 420069000000000000000000000000n);
    console.log(random_wallet.sign_message("test message\ntest test"));
    -

    Contributing

    git clone https://github.com/stjet/banani.git
    cd banani
    ...
    <make your changes with your favourite editor>
    ...
    npm run build +

    Contributing

    git clone https://github.com/stjet/banani.git
    cd banani
    ...
    <make your changes with your favourite editor>
    ...
    npm run build

    Then commit and push your changes.

    In most cases, you will only need to touch the typescript (.ts) files.

    diff --git a/docs/interfaces/AccountBalanceRPC.html b/docs/interfaces/AccountBalanceRPC.html index a6f366e..9cc1365 100644 --- a/docs/interfaces/AccountBalanceRPC.html +++ b/docs/interfaces/AccountBalanceRPC.html @@ -1,4 +1,4 @@ -AccountBalanceRPC | banani

    Interface AccountBalanceRPC

    interface AccountBalanceRPC {
        balance: `${number}`;
        pending: `${number}`;
        receivable?: `${number}`;
    }

    Properties

    balance +AccountBalanceRPC | banani

    Interface AccountBalanceRPC

    interface AccountBalanceRPC {
        balance: `${number}`;
        pending: `${number}`;
        receivable?: `${number}`;
    }

    Properties

    balance: `${number}`
    pending: `${number}`
    receivable?: `${number}`
    \ No newline at end of file +

    Properties

    balance: `${number}`
    pending: `${number}`
    receivable?: `${number}`
    \ No newline at end of file diff --git a/docs/interfaces/AccountHistoryBlock.html b/docs/interfaces/AccountHistoryBlock.html index 4f48ae3..b927ccd 100644 --- a/docs/interfaces/AccountHistoryBlock.html +++ b/docs/interfaces/AccountHistoryBlock.html @@ -1,8 +1,8 @@ -AccountHistoryBlock | banani

    Interface AccountHistoryBlock

    interface AccountHistoryBlock {
        account: `ban_${string}` | `nano_${string}`;
        amount: `${number}`;
        confirmed: boolean;
        hash: string;
        height: `${number}`;
        local_timestamp: `${number}`;
        type: BlockStateChangeTypes;
    }

    Properties

    account +AccountHistoryBlock | banani

    Interface AccountHistoryBlock

    interface AccountHistoryBlock {
        account: `ban_${string}` | `nano_${string}`;
        amount: `${number}`;
        confirmed: boolean;
        hash: string;
        height: `${number}`;
        local_timestamp: `${number}`;
        type: BlockStateChangeTypes;
    }

    Properties

    account: `ban_${string}` | `nano_${string}`
    amount: `${number}`
    confirmed: boolean
    hash: string
    height: `${number}`
    local_timestamp: `${number}`
    \ No newline at end of file +

    Properties

    account: `ban_${string}` | `nano_${string}`
    amount: `${number}`
    confirmed: boolean
    hash: string
    height: `${number}`
    local_timestamp: `${number}`
    \ No newline at end of file diff --git a/docs/interfaces/AccountHistoryRPC.html b/docs/interfaces/AccountHistoryRPC.html index cc96b5c..a7f2118 100644 --- a/docs/interfaces/AccountHistoryRPC.html +++ b/docs/interfaces/AccountHistoryRPC.html @@ -1,4 +1,4 @@ -AccountHistoryRPC | banani

    Interface AccountHistoryRPC

    interface AccountHistoryRPC {
        account: `ban_${string}` | `nano_${string}`;
        history: AccountHistoryBlock[];
        previous?: string;
    }

    Properties

    account +AccountHistoryRPC | banani

    Interface AccountHistoryRPC

    interface AccountHistoryRPC {
        account: `ban_${string}` | `nano_${string}`;
        history: AccountHistoryBlock[];
        previous?: string;
    }

    Properties

    account: `ban_${string}` | `nano_${string}`
    previous?: string
    \ No newline at end of file +

    Properties

    account: `ban_${string}` | `nano_${string}`
    previous?: string
    \ No newline at end of file diff --git a/docs/interfaces/AccountHistoryRawBlock.html b/docs/interfaces/AccountHistoryRawBlock.html index 12bda02..b5d34cc 100644 --- a/docs/interfaces/AccountHistoryRawBlock.html +++ b/docs/interfaces/AccountHistoryRawBlock.html @@ -1,4 +1,4 @@ -AccountHistoryRawBlock | banani

    Interface AccountHistoryRawBlock

    interface AccountHistoryRawBlock {
        account: `ban_${string}` | `nano_${string}`;
        amount: `${number}`;
        amount_decimal: `${number}`;
        balance: `${number}`;
        balance_decimal: `${number}`;
        confirmed: "false" | "true";
        hash: string;
        height: `${number}`;
        link: string;
        local_timestamp: `${number}`;
        previous: string;
        representative: `ban_${string}` | `nano_${string}`;
        signature: string;
        subtype: BlockSubtype;
        type: BlockAllTypes;
        work: string;
    }

    Properties

    account +AccountHistoryRawBlock | banani

    Interface AccountHistoryRawBlock

    interface AccountHistoryRawBlock {
        account: `ban_${string}` | `nano_${string}`;
        amount: `${number}`;
        amount_decimal: `${number}`;
        balance: `${number}`;
        balance_decimal: `${number}`;
        confirmed: "false" | "true";
        hash: string;
        height: `${number}`;
        link: string;
        local_timestamp: `${number}`;
        previous: string;
        representative: `ban_${string}` | `nano_${string}`;
        signature: string;
        subtype: BlockSubtype;
        type: BlockAllTypes;
        work: string;
    }

    Properties

    Properties

    account: `ban_${string}` | `nano_${string}`
    amount: `${number}`
    amount_decimal: `${number}`
    balance: `${number}`
    balance_decimal: `${number}`
    confirmed: "false" | "true"
    hash: string
    height: `${number}`
    link: string
    local_timestamp: `${number}`
    previous: string
    representative: `ban_${string}` | `nano_${string}`
    signature: string
    subtype: BlockSubtype
    work: string
    \ No newline at end of file +

    Properties

    account: `ban_${string}` | `nano_${string}`
    amount: `${number}`
    amount_decimal: `${number}`
    balance: `${number}`
    balance_decimal: `${number}`
    confirmed: "false" | "true"
    hash: string
    height: `${number}`
    link: string
    local_timestamp: `${number}`
    previous: string
    representative: `ban_${string}` | `nano_${string}`
    signature: string
    subtype: BlockSubtype
    work: string
    \ No newline at end of file diff --git a/docs/interfaces/AccountHistoryRawRPC.html b/docs/interfaces/AccountHistoryRawRPC.html index 4645c21..4ce4ab3 100644 --- a/docs/interfaces/AccountHistoryRawRPC.html +++ b/docs/interfaces/AccountHistoryRawRPC.html @@ -1,4 +1,4 @@ -AccountHistoryRawRPC | banani

    Interface AccountHistoryRawRPC

    interface AccountHistoryRawRPC {
        account: `ban_${string}` | `nano_${string}`;
        history: AccountHistoryRawBlock[];
        previous?: string;
    }

    Properties

    account +AccountHistoryRawRPC | banani

    Interface AccountHistoryRawRPC

    interface AccountHistoryRawRPC {
        account: `ban_${string}` | `nano_${string}`;
        history: AccountHistoryRawBlock[];
        previous?: string;
    }

    Properties

    account: `ban_${string}` | `nano_${string}`
    previous?: string
    \ No newline at end of file +

    Properties

    account: `ban_${string}` | `nano_${string}`
    previous?: string
    \ No newline at end of file diff --git a/docs/interfaces/AccountInfoRPC.html b/docs/interfaces/AccountInfoRPC.html index a693f73..5658dd6 100644 --- a/docs/interfaces/AccountInfoRPC.html +++ b/docs/interfaces/AccountInfoRPC.html @@ -1,4 +1,4 @@ -AccountInfoRPC | banani

    Interface AccountInfoRPC

    interface AccountInfoRPC {
        account_version: `${number}`;
        balance: `${number}`;
        block_count: `${number}`;
        confirmation_height?: `${number}`;
        confirmation_height_frontier?: string;
        confirmed_balance?: `${number}`;
        confirmed_frontier?: string;
        confirmed_height?: `${number}`;
        confirmed_pending?: `${number}`;
        confirmed_receivable?: `${number}`;
        confirmed_representative?: `ban_${string}` | `nano_${string}`;
        frontier: string;
        modified_timestamp: `${number}`;
        open_block: string;
        pending?: `${number}`;
        receivable?: `${number}`;
        representative?: `ban_${string}` | `nano_${string}`;
        representative_block: string;
        weight?: `${number}`;
    }

    Properties

    account_version +AccountInfoRPC | banani

    Interface AccountInfoRPC

    interface AccountInfoRPC {
        account_version: `${number}`;
        balance: `${number}`;
        block_count: `${number}`;
        confirmation_height?: `${number}`;
        confirmation_height_frontier?: string;
        confirmed_balance?: `${number}`;
        confirmed_frontier?: string;
        confirmed_height?: `${number}`;
        confirmed_pending?: `${number}`;
        confirmed_receivable?: `${number}`;
        confirmed_representative?: `ban_${string}` | `nano_${string}`;
        frontier: string;
        modified_timestamp: `${number}`;
        open_block: string;
        pending?: `${number}`;
        receivable?: `${number}`;
        representative?: `ban_${string}` | `nano_${string}`;
        representative_block: string;
        weight?: `${number}`;
    }

    Properties

    account_version: `${number}`
    balance: `${number}`
    block_count: `${number}`
    confirmation_height?: `${number}`
    confirmation_height_frontier?: string
    confirmed_balance?: `${number}`
    confirmed_frontier?: string
    confirmed_height?: `${number}`
    confirmed_pending?: `${number}`
    confirmed_receivable?: `${number}`
    confirmed_representative?: `ban_${string}` | `nano_${string}`
    frontier: string
    modified_timestamp: `${number}`
    open_block: string
    pending?: `${number}`
    receivable?: `${number}`
    representative?: `ban_${string}` | `nano_${string}`
    representative_block: string
    weight?: `${number}`
    \ No newline at end of file +

    Properties

    account_version: `${number}`
    balance: `${number}`
    block_count: `${number}`
    confirmation_height?: `${number}`
    confirmation_height_frontier?: string
    confirmed_balance?: `${number}`
    confirmed_frontier?: string
    confirmed_height?: `${number}`
    confirmed_pending?: `${number}`
    confirmed_receivable?: `${number}`
    confirmed_representative?: `ban_${string}` | `nano_${string}`
    frontier: string
    modified_timestamp: `${number}`
    open_block: string
    pending?: `${number}`
    receivable?: `${number}`
    representative?: `ban_${string}` | `nano_${string}`
    representative_block: string
    weight?: `${number}`
    \ No newline at end of file diff --git a/docs/interfaces/AccountReceivableRPC.html b/docs/interfaces/AccountReceivableRPC.html index 6342660..79b3987 100644 --- a/docs/interfaces/AccountReceivableRPC.html +++ b/docs/interfaces/AccountReceivableRPC.html @@ -1,2 +1,2 @@ -AccountReceivableRPC | banani

    Interface AccountReceivableRPC

    interface AccountReceivableRPC {
        blocks: string[];
    }

    Properties

    Properties

    blocks: string[]
    \ No newline at end of file +AccountReceivableRPC | banani

    Interface AccountReceivableRPC

    interface AccountReceivableRPC {
        blocks: string[];
    }

    Properties

    Properties

    blocks: string[]
    \ No newline at end of file diff --git a/docs/interfaces/AccountReceivableSourceRPC.html b/docs/interfaces/AccountReceivableSourceRPC.html index 6d86b1b..93af8d9 100644 --- a/docs/interfaces/AccountReceivableSourceRPC.html +++ b/docs/interfaces/AccountReceivableSourceRPC.html @@ -1,2 +1,2 @@ -AccountReceivableSourceRPC | banani

    Interface AccountReceivableSourceRPC

    interface AccountReceivableSourceRPC {
        blocks: Record<string, {
            amount: `${number}`;
            source: `ban_${string}` | `nano_${string}`;
        }>;
    }

    Properties

    Properties

    blocks: Record<string, {
        amount: `${number}`;
        source: `ban_${string}` | `nano_${string}`;
    }>

    Type declaration

    • amount: `${number}`
    • source: `ban_${string}` | `nano_${string}`
    \ No newline at end of file +AccountReceivableSourceRPC | banani

    Interface AccountReceivableSourceRPC

    interface AccountReceivableSourceRPC {
        blocks: Record<string, {
            amount: `${number}`;
            source: `ban_${string}` | `nano_${string}`;
        }>;
    }

    Properties

    Properties

    blocks: Record<string, {
        amount: `${number}`;
        source: `ban_${string}` | `nano_${string}`;
    }>

    Type declaration

    • amount: `${number}`
    • source: `ban_${string}` | `nano_${string}`
    \ No newline at end of file diff --git a/docs/interfaces/AccountReceivableThresholdRPC.html b/docs/interfaces/AccountReceivableThresholdRPC.html index 6109004..251b78d 100644 --- a/docs/interfaces/AccountReceivableThresholdRPC.html +++ b/docs/interfaces/AccountReceivableThresholdRPC.html @@ -1,2 +1,2 @@ -AccountReceivableThresholdRPC | banani

    Interface AccountReceivableThresholdRPC

    interface AccountReceivableThresholdRPC {
        blocks: Record<string, `${number}`>;
    }

    Properties

    Properties

    blocks: Record<string, `${number}`>
    \ No newline at end of file +AccountReceivableThresholdRPC | banani

    Interface AccountReceivableThresholdRPC

    interface AccountReceivableThresholdRPC {
        blocks: Record<string, `${number}`>;
    }

    Properties

    Properties

    blocks: Record<string, `${number}`>
    \ No newline at end of file diff --git a/docs/interfaces/AccountRepresentativeRPC.html b/docs/interfaces/AccountRepresentativeRPC.html index 711a518..2f61ab5 100644 --- a/docs/interfaces/AccountRepresentativeRPC.html +++ b/docs/interfaces/AccountRepresentativeRPC.html @@ -1,2 +1,2 @@ -AccountRepresentativeRPC | banani

    Interface AccountRepresentativeRPC

    interface AccountRepresentativeRPC {
        representative: `ban_${string}` | `nano_${string}`;
    }

    Properties

    Properties

    representative: `ban_${string}` | `nano_${string}`
    \ No newline at end of file +AccountRepresentativeRPC | banani

    Interface AccountRepresentativeRPC

    interface AccountRepresentativeRPC {
        representative: `ban_${string}` | `nano_${string}`;
    }

    Properties

    Properties

    representative: `ban_${string}` | `nano_${string}`
    \ No newline at end of file diff --git a/docs/interfaces/AccountWeightRPC.html b/docs/interfaces/AccountWeightRPC.html index 9f1eab6..534cc9c 100644 --- a/docs/interfaces/AccountWeightRPC.html +++ b/docs/interfaces/AccountWeightRPC.html @@ -1,2 +1,2 @@ -AccountWeightRPC | banani

    Interface AccountWeightRPC

    interface AccountWeightRPC {
        weight: `${number}`;
    }

    Properties

    Properties

    weight: `${number}`
    \ No newline at end of file +AccountWeightRPC | banani

    Interface AccountWeightRPC

    interface AccountWeightRPC {
        weight: `${number}`;
    }

    Properties

    Properties

    weight: `${number}`
    \ No newline at end of file diff --git a/docs/interfaces/AccountsBalancesRPC.html b/docs/interfaces/AccountsBalancesRPC.html index 6190022..bb28860 100644 --- a/docs/interfaces/AccountsBalancesRPC.html +++ b/docs/interfaces/AccountsBalancesRPC.html @@ -1,2 +1,2 @@ -AccountsBalancesRPC | banani

    Interface AccountsBalancesRPC

    interface AccountsBalancesRPC {
        balances: Record<`ban_${string}` | `nano_${string}`, AccountBalanceRPC>;
    }

    Properties

    Properties

    balances: Record<`ban_${string}` | `nano_${string}`, AccountBalanceRPC>
    \ No newline at end of file +AccountsBalancesRPC | banani

    Interface AccountsBalancesRPC

    interface AccountsBalancesRPC {
        balances: Record<`ban_${string}` | `nano_${string}`, AccountBalanceRPC>;
    }

    Properties

    Properties

    balances: Record<`ban_${string}` | `nano_${string}`, AccountBalanceRPC>
    \ No newline at end of file diff --git a/docs/interfaces/AccountsRepresentativesRPC.html b/docs/interfaces/AccountsRepresentativesRPC.html index ea7eda1..27896e8 100644 --- a/docs/interfaces/AccountsRepresentativesRPC.html +++ b/docs/interfaces/AccountsRepresentativesRPC.html @@ -1,2 +1,2 @@ -AccountsRepresentativesRPC | banani

    Interface AccountsRepresentativesRPC

    interface AccountsRepresentativesRPC {
        representatives: Record<`ban_${string}` | `nano_${string}`, `ban_${string}` | `nano_${string}`>;
    }

    Properties

    Properties

    representatives: Record<`ban_${string}` | `nano_${string}`, `ban_${string}` | `nano_${string}`>
    \ No newline at end of file +AccountsRepresentativesRPC | banani

    Interface AccountsRepresentativesRPC

    interface AccountsRepresentativesRPC {
        representatives: Record<`ban_${string}` | `nano_${string}`, `ban_${string}` | `nano_${string}`>;
    }

    Properties

    Properties

    representatives: Record<`ban_${string}` | `nano_${string}`, `ban_${string}` | `nano_${string}`>
    \ No newline at end of file diff --git a/docs/interfaces/Block.html b/docs/interfaces/Block.html index 122c301..7bfbdd5 100644 --- a/docs/interfaces/Block.html +++ b/docs/interfaces/Block.html @@ -1,4 +1,4 @@ -Block | banani

    Interface Block

    interface Block {
        account: `ban_${string}` | `nano_${string}`;
        balance: `${number}`;
        link: string;
        link_as_account?: `ban_${string}` | `nano_${string}`;
        previous: string;
        representative: `ban_${string}` | `nano_${string}`;
        signature: string;
        type: BlockAllTypes;
        work?: string;
    }

    Hierarchy (view full)

    Properties

    account +Block | banani

    Interface Block

    interface Block {
        account: `ban_${string}` | `nano_${string}`;
        balance: `${number}`;
        link: string;
        link_as_account?: `ban_${string}` | `nano_${string}`;
        previous: string;
        representative: `ban_${string}` | `nano_${string}`;
        signature: string;
        type: BlockAllTypes;
        work?: string;
    }

    Hierarchy (view full)

    Properties

    account: `ban_${string}` | `nano_${string}`
    balance: `${number}`
    link: string
    link_as_account?: `ban_${string}` | `nano_${string}`
    previous: string
    representative: `ban_${string}` | `nano_${string}`
    signature: string
    work?: string
    \ No newline at end of file +

    Properties

    account: `ban_${string}` | `nano_${string}`
    balance: `${number}`
    link: string
    link_as_account?: `ban_${string}` | `nano_${string}`
    previous: string
    representative: `ban_${string}` | `nano_${string}`
    signature: string
    work?: string
    \ No newline at end of file diff --git a/docs/interfaces/BlockCountRPC.html b/docs/interfaces/BlockCountRPC.html index 4e8b8f5..ed1436c 100644 --- a/docs/interfaces/BlockCountRPC.html +++ b/docs/interfaces/BlockCountRPC.html @@ -1,4 +1,4 @@ -BlockCountRPC | banani

    Interface BlockCountRPC

    interface BlockCountRPC {
        cemented?: `${number}`;
        count: `${number}`;
        unchecked: `${number}`;
    }

    Properties

    cemented? +BlockCountRPC | banani

    Interface BlockCountRPC

    interface BlockCountRPC {
        cemented?: `${number}`;
        count: `${number}`;
        unchecked: `${number}`;
    }

    Properties

    cemented?: `${number}`
    count: `${number}`
    unchecked: `${number}`
    \ No newline at end of file +

    Properties

    cemented?: `${number}`
    count: `${number}`
    unchecked: `${number}`
    \ No newline at end of file diff --git a/docs/interfaces/BlockInfoRPC.html b/docs/interfaces/BlockInfoRPC.html index 605db41..9030b17 100644 --- a/docs/interfaces/BlockInfoRPC.html +++ b/docs/interfaces/BlockInfoRPC.html @@ -1,4 +1,4 @@ -BlockInfoRPC | banani

    Interface BlockInfoRPC

    interface BlockInfoRPC {
        amount: `${number}`;
        balance: `${number}`;
        block_account: `ban_${string}` | `nano_${string}`;
        confirmed?: "false" | "true";
        contents: Block;
        height: `${number}`;
        subtype?: BlockSubtype;
        successor?: string;
        timestamp: `${number}`;
    }

    Properties

    amount +BlockInfoRPC | banani

    Interface BlockInfoRPC

    interface BlockInfoRPC {
        amount: `${number}`;
        balance: `${number}`;
        block_account: `ban_${string}` | `nano_${string}`;
        confirmed?: "false" | "true";
        contents: Block;
        height: `${number}`;
        subtype?: BlockSubtype;
        successor?: string;
        timestamp: `${number}`;
    }

    Properties

    amount: `${number}`
    balance: `${number}`
    block_account: `ban_${string}` | `nano_${string}`
    confirmed?: "false" | "true"
    contents: Block
    height: `${number}`
    subtype?: BlockSubtype
    successor?: string
    timestamp: `${number}`
    \ No newline at end of file +

    Properties

    amount: `${number}`
    balance: `${number}`
    block_account: `ban_${string}` | `nano_${string}`
    confirmed?: "false" | "true"
    contents: Block
    height: `${number}`
    subtype?: BlockSubtype
    successor?: string
    timestamp: `${number}`
    \ No newline at end of file diff --git a/docs/interfaces/BlockNoSignature.html b/docs/interfaces/BlockNoSignature.html index 35bbb07..5660ca7 100644 --- a/docs/interfaces/BlockNoSignature.html +++ b/docs/interfaces/BlockNoSignature.html @@ -1,8 +1,8 @@ -BlockNoSignature | banani

    Interface BlockNoSignature

    interface BlockNoSignature {
        account: `ban_${string}` | `nano_${string}`;
        balance: `${number}`;
        link: string;
        link_as_account?: `ban_${string}` | `nano_${string}`;
        previous: string;
        representative: `ban_${string}` | `nano_${string}`;
        type: BlockAllTypes;
    }

    Hierarchy (view full)

    Properties

    account +BlockNoSignature | banani

    Interface BlockNoSignature

    interface BlockNoSignature {
        account: `ban_${string}` | `nano_${string}`;
        balance: `${number}`;
        link: string;
        link_as_account?: `ban_${string}` | `nano_${string}`;
        previous: string;
        representative: `ban_${string}` | `nano_${string}`;
        type: BlockAllTypes;
    }

    Hierarchy (view full)

    Properties

    account: `ban_${string}` | `nano_${string}`
    balance: `${number}`
    link: string
    link_as_account?: `ban_${string}` | `nano_${string}`
    previous: string
    representative: `ban_${string}` | `nano_${string}`
    \ No newline at end of file +

    Properties

    account: `ban_${string}` | `nano_${string}`
    balance: `${number}`
    link: string
    link_as_account?: `ban_${string}` | `nano_${string}`
    previous: string
    representative: `ban_${string}` | `nano_${string}`
    \ No newline at end of file diff --git a/docs/interfaces/BlocksInfoRPC.html b/docs/interfaces/BlocksInfoRPC.html index d987f65..b9a4ab3 100644 --- a/docs/interfaces/BlocksInfoRPC.html +++ b/docs/interfaces/BlocksInfoRPC.html @@ -1,2 +1,2 @@ -BlocksInfoRPC | banani

    Interface BlocksInfoRPC

    interface BlocksInfoRPC {
        blocks: Record<string, BlockInfoRPC>;
    }

    Properties

    Properties

    blocks: Record<string, BlockInfoRPC>
    \ No newline at end of file +BlocksInfoRPC | banani

    Interface BlocksInfoRPC

    interface BlocksInfoRPC {
        blocks: Record<string, BlockInfoRPC>;
    }

    Properties

    Properties

    blocks: Record<string, BlockInfoRPC>
    \ No newline at end of file diff --git a/docs/interfaces/BlocksRPC.html b/docs/interfaces/BlocksRPC.html index 6c200ec..dc9be06 100644 --- a/docs/interfaces/BlocksRPC.html +++ b/docs/interfaces/BlocksRPC.html @@ -1,2 +1,2 @@ -BlocksRPC | banani

    Interface BlocksRPC

    interface BlocksRPC {
        blocks: Record<string, Block>;
    }

    Properties

    Properties

    blocks: Record<string, Block>
    \ No newline at end of file +BlocksRPC | banani

    Interface BlocksRPC

    interface BlocksRPC {
        blocks: Record<string, Block>;
    }

    Properties

    Properties

    blocks: Record<string, Block>
    \ No newline at end of file diff --git a/docs/interfaces/DelegatorsCountRPC.html b/docs/interfaces/DelegatorsCountRPC.html index 358b82d..d1f9357 100644 --- a/docs/interfaces/DelegatorsCountRPC.html +++ b/docs/interfaces/DelegatorsCountRPC.html @@ -1,2 +1,2 @@ -DelegatorsCountRPC | banani

    Interface DelegatorsCountRPC

    interface DelegatorsCountRPC {
        count: `${number}`;
    }

    Properties

    Properties

    count: `${number}`
    \ No newline at end of file +DelegatorsCountRPC | banani

    Interface DelegatorsCountRPC

    interface DelegatorsCountRPC {
        count: `${number}`;
    }

    Properties

    Properties

    count: `${number}`
    \ No newline at end of file diff --git a/docs/interfaces/DelegatorsRPC.html b/docs/interfaces/DelegatorsRPC.html index 93a6a09..67d1981 100644 --- a/docs/interfaces/DelegatorsRPC.html +++ b/docs/interfaces/DelegatorsRPC.html @@ -1,2 +1,2 @@ -DelegatorsRPC | banani

    Interface DelegatorsRPC

    interface DelegatorsRPC {
        delegators: Record<`ban_${string}` | `nano_${string}`, `${number}`>;
    }

    Properties

    Properties

    delegators: Record<`ban_${string}` | `nano_${string}`, `${number}`>
    \ No newline at end of file +DelegatorsRPC | banani

    Interface DelegatorsRPC

    interface DelegatorsRPC {
        delegators: Record<`ban_${string}` | `nano_${string}`, `${number}`>;
    }

    Properties

    Properties

    delegators: Record<`ban_${string}` | `nano_${string}`, `${number}`>
    \ No newline at end of file diff --git a/docs/interfaces/RPCInterface.html b/docs/interfaces/RPCInterface.html index a32b48b..d8195dc 100644 --- a/docs/interfaces/RPCInterface.html +++ b/docs/interfaces/RPCInterface.html @@ -1,9 +1,9 @@ RPCInterface | banani

    Interface RPCInterface

    Implement this interface if the built-in RPC class does not fit your needs. The easiest way to do this is by just extending the built-in RPC class

    -
    interface RPCInterface {
        DECIMALS?: number;
        rpc_url: string;
        use_pending: boolean;
        call(payload): Promise<Record<string, string>>;
        get_account_info(account, include_confirmed?, representative?, weight?, pending?): Promise<AccountInfoRPC>;
        get_account_receivable(account, count?, threshold?, source?): Promise<AccountReceivableRPC | AccountReceivableThresholdRPC | AccountReceivableSourceRPC>;
        get_block_info(block_hash): Promise<BlockInfoRPC>;
    }

    Implemented by

    Properties

    interface RPCInterface {
        DECIMALS?: number;
        rpc_url: string;
        use_pending: boolean;
        call(payload): Promise<Record<string, string>>;
        get_account_info(account, include_confirmed?, representative?, weight?, pending?): Promise<AccountInfoRPC>;
        get_account_receivable(account, count?, threshold?, source?): Promise<AccountReceivableRPC | AccountReceivableThresholdRPC | AccountReceivableSourceRPC>;
        get_block_info(block_hash): Promise<BlockInfoRPC>;
    }

    Implemented by

    Properties

    DECIMALS?: number
    rpc_url: string
    use_pending: boolean

    Methods

    • Parameters

      • payload: Record<string, any>

      Returns Promise<Record<string, string>>

    • Parameters

      • account: `ban_${string}` | `nano_${string}`
      • Optional include_confirmed: boolean
      • Optional representative: boolean
      • Optional weight: boolean
      • Optional pending: boolean

      Returns Promise<AccountInfoRPC>

    \ No newline at end of file +

    Properties

    DECIMALS?: number
    rpc_url: string
    use_pending: boolean

    Methods

    • Parameters

      • payload: Record<string, any>

      Returns Promise<Record<string, string>>

    • Parameters

      • account: `ban_${string}` | `nano_${string}`
      • Optional include_confirmed: boolean
      • Optional representative: boolean
      • Optional weight: boolean
      • Optional pending: boolean

      Returns Promise<AccountInfoRPC>

    \ No newline at end of file diff --git a/docs/interfaces/RepresentativesOnlineRPC.html b/docs/interfaces/RepresentativesOnlineRPC.html index 2e6107c..bceef6e 100644 --- a/docs/interfaces/RepresentativesOnlineRPC.html +++ b/docs/interfaces/RepresentativesOnlineRPC.html @@ -1,2 +1,2 @@ -RepresentativesOnlineRPC | banani

    Interface RepresentativesOnlineRPC

    interface RepresentativesOnlineRPC {
        representatives: (`ban_${string}` | `nano_${string}`)[];
    }

    Properties

    Properties

    representatives: (`ban_${string}` | `nano_${string}`)[]
    \ No newline at end of file +RepresentativesOnlineRPC | banani

    Interface RepresentativesOnlineRPC

    interface RepresentativesOnlineRPC {
        representatives: (`ban_${string}` | `nano_${string}`)[];
    }

    Properties

    Properties

    representatives: (`ban_${string}` | `nano_${string}`)[]
    \ No newline at end of file diff --git a/docs/interfaces/RepresentativesOnlineWeightRPC.html b/docs/interfaces/RepresentativesOnlineWeightRPC.html index 2424355..f7e5dc6 100644 --- a/docs/interfaces/RepresentativesOnlineWeightRPC.html +++ b/docs/interfaces/RepresentativesOnlineWeightRPC.html @@ -1,2 +1,2 @@ -RepresentativesOnlineWeightRPC | banani

    Interface RepresentativesOnlineWeightRPC

    interface RepresentativesOnlineWeightRPC {
        representatives: Record<`ban_${string}` | `nano_${string}`, {
            weight: `${number}`;
        }>;
    }

    Properties

    Properties

    representatives: Record<`ban_${string}` | `nano_${string}`, {
        weight: `${number}`;
    }>

    Type declaration

    • weight: `${number}`
    \ No newline at end of file +RepresentativesOnlineWeightRPC | banani

    Interface RepresentativesOnlineWeightRPC

    interface RepresentativesOnlineWeightRPC {
        representatives: Record<`ban_${string}` | `nano_${string}`, {
            weight: `${number}`;
        }>;
    }

    Properties

    Properties

    representatives: Record<`ban_${string}` | `nano_${string}`, {
        weight: `${number}`;
    }>

    Type declaration

    • weight: `${number}`
    \ No newline at end of file diff --git a/docs/interfaces/RepresentativesRPC.html b/docs/interfaces/RepresentativesRPC.html index 8c0c6d7..b53efb5 100644 --- a/docs/interfaces/RepresentativesRPC.html +++ b/docs/interfaces/RepresentativesRPC.html @@ -1,2 +1,2 @@ -RepresentativesRPC | banani

    Interface RepresentativesRPC

    interface RepresentativesRPC {
        representatives: Record<`ban_${string}` | `nano_${string}`, `${number}`>;
    }

    Properties

    Properties

    representatives: Record<`ban_${string}` | `nano_${string}`, `${number}`>
    \ No newline at end of file +RepresentativesRPC | banani

    Interface RepresentativesRPC

    interface RepresentativesRPC {
        representatives: Record<`ban_${string}` | `nano_${string}`, `${number}`>;
    }

    Properties

    Properties

    representatives: Record<`ban_${string}` | `nano_${string}`, `${number}`>
    \ No newline at end of file diff --git a/docs/interfaces/WorkProvider.html b/docs/interfaces/WorkProvider.html index 400e804..61f410e 100644 --- a/docs/interfaces/WorkProvider.html +++ b/docs/interfaces/WorkProvider.html @@ -1,2 +1,2 @@ -WorkProvider | banani

    Interface WorkProvider

    interface WorkProvider {
        request_work(block_hash): Promise<string>;
    }

    Methods

    Methods

    • Parameters

      • block_hash: string

      Returns Promise<string>

    \ No newline at end of file +WorkProvider | banani

    Interface WorkProvider

    interface WorkProvider {
        request_work(block_hash): Promise<string>;
    }

    Methods

    Methods

    • Parameters

      • block_hash: string

      Returns Promise<string>

    \ No newline at end of file diff --git a/docs/types/Address.html b/docs/types/Address.html index 6eeae9d..53729ac 100644 --- a/docs/types/Address.html +++ b/docs/types/Address.html @@ -1 +1 @@ -Address | banani

    Type alias Address

    Address: `${AddressPrefix}${string}`
    \ No newline at end of file +Address | banani

    Type alias Address

    Address: `${AddressPrefix}${string}`
    \ No newline at end of file diff --git a/docs/types/AddressPrefix.html b/docs/types/AddressPrefix.html index 973ca01..06428c5 100644 --- a/docs/types/AddressPrefix.html +++ b/docs/types/AddressPrefix.html @@ -1 +1 @@ -AddressPrefix | banani

    Type alias AddressPrefix

    AddressPrefix: "ban_" | "nano_"
    \ No newline at end of file +AddressPrefix | banani

    Type alias AddressPrefix

    AddressPrefix: "ban_" | "nano_"
    \ No newline at end of file diff --git a/docs/types/BlockAllTypes.html b/docs/types/BlockAllTypes.html index 240a31e..dd0dbd6 100644 --- a/docs/types/BlockAllTypes.html +++ b/docs/types/BlockAllTypes.html @@ -1 +1 @@ -BlockAllTypes | banani

    Type alias BlockAllTypes

    BlockAllTypes: BlockLegacyTypes | "state"
    \ No newline at end of file +BlockAllTypes | banani

    Type alias BlockAllTypes

    BlockAllTypes: BlockLegacyTypes | "state"
    \ No newline at end of file diff --git a/docs/types/BlockBasicTypes.html b/docs/types/BlockBasicTypes.html index 3bc7b69..aafda91 100644 --- a/docs/types/BlockBasicTypes.html +++ b/docs/types/BlockBasicTypes.html @@ -1 +1 @@ -BlockBasicTypes | banani

    Type alias BlockBasicTypes

    BlockBasicTypes: BlockStateChangeTypes | "change"
    \ No newline at end of file +BlockBasicTypes | banani

    Type alias BlockBasicTypes

    BlockBasicTypes: BlockStateChangeTypes | "change"
    \ No newline at end of file diff --git a/docs/types/BlockHash.html b/docs/types/BlockHash.html index 4fe34e7..6d7f2e4 100644 --- a/docs/types/BlockHash.html +++ b/docs/types/BlockHash.html @@ -1,2 +1,2 @@ BlockHash | banani

    Type alias BlockHash

    BlockHash: string

    32 byte block hash represented as 64 char hexadecimal

    -
    \ No newline at end of file +
    \ No newline at end of file diff --git a/docs/types/BlockLegacyTypes.html b/docs/types/BlockLegacyTypes.html index 3a61ebf..cec8bcc 100644 --- a/docs/types/BlockLegacyTypes.html +++ b/docs/types/BlockLegacyTypes.html @@ -1 +1 @@ -BlockLegacyTypes | banani

    Type alias BlockLegacyTypes

    BlockLegacyTypes: BlockBasicTypes | "open"
    \ No newline at end of file +BlockLegacyTypes | banani

    Type alias BlockLegacyTypes

    BlockLegacyTypes: BlockBasicTypes | "open"
    \ No newline at end of file diff --git a/docs/types/BlockStateChangeTypes.html b/docs/types/BlockStateChangeTypes.html index e65d30d..7d398fb 100644 --- a/docs/types/BlockStateChangeTypes.html +++ b/docs/types/BlockStateChangeTypes.html @@ -1 +1 @@ -BlockStateChangeTypes | banani

    Type alias BlockStateChangeTypes

    BlockStateChangeTypes: "send" | "receive"
    \ No newline at end of file +BlockStateChangeTypes | banani

    Type alias BlockStateChangeTypes

    BlockStateChangeTypes: "send" | "receive"
    \ No newline at end of file diff --git a/docs/types/BlockSubtype.html b/docs/types/BlockSubtype.html index d915201..d58132c 100644 --- a/docs/types/BlockSubtype.html +++ b/docs/types/BlockSubtype.html @@ -1 +1 @@ -BlockSubtype | banani

    Type alias BlockSubtype

    BlockSubtype: BlockBasicTypes | "epoch"
    \ No newline at end of file +BlockSubtype | banani

    Type alias BlockSubtype

    BlockSubtype: BlockBasicTypes | "epoch"
    \ No newline at end of file diff --git a/docs/types/Whole.html b/docs/types/Whole.html index 15dcc8f..87888a7 100644 --- a/docs/types/Whole.html +++ b/docs/types/Whole.html @@ -1,2 +1,2 @@ Whole | banani

    Type alias Whole

    Whole: `${number}`

    Does NOT mean whole number, can be decimal like "4.2001". Use instead of regular number since those lose precision when decimal

    -
    \ No newline at end of file +
    \ No newline at end of file diff --git a/docs/types/WorkFunction.html b/docs/types/WorkFunction.html index b68d218..e177c62 100644 --- a/docs/types/WorkFunction.html +++ b/docs/types/WorkFunction.html @@ -1 +1 @@ -WorkFunction | banani

    Type alias WorkFunction

    WorkFunction: ((block_hash) => Promise<string>)

    Type declaration

      • (block_hash): Promise<string>
      • Parameters

        Returns Promise<string>

    \ No newline at end of file +WorkFunction | banani

    Type alias WorkFunction

    WorkFunction: ((block_hash) => Promise<string>)

    Type declaration

      • (block_hash): Promise<string>
      • Parameters

        Returns Promise<string>

    \ No newline at end of file diff --git a/main.ts b/main.ts index 3a6778b..814a044 100644 --- a/main.ts +++ b/main.ts @@ -3,4 +3,3 @@ export * from "./rpc"; export * from "./rpc_types"; export * from "./wallet"; export * from "./work"; - diff --git a/node_test/index.js b/node_test/index.js index 098ce6b..c078c57 100644 --- a/node_test/index.js +++ b/node_test/index.js @@ -1,11 +1,12 @@ -import * as banani from "../main.js";//"banani"; +//import * as banani from "../main.js" +import * as banani from "banani"; import * as fs from "fs"; let rpc = new banani.RPC("https://kaliumapi.appditto.com/api"); //rpc.debug = true console.log(rpc.rpc_url); -console.log(await rpc.get_block_count()) +console.log(await rpc.get_block_count()); let random_wallet = banani.Wallet.gen_random_wallet(rpc); @@ -42,4 +43,3 @@ console.log(await wallet.receive_all()); await wallet.change_rep("ban_3p3sp1ynb5i3qxmqoha3pt79hyk8gxhtr58tk51qctwyyik6hy4dbbqbanan"); // - diff --git a/node_test/package-lock.json b/node_test/package-lock.json index 1716d20..bba4129 100644 --- a/node_test/package-lock.json +++ b/node_test/package-lock.json @@ -9,7 +9,7 @@ "version": "1.0.0", "license": "ISC", "dependencies": { - "banani": "^0.0.1-wip-3" + "banani": "^1.0.0" } }, "node_modules/b4a": { @@ -19,13 +19,12 @@ "license": "Apache-2.0" }, "node_modules/banani": { - "version": "0.0.1-wip-3", - "resolved": "https://registry.npmjs.org/banani/-/banani-0.0.1-wip-3.tgz", - "integrity": "sha512-6As7zKa+2hCUrgSXRuAc9DyWpKoXnE8ew91JbX9FOMIl748MRXLj3Ob+Q6IhdmV0oPL42jpUYRDr5ApKZmqW8g==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/banani/-/banani-1.0.0.tgz", + "integrity": "sha512-qktSBh4qWcnX8L24ZplShQAESrTZ++Y/ipjSfP2c0z8xz7aL5TUyy19+oQZz9nnpNNXrRdtll3Ye17dQUWcrfQ==", "license": "MIT", "dependencies": { - "blake2b": "^2.1.4", - "tweetnacl": "^1.0.3" + "blake2b": "^2.1.4" } }, "node_modules/blake2b": { @@ -53,12 +52,6 @@ "resolved": "https://registry.npmjs.org/nanoassert/-/nanoassert-2.0.0.tgz", "integrity": "sha512-7vO7n28+aYO4J+8w96AzhmU8G+Y/xpPDJz/se19ICsqj/momRbb9mh9ZUtkoJ5X3nTnPdhEJyc0qnM6yAsHBaA==", "license": "ISC" - }, - "node_modules/tweetnacl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", - "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==", - "license": "Unlicense" } } } diff --git a/node_test/package.json b/node_test/package.json index 575dbd9..23de473 100644 --- a/node_test/package.json +++ b/node_test/package.json @@ -10,6 +10,6 @@ "description": "", "type": "module", "dependencies": { - "banani": "^0.9.0-beta" + "banani": "^1.0.0" } } diff --git a/package-lock.json b/package-lock.json index d570fa5..470f704 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,19 +1,19 @@ { "name": "banani", - "version": "0.0.1-wip-1", + "version": "1.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "banani", - "version": "0.0.1-wip-1", + "version": "1.0.0", "license": "MIT", "dependencies": { - "blake2b": "^2.1.4", - "tweetnacl": "^1.0.3" + "blake2b": "^2.1.4" }, "devDependencies": { "esbuild": "^0.21.4", + "prettier": "3.3.2", "typedoc": "^0.25.13", "typescript": "^5.4.5" } @@ -516,6 +516,22 @@ "integrity": "sha512-7vO7n28+aYO4J+8w96AzhmU8G+Y/xpPDJz/se19ICsqj/momRbb9mh9ZUtkoJ5X3nTnPdhEJyc0qnM6yAsHBaA==", "license": "ISC" }, + "node_modules/prettier": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.2.tgz", + "integrity": "sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/shiki": { "version": "0.14.7", "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.14.7.tgz", @@ -528,11 +544,6 @@ "vscode-textmate": "^8.0.0" } }, - "node_modules/tweetnacl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", - "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" - }, "node_modules/typedoc": { "version": "0.25.13", "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.25.13.tgz", diff --git a/package.json b/package.json index 2825b39..2a50efc 100644 --- a/package.json +++ b/package.json @@ -5,10 +5,12 @@ "main": "main.js", "scripts": { "compile": "tsc -p .", - "docs": "typedoc --name banani --entryPoints ./main.ts", + "prettier": "prettier . --write", + "docs": "typedoc --name banani --entryPoints ./main.ts && node --eval \"require('fs').writeFileSync('./docs/CNAME', 'banani.prussia.dev')\"", "browser": "esbuild browser-main.ts --bundle --minify --keep-names --drop-labels=NODE --outfile=banani-browser.js", - "build": "npm run compile && npm run docs && npm run browser", - "cryptodiff": "diff tweetnacl_og.js tweetnacl_mod.js" + "build": "npm run prettier && npm run compile && npm run docs && npm run browser", + "cryptodiff": "diff tweetnacl_og.js tweetnacl_mod.js", + "diff": "git diff --cached -- *.{ts,md,json} 'browser_test/index.html' 'node_test/index.js'" }, "repository": { "type": "git", @@ -26,6 +28,7 @@ "homepage": "https://github.com/stjet/banani#readme", "devDependencies": { "esbuild": "^0.21.4", + "prettier": "3.3.2", "typedoc": "^0.25.13", "typescript": "^5.4.5" }, diff --git a/rpc.ts b/rpc.ts index 077947c..64716f7 100644 --- a/rpc.ts +++ b/rpc.ts @@ -3,13 +3,13 @@ import { whole_to_raw } from "./util"; /** Implement this interface if the built-in RPC class does not fit your needs. The easiest way to do this is by just extending the built-in RPC class */ export interface RPCInterface { - rpc_url: string, - use_pending: boolean, - DECIMALS?: number, - call(payload: Record): Promise>, - get_block_info(block_hash: BlockHash): Promise, - get_account_info(account: Address, include_confirmed?: boolean, representative?: boolean, weight?: boolean, pending?: boolean): Promise, - get_account_receivable(account: Address, count?: number, threshold?: `${number}`, source?: boolean): Promise, + rpc_url: string; + use_pending: boolean; + DECIMALS?: number; + call(payload: Record): Promise>; + get_block_info(block_hash: BlockHash): Promise; + get_account_info(account: Address, include_confirmed?: boolean, representative?: boolean, weight?: boolean, pending?: boolean): Promise; + get_account_receivable(account: Address, count?: number, threshold?: `${number}`, source?: boolean): Promise; } /** Sends RPC requests to the RPC node, also has wrappers for actions that only read the network (write actions are handled by the Wallet class) */ @@ -26,7 +26,7 @@ export class RPC implements RPCInterface { /** * @param {boolean} [use_pending = false] If true, uses "pending" instead of "receivable" in RPC action names, for compatibility with older versions of the node - */ + */ constructor(rpc_url: string, use_pending: boolean = false) { this.rpc_url = rpc_url; this.use_pending = use_pending; @@ -36,13 +36,13 @@ export class RPC implements RPCInterface { /** The function that sends the RPC POST request */ async call(payload: Record): Promise> { - if (this.debug) console.log(JSON.stringify(payload)) + if (this.debug) console.log(JSON.stringify(payload)); const resp = await fetch(this.rpc_url, { method: "POST", headers: this.headers ?? { "Content-Type": "application/json" }, body: JSON.stringify(payload), }); - if (!resp.ok && this.debug) console.log(await resp.text()) + if (!resp.ok && this.debug) console.log(await resp.text()); if (!resp.ok) throw Error(`Request to RPC node failed with status code ${resp.status}`); const resp_json = await resp.json(); if (resp_json.error) throw Error(`RPC node response: ${resp_json.error}`); @@ -188,7 +188,7 @@ export class RPCWithBackup extends RPC { /** * @param {number} [timeout] Request to RPC timeout, in milliseconds. If RPC request fails or timeouts, tries the next RPC - */ + */ constructor(rpc_urls: string[], timeout: number, use_pending: boolean = false) { if (rpc_urls.length < 2) throw Error("Must provide at least two RPC URLs"); super(rpc_urls[0], use_pending); @@ -215,4 +215,3 @@ export class RPCWithBackup extends RPC { } } } - diff --git a/rpc_types.ts b/rpc_types.ts index 88befa9..d3e4b81 100644 --- a/rpc_types.ts +++ b/rpc_types.ts @@ -11,168 +11,170 @@ export type BlockLegacyTypes = BlockBasicTypes | "open"; export type BlockAllTypes = BlockLegacyTypes | "state"; export interface BlockNoSignature { - type: BlockAllTypes, - account: Address, - previous: BlockHash, - representative: Address, - balance: `${number}`, - link: BlockHash, - link_as_account?: Address, + type: BlockAllTypes; + account: Address; + previous: BlockHash; + representative: Address; + balance: `${number}`; + link: BlockHash; + link_as_account?: Address; } export interface Block extends BlockNoSignature { - signature: string, - work?: string, + signature: string; + work?: string; } export interface BlockCountRPC { - count: `${number}`, - unchecked: `${number}`, - cemented?: `${number}`, + count: `${number}`; + unchecked: `${number}`; + cemented?: `${number}`; } export interface BlockInfoRPC { - block_account: Address, - amount: `${number}`, - balance: `${number}`, - height: `${number}`, - timestamp: `${number}`, - contents: Block, + block_account: Address; + amount: `${number}`; + balance: `${number}`; + height: `${number}`; + timestamp: `${number}`; + contents: Block; //v19 or newer only - confirmed?: `${boolean}`, - subtype?: BlockSubtype, //for state blocks only + confirmed?: `${boolean}`; + subtype?: BlockSubtype; //for state blocks only //v23 or newer only - successor?: `${string}`, + successor?: `${string}`; } export interface BlocksRPC { - blocks: Record, + blocks: Record; } export interface BlocksInfoRPC { - blocks: Record, + blocks: Record; } export interface RepresentativesRPC { - representatives: Record, + representatives: Record; } export interface RepresentativesOnlineRPC { - representatives: Address[], + representatives: Address[]; } export interface RepresentativesOnlineWeightRPC { - representatives: Record, + representatives: Record; } export interface AccountHistoryBlock { - type: BlockStateChangeTypes, - account: Address, - amount: `${number}`, - local_timestamp: `${number}`, - height: `${number}`, - hash: BlockHash, - confirmed: boolean, + type: BlockStateChangeTypes; + account: Address; + amount: `${number}`; + local_timestamp: `${number}`; + height: `${number}`; + hash: BlockHash; + confirmed: boolean; } export interface AccountHistoryRawBlock { - account: Address, - amount: `${number}`, - amount_decimal: `${number}`, - balance: `${number}`, - balance_decimal: `${number}`, - confirmed: `${boolean}`, - hash: BlockHash, - height: `${number}`, - link: BlockHash, - local_timestamp: `${number}`, - previous: BlockHash, - representative: Address, - signature: string, - subtype: BlockSubtype, - type: BlockAllTypes, - work: string, + account: Address; + amount: `${number}`; + amount_decimal: `${number}`; + balance: `${number}`; + balance_decimal: `${number}`; + confirmed: `${boolean}`; + hash: BlockHash; + height: `${number}`; + link: BlockHash; + local_timestamp: `${number}`; + previous: BlockHash; + representative: Address; + signature: string; + subtype: BlockSubtype; + type: BlockAllTypes; + work: string; } export interface AccountHistoryRPC { - account: Address, - history: AccountHistoryBlock[], - previous?: BlockHash, + account: Address; + history: AccountHistoryBlock[]; + previous?: BlockHash; } export interface AccountHistoryRawRPC { - account: Address, - history: AccountHistoryRawBlock[], - previous?: BlockHash, + account: Address; + history: AccountHistoryRawBlock[]; + previous?: BlockHash; } export interface AccountInfoRPC { - frontier: BlockHash, - open_block: BlockHash, - representative_block: BlockHash, - balance: `${number}`, - modified_timestamp: `${number}`, - block_count: `${number}`, - account_version: `${number}`, - confirmation_height?: `${number}`, - confirmation_height_frontier?: BlockHash, - representative?: Address, - weight?: `${number}`, - pending?: `${number}`, - receivable?: `${number}`, - confirmed_balance?: `${number}`, - confirmed_height?: `${number}`, - confirmed_frontier?: BlockHash, - confirmed_representative?: Address, - confirmed_receivable?: `${number}`, - confirmed_pending?: `${number}`, + frontier: BlockHash; + open_block: BlockHash; + representative_block: BlockHash; + balance: `${number}`; + modified_timestamp: `${number}`; + block_count: `${number}`; + account_version: `${number}`; + confirmation_height?: `${number}`; + confirmation_height_frontier?: BlockHash; + representative?: Address; + weight?: `${number}`; + pending?: `${number}`; + receivable?: `${number}`; + confirmed_balance?: `${number}`; + confirmed_height?: `${number}`; + confirmed_frontier?: BlockHash; + confirmed_representative?: Address; + confirmed_receivable?: `${number}`; + confirmed_pending?: `${number}`; } export interface AccountBalanceRPC { - balance: `${number}`, - pending: `${number}`, - receivable?: `${number}`, + balance: `${number}`; + pending: `${number}`; + receivable?: `${number}`; } export interface AccountsBalancesRPC { - balances: Record, + balances: Record; } export interface AccountRepresentativeRPC { - representative: Address, + representative: Address; } export interface AccountsRepresentativesRPC { - representatives: Record, + representatives: Record; } export interface AccountWeightRPC { - weight: `${number}`, + weight: `${number}`; } export interface AccountReceivableRPC { - blocks: BlockHash[], + blocks: BlockHash[]; } //doesn't happen if threshold is "0" for some reason. why, nano node rpc... export interface AccountReceivableThresholdRPC { - blocks: Record, + blocks: Record; } export interface AccountReceivableSourceRPC { - blocks: Record, + blocks: Record< + BlockHash, + { + amount: `${number}`; + source: Address; + } + >; } export interface DelegatorsRPC { - delegators: Record, + delegators: Record; } export interface DelegatorsCountRPC { - count: `${number}`, + count: `${number}`; } // - diff --git a/tsconfig.json b/tsconfig.json index d3a7ddf..2c0ab3c 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,19 +3,11 @@ "target": "es2020", "module": "node16", "moduleResolution": "node16", - "typeRoots": [ - "./node_modules/@types" - ], + "typeRoots": ["./node_modules/@types"], "esModuleInterop": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true }, - "lib": [ - "ES2020" - ], - "exclude": [ - "node_modules", - ".build", - "browser-main.ts" - ] + "lib": ["ES2020"], + "exclude": ["node_modules", ".build", "browser-main.ts"] } diff --git a/util.ts b/util.ts index dde3216..025926f 100644 --- a/util.ts +++ b/util.ts @@ -35,13 +35,13 @@ export function int_to_uint8array(int: number, len: number): Uint8Array { let uint8array: Uint8Array = new Uint8Array(len); for (let i = 1; i <= len; i++) { if (i === 1) { - uint8array[len - i] = int % (16 ** 2); + uint8array[len - i] = int % 16 ** 2; } else { let subbed_int = int; for (let j = i - 1; j > 0; j--) { - subbed_int -= uint8array[len - j] * (16 ** (2 * (j - 1))); + subbed_int -= uint8array[len - j] * 16 ** (2 * (j - 1)); } - uint8array[len - i] = Math.floor((subbed_int) / (16 ** (2 * (i - 1)))); + uint8array[len - i] = Math.floor(subbed_int / 16 ** (2 * (i - 1))); } } return uint8array; @@ -50,22 +50,21 @@ export function int_to_uint8array(int: number, len: number): Uint8Array { const BASE32_CHARS = ["1", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "m", "n", "o", "p", "q", "r", "s", "t", "u", "w", "x", "y", "z"]; //const BASE32_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ01234567".split(""); -//this works for normal base32 (with the exception of the second to last character) but not for nano?????? //ok, so in addition to the different character set,** you need to pad 4 bits at the front (with 0)** so no left over bits exist. we will pad before this function is called //now officially a bitwise operator enthusiast export function uint8array_to_base32(uint8array: Uint8Array): string { let base32: string = ""; - for (let i = 0; i < Math.floor(uint8array.length * 8 / 5); i++) { - let bitn = i * 5; //bit # - let bytn = Math.floor(bitn / 8); //byte # - let bits = bitn % 8; //bit start (in the byte) + for (let i = 0; i < Math.floor((uint8array.length * 8) / 5); i++) { + const bitn = i * 5; //bit # + const bytn = Math.floor(bitn / 8); //byte # + const bits = bitn % 8; //bit start (in the byte) let b32in: number; //base32 chars array index (5 bit integer) - let r = 8 - bits; + const r = 8 - bits; if (r >= 5) { - b32in = uint8array[bytn] >> (r - 5) & 31; //rightshift to get rid of extra bits on the right, then & 31 to get it down to 5 bits + b32in = (uint8array[bytn] >> (r - 5)) & 31; //rightshift to get rid of extra bits on the right, then & 31 to get it down to 5 bits } else { - let n = 5 - r; //amount of bits to get from the next byte - b32in = (uint8array[bytn] << n & 31) + (uint8array[bytn + 1] >> (8 - n) & (2 ** (8 - n) - 1)); //first part: left shift to get the bits from the current byte in the right position, then & 31 to get it down to 5 bits. second part: get remaining bits from front of the next byte by rightshifting (get rid of extra bits on the right) and then again doing & to get it down to the appropriate amount of bits + const n = 5 - r; //amount of bits to get from the next byte + b32in = ((uint8array[bytn] << n) & 31) + ((uint8array[bytn + 1] >> (8 - n)) & (2 ** (8 - n) - 1)); //first part: left shift to get the bits from the current byte in the right position, then & 31 to get it down to 5 bits. second part: get remaining bits from front of the next byte by rightshifting (get rid of extra bits on the right) and then again doing & to get it down to the appropriate amount of bits } base32 += BASE32_CHARS[b32in]; } @@ -100,8 +99,11 @@ function binary_to_int(binary: string): number { //I don't feel like using bitwise operators for this. might need to use up to 3 bytes, too much work //expects length * 5 to be multiple of 8 export function base32_to_uint8array(base32: string): Uint8Array { - let binary = base32.split("").map((c) => int_to_binary(BASE32_CHARS.indexOf(c), 5)).join(""); - let uint8array = new Uint8Array(Math.ceil(base32.length * 5 / 8)); + const binary = base32 + .split("") + .map((c) => int_to_binary(BASE32_CHARS.indexOf(c), 5)) + .join(""); + let uint8array = new Uint8Array(Math.ceil((base32.length * 5) / 8)); for (let i = 0; i < uint8array.length; i++) { uint8array[i] = binary_to_int(binary.slice(i * 8, i * 8 + 8)); } @@ -109,7 +111,7 @@ export function base32_to_uint8array(base32: string): Uint8Array { } export function utf8_to_uint8array(utf8: string): Uint8Array { - return (new TextEncoder()).encode(utf8); + return new TextEncoder().encode(utf8); } // @@ -117,6 +119,8 @@ export function utf8_to_uint8array(utf8: string): Uint8Array { // whole and raw related const BANANO_DECIMALS: number = 29; +/** Do `rpc.DECIMALS = banani.NANO_DECIMALS` if using Nano. Putting the wrong amount of decimals in may result in LOSS OF FUNDS. */ +const NANO_DECIMALS: number = 30; /** Does NOT mean whole number, can be decimal like "4.2001". Use instead of regular number since those lose precision when decimal */ export type Whole = `${number}`; //number can include non-base-10 formats... but whatever, we can assume users will pass in only base-10 because they are normal for the most part @@ -125,11 +129,11 @@ export type Whole = `${number}`; //number can include non-base-10 formats... but export function whole_to_raw(whole: Whole, decimals = BANANO_DECIMALS): bigint { let raw: bigint; if (whole.includes(".")) { - let parts = whole.split("."); - if (0 > (decimals - parts[1].length)) throw Error(`Too many decimals, cannot exceed ${decimals}`) - raw = BigInt(parts[0]) * (BigInt(10) ** BigInt(decimals)) + BigInt(parts[1]) * (BigInt(10) ** BigInt(decimals - parts[1].length)); + const parts = whole.split("."); + if (0 > decimals - parts[1].length) throw Error(`Too many decimals, cannot exceed ${decimals}`); + raw = BigInt(parts[0]) * BigInt(10) ** BigInt(decimals) + BigInt(parts[1]) * BigInt(10) ** BigInt(decimals - parts[1].length); } else { - raw = BigInt(whole) * (BigInt(10) ** BigInt(decimals)); + raw = BigInt(whole) * BigInt(10) ** BigInt(decimals); } return raw; } @@ -141,11 +145,11 @@ export function raw_to_whole(raw: bigint, decimals = BANANO_DECIMALS): Whole { if (raw_string.length > decimals) { whole_string = raw_string.slice(0, -decimals) + "." + raw_string.slice(-decimals); } else { - let r: number = decimals - raw_string.length; + const r: number = decimals - raw_string.length; whole_string = "0." + "0".repeat(r > 0 ? r : 0) + raw_string; } //truncate any extra zeroes - let cl: number = whole_string.length; + const cl: number = whole_string.length; for (let c = 0; c < cl; c++) { if (whole_string.slice(-1) === "0" || whole_string.slice(-1) === ".") { whole_string = whole_string.slice(0, -1); @@ -167,15 +171,15 @@ export function get_public_key_from_private_key(private_key: string): string { export function get_address_from_public_key(public_key: string, prefix: AddressPrefix = "ban_"): Address { //the previously mentioned padding the front with 4 bits - let encoded = uint8array_to_base32(hex_to_uint8array(`0${public_key}`)); + const encoded = uint8array_to_base32(hex_to_uint8array(`0${public_key}`)); //skip byte length assertions - let hashed = uint8array_to_base32(blake2b(5, null, null, null, true).update(hex_to_uint8array(public_key)).digest().reverse()); + const hashed = uint8array_to_base32(blake2b(5, null, null, null, true).update(hex_to_uint8array(public_key)).digest().reverse()); return `ban_${encoded}${hashed}`; } export function get_public_key_from_address(address: Address): string { //extract just the public key portion - let b = base32_to_uint8array(address.split("_")[1].slice(0, 52)); + const b = base32_to_uint8array(address.split("_")[1].slice(0, 52)); b[b.length - 1] = b[b.length - 1] * 16; //this is a bug fix //remove padding 0 added when encoding to address, remove trailing zero added by the code return uint8array_to_hex(b).slice(1, -1); @@ -194,7 +198,8 @@ export function hash_block(block: BlockNoSignature): string { .update(hex_to_uint8array(get_public_key_from_address(block.representative))) .update(hex_to_uint8array(padded_balance)) .update(hex_to_uint8array(block.link)) - .digest("hex").toUpperCase(); + .digest("hex") + .toUpperCase(); } export function sign_block_hash(private_key: string, block_hash: BlockHash): string { @@ -207,12 +212,12 @@ export function verify_block_hash(public_key: string, signature: string, block_h } /** sign message by constructing a dummy block with the message (why not just sign the message itself instead of putting it in a dummy block? ledger support). This is already the standard across Banano services and wallets which support signing so please don't invent your own scheme -* @return {string} The signature in hex -*/ -export function sign_message(private_key: string, message: string, preamble=MESSAGE_PREAMBLE): string { + * @return {string} The signature in hex + */ +export function sign_message(private_key: string, message: string, preamble = MESSAGE_PREAMBLE): string { //construct the dummy block const dummy32 = "0".repeat(64); - let dummy_block: BlockNoSignature = { + const dummy_block: BlockNoSignature = { type: "state", account: get_address_from_public_key(get_public_key_from_private_key(private_key)), previous: dummy32, @@ -225,4 +230,3 @@ export function sign_message(private_key: string, message: string, preamble=MESS } // - diff --git a/wallet.ts b/wallet.ts index 436a8b9..d0f0a29 100644 --- a/wallet.ts +++ b/wallet.ts @@ -14,10 +14,10 @@ export class Wallet { try_work: boolean; add_do_work: boolean = true; work_function?: WorkFunction; - + /** * @param {string} [seed] Seed for the wallet from which private keys are derived. 64 character hex string (32 bytes) - */ + */ constructor(rpc: RPCInterface, seed: string, index: number = 0, try_work: boolean = false, work_function?: WorkFunction) { this.rpc = rpc; if (typeof seed !== "string" || seed?.length !== 64) throw Error("Seed needs to be 64 character (hex) string"); @@ -47,13 +47,15 @@ export class Wallet { //Actions async send_process(block: Block, subtype: BlockSubtype): Promise { - return (await this.rpc.call({ - action: "process", - json_block: "true", - subtype, - block, - do_work: (!block.work && this.add_do_work) ? true : undefined, - })).hash as BlockHash; + return ( + await this.rpc.call({ + action: "process", + json_block: "true", + subtype, + block, + do_work: !block.work && this.add_do_work ? true : undefined, + }) + ).hash as BlockHash; } /** * @param {Address} [to] address to send to @@ -64,16 +66,16 @@ export class Wallet { Send Bananos */ async send(to: Address, amount: util.Whole, gen_work?: boolean, representative?: Address, cached_account_info?: AccountInfoRPC): Promise { - let raw_send = util.whole_to_raw(amount, this.rpc.DECIMALS); - let info = cached_account_info ?? await this.get_account_info(undefined, true); //this should be lazy. the true makes sure representative is included - let pub_receive = util.get_public_key_from_address(to); + const raw_send = util.whole_to_raw(amount, this.rpc.DECIMALS); + const info = cached_account_info ?? (await this.get_account_info(undefined, true)); //this should be lazy. the true makes sure representative is included + const pub_receive = util.get_public_key_from_address(to); if (!representative) representative = info.representative; - let before_balance = BigInt(info.balance); - let new_balance = before_balance - raw_send; + const before_balance = BigInt(info.balance); + const new_balance = before_balance - raw_send; if (new_balance < 0n) { throw Error(`Insufficient funds to send. Cannot send more than balance; ie, Before balance (raw: ${before_balance}) less than send amount (raw: ${raw_send})`); } - let block_ns: BlockNoSignature = { + const block_ns: BlockNoSignature = { type: "state", account: this.address, previous: info.frontier, @@ -83,16 +85,16 @@ export class Wallet { link: pub_receive, link_as_account: to, }; - let s_block_hash = util.hash_block(block_ns); //block hash of the send block + const s_block_hash = util.hash_block(block_ns); //block hash of the send block let work = undefined; if (gen_work) work = await this.work_function(s_block_hash); - let signature = util.sign_block_hash(this.private_key, s_block_hash); - let block = { ...block_ns, signature, work }; + const signature = util.sign_block_hash(this.private_key, s_block_hash); + const block = { ...block_ns, signature, work }; return await this.send_process(block, "send"); } /* Send all Bananos */ async send_all(to: Address, work?: boolean, representative?: Address): Promise { - let info = await this.get_account_info(undefined, true); + const info = await this.get_account_info(undefined, true); return await this.send(to, util.raw_to_whole(BigInt(info.balance), this.rpc.DECIMALS), work, representative, info); } /** @@ -103,12 +105,12 @@ export class Wallet { */ async receive(block_hash: BlockHash, gen_work?: boolean, representative?: Address): Promise { //doesn't matter if open or not, I think? - let block_info = await this.rpc.get_block_info(block_hash); + const block_info = await this.rpc.get_block_info(block_hash); let before_balance = 0n; if (!representative) representative = this.address; let previous; try { - let info = await this.get_account_info(undefined, true); + const info = await this.get_account_info(undefined, true); previous = info.frontier; representative = info.representative; before_balance = BigInt(info.balance); @@ -118,20 +120,20 @@ export class Wallet { //unopened account probably previous = "0".repeat(64); } - let block_ns: BlockNoSignature = { + const block_ns: BlockNoSignature = { type: "state", account: this.address, previous, representative, - balance: ((before_balance + BigInt(block_info.amount)).toString() as `${number}`), + balance: (before_balance + BigInt(block_info.amount)).toString() as `${number}`, //link is hash of send block link: block_hash, }; - let r_block_hash = util.hash_block(block_ns); //block hash of the receive block + const r_block_hash = util.hash_block(block_ns); //block hash of the receive block let work = undefined; if (gen_work) work = await this.work_function(r_block_hash); - let signature = util.sign_block_hash(this.private_key, r_block_hash); - let block = { ...block_ns, signature, work }; + const signature = util.sign_block_hash(this.private_key, r_block_hash); + const block = { ...block_ns, signature, work }; return await this.send_process(block, "receive"); } //todo: might have some error with multiple receives? @@ -143,10 +145,10 @@ export class Wallet { Receive all receivable transactions (up to count, and over threshold */ async receive_all(count: number = 20, threshold?: `${number}`, gen_work?: boolean): Promise { - let to_receive = (await this.get_account_receivable(count, threshold, true) as AccountReceivableSourceRPC).blocks; + const to_receive = ((await this.get_account_receivable(count, threshold, true)) as AccountReceivableSourceRPC).blocks; let previous, representative, before_balance; try { - let info = await this.get_account_info(undefined, true); + const info = await this.get_account_info(undefined, true); previous = info.frontier; representative = info.representative; before_balance = BigInt(info.balance); @@ -160,8 +162,8 @@ export class Wallet { } let receive_block_hashes: BlockHash[] = []; for (const receive_hash of Object.keys(to_receive)) { - let new_balance = (before_balance + BigInt(to_receive[receive_hash].amount)).toString() as `${number}`; - let block_ns: BlockNoSignature = { + const new_balance = (before_balance + BigInt(to_receive[receive_hash].amount)).toString() as `${number}`; + const block_ns: BlockNoSignature = { type: "state", account: this.address, previous, @@ -170,12 +172,12 @@ export class Wallet { //link is hash of send block link: receive_hash, }; - let r_block_hash = util.hash_block(block_ns); //block hash of the receive block + const r_block_hash = util.hash_block(block_ns); //block hash of the receive block let work = undefined; if (gen_work) work = await this.work_function(r_block_hash); - let signature = util.sign_block_hash(this.private_key, r_block_hash); - let block = { ...block_ns, signature, work }; - await this.send_process(block, "receive") + const signature = util.sign_block_hash(this.private_key, r_block_hash); + const block = { ...block_ns, signature, work }; + await this.send_process(block, "receive"); receive_block_hashes.push(r_block_hash); previous = r_block_hash; before_balance = BigInt(new_balance); @@ -185,10 +187,10 @@ export class Wallet { /** * @param {Address} [new_representative] banano address to change representative to * @param {boolean?} [gen_work] whether or not to call work function to generate work - */ + */ async change_representative(new_representative: Address, gen_work?: boolean): Promise { - let info = await this.get_account_info(); - let block_ns: BlockNoSignature = { + const info = await this.get_account_info(); + const block_ns: BlockNoSignature = { type: "state", account: this.address, previous: info.frontier, @@ -197,11 +199,11 @@ export class Wallet { //link is 0 link: "0".repeat(64), }; - let c_block_hash = util.hash_block(block_ns); //block hash of the change block + const c_block_hash = util.hash_block(block_ns); //block hash of the change block let work = undefined; if (gen_work) work = await this.work_function(c_block_hash); - let signature = util.sign_block_hash(this.private_key, c_block_hash); - let block = { ...block_ns, signature, work }; + const signature = util.sign_block_hash(this.private_key, c_block_hash); + const block = { ...block_ns, signature, work }; return await this.send_process(block, "change"); } /* alias for the change_representative method */ @@ -222,4 +224,3 @@ export class Wallet { return util.sign_message(this.private_key, message); } } - diff --git a/work.ts b/work.ts index aa09d3c..8d407bc 100644 --- a/work.ts +++ b/work.ts @@ -2,10 +2,9 @@ import type { BlockHash } from "./rpc_types"; import type { RPC } from "./rpc"; export interface WorkProvider { - request_work(block_hash: BlockHash): Promise, + request_work(block_hash: BlockHash): Promise; } - export class RPCWorkProvider { readonly rpc: RPC; @@ -17,13 +16,14 @@ export class RPCWorkProvider { } async request_work(block_hash: BlockHash): Promise { - return (await this.rpc.call({ - action: "work_generate", - hash: block_hash, - ...this.extra_payload, - })).work; + return ( + await this.rpc.call({ + action: "work_generate", + hash: block_hash, + ...this.extra_payload, + }) + ).work; } } // -