0)tail+=16;XorAndSalsa(out,head,input,ii+=16,out,tail)}}function scryptInit(password,salt,_opts){const opts=checkOpts({dkLen:32,asyncTick:10,maxmem:1024**3+1024},_opts);const{N,r,p,dkLen,asyncTick,maxmem,onProgress}=opts;number(N);number(r);number(p);number(dkLen);number(asyncTick);number(maxmem);if(onProgress!==undefined&&typeof onProgress!=="function")throw new Error("progressCb should be function");const blockSize=128*r;const blockSize32=blockSize/4;if(N<=1||(N&N-1)!==0||N>=2**(blockSize/8)||N>2**32){throw new Error("Scrypt: N must be larger than 1, a power of 2, less than 2^(128 * r / 8) and less than 2^32")}if(p<0||p>(2**32-1)*32/blockSize){throw new Error("Scrypt: p must be a positive integer less than or equal to ((2^32 - 1) * 32) / (128 * r)")}if(dkLen<0||dkLen>(2**32-1)*32){throw new Error("Scrypt: dkLen should be positive integer less than or equal to (2^32 - 1) * 32")}const memUsed=blockSize*(N+p);if(memUsed>maxmem){throw new Error(`Scrypt: parameters too large, ${memUsed} (128 * r * (N + p)) > ${maxmem} (maxmem)`)}const B=pbkdf2$1(sha256$1,password,salt,{c:1,dkLen:blockSize*p});const B32=u32(B);const V=u32(new Uint8Array(blockSize*N));const tmp=u32(new Uint8Array(blockSize));let blockMixCb=()=>{};if(onProgress){const totalBlockMix=2*N*p;const callbackPer=Math.max(Math.floor(totalBlockMix/1e4),1);let blockMixCnt=0;blockMixCb=()=>{blockMixCnt++;if(onProgress&&(!(blockMixCnt%callbackPer)||blockMixCnt===totalBlockMix))onProgress(blockMixCnt/totalBlockMix)}}return{N:N,r:r,p:p,dkLen:dkLen,blockSize32:blockSize32,V:V,B32:B32,B:B,tmp:tmp,blockMixCb:blockMixCb,asyncTick:asyncTick}}function scryptOutput(password,dkLen,B,V,tmp){const res=pbkdf2$1(sha256$1,password,B,{c:1,dkLen:dkLen});B.fill(0);V.fill(0);tmp.fill(0);return res}function scrypt$1(password,salt,opts){const{N,r,p,dkLen,blockSize32,V,B32,B,tmp,blockMixCb}=scryptInit(password,salt,opts);for(let pi=0;pi{BlockMix(V,pos,V,pos+=blockSize32,r);blockMixCb()});BlockMix(V,(N-1)*blockSize32,B32,Pi,r);blockMixCb();await asyncLoop(N,asyncTick,()=>{const j=B32[Pi+blockSize32-16]%N;for(let k=0;kmod(mod(x*x)*x+CURVE.b);const err=(m="")=>{throw new Error(m)};const big=n=>typeof n==="bigint";const str=s=>typeof s==="string";const fe=n=>big(n)&&0nbig(n)&&0n!(a instanceof Uint8Array)||typeof l==="number"&&l>0&&a.length!==l?err("Uint8Array expected"):a;const u8n=data=>new Uint8Array(data);const toU8=(a,len)=>au8(str(a)?h2b(a):u8n(a),len);const mod=(a,b=P)=>{let r=a%b;return r>=0n?r:b+r};const isPoint=p=>p instanceof Point?p:err("Point expected");let Gpows=undefined;class Point{constructor(px,py,pz){this.px=px;this.py=py;this.pz=pz}static fromAffine(p){return new Point(p.x,p.y,1n)}static fromHex(hex){hex=toU8(hex);let p=undefined;const head=hex[0],tail=hex.subarray(1);const x=slcNum(tail,0,fLen),len=hex.length;if(len===33&&[2,3].includes(head)){if(!fe(x))err("Point hex invalid: x not FE");let y=sqrt(crv(x));const isYOdd=(y&1n)===1n;const headOdd=(head&1)===1;if(headOdd!==isYOdd)y=mod(-y);p=new Point(x,y,1n)}if(len===65&&head===4)p=new Point(x,slcNum(tail,fLen,2*fLen),1n);return p?p.ok():err("Point is not on curve")}static fromPrivateKey(k){return G.mul(toPriv(k))}get x(){return this.aff().x}get y(){return this.aff().y}equals(other){const{px:X1,py:Y1,pz:Z1}=this;const{px:X2,py:Y2,pz:Z2}=isPoint(other);const X1Z2=mod(X1*Z2),X2Z1=mod(X2*Z1);const Y1Z2=mod(Y1*Z2),Y2Z1=mod(Y2*Z1);return X1Z2===X2Z1&&Y1Z2===Y2Z1}negate(){return new Point(this.px,mod(-this.py),this.pz)}double(){return this.add(this)}add(other){const{px:X1,py:Y1,pz:Z1}=this;const{px:X2,py:Y2,pz:Z2}=isPoint(other);const{a,b}=CURVE;let X3=0n,Y3=0n,Z3=0n;const b3=mod(b*3n);let t0=mod(X1*X2),t1=mod(Y1*Y2),t2=mod(Z1*Z2),t3=mod(X1+Y1);let t4=mod(X2+Y2);t3=mod(t3*t4);t4=mod(t0+t1);t3=mod(t3-t4);t4=mod(X1+Z1);let t5=mod(X2+Z2);t4=mod(t4*t5);t5=mod(t0+t2);t4=mod(t4-t5);t5=mod(Y1+Z1);X3=mod(Y2+Z2);t5=mod(t5*X3);X3=mod(t1+t2);t5=mod(t5-X3);Z3=mod(a*t4);X3=mod(b3*t2);Z3=mod(X3+Z3);X3=mod(t1-Z3);Z3=mod(t1+Z3);Y3=mod(X3*Z3);t1=mod(t0+t0);t1=mod(t1+t0);t2=mod(a*t2);t4=mod(b3*t4);t1=mod(t1+t2);t2=mod(t0-t2);t2=mod(a*t2);t4=mod(t4+t2);t0=mod(t1*t4);Y3=mod(Y3+t0);t0=mod(t5*t4);X3=mod(t3*X3);X3=mod(X3-t0);t0=mod(t3*t1);Z3=mod(t5*Z3);Z3=mod(Z3+t0);return new Point(X3,Y3,Z3)}mul(n,safe=true){if(!safe&&n===0n)return I;if(!ge(n))err("invalid scalar");if(this.equals(G))return wNAF(n).p;let p=I,f=G;for(let d=this;n>0n;d=d.double(),n>>=1n){if(n&1n)p=p.add(d);else if(safe)f=f.add(d)}return p}mulAddQUns(R,u1,u2){return this.mul(u1,false).add(R.mul(u2,false)).ok()}toAffine(){const{px:x,py:y,pz:z}=this;if(this.equals(I))return{x:0n,y:0n};if(z===1n)return{x:x,y:y};const iz=inv(z);if(mod(z*iz)!==1n)err("invalid inverse");return{x:mod(x*iz),y:mod(y*iz)}}assertValidity(){const{x,y}=this.aff();if(!fe(x)||!fe(y))err("Point invalid: x or y");return mod(y*y)===crv(x)?this:err("Point invalid: not on curve")}multiply(n){return this.mul(n)}aff(){return this.toAffine()}ok(){return this.assertValidity()}toHex(isCompressed=true){const{x,y}=this.aff();const head=isCompressed?(y&1n)===0n?"02":"03":"04";return head+n2h(x)+(isCompressed?"":n2h(y))}toRawBytes(isCompressed=true){return h2b(this.toHex(isCompressed))}}Point.BASE=new Point(Gx,Gy,1n);Point.ZERO=new Point(0n,1n,0n);const{BASE:G,ZERO:I}=Point;const padh=(n,pad)=>n.toString(16).padStart(pad,"0");const b2h=b=>Array.from(b).map(e=>padh(e,2)).join("");const h2b=hex=>{const l=hex.length;if(!str(hex)||l%2)err("hex invalid 1");const arr=u8n(l/2);for(let i=0;iBigInt("0x"+(b2h(b)||"0"));const slcNum=(b,from,to)=>b2n(b.slice(from,to));const n2b=num=>{return big(num)&&num>=0n&&numb2h(n2b(num));const inv=(num,md=P)=>{if(num===0n||md<=0n)err("no inverse n="+num+" mod="+md);let a=mod(num,md),b=md,x=0n,u=1n;while(a!==0n){const q=b/a,r=b%a;const m=x-u*q;b=a,a=r,x=u,u=m}return b===1n?mod(x,md):err("no inverse")};const sqrt=n=>{let r=1n;for(let num=n,e=(P+1n)/4n;e>0n;e>>=1n){if(e&1n)r=r*num%P;num=num*num%P}return mod(r*r)===n?r:err("sqrt invalid")};const toPriv=p=>{if(!big(p))p=b2n(toU8(p,fLen));return ge(p)?p:err("private key out of range")};function getSharedSecret(privA,pubB,isCompressed=true){return Point.fromHex(pubB).mul(toPriv(privA)).toRawBytes(isCompressed)}const W=8;const precompute=()=>{const points=[];const windows=256/W+1;let p=G,b=p;for(let w=0;w{const comp=Gpows||(Gpows=precompute());const neg=(cnd,p)=>{let n=p.negate();return cnd?n:p};let p=I,f=G;const windows=1+256/W;const wsize=2**(W-1);const mask=BigInt(2**W-1);const maxNum=2**W;const shiftBy=BigInt(W);for(let w=0;w>=shiftBy;if(wbits>wsize){wbits-=maxNum;n+=1n}const off1=off,off2=off+Math.abs(wbits)-1;const cnd1=w%2!==0,cnd2=wbits<0;if(wbits===0){f=f.add(neg(cnd1,comp[off1]))}else{p=p.add(neg(cnd2,comp[off2]))}}return{p:p,f:f}};const logger$2=new Logger("signing-key/0.0.1");class SigningKey{#privateKey;constructor(privateKey){let tmp=privateKey;if(typeof tmp==="string"&&tmp.startsWith("0x")){tmp=tmp.replace("0x","")}assertArgument(dataLength("0x"+tmp)===57,"invalid private key","privateKey","[REDACTED]");this.#privateKey=hexlify("0x"+tmp)}get privateKey(){return this.#privateKey}get publicKey(){return SigningKey.computePublicKey(this.#privateKey)}get compressedPublicKey(){return SigningKey.computePublicKey(this.#privateKey,true)}sign(digest){const key=getBytesCopy(this.#privateKey);assertArgument(dataLength(digest)===32,"invalid digest length","digest",digest);const keyBuffer=new Uint8Array(arrayify(key));if(keyBuffer.length!==57){logger$2.throwArgumentError("invalid private key","key","[REDACTED]")}const digestBuffer=new Uint8Array(arrayify(digest));if(digestBuffer.length!==32){logger$2.throwArgumentError("bad digest length","digest",digest)}if(keyBuffer[56]>127){const prefix=keyBuffer.slice(0,57);prefix[0]&=252;prefix[55]|=128;prefix[56]=0;const scalar=prefix.slice(0,56);const bufferDigest=Buffer$1.from(digestBuffer);const bufferPrfx=Buffer$1.from(prefix);const bufferScalar=Buffer$1.from(scalar);const sig=ed448.signWithScalar(bufferDigest,bufferScalar,bufferPrfx);const hexlified=hexlify(sig);return hexConcat([hexlified,this.publicKey])}const sig=ed448.sign(Buffer$1.from(digestBuffer),Buffer$1.from(keyBuffer));const hexlified=hexlify(sig);return hexConcat([hexlified,this.publicKey])}computeSharedSecret(other){const pubKey=SigningKey.computePublicKey(other);return hexlify(getSharedSecret(getBytesCopy(this.#privateKey),getBytes(pubKey)))}static computePublicKey(key,compressed){const bytes=Buffer$1.from(arrayify(key));if(bytes.length!==57){logger$2.throwArgumentError("invalid private key","key","[REDACTED]")}if(bytes[56]>127){const scalar=bytes.slice(0,56);scalar[0]&=252;scalar[55]|=128;const pub=ed448.publicKeyFromScalar(scalar);return hexlify(pub)}const pub=ed448.publicKeyCreate(bytes);return hexlify(pub)}static recoverPublicKey(digest,signature){assertArgument(dataLength(digest)===32,"invalid digest length","digest",digest);const digestBuffer=Buffer$1.from(arrayify(digest));const sigBuffer=Buffer$1.from(arrayify(signature));if(sigBuffer.length!==171){logger$2.throwArgumentError("invalid signature","signature",signature)}const sig=sigBuffer.slice(0,114);const pub=sigBuffer.slice(114);if(ed448.verify(digestBuffer,sig,pub)){return hexlify(pub)}logger$2.throwArgumentError("invalid signature","signature",signature);return""}static addPoints(p0,p1,compressed){const pub0=Point.fromHex(SigningKey.computePublicKey(p0).substring(2));const pub1=Point.fromHex(SigningKey.computePublicKey(p1).substring(2));return"0x"+pub0.add(pub1).toHex(!!compressed)}}const BN_0$6=BigInt(0);const BN_1$3=BigInt(1);const BN_2$1=BigInt(2);const BN_27=BigInt(27);const BN_28=BigInt(28);const BN_35=BigInt(35);const _guard$4={};class Signature{#r;#s;#v;#networkV;get r(){return this.#r}set r(value){assertArgument(dataLength(value)===32,"invalid r","value",value);this.#r=hexlify(value)}get s(){return this.#s}set s(_value){assertArgument(dataLength(_value)===32,"invalid s","value",_value);const value=hexlify(_value);assertArgument(parseInt(value.substring(0,3))<8,"non-canonical s","value",value);this.#s=value}get v(){return this.#v}set v(value){const v=getNumber(value,"value");assertArgument(v===27||v===28,"invalid v","v",value);this.#v=v}get networkV(){return this.#networkV}get legacynetworkId(){const v=this.networkV;if(v==null){return null}return Signature.getnetworkId(v)}get yParity(){return this.v===27?0:1}get yParityAndS(){const yParityAndS=getBytes(this.s);if(this.yParity){yParityAndS[0]|=128}return hexlify(yParityAndS)}get compactSerialized(){return concat([this.r,this.yParityAndS])}get serialized(){return concat([this.r,this.s,this.yParity?"0x1c":"0x1b"])}constructor(guard,r,s,v){assertPrivate(guard,_guard$4,"Signature");this.#r=r;this.#s=s;this.#v=v;this.#networkV=null}[Symbol.for("nodejs.util.inspect.custom")](){return`Signature { r: "${this.r}", s: "${this.s}", yParity: ${this.yParity}, networkV: ${this.networkV} }`}clone(){const clone=new Signature(_guard$4,this.r,this.s,this.v);if(this.networkV){clone.#networkV=this.networkV}return clone}toJSON(){const networkV=this.networkV;return{_type:"signature",networkV:networkV!=null?networkV.toString():null,r:this.r,s:this.s,v:this.v}}static getnetworkId(v){const bv=getBigInt(v,"v");if(bv==BN_27||bv==BN_28){return BN_0$6}assertArgument(bv>=BN_35,"invalid EIP-155 v","v",v);return(bv-BN_35)/BN_2$1}static getnetworkIdV(networkId,v){return getBigInt(networkId)*BN_2$1+BigInt(35+v-27)}static getNormalizedV(v){const bv=getBigInt(v);if(bv===BN_0$6||bv===BN_27){return 27}if(bv===BN_1$3||bv===BN_28){return 28}assertArgument(bv>=BN_35,"invalid v","v",v);return bv&BN_1$3?27:28}}function lock(){computeHmac.lock();pbkdf2.lock();randomBytes.lock();ripemd160.lock();scrypt.lock();scryptSync.lock();sha256.lock();sha512.lock();randomBytes.lock()}function removeHexPrefix(val){return val.substring(0,2)==="0x"?val.substring(2):val}function publicToAddress(key,prefix){const val=hexDataSlice(sha256(key),12);const checksum=calculateCheckSum(val,prefix);return"0x"+prefix+checksum+removeHexPrefix(val)}function computeAddress(key,prefix){let pubkey;if(typeof key==="string"){pubkey=SigningKey.computePublicKey(key,false)}else{pubkey=key.publicKey}return publicToAddress(pubkey,prefix)}function recoverAddress(digest,signature,prefix){const publicKey=SigningKey.recoverPublicKey(arrayify(digest),signature);return publicToAddress(publicKey,prefix)}function extractPrefix(address){address=getAddress(address);return address.substring(2,4)}const WordSize=32;const Padding=new Uint8Array(WordSize);const passProperties$1=["then"];const _guard$3={};function throwError(name,error){const wrapped=new Error(`deferred error during ABI decoding triggered accessing ${name}`);wrapped.error=error;throw wrapped}class Result extends Array{#names;constructor(...args){const guard=args[0];let items=args[1];let names=(args[2]||[]).slice();let wrap=true;if(guard!==_guard$3){items=args;names=[];wrap=false}super(items.length);items.forEach((item,index)=>{this[index]=item});const nameCounts=names.reduce((accum,name)=>{if(typeof name==="string"){accum.set(name,(accum.get(name)||0)+1)}return accum},new Map);this.#names=Object.freeze(items.map((item,index)=>{const name=names[index];if(name!=null&&nameCounts.get(name)===1){return name}return null}));if(!wrap){return}Object.freeze(this);return new Proxy(this,{get:(target,prop,receiver)=>{if(typeof prop==="string"){if(prop.match(/^[0-9]+$/)){const index=getNumber(prop,"%index");if(index<0||index>=this.length){throw new RangeError("out of result range")}const item=target[index];if(item instanceof Error){throwError(`index ${index}`,item)}return item}if(passProperties$1.indexOf(prop)>=0){return Reflect.get(target,prop,receiver)}const value=target[prop];if(value instanceof Function){return function(...args){return value.apply(this===receiver?target:this,args)}}else if(!(prop in target)){return target.getValue.apply(this===receiver?target:this,[prop])}}return Reflect.get(target,prop,receiver)}})}toArray(){const result=[];this.forEach((item,index)=>{if(item instanceof Error){throwError(`index ${index}`,item)}result.push(item)});return result}toObject(){return this.#names.reduce((accum,name,index)=>{assert(name!=null,"value at index ${ index } unnamed","UNSUPPORTED_OPERATION",{operation:"toObject()"});if(!(name in accum)){accum[name]=this.getValue(name)}return accum},{})}slice(start,end){if(start==null){start=0}if(start<0){start+=this.length;if(start<0){start=0}}if(end==null){end=this.length}if(end<0){end+=this.length;if(end<0){end=0}}if(end>this.length){end=this.length}const result=[],names=[];for(let i=start;i{this.#data[offset]=getValue$1(value)}}}class Reader{allowLoose;#data;#offset;constructor(data,allowLoose){defineProperties(this,{allowLoose:!!allowLoose});this.#data=getBytesCopy(data);this.#offset=0}get data(){return hexlify(this.#data)}get dataLength(){return this.#data.length}get consumed(){return this.#offset}get bytes(){return new Uint8Array(this.#data)}#peekBytes(offset,length,loose){let alignedLength=Math.ceil(length/WordSize)*WordSize;if(this.#offset+alignedLength>this.#data.length){if(this.allowLoose&&loose&&this.#offset+length<=this.#data.length){alignedLength=length}else{assert(false,"data out-of-bounds","BUFFER_OVERRUN",{buffer:getBytesCopy(this.#data),length:this.#data.length,offset:this.#offset+alignedLength})}}return this.#data.slice(this.#offset,this.#offset+alignedLength)}subReader(offset){return new Reader(this.#data.slice(this.#offset+offset),this.allowLoose)}readBytes(length,loose){let bytes=this.#peekBytes(0,length,!!loose);this.#offset+=bytes.length;return bytes.slice(0,length)}readValue(){return toBigInt(this.readBytes(WordSize))}readIndex(){return toNumber(this.readBytes(WordSize))}}const _gaurd={};function n(value,width){let signed=false;if(width<0){signed=true;width*=-1}return new Typed(_gaurd,`${signed?"":"u"}int${width}`,value,{signed:signed,width:width})}function b(value,size){return new Typed(_gaurd,`bytes${size?size:""}`,value,{size:size})}const _typedSymbol=Symbol.for("_corebc_typed");class Typed{type;value;#options;_typedSymbol;constructor(gaurd,type,value,options){if(options==null){options=null}assertPrivate(_gaurd,gaurd,"Typed");defineProperties(this,{_typedSymbol:_typedSymbol,type:type,value:value});this.#options=options;this.format()}format(){if(this.type==="array"){throw new Error("")}else if(this.type==="dynamicArray"){throw new Error("")}else if(this.type==="tuple"){return`tuple(${this.value.map(v=>v.format()).join(",")})`}return this.type}defaultValue(){return 0}minValue(){return 0}maxValue(){return 0}isBigInt(){return!!this.type.match(/^u?int[0-9]+$/)}isData(){return this.type.startsWith("bytes")}isString(){return this.type==="string"}get tupleName(){if(this.type!=="tuple"){throw TypeError("not a tuple")}return this.#options}get arrayLength(){if(this.type!=="array"){throw TypeError("not an array")}if(this.#options===true){return-1}if(this.#options===false){return this.value.length}return null}static from(type,value){return new Typed(_gaurd,type,value)}static uint8(v){return n(v,8)}static uint16(v){return n(v,16)}static uint24(v){return n(v,24)}static uint32(v){return n(v,32)}static uint40(v){return n(v,40)}static uint48(v){return n(v,48)}static uint56(v){return n(v,56)}static uint64(v){return n(v,64)}static uint72(v){return n(v,72)}static uint80(v){return n(v,80)}static uint88(v){return n(v,88)}static uint96(v){return n(v,96)}static uint104(v){return n(v,104)}static uint112(v){return n(v,112)}static uint120(v){return n(v,120)}static uint128(v){return n(v,128)}static uint136(v){return n(v,136)}static uint144(v){return n(v,144)}static uint152(v){return n(v,152)}static uint160(v){return n(v,160)}static uint168(v){return n(v,168)}static uint176(v){return n(v,176)}static uint184(v){return n(v,184)}static uint192(v){return n(v,192)}static uint200(v){return n(v,200)}static uint208(v){return n(v,208)}static uint216(v){return n(v,216)}static uint224(v){return n(v,224)}static uint232(v){return n(v,232)}static uint240(v){return n(v,240)}static uint248(v){return n(v,248)}static uint256(v){return n(v,256)}static uint(v){return n(v,256)}static int8(v){return n(v,-8)}static int16(v){return n(v,-16)}static int24(v){return n(v,-24)}static int32(v){return n(v,-32)}static int40(v){return n(v,-40)}static int48(v){return n(v,-48)}static int56(v){return n(v,-56)}static int64(v){return n(v,-64)}static int72(v){return n(v,-72)}static int80(v){return n(v,-80)}static int88(v){return n(v,-88)}static int96(v){return n(v,-96)}static int104(v){return n(v,-104)}static int112(v){return n(v,-112)}static int120(v){return n(v,-120)}static int128(v){return n(v,-128)}static int136(v){return n(v,-136)}static int144(v){return n(v,-144)}static int152(v){return n(v,-152)}static int160(v){return n(v,-160)}static int168(v){return n(v,-168)}static int176(v){return n(v,-176)}static int184(v){return n(v,-184)}static int192(v){return n(v,-192)}static int200(v){return n(v,-200)}static int208(v){return n(v,-208)}static int216(v){return n(v,-216)}static int224(v){return n(v,-224)}static int232(v){return n(v,-232)}static int240(v){return n(v,-240)}static int248(v){return n(v,-248)}static int256(v){return n(v,-256)}static int(v){return n(v,-256)}static bytes1(v){return b(v,1)}static bytes2(v){return b(v,2)}static bytes3(v){return b(v,3)}static bytes4(v){return b(v,4)}static bytes5(v){return b(v,5)}static bytes6(v){return b(v,6)}static bytes7(v){return b(v,7)}static bytes8(v){return b(v,8)}static bytes9(v){return b(v,9)}static bytes10(v){return b(v,10)}static bytes11(v){return b(v,11)}static bytes12(v){return b(v,12)}static bytes13(v){return b(v,13)}static bytes14(v){return b(v,14)}static bytes15(v){return b(v,15)}static bytes16(v){return b(v,16)}static bytes17(v){return b(v,17)}static bytes18(v){return b(v,18)}static bytes19(v){return b(v,19)}static bytes20(v){return b(v,20)}static bytes21(v){return b(v,21)}static bytes22(v){return b(v,22)}static bytes23(v){return b(v,23)}static bytes24(v){return b(v,24)}static bytes25(v){return b(v,25)}static bytes26(v){return b(v,26)}static bytes27(v){return b(v,27)}static bytes28(v){return b(v,28)}static bytes29(v){return b(v,29)}static bytes30(v){return b(v,30)}static bytes31(v){return b(v,31)}static bytes32(v){return b(v,32)}static address(v){return new Typed(_gaurd,"address",v)}static bool(v){return new Typed(_gaurd,"bool",!!v)}static bytes(v){return new Typed(_gaurd,"bytes",v)}static string(v){return new Typed(_gaurd,"string",v)}static array(v,dynamic){throw new Error("not implemented yet")}static tuple(v,name){throw new Error("not implemented yet")}static overrides(v){return new Typed(_gaurd,"overrides",Object.assign({},v))}static isTyped(value){return value&&value._typedSymbol===_typedSymbol}static dereference(value,type){if(Typed.isTyped(value)){if(value.type!==type){throw new Error(`invalid type: expecetd ${type}, got ${value.type}`)}return value.value}return value}}class AddressCoder extends Coder{constructor(localName){super("address","address",localName,false)}defaultValue(){return"0x0000000000000000000000000000000000000000"}encode(writer,_value){let value=Typed.dereference(_value,"string");try{value=getAddress(value)}catch(error){return this._throwError(error.message,_value)}return writer.writeValue(value)}decode(reader){return getAddress(toBeHex(reader.readValue(),22))}}class AnonymousCoder extends Coder{coder;constructor(coder){super(coder.name,coder.type,"_",coder.dynamic);this.coder=coder}defaultValue(){return this.coder.defaultValue()}encode(writer,value){return this.coder.encode(writer,value)}decode(reader){return this.coder.decode(reader)}}function pack(writer,coders,values){let arrayValues=[];if(Array.isArray(values)){arrayValues=values}else if(values&&typeof values==="object"){let unique={};arrayValues=coders.map(coder=>{const name=coder.localName;assert(name,"cannot encode object for signature with missing names","INVALID_ARGUMENT",{argument:"values",info:{coder:coder},value:values});assert(!unique[name],"cannot encode object for signature with duplicate names","INVALID_ARGUMENT",{argument:"values",info:{coder:coder},value:values});unique[name]=true;return values[name]})}else{assertArgument(false,"invalid tuple value","tuple",values)}assertArgument(coders.length===arrayValues.length,"types/value length mismatch","tuple",values);let staticWriter=new Writer;let dynamicWriter=new Writer;let updateFuncs=[];coders.forEach((coder,index)=>{let value=arrayValues[index];if(coder.dynamic){let dynamicOffset=dynamicWriter.length;coder.encode(dynamicWriter,value);let updateFunc=staticWriter.writeUpdatableValue();updateFuncs.push(baseOffset=>{updateFunc(baseOffset+dynamicOffset)})}else{coder.encode(staticWriter,value)}});updateFuncs.forEach(func=>{func(staticWriter.length)});let length=writer.appendWriter(staticWriter);length+=writer.appendWriter(dynamicWriter);return length}function unpack(reader,coders){let values=[];let keys=[];let baseReader=reader.subReader(0);coders.forEach(coder=>{let value=null;if(coder.dynamic){let offset=reader.readIndex();let offsetReader=baseReader.subReader(offset);try{value=coder.decode(offsetReader)}catch(error){if(isError(error,"BUFFER_OVERRUN")){throw error}value=error;value.baseType=coder.name;value.name=coder.localName;value.type=coder.type}}else{try{value=coder.decode(reader)}catch(error){if(isError(error,"BUFFER_OVERRUN")){throw error}value=error;value.baseType=coder.name;value.name=coder.localName;value.type=coder.type}}if(value==undefined){throw new Error("investigate")}values.push(value);keys.push(coder.localName||null)});return Result.fromItems(values,keys)}class ArrayCoder extends Coder{coder;length;constructor(coder,length,localName){const type=coder.type+"["+(length>=0?length:"")+"]";const dynamic=length===-1||coder.dynamic;super("array",type,localName,dynamic);defineProperties(this,{coder:coder,length:length})}defaultValue(){const defaultChild=this.coder.defaultValue();const result=[];for(let i=0;ibounds||value<-(bounds+BN_1$2)){this._throwError("value out-of-bounds",_value)}value=toTwos(value,8*WordSize)}else if(valuemask(maxUintValue,this.size*8)){this._throwError("value out-of-bounds",_value)}return writer.writeValue(value)}decode(reader){let value=mask(reader.readValue(),this.size*8);if(this.signed){value=fromTwos(value,this.size*8)}return value}}class StringCoder extends DynamicBytesCoder{constructor(localName){super("string",localName)}defaultValue(){return""}encode(writer,_value){return super.encode(writer,toUtf8Bytes(Typed.dereference(_value,"string")))}decode(reader){return toUtf8String(super.decode(reader))}}class TupleCoder extends Coder{coders;constructor(coders,localName){let dynamic=false;const types=[];coders.forEach(coder=>{if(coder.dynamic){dynamic=true}types.push(coder.type)});const type="tuple("+types.join(",")+")";super("tuple",type,localName,dynamic);defineProperties(this,{coders:Object.freeze(coders.slice())})}defaultValue(){const values=[];this.coders.forEach(coder=>{values.push(coder.defaultValue())});const uniqueNames=this.coders.reduce((accum,coder)=>{const name=coder.localName;if(name){if(!accum[name]){accum[name]=0}accum[name]++}return accum},{});this.coders.forEach((coder,index)=>{let name=coder.localName;if(!name||uniqueNames[name]!==1){return}if(name==="length"){name="_length"}if(values[name]!=null){return}values[name]=values[index]});return Object.freeze(values)}encode(writer,_value){const value=Typed.dereference(_value,"tuple");return pack(writer,this.coders,value)}decode(reader){return unpack(reader,this.coders)}}function id(value,useKeccak){if(useKeccak){return keccak256(toUtf8Bytes(value))}return sha256(toUtf8Bytes(value))}const ZeroAddress="0x0000000000000000000000000000000000000000";const ZeroHash="0x0000000000000000000000000000000000000000000000000000000000000000";const N=BigInt("0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141");const OrePerXCB=BigInt("1000000000000000000");const MaxUint256=BigInt("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");const MinInt256=BigInt("0x8000000000000000000000000000000000000000000000000000000000000000")*BigInt(-1);const MaxInt256=BigInt("0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");const CoreSymbol="Ξ";const MessagePrefix="Core Signed Message:\n";function accessSetify(addr,storageKeys){return{address:getAddress(addr),storageKeys:storageKeys.map((storageKey,index)=>{assertArgument(isHexString(storageKey,32),"invalid slot",`storageKeys[${index}]`,storageKey);return storageKey.toLowerCase()})}}function accessListify(value){if(Array.isArray(value)){return value.map((set,index)=>{if(Array.isArray(set)){assertArgument(set.length===2,"invalid slot set",`value[${index}]`,set);return accessSetify(set[0],set[1])}assertArgument(set!=null&&typeof set==="object","invalid address-slot set","value",value);return accessSetify(set.address,set.storageKeys)})}assertArgument(value!=null&&typeof value==="object","invalid access list","value",value);const result=Object.keys(value).map(addr=>{const storageKeys=value[addr].reduce((accum,storageKey)=>{accum[storageKey]=true;return accum},{});return accessSetify(addr,Object.keys(storageKeys).sort())});result.sort((a,b)=>a.address.localeCompare(b.address));return result}const logger$1=new Logger("transaction/0.0.1");const BN_0$4=BigInt(0);function handleAddress(value){if(value==="0x"){return null}return getAddress(value)}function parse(data){const handleNumber=value=>{if(value==="0x"){return BigNumber.from(0)}return BigNumber.from(value)};const transaction=decode$1(data);if(transaction.length!==7&&transaction.length!==8){logger$1.throwArgumentError("invalid raw transaction","data",data)}const isSigned=transaction.length===8;const tx={nonce:Number(handleNumber(transaction[0])),energyPrice:handleNumber(transaction[1]).toBigInt(),energyLimit:handleNumber(transaction[2]).toBigInt(),networkId:handleNumber(transaction[isSigned?3:6]).toBigInt(),to:handleAddress(transaction[isSigned?4:3]),value:handleNumber(transaction[isSigned?5:4]).toBigInt(),data:transaction[isSigned?6:5]};if(transaction.length===8){const prefix=networkIdToPrefix(Number(tx.networkId));const digest=sha256(serialize(tx));tx.hash=sha256(serialize(tx,transaction[7]));tx.from=recoverAddress(digest,transaction[7],prefix);tx.signature=transaction[7]}return tx}const unsignedTransactionFields=[{name:"nonce",maxLength:32,numeric:true},{name:"energyPrice",maxLength:32,numeric:true},{name:"energyLimit",maxLength:32,numeric:true},{name:"to",length:22},{name:"value",maxLength:32,numeric:true},{name:"data"},{name:"networkId",maxLength:32,numeric:true}];const transactionFields=[{name:"nonce",maxLength:32,numeric:true},{name:"energyPrice",maxLength:32,numeric:true},{name:"energyLimit",maxLength:32,numeric:true},{name:"networkId",maxLength:32,numeric:true},{name:"to",length:22},{name:"value",maxLength:32,numeric:true},{name:"data"}];const allowedTransactionKeys={networkId:true,data:true,energyLimit:true,energyPrice:true,nonce:true,to:true,value:true};function serialize(transaction,signature){checkProperties(transaction,allowedTransactionKeys);const raw=[];(!!signature?transactionFields:unsignedTransactionFields).forEach(function({numeric,maxLength,name,length}){let value=transaction[name]||[];const options={};if(numeric){options.hexPad="left"}const tmpHexlified=hexlify(value,options);value=arrayify(tmpHexlified);if(length&&value.length!==length&&value.length>0){logger$1.throwArgumentError("invalid length for "+name,"transaction:"+name,value)}if(maxLength){value=stripZeros(value);if(value.length>maxLength){logger$1.throwArgumentError("invalid length for "+name,"transaction:"+name,value)}}const hexlified=hexlify(value);raw.push(hexlified)});if(!!signature){raw.push(hexlify(signature))}const finalValue=encode(raw);return finalValue}class Transaction{#to;#data;#nonce;#energyLimit;#energyPrice;#value;#networkId;#sig;get to(){return this.#to}set to(value){this.#to=value==null?null:getAddress(value)}get nonce(){return this.#nonce}set nonce(value){this.#nonce=getNumber(value,"value")}get energyLimit(){return this.#energyLimit}set energyLimit(value){this.#energyLimit=getBigInt(value)}get energyPrice(){const value=this.#energyPrice;if(value==null){return BN_0$4}return value}set energyPrice(value){this.#energyPrice=value==null?null:getBigInt(value,"energyPrice")}get data(){return this.#data}set data(value){this.#data=hexlify(value)}get value(){return this.#value}set value(value){this.#value=getBigInt(value,"value")}get networkId(){return this.#networkId}set networkId(value){this.#networkId=getBigInt(value)}get signature(){return this.#sig||null}set signature(value){this.#sig=value==null?null:value}constructor(){this.#to=null;this.#nonce=0;this.#energyLimit=BigInt(0);this.#energyPrice=null;this.#data="0x";this.#value=BigInt(0);this.#networkId=BigInt(0);this.#sig=null}get hash(){if(this.signature==null){return null}return sha256(this.serialized)}get unsignedHash(){return sha256(this.unsignedSerialized)}get from(){if(this.signature==null){return null}const prefix=networkIdToPrefix(Number(this.#networkId));return recoverAddress(this.unsignedHash,this.signature,prefix)}get fromPublicKey(){if(this.signature==null){return null}return SigningKey.recoverPublicKey(this.unsignedHash,this.signature)}isSigned(){return this.signature!=null}get serialized(){assert(this.signature!=null,"cannot serialize unsigned transaction; maybe you meant .unsignedSerialized","UNSUPPORTED_OPERATION",{operation:".serialized"});return serialize(this,this.signature)}get unsignedSerialized(){return serialize(this)}clone(){return Transaction.from(this)}toJSON(){const s=v=>{if(v==null){return null}return v.toString()};return{to:this.to,data:this.data,nonce:this.nonce,energyLimit:s(this.energyLimit),energyPrice:s(this.energyPrice),value:s(this.value),networkId:s(this.networkId),sig:this.signature?this.signature:null}}static from(tx){if(tx==null){return new Transaction}if(typeof tx==="string"){const payload=getBytes(tx);return Transaction.from(parse(payload))}const result=new Transaction;if(tx.to!=null){result.to=tx.to}if(tx.nonce!=null){result.nonce=tx.nonce}if(tx.energyLimit!=null){result.energyLimit=tx.energyLimit}if(tx.energyPrice!=null){result.energyPrice=tx.energyPrice}if(tx.data!=null){result.data=tx.data}if(tx.value!=null){result.value=tx.value}if(tx.networkId!=null){result.networkId=tx.networkId}if(tx.signature!=null){result.signature=tx.signature}if(tx.hash!=null){assertArgument(result.isSigned(),"unsigned transaction cannot define hash","tx",tx);assertArgument(result.hash===tx.hash,"hash mismatch","tx",tx)}if(tx.from!=null){assertArgument(result.isSigned(),"unsigned transaction cannot define from","tx",tx);assertArgument(result.from.toLowerCase()===(tx.from||"").toLowerCase(),"from mismatch","tx",tx)}return result}}function hashMessage(message){if(typeof message==="string"){message=toUtf8Bytes(message)}return sha256(concat([toUtf8Bytes(MessagePrefix),toUtf8Bytes(String(message.length)),message]))}function verifyMessage(message,sig,prefix){const digest=hashMessage(message);return recoverAddress(digest,sig,prefix)}const regexBytes=new RegExp("^bytes([0-9]+)$");const regexNumber=new RegExp("^(u?int)([0-9]*)$");const regexArray=new RegExp("^(.*)\\[([0-9]*)\\]$");function _pack(type,value,isArray){switch(type){case"address":if(isArray){return getBytes(zeroPadValue(value,32))}return getBytes(getAddress(value));case"string":return toUtf8Bytes(value);case"bytes":return getBytes(value);case"bool":value=!!value?"0x01":"0x00";if(isArray){return getBytes(zeroPadValue(value,32))}return getBytes(value)}let match=type.match(regexNumber);if(match){let signed=match[1]==="int";let size=parseInt(match[2]||"256");assertArgument((!match[2]||match[2]===String(size))&&size%8===0&&size!==0&&size<=256,"invalid number type","type",type);if(isArray){size=256}if(signed){value=toTwos(value,size)}return getBytes(zeroPadValue(toBeArray(value),size/8))}match=type.match(regexBytes);if(match){const size=parseInt(match[1]);assertArgument(String(size)===match[1]&&size!==0&&size<=32,"invalid bytes type","type",type);assertArgument(dataLength(value)===size,`invalid value for ${type}`,"value",value);if(isArray){return getBytes(zeroPadBytes(value,32))}return value}match=type.match(regexArray);if(match&&Array.isArray(value)){const baseType=match[1];const count=parseInt(match[2]||String(value.length));assertArgument(count===value.length,`invalid array length for ${type}`,"value",value);const result=[];value.forEach(function(value){result.push(_pack(baseType,value,true))});return getBytes(concat(result))}assertArgument(false,"invalid type","type",type)}function solidityPacked(types,values){assertArgument(types.length===values.length,"wrong number of values; expected ${ types.length }","values",values);const tight=[];types.forEach(function(type,index){tight.push(_pack(type,values[index]))});return hexlify(concat(tight))}function solidityPackedSha256(types,values){return sha256(solidityPacked(types,values))}const padding=new Uint8Array(32);padding.fill(0);const BN__1=BigInt(-1);const BN_0$3=BigInt(0);const BN_1$1=BigInt(1);const BN_MAX_UINT256=BigInt("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");function hexPadRight(value){const bytes=getBytes(value);const padOffset=bytes.length%32;if(padOffset){return concat([bytes,padding.slice(padOffset)])}return hexlify(bytes)}const hexTrue=toBeHex(BN_1$1,32);const hexFalse=toBeHex(BN_0$3,32);const domainFieldTypes={name:"string",version:"string",networkId:"uint256",verifyingContract:"address",salt:"bytes32"};const domainFieldNames=["name","version","networkId","verifyingContract","salt"];function checkString(key){return function(value){assertArgument(typeof value==="string",`invalid domain value for ${JSON.stringify(key)}`,`domain.${key}`,value);return value}}const domainChecks={name:checkString("name"),version:checkString("version"),networkId:function(_value){const value=getBigInt(_value,"domain.networkId");assertArgument(value>=0,"invalid chain ID","domain.networkId",_value);if(Number.isSafeInteger(value)){return Number(value)}return toQuantity(value)},verifyingContract:function(value){try{return getAddress(value).toLowerCase()}catch(error){}assertArgument(false,`invalid domain value "verifyingContract"`,"domain.verifyingContract",value)},salt:function(value){const bytes=getBytes(value,"domain.salt");assertArgument(bytes.length===32,`invalid domain value "salt"`,"domain.salt",value);return hexlify(bytes)}};function getBaseEncoder(type){{const match=type.match(/^(u?)int(\d*)$/);if(match){const signed=match[1]==="";const width=parseInt(match[2]||"256");assertArgument(width%8===0&&width!==0&&width<=256&&(match[2]==null||match[2]===String(width)),"invalid numeric width","type",type);const boundsUpper=mask(BN_MAX_UINT256,signed?width-1:width);const boundsLower=signed?(boundsUpper+BN_1$1)*BN__1:BN_0$3;return function(_value){const value=getBigInt(_value,"value");assertArgument(value>=boundsLower&&value<=boundsUpper,`value out-of-bounds for ${type}`,"value",value);return toBeHex(signed?toTwos(value,256):value,32)}}}{const match=type.match(/^bytes(\d+)$/);if(match){const width=parseInt(match[1]);assertArgument(width!==0&&width<=32&&match[1]===String(width),"invalid bytes width","type",type);return function(value){const bytes=getBytes(value);assertArgument(bytes.length===width,`invalid length for ${type}`,"value",value);return hexPadRight(value)}}}switch(type){case"address":return function(value){return zeroPadValue(getAddress(value),32)};case"bool":return function(value){return!value?hexFalse:hexTrue};case"bytes":return function(value){return sha256(value)};case"string":return function(value){return id(value)}}return null}function encodeType(name,fields){return`${name}(${fields.map(({name,type})=>type+" "+name).join(",")})`}class TypedDataEncoder{primaryType;#types;get types(){return JSON.parse(this.#types)}#fullTypes;#encoderCache;constructor(types){this.#types=JSON.stringify(types);this.#fullTypes=new Map;this.#encoderCache=new Map;const links=new Map;const parents=new Map;const subtypes=new Map;Object.keys(types).forEach(type=>{links.set(type,new Set);parents.set(type,[]);subtypes.set(type,new Set)});for(const name in types){const uniqueNames=new Set;for(const field of types[name]){assertArgument(!uniqueNames.has(field.name),`duplicate variable name ${JSON.stringify(field.name)} in ${JSON.stringify(name)}`,"types",types);uniqueNames.add(field.name);const baseType=field.type.match(/^([^\x5b]*)(\x5b|$)/)[1]||null;assertArgument(baseType!==name,`circular type reference to ${JSON.stringify(baseType)}`,"types",types);const encoder=getBaseEncoder(baseType);if(encoder){continue}assertArgument(parents.has(baseType),`unknown type ${JSON.stringify(baseType)}`,"types",types);parents.get(baseType).push(name);links.get(name).add(baseType)}}const primaryTypes=Array.from(parents.keys()).filter(n=>parents.get(n).length===0);assertArgument(primaryTypes.length!==0,"missing primary type","types",types);assertArgument(primaryTypes.length===1,`ambiguous primary types or unused types: ${primaryTypes.map(t=>JSON.stringify(t)).join(", ")}`,"types",types);defineProperties(this,{primaryType:primaryTypes[0]});function checkCircular(type,found){assertArgument(!found.has(type),`circular type reference to ${JSON.stringify(type)}`,"types",types);found.add(type);for(const child of links.get(type)){if(!parents.has(child)){continue}checkCircular(child,found);for(const subtype of found){subtypes.get(subtype).add(child)}}found.delete(type)}checkCircular(this.primaryType,new Set);for(const[name,set]of subtypes){const st=Array.from(set);st.sort();this.#fullTypes.set(name,encodeType(name,types[name])+st.map(t=>encodeType(t,types[t])).join(""))}}getEncoder(type){let encoder=this.#encoderCache.get(type);if(!encoder){encoder=this.#getEncoder(type);this.#encoderCache.set(type,encoder)}return encoder}#getEncoder(type){{const encoder=getBaseEncoder(type);if(encoder){return encoder}}const match=type.match(/^(.*)(\x5b(\d*)\x5d)$/);if(match){const subtype=match[1];const subEncoder=this.getEncoder(subtype);return value=>{assertArgument(!match[3]||parseInt(match[3])===value.length,`array length mismatch; expected length ${parseInt(match[3])}`,"value",value);let result=value.map(subEncoder);if(this.#fullTypes.has(subtype)){result=result.map(sha256)}return sha256(concat(result))}}const fields=this.types[type];if(fields){const encodedType=id(this.#fullTypes.get(type));return value=>{const values=fields.map(({name,type})=>{const result=this.getEncoder(type)(value[name]);if(this.#fullTypes.has(type)){return sha256(result)}return result});values.unshift(encodedType);return concat(values)}}assertArgument(false,`unknown type: ${type}`,"type",type)}encodeType(name){const result=this.#fullTypes.get(name);assertArgument(result,`unknown type: ${JSON.stringify(name)}`,"name",name);return result}encodeData(type,value){return this.getEncoder(type)(value)}hashStruct(name,value){return sha256(this.encodeData(name,value))}encode(value){return this.encodeData(this.primaryType,value)}hash(value){return this.hashStruct(this.primaryType,value)}_visit(type,value,callback){{const encoder=getBaseEncoder(type);if(encoder){return callback(type,value)}}const match=type.match(/^(.*)(\x5b(\d*)\x5d)$/);if(match){assertArgument(!match[3]||parseInt(match[3])===value.length,`array length mismatch; expected length ${parseInt(match[3])}`,"value",value);return value.map(v=>this._visit(match[1],v,callback))}const fields=this.types[type];if(fields){return fields.reduce((accum,{name,type})=>{accum[name]=this._visit(type,value[name],callback);return accum},{})}assertArgument(false,`unknown type: ${type}`,"type",type)}visit(value,callback){return this._visit(this.primaryType,value,callback)}static from(types){return new TypedDataEncoder(types)}static getPrimaryType(types){return TypedDataEncoder.from(types).primaryType}static hashStruct(name,types,value){return TypedDataEncoder.from(types).hashStruct(name,value)}static hashDomain(domain){const domainFields=[];for(const name in domain){if(domain[name]==null){continue}const type=domainFieldTypes[name];assertArgument(type,`invalid typed-data domain key: ${JSON.stringify(name)}`,"domain",domain);domainFields.push({name:name,type:type})}domainFields.sort((a,b)=>{return domainFieldNames.indexOf(a.name)-domainFieldNames.indexOf(b.name)});return TypedDataEncoder.hashStruct("EIP712Domain",{EIP712Domain:domainFields},domain)}static encode(domain,types,value){return concat(["0x1901",TypedDataEncoder.hashDomain(domain),TypedDataEncoder.from(types).hash(value)])}static hash(domain,types,value){return sha256(TypedDataEncoder.encode(domain,types,value))}static async resolveNames(domain,types,value,resolveName){domain=Object.assign({},domain);for(const key in domain){if(domain[key]==null){delete domain[key]}}const ensCache={};if(domain.verifyingContract&&!isHexString(domain.verifyingContract,20)){ensCache[domain.verifyingContract]="0x"}const encoder=TypedDataEncoder.from(types);encoder.visit(value,(type,value)=>{if(type==="address"&&!isHexString(value,20)){ensCache[value]="0x"}return value});for(const name in ensCache){ensCache[name]=await resolveName(name)}if(domain.verifyingContract&&ensCache[domain.verifyingContract]){domain.verifyingContract=ensCache[domain.verifyingContract]}value=encoder.visit(value,(type,value)=>{if(type==="address"&&ensCache[value]){return ensCache[value]}return value});return{domain:domain,value:value}}static getPayload(domain,types,value){TypedDataEncoder.hashDomain(domain);const domainValues={};const domainTypes=[];domainFieldNames.forEach(name=>{const value=domain[name];if(value==null){return}domainValues[name]=domainChecks[name](value);domainTypes.push({name:name,type:domainFieldTypes[name]})});const encoder=TypedDataEncoder.from(types);const typesWithDomain=Object.assign({},types);assertArgument(typesWithDomain.EIP712Domain==null,"types must not contain EIP712Domain type","types.EIP712Domain",types);typesWithDomain.EIP712Domain=domainTypes;encoder.encode(value);return{types:typesWithDomain,domain:domainValues,primaryType:encoder.primaryType,message:encoder.visit(value,(type,value)=>{if(type.match(/^bytes(\d*)/)){return hexlify(getBytes(value))}if(type.match(/^u?int/)){return getBigInt(value).toString()}switch(type){case"address":return value.toLowerCase();case"bool":return!!value;case"string":assertArgument(typeof value==="string","invalid string","value",value);return value}assertArgument(false,"unsupported type","type",type)})}}}function verifyTypedData(domain,types,value,signature,prefix){return recoverAddress(TypedDataEncoder.hash(domain,types,value),signature,prefix)}var _a;function setify(items){const result=new Set;items.forEach(k=>result.add(k));return Object.freeze(result)}const _kwVisib="constant external internal payable private public pure view";const KwVisib=setify(_kwVisib.split(" "));const _kwTypes="constructor error event fallback function receive struct";const KwTypes=setify(_kwTypes.split(" "));const _kwModifiers="calldata memory storage payable indexed";const KwModifiers=setify(_kwModifiers.split(" "));const _kwOther="tuple returns";const _keywords=[_kwTypes,_kwModifiers,_kwOther,_kwVisib].join(" ");const Keywords=setify(_keywords.split(" "));const SimpleTokens={"(":"OPEN_PAREN",")":"CLOSE_PAREN","[":"OPEN_BRACKET","]":"CLOSE_BRACKET",",":"COMMA","@":"AT"};const regexWhitespacePrefix=new RegExp("^(\\s*)");const regexNumberPrefix=new RegExp("^([0-9]+)");const regexIdPrefix=new RegExp("^([a-zA-Z$_][a-zA-Z0-9$_]*)");const regexId=new RegExp("^([a-zA-Z$_][a-zA-Z0-9$_]*)$");const regexType=new RegExp("^(address|bool|bytes([0-9]*)|string|u?int([0-9]*))$");class TokenString{#offset;#tokens;get offset(){return this.#offset}get length(){return this.#tokens.length-this.#offset}constructor(tokens){this.#offset=0;this.#tokens=tokens.slice()}clone(){return new _a(this.#tokens)}reset(){this.#offset=0}#subTokenString(from=0,to=0){return new _a(this.#tokens.slice(from,to).map(t=>{return Object.freeze(Object.assign({},t,{match:t.match-from,linkBack:t.linkBack-from,linkNext:t.linkNext-from}))}))}popKeyword(allowed){const top=this.peek();if(top.type!=="KEYWORD"||!allowed.has(top.text)){throw new Error(`expected keyword ${top.text}`)}return this.pop().text}popType(type){if(this.peek().type!==type){throw new Error(`expected ${type}; got ${JSON.stringify(this.peek())}`)}return this.pop().text}popParen(){const top=this.peek();if(top.type!=="OPEN_PAREN"){throw new Error("bad start")}const result=this.#subTokenString(this.#offset+1,top.match+1);this.#offset=top.match+1;return result}popParams(){const top=this.peek();if(top.type!=="OPEN_PAREN"){throw new Error("bad start")}const result=[];while(this.#offset=this.#tokens.length){throw new Error("out-of-bounds")}return this.#tokens[this.#offset]}peekKeyword(allowed){const top=this.peekType("KEYWORD");return top!=null&&allowed.has(top)?top:null}peekType(type){if(this.length===0){return null}const top=this.peek();return top.type===type?top.text:null}pop(){const result=this.peek();this.#offset++;return result}toString(){const tokens=[];for(let i=this.#offset;i`}}_a=TokenString;function lex(text){const tokens=[];const throwError=message=>{const token=offset0&&tokens[tokens.length-1].type==="NUMBER"){const value=tokens.pop().text;suffix=value+suffix;tokens[tokens.length-1].value=getNumber(value)}if(tokens.length===0||tokens[tokens.length-1].type!=="BRACKET"){throw new Error("missing opening bracket")}tokens[tokens.length-1].text+=suffix}continue}match=cur.match(regexIdPrefix);if(match){token.text=match[1];offset+=token.text.length;if(Keywords.has(token.text)){token.type="KEYWORD";continue}if(token.text.match(regexType)){token.type="TYPE";continue}token.type="ID";continue}match=cur.match(regexNumberPrefix);if(match){token.text=match[1];token.type="NUMBER";offset+=token.text.length;continue}throw new Error(`unexpected token ${JSON.stringify(cur[0])} at position ${offset}`)}return new TokenString(tokens.map(t=>Object.freeze(t)))}function allowSingle(set,allowed){let included=[];for(const key in allowed.keys()){if(set.has(key)){included.push(key)}}if(included.length>1){throw new Error(`conflicting types: ${included.join(", ")}`)}}function consumeName(type,tokens){if(tokens.peekKeyword(KwTypes)){const keyword=tokens.pop().text;if(keyword!==type){throw new Error(`expected ${type}, got ${keyword}`)}}return tokens.popType("ID")}function consumeKeywords(tokens,allowed){const keywords=new Set;while(true){const keyword=tokens.peekType("KEYWORD");if(keyword==null||allowed&&!allowed.has(keyword)){break}tokens.pop();if(keywords.has(keyword)){throw new Error(`duplicate keywords: ${JSON.stringify(keyword)}`)}keywords.add(keyword)}return Object.freeze(keywords)}function consumeMutability(tokens){let modifiers=consumeKeywords(tokens,KwVisib);allowSingle(modifiers,setify("constant payable nonpayable".split(" ")));allowSingle(modifiers,setify("pure view payable nonpayable".split(" ")));if(modifiers.has("view")){return"view"}if(modifiers.has("pure")){return"pure"}if(modifiers.has("payable")){return"payable"}if(modifiers.has("nonpayable")){return"nonpayable"}if(modifiers.has("constant")){return"view"}return"nonpayable"}function consumeParams(tokens,allowIndexed){return tokens.popParams().map(t=>ParamType.from(t,allowIndexed))}function consumeEnergy(tokens){if(tokens.peekType("AT")){tokens.pop();if(tokens.peekType("NUMBER")){return getBigInt(tokens.pop().text)}throw new Error("invalid energy")}return null}function consumeEoi(tokens){if(tokens.length){throw new Error(`unexpected tokens: ${tokens.toString()}`)}}const regexArrayType=new RegExp(/^(.*)\[([0-9]*)\]$/);function verifyBasicType(type){const match=type.match(regexType);assertArgument(match,"invalid type","type",type);if(type==="uint"){return"uint256"}if(type==="int"){return"int256"}if(match[2]){const length=parseInt(match[2]);assertArgument(length!==0&&length<=32,"invalid bytes length","type",type)}else if(match[3]){const size=parseInt(match[3]);assertArgument(size!==0&&size<=256&&size%8===0,"invalid numeric width","type",type)}return type}const _guard$2={};const internal$1=Symbol.for("_corebc_internal");const ParamTypeInternal="_ParamTypeInternal";const ErrorFragmentInternal="_ErrorInternal";const EventFragmentInternal="_EventInternal";const ConstructorFragmentInternal="_ConstructorInternal";const FallbackFragmentInternal="_FallbackInternal";const FunctionFragmentInternal="_FunctionInternal";const StructFragmentInternal="_StructInternal";class ParamType{name;type;baseType;indexed;components;arrayLength;arrayChildren;constructor(guard,name,type,baseType,indexed,components,arrayLength,arrayChildren){assertPrivate(guard,_guard$2,"ParamType");Object.defineProperty(this,internal$1,{value:ParamTypeInternal});if(components){components=Object.freeze(components.slice())}if(baseType==="array"){if(arrayLength==null||arrayChildren==null){throw new Error("")}}else if(arrayLength!=null||arrayChildren!=null){throw new Error("")}if(baseType==="tuple"){if(components==null){throw new Error("")}}else if(components!=null){throw new Error("")}defineProperties(this,{name:name,type:type,baseType:baseType,indexed:indexed,components:components,arrayLength:arrayLength,arrayChildren:arrayChildren})}format(format){if(format==null){format="sighash"}if(format==="json"){let result={type:this.baseType==="tuple"?"tuple":this.type,name:this.name||undefined};if(typeof this.indexed==="boolean"){result.indexed=this.indexed}if(this.isTuple()){result.components=this.components.map(c=>JSON.parse(c.format(format)))}return JSON.stringify(result)}let result="";if(this.isArray()){result+=this.arrayChildren.format(format);result+=`[${this.arrayLength<0?"":String(this.arrayLength)}]`}else{if(this.isTuple()){if(format!=="sighash"){result+=this.type}result+="("+this.components.map(comp=>comp.format(format)).join(format==="full"?", ":",")+")"}else{result+=this.type}}if(format!=="sighash"){if(this.indexed===true){result+=" indexed"}if(format==="full"&&this.name){result+=" "+this.name}}return result}isArray(){return this.baseType==="array"}isTuple(){return this.baseType==="tuple"}isIndexable(){return this.indexed!=null}walk(value,process){if(this.isArray()){if(!Array.isArray(value)){throw new Error("invalid array value")}if(this.arrayLength!==-1&&value.length!==this.arrayLength){throw new Error("array is wrong length")}const _this=this;return value.map(v=>_this.arrayChildren.walk(v,process))}if(this.isTuple()){if(!Array.isArray(value)){throw new Error("invalid tuple value")}if(value.length!==this.components.length){throw new Error("array is wrong length")}const _this=this;return value.map((v,i)=>_this.components[i].walk(v,process))}return process(this.type,value)}#walkAsync(promises,value,process,setValue){if(this.isArray()){if(!Array.isArray(value)){throw new Error("invalid array value")}if(this.arrayLength!==-1&&value.length!==this.arrayLength){throw new Error("array is wrong length")}const childType=this.arrayChildren;const result=value.slice();result.forEach((value,index)=>{childType.#walkAsync(promises,value,process,value=>{result[index]=value})});setValue(result);return}if(this.isTuple()){const components=this.components;let result;if(Array.isArray(value)){result=value.slice()}else{if(value==null||typeof value!=="object"){throw new Error("invalid tuple value")}result=components.map(param=>{if(!param.name){throw new Error("cannot use object value with unnamed components")}if(!(param.name in value)){throw new Error(`missing value for component ${param.name}`)}return value[param.name]})}if(result.length!==this.components.length){throw new Error("array is wrong length")}result.forEach((value,index)=>{components[index].#walkAsync(promises,value,process,value=>{result[index]=value})});setValue(result);return}const result=process(this.type,value);if(result.then){promises.push(async function(){setValue(await result)}())}else{setValue(result)}}async walkAsync(value,process){const promises=[];const result=[value];this.#walkAsync(promises,value,process,value=>{result[0]=value});if(promises.length){await Promise.all(promises)}return result[0]}static from(obj,allowIndexed){if(ParamType.isParamType(obj)){return obj}if(typeof obj==="string"){return ParamType.from(lex(obj),allowIndexed)}else if(obj instanceof TokenString){let type="",baseType="";let comps=null;if(consumeKeywords(obj,setify(["tuple"])).has("tuple")||obj.peekType("OPEN_PAREN")){baseType="tuple";comps=obj.popParams().map(t=>ParamType.from(t));type=`tuple(${comps.map(c=>c.format()).join(",")})`}else{type=verifyBasicType(obj.popType("TYPE"));baseType=type}let arrayChildren=null;let arrayLength=null;while(obj.length&&obj.peekType("BRACKET")){const bracket=obj.pop();arrayChildren=new ParamType(_guard$2,"",type,baseType,null,comps,arrayLength,arrayChildren);arrayLength=bracket.value;type+=bracket.text;baseType="array";comps=null}let indexed=null;const keywords=consumeKeywords(obj,KwModifiers);if(keywords.has("indexed")){if(!allowIndexed){throw new Error("")}indexed=true}const name=obj.peekType("ID")?obj.pop().text:"";if(obj.length){throw new Error("leftover tokens")}return new ParamType(_guard$2,name,type,baseType,indexed,comps,arrayLength,arrayChildren)}const name=obj.name;assertArgument(!name||typeof name==="string"&&name.match(regexId),"invalid name","obj.name",name);let indexed=obj.indexed;if(indexed!=null){assertArgument(allowIndexed,"parameter cannot be indexed","obj.indexed",obj.indexed);indexed=!!indexed}let type=obj.type;let arrayMatch=type.match(regexArrayType);if(arrayMatch){const arrayLength=parseInt(arrayMatch[2]||"-1");const arrayChildren=ParamType.from({type:arrayMatch[1],components:obj.components});return new ParamType(_guard$2,name||"",type,"array",indexed,null,arrayLength,arrayChildren)}if(type==="tuple"||type.startsWith("tuple(")||type.startsWith("(")){const comps=obj.components!=null?obj.components.map(c=>ParamType.from(c)):null;const tuple=new ParamType(_guard$2,name||"",type,"tuple",indexed,comps,null,null);return tuple}type=verifyBasicType(obj.type);return new ParamType(_guard$2,name||"",type,type,indexed,null,null,null)}static isParamType(value){return value&&value[internal$1]===ParamTypeInternal}}class Fragment{type;inputs;constructor(guard,type,inputs){assertPrivate(guard,_guard$2,"Fragment");inputs=Object.freeze(inputs.slice());defineProperties(this,{type:type,inputs:inputs})}static from(obj){if(typeof obj==="string"){try{Fragment.from(JSON.parse(obj))}catch(e){}return Fragment.from(lex(obj))}if(obj instanceof TokenString){const type=obj.peekKeyword(KwTypes);switch(type){case"constructor":return ConstructorFragment.from(obj);case"error":return ErrorFragment.from(obj);case"event":return EventFragment.from(obj);case"fallback":case"receive":return FallbackFragment.from(obj);case"function":return FunctionFragment.from(obj);case"struct":return StructFragment.from(obj)}}else if(typeof obj==="object"){switch(obj.type){case"constructor":return ConstructorFragment.from(obj);case"error":return ErrorFragment.from(obj);case"event":return EventFragment.from(obj);case"fallback":case"receive":return FallbackFragment.from(obj);case"function":return FunctionFragment.from(obj);case"struct":return StructFragment.from(obj)}assert(false,`unsupported type: ${obj.type}`,"UNSUPPORTED_OPERATION",{operation:"Fragment.from"})}assertArgument(false,"unsupported frgament object","obj",obj)}static isConstructor(value){return ConstructorFragment.isFragment(value)}static isError(value){return ErrorFragment.isFragment(value)}static isEvent(value){return EventFragment.isFragment(value)}static isFunction(value){return FunctionFragment.isFragment(value)}static isStruct(value){return StructFragment.isFragment(value)}}class NamedFragment extends Fragment{name;constructor(guard,type,name,inputs){super(guard,type,inputs);assertArgument(typeof name==="string"&&name.match(regexId),"invalid identifier","name",name);inputs=Object.freeze(inputs.slice());defineProperties(this,{name:name})}}function joinParams(format,params){return"("+params.map(p=>p.format(format)).join(format==="full"?", ":",")+")"}class ErrorFragment extends NamedFragment{constructor(guard,name,inputs){super(guard,"error",name,inputs);Object.defineProperty(this,internal$1,{value:ErrorFragmentInternal})}get selector(){return id(this.format("sighash")).substring(0,10)}format(format){if(format==null){format="sighash"}if(format==="json"){return JSON.stringify({type:"error",name:this.name,inputs:this.inputs.map(input=>JSON.parse(input.format(format)))})}const result=[];if(format!=="sighash"){result.push("error")}result.push(this.name+joinParams(format,this.inputs));return result.join(" ")}static from(obj){if(ErrorFragment.isFragment(obj)){return obj}if(typeof obj==="string"){return ErrorFragment.from(lex(obj))}else if(obj instanceof TokenString){const name=consumeName("error",obj);const inputs=consumeParams(obj);consumeEoi(obj);return new ErrorFragment(_guard$2,name,inputs)}return new ErrorFragment(_guard$2,obj.name,obj.inputs?obj.inputs.map(ParamType.from):[])}static isFragment(value){return value&&value[internal$1]===ErrorFragmentInternal}}class EventFragment extends NamedFragment{anonymous;constructor(guard,name,inputs,anonymous){super(guard,"event",name,inputs);Object.defineProperty(this,internal$1,{value:EventFragmentInternal});defineProperties(this,{anonymous:anonymous})}get topicHash(){return id(this.format("sighash"))}format(format){if(format==null){format="sighash"}if(format==="json"){return JSON.stringify({type:"event",anonymous:this.anonymous,name:this.name,inputs:this.inputs.map(i=>JSON.parse(i.format(format)))})}const result=[];if(format!=="sighash"){result.push("event")}result.push(this.name+joinParams(format,this.inputs));if(format!=="sighash"&&this.anonymous){result.push("anonymous")}return result.join(" ")}static getTopicHash(name,params){params=(params||[]).map(p=>ParamType.from(p));const fragment=new EventFragment(_guard$2,name,params,false);return fragment.topicHash}static from(obj){if(EventFragment.isFragment(obj)){return obj}if(typeof obj==="string"){return EventFragment.from(lex(obj))}else if(obj instanceof TokenString){const name=consumeName("event",obj);const inputs=consumeParams(obj,true);const anonymous=!!consumeKeywords(obj,setify(["anonymous"])).has("anonymous");consumeEoi(obj);return new EventFragment(_guard$2,name,inputs,anonymous)}return new EventFragment(_guard$2,obj.name,obj.inputs?obj.inputs.map(p=>ParamType.from(p,true)):[],!!obj.anonymous)}static isFragment(value){return value&&value[internal$1]===EventFragmentInternal}}class ConstructorFragment extends Fragment{payable;energy;constructor(guard,type,inputs,payable,energy){super(guard,type,inputs);Object.defineProperty(this,internal$1,{value:ConstructorFragmentInternal});defineProperties(this,{payable:payable,energy:energy})}format(format){assert(format!=null&&format!=="sighash","cannot format a constructor for sighash","UNSUPPORTED_OPERATION",{operation:"format(sighash)"});if(format==="json"){return JSON.stringify({type:"constructor",stateMutability:this.payable?"payable":"undefined",payable:this.payable,energy:this.energy!=null?this.energy:undefined,inputs:this.inputs.map(i=>JSON.parse(i.format(format)))})}const result=[`constructor${joinParams(format,this.inputs)}`];result.push(this.payable?"payable":"nonpayable");if(this.energy!=null){result.push(`@${this.energy.toString()}`)}return result.join(" ")}static from(obj){if(ConstructorFragment.isFragment(obj)){return obj}if(typeof obj==="string"){return ConstructorFragment.from(lex(obj))}else if(obj instanceof TokenString){consumeKeywords(obj,setify(["constructor"]));const inputs=consumeParams(obj);const payable=!!consumeKeywords(obj,setify(["payable"])).has("payable");const energy=consumeEnergy(obj);consumeEoi(obj);return new ConstructorFragment(_guard$2,"constructor",inputs,payable,energy)}return new ConstructorFragment(_guard$2,"constructor",obj.inputs?obj.inputs.map(ParamType.from):[],!!obj.payable,obj.energy!=null?obj.energy:null)}static isFragment(value){return value&&value[internal$1]===ConstructorFragmentInternal}}class FallbackFragment extends Fragment{payable;constructor(guard,inputs,payable){super(guard,"fallback",inputs);Object.defineProperty(this,internal$1,{value:FallbackFragmentInternal});defineProperties(this,{payable:payable})}format(format){const type=this.inputs.length===0?"receive":"fallback";if(format==="json"){const stateMutability=this.payable?"payable":"nonpayable";return JSON.stringify({type:type,stateMutability:stateMutability})}return`${type}()${this.payable?" payable":""}`}static from(obj){if(FallbackFragment.isFragment(obj)){return obj}if(typeof obj==="string"){return FallbackFragment.from(lex(obj))}else if(obj instanceof TokenString){const errorObj=obj.toString();const topIsValid=obj.peekKeyword(setify(["fallback","receive"]));assertArgument(topIsValid,"type must be fallback or receive","obj",errorObj);const type=obj.popKeyword(setify(["fallback","receive"]));if(type==="receive"){const inputs=consumeParams(obj);assertArgument(inputs.length===0,`receive cannot have arguments`,"obj.inputs",inputs);consumeKeywords(obj,setify(["payable"]));consumeEoi(obj);return new FallbackFragment(_guard$2,[],true)}let inputs=consumeParams(obj);if(inputs.length){assertArgument(inputs.length===1&&inputs[0].type==="bytes","invalid fallback inputs","obj.inputs",inputs.map(i=>i.format("minimal")).join(", "))}else{inputs=[ParamType.from("bytes")]}const mutability=consumeMutability(obj);assertArgument(mutability==="nonpayable"||mutability==="payable","fallback cannot be constants","obj.stateMutability",mutability);if(consumeKeywords(obj,setify(["returns"])).has("returns")){const outputs=consumeParams(obj);assertArgument(outputs.length===1&&outputs[0].type==="bytes","invalid fallback outputs","obj.outputs",outputs.map(i=>i.format("minimal")).join(", "))}consumeEoi(obj);return new FallbackFragment(_guard$2,inputs,mutability==="payable")}if(obj.type==="receive"){return new FallbackFragment(_guard$2,[],true)}if(obj.type==="fallback"){const inputs=[ParamType.from("bytes")];const payable=obj.stateMutability==="payable";return new FallbackFragment(_guard$2,inputs,payable)}assertArgument(false,"invalid fallback description","obj",obj)}static isFragment(value){return value&&value[internal$1]===FallbackFragmentInternal}}class FunctionFragment extends NamedFragment{constant;outputs;stateMutability;payable;energy;constructor(guard,name,stateMutability,inputs,outputs,energy){super(guard,"function",name,inputs);Object.defineProperty(this,internal$1,{value:FunctionFragmentInternal});outputs=Object.freeze(outputs.slice());const constant=stateMutability==="view"||stateMutability==="pure";const payable=stateMutability==="payable";defineProperties(this,{constant:constant,energy:energy,outputs:outputs,payable:payable,stateMutability:stateMutability})}get selector(){return id(this.format("sighash")).substring(0,10)}format(format){if(format==null){format="sighash"}if(format==="json"){return JSON.stringify({type:"function",name:this.name,constant:this.constant,stateMutability:this.stateMutability!=="nonpayable"?this.stateMutability:undefined,payable:this.payable,energy:this.energy!=null?this.energy:undefined,inputs:this.inputs.map(i=>JSON.parse(i.format(format))),outputs:this.outputs.map(o=>JSON.parse(o.format(format)))})}const result=[];if(format!=="sighash"){result.push("function")}result.push(this.name+joinParams(format,this.inputs));if(format!=="sighash"){if(this.stateMutability!=="nonpayable"){result.push(this.stateMutability)}if(this.outputs&&this.outputs.length){result.push("returns");result.push(joinParams(format,this.outputs))}if(this.energy!=null){result.push(`@${this.energy.toString()}`)}}return result.join(" ")}static getSelector(name,params){params=(params||[]).map(p=>ParamType.from(p));const fragment=new FunctionFragment(_guard$2,name,"view",params,[],null);return fragment.selector}static from(obj){if(FunctionFragment.isFragment(obj)){return obj}if(typeof obj==="string"){return FunctionFragment.from(lex(obj))}else if(obj instanceof TokenString){const name=consumeName("function",obj);const inputs=consumeParams(obj);const mutability=consumeMutability(obj);let outputs=[];if(consumeKeywords(obj,setify(["returns"])).has("returns")){outputs=consumeParams(obj)}const energy=consumeEnergy(obj);consumeEoi(obj);return new FunctionFragment(_guard$2,name,mutability,inputs,outputs,energy)}let stateMutability=obj.stateMutability;if(stateMutability==null){stateMutability="payable";if(typeof obj.constant==="boolean"){stateMutability="view";if(!obj.constant){stateMutability="payable";if(typeof obj.payable==="boolean"&&!obj.payable){stateMutability="nonpayable"}}}else if(typeof obj.payable==="boolean"&&!obj.payable){stateMutability="nonpayable"}}return new FunctionFragment(_guard$2,obj.name,stateMutability,obj.inputs?obj.inputs.map(ParamType.from):[],obj.outputs?obj.outputs.map(ParamType.from):[],obj.energy!=null?obj.energy:null)}static isFragment(value){return value&&value[internal$1]===FunctionFragmentInternal}}class StructFragment extends NamedFragment{constructor(guard,name,inputs){super(guard,"struct",name,inputs);Object.defineProperty(this,internal$1,{value:StructFragmentInternal})}format(){throw new Error("@TODO")}static from(obj){if(typeof obj==="string"){return StructFragment.from(lex(obj))}else if(obj instanceof TokenString){const name=consumeName("struct",obj);const inputs=consumeParams(obj);consumeEoi(obj);return new StructFragment(_guard$2,name,inputs)}return new StructFragment(_guard$2,obj.name,obj.inputs?obj.inputs.map(ParamType.from):[])}static isFragment(value){return value&&value[internal$1]===StructFragmentInternal}}const PanicReasons$1=new Map;PanicReasons$1.set(0,"GENERIC_PANIC");PanicReasons$1.set(1,"ASSERT_FALSE");PanicReasons$1.set(17,"OVERFLOW");PanicReasons$1.set(18,"DIVIDE_BY_ZERO");PanicReasons$1.set(33,"ENUM_RANGE_ERROR");PanicReasons$1.set(34,"BAD_STORAGE_DATA");PanicReasons$1.set(49,"STACK_UNDERFLOW");PanicReasons$1.set(50,"ARRAY_RANGE_ERROR");PanicReasons$1.set(65,"OUT_OF_MEMORY");PanicReasons$1.set(81,"UNINITIALIZED_FUNCTION_CALL");const paramTypeBytes=new RegExp(/^bytes([0-9]*)$/);const paramTypeNumber=new RegExp(/^(u?int)([0-9]*)$/);let defaultCoder=null;function getBuiltinCallException(action,tx,data,abiCoder){let message="missing revert data";let reason=null;const invocation=null;let revert=null;if(data){message="execution reverted";const bytes=getBytes(data);data=hexlify(data);if(bytes.length===0){message+=" (no data present; likely require(false) occurred";reason="require(false)"}else if(bytes.length%32!==4){message+=" (could not decode reason; invalid data length)"}else if(hexlify(bytes.slice(0,4))==="0x08c379a0"){try{reason=abiCoder.decode(["string"],bytes.slice(4))[0];revert={signature:"Error(string)",name:"Error",args:[reason]};message+=`: ${JSON.stringify(reason)}`}catch(error){message+=" (could not decode reason; invalid string data)"}}else if(hexlify(bytes.slice(0,4))==="0x4e487b71"){try{const code=Number(abiCoder.decode(["uint256"],bytes.slice(4))[0]);revert={signature:"Panic(uint256)",name:"Panic",args:[code]};reason=`Panic due to ${PanicReasons$1.get(code)||"UNKNOWN"}(${code})`;message+=`: ${reason}`}catch(error){message+=" (could not decode panic code)"}}else{message+=" (unknown custom error)"}}const transaction={to:tx.to?getAddress(tx.to):null,data:tx.data||"0x"};if(tx.from){transaction.from=getAddress(tx.from)}return makeError(message,"CALL_EXCEPTION",{action:action,data:data,reason:reason,transaction:transaction,invocation:invocation,revert:revert})}class AbiCoder{#getCoder(param){if(param.isArray()){return new ArrayCoder(this.#getCoder(param.arrayChildren),param.arrayLength,param.name)}if(param.isTuple()){return new TupleCoder(param.components.map(c=>this.#getCoder(c)),param.name)}switch(param.baseType){case"address":return new AddressCoder(param.name);case"bool":return new BooleanCoder(param.name);case"string":return new StringCoder(param.name);case"bytes":return new BytesCoder(param.name);case"":return new NullCoder(param.name)}let match=param.type.match(paramTypeNumber);if(match){let size=parseInt(match[2]||"256");assertArgument(size!==0&&size<=256&&size%8===0,"invalid "+match[1]+" bit length","param",param);return new NumberCoder(size/8,match[1]==="int",param.name)}match=param.type.match(paramTypeBytes);if(match){let size=parseInt(match[1]);assertArgument(size!==0&&size<=32,"invalid bytes length","param",param);return new FixedBytesCoder(size,param.name)}assertArgument(false,"invalid type","type",param.type)}getDefaultValue(types){const coders=types.map(type=>this.#getCoder(ParamType.from(type)));const coder=new TupleCoder(coders,"_");return coder.defaultValue()}encode(types,values){assertArgumentCount(values.length,types.length,"types/values length mismatch");const coders=types.map(type=>this.#getCoder(ParamType.from(type)));const coder=new TupleCoder(coders,"_");const writer=new Writer;coder.encode(writer,values);return writer.data}decode(types,data,loose){const coders=types.map(type=>this.#getCoder(ParamType.from(type)));const coder=new TupleCoder(coders,"_");return coder.decode(new Reader(data,loose))}static defaultAbiCoder(){if(defaultCoder==null){defaultCoder=new AbiCoder}return defaultCoder}static getBuiltinCallException(action,tx,data){return getBuiltinCallException(action,tx,data,AbiCoder.defaultAbiCoder())}}function encodeBytes32String(text){const bytes=toUtf8Bytes(text);if(bytes.length>31){throw new Error("bytes32 string must be less than 32 bytes")}return zeroPadBytes(bytes,32)}function decodeBytes32String(_bytes){const data=getBytes(_bytes,"bytes");if(data.length!==32){throw new Error("invalid bytes32 - not 32 bytes long")}if(data[31]!==0){throw new Error("invalid bytes32 string - no null terminator")}let length=31;while(data[length-1]===0){length--}return toUtf8String(data.slice(0,length))}class LogDescription{fragment;name;signature;topic;args;constructor(fragment,topic,args){const name=fragment.name,signature=fragment.format();defineProperties(this,{fragment:fragment,name:name,signature:signature,topic:topic,args:args})}}class TransactionDescription{fragment;name;args;signature;selector;value;constructor(fragment,selector,args,value){const name=fragment.name,signature=fragment.format();defineProperties(this,{fragment:fragment,name:name,args:args,signature:signature,selector:selector,value:value})}}class ErrorDescription{fragment;name;args;signature;selector;constructor(fragment,selector,args){const name=fragment.name,signature=fragment.format();defineProperties(this,{fragment:fragment,name:name,args:args,signature:signature,selector:selector})}}class Indexed{hash;_isIndexed;static isIndexed(value){return!!(value&&value._isIndexed)}constructor(hash){defineProperties(this,{hash:hash,_isIndexed:true})}}const PanicReasons={0:"generic panic",1:"assert(false)",17:"arithmetic overflow",18:"division or modulo by zero",33:"enum overflow",34:"invalid encoded storage byte array accessed",49:"out-of-bounds array access; popping on an empty array",50:"out-of-bounds access of an array or bytesN",65:"out of memory",81:"uninitialized function"};const BuiltinErrors={"0x08c379a0":{signature:"Error(string)",name:"Error",inputs:["string"],reason:message=>{return`reverted with reason string ${JSON.stringify(message)}`}},"0x4e487b71":{signature:"Panic(uint256)",name:"Panic",inputs:["uint256"],reason:code=>{let reason="unknown panic code";if(code>=0&&code<=255&&PanicReasons[code.toString()]){reason=PanicReasons[code.toString()]}return`reverted with panic code 0x${code.toString(16)} (${reason})`}}};class Interface{fragments;deploy;fallback;receive;#errors;#events;#functions;#abiCoder;constructor(fragments){let abi=[];if(typeof fragments==="string"){abi=JSON.parse(fragments)}else{abi=fragments}this.#functions=new Map;this.#errors=new Map;this.#events=new Map;const frags=[];for(const a of abi){try{frags.push(Fragment.from(a))}catch(error){console.log("EE",error)}}defineProperties(this,{fragments:Object.freeze(frags)});let fallback=null;let receive=false;this.#abiCoder=this.getAbiCoder();this.fragments.forEach((fragment,index)=>{let bucket;switch(fragment.type){case"constructor":if(this.deploy){console.log("duplicate definition - constructor");return}defineProperties(this,{deploy:fragment});return;case"fallback":if(fragment.inputs.length===0){receive=true}else{assertArgument(!fallback||fragment.payable!==fallback.payable,"conflicting fallback fragments",`fragments[${index}]`,fragment);fallback=fragment;receive=fallback.payable}return;case"function":bucket=this.#functions;break;case"event":bucket=this.#events;break;case"error":bucket=this.#errors;break;default:return}const signature=fragment.format();if(bucket.has(signature)){return}bucket.set(signature,fragment)});if(!this.deploy){defineProperties(this,{deploy:ConstructorFragment.from("constructor()")})}defineProperties(this,{fallback:fallback,receive:receive})}format(minimal){const format=minimal?"minimal":"full";const abi=this.fragments.map(f=>f.format(format));return abi}formatJson(){const abi=this.fragments.map(f=>f.format("json"));return JSON.stringify(abi.map(j=>JSON.parse(j)))}getAbiCoder(){return AbiCoder.defaultAbiCoder()}#getFunction(key,values,forceUnique){if(isHexString(key)){const selector=key.toLowerCase();for(const fragment of this.#functions.values()){if(selector===fragment.selector){return fragment}}return null}if(key.indexOf("(")===-1){const matching=[];for(const[name,fragment]of this.#functions){if(name.split("(")[0]===key){matching.push(fragment)}}if(values){const lastValue=values.length>0?values[values.length-1]:null;let valueLength=values.length;let allowOptions=true;if(Typed.isTyped(lastValue)&&lastValue.type==="overrides"){allowOptions=false;valueLength--}for(let i=matching.length-1;i>=0;i--){const inputs=matching[i].inputs.length;if(inputs!==valueLength&&(!allowOptions||inputs!==valueLength-1)){matching.splice(i,1)}}for(let i=matching.length-1;i>=0;i--){const inputs=matching[i].inputs;for(let j=0;j=inputs.length){if(values[j].type==="overrides"){continue}matching.splice(i,1);break}if(values[j].type!==inputs[j].baseType){matching.splice(i,1);break}}}}if(matching.length===1&&values&&values.length!==matching[0].inputs.length){const lastArg=values[values.length-1];if(lastArg==null||Array.isArray(lastArg)||typeof lastArg!=="object"){matching.splice(0,1)}}if(matching.length===0){return null}if(matching.length>1&&forceUnique){const matchStr=matching.map(m=>JSON.stringify(m.format())).join(", ");assertArgument(false,`ambiguous function description (i.e. matches ${matchStr})`,"key",key)}return matching[0]}const result=this.#functions.get(FunctionFragment.from(key).format());if(result){return result}return null}getFunctionName(key){const fragment=this.#getFunction(key,null,false);assertArgument(fragment,"no matching function","key",key);return fragment.name}hasFunction(key){return!!this.#getFunction(key,null,false)}getFunction(key,values){return this.#getFunction(key,values||null,true)}forEachFunction(callback){const names=Array.from(this.#functions.keys());names.sort((a,b)=>a.localeCompare(b));for(let i=0;i=0;i--){if(matching[i].inputs.length=0;i--){const inputs=matching[i].inputs;for(let j=0;j1&&forceUnique){const matchStr=matching.map(m=>JSON.stringify(m.format())).join(", ");assertArgument(false,`ambiguous event description (i.e. matches ${matchStr})`,"key",key)}return matching[0]}const result=this.#events.get(EventFragment.from(key).format());if(result){return result}return null}getEventName(key){const fragment=this.#getEvent(key,null,false);assertArgument(fragment,"no matching event","key",key);return fragment.name}hasEvent(key){return!!this.#getEvent(key,null,false)}getEvent(key,values){return this.#getEvent(key,values||null,true)}forEachEvent(callback){const names=Array.from(this.#events.keys());names.sort((a,b)=>a.localeCompare(b));for(let i=0;i1){const matchStr=matching.map(m=>JSON.stringify(m.format())).join(", ");assertArgument(false,`ambiguous error description (i.e. ${matchStr})`,"name",key)}return matching[0]}key=ErrorFragment.from(key).format();if(key==="Error(string)"){return ErrorFragment.from("error Error(string)")}if(key==="Panic(uint256)"){return ErrorFragment.from("error Panic(uint256)")}const result=this.#errors.get(key);if(result){return result}return null}forEachError(callback){const names=Array.from(this.#errors.keys());names.sort((a,b)=>a.localeCompare(b));for(let i=0;i{if(param.type==="string"){return id(value)}else if(param.type==="bytes"){return sha256(hexlify(value))}if(param.type==="bool"&&typeof value==="boolean"){value=value?"0x01":"0x00"}if(param.type.match(/^u?int/)){value=toBeHex(value)}if(param.type==="address"){this.#abiCoder.encode(["address"],[value])}return zeroPadValue(hexlify(value),32)};values.forEach((value,index)=>{const param=fragment.inputs[index];if(!param.indexed){assertArgument(value==null,"cannot filter non-indexed parameters; must be null","contract."+param.name,value);return}if(value==null){topics.push(null)}else if(param.baseType==="array"||param.baseType==="tuple"){assertArgument(false,"filtering with tuples or arrays not supported","contract."+param.name,value)}else if(Array.isArray(value)){topics.push(value.map(value=>encodeTopic(param,value)))}else{topics.push(encodeTopic(param,value))}});while(topics.length&&topics[topics.length-1]===null){topics.pop()}return topics}encodeEventLog(fragment,values){if(typeof fragment==="string"){const f=this.getEvent(fragment);assertArgument(f,"unknown event","eventFragment",fragment);fragment=f}const topics=[];const dataTypes=[];const dataValues=[];if(!fragment.anonymous){topics.push(fragment.topicHash)}assertArgument(values.length===fragment.inputs.length,"event arguments/values mismatch","values",values);fragment.inputs.forEach((param,index)=>{const value=values[index];if(param.indexed){if(param.type==="string"){topics.push(id(value))}else if(param.type==="bytes"){topics.push(sha256(value))}else if(param.baseType==="tuple"||param.baseType==="array"){throw new Error("not implemented")}else{topics.push(this.#abiCoder.encode([param.type],[value]))}}else{dataTypes.push(param);dataValues.push(value)}});return{data:this.#abiCoder.encode(dataTypes,dataValues),topics:topics}}decodeEventLog(fragment,data,topics){if(typeof fragment==="string"){const f=this.getEvent(fragment);assertArgument(f,"unknown event","eventFragment",fragment);fragment=f}if(topics!=null&&!fragment.anonymous){const eventTopic=fragment.topicHash;assertArgument(isHexString(topics[0],32)&&topics[0].toLowerCase()===eventTopic,"fragment/topic mismatch","topics[0]",topics[0]);topics=topics.slice(1)}const indexed=[];const nonIndexed=[];const dynamic=[];fragment.inputs.forEach((param,index)=>{if(param.indexed){if(param.type==="string"||param.type==="bytes"||param.baseType==="tuple"||param.baseType==="array"){indexed.push(ParamType.from({type:"bytes32",name:param.name}));dynamic.push(true)}else{indexed.push(param);dynamic.push(false)}}else{nonIndexed.push(param);dynamic.push(false)}});const resultIndexed=topics!=null?this.#abiCoder.decode(indexed,concat(topics)):null;const resultNonIndexed=this.#abiCoder.decode(nonIndexed,data,true);const values=[];const keys=[];let nonIndexedIndex=0,indexedIndex=0;fragment.inputs.forEach((param,index)=>{let value=null;if(param.indexed){if(resultIndexed==null){value=new Indexed(null)}else if(dynamic[index]){value=new Indexed(resultIndexed[indexedIndex++])}else{try{value=resultIndexed[indexedIndex++]}catch(error){value=error}}}else{try{value=resultNonIndexed[nonIndexedIndex++]}catch(error){value=error}}values.push(value);keys.push(param.name||null)});return Result.fromItems(values,keys)}parseTransaction(tx){const data=getBytes(tx.data,"tx.data");const value=getBigInt(tx.value!=null?tx.value:0,"tx.value");const fragment=this.getFunction(hexlify(data.slice(0,4)));if(!fragment){return null}const args=this.#abiCoder.decode(fragment.inputs,data.slice(4));return new TransactionDescription(fragment,fragment.selector,args,value)}parseCallResult(data){throw new Error("@TODO")}parseLog(log){const fragment=this.getEvent(log.topics[0]);if(!fragment||fragment.anonymous){return null}return new LogDescription(fragment,fragment.topicHash,this.decodeEventLog(fragment,log.data,log.topics))}parseError(data){const hexData=hexlify(data);const fragment=this.getError(dataSlice(hexData,0,4));if(!fragment){return null}const args=this.#abiCoder.decode(fragment.inputs,dataSlice(hexData,4));return new ErrorDescription(fragment,fragment.selector,args)}static from(value){if(value instanceof Interface){return value}if(typeof value==="string"){return new Interface(JSON.parse(value))}if(typeof value.format==="function"){return new Interface(value.format("json"))}return new Interface(value)}}const logger=new Logger("contract-address/0.0.1");function getCreateAddress(tx){const from=getAddress(tx.from);const nonce=getBigInt(tx.nonce,"tx.nonce");let nonceHex=nonce.toString(16);if(nonceHex==="0"){nonceHex="0x"}else if(nonceHex.length%2){nonceHex="0x0"+nonceHex}else{nonceHex="0x"+nonceHex}return getAddress(from)}function getCreate2Address(from,salt,initCodeHash){if(hexDataLength(salt)!==32){logger.throwArgumentError("salt must be 32 bytes","salt",salt)}if(hexDataLength(initCodeHash)!==32){logger.throwArgumentError("initCodeHash must be 32 bytes","initCodeHash",initCodeHash)}const val=hexDataSlice(sha256(concat(["0xff",getAddress(from),salt,initCodeHash])),12);console.log({"contract-address/74=>should be string":val});const prefix=from.substring(2,4);const checksum=calculateCheckSum(val,prefix);return"0x"+prefix+checksum+removeHexPrefix(val)}function isAddressable(value){return value&&typeof value.getAddress==="function"}function isAddress(value){try{getAddress(value);return true}catch(error){}return false}async function checkAddress(target,promise){const result=await promise;if(result==null||result==="0x0000000000000000000000000000000000000000"){assert(typeof target!=="string","unconfigured name","UNCONFIGURED_NAME",{value:target});assertArgument(false,"invalid AddressLike value; did not resolve to a value address","target",target)}return getAddress(result)}function resolveAddress(target){if(typeof target==="string"){return getAddress(target)}else if(isAddressable(target)){return checkAddress(target,target.getAddress())}else if(target&&typeof target.then==="function"){return checkAddress(target,target)}assertArgument(false,"unsupported addressable value","target",target)}const BN_0$2=BigInt(0);function getValue(value){if(value==null){return null}return value}function toJson(value){if(value==null){return null}return value.toString()}class FeeData{energyPrice;constructor(energyPrice){defineProperties(this,{energyPrice:getValue(energyPrice)})}toJSON(){const{energyPrice}=this;return{_type:"FeeData",energyPrice:toJson(energyPrice)}}}function copyRequest(req){const result={};if(req.to){result.to=req.to}if(req.from){result.from=req.from}if(req.data){result.data=hexlify(req.data)}const bigIntKeys="networkId,energyLimit,energyPrice,value".split(/,/);for(const key of bigIntKeys){if(!(key in req)||req[key]==null){continue}result[key]=getBigInt(req[key],`request.${key}`)}const numberKeys="type,nonce".split(/,/);for(const key of numberKeys){if(!(key in req)||req[key]==null){continue}result[key]=getNumber(req[key],`request.${key}`)}if("blockTag"in req){result.blockTag=req.blockTag}if("enableCcipRead"in req){result.enableCcipReadEnabled=!!req.enableCcipRead}if("customData"in req){result.customData=req.customData}return result}class Block{provider;number;hash;timestamp;parentHash;nonce;difficulty;energyLimit;energyUsed;miner;extraData;baseFeePerEnergy;#transactions;constructor(block,provider){this.#transactions=block.transactions.map(tx=>{if(typeof tx!=="string"){return new TransactionResponse(tx,provider)}return tx});defineProperties(this,{provider:provider,hash:getValue(block.hash),number:block.number,timestamp:block.timestamp,parentHash:block.parentHash,nonce:block.nonce,difficulty:block.difficulty,energyLimit:block.energyLimit,energyUsed:block.energyUsed,miner:block.miner,extraData:block.extraData,baseFeePerEnergy:getValue(block.baseFeePerEnergy)})}get transactions(){return this.#transactions.map(tx=>{if(typeof tx==="string"){return tx}return tx.hash})}get prefetchedTransactions(){const txs=this.#transactions.slice();if(txs.length===0){return[]}assert(typeof txs[0]==="object","transactions were not prefetched with block request","UNSUPPORTED_OPERATION",{operation:"transactionResponses()"});return txs}toJSON(){const{baseFeePerEnergy,difficulty,extraData,energyLimit,energyUsed,hash,miner,nonce,number,parentHash,timestamp,transactions}=this;return{_type:"Block",baseFeePerEnergy:toJson(baseFeePerEnergy),difficulty:toJson(difficulty),extraData:extraData,energyLimit:toJson(energyLimit),energyUsed:toJson(energyUsed),hash:hash,miner:miner,nonce:nonce,number:number,parentHash:parentHash,timestamp:timestamp,transactions:transactions}}[Symbol.iterator](){let index=0;const txs=this.transactions;return{next:()=>{if(index{return new Log(log,provider)}));defineProperties(this,{provider:provider,to:tx.to,from:tx.from,contractAddress:tx.contractAddress,hash:tx.hash,index:tx.index,blockHash:tx.blockHash,blockNumber:tx.blockNumber,logsBloom:tx.logsBloom,energyUsed:tx.energyUsed,cumulativeEnergyUsed:tx.cumulativeEnergyUsed,energyPrice:tx.effectiveEnergyPrice||tx.energyPrice,status:tx.status,root:tx.root})}get logs(){return this.#logs}toJSON(){const{to,from,contractAddress,hash,index,blockHash,blockNumber,logsBloom,logs,status,root}=this;return{_type:"TransactionReceipt",blockHash:blockHash,blockNumber:blockNumber,contractAddress:contractAddress,cumulativeEnergyUsed:toJson(this.cumulativeEnergyUsed),from:from,energyPrice:toJson(this.energyPrice),energyUsed:toJson(this.energyUsed),hash:hash,index:index,logs:logs,logsBloom:logsBloom,root:root,status:status,to:to}}get length(){return this.logs.length}[Symbol.iterator](){let index=0;return{next:()=>{if(index{if(stopScanning){return null}const{blockNumber,nonce}=await resolveProperties({blockNumber:this.provider.getBlockNumber(),nonce:this.provider.getTransactionCount(this.from)});if(nonce=confirms){return receipt}}else{await checkReplacement();if(confirms===0){return null}}const waiter=new Promise((resolve,reject)=>{const cancellers=[];const cancel=()=>{cancellers.forEach(c=>c())};cancellers.push(()=>{stopScanning=true});if(timeout>0){const timer=setTimeout(()=>{cancel();reject(makeError("wait for transaction timeout","TIMEOUT"))},timeout);cancellers.push(()=>{clearTimeout(timer)})}const txListener=async receipt=>{if(await receipt.confirmations()>=confirms){cancel();resolve(receipt)}};cancellers.push(()=>{this.provider.off(this.hash,txListener)});this.provider.on(this.hash,txListener);if(startBlock>=0){const replaceListener=async()=>{try{await checkReplacement()}catch(error){if(isError(error,"TRANSACTION_REPLACED")){cancel();reject(error);return}}if(!stopScanning){this.provider.once("block",replaceListener)}};cancellers.push(()=>{this.provider.off("block",replaceListener)});this.provider.once("block",replaceListener)}});return await waiter}isMined(){return this.blockHash!=null}isLegacy(){return this.type===0}removedEvent(){assert(this.isMined(),"unmined transaction canot be orphaned","UNSUPPORTED_OPERATION",{operation:"removeEvent()"});return createRemovedTransactionFilter(this)}reorderedEvent(other){assert(this.isMined(),"unmined transaction canot be orphaned","UNSUPPORTED_OPERATION",{operation:"removeEvent()"});assert(!other||other.isMined(),"unmined 'other' transaction canot be orphaned","UNSUPPORTED_OPERATION",{operation:"removeEvent()"});return createReorderedTransactionFilter(this,other)}replaceableTransaction(startBlock){assertArgument(Number.isInteger(startBlock)&&startBlock>=0,"invalid startBlock","startBlock",startBlock);const tx=new TransactionResponse(this,this.provider);tx.#startBlock=startBlock;return tx}}function createOrphanedBlockFilter(block){return{orphan:"drop-block",hash:block.hash,number:block.number}}function createReorderedTransactionFilter(tx,other){return{orphan:"reorder-transaction",tx:tx,other:other}}function createRemovedTransactionFilter(tx){return{orphan:"drop-transaction",tx:tx}}function createRemovedLogFilter(log){return{orphan:"drop-log",log:{transactionHash:log.transactionHash,blockHash:log.blockHash,blockNumber:log.blockNumber,address:log.address,data:log.data,topics:Object.freeze(log.topics.slice()),index:log.index}}}class EventLog extends Log{interface;fragment;args;constructor(log,iface,fragment){super(log,log.provider);const args=iface.decodeEventLog(fragment,log.data,log.topics);defineProperties(this,{args:args,fragment:fragment,interface:iface})}get eventName(){return this.fragment.name}get eventSignature(){return this.fragment.format()}}class ContractTransactionReceipt extends TransactionReceipt{#iface;constructor(iface,provider,tx){super(tx,provider);this.#iface=iface}get logs(){return super.logs.map(log=>{const fragment=log.topics.length?this.#iface.getEvent(log.topics[0]):null;if(fragment){return new EventLog(log,this.#iface,fragment)}else{return log}})}}class ContractTransactionResponse extends TransactionResponse{#iface;constructor(iface,provider,tx){super(tx,provider);this.#iface=iface}async wait(confirms){const receipt=await super.wait();if(receipt==null){return null}return new ContractTransactionReceipt(this.#iface,this.provider,receipt)}}class ContractUnknownEventPayload extends EventPayload{log;constructor(contract,listener,filter,log){super(contract,listener,filter);defineProperties(this,{log:log})}async getBlock(){return await this.log.getBlock()}async getTransaction(){return await this.log.getTransaction()}async getTransactionReceipt(){return await this.log.getTransactionReceipt()}}class ContractEventPayload extends ContractUnknownEventPayload{constructor(contract,listener,filter,fragment,_log){super(contract,listener,filter,new EventLog(_log,contract.interface,fragment));const args=contract.interface.decodeEventLog(fragment,this.log.data,this.log.topics);defineProperties(this,{args:args,fragment:fragment})}get eventName(){return this.fragment.name}get eventSignature(){return this.fragment.format()}}const BN_0$1=BigInt(0);function canCall(value){return value&&typeof value.call==="function"}function canEstimate(value){return value&&typeof value.estimateEnergy==="function"}function canResolve(value){return value&&typeof value.resolveName==="function"}function canSend(value){return value&&typeof value.sendTransaction==="function"}class PreparedTopicFilter{#filter;fragment;constructor(contract,fragment,args){defineProperties(this,{fragment:fragment});if(fragment.inputs.length{const arg=args[index];if(arg==null){return null}return param.walkAsync(args[index],(type,value)=>{if(type==="address"){return resolveAddress(value)}return value})}));return contract.interface.encodeFilterTopics(fragment,resolvedArgs)}()}getTopicFilter(){return this.#filter}}function getRunner(value,feature){if(value==null){return null}if(typeof value[feature]==="function"){return value}if(value.provider&&typeof value.provider[feature]==="function"){return value.provider}return null}function getProvider(value){if(value==null){return null}return value.provider||null}async function copyOverrides(arg,allowed){const overrides=copyRequest(Typed.dereference(arg,"overrides"));assertArgument(overrides.to==null||(allowed||[]).indexOf("to")>=0,"cannot override to","overrides.to",overrides.to);assertArgument(overrides.data==null||(allowed||[]).indexOf("data")>=0,"cannot override data","overrides.data",overrides.data);if(overrides.from){overrides.from=await resolveAddress(overrides.from)}return overrides}async function resolveArgs(_runner,inputs,args){return await Promise.all(inputs.map((param,index)=>{return param.walkAsync(args[index],(type,value)=>{value=Typed.dereference(value,type);if(type==="address"){return resolveAddress(value)}return value})}))}function buildWrappedFallback(contract){const populateTransaction=async function(overrides){const tx=await copyOverrides(overrides,["data"]);tx.to=await contract.getAddress();const iface=contract.interface;const payable=iface.receive||iface.fallback&&iface.fallback.payable;assertArgument(payable||(tx.value||BN_0$1)===BN_0$1,"cannot send value to non-payable contract","overrides.value",tx.value);assertArgument(iface.fallback||(tx.data||"0x")==="0x","cannot send data to receive-only contract","overrides.data",tx.data);return tx};const staticCall=async function(overrides){const runner=getRunner(contract.runner,"call");assert(canCall(runner),"contract runner does not support calling","UNSUPPORTED_OPERATION",{operation:"call"});const tx=await populateTransaction(overrides);try{return await runner.call(tx)}catch(error){if(isCallException(error)&&error.data){throw contract.interface.makeError(error.data,tx)}throw error}};const send=async function(overrides){const runner=contract.runner;assert(canSend(runner),"contract runner does not support sending transactions","UNSUPPORTED_OPERATION",{operation:"sendTransaction"});const tx=await runner.sendTransaction(await populateTransaction(overrides));const provider=getProvider(contract.runner);return new ContractTransactionResponse(contract.interface,provider,tx)};const estimateEnergy=async function(overrides){const runner=getRunner(contract.runner,"estimateEnergy");assert(canEstimate(runner),"contract runner does not support energy estimation","UNSUPPORTED_OPERATION",{operation:"estimateEnergy"});return await runner.estimateEnergy(await populateTransaction(overrides))};const method=async overrides=>{return await send(overrides)};defineProperties(method,{_contract:contract,estimateEnergy:estimateEnergy,populateTransaction:populateTransaction,send:send,staticCall:staticCall});return method}function buildWrappedMethod(contract,key){const getFragment=function(...args){const fragment=contract.interface.getFunction(key,args);assert(fragment,"no matching fragment in getFragment","UNSUPPORTED_OPERATION",{operation:"fragment"});return fragment};const populateTransaction=async function(...args){const fragment=getFragment(...args);let overrides={};if(fragment.inputs.length+1===args.length){overrides=await copyOverrides(args.pop())}if(fragment.inputs.length!==args.length){throw new Error("internal error: fragment inputs doesn't match arguments; should not happen")}const resolvedArgs=await resolveArgs(contract.runner,fragment.inputs,args);return Object.assign({},overrides,await resolveProperties({to:contract.getAddress(),data:contract.interface.encodeFunctionData(fragment,resolvedArgs)}))};const staticCall=async function(...args){const result=await staticCallResult(...args);if(result.length===1){return result[0]}return result};const send=async function(...args){const runner=contract.runner;assert(canSend(runner),"contract runner does not support sending transactions","UNSUPPORTED_OPERATION",{operation:"sendTransaction"});const tx=await runner.sendTransaction(await populateTransaction(...args));const provider=getProvider(contract.runner);return new ContractTransactionResponse(contract.interface,provider,tx)};const estimateEnergy=async function(...args){const runner=getRunner(contract.runner,"estimateEnergy");assert(canEstimate(runner),"contract runner does not support energy estimation","UNSUPPORTED_OPERATION",{operation:"estimateEnergy"});return await runner.estimateEnergy(await populateTransaction(...args))};const staticCallResult=async function(...args){const runner=getRunner(contract.runner,"call");assert(canCall(runner),"contract runner does not support calling","UNSUPPORTED_OPERATION",{operation:"call"});const tx=await populateTransaction(...args);let result="0x";try{result=await runner.call(tx)}catch(error){if(isCallException(error)&&error.data){throw contract.interface.makeError(error.data,tx)}throw error}const fragment=getFragment(...args);return contract.interface.decodeFunctionResult(fragment,result)};const method=async(...args)=>{const fragment=getFragment(...args);if(fragment.constant){return await staticCall(...args)}return await send(...args)};defineProperties(method,{name:contract.interface.getFunctionName(key),_contract:contract,_key:key,getFragment:getFragment,estimateEnergy:estimateEnergy,populateTransaction:populateTransaction,send:send,staticCall:staticCall,staticCallResult:staticCallResult});Object.defineProperty(method,"fragment",{configurable:false,enumerable:true,get:()=>{const fragment=contract.interface.getFunction(key);assert(fragment,"no matching fragment in defineProperty","UNSUPPORTED_OPERATION",{operation:"fragment"});return fragment}});return method}function buildWrappedEvent(contract,key){const getFragment=function(...args){const fragment=contract.interface.getEvent(key,args);assert(fragment,"no matching fragment in","UNSUPPORTED_OPERATION",{operation:"fragment"});return fragment};const method=function(...args){return new PreparedTopicFilter(contract,getFragment(...args),args)};defineProperties(method,{name:contract.interface.getEventName(key),_contract:contract,_key:key,getFragment:getFragment});Object.defineProperty(method,"fragment",{configurable:false,enumerable:true,get:()=>{const fragment=contract.interface.getEvent(key);assert(fragment,"no matching fragment","UNSUPPORTED_OPERATION",{operation:"fragment"});return fragment}});return method}const internal=Symbol.for("_corebcInternal_contract");const internalValues=new WeakMap;function setInternal(contract,values){internalValues.set(contract[internal],values)}function getInternal(contract){return internalValues.get(contract[internal])}function isDeferred(value){return value&&typeof value==="object"&&"getTopicFilter"in value&&typeof value.getTopicFilter==="function"&&value.fragment}async function getSubInfo(contract,event){let topics;let fragment=null;if(Array.isArray(event)){const topicHashify=function(name){if(isHexString(name,32)){return name}const fragment=contract.interface.getEvent(name);assertArgument(fragment,"unknown fragment","name",name);return fragment.topicHash};topics=event.map(e=>{if(e==null){return null}if(Array.isArray(e)){return e.map(topicHashify)}return topicHashify(e)})}else if(event==="*"){topics=[null]}else if(typeof event==="string"){if(isHexString(event,32)){topics=[event]}else{fragment=contract.interface.getEvent(event);assertArgument(fragment,"unknown fragment","event",event);topics=[fragment.topicHash]}}else if(isDeferred(event)){topics=await event.getTopicFilter()}else if("fragment"in event){fragment=event.fragment;topics=[fragment.topicHash]}else{assertArgument(false,"unknown event name","event",event)}topics=topics.map(t=>{if(t==null){return null}if(Array.isArray(t)){const items=Array.from(new Set(t.map(t=>t.toLowerCase())).values());if(items.length===1){return items[0]}items.sort();return items}return t.toLowerCase()});const tag=topics.map(t=>{if(t==null){return"null"}if(Array.isArray(t)){return t.join("|")}return t}).join("&");return{fragment:fragment,tag:tag,topics:topics}}async function hasSub(contract,event){const{subs}=getInternal(contract);return subs.get((await getSubInfo(contract,event)).tag)||null}async function getSub(contract,operation,event){const provider=getProvider(contract.runner);assert(provider,"contract runner does not support subscribing","UNSUPPORTED_OPERATION",{operation:operation});const{fragment,tag,topics}=await getSubInfo(contract,event);const{addr,subs}=getInternal(contract);let sub=subs.get(tag);if(!sub){const address=addr?addr:contract;const filter={address:address,topics:topics};const listener=log=>{let foundFragment=fragment;if(foundFragment==null){try{foundFragment=contract.interface.getEvent(log.topics[0])}catch(error){}}if(foundFragment){const _foundFragment=foundFragment;const args=fragment?contract.interface.decodeEventLog(fragment,log.data,log.topics):[];emit(contract,event,args,listener=>{return new ContractEventPayload(contract,listener,event,_foundFragment,log)})}else{emit(contract,event,[],listener=>{return new ContractUnknownEventPayload(contract,listener,event,log)})}};let starting=[];const start=()=>{if(starting.length){return}starting.push(provider.on(filter,listener))};const stop=async()=>{if(starting.length==0){return}let started=starting;starting=[];await Promise.all(started);provider.off(filter,listener)};sub={tag:tag,listeners:[],start:start,stop:stop};subs.set(tag,sub)}return sub}let lastEmit=Promise.resolve();async function _emit(contract,event,args,payloadFunc){await lastEmit;const sub=await hasSub(contract,event);if(!sub){return false}const count=sub.listeners.length;sub.listeners=sub.listeners.filter(({listener,once})=>{const passArgs=Array.from(args);if(payloadFunc){passArgs.push(payloadFunc(once?null:listener))}try{listener.call(contract,...passArgs)}catch(error){}return!once});return count>0}async function emit(contract,event,args,payloadFunc){try{await lastEmit}catch(error){}const resultPromise=_emit(contract,event,args,payloadFunc);lastEmit=resultPromise;return await resultPromise}const passProperties=["then"];class BaseContract{target;interface;runner;filters;[internal];fallback;constructor(target,abi,runner,_deployTx){if(runner==null){runner=null}const iface=Interface.from(abi);defineProperties(this,{target:target,runner:runner,interface:iface});Object.defineProperty(this,internal,{value:{}});let addrPromise;let addr=null;let deployTx=null;if(_deployTx){const provider=getProvider(runner);deployTx=new ContractTransactionResponse(this.interface,provider,_deployTx)}let subs=new Map;if(typeof target==="string"){if(isHexString(target)){addr=target;addrPromise=Promise.resolve(target)}else{const resolver=getRunner(runner,"resolveName");if(!canResolve(resolver)){throw makeError("contract runner does not support name resolution","UNSUPPORTED_OPERATION",{operation:"resolveName"})}addrPromise=resolver.resolveName(target).then(addr=>{if(addr==null){throw new Error("TODO")}getInternal(this).addr=addr;return addr})}}else{addrPromise=target.getAddress().then(addr=>{if(addr==null){throw new Error("TODO")}getInternal(this).addr=addr;return addr})}setInternal(this,{addrPromise:addrPromise,addr:addr,deployTx:deployTx,subs:subs});const filters=new Proxy({},{get:(target,_prop,receiver)=>{if(passProperties.indexOf(_prop)>=0){return Reflect.get(target,_prop,receiver)}const prop=String(_prop);const result=this.getEvent(prop);if(result){return result}throw new Error(`unknown contract event: ${prop}`)},has:(target,prop)=>{if(passProperties.indexOf(prop)>=0){return Reflect.has(target,prop)}return Reflect.has(target,prop)||this.interface.hasEvent(String(prop))}});defineProperties(this,{filters:filters});defineProperties(this,{fallback:iface.receive||iface.fallback?buildWrappedFallback(this):null});return new Proxy(this,{get:(target,_prop,receiver)=>{if(_prop in target||passProperties.indexOf(_prop)>=0){return Reflect.get(target,_prop,receiver)}const prop=String(_prop);const result=target.getFunction(prop);if(result){return result}throw new Error(`unknown contract method: ${prop}`)},has:(target,prop)=>{if(prop in target||passProperties.indexOf(prop)>=0){return Reflect.has(target,prop)}return target.interface.hasFunction(String(prop))}})}connect(runner){return new BaseContract(this.target,this.interface,runner)}async getAddress(){return await getInternal(this).addrPromise}async getDeployedCode(){const provider=getProvider(this.runner);assert(provider,"runner does not support .provider","UNSUPPORTED_OPERATION",{operation:"getDeployedCode"});const code=await provider.getCode(await this.getAddress());if(code==="0x"){return null}return code}async waitForDeployment(){const deployTx=this.deploymentTransaction();if(deployTx){await deployTx.wait();return this}const code=await this.getDeployedCode();if(code!=null){return this}const provider=getProvider(this.runner);assert(provider!=null,"contract runner does not support .provider","UNSUPPORTED_OPERATION",{operation:"waitForDeployment"});return new Promise((resolve,reject)=>{const checkCode=async()=>{try{const code=await this.getDeployedCode();if(code!=null){return resolve(this)}provider.once("block",checkCode)}catch(error){reject(error)}};checkCode()})}deploymentTransaction(){return getInternal(this).deployTx}getFunction(key){if(typeof key!=="string"){key=key.format()}const func=buildWrappedMethod(this,key);return func}getEvent(key){if(typeof key!=="string"){key=key.format()}return buildWrappedEvent(this,key)}async queryTransaction(hash){throw new Error("@TODO")}async queryFilter(event,fromBlock,toBlock){if(fromBlock==null){fromBlock=0}if(toBlock==null){toBlock="latest"}const{addr,addrPromise}=getInternal(this);const address=addr?addr:await addrPromise;const{fragment,topics}=await getSubInfo(this,event);const filter={address:address,topics:topics,fromBlock:fromBlock,toBlock:toBlock};const provider=getProvider(this.runner);assert(provider,"contract runner does not have a provider","UNSUPPORTED_OPERATION",{operation:"queryFilter"});return(await provider.getLogs(filter)).map(log=>{let foundFragment=fragment;if(foundFragment==null){try{foundFragment=this.interface.getEvent(log.topics[0])}catch(error){}}if(foundFragment){return new EventLog(log,this.interface,foundFragment)}else{return new Log(log,provider)}})}async on(event,listener){const sub=await getSub(this,"on",event);sub.listeners.push({listener:listener,once:false});sub.start();return this}async once(event,listener){const sub=await getSub(this,"once",event);sub.listeners.push({listener:listener,once:true});sub.start();return this}async emit(event,...args){return await emit(this,event,args,null)}async listenerCount(event){if(event){const sub=await hasSub(this,event);if(!sub){return 0}return sub.listeners.length}const{subs}=getInternal(this);let total=0;for(const{listeners}of subs.values()){total+=listeners.length}return total}async listeners(event){if(event){const sub=await hasSub(this,event);if(!sub){return[]}return sub.listeners.map(({listener})=>listener)}const{subs}=getInternal(this);let result=[];for(const{listeners}of subs.values()){result=result.concat(listeners.map(({listener})=>listener))}return result}async off(event,listener){const sub=await hasSub(this,event);if(!sub){return this}if(listener){const index=sub.listeners.map(({listener})=>listener).indexOf(listener);if(index>=0){sub.listeners.splice(index,1)}}if(listener==null||sub.listeners.length===0){sub.stop();getInternal(this).subs.delete(sub.tag)}return this}async removeAllListeners(event){if(event){const sub=await hasSub(this,event);if(!sub){return this}sub.stop();getInternal(this).subs.delete(sub.tag)}else{const{subs}=getInternal(this);for(const{tag,stop}of subs.values()){stop();subs.delete(tag)}}return this}async addListener(event,listener){return await this.on(event,listener)}async removeListener(event,listener){return await this.off(event,listener)}static buildClass(abi){class CustomContract extends BaseContract{constructor(address,runner=null){super(address,abi,runner)}}return CustomContract}static from(target,abi,runner){if(runner==null){runner=null}const contract=new this(target,abi,runner);return contract}static isIndexed(value){return Indexed.isIndexed(value)}}function _ContractBase(){return BaseContract}class Contract extends _ContractBase(){}class ContractFactory{interface;bytecode;runner;constructor(abi,bytecode,runner){const iface=Interface.from(abi);if(bytecode instanceof Uint8Array){bytecode=hexlify(getBytes(bytecode))}else if(typeof bytecode==="string"){bytecode=bytecode}else if(isBytes(bytecode)){bytecode=hexlify(bytecode)}else if(bytecode&&typeof bytecode.object==="string"){bytecode=bytecode.object}else{bytecode="!"}defineProperties(this,{bytecode:bytecode,interface:iface,runner:runner||null})}async getDeployTransaction(...args){let overrides={};const fragment=this.interface.deploy;if(fragment.inputs.length+1===args.length){overrides=await copyOverrides(args.pop())}if(fragment.inputs.length!==args.length){throw new Error("incorrect number of arguments to constructor")}const resolvedArgs=await resolveArgs(this.runner,fragment.inputs,args);const data=concat([this.bytecode,this.interface.encodeDeploy(resolvedArgs)]);return Object.assign({},overrides,{data:data})}async deploy(...args){const tx=await this.getDeployTransaction(...args);assert(this.runner&&typeof this.runner.sendTransaction==="function","factory runner does not support sending transactions","UNSUPPORTED_OPERATION",{operation:"sendTransaction"});const sentTx=await this.runner.sendTransaction(tx);const address=getCreateAddress(sentTx);return new BaseContract(address,this.interface,this.runner,sentTx)}connect(runner){return new ContractFactory(this.interface,this.bytecode,runner)}static fromSolidity(output,runner){assertArgument(output!=null,"bad compiler output","output",output);if(typeof output==="string"){output=JSON.parse(output)}const abi=output.abi;let bytecode="";if(output.bytecode){bytecode=output.bytecode}else if(output.evm&&output.evm.bytecode){bytecode=output.evm.bytecode}return new this(abi,bytecode,runner)}}const BN_0=BigInt(0);function allowNull(format,nullValue){return function(value){if(value==null){return nullValue}return format(value)}}function arrayOf(format){return array=>{if(!Array.isArray(array)){throw new Error("not an array")}return array.map(i=>format(i))}}function object(format,altNames){return value=>{const result={};for(const key in format){let srcKey=key;if(altNames&&key in altNames&&!(srcKey in value)){for(const altKey of altNames[key]){if(altKey in value){srcKey=altKey;break}}}try{const nv=format[key](value[srcKey]);if(nv!==undefined){result[key]=nv}}catch(error){const message=error instanceof Error?error.message:"not-an-error";assert(false,`invalid value for value.${key} (${message})`,"BAD_DATA",{value:value})}}return result}}function formatBoolean(value){switch(value){case true:case"true":return true;case false:case"false":return false}assertArgument(false,`invalid boolean; ${JSON.stringify(value)}`,"value",value)}function formatData(value){assertArgument(isHexString(value,true),"invalid data","value",value);return value}function formatHash(value){assertArgument(isHexString(value,32),"invalid hash","value",value);return value}const _formatLog=object({address:getAddress,blockHash:formatHash,blockNumber:getNumber,data:formatData,index:getNumber,removed:allowNull(formatBoolean,false),topics:arrayOf(formatHash),transactionHash:formatHash,transactionIndex:getNumber},{index:["logIndex"]});function formatLog(value){return _formatLog(value)}const _formatBlock=object({hash:allowNull(formatHash),parentHash:formatHash,number:getNumber,timestamp:getNumber,nonce:allowNull(formatData),difficulty:getBigInt,energyLimit:getBigInt,energyUsed:getBigInt,miner:allowNull(getAddress),extraData:formatData,baseFeePerEnergy:allowNull(getBigInt)});function formatBlock(value){const result=_formatBlock(value);result.transactions=value.transactions.map(tx=>{if(typeof tx==="string"){return tx}return formatTransactionResponse(tx)});return result}const _formatReceiptLog=object({transactionIndex:getNumber,blockNumber:getNumber,transactionHash:formatHash,address:getAddress,topics:arrayOf(formatHash),data:formatData,index:getNumber,blockHash:formatHash},{index:["logIndex"]});function formatReceiptLog(value){return _formatReceiptLog(value)}const _formatTransactionReceipt=object({to:allowNull(getAddress,null),from:allowNull(getAddress,null),contractAddress:allowNull(getAddress,null),index:getNumber,root:allowNull(hexlify),energyUsed:getBigInt,logsBloom:allowNull(formatData),blockHash:formatHash,hash:formatHash,logs:arrayOf(formatReceiptLog),blockNumber:getNumber,cumulativeEnergyUsed:getBigInt,effectiveEnergyPrice:allowNull(getBigInt),status:allowNull(getNumber),type:allowNull(getNumber,0)},{effectiveEnergyPrice:["energyPrice"],hash:["transactionHash"],index:["transactionIndex"]});function formatTransactionReceipt(value){return _formatTransactionReceipt(value)}function formatTransactionResponse(value){if(value.to&&!getAddress(value.to)&&getBigInt(value.to)===BN_0){value.to="0x0000000000000000000000000000000000000000"}const result=object({hash:formatHash,type:value=>{if(value==="0x"||value==null){return 0}return getNumber(value)},accessList:allowNull(accessListify,null),blockHash:allowNull(formatHash,null),blockNumber:allowNull(getNumber,null),transactionIndex:allowNull(getNumber,null),from:getAddress,maxFeePerEnergy:allowNull(getBigInt),energyLimit:getBigInt,to:allowNull(getAddress,null),value:getBigInt,nonce:getNumber,data:formatData,creates:allowNull(getAddress,null),networkId:allowNull(getBigInt,null)},{data:["input"],energyLimit:["energy"]})(value);if(result.to==null&&result.creates==null){result.creates=getCreateAddress(result)}if(value.signature){result.signature=value.signature}else{result.signature=value}if(result.networkId==null){const networkId=result.signature.legacynetworkId;if(networkId!=null){result.networkId=networkId}}if(result.blockHash&&getBigInt(result.blockHash)===BN_0){result.blockHash=null}return result}class NetworkPlugin{name;constructor(name){defineProperties(this,{name:name})}clone(){return new NetworkPlugin(this.name)}}class EnergyCostPlugin extends NetworkPlugin{effectiveBlock;txBase;txCreate;txDataZero;txDataNonzero;txAccessListStorageKey;txAccessListAddress;constructor(effectiveBlock,costs){if(effectiveBlock==null){effectiveBlock=0}super(`org.corebc.network.plugins.EnergyCost#${effectiveBlock||0}`);const props={effectiveBlock:effectiveBlock};function set(name,nullish){let value=(costs||{})[name];if(value==null){value=nullish}assertArgument(typeof value==="number",`invalud value for ${name}`,"costs",costs);props[name]=value}set("txBase",21e3);set("txCreate",32e3);set("txDataZero",4);set("txDataNonzero",16);set("txAccessListStorageKey",1900);set("txAccessListAddress",2400);defineProperties(this,props)}clone(){return new EnergyCostPlugin(this.effectiveBlock,this)}}class FeeDataNetworkPlugin extends NetworkPlugin{#feeDataFunc;get feeDataFunc(){return this.#feeDataFunc}constructor(feeDataFunc){super("org.corebc.plugins.network.FeeData");this.#feeDataFunc=feeDataFunc}async getFeeData(provider){return await this.#feeDataFunc(provider)}clone(){return new FeeDataNetworkPlugin(this.#feeDataFunc)}}const Networks=new Map;class Network{#name;#networkId;#plugins;constructor(name,networkId){this.#name=name;this.#networkId=getBigInt(networkId);this.#plugins=new Map}toJSON(){return{name:this.name,networkId:String(this.networkId)}}get name(){return this.#name}set name(value){this.#name=value}get networkId(){return this.#networkId}set networkId(value){this.#networkId=getBigInt(value,"networkId")}matches(other){if(other==null){return false}if(typeof other==="string"){try{return this.networkId===getBigInt(other)}catch(error){}return this.name===other}if(typeof other==="number"||typeof other==="bigint"){try{return this.networkId===getBigInt(other)}catch(error){}return false}if(typeof other==="object"){if(other.networkId!=null){try{return this.networkId===getBigInt(other.networkId)}catch(error){}return false}if(other.name!=null){return this.name===other.name}return false}return false}get plugins(){return Array.from(this.#plugins.values())}attachPlugin(plugin){if(this.#plugins.get(plugin.name)){throw new Error(`cannot replace existing plugin: ${plugin.name} `)}this.#plugins.set(plugin.name,plugin.clone());return this}getPlugin(name){return this.#plugins.get(name)||null}getPlugins(basename){return this.plugins.filter(p=>p.name.split("#")[0]===basename)}clone(){const clone=new Network(this.name,this.networkId);this.plugins.forEach(plugin=>{clone.attachPlugin(plugin.clone())});return clone}computeIntrinsicEnergy(tx){const costs=this.getPlugin("org.corebc.plugins.network.EnergyCost")||new EnergyCostPlugin;let energy=costs.txBase;if(tx.to==null){energy+=costs.txCreate}if(tx.data){for(let i=2;i{Network.register(name,func)})}}registerEth("mainnet",1,{ensNetwork:1,altNames:["homestead"]});registerEth("ropsten",3,{ensNetwork:3});registerEth("rinkeby",4,{ensNetwork:4});registerEth("goerli",5,{ensNetwork:5});registerEth("kovan",42,{ensNetwork:42});registerEth("sepolia",11155111,{});registerEth("classic",61,{});registerEth("classicKotti",6,{});registerEth("xdai",100,{ensNetwork:1})}function copy$2(obj){return JSON.parse(JSON.stringify(obj))}class PollingBlockSubscriber{#provider;#poller;#interval;#blockNumber;constructor(provider){this.#provider=provider;this.#poller=null;this.#interval=4e3;this.#blockNumber=-2}get pollingInterval(){return this.#interval}set pollingInterval(value){this.#interval=value}async#poll(){try{const blockNumber=await this.#provider.getBlockNumber();if(this.#blockNumber===-2){this.#blockNumber=blockNumber;return}if(blockNumber!==this.#blockNumber){for(let b=this.#blockNumber+1;b<=blockNumber;b++){if(this.#poller==null){return}await this.#provider.emit("block",b)}this.#blockNumber=blockNumber}}catch(error){}if(this.#poller==null){return}this.#poller=this.#provider._setTimeout(this.#poll.bind(this),this.#interval)}start(){if(this.#poller){return}this.#poller=this.#provider._setTimeout(this.#poll.bind(this),this.#interval);this.#poll()}stop(){if(!this.#poller){return}this.#provider._clearTimeout(this.#poller);this.#poller=null}pause(dropWhilePaused){this.stop();if(dropWhilePaused){this.#blockNumber=-2}}resume(){this.start()}}class OnBlockSubscriber{#provider;#poll;#running;constructor(provider){this.#provider=provider;this.#running=false;this.#poll=blockNumber=>{this._poll(blockNumber,this.#provider)}}async _poll(blockNumber,provider){throw new Error("sub-classes must override this")}start(){if(this.#running){return}this.#running=true;this.#poll(-2);this.#provider.on("block",this.#poll)}stop(){if(!this.#running){return}this.#running=false;this.#provider.off("block",this.#poll)}pause(dropWhilePaused){this.stop()}resume(){this.start()}}class PollingOrphanSubscriber extends OnBlockSubscriber{#filter;constructor(provider,filter){super(provider);this.#filter=copy$2(filter)}async _poll(blockNumber,provider){throw new Error("@TODO")}}class PollingTransactionSubscriber extends OnBlockSubscriber{#hash;constructor(provider,hash){super(provider);this.#hash=hash}async _poll(blockNumber,provider){const tx=await provider.getTransactionReceipt(this.#hash);if(tx){provider.emit(this.#hash,tx)}}}class PollingEventSubscriber{#provider;#filter;#poller;#running;#blockNumber;constructor(provider,filter){this.#provider=provider;this.#filter=copy$2(filter);this.#poller=this.#poll.bind(this);this.#running=false;this.#blockNumber=-2}async#poll(blockNumber){if(this.#blockNumber===-2){return}const filter=copy$2(this.#filter);filter.fromBlock=this.#blockNumber+1;filter.toBlock=blockNumber;const logs=await this.#provider.getLogs(filter);if(logs.length===0){if(this.#blockNumber{this.#blockNumber=blockNumber})}this.#provider.on("block",this.#poller)}stop(){if(!this.#running){return}this.#running=false;this.#provider.off("block",this.#poller)}pause(dropWhilePaused){this.stop();if(dropWhilePaused){this.#blockNumber=-2}}resume(){this.start()}}const MAX_CCIP_REDIRECTS=10;function isPromise(value){return value&&typeof value.then==="function"}function getTag(prefix,value){return prefix+":"+JSON.stringify(value,(k,v)=>{if(v==null){return"null"}if(typeof v==="bigint"){return`bigint:${v.toString()}`}if(typeof v==="string"){return v.toLowerCase()}if(typeof v==="object"&&!Array.isArray(v)){const keys=Object.keys(v);keys.sort();return keys.reduce((accum,key)=>{accum[key]=v[key];return accum},{})}return v})}class UnmanagedSubscriber{name;constructor(name){defineProperties(this,{name:name})}start(){}stop(){}pause(dropWhilePaused){}resume(){}}function copy$1(value){return JSON.parse(JSON.stringify(value))}function concisify(items){items=Array.from(new Set(items).values());items.sort();return items}async function getSubscription(_event,provider){if(_event==null){throw new Error("invalid event")}if(Array.isArray(_event)){_event={topics:_event}}if(typeof _event==="string"){switch(_event){case"block":case"pending":case"debug":case"error":case"network":{return{type:_event,tag:_event}}}}if(isHexString(_event,32)){const hash=_event.toLowerCase();return{type:"transaction",tag:getTag("tx",{hash:hash}),hash:hash}}if(_event.orphan){const event=_event;return{type:"orphan",tag:getTag("orphan",event),filter:copy$1(event)}}if(_event.address||_event.topics){const event=_event;const filter={topics:(event.topics||[]).map(t=>{if(t==null){return null}if(Array.isArray(t)){return concisify(t.map(t=>t.toLowerCase()))}return t.toLowerCase()})};if(event.address){const addresses=[];const promises=[];const addAddress=addr=>{if(isHexString(addr)){addresses.push(addr)}else{promises.push((async()=>{addresses.push(await resolveAddress(addr))})())}};if(Array.isArray(event.address)){event.address.forEach(addAddress)}else{addAddress(event.address)}if(promises.length){await Promise.all(promises)}filter.address=concisify(addresses.map(a=>a.toLowerCase()))}return{filter:filter,tag:getTag("event",filter),type:"event"}}assertArgument(false,"unknown ProviderEvent","event",_event)}function getTime$1(){return(new Date).getTime()}class AbstractProvider{#subs;#plugins;#pausedState;#networkPromise;#anyNetwork;#performCache;#lastBlockNumber;#nextTimer;#timers;#disableCcipRead;constructor(_network){if(_network==="any"){this.#anyNetwork=true;this.#networkPromise=null}else if(_network){const network=Network.from(_network);this.#anyNetwork=false;this.#networkPromise=Promise.resolve(network);setTimeout(()=>{this.emit("network",network,null)},0)}else{this.#anyNetwork=false;this.#networkPromise=null}this.#lastBlockNumber=-1;this.#performCache=new Map;this.#subs=new Map;this.#plugins=new Map;this.#pausedState=null;this.#nextTimer=1;this.#timers=new Map;this.#disableCcipRead=false}get provider(){return this}get plugins(){return Array.from(this.#plugins.values())}attachPlugin(plugin){if(this.#plugins.get(plugin.name)){throw new Error(`cannot replace existing plugin: ${plugin.name} `)}this.#plugins.set(plugin.name,plugin.connect(this));return this}getPlugin(name){return this.#plugins.get(name)||null}get disableCcipRead(){return this.#disableCcipRead}set disableCcipRead(value){this.#disableCcipRead=!!value}async#perform(req){const tag=getTag(req.method,req);let perform=this.#performCache.get(tag);if(!perform){perform=this._perform(req);this.#performCache.set(tag,perform);setTimeout(()=>{if(this.#performCache.get(tag)===perform){this.#performCache.delete(tag)}},250)}return await perform}async ccipReadFetch(tx,calldata,urls){if(this.disableCcipRead||urls.length===0||tx.to==null){return null}const sender=tx.to.toLowerCase();const data=calldata.toLowerCase();const errorMessages=[];for(let i=0;i=500,`response not found during CCIP fetch: ${errorMessage}`,"OFFCHAIN_FAULT",{reason:"404_MISSING_RESOURCE",transaction:tx,info:{url:url,errorMessage:errorMessage}});errorMessages.push(errorMessage)}assert(false,`error encountered during CCIP fetch: ${errorMessages.map(m=>JSON.stringify(m)).join(", ")}`,"OFFCHAIN_FAULT",{reason:"500_SERVER_ERROR",transaction:tx,info:{urls:urls,errorMessages:errorMessages}})}_wrapBlock(value,network){return new Block(formatBlock(value),this)}_wrapLog(value,network){return new Log(formatLog(value),this)}_wrapTransactionReceipt(value,network){return new TransactionReceipt(formatTransactionReceipt(value),this)}_wrapTransactionResponse(tx,network){return new TransactionResponse(formatTransactionResponse(tx),this)}_detectNetwork(){assert(false,"sub-classes must implement this","UNSUPPORTED_OPERATION",{operation:"_detectNetwork"})}async _perform(req){assert(false,`unsupported method: ${req.method}`,"UNSUPPORTED_OPERATION",{operation:req.method,info:req})}async getBlockNumber(){const blockNumber=getNumber(await this.#perform({method:"getBlockNumber"}),"%response");if(this.#lastBlockNumber>=0){this.#lastBlockNumber=blockNumber}return blockNumber}_getAddress(address){return resolveAddress(address)}_getBlockTag(blockTag){if(blockTag==null){return"latest"}switch(blockTag){case"earliest":return"0x0";case"latest":case"pending":case"safe":case"finalized":return blockTag}if(isHexString(blockTag)){if(isHexString(blockTag,32)){return blockTag}return toQuantity(blockTag)}if(typeof blockTag==="bigint"){blockTag=getNumber(blockTag,"blockTag")}if(typeof blockTag==="number"){if(blockTag>=0){return toQuantity(blockTag)}if(this.#lastBlockNumber>=0){return toQuantity(this.#lastBlockNumber+blockTag)}return this.getBlockNumber().then(b=>toQuantity(b+blockTag))}assertArgument(false,"invalid blockTag","blockTag",blockTag)}_getFilter(filter){const topics=(filter.topics||[]).map(t=>{if(t==null){return null}if(Array.isArray(t)){return concisify(t.map(t=>t.toLowerCase()))}return t.toLowerCase()});const blockHash="blockHash"in filter?filter.blockHash:undefined;const resolve=(_address,fromBlock,toBlock)=>{let address=undefined;switch(_address.length){case 0:break;case 1:address=_address[0];break;default:_address.sort();address=_address}if(blockHash){if(fromBlock!=null||toBlock!=null){throw new Error("invalid filter")}}const filter={};if(address){filter.address=address}if(topics.length){filter.topics=topics}if(fromBlock){filter.fromBlock=fromBlock}if(toBlock){filter.toBlock=toBlock}if(blockHash){filter.blockHash=blockHash}return filter};let address=[];if(filter.address){if(Array.isArray(filter.address)){for(const addr of filter.address){address.push(this._getAddress(addr))}}else{address.push(this._getAddress(filter.address))}}let fromBlock=undefined;if("fromBlock"in filter){fromBlock=this._getBlockTag(filter.fromBlock)}let toBlock=undefined;if("toBlock"in filter){toBlock=this._getBlockTag(filter.toBlock)}if(address.filter(a=>typeof a!=="string").length||fromBlock!=null&&typeof fromBlock!=="string"||toBlock!=null&&typeof toBlock!=="string"){return Promise.all([Promise.all(address),fromBlock,toBlock]).then(result=>{return resolve(result[0],result[1],result[2])})}return resolve(address,fromBlock,toBlock)}_getTransactionRequest(_request){const request=copyRequest(_request);const promises=[];["to","from"].forEach(key=>{if(request[key]==null){return}const addr=resolveAddress(request[key]);if(isPromise(addr)){promises.push(async function(){request[key]=await addr}())}else{request[key]=addr}});if(request.blockTag!=null){const blockTag=this._getBlockTag(request.blockTag);if(isPromise(blockTag)){promises.push(async function(){request.blockTag=await blockTag}())}else{request.blockTag=blockTag}}if(promises.length){return async function(){await Promise.all(promises);return request}()}return request}async getNetwork(){if(this.#networkPromise==null){const detectNetwork=this._detectNetwork().then(network=>{this.emit("network",network,null);return network},error=>{if(this.#networkPromise===detectNetwork){this.#networkPromise=null}throw error});this.#networkPromise=detectNetwork;return(await detectNetwork).clone()}const networkPromise=this.#networkPromise;const[expected,actual]=await Promise.all([networkPromise,this._detectNetwork()]);if(expected.networkId!==actual.networkId){if(this.#anyNetwork){this.emit("network",actual,expected);if(this.#networkPromise===networkPromise){this.#networkPromise=Promise.resolve(actual)}}else{assert(false,`network changed: ${expected.networkId} => ${actual.networkId} `,"NETWORK_ERROR",{event:"changed"})}}return expected.clone()}async getEnergyPrice(){const{energyPrice}=await resolveProperties({block:this.getBlock("latest"),energyPrice:(async()=>{try{const energyPrice=await this.#perform({method:"getEnergyPrice"});return getBigInt(energyPrice,"%response")}catch(error){}return null})()});return new FeeData(energyPrice)}async getFeeData(){const{energyPrice}=await resolveProperties({block:this.getBlock("latest"),energyPrice:(async()=>{try{const energyPrice=await this.#perform({method:"getEnergyPrice"});return getBigInt(energyPrice,"%response")}catch(error){}return null})()});return new FeeData(energyPrice)}async estimateEnergy(_tx){let tx=this._getTransactionRequest(_tx);if(isPromise(tx)){tx=await tx}return getBigInt(await this.#perform({method:"estimateEnergy",transaction:tx}),"%response")}async#call(tx,blockTag,attempt){assert(attempt=0&&blockTag==="latest"&&transaction.to!=null&&dataSlice(error.data,0,4)==="0x556f1830"){const data=error.data;const txSender=await resolveAddress(transaction.to);let ccipArgs;try{ccipArgs=parseOffchainLookup(dataSlice(error.data,4))}catch(error){assert(false,error.message,"OFFCHAIN_FAULT",{reason:"BAD_DATA",transaction:transaction,info:{data:data}})}assert(ccipArgs.sender.toLowerCase()===txSender.toLowerCase(),"CCIP Read sender mismatch","CALL_EXCEPTION",{action:"call",data:data,reason:"OffchainLookup",transaction:transaction,invocation:null,revert:{signature:"OffchainLookup(address,string[],bytes,bytes4,bytes)",name:"OffchainLookup",args:ccipArgs.errorArgs}});const ccipResult=await this.ccipReadFetch(transaction,ccipArgs.calldata,ccipArgs.urls);assert(ccipResult!=null,"CCIP Read failed to fetch data","OFFCHAIN_FAULT",{reason:"FETCH_FAILED",transaction:transaction,info:{data:error.data,errorArgs:ccipArgs.errorArgs}});const tx={to:txSender,data:concat([ccipArgs.selector,encodeBytes([ccipResult,ccipArgs.extraData])])};this.emit("debug",{action:"sendCcipReadCall",transaction:tx});try{const result=await this.#call(tx,blockTag,attempt+1);this.emit("debug",{action:"receiveCcipReadCallResult",transaction:Object.assign({},tx),result:result});return result}catch(error){this.emit("debug",{action:"receiveCcipReadCallError",transaction:Object.assign({},tx),error:error});throw error}}throw error}}async#checkNetwork(promise){const{value}=await resolveProperties({network:this.getNetwork(),value:promise});return value}async call(_tx){const{tx,blockTag}=await resolveProperties({tx:this._getTransactionRequest(_tx),blockTag:this._getBlockTag(_tx.blockTag)});return await this.#checkNetwork(this.#call(tx,blockTag,_tx.enableCcipRead?0:-1))}async#getAccountValue(request,_address,_blockTag){let address=this._getAddress(_address);let blockTag=this._getBlockTag(_blockTag);if(typeof address!=="string"||typeof blockTag!=="string"){[address,blockTag]=await Promise.all([address,blockTag])}return await this.#checkNetwork(this.#perform(Object.assign(request,{address:address,blockTag:blockTag})))}async getBalance(address,blockTag){return getBigInt(await this.#getAccountValue({method:"getBalance"},address,blockTag),"%response")}async getTransactionCount(address,blockTag){return getNumber(await this.#getAccountValue({method:"getTransactionCount"},address,blockTag),"%response")}async getCode(address,blockTag){return hexlify(await this.#getAccountValue({method:"getCode"},address,blockTag))}async getStorage(address,_position,blockTag){const position=getBigInt(_position,"position");return hexlify(await this.#getAccountValue({method:"getStorage",position:position},address,blockTag))}async broadcastTransaction(signedTx){const{blockNumber,hash,network}=await resolveProperties({blockNumber:this.getBlockNumber(),hash:this._perform({method:"broadcastTransaction",signedTransaction:signedTx}),network:this.getNetwork()});const tx=Transaction.from(signedTx);if(tx.hash!==hash){throw new Error("@TODO: the returned hash did not match")}return this._wrapTransactionResponse(tx,network).replaceableTransaction(blockNumber)}async#getBlock(block,includeTransactions){if(isHexString(block,32)){return await this.#perform({method:"getBlock",blockHash:block,includeTransactions:includeTransactions})}let blockTag=this._getBlockTag(block);if(typeof blockTag!=="string"){blockTag=await blockTag}return await this.#perform({method:"getBlock",blockTag:blockTag,includeTransactions:includeTransactions})}async getBlock(block,prefetchTxs){const{network,params}=await resolveProperties({network:this.getNetwork(),params:this.#getBlock(block,!!prefetchTxs)});if(params==null){return null}return this._wrapBlock(params,network)}async getTransaction(hash){const{network,params}=await resolveProperties({network:this.getNetwork(),params:this.#perform({method:"getTransaction",hash:hash})});if(params==null){return null}return this._wrapTransactionResponse(params,network)}async getTransactionReceipt(hash){const{network,params}=await resolveProperties({network:this.getNetwork(),params:this.#perform({method:"getTransactionReceipt",hash:hash})});if(params==null){return null}if(params.energyPrice==null&¶ms.effectiveEnergyPrice==null){const tx=await this.#perform({method:"getTransaction",hash:hash});if(tx==null){throw new Error("report this; could not find tx or effectiveEnergyPrice")}params.effectiveEnergyPrice=tx.energyPrice}return this._wrapTransactionReceipt(params,network)}async getTransactionResult(hash){const{result}=await resolveProperties({network:this.getNetwork(),result:this.#perform({method:"getTransactionResult",hash:hash})});if(result==null){return null}return hexlify(result)}async getLogs(_filter){let filter=this._getFilter(_filter);if(isPromise(filter)){filter=await filter}const{network,params}=await resolveProperties({network:this.getNetwork(),params:this.#perform({method:"getLogs",filter:filter})});return params.map(p=>this._wrapLog(p,network))}_getProvider(networkId){assert(false,"provider cannot connect to target network","UNSUPPORTED_OPERATION",{operation:"_getProvider()"})}async waitForTransaction(hash,_confirms,timeout){const confirms=_confirms!=null?_confirms:1;if(confirms===0){return this.getTransactionReceipt(hash)}return new Promise(async(resolve,reject)=>{let timer=null;const listener=async blockNumber=>{try{const receipt=await this.getTransactionReceipt(hash);if(receipt!=null){if(blockNumber-receipt.blockNumber+1>=confirms){resolve(receipt);if(timer){clearTimeout(timer);timer=null}return}}}catch(error){console.log("EEE",error)}this.once("block",listener)};if(timeout!=null){timer=setTimeout(()=>{if(timer==null){return}timer=null;this.off("block",listener);reject(makeError("timeout","TIMEOUT",{reason:"timeout"}))},timeout)}listener(await this.getBlockNumber())})}async waitForBlock(blockTag){assert(false,"not implemented yet","NOT_IMPLEMENTED",{operation:"waitForBlock"})}_clearTimeout(timerId){const timer=this.#timers.get(timerId);if(!timer){return}if(timer.timer){clearTimeout(timer.timer)}this.#timers.delete(timerId)}_setTimeout(_func,timeout){if(timeout==null){timeout=0}const timerId=this.#nextTimer++;const func=()=>{this.#timers.delete(timerId);_func()};if(this.paused){this.#timers.set(timerId,{timer:null,func:func,time:timeout})}else{const timer=setTimeout(func,timeout);this.#timers.set(timerId,{timer:timer,func:func,time:getTime$1()})}return timerId}_forEachSubscriber(func){for(const sub of this.#subs.values()){func(sub.subscriber)}}_getSubscriber(sub){switch(sub.type){case"debug":case"error":case"network":return new UnmanagedSubscriber(sub.type);case"block":return new PollingBlockSubscriber(this);case"event":return new PollingEventSubscriber(this,sub.filter);case"transaction":return new PollingTransactionSubscriber(this,sub.hash);case"orphan":return new PollingOrphanSubscriber(this,sub.filter)}throw new Error(`unsupported event: ${sub.type}`)}_recoverSubscriber(oldSub,newSub){for(const sub of this.#subs.values()){if(sub.subscriber===oldSub){if(sub.started){sub.subscriber.stop()}sub.subscriber=newSub;if(sub.started){newSub.start()}if(this.#pausedState!=null){newSub.pause(this.#pausedState)}break}}}async#hasSub(event,emitArgs){let sub=await getSubscription(event);if(sub.type==="event"&&emitArgs&&emitArgs.length>0&&emitArgs[0].removed===true){sub=await getSubscription({orphan:"drop-log",log:emitArgs[0]})}return this.#subs.get(sub.tag)||null}async#getSub(event){const subscription=await getSubscription(event);const tag=subscription.tag;let sub=this.#subs.get(tag);if(!sub){const subscriber=this._getSubscriber(subscription);const addressableMap=new WeakMap;const nameMap=new Map;sub={subscriber:subscriber,tag:tag,addressableMap:addressableMap,nameMap:nameMap,started:false,listeners:[]};this.#subs.set(tag,sub)}return sub}async on(event,listener){const sub=await this.#getSub(event);sub.listeners.push({listener:listener,once:false});if(!sub.started){sub.subscriber.start();sub.started=true;if(this.#pausedState!=null){sub.subscriber.pause(this.#pausedState)}}return this}async once(event,listener){const sub=await this.#getSub(event);sub.listeners.push({listener:listener,once:true});if(!sub.started){sub.subscriber.start();sub.started=true;if(this.#pausedState!=null){sub.subscriber.pause(this.#pausedState)}}return this}async emit(event,...args){const sub=await this.#hasSub(event,args);if(!sub||sub.listeners.length===0){return false}const count=sub.listeners.length;sub.listeners=sub.listeners.filter(({listener,once})=>{const payload=new EventPayload(this,once?null:listener,event);try{listener.call(this,...args,payload)}catch(error){}return!once});if(sub.listeners.length===0){if(sub.started){sub.subscriber.stop()}this.#subs.delete(sub.tag)}return count>0}async listenerCount(event){if(event){const sub=await this.#hasSub(event);if(!sub){return 0}return sub.listeners.length}let total=0;for(const{listeners}of this.#subs.values()){total+=listeners.length}return total}async listeners(event){if(event){const sub=await this.#hasSub(event);if(!sub){return[]}return sub.listeners.map(({listener})=>listener)}let result=[];for(const{listeners}of this.#subs.values()){result=result.concat(listeners.map(({listener})=>listener))}return result}async off(event,listener){const sub=await this.#hasSub(event);if(!sub){return this}if(listener){const index=sub.listeners.map(({listener})=>listener).indexOf(listener);if(index>=0){sub.listeners.splice(index,1)}}if(!listener||sub.listeners.length===0){if(sub.started){sub.subscriber.stop()}this.#subs.delete(sub.tag)}return this}async removeAllListeners(event){if(event){const{tag,started,subscriber}=await this.#getSub(event);if(started){subscriber.stop()}this.#subs.delete(tag)}else{for(const[tag,{started,subscriber}]of this.#subs){if(started){subscriber.stop()}this.#subs.delete(tag)}}return this}async addListener(event,listener){return await this.on(event,listener)}async removeListener(event,listener){return this.off(event,listener)}destroy(){this.removeAllListeners();for(const timerId of this.#timers.keys()){this._clearTimeout(timerId)}}get paused(){return this.#pausedState!=null}set paused(pause){if(!!pause===this.paused){return}if(this.paused){this.resume()}else{this.pause(false)}}pause(dropWhilePaused){this.#lastBlockNumber=-1;if(this.#pausedState!=null){if(this.#pausedState==!!dropWhilePaused){return}assert(false,"cannot change pause type; resume first","UNSUPPORTED_OPERATION",{operation:"pause"})}this._forEachSubscriber(s=>s.pause(dropWhilePaused));this.#pausedState=!!dropWhilePaused;for(const timer of this.#timers.values()){if(timer.timer){clearTimeout(timer.timer)}timer.time=getTime$1()-timer.time}}resume(){if(this.#pausedState==null){return}this._forEachSubscriber(s=>s.resume());this.#pausedState=null;for(const timer of this.#timers.values()){let timeout=timer.time;if(timeout<0){timeout=0}timer.time=getTime$1();setTimeout(timer.func,timeout)}}}function _parseString(result,start){try{const bytes=_parseBytes(result,start);if(bytes){return toUtf8String(bytes)}}catch(error){}return null}function _parseBytes(result,start){if(result==="0x"){return null}try{const offset=getNumber(dataSlice(result,start,start+32));const length=getNumber(dataSlice(result,offset,offset+32));return dataSlice(result,offset+32,offset+32+length)}catch(error){}return null}function numPad(value){const result=toBeArray(value);if(result.length>32){throw new Error("internal; should not happen")}const padded=new Uint8Array(32);padded.set(result,32-result.length);return padded}function bytesPad(value){if(value.length%32===0){return value}const result=new Uint8Array(Math.ceil(value.length/32)*32);result.set(value);return result}const empty=new Uint8Array([]);function encodeBytes(datas){const result=[];let byteCount=0;for(let i=0;i=5*32,"insufficient OffchainLookup data","OFFCHAIN_FAULT",{reason:"insufficient OffchainLookup data"});const sender=dataSlice(data,0,32);assert(dataSlice(sender,0,12)===dataSlice(zeros,0,12),"corrupt OffchainLookup sender","OFFCHAIN_FAULT",{reason:"corrupt OffchainLookup sender"});result.sender=dataSlice(sender,12);try{const urls=[];const urlsOffset=getNumber(dataSlice(data,32,64));const urlsLength=getNumber(dataSlice(data,urlsOffset,urlsOffset+32));const urlsData=dataSlice(data,urlsOffset+32);for(let u=0;uresult[k]);return result}function checkProvider(signer,operation){if(signer.provider){return signer.provider}assert(false,"missing provider","UNSUPPORTED_OPERATION",{operation:operation})}async function populate(signer,tx){let pop=copyRequest(tx);if(pop.to!=null){pop.to=resolveAddress(pop.to)}if(pop.from!=null){const from=pop.from;pop.from=Promise.all([signer.getAddress(),resolveAddress(from)]).then(([address,from])=>{assertArgument(address.toLowerCase()===from.toLowerCase(),"transaction from mismatch","tx.from",from);return address})}else{pop.from=signer.getAddress()}return await resolveProperties(pop)}class AbstractSigner{provider;constructor(provider){defineProperties(this,{provider:provider||null})}async getNonce(blockTag){return checkProvider(this,"getTransactionCount").getTransactionCount(await this.getAddress(),blockTag)}async populateCall(tx){const pop=await populate(this,tx);return pop}async populateTransaction(tx){const provider=checkProvider(this,"populateTransaction");const pop=await populate(this,tx);if(pop.nonce==null){pop.nonce=await this.getNonce("pending")}if(pop.energyLimit==null){pop.energyLimit=await this.estimateEnergy(pop)}const network=await this.provider.getNetwork();if(pop.networkId!=null){const networkId=getBigInt(pop.networkId);assertArgument(networkId===network.networkId,"transaction networkId mismatch","tx.networkId",tx.networkId)}else{pop.networkId=network.networkId}const feeData=await provider.getFeeData();if(feeData.energyPrice!=null){if(pop.energyPrice==null){pop.energyPrice=feeData.energyPrice}}else{assert(false,"failed to get consistent fee data","UNSUPPORTED_OPERATION",{operation:"signer.getFeeData"})}return await resolveProperties(pop)}async estimateEnergy(tx){return checkProvider(this,"estimateEnergy").estimateEnergy(await this.populateCall(tx))}async call(tx){return checkProvider(this,"call").call(await this.populateCall(tx))}async resolveName(name){return getAddress(name)}async sendTransaction(tx){const provider=checkProvider(this,"sendTransaction");const pop=await this.populateTransaction(tx);delete pop.from;const txObj=Transaction.from(pop);return await provider.broadcastTransaction(await this.signTransaction(txObj))}}class VoidSigner extends AbstractSigner{address;constructor(address,provider){super(provider);defineProperties(this,{address:address})}async getAddress(){return this.address}connect(provider){return new VoidSigner(this.address,provider)}#throwUnsupported(suffix,operation){assert(false,`VoidSigner cannot sign ${suffix}`,"UNSUPPORTED_OPERATION",{operation:operation})}async signTransaction(tx){this.#throwUnsupported("transactions","signTransaction")}async signMessage(message){this.#throwUnsupported("messages","signMessage")}async signTypedData(domain,types,value){this.#throwUnsupported("typed-data","signTypedData")}}const shown=new Set;function showThrottleMessage(service){if(shown.has(service)){return}shown.add(service);console.log("========= NOTICE =========");console.log(`Request-Rate Exceeded for ${service} (this message will not be repeated)`);console.log("");console.log("The default API keys for each service are provided as a highly-throttled,");console.log("community resource for low-traffic projects and early prototyping.");console.log("");console.log("While your application will continue to function, we highly recommended");console.log("signing up for your own API keys to improve performance, increase your");console.log("request rate/limit and enable other perks, such as metrics and advanced APIs.");console.log("")}function copy(obj){return JSON.parse(JSON.stringify(obj))}class FilterIdSubscriber{#provider;#filterIdPromise;#poller;#running;#network;#hault;constructor(provider){this.#provider=provider;this.#filterIdPromise=null;this.#poller=this.#poll.bind(this);this.#running=false;this.#network=null;this.#hault=false}_subscribe(provider){throw new Error("subclasses must override this")}_emitResults(provider,result){throw new Error("subclasses must override this")}_recover(provider){throw new Error("subclasses must override this")}async#poll(blockNumber){try{if(this.#filterIdPromise==null){this.#filterIdPromise=this._subscribe(this.#provider)}let filterId=null;try{filterId=await this.#filterIdPromise}catch(error){if(!isError(error,"UNSUPPORTED_OPERATION")||error.operation!=="xcb_newFilter"){throw error}}if(filterId==null){this.#filterIdPromise=null;this.#provider._recoverSubscriber(this,this._recover(this.#provider));return}const network=await this.#provider.getNetwork();if(!this.#network){this.#network=network}if(this.#network.networkId!==network.networkId){throw new Error("chaid changed")}if(this.#hault){return}const result=await this.#provider.send("xcb_getFilterChanges",[filterId]);await this._emitResults(this.#provider,result)}catch(error){console.log("@TODO",error)}this.#provider.once("block",this.#poller)}#teardown(){const filterIdPromise=this.#filterIdPromise;if(filterIdPromise){this.#filterIdPromise=null;filterIdPromise.then(filterId=>{this.#provider.send("xcb_uninstallFilter",[filterId])})}}start(){if(this.#running){return}this.#running=true;this.#poll(-2)}stop(){if(!this.#running){return}this.#running=false;this.#hault=true;this.#teardown();this.#provider.off("block",this.#poller)}pause(dropWhilePaused){if(dropWhilePaused){this.#teardown()}this.#provider.off("block",this.#poller)}resume(){this.start()}}class FilterIdEventSubscriber extends FilterIdSubscriber{#event;constructor(provider,filter){super(provider);this.#event=copy(filter)}_recover(provider){return new PollingEventSubscriber(provider,this.#event)}async _subscribe(provider){const filterId=await provider.send("xcb_newFilter",[this.#event]);return filterId}async _emitResults(provider,results){for(const result of results){provider.emit(this.#event,provider._wrapLog(result,provider._network))}}}class FilterIdPendingSubscriber extends FilterIdSubscriber{async _subscribe(provider){return await provider.send("xcb_newPendingTransactionFilter",[])}async _emitResults(provider,results){for(const result of results){provider.emit("pending",result)}}}const Primitive="bigint,boolean,function,number,string,symbol".split(/,/g);function deepCopy(value){if(value==null||Primitive.indexOf(typeof value)>=0){return value}if(typeof value.getAddress==="function"){return value}if(Array.isArray(value)){return value.map(deepCopy)}if(typeof value==="object"){return Object.keys(value).reduce((accum,key)=>{accum[key]=value[key];return accum},{})}throw new Error(`should not happen: ${value} (${typeof value})`)}function stall$3(duration){return new Promise(resolve=>{setTimeout(resolve,duration)})}function getLowerCase(value){if(value){return value.toLowerCase()}return value}function isPollable(value){return value&&typeof value.pollingInterval==="number"}const defaultOptions={polling:false,staticNetwork:null,batchStallTime:10,batchMaxSize:1<<20,batchMaxCount:100};class JsonRpcSigner extends AbstractSigner{address;constructor(provider,address){super(provider);address=getAddress(address);defineProperties(this,{address:address})}connect(provider){assert(false,"cannot reconnect JsonRpcSigner","UNSUPPORTED_OPERATION",{operation:"signer.connect"})}async getAddress(){return this.address}async populateTransaction(tx){return await this.populateCall(tx)}async sendUncheckedTransaction(_tx){const tx=deepCopy(_tx);const promises=[];if(tx.from){const _from=tx.from;promises.push((async()=>{const from=await resolveAddress(_from);assertArgument(from!=null&&from.toLowerCase()===this.address.toLowerCase(),"from address mismatch","transaction",_tx);tx.from=from})())}else{tx.from=this.address}if(tx.energyLimit==null){promises.push((async()=>{tx.energyLimit=await this.provider.estimateEnergy({...tx,from:this.address})})())}if(tx.to!=null){const _to=tx.to;promises.push((async()=>{tx.to=await resolveAddress(_to)})())}if(promises.length){await Promise.all(promises)}const hexTx=this.provider.getRpcTransaction(tx);return this.provider.send("xcb_sendTransaction",[hexTx])}async sendTransaction(tx){const blockNumber=await this.provider.getBlockNumber();const hash=await this.sendUncheckedTransaction(tx);return await new Promise((resolve,reject)=>{const timeouts=[1e3,100];const checkTx=async()=>{const tx=await this.provider.getTransaction(hash);if(tx!=null){resolve(tx.replaceableTransaction(blockNumber));return}this.provider._setTimeout(()=>{checkTx()},timeouts.pop()||4e3)};checkTx()})}async signTransaction(_tx){const tx=deepCopy(_tx);if(tx.from){const from=await resolveAddress(tx.from);assertArgument(from!=null&&from.toLowerCase()===this.address.toLowerCase(),"from address mismatch","transaction",_tx);tx.from=from}else{tx.from=this.address}const hexTx=this.provider.getRpcTransaction(tx);return await this.provider.send("xcb_signTransaction",[hexTx])}async signMessage(_message){const message=typeof _message==="string"?toUtf8Bytes(_message):_message;return await this.provider.send("personal_sign",[hexlify(message),this.address.toLowerCase()])}async signTypedData(domain,types,_value){const value=deepCopy(_value);const populated=await TypedDataEncoder.resolveNames(domain,types,value,async value=>{const address=await resolveAddress(value);assertArgument(address!=null,"TypedData does not support null address","value",value);return address});return await this.provider.send("xcb_signTypedData_v4",[this.address.toLowerCase(),JSON.stringify(TypedDataEncoder.getPayload(populated.domain,types,populated.value))])}async unlock(password){return this.provider.send("personal_unlockAccount",[this.address.toLowerCase(),password,null])}async _legacySignMessage(_message){const message=typeof _message==="string"?toUtf8Bytes(_message):_message;return await this.provider.send("xcb_sign",[this.address.toLowerCase(),hexlify(message)])}}class JsonRpcApiProvider extends AbstractProvider{#options;#nextId;#payloads;#drainTimer;#notReady;#network;#scheduleDrain(){if(this.#drainTimer){return}const stallTime=this._getOption("batchMaxCount")===1?0:this._getOption("batchStallTime");this.#drainTimer=setTimeout(()=>{this.#drainTimer=null;const payloads=this.#payloads;this.#payloads=[];while(payloads.length){const batch=[payloads.shift()];while(payloads.length){if(batch.length===this.#options.batchMaxCount){break}batch.push(payloads.shift());const bytes=JSON.stringify(batch.map(p=>p.payload));if(bytes.length>this.#options.batchMaxSize){payloads.unshift(batch.pop());break}}(async()=>{const payload=batch.length===1?batch[0].payload:batch.map(p=>p.payload);this.emit("debug",{action:"sendRpcPayload",payload:payload});try{const result=await this._send(payload);this.emit("debug",{action:"receiveRpcResult",result:result});for(const{resolve,reject,payload}of batch){const resp=result.filter(r=>r.id===payload.id)[0];if(resp==null){return reject(makeError("no response from server","BAD_DATA",{value:result,info:{payload:payload}}))}if("error"in resp){return reject(this.getRpcError(payload,resp))}resolve(resp.result)}}catch(error){this.emit("debug",{action:"receiveRpcError",error:error});for(const{reject}of batch){reject(error)}}})()}},stallTime)}constructor(network,options){super(network);this.#nextId=1;this.#options=Object.assign({},defaultOptions,options||{});this.#payloads=[];this.#drainTimer=null;this.#network=null;{let resolve=null;const promise=new Promise(_resolve=>{resolve=_resolve});this.#notReady={promise:promise,resolve:resolve}}const staticNetwork=this._getOption("staticNetwork");if(staticNetwork){assertArgument(network==null||staticNetwork.matches(network),"staticNetwork MUST match network object","options",options);this.#network=staticNetwork}}_getOption(key){return this.#options[key]}get _network(){assert(this.#network,"network is not available yet","NETWORK_ERROR");return this.#network}async _perform(req){const request=this.getRpcRequest(req);if(request!=null){return await this.send(request.method,request.args)}return super._perform(req)}async _detectNetwork(){const network=this._getOption("staticNetwork");if(network){return network}if(this.ready){return Network.from(getBigInt(await this.send("xcb_networkId",[])))}const payload={id:this.#nextId++,method:"xcb_networkId",params:[],jsonrpc:"2.0"};this.emit("debug",{action:"sendRpcPayload",payload:payload});let result;try{result=(await this._send(payload))[0]}catch(error){this.emit("debug",{action:"receiveRpcError",error:error});throw error}this.emit("debug",{action:"receiveRpcResult",result:result});if("result"in result){return Network.from(getBigInt(result.result))}throw this.getRpcError(payload,result)}_start(){if(this.#notReady==null||this.#notReady.resolve==null){return}this.#notReady.resolve();this.#notReady=null;(async()=>{while(this.#network==null){try{this.#network=await this._detectNetwork()}catch(error){console.log("JsonRpcProvider failed to startup; retry in 1s");await stall$3(1e3)}}this.#scheduleDrain()})()}async _waitUntilReady(){if(this.#notReady==null){return}return await this.#notReady.promise}_getSubscriber(sub){if(sub.type==="pending"){return new FilterIdPendingSubscriber(this)}if(sub.type==="event"){if(this._getOption("polling")){return new PollingEventSubscriber(this,sub.filter)}return new FilterIdEventSubscriber(this,sub.filter)}if(sub.type==="orphan"&&sub.filter.orphan==="drop-log"){return new UnmanagedSubscriber("orphan")}return super._getSubscriber(sub)}get ready(){return this.#notReady==null}getRpcTransaction(tx){const result={};["networkId","energyLimit","energyPrice","type","nonce","value"].forEach(key=>{if(tx[key]==null){return}let dstKey=key;if(key==="energyLimit"){dstKey="energy"}result[dstKey]=toQuantity(getBigInt(tx[key],`tx.${key}`))});["from","to","data"].forEach(key=>{if(tx[key]==null){return}result[key]=hexlify(tx[key])});return result}getRpcRequest(req){switch(req.method){case"networkId":return{method:"xcb_networkId",args:[]};case"getBlockNumber":return{method:"xcb_blockNumber",args:[]};case"getEnergyPrice":return{method:"xcb_energyPrice",args:[]};case"getBalance":{return{method:"xcb_getBalance",args:[getLowerCase(req.address),req.blockTag]}}case"getTransactionCount":return{method:"xcb_getTransactionCount",args:[getLowerCase(req.address),req.blockTag]};case"getCode":return{method:"xcb_getCode",args:[getLowerCase(req.address),req.blockTag]};case"getStorage":return{method:"xcb_getStorageAt",args:[getLowerCase(req.address),"0x"+req.position.toString(16),req.blockTag]};case"broadcastTransaction":return{method:"xcb_sendRawTransaction",args:[req.signedTransaction]};case"getBlock":if("blockTag"in req){return{method:"xcb_getBlockByNumber",args:[req.blockTag,!!req.includeTransactions]}}else if("blockHash"in req){return{method:"xcb_getBlockByHash",args:[req.blockHash,!!req.includeTransactions]}}break;case"getTransaction":return{method:"xcb_getTransactionByHash",args:[req.hash]};case"getTransactionReceipt":return{method:"xcb_getTransactionReceipt",args:[req.hash]};case"call":return{method:"xcb_call",args:[this.getRpcTransaction(req.transaction),req.blockTag]};case"estimateEnergy":{return{method:"xcb_estimateEnergy",args:[this.getRpcTransaction(req.transaction)]}}case"getLogs":if(req.filter&&req.filter.address!=null){if(Array.isArray(req.filter.address)){req.filter.address=req.filter.address.map(getLowerCase)}else{req.filter.address=getLowerCase(req.filter.address)}}return{method:"xcb_getLogs",args:[req.filter]}}return null}getRpcError(payload,_error){const{method}=payload;const{error}=_error;if(method==="xcb_estimateEnergy"&&error.message){const msg=error.message;if(!msg.match(/revert/i)&&msg.match(/insufficient funds/i)){return makeError("insufficient funds","INSUFFICIENT_FUNDS",{transaction:payload.params[0],info:{payload:payload,error:error}})}}if(method==="xcb_call"||method==="xcb_estimateEnergy"){const result=spelunkData(error);const e=AbiCoder.getBuiltinCallException(method==="xcb_call"?"call":"estimateEnergy",payload.params[0],result?result.data:null);e.info={error:error,payload:payload};return e}const message=JSON.stringify(spelunkMessage(error));if(typeof error.message==="string"&&error.message.match(/user denied|corebc-user-denied/i)){const actionMap={xcb_sign:"signMessage",personal_sign:"signMessage",xcb_signTypedData_v4:"signTypedData",xcb_signTransaction:"signTransaction",xcb_sendTransaction:"sendTransaction",xcb_requestAccounts:"requestAccess",wallet_requestAccounts:"requestAccess"};return makeError(`user rejected action`,"ACTION_REJECTED",{action:actionMap[method]||"unknown",reason:"rejected",info:{payload:payload,error:error}})}if(method==="xcb_sendRawTransaction"||method==="xcb_sendTransaction"){const transaction=payload.params[0];if(message.match(/insufficient funds|base fee exceeds energy limit/i)){return makeError("insufficient funds for intrinsic transaction cost","INSUFFICIENT_FUNDS",{transaction:transaction,info:{error:error}})}if(message.match(/nonce/i)&&message.match(/too low/i)){return makeError("nonce has already been used","NONCE_EXPIRED",{transaction:transaction,info:{error:error}})}if(message.match(/replacement transaction/i)&&message.match(/underpriced/i)){return makeError("replacement fee too low","REPLACEMENT_UNDERPRICED",{transaction:transaction,info:{error:error}})}if(message.match(/only replay-protected/i)){return makeError("legacy pre-eip-155 transactions not supported","UNSUPPORTED_OPERATION",{operation:method,info:{transaction:transaction,info:{error:error}}})}}if(message.match(/the method .* does not exist/i)){return makeError("unsupported operation","UNSUPPORTED_OPERATION",{operation:payload.method,info:{error:error}})}return makeError("could not coalesce error","UNKNOWN_ERROR",{error:error})}send(method,params){const id=this.#nextId++;const promise=new Promise((resolve,reject)=>{this.#payloads.push({resolve:resolve,reject:reject,payload:{method:method,params:params,id:id,jsonrpc:"2.0"}})});this.#scheduleDrain();return promise}async getSigner(address){if(address==null){address=0}const accountsPromise=this.send("xcb_accounts",[]);if(typeof address==="number"){const accounts=await accountsPromise;if(address>=accounts.length){throw new Error("no such account")}return new JsonRpcSigner(this,accounts[address])}const{accounts}=await resolveProperties({network:this.getNetwork(),accounts:accountsPromise});address=getAddress(address);for(const account of accounts){if(getAddress(account)===address){return new JsonRpcSigner(this,address)}}throw new Error("invalid account")}async listAccounts(){const accounts=await this.send("xcb_accounts",[]);return accounts.map(a=>new JsonRpcSigner(this,a))}}class JsonRpcApiPollingProvider extends JsonRpcApiProvider{#pollingInterval;constructor(network,options){super(network,options);this.#pollingInterval=4e3}_getSubscriber(sub){const subscriber=super._getSubscriber(sub);if(isPollable(subscriber)){subscriber.pollingInterval=this.#pollingInterval}return subscriber}get pollingInterval(){return this.#pollingInterval}set pollingInterval(value){if(!Number.isInteger(value)||value<0){throw new Error("invalid interval")}this.#pollingInterval=value;this._forEachSubscriber(sub=>{if(isPollable(sub)){sub.pollingInterval=this.#pollingInterval}})}}class JsonRpcProvider extends JsonRpcApiPollingProvider{#connect;constructor(url,network,options){if(url==null){url="http://localhost:8545"}super(network,options);if(typeof url==="string"){this.#connect=new FetchRequest(url)}else{this.#connect=url.clone()}}_getConnection(){return this.#connect.clone()}async send(method,params){await this._start();return await super.send(method,params)}async _send(payload){const request=this._getConnection();request.body=JSON.stringify(payload);request.setHeader("content-type","application/json");const response=await request.send();response.assertOk();let resp=response.bodyJson;if(!Array.isArray(resp)){resp=[resp]}return resp}}function spelunkData(value){if(value==null){return null}if(typeof value.message==="string"&&value.message.match("reverted")&&isHexString(value.data)){return{message:value.message,data:value.data}}if(typeof value==="object"){for(const key in value){const result=spelunkData(value[key]);if(result){return result}}return null}if(typeof value==="string"){try{return spelunkData(JSON.parse(value))}catch(error){}}return null}function _spelunkMessage(value,result){if(value==null){return}if(typeof value.message==="string"){result.push(value.message)}if(typeof value==="object"){for(const key in value){_spelunkMessage(value[key],result)}}if(typeof value==="string"){try{return _spelunkMessage(JSON.parse(value),result)}catch(error){}}}function spelunkMessage(value){const result=[];_spelunkMessage(value,result);return result}const defaultApiKey$1="9f7d929b018cdffb338517efa06f58359e86ff1ffd350bc889738523659e7972";function getHost$4(name){switch(name){case"mainnet":return"rpc.ankr.com/eth";case"goerli":return"rpc.ankr.com/xcb_goerli";case"matic":return"rpc.ankr.com/polygon";case"arbitrum":return"rpc.ankr.com/arbitrum"}assertArgument(false,"unsupported network","network",name)}class AnkrProvider extends JsonRpcProvider{apiKey;constructor(_network,apiKey){if(_network==null){_network="mainnet"}const network=Network.from(_network);if(apiKey==null){apiKey=defaultApiKey$1}const options={polling:true,staticNetwork:network};const request=AnkrProvider.getRequest(network,apiKey);super(request,network,options);defineProperties(this,{apiKey:apiKey})}_getProvider(networkId){try{return new AnkrProvider(networkId,this.apiKey)}catch(error){}return super._getProvider(networkId)}static getRequest(network,apiKey){if(apiKey==null){apiKey=defaultApiKey$1}const request=new FetchRequest(`https:/\/${getHost$4(network.name)}/${apiKey}`);request.allowGzip=true;if(apiKey===defaultApiKey$1){request.retryFunc=async(request,response,attempt)=>{showThrottleMessage("AnkrProvider");return true}}return request}getRpcError(payload,error){if(payload.method==="xcb_sendRawTransaction"){if(error&&error.error&&error.error.message==="INTERNAL_ERROR: could not replace existing tx"){error.error.message="replacement transaction underpriced"}}return super.getRpcError(payload,error)}isCommunityResource(){return this.apiKey===defaultApiKey$1}}const defaultApiKey="_gg7wSSi0KMBsdKnGVfHDueq6xMB9EkC";function getHost$3(name){switch(name){case"mainnet":return"eth-mainnet.alchemyapi.io";case"goerli":return"eth-goerli.g.alchemy.com";case"sepolia":return"eth-sepolia.g.alchemy.com";case"arbitrum":return"arb-mainnet.g.alchemy.com";case"arbitrum-goerli":return"arb-goerli.g.alchemy.com";case"matic":return"polygon-mainnet.g.alchemy.com";case"matic-mumbai":return"polygon-mumbai.g.alchemy.com";case"optimism":return"opt-mainnet.g.alchemy.com";case"optimism-goerli":return"opt-goerli.g.alchemy.com"}assertArgument(false,"unsupported network","network",name)}class AlchemyProvider extends JsonRpcProvider{apiKey;constructor(_network,apiKey){if(_network==null){_network="mainnet"}const network=Network.from(_network);if(apiKey==null){apiKey=defaultApiKey}const request=AlchemyProvider.getRequest(network,apiKey);super(request,network,{staticNetwork:network});defineProperties(this,{apiKey:apiKey})}_getProvider(networkId){try{return new AlchemyProvider(networkId,this.apiKey)}catch(error){}return super._getProvider(networkId)}async _perform(req){if(req.method==="getTransactionResult"){const{trace,tx}=await resolveProperties({trace:this.send("trace_transaction",[req.hash]),tx:this.getTransaction(req.hash)});if(trace==null||tx==null){return null}let data;let error=false;try{data=trace[0].result.output;error=trace[0].error==="Reverted"}catch(error){}if(data){assert(!error,"an error occurred during transaction executions","CALL_EXCEPTION",{action:"getTransactionResult",data:data,reason:null,transaction:tx,invocation:null,revert:null});return data}assert(false,"could not parse trace result","BAD_DATA",{value:trace})}return await super._perform(req)}isCommunityResource(){return this.apiKey===defaultApiKey}static getRequest(network,apiKey){if(apiKey==null){apiKey=defaultApiKey}const request=new FetchRequest(`https:/\/${getHost$3(network.name)}/v2/${apiKey}`);request.allowGzip=true;if(apiKey===defaultApiKey){request.retryFunc=async(request,response,attempt)=>{showThrottleMessage("alchemy");return true}}return request}}class CloudflareProvider extends JsonRpcProvider{constructor(_network){if(_network==null){_network="mainnet"}const network=Network.from(_network);assertArgument(network.name==="mainnet","unsupported network","network",_network);super("https://cloudflare-eth.com/",network,{staticNetwork:network})}}function getGlobal(){if(typeof self!=="undefined"){return self}if(typeof window!=="undefined"){return window}if(typeof global!=="undefined"){return global}throw new Error("unable to locate global object")}const _WebSocket=getGlobal().WebSocket;class SocketSubscriber{#provider;#filter;get filter(){return JSON.parse(this.#filter)}#filterId;#paused;#emitPromise;constructor(provider,filter){this.#provider=provider;this.#filter=JSON.stringify(filter);this.#filterId=null;this.#paused=null;this.#emitPromise=null}start(){this.#filterId=this.#provider.send("xcb_subscribe",this.filter).then(filterId=>{this.#provider._register(filterId,this);return filterId})}stop(){this.#filterId.then(filterId=>{this.#provider.send("xcb_unsubscribe",[filterId])});this.#filterId=null}pause(dropWhilePaused){assert(dropWhilePaused,"preserve logs while paused not supported by SocketSubscriber yet","UNSUPPORTED_OPERATION",{operation:"pause(false)"});this.#paused=!!dropWhilePaused}resume(){this.#paused=null}_handleMessage(message){if(this.#filterId==null){return}if(this.#paused===null){let emitPromise=this.#emitPromise;if(emitPromise==null){emitPromise=this._emit(this.#provider,message)}else{emitPromise=emitPromise.then(async()=>{await this._emit(this.#provider,message)})}this.#emitPromise=emitPromise.then(()=>{if(this.#emitPromise===emitPromise){this.#emitPromise=null}})}}async _emit(provider,message){throw new Error("sub-classes must implemente this; _emit")}}class SocketBlockSubscriber extends SocketSubscriber{constructor(provider){super(provider,["newHeads"])}async _emit(provider,message){provider.emit("block",parseInt(message.number))}}class SocketPendingSubscriber extends SocketSubscriber{constructor(provider){super(provider,["newPendingTransactions"])}async _emit(provider,message){provider.emit("pending",message)}}class SocketEventSubscriber extends SocketSubscriber{#logFilter;get logFilter(){return JSON.parse(this.#logFilter)}constructor(provider,filter){super(provider,["logs",filter]);this.#logFilter=JSON.stringify(filter)}async _emit(provider,message){provider.emit(this.logFilter,provider._wrapLog(message,provider._network))}}class SocketProvider extends JsonRpcApiProvider{#callbacks;#subs;#pending;constructor(network){super(network,{batchMaxCount:1});this.#callbacks=new Map;this.#subs=new Map;this.#pending=new Map}_getSubscriber(sub){switch(sub.type){case"close":return new UnmanagedSubscriber("close");case"block":return new SocketBlockSubscriber(this);case"pending":return new SocketPendingSubscriber(this);case"event":return new SocketEventSubscriber(this,sub.filter);case"orphan":if(sub.filter.orphan==="drop-log"){return new UnmanagedSubscriber("drop-log")}}return super._getSubscriber(sub)}_register(filterId,subscriber){this.#subs.set(filterId,subscriber);const pending=this.#pending.get(filterId);if(pending){for(const message of pending){subscriber._handleMessage(message)}this.#pending.delete(filterId)}}async _send(payload){assertArgument(!Array.isArray(payload),"WebSocket does not support batch send","payload",payload);const promise=new Promise((resolve,reject)=>{this.#callbacks.set(payload.id,{payload:payload,resolve:resolve,reject:reject})});await this._waitUntilReady();await this._write(JSON.stringify(payload));return[await promise]}async _processMessage(message){const result=JSON.parse(message);if("id"in result){const callback=this.#callbacks.get(result.id);if(callback==null){this.emit("error",makeError("received result for unknown id","UNKNOWN_ERROR",{reasonCode:"UNKNOWN_ID",result:result}));return}this.#callbacks.delete(result.id);callback.resolve(result)}else if(result.method==="xcb_subscription"){const filterId=result.params.subscription;const subscriber=this.#subs.get(filterId);if(subscriber){subscriber._handleMessage(result.params.result)}else{let pending=this.#pending.get(filterId);if(pending==null){pending=[];this.#pending.set(filterId,pending)}pending.push(result.params.result)}}}async _write(message){throw new Error("sub-classes must override this")}}class WebSocketProvider extends SocketProvider{#connect;#websocket;get websocket(){if(this.#websocket==null){throw new Error("websocket closed")}return this.#websocket}constructor(url,network){super(network);if(typeof url==="string"){this.#connect=()=>{return new _WebSocket(url)};this.#websocket=this.#connect()}else if(typeof url==="function"){this.#connect=url;this.#websocket=url()}else{this.#connect=null;this.#websocket=url}this.websocket.onopen=async()=>{try{await this._start();this.resume()}catch(error){console.log("failed to start WebsocketProvider",error)}};this.websocket.onmessage=message=>{this._processMessage(message.data)}}async _write(message){this.websocket.send(message)}async destroy(){if(this.#websocket!=null){this.#websocket.close();this.#websocket=null}super.destroy()}}const defaultProjectId="84842078b09946638c03157f83405213";function getHost$2(name){switch(name){case"mainnet":return"mainnet.infura.io";case"goerli":return"goerli.infura.io";case"sepolia":return"sepolia.infura.io";case"arbitrum":return"arbitrum-mainnet.infura.io";case"arbitrum-goerli":return"arbitrum-goerli.infura.io";case"matic":return"polygon-mainnet.infura.io";case"matic-mumbai":return"polygon-mumbai.infura.io";case"optimism":return"optimism-mainnet.infura.io";case"optimism-goerli":return"optimism-goerli.infura.io"}assertArgument(false,"unsupported network","network",name)}class InfuraWebSocketProvider extends WebSocketProvider{projectId;projectSecret;constructor(network,projectId){const provider=new InfuraProvider(network,projectId);const req=provider._getConnection();assert(!req.credentials,"INFURA WebSocket project secrets unsupported","UNSUPPORTED_OPERATION",{operation:"InfuraProvider.getWebSocketProvider()"});const url=req.url.replace(/^http/i,"ws").replace("/v3/","/ws/v3/");super(url,network);defineProperties(this,{projectId:provider.projectId,projectSecret:provider.projectSecret})}isCommunityResource(){return this.projectId===defaultProjectId}}class InfuraProvider extends JsonRpcProvider{projectId;projectSecret;constructor(_network,projectId,projectSecret){if(_network==null){_network="mainnet"}const network=Network.from(_network);if(projectId==null){projectId=defaultProjectId}if(projectSecret==null){projectSecret=null}const request=InfuraProvider.getRequest(network,projectId,projectSecret);super(request,network,{staticNetwork:network});defineProperties(this,{projectId:projectId,projectSecret:projectSecret})}_getProvider(networkId){try{return new InfuraProvider(networkId,this.projectId,this.projectSecret)}catch(error){}return super._getProvider(networkId)}isCommunityResource(){return this.projectId===defaultProjectId}static getWebSocketProvider(network,projectId){return new InfuraWebSocketProvider(network,projectId)}static getRequest(network,projectId,projectSecret){if(projectId==null){projectId=defaultProjectId}if(projectSecret==null){projectSecret=null}const request=new FetchRequest(`https:/\/${getHost$2(network.name)}/v3/${projectId}`);request.allowGzip=true;if(projectSecret){request.setCredentials("",projectSecret)}if(projectId===defaultProjectId){request.retryFunc=async(request,response,attempt)=>{showThrottleMessage("InfuraProvider");return true}}return request}}const defaultToken="919b412a057b5e9c9b6dce193c5a60242d6efadb";function getHost$1(name){switch(name){case"mainnet":return"corebc.quiknode.pro";case"arbitrum":return"corebc.arbitrum-mainnet.quiknode.pro";case"arbitrum-goerli":return"corebc.arbitrum-goerli.quiknode.pro";case"matic":return"corebc.matic.quiknode.pro";case"matic-mumbai":return"corebc.matic-testnet.quiknode.pro";case"optimism":return"corebc.optimism.quiknode.pro";case"optimism-goerli":return"corebc.optimism-goerli.quiknode.pro"}assertArgument(false,"unsupported network","network",name)}class QuickNodeProvider extends JsonRpcProvider{token;constructor(_network,token){if(_network==null){_network="mainnet"}const network=Network.from(_network);if(token==null){token=defaultToken}const request=QuickNodeProvider.getRequest(network,token);super(request,network,{staticNetwork:network});defineProperties(this,{token:token})}_getProvider(networkId){try{return new QuickNodeProvider(networkId,this.token)}catch(error){}return super._getProvider(networkId)}isCommunityResource(){return this.token===defaultToken}static getRequest(network,token){if(token==null){token=defaultToken}const request=new FetchRequest(`https:/\/${getHost$1(network.name)}/${token}`);request.allowGzip=true;if(token===defaultToken){request.retryFunc=async(request,response,attempt)=>{showThrottleMessage("QuickNodeProvider");return true}}return request}}const BN_1=BigInt("1");const BN_2=BigInt("2");function shuffle(array){for(let i=array.length-1;i>0;i--){const j=Math.floor(Math.random()*(i+1));const tmp=array[i];array[i]=array[j];array[j]=tmp}}function stall$2(duration){return new Promise(resolve=>{setTimeout(resolve,duration)})}function getTime(){return(new Date).getTime()}function stringify(value){return JSON.stringify(value,(key,value)=>{if(typeof value==="bigint"){return{type:"bigint",value:value.toString()}}return value})}const defaultConfig={stallTimeout:400,priority:1,weight:1};const defaultState={blockNumber:-2,requests:0,lateResponses:0,errorResponses:0,outOfSync:-1,unsupportedEvents:0,rollingDuration:0,score:0,_network:null,_updateNumber:null,_totalTime:0};async function waitForSync(config,blockNumber){while(config.blockNumber<0||config.blockNumber{const blockNumber=await config.provider.getBlockNumber();if(blockNumber>config.blockNumber){config.blockNumber=blockNumber}config._updateNumber=null})()}await config._updateNumber;config.outOfSync++}}function _normalize(value){if(value==null){return"null"}if(Array.isArray(value)){return"["+value.map(_normalize).join(",")+"]"}if(typeof value==="object"&&typeof value.toJSON==="function"){return _normalize(value.toJSON())}switch(typeof value){case"boolean":case"symbol":return value.toString();case"bigint":case"number":return BigInt(value).toString();case"string":return JSON.stringify(value);case"object":{const keys=Object.keys(value);keys.sort();return"{"+keys.map(k=>`${JSON.stringify(k)}:${_normalize(value[k])}`).join(",")+"}"}}console.log("Could not serialize",value);throw new Error("Hmm...")}function normalizeResult(value){if("error"in value){const error=value.error;return{tag:_normalize(error),value:error}}const result=value.result;return{tag:_normalize(result),value:result}}function checkQuorum(quorum,results){const tally=new Map;for(const{value,tag,weight}of results){const t=tally.get(tag)||{value:value,weight:0};t.weight+=weight;tally.set(tag,t)}let best=null;for(const r of tally.values()){if(r.weight>=quorum&&(!best||r.weight>best.weight)){best=r}}if(best){return best.value}return undefined}function getMedian(quorum,results){let resultWeight=0;const errorMap=new Map;let bestError=null;const values=[];for(const{value,tag,weight}of results){if(value instanceof Error){const e=errorMap.get(tag)||{value:value,weight:0};e.weight+=weight;errorMap.set(tag,e);if(bestError==null||e.weight>bestError.weight){bestError=e}}else{values.push(BigInt(value));resultWeight+=weight}}if(resultWeight=quorum){return bestError.value}return undefined}values.sort((a,b)=>aa?1:0);const mid=Math.floor(values.length/2);if(values.length%2){return values[mid]}return(values[mid-1]+values[mid]+BN_1)/BN_2}function getAnyResult(quorum,results){const result=checkQuorum(quorum,results);if(result!==undefined){return result}for(const r of results){if(r.value){return r.value}}return undefined}function getFuzzyMode(quorum,results){if(quorum===1){return getNumber(getMedian(quorum,results),"%internal")}const tally=new Map;const add=(result,weight)=>{const t=tally.get(result)||{result:result,weight:0};t.weight+=weight;tally.set(result,t)};for(const{weight,value}of results){const r=getNumber(value);add(r-1,weight);add(r,weight);add(r+1,weight)}let bestWeight=0;let bestResult=undefined;for(const{weight,result}of tally.values()){if(weight>=quorum&&(weight>bestWeight||bestResult!=null&&weight===bestWeight&&result>bestResult)){bestWeight=weight;bestResult=result}}return bestResult}class FallbackProvider extends AbstractProvider{quorum;eventQuorum;eventWorkers;#configs;#height;#initialSyncPromise;constructor(providers,network){super(network);this.#configs=providers.map(p=>{if(p instanceof AbstractProvider){return Object.assign({provider:p},defaultConfig,defaultState)}else{return Object.assign({},defaultConfig,p,defaultState)}});this.#height=-2;this.#initialSyncPromise=null;this.quorum=2;this.eventQuorum=1;this.eventWorkers=1;assertArgument(this.quorum<=this.#configs.reduce((a,c)=>a+c.weight,0),"quorum exceed provider wieght","quorum",this.quorum)}get providerConfigs(){return this.#configs.map(c=>{const result=Object.assign({},c);for(const key in result){if(key[0]==="_"){delete result[key]}}return result})}async _detectNetwork(){return Network.from(getBigInt(await this._perform({method:"networkId"})))}async _translatePerform(provider,req){switch(req.method){case"broadcastTransaction":return await provider.broadcastTransaction(req.signedTransaction);case"call":return await provider.call(Object.assign({},req.transaction,{blockTag:req.blockTag}));case"networkId":return(await provider.getNetwork()).networkId;case"estimateEnergy":return await provider.estimateEnergy(req.transaction);case"getBalance":return await provider.getBalance(req.address,req.blockTag);case"getBlock":{const block="blockHash"in req?req.blockHash:req.blockTag;return await provider.getBlock(block,req.includeTransactions)}case"getBlockNumber":return await provider.getBlockNumber();case"getCode":return await provider.getCode(req.address,req.blockTag);case"getEnergyPrice":return(await provider.getFeeData()).energyPrice;case"getLogs":return await provider.getLogs(req.filter);case"getStorage":return await provider.getStorage(req.address,req.position,req.blockTag);case"getTransaction":return await provider.getTransaction(req.hash);case"getTransactionCount":return await provider.getTransactionCount(req.address,req.blockTag);case"getTransactionReceipt":return await provider.getTransactionReceipt(req.hash);case"getTransactionResult":return await provider.getTransactionResult(req.hash)}}#getNextConfig(running){const configs=Array.from(running).map(r=>r.config);const allConfigs=this.#configs.slice();shuffle(allConfigs);allConfigs.sort((a,b)=>b.priority-a.priority);for(const config of allConfigs){if(configs.indexOf(config)===-1){return config}}return null}#addRunner(running,req){const config=this.#getNextConfig(running);if(config==null){return null}const runner={config:config,result:null,didBump:false,perform:null,staller:null};const now=getTime();runner.perform=(async()=>{try{config.requests++;const result=await this._translatePerform(config.provider,req);runner.result={result:result}}catch(error){config.errorResponses++;runner.result={error:error}}const dt=getTime()-now;config._totalTime+=dt;config.rollingDuration=.95*config.rollingDuration+.05*dt;runner.perform=null})();runner.staller=(async()=>{await stall$2(config.stallTimeout);runner.staller=null})();running.add(runner);return runner}async#initialSync(){let initialSync=this.#initialSyncPromise;if(!initialSync){const promises=[];this.#configs.forEach(config=>{promises.push(waitForSync(config,0));promises.push((async()=>{config._network=await config.provider.getNetwork()})())});this.#initialSyncPromise=initialSync=(async()=>{await Promise.all(promises);let networkId=null;for(const config of this.#configs){const network=config._network;if(networkId==null){networkId=network.networkId}else if(network.networkId!==networkId){assert(false,"cannot mix providers on different networks","UNSUPPORTED_OPERATION",{operation:"new FallbackProvider"})}}})()}await initialSync}async#checkQuorum(running,req){const results=[];for(const runner of running){if(runner.result!=null){const{tag,value}=normalizeResult(runner.result);results.push({tag:tag,value:value,weight:runner.config.weight})}}if(results.reduce((a,r)=>a+r.weight,0)({value:c.blockNumber,tag:getNumber(c.blockNumber).toString(),weight:c.weight})))))}const mode=getFuzzyMode(this.quorum,results);if(mode===undefined){return undefined}if(mode>this.#height){this.#height=mode}return this.#height}case"getEnergyPrice":case"estimateEnergy":return getMedian(this.quorum,results);case"getBlock":if("blockTag"in req&&req.blockTag==="pending"){return getAnyResult(this.quorum,results)}return checkQuorum(this.quorum,results);case"call":case"networkId":case"getBalance":case"getTransactionCount":case"getCode":case"getStorage":case"getTransaction":case"getTransactionReceipt":case"getLogs":return checkQuorum(this.quorum,results);case"broadcastTransaction":return getAnyResult(this.quorum,results)}assert(false,"unsupported method","UNSUPPORTED_OPERATION",{operation:`_perform(${stringify(req.method)})`})}async#waitForQuorum(running,req){if(running.size===0){throw new Error("no runners?!")}const interesting=[];let newRunners=0;for(const runner of running){if(runner.perform){interesting.push(runner.perform)}if(runner.staller){interesting.push(runner.staller);continue}if(runner.didBump){continue}runner.didBump=true;newRunners++}const value=await this.#checkQuorum(running,req);if(value!==undefined){if(value instanceof Error){throw value}return value}for(let i=0;i0,"quorum not met","SERVER_ERROR",{request:"%sub-requests",info:{request:req,results:Array.from(running).map(r=>stringify(r.result))}});await Promise.race(interesting);return await this.#waitForQuorum(running,req)}async _perform(req){if(req.method==="broadcastTransaction"){const results=await Promise.all(this.#configs.map(async({provider,weight})=>{try{const result=await provider._perform(req);return Object.assign(normalizeResult({result:result}),{weight:weight})}catch(error){return Object.assign(normalizeResult({error:error}),{weight:weight})}}));const result=getAnyResult(this.quorum,results);assert(result!==undefined,"problem multi-broadcasting","SERVER_ERROR",{request:"%sub-requests",info:{request:req,results:results.map(stringify)}});if(result instanceof Error){throw result}return result}await this.#initialSync();const running=new Set;for(let i=0;i{const payload={method:method,params:params};this.emit("debug",{action:"sendEip1193Request",payload:payload});try{const result=await core.request(payload);this.emit("debug",{action:"receiveEip1193Result",result:result});return result}catch(e){const error=new Error(e.message);error.code=e.code;error.data=e.data;error.payload=payload;this.emit("debug",{action:"receiveEip1193Error",error:error});throw error}}}async send(method,params){await this._start();return await super.send(method,params)}async _send(payload){assertArgument(!Array.isArray(payload),"EIP-1193 does not support batch request","payload",payload);try{const result=await this.#request(payload.method,payload.params||[]);return[{id:payload.id,result:result}]}catch(e){return[{id:payload.id,error:{code:e.code,data:e.data,message:e.message}}]}}getRpcError(payload,error){error=JSON.parse(JSON.stringify(error));switch(error.error.code||-1){case 4001:error.error.message=`corebc-user-denied: ${error.error.message}`;break;case 4200:error.error.message=`corebc-unsupported: ${error.error.message}`;break}return super.getRpcError(payload,error)}async hasSigner(address){if(address==null){address=0}const accounts=await this.send("xcb_accounts",[]);if(typeof address==="number"){return accounts.length>address}address=address.toLowerCase();return accounts.filter(a=>a.toLowerCase()===address).length!==0}async getSigner(address){if(address==null){address=0}if(!await this.hasSigner(address)){try{await this.#request("xcb_requestAccounts",[])}catch(error){const payload=error.payload;throw this.getRpcError(payload,{id:payload.id,error:error})}}return await super.getSigner(address)}}const defaultApplicationId="62e1ad51b37b8e00394bda3b";function getHost(name){switch(name){case"mainnet":return"eth-mainnet.gateway.pokt.network";case"goerli":return"eth-goerli.gateway.pokt.network";case"matic":return"poly-mainnet.gateway.pokt.network";case"matic-mumbai":return"polygon-mumbai-rpc.gateway.pokt.network"}assertArgument(false,"unsupported network","network",name)}class PocketProvider extends JsonRpcProvider{applicationId;applicationSecret;constructor(_network,applicationId,applicationSecret){if(_network==null){_network="mainnet"}const network=Network.from(_network);if(applicationId==null){applicationId=defaultApplicationId}if(applicationSecret==null){applicationSecret=null}const options={staticNetwork:network};const request=PocketProvider.getRequest(network,applicationId,applicationSecret);super(request,network,options);defineProperties(this,{applicationId:applicationId,applicationSecret:applicationSecret})}_getProvider(networkId){try{return new PocketProvider(networkId,this.applicationId,this.applicationSecret)}catch(error){}return super._getProvider(networkId)}static getRequest(network,applicationId,applicationSecret){if(applicationId==null){applicationId=defaultApplicationId}const request=new FetchRequest(`https:/\/${getHost(network.name)}/v1/lb/${applicationId}`);request.allowGzip=true;if(applicationSecret){request.setCredentials("",applicationSecret)}if(applicationId===defaultApplicationId){request.retryFunc=async(request,response,attempt)=>{showThrottleMessage("PocketProvider");return true}}return request}isCommunityResource(){return this.applicationId===defaultApplicationId}}const IpcSocketProvider=undefined;class BaseWallet extends AbstractSigner{address;prefix;#signingKey;constructor({signingKey,prefix,provider}){super(provider);this.prefix=prefix;assertArgument(signingKey&&typeof signingKey.sign==="function","invalid signingKey key","signingKey","[ REDACTED ]");this.#signingKey=signingKey;const address=computeAddress(this.#signingKey,prefix);defineProperties(this,{address:address})}get signingKey(){return this.#signingKey}get privateKey(){return this.signingKey.privateKey}async getAddress(){return this.address}connect(provider){return new BaseWallet({signingKey:this.#signingKey,prefix:this.prefix,provider:provider})}async signTransaction(tx){const{to,from}=await resolveProperties({to:tx.to||undefined,from:tx.from||undefined});if(to!=null){tx.to=to}if(from!=null){tx.from=from}if(tx.from!=null){assertArgument(getAddress(tx.from)===this.address,"transaction from address mismatch","tx.from",tx.from);delete tx.from}const btx=Transaction.from(tx);const unSignedSerialized=btx.unsignedSerialized;const unsignedHash=sha256(unSignedSerialized);btx.signature=this.signingKey.sign(unsignedHash);return btx.serialized}async signMessage(message){return this.signMessageSync(message)}signMessageSync(message){return this.signingKey.sign(hashMessage(message))}async signTypedData(domain,types,value){const populated=await TypedDataEncoder.resolveNames(domain,types,value,async name=>{assert(this.provider!=null,"cannot resolve ENS names without a provider","UNSUPPORTED_OPERATION",{operation:"resolveName",info:{name:name}});const address=getAddress(name);assert(address!=null,"unconfigured ENS name","UNCONFIGURED_NAME",{value:name});return address});return this.signingKey.sign(TypedDataEncoder.hash(populated.domain,types,populated.value))}}const subsChrs=" !#$%&'()*+,-./<=>?@[]^_`{|}~";const Word=/^[a-z]*$/i;function unfold(words,sep){let initial=97;return words.reduce((accum,word)=>{if(word===sep){initial++}else if(word.match(Word)){accum.push(String.fromCharCode(initial)+word)}else{initial=97;accum.push(word)}return accum},[])}function decode(data,subs){for(let i=subsChrs.length-1;i>=0;i--){data=data.split(subsChrs[i]).join(subs.substring(2*i,2*i+2))}const clumps=[];const leftover=data.replace(/(:|([0-9])|([A-Z][a-z]*))/g,(all,item,semi,word)=>{if(semi){for(let i=parseInt(semi);i>=0;i--){clumps.push(";")}}else{clumps.push(item.toLowerCase())}return""});if(leftover){throw new Error(`leftovers: ${JSON.stringify(leftover)}`)}return unfold(unfold(clumps,";"),":")}function decodeOwl(data){assertArgument(data[0]==="0","unsupported auwl data","data",data);return decode(data.substring(1+2*subsChrs.length),data.substring(1,1+2*subsChrs.length))}class Wordlist{locale;constructor(locale){defineProperties(this,{locale:locale})}split(phrase){return phrase.toLowerCase().split(/\s+/g)}join(words){return words.join(" ")}static check(wordlist){const words=[];for(let i=0;i<2048;i++){const word=wordlist.getWord(i);if(i!==wordlist.getWordIndex(word)){return"0x"}words.push(word)}return id(words.join("\n")+"\n")}}class WordlistOwl extends Wordlist{#data;#checksum;constructor(locale,data,checksum){super(locale);this.#data=data;this.#checksum=checksum;this.#words=null}get _data(){return this.#data}_decodeWords(){return decodeOwl(this.#data)}#words;#loadWords(){if(this.#words==null){const words=this._decodeWords();const checksum=id(words.join("\n")+"\n",true);if(checksum!==this.#checksum){throw new Error(`BIP39 Wordlist for ${this.locale} FffffAILED`)}this.#words=words}return this.#words}getWord(index){const words=this.#loadWords();assertArgument(index>=0&&index{const goldilockSaltPrefix="mnemonic";const aesSaltPrefix="mnemonicfortheAESkey";const goldilockSalt=utf8.encode(goldilockSaltPrefix+password);const aesSalt=utf8.encode(aesSaltPrefix+password);const goldilockKey=pbkdf2Sync(Buffer.from(mnemonic),goldilockSalt,2048,64,"sha512");const aesKeySeed=pbkdf2Sync(Buffer.from(mnemonic),aesSalt,2048,64,"sha512");return{aes:aesKeySeed.toString("hex"),goldilock:goldilockKey.toString("hex")}};function getUpperMask(bits){return(1<=12&&words.length<=24,"invalid mnemonic length","mnemonic","[ REDACTED ]");const entropy=new Uint8Array(Math.ceil(11*words.length/8));let offset=0;for(let i=0;i=0,`invalid mnemonic word at index ${i}`,"mnemonic","[ REDACTED ]");for(let bit=0;bit<11;bit++){if(index&1<<10-bit){entropy[offset>>3]|=1<<7-offset%8}offset++}}const entropyBits=32*words.length/3;const checksumBits=words.length/3;const checksumMask=getUpperMask(checksumBits);const checksum=getBytes(legacySha256(entropy.slice(0,entropyBits/8)))[0]&checksumMask;assertArgument(checksum===(entropy[entropy.length-1]&checksumMask),"invalid mnemonic checksum","mnemonic","[ REDACTED ]");return hexlify(entropy.slice(0,entropyBits/8))}function entropyToMnemonic(entropy,wordlist){assertArgument(entropy.length%4===0&&entropy.length>=16&&entropy.length<=32,"invalid entropy size","entropy","[ REDACTED ]");if(wordlist==null){wordlist=LangEn.wordlist()}const indices=[0];let remainingBits=11;for(let i=0;i8){indices[indices.length-1]<<=8;indices[indices.length-1]|=entropy[i];remainingBits-=8}else{indices[indices.length-1]<<=remainingBits;indices[indices.length-1]|=entropy[i]>>8-remainingBits;indices.push(entropy[i]&getLowerMask(8-remainingBits));remainingBits+=3}}const checksumBits=entropy.length/4;const checksum=parseInt(legacySha256(entropy).substring(2,4),16)&getUpperMask(checksumBits);indices[indices.length-1]<<=checksumBits;indices[indices.length-1]|=checksum>>8-checksumBits;return wordlist.join(indices.map(index=>wordlist.getWord(index)))}const _guard$1={};class Mnemonic{phrase;password;wordlist;entropy;constructor(guard,entropy,phrase,password,wordlist){if(password==null){password=""}if(wordlist==null){wordlist=LangEn.wordlist()}assertPrivate(guard,_guard$1,"Mnemonic");defineProperties(this,{phrase:phrase,password:password,wordlist:wordlist,entropy:entropy})}computeSeed(){return mnemonicToSeed(this.phrase,this.password)}static fromPhrase({phrase,password,wordlist}){const entropy=mnemonicToEntropy(phrase,wordlist);phrase=entropyToMnemonic(getBytes(entropy),wordlist);return new Mnemonic(_guard$1,entropy,phrase,password,wordlist)}static fromEntropy(_entropy,password,wordlist){const entropy=getBytes(_entropy,"entropy");const phrase=entropyToMnemonic(entropy,wordlist);return new Mnemonic(_guard$1,hexlify(entropy),phrase,password,wordlist)}static entropyToPhrase(_entropy,wordlist){const entropy=getBytes(_entropy,"entropy");return entropyToMnemonic(entropy,wordlist)}static phraseToEntropy(phrase,wordlist){return mnemonicToEntropy(phrase,wordlist)}static isValidMnemonic(phrase,wordlist){try{mnemonicToEntropy(phrase,wordlist);return true}catch(error){}return false}}function looseArrayify(hexString){if(typeof hexString==="string"&&!hexString.startsWith("0x")){hexString="0x"+hexString}return getBytesCopy(hexString)}function zpad(value,length){value=String(value);while(value.length0&&(N&N-1)===0,"invalid kdf.N","kdf.N",N);assertArgument(r>0&&p>0,"invalid kdf","kdf",kdf);const dkLen=spelunk(data,"crypto.kdfparams.dklen:int!");assertArgument(dkLen===32,"invalid kdf.dklen","kdf.dflen",dkLen);return{name:"scrypt",salt:salt,N:N,r:r,p:p,dkLen:64}}else if(kdf.toLowerCase()==="pbkdf2"){const salt=spelunk(data,"crypto.kdfparams.salt:data!");const prf=spelunk(data,"crypto.kdfparams.prf:string!");const algorithm=prf.split("-").pop();assertArgument(algorithm==="sha256"||algorithm==="sha512","invalid kdf.pdf","kdf.pdf",prf);const count=spelunk(data,"crypto.kdfparams.c:int!");const dkLen=spelunk(data,"crypto.kdfparams.dklen:int!");assertArgument(dkLen===32,"invalid kdf.dklen","kdf.dklen",dkLen);return{name:"pbkdf2",salt:salt,count:count,dkLen:dkLen,algorithm:algorithm}}}assertArgument(false,"unsupported key-derivation function","kdf",kdf)}function decryptKeystoreJsonSync(json,_password){const data=JSON.parse(json);const password=getPassword(_password);const params=getDecryptKdfParams(data);if(params.name==="pbkdf2"){const{salt,count,dkLen,algorithm}=params;const key=pbkdf2(password,salt,count,dkLen,algorithm);return getAccount(data,key)}assert(params.name==="scrypt","cannot be reached","UNKNOWN_ERROR",{params:params});const{salt,N,r,p,dkLen}=params;const key=scryptSync(password,salt,N,r,p,dkLen);return getAccount(data,key)}function stall$1(duration){return new Promise(resolve=>{setTimeout(()=>{resolve()},duration)})}async function decryptKeystoreJson(json,_password,progress){const data=JSON.parse(json);const password=getPassword(_password);const params=getDecryptKdfParams(data);if(params.name==="pbkdf2"){if(progress){progress(0);await stall$1(0)}const{salt,count,dkLen,algorithm}=params;const key=pbkdf2(password,salt,count,dkLen,algorithm);if(progress){progress(1);await stall$1(0)}return getAccount(data,key)}assert(params.name==="scrypt","cannot be reached","UNKNOWN_ERROR",{params:params});const{salt,N,r,p,dkLen}=params;const key=await scrypt(password,salt,N,r,p,dkLen,progress);return getAccount(data,key)}function getEncryptKdfParams(options){const salt=options.salt!=null?getBytes(options.salt,"options.salt"):randomBytes(32);let N=1<<17,r=8,p=1;if(options.scrypt){if(options.scrypt.N){N=options.scrypt.N}if(options.scrypt.r){r=options.scrypt.r}if(options.scrypt.p){p=options.scrypt.p}}assertArgument(typeof N==="number"&&N>0&&Number.isSafeInteger(N)&&(BigInt(N)&BigInt(N-1))===BigInt(0),"invalid scrypt N parameter","options.N",N);assertArgument(typeof r==="number"&&r>0&&Number.isSafeInteger(r),"invalid scrypt r parameter","options.r",r);assertArgument(typeof p==="number"&&p>0&&Number.isSafeInteger(p),"invalid scrypt p parameter","options.p",p);return{name:"scrypt",dkLen:32,salt:salt,N:N,r:r,p:p}}function _encryptKeystore(key,kdf,account,options){const privateKey=getBytes(account.privateKey,"privateKey");const iv=options.iv!=null?getBytes(options.iv,"options.iv"):randomBytes(16);assertArgument(iv.length===16,"invalid options.iv length","options.iv",options.iv);const uuidRandom=options.uuid!=null?getBytes(options.uuid,"options.uuid"):randomBytes(16);assertArgument(uuidRandom.length===16,"invalid options.uuid length","options.uuid",options.iv);const derivedKey=key.slice(0,16);const macPrefix=key.slice(16,32);const aesCtr=new CTR(derivedKey,iv);const ciphertext=getBytes(aesCtr.encrypt(privateKey));const mac=sha256(concat([macPrefix,ciphertext]));const data={address:account.address.substring(2).toLowerCase(),id:uuidV4(uuidRandom),version:3,Crypto:{cipher:"aes-128-ctr",cipherparams:{iv:hexlify(iv).substring(2)},ciphertext:hexlify(ciphertext).substring(2),kdf:"scrypt",kdfparams:{salt:hexlify(kdf.salt).substring(2),n:kdf.N,dklen:32,p:kdf.p,r:kdf.r},mac:mac.substring(2)}};if(account.mnemonic){const client=options.client!=null?options.client:`corebc/${version}`;const path=account.mnemonic.path||defaultPath$1;const locale=account.mnemonic.locale||"en";const mnemonicKey=key.slice(32,64);const entropy=getBytes(account.mnemonic.entropy,"account.mnemonic.entropy");const mnemonicIv=randomBytes(16);const mnemonicAesCtr=new CTR(mnemonicKey,mnemonicIv);const mnemonicCiphertext=getBytes(mnemonicAesCtr.encrypt(entropy));const now=new Date;const timestamp=now.getUTCFullYear()+"-"+zpad(now.getUTCMonth()+1,2)+"-"+zpad(now.getUTCDate(),2)+"T"+zpad(now.getUTCHours(),2)+"-"+zpad(now.getUTCMinutes(),2)+"-"+zpad(now.getUTCSeconds(),2)+".0Z";const gethFilename="UTC--"+timestamp+"--"+data.address;data["x-corebc"]={client:client,gethFilename:gethFilename,path:path,locale:locale,mnemonicCounter:hexlify(mnemonicIv).substring(2),mnemonicCiphertext:hexlify(mnemonicCiphertext).substring(2),version:"0.1"}}return JSON.stringify(data)}function encryptKeystoreJsonSync(account,password,options){if(options==null){options={}}const passwordBytes=getPassword(password);const kdf=getEncryptKdfParams(options);const key=scryptSync(passwordBytes,kdf.salt,kdf.N,kdf.r,kdf.p,64);return _encryptKeystore(getBytes(key),kdf,account,options)}async function encryptKeystoreJson(account,password,options){if(options==null){options={}}const passwordBytes=getPassword(password);const kdf=getEncryptKdfParams(options);const key=await scrypt(passwordBytes,kdf.salt,kdf.N,kdf.r,kdf.p,64,options.progressCallback);return _encryptKeystore(getBytes(key),kdf,account,options)}const defaultPath="m";const HardenedBit=2147483648;const _guard={};function derivePath(node,path){const components=path.split("/");assertArgument(components.length>0&&(components[0]==="m"||node.depth>0),"invalid path","path",path);if(components[0]==="m"){components.shift()}let result=node;for(let i=0;i=0&&index=0&&index{setTimeout(()=>{resolve()},duration)})}class Wallet extends BaseWallet{constructor({key,prefix,provider}){if(typeof key==="string"&&!key.startsWith("0x")){key="0x"+key}let signingKey=typeof key==="string"?new SigningKey(key):key;super({signingKey:signingKey,prefix:prefix,provider:provider})}connect(provider){return new Wallet({key:this.signingKey,prefix:this.prefix,provider:provider})}async encrypt(password,progressCallback){const account={address:this.address,privateKey:this.privateKey};return await encryptKeystoreJson(account,password,{progressCallback:progressCallback})}encryptSync(password){const account={address:this.address,privateKey:this.privateKey};return encryptKeystoreJsonSync(account,password)}static#fromAccount(account){assertArgument(account,"invalid JSON wallet","json","[ REDACTED ]");const address=account.address;const prefix=extractPrefix(address);if("mnemonic"in account&&account.mnemonic&&account.mnemonic.locale==="en"){const mnemonic=Mnemonic.fromEntropy(account.mnemonic.entropy);const wallet=HDNodeWallet.fromMnemonic(mnemonic,prefix,account.mnemonic.path);if(wallet.address===account.address&&wallet.privateKey===account.privateKey){return wallet}console.log("WARNING: JSON mismatch address/privateKey != mnemonic; fallback onto private key")}const wallet=new Wallet({key:account.privateKey,prefix:prefix});assertArgument(wallet.address===account.address,"address/privateKey mismatch","json","[ REDACTED ]");return wallet}static async fromEncryptedJson(json,password,progress){let account=null;if(isKeystoreJson(json)){account=await decryptKeystoreJson(json,password,progress)}else if(isCrowdsaleJson(json)){if(progress){progress(0);await stall(0)}account=decryptCrowdsaleJson(json,password);if(progress){progress(1);await stall(0)}}return Wallet.#fromAccount(account)}static fromEncryptedJsonSync(json,password){let account=null;if(isKeystoreJson(json)){account=decryptKeystoreJsonSync(json,password)}else if(isCrowdsaleJson(json)){account=decryptCrowdsaleJson(json,password)}else{assertArgument(false,"invalid JSON wallet","json","[ REDACTED ]")}return Wallet.#fromAccount(account)}static createRandom(prefix,provider){const wallet=HDNodeWallet.createRandom(prefix,undefined,undefined,undefined);if(provider){return wallet.connect(provider)}return wallet}static fromPhrase({phrase,prefix,provider,password}){const wallet=HDNodeWallet.fromPhrase({phrase:phrase,prefix:prefix,password:password});if(provider){return wallet.connect(provider)}return wallet}static fromSeed({seed,prefix,provider,path}){const wallet=HDNodeWallet.fromSeed({seed:seed,prefix:prefix,path:path||defaultPath});if(provider){return wallet.connect(provider)}return wallet}}const Base64=")!@#$%^&*(ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_";function decodeBits(width,data){const maxValue=(1<=width){const value=accum>>bits-width;accum&=(1<{const match=accent.match(/^([a-z]*)([0-9]+)([0-9])(.*)$/);assertArgument(match!==null,"internal error parsing accents","accents",accents);let posOffset=0;const positions=decodeBits(parseInt(match[3]),match[4]);const charCode=parseInt(match[2]);const regex=new RegExp(`([${match[1]}])`,"g");words=words.replace(regex,(all,letter)=>{const rem=--positions[posOffset];if(rem===0){letter=String.fromCharCode(letter.charCodeAt(0),charCode);posOffset++}return letter})});return words.split(",")}class WordlistOwlA extends WordlistOwl{#accent;constructor(locale,data,accent,checksum){super(locale,data,checksum);this.#accent=accent}get _accent(){return this.#accent}_decodeWords(){return decodeOwlA(this._data,this._accent)}}const wordlists={en:LangEn.wordlist()};var corebc=Object.freeze({__proto__:null,AbiCoder:AbiCoder,AbstractProvider:AbstractProvider,AbstractSigner:AbstractSigner,AlchemyProvider:AlchemyProvider,AnkrProvider:AnkrProvider,BaseContract:BaseContract,BaseWallet:BaseWallet,BigNumber:BigNumber,Block:Block,BrowserProvider:BrowserProvider,CloudflareProvider:CloudflareProvider,ConstructorFragment:ConstructorFragment,Contract:Contract,ContractEventPayload:ContractEventPayload,ContractFactory:ContractFactory,ContractTransactionReceipt:ContractTransactionReceipt,ContractTransactionResponse:ContractTransactionResponse,ContractUnknownEventPayload:ContractUnknownEventPayload,CoreSymbol:CoreSymbol,Ed448Goldilock:Ed448Goldilock,EnergyCostPlugin:EnergyCostPlugin,ErrorDescription:ErrorDescription,ErrorFragment:ErrorFragment,EventFragment:EventFragment,EventLog:EventLog,EventPayload:EventPayload,FallbackFragment:FallbackFragment,FallbackProvider:FallbackProvider,FeeData:FeeData,FeeDataNetworkPlugin:FeeDataNetworkPlugin,FetchCancelSignal:FetchCancelSignal,FetchRequest:FetchRequest,FetchResponse:FetchResponse,FixedNumber:FixedNumber,Fragment:Fragment,FunctionFragment:FunctionFragment,HDNodeWallet:HDNodeWallet,Indexed:Indexed,InfuraProvider:InfuraProvider,InfuraWebSocketProvider:InfuraWebSocketProvider,Interface:Interface,IpcSocketProvider:IpcSocketProvider,JsonRpcApiProvider:JsonRpcApiProvider,JsonRpcProvider:JsonRpcProvider,JsonRpcSigner:JsonRpcSigner,LangEn:LangEn,Log:Log,LogDescription:LogDescription,MaxInt256:MaxInt256,MaxUint256:MaxUint256,MessagePrefix:MessagePrefix,MinInt256:MinInt256,Mnemonic:Mnemonic,N:N,NamedFragment:NamedFragment,Network:Network,NetworkPlugin:NetworkPlugin,NonceManager:NonceManager,OrePerXCB:OrePerXCB,ParamType:ParamType,PocketProvider:PocketProvider,QuickNodeProvider:QuickNodeProvider,Result:Result,Signature:Signature,SigningKey:SigningKey,SocketBlockSubscriber:SocketBlockSubscriber,SocketEventSubscriber:SocketEventSubscriber,SocketPendingSubscriber:SocketPendingSubscriber,SocketProvider:SocketProvider,SocketSubscriber:SocketSubscriber,StructFragment:StructFragment,Transaction:Transaction,TransactionDescription:TransactionDescription,TransactionReceipt:TransactionReceipt,TransactionResponse:TransactionResponse,Typed:Typed,TypedDataEncoder:TypedDataEncoder,UnmanagedSubscriber:UnmanagedSubscriber,Utf8ErrorFuncs:Utf8ErrorFuncs,VoidSigner:VoidSigner,Wallet:Wallet,WebSocketProvider:WebSocketProvider,Wordlist:Wordlist,WordlistOwl:WordlistOwl,WordlistOwlA:WordlistOwlA,ZeroAddress:ZeroAddress,ZeroHash:ZeroHash,accessListify:accessListify,arrayify:arrayify,assert:assert,assertArgument:assertArgument,assertArgumentCount:assertArgumentCount,assertNormalize:assertNormalize,assertPrivate:assertPrivate,checkResultErrors:checkResultErrors,computeAddress:computeAddress,computeHmac:computeHmac,concat:concat,copyRequest:copyRequest,dataLength:dataLength,dataSlice:dataSlice,decodeBase58:decodeBase58,decodeBase64:decodeBase64,decodeBytes32String:decodeBytes32String,decodeRlp:decodeRlp,decryptCrowdsaleJson:decryptCrowdsaleJson,decryptKeystoreJson:decryptKeystoreJson,decryptKeystoreJsonSync:decryptKeystoreJsonSync,defaultPath:defaultPath,defineProperties:defineProperties,encodeBase58:encodeBase58,encodeBase64:encodeBase64,encodeBytes32String:encodeBytes32String,encodeRlp:encodeRlp,encryptKeystoreJson:encryptKeystoreJson,encryptKeystoreJsonSync:encryptKeystoreJsonSync,formatUnits:formatUnits,formatXCB:formatXCB,fromTwos:fromTwos,getAccountPath:getAccountPath,getAddress:getAddress,getBigInt:getBigInt,getBytes:getBytes,getBytesCopy:getBytesCopy,getCreate2Address:getCreate2Address,getCreateAddress:getCreateAddress,getDefaultProvider:getDefaultProvider,getIndexedAccountPath:getIndexedAccountPath,getNumber:getNumber,getUint:getUint,hashMessage:hashMessage,hexConcat:hexConcat,hexlify:hexlify,id:id,isAddress:isAddress,isAddressable:isAddressable,isBytesLike:isBytesLike,isCallException:isCallException,isCrowdsaleJson:isCrowdsaleJson,isError:isError,isHexString:isHexString,isKeystoreJson:isKeystoreJson,keccak256:keccak256,lock:lock,makeError:makeError,mask:mask,networkIdToPrefix:networkIdToPrefix,parseUnits:parseUnits,parseXCB:parseXCB,pbkdf2:pbkdf2,publicToAddress:publicToAddress,randomBytes:randomBytes,recoverAddress:recoverAddress,resolveAddress:resolveAddress,resolveProperties:resolveProperties,ripemd160:ripemd160,scrypt:scrypt,scryptSync:scryptSync,sha256:sha256,sha512:sha512,showThrottleMessage:showThrottleMessage,solidityPacked:solidityPacked,solidityPackedSha256:solidityPackedSha256,stripZerosLeft:stripZerosLeft,toBeArray:toBeArray,toBeHex:toBeHex,toBigInt:toBigInt,toNumber:toNumber,toQuantity:toQuantity,toTwos:toTwos,toUtf8Bytes:toUtf8Bytes,toUtf8CodePoints:toUtf8CodePoints,toUtf8String:toUtf8String,uuidV4:uuidV4,verifyMessage:verifyMessage,verifyTypedData:verifyTypedData,version:version,wordlists:wordlists,zeroPadBytes:zeroPadBytes,zeroPadValue:zeroPadValue});export{AbiCoder,AbstractProvider,AbstractSigner,AlchemyProvider,AnkrProvider,BaseContract,BaseWallet,BigNumber,Block,BrowserProvider,CloudflareProvider,ConstructorFragment,Contract,ContractEventPayload,ContractFactory,ContractTransactionReceipt,ContractTransactionResponse,ContractUnknownEventPayload,CoreSymbol,Ed448Goldilock,EnergyCostPlugin,ErrorDescription,ErrorFragment,EventFragment,EventLog,EventPayload,FallbackFragment,FallbackProvider,FeeData,FeeDataNetworkPlugin,FetchCancelSignal,FetchRequest,FetchResponse,FixedNumber,Fragment,FunctionFragment,HDNodeWallet,Indexed,InfuraProvider,InfuraWebSocketProvider,Interface,IpcSocketProvider,JsonRpcApiProvider,JsonRpcProvider,JsonRpcSigner,LangEn,Log,LogDescription,MaxInt256,MaxUint256,MessagePrefix,MinInt256,Mnemonic,N,NamedFragment,Network,NetworkPlugin,NonceManager,OrePerXCB,ParamType,PocketProvider,QuickNodeProvider,Result,Signature,SigningKey,SocketBlockSubscriber,SocketEventSubscriber,SocketPendingSubscriber,SocketProvider,SocketSubscriber,StructFragment,Transaction,TransactionDescription,TransactionReceipt,TransactionResponse,Typed,TypedDataEncoder,UnmanagedSubscriber,Utf8ErrorFuncs,VoidSigner,Wallet,WebSocketProvider,Wordlist,WordlistOwl,WordlistOwlA,ZeroAddress,ZeroHash,accessListify,arrayify,assert,assertArgument,assertArgumentCount,assertNormalize,assertPrivate,checkResultErrors,computeAddress,computeHmac,concat,copyRequest,corebc,dataLength,dataSlice,decodeBase58,decodeBase64,decodeBytes32String,decodeRlp,decryptCrowdsaleJson,decryptKeystoreJson,decryptKeystoreJsonSync,defaultPath,defineProperties,encodeBase58,encodeBase64,encodeBytes32String,encodeRlp,encryptKeystoreJson,encryptKeystoreJsonSync,formatUnits,formatXCB,fromTwos,getAccountPath,getAddress,getBigInt,getBytes,getBytesCopy,getCreate2Address,getCreateAddress,getDefaultProvider,getIndexedAccountPath,getNumber,getUint,hashMessage,hexConcat,hexlify,id,isAddress,isAddressable,isBytesLike,isCallException,isCrowdsaleJson,isError,isHexString,isKeystoreJson,keccak256,lock,makeError,mask,networkIdToPrefix,parseUnits,parseXCB,pbkdf2,publicToAddress,randomBytes,recoverAddress,resolveAddress,resolveProperties,ripemd160,scrypt,scryptSync,sha256,sha512,showThrottleMessage,solidityPacked,solidityPackedSha256,stripZerosLeft,toBeArray,toBeHex,toBigInt,toNumber,toQuantity,toTwos,toUtf8Bytes,toUtf8CodePoints,toUtf8String,uuidV4,verifyMessage,verifyTypedData,version,wordlists,zeroPadBytes,zeroPadValue};
\ No newline at end of file
diff --git a/dist/corebc.umd.js b/dist/corebc.umd.js
deleted file mode 100644
index b17f76aad..000000000
--- a/dist/corebc.umd.js
+++ /dev/null
@@ -1,19982 +0,0 @@
-const __$G = (typeof globalThis !== 'undefined' ? globalThis: typeof window !== 'undefined' ? window: typeof global !== 'undefined' ? global: typeof self !== 'undefined' ? self: {});
-(function (global, factory) {
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('buffer'), require('bcrypto/lib/ed448-browser.js'), require('bn.js'), require('bcrypto/lib/pbkdf2-browser.js'), require('bcrypto/lib/sha3-512.js'), require('utf8'), require('aes-js')) :
- typeof define === 'function' && define.amd ? define(['exports', 'buffer', 'bcrypto/lib/ed448-browser.js', 'bn.js', 'bcrypto/lib/pbkdf2-browser.js', 'bcrypto/lib/sha3-512.js', 'utf8', 'aes-js'], factory) :
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.corebc = {}, global.buffer, global.ed448, global._BN, global.pbkdf2$2, global.SHA3_512, global.utf8, global.pkg));
-})(this, (function (exports, buffer, ed448, _BN, pbkdf2$2, SHA3_512, utf8, pkg) { 'use strict';
-
- /* Do NOT modify this file; see /src.ts/_admin/update-version.ts */
- /**
- * The current version of corebc.
- */
- const version = "6.4.0";
-
- let _permanentCensorErrors = false;
- let _censorErrors = false;
- const LogLevels = {
- debug: 1,
- default: 2,
- info: 2,
- warning: 3,
- error: 4,
- off: 5,
- };
- let _logLevel = LogLevels["default"];
- let _globalLogger = null;
- function _checkNormalize() {
- try {
- const missing = [];
- // Make sure all forms of normalization are supported
- ["NFD", "NFC", "NFKD", "NFKC"].forEach((form) => {
- try {
- if ("test".normalize(form) !== "test") {
- throw new Error("bad normalize");
- }
- }
- catch (error) {
- missing.push(form);
- }
- });
- if (missing.length) {
- throw new Error("missing " + missing.join(", "));
- }
- if (String.fromCharCode(0xe9).normalize("NFD") !==
- String.fromCharCode(0x65, 0x0301)) {
- throw new Error("broken implementation");
- }
- }
- catch (error) {
- return error.message;
- }
- return null;
- }
- const _normalizeError = _checkNormalize();
- var LogLevel;
- (function (LogLevel) {
- LogLevel["DEBUG"] = "DEBUG";
- LogLevel["INFO"] = "INFO";
- LogLevel["WARNING"] = "WARNING";
- LogLevel["ERROR"] = "ERROR";
- LogLevel["OFF"] = "OFF";
- })(LogLevel || (LogLevel = {}));
- var ErrorCode;
- (function (ErrorCode) {
- ///////////////////
- // Generic Errors
- // Unknown Error
- ErrorCode["UNKNOWN_ERROR"] = "UNKNOWN_ERROR";
- // Not Implemented
- ErrorCode["NOT_IMPLEMENTED"] = "NOT_IMPLEMENTED";
- // Unsupported Operation
- // - operation
- ErrorCode["UNSUPPORTED_OPERATION"] = "UNSUPPORTED_OPERATION";
- // Network Error (i.e. Core Network, such as an invalid network ID)
- // - event ("noNetwork" is not re-thrown in provider.ready; otherwise thrown)
- ErrorCode["NETWORK_ERROR"] = "NETWORK_ERROR";
- // Some sort of bad response from the server
- ErrorCode["SERVER_ERROR"] = "SERVER_ERROR";
- // Timeout
- ErrorCode["TIMEOUT"] = "TIMEOUT";
- ///////////////////
- // Operational Errors
- // Buffer Overrun
- ErrorCode["BUFFER_OVERRUN"] = "BUFFER_OVERRUN";
- // Numeric Fault
- // - operation: the operation being executed
- // - fault: the reason this faulted
- ErrorCode["NUMERIC_FAULT"] = "NUMERIC_FAULT";
- ///////////////////
- // Argument Errors
- // Missing new operator to an object
- // - name: The name of the class
- ErrorCode["MISSING_NEW"] = "MISSING_NEW";
- // Invalid argument (e.g. value is incompatible with type) to a function:
- // - argument: The argument name that was invalid
- // - value: The value of the argument
- ErrorCode["INVALID_ARGUMENT"] = "INVALID_ARGUMENT";
- // Missing argument to a function:
- // - count: The number of arguments received
- // - expectedCount: The number of arguments expected
- ErrorCode["MISSING_ARGUMENT"] = "MISSING_ARGUMENT";
- // Too many arguments
- // - count: The number of arguments received
- // - expectedCount: The number of arguments expected
- ErrorCode["UNEXPECTED_ARGUMENT"] = "UNEXPECTED_ARGUMENT";
- ///////////////////
- // Blockchain Errors
- // Call exception
- // - transaction: the transaction
- // - address?: the contract address
- // - args?: The arguments passed into the function
- // - method?: The Solidity method signature
- // - errorSignature?: The EIP848 error signature
- // - errorArgs?: The EIP848 error parameters
- // - reason: The reason (only for EIP848 "Error(string)")
- ErrorCode["CALL_EXCEPTION"] = "CALL_EXCEPTION";
- // Insufficient funds (< value + energyLimit * energyPrice)
- // - transaction: the transaction attempted
- ErrorCode["INSUFFICIENT_FUNDS"] = "INSUFFICIENT_FUNDS";
- // Nonce has already been used
- // - transaction: the transaction attempted
- ErrorCode["NONCE_EXPIRED"] = "NONCE_EXPIRED";
- // The replacement fee for the transaction is too low
- // - transaction: the transaction attempted
- ErrorCode["REPLACEMENT_UNDERPRICED"] = "REPLACEMENT_UNDERPRICED";
- // The energy limit could not be estimated
- // - transaction: the transaction passed to estimateEnergy
- ErrorCode["UNPREDICTABLE_ENERGY_LIMIT"] = "UNPREDICTABLE_ENERGY_LIMIT";
- // The transaction was replaced by one with a higher energy price
- // - reason: "cancelled", "replaced" or "repriced"
- // - cancelled: true if reason == "cancelled" or reason == "replaced")
- // - hash: original transaction hash
- // - replacement: the full TransactionsResponse for the replacement
- // - receipt: the receipt of the replacement
- ErrorCode["TRANSACTION_REPLACED"] = "TRANSACTION_REPLACED";
- })(ErrorCode || (ErrorCode = {}));
- const HEX = "0123456789abcdef";
- class Logger {
- version = "0.0.1";
- static errors = ErrorCode;
- static levels = LogLevel;
- constructor(version) {
- Object.defineProperty(this, "version", {
- enumerable: true,
- value: version,
- writable: false,
- });
- }
- _log(logLevel, args) {
- const level = logLevel.toLowerCase();
- if (LogLevels[level] == null) {
- this.throwArgumentError("invalid log level name", "logLevel", logLevel);
- }
- if (_logLevel > LogLevels[level]) {
- return;
- }
- console.log.apply(console, args);
- }
- debug(...args) {
- this._log(Logger.levels.DEBUG, args);
- }
- info(...args) {
- this._log(Logger.levels.INFO, args);
- }
- warn(...args) {
- this._log(Logger.levels.WARNING, args);
- }
- makeError(message, code, params) {
- // Errors are being censored
- if (_censorErrors) {
- return this.makeError("censored error", code, {});
- }
- if (!code) {
- code = Logger.errors.UNKNOWN_ERROR;
- }
- if (!params) {
- params = {};
- }
- const messageDetails = [];
- Object.keys(params).forEach((key) => {
- const value = params[key];
- try {
- if (value instanceof Uint8Array) {
- let hex = "";
- for (let i = 0; i < value.length; i++) {
- hex += HEX[value[i] >> 4];
- hex += HEX[value[i] & 0x0f];
- }
- messageDetails.push(key + "=Uint8Array(0x" + hex + ")");
- }
- else {
- messageDetails.push(key + "=" + JSON.stringify(value));
- }
- }
- catch (error) {
- messageDetails.push(key + "=" + JSON.stringify(params[key].toString()));
- }
- });
- messageDetails.push(`code=${code}`);
- messageDetails.push(`version=${this.version}`);
- const reason = message;
- if (messageDetails.length) {
- message += " (" + messageDetails.join(", ") + ")";
- }
- // @TODO: Any??
- const error = new Error(message);
- error.reason = reason;
- error.code = code;
- Object.keys(params).forEach(function (key) {
- error[key] = params[key];
- });
- return error;
- }
- throwError(message, code, params) {
- throw this.makeError(message, code, params);
- }
- throwArgumentError(message, name, value) {
- return this.throwError(message, Logger.errors.INVALID_ARGUMENT, {
- argument: name,
- value: value,
- });
- }
- assert(condition, message, code, params) {
- if (!!condition) {
- return;
- }
- this.throwError(message, code, params);
- }
- assertArgument(condition, message, name, value) {
- if (!!condition) {
- return;
- }
- this.throwArgumentError(message, name, value);
- }
- checkNormalize(message) {
- if (_normalizeError) {
- this.throwError("platform missing String.prototype.normalize", Logger.errors.UNSUPPORTED_OPERATION, {
- operation: "String.prototype.normalize",
- form: _normalizeError,
- });
- }
- }
- checkSafeUint53(value, message) {
- if (typeof value !== "number") {
- return;
- }
- if (message == null) {
- message = "value not safe";
- }
- if (value < 0 || value >= 0x1fffffffffffff) {
- this.throwError(message, Logger.errors.NUMERIC_FAULT, {
- operation: "checkSafeInteger",
- fault: "out-of-safe-range",
- value: value,
- });
- }
- if (value % 1) {
- this.throwError(message, Logger.errors.NUMERIC_FAULT, {
- operation: "checkSafeInteger",
- fault: "non-integer",
- value: value,
- });
- }
- }
- checkArgumentCount(count, expectedCount, message) {
- if (message) {
- message = ": " + message;
- }
- else {
- message = "";
- }
- if (count < expectedCount) {
- this.throwError("missing argument" + message, Logger.errors.MISSING_ARGUMENT, {
- count: count,
- expectedCount: expectedCount,
- });
- }
- if (count > expectedCount) {
- this.throwError("too many arguments" + message, Logger.errors.UNEXPECTED_ARGUMENT, {
- count: count,
- expectedCount: expectedCount,
- });
- }
- }
- checkNew(target, kind) {
- if (target === Object || target == null) {
- this.throwError("missing new", Logger.errors.MISSING_NEW, {
- name: kind.name,
- });
- }
- }
- checkAbstract(target, kind) {
- if (target === kind) {
- this.throwError("cannot instantiate abstract class " +
- JSON.stringify(kind.name) +
- " directly; use a sub-class", Logger.errors.UNSUPPORTED_OPERATION, { name: target.name, operation: "new" });
- }
- else if (target === Object || target == null) {
- this.throwError("missing new", Logger.errors.MISSING_NEW, {
- name: kind.name,
- });
- }
- }
- static globalLogger() {
- if (!_globalLogger) {
- _globalLogger = new Logger("logger/0.0.1");
- }
- return _globalLogger;
- }
- static setCensorship(censorship, permanent) {
- if (!censorship && permanent) {
- this.globalLogger().throwError("cannot permanently disable censorship", Logger.errors.UNSUPPORTED_OPERATION, {
- operation: "setCensorship",
- });
- }
- if (_permanentCensorErrors) {
- if (!censorship) {
- return;
- }
- this.globalLogger().throwError("error censorship permanent", Logger.errors.UNSUPPORTED_OPERATION, {
- operation: "setCensorship",
- });
- }
- _censorErrors = !!censorship;
- _permanentCensorErrors = !!permanent;
- }
- static setLogLevel(logLevel) {
- const level = LogLevels[logLevel.toLowerCase()];
- if (level == null) {
- Logger.globalLogger().warn("invalid log level - " + logLevel);
- return;
- }
- _logLevel = level;
- }
- static from(version) {
- return new Logger(version);
- }
- }
-
- /**
- * Property helper functions.
- *
- * @_subsection api/utils:Properties [about-properties]
- */
- const logger$7 = new Logger("utils/properties/0.0.1");
- function checkType(value, type, name) {
- const types = type.split("|").map((t) => t.trim());
- for (let i = 0; i < types.length; i++) {
- switch (type) {
- case "any":
- return;
- case "bigint":
- case "boolean":
- case "number":
- case "string":
- if (typeof value === type) {
- return;
- }
- }
- }
- const error = new Error(`invalid value for type ${type}`);
- error.code = "INVALID_ARGUMENT";
- error.argument = `value.${name}`;
- error.value = value;
- throw error;
- }
- /**
- * Resolves to a new object that is a copy of %%value%%, but with all
- * values resolved.
- */
- async function resolveProperties(value) {
- const keys = Object.keys(value);
- const results = await Promise.all(keys.map((k) => Promise.resolve(value[k])));
- return results.reduce((accum, v, index) => {
- accum[keys[index]] = v;
- return accum;
- }, {});
- }
- /**
- * Assigns the %%values%% to %%target%% as read-only values.
- *
- * It %%types%% is specified, the values are checked.
- */
- function defineProperties(target, values, types) {
- for (let key in values) {
- let value = values[key];
- const type = types ? types[key] : null;
- if (type) {
- checkType(value, type, key);
- }
- Object.defineProperty(target, key, {
- enumerable: true,
- value,
- writable: false,
- });
- }
- }
- function checkProperties(object, properties) {
- if (!object || typeof object !== "object") {
- logger$7.throwArgumentError("invalid object", "object", object);
- }
- Object.keys(object).forEach((key) => {
- if (!properties[key]) {
- logger$7.throwArgumentError("invalid object key - " + key, "transaction:" + key, object);
- }
- });
- }
-
- /**
- * About Errors.
- *
- * @_section: api/utils/errors:Errors [about-errors]
- */
- function stringify$1(value) {
- if (value == null) {
- return "null";
- }
- if (Array.isArray(value)) {
- return "[ " + value.map(stringify$1).join(", ") + " ]";
- }
- if (value instanceof Uint8Array) {
- const HEX = "0123456789abcdef";
- let result = "0x";
- for (let i = 0; i < value.length; i++) {
- result += HEX[value[i] >> 4];
- result += HEX[value[i] & 0xf];
- }
- return result;
- }
- if (typeof value === "object" && typeof value.toJSON === "function") {
- return stringify$1(value.toJSON());
- }
- switch (typeof value) {
- case "boolean":
- case "symbol":
- return value.toString();
- case "bigint":
- return BigInt(value).toString();
- case "number":
- return value.toString();
- case "string":
- return JSON.stringify(value);
- case "object": {
- const keys = Object.keys(value);
- keys.sort();
- return ("{ " +
- keys.map((k) => `${stringify$1(k)}: ${stringify$1(value[k])}`).join(", ") +
- " }");
- }
- }
- return `[ COULD NOT SERIALIZE ]`;
- }
- /**
- * Returns true if the %%error%% matches an error thrown by corebc
- * that matches the error %%code%%.
- *
- * In TypeScript envornoments, this can be used to check that %%error%%
- * matches an corebcError type, which means the expected properties will
- * be set.
- *
- * @See [ErrorCodes](api:ErrorCode)
- * @example
- * try {
- * // code....
- * } catch (e) {
- * if (isError(e, "CALL_EXCEPTION")) {
- * // The Type Guard has validated this object
- * console.log(e.data);
- * }
- * }
- */
- function isError(error, code) {
- return error && error.code === code;
- }
- /**
- * Returns true if %%error%% is a [[CallExceptionError].
- */
- function isCallException(error) {
- return isError(error, "CALL_EXCEPTION");
- }
- /**
- * Returns a new Error configured to the format corebc emits errors, with
- * the %%message%%, [[api:ErrorCode]] %%code%% and additioanl properties
- * for the corresponding corebcError.
- *
- * Each error in corebc includes the version of corebc, a
- * machine-readable [[ErrorCode]], and depneding on %%code%%, additional
- * required properties. The error message will also include the %%meeage%%,
- * corebc version, %%code%% and all aditional properties, serialized.
- */
- function makeError(message, code, info) {
- {
- const details = [];
- if (info) {
- if ("message" in info || "code" in info || "name" in info) {
- throw new Error(`value will overwrite populated values: ${stringify$1(info)}`);
- }
- for (const key in info) {
- const value = info[key];
- // try {
- details.push(key + "=" + stringify$1(value));
- // } catch (error: any) {
- // console.log("MMM", error.message);
- // details.push(key + "=[could not serialize object]");
- // }
- }
- }
- details.push(`code=${code}`);
- details.push(`version=${version}`);
- if (details.length) {
- message += " (" + details.join(", ") + ")";
- }
- }
- let error;
- switch (code) {
- case "INVALID_ARGUMENT":
- error = new TypeError(message);
- break;
- case "NUMERIC_FAULT":
- case "BUFFER_OVERRUN":
- error = new RangeError(message);
- break;
- default:
- error = new Error(message);
- }
- defineProperties(error, { code });
- if (info) {
- Object.assign(error, info);
- }
- return error;
- }
- /**
- * Throws an corebcError with %%message%%, %%code%% and additional error
- * %%info%% when %%check%% is falsish..
- *
- * @see [[api:makeError]]
- */
- function assert(check, message, code, info) {
- if (!check) {
- throw makeError(message, code, info);
- }
- }
- /**
- * A simple helper to simply ensuring provided arguments match expected
- * constraints, throwing if not.
- *
- * In TypeScript environments, the %%check%% has been asserted true, so
- * any further code does not need additional compile-time checks.
- */
- function assertArgument(check, message, name, value) {
- assert(check, message, "INVALID_ARGUMENT", { argument: name, value: value });
- }
- function assertArgumentCount(count, expectedCount, message) {
- if (message == null) {
- message = "";
- }
- if (message) {
- message = ": " + message;
- }
- assert(count >= expectedCount, "missing arguemnt" + message, "MISSING_ARGUMENT", {
- count: count,
- expectedCount: expectedCount,
- });
- assert(count <= expectedCount, "too many arguemnts" + message, "UNEXPECTED_ARGUMENT", {
- count: count,
- expectedCount: expectedCount,
- });
- }
- const _normalizeForms = ["NFD", "NFC", "NFKD", "NFKC"].reduce((accum, form) => {
- try {
- // General test for normalize
- /* c8 ignore start */
- if ("test".normalize(form) !== "test") {
- throw new Error("bad");
- }
- /* c8 ignore stop */
- if (form === "NFD") {
- const check = String.fromCharCode(0xe9).normalize("NFD");
- const expected = String.fromCharCode(0x65, 0x0301);
- /* c8 ignore start */
- if (check !== expected) {
- throw new Error("broken");
- }
- /* c8 ignore stop */
- }
- accum.push(form);
- }
- catch (error) { }
- return accum;
- }, []);
- /**
- * Throws if the normalization %%form%% is not supported.
- */
- function assertNormalize(form) {
- assert(_normalizeForms.indexOf(form) >= 0, "platform missing String.prototype.normalize", "UNSUPPORTED_OPERATION", {
- operation: "String.prototype.normalize",
- info: { form },
- });
- }
- /**
- * Many classes use file-scoped values to guard the constructor,
- * making it effectively private. This facilitates that pattern
- * by ensuring the %%givenGaurd%% matches the file-scoped %%guard%%,
- * throwing if not, indicating the %%className%% if provided.
- */
- function assertPrivate(givenGuard, guard, className) {
- if (className == null) {
- className = "";
- }
- if (givenGuard !== guard) {
- let method = className, operation = "new";
- if (className) {
- method += ".";
- operation += " " + className;
- }
- assert(false, `private constructor; use ${method}from* methods`, "UNSUPPORTED_OPERATION", {
- operation,
- });
- }
- }
-
- /**
- * Some data helpers.
- *
- *
- * @_subsection api/utils:Data Helpers [about-data]
- */
- const logger$6 = new Logger("utils/data/0.0.1");
- function isHexable(value) {
- return !!value.toHexString;
- }
- function isInteger(value) {
- return typeof value === "number" && value == value && value % 1 === 0;
- }
- function isBytes(value) {
- if (value == null) {
- return false;
- }
- if (value.constructor === Uint8Array) {
- return true;
- }
- if (typeof value === "string") {
- return false;
- }
- if (!isInteger(value.length) || value.length < 0) {
- return false;
- }
- for (let i = 0; i < value.length; i++) {
- const v = value[i];
- if (!isInteger(v) || v < 0 || v >= 256) {
- return false;
- }
- }
- return true;
- }
- function _getBytes(value, name, copy) {
- if (value instanceof Uint8Array) {
- if (copy) {
- return new Uint8Array(value);
- }
- return value;
- }
- if (typeof value === "string" && value.match(/^0x([0-9a-f][0-9a-f])*$/i)) {
- const result = new Uint8Array((value.length - 2) / 2);
- let offset = 2;
- for (let i = 0; i < result.length; i++) {
- result[i] = parseInt(value.substring(offset, offset + 2), 16);
- offset += 2;
- }
- return result;
- }
- assertArgument(false, "invalid BytesLike value", name || "value", value);
- }
- /**
- * Get a typed Uint8Array for %%value%%. If already a Uint8Array
- * the original %%value%% is returned; if a copy is required use
- * [[getBytesCopy]].
- *
- * @see: getBytesCopy
- */
- function getBytes(value, name) {
- return _getBytes(value, name, false);
- }
- /**
- * Get a typed Uint8Array for %%value%%, creating a copy if necessary
- * to prevent any modifications of the returned value from being
- * reflected elsewhere.
- *
- * @see: getBytes
- */
- function getBytesCopy(value, name) {
- return _getBytes(value, name, true);
- }
- /**
- * Returns true if %%value%% is a valid [[HexString]].
- *
- * If %%length%% is ``true`` or a //number//, it also checks that
- * %%value%% is a valid [[DataHexString]] of %%length%% (if a //number//)
- * bytes of data (e.g. ``0x1234`` is 2 bytes).
- */
- function isHexString(value, length) {
- if (typeof value !== "string" || !value.match(/^0x[0-9A-Fa-f]*$/)) {
- return false;
- }
- if (typeof length === "number" && value.length !== 2 + 2 * length) {
- return false;
- }
- if (length === true && value.length % 2 !== 0) {
- return false;
- }
- return true;
- }
- /**
- * Returns true if %%value%% is a valid representation of arbitrary
- * data (i.e. a valid [[DataHexString]] or a Uint8Array).
- */
- function isBytesLike(value) {
- return isHexString(value, true) || value instanceof Uint8Array;
- }
- const HexCharacters = "0123456789abcdef";
- /**
- * Returns a [[DataHexString]] representation of %%data%%.
- */
- function hexlify(value, options) {
- if (!options) {
- options = {};
- }
- if (typeof value === "string") {
- if (value.includes(",") && value.startsWith("0x")) {
- const v = value
- .replace("0x", "")
- .split(",")
- .map((item) => Number(item));
- // @ts-ignore
- value = new Uint8Array(v);
- }
- }
- if (typeof value === "number") {
- logger$6.checkSafeUint53(value, "invalid hexlify value");
- let hex = "";
- while (value) {
- hex = HexCharacters[value & 0xf] + hex;
- value = Math.floor(value / 16);
- }
- if (hex.length) {
- if (hex.length % 2) {
- hex = "0" + hex;
- }
- return "0x" + hex;
- }
- return "0x00";
- }
- if (typeof value === "bigint") {
- value = value.toString(16);
- if (value.length % 2) {
- return "0x0" + value;
- }
- return "0x" + value;
- }
- if (options.allowMissingPrefix &&
- typeof value === "string" &&
- value.substring(0, 2) !== "0x") {
- value = "0x" + value;
- }
- if (isHexable(value)) {
- return value.toHexString();
- }
- if (isHexString(value)) {
- if (value.length % 2) {
- if (options.hexPad === "left") {
- value = "0x0" + value.substring(2);
- }
- else if (options.hexPad === "right") {
- value += "0";
- }
- else {
- logger$6.throwArgumentError("hex data is odd-length", "value", value);
- }
- }
- return value.toLowerCase();
- }
- if (isBytes(value)) {
- let result = "0x";
- for (let i = 0; i < value.length; i++) {
- let v = value[i];
- result += HexCharacters[(v & 0xf0) >> 4] + HexCharacters[v & 0x0f];
- }
- return result;
- }
- return logger$6.throwArgumentError("invalid hexlify value", "value", value);
- }
- /**
- * Returns a [[DataHexString]] by concatenating all values
- * within %%data%%.
- */
- function concat(items) {
- return "0x" + items.map((d) => hexlify(d).substring(2)).join("");
- }
- function hexDataSlice(data, offset, endOffset) {
- if (typeof data !== "string") {
- data = hexlify(data);
- }
- else if (!isHexString(data) || data.length % 2) {
- logger$6.throwArgumentError("invalid hexData", "value", data);
- }
- offset = 2 + 2 * offset;
- if (endOffset != null) {
- return "0x" + data.substring(offset, 2 + 2 * endOffset);
- }
- return "0x" + data.substring(offset);
- }
- function hexDataLength(data) {
- if (typeof data !== "string") {
- data = hexlify(data);
- }
- else if (!isHexString(data) || data.length % 2) {
- return null;
- }
- return (data.length - 2) / 2;
- }
- /**
- * Returns the length of %%data%%, in bytes.
- */
- function dataLength(data) {
- if (isHexString(data, true)) {
- return (data.length - 2) / 2;
- }
- return getBytes(data).length;
- }
- /**
- * Returns a [[DataHexString]] by slicing %%data%% from the %%start%%
- * offset to the %%end%% offset.
- *
- * By default %%start%% is 0 and %%end%% is the length of %%data%%.
- */
- function dataSlice(data, start, end) {
- const bytes = getBytes(data);
- if (end != null && end > bytes.length) {
- assert(false, "cannot slice beyond data bounds", "BUFFER_OVERRUN", {
- buffer: bytes,
- length: bytes.length,
- offset: end,
- });
- }
- return hexlify(bytes.slice(start == null ? 0 : start, end == null ? bytes.length : end));
- }
- /**
- * Return the [[DataHexString]] result by stripping all **leading**
- ** zero bytes from %%data%%.
- */
- function stripZerosLeft(data) {
- let bytes = hexlify(data).substring(2);
- while (bytes.startsWith("00")) {
- bytes = bytes.substring(2);
- }
- return "0x" + bytes;
- }
- function zeroPad(data, length, left) {
- const bytes = getBytes(data);
- assert(length >= bytes.length, "padding exceeds data length", "BUFFER_OVERRUN", {
- buffer: new Uint8Array(bytes),
- length: length,
- offset: length + 1,
- });
- const result = new Uint8Array(length);
- result.fill(0);
- if (left) {
- result.set(bytes, length - bytes.length);
- }
- else {
- result.set(bytes, 0);
- }
- return hexlify(result);
- }
- /**
- * Return the [[DataHexString]] of %%data%% padded on the **left**
- * to %%length%% bytes.
- *
- * If %%data%% already exceeds %%length%%, a [[BufferOverrunError]] is
- * thrown.
- *
- * This pads data the same as **values** are in Solidity
- * (e.g. ``uint128``).
- */
- function zeroPadValue(data, length) {
- return zeroPad(data, length, true);
- }
- /**
- * Return the [[DataHexString]] of %%data%% padded on the **right**
- * to %%length%% bytes.
- *
- * If %%data%% already exceeds %%length%%, a [[BufferOverrunError]] is
- * thrown.
- *
- * This pads data the same as **bytes** are in Solidity
- * (e.g. ``bytes16``).
- */
- function zeroPadBytes(data, length) {
- return zeroPad(data, length, false);
- }
- function stripZeros(value) {
- let result = arrayify(value);
- if (result.length === 0) {
- return result;
- }
- // Find the first non-zero entry
- let start = 0;
- while (start < result.length && result[start] === 0) {
- start++;
- }
- // If we started with zeros, strip them
- if (start) {
- result = result.slice(start);
- }
- return result;
- }
- function arrayify(value, options) {
- if (!options) {
- options = {};
- }
- if (typeof value === "number") {
- logger$6.checkSafeUint53(value, "invalid arrayify value");
- const result = [];
- while (value) {
- // @ts-ignore
- result.unshift(value & 0xff);
- value = parseInt(String(value / 256));
- }
- if (result.length === 0) {
- result.push(0);
- }
- return addSlice(new Uint8Array(result));
- }
- if (options.allowMissingPrefix &&
- typeof value === "string" &&
- value.substring(0, 2) !== "0x") {
- value = "0x" + value;
- }
- if (isHexable(value)) {
- value = value.toHexString();
- }
- if (isHexString(value)) {
- let hex = value.substring(2);
- if (hex.length % 2) {
- if (options.hexPad === "left") {
- hex = "0x0" + hex.substring(2);
- }
- else if (options.hexPad === "right") {
- hex += "0";
- }
- else {
- logger$6.throwArgumentError("hex data is odd-length", "value", value);
- }
- }
- const result = [];
- for (let i = 0; i < hex.length; i += 2) {
- // @ts-ignore
- result.push(parseInt(hex.substring(i, i + 2), 16));
- }
- return addSlice(new Uint8Array(result));
- }
- if (isBytes(value)) {
- return addSlice(new Uint8Array(value));
- }
- return logger$6.throwArgumentError("invalid arrayify value", "value", value);
- }
- function addSlice(array) {
- // @ts-ignore
- if (array.slice) {
- return array;
- }
- array.slice = function () {
- const args = Array.prototype.slice.call(arguments);
- return addSlice(new Uint8Array(Array.prototype.slice.apply(array, args)));
- };
- return array;
- }
- function hexConcat(items) {
- let result = "0x";
- items.forEach((item) => {
- result += hexlify(item).substring(2);
- });
- return result;
- }
-
- var BN = _BN.BN;
- const logger$5 = new Logger("bigNumber/0.0.1");
- const _constructorGuard = {};
- const MAX_SAFE = 0x1fffffffffffff;
- // Only warn about passing 10 into radix once
- let _warnedToStringRadix = false;
- class BigNumber {
- _hex;
- _isBigNumber;
- constructor(constructorGuard, hex) {
- logger$5.checkNew(new.target, BigNumber);
- if (constructorGuard !== _constructorGuard) {
- logger$5.throwError("cannot call constructor directly; use BigNumber.from", Logger.errors.UNSUPPORTED_OPERATION, {
- operation: "new (BigNumber)",
- });
- }
- this._hex = hex;
- this._isBigNumber = true;
- Object.freeze(this);
- }
- fromTwos(value) {
- return toBigNumber(toBN(this).fromTwos(value));
- }
- toTwos(value) {
- return toBigNumber(toBN(this).toTwos(value));
- }
- abs() {
- if (this._hex[0] === "-") {
- return BigNumber.from(this._hex.substring(1));
- }
- return this;
- }
- add(other) {
- return toBigNumber(toBN(this).add(toBN(other)));
- }
- sub(other) {
- return toBigNumber(toBN(this).sub(toBN(other)));
- }
- div(other) {
- const o = BigNumber.from(other);
- if (o.isZero()) {
- throwFault("division by zero", "div");
- }
- return toBigNumber(toBN(this).div(toBN(other)));
- }
- mul(other) {
- return toBigNumber(toBN(this).mul(toBN(other)));
- }
- mod(other) {
- const value = toBN(other);
- if (value.isNeg()) {
- throwFault("cannot modulo negative values", "mod");
- }
- return toBigNumber(toBN(this).umod(value));
- }
- pow(other) {
- const value = toBN(other);
- if (value.isNeg()) {
- throwFault("cannot raise to negative values", "pow");
- }
- return toBigNumber(toBN(this).pow(value));
- }
- and(other) {
- const value = toBN(other);
- if (this.isNegative() || value.isNeg()) {
- throwFault("cannot 'and' negative values", "and");
- }
- return toBigNumber(toBN(this).and(value));
- }
- or(other) {
- const value = toBN(other);
- if (this.isNegative() || value.isNeg()) {
- throwFault("cannot 'or' negative values", "or");
- }
- return toBigNumber(toBN(this).or(value));
- }
- xor(other) {
- const value = toBN(other);
- if (this.isNegative() || value.isNeg()) {
- throwFault("cannot 'xor' negative values", "xor");
- }
- return toBigNumber(toBN(this).xor(value));
- }
- mask(value) {
- if (this.isNegative() || value < 0) {
- throwFault("cannot mask negative values", "mask");
- }
- return toBigNumber(toBN(this).maskn(value));
- }
- shl(value) {
- if (this.isNegative() || value < 0) {
- throwFault("cannot shift negative values", "shl");
- }
- return toBigNumber(toBN(this).shln(value));
- }
- shr(value) {
- if (this.isNegative() || value < 0) {
- throwFault("cannot shift negative values", "shr");
- }
- return toBigNumber(toBN(this).shrn(value));
- }
- eq(other) {
- return toBN(this).eq(toBN(other));
- }
- lt(other) {
- return toBN(this).lt(toBN(other));
- }
- lte(other) {
- return toBN(this).lte(toBN(other));
- }
- gt(other) {
- return toBN(this).gt(toBN(other));
- }
- gte(other) {
- return toBN(this).gte(toBN(other));
- }
- isNegative() {
- return this._hex[0] === "-";
- }
- isZero() {
- return toBN(this).isZero();
- }
- toNumber() {
- try {
- return toBN(this).toNumber();
- }
- catch (error) {
- throwFault("overflow", "toNumber", this.toString());
- }
- // @ts-ignore
- return null;
- }
- toBigInt() {
- try {
- return BigInt(this.toString());
- }
- catch (e) { }
- return logger$5.throwError("this platform does not support BigInt", Logger.errors.UNSUPPORTED_OPERATION, {
- value: this.toString(),
- });
- }
- toString() {
- // Lots of people expect this, which we do not support, so check (See: #889)
- if (arguments.length > 0) {
- if (arguments[0] === 10) {
- if (!_warnedToStringRadix) {
- _warnedToStringRadix = true;
- logger$5.warn("BigNumber.toString does not accept any parameters; base-10 is assumed");
- }
- }
- else if (arguments[0] === 16) {
- logger$5.throwError("BigNumber.toString does not accept any parameters; use bigNumber.toHexString()", Logger.errors.UNEXPECTED_ARGUMENT, {});
- }
- else {
- logger$5.throwError("BigNumber.toString does not accept parameters", Logger.errors.UNEXPECTED_ARGUMENT, {});
- }
- }
- return toBN(this).toString(10);
- }
- toHexString() {
- return this._hex;
- }
- toJSON(key) {
- return { type: "BigNumber", hex: this.toHexString() };
- }
- static from(value) {
- if (value instanceof BigNumber) {
- return value;
- }
- if (typeof value === "string") {
- if (value.match(/^-?0x[0-9a-f]+$/i)) {
- return new BigNumber(_constructorGuard, toHex(value));
- }
- if (value.match(/^-?[0-9]+$/)) {
- return new BigNumber(_constructorGuard, toHex(new BN(value)));
- }
- return logger$5.throwArgumentError("invalid BigNumber string", "value", value);
- }
- if (typeof value === "number") {
- if (value % 1) {
- throwFault("underflow", "BigNumber.from", value);
- }
- if (value >= MAX_SAFE || value <= -MAX_SAFE) {
- throwFault("overflow", "BigNumber.from", value);
- }
- return BigNumber.from(String(value));
- }
- const anyValue = value;
- if (typeof anyValue === "bigint") {
- return BigNumber.from(anyValue.toString());
- }
- if (isBytes(anyValue)) {
- return BigNumber.from(hexlify(anyValue));
- }
- if (anyValue) {
- // Hexable interface (takes priority)
- if (anyValue.toHexString) {
- const hex = anyValue.toHexString();
- if (typeof hex === "string") {
- return BigNumber.from(hex);
- }
- }
- else {
- // For now, handle legacy JSON-ified values (goes away in v6)
- let hex = anyValue._hex;
- // New-form JSON
- if (hex == null && anyValue.type === "BigNumber") {
- hex = anyValue.hex;
- }
- if (typeof hex === "string") {
- if (isHexString(hex) ||
- (hex[0] === "-" && isHexString(hex.substring(1)))) {
- return BigNumber.from(hex);
- }
- }
- }
- }
- return logger$5.throwArgumentError("invalid BigNumber value", "value", value);
- }
- static isBigNumber(value) {
- return !!(value && value._isBigNumber);
- }
- }
- // Normalize the hex string
- // @ts-ignore
- function toHex(value) {
- // For BN, call on the hex string
- if (typeof value !== "string") {
- return toHex(value.toString(16));
- }
- // If negative, prepend the negative sign to the normalized positive value
- if (value[0] === "-") {
- // Strip off the negative sign
- value = value.substring(1);
- // Cannot have multiple negative signs (e.g. "--0x04")
- if (value[0] === "-") {
- logger$5.throwArgumentError("invalid hex", "value", value);
- }
- // Call toHex on the positive component
- value = toHex(value);
- // Do not allow "-0x00"
- if (value === "0x00") {
- return value;
- }
- // Negate the value
- return "-" + value;
- }
- // Add a "0x" prefix if missing
- if (value.substring(0, 2) !== "0x") {
- value = "0x" + value;
- }
- // Normalize zero
- if (value === "0x") {
- return "0x00";
- }
- // Make the string even length
- if (value.length % 2) {
- value = "0x0" + value.substring(2);
- }
- // Trim to smallest even-length string
- while (value.length > 4 && value.substring(0, 4) === "0x00") {
- value = "0x" + value.substring(4);
- }
- return value;
- }
- // @ts-ignore
- function toBigNumber(value) {
- return BigNumber.from(toHex(value));
- }
- // @ts-ignore
- function toBN(value) {
- const hex = BigNumber.from(value).toHexString();
- if (hex[0] === "-") {
- return new BN("-" + hex.substring(3), 16);
- }
- return new BN(hex.substring(2), 16);
- }
- function throwFault(fault, operation, value) {
- const params = { fault: fault, operation: operation };
- if (value != null) {
- params.value = value;
- }
- return logger$5.throwError(fault, Logger.errors.NUMERIC_FAULT, params);
- }
-
- const logger$4 = new Logger("rlp/0.0.1");
- function arrayifyInteger$1(value) {
- const result = [];
- while (value) {
- // @ts-ignore
- result.unshift(value & 0xff);
- value >>= 8;
- }
- return result;
- }
- function unarrayifyInteger$1(data, offset, length) {
- let result = 0;
- for (let i = 0; i < length; i++) {
- result = result * 256 + data[offset + i];
- }
- return result;
- }
- function _encode$1(object) {
- if (Array.isArray(object)) {
- let payload = [];
- object.forEach(function (child) {
- payload = payload.concat(_encode$1(child));
- });
- if (payload.length <= 55) {
- payload.unshift(0xc0 + payload.length);
- return payload;
- }
- const length = arrayifyInteger$1(payload.length);
- length.unshift(0xf7 + length.length);
- return length.concat(payload);
- }
- if (!isBytesLike(object)) {
- logger$4.throwArgumentError("RLP object must be BytesLike", "object", object);
- }
- const data = Array.prototype.slice.call(arrayify(object));
- if (data.length === 1 && data[0] <= 0x7f) {
- return data;
- }
- else if (data.length <= 55) {
- data.unshift(0x80 + data.length);
- return data;
- }
- const length = arrayifyInteger$1(data.length);
- length.unshift(0xb7 + length.length);
- return length.concat(data);
- }
- function encode(object) {
- return hexlify(_encode$1(object));
- }
- function _decodeChildren$1(data, offset, childOffset, length) {
- const result = [];
- while (childOffset < offset + 1 + length) {
- const decoded = _decode$1(data, childOffset);
- result.push(decoded.result);
- childOffset += decoded.consumed;
- if (childOffset > offset + 1 + length) {
- logger$4.throwError("child data too short", Logger.errors.BUFFER_OVERRUN, {});
- }
- }
- return { consumed: 1 + length, result: result };
- }
- // returns { consumed: number, result: Object }
- function _decode$1(data, offset) {
- if (data.length === 0) {
- logger$4.throwError("data too short", Logger.errors.BUFFER_OVERRUN, {});
- }
- // Array with extra length prefix
- if (data[offset] >= 0xf8) {
- const lengthLength = data[offset] - 0xf7;
- if (offset + 1 + lengthLength > data.length) {
- logger$4.throwError("data short segment too short", Logger.errors.BUFFER_OVERRUN, {});
- }
- const length = unarrayifyInteger$1(data, offset + 1, lengthLength);
- if (offset + 1 + lengthLength + length > data.length) {
- logger$4.throwError("data long segment too short", Logger.errors.BUFFER_OVERRUN, {});
- }
- return _decodeChildren$1(data, offset, offset + 1 + lengthLength, lengthLength + length);
- }
- else if (data[offset] >= 0xc0) {
- const length = data[offset] - 0xc0;
- if (offset + 1 + length > data.length) {
- logger$4.throwError("data array too short", Logger.errors.BUFFER_OVERRUN, {});
- }
- return _decodeChildren$1(data, offset, offset + 1, length);
- }
- else if (data[offset] >= 0xb8) {
- const lengthLength = data[offset] - 0xb7;
- if (offset + 1 + lengthLength > data.length) {
- logger$4.throwError("data array too short", Logger.errors.BUFFER_OVERRUN, {});
- }
- const length = unarrayifyInteger$1(data, offset + 1, lengthLength);
- if (offset + 1 + lengthLength + length > data.length) {
- logger$4.throwError("data array too short", Logger.errors.BUFFER_OVERRUN, {});
- }
- const result = hexlify(data.slice(offset + 1 + lengthLength, offset + 1 + lengthLength + length));
- return { consumed: 1 + lengthLength + length, result: result };
- }
- else if (data[offset] >= 0x80) {
- const length = data[offset] - 0x80;
- if (offset + 1 + length > data.length) {
- logger$4.throwError("data too short", Logger.errors.BUFFER_OVERRUN, {});
- }
- const result = hexlify(data.slice(offset + 1, offset + 1 + length));
- return { consumed: 1 + length, result: result };
- }
- return { consumed: 1, result: hexlify(data[offset]) };
- }
- function decode$1(data) {
- const bytes = arrayify(data);
- const decoded = _decode$1(bytes, 0);
- if (decoded.consumed !== bytes.length) {
- logger$4.throwArgumentError("invalid rlp data", "data", data);
- }
- return decoded.result;
- }
-
- function number(n) {
- if (!Number.isSafeInteger(n) || n < 0)
- throw new Error(`Wrong positive integer: ${n}`);
- }
- function bytes(b, ...lengths) {
- if (!(b instanceof Uint8Array))
- throw new Error('Expected Uint8Array');
- if (lengths.length > 0 && !lengths.includes(b.length))
- throw new Error(`Expected Uint8Array of length ${lengths}, not of length=${b.length}`);
- }
- function hash(hash) {
- if (typeof hash !== 'function' || typeof hash.create !== 'function')
- throw new Error('Hash should be wrapped by utils.wrapConstructor');
- number(hash.outputLen);
- number(hash.blockLen);
- }
- function exists(instance, checkFinished = true) {
- if (instance.destroyed)
- throw new Error('Hash instance has been destroyed');
- if (checkFinished && instance.finished)
- throw new Error('Hash#digest() has already been called');
- }
- function output(out, instance) {
- bytes(out);
- const min = instance.outputLen;
- if (out.length < min) {
- throw new Error(`digestInto() expects output buffer of length at least ${min}`);
- }
- }
-
- /*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */
- // We use WebCrypto aka globalThis.crypto, which exists in browsers and node.js 16+.
- // node.js versions earlier than v19 don't declare it in global scope.
- // For node.js, package.json#exports field mapping rewrites import
- // from `crypto` to `cryptoNode`, which imports native module.
- // Makes the utils un-importable in browsers without a bundler.
- // Once node.js 18 is deprecated, we can just drop the import.
- const u8a = (a) => a instanceof Uint8Array;
- const u32 = (arr) => new Uint32Array(arr.buffer, arr.byteOffset, Math.floor(arr.byteLength / 4));
- // Cast array to view
- const createView = (arr) => new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
- // The rotate right (circular right shift) operation for uint32
- const rotr = (word, shift) => (word << (32 - shift)) | (word >>> shift);
- // big-endian hardware is rare. Just in case someone still decides to run hashes:
- // early-throw an error because we don't support BE yet.
- const isLE = new Uint8Array(new Uint32Array([0x11223344]).buffer)[0] === 0x44;
- if (!isLE)
- throw new Error('Non little-endian hardware is not supported');
- // There is no setImmediate in browser and setTimeout is slow.
- // call of async fn will return Promise, which will be fullfiled only on
- // next scheduler queue processing step and this is exactly what we need.
- const nextTick = async () => { };
- // Returns control to thread each 'tick' ms to avoid blocking
- async function asyncLoop(iters, tick, cb) {
- let ts = Date.now();
- for (let i = 0; i < iters; i++) {
- cb(i);
- // Date.now() is not monotonic, so in case if clock goes backwards we return return control too
- const diff = Date.now() - ts;
- if (diff >= 0 && diff < tick)
- continue;
- await nextTick();
- ts += diff;
- }
- }
- /**
- * @example utf8ToBytes('abc') // new Uint8Array([97, 98, 99])
- */
- function utf8ToBytes(str) {
- if (typeof str !== 'string')
- throw new Error(`utf8ToBytes expected string, got ${typeof str}`);
- return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809
- }
- /**
- * Normalizes (non-hex) string or Uint8Array to Uint8Array.
- * Warning: when Uint8Array is passed, it would NOT get copied.
- * Keep in mind for future mutable operations.
- */
- function toBytes(data) {
- if (typeof data === 'string')
- data = utf8ToBytes(data);
- if (!u8a(data))
- throw new Error(`expected Uint8Array, got ${typeof data}`);
- return data;
- }
- // For runtime check if class implements interface
- class Hash {
- // Safe version that clones internal state
- clone() {
- return this._cloneInto();
- }
- }
- const toStr = {}.toString;
- function checkOpts(defaults, opts) {
- if (opts !== undefined && toStr.call(opts) !== '[object Object]')
- throw new Error('Options should be object or undefined');
- const merged = Object.assign(defaults, opts);
- return merged;
- }
- function wrapConstructor(hashCons) {
- const hashC = (msg) => hashCons().update(toBytes(msg)).digest();
- const tmp = hashCons();
- hashC.outputLen = tmp.outputLen;
- hashC.blockLen = tmp.blockLen;
- hashC.create = () => hashCons();
- return hashC;
- }
-
- // HMAC (RFC 2104)
- class HMAC extends Hash {
- constructor(hash$1, _key) {
- super();
- this.finished = false;
- this.destroyed = false;
- hash(hash$1);
- const key = toBytes(_key);
- this.iHash = hash$1.create();
- if (typeof this.iHash.update !== 'function')
- throw new Error('Expected instance of class which extends utils.Hash');
- this.blockLen = this.iHash.blockLen;
- this.outputLen = this.iHash.outputLen;
- const blockLen = this.blockLen;
- const pad = new Uint8Array(blockLen);
- // blockLen can be bigger than outputLen
- pad.set(key.length > blockLen ? hash$1.create().update(key).digest() : key);
- for (let i = 0; i < pad.length; i++)
- pad[i] ^= 0x36;
- this.iHash.update(pad);
- // By doing update (processing of first block) of outer hash here we can re-use it between multiple calls via clone
- this.oHash = hash$1.create();
- // Undo internal XOR && apply outer XOR
- for (let i = 0; i < pad.length; i++)
- pad[i] ^= 0x36 ^ 0x5c;
- this.oHash.update(pad);
- pad.fill(0);
- }
- update(buf) {
- exists(this);
- this.iHash.update(buf);
- return this;
- }
- digestInto(out) {
- exists(this);
- bytes(out, this.outputLen);
- this.finished = true;
- this.iHash.digestInto(out);
- this.oHash.update(out);
- this.oHash.digestInto(out);
- this.destroy();
- }
- digest() {
- const out = new Uint8Array(this.oHash.outputLen);
- this.digestInto(out);
- return out;
- }
- _cloneInto(to) {
- // Create new instance without calling constructor since key already in state and we don't know it.
- to || (to = Object.create(Object.getPrototypeOf(this), {}));
- const { oHash, iHash, finished, destroyed, blockLen, outputLen } = this;
- to = to;
- to.finished = finished;
- to.destroyed = destroyed;
- to.blockLen = blockLen;
- to.outputLen = outputLen;
- to.oHash = oHash._cloneInto(to.oHash);
- to.iHash = iHash._cloneInto(to.iHash);
- return to;
- }
- destroy() {
- this.destroyed = true;
- this.oHash.destroy();
- this.iHash.destroy();
- }
- }
- /**
- * HMAC: RFC2104 message authentication code.
- * @param hash - function that would be used e.g. sha256
- * @param key - message key
- * @param message - message data
- */
- const hmac = (hash, key, message) => new HMAC(hash, key).update(message).digest();
- hmac.create = (hash, key) => new HMAC(hash, key);
-
- // Common prologue and epilogue for sync/async functions
- function pbkdf2Init(hash$1, _password, _salt, _opts) {
- hash(hash$1);
- const opts = checkOpts({ dkLen: 32, asyncTick: 10 }, _opts);
- const { c, dkLen, asyncTick } = opts;
- number(c);
- number(dkLen);
- number(asyncTick);
- if (c < 1)
- throw new Error('PBKDF2: iterations (c) should be >= 1');
- const password = toBytes(_password);
- const salt = toBytes(_salt);
- // DK = PBKDF2(PRF, Password, Salt, c, dkLen);
- const DK = new Uint8Array(dkLen);
- // U1 = PRF(Password, Salt + INT_32_BE(i))
- const PRF = hmac.create(hash$1, password);
- const PRFSalt = PRF._cloneInto().update(salt);
- return { c, dkLen, asyncTick, DK, PRF, PRFSalt };
- }
- function pbkdf2Output(PRF, PRFSalt, DK, prfW, u) {
- PRF.destroy();
- PRFSalt.destroy();
- if (prfW)
- prfW.destroy();
- u.fill(0);
- return DK;
- }
- /**
- * PBKDF2-HMAC: RFC 2898 key derivation function
- * @param hash - hash function that would be used e.g. sha256
- * @param password - password from which a derived key is generated
- * @param salt - cryptographic salt
- * @param opts - {c, dkLen} where c is work factor and dkLen is output message size
- */
- function pbkdf2$1(hash, password, salt, opts) {
- const { c, dkLen, DK, PRF, PRFSalt } = pbkdf2Init(hash, password, salt, opts);
- let prfW; // Working copy
- const arr = new Uint8Array(4);
- const view = createView(arr);
- const u = new Uint8Array(PRF.outputLen);
- // DK = T1 + T2 + ⋯ + Tdklen/hlen
- for (let ti = 1, pos = 0; pos < dkLen; ti++, pos += PRF.outputLen) {
- // Ti = F(Password, Salt, c, i)
- const Ti = DK.subarray(pos, pos + PRF.outputLen);
- view.setInt32(0, ti, false);
- // F(Password, Salt, c, i) = U1 ^ U2 ^ ⋯ ^ Uc
- // U1 = PRF(Password, Salt + INT_32_BE(i))
- (prfW = PRFSalt._cloneInto(prfW)).update(arr).digestInto(u);
- Ti.set(u.subarray(0, Ti.length));
- for (let ui = 1; ui < c; ui++) {
- // Uc = PRF(Password, Uc−1)
- PRF._cloneInto(prfW).update(u).digestInto(u);
- for (let i = 0; i < Ti.length; i++)
- Ti[i] ^= u[i];
- }
- }
- return pbkdf2Output(PRF, PRFSalt, DK, prfW, u);
- }
-
- // Polyfill for Safari 14
- function setBigUint64(view, byteOffset, value, isLE) {
- if (typeof view.setBigUint64 === 'function')
- return view.setBigUint64(byteOffset, value, isLE);
- const _32n = BigInt(32);
- const _u32_max = BigInt(0xffffffff);
- const wh = Number((value >> _32n) & _u32_max);
- const wl = Number(value & _u32_max);
- const h = isLE ? 4 : 0;
- const l = isLE ? 0 : 4;
- view.setUint32(byteOffset + h, wh, isLE);
- view.setUint32(byteOffset + l, wl, isLE);
- }
- // Base SHA2 class (RFC 6234)
- class SHA2 extends Hash {
- constructor(blockLen, outputLen, padOffset, isLE) {
- super();
- this.blockLen = blockLen;
- this.outputLen = outputLen;
- this.padOffset = padOffset;
- this.isLE = isLE;
- this.finished = false;
- this.length = 0;
- this.pos = 0;
- this.destroyed = false;
- this.buffer = new Uint8Array(blockLen);
- this.view = createView(this.buffer);
- }
- update(data) {
- exists(this);
- const { view, buffer, blockLen } = this;
- data = toBytes(data);
- const len = data.length;
- for (let pos = 0; pos < len;) {
- const take = Math.min(blockLen - this.pos, len - pos);
- // Fast path: we have at least one block in input, cast it to view and process
- if (take === blockLen) {
- const dataView = createView(data);
- for (; blockLen <= len - pos; pos += blockLen)
- this.process(dataView, pos);
- continue;
- }
- buffer.set(data.subarray(pos, pos + take), this.pos);
- this.pos += take;
- pos += take;
- if (this.pos === blockLen) {
- this.process(view, 0);
- this.pos = 0;
- }
- }
- this.length += data.length;
- this.roundClean();
- return this;
- }
- digestInto(out) {
- exists(this);
- output(out, this);
- this.finished = true;
- // Padding
- // We can avoid allocation of buffer for padding completely if it
- // was previously not allocated here. But it won't change performance.
- const { buffer, view, blockLen, isLE } = this;
- let { pos } = this;
- // append the bit '1' to the message
- buffer[pos++] = 0b10000000;
- this.buffer.subarray(pos).fill(0);
- // we have less than padOffset left in buffer, so we cannot put length in current block, need process it and pad again
- if (this.padOffset > blockLen - pos) {
- this.process(view, 0);
- pos = 0;
- }
- // Pad until full block byte with zeros
- for (let i = pos; i < blockLen; i++)
- buffer[i] = 0;
- // Note: sha512 requires length to be 128bit integer, but length in JS will overflow before that
- // You need to write around 2 exabytes (u64_max / 8 / (1024**6)) for this to happen.
- // So we just write lowest 64 bits of that value.
- setBigUint64(view, blockLen - 8, BigInt(this.length * 8), isLE);
- this.process(view, 0);
- const oview = createView(out);
- const len = this.outputLen;
- // NOTE: we do division by 4 later, which should be fused in single op with modulo by JIT
- if (len % 4)
- throw new Error('_sha2: outputLen should be aligned to 32bit');
- const outLen = len / 4;
- const state = this.get();
- if (outLen > state.length)
- throw new Error('_sha2: outputLen bigger than state');
- for (let i = 0; i < outLen; i++)
- oview.setUint32(4 * i, state[i], isLE);
- }
- digest() {
- const { buffer, outputLen } = this;
- this.digestInto(buffer);
- const res = buffer.slice(0, outputLen);
- this.destroy();
- return res;
- }
- _cloneInto(to) {
- to || (to = new this.constructor());
- to.set(...this.get());
- const { blockLen, buffer, length, finished, destroyed, pos } = this;
- to.length = length;
- to.pos = pos;
- to.finished = finished;
- to.destroyed = destroyed;
- if (length % blockLen)
- to.buffer.set(buffer);
- return to;
- }
- }
-
- // SHA2-256 need to try 2^128 hashes to execute birthday attack.
- // BTC network is doing 2^67 hashes/sec as per early 2023.
- // Choice: a ? b : c
- const Chi = (a, b, c) => (a & b) ^ (~a & c);
- // Majority function, true if any two inpust is true
- const Maj = (a, b, c) => (a & b) ^ (a & c) ^ (b & c);
- // Round constants:
- // first 32 bits of the fractional parts of the cube roots of the first 64 primes 2..311)
- // prettier-ignore
- const SHA256_K = /* @__PURE__ */ new Uint32Array([
- 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
- 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
- 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
- 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
- 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
- 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
- 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
- 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
- ]);
- // Initial state (first 32 bits of the fractional parts of the square roots of the first 8 primes 2..19):
- // prettier-ignore
- const IV = /* @__PURE__ */ new Uint32Array([
- 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
- ]);
- // Temporary buffer, not used to store anything between runs
- // Named this way because it matches specification.
- const SHA256_W = /* @__PURE__ */ new Uint32Array(64);
- class SHA256 extends SHA2 {
- constructor() {
- super(64, 32, 8, false);
- // We cannot use array here since array allows indexing by variable
- // which means optimizer/compiler cannot use registers.
- this.A = IV[0] | 0;
- this.B = IV[1] | 0;
- this.C = IV[2] | 0;
- this.D = IV[3] | 0;
- this.E = IV[4] | 0;
- this.F = IV[5] | 0;
- this.G = IV[6] | 0;
- this.H = IV[7] | 0;
- }
- get() {
- const { A, B, C, D, E, F, G, H } = this;
- return [A, B, C, D, E, F, G, H];
- }
- // prettier-ignore
- set(A, B, C, D, E, F, G, H) {
- this.A = A | 0;
- this.B = B | 0;
- this.C = C | 0;
- this.D = D | 0;
- this.E = E | 0;
- this.F = F | 0;
- this.G = G | 0;
- this.H = H | 0;
- }
- process(view, offset) {
- // Extend the first 16 words into the remaining 48 words w[16..63] of the message schedule array
- for (let i = 0; i < 16; i++, offset += 4)
- SHA256_W[i] = view.getUint32(offset, false);
- for (let i = 16; i < 64; i++) {
- const W15 = SHA256_W[i - 15];
- const W2 = SHA256_W[i - 2];
- const s0 = rotr(W15, 7) ^ rotr(W15, 18) ^ (W15 >>> 3);
- const s1 = rotr(W2, 17) ^ rotr(W2, 19) ^ (W2 >>> 10);
- SHA256_W[i] = (s1 + SHA256_W[i - 7] + s0 + SHA256_W[i - 16]) | 0;
- }
- // Compression function main loop, 64 rounds
- let { A, B, C, D, E, F, G, H } = this;
- for (let i = 0; i < 64; i++) {
- const sigma1 = rotr(E, 6) ^ rotr(E, 11) ^ rotr(E, 25);
- const T1 = (H + sigma1 + Chi(E, F, G) + SHA256_K[i] + SHA256_W[i]) | 0;
- const sigma0 = rotr(A, 2) ^ rotr(A, 13) ^ rotr(A, 22);
- const T2 = (sigma0 + Maj(A, B, C)) | 0;
- H = G;
- G = F;
- F = E;
- E = (D + T1) | 0;
- D = C;
- C = B;
- B = A;
- A = (T1 + T2) | 0;
- }
- // Add the compressed chunk to the current hash value
- A = (A + this.A) | 0;
- B = (B + this.B) | 0;
- C = (C + this.C) | 0;
- D = (D + this.D) | 0;
- E = (E + this.E) | 0;
- F = (F + this.F) | 0;
- G = (G + this.G) | 0;
- H = (H + this.H) | 0;
- this.set(A, B, C, D, E, F, G, H);
- }
- roundClean() {
- SHA256_W.fill(0);
- }
- destroy() {
- this.set(0, 0, 0, 0, 0, 0, 0, 0);
- this.buffer.fill(0);
- }
- }
- /**
- * SHA2-256 hash function
- * @param message - data that would be hashed
- */
- const sha256$1 = /* @__PURE__ */ wrapConstructor(() => new SHA256());
-
- const U32_MASK64 = /* @__PURE__ */ BigInt(2 ** 32 - 1);
- const _32n = /* @__PURE__ */ BigInt(32);
- // We are not using BigUint64Array, because they are extremely slow as per 2022
- function fromBig(n, le = false) {
- if (le)
- return { h: Number(n & U32_MASK64), l: Number((n >> _32n) & U32_MASK64) };
- return { h: Number((n >> _32n) & U32_MASK64) | 0, l: Number(n & U32_MASK64) | 0 };
- }
- function split(lst, le = false) {
- let Ah = new Uint32Array(lst.length);
- let Al = new Uint32Array(lst.length);
- for (let i = 0; i < lst.length; i++) {
- const { h, l } = fromBig(lst[i], le);
- [Ah[i], Al[i]] = [h, l];
- }
- return [Ah, Al];
- }
- const toBig = (h, l) => (BigInt(h >>> 0) << _32n) | BigInt(l >>> 0);
- // for Shift in [0, 32)
- const shrSH = (h, _l, s) => h >>> s;
- const shrSL = (h, l, s) => (h << (32 - s)) | (l >>> s);
- // Right rotate for Shift in [1, 32)
- const rotrSH = (h, l, s) => (h >>> s) | (l << (32 - s));
- const rotrSL = (h, l, s) => (h << (32 - s)) | (l >>> s);
- // Right rotate for Shift in (32, 64), NOTE: 32 is special case.
- const rotrBH = (h, l, s) => (h << (64 - s)) | (l >>> (s - 32));
- const rotrBL = (h, l, s) => (h >>> (s - 32)) | (l << (64 - s));
- // Right rotate for shift===32 (just swaps l&h)
- const rotr32H = (_h, l) => l;
- const rotr32L = (h, _l) => h;
- // Left rotate for Shift in [1, 32)
- const rotlSH = (h, l, s) => (h << s) | (l >>> (32 - s));
- const rotlSL = (h, l, s) => (l << s) | (h >>> (32 - s));
- // Left rotate for Shift in (32, 64), NOTE: 32 is special case.
- const rotlBH = (h, l, s) => (l << (s - 32)) | (h >>> (64 - s));
- const rotlBL = (h, l, s) => (h << (s - 32)) | (l >>> (64 - s));
- // JS uses 32-bit signed integers for bitwise operations which means we cannot
- // simple take carry out of low bit sum by shift, we need to use division.
- function add(Ah, Al, Bh, Bl) {
- const l = (Al >>> 0) + (Bl >>> 0);
- return { h: (Ah + Bh + ((l / 2 ** 32) | 0)) | 0, l: l | 0 };
- }
- // Addition with more than 2 elements
- const add3L = (Al, Bl, Cl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0);
- const add3H = (low, Ah, Bh, Ch) => (Ah + Bh + Ch + ((low / 2 ** 32) | 0)) | 0;
- const add4L = (Al, Bl, Cl, Dl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0);
- const add4H = (low, Ah, Bh, Ch, Dh) => (Ah + Bh + Ch + Dh + ((low / 2 ** 32) | 0)) | 0;
- const add5L = (Al, Bl, Cl, Dl, El) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0) + (El >>> 0);
- const add5H = (low, Ah, Bh, Ch, Dh, Eh) => (Ah + Bh + Ch + Dh + Eh + ((low / 2 ** 32) | 0)) | 0;
- // prettier-ignore
- const u64 = {
- fromBig, split, toBig,
- shrSH, shrSL,
- rotrSH, rotrSL, rotrBH, rotrBL,
- rotr32H, rotr32L,
- rotlSH, rotlSL, rotlBH, rotlBL,
- add, add3L, add3H, add4L, add4H, add5H, add5L,
- };
- var u64$1 = u64;
-
- // Round contants (first 32 bits of the fractional parts of the cube roots of the first 80 primes 2..409):
- // prettier-ignore
- const [SHA512_Kh, SHA512_Kl] = /* @__PURE__ */ (() => u64$1.split([
- '0x428a2f98d728ae22', '0x7137449123ef65cd', '0xb5c0fbcfec4d3b2f', '0xe9b5dba58189dbbc',
- '0x3956c25bf348b538', '0x59f111f1b605d019', '0x923f82a4af194f9b', '0xab1c5ed5da6d8118',
- '0xd807aa98a3030242', '0x12835b0145706fbe', '0x243185be4ee4b28c', '0x550c7dc3d5ffb4e2',
- '0x72be5d74f27b896f', '0x80deb1fe3b1696b1', '0x9bdc06a725c71235', '0xc19bf174cf692694',
- '0xe49b69c19ef14ad2', '0xefbe4786384f25e3', '0x0fc19dc68b8cd5b5', '0x240ca1cc77ac9c65',
- '0x2de92c6f592b0275', '0x4a7484aa6ea6e483', '0x5cb0a9dcbd41fbd4', '0x76f988da831153b5',
- '0x983e5152ee66dfab', '0xa831c66d2db43210', '0xb00327c898fb213f', '0xbf597fc7beef0ee4',
- '0xc6e00bf33da88fc2', '0xd5a79147930aa725', '0x06ca6351e003826f', '0x142929670a0e6e70',
- '0x27b70a8546d22ffc', '0x2e1b21385c26c926', '0x4d2c6dfc5ac42aed', '0x53380d139d95b3df',
- '0x650a73548baf63de', '0x766a0abb3c77b2a8', '0x81c2c92e47edaee6', '0x92722c851482353b',
- '0xa2bfe8a14cf10364', '0xa81a664bbc423001', '0xc24b8b70d0f89791', '0xc76c51a30654be30',
- '0xd192e819d6ef5218', '0xd69906245565a910', '0xf40e35855771202a', '0x106aa07032bbd1b8',
- '0x19a4c116b8d2d0c8', '0x1e376c085141ab53', '0x2748774cdf8eeb99', '0x34b0bcb5e19b48a8',
- '0x391c0cb3c5c95a63', '0x4ed8aa4ae3418acb', '0x5b9cca4f7763e373', '0x682e6ff3d6b2b8a3',
- '0x748f82ee5defb2fc', '0x78a5636f43172f60', '0x84c87814a1f0ab72', '0x8cc702081a6439ec',
- '0x90befffa23631e28', '0xa4506cebde82bde9', '0xbef9a3f7b2c67915', '0xc67178f2e372532b',
- '0xca273eceea26619c', '0xd186b8c721c0c207', '0xeada7dd6cde0eb1e', '0xf57d4f7fee6ed178',
- '0x06f067aa72176fba', '0x0a637dc5a2c898a6', '0x113f9804bef90dae', '0x1b710b35131c471b',
- '0x28db77f523047d84', '0x32caab7b40c72493', '0x3c9ebe0a15c9bebc', '0x431d67c49c100d4c',
- '0x4cc5d4becb3e42b6', '0x597f299cfc657e2a', '0x5fcb6fab3ad6faec', '0x6c44198c4a475817'
- ].map(n => BigInt(n))))();
- // Temporary buffer, not used to store anything between runs
- const SHA512_W_H = /* @__PURE__ */ new Uint32Array(80);
- const SHA512_W_L = /* @__PURE__ */ new Uint32Array(80);
- class SHA512 extends SHA2 {
- constructor() {
- super(128, 64, 16, false);
- // We cannot use array here since array allows indexing by variable which means optimizer/compiler cannot use registers.
- // Also looks cleaner and easier to verify with spec.
- // Initial state (first 32 bits of the fractional parts of the square roots of the first 8 primes 2..19):
- // h -- high 32 bits, l -- low 32 bits
- this.Ah = 0x6a09e667 | 0;
- this.Al = 0xf3bcc908 | 0;
- this.Bh = 0xbb67ae85 | 0;
- this.Bl = 0x84caa73b | 0;
- this.Ch = 0x3c6ef372 | 0;
- this.Cl = 0xfe94f82b | 0;
- this.Dh = 0xa54ff53a | 0;
- this.Dl = 0x5f1d36f1 | 0;
- this.Eh = 0x510e527f | 0;
- this.El = 0xade682d1 | 0;
- this.Fh = 0x9b05688c | 0;
- this.Fl = 0x2b3e6c1f | 0;
- this.Gh = 0x1f83d9ab | 0;
- this.Gl = 0xfb41bd6b | 0;
- this.Hh = 0x5be0cd19 | 0;
- this.Hl = 0x137e2179 | 0;
- }
- // prettier-ignore
- get() {
- const { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this;
- return [Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl];
- }
- // prettier-ignore
- set(Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl) {
- this.Ah = Ah | 0;
- this.Al = Al | 0;
- this.Bh = Bh | 0;
- this.Bl = Bl | 0;
- this.Ch = Ch | 0;
- this.Cl = Cl | 0;
- this.Dh = Dh | 0;
- this.Dl = Dl | 0;
- this.Eh = Eh | 0;
- this.El = El | 0;
- this.Fh = Fh | 0;
- this.Fl = Fl | 0;
- this.Gh = Gh | 0;
- this.Gl = Gl | 0;
- this.Hh = Hh | 0;
- this.Hl = Hl | 0;
- }
- process(view, offset) {
- // Extend the first 16 words into the remaining 64 words w[16..79] of the message schedule array
- for (let i = 0; i < 16; i++, offset += 4) {
- SHA512_W_H[i] = view.getUint32(offset);
- SHA512_W_L[i] = view.getUint32((offset += 4));
- }
- for (let i = 16; i < 80; i++) {
- // s0 := (w[i-15] rightrotate 1) xor (w[i-15] rightrotate 8) xor (w[i-15] rightshift 7)
- const W15h = SHA512_W_H[i - 15] | 0;
- const W15l = SHA512_W_L[i - 15] | 0;
- const s0h = u64$1.rotrSH(W15h, W15l, 1) ^ u64$1.rotrSH(W15h, W15l, 8) ^ u64$1.shrSH(W15h, W15l, 7);
- const s0l = u64$1.rotrSL(W15h, W15l, 1) ^ u64$1.rotrSL(W15h, W15l, 8) ^ u64$1.shrSL(W15h, W15l, 7);
- // s1 := (w[i-2] rightrotate 19) xor (w[i-2] rightrotate 61) xor (w[i-2] rightshift 6)
- const W2h = SHA512_W_H[i - 2] | 0;
- const W2l = SHA512_W_L[i - 2] | 0;
- const s1h = u64$1.rotrSH(W2h, W2l, 19) ^ u64$1.rotrBH(W2h, W2l, 61) ^ u64$1.shrSH(W2h, W2l, 6);
- const s1l = u64$1.rotrSL(W2h, W2l, 19) ^ u64$1.rotrBL(W2h, W2l, 61) ^ u64$1.shrSL(W2h, W2l, 6);
- // SHA256_W[i] = s0 + s1 + SHA256_W[i - 7] + SHA256_W[i - 16];
- const SUMl = u64$1.add4L(s0l, s1l, SHA512_W_L[i - 7], SHA512_W_L[i - 16]);
- const SUMh = u64$1.add4H(SUMl, s0h, s1h, SHA512_W_H[i - 7], SHA512_W_H[i - 16]);
- SHA512_W_H[i] = SUMh | 0;
- SHA512_W_L[i] = SUMl | 0;
- }
- let { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this;
- // Compression function main loop, 80 rounds
- for (let i = 0; i < 80; i++) {
- // S1 := (e rightrotate 14) xor (e rightrotate 18) xor (e rightrotate 41)
- const sigma1h = u64$1.rotrSH(Eh, El, 14) ^ u64$1.rotrSH(Eh, El, 18) ^ u64$1.rotrBH(Eh, El, 41);
- const sigma1l = u64$1.rotrSL(Eh, El, 14) ^ u64$1.rotrSL(Eh, El, 18) ^ u64$1.rotrBL(Eh, El, 41);
- //const T1 = (H + sigma1 + Chi(E, F, G) + SHA256_K[i] + SHA256_W[i]) | 0;
- const CHIh = (Eh & Fh) ^ (~Eh & Gh);
- const CHIl = (El & Fl) ^ (~El & Gl);
- // T1 = H + sigma1 + Chi(E, F, G) + SHA512_K[i] + SHA512_W[i]
- // prettier-ignore
- const T1ll = u64$1.add5L(Hl, sigma1l, CHIl, SHA512_Kl[i], SHA512_W_L[i]);
- const T1h = u64$1.add5H(T1ll, Hh, sigma1h, CHIh, SHA512_Kh[i], SHA512_W_H[i]);
- const T1l = T1ll | 0;
- // S0 := (a rightrotate 28) xor (a rightrotate 34) xor (a rightrotate 39)
- const sigma0h = u64$1.rotrSH(Ah, Al, 28) ^ u64$1.rotrBH(Ah, Al, 34) ^ u64$1.rotrBH(Ah, Al, 39);
- const sigma0l = u64$1.rotrSL(Ah, Al, 28) ^ u64$1.rotrBL(Ah, Al, 34) ^ u64$1.rotrBL(Ah, Al, 39);
- const MAJh = (Ah & Bh) ^ (Ah & Ch) ^ (Bh & Ch);
- const MAJl = (Al & Bl) ^ (Al & Cl) ^ (Bl & Cl);
- Hh = Gh | 0;
- Hl = Gl | 0;
- Gh = Fh | 0;
- Gl = Fl | 0;
- Fh = Eh | 0;
- Fl = El | 0;
- ({ h: Eh, l: El } = u64$1.add(Dh | 0, Dl | 0, T1h | 0, T1l | 0));
- Dh = Ch | 0;
- Dl = Cl | 0;
- Ch = Bh | 0;
- Cl = Bl | 0;
- Bh = Ah | 0;
- Bl = Al | 0;
- const All = u64$1.add3L(T1l, sigma0l, MAJl);
- Ah = u64$1.add3H(All, T1h, sigma0h, MAJh);
- Al = All | 0;
- }
- // Add the compressed chunk to the current hash value
- ({ h: Ah, l: Al } = u64$1.add(this.Ah | 0, this.Al | 0, Ah | 0, Al | 0));
- ({ h: Bh, l: Bl } = u64$1.add(this.Bh | 0, this.Bl | 0, Bh | 0, Bl | 0));
- ({ h: Ch, l: Cl } = u64$1.add(this.Ch | 0, this.Cl | 0, Ch | 0, Cl | 0));
- ({ h: Dh, l: Dl } = u64$1.add(this.Dh | 0, this.Dl | 0, Dh | 0, Dl | 0));
- ({ h: Eh, l: El } = u64$1.add(this.Eh | 0, this.El | 0, Eh | 0, El | 0));
- ({ h: Fh, l: Fl } = u64$1.add(this.Fh | 0, this.Fl | 0, Fh | 0, Fl | 0));
- ({ h: Gh, l: Gl } = u64$1.add(this.Gh | 0, this.Gl | 0, Gh | 0, Gl | 0));
- ({ h: Hh, l: Hl } = u64$1.add(this.Hh | 0, this.Hl | 0, Hh | 0, Hl | 0));
- this.set(Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl);
- }
- roundClean() {
- SHA512_W_H.fill(0);
- SHA512_W_L.fill(0);
- }
- destroy() {
- this.buffer.fill(0);
- this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
- }
- }
- const sha512$1 = /* @__PURE__ */ wrapConstructor(() => new SHA512());
-
- // SHA3 (keccak) is based on a new design: basically, the internal state is bigger than output size.
- // It's called a sponge function.
- // Various per round constants calculations
- const [SHA3_PI, SHA3_ROTL, _SHA3_IOTA] = [[], [], []];
- const _0n = /* @__PURE__ */ BigInt(0);
- const _1n = /* @__PURE__ */ BigInt(1);
- const _2n = /* @__PURE__ */ BigInt(2);
- const _7n = /* @__PURE__ */ BigInt(7);
- const _256n = /* @__PURE__ */ BigInt(256);
- const _0x71n = /* @__PURE__ */ BigInt(0x71);
- for (let round = 0, R = _1n, x = 1, y = 0; round < 24; round++) {
- // Pi
- [x, y] = [y, (2 * x + 3 * y) % 5];
- SHA3_PI.push(2 * (5 * y + x));
- // Rotational
- SHA3_ROTL.push((((round + 1) * (round + 2)) / 2) % 64);
- // Iota
- let t = _0n;
- for (let j = 0; j < 7; j++) {
- R = ((R << _1n) ^ ((R >> _7n) * _0x71n)) % _256n;
- if (R & _2n)
- t ^= _1n << ((_1n << /* @__PURE__ */ BigInt(j)) - _1n);
- }
- _SHA3_IOTA.push(t);
- }
- const [SHA3_IOTA_H, SHA3_IOTA_L] = /* @__PURE__ */ split(_SHA3_IOTA, true);
- // Left rotation (without 0, 32, 64)
- const rotlH = (h, l, s) => (s > 32 ? rotlBH(h, l, s) : rotlSH(h, l, s));
- const rotlL = (h, l, s) => (s > 32 ? rotlBL(h, l, s) : rotlSL(h, l, s));
- // Same as keccakf1600, but allows to skip some rounds
- function keccakP(s, rounds = 24) {
- const B = new Uint32Array(5 * 2);
- // NOTE: all indices are x2 since we store state as u32 instead of u64 (bigints to slow in js)
- for (let round = 24 - rounds; round < 24; round++) {
- // Theta θ
- for (let x = 0; x < 10; x++)
- B[x] = s[x] ^ s[x + 10] ^ s[x + 20] ^ s[x + 30] ^ s[x + 40];
- for (let x = 0; x < 10; x += 2) {
- const idx1 = (x + 8) % 10;
- const idx0 = (x + 2) % 10;
- const B0 = B[idx0];
- const B1 = B[idx0 + 1];
- const Th = rotlH(B0, B1, 1) ^ B[idx1];
- const Tl = rotlL(B0, B1, 1) ^ B[idx1 + 1];
- for (let y = 0; y < 50; y += 10) {
- s[x + y] ^= Th;
- s[x + y + 1] ^= Tl;
- }
- }
- // Rho (ρ) and Pi (π)
- let curH = s[2];
- let curL = s[3];
- for (let t = 0; t < 24; t++) {
- const shift = SHA3_ROTL[t];
- const Th = rotlH(curH, curL, shift);
- const Tl = rotlL(curH, curL, shift);
- const PI = SHA3_PI[t];
- curH = s[PI];
- curL = s[PI + 1];
- s[PI] = Th;
- s[PI + 1] = Tl;
- }
- // Chi (χ)
- for (let y = 0; y < 50; y += 10) {
- for (let x = 0; x < 10; x++)
- B[x] = s[y + x];
- for (let x = 0; x < 10; x++)
- s[y + x] ^= ~B[(x + 2) % 10] & B[(x + 4) % 10];
- }
- // Iota (ι)
- s[0] ^= SHA3_IOTA_H[round];
- s[1] ^= SHA3_IOTA_L[round];
- }
- B.fill(0);
- }
- class Keccak extends Hash {
- // NOTE: we accept arguments in bytes instead of bits here.
- constructor(blockLen, suffix, outputLen, enableXOF = false, rounds = 24) {
- super();
- this.blockLen = blockLen;
- this.suffix = suffix;
- this.outputLen = outputLen;
- this.enableXOF = enableXOF;
- this.rounds = rounds;
- this.pos = 0;
- this.posOut = 0;
- this.finished = false;
- this.destroyed = false;
- // Can be passed from user as dkLen
- number(outputLen);
- // 1600 = 5x5 matrix of 64bit. 1600 bits === 200 bytes
- if (0 >= this.blockLen || this.blockLen >= 200)
- throw new Error('Sha3 supports only keccak-f1600 function');
- this.state = new Uint8Array(200);
- this.state32 = u32(this.state);
- }
- keccak() {
- keccakP(this.state32, this.rounds);
- this.posOut = 0;
- this.pos = 0;
- }
- update(data) {
- exists(this);
- const { blockLen, state } = this;
- data = toBytes(data);
- const len = data.length;
- for (let pos = 0; pos < len;) {
- const take = Math.min(blockLen - this.pos, len - pos);
- for (let i = 0; i < take; i++)
- state[this.pos++] ^= data[pos++];
- if (this.pos === blockLen)
- this.keccak();
- }
- return this;
- }
- finish() {
- if (this.finished)
- return;
- this.finished = true;
- const { state, suffix, pos, blockLen } = this;
- // Do the padding
- state[pos] ^= suffix;
- if ((suffix & 0x80) !== 0 && pos === blockLen - 1)
- this.keccak();
- state[blockLen - 1] ^= 0x80;
- this.keccak();
- }
- writeInto(out) {
- exists(this, false);
- bytes(out);
- this.finish();
- const bufferOut = this.state;
- const { blockLen } = this;
- for (let pos = 0, len = out.length; pos < len;) {
- if (this.posOut >= blockLen)
- this.keccak();
- const take = Math.min(blockLen - this.posOut, len - pos);
- out.set(bufferOut.subarray(this.posOut, this.posOut + take), pos);
- this.posOut += take;
- pos += take;
- }
- return out;
- }
- xofInto(out) {
- // Sha3/Keccak usage with XOF is probably mistake, only SHAKE instances can do XOF
- if (!this.enableXOF)
- throw new Error('XOF is not possible for this instance');
- return this.writeInto(out);
- }
- xof(bytes) {
- number(bytes);
- return this.xofInto(new Uint8Array(bytes));
- }
- digestInto(out) {
- output(out, this);
- if (this.finished)
- throw new Error('digest() was already called');
- this.writeInto(out);
- this.destroy();
- return out;
- }
- digest() {
- return this.digestInto(new Uint8Array(this.outputLen));
- }
- destroy() {
- this.destroyed = true;
- this.state.fill(0);
- }
- _cloneInto(to) {
- const { blockLen, suffix, outputLen, rounds, enableXOF } = this;
- to || (to = new Keccak(blockLen, suffix, outputLen, enableXOF, rounds));
- to.state32.set(this.state32);
- to.pos = this.pos;
- to.posOut = this.posOut;
- to.finished = this.finished;
- to.rounds = rounds;
- // Suffix can change in cSHAKE
- to.suffix = suffix;
- to.outputLen = outputLen;
- to.enableXOF = enableXOF;
- to.destroyed = this.destroyed;
- return to;
- }
- }
- const gen = (suffix, blockLen, outputLen) => wrapConstructor(() => new Keccak(blockLen, suffix, outputLen));
- /**
- * SHA3-256 hash function
- * @param message - that would be hashed
- */
- const sha3_256 = /* @__PURE__ */ gen(0x06, 136, 256 / 8);
- const sha3_512 = /* @__PURE__ */ gen(0x06, 72, 512 / 8);
- /**
- * keccak-256 hash function. Different from SHA3-256.
- * @param message - that would be hashed
- */
- const keccak_256 = /* @__PURE__ */ gen(0x01, 136, 256 / 8);
-
- /**
- * Some mathematic operations.
- *
- * @_subsection: api/utils:Math Helpers [about-maths]
- */
- const BN_0$9 = BigInt(0);
- const BN_1$5 = BigInt(1);
- //const BN_Max256 = (BN_1 << BigInt(256)) - BN_1;
- // IEEE 754 support 53-bits of mantissa
- const maxValue = 0x1fffffffffffff;
- /**
- * Convert %%value%% from a twos-compliment representation of %%width%%
- * bits to its value.
- *
- * If the highest bit is ``1``, the result will be negative.
- */
- function fromTwos(_value, _width) {
- const value = getUint(_value, "value");
- const width = BigInt(getNumber(_width, "width"));
- assert(value >> width === BN_0$9, "overflow", "NUMERIC_FAULT", {
- operation: "fromTwos",
- fault: "overflow",
- value: _value,
- });
- // Top bit set; treat as a negative value
- if (value >> (width - BN_1$5)) {
- const mask = (BN_1$5 << width) - BN_1$5;
- return -((~value & mask) + BN_1$5);
- }
- return value;
- }
- /**
- * Convert %%value%% to a twos-compliment representation of
- * %%width%% bits.
- *
- * The result will always be positive.
- */
- function toTwos(_value, _width) {
- let value = getBigInt(_value, "value");
- const width = BigInt(getNumber(_width, "width"));
- const limit = BN_1$5 << (width - BN_1$5);
- if (value < BN_0$9) {
- value = -value;
- assert(value <= limit, "too low", "NUMERIC_FAULT", {
- operation: "toTwos",
- fault: "overflow",
- value: _value,
- });
- const mask = (BN_1$5 << width) - BN_1$5;
- return (~value & mask) + BN_1$5;
- }
- else {
- assert(value < limit, "too high", "NUMERIC_FAULT", {
- operation: "toTwos",
- fault: "overflow",
- value: _value,
- });
- }
- return value;
- }
- /**
- * Mask %%value%% with a bitmask of %%bits%% ones.
- */
- function mask(_value, _bits) {
- const value = getUint(_value, "value");
- const bits = BigInt(getNumber(_bits, "bits"));
- return value & ((BN_1$5 << bits) - BN_1$5);
- }
- /**
- * Gets a BigInt from %%value%%. If it is an invalid value for
- * a BigInt, then an ArgumentError will be thrown for %%name%%.
- */
- function getBigInt(value, name) {
- switch (typeof value) {
- case "bigint":
- return value;
- case "number":
- assertArgument(Number.isInteger(value), "underflow", name || "value", value);
- assertArgument(value >= -maxValue && value <= maxValue, "overflow", name || "value", value);
- return BigInt(value);
- case "string":
- try {
- if (value === "") {
- throw new Error("empty string");
- }
- if (value[0] === "-" && value[1] !== "-") {
- return -BigInt(value.substring(1));
- }
- return BigInt(value);
- }
- catch (e) {
- assertArgument(false, `invalid BigNumberish string: ${e.message}`, name || "value", value);
- }
- }
- assertArgument(false, "invalid BigNumberish value", name || "value", value);
- }
- function getUint(value, name) {
- const result = getBigInt(value, name);
- assert(result >= BN_0$9, "unsigned value cannot be negative", "NUMERIC_FAULT", {
- fault: "overflow",
- operation: "getUint",
- value,
- });
- return result;
- }
- const Nibbles = "0123456789abcdef";
- /*
- * Converts %%value%% to a BigInt. If %%value%% is a Uint8Array, it
- * is treated as Big Endian data.
- */
- function toBigInt(value) {
- if (value instanceof Uint8Array) {
- let result = "0x0";
- for (const v of value) {
- result += Nibbles[v >> 4];
- result += Nibbles[v & 0x0f];
- }
- return BigInt(result);
- }
- return getBigInt(value);
- }
- /**
- * Gets a //number// from %%value%%. If it is an invalid value for
- * a //number//, then an ArgumentError will be thrown for %%name%%.
- */
- function getNumber(value, name) {
- switch (typeof value) {
- case "bigint":
- assertArgument(value >= -maxValue && value <= maxValue, "overflow", name || "value", value);
- return Number(value);
- case "number":
- assertArgument(Number.isInteger(value), "underflow", name || "value", value);
- assertArgument(value >= -maxValue && value <= maxValue, "overflow", name || "value", value);
- return value;
- case "string":
- try {
- if (value === "") {
- throw new Error("empty string");
- }
- return getNumber(BigInt(value), name);
- }
- catch (e) {
- assertArgument(false, `invalid numeric string: ${e.message}`, name || "value", value);
- }
- }
- assertArgument(false, "invalid numeric value", name || "value", value);
- }
- /**
- * Converts %%value%% to a number. If %%value%% is a Uint8Array, it
- * is treated as Big Endian data. Throws if the value is not safe.
- */
- function toNumber(value) {
- return getNumber(toBigInt(value));
- }
- /**
- * Converts %%value%% to a Big Endian hexstring, optionally padded to
- * %%width%% bytes.
- */
- function toBeHex(_value, _width) {
- const value = getUint(_value, "value");
- let result = value.toString(16);
- if (_width == null) {
- // Ensure the value is of even length
- if (result.length % 2) {
- result = "0" + result;
- }
- }
- else {
- const width = getNumber(_width, "width");
- assert(width * 2 >= result.length, `value exceeds width (${width} bits)`, "NUMERIC_FAULT", {
- operation: "toBeHex",
- fault: "overflow",
- value: _value,
- });
- // Pad the value to the required width
- while (result.length < width * 2) {
- result = "0" + result;
- }
- }
- return "0x" + result;
- }
- /**
- * Converts %%value%% to a Big Endian Uint8Array.
- */
- function toBeArray(_value) {
- const value = getUint(_value, "value");
- if (value === BN_0$9) {
- return new Uint8Array([]);
- }
- let hex = value.toString(16);
- if (hex.length % 2) {
- hex = "0" + hex;
- }
- const result = new Uint8Array(hex.length / 2);
- for (let i = 0; i < result.length; i++) {
- const offset = i * 2;
- result[i] = parseInt(hex.substring(offset, offset + 2), 16);
- }
- return result;
- }
- /**
- * Returns a [[HexString]] for %%value%% safe to use as a //Quantity//.
- *
- * A //Quantity// does not have and leading 0 values unless the value is
- * the literal value `0x0`. This is most commonly used for JSSON-RPC
- * numeric values.
- */
- function toQuantity(value) {
- let result = hexlify(isBytesLike(value) ? value : toBeArray(value)).substring(2);
- while (result.startsWith("0")) {
- result = result.substring(1);
- }
- if (result === "") {
- result = "0";
- }
- return "0x" + result;
- }
-
- /**
- * The [Base58 Encoding](link-base58) scheme allows a **numeric** value
- * to be encoded as a compact string using a radix of 58 using only
- * alpha-numeric characters. Confusingly similar characters are omitted
- * (i.e. ``"l0O"``).
- *
- * Note that Base58 encodes a **numeric** value, not arbitrary bytes,
- * since any zero-bytes on the left would get removed. To mitigate this
- * issue most schemes that use Base58 choose specific high-order values
- * to ensure non-zero prefixes.
- *
- * @_subsection: api/utils:Base58 Encoding [about-base58]
- */
- const Alphabet = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
- let Lookup = null;
- function getAlpha(letter) {
- if (Lookup == null) {
- Lookup = {};
- for (let i = 0; i < Alphabet.length; i++) {
- Lookup[Alphabet[i]] = BigInt(i);
- }
- }
- const result = Lookup[letter];
- assertArgument(result != null, `invalid base58 value`, "letter", letter);
- return result;
- }
- const BN_0$8 = BigInt(0);
- const BN_58 = BigInt(58);
- /**
- * Encode %%value%% as a Base58-encoded string.
- */
- function encodeBase58(_value) {
- let value = toBigInt(getBytes(_value));
- let result = "";
- while (value) {
- result = Alphabet[Number(value % BN_58)] + result;
- value /= BN_58;
- }
- return result;
- }
- /**
- * Decode the Base58-encoded %%value%%.
- */
- function decodeBase58(value) {
- let result = BN_0$8;
- for (let i = 0; i < value.length; i++) {
- result *= BN_58;
- result += getAlpha(value[i]);
- }
- return result;
- }
-
- // utils/base64-browser
- function decodeBase64(textData) {
- textData = atob(textData);
- const data = new Uint8Array(textData.length);
- for (let i = 0; i < textData.length; i++) {
- data[i] = textData.charCodeAt(i);
- }
- return getBytes(data);
- }
- function encodeBase64(_data) {
- const data = getBytes(_data);
- let textData = "";
- for (let i = 0; i < data.length; i++) {
- textData += String.fromCharCode(data[i]);
- }
- return btoa(textData);
- }
-
- /**
- * Explain events...
- *
- * @_section api/utils/events:Events [about-events]
- */
- /**
- * When an [[EventEmitterable]] triggers a [[Listener]], the
- * callback always ahas one additional argument passed, which is
- * an **EventPayload**.
- */
- class EventPayload {
- /**
- * The event filter.
- */
- filter;
- /**
- * The **EventEmitterable**.
- */
- emitter;
- #listener;
- /**
- * Create a new **EventPayload** for %%emitter%% with
- * the %%listener%% and for %%filter%%.
- */
- constructor(emitter, listener, filter) {
- this.#listener = listener;
- defineProperties(this, { emitter, filter });
- }
- /**
- * Unregister the triggered listener for future events.
- */
- async removeListener() {
- if (this.#listener == null) {
- return;
- }
- await this.emitter.off(this.filter, this.#listener);
- }
- }
-
- /**
- * Using strings in Core (or any security-basd system) requires
- * additional care. These utilities attempt to mitigate some of the
- * safety issues as well as provide the ability to recover and analyse
- * strings.
- *
- * @_subsection api/utils:Strings and UTF-8 [about-strings]
- */
- function errorFunc(reason, offset, bytes, output, badCodepoint) {
- assertArgument(false, `invalid codepoint at offset ${offset}; ${reason}`, "bytes", bytes);
- }
- function ignoreFunc(reason, offset, bytes, output, badCodepoint) {
- // If there is an invalid prefix (including stray continuation), skip any additional continuation bytes
- if (reason === "BAD_PREFIX" || reason === "UNEXPECTED_CONTINUE") {
- let i = 0;
- for (let o = offset + 1; o < bytes.length; o++) {
- if (bytes[o] >> 6 !== 0x02) {
- break;
- }
- i++;
- }
- return i;
- }
- // This byte runs us past the end of the string, so just jump to the end
- // (but the first byte was read already read and therefore skipped)
- if (reason === "OVERRUN") {
- return bytes.length - offset - 1;
- }
- // Nothing to skip
- return 0;
- }
- function replaceFunc(reason, offset, bytes, output, badCodepoint) {
- // Overlong representations are otherwise "valid" code points; just non-deistingtished
- if (reason === "OVERLONG") {
- assertArgument(typeof badCodepoint === "number", "invalid bad code point for replacement", "badCodepoint", badCodepoint);
- output.push(badCodepoint);
- return 0;
- }
- // Put the replacement character into the output
- output.push(0xfffd);
- // Otherwise, process as if ignoring errors
- return ignoreFunc(reason, offset, bytes);
- }
- /**
- * A handful of popular, built-in UTF-8 error handling strategies.
- *
- * **``"error"``** - throws on ANY illegal UTF-8 sequence or
- * non-canonical (overlong) codepoints (this is the default)
- *
- * **``"ignore"``** - silently drops any illegal UTF-8 sequence
- * and accepts non-canonical (overlong) codepoints
- *
- * **``"replace"``** - replace any illegal UTF-8 sequence with the
- * UTF-8 replacement character (i.e. ``"\\ufffd"``) and accepts
- * non-canonical (overlong) codepoints
- *
- * @returns: Record<"error" | "ignore" | "replace", Utf8ErrorFunc>
- */
- const Utf8ErrorFuncs = Object.freeze({
- error: errorFunc,
- ignore: ignoreFunc,
- replace: replaceFunc,
- });
- // http://stackoverflow.com/questions/13356493/decode-utf-8-with-javascript#13691499
- function getUtf8CodePoints(_bytes, onError) {
- if (onError == null) {
- onError = Utf8ErrorFuncs.error;
- }
- const bytes = getBytes(_bytes, "bytes");
- const result = [];
- let i = 0;
- // Invalid bytes are ignored
- while (i < bytes.length) {
- const c = bytes[i++];
- // 0xxx xxxx
- if (c >> 7 === 0) {
- result.push(c);
- continue;
- }
- // Multibyte; how many bytes left for this character?
- let extraLength = null;
- let overlongMask = null;
- // 110x xxxx 10xx xxxx
- if ((c & 0xe0) === 0xc0) {
- extraLength = 1;
- overlongMask = 0x7f;
- // 1110 xxxx 10xx xxxx 10xx xxxx
- }
- else if ((c & 0xf0) === 0xe0) {
- extraLength = 2;
- overlongMask = 0x7ff;
- // 1111 0xxx 10xx xxxx 10xx xxxx 10xx xxxx
- }
- else if ((c & 0xf8) === 0xf0) {
- extraLength = 3;
- overlongMask = 0xffff;
- }
- else {
- if ((c & 0xc0) === 0x80) {
- i += onError("UNEXPECTED_CONTINUE", i - 1, bytes, result);
- }
- else {
- i += onError("BAD_PREFIX", i - 1, bytes, result);
- }
- continue;
- }
- // Do we have enough bytes in our data?
- if (i - 1 + extraLength >= bytes.length) {
- i += onError("OVERRUN", i - 1, bytes, result);
- continue;
- }
- // Remove the length prefix from the char
- let res = c & ((1 << (8 - extraLength - 1)) - 1);
- for (let j = 0; j < extraLength; j++) {
- let nextChar = bytes[i];
- // Invalid continuation byte
- if ((nextChar & 0xc0) != 0x80) {
- i += onError("MISSING_CONTINUE", i, bytes, result);
- res = null;
- break;
- }
- res = (res << 6) | (nextChar & 0x3f);
- i++;
- }
- // See above loop for invalid continuation byte
- if (res === null) {
- continue;
- }
- // Maximum code point
- if (res > 0x10ffff) {
- i += onError("OUT_OF_RANGE", i - 1 - extraLength, bytes, result, res);
- continue;
- }
- // Reserved for UTF-16 surrogate halves
- if (res >= 0xd800 && res <= 0xdfff) {
- i += onError("UTF16_SURROGATE", i - 1 - extraLength, bytes, result, res);
- continue;
- }
- // Check for overlong sequences (more bytes than needed)
- if (res <= overlongMask) {
- i += onError("OVERLONG", i - 1 - extraLength, bytes, result, res);
- continue;
- }
- result.push(res);
- }
- return result;
- }
- // http://stackoverflow.com/questions/18729405/how-to-convert-utf8-string-to-byte-array
- /**
- * Returns the UTF-8 byte representation of %%str%%.
- *
- * If %%form%% is specified, the string is normalized.
- */
- function toUtf8Bytes(str, form) {
- if (form != null) {
- assertNormalize(form);
- str = str.normalize(form);
- }
- let result = [];
- for (let i = 0; i < str.length; i++) {
- const c = str.charCodeAt(i);
- if (c < 0x80) {
- result.push(c);
- }
- else if (c < 0x800) {
- result.push((c >> 6) | 0xc0);
- result.push((c & 0x3f) | 0x80);
- }
- else if ((c & 0xfc00) == 0xd800) {
- i++;
- const c2 = str.charCodeAt(i);
- assertArgument(i < str.length && (c2 & 0xfc00) === 0xdc00, "invalid surrogate pair", "str", str);
- // Surrogate Pair
- const pair = 0x10000 + ((c & 0x03ff) << 10) + (c2 & 0x03ff);
- result.push((pair >> 18) | 0xf0);
- result.push(((pair >> 12) & 0x3f) | 0x80);
- result.push(((pair >> 6) & 0x3f) | 0x80);
- result.push((pair & 0x3f) | 0x80);
- }
- else {
- result.push((c >> 12) | 0xe0);
- result.push(((c >> 6) & 0x3f) | 0x80);
- result.push((c & 0x3f) | 0x80);
- }
- }
- return new Uint8Array(result);
- }
- //export
- function _toUtf8String(codePoints) {
- return codePoints
- .map((codePoint) => {
- if (codePoint <= 0xffff) {
- return String.fromCharCode(codePoint);
- }
- codePoint -= 0x10000;
- return String.fromCharCode(((codePoint >> 10) & 0x3ff) + 0xd800, (codePoint & 0x3ff) + 0xdc00);
- })
- .join("");
- }
- /**
- * Returns the string represented by the UTF-8 data %%bytes%%.
- *
- * When %%onError%% function is specified, it is called on UTF-8
- * errors allowing recovery using the [[Utf8ErrorFunc]] API.
- * (default: [error](Utf8ErrorFuncs))
- */
- function toUtf8String(bytes, onError) {
- return _toUtf8String(getUtf8CodePoints(bytes, onError));
- }
- /**
- * Returns the UTF-8 code-points for %%str%%.
- *
- * If %%form%% is specified, the string is normalized.
- */
- function toUtf8CodePoints(str, form) {
- return getUtf8CodePoints(toUtf8Bytes(str, form));
- }
-
- // @TODO: timeout is completely ignored; start a Promise.any with a reject?
- // @ts-ignore
- async function getUrl(req, _signal) {
- const protocol = req.url.split(":")[0].toLowerCase();
- assert(protocol === "http" || protocol === "https", `unsupported protocol ${protocol}`, "UNSUPPORTED_OPERATION", {
- info: { protocol },
- operation: "request",
- });
- assert(protocol === "https" || !req.credentials || req.allowInsecureAuthentication, "insecure authorized connections unsupported", "UNSUPPORTED_OPERATION", {
- operation: "request",
- });
- let signal = undefined;
- if (_signal) {
- const controller = new AbortController();
- signal = controller.signal;
- _signal.addListener(() => {
- controller.abort();
- });
- }
- const init = {
- method: req.method,
- headers: new Headers(Array.from(req)),
- body: req.body || undefined,
- signal,
- };
- try {
- const resp = await fetch(req.url, init);
- const headers = {};
- resp.headers.forEach((value, key) => {
- headers[key.toLowerCase()] = value;
- });
- const respBody = await resp.arrayBuffer();
- const body = respBody == null ? null : new Uint8Array(respBody);
- return {
- statusCode: resp.status,
- statusMessage: resp.statusText,
- headers,
- body,
- };
- }
- catch (error) {
- console.log({ error });
- return undefined;
- }
- }
-
- /**
- * Explain fetching here...
- *
- * @_section api/utils/fetching:Fetching Web Content [about-fetch]
- */
- const MAX_ATTEMPTS = 12;
- const SLOT_INTERVAL = 250;
- // The global FetchGetUrlFunc implementation.
- let getUrlFunc = getUrl;
- const reData = new RegExp("^data:([^;:]*)?(;base64)?,(.*)$", "i");
- const reIpfs = new RegExp("^ipfs://(ipfs/)?(.*)$", "i");
- // If locked, new Gateways cannot be added
- let locked$5 = false;
- // https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URLs
- async function dataGatewayFunc(url, signal) {
- try {
- const match = url.match(reData);
- if (!match) {
- throw new Error("invalid data");
- }
- return new FetchResponse(200, "OK", {
- "content-type": match[1] || "text/plain",
- }, match[2] ? decodeBase64(match[3]) : unpercent(match[3]));
- }
- catch (error) {
- return new FetchResponse(599, "BAD REQUEST (invalid data: URI)", {}, null, new FetchRequest(url));
- }
- }
- /**
- * Returns a [[FetchGatewayFunc]] for fetching content from a standard
- * IPFS gateway hosted at %%baseUrl%%.
- */
- function getIpfsGatewayFunc(baseUrl) {
- async function gatewayIpfs(url, signal) {
- try {
- const match = url.match(reIpfs);
- if (!match) {
- throw new Error("invalid link");
- }
- return new FetchRequest(`${baseUrl}${match[2]}`);
- }
- catch (error) {
- return new FetchResponse(599, "BAD REQUEST (invalid IPFS URI)", {}, null, new FetchRequest(url));
- }
- }
- return gatewayIpfs;
- }
- const Gateways = {
- data: dataGatewayFunc,
- ipfs: getIpfsGatewayFunc("https://gateway.ipfs.io/ipfs/"),
- };
- const fetchSignals = new WeakMap();
- /**
- * @_ignore
- */
- class FetchCancelSignal {
- #listeners;
- #cancelled;
- constructor(request) {
- this.#listeners = [];
- this.#cancelled = false;
- fetchSignals.set(request, () => {
- if (this.#cancelled) {
- return;
- }
- this.#cancelled = true;
- for (const listener of this.#listeners) {
- setTimeout(() => {
- listener();
- }, 0);
- }
- this.#listeners = [];
- });
- }
- addListener(listener) {
- assert(!this.#cancelled, "singal already cancelled", "UNSUPPORTED_OPERATION", {
- operation: "fetchCancelSignal.addCancelListener",
- });
- this.#listeners.push(listener);
- }
- get cancelled() {
- return this.#cancelled;
- }
- checkSignal() {
- assert(!this.cancelled, "cancelled", "CANCELLED", {});
- }
- }
- // Check the signal, throwing if it is cancelled
- function checkSignal(signal) {
- if (signal == null) {
- throw new Error("missing signal; should not happen");
- }
- signal.checkSignal();
- return signal;
- }
- /**
- * Represents a request for a resource using a URI.
- *
- * By default, the supported schemes are ``HTTP``, ``HTTPS``, ``data:``,
- * and ``IPFS:``.
- *
- * Additional schemes can be added globally using [[registerGateway]].
- *
- * @example:
- * req = new FetchRequest("https://www.ricmoo.com")
- * resp = await req.send()
- * resp.body.length
- * //_result:
- */
- class FetchRequest {
- #allowInsecure;
- #gzip;
- #headers;
- #method;
- #timeout;
- #url;
- #body;
- #bodyType;
- #creds;
- // Hooks
- #preflight;
- #process;
- #retry;
- #signal;
- #throttle;
- /**
- * The fetch URI to requrest.
- */
- get url() {
- return this.#url;
- }
- set url(url) {
- this.#url = String(url);
- }
- /**
- * The fetch body, if any, to send as the request body. //(default: null)//
- *
- * When setting a body, the intrinsic ``Content-Type`` is automatically
- * set and will be used if **not overridden** by setting a custom
- * header.
- *
- * If %%body%% is null, the body is cleared (along with the
- * intrinsic ``Content-Type``) and the .
- *
- * If %%body%% is a string, the intrincis ``Content-Type`` is set to
- * ``text/plain``.
- *
- * If %%body%% is a Uint8Array, the intrincis ``Content-Type`` is set to
- * ``application/octet-stream``.
- *
- * If %%body%% is any other object, the intrincis ``Content-Type`` is
- * set to ``application/json``.
- */
- get body() {
- if (this.#body == null) {
- return null;
- }
- return new Uint8Array(this.#body);
- }
- set body(body) {
- if (body == null) {
- this.#body = undefined;
- this.#bodyType = undefined;
- }
- else if (typeof body === "string") {
- this.#body = toUtf8Bytes(body);
- this.#bodyType = "text/plain";
- }
- else if (body instanceof Uint8Array) {
- this.#body = body;
- this.#bodyType = "application/octet-stream";
- }
- else if (typeof body === "object") {
- this.#body = toUtf8Bytes(JSON.stringify(body));
- this.#bodyType = "application/json";
- }
- else {
- throw new Error("invalid body");
- }
- }
- /**
- * Returns true if the request has a body.
- */
- hasBody() {
- return this.#body != null;
- }
- /**
- * The HTTP method to use when requesting the URI. If no method
- * has been explicitly set, then ``GET`` is used if the body is
- * null and ``POST`` otherwise.
- */
- get method() {
- if (this.#method) {
- return this.#method;
- }
- if (this.hasBody()) {
- return "POST";
- }
- return "GET";
- }
- set method(method) {
- if (method == null) {
- method = "";
- }
- this.#method = String(method).toUpperCase();
- }
- /**
- * The headers that will be used when requesting the URI. All
- * keys are lower-case.
- *
- * This object is a copy, so any chnages will **NOT** be reflected
- * in the ``FetchRequest``.
- *
- * To set a header entry, use the ``setHeader`` method.
- */
- get headers() {
- const headers = Object.assign({}, this.#headers);
- if (this.#creds) {
- headers["authorization"] = `Basic ${encodeBase64(toUtf8Bytes(this.#creds))}`;
- }
- if (this.allowGzip) {
- headers["accept-encoding"] = "gzip";
- }
- if (headers["content-type"] == null && this.#bodyType) {
- headers["content-type"] = this.#bodyType;
- }
- if (this.body) {
- headers["content-length"] = String(this.body.length);
- }
- return headers;
- }
- /**
- * Get the header for %%key%%, ignoring case.
- */
- getHeader(key) {
- return this.headers[key.toLowerCase()];
- }
- /**
- * Set the header for %%key%% to %%value%%. All values are coerced
- * to a string.
- */
- setHeader(key, value) {
- this.#headers[String(key).toLowerCase()] = String(value);
- }
- /**
- * Clear all headers, resetting all intrinsic headers.
- */
- clearHeaders() {
- this.#headers = {};
- }
- [Symbol.iterator]() {
- const headers = this.headers;
- const keys = Object.keys(headers);
- let index = 0;
- return {
- next: () => {
- if (index < keys.length) {
- const key = keys[index++];
- return {
- value: [key, headers[key]],
- done: false,
- };
- }
- return { value: undefined, done: true };
- },
- };
- }
- /**
- * The value that will be sent for the ``Authorization`` header.
- *
- * To set the credentials, use the ``setCredentials`` method.
- */
- get credentials() {
- return this.#creds || null;
- }
- /**
- * Sets an ``Authorization`` for %%username%% with %%password%%.
- */
- setCredentials(username, password) {
- assertArgument(!username.match(/:/), "invalid basic authentication username", "username", "[REDACTED]");
- this.#creds = `${username}:${password}`;
- }
- /**
- * Enable and request gzip-encoded responses. The response will
- * automatically be decompressed. //(default: true)//
- */
- get allowGzip() {
- return this.#gzip;
- }
- set allowGzip(value) {
- this.#gzip = !!value;
- }
- /**
- * Allow ``Authentication`` credentials to be sent over insecure
- * channels. //(default: false)//
- */
- get allowInsecureAuthentication() {
- return !!this.#allowInsecure;
- }
- set allowInsecureAuthentication(value) {
- this.#allowInsecure = !!value;
- }
- /**
- * The timeout (in milliseconds) to wait for a complere response.
- * //(default: 5 minutes)//
- */
- get timeout() {
- return this.#timeout;
- }
- set timeout(timeout) {
- assertArgument(timeout >= 0, "timeout must be non-zero", "timeout", timeout);
- this.#timeout = timeout;
- }
- /**
- * This function is called prior to each request, for example
- * during a redirection or retry in case of server throttling.
- *
- * This offers an opportunity to populate headers or update
- * content before sending a request.
- */
- get preflightFunc() {
- return this.#preflight || null;
- }
- set preflightFunc(preflight) {
- this.#preflight = preflight;
- }
- /**
- * This function is called after each response, offering an
- * opportunity to provide client-level throttling or updating
- * response data.
- *
- * Any error thrown in this causes the ``send()`` to throw.
- *
- * To schedule a retry attempt (assuming the maximum retry limit
- * has not been reached), use [[response.throwThrottleError]].
- */
- get processFunc() {
- return this.#process || null;
- }
- set processFunc(process) {
- this.#process = process;
- }
- /**
- * This function is called on each retry attempt.
- */
- get retryFunc() {
- return this.#retry || null;
- }
- set retryFunc(retry) {
- this.#retry = retry;
- }
- /**
- * Create a new FetchRequest instance with default values.
- *
- * Once created, each property may be set before issuing a
- * ``.send()`` to make the request.
- */
- constructor(url) {
- this.#url = String(url);
- this.#allowInsecure = false;
- this.#gzip = true;
- this.#headers = {};
- this.#method = "";
- this.#timeout = 300000;
- this.#throttle = {
- slotInterval: SLOT_INTERVAL,
- maxAttempts: MAX_ATTEMPTS,
- };
- }
- toString() {
- return ``;
- }
- /**
- * Update the throttle parameters used to determine maximum
- * attempts and exponential-backoff properties.
- */
- setThrottleParams(params) {
- if (params.slotInterval != null) {
- this.#throttle.slotInterval = params.slotInterval;
- }
- if (params.maxAttempts != null) {
- this.#throttle.maxAttempts = params.maxAttempts;
- }
- }
- async #send(attempt, expires, delay, _request, _response) {
- if (attempt >= this.#throttle.maxAttempts) {
- return _response.makeServerError("exceeded maximum retry limit");
- }
- assert(getTime$2() <= expires, "timeout", "TIMEOUT", {
- operation: "request.send",
- reason: "timeout",
- request: _request,
- });
- if (delay > 0) {
- await wait(delay);
- }
- let req = this.clone();
- const scheme = (req.url.split(":")[0] || "").toLowerCase();
- // Process any Gateways
- if (scheme in Gateways) {
- const result = await Gateways[scheme](req.url, checkSignal(_request.#signal));
- if (result instanceof FetchResponse) {
- let response = result;
- if (this.processFunc) {
- checkSignal(_request.#signal);
- try {
- response = await this.processFunc(req, response);
- }
- catch (error) {
- // Something went wrong during processing; throw a 5xx server error
- if (error.throttle == null || typeof error.stall !== "number") {
- response
- .makeServerError("error in post-processing function", error)
- .assertOk();
- }
- // Ignore throttling
- }
- }
- return response;
- }
- req = result;
- }
- // We have a preflight function; update the request
- if (this.preflightFunc) {
- req = await this.preflightFunc(req);
- }
- const resp = await getUrlFunc(req, checkSignal(_request.#signal));
- let response = new FetchResponse(resp.statusCode, resp.statusMessage, resp.headers, resp.body, _request);
- if (response.statusCode === 301 || response.statusCode === 302) {
- // Redirect
- try {
- const location = response.headers.location || "";
- return req
- .redirect(location)
- .#send(attempt + 1, expires, 0, _request, response);
- }
- catch (error) { }
- // Things won't get any better on another attempt; abort
- return response;
- }
- else if (response.statusCode === 429) {
- // Throttle
- if (this.retryFunc == null ||
- (await this.retryFunc(req, response, attempt))) {
- const retryAfter = response.headers["retry-after"];
- let delay = this.#throttle.slotInterval *
- Math.trunc(Math.random() * Math.pow(2, attempt));
- if (typeof retryAfter === "string" &&
- retryAfter.match(/^[1-9][0-9]*$/)) {
- delay = parseInt(retryAfter);
- }
- return req
- .clone()
- .#send(attempt + 1, expires, delay, _request, response);
- }
- }
- if (this.processFunc) {
- checkSignal(_request.#signal);
- try {
- response = await this.processFunc(req, response);
- }
- catch (error) {
- // Something went wrong during processing; throw a 5xx server error
- if (error.throttle == null || typeof error.stall !== "number") {
- response
- .makeServerError("error in post-processing function", error)
- .assertOk();
- }
- // Throttle
- let delay = this.#throttle.slotInterval *
- Math.trunc(Math.random() * Math.pow(2, attempt));
- if (error.stall >= 0) {
- delay = error.stall;
- }
- return req
- .clone()
- .#send(attempt + 1, expires, delay, _request, response);
- }
- }
- return response;
- }
- /**
- * Resolves to the response by sending the request.
- */
- send() {
- assert(this.#signal == null, "request already sent", "UNSUPPORTED_OPERATION", { operation: "fetchRequest.send" });
- this.#signal = new FetchCancelSignal(this);
- return this.#send(0, getTime$2() + this.timeout, 0, this, new FetchResponse(0, "", {}, null, this));
- }
- /**
- * Cancels the inflight response, causing a ``CANCELLED``
- * error to be rejected from the [[send]].
- */
- cancel() {
- assert(this.#signal != null, "request has not been sent", "UNSUPPORTED_OPERATION", { operation: "fetchRequest.cancel" });
- const signal = fetchSignals.get(this);
- if (!signal) {
- throw new Error("missing signal; should not happen");
- }
- signal();
- }
- /**
- * Returns a new [[FetchRequest]] that represents the redirection
- * to %%location%%.
- */
- redirect(location) {
- // Redirection; for now we only support absolute locataions
- const current = this.url.split(":")[0].toLowerCase();
- const target = location.split(":")[0].toLowerCase();
- // Don't allow redirecting:
- // - non-GET requests
- // - downgrading the security (e.g. https => http)
- // - to non-HTTP (or non-HTTPS) protocols [this could be relaxed?]
- assert(this.method === "GET" &&
- (current !== "https" || target !== "http") &&
- location.match(/^https?:/), `unsupported redirect`, "UNSUPPORTED_OPERATION", {
- operation: `redirect(${this.method} ${JSON.stringify(this.url)} => ${JSON.stringify(location)})`,
- });
- // Create a copy of this request, with a new URL
- const req = new FetchRequest(location);
- req.method = "GET";
- req.allowGzip = this.allowGzip;
- req.timeout = this.timeout;
- req.#headers = Object.assign({}, this.#headers);
- if (this.#body) {
- req.#body = new Uint8Array(this.#body);
- }
- req.#bodyType = this.#bodyType;
- // Do not forward credentials unless on the same domain; only absolute
- //req.allowInsecure = false;
- // paths are currently supported; may want a way to specify to forward?
- //setStore(req.#props, "creds", getStore(this.#pros, "creds"));
- return req;
- }
- /**
- * Create a new copy of this request.
- */
- clone() {
- const clone = new FetchRequest(this.url);
- // Preserve "default method" (i.e. null)
- clone.#method = this.#method;
- // Preserve "default body" with type, copying the Uint8Array is present
- if (this.#body) {
- clone.#body = this.#body;
- }
- clone.#bodyType = this.#bodyType;
- // Preserve "default headers"
- clone.#headers = Object.assign({}, this.#headers);
- // Credentials is readonly, so we copy internally
- clone.#creds = this.#creds;
- if (this.allowGzip) {
- clone.allowGzip = true;
- }
- clone.timeout = this.timeout;
- if (this.allowInsecureAuthentication) {
- clone.allowInsecureAuthentication = true;
- }
- clone.#preflight = this.#preflight;
- clone.#process = this.#process;
- clone.#retry = this.#retry;
- return clone;
- }
- /**
- * Locks all static configuration for gateways and FetchGetUrlFunc
- * registration.
- */
- static lockConfig() {
- locked$5 = true;
- }
- /**
- * Get the current Gateway function for %%scheme%%.
- */
- static getGateway(scheme) {
- return Gateways[scheme.toLowerCase()] || null;
- }
- /**
- * Use the %%func%% when fetching URIs using %%scheme%%.
- *
- * This method affects all requests globally.
- *
- * If [[lockConfig]] has been called, no change is made and this
- * throws.
- */
- static registerGateway(scheme, func) {
- scheme = scheme.toLowerCase();
- if (scheme === "http" || scheme === "https") {
- throw new Error(`cannot intercept ${scheme}; use registerGetUrl`);
- }
- if (locked$5) {
- throw new Error("gateways locked");
- }
- Gateways[scheme] = func;
- }
- /**
- * Use %%getUrl%% when fetching URIs over HTTP and HTTPS requests.
- *
- * This method affects all requests globally.
- *
- * If [[lockConfig]] has been called, no change is made and this
- * throws.
- */
- static registerGetUrl(getUrl) {
- if (locked$5) {
- throw new Error("gateways locked");
- }
- getUrlFunc = getUrl;
- }
- /**
- * Creates a function that can "fetch" data URIs.
- *
- * Note that this is automatically done internally to support
- * data URIs, so it is not necessary to register it.
- *
- * This is not generally something that is needed, but may
- * be useful in a wrapper to perfom custom data URI functionality.
- */
- static createDataGateway() {
- return dataGatewayFunc;
- }
- /**
- * Creates a function that will fetch IPFS (unvalidated) from
- * a custom gateway baseUrl.
- *
- * The default IPFS gateway used internally is
- * ``"https:/\/gateway.ipfs.io/ipfs/"``.
- */
- static createIpfsGatewayFunc(baseUrl) {
- return getIpfsGatewayFunc(baseUrl);
- }
- }
- /**
- * The response for a FetchREquest.
- */
- class FetchResponse {
- #statusCode;
- #statusMessage;
- #headers;
- #body;
- #request;
- #error;
- toString() {
- return ``;
- }
- /**
- * The response status code.
- */
- get statusCode() {
- return this.#statusCode;
- }
- /**
- * The response status message.
- */
- get statusMessage() {
- return this.#statusMessage;
- }
- /**
- * The response headers. All keys are lower-case.
- */
- get headers() {
- return Object.assign({}, this.#headers);
- }
- /**
- * The response body, or ``null`` if there was no body.
- */
- get body() {
- return this.#body == null ? null : new Uint8Array(this.#body);
- }
- /**
- * The response body as a UTF-8 encoded string, or the empty
- * string (i.e. ``""``) if there was no body.
- *
- * An error is thrown if the body is invalid UTF-8 data.
- */
- get bodyText() {
- try {
- return this.#body == null ? "" : toUtf8String(this.#body);
- }
- catch (error) {
- assert(false, "response body is not valid UTF-8 data", "UNSUPPORTED_OPERATION", {
- operation: "bodyText",
- info: { response: this },
- });
- }
- }
- /**
- * The response body, decoded as JSON.
- *
- * An error is thrown if the body is invalid JSON-encoded data
- * or if there was no body.
- */
- get bodyJson() {
- try {
- return JSON.parse(this.bodyText);
- }
- catch (error) {
- assert(false, "response body is not valid JSON", "UNSUPPORTED_OPERATION", {
- operation: "bodyJson",
- info: { response: this },
- });
- }
- }
- [Symbol.iterator]() {
- const headers = this.headers;
- const keys = Object.keys(headers);
- let index = 0;
- return {
- next: () => {
- if (index < keys.length) {
- const key = keys[index++];
- return {
- value: [key, headers[key]],
- done: false,
- };
- }
- return { value: undefined, done: true };
- },
- };
- }
- constructor(statusCode, statusMessage, headers, body, request) {
- this.#statusCode = statusCode;
- this.#statusMessage = statusMessage;
- this.#headers = Object.keys(headers).reduce((accum, k) => {
- accum[k.toLowerCase()] = String(headers[k]);
- return accum;
- }, {});
- this.#body = body == null ? null : new Uint8Array(body);
- this.#request = request || null;
- this.#error = { message: "" };
- }
- /**
- * Return a Response with matching headers and body, but with
- * an error status code (i.e. 599) and %%message%% with an
- * optional %%error%%.
- */
- makeServerError(message, error) {
- let statusMessage;
- if (!message) {
- message = `${this.statusCode} ${this.statusMessage}`;
- statusMessage = `CLIENT ESCALATED SERVER ERROR (${message})`;
- }
- else {
- statusMessage = `CLIENT ESCALATED SERVER ERROR (${this.statusCode} ${this.statusMessage}; ${message})`;
- }
- const response = new FetchResponse(599, statusMessage, this.headers, this.body, this.#request || undefined);
- response.#error = { message, error };
- return response;
- }
- /**
- * If called within a [request.processFunc](FetchRequest-processFunc)
- * call, causes the request to retry as if throttled for %%stall%%
- * milliseconds.
- */
- throwThrottleError(message, stall) {
- if (stall == null) {
- stall = -1;
- }
- else {
- assertArgument(Number.isInteger(stall) && stall >= 0, "invalid stall timeout", "stall", stall);
- }
- const error = new Error(message || "throttling requests");
- defineProperties(error, { stall, throttle: true });
- throw error;
- }
- /**
- * Get the header value for %%key%%, ignoring case.
- */
- getHeader(key) {
- return this.headers[key.toLowerCase()];
- }
- /**
- * Returns true of the response has a body.
- */
- hasBody() {
- return this.#body != null;
- }
- /**
- * The request made for this response.
- */
- get request() {
- return this.#request;
- }
- /**
- * Returns true if this response was a success statusCode.
- */
- ok() {
- return (this.#error.message === "" &&
- this.statusCode >= 200 &&
- this.statusCode < 300);
- }
- /**
- * Throws a ``SERVER_ERROR`` if this response is not ok.
- */
- assertOk() {
- if (this.ok()) {
- return;
- }
- let { message, error } = this.#error;
- if (message === "") {
- message = `server response ${this.statusCode} ${this.statusMessage}`;
- }
- assert(false, message, "SERVER_ERROR", {
- request: this.request || "unknown request",
- response: this,
- error,
- });
- }
- }
- function getTime$2() {
- return new Date().getTime();
- }
- function unpercent(value) {
- return toUtf8Bytes(value.replace(/%([0-9a-f][0-9a-f])/gi, (all, code) => {
- return String.fromCharCode(parseInt(code, 16));
- }));
- }
- function wait(delay) {
- return new Promise((resolve) => setTimeout(resolve, delay));
- }
-
- var _a$1;
- const BN_N1 = BigInt(-1);
- const BN_0$7 = BigInt(0);
- const BN_1$4 = BigInt(1);
- const BN_5 = BigInt(5);
- const _guard$5 = {};
- // Constant to pull zeros from for multipliers
- let Zeros = "0000";
- while (Zeros.length < 80) {
- Zeros += Zeros;
- }
- // Returns a string "1" followed by decimal "0"s
- function getTens(decimals) {
- let result = Zeros;
- while (result.length < decimals) {
- result += result;
- }
- return BigInt("1" + result.substring(0, decimals));
- }
- function checkValue(val, format, safeOp) {
- const width = BigInt(format.width);
- if (format.signed) {
- const limit = BN_1$4 << (width - BN_1$4);
- assert(safeOp == null || (val >= -limit && val < limit), "overflow", "NUMERIC_FAULT", {
- operation: safeOp,
- fault: "overflow",
- value: val,
- });
- if (val > BN_0$7) {
- val = fromTwos(mask(val, width), width);
- }
- else {
- val = -fromTwos(mask(-val, width), width);
- }
- }
- else {
- const limit = BN_1$4 << width;
- assert(safeOp == null || (val >= 0 && val < limit), "overflow", "NUMERIC_FAULT", {
- operation: safeOp,
- fault: "overflow",
- value: val,
- });
- val = ((val % limit) + limit) % limit & (limit - BN_1$4);
- }
- return val;
- }
- function getFormat(value) {
- if (typeof value === "number") {
- value = `fixed128x${value}`;
- }
- let signed = true;
- let width = 128;
- let decimals = 18;
- if (typeof value === "string") {
- // Parse the format string
- if (value === "fixed") ;
- else if (value === "ufixed") {
- signed = false;
- }
- else {
- const match = value.match(/^(u?)fixed([0-9]+)x([0-9]+)$/);
- assertArgument(match, "invalid fixed format", "format", value);
- signed = match[1] !== "u";
- width = parseInt(match[2]);
- decimals = parseInt(match[3]);
- }
- }
- else if (value) {
- // Extract the values from the object
- const v = value;
- const check = (key, type, defaultValue) => {
- if (v[key] == null) {
- return defaultValue;
- }
- assertArgument(typeof v[key] === type, "invalid fixed format (" + key + " not " + type + ")", "format." + key, v[key]);
- return v[key];
- };
- signed = check("signed", "boolean", signed);
- width = check("width", "number", width);
- decimals = check("decimals", "number", decimals);
- }
- assertArgument(width % 8 === 0, "invalid FixedNumber width (not byte aligned)", "format.width", width);
- assertArgument(decimals <= 80, "invalid FixedNumber decimals (too large)", "format.decimals", decimals);
- const name = (signed ? "" : "u") + "fixed" + String(width) + "x" + String(decimals);
- return { signed, width, decimals, name };
- }
- function toString(val, decimals) {
- let negative = "";
- if (val < BN_0$7) {
- negative = "-";
- val *= BN_N1;
- }
- let str = val.toString();
- // No decimal point for whole values
- if (decimals === 0) {
- return negative + str;
- }
- // Pad out to the whole component (including a whole digit)
- while (str.length <= decimals) {
- str = Zeros + str;
- }
- // Insert the decimal point
- const index = str.length - decimals;
- str = str.substring(0, index) + "." + str.substring(index);
- // Trim the whole component (leaving at least one 0)
- while (str[0] === "0" && str[1] !== ".") {
- str = str.substring(1);
- }
- // Trim the decimal component (leaving at least one 0)
- while (str[str.length - 1] === "0" && str[str.length - 2] !== ".") {
- str = str.substring(0, str.length - 1);
- }
- return negative + str;
- }
- /**
- * A FixedNumber represents a value over its [[FixedFormat]]
- * arithmetic field.
- *
- * A FixedNumber can be used to perform math, losslessly, on
- * values which have decmial places.
- *
- * A FixedNumber has a fixed bit-width to store values in, and stores all
- * values internally by multiplying the value by 10 raised to the power of
- * %%decimals%%.
- *
- * If operations are performed that cause a value to grow too high (close to
- * positive infinity) or too low (close to negative infinity), the value
- * is said to //overflow//.
- *
- * For example, an 8-bit signed value, with 0 decimals may only be within
- * the range ``-128`` to ``127``; so ``-128 - 1`` will overflow and become
- * ``127``. Likewise, ``127 + 1`` will overflow and become ``-127``.
- *
- * Many operation have a normal and //unsafe// variant. The normal variant
- * will throw a [[NumericFaultError]] on any overflow, while the //unsafe//
- * variant will silently allow overflow, corrupting its value value.
- *
- * If operations are performed that cause a value to become too small
- * (close to zero), the value loses precison and is said to //underflow//.
- *
- * For example, an value with 1 decimal place may store a number as small
- * as ``0.1``, but the value of ``0.1 / 2`` is ``0.05``, which cannot fit
- * into 1 decimal place, so underflow occurs which means precision is lost
- * and the value becomes ``0``.
- *
- * Some operations have a normal and //signalling// variant. The normal
- * variant will silently ignore underflow, while the //signalling// variant
- * will thow a [[NumericFaultError]] on underflow.
- */
- class FixedNumber {
- /**
- * The specific fixed-point arithmetic field for this value.
- */
- format;
- #format;
- // The actual value (accounting for decimals)
- #val;
- // A base-10 value to multiple values by to maintain the magnitude
- #tens;
- /**
- * This is a property so console.log shows a human-meaningful value.
- *
- * @private
- */
- _value;
- // Use this when changing this file to get some typing info,
- // but then switch to any to mask the internal type
- //constructor(guard: any, value: bigint, format: _FixedFormat) {
- /**
- * @private
- */
- constructor(guard, value, format) {
- assertPrivate(guard, _guard$5, "FixedNumber");
- this.#val = value;
- this.#format = format;
- const _value = toString(value, format.decimals);
- defineProperties(this, { format: format.name, _value });
- this.#tens = getTens(format.decimals);
- }
- /**
- * If true, negative values are permitted, otherwise only
- * positive values and zero are allowed.
- */
- get signed() {
- return this.#format.signed;
- }
- /**
- * The number of bits available to store the value.
- */
- get width() {
- return this.#format.width;
- }
- /**
- * The number of decimal places in the fixed-point arithment field.
- */
- get decimals() {
- return this.#format.decimals;
- }
- /**
- * The value as an integer, based on the smallest unit the
- * [[decimals]] allow.
- */
- get value() {
- return this.#val;
- }
- #checkFormat(other) {
- assertArgument(this.format === other.format, "incompatible format; use fixedNumber.toFormat", "other", other);
- }
- #checkValue(val, safeOp) {
- /*
- const width = BigInt(this.width);
- if (this.signed) {
- const limit = (BN_1 << (width - BN_1));
- assert(safeOp == null || (val >= -limit && val < limit), "overflow", "NUMERIC_FAULT", {
- operation: safeOp, fault: "overflow", value: val
- });
-
- if (val > BN_0) {
- val = fromTwos(mask(val, width), width);
- } else {
- val = -fromTwos(mask(-val, width), width);
- }
-
- } else {
- const masked = mask(val, width);
- assert(safeOp == null || (val >= 0 && val === masked), "overflow", "NUMERIC_FAULT", {
- operation: safeOp, fault: "overflow", value: val
- });
- val = masked;
- }
- */
- val = checkValue(val, this.#format, safeOp);
- return new _a$1(_guard$5, val, this.#format);
- }
- #add(o, safeOp) {
- this.#checkFormat(o);
- return this.#checkValue(this.#val + o.#val, safeOp);
- }
- /**
- * Returns a new [[FixedNumber]] with the result of %%this%% added
- * to %%other%%, ignoring overflow.
- */
- addUnsafe(other) {
- return this.#add(other);
- }
- /**
- * Returns a new [[FixedNumber]] with the result of %%this%% added
- * to %%other%%. A [[NumericFaultError]] is thrown if overflow
- * occurs.
- */
- add(other) {
- return this.#add(other, "add");
- }
- #sub(o, safeOp) {
- this.#checkFormat(o);
- return this.#checkValue(this.#val - o.#val, safeOp);
- }
- /**
- * Returns a new [[FixedNumber]] with the result of %%other%% subtracted
- * from %%this%%, ignoring overflow.
- */
- subUnsafe(other) {
- return this.#sub(other);
- }
- /**
- * Returns a new [[FixedNumber]] with the result of %%other%% subtracted
- * from %%this%%. A [[NumericFaultError]] is thrown if overflow
- * occurs.
- */
- sub(other) {
- return this.#sub(other, "sub");
- }
- #mul(o, safeOp) {
- this.#checkFormat(o);
- return this.#checkValue((this.#val * o.#val) / this.#tens, safeOp);
- }
- /**
- * Returns a new [[FixedNumber]] with the result of %%this%% multiplied
- * by %%other%%, ignoring overflow and underflow (precision loss).
- */
- mulUnsafe(other) {
- return this.#mul(other);
- }
- /**
- * Returns a new [[FixedNumber]] with the result of %%this%% multiplied
- * by %%other%%. A [[NumericFaultError]] is thrown if overflow
- * occurs.
- */
- mul(other) {
- return this.#mul(other, "mul");
- }
- /**
- * Returns a new [[FixedNumber]] with the result of %%this%% multiplied
- * by %%other%%. A [[NumericFaultError]] is thrown if overflow
- * occurs or if underflow (precision loss) occurs.
- */
- mulSignal(other) {
- this.#checkFormat(other);
- const value = this.#val * other.#val;
- assert(value % this.#tens === BN_0$7, "precision lost during signalling mul", "NUMERIC_FAULT", {
- operation: "mulSignal",
- fault: "underflow",
- value: this,
- });
- return this.#checkValue(value / this.#tens, "mulSignal");
- }
- #div(o, safeOp) {
- assert(o.#val !== BN_0$7, "division by zero", "NUMERIC_FAULT", {
- operation: "div",
- fault: "divide-by-zero",
- value: this,
- });
- this.#checkFormat(o);
- return this.#checkValue((this.#val * this.#tens) / o.#val, safeOp);
- }
- /**
- * Returns a new [[FixedNumber]] with the result of %%this%% divided
- * by %%other%%, ignoring underflow (precision loss). A
- * [[NumericFaultError]] is thrown if overflow occurs.
- */
- divUnsafe(other) {
- return this.#div(other);
- }
- /**
- * Returns a new [[FixedNumber]] with the result of %%this%% divided
- * by %%other%%, ignoring underflow (precision loss). A
- * [[NumericFaultError]] is thrown if overflow occurs.
- */
- div(other) {
- return this.#div(other, "div");
- }
- /**
- * Returns a new [[FixedNumber]] with the result of %%this%% divided
- * by %%other%%. A [[NumericFaultError]] is thrown if underflow
- * (precision loss) occurs.
- */
- divSignal(other) {
- assert(other.#val !== BN_0$7, "division by zero", "NUMERIC_FAULT", {
- operation: "div",
- fault: "divide-by-zero",
- value: this,
- });
- this.#checkFormat(other);
- const value = this.#val * this.#tens;
- assert(value % other.#val === BN_0$7, "precision lost during signalling div", "NUMERIC_FAULT", {
- operation: "divSignal",
- fault: "underflow",
- value: this,
- });
- return this.#checkValue(value / other.#val, "divSignal");
- }
- /**
- * Returns a comparison result between %%this%% and %%other%%.
- *
- * This is suitable for use in sorting, where ``-1`` implies %%this%%
- * is smaller, ``1`` implies %%other%% is larger and ``0`` implies
- * both are equal.
- */
- cmp(other) {
- let a = this.value, b = other.value;
- // Coerce a and b to the same magnitude
- const delta = this.decimals - other.decimals;
- if (delta > 0) {
- b *= getTens(delta);
- }
- else if (delta < 0) {
- a *= getTens(-delta);
- }
- // Comnpare
- if (a < b) {
- return -1;
- }
- if (a > b) {
- return -1;
- }
- return 0;
- }
- /**
- * Returns true if %%other%% is equal to %%this%%.
- */
- eq(other) {
- return this.cmp(other) === 0;
- }
- /**
- * Returns true if %%other%% is less than to %%this%%.
- */
- lt(other) {
- return this.cmp(other) < 0;
- }
- /**
- * Returns true if %%other%% is less than or equal to %%this%%.
- */
- lte(other) {
- return this.cmp(other) <= 0;
- }
- /**
- * Returns true if %%other%% is greater than to %%this%%.
- */
- gt(other) {
- return this.cmp(other) > 0;
- }
- /**
- * Returns true if %%other%% is greater than or equal to %%this%%.
- */
- gte(other) {
- return this.cmp(other) >= 0;
- }
- /**
- * Returns a new [[FixedNumber]] which is the largest **integer**
- * that is less than or equal to %%this%%.
- *
- * The decimal component of the result will always be ``0``.
- */
- floor() {
- let val = this.#val;
- if (this.#val < BN_0$7) {
- val -= this.#tens - BN_1$4;
- }
- val = (this.#val / this.#tens) * this.#tens;
- return this.#checkValue(val, "floor");
- }
- /**
- * Returns a new [[FixedNumber]] which is the smallest **integer**
- * that is greater than or equal to %%this%%.
- *
- * The decimal component of the result will always be ``0``.
- */
- ceiling() {
- let val = this.#val;
- if (this.#val > BN_0$7) {
- val += this.#tens - BN_1$4;
- }
- val = (this.#val / this.#tens) * this.#tens;
- return this.#checkValue(val, "ceiling");
- }
- /**
- * Returns a new [[FixedNumber]] with the decimal component
- * rounded up on ties at %%decimals%% places.
- */
- round(decimals) {
- if (decimals == null) {
- decimals = 0;
- }
- // Not enough precision to not already be rounded
- if (decimals >= this.decimals) {
- return this;
- }
- const delta = this.decimals - decimals;
- const bump = BN_5 * getTens(delta - 1);
- let value = this.value + bump;
- const tens = getTens(delta);
- value = (value / tens) * tens;
- checkValue(value, this.#format, "round");
- return new _a$1(_guard$5, value, this.#format);
- }
- /**
- * Returns true if %%this%% is equal to ``0``.
- */
- isZero() {
- return this.#val === BN_0$7;
- }
- /**
- * Returns true if %%this%% is less than ``0``.
- */
- isNegative() {
- return this.#val < BN_0$7;
- }
- /**
- * Returns the string representation of %%this%%.
- */
- toString() {
- return this._value;
- }
- /**
- * Returns a float approximation.
- *
- * Due to IEEE 754 precission (or lack thereof), this function
- * can only return an approximation and most values will contain
- * rounding errors.
- */
- toUnsafeFloat() {
- return parseFloat(this.toString());
- }
- /**
- * Return a new [[FixedNumber]] with the same value but has had
- * its field set to %%format%%.
- *
- * This will throw if the value cannot fit into %%format%%.
- */
- toFormat(format) {
- return _a$1.fromString(this.toString(), format);
- }
- /**
- * Creates a new [[FixedNumber]] for %%value%% divided by
- * %%decimal%% places with %%format%%.
- *
- * This will throw a [[NumericFaultError]] if %%value%% (once adjusted
- * for %%decimals%%) cannot fit in %%format%%, either due to overflow
- * or underflow (precision loss).
- */
- static fromValue(_value, decimals, _format) {
- if (decimals == null) {
- decimals = 0;
- }
- const format = getFormat(_format);
- let value = getBigInt(_value, "value");
- const delta = decimals - format.decimals;
- if (delta > 0) {
- const tens = getTens(delta);
- assert(value % tens === BN_0$7, "value loses precision for format", "NUMERIC_FAULT", {
- operation: "fromValue",
- fault: "underflow",
- value: _value,
- });
- value /= tens;
- }
- else if (delta < 0) {
- value *= getTens(-delta);
- }
- checkValue(value, format, "fromValue");
- return new _a$1(_guard$5, value, format);
- }
- /**
- * Creates a new [[FixedNumber]] for %%value%% with %%format%%.
- *
- * This will throw a [[NumericFaultError]] if %%value%% cannot fit
- * in %%format%%, either due to overflow or underflow (precision loss).
- */
- static fromString(_value, _format) {
- const match = _value.match(/^(-?)([0-9]*)\.?([0-9]*)$/);
- assertArgument(match && match[2].length + match[3].length > 0, "invalid FixedNumber string value", "value", _value);
- const format = getFormat(_format);
- let whole = match[2] || "0", decimal = match[3] || "";
- // Pad out the decimals
- while (decimal.length < format.decimals) {
- decimal += Zeros;
- }
- // Check precision is safe
- assert(decimal.substring(format.decimals).match(/^0*$/), "too many decimals for format", "NUMERIC_FAULT", {
- operation: "fromString",
- fault: "underflow",
- value: _value,
- });
- // Remove extra padding
- decimal = decimal.substring(0, format.decimals);
- const value = BigInt(match[1] + whole + decimal);
- checkValue(value, format, "fromString");
- return new _a$1(_guard$5, value, format);
- }
- /**
- * Creates a new [[FixedNumber]] with the big-endian representation
- * %%value%% with %%format%%.
- *
- * This will throw a [[NumericFaultError]] if %%value%% cannot fit
- * in %%format%% due to overflow.
- */
- static fromBytes(_value, _format) {
- let value = toBigInt(getBytes(_value, "value"));
- const format = getFormat(_format);
- if (format.signed) {
- value = fromTwos(value, format.width);
- }
- checkValue(value, format, "fromBytes");
- return new _a$1(_guard$5, value, format);
- }
- }
- _a$1 = FixedNumber;
- //const f1 = FixedNumber.fromString("12.56", "fixed16x2");
- //const f2 = FixedNumber.fromString("0.3", "fixed16x2");
- //console.log(f1.divSignal(f2));
- //const BUMP = FixedNumber.from("0.5");
-
- function hexlifyByte(value) {
- let result = value.toString(16);
- while (result.length < 2) {
- result = "0" + result;
- }
- return "0x" + result;
- }
- function unarrayifyInteger(data, offset, length) {
- let result = 0;
- for (let i = 0; i < length; i++) {
- result = result * 256 + data[offset + i];
- }
- return result;
- }
- function _decodeChildren(data, offset, childOffset, length) {
- const result = [];
- while (childOffset < offset + 1 + length) {
- const decoded = _decode(data, childOffset);
- result.push(decoded.result);
- childOffset += decoded.consumed;
- assert(childOffset <= offset + 1 + length, "child data too short", "BUFFER_OVERRUN", {
- buffer: data,
- length,
- offset,
- });
- }
- return { consumed: 1 + length, result: result };
- }
- // returns { consumed: number, result: Object }
- function _decode(data, offset) {
- assert(data.length !== 0, "data too short", "BUFFER_OVERRUN", {
- buffer: data,
- length: 0,
- offset: 1,
- });
- const checkOffset = (offset) => {
- assert(offset <= data.length, "data short segment too short", "BUFFER_OVERRUN", {
- buffer: data,
- length: data.length,
- offset,
- });
- };
- // Array with extra length prefix
- if (data[offset] >= 0xf8) {
- const lengthLength = data[offset] - 0xf7;
- checkOffset(offset + 1 + lengthLength);
- const length = unarrayifyInteger(data, offset + 1, lengthLength);
- checkOffset(offset + 1 + lengthLength + length);
- return _decodeChildren(data, offset, offset + 1 + lengthLength, lengthLength + length);
- }
- else if (data[offset] >= 0xc0) {
- const length = data[offset] - 0xc0;
- checkOffset(offset + 1 + length);
- return _decodeChildren(data, offset, offset + 1, length);
- }
- else if (data[offset] >= 0xb8) {
- const lengthLength = data[offset] - 0xb7;
- checkOffset(offset + 1 + lengthLength);
- const length = unarrayifyInteger(data, offset + 1, lengthLength);
- checkOffset(offset + 1 + lengthLength + length);
- const result = hexlify(data.slice(offset + 1 + lengthLength, offset + 1 + lengthLength + length));
- return { consumed: 1 + lengthLength + length, result: result };
- }
- else if (data[offset] >= 0x80) {
- const length = data[offset] - 0x80;
- checkOffset(offset + 1 + length);
- const result = hexlify(data.slice(offset + 1, offset + 1 + length));
- return { consumed: 1 + length, result: result };
- }
- return { consumed: 1, result: hexlifyByte(data[offset]) };
- }
- /**
- * Decodes %%data%% into the structured data it represents.
- */
- function decodeRlp(_data) {
- const data = getBytes(_data, "data");
- const decoded = _decode(data, 0);
- assertArgument(decoded.consumed === data.length, "unexpected junk after rlp payload", "data", _data);
- return decoded.result;
- }
-
- function arrayifyInteger(value) {
- const result = [];
- while (value) {
- result.unshift(value & 0xff);
- value >>= 8;
- }
- return result;
- }
- function _encode(object) {
- if (Array.isArray(object)) {
- let payload = [];
- object.forEach(function (child) {
- payload = payload.concat(_encode(child));
- });
- if (payload.length <= 55) {
- payload.unshift(0xc0 + payload.length);
- return payload;
- }
- const length = arrayifyInteger(payload.length);
- length.unshift(0xf7 + length.length);
- return length.concat(payload);
- }
- const data = Array.prototype.slice.call(getBytes(object, "object"));
- if (data.length === 1 && data[0] <= 0x7f) {
- return data;
- }
- else if (data.length <= 55) {
- data.unshift(0x80 + data.length);
- return data;
- }
- const length = arrayifyInteger(data.length);
- length.unshift(0xb7 + length.length);
- return length.concat(data);
- }
- const nibbles = "0123456789abcdef";
- /**
- * Encodes %%object%% as an RLP-encoded [[DataHexString]].
- */
- function encodeRlp(object) {
- let result = "0x";
- for (const v of _encode(object)) {
- result += nibbles[v >> 4];
- result += nibbles[v & 0xf];
- }
- return result;
- }
-
- /**
- * Most interactions with Core requires integer values, which use
- * the smallest magnitude unit.
- *
- * For example, imagine dealing with dollars and cents. Since dollars
- * are divisible, non-integer values are possible, such as ``$10.77``.
- * By using the smallest indivisible unit (i.e. cents), the value can
- * be kept as the integer ``1077``.
- *
- * When receiving decimal input from the user (as a decimal string),
- * the value should be converted to an integer and when showing a user
- * a value, the integer value should be converted to a decimal string.
- *
- * This creates a clear distinction, between values to be used by code
- * (integers) and values used for display logic to users (decimals).
- *
- * The native unit in Core, //Core// is divisible to 18 decimal places,
- * where each individual unit is called a //ore//.
- *
- * @_subsection api/utils:Unit Conversion [about-units]
- */
- const names = [
- ///Ore, the smallest and atomic amount of Core
- "ore",
- ///fecore, 1000 ore
- "fecore",
- ///Picore, one million ore
- "picore",
- ///Nacore, one billion ore. Typically a reasonable unit to measure energy prices.
- "nacore",
- ///Μcore, 10^12 ore or 1 μCore
- "mcore",
- ///micore, 10^15 ore or 1 mcore
- "micore",
- "core",
- ];
- /**
- * Converts %%value%% into a //decimal string//, assuming %%unit%% decimal
- * places. The %%unit%% may be the number of decimal places or the name of
- * a unit
- *
- */
- function formatUnits(value, unit) {
- let decimals = 18;
- if (typeof unit === "string") {
- const index = names.indexOf(unit);
- assertArgument(index >= 0, "invalid unit", "unit", unit);
- decimals = 3 * index;
- }
- else if (unit != null) {
- decimals = getNumber(unit, "unit");
- }
- return FixedNumber.fromValue(value, decimals, { decimals }).toString();
- }
- /**
- * Converts the //decimal string// %%value%% to a BigInt, assuming
- * %%unit%% decimal places. The %%unit%% may the number of decimal places
- * or the name of a unit.
- */
- const scientificToDecimal = (num) => {
- // @ts-ignore
- var nsign = Math.sign(num);
- //remove the sign
- // @ts-ignore
- num = Math.abs(num);
- //if the number is in scientific notation remove it
- // @ts-ignore
- if (/\d+\.?\d*e[\+\-]*\d+/i.test(num)) {
- var zero = "0",
- // @ts-ignore
- parts = String(num).toLowerCase().split("e"), //split into coeff and exponent
- e = parts.pop(), //store the exponential part
- // @ts-ignore
- l = Math.abs(e), //get the number of zeros
- // @ts-ignore
- sign = e / l, coeff_array = parts[0].split(".");
- if (sign === -1) {
- l = l - coeff_array[0].length;
- if (l < 0) {
- // @ts-ignore
- num =
- coeff_array[0].slice(0, l) +
- "." +
- coeff_array[0].slice(l) +
- (coeff_array.length === 2 ? coeff_array[1] : "");
- }
- else {
- // @ts-ignore
- num = zero + "." + new Array(l + 1).join(zero) + coeff_array.join("");
- }
- }
- else {
- var dec = coeff_array[1];
- if (dec)
- l = l - dec.length;
- if (l < 0) {
- // @ts-ignore
- num = coeff_array[0] + dec.slice(0, l) + "." + dec.slice(l);
- }
- else {
- // @ts-ignore
- num = coeff_array.join("") + new Array(l + 1).join(zero);
- }
- }
- }
- // @ts-ignore
- return nsign < 0 ? "-" + num : num;
- };
- const trimDecimals = (n, decimals = 18) => {
- n += "";
- if (n.indexOf(".") === -1)
- return n;
- const arr = n.split(".");
- const fraction = arr[1].substr(0, decimals);
- return arr[0] + "." + fraction;
- };
- function parseUnits(value, unit) {
- assertArgument(typeof value === "string", "value must be a string", "value", value);
- if (value.includes("e")) {
- value = scientificToDecimal(value).toString();
- }
- let decimals = 18;
- if (typeof unit === "string") {
- const index = names.indexOf(unit);
- assertArgument(index >= 0, "invalid unit", "unit", unit);
- decimals = 3 * index;
- value = trimDecimals(value, decimals);
- }
- else if (unit != null) {
- decimals = getNumber(unit, "unit");
- value = trimDecimals(value, decimals);
- }
- return FixedNumber.fromString(value, { decimals }).value;
- }
- /**
- * Converts %%value%% into a //decimal string// using 18 decimal places.
- */
- function formatXCB(ore) {
- return formatUnits(ore, 18);
- }
- /**
- * Converts the //decimal string// %%xcb%% to a BigInt, using 18
- * decimal places.
- */
- function parseXCB(xcb) {
- return parseUnits(xcb, 18);
- }
-
- /**
- * Explain UUID and link to RFC here.
- *
- * @_subsection: api/utils:UUID [about-uuid]
- */
- /**
- * Returns the version 4 [[link-uuid]] for the %%randomBytes%%.
- *
- * @see: https://www.ietf.org/rfc/rfc4122.txt (Section 4.4)
- */
- function uuidV4(randomBytes) {
- const bytes = getBytes(randomBytes, "randomBytes");
- // Section: 4.1.3:
- // - time_hi_and_version[12:16] = 0b0100
- bytes[6] = (bytes[6] & 0x0f) | 0x40;
- // Section 4.4
- // - clock_seq_hi_and_reserved[6] = 0b0
- // - clock_seq_hi_and_reserved[7] = 0b1
- bytes[8] = (bytes[8] & 0x3f) | 0x80;
- const value = hexlify(bytes);
- return [
- value.substring(2, 10),
- value.substring(10, 14),
- value.substring(14, 18),
- value.substring(18, 22),
- value.substring(22, 34),
- ].join("-");
- }
-
- // @ts-ignore
- class Ed448Goldilock {
- static _channel = ed448;
- static generatePrivateKey() {
- var privateKey = ed448.privateKeyGenerate();
- privateKey[56] &= 0x7f;
- return privateKey;
- }
- static getPublicKeyFromPrivateKey(privateKey) {
- var secret = Buffer.from(privateKey, "hex");
- if (secret[56] > 127) {
- var scalar = secret.slice(0, 56);
- scalar[0] &= 0xfc;
- scalar[55] |= 0x80;
- var publicKey = this._channel.publicKeyFromScalar(scalar);
- return Buffer.from(publicKey).toString("hex");
- }
- else {
- var publicKey = this._channel.publicKeyCreate(secret);
- return Buffer.from(publicKey).toString("hex");
- }
- }
- static signWithPrivateKey(privateKey, msg) {
- var msgToSign = Buffer.from(msg, "hex");
- var secret = Buffer.from(privateKey, "hex");
- if (secret[56] > 127) {
- var prefix = secret.slice(0, 57);
- prefix[0] &= 0xfc;
- prefix[56] = 0;
- prefix[55] |= 0x80;
- var scalar = prefix.slice(0, 56);
- var signedMessage = this._channel.signWithScalar(msgToSign, scalar, prefix);
- return Buffer.from(signedMessage).toString("hex");
- }
- else {
- var signedMessage = this._channel.sign(msgToSign, secret);
- return Buffer.from(signedMessage).toString("hex");
- }
- }
- static signWithPrivateKeyNConcatPubkey(privateKey, msg) {
- var signedMessage = Ed448Goldilock.signWithPrivateKey(privateKey, msg);
- var publicKey = Ed448Goldilock.getPublicKeyFromPrivateKey(privateKey);
- return signedMessage + publicKey;
- }
- static verifySignature(msgHash, signedMsg, pubKey) {
- return this._channel.verify(msgHash, signedMsg, pubKey);
- }
- static SHA512Hash(password, salt) {
- var p1 = Buffer.from(password, "hex");
- var s1 = Buffer.from(salt, "hex");
- return Buffer.from(pbkdf2$2.derive(SHA3_512, p1, s1, 2048, 57)).toString("hex");
- }
- static concatenateAndHex(prefix, key, index, salt) {
- var ind = Buffer.alloc(4);
- var p = Buffer.alloc(1);
- p[0] = prefix % 256;
- var j = index;
- for (let i = 0; i < 4; i++) {
- ind[i] = j % 256;
- j = Math.floor(j / 256);
- }
- var t = p.toString("hex") + key + ind.toString("hex");
- return Ed448Goldilock.SHA512Hash(t, salt);
- }
- static addScalar(a, b) {
- var a1 = Buffer.from(a, "hex");
- var b1 = Buffer.from(b.substr(0, 106) + "00000000", "hex");
- b1[0] &= 0xfc;
- var c = Buffer.alloc(57);
- var hold = 0;
- for (let i = 0; i < 57; i++) {
- hold += a1[i] + b1[i];
- c[i] = hold % 256;
- hold = Math.floor(hold / 256);
- }
- return c.toString("hex");
- }
- static seedToExtendedPrivate(seed) {
- var s1 = Ed448Goldilock.SHA512Hash(seed, "6d6e656d6f6e6963666f72746865636861696e");
- var s2 = Ed448Goldilock.SHA512Hash(seed, "6d6e656d6f6e6963666f727468656b6579");
- var b = Buffer.from(s2, "hex");
- b[56] |= 0x80;
- b[55] |= 0x80;
- b[55] &= 0xbf;
- var s3 = b.toString("hex");
- return s1 + s3;
- }
- static childPrivateToPrivate(s, index) {
- var s0 = s.substr(0, 114);
- var s1 = s.substr(114, 228);
- var r0, r1;
- if (index >= 0x80000000) {
- r0 = Ed448Goldilock.concatenateAndHex(1, s1, index, s0);
- r1 = Ed448Goldilock.concatenateAndHex(0, s1, index, s0);
- return r0 + Ed448Goldilock.addScalar(s1, r1);
- }
- else {
- var pub = Ed448Goldilock.getPublicKeyFromPrivateKey(s1);
- r0 = Ed448Goldilock.concatenateAndHex(3, pub, index, s0);
- r1 = Ed448Goldilock.concatenateAndHex(2, pub, index, s0);
- return r0 + Ed448Goldilock.addScalar(s1, r1);
- }
- }
- static HDWalletGenerateKeyFromSeed(seed, index) {
- var m = Ed448Goldilock.seedToExtendedPrivate(seed);
- var k1 = Ed448Goldilock.childPrivateToPrivate(m, 0x80000000 + 44);
- var k2 = Ed448Goldilock.childPrivateToPrivate(k1, 0x80000000 + 654);
- var k3 = Ed448Goldilock.childPrivateToPrivate(k2, 0x80000000 + 0);
- var k4 = Ed448Goldilock.childPrivateToPrivate(k3, 0x80000000 + 0);
- var k5 = Ed448Goldilock.childPrivateToPrivate(k4, index);
- return k5.substr(114, 228);
- }
- }
-
- /* Browser Crypto Shims */
- function getGlobal$1() {
- if (typeof self !== "undefined") {
- return self;
- }
- if (typeof window !== "undefined") {
- return window;
- }
- if (typeof global !== "undefined") {
- return global;
- }
- throw new Error("unable to locate global object");
- }
- const anyGlobal = getGlobal$1();
- const crypto = anyGlobal.crypto || anyGlobal.msCrypto;
- function createHash(algo) {
- switch (algo) {
- case "sha256":
- return sha256$1.create();
- case "sha512":
- return sha512$1.create();
- case "sha3-256":
- return sha3_256.create();
- case "sha3-512":
- return sha3_512.create();
- }
- assertArgument(false, "invalid hashing algorithm name", "algorithm", algo);
- }
- function createHmac(_algo, key) {
- const algo = { sha256: sha256$1, sha512: sha512$1 }[_algo];
- assertArgument(algo != null, "invalid hmac algorithm", "algorithm", _algo);
- return hmac.create(algo, key);
- }
- function pbkdf2Sync(password, salt, iterations, keylen, _algo) {
- const algo = { sha256: sha256$1, sha512: sha512$1 }[_algo];
- assertArgument(algo != null, "invalid pbkdf2 algorithm", "algorithm", _algo);
- return pbkdf2$1(algo, password, salt, { c: iterations, dkLen: keylen });
- }
- function randomBytes$1(length) {
- assert(crypto != null, "platform does not support secure random numbers", "UNSUPPORTED_OPERATION", {
- operation: "randomBytes",
- });
- assertArgument(Number.isInteger(length) && length > 0 && length <= 1024, "invalid length", "length", length);
- const result = new Uint8Array(length);
- crypto.getRandomValues(result);
- return result;
- }
-
- const _sha256 = function (data) {
- let v = "0x" +
- createHash("sha3-256")
- .update(buffer.Buffer.from(arrayify(data)))
- .digest("hex");
- return v;
- };
- const _sha512 = function (data) {
- let v = "0x" +
- createHash("sha3-512")
- .update(buffer.Buffer.from(arrayify(data)))
- .digest("hex");
- return v;
- };
- let locked256 = false, locked512 = false;
- /**
- * Compute the cryptographic SHA2-256 hash of %%data%%.
- *
- * @_docloc: api/crypto:Hash Functions
- * @returns DataHexstring
- *
- * @example:
- * sha256("0x")
- * //_result:
- *
- * sha256("0x1337")
- * //_result:
- *
- * sha256(new Uint8Array([ 0x13, 0x37 ]))
- * //_result:
- *
- */
- var SupportedAlgorithm;
- (function (SupportedAlgorithm) {
- SupportedAlgorithm["sha256"] = "sha256";
- SupportedAlgorithm["sha512"] = "sha512";
- })(SupportedAlgorithm || (SupportedAlgorithm = {}));
- function sha256(data) {
- let createdHash = createHash("sha3-256")
- .update(buffer.Buffer.from(arrayify(data)))
- .digest("hex");
- const v = "0x" + createdHash;
- if (typeof createdHash !== "string") {
- createdHash = hexlify(createdHash);
- return createdHash;
- }
- return v;
- }
- function legacySha256(data) {
- const _data = getBytes(data, "data");
- const hexlified = hexlify(createHash("sha256").update(_data).digest());
- return hexlified;
- }
- sha256._ = _sha256;
- sha256.lock = function () {
- locked256 = true;
- };
- sha256.register = function (func) {
- if (locked256) {
- throw new Error("sha256 is locked");
- }
- };
- Object.freeze(sha256);
- /**
- * Compute the cryptographic SHA2-512 hash of %%data%%.
- *
- * @_docloc: api/crypto:Hash Functions
- * @returns DataHexstring
- *
- * @example:
- * sha512("0x")
- * //_result:
- *
- * sha512("0x1337")
- * //_result:
- *
- * sha512(new Uint8Array([ 0x13, 0x37 ]))
- * //_result:
- */
- function sha512(data) {
- let createdHash = createHash("sha3-512")
- .update(buffer.Buffer.from(arrayify(data)))
- .digest("hex");
- const v = "0x" + createdHash;
- if (typeof createdHash !== "string") {
- createdHash = hexlify(createdHash);
- return createdHash;
- }
- return v;
- }
- sha512._ = _sha512;
- sha512.lock = function () {
- locked512 = true;
- };
- sha512.register = function (func) {
- if (locked512) {
- throw new Error("sha512 is locked");
- }
- };
- Object.freeze(sha256);
-
- /**
- * Addresses are a fundamental part of interacting with Core. They
- * represent the gloabal identity of Externally Owned Accounts (accounts
- * backed by a private key) and contracts.
- *
- * The Core Naming Service (CNS) provides an interconnected ecosystem
- * of contracts, standards and libraries which enable looking up an
- * address for an ENS name.
- *
- * These functions help convert between various formats, validate
- * addresses and safely resolve ENS names.
- *
- * @_section: api/address:Addresses [about-addresses]
- */
- const logger$3 = new Logger("address/0.0.1");
- const precompiledAddresses = [
- "0000000000000000000000000000000000000000000000000000000000000000",
- "0000000000000000000000000000000000000000000000000000000000000001",
- "0000000000000000000000000000000000000000000000000000000000000002",
- "0000000000000000000000000000000000000000000000000000000000000003",
- "0000000000000000000000000000000000000000000000000000000000000004",
- "0000000000000000000000000000000000000000000000000000000000000005",
- "0000000000000000000000000000000000000000000000000000000000000006",
- "0000000000000000000000000000000000000000000000000000000000000007",
- "0000000000000000000000000000000000000000000000000000000000000008",
- "0000000000000000000000000000000000000000000000000000000000000009",
- ];
- function removeHexPrefix$1(val) {
- return val.substring(0, 2) === "0x" ? val.substring(2) : val;
- }
- function calculateCheckSum(_address, _prefix) {
- const address = getBytes("0x" + _address.replace("0x", ""));
- const prefix = getBytes("0x" + _prefix.replace("0x", ""));
- const tmpConcated = new Uint8Array([...address, ...prefix]);
- const hexedConcat = hexlify(tmpConcated).replace("0x", "") + "00";
- const mods = Array.from(hexedConcat.toUpperCase(), (c) => {
- const charCode = c.charCodeAt(0);
- return charCode > 64 && charCode < 91
- ? (charCode - 55).toString()
- : (charCode - 48).toString();
- }).join("");
- const bigVal = BigInt(mods);
- const val97 = BigInt(97);
- const val98 = BigInt(98);
- const remainder = bigVal % val97;
- const checkSum = val98 - remainder;
- const result = checkSum > 9 ? checkSum.toString() : "0" + checkSum.toString();
- return result;
- }
- /**
- * Returns a normalized and checksumed address for %%address%%.
- * This accepts non-checksum addresses, checksum addresses and
- * [[getIcapAddress]] formats.
- *
- * The checksum in Core uses the capitalization (upper-case
- * vs lower-case) of the characters within an address to encode
- * its checksum, which offers, on average, a checksum of 15-bits.
- *
- * If %%address%% contains both upper-case and lower-case, it is
- * assumed to already be a checksum address and its checksum is
- * validated, and if the address fails its expected checksum an
- * error is thrown.
- *
- * If you wish the checksum of %%address%% to be ignore, it should
- * be converted to lower-case (i.e. ``.toLowercase()``) before
- * being passed in. This should be a very rare situation though,
- * that you wish to bypass the safegaurds in place to protect
- * against an address that has been incorrectly copied from another
- * source.
- *
- * @example:
- * // Adds the checksum (via upper-casing specific letters)
- * getAddress("0x8ba1f109551bd432803012645ac136ddd64dba72")
- * //_result:
- *
- * // Converts ICAP address and adds checksum
- * getAddress("XE65GB6LDNXYOFTX0NSV3FUWKOWIXAMJK36");
- * //_result:
- *
- * // Throws an error if an address contains mixed case,
- * // but the checksum fails
- * getAddress("0x8Ba1f109551bD432803012645Ac136ddd64DBA72")
- * //_error:
- */
- function getAddress(address) {
- if (typeof address !== "string") {
- logger$3.throwArgumentError("invalid address", "address", address);
- }
- if (!address.match(/^(0x)?[0-9a-fA-F]{44}$/)) {
- logger$3.throwArgumentError("invalid address", "address", address);
- }
- const raw = removeHexPrefix$1(address);
- if (precompiledAddresses.includes(raw)) {
- return "0x" + raw;
- }
- const prefix = raw.substring(0, 2);
- const val = raw.substring(4);
- const checksum = calculateCheckSum(val, prefix);
- if (checksum !== raw.substring(2, 4)) {
- logger$3.throwArgumentError("bad address checksum", "address", address);
- }
- return "0x" + prefix + checksum + val;
- }
- function networkIdToPrefix(networkId) {
- if (networkId == 1) {
- return "cb";
- }
- else if (networkId == 3 || networkId == 4) {
- return "ab";
- }
- else if (networkId > 10 || networkId == 0) {
- return "ce";
- }
- else {
- logger$3.throwArgumentError("bad networkId", "networkId", networkId);
- return "";
- }
- }
-
- /**
- * An **HMAC** enables verification that a given key was used
- * to authenticate a payload.
- *
- * See: [[link-wiki-hmac]]
- *
- * @_subsection: api/crypto:HMAC [about-hmac]
- */
- let locked$4 = false;
- const _computeHmac = function (algorithm, key, data) {
- return createHmac(algorithm, key).update(data).digest();
- };
- let __computeHmac = _computeHmac;
- /**
- * Return the HMAC for %%data%% using the %%key%% key with the underlying
- * %%algo%% used for compression.
- *
- * @example:
- * key = id("some-secret")
- *
- * // Compute the HMAC
- * computeHmac("sha256", key, "0x1337")
- * //_result:
- *
- * // To compute the HMAC of UTF-8 data, the data must be
- * // converted to UTF-8 bytes
- * computeHmac("sha256", key, toUtf8Bytes("Hello World"))
- * //_result:
- *
- */
- function computeHmac(algorithm, _key, _data) {
- const key = getBytes(_key, "key");
- const data = getBytes(_data, "data");
- return hexlify(__computeHmac(algorithm, key, data));
- }
- computeHmac._ = _computeHmac;
- computeHmac.lock = function () {
- locked$4 = true;
- };
- computeHmac.register = function (func) {
- if (locked$4) {
- throw new Error("computeHmac is locked");
- }
- __computeHmac = func;
- };
- Object.freeze(computeHmac);
-
- // https://homes.esat.kuleuven.be/~bosselae/ripemd160.html
- // https://homes.esat.kuleuven.be/~bosselae/ripemd160/pdf/AB-9601/AB-9601.pdf
- const Rho = /* @__PURE__ */ new Uint8Array([7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8]);
- const Id = /* @__PURE__ */ Uint8Array.from({ length: 16 }, (_, i) => i);
- const Pi = /* @__PURE__ */ Id.map((i) => (9 * i + 5) % 16);
- let idxL = [Id];
- let idxR = [Pi];
- for (let i = 0; i < 4; i++)
- for (let j of [idxL, idxR])
- j.push(j[i].map((k) => Rho[k]));
- const shifts = /* @__PURE__ */ [
- [11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8],
- [12, 13, 11, 15, 6, 9, 9, 7, 12, 15, 11, 13, 7, 8, 7, 7],
- [13, 15, 14, 11, 7, 7, 6, 8, 13, 14, 13, 12, 5, 5, 6, 9],
- [14, 11, 12, 14, 8, 6, 5, 5, 15, 12, 15, 14, 9, 9, 8, 6],
- [15, 12, 13, 13, 9, 5, 8, 6, 14, 11, 12, 11, 8, 6, 5, 5],
- ].map((i) => new Uint8Array(i));
- const shiftsL = /* @__PURE__ */ idxL.map((idx, i) => idx.map((j) => shifts[i][j]));
- const shiftsR = /* @__PURE__ */ idxR.map((idx, i) => idx.map((j) => shifts[i][j]));
- const Kl = /* @__PURE__ */ new Uint32Array([
- 0x00000000, 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xa953fd4e,
- ]);
- const Kr = /* @__PURE__ */ new Uint32Array([
- 0x50a28be6, 0x5c4dd124, 0x6d703ef3, 0x7a6d76e9, 0x00000000,
- ]);
- // The rotate left (circular left shift) operation for uint32
- const rotl$1 = (word, shift) => (word << shift) | (word >>> (32 - shift));
- // It's called f() in spec.
- function f(group, x, y, z) {
- if (group === 0)
- return x ^ y ^ z;
- else if (group === 1)
- return (x & y) | (~x & z);
- else if (group === 2)
- return (x | ~y) ^ z;
- else if (group === 3)
- return (x & z) | (y & ~z);
- else
- return x ^ (y | ~z);
- }
- // Temporary buffer, not used to store anything between runs
- const BUF = /* @__PURE__ */ new Uint32Array(16);
- class RIPEMD160 extends SHA2 {
- constructor() {
- super(64, 20, 8, true);
- this.h0 = 0x67452301 | 0;
- this.h1 = 0xefcdab89 | 0;
- this.h2 = 0x98badcfe | 0;
- this.h3 = 0x10325476 | 0;
- this.h4 = 0xc3d2e1f0 | 0;
- }
- get() {
- const { h0, h1, h2, h3, h4 } = this;
- return [h0, h1, h2, h3, h4];
- }
- set(h0, h1, h2, h3, h4) {
- this.h0 = h0 | 0;
- this.h1 = h1 | 0;
- this.h2 = h2 | 0;
- this.h3 = h3 | 0;
- this.h4 = h4 | 0;
- }
- process(view, offset) {
- for (let i = 0; i < 16; i++, offset += 4)
- BUF[i] = view.getUint32(offset, true);
- // prettier-ignore
- let al = this.h0 | 0, ar = al, bl = this.h1 | 0, br = bl, cl = this.h2 | 0, cr = cl, dl = this.h3 | 0, dr = dl, el = this.h4 | 0, er = el;
- // Instead of iterating 0 to 80, we split it into 5 groups
- // And use the groups in constants, functions, etc. Much simpler
- for (let group = 0; group < 5; group++) {
- const rGroup = 4 - group;
- const hbl = Kl[group], hbr = Kr[group]; // prettier-ignore
- const rl = idxL[group], rr = idxR[group]; // prettier-ignore
- const sl = shiftsL[group], sr = shiftsR[group]; // prettier-ignore
- for (let i = 0; i < 16; i++) {
- const tl = (rotl$1(al + f(group, bl, cl, dl) + BUF[rl[i]] + hbl, sl[i]) + el) | 0;
- al = el, el = dl, dl = rotl$1(cl, 10) | 0, cl = bl, bl = tl; // prettier-ignore
- }
- // 2 loops are 10% faster
- for (let i = 0; i < 16; i++) {
- const tr = (rotl$1(ar + f(rGroup, br, cr, dr) + BUF[rr[i]] + hbr, sr[i]) + er) | 0;
- ar = er, er = dr, dr = rotl$1(cr, 10) | 0, cr = br, br = tr; // prettier-ignore
- }
- }
- // Add the compressed chunk to the current hash value
- this.set((this.h1 + cl + dr) | 0, (this.h2 + dl + er) | 0, (this.h3 + el + ar) | 0, (this.h4 + al + br) | 0, (this.h0 + bl + cr) | 0);
- }
- roundClean() {
- BUF.fill(0);
- }
- destroy() {
- this.destroyed = true;
- this.buffer.fill(0);
- this.set(0, 0, 0, 0, 0);
- }
- }
- /**
- * RIPEMD-160 - a hash function from 1990s.
- * @param message - msg that would be hashed
- */
- const ripemd160$1 = /* @__PURE__ */ wrapConstructor(() => new RIPEMD160());
-
- let locked$3 = false;
- const _ripemd160 = function (data) {
- return ripemd160$1(data);
- };
- let __ripemd160 = _ripemd160;
- /**
- * Compute the cryptographic RIPEMD-160 hash of %%data%%.
- *
- * @_docloc: api/crypto:Hash Functions
- * @returns DataHexstring
- *
- * @example:
- * ripemd160("0x")
- * //_result:
- *
- * ripemd160("0x1337")
- * //_result:
- *
- * ripemd160(new Uint8Array([ 0x13, 0x37 ]))
- * //_result:
- *
- */
- function ripemd160(_data) {
- const data = getBytes(_data, "data");
- return hexlify(__ripemd160(data));
- }
- ripemd160._ = _ripemd160;
- ripemd160.lock = function () {
- locked$3 = true;
- };
- ripemd160.register = function (func) {
- if (locked$3) {
- throw new TypeError("ripemd160 is locked");
- }
- __ripemd160 = func;
- };
- Object.freeze(ripemd160);
-
- /**
- * A **Password-Based Key-Derivation Function** is designed to create
- * a sequence of bytes suitible as a **key** from a human-rememberable
- * password.
- *
- * @_subsection: api/crypto:Passwords [about-pbkdf]
- */
- let locked$2 = false;
- const _pbkdf2 = function (password, salt, iterations, keylen, algo) {
- return pbkdf2Sync(password, salt, iterations, keylen, algo);
- };
- let __pbkdf2 = _pbkdf2;
- /**
- * Return the [[link-pbkdf2]] for %%keylen%% bytes for %%password%% using
- * the %%salt%% and using %%iterations%% of %%algo%%.
- *
- * This PBKDF is outdated and should not be used in new projects, but is
- * required to decrypt older files.
- *
- * @example:
- * // The password must be converted to bytes, and it is generally
- * // best practices to ensure the string has been normalized. Many
- * // formats explicitly indicate the normalization form to use.
- * password = "hello"
- * passwordBytes = toUtf8Bytes(password, "NFKC")
- *
- * salt = id("some-salt")
- *
- * // Compute the PBKDF2
- * pbkdf2(passwordBytes, salt, 1024, 16, "sha256")
- * //_result:
- */
- function pbkdf2(_password, _salt, iterations, keylen, algo) {
- const password = getBytes(_password, "password");
- const salt = getBytes(_salt, "salt");
- return hexlify(__pbkdf2(password, salt, iterations, keylen, algo));
- }
- pbkdf2._ = _pbkdf2;
- pbkdf2.lock = function () {
- locked$2 = true;
- };
- pbkdf2.register = function (func) {
- if (locked$2) {
- throw new Error("pbkdf2 is locked");
- }
- __pbkdf2 = func;
- };
- Object.freeze(pbkdf2);
-
- /**
- * A **Cryptographically Secure Random Value** is one that has been
- * generated with additional care take to prevent side-channels
- * from allowing others to detect it and prevent others from through
- * coincidence generate the same values.
- *
- * @_subsection: api/crypto:Random Values [about-crypto-random]
- */
- let locked$1 = false;
- const _randomBytes = function (length) {
- return new Uint8Array(randomBytes$1(length));
- };
- let __randomBytes = _randomBytes;
- /**
- * Return %%length%% bytes of cryptographically secure random data.
- *
- * @example:
- * randomBytes(8)
- * //_result:
- */
- function randomBytes(length) {
- return __randomBytes(length);
- }
- randomBytes._ = _randomBytes;
- randomBytes.lock = function () {
- locked$1 = true;
- };
- randomBytes.register = function (func) {
- if (locked$1) {
- throw new Error("randomBytes is locked");
- }
- __randomBytes = func;
- };
- Object.freeze(randomBytes);
-
- // RFC 7914 Scrypt KDF
- // Left rotate for uint32
- const rotl = (a, b) => (a << b) | (a >>> (32 - b));
- // The main Scrypt loop: uses Salsa extensively.
- // Six versions of the function were tried, this is the fastest one.
- // prettier-ignore
- function XorAndSalsa(prev, pi, input, ii, out, oi) {
- // Based on https://cr.yp.to/salsa20.html
- // Xor blocks
- let y00 = prev[pi++] ^ input[ii++], y01 = prev[pi++] ^ input[ii++];
- let y02 = prev[pi++] ^ input[ii++], y03 = prev[pi++] ^ input[ii++];
- let y04 = prev[pi++] ^ input[ii++], y05 = prev[pi++] ^ input[ii++];
- let y06 = prev[pi++] ^ input[ii++], y07 = prev[pi++] ^ input[ii++];
- let y08 = prev[pi++] ^ input[ii++], y09 = prev[pi++] ^ input[ii++];
- let y10 = prev[pi++] ^ input[ii++], y11 = prev[pi++] ^ input[ii++];
- let y12 = prev[pi++] ^ input[ii++], y13 = prev[pi++] ^ input[ii++];
- let y14 = prev[pi++] ^ input[ii++], y15 = prev[pi++] ^ input[ii++];
- // Save state to temporary variables (salsa)
- let x00 = y00, x01 = y01, x02 = y02, x03 = y03, x04 = y04, x05 = y05, x06 = y06, x07 = y07, x08 = y08, x09 = y09, x10 = y10, x11 = y11, x12 = y12, x13 = y13, x14 = y14, x15 = y15;
- // Main loop (salsa)
- for (let i = 0; i < 8; i += 2) {
- x04 ^= rotl(x00 + x12 | 0, 7);
- x08 ^= rotl(x04 + x00 | 0, 9);
- x12 ^= rotl(x08 + x04 | 0, 13);
- x00 ^= rotl(x12 + x08 | 0, 18);
- x09 ^= rotl(x05 + x01 | 0, 7);
- x13 ^= rotl(x09 + x05 | 0, 9);
- x01 ^= rotl(x13 + x09 | 0, 13);
- x05 ^= rotl(x01 + x13 | 0, 18);
- x14 ^= rotl(x10 + x06 | 0, 7);
- x02 ^= rotl(x14 + x10 | 0, 9);
- x06 ^= rotl(x02 + x14 | 0, 13);
- x10 ^= rotl(x06 + x02 | 0, 18);
- x03 ^= rotl(x15 + x11 | 0, 7);
- x07 ^= rotl(x03 + x15 | 0, 9);
- x11 ^= rotl(x07 + x03 | 0, 13);
- x15 ^= rotl(x11 + x07 | 0, 18);
- x01 ^= rotl(x00 + x03 | 0, 7);
- x02 ^= rotl(x01 + x00 | 0, 9);
- x03 ^= rotl(x02 + x01 | 0, 13);
- x00 ^= rotl(x03 + x02 | 0, 18);
- x06 ^= rotl(x05 + x04 | 0, 7);
- x07 ^= rotl(x06 + x05 | 0, 9);
- x04 ^= rotl(x07 + x06 | 0, 13);
- x05 ^= rotl(x04 + x07 | 0, 18);
- x11 ^= rotl(x10 + x09 | 0, 7);
- x08 ^= rotl(x11 + x10 | 0, 9);
- x09 ^= rotl(x08 + x11 | 0, 13);
- x10 ^= rotl(x09 + x08 | 0, 18);
- x12 ^= rotl(x15 + x14 | 0, 7);
- x13 ^= rotl(x12 + x15 | 0, 9);
- x14 ^= rotl(x13 + x12 | 0, 13);
- x15 ^= rotl(x14 + x13 | 0, 18);
- }
- // Write output (salsa)
- out[oi++] = (y00 + x00) | 0;
- out[oi++] = (y01 + x01) | 0;
- out[oi++] = (y02 + x02) | 0;
- out[oi++] = (y03 + x03) | 0;
- out[oi++] = (y04 + x04) | 0;
- out[oi++] = (y05 + x05) | 0;
- out[oi++] = (y06 + x06) | 0;
- out[oi++] = (y07 + x07) | 0;
- out[oi++] = (y08 + x08) | 0;
- out[oi++] = (y09 + x09) | 0;
- out[oi++] = (y10 + x10) | 0;
- out[oi++] = (y11 + x11) | 0;
- out[oi++] = (y12 + x12) | 0;
- out[oi++] = (y13 + x13) | 0;
- out[oi++] = (y14 + x14) | 0;
- out[oi++] = (y15 + x15) | 0;
- }
- function BlockMix(input, ii, out, oi, r) {
- // The block B is r 128-byte chunks (which is equivalent of 2r 64-byte chunks)
- let head = oi + 0;
- let tail = oi + 16 * r;
- for (let i = 0; i < 16; i++)
- out[tail + i] = input[ii + (2 * r - 1) * 16 + i]; // X ← B[2r−1]
- for (let i = 0; i < r; i++, head += 16, ii += 16) {
- // We write odd & even Yi at same time. Even: 0bXXXXX0 Odd: 0bXXXXX1
- XorAndSalsa(out, tail, input, ii, out, head); // head[i] = Salsa(blockIn[2*i] ^ tail[i-1])
- if (i > 0)
- tail += 16; // First iteration overwrites tmp value in tail
- XorAndSalsa(out, head, input, (ii += 16), out, tail); // tail[i] = Salsa(blockIn[2*i+1] ^ head[i])
- }
- }
- // Common prologue and epilogue for sync/async functions
- function scryptInit(password, salt, _opts) {
- // Maxmem - 1GB+1KB by default
- const opts = checkOpts({
- dkLen: 32,
- asyncTick: 10,
- maxmem: 1024 ** 3 + 1024,
- }, _opts);
- const { N, r, p, dkLen, asyncTick, maxmem, onProgress } = opts;
- number(N);
- number(r);
- number(p);
- number(dkLen);
- number(asyncTick);
- number(maxmem);
- if (onProgress !== undefined && typeof onProgress !== 'function')
- throw new Error('progressCb should be function');
- const blockSize = 128 * r;
- const blockSize32 = blockSize / 4;
- if (N <= 1 || (N & (N - 1)) !== 0 || N >= 2 ** (blockSize / 8) || N > 2 ** 32) {
- // NOTE: we limit N to be less than 2**32 because of 32 bit variant of Integrify function
- // There is no JS engines that allows alocate more than 4GB per single Uint8Array for now, but can change in future.
- throw new Error('Scrypt: N must be larger than 1, a power of 2, less than 2^(128 * r / 8) and less than 2^32');
- }
- if (p < 0 || p > ((2 ** 32 - 1) * 32) / blockSize) {
- throw new Error('Scrypt: p must be a positive integer less than or equal to ((2^32 - 1) * 32) / (128 * r)');
- }
- if (dkLen < 0 || dkLen > (2 ** 32 - 1) * 32) {
- throw new Error('Scrypt: dkLen should be positive integer less than or equal to (2^32 - 1) * 32');
- }
- const memUsed = blockSize * (N + p);
- if (memUsed > maxmem) {
- throw new Error(`Scrypt: parameters too large, ${memUsed} (128 * r * (N + p)) > ${maxmem} (maxmem)`);
- }
- // [B0...Bp−1] ← PBKDF2HMAC-SHA256(Passphrase, Salt, 1, blockSize*ParallelizationFactor)
- // Since it has only one iteration there is no reason to use async variant
- const B = pbkdf2$1(sha256$1, password, salt, { c: 1, dkLen: blockSize * p });
- const B32 = u32(B);
- // Re-used between parallel iterations. Array(iterations) of B
- const V = u32(new Uint8Array(blockSize * N));
- const tmp = u32(new Uint8Array(blockSize));
- let blockMixCb = () => { };
- if (onProgress) {
- const totalBlockMix = 2 * N * p;
- // Invoke callback if progress changes from 10.01 to 10.02
- // Allows to draw smooth progress bar on up to 8K screen
- const callbackPer = Math.max(Math.floor(totalBlockMix / 10000), 1);
- let blockMixCnt = 0;
- blockMixCb = () => {
- blockMixCnt++;
- if (onProgress && (!(blockMixCnt % callbackPer) || blockMixCnt === totalBlockMix))
- onProgress(blockMixCnt / totalBlockMix);
- };
- }
- return { N, r, p, dkLen, blockSize32, V, B32, B, tmp, blockMixCb, asyncTick };
- }
- function scryptOutput(password, dkLen, B, V, tmp) {
- const res = pbkdf2$1(sha256$1, password, B, { c: 1, dkLen });
- B.fill(0);
- V.fill(0);
- tmp.fill(0);
- return res;
- }
- /**
- * Scrypt KDF from RFC 7914.
- * @param password - pass
- * @param salt - salt
- * @param opts - parameters
- * - `N` is cpu/mem work factor (power of 2 e.g. 2**18)
- * - `r` is block size (8 is common), fine-tunes sequential memory read size and performance
- * - `p` is parallelization factor (1 is common)
- * - `dkLen` is output key length in bytes e.g. 32.
- * - `asyncTick` - (default: 10) max time in ms for which async function can block execution
- * - `maxmem` - (default: `1024 ** 3 + 1024` aka 1GB+1KB). A limit that the app could use for scrypt
- * - `onProgress` - callback function that would be executed for progress report
- * @returns Derived key
- */
- function scrypt$1(password, salt, opts) {
- const { N, r, p, dkLen, blockSize32, V, B32, B, tmp, blockMixCb } = scryptInit(password, salt, opts);
- for (let pi = 0; pi < p; pi++) {
- const Pi = blockSize32 * pi;
- for (let i = 0; i < blockSize32; i++)
- V[i] = B32[Pi + i]; // V[0] = B[i]
- for (let i = 0, pos = 0; i < N - 1; i++) {
- BlockMix(V, pos, V, (pos += blockSize32), r); // V[i] = BlockMix(V[i-1]);
- blockMixCb();
- }
- BlockMix(V, (N - 1) * blockSize32, B32, Pi, r); // Process last element
- blockMixCb();
- for (let i = 0; i < N; i++) {
- // First u32 of the last 64-byte block (u32 is LE)
- const j = B32[Pi + blockSize32 - 16] % N; // j = Integrify(X) % iterations
- for (let k = 0; k < blockSize32; k++)
- tmp[k] = B32[Pi + k] ^ V[j * blockSize32 + k]; // tmp = B ^ V[j]
- BlockMix(tmp, 0, B32, Pi, r); // B = BlockMix(B ^ V[j])
- blockMixCb();
- }
- }
- return scryptOutput(password, dkLen, B, V, tmp);
- }
- /**
- * Scrypt KDF from RFC 7914.
- */
- async function scryptAsync(password, salt, opts) {
- const { N, r, p, dkLen, blockSize32, V, B32, B, tmp, blockMixCb, asyncTick } = scryptInit(password, salt, opts);
- for (let pi = 0; pi < p; pi++) {
- const Pi = blockSize32 * pi;
- for (let i = 0; i < blockSize32; i++)
- V[i] = B32[Pi + i]; // V[0] = B[i]
- let pos = 0;
- await asyncLoop(N - 1, asyncTick, () => {
- BlockMix(V, pos, V, (pos += blockSize32), r); // V[i] = BlockMix(V[i-1]);
- blockMixCb();
- });
- BlockMix(V, (N - 1) * blockSize32, B32, Pi, r); // Process last element
- blockMixCb();
- await asyncLoop(N, asyncTick, () => {
- // First u32 of the last 64-byte block (u32 is LE)
- const j = B32[Pi + blockSize32 - 16] % N; // j = Integrify(X) % iterations
- for (let k = 0; k < blockSize32; k++)
- tmp[k] = B32[Pi + k] ^ V[j * blockSize32 + k]; // tmp = B ^ V[j]
- BlockMix(tmp, 0, B32, Pi, r); // B = BlockMix(B ^ V[j])
- blockMixCb();
- });
- }
- return scryptOutput(password, dkLen, B, V, tmp);
- }
-
- let lockedSync = false, lockedAsync = false;
- const _scryptAsync = async function (passwd, salt, N, r, p, dkLen, onProgress) {
- return await scryptAsync(passwd, salt, { N, r, p, dkLen, onProgress });
- };
- const _scryptSync = function (passwd, salt, N, r, p, dkLen) {
- return scrypt$1(passwd, salt, { N, r, p, dkLen });
- };
- let __scryptAsync = _scryptAsync;
- let __scryptSync = _scryptSync;
- /**
- * The [[link-wiki-scrypt]] uses a memory and cpu hard method of
- * derivation to increase the resource cost to brute-force a password
- * for a given key.
- *
- * This means this algorithm is intentionally slow, and can be tuned to
- * become slower. As computation and memory speed improve over time,
- * increasing the difficulty maintains the cost of an attacker.
- *
- * For example, if a target time of 5 seconds is used, a legitimate user
- * which knows their password requires only 5 seconds to unlock their
- * account. A 6 character password has 68 billion possibilities, which
- * would require an attacker to invest over 10,000 years of CPU time. This
- * is of course a crude example (as password generally aren't random),
- * but demonstrates to value of imposing large costs to decryption.
- *
- * For this reason, if building a UI which involved decrypting or
- * encrypting datsa using scrypt, it is recommended to use a
- * [[ProgressCallback]] (as event short periods can seem lik an eternity
- * if the UI freezes). Including the phrase //"decrypting"// in the UI
- * can also help, assuring the user their waiting is for a good reason.
- *
- * @_docloc: api/crypto:Passwords
- *
- * @example:
- * // The password must be converted to bytes, and it is generally
- * // best practices to ensure the string has been normalized. Many
- * // formats explicitly indicate the normalization form to use.
- * password = "hello"
- * passwordBytes = toUtf8Bytes(password, "NFKC")
- *
- * salt = id("some-salt")
- *
- * // Compute the scrypt
- * scrypt(passwordBytes, salt, 1024, 8, 1, 16)
- * //_result:
- */
- async function scrypt(_passwd, _salt, N, r, p, dkLen, progress) {
- const passwd = getBytes(_passwd, "passwd");
- const salt = getBytes(_salt, "salt");
- return hexlify(await __scryptAsync(passwd, salt, N, r, p, dkLen, progress));
- }
- scrypt._ = _scryptAsync;
- scrypt.lock = function () {
- lockedAsync = true;
- };
- scrypt.register = function (func) {
- if (lockedAsync) {
- throw new Error("scrypt is locked");
- }
- __scryptAsync = func;
- };
- Object.freeze(scrypt);
- /**
- * Provides a synchronous variant of [[scrypt]].
- *
- * This will completely lock up and freeze the UI in a browser and will
- * prevent any event loop from progressing. For this reason, it is
- * preferred to use the [async variant](scrypt).
- *
- * @_docloc: api/crypto:Passwords
- *
- * @example:
- * // The password must be converted to bytes, and it is generally
- * // best practices to ensure the string has been normalized. Many
- * // formats explicitly indicate the normalization form to use.
- * password = "hello"
- * passwordBytes = toUtf8Bytes(password, "NFKC")
- *
- * salt = id("some-salt")
- *
- * // Compute the scrypt
- * scryptSync(passwordBytes, salt, 1024, 8, 1, 16)
- * //_result:
- */
- function scryptSync(_passwd, _salt, N, r, p, dkLen) {
- const passwd = getBytes(_passwd, "passwd");
- const salt = getBytes(_salt, "salt");
- return hexlify(__scryptSync(passwd, salt, N, r, p, dkLen));
- }
- scryptSync._ = _scryptSync;
- scryptSync.lock = function () {
- lockedSync = true;
- };
- scryptSync.register = function (func) {
- if (lockedSync) {
- throw new Error("scryptSync is locked");
- }
- __scryptSync = func;
- };
- Object.freeze(scryptSync);
-
- /**
- * Cryptographic hashing functions
- *
- * @_subsection: api/crypto:Hash Functions [about-crypto-hashing]
- */
- let locked = false;
- const _keccak256 = function (data) {
- return keccak_256(data);
- };
- let __keccak256 = _keccak256;
- /**
- * Compute the cryptographic KECCAK256 hash of %%data%%.
- *
- * The %%data%% **must** be a data representation, to compute the
- * hash of UTF-8 data use the [[id]] function.
- *
- * @returns DataHexstring
- * @example:
- * keccak256("0x")
- * //_result:
- *
- * keccak256("0x1337")
- * //_result:
- *
- * keccak256(new Uint8Array([ 0x13, 0x37 ]))
- * //_result:
- *
- * // Strings are assumed to be DataHexString, otherwise it will
- * // throw. To hash UTF-8 data, see the note above.
- * keccak256("Hello World")
- * //_error:
- */
- function keccak256(_data) {
- const data = getBytes(_data, "data");
- return hexlify(__keccak256(data));
- }
- keccak256._ = _keccak256;
- keccak256.lock = function () {
- locked = true;
- };
- keccak256.register = function (func) {
- if (locked) {
- throw new TypeError("keccak256 is locked");
- }
- __keccak256 = func;
- };
- Object.freeze(keccak256);
-
- /*! noble-secp256k1 - MIT License (c) 2019 Paul Miller (paulmillr.com) */
- const B256 = 2n ** 256n; // secp256k1 is short weierstrass curve
- const P = B256 - 0x1000003d1n; // curve's field prime
- const N$1 = B256 - 0x14551231950b75fc4402da1732fc9bebfn; // curve (group) order
- const Gx = 0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798n; // base point x
- const Gy = 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8n; // base point y
- const CURVE = { p: P, n: N$1, a: 0n, b: 7n, Gx, Gy }; // exported variables incl. a, b
- const fLen = 32; // field / group byte length
- const crv = (x) => mod(mod(x * x) * x + CURVE.b); // x³ + ax + b weierstrass formula; no a
- const err = (m = '') => { throw new Error(m); }; // error helper, messes-up stack trace
- const big = (n) => typeof n === 'bigint'; // is big integer
- const str = (s) => typeof s === 'string'; // is string
- const fe = (n) => big(n) && 0n < n && n < P; // is field element (invertible)
- const ge = (n) => big(n) && 0n < n && n < N$1; // is group element
- const au8 = (a, l) => // is Uint8Array (of specific length)
- !(a instanceof Uint8Array) || (typeof l === 'number' && l > 0 && a.length !== l) ?
- err('Uint8Array expected') : a;
- const u8n = (data) => new Uint8Array(data); // creates Uint8Array
- const toU8 = (a, len) => au8(str(a) ? h2b(a) : u8n(a), len); // norm(hex/u8a) to u8a
- const mod = (a, b = P) => { let r = a % b; return r >= 0n ? r : b + r; }; // mod division
- const isPoint = (p) => (p instanceof Point ? p : err('Point expected')); // is 3d point
- let Gpows = undefined; // precomputes for base point G
- class Point {
- constructor(px, py, pz) {
- this.px = px;
- this.py = py;
- this.pz = pz;
- } //3d=less inversions
- static fromAffine(p) { return new Point(p.x, p.y, 1n); }
- static fromHex(hex) {
- hex = toU8(hex); // convert hex string to Uint8Array
- let p = undefined;
- const head = hex[0], tail = hex.subarray(1); // first byte is prefix, rest is data
- const x = slcNum(tail, 0, fLen), len = hex.length; // next 32 bytes are x coordinate
- if (len === 33 && [0x02, 0x03].includes(head)) { // compressed points: 33b, start
- if (!fe(x))
- err('Point hex invalid: x not FE'); // with byte 0x02 or 0x03. Check if 0 0n; d = d.double(), n >>= 1n) { // double-and-add ladder
- if (n & 1n)
- p = p.add(d); // if bit is present, add to point
- else if (safe)
- f = f.add(d); // if not, add to fake for timing safety
- }
- return p;
- }
- mulAddQUns(R, u1, u2) {
- return this.mul(u1, false).add(R.mul(u2, false)).ok(); // Unsafe: do NOT use for stuff related
- } // to private keys. Doesn't use Shamir trick
- toAffine() {
- const { px: x, py: y, pz: z } = this; // (x, y, z) ∋ (x=x/z, y=y/z)
- if (this.equals(I))
- return { x: 0n, y: 0n }; // fast-path for zero point
- if (z === 1n)
- return { x, y }; // if z is 1, pass affine coordinates as-is
- const iz = inv(z); // z^-1: invert z
- if (mod(z * iz) !== 1n)
- err('invalid inverse'); // (z * z^-1) must be 1, otherwise bad math
- return { x: mod(x * iz), y: mod(y * iz) }; // x = x*z^-1; y = y*z^-1
- }
- assertValidity() {
- const { x, y } = this.aff(); // convert to 2d xy affine point.
- if (!fe(x) || !fe(y))
- err('Point invalid: x or y'); // x and y must be in range 0 < n < P
- return mod(y * y) === crv(x) ? // y² = x³ + ax + b, must be equal
- this : err('Point invalid: not on curve');
- }
- multiply(n) { return this.mul(n); } // Aliases to compress code
- aff() { return this.toAffine(); }
- ok() { return this.assertValidity(); }
- toHex(isCompressed = true) {
- const { x, y } = this.aff(); // convert to 2d xy affine point
- const head = isCompressed ? ((y & 1n) === 0n ? '02' : '03') : '04'; // 0x02, 0x03, 0x04 prefix
- return head + n2h(x) + (isCompressed ? '' : n2h(y)); // prefix||x and ||y
- }
- toRawBytes(isCompressed = true) {
- return h2b(this.toHex(isCompressed)); // re-use toHex(), convert hex to bytes
- }
- }
- Point.BASE = new Point(Gx, Gy, 1n); // Generator / base point
- Point.ZERO = new Point(0n, 1n, 0n); // Identity / zero point
- const { BASE: G, ZERO: I } = Point; // Generator, identity points
- const padh = (n, pad) => n.toString(16).padStart(pad, '0');
- const b2h = (b) => Array.from(b).map(e => padh(e, 2)).join(''); // bytes to hex
- const h2b = (hex) => {
- const l = hex.length; // error if not string,
- if (!str(hex) || l % 2)
- err('hex invalid 1'); // or has odd length like 3, 5.
- const arr = u8n(l / 2); // create result array
- for (let i = 0; i < arr.length; i++) {
- const j = i * 2;
- const h = hex.slice(j, j + 2); // hexByte. slice is faster than substr
- const b = Number.parseInt(h, 16); // byte, created from string part
- if (Number.isNaN(b) || b < 0)
- err('hex invalid 2'); // byte must be valid 0 <= byte < 256
- arr[i] = b;
- }
- return arr;
- };
- const b2n = (b) => BigInt('0x' + (b2h(b) || '0')); // bytes to number
- const slcNum = (b, from, to) => b2n(b.slice(from, to)); // slice bytes num
- const n2b = (num) => {
- return big(num) && num >= 0n && num < B256 ? h2b(padh(num, 2 * fLen)) : err('bigint expected');
- };
- const n2h = (num) => b2h(n2b(num)); // number to 32b hex
- const inv = (num, md = P) => {
- if (num === 0n || md <= 0n)
- err('no inverse n=' + num + ' mod=' + md); // no neg exponent for now
- let a = mod(num, md), b = md, x = 0n, u = 1n;
- while (a !== 0n) { // uses euclidean gcd algorithm
- const q = b / a, r = b % a; // not constant-time
- const m = x - u * q;
- b = a, a = r, x = u, u = m;
- }
- return b === 1n ? mod(x, md) : err('no inverse'); // b is gcd at this point
- };
- const sqrt = (n) => {
- let r = 1n; // So, a special, fast case. Paper: "Square Roots from 1;24,51,10 to Dan Shanks".
- for (let num = n, e = (P + 1n) / 4n; e > 0n; e >>= 1n) { // powMod: modular exponentiation.
- if (e & 1n)
- r = (r * num) % P; // Uses exponentiation by squaring.
- num = (num * num) % P; // Not constant-time.
- }
- return mod(r * r) === n ? r : err('sqrt invalid'); // check if result is valid
- };
- const toPriv = (p) => {
- if (!big(p))
- p = b2n(toU8(p, fLen)); // convert to bigint when bytes
- return ge(p) ? p : err('private key out of range'); // check if bigint is in range
- };
- function getSharedSecret(privA, pubB, isCompressed = true) {
- return Point.fromHex(pubB).mul(toPriv(privA)).toRawBytes(isCompressed); // ECDH
- }
- const W = 8; // Precomputes-related code. W = window size
- const precompute = () => {
- const points = []; // 10x sign(), 2x verify(). To achieve this,
- const windows = 256 / W + 1; // app needs to spend 40ms+ to calculate
- let p = G, b = p; // a lot of points related to base point G.
- for (let w = 0; w < windows; w++) { // Points are stored in array and used
- b = p; // any time Gx multiplication is done.
- points.push(b); // They consume 16-32 MiB of RAM.
- for (let i = 1; i < 2 ** (W - 1); i++) {
- b = b.add(p);
- points.push(b);
- }
- p = b.double(); // Precomputes don't speed-up getSharedKey,
- } // which multiplies user point by scalar,
- return points; // when precomputes are using base point
- };
- const wNAF = (n) => {
- // Compared to other point mult methods,
- const comp = Gpows || (Gpows = precompute()); // stores 2x less points using subtraction
- const neg = (cnd, p) => { let n = p.negate(); return cnd ? n : p; }; // negate
- let p = I, f = G; // f must be G, or could become I in the end
- const windows = 1 + 256 / W; // W=8 17 windows
- const wsize = 2 ** (W - 1); // W=8 128 window size
- const mask = BigInt(2 ** W - 1); // W=8 will create mask 0b11111111
- const maxNum = 2 ** W; // W=8 256
- const shiftBy = BigInt(W); // W=8 8
- for (let w = 0; w < windows; w++) {
- const off = w * wsize;
- let wbits = Number(n & mask); // extract W bits.
- n >>= shiftBy; // shift number by W bits.
- if (wbits > wsize) {
- wbits -= maxNum;
- n += 1n;
- } // split if bits > max: +224 => 256-32
- const off1 = off, off2 = off + Math.abs(wbits) - 1; // offsets, evaluate both
- const cnd1 = w % 2 !== 0, cnd2 = wbits < 0; // conditions, evaluate both
- if (wbits === 0) {
- f = f.add(neg(cnd1, comp[off1])); // bits are 0: add garbage to fake point
- }
- else { // ^ can't add off2, off2 = I
- p = p.add(neg(cnd2, comp[off2])); // bits are 1: add to result point
- }
- }
- return { p, f }; // return both real and fake points for JIT
- }; // !! you can disable precomputes by commenting-out call of the wNAF() inside Point#mul()
-
- /**
- * Add details about signing here.
- *
- * @_subsection: api/crypto:Signing [about-signing]
- */
- const logger$2 = new Logger("signing-key/0.0.1");
- //const N = BigInt("0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141");
- // Make noble-secp256k1 sync
- /**
- * A **SigningKey** provides high-level access to the elliptic curve
- * cryptography (ECC) operations and key management.
- */
- class SigningKey {
- #privateKey;
- /**
- * Creates a new **SigningKey** for %%privateKey%%.
- */
- constructor(privateKey) {
- let tmp = privateKey;
- if (typeof tmp === "string" && tmp.startsWith("0x")) {
- tmp = tmp.replace("0x", "");
- }
- assertArgument(dataLength("0x" + tmp) === 57, "invalid private key", "privateKey", "[REDACTED]");
- this.#privateKey = hexlify("0x" + tmp);
- }
- /**
- * The private key.
- */
- get privateKey() {
- return this.#privateKey;
- }
- /**
- * The uncompressed public key.
- *
- * This will always begin with the prefix ``0x04`` and be 132
- * characters long (the ``0x`` prefix and 130 hexadecimal nibbles).
- */
- get publicKey() {
- return SigningKey.computePublicKey(this.#privateKey);
- }
- /**
- * The compressed public key.
- *
- * This will always begin with either the prefix ``0x02`` or ``0x03``
- * and be 68 characters long (the ``0x`` prefix and 33 hexadecimal
- * nibbles)
- */
- get compressedPublicKey() {
- return SigningKey.computePublicKey(this.#privateKey, true);
- }
- /**
- * Return the signature of the signed %%digest%%.
- */
- sign(digest) {
- const key = getBytesCopy(this.#privateKey);
- assertArgument(dataLength(digest) === 32, "invalid digest length", "digest", digest);
- const keyBuffer = new Uint8Array(arrayify(key));
- if (keyBuffer.length !== 57) {
- logger$2.throwArgumentError("invalid private key", "key", "[REDACTED]");
- }
- const digestBuffer = new Uint8Array(arrayify(digest));
- if (digestBuffer.length !== 32) {
- logger$2.throwArgumentError("bad digest length", "digest", digest);
- }
- if (keyBuffer[56] > 127) {
- const prefix = keyBuffer.slice(0, 57);
- prefix[0] &= 0xfc;
- prefix[55] |= 0x80;
- prefix[56] = 0;
- const scalar = prefix.slice(0, 56);
- const bufferDigest = buffer.Buffer.from(digestBuffer);
- const bufferPrfx = buffer.Buffer.from(prefix);
- const bufferScalar = buffer.Buffer.from(scalar);
- const sig = ed448.signWithScalar(bufferDigest, bufferScalar, bufferPrfx);
- const hexlified = hexlify(sig);
- return hexConcat([hexlified, this.publicKey]);
- }
- const sig = ed448.sign(buffer.Buffer.from(digestBuffer), buffer.Buffer.from(keyBuffer));
- const hexlified = hexlify(sig);
- return hexConcat([hexlified, this.publicKey]);
- }
- /**
- * Returns the [[link-wiki-ecdh]] shared secret between this
- * private key and the %%other%% key.
- *
- * The %%other%% key may be any type of key, a raw public key,
- * a compressed/uncompressed pubic key or aprivate key.
- *
- * Best practice is usually to use a cryptographic hash on the
- * returned value before using it as a symetric secret.
- *
- * @example:
- * sign1 = new SigningKey(id("some-secret-1"))
- * sign2 = new SigningKey(id("some-secret-2"))
- *
- * // Notice that privA.computeSharedSecret(pubB)...
- * sign1.computeSharedSecret(sign2.publicKey)
- * //_result:
- *
- * // ...is equal to privB.computeSharedSecret(pubA).
- * sign2.computeSharedSecret(sign1.publicKey)
- * //_result:
- */
- computeSharedSecret(other) {
- const pubKey = SigningKey.computePublicKey(other);
- return hexlify(getSharedSecret(getBytesCopy(this.#privateKey), getBytes(pubKey)));
- }
- /**
- * Compute the public key for %%key%%, optionally %%compressed%%.
- *
- * The %%key%% may be any type of key, a raw public key, a
- * compressed/uncompressed public key or private key.
- *
- * @example:
- * sign = new SigningKey(id("some-secret"));
- *
- * // Compute the uncompressed public key for a private key
- * SigningKey.computePublicKey(sign.privateKey)
- * //_result:
- *
- * // Compute the compressed public key for a private key
- * SigningKey.computePublicKey(sign.privateKey, true)
- * //_result:
- *
- * // Compute the uncompressed public key
- * SigningKey.computePublicKey(sign.publicKey, false);
- * //_result:
- *
- * // Compute the Compressed a public key
- * SigningKey.computePublicKey(sign.publicKey, true);
- * //_result:
- */
- static computePublicKey(key, compressed) {
- const bytes = buffer.Buffer.from(arrayify(key));
- if (bytes.length !== 57) {
- logger$2.throwArgumentError("invalid private key", "key", "[REDACTED]");
- }
- if (bytes[56] > 127) {
- const scalar = bytes.slice(0, 56);
- scalar[0] &= 0xfc;
- scalar[55] |= 0x80;
- const pub = ed448.publicKeyFromScalar(scalar);
- return hexlify(pub);
- }
- const pub = ed448.publicKeyCreate(bytes);
- return hexlify(pub);
- }
- /**
- * Returns the public key for the private key which produced the
- * %%signature%% for the given %%digest%%.
- *
- * @example:
- * key = new SigningKey(id("some-secret"))
- * digest = id("hello world")
- * sig = key.sign(digest)
- *
- * // Notice the signer public key...
- * key.publicKey
- * //_result:
- *
- * // ...is equal to the recovered public key
- * SigningKey.recoverPublicKey(digest, sig)
- * //_result:
- *
- */
- static recoverPublicKey(digest, signature) {
- assertArgument(dataLength(digest) === 32, "invalid digest length", "digest", digest);
- const digestBuffer = buffer.Buffer.from(arrayify(digest));
- const sigBuffer = buffer.Buffer.from(arrayify(signature));
- if (sigBuffer.length !== 171) {
- logger$2.throwArgumentError("invalid signature", "signature", signature);
- }
- const sig = sigBuffer.slice(0, 114);
- const pub = sigBuffer.slice(114);
- if (ed448.verify(digestBuffer, sig, pub)) {
- return hexlify(pub);
- }
- logger$2.throwArgumentError("invalid signature", "signature", signature);
- return "";
- }
- /**
- * Returns the point resulting from adding the ellipic curve points
- * %%p0%% and %%p1%%.
- *
- * This is not a common function most developers should require, but
- * can be useful for certain privacy-specific techniques.
- *
- * For example, it is used by [[HDNodeWallet]] to compute child
- * addresses from parent public keys and chain codes.
- */
- static addPoints(p0, p1, compressed) {
- const pub0 = Point.fromHex(SigningKey.computePublicKey(p0).substring(2));
- const pub1 = Point.fromHex(SigningKey.computePublicKey(p1).substring(2));
- return "0x" + pub0.add(pub1).toHex(!!compressed);
- }
- }
-
- // Constants
- const BN_0$6 = BigInt(0);
- const BN_1$3 = BigInt(1);
- const BN_2$1 = BigInt(2);
- const BN_27 = BigInt(27);
- const BN_28 = BigInt(28);
- const BN_35 = BigInt(35);
- const _guard$4 = {};
- /**
- * A Signature @TODO
- *
- *
- * @_docloc: api/crypto:Signing
- */
- class Signature {
- #r;
- #s;
- #v;
- #networkV;
- /**
- * The ``r`` value for a signautre.
- *
- * This represents the ``x`` coordinate of a "reference" or
- * challenge point, from which the ``y`` can be computed.
- */
- get r() {
- return this.#r;
- }
- set r(value) {
- assertArgument(dataLength(value) === 32, "invalid r", "value", value);
- this.#r = hexlify(value);
- }
- /**
- * The ``s`` value for a signature.
- */
- get s() {
- return this.#s;
- }
- set s(_value) {
- assertArgument(dataLength(_value) === 32, "invalid s", "value", _value);
- const value = hexlify(_value);
- assertArgument(parseInt(value.substring(0, 3)) < 8, "non-canonical s", "value", value);
- this.#s = value;
- }
- /**
- * The ``v`` value for a signature.
- *
- * Since a given ``x`` value for ``r`` has two possible values for
- * its correspondin ``y``, the ``v`` indicates which of the two ``y``
- * values to use.
- *
- * It is normalized to the values ``27`` or ``28`` for legacy
- * purposes.
- */
- get v() {
- return this.#v;
- }
- set v(value) {
- const v = getNumber(value, "value");
- assertArgument(v === 27 || v === 28, "invalid v", "v", value);
- this.#v = v;
- }
- /**
- * The EIP-155 ``v`` for legacy transactions. For non-legacy
- * transactions, this value is ``null``.
- */
- get networkV() {
- return this.#networkV;
- }
- /**
- * The chain ID for EIP-155 legacy transactions. For non-legacy
- * transactions, this value is ``null``.
- */
- get legacynetworkId() {
- const v = this.networkV;
- if (v == null) {
- return null;
- }
- return Signature.getnetworkId(v);
- }
- /**
- * The ``yParity`` for the signature.
- *
- * See ``v`` for more details on how this value is used.
- */
- get yParity() {
- return this.v === 27 ? 0 : 1;
- }
- /**
- * The [[link-eip-2098]] compact representation of the ``yParity``
- * and ``s`` compacted into a single ``bytes32``.
- */
- get yParityAndS() {
- // The EIP-2098 compact representation
- const yParityAndS = getBytes(this.s);
- if (this.yParity) {
- yParityAndS[0] |= 0x80;
- }
- return hexlify(yParityAndS);
- }
- /**
- * The [[link-eip-2098]] compact representation.
- */
- get compactSerialized() {
- return concat([this.r, this.yParityAndS]);
- }
- /**
- * The serialized representation.
- */
- get serialized() {
- return concat([this.r, this.s, this.yParity ? "0x1c" : "0x1b"]);
- }
- /**
- * @private
- */
- constructor(guard, r, s, v) {
- assertPrivate(guard, _guard$4, "Signature");
- this.#r = r;
- this.#s = s;
- this.#v = v;
- this.#networkV = null;
- }
- [Symbol.for("nodejs.util.inspect.custom")]() {
- return `Signature { r: "${this.r}", s: "${this.s}", yParity: ${this.yParity}, networkV: ${this.networkV} }`;
- }
- /**
- * Returns a new identical [[Signature]].
- */
- clone() {
- const clone = new Signature(_guard$4, this.r, this.s, this.v);
- if (this.networkV) {
- clone.#networkV = this.networkV;
- }
- return clone;
- }
- /**
- * Returns a representation that is compatible with ``JSON.stringify``.
- */
- toJSON() {
- const networkV = this.networkV;
- return {
- _type: "signature",
- networkV: networkV != null ? networkV.toString() : null,
- r: this.r,
- s: this.s,
- v: this.v,
- };
- }
- /**
- * Compute the chain ID from the ``v`` in a legacy EIP-155 transactions.
- *
- * @example:
- * Signature.getnetworkId(45)
- * //_result:
- *
- * Signature.getnetworkId(46)
- * //_result:
- */
- static getnetworkId(v) {
- const bv = getBigInt(v, "v");
- // The v is not an EIP-155 v, so it is the unspecified chain ID
- if (bv == BN_27 || bv == BN_28) {
- return BN_0$6;
- }
- // Bad value for an EIP-155 v
- assertArgument(bv >= BN_35, "invalid EIP-155 v", "v", v);
- return (bv - BN_35) / BN_2$1;
- }
- /**
- * Compute the ``v`` for a chain ID for a legacy EIP-155 transactions.
- *
- * Legacy transactions which use [[link-eip-155]] hijack the ``v``
- * property to include the chain ID.
- *
- * @example:
- * Signature.getnetworkIdV(5, 27)
- * //_result:
- *
- * Signature.getnetworkIdV(5, 28)
- * //_result:
- *
- */
- static getnetworkIdV(networkId, v) {
- return getBigInt(networkId) * BN_2$1 + BigInt(35 + v - 27);
- }
- /**
- * Compute the normalized legacy transaction ``v`` from a ``yParirty``,
- * a legacy transaction ``v`` or a legacy [[link-eip-155]] transaction.
- *
- * @example:
- * // The values 0 and 1 imply v is actually yParity
- * Signature.getNormalizedV(0)
- * //_result:
- *
- * // Legacy non-EIP-1559 transaction (i.e. 27 or 28)
- * Signature.getNormalizedV(27)
- * //_result:
- *
- * // Legacy EIP-155 transaction (i.e. >= 35)
- * Signature.getNormalizedV(46)
- * //_result:
- *
- * // Invalid values throw
- * Signature.getNormalizedV(5)
- * //_error:
- */
- static getNormalizedV(v) {
- const bv = getBigInt(v);
- if (bv === BN_0$6 || bv === BN_27) {
- return 27;
- }
- if (bv === BN_1$3 || bv === BN_28) {
- return 28;
- }
- assertArgument(bv >= BN_35, "invalid v", "v", v);
- // Otherwise, EIP-155 v means odd is 27 and even is 28
- return bv & BN_1$3 ? 27 : 28;
- }
- }
-
- /**
- * A fundamental building block of Core is the underlying
- * cryptographic primitives.
- *
- * @_section: api/crypto:Cryptographic Functions [about-crypto]
- */
- function lock() {
- computeHmac.lock();
- pbkdf2.lock();
- randomBytes.lock();
- ripemd160.lock();
- scrypt.lock();
- scryptSync.lock();
- sha256.lock();
- sha512.lock();
- randomBytes.lock();
- }
-
- /**
- * Returns the address for the %%key%%.
- *
- * The key may be any standard form of public key or a private key.
- */
- function removeHexPrefix(val) {
- return val.substring(0, 2) === "0x" ? val.substring(2) : val;
- }
- function publicToAddress(key, prefix) {
- const val = hexDataSlice(sha256(key), 12);
- const checksum = calculateCheckSum(val, prefix);
- return "0x" + prefix + checksum + removeHexPrefix(val);
- }
- function computeAddress(key, prefix) {
- let pubkey;
- if (typeof key === "string") {
- pubkey = SigningKey.computePublicKey(key, false);
- }
- else {
- pubkey = key.publicKey;
- }
- return publicToAddress(pubkey, prefix); // getAddress(sha256("0x" + pubkey.substring(4)).substring(26));
- }
- /**
- * Returns the recovered address for the private key that was
- * used to sign %%digest%% that resulted in %%signature%%.
- */
- function recoverAddress(digest, signature, prefix) {
- // return computeAddress(SigningKey.recoverPublicKey(digest, signature));
- const publicKey = SigningKey.recoverPublicKey(arrayify(digest), signature);
- return publicToAddress(publicKey, prefix);
- }
- function extractPrefix(address) {
- address = getAddress(address);
- return address.substring(2, 4);
- }
-
- /**
- * @_ignore:
- */
- const WordSize = 32;
- const Padding = new Uint8Array(WordSize);
- // Properties used to immediate pass through to the underlying object
- // - `then` is used to detect if an object is a Promise for await
- const passProperties$1 = ["then"];
- const _guard$3 = {};
- function throwError(name, error) {
- const wrapped = new Error(`deferred error during ABI decoding triggered accessing ${name}`);
- wrapped.error = error;
- throw wrapped;
- }
- /**
- * A [[Result]] is a sub-class of Array, which allows accessing any
- * of its values either positionally by its index or, if keys are
- * provided by its name.
- *
- * @_docloc: api/abi
- */
- class Result extends Array {
- #names;
- /**
- * @private
- */
- constructor(...args) {
- // To properly sub-class Array so the other built-in
- // functions work, the constructor has to behave fairly
- // well. So, in the event we are created via fromItems()
- // we build the read-only Result object we want, but on
- // any other input, we use the default constructor
- // constructor(guard: any, items: Array, keys?: Array);
- const guard = args[0];
- let items = args[1];
- let names = (args[2] || []).slice();
- let wrap = true;
- if (guard !== _guard$3) {
- items = args;
- names = [];
- wrap = false;
- }
- // Can't just pass in ...items since an array of length 1
- // is a special case in the super.
- super(items.length);
- items.forEach((item, index) => {
- this[index] = item;
- });
- // Find all unique keys
- const nameCounts = names.reduce((accum, name) => {
- if (typeof name === "string") {
- accum.set(name, (accum.get(name) || 0) + 1);
- }
- return accum;
- }, new Map());
- // Remove any key thats not unique
- this.#names = Object.freeze(items.map((item, index) => {
- const name = names[index];
- if (name != null && nameCounts.get(name) === 1) {
- return name;
- }
- return null;
- }));
- if (!wrap) {
- return;
- }
- // A wrapped Result is immutable
- Object.freeze(this);
- // Proxy indices and names so we can trap deferred errors
- return new Proxy(this, {
- get: (target, prop, receiver) => {
- if (typeof prop === "string") {
- // Index accessor
- if (prop.match(/^[0-9]+$/)) {
- const index = getNumber(prop, "%index");
- if (index < 0 || index >= this.length) {
- throw new RangeError("out of result range");
- }
- const item = target[index];
- if (item instanceof Error) {
- throwError(`index ${index}`, item);
- }
- return item;
- }
- // Pass important checks (like `then` for Promise) through
- if (passProperties$1.indexOf(prop) >= 0) {
- return Reflect.get(target, prop, receiver);
- }
- const value = target[prop];
- if (value instanceof Function) {
- // Make sure functions work with private variables
- // See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy#no_private_property_forwarding
- return function (...args) {
- return value.apply(this === receiver ? target : this, args);
- };
- }
- else if (!(prop in target)) {
- // Possible name accessor
- return target.getValue.apply(this === receiver ? target : this, [
- prop,
- ]);
- }
- }
- return Reflect.get(target, prop, receiver);
- },
- });
- }
- /**
- * Returns the Result as a normal Array.
- *
- * This will throw if there are any outstanding deferred
- * errors.
- */
- toArray() {
- const result = [];
- this.forEach((item, index) => {
- if (item instanceof Error) {
- throwError(`index ${index}`, item);
- }
- result.push(item);
- });
- return result;
- }
- /**
- * Returns the Result as an Object with each name-value pair.
- *
- * This will throw if any value is unnamed, or if there are
- * any outstanding deferred errors.
- */
- toObject() {
- return this.#names.reduce((accum, name, index) => {
- assert(name != null, "value at index ${ index } unnamed", "UNSUPPORTED_OPERATION", {
- operation: "toObject()",
- });
- // Add values for names that don't conflict
- if (!(name in accum)) {
- accum[name] = this.getValue(name);
- }
- return accum;
- }, {});
- }
- /**
- * @_ignore
- */
- slice(start, end) {
- if (start == null) {
- start = 0;
- }
- if (start < 0) {
- start += this.length;
- if (start < 0) {
- start = 0;
- }
- }
- if (end == null) {
- end = this.length;
- }
- if (end < 0) {
- end += this.length;
- if (end < 0) {
- end = 0;
- }
- }
- if (end > this.length) {
- end = this.length;
- }
- const result = [], names = [];
- for (let i = start; i < end; i++) {
- result.push(this[i]);
- names.push(this.#names[i]);
- }
- return new Result(_guard$3, result, names);
- }
- /**
- * @_ignore
- */
- filter(callback, thisArg) {
- const result = [], names = [];
- for (let i = 0; i < this.length; i++) {
- const item = this[i];
- if (item instanceof Error) {
- throwError(`index ${i}`, item);
- }
- if (callback.call(thisArg, item, i, this)) {
- result.push(item);
- names.push(this.#names[i]);
- }
- }
- return new Result(_guard$3, result, names);
- }
- /**
- * Returns the value for %%name%%.
- *
- * Since it is possible to have a key whose name conflicts with
- * a method on a [[Result]] or its superclass Array, or any
- * JavaScript keyword, this ensures all named values are still
- * accessible by name.
- */
- getValue(name) {
- const index = this.#names.indexOf(name);
- if (index === -1) {
- return undefined;
- }
- const value = this[index];
- if (value instanceof Error) {
- throwError(`property ${JSON.stringify(name)}`, value.error);
- }
- return value;
- }
- /**
- * Creates a new [[Result]] for %%items%% with each entry
- * also accessible by its corresponding name in %%keys%%.
- */
- static fromItems(items, keys) {
- return new Result(_guard$3, items, keys);
- }
- }
- /**
- * Returns all errors found in a [[Result]].
- *
- * Since certain errors encountered when creating a [[Result]] do
- * not impact the ability to continue parsing data, they are
- * deferred until they are actually accessed. Hence a faulty string
- * in an Event that is never used does not impact the program flow.
- *
- * However, sometimes it may be useful to access, identify or
- * validate correctness of a [[Result]].
- *
- * @_docloc api/abi
- */
- function checkResultErrors(result) {
- // Find the first error (if any)
- const errors = [];
- const checkErrors = function (path, object) {
- if (!Array.isArray(object)) {
- return;
- }
- for (let key in object) {
- const childPath = path.slice();
- childPath.push(key);
- try {
- checkErrors(childPath, object[key]);
- }
- catch (error) {
- errors.push({ path: childPath, error: error });
- }
- }
- };
- checkErrors([], result);
- return errors;
- }
- function getValue$1(value) {
- let bytes = toBeArray(value);
- assert(bytes.length <= WordSize, "value out-of-bounds", "BUFFER_OVERRUN", {
- buffer: bytes,
- length: WordSize,
- offset: bytes.length,
- });
- if (bytes.length !== WordSize) {
- bytes = getBytesCopy(concat([Padding.slice(bytes.length % WordSize), bytes]));
- }
- return bytes;
- }
- /**
- * @_ignore
- */
- class Coder {
- // The coder name:
- // - address, uint256, tuple, array, etc.
- name;
- // The fully expanded type, including composite types:
- // - address, uint256, tuple(address,bytes), uint256[3][4][], etc.
- type;
- // The localName bound in the signature, in this example it is "baz":
- // - tuple(address foo, uint bar) baz
- localName;
- // Whether this type is dynamic:
- // - Dynamic: bytes, string, address[], tuple(boolean[]), etc.
- // - Not Dynamic: address, uint256, boolean[3], tuple(address, uint8)
- dynamic;
- constructor(name, type, localName, dynamic) {
- defineProperties(this, { name, type, localName, dynamic }, {
- name: "string",
- type: "string",
- localName: "string",
- dynamic: "boolean",
- });
- }
- _throwError(message, value) {
- assertArgument(false, message, this.localName, value);
- }
- }
- /**
- * @_ignore
- */
- class Writer {
- // An array of WordSize lengthed objects to concatenation
- #data;
- #dataLength;
- constructor() {
- this.#data = [];
- this.#dataLength = 0;
- }
- get data() {
- return concat(this.#data);
- }
- get length() {
- return this.#dataLength;
- }
- #writeData(data) {
- this.#data.push(data);
- this.#dataLength += data.length;
- return data.length;
- }
- appendWriter(writer) {
- return this.#writeData(getBytesCopy(writer.data));
- }
- // Arrayish item; pad on the right to *nearest* WordSize
- writeBytes(value) {
- let bytes = getBytesCopy(value);
- const paddingOffset = bytes.length % WordSize;
- if (paddingOffset) {
- bytes = getBytesCopy(concat([bytes, Padding.slice(paddingOffset)]));
- }
- return this.#writeData(bytes);
- }
- // Numeric item; pad on the left *to* WordSize
- writeValue(value) {
- return this.#writeData(getValue$1(value));
- }
- // Inserts a numeric place-holder, returning a callback that can
- // be used to asjust the value later
- writeUpdatableValue() {
- const offset = this.#data.length;
- this.#data.push(Padding);
- this.#dataLength += WordSize;
- return (value) => {
- this.#data[offset] = getValue$1(value);
- };
- }
- }
- /**
- * @_ignore
- */
- class Reader {
- // Allows incomplete unpadded data to be read; otherwise an error
- // is raised if attempting to overrun the buffer. This is required
- // to deal with an old Solidity bug, in which event data for
- // external (not public thoguh) was tightly packed.
- allowLoose;
- #data;
- #offset;
- constructor(data, allowLoose) {
- defineProperties(this, { allowLoose: !!allowLoose });
- this.#data = getBytesCopy(data);
- this.#offset = 0;
- }
- get data() {
- return hexlify(this.#data);
- }
- get dataLength() {
- return this.#data.length;
- }
- get consumed() {
- return this.#offset;
- }
- get bytes() {
- return new Uint8Array(this.#data);
- }
- #peekBytes(offset, length, loose) {
- let alignedLength = Math.ceil(length / WordSize) * WordSize;
- if (this.#offset + alignedLength > this.#data.length) {
- if (this.allowLoose &&
- loose &&
- this.#offset + length <= this.#data.length) {
- alignedLength = length;
- }
- else {
- assert(false, "data out-of-bounds", "BUFFER_OVERRUN", {
- buffer: getBytesCopy(this.#data),
- length: this.#data.length,
- offset: this.#offset + alignedLength,
- });
- }
- }
- return this.#data.slice(this.#offset, this.#offset + alignedLength);
- }
- // Create a sub-reader with the same underlying data, but offset
- subReader(offset) {
- return new Reader(this.#data.slice(this.#offset + offset), this.allowLoose);
- }
- // Read bytes
- readBytes(length, loose) {
- let bytes = this.#peekBytes(0, length, !!loose);
- this.#offset += bytes.length;
- // @TODO: Make sure the length..end bytes are all 0?
- return bytes.slice(0, length);
- }
- // Read a numeric values
- readValue() {
- return toBigInt(this.readBytes(WordSize));
- }
- readIndex() {
- return toNumber(this.readBytes(WordSize));
- }
- }
-
- /**
- * A Typed object allows a value to have its type explicitly
- * specified.
- *
- * For example, in Solidity, the value ``45`` could represent a
- * ``uint8`` or a ``uint256``. The value ``0x1234`` could represent
- * a ``bytes2`` or ``bytes``.
- *
- * Since JavaScript has no meaningful way to explicitly inform any
- * APIs which what the type is, this allows transparent interoperation
- * with Soldity.
- *
- * @_subsection: api/abi:Typed Values
- */
- const _gaurd = {};
- function n(value, width) {
- let signed = false;
- if (width < 0) {
- signed = true;
- width *= -1;
- }
- // @TODO: Check range is valid for value
- return new Typed(_gaurd, `${signed ? "" : "u"}int${width}`, value, {
- signed,
- width,
- });
- }
- function b(value, size) {
- // @TODO: Check range is valid for value
- return new Typed(_gaurd, `bytes${size ? size : ""}`, value, { size });
- }
- const _typedSymbol = Symbol.for("_corebc_typed");
- class Typed {
- type;
- value;
- #options;
- _typedSymbol;
- constructor(gaurd, type, value, options) {
- if (options == null) {
- options = null;
- }
- assertPrivate(_gaurd, gaurd, "Typed");
- defineProperties(this, { _typedSymbol, type, value });
- this.#options = options;
- // Check the value is valid
- this.format();
- }
- format() {
- if (this.type === "array") {
- throw new Error("");
- }
- else if (this.type === "dynamicArray") {
- throw new Error("");
- }
- else if (this.type === "tuple") {
- return `tuple(${this.value.map((v) => v.format()).join(",")})`;
- }
- return this.type;
- }
- defaultValue() {
- return 0;
- }
- minValue() {
- return 0;
- }
- maxValue() {
- return 0;
- }
- isBigInt() {
- return !!this.type.match(/^u?int[0-9]+$/);
- }
- isData() {
- return this.type.startsWith("bytes");
- }
- isString() {
- return this.type === "string";
- }
- get tupleName() {
- if (this.type !== "tuple") {
- throw TypeError("not a tuple");
- }
- return this.#options;
- }
- // Returns the length of this type as an array
- // - `null` indicates the length is unforced, it could be dynamic
- // - `-1` indicates the length is dynamic
- // - any other value indicates it is a static array and is its length
- get arrayLength() {
- if (this.type !== "array") {
- throw TypeError("not an array");
- }
- if (this.#options === true) {
- return -1;
- }
- if (this.#options === false) {
- return this.value.length;
- }
- return null;
- }
- static from(type, value) {
- return new Typed(_gaurd, type, value);
- }
- static uint8(v) {
- return n(v, 8);
- }
- static uint16(v) {
- return n(v, 16);
- }
- static uint24(v) {
- return n(v, 24);
- }
- static uint32(v) {
- return n(v, 32);
- }
- static uint40(v) {
- return n(v, 40);
- }
- static uint48(v) {
- return n(v, 48);
- }
- static uint56(v) {
- return n(v, 56);
- }
- static uint64(v) {
- return n(v, 64);
- }
- static uint72(v) {
- return n(v, 72);
- }
- static uint80(v) {
- return n(v, 80);
- }
- static uint88(v) {
- return n(v, 88);
- }
- static uint96(v) {
- return n(v, 96);
- }
- static uint104(v) {
- return n(v, 104);
- }
- static uint112(v) {
- return n(v, 112);
- }
- static uint120(v) {
- return n(v, 120);
- }
- static uint128(v) {
- return n(v, 128);
- }
- static uint136(v) {
- return n(v, 136);
- }
- static uint144(v) {
- return n(v, 144);
- }
- static uint152(v) {
- return n(v, 152);
- }
- static uint160(v) {
- return n(v, 160);
- }
- static uint168(v) {
- return n(v, 168);
- }
- static uint176(v) {
- return n(v, 176);
- }
- static uint184(v) {
- return n(v, 184);
- }
- static uint192(v) {
- return n(v, 192);
- }
- static uint200(v) {
- return n(v, 200);
- }
- static uint208(v) {
- return n(v, 208);
- }
- static uint216(v) {
- return n(v, 216);
- }
- static uint224(v) {
- return n(v, 224);
- }
- static uint232(v) {
- return n(v, 232);
- }
- static uint240(v) {
- return n(v, 240);
- }
- static uint248(v) {
- return n(v, 248);
- }
- static uint256(v) {
- return n(v, 256);
- }
- static uint(v) {
- return n(v, 256);
- }
- static int8(v) {
- return n(v, -8);
- }
- static int16(v) {
- return n(v, -16);
- }
- static int24(v) {
- return n(v, -24);
- }
- static int32(v) {
- return n(v, -32);
- }
- static int40(v) {
- return n(v, -40);
- }
- static int48(v) {
- return n(v, -48);
- }
- static int56(v) {
- return n(v, -56);
- }
- static int64(v) {
- return n(v, -64);
- }
- static int72(v) {
- return n(v, -72);
- }
- static int80(v) {
- return n(v, -80);
- }
- static int88(v) {
- return n(v, -88);
- }
- static int96(v) {
- return n(v, -96);
- }
- static int104(v) {
- return n(v, -104);
- }
- static int112(v) {
- return n(v, -112);
- }
- static int120(v) {
- return n(v, -120);
- }
- static int128(v) {
- return n(v, -128);
- }
- static int136(v) {
- return n(v, -136);
- }
- static int144(v) {
- return n(v, -144);
- }
- static int152(v) {
- return n(v, -152);
- }
- static int160(v) {
- return n(v, -160);
- }
- static int168(v) {
- return n(v, -168);
- }
- static int176(v) {
- return n(v, -176);
- }
- static int184(v) {
- return n(v, -184);
- }
- static int192(v) {
- return n(v, -192);
- }
- static int200(v) {
- return n(v, -200);
- }
- static int208(v) {
- return n(v, -208);
- }
- static int216(v) {
- return n(v, -216);
- }
- static int224(v) {
- return n(v, -224);
- }
- static int232(v) {
- return n(v, -232);
- }
- static int240(v) {
- return n(v, -240);
- }
- static int248(v) {
- return n(v, -248);
- }
- static int256(v) {
- return n(v, -256);
- }
- static int(v) {
- return n(v, -256);
- }
- static bytes1(v) {
- return b(v, 1);
- }
- static bytes2(v) {
- return b(v, 2);
- }
- static bytes3(v) {
- return b(v, 3);
- }
- static bytes4(v) {
- return b(v, 4);
- }
- static bytes5(v) {
- return b(v, 5);
- }
- static bytes6(v) {
- return b(v, 6);
- }
- static bytes7(v) {
- return b(v, 7);
- }
- static bytes8(v) {
- return b(v, 8);
- }
- static bytes9(v) {
- return b(v, 9);
- }
- static bytes10(v) {
- return b(v, 10);
- }
- static bytes11(v) {
- return b(v, 11);
- }
- static bytes12(v) {
- return b(v, 12);
- }
- static bytes13(v) {
- return b(v, 13);
- }
- static bytes14(v) {
- return b(v, 14);
- }
- static bytes15(v) {
- return b(v, 15);
- }
- static bytes16(v) {
- return b(v, 16);
- }
- static bytes17(v) {
- return b(v, 17);
- }
- static bytes18(v) {
- return b(v, 18);
- }
- static bytes19(v) {
- return b(v, 19);
- }
- static bytes20(v) {
- return b(v, 20);
- }
- static bytes21(v) {
- return b(v, 21);
- }
- static bytes22(v) {
- return b(v, 22);
- }
- static bytes23(v) {
- return b(v, 23);
- }
- static bytes24(v) {
- return b(v, 24);
- }
- static bytes25(v) {
- return b(v, 25);
- }
- static bytes26(v) {
- return b(v, 26);
- }
- static bytes27(v) {
- return b(v, 27);
- }
- static bytes28(v) {
- return b(v, 28);
- }
- static bytes29(v) {
- return b(v, 29);
- }
- static bytes30(v) {
- return b(v, 30);
- }
- static bytes31(v) {
- return b(v, 31);
- }
- static bytes32(v) {
- return b(v, 32);
- }
- static address(v) {
- return new Typed(_gaurd, "address", v);
- }
- static bool(v) {
- return new Typed(_gaurd, "bool", !!v);
- }
- static bytes(v) {
- return new Typed(_gaurd, "bytes", v);
- }
- static string(v) {
- return new Typed(_gaurd, "string", v);
- }
- static array(v, dynamic) {
- throw new Error("not implemented yet");
- }
- static tuple(v, name) {
- throw new Error("not implemented yet");
- }
- static overrides(v) {
- return new Typed(_gaurd, "overrides", Object.assign({}, v));
- }
- /**
- * Returns true only if %%value%% is a [[Typed]] instance.
- */
- static isTyped(value) {
- return value && value._typedSymbol === _typedSymbol;
- }
- /**
- * If the value is a [[Typed]] instance, validates the underlying value
- * and returns it, otherwise returns value directly.
- *
- * This is useful for functions that with to accept either a [[Typed]]
- * object or values.
- */
- static dereference(value, type) {
- if (Typed.isTyped(value)) {
- if (value.type !== type) {
- throw new Error(`invalid type: expecetd ${type}, got ${value.type}`);
- }
- return value.value;
- }
- return value;
- }
- }
-
- /**
- * @_ignore
- */
- class AddressCoder extends Coder {
- constructor(localName) {
- super("address", "address", localName, false);
- }
- defaultValue() {
- return "0x0000000000000000000000000000000000000000";
- }
- encode(writer, _value) {
- let value = Typed.dereference(_value, "string");
- try {
- value = getAddress(value);
- }
- catch (error) {
- return this._throwError(error.message, _value);
- }
- return writer.writeValue(value);
- }
- decode(reader) {
- return getAddress(toBeHex(reader.readValue(), 22));
- }
- }
-
- /**
- * Clones the functionality of an existing Coder, but without a localName
- *
- * @_ignore
- */
- class AnonymousCoder extends Coder {
- coder;
- constructor(coder) {
- super(coder.name, coder.type, "_", coder.dynamic);
- this.coder = coder;
- }
- defaultValue() {
- return this.coder.defaultValue();
- }
- encode(writer, value) {
- return this.coder.encode(writer, value);
- }
- decode(reader) {
- return this.coder.decode(reader);
- }
- }
-
- /**
- * @_ignore
- */
- function pack(writer, coders, values) {
- let arrayValues = [];
- if (Array.isArray(values)) {
- arrayValues = values;
- }
- else if (values && typeof values === "object") {
- let unique = {};
- arrayValues = coders.map((coder) => {
- const name = coder.localName;
- assert(name, "cannot encode object for signature with missing names", "INVALID_ARGUMENT", { argument: "values", info: { coder }, value: values });
- assert(!unique[name], "cannot encode object for signature with duplicate names", "INVALID_ARGUMENT", { argument: "values", info: { coder }, value: values });
- unique[name] = true;
- return values[name];
- });
- }
- else {
- assertArgument(false, "invalid tuple value", "tuple", values);
- }
- assertArgument(coders.length === arrayValues.length, "types/value length mismatch", "tuple", values);
- let staticWriter = new Writer();
- let dynamicWriter = new Writer();
- let updateFuncs = [];
- coders.forEach((coder, index) => {
- let value = arrayValues[index];
- if (coder.dynamic) {
- // Get current dynamic offset (for the future pointer)
- let dynamicOffset = dynamicWriter.length;
- // Encode the dynamic value into the dynamicWriter
- coder.encode(dynamicWriter, value);
- // Prepare to populate the correct offset once we are done
- let updateFunc = staticWriter.writeUpdatableValue();
- updateFuncs.push((baseOffset) => {
- updateFunc(baseOffset + dynamicOffset);
- });
- }
- else {
- coder.encode(staticWriter, value);
- }
- });
- // Backfill all the dynamic offsets, now that we know the static length
- updateFuncs.forEach((func) => {
- func(staticWriter.length);
- });
- let length = writer.appendWriter(staticWriter);
- length += writer.appendWriter(dynamicWriter);
- return length;
- }
- /**
- * @_ignore
- */
- function unpack(reader, coders) {
- let values = [];
- let keys = [];
- // A reader anchored to this base
- let baseReader = reader.subReader(0);
- coders.forEach((coder) => {
- let value = null;
- if (coder.dynamic) {
- let offset = reader.readIndex();
- let offsetReader = baseReader.subReader(offset);
- try {
- value = coder.decode(offsetReader);
- }
- catch (error) {
- // Cannot recover from this
- if (isError(error, "BUFFER_OVERRUN")) {
- throw error;
- }
- value = error;
- value.baseType = coder.name;
- value.name = coder.localName;
- value.type = coder.type;
- }
- }
- else {
- try {
- value = coder.decode(reader);
- }
- catch (error) {
- // Cannot recover from this
- if (isError(error, "BUFFER_OVERRUN")) {
- throw error;
- }
- value = error;
- value.baseType = coder.name;
- value.name = coder.localName;
- value.type = coder.type;
- }
- }
- if (value == undefined) {
- throw new Error("investigate");
- }
- values.push(value);
- keys.push(coder.localName || null);
- });
- return Result.fromItems(values, keys);
- }
- /**
- * @_ignore
- */
- class ArrayCoder extends Coder {
- coder;
- length;
- constructor(coder, length, localName) {
- const type = coder.type + "[" + (length >= 0 ? length : "") + "]";
- const dynamic = length === -1 || coder.dynamic;
- super("array", type, localName, dynamic);
- defineProperties(this, { coder, length });
- }
- defaultValue() {
- // Verifies the child coder is valid (even if the array is dynamic or 0-length)
- const defaultChild = this.coder.defaultValue();
- const result = [];
- for (let i = 0; i < this.length; i++) {
- result.push(defaultChild);
- }
- return result;
- }
- encode(writer, _value) {
- const value = Typed.dereference(_value, "array");
- if (!Array.isArray(value)) {
- this._throwError("expected array value", value);
- }
- let count = this.length;
- if (count === -1) {
- count = value.length;
- writer.writeValue(value.length);
- }
- assertArgumentCount(value.length, count, "coder array" + (this.localName ? " " + this.localName : ""));
- let coders = [];
- for (let i = 0; i < value.length; i++) {
- coders.push(this.coder);
- }
- return pack(writer, coders, value);
- }
- decode(reader) {
- let count = this.length;
- if (count === -1) {
- count = reader.readIndex();
- // Check that there is *roughly* enough data to ensure
- // stray random data is not being read as a length. Each
- // slot requires at least 32 bytes for their value (or 32
- // bytes as a link to the data). This could use a much
- // tighter bound, but we are erroring on the side of safety.
- assert(count * WordSize <= reader.dataLength, "insufficient data length", "BUFFER_OVERRUN", {
- buffer: reader.bytes,
- offset: count * WordSize,
- length: reader.dataLength,
- });
- }
- let coders = [];
- for (let i = 0; i < count; i++) {
- coders.push(new AnonymousCoder(this.coder));
- }
- return unpack(reader, coders);
- }
- }
-
- /**
- * @_ignore
- */
- class BooleanCoder extends Coder {
- constructor(localName) {
- super("bool", "bool", localName, false);
- }
- defaultValue() {
- return false;
- }
- encode(writer, _value) {
- const value = Typed.dereference(_value, "bool");
- return writer.writeValue(value ? 1 : 0);
- }
- decode(reader) {
- return !!reader.readValue();
- }
- }
-
- /**
- * @_ignore
- */
- class DynamicBytesCoder extends Coder {
- constructor(type, localName) {
- super(type, type, localName, true);
- }
- defaultValue() {
- return "0x";
- }
- encode(writer, value) {
- value = getBytesCopy(value);
- let length = writer.writeValue(value.length);
- length += writer.writeBytes(value);
- return length;
- }
- decode(reader) {
- return reader.readBytes(reader.readIndex(), true);
- }
- }
- /**
- * @_ignore
- */
- class BytesCoder extends DynamicBytesCoder {
- constructor(localName) {
- super("bytes", localName);
- }
- decode(reader) {
- return hexlify(super.decode(reader));
- }
- }
-
- /**
- * @_ignore
- */
- class FixedBytesCoder extends Coder {
- size;
- constructor(size, localName) {
- let name = "bytes" + String(size);
- super(name, name, localName, false);
- defineProperties(this, { size }, { size: "number" });
- }
- defaultValue() {
- return "0x0000000000000000000000000000000000000000000000000000000000000000".substring(0, 2 + this.size * 2);
- }
- encode(writer, _value) {
- let data = getBytesCopy(Typed.dereference(_value, this.type));
- if (data.length !== this.size) {
- this._throwError("incorrect data length", _value);
- }
- return writer.writeBytes(data);
- }
- decode(reader) {
- return hexlify(reader.readBytes(this.size));
- }
- }
-
- const Empty = new Uint8Array([]);
- /**
- * @_ignore
- */
- class NullCoder extends Coder {
- constructor(localName) {
- super("null", "", localName, false);
- }
- defaultValue() {
- return null;
- }
- encode(writer, value) {
- if (value != null) {
- this._throwError("not null", value);
- }
- return writer.writeBytes(Empty);
- }
- decode(reader) {
- reader.readBytes(0);
- return null;
- }
- }
-
- const BN_0$5 = BigInt(0);
- const BN_1$2 = BigInt(1);
- const BN_MAX_UINT256$1 = BigInt("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
- /**
- * @_ignore
- */
- class NumberCoder extends Coder {
- size;
- signed;
- constructor(size, signed, localName) {
- const name = (signed ? "int" : "uint") + size * 8;
- super(name, name, localName, false);
- defineProperties(this, { size, signed }, { size: "number", signed: "boolean" });
- }
- defaultValue() {
- return 0;
- }
- encode(writer, _value) {
- let value = getBigInt(Typed.dereference(_value, this.type));
- // Check bounds are safe for encoding
- let maxUintValue = mask(BN_MAX_UINT256$1, WordSize * 8);
- if (this.signed) {
- let bounds = mask(maxUintValue, this.size * 8 - 1);
- if (value > bounds || value < -(bounds + BN_1$2)) {
- this._throwError("value out-of-bounds", _value);
- }
- value = toTwos(value, 8 * WordSize);
- }
- else if (value < BN_0$5 || value > mask(maxUintValue, this.size * 8)) {
- this._throwError("value out-of-bounds", _value);
- }
- return writer.writeValue(value);
- }
- decode(reader) {
- let value = mask(reader.readValue(), this.size * 8);
- if (this.signed) {
- value = fromTwos(value, this.size * 8);
- }
- return value;
- }
- }
-
- /**
- * @_ignore
- */
- class StringCoder extends DynamicBytesCoder {
- constructor(localName) {
- super("string", localName);
- }
- defaultValue() {
- return "";
- }
- encode(writer, _value) {
- return super.encode(writer, toUtf8Bytes(Typed.dereference(_value, "string")));
- }
- decode(reader) {
- return toUtf8String(super.decode(reader));
- }
- }
-
- /**
- * @_ignore
- */
- class TupleCoder extends Coder {
- coders;
- constructor(coders, localName) {
- let dynamic = false;
- const types = [];
- coders.forEach((coder) => {
- if (coder.dynamic) {
- dynamic = true;
- }
- types.push(coder.type);
- });
- const type = "tuple(" + types.join(",") + ")";
- super("tuple", type, localName, dynamic);
- defineProperties(this, {
- coders: Object.freeze(coders.slice()),
- });
- }
- defaultValue() {
- const values = [];
- this.coders.forEach((coder) => {
- values.push(coder.defaultValue());
- });
- // We only output named properties for uniquely named coders
- const uniqueNames = this.coders.reduce((accum, coder) => {
- const name = coder.localName;
- if (name) {
- if (!accum[name]) {
- accum[name] = 0;
- }
- accum[name]++;
- }
- return accum;
- }, {});
- // Add named values
- this.coders.forEach((coder, index) => {
- let name = coder.localName;
- if (!name || uniqueNames[name] !== 1) {
- return;
- }
- if (name === "length") {
- name = "_length";
- }
- if (values[name] != null) {
- return;
- }
- values[name] = values[index];
- });
- return Object.freeze(values);
- }
- encode(writer, _value) {
- const value = Typed.dereference(_value, "tuple");
- return pack(writer, this.coders, value);
- }
- decode(reader) {
- return unpack(reader, this.coders);
- }
- }
-
- /**
- * A simple hashing function which operates on UTF-8 strings to
- * compute an 32-byte identifier.
- *
- *
- * @example:
- * id("hello world")
- * //_result:
- */
- function id(value, useKeccak) {
- if (useKeccak) {
- return keccak256(toUtf8Bytes(value));
- }
- return sha256(toUtf8Bytes(value));
- }
-
- /**
- * A constant for the zero address.
- *
- * (**i.e.** ``"0x0000000000000000000000000000000000000000"``)
- */
- const ZeroAddress = "0x0000000000000000000000000000000000000000";
-
- /**
- * A constant for the zero hash.
- *
- * (**i.e.** ``"0x0000000000000000000000000000000000000000000000000000000000000000"``)
- */
- const ZeroHash = "0x0000000000000000000000000000000000000000000000000000000000000000";
-
- /**
- * A constant for the order N for the secp256k1 curve.
- *
- * (**i.e.** ``0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141n``)
- */
- const N = BigInt("0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141");
- /**
- * A constant for the number of ore in a single xcb.
- *
- * (**i.e.** ``1000000000000000000n``)
- */
- const OrePerXCB = BigInt("1000000000000000000");
- /**
- * A constant for the maximum value for a ``uint256``.
- *
- * (**i.e.** ``0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffn``)
- */
- const MaxUint256 = BigInt("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
- /**
- * A constant for the minimum value for an ``int256``.
- *
- * (**i.e.** ``-8000000000000000000000000000000000000000000000000000000000000000n``)
- */
- const MinInt256 = BigInt("0x8000000000000000000000000000000000000000000000000000000000000000") *
- BigInt(-1);
- /**
- * A constant for the maximum value for an ``int256``.
- *
- * (**i.e.** ``0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffn``)
- */
- const MaxInt256 = BigInt("0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
-
- // NFKC (composed) // (decomposed)
- /**
- * A constant for the core symbol (normalized using NFKC).
- *
- * (**i.e.** ``"\\u039e"``)
- */
- const CoreSymbol = "\u039e"; // "\uD835\uDF63";
- /**
- * A constant for the [[link-eip-191]] personal message prefix.
- *
- * (**i.e.** ``"\\x19Core Signed Message:\\n"``)
- */
- const MessagePrefix = "\x19Core Signed Message:\n";
-
- function accessSetify(addr, storageKeys) {
- return {
- address: getAddress(addr),
- storageKeys: storageKeys.map((storageKey, index) => {
- assertArgument(isHexString(storageKey, 32), "invalid slot", `storageKeys[${index}]`, storageKey);
- return storageKey.toLowerCase();
- }),
- };
- }
- /**
- * Returns a [[AccessList]] from any corebcsupported access-list structure.
- */
- function accessListify(value) {
- if (Array.isArray(value)) {
- return value.map((set, index) => {
- if (Array.isArray(set)) {
- assertArgument(set.length === 2, "invalid slot set", `value[${index}]`, set);
- return accessSetify(set[0], set[1]);
- }
- assertArgument(set != null && typeof set === "object", "invalid address-slot set", "value", value);
- return accessSetify(set.address, set.storageKeys);
- });
- }
- assertArgument(value != null && typeof value === "object", "invalid access list", "value", value);
- const result = Object.keys(value).map((addr) => {
- const storageKeys = value[addr].reduce((accum, storageKey) => {
- accum[storageKey] = true;
- return accum;
- }, {});
- return accessSetify(addr, Object.keys(storageKeys).sort());
- });
- result.sort((a, b) => a.address.localeCompare(b.address));
- return result;
- }
-
- const logger$1 = new Logger("transaction/0.0.1");
- const BN_0$4 = BigInt(0);
- function handleAddress(value) {
- if (value === "0x") {
- return null;
- }
- return getAddress(value);
- }
- function parse(data) {
- const handleNumber = (value) => {
- // @ts-ignore
- if (value === "0x") {
- return BigNumber.from(0);
- }
- return BigNumber.from(value);
- };
- const transaction = decode$1(data);
- if (transaction.length !== 7 && transaction.length !== 8) {
- logger$1.throwArgumentError("invalid raw transaction", "data", data);
- }
- const isSigned = transaction.length === 8;
- const tx = {
- nonce: Number(handleNumber(transaction[0])),
- energyPrice: handleNumber(transaction[1]).toBigInt(),
- energyLimit: handleNumber(transaction[2]).toBigInt(),
- networkId: handleNumber(transaction[isSigned ? 3 : 6]).toBigInt(),
- to: handleAddress(transaction[isSigned ? 4 : 3]),
- value: handleNumber(transaction[isSigned ? 5 : 4]).toBigInt(),
- data: transaction[isSigned ? 6 : 5],
- };
- if (transaction.length === 8) {
- const prefix = networkIdToPrefix(Number(tx.networkId));
- const digest = sha256(serialize(tx));
- tx.hash = sha256(serialize(tx, transaction[7]));
- tx.from = recoverAddress(digest, transaction[7], prefix);
- tx.signature = transaction[7];
- }
- return tx;
- }
- const unsignedTransactionFields = [
- { name: "nonce", maxLength: 32, numeric: true },
- { name: "energyPrice", maxLength: 32, numeric: true },
- { name: "energyLimit", maxLength: 32, numeric: true },
- { name: "to", length: 22 },
- { name: "value", maxLength: 32, numeric: true },
- { name: "data" },
- { name: "networkId", maxLength: 32, numeric: true },
- ];
- const transactionFields = [
- { name: "nonce", maxLength: 32, numeric: true },
- { name: "energyPrice", maxLength: 32, numeric: true },
- { name: "energyLimit", maxLength: 32, numeric: true },
- { name: "networkId", maxLength: 32, numeric: true },
- { name: "to", length: 22 },
- { name: "value", maxLength: 32, numeric: true },
- { name: "data" },
- ];
- const allowedTransactionKeys = {
- networkId: true,
- data: true,
- energyLimit: true,
- energyPrice: true,
- nonce: true,
- to: true,
- value: true,
- };
- function serialize(transaction, signature) {
- checkProperties(transaction, allowedTransactionKeys);
- const raw = [];
- (!!signature ? transactionFields : unsignedTransactionFields).forEach(function ({ numeric, maxLength, name, length }) {
- let value = transaction[name] || [];
- const options = {};
- if (numeric) {
- options.hexPad = "left";
- }
- const tmpHexlified = hexlify(value, options);
- value = arrayify(tmpHexlified);
- // Fixed-width field
- if (length && value.length !== length && value.length > 0) {
- logger$1.throwArgumentError("invalid length for " + name, "transaction:" + name, value);
- }
- // Variable-width (with a maximum)
- if (maxLength) {
- value = stripZeros(value);
- if (value.length > maxLength) {
- logger$1.throwArgumentError("invalid length for " + name, "transaction:" + name, value);
- }
- }
- const hexlified = hexlify(value);
- raw.push(hexlified);
- });
- if (!!signature) {
- raw.push(hexlify(signature));
- }
- const finalValue = encode(raw);
- return finalValue;
- }
- /**
- * A **Transaction** describes an operation to be executed on
- * Core by an Externally Owned Account (EOA). It includes
- * who (the [[to]] address), what (the [[data]]) and how much (the
- * [[value]] in corebc) the operation should entail.
- *
- * @example:
- * tx = new Transaction()
- * //_result:
- *
- * tx.data = "0x1234";
- * //_result:
- */
- class Transaction {
- #to;
- #data;
- #nonce;
- #energyLimit;
- #energyPrice;
- #value;
- #networkId;
- #sig;
- /**
- * The ``to`` address for the transaction or ``null`` if the
- * transaction is an ``init`` transaction.
- */
- get to() {
- return this.#to;
- }
- set to(value) {
- this.#to = value == null ? null : getAddress(value);
- }
- /**
- * The transaction nonce.
- */
- get nonce() {
- return this.#nonce;
- }
- set nonce(value) {
- this.#nonce = getNumber(value, "value");
- }
- /**
- * The energy limit.
- */
- get energyLimit() {
- return this.#energyLimit;
- }
- set energyLimit(value) {
- this.#energyLimit = getBigInt(value);
- }
- /**
- * The energy price.
- *
- * On legacy networks this defines the fee that will be paid. On
- * EIP-1559 networks, this should be ``null``.
- */
- get energyPrice() {
- const value = this.#energyPrice;
- if (value == null) {
- return BN_0$4;
- }
- return value;
- }
- set energyPrice(value) {
- this.#energyPrice = value == null ? null : getBigInt(value, "energyPrice");
- }
- /**
- * The transaction data. For ``init`` transactions this is the
- * deployment code.
- */
- get data() {
- return this.#data;
- }
- set data(value) {
- this.#data = hexlify(value);
- }
- /**
- * The amount of xcb (in ore) to send in this transactions.
- */
- get value() {
- return this.#value;
- }
- set value(value) {
- this.#value = getBigInt(value, "value");
- }
- /**
- * The chain ID this transaction is valid on.
- */
- get networkId() {
- return this.#networkId;
- }
- set networkId(value) {
- this.#networkId = getBigInt(value);
- }
- /**
- * If signed, the signature for this transaction.
- */
- get signature() {
- return this.#sig || null;
- }
- set signature(value) {
- this.#sig = value == null ? null : value;
- }
- /**
- * Creates a new Transaction with default values.
- */
- constructor() {
- this.#to = null;
- this.#nonce = 0;
- this.#energyLimit = BigInt(0);
- this.#energyPrice = null;
- this.#data = "0x";
- this.#value = BigInt(0);
- this.#networkId = BigInt(0);
- this.#sig = null;
- }
- /**
- * The transaction hash, if signed. Otherwise, ``null``.
- */
- get hash() {
- if (this.signature == null) {
- return null;
- }
- return sha256(this.serialized);
- }
- /**
- * The pre-image hash of this transaction.
- *
- * This is the digest that a [[Signer]] must sign to authorize
- * this transaction.
- */
- get unsignedHash() {
- return sha256(this.unsignedSerialized);
- }
- /**
- * The sending address, if signed. Otherwise, ``null``.
- */
- get from() {
- if (this.signature == null) {
- return null;
- }
- const prefix = networkIdToPrefix(Number(this.#networkId));
- return recoverAddress(this.unsignedHash, this.signature, prefix);
- }
- /**
- * The public key of the sender, if signed. Otherwise, ``null``.
- */
- get fromPublicKey() {
- if (this.signature == null) {
- return null;
- }
- return SigningKey.recoverPublicKey(this.unsignedHash, this.signature);
- }
- /**
- * Returns true if signed.
- *
- * This provides a Type Guard that properties requiring a signed
- * transaction are non-null.
- */
- isSigned() {
- //isSigned(): this is SignedTransaction {
- return this.signature != null;
- }
- /**
- * The serialized transaction.
- *
- * This throws if the transaction is unsigned. For the pre-image,
- * use [[unsignedSerialized]].
- */
- get serialized() {
- assert(this.signature != null, "cannot serialize unsigned transaction; maybe you meant .unsignedSerialized", "UNSUPPORTED_OPERATION", { operation: ".serialized" });
- return serialize(this, this.signature);
- }
- /**
- * The transaction pre-image.
- *
- * The hash of this is the digest which needs to be signed to
- * authorize this transaction.
- */
- get unsignedSerialized() {
- return serialize(this);
- }
- /**
- * Create a copy of this transaciton.
- */
- clone() {
- return Transaction.from(this);
- }
- /**
- * Return a JSON-friendly object.
- */
- toJSON() {
- const s = (v) => {
- if (v == null) {
- return null;
- }
- return v.toString();
- };
- return {
- to: this.to,
- data: this.data,
- nonce: this.nonce,
- energyLimit: s(this.energyLimit),
- energyPrice: s(this.energyPrice),
- value: s(this.value),
- networkId: s(this.networkId),
- sig: this.signature ? this.signature : null,
- };
- }
- /**
- * Create a **Transaction** from a serialized transaction or a
- * Transaction-like object.
- */
- static from(tx) {
- if (tx == null) {
- return new Transaction();
- }
- if (typeof tx === "string") {
- const payload = getBytes(tx);
- return Transaction.from(parse(payload));
- }
- const result = new Transaction();
- if (tx.to != null) {
- result.to = tx.to;
- }
- if (tx.nonce != null) {
- result.nonce = tx.nonce;
- }
- if (tx.energyLimit != null) {
- result.energyLimit = tx.energyLimit;
- }
- if (tx.energyPrice != null) {
- result.energyPrice = tx.energyPrice;
- }
- if (tx.data != null) {
- result.data = tx.data;
- }
- if (tx.value != null) {
- result.value = tx.value;
- }
- if (tx.networkId != null) {
- result.networkId = tx.networkId;
- }
- if (tx.signature != null) {
- result.signature = tx.signature;
- }
- if (tx.hash != null) {
- assertArgument(result.isSigned(), "unsigned transaction cannot define hash", "tx", tx);
- assertArgument(result.hash === tx.hash, "hash mismatch", "tx", tx);
- }
- if (tx.from != null) {
- assertArgument(result.isSigned(), "unsigned transaction cannot define from", "tx", tx);
- assertArgument(result.from.toLowerCase() === (tx.from || "").toLowerCase(), "from mismatch", "tx", tx);
- }
- return result;
- }
- }
-
- /**
- * Computes the [[link-eip-191]] personal-sign message digest to sign.
- *
- *
- * If %%message%% is a string, it is converted to its UTF-8 bytes
- * first. To compute the digest of a [[DataHexString]], it must be converted
- * to [bytes](getBytes).
- *
- * @example:
- * hashMessage("Hello World")
- * //_result:
- *
- * // Hashes the SIX (6) string characters, i.e.
- * // [ "0", "x", "4", "2", "4", "3" ]
- * hashMessage("0x4243")
- * //_result:
- *
- * // Hashes the TWO (2) bytes [ 0x42, 0x43 ]...
- * hashMessage(getBytes("0x4243"))
- * //_result:
- *
- * // ...which is equal to using data
- * hashMessage(new Uint8Array([ 0x42, 0x43 ]))
- * //_result:
- *
- */
- function hashMessage(message) {
- if (typeof message === "string") {
- message = toUtf8Bytes(message);
- }
- return sha256(concat([
- toUtf8Bytes(MessagePrefix),
- toUtf8Bytes(String(message.length)),
- message,
- ]));
- }
- /**
- * Return the address of the private key that produced
- * the signature %%sig%% during signing for %%message%%.
- */
- function verifyMessage(message, sig, prefix) {
- const digest = hashMessage(message);
- return recoverAddress(digest, sig, prefix);
- }
-
- const regexBytes = new RegExp("^bytes([0-9]+)$");
- const regexNumber = new RegExp("^(u?int)([0-9]*)$");
- const regexArray = new RegExp("^(.*)\\[([0-9]*)\\]$");
- function _pack(type, value, isArray) {
- switch (type) {
- case "address":
- if (isArray) {
- return getBytes(zeroPadValue(value, 32));
- }
- return getBytes(getAddress(value));
- case "string":
- return toUtf8Bytes(value);
- case "bytes":
- return getBytes(value);
- case "bool":
- value = !!value ? "0x01" : "0x00";
- if (isArray) {
- return getBytes(zeroPadValue(value, 32));
- }
- return getBytes(value);
- }
- let match = type.match(regexNumber);
- if (match) {
- let signed = match[1] === "int";
- let size = parseInt(match[2] || "256");
- assertArgument((!match[2] || match[2] === String(size)) &&
- size % 8 === 0 &&
- size !== 0 &&
- size <= 256, "invalid number type", "type", type);
- if (isArray) {
- size = 256;
- }
- if (signed) {
- value = toTwos(value, size);
- }
- return getBytes(zeroPadValue(toBeArray(value), size / 8));
- }
- match = type.match(regexBytes);
- if (match) {
- const size = parseInt(match[1]);
- assertArgument(String(size) === match[1] && size !== 0 && size <= 32, "invalid bytes type", "type", type);
- assertArgument(dataLength(value) === size, `invalid value for ${type}`, "value", value);
- if (isArray) {
- return getBytes(zeroPadBytes(value, 32));
- }
- return value;
- }
- match = type.match(regexArray);
- if (match && Array.isArray(value)) {
- const baseType = match[1];
- const count = parseInt(match[2] || String(value.length));
- assertArgument(count === value.length, `invalid array length for ${type}`, "value", value);
- const result = [];
- value.forEach(function (value) {
- result.push(_pack(baseType, value, true));
- });
- return getBytes(concat(result));
- }
- assertArgument(false, "invalid type", "type", type);
- }
- // @TODO: Array Enum
- /**
- * Computes the [[link-solc-packed]] representation of %%values%%
- * respectively to their %%types%%.
- *
- * @example:
- * addr = "0x8ba1f109551bd432803012645ac136ddd64dba72"
- * solidityPacked([ "address", "uint" ], [ addr, 45 ]);
- * //_result:
- */
- function solidityPacked(types, values) {
- assertArgument(types.length === values.length, "wrong number of values; expected ${ types.length }", "values", values);
- const tight = [];
- types.forEach(function (type, index) {
- tight.push(_pack(type, values[index]));
- });
- return hexlify(concat(tight));
- }
- /**
- * Computes the [[link-solc-packed]] [[sha256]] hash of %%values%%
- * respectively to their %%types%%.
- *
- * @example:
- * addr = "0x8ba1f109551bd432803012645ac136ddd64dba72"
- * solidityPackedSha256([ "address", "uint" ], [ addr, 45 ]);
- * //_result:
- */
- function solidityPackedSha256(types, values) {
- return sha256(solidityPacked(types, values));
- }
-
- const padding = new Uint8Array(32);
- padding.fill(0);
- const BN__1 = BigInt(-1);
- const BN_0$3 = BigInt(0);
- const BN_1$1 = BigInt(1);
- const BN_MAX_UINT256 = BigInt("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
- function hexPadRight(value) {
- const bytes = getBytes(value);
- const padOffset = bytes.length % 32;
- if (padOffset) {
- return concat([bytes, padding.slice(padOffset)]);
- }
- return hexlify(bytes);
- }
- const hexTrue = toBeHex(BN_1$1, 32);
- const hexFalse = toBeHex(BN_0$3, 32);
- const domainFieldTypes = {
- name: "string",
- version: "string",
- networkId: "uint256",
- verifyingContract: "address",
- salt: "bytes32",
- };
- const domainFieldNames = [
- "name",
- "version",
- "networkId",
- "verifyingContract",
- "salt",
- ];
- function checkString(key) {
- return function (value) {
- assertArgument(typeof value === "string", `invalid domain value for ${JSON.stringify(key)}`, `domain.${key}`, value);
- return value;
- };
- }
- const domainChecks = {
- name: checkString("name"),
- version: checkString("version"),
- networkId: function (_value) {
- const value = getBigInt(_value, "domain.networkId");
- assertArgument(value >= 0, "invalid chain ID", "domain.networkId", _value);
- if (Number.isSafeInteger(value)) {
- return Number(value);
- }
- return toQuantity(value);
- },
- verifyingContract: function (value) {
- try {
- return getAddress(value).toLowerCase();
- }
- catch (error) { }
- assertArgument(false, `invalid domain value "verifyingContract"`, "domain.verifyingContract", value);
- },
- salt: function (value) {
- const bytes = getBytes(value, "domain.salt");
- assertArgument(bytes.length === 32, `invalid domain value "salt"`, "domain.salt", value);
- return hexlify(bytes);
- },
- };
- function getBaseEncoder(type) {
- // intXX and uintXX
- {
- const match = type.match(/^(u?)int(\d*)$/);
- if (match) {
- const signed = match[1] === "";
- const width = parseInt(match[2] || "256");
- assertArgument(width % 8 === 0 &&
- width !== 0 &&
- width <= 256 &&
- (match[2] == null || match[2] === String(width)), "invalid numeric width", "type", type);
- const boundsUpper = mask(BN_MAX_UINT256, signed ? width - 1 : width);
- const boundsLower = signed ? (boundsUpper + BN_1$1) * BN__1 : BN_0$3;
- return function (_value) {
- const value = getBigInt(_value, "value");
- assertArgument(value >= boundsLower && value <= boundsUpper, `value out-of-bounds for ${type}`, "value", value);
- return toBeHex(signed ? toTwos(value, 256) : value, 32);
- };
- }
- }
- // bytesXX
- {
- const match = type.match(/^bytes(\d+)$/);
- if (match) {
- const width = parseInt(match[1]);
- assertArgument(width !== 0 && width <= 32 && match[1] === String(width), "invalid bytes width", "type", type);
- return function (value) {
- const bytes = getBytes(value);
- assertArgument(bytes.length === width, `invalid length for ${type}`, "value", value);
- return hexPadRight(value);
- };
- }
- }
- switch (type) {
- case "address":
- return function (value) {
- return zeroPadValue(getAddress(value), 32);
- };
- case "bool":
- return function (value) {
- return !value ? hexFalse : hexTrue;
- };
- case "bytes":
- return function (value) {
- return sha256(value);
- };
- case "string":
- return function (value) {
- return id(value);
- };
- }
- return null;
- }
- function encodeType(name, fields) {
- return `${name}(${fields
- .map(({ name, type }) => type + " " + name)
- .join(",")})`;
- }
- class TypedDataEncoder {
- primaryType;
- #types;
- get types() {
- return JSON.parse(this.#types);
- }
- #fullTypes;
- #encoderCache;
- constructor(types) {
- this.#types = JSON.stringify(types);
- this.#fullTypes = new Map();
- this.#encoderCache = new Map();
- // Link struct types to their direct child structs
- const links = new Map();
- // Link structs to structs which contain them as a child
- const parents = new Map();
- // Link all subtypes within a given struct
- const subtypes = new Map();
- Object.keys(types).forEach((type) => {
- links.set(type, new Set());
- parents.set(type, []);
- subtypes.set(type, new Set());
- });
- for (const name in types) {
- const uniqueNames = new Set();
- for (const field of types[name]) {
- // Check each field has a unique name
- assertArgument(!uniqueNames.has(field.name), `duplicate variable name ${JSON.stringify(field.name)} in ${JSON.stringify(name)}`, "types", types);
- uniqueNames.add(field.name);
- // Get the base type (drop any array specifiers)
- const baseType = field.type.match(/^([^\x5b]*)(\x5b|$)/)[1] || null;
- assertArgument(baseType !== name, `circular type reference to ${JSON.stringify(baseType)}`, "types", types);
- // Is this a base encoding type?
- const encoder = getBaseEncoder(baseType);
- if (encoder) {
- continue;
- }
- assertArgument(parents.has(baseType), `unknown type ${JSON.stringify(baseType)}`, "types", types);
- // Add linkage
- parents.get(baseType).push(name);
- links.get(name).add(baseType);
- }
- }
- // Deduce the primary type
- const primaryTypes = Array.from(parents.keys()).filter((n) => parents.get(n).length === 0);
- assertArgument(primaryTypes.length !== 0, "missing primary type", "types", types);
- assertArgument(primaryTypes.length === 1, `ambiguous primary types or unused types: ${primaryTypes
- .map((t) => JSON.stringify(t))
- .join(", ")}`, "types", types);
- defineProperties(this, { primaryType: primaryTypes[0] });
- // Check for circular type references
- function checkCircular(type, found) {
- assertArgument(!found.has(type), `circular type reference to ${JSON.stringify(type)}`, "types", types);
- found.add(type);
- for (const child of links.get(type)) {
- if (!parents.has(child)) {
- continue;
- }
- // Recursively check children
- checkCircular(child, found);
- // Mark all ancestors as having this decendant
- for (const subtype of found) {
- subtypes.get(subtype).add(child);
- }
- }
- found.delete(type);
- }
- checkCircular(this.primaryType, new Set());
- // Compute each fully describe type
- for (const [name, set] of subtypes) {
- const st = Array.from(set);
- st.sort();
- this.#fullTypes.set(name, encodeType(name, types[name]) +
- st.map((t) => encodeType(t, types[t])).join(""));
- }
- }
- getEncoder(type) {
- let encoder = this.#encoderCache.get(type);
- if (!encoder) {
- encoder = this.#getEncoder(type);
- this.#encoderCache.set(type, encoder);
- }
- return encoder;
- }
- #getEncoder(type) {
- // Basic encoder type (address, bool, uint256, etc)
- {
- const encoder = getBaseEncoder(type);
- if (encoder) {
- return encoder;
- }
- }
- // Array
- const match = type.match(/^(.*)(\x5b(\d*)\x5d)$/);
- if (match) {
- const subtype = match[1];
- const subEncoder = this.getEncoder(subtype);
- return (value) => {
- assertArgument(!match[3] || parseInt(match[3]) === value.length, `array length mismatch; expected length ${parseInt(match[3])}`, "value", value);
- let result = value.map(subEncoder);
- if (this.#fullTypes.has(subtype)) {
- result = result.map(sha256);
- }
- return sha256(concat(result));
- };
- }
- // Struct
- const fields = this.types[type];
- if (fields) {
- const encodedType = id(this.#fullTypes.get(type));
- return (value) => {
- const values = fields.map(({ name, type }) => {
- const result = this.getEncoder(type)(value[name]);
- if (this.#fullTypes.has(type)) {
- return sha256(result);
- }
- return result;
- });
- values.unshift(encodedType);
- return concat(values);
- };
- }
- assertArgument(false, `unknown type: ${type}`, "type", type);
- }
- encodeType(name) {
- const result = this.#fullTypes.get(name);
- assertArgument(result, `unknown type: ${JSON.stringify(name)}`, "name", name);
- return result;
- }
- encodeData(type, value) {
- return this.getEncoder(type)(value);
- }
- hashStruct(name, value) {
- return sha256(this.encodeData(name, value));
- }
- encode(value) {
- return this.encodeData(this.primaryType, value);
- }
- hash(value) {
- return this.hashStruct(this.primaryType, value);
- }
- _visit(type, value, callback) {
- // Basic encoder type (address, bool, uint256, etc)
- {
- const encoder = getBaseEncoder(type);
- if (encoder) {
- return callback(type, value);
- }
- }
- // Array
- const match = type.match(/^(.*)(\x5b(\d*)\x5d)$/);
- if (match) {
- assertArgument(!match[3] || parseInt(match[3]) === value.length, `array length mismatch; expected length ${parseInt(match[3])}`, "value", value);
- return value.map((v) => this._visit(match[1], v, callback));
- }
- // Struct
- const fields = this.types[type];
- if (fields) {
- return fields.reduce((accum, { name, type }) => {
- accum[name] = this._visit(type, value[name], callback);
- return accum;
- }, {});
- }
- assertArgument(false, `unknown type: ${type}`, "type", type);
- }
- visit(value, callback) {
- return this._visit(this.primaryType, value, callback);
- }
- static from(types) {
- return new TypedDataEncoder(types);
- }
- static getPrimaryType(types) {
- return TypedDataEncoder.from(types).primaryType;
- }
- static hashStruct(name, types, value) {
- return TypedDataEncoder.from(types).hashStruct(name, value);
- }
- static hashDomain(domain) {
- const domainFields = [];
- for (const name in domain) {
- if (domain[name] == null) {
- continue;
- }
- const type = domainFieldTypes[name];
- assertArgument(type, `invalid typed-data domain key: ${JSON.stringify(name)}`, "domain", domain);
- domainFields.push({ name, type });
- }
- domainFields.sort((a, b) => {
- return (domainFieldNames.indexOf(a.name) - domainFieldNames.indexOf(b.name));
- });
- return TypedDataEncoder.hashStruct("EIP712Domain", { EIP712Domain: domainFields }, domain);
- }
- static encode(domain, types, value) {
- return concat([
- "0x1901",
- TypedDataEncoder.hashDomain(domain),
- TypedDataEncoder.from(types).hash(value),
- ]);
- }
- static hash(domain, types, value) {
- return sha256(TypedDataEncoder.encode(domain, types, value));
- }
- // Replaces all address types with ENS names with their looked up address
- static async resolveNames(domain, types, value, resolveName) {
- // Make a copy to isolate it from the object passed in
- domain = Object.assign({}, domain);
- // Allow passing null to ignore value
- for (const key in domain) {
- if (domain[key] == null) {
- delete domain[key];
- }
- }
- // Look up all ENS names
- const ensCache = {};
- // Do we need to look up the domain's verifyingContract?
- if (domain.verifyingContract &&
- !isHexString(domain.verifyingContract, 20)) {
- ensCache[domain.verifyingContract] = "0x";
- }
- // We are going to use the encoder to visit all the base values
- const encoder = TypedDataEncoder.from(types);
- // Get a list of all the addresses
- encoder.visit(value, (type, value) => {
- if (type === "address" && !isHexString(value, 20)) {
- ensCache[value] = "0x";
- }
- return value;
- });
- // Lookup each name
- for (const name in ensCache) {
- ensCache[name] = await resolveName(name);
- }
- // Replace the domain verifyingContract if needed
- if (domain.verifyingContract && ensCache[domain.verifyingContract]) {
- domain.verifyingContract = ensCache[domain.verifyingContract];
- }
- // Replace all ENS names with their address
- value = encoder.visit(value, (type, value) => {
- if (type === "address" && ensCache[value]) {
- return ensCache[value];
- }
- return value;
- });
- return { domain, value };
- }
- static getPayload(domain, types, value) {
- // Validate the domain fields
- TypedDataEncoder.hashDomain(domain);
- // Derive the EIP712Domain Struct reference type
- const domainValues = {};
- const domainTypes = [];
- domainFieldNames.forEach((name) => {
- const value = domain[name];
- if (value == null) {
- return;
- }
- domainValues[name] = domainChecks[name](value);
- domainTypes.push({ name, type: domainFieldTypes[name] });
- });
- const encoder = TypedDataEncoder.from(types);
- const typesWithDomain = Object.assign({}, types);
- assertArgument(typesWithDomain.EIP712Domain == null, "types must not contain EIP712Domain type", "types.EIP712Domain", types);
- typesWithDomain.EIP712Domain = domainTypes;
- // Validate the data structures and types
- encoder.encode(value);
- return {
- types: typesWithDomain,
- domain: domainValues,
- primaryType: encoder.primaryType,
- message: encoder.visit(value, (type, value) => {
- // bytes
- if (type.match(/^bytes(\d*)/)) {
- return hexlify(getBytes(value));
- }
- // uint or int
- if (type.match(/^u?int/)) {
- return getBigInt(value).toString();
- }
- switch (type) {
- case "address":
- return value.toLowerCase();
- case "bool":
- return !!value;
- case "string":
- assertArgument(typeof value === "string", "invalid string", "value", value);
- return value;
- }
- assertArgument(false, "unsupported type", "type", type);
- }),
- };
- }
- }
- /**
- * Compute the address used to sign the typed data for the %%signature%%.
- */
- function verifyTypedData(domain, types, value, signature, prefix) {
- return recoverAddress(TypedDataEncoder.hash(domain, types, value), signature, prefix);
- }
-
- /**
- * About frgaments...
- *
- * @_subsection api/abi/abi-coder:Fragments [about-fragments]
- */
- var _a;
- // [ "a", "b" ] => { "a": 1, "b": 1 }
- function setify(items) {
- const result = new Set();
- items.forEach((k) => result.add(k));
- return Object.freeze(result);
- }
- // Visibility Keywords
- const _kwVisib = "constant external internal payable private public pure view";
- const KwVisib = setify(_kwVisib.split(" "));
- const _kwTypes = "constructor error event fallback function receive struct";
- const KwTypes = setify(_kwTypes.split(" "));
- const _kwModifiers = "calldata memory storage payable indexed";
- const KwModifiers = setify(_kwModifiers.split(" "));
- const _kwOther = "tuple returns";
- // All Keywords
- const _keywords = [_kwTypes, _kwModifiers, _kwOther, _kwVisib].join(" ");
- const Keywords = setify(_keywords.split(" "));
- // Single character tokens
- const SimpleTokens = {
- "(": "OPEN_PAREN",
- ")": "CLOSE_PAREN",
- "[": "OPEN_BRACKET",
- "]": "CLOSE_BRACKET",
- ",": "COMMA",
- "@": "AT",
- };
- // Parser regexes to consume the next token
- const regexWhitespacePrefix = new RegExp("^(\\s*)");
- const regexNumberPrefix = new RegExp("^([0-9]+)");
- const regexIdPrefix = new RegExp("^([a-zA-Z$_][a-zA-Z0-9$_]*)");
- // Parser regexs to check validity
- const regexId = new RegExp("^([a-zA-Z$_][a-zA-Z0-9$_]*)$");
- const regexType = new RegExp("^(address|bool|bytes([0-9]*)|string|u?int([0-9]*))$");
- class TokenString {
- #offset;
- #tokens;
- get offset() {
- return this.#offset;
- }
- get length() {
- return this.#tokens.length - this.#offset;
- }
- constructor(tokens) {
- this.#offset = 0;
- this.#tokens = tokens.slice();
- }
- clone() {
- return new _a(this.#tokens);
- }
- reset() {
- this.#offset = 0;
- }
- #subTokenString(from = 0, to = 0) {
- return new _a(this.#tokens.slice(from, to).map((t) => {
- return Object.freeze(Object.assign({}, t, {
- match: t.match - from,
- linkBack: t.linkBack - from,
- linkNext: t.linkNext - from,
- }));
- }));
- }
- // Pops and returns the value of the next token, if it is a keyword in allowed; throws if out of tokens
- popKeyword(allowed) {
- const top = this.peek();
- if (top.type !== "KEYWORD" || !allowed.has(top.text)) {
- throw new Error(`expected keyword ${top.text}`);
- }
- return this.pop().text;
- }
- // Pops and returns the value of the next token if it is `type`; throws if out of tokens
- popType(type) {
- if (this.peek().type !== type) {
- throw new Error(`expected ${type}; got ${JSON.stringify(this.peek())}`);
- }
- return this.pop().text;
- }
- // Pops and returns a "(" TOKENS ")"
- popParen() {
- const top = this.peek();
- if (top.type !== "OPEN_PAREN") {
- throw new Error("bad start");
- }
- const result = this.#subTokenString(this.#offset + 1, top.match + 1);
- this.#offset = top.match + 1;
- return result;
- }
- // Pops and returns the items within "(" ITEM1 "," ITEM2 "," ... ")"
- popParams() {
- const top = this.peek();
- if (top.type !== "OPEN_PAREN") {
- throw new Error("bad start");
- }
- const result = [];
- while (this.#offset < top.match - 1) {
- const link = this.peek().linkNext;
- result.push(this.#subTokenString(this.#offset + 1, link));
- this.#offset = link;
- }
- this.#offset = top.match + 1;
- return result;
- }
- // Returns the top Token, throwing if out of tokens
- peek() {
- if (this.#offset >= this.#tokens.length) {
- throw new Error("out-of-bounds");
- }
- return this.#tokens[this.#offset];
- }
- // Returns the next value, if it is a keyword in `allowed`
- peekKeyword(allowed) {
- const top = this.peekType("KEYWORD");
- return top != null && allowed.has(top) ? top : null;
- }
- // Returns the value of the next token if it is `type`
- peekType(type) {
- if (this.length === 0) {
- return null;
- }
- const top = this.peek();
- return top.type === type ? top.text : null;
- }
- // Returns the next token; throws if out of tokens
- pop() {
- const result = this.peek();
- this.#offset++;
- return result;
- }
- toString() {
- const tokens = [];
- for (let i = this.#offset; i < this.#tokens.length; i++) {
- const token = this.#tokens[i];
- tokens.push(`${token.type}:${token.text}`);
- }
- return ``;
- }
- }
- _a = TokenString;
- function lex(text) {
- const tokens = [];
- const throwError = (message) => {
- const token = offset < text.length ? JSON.stringify(text[offset]) : "$EOI";
- throw new Error(`invalid token ${token} at ${offset}: ${message}`);
- };
- let brackets = [];
- let commas = [];
- let offset = 0;
- while (offset < text.length) {
- // Strip off any leading whitespace
- let cur = text.substring(offset);
- let match = cur.match(regexWhitespacePrefix);
- if (match) {
- offset += match[1].length;
- cur = text.substring(offset);
- }
- const token = {
- depth: brackets.length,
- linkBack: -1,
- linkNext: -1,
- match: -1,
- type: "",
- text: "",
- offset,
- value: -1,
- };
- tokens.push(token);
- let type = SimpleTokens[cur[0]] || "";
- if (type) {
- token.type = type;
- token.text = cur[0];
- offset++;
- if (type === "OPEN_PAREN") {
- brackets.push(tokens.length - 1);
- commas.push(tokens.length - 1);
- }
- else if (type == "CLOSE_PAREN") {
- if (brackets.length === 0) {
- throwError("no matching open bracket");
- }
- token.match = brackets.pop();
- tokens[token.match].match = tokens.length - 1;
- token.depth--;
- token.linkBack = commas.pop();
- tokens[token.linkBack].linkNext = tokens.length - 1;
- }
- else if (type === "COMMA") {
- token.linkBack = commas.pop();
- tokens[token.linkBack].linkNext = tokens.length - 1;
- commas.push(tokens.length - 1);
- }
- else if (type === "OPEN_BRACKET") {
- token.type = "BRACKET";
- }
- else if (type === "CLOSE_BRACKET") {
- // Remove the CLOSE_BRACKET
- let suffix = tokens.pop().text;
- if (tokens.length > 0 && tokens[tokens.length - 1].type === "NUMBER") {
- const value = tokens.pop().text;
- suffix = value + suffix;
- tokens[tokens.length - 1].value =
- getNumber(value);
- }
- if (tokens.length === 0 ||
- tokens[tokens.length - 1].type !== "BRACKET") {
- throw new Error("missing opening bracket");
- }
- tokens[tokens.length - 1].text += suffix;
- }
- continue;
- }
- match = cur.match(regexIdPrefix);
- if (match) {
- token.text = match[1];
- offset += token.text.length;
- if (Keywords.has(token.text)) {
- token.type = "KEYWORD";
- continue;
- }
- if (token.text.match(regexType)) {
- token.type = "TYPE";
- continue;
- }
- token.type = "ID";
- continue;
- }
- match = cur.match(regexNumberPrefix);
- if (match) {
- token.text = match[1];
- token.type = "NUMBER";
- offset += token.text.length;
- continue;
- }
- throw new Error(`unexpected token ${JSON.stringify(cur[0])} at position ${offset}`);
- }
- return new TokenString(tokens.map((t) => Object.freeze(t)));
- }
- // Check only one of `allowed` is in `set`
- function allowSingle(set, allowed) {
- let included = [];
- for (const key in allowed.keys()) {
- if (set.has(key)) {
- included.push(key);
- }
- }
- if (included.length > 1) {
- throw new Error(`conflicting types: ${included.join(", ")}`);
- }
- }
- // Functions to process a Solidity Signature TokenString from left-to-right for...
- // ...the name with an optional type, returning the name
- function consumeName(type, tokens) {
- if (tokens.peekKeyword(KwTypes)) {
- const keyword = tokens.pop().text;
- if (keyword !== type) {
- throw new Error(`expected ${type}, got ${keyword}`);
- }
- }
- return tokens.popType("ID");
- }
- // ...all keywords matching allowed, returning the keywords
- function consumeKeywords(tokens, allowed) {
- const keywords = new Set();
- while (true) {
- const keyword = tokens.peekType("KEYWORD");
- if (keyword == null || (allowed && !allowed.has(keyword))) {
- break;
- }
- tokens.pop();
- if (keywords.has(keyword)) {
- throw new Error(`duplicate keywords: ${JSON.stringify(keyword)}`);
- }
- keywords.add(keyword);
- }
- return Object.freeze(keywords);
- }
- // ...all visibility keywords, returning the coalesced mutability
- function consumeMutability(tokens) {
- let modifiers = consumeKeywords(tokens, KwVisib);
- // Detect conflicting modifiers
- allowSingle(modifiers, setify("constant payable nonpayable".split(" ")));
- allowSingle(modifiers, setify("pure view payable nonpayable".split(" ")));
- // Process mutability states
- if (modifiers.has("view")) {
- return "view";
- }
- if (modifiers.has("pure")) {
- return "pure";
- }
- if (modifiers.has("payable")) {
- return "payable";
- }
- if (modifiers.has("nonpayable")) {
- return "nonpayable";
- }
- // Process legacy `constant` last
- if (modifiers.has("constant")) {
- return "view";
- }
- return "nonpayable";
- }
- // ...a parameter list, returning the ParamType list
- function consumeParams(tokens, allowIndexed) {
- return tokens.popParams().map((t) => ParamType.from(t, allowIndexed));
- }
- // ...a energy limit, returning a BigNumber or null if none
- function consumeEnergy(tokens) {
- if (tokens.peekType("AT")) {
- tokens.pop();
- if (tokens.peekType("NUMBER")) {
- return getBigInt(tokens.pop().text);
- }
- throw new Error("invalid energy");
- }
- return null;
- }
- function consumeEoi(tokens) {
- if (tokens.length) {
- throw new Error(`unexpected tokens: ${tokens.toString()}`);
- }
- }
- const regexArrayType = new RegExp(/^(.*)\[([0-9]*)\]$/);
- function verifyBasicType(type) {
- const match = type.match(regexType);
- assertArgument(match, "invalid type", "type", type);
- if (type === "uint") {
- return "uint256";
- }
- if (type === "int") {
- return "int256";
- }
- if (match[2]) {
- // bytesXX
- const length = parseInt(match[2]);
- assertArgument(length !== 0 && length <= 32, "invalid bytes length", "type", type);
- }
- else if (match[3]) {
- // intXX or uintXX
- const size = parseInt(match[3]);
- assertArgument(size !== 0 && size <= 256 && size % 8 === 0, "invalid numeric width", "type", type);
- }
- return type;
- }
- // Make the Fragment constructors effectively private
- const _guard$2 = {};
- const internal$1 = Symbol.for("_corebc_internal");
- const ParamTypeInternal = "_ParamTypeInternal";
- const ErrorFragmentInternal = "_ErrorInternal";
- const EventFragmentInternal = "_EventInternal";
- const ConstructorFragmentInternal = "_ConstructorInternal";
- const FallbackFragmentInternal = "_FallbackInternal";
- const FunctionFragmentInternal = "_FunctionInternal";
- const StructFragmentInternal = "_StructInternal";
- /**
- * Each input and output of a [[Fragment]] is an Array of **PAramType**.
- */
- class ParamType {
- /**
- * The local name of the parameter (or ``""`` if unbound)
- */
- name;
- /**
- * The fully qualified type (e.g. ``"address"``, ``"tuple(address)"``,
- * ``"uint256[3][]"``)
- */
- type;
- /**
- * The base type (e.g. ``"address"``, ``"tuple"``, ``"array"``)
- */
- baseType;
- /**
- * True if the parameters is indexed.
- *
- * For non-indexable types this is ``null``.
- */
- indexed;
- /**
- * The components for the tuple.
- *
- * For non-tuple types this is ``null``.
- */
- components;
- /**
- * The array length, or ``-1`` for dynamic-lengthed arrays.
- *
- * For non-array types this is ``null``.
- */
- arrayLength;
- /**
- * The type of each child in the array.
- *
- * For non-array types this is ``null``.
- */
- arrayChildren;
- /**
- * @private
- */
- constructor(guard, name, type, baseType, indexed, components, arrayLength, arrayChildren) {
- assertPrivate(guard, _guard$2, "ParamType");
- Object.defineProperty(this, internal$1, { value: ParamTypeInternal });
- if (components) {
- components = Object.freeze(components.slice());
- }
- if (baseType === "array") {
- if (arrayLength == null || arrayChildren == null) {
- throw new Error("");
- }
- }
- else if (arrayLength != null || arrayChildren != null) {
- throw new Error("");
- }
- if (baseType === "tuple") {
- if (components == null) {
- throw new Error("");
- }
- }
- else if (components != null) {
- throw new Error("");
- }
- defineProperties(this, {
- name,
- type,
- baseType,
- indexed,
- components,
- arrayLength,
- arrayChildren,
- });
- }
- /**
- * Return a string representation of this type.
- *
- * For example,
- *
- * ``sighash" => "(uint256,address)"``
- *
- * ``"minimal" => "tuple(uint256,address) indexed"``
- *
- * ``"full" => "tuple(uint256 foo, address bar) indexed baz"``
- */
- format(format) {
- if (format == null) {
- format = "sighash";
- }
- if (format === "json") {
- let result = {
- type: this.baseType === "tuple" ? "tuple" : this.type,
- name: this.name || undefined,
- };
- if (typeof this.indexed === "boolean") {
- result.indexed = this.indexed;
- }
- if (this.isTuple()) {
- result.components = this.components.map((c) => JSON.parse(c.format(format)));
- }
- return JSON.stringify(result);
- }
- let result = "";
- // Array
- if (this.isArray()) {
- result += this.arrayChildren.format(format);
- result += `[${this.arrayLength < 0 ? "" : String(this.arrayLength)}]`;
- }
- else {
- if (this.isTuple()) {
- if (format !== "sighash") {
- result += this.type;
- }
- result +=
- "(" +
- this.components
- .map((comp) => comp.format(format))
- .join(format === "full" ? ", " : ",") +
- ")";
- }
- else {
- result += this.type;
- }
- }
- if (format !== "sighash") {
- if (this.indexed === true) {
- result += " indexed";
- }
- if (format === "full" && this.name) {
- result += " " + this.name;
- }
- }
- return result;
- }
- /*
- * Returns true if %%value%% is an Array type.
- *
- * This provides a type gaurd ensuring that the
- * [[arrayChildren]] and [[arrayLength]] are non-null.
- */
- //static isArray(value: any): value is { arrayChildren: ParamType, arrayLength: number } {
- // return value && (value.baseType === "array")
- //}
- /**
- * Returns true if %%this%% is an Array type.
- *
- * This provides a type gaurd ensuring that [[arrayChildren]]
- * and [[arrayLength]] are non-null.
- */
- isArray() {
- return this.baseType === "array";
- }
- /**
- * Returns true if %%this%% is a Tuple type.
- *
- * This provides a type gaurd ensuring that [[components]]
- * is non-null.
- */
- isTuple() {
- return this.baseType === "tuple";
- }
- /**
- * Returns true if %%this%% is an Indexable type.
- *
- * This provides a type gaurd ensuring that [[indexed]]
- * is non-null.
- */
- isIndexable() {
- return this.indexed != null;
- }
- /**
- * Walks the **ParamType** with %%value%%, calling %%process%%
- * on each type, destructing the %%value%% recursively.
- */
- walk(value, process) {
- if (this.isArray()) {
- if (!Array.isArray(value)) {
- throw new Error("invalid array value");
- }
- if (this.arrayLength !== -1 && value.length !== this.arrayLength) {
- throw new Error("array is wrong length");
- }
- const _this = this;
- return value.map((v) => _this.arrayChildren.walk(v, process));
- }
- if (this.isTuple()) {
- if (!Array.isArray(value)) {
- throw new Error("invalid tuple value");
- }
- if (value.length !== this.components.length) {
- throw new Error("array is wrong length");
- }
- const _this = this;
- return value.map((v, i) => _this.components[i].walk(v, process));
- }
- return process(this.type, value);
- }
- #walkAsync(promises, value, process, setValue) {
- if (this.isArray()) {
- if (!Array.isArray(value)) {
- throw new Error("invalid array value");
- }
- if (this.arrayLength !== -1 && value.length !== this.arrayLength) {
- throw new Error("array is wrong length");
- }
- const childType = this.arrayChildren;
- const result = value.slice();
- result.forEach((value, index) => {
- childType.#walkAsync(promises, value, process, (value) => {
- result[index] = value;
- });
- });
- setValue(result);
- return;
- }
- if (this.isTuple()) {
- const components = this.components;
- // Convert the object into an array
- let result;
- if (Array.isArray(value)) {
- result = value.slice();
- }
- else {
- if (value == null || typeof value !== "object") {
- throw new Error("invalid tuple value");
- }
- result = components.map((param) => {
- if (!param.name) {
- throw new Error("cannot use object value with unnamed components");
- }
- if (!(param.name in value)) {
- throw new Error(`missing value for component ${param.name}`);
- }
- return value[param.name];
- });
- }
- if (result.length !== this.components.length) {
- throw new Error("array is wrong length");
- }
- result.forEach((value, index) => {
- components[index].#walkAsync(promises, value, process, (value) => {
- result[index] = value;
- });
- });
- setValue(result);
- return;
- }
- const result = process(this.type, value);
- if (result.then) {
- promises.push((async function () {
- setValue(await result);
- })());
- }
- else {
- setValue(result);
- }
- }
- /**
- * Walks the **ParamType** with %%value%%, asynchronously calling
- * %%process%% on each type, destructing the %%value%% recursively.
- *
- * This can be used to resolve ENS naes by walking and resolving each
- * ``"address"`` type.
- */
- async walkAsync(value, process) {
- const promises = [];
- const result = [value];
- this.#walkAsync(promises, value, process, (value) => {
- result[0] = value;
- });
- if (promises.length) {
- await Promise.all(promises);
- }
- return result[0];
- }
- /**
- * Creates a new **ParamType** for %%obj%%.
- *
- * If %%allowIndexed%% then the ``indexed`` keyword is permitted,
- * otherwise the ``indexed`` keyword will throw an error.
- */
- static from(obj, allowIndexed) {
- if (ParamType.isParamType(obj)) {
- return obj;
- }
- if (typeof obj === "string") {
- return ParamType.from(lex(obj), allowIndexed);
- }
- else if (obj instanceof TokenString) {
- let type = "", baseType = "";
- let comps = null;
- if (consumeKeywords(obj, setify(["tuple"])).has("tuple") ||
- obj.peekType("OPEN_PAREN")) {
- // Tuple
- baseType = "tuple";
- comps = obj.popParams().map((t) => ParamType.from(t));
- type = `tuple(${comps.map((c) => c.format()).join(",")})`;
- }
- else {
- // Normal
- type = verifyBasicType(obj.popType("TYPE"));
- baseType = type;
- }
- // Check for Array
- let arrayChildren = null;
- let arrayLength = null;
- while (obj.length && obj.peekType("BRACKET")) {
- const bracket = obj.pop(); //arrays[i];
- arrayChildren = new ParamType(_guard$2, "", type, baseType, null, comps, arrayLength, arrayChildren);
- arrayLength = bracket.value;
- type += bracket.text;
- baseType = "array";
- comps = null;
- }
- let indexed = null;
- const keywords = consumeKeywords(obj, KwModifiers);
- if (keywords.has("indexed")) {
- if (!allowIndexed) {
- throw new Error("");
- }
- indexed = true;
- }
- const name = obj.peekType("ID") ? obj.pop().text : "";
- if (obj.length) {
- throw new Error("leftover tokens");
- }
- return new ParamType(_guard$2, name, type, baseType, indexed, comps, arrayLength, arrayChildren);
- }
- const name = obj.name;
- assertArgument(!name || (typeof name === "string" && name.match(regexId)), "invalid name", "obj.name", name);
- let indexed = obj.indexed;
- if (indexed != null) {
- assertArgument(allowIndexed, "parameter cannot be indexed", "obj.indexed", obj.indexed);
- indexed = !!indexed;
- }
- let type = obj.type;
- let arrayMatch = type.match(regexArrayType);
- if (arrayMatch) {
- const arrayLength = parseInt(arrayMatch[2] || "-1");
- const arrayChildren = ParamType.from({
- type: arrayMatch[1],
- components: obj.components,
- });
- return new ParamType(_guard$2, name || "", type, "array", indexed, null, arrayLength, arrayChildren);
- }
- if (type === "tuple" ||
- type.startsWith("tuple(" /* fix: ) */) ||
- type.startsWith("(" /* fix: ) */)) {
- const comps = obj.components != null
- ? obj.components.map((c) => ParamType.from(c))
- : null;
- const tuple = new ParamType(_guard$2, name || "", type, "tuple", indexed, comps, null, null);
- // @TODO: use lexer to validate and normalize type
- return tuple;
- }
- type = verifyBasicType(obj.type);
- return new ParamType(_guard$2, name || "", type, type, indexed, null, null, null);
- }
- /**
- * Returns true if %%value%% is a **ParamType**.
- */
- static isParamType(value) {
- return value && value[internal$1] === ParamTypeInternal;
- }
- }
- /**
- * An abstract class to represent An individual fragment from a parse ABI.
- */
- class Fragment {
- /**
- * The type of the fragment.
- */
- type;
- /**
- * The inputs for the fragment.
- */
- inputs;
- /**
- * @private
- */
- constructor(guard, type, inputs) {
- assertPrivate(guard, _guard$2, "Fragment");
- inputs = Object.freeze(inputs.slice());
- defineProperties(this, { type, inputs });
- }
- /**
- * Creates a new **Fragment** for %%obj%%, wich can be any supported
- * ABI frgament type.
- */
- static from(obj) {
- if (typeof obj === "string") {
- // Try parsing JSON...
- try {
- Fragment.from(JSON.parse(obj));
- }
- catch (e) { }
- // ...otherwise, use the human-readable lexer
- return Fragment.from(lex(obj));
- }
- if (obj instanceof TokenString) {
- // Human-readable ABI (already lexed)
- const type = obj.peekKeyword(KwTypes);
- switch (type) {
- case "constructor":
- return ConstructorFragment.from(obj);
- case "error":
- return ErrorFragment.from(obj);
- case "event":
- return EventFragment.from(obj);
- case "fallback":
- case "receive":
- return FallbackFragment.from(obj);
- case "function":
- return FunctionFragment.from(obj);
- case "struct":
- return StructFragment.from(obj);
- }
- }
- else if (typeof obj === "object") {
- // JSON ABI
- switch (obj.type) {
- case "constructor":
- return ConstructorFragment.from(obj);
- case "error":
- return ErrorFragment.from(obj);
- case "event":
- return EventFragment.from(obj);
- case "fallback":
- case "receive":
- return FallbackFragment.from(obj);
- case "function":
- return FunctionFragment.from(obj);
- case "struct":
- return StructFragment.from(obj);
- }
- assert(false, `unsupported type: ${obj.type}`, "UNSUPPORTED_OPERATION", {
- operation: "Fragment.from",
- });
- }
- assertArgument(false, "unsupported frgament object", "obj", obj);
- }
- /**
- * Returns true if %%value%% is a [[ConstructorFragment]].
- */
- static isConstructor(value) {
- return ConstructorFragment.isFragment(value);
- }
- /**
- * Returns true if %%value%% is an [[ErrorFragment]].
- */
- static isError(value) {
- return ErrorFragment.isFragment(value);
- }
- /**
- * Returns true if %%value%% is an [[EventFragment]].
- */
- static isEvent(value) {
- return EventFragment.isFragment(value);
- }
- /**
- * Returns true if %%value%% is a [[FunctionFragment]].
- */
- static isFunction(value) {
- return FunctionFragment.isFragment(value);
- }
- /**
- * Returns true if %%value%% is a [[StructFragment]].
- */
- static isStruct(value) {
- return StructFragment.isFragment(value);
- }
- }
- /**
- * An abstract class to represent An individual fragment
- * which has a name from a parse ABI.
- */
- class NamedFragment extends Fragment {
- /**
- * The name of the fragment.
- */
- name;
- /**
- * @private
- */
- constructor(guard, type, name, inputs) {
- super(guard, type, inputs);
- assertArgument(typeof name === "string" && name.match(regexId), "invalid identifier", "name", name);
- inputs = Object.freeze(inputs.slice());
- defineProperties(this, { name });
- }
- }
- function joinParams(format, params) {
- return ("(" +
- params.map((p) => p.format(format)).join(format === "full" ? ", " : ",") +
- ")");
- }
- /**
- * A Fragment which represents a //Custom Error//.
- */
- class ErrorFragment extends NamedFragment {
- /**
- * @private
- */
- constructor(guard, name, inputs) {
- super(guard, "error", name, inputs);
- Object.defineProperty(this, internal$1, { value: ErrorFragmentInternal });
- }
- /**
- * The Custom Error selector.
- */
- get selector() {
- return id(this.format("sighash")).substring(0, 10);
- }
- format(format) {
- if (format == null) {
- format = "sighash";
- }
- if (format === "json") {
- return JSON.stringify({
- type: "error",
- name: this.name,
- inputs: this.inputs.map((input) => JSON.parse(input.format(format))),
- });
- }
- const result = [];
- if (format !== "sighash") {
- result.push("error");
- }
- result.push(this.name + joinParams(format, this.inputs));
- return result.join(" ");
- }
- static from(obj) {
- if (ErrorFragment.isFragment(obj)) {
- return obj;
- }
- if (typeof obj === "string") {
- return ErrorFragment.from(lex(obj));
- }
- else if (obj instanceof TokenString) {
- const name = consumeName("error", obj);
- const inputs = consumeParams(obj);
- consumeEoi(obj);
- return new ErrorFragment(_guard$2, name, inputs);
- }
- return new ErrorFragment(_guard$2, obj.name, obj.inputs ? obj.inputs.map(ParamType.from) : []);
- }
- static isFragment(value) {
- return value && value[internal$1] === ErrorFragmentInternal;
- }
- }
- /**
- * A Fragment which represents an Event.
- */
- class EventFragment extends NamedFragment {
- anonymous;
- /**
- * @private
- */
- constructor(guard, name, inputs, anonymous) {
- super(guard, "event", name, inputs);
- Object.defineProperty(this, internal$1, { value: EventFragmentInternal });
- defineProperties(this, { anonymous });
- }
- /**
- * The Event topic hash.
- */
- get topicHash() {
- return id(this.format("sighash"));
- }
- format(format) {
- if (format == null) {
- format = "sighash";
- }
- if (format === "json") {
- return JSON.stringify({
- type: "event",
- anonymous: this.anonymous,
- name: this.name,
- inputs: this.inputs.map((i) => JSON.parse(i.format(format))),
- });
- }
- const result = [];
- if (format !== "sighash") {
- result.push("event");
- }
- result.push(this.name + joinParams(format, this.inputs));
- if (format !== "sighash" && this.anonymous) {
- result.push("anonymous");
- }
- return result.join(" ");
- }
- static getTopicHash(name, params) {
- params = (params || []).map((p) => ParamType.from(p));
- const fragment = new EventFragment(_guard$2, name, params, false);
- return fragment.topicHash;
- }
- static from(obj) {
- if (EventFragment.isFragment(obj)) {
- return obj;
- }
- if (typeof obj === "string") {
- return EventFragment.from(lex(obj));
- }
- else if (obj instanceof TokenString) {
- const name = consumeName("event", obj);
- const inputs = consumeParams(obj, true);
- const anonymous = !!consumeKeywords(obj, setify(["anonymous"])).has("anonymous");
- consumeEoi(obj);
- return new EventFragment(_guard$2, name, inputs, anonymous);
- }
- return new EventFragment(_guard$2, obj.name, obj.inputs ? obj.inputs.map((p) => ParamType.from(p, true)) : [], !!obj.anonymous);
- }
- static isFragment(value) {
- return value && value[internal$1] === EventFragmentInternal;
- }
- }
- /**
- * A Fragment which represents a constructor.
- */
- class ConstructorFragment extends Fragment {
- payable;
- energy;
- /**
- * @private
- */
- constructor(guard, type, inputs, payable, energy) {
- super(guard, type, inputs);
- Object.defineProperty(this, internal$1, {
- value: ConstructorFragmentInternal,
- });
- defineProperties(this, { payable, energy });
- }
- format(format) {
- assert(format != null && format !== "sighash", "cannot format a constructor for sighash", "UNSUPPORTED_OPERATION", { operation: "format(sighash)" });
- if (format === "json") {
- return JSON.stringify({
- type: "constructor",
- stateMutability: this.payable ? "payable" : "undefined",
- payable: this.payable,
- energy: this.energy != null ? this.energy : undefined,
- inputs: this.inputs.map((i) => JSON.parse(i.format(format))),
- });
- }
- const result = [`constructor${joinParams(format, this.inputs)}`];
- result.push(this.payable ? "payable" : "nonpayable");
- if (this.energy != null) {
- result.push(`@${this.energy.toString()}`);
- }
- return result.join(" ");
- }
- static from(obj) {
- if (ConstructorFragment.isFragment(obj)) {
- return obj;
- }
- if (typeof obj === "string") {
- return ConstructorFragment.from(lex(obj));
- }
- else if (obj instanceof TokenString) {
- consumeKeywords(obj, setify(["constructor"]));
- const inputs = consumeParams(obj);
- const payable = !!consumeKeywords(obj, setify(["payable"])).has("payable");
- const energy = consumeEnergy(obj);
- consumeEoi(obj);
- return new ConstructorFragment(_guard$2, "constructor", inputs, payable, energy);
- }
- return new ConstructorFragment(_guard$2, "constructor", obj.inputs ? obj.inputs.map(ParamType.from) : [], !!obj.payable, obj.energy != null ? obj.energy : null);
- }
- static isFragment(value) {
- return value && value[internal$1] === ConstructorFragmentInternal;
- }
- }
- /**
- * A Fragment which represents a method.
- */
- class FallbackFragment extends Fragment {
- /**
- * If the function can be sent value during invocation.
- */
- payable;
- constructor(guard, inputs, payable) {
- super(guard, "fallback", inputs);
- Object.defineProperty(this, internal$1, { value: FallbackFragmentInternal });
- defineProperties(this, { payable });
- }
- format(format) {
- const type = this.inputs.length === 0 ? "receive" : "fallback";
- if (format === "json") {
- const stateMutability = this.payable ? "payable" : "nonpayable";
- return JSON.stringify({ type, stateMutability });
- }
- return `${type}()${this.payable ? " payable" : ""}`;
- }
- static from(obj) {
- if (FallbackFragment.isFragment(obj)) {
- return obj;
- }
- if (typeof obj === "string") {
- return FallbackFragment.from(lex(obj));
- }
- else if (obj instanceof TokenString) {
- const errorObj = obj.toString();
- const topIsValid = obj.peekKeyword(setify(["fallback", "receive"]));
- assertArgument(topIsValid, "type must be fallback or receive", "obj", errorObj);
- const type = obj.popKeyword(setify(["fallback", "receive"]));
- // receive()
- if (type === "receive") {
- const inputs = consumeParams(obj);
- assertArgument(inputs.length === 0, `receive cannot have arguments`, "obj.inputs", inputs);
- consumeKeywords(obj, setify(["payable"]));
- consumeEoi(obj);
- return new FallbackFragment(_guard$2, [], true);
- }
- // fallback() [payable]
- // fallback(bytes) [payable] returns (bytes)
- let inputs = consumeParams(obj);
- if (inputs.length) {
- assertArgument(inputs.length === 1 && inputs[0].type === "bytes", "invalid fallback inputs", "obj.inputs", inputs.map((i) => i.format("minimal")).join(", "));
- }
- else {
- inputs = [ParamType.from("bytes")];
- }
- const mutability = consumeMutability(obj);
- assertArgument(mutability === "nonpayable" || mutability === "payable", "fallback cannot be constants", "obj.stateMutability", mutability);
- if (consumeKeywords(obj, setify(["returns"])).has("returns")) {
- const outputs = consumeParams(obj);
- assertArgument(outputs.length === 1 && outputs[0].type === "bytes", "invalid fallback outputs", "obj.outputs", outputs.map((i) => i.format("minimal")).join(", "));
- }
- consumeEoi(obj);
- return new FallbackFragment(_guard$2, inputs, mutability === "payable");
- }
- if (obj.type === "receive") {
- return new FallbackFragment(_guard$2, [], true);
- }
- if (obj.type === "fallback") {
- const inputs = [ParamType.from("bytes")];
- const payable = obj.stateMutability === "payable";
- return new FallbackFragment(_guard$2, inputs, payable);
- }
- assertArgument(false, "invalid fallback description", "obj", obj);
- }
- static isFragment(value) {
- return value && value[internal$1] === FallbackFragmentInternal;
- }
- }
- /**
- * A Fragment which represents a method.
- */
- class FunctionFragment extends NamedFragment {
- /**
- * If the function is constant (e.g. ``pure`` or ``view`` functions).
- */
- constant;
- /**
- * The returned types for the result of calling this function.
- */
- outputs;
- /**
- * The state mutability (e.g. ``payable``, ``nonpayable``, ``view``
- * or ``pure``)
- */
- stateMutability;
- /**
- * If the function can be sent value during invocation.
- */
- payable;
- /**
- * The amount of energy to send when calling this function
- */
- energy;
- /**
- * @private
- */
- constructor(guard, name, stateMutability, inputs, outputs, energy) {
- super(guard, "function", name, inputs);
- Object.defineProperty(this, internal$1, { value: FunctionFragmentInternal });
- outputs = Object.freeze(outputs.slice());
- const constant = stateMutability === "view" || stateMutability === "pure";
- const payable = stateMutability === "payable";
- defineProperties(this, {
- constant,
- energy,
- outputs,
- payable,
- stateMutability,
- });
- }
- /**
- * The Function selector.
- */
- get selector() {
- return id(this.format("sighash")).substring(0, 10);
- }
- format(format) {
- if (format == null) {
- format = "sighash";
- }
- if (format === "json") {
- return JSON.stringify({
- type: "function",
- name: this.name,
- constant: this.constant,
- stateMutability: this.stateMutability !== "nonpayable"
- ? this.stateMutability
- : undefined,
- payable: this.payable,
- energy: this.energy != null ? this.energy : undefined,
- inputs: this.inputs.map((i) => JSON.parse(i.format(format))),
- outputs: this.outputs.map((o) => JSON.parse(o.format(format))),
- });
- }
- const result = [];
- if (format !== "sighash") {
- result.push("function");
- }
- result.push(this.name + joinParams(format, this.inputs));
- if (format !== "sighash") {
- if (this.stateMutability !== "nonpayable") {
- result.push(this.stateMutability);
- }
- if (this.outputs && this.outputs.length) {
- result.push("returns");
- result.push(joinParams(format, this.outputs));
- }
- if (this.energy != null) {
- result.push(`@${this.energy.toString()}`);
- }
- }
- return result.join(" ");
- }
- static getSelector(name, params) {
- params = (params || []).map((p) => ParamType.from(p));
- const fragment = new FunctionFragment(_guard$2, name, "view", params, [], null);
- return fragment.selector;
- }
- static from(obj) {
- if (FunctionFragment.isFragment(obj)) {
- return obj;
- }
- if (typeof obj === "string") {
- return FunctionFragment.from(lex(obj));
- }
- else if (obj instanceof TokenString) {
- const name = consumeName("function", obj);
- const inputs = consumeParams(obj);
- const mutability = consumeMutability(obj);
- let outputs = [];
- if (consumeKeywords(obj, setify(["returns"])).has("returns")) {
- outputs = consumeParams(obj);
- }
- const energy = consumeEnergy(obj);
- consumeEoi(obj);
- return new FunctionFragment(_guard$2, name, mutability, inputs, outputs, energy);
- }
- let stateMutability = obj.stateMutability;
- // Use legacy Solidity ABI logic if stateMutability is missing
- if (stateMutability == null) {
- stateMutability = "payable";
- if (typeof obj.constant === "boolean") {
- stateMutability = "view";
- if (!obj.constant) {
- stateMutability = "payable";
- if (typeof obj.payable === "boolean" && !obj.payable) {
- stateMutability = "nonpayable";
- }
- }
- }
- else if (typeof obj.payable === "boolean" && !obj.payable) {
- stateMutability = "nonpayable";
- }
- }
- // @TODO: verifyState for stateMutability (e.g. throw if
- // payable: false but stateMutability is "nonpayable")
- return new FunctionFragment(_guard$2, obj.name, stateMutability, obj.inputs ? obj.inputs.map(ParamType.from) : [], obj.outputs ? obj.outputs.map(ParamType.from) : [], obj.energy != null ? obj.energy : null);
- }
- static isFragment(value) {
- return value && value[internal$1] === FunctionFragmentInternal;
- }
- }
- /**
- * A Fragment which represents a structure.
- */
- class StructFragment extends NamedFragment {
- /**
- * @private
- */
- constructor(guard, name, inputs) {
- super(guard, "struct", name, inputs);
- Object.defineProperty(this, internal$1, { value: StructFragmentInternal });
- }
- format() {
- throw new Error("@TODO");
- }
- static from(obj) {
- if (typeof obj === "string") {
- return StructFragment.from(lex(obj));
- }
- else if (obj instanceof TokenString) {
- const name = consumeName("struct", obj);
- const inputs = consumeParams(obj);
- consumeEoi(obj);
- return new StructFragment(_guard$2, name, inputs);
- }
- return new StructFragment(_guard$2, obj.name, obj.inputs ? obj.inputs.map(ParamType.from) : []);
- }
- static isFragment(value) {
- return value && value[internal$1] === StructFragmentInternal;
- }
- }
-
- /**
- * When sending values to or receiving values from a [[Contract]], the
- * data is generally encoded using the [ABI standard](link-solc-abi).
- *
- * The AbiCoder provides a utility to encode values to ABI data and
- * decode values from ABI data.
- *
- * Most of the time, developers should favour the [[Contract]] class,
- * which further abstracts a lot of the finer details of ABI data.
- *
- * @_section api/abi/abi-coder:ABI Encoding
- */
- // https://docs.soliditylang.org/en/v0.8.17/control-structures.html
- const PanicReasons$1 = new Map();
- PanicReasons$1.set(0x00, "GENERIC_PANIC");
- PanicReasons$1.set(0x01, "ASSERT_FALSE");
- PanicReasons$1.set(0x11, "OVERFLOW");
- PanicReasons$1.set(0x12, "DIVIDE_BY_ZERO");
- PanicReasons$1.set(0x21, "ENUM_RANGE_ERROR");
- PanicReasons$1.set(0x22, "BAD_STORAGE_DATA");
- PanicReasons$1.set(0x31, "STACK_UNDERFLOW");
- PanicReasons$1.set(0x32, "ARRAY_RANGE_ERROR");
- PanicReasons$1.set(0x41, "OUT_OF_MEMORY");
- PanicReasons$1.set(0x51, "UNINITIALIZED_FUNCTION_CALL");
- const paramTypeBytes = new RegExp(/^bytes([0-9]*)$/);
- const paramTypeNumber = new RegExp(/^(u?int)([0-9]*)$/);
- let defaultCoder = null;
- function getBuiltinCallException(action, tx, data, abiCoder) {
- let message = "missing revert data";
- let reason = null;
- const invocation = null;
- let revert = null;
- if (data) {
- message = "execution reverted";
- const bytes = getBytes(data);
- data = hexlify(data);
- if (bytes.length === 0) {
- message += " (no data present; likely require(false) occurred";
- reason = "require(false)";
- }
- else if (bytes.length % 32 !== 4) {
- message += " (could not decode reason; invalid data length)";
- }
- else if (hexlify(bytes.slice(0, 4)) === "0x08c379a0") {
- // Error(string)
- try {
- reason = abiCoder.decode(["string"], bytes.slice(4))[0];
- revert = {
- signature: "Error(string)",
- name: "Error",
- args: [reason],
- };
- message += `: ${JSON.stringify(reason)}`;
- }
- catch (error) {
- message += " (could not decode reason; invalid string data)";
- }
- }
- else if (hexlify(bytes.slice(0, 4)) === "0x4e487b71") {
- // Panic(uint256)
- try {
- const code = Number(abiCoder.decode(["uint256"], bytes.slice(4))[0]);
- revert = {
- signature: "Panic(uint256)",
- name: "Panic",
- args: [code],
- };
- reason = `Panic due to ${PanicReasons$1.get(code) || "UNKNOWN"}(${code})`;
- message += `: ${reason}`;
- }
- catch (error) {
- message += " (could not decode panic code)";
- }
- }
- else {
- message += " (unknown custom error)";
- }
- }
- const transaction = {
- to: tx.to ? getAddress(tx.to) : null,
- data: tx.data || "0x",
- };
- if (tx.from) {
- transaction.from = getAddress(tx.from);
- }
- return makeError(message, "CALL_EXCEPTION", {
- action,
- data,
- reason,
- transaction,
- invocation,
- revert,
- });
- }
- /**
- * About AbiCoder
- */
- class AbiCoder {
- #getCoder(param) {
- if (param.isArray()) {
- return new ArrayCoder(this.#getCoder(param.arrayChildren), param.arrayLength, param.name);
- }
- if (param.isTuple()) {
- return new TupleCoder(param.components.map((c) => this.#getCoder(c)), param.name);
- }
- switch (param.baseType) {
- case "address":
- return new AddressCoder(param.name);
- case "bool":
- return new BooleanCoder(param.name);
- case "string":
- return new StringCoder(param.name);
- case "bytes":
- return new BytesCoder(param.name);
- case "":
- return new NullCoder(param.name);
- }
- // u?int[0-9]*
- let match = param.type.match(paramTypeNumber);
- if (match) {
- let size = parseInt(match[2] || "256");
- assertArgument(size !== 0 && size <= 256 && size % 8 === 0, "invalid " + match[1] + " bit length", "param", param);
- return new NumberCoder(size / 8, match[1] === "int", param.name);
- }
- // bytes[0-9]+
- match = param.type.match(paramTypeBytes);
- if (match) {
- let size = parseInt(match[1]);
- assertArgument(size !== 0 && size <= 32, "invalid bytes length", "param", param);
- return new FixedBytesCoder(size, param.name);
- }
- assertArgument(false, "invalid type", "type", param.type);
- }
- /**
- * Get the default values for the given %%types%%.
- *
- * For example, a ``uint`` is by default ``0`` and ``bool``
- * is by default ``false``.
- */
- getDefaultValue(types) {
- const coders = types.map((type) => this.#getCoder(ParamType.from(type)));
- const coder = new TupleCoder(coders, "_");
- return coder.defaultValue();
- }
- /**
- * Encode the %%values%% as the %%types%% into ABI data.
- *
- * @returns DataHexstring
- */
- encode(types, values) {
- assertArgumentCount(values.length, types.length, "types/values length mismatch");
- const coders = types.map((type) => this.#getCoder(ParamType.from(type)));
- const coder = new TupleCoder(coders, "_");
- const writer = new Writer();
- coder.encode(writer, values);
- return writer.data;
- }
- /**
- * Decode the ABI %%data%% as the %%types%% into values.
- *
- * If %%loose%% decoding is enabled, then strict padding is
- * not enforced. Some older versions of Solidity incorrectly
- * padded event data emitted from ``external`` functions.
- */
- decode(types, data, loose) {
- const coders = types.map((type) => this.#getCoder(ParamType.from(type)));
- const coder = new TupleCoder(coders, "_");
- return coder.decode(new Reader(data, loose));
- }
- /**
- * Returns the shared singleton instance of a default [[AbiCoder]].
- *
- * On the first call, the instance is created internally.
- */
- static defaultAbiCoder() {
- if (defaultCoder == null) {
- defaultCoder = new AbiCoder();
- }
- return defaultCoder;
- }
- /**
- * Returns an corebc-compatible [[CallExceptionError]] Error for the given
- * result %%data%% for the [[CallExceptionAction]] %%action%% against
- * the Transaction %%tx%%.
- */
- static getBuiltinCallException(action, tx, data) {
- return getBuiltinCallException(action, tx, data, AbiCoder.defaultAbiCoder());
- }
- }
-
- /**
- * About bytes32 strings...
- *
- * @_docloc: api/utils:Bytes32 Strings
- */
- /**
- * Encodes %%text%% as a Bytes32 string.
- */
- function encodeBytes32String(text) {
- // Get the bytes
- const bytes = toUtf8Bytes(text);
- // Check we have room for null-termination
- if (bytes.length > 31) {
- throw new Error("bytes32 string must be less than 32 bytes");
- }
- // Zero-pad (implicitly null-terminates)
- return zeroPadBytes(bytes, 32);
- }
- /**
- * Encodes the Bytes32-encoded %%bytes%% into a string.
- */
- function decodeBytes32String(_bytes) {
- const data = getBytes(_bytes, "bytes");
- // Must be 32 bytes with a null-termination
- if (data.length !== 32) {
- throw new Error("invalid bytes32 - not 32 bytes long");
- }
- if (data[31] !== 0) {
- throw new Error("invalid bytes32 string - no null terminator");
- }
- // Find the null termination
- let length = 31;
- while (data[length - 1] === 0) {
- length--;
- }
- // Determine the string value
- return toUtf8String(data.slice(0, length));
- }
-
- /**
- * About Interface
- *
- * @_subsection api/abi:Interfaces [interfaces]
- */
- class LogDescription {
- fragment;
- name;
- signature;
- topic;
- args;
- constructor(fragment, topic, args) {
- const name = fragment.name, signature = fragment.format();
- defineProperties(this, {
- fragment,
- name,
- signature,
- topic,
- args,
- });
- }
- }
- class TransactionDescription {
- fragment;
- name;
- args;
- signature;
- selector;
- value;
- constructor(fragment, selector, args, value) {
- const name = fragment.name, signature = fragment.format();
- defineProperties(this, {
- fragment,
- name,
- args,
- signature,
- selector,
- value,
- });
- }
- }
- class ErrorDescription {
- fragment;
- name;
- args;
- signature;
- selector;
- constructor(fragment, selector, args) {
- const name = fragment.name, signature = fragment.format();
- defineProperties(this, {
- fragment,
- name,
- args,
- signature,
- selector,
- });
- }
- }
- class Indexed {
- hash;
- _isIndexed;
- static isIndexed(value) {
- return !!(value && value._isIndexed);
- }
- constructor(hash) {
- defineProperties(this, { hash, _isIndexed: true });
- }
- }
- // https://docs.soliditylang.org/en/v0.8.13/control-structures.html?highlight=panic#panic-via-assert-and-error-via-require
- const PanicReasons = {
- "0": "generic panic",
- "1": "assert(false)",
- "17": "arithmetic overflow",
- "18": "division or modulo by zero",
- "33": "enum overflow",
- "34": "invalid encoded storage byte array accessed",
- "49": "out-of-bounds array access; popping on an empty array",
- "50": "out-of-bounds access of an array or bytesN",
- "65": "out of memory",
- "81": "uninitialized function",
- };
- const BuiltinErrors = {
- "0x08c379a0": {
- signature: "Error(string)",
- name: "Error",
- inputs: ["string"],
- reason: (message) => {
- return `reverted with reason string ${JSON.stringify(message)}`;
- },
- },
- "0x4e487b71": {
- signature: "Panic(uint256)",
- name: "Panic",
- inputs: ["uint256"],
- reason: (code) => {
- let reason = "unknown panic code";
- if (code >= 0 && code <= 0xff && PanicReasons[code.toString()]) {
- reason = PanicReasons[code.toString()];
- }
- return `reverted with panic code 0x${code.toString(16)} (${reason})`;
- },
- },
- };
- /**
- * An Interface abstracts many of the low-level details for
- * encoding and decoding the data on the blockchain.
- *
- * An ABI provides information on how to encode data to send to
- * a Contract, how to decode the results and events and how to
- * interpret revert errors.
- *
- * The ABI can be specified by [any supported format](InterfaceAbi).
- */
- class Interface {
- /**
- * All the Contract ABI members (i.e. methods, events, errors, etc).
- */
- fragments;
- /**
- * The Contract constructor.
- */
- deploy;
- /**
- * The Fallback method, if any.
- */
- fallback;
- /**
- * If receiving xcb is supported.
- */
- receive;
- #errors;
- #events;
- #functions;
- // #structs: Map;
- #abiCoder;
- /**
- * Create a new Interface for the %%fragments%%.
- */
- constructor(fragments) {
- let abi = [];
- if (typeof fragments === "string") {
- abi = JSON.parse(fragments);
- }
- else {
- abi = fragments;
- }
- this.#functions = new Map();
- this.#errors = new Map();
- this.#events = new Map();
- // this.#structs = new Map();
- const frags = [];
- for (const a of abi) {
- try {
- frags.push(Fragment.from(a));
- }
- catch (error) {
- console.log("EE", error);
- }
- }
- defineProperties(this, {
- fragments: Object.freeze(frags),
- });
- let fallback = null;
- let receive = false;
- this.#abiCoder = this.getAbiCoder();
- // Add all fragments by their signature
- this.fragments.forEach((fragment, index) => {
- let bucket;
- switch (fragment.type) {
- case "constructor":
- if (this.deploy) {
- console.log("duplicate definition - constructor");
- return;
- }
- //checkNames(fragment, "input", fragment.inputs);
- defineProperties(this, {
- deploy: fragment,
- });
- return;
- case "fallback":
- if (fragment.inputs.length === 0) {
- receive = true;
- }
- else {
- assertArgument(!fallback ||
- fragment.payable !== fallback.payable, "conflicting fallback fragments", `fragments[${index}]`, fragment);
- fallback = fragment;
- receive = fallback.payable;
- }
- return;
- case "function":
- //checkNames(fragment, "input", fragment.inputs);
- //checkNames(fragment, "output", (fragment).outputs);
- bucket = this.#functions;
- break;
- case "event":
- //checkNames(fragment, "input", fragment.inputs);
- bucket = this.#events;
- break;
- case "error":
- bucket = this.#errors;
- break;
- default:
- return;
- }
- // Two identical entries; ignore it
- const signature = fragment.format();
- if (bucket.has(signature)) {
- return;
- }
- bucket.set(signature, fragment);
- });
- // If we do not have a constructor add a default
- if (!this.deploy) {
- defineProperties(this, {
- deploy: ConstructorFragment.from("constructor()"),
- });
- }
- defineProperties(this, { fallback, receive });
- }
- /**
- * Returns the entire Human-Readable ABI, as an array of
- * signatures, optionally as %%minimal%% strings, which
- * removes parameter names and unneceesary spaces.
- */
- format(minimal) {
- const format = minimal ? "minimal" : "full";
- const abi = this.fragments.map((f) => f.format(format));
- return abi;
- }
- /**
- * Return the JSON-encoded ABI. This is the format Solidiy
- * returns.
- */
- formatJson() {
- const abi = this.fragments.map((f) => f.format("json"));
- // We need to re-bundle the JSON fragments a bit
- return JSON.stringify(abi.map((j) => JSON.parse(j)));
- }
- /**
- * The ABI coder that will be used to encode and decode binary
- * data.
- */
- getAbiCoder() {
- return AbiCoder.defaultAbiCoder();
- }
- // Find a function definition by any means necessary (unless it is ambiguous)
- #getFunction(key, values, forceUnique) {
- // Selector
- if (isHexString(key)) {
- const selector = key.toLowerCase();
- for (const fragment of this.#functions.values()) {
- if (selector === fragment.selector) {
- return fragment;
- }
- }
- return null;
- }
- // It is a bare name, look up the function (will return null if ambiguous)
- if (key.indexOf("(") === -1) {
- const matching = [];
- for (const [name, fragment] of this.#functions) {
- if (name.split("(" /* fix:) */)[0] === key) {
- matching.push(fragment);
- }
- }
- if (values) {
- const lastValue = values.length > 0 ? values[values.length - 1] : null;
- let valueLength = values.length;
- let allowOptions = true;
- if (Typed.isTyped(lastValue) && lastValue.type === "overrides") {
- allowOptions = false;
- valueLength--;
- }
- // Remove all matches that don't have a compatible length. The args
- // may contain an overrides, so the match may have n or n - 1 parameters
- for (let i = matching.length - 1; i >= 0; i--) {
- const inputs = matching[i].inputs.length;
- if (inputs !== valueLength &&
- (!allowOptions || inputs !== valueLength - 1)) {
- matching.splice(i, 1);
- }
- }
- // Remove all matches that don't match the Typed signature
- for (let i = matching.length - 1; i >= 0; i--) {
- const inputs = matching[i].inputs;
- for (let j = 0; j < values.length; j++) {
- // Not a typed value
- if (!Typed.isTyped(values[j])) {
- continue;
- }
- // We are past the inputs
- if (j >= inputs.length) {
- if (values[j].type === "overrides") {
- continue;
- }
- matching.splice(i, 1);
- break;
- }
- // Make sure the value type matches the input type
- if (values[j].type !== inputs[j].baseType) {
- matching.splice(i, 1);
- break;
- }
- }
- }
- }
- // We found a single matching signature with an overrides, but the
- // last value is something that cannot possibly be an options
- if (matching.length === 1 &&
- values &&
- values.length !== matching[0].inputs.length) {
- const lastArg = values[values.length - 1];
- if (lastArg == null ||
- Array.isArray(lastArg) ||
- typeof lastArg !== "object") {
- matching.splice(0, 1);
- }
- }
- if (matching.length === 0) {
- return null;
- }
- if (matching.length > 1 && forceUnique) {
- const matchStr = matching
- .map((m) => JSON.stringify(m.format()))
- .join(", ");
- assertArgument(false, `ambiguous function description (i.e. matches ${matchStr})`, "key", key);
- }
- return matching[0];
- }
- // Normalize the signature and lookup the function
- const result = this.#functions.get(FunctionFragment.from(key).format());
- if (result) {
- return result;
- }
- return null;
- }
- /**
- * Get the function name for %%key%%, which may be a function selector,
- * function name or function signature that belongs to the ABI.
- */
- getFunctionName(key) {
- const fragment = this.#getFunction(key, null, false);
- assertArgument(fragment, "no matching function", "key", key);
- return fragment.name;
- }
- /**
- * Returns true if %%key%% (a function selector, function name or
- * function signature) is present in the ABI.
- *
- * In the case of a function name, the name may be ambiguous, so
- * accessing the [[FunctionFragment]] may require refinement.
- */
- hasFunction(key) {
- return !!this.#getFunction(key, null, false);
- }
- /**
- * Get the [[FunctionFragment]] for %%key%%, which may be a function
- * selector, function name or function signature that belongs to the ABI.
- *
- * If %%values%% is provided, it will use the Typed API to handle
- * ambiguous cases where multiple functions match by name.
- *
- * If the %%key%% and %%values%% do not refine to a single function in
- * the ABI, this will throw.
- */
- getFunction(key, values) {
- return this.#getFunction(key, values || null, true);
- }
- /**
- * Iterate over all functions, calling %%callback%%, sorted by their name.
- */
- forEachFunction(callback) {
- const names = Array.from(this.#functions.keys());
- names.sort((a, b) => a.localeCompare(b));
- for (let i = 0; i < names.length; i++) {
- const name = names[i];
- callback(this.#functions.get(name), i);
- }
- }
- // Find an event definition by any means necessary (unless it is ambiguous)
- #getEvent(key, values, forceUnique) {
- // EventTopic
- if (isHexString(key)) {
- const eventTopic = key.toLowerCase();
- for (const fragment of this.#events.values()) {
- if (eventTopic === fragment.topicHash) {
- return fragment;
- }
- }
- return null;
- }
- // It is a bare name, look up the function (will return null if ambiguous)
- if (key.indexOf("(") === -1) {
- const matching = [];
- for (const [name, fragment] of this.#events) {
- if (name.split("(" /* fix:) */)[0] === key) {
- matching.push(fragment);
- }
- }
- if (values) {
- // Remove all matches that don't have a compatible length.
- for (let i = matching.length - 1; i >= 0; i--) {
- if (matching[i].inputs.length < values.length) {
- matching.splice(i, 1);
- }
- }
- // Remove all matches that don't match the Typed signature
- for (let i = matching.length - 1; i >= 0; i--) {
- const inputs = matching[i].inputs;
- for (let j = 0; j < values.length; j++) {
- // Not a typed value
- if (!Typed.isTyped(values[j])) {
- continue;
- }
- // Make sure the value type matches the input type
- if (values[j].type !== inputs[j].baseType) {
- matching.splice(i, 1);
- break;
- }
- }
- }
- }
- if (matching.length === 0) {
- return null;
- }
- if (matching.length > 1 && forceUnique) {
- const matchStr = matching
- .map((m) => JSON.stringify(m.format()))
- .join(", ");
- assertArgument(false, `ambiguous event description (i.e. matches ${matchStr})`, "key", key);
- }
- return matching[0];
- }
- // Normalize the signature and lookup the function
- const result = this.#events.get(EventFragment.from(key).format());
- if (result) {
- return result;
- }
- return null;
- }
- /**
- * Get the event name for %%key%%, which may be a topic hash,
- * event name or event signature that belongs to the ABI.
- */
- getEventName(key) {
- const fragment = this.#getEvent(key, null, false);
- assertArgument(fragment, "no matching event", "key", key);
- return fragment.name;
- }
- /**
- * Returns true if %%key%% (an event topic hash, event name or
- * event signature) is present in the ABI.
- *
- * In the case of an event name, the name may be ambiguous, so
- * accessing the [[EventFragment]] may require refinement.
- */
- hasEvent(key) {
- return !!this.#getEvent(key, null, false);
- }
- /**
- * Get the [[EventFragment]] for %%key%%, which may be a topic hash,
- * event name or event signature that belongs to the ABI.
- *
- * If %%values%% is provided, it will use the Typed API to handle
- * ambiguous cases where multiple events match by name.
- *
- * If the %%key%% and %%values%% do not refine to a single event in
- * the ABI, this will throw.
- */
- getEvent(key, values) {
- return this.#getEvent(key, values || null, true);
- }
- /**
- * Iterate over all events, calling %%callback%%, sorted by their name.
- */
- forEachEvent(callback) {
- const names = Array.from(this.#events.keys());
- names.sort((a, b) => a.localeCompare(b));
- for (let i = 0; i < names.length; i++) {
- const name = names[i];
- callback(this.#events.get(name), i);
- }
- }
- /**
- * Get the [[ErrorFragment]] for %%key%%, which may be an error
- * selector, error name or error signature that belongs to the ABI.
- *
- * If %%values%% is provided, it will use the Typed API to handle
- * ambiguous cases where multiple errors match by name.
- *
- * If the %%key%% and %%values%% do not refine to a single error in
- * the ABI, this will throw.
- */
- getError(key, values) {
- if (isHexString(key)) {
- const selector = key.toLowerCase();
- if (BuiltinErrors[selector]) {
- return ErrorFragment.from(BuiltinErrors[selector].signature);
- }
- for (const fragment of this.#errors.values()) {
- if (selector === fragment.selector) {
- return fragment;
- }
- }
- return null;
- }
- // It is a bare name, look up the function (will return null if ambiguous)
- if (key.indexOf("(") === -1) {
- const matching = [];
- for (const [name, fragment] of this.#errors) {
- if (name.split("(" /* fix:) */)[0] === key) {
- matching.push(fragment);
- }
- }
- if (matching.length === 0) {
- if (key === "Error") {
- return ErrorFragment.from("error Error(string)");
- }
- if (key === "Panic") {
- return ErrorFragment.from("error Panic(uint256)");
- }
- return null;
- }
- else if (matching.length > 1) {
- const matchStr = matching
- .map((m) => JSON.stringify(m.format()))
- .join(", ");
- assertArgument(false, `ambiguous error description (i.e. ${matchStr})`, "name", key);
- }
- return matching[0];
- }
- // Normalize the signature and lookup the function
- key = ErrorFragment.from(key).format();
- if (key === "Error(string)") {
- return ErrorFragment.from("error Error(string)");
- }
- if (key === "Panic(uint256)") {
- return ErrorFragment.from("error Panic(uint256)");
- }
- const result = this.#errors.get(key);
- if (result) {
- return result;
- }
- return null;
- }
- /**
- * Iterate over all errors, calling %%callback%%, sorted by their name.
- */
- forEachError(callback) {
- const names = Array.from(this.#errors.keys());
- names.sort((a, b) => a.localeCompare(b));
- for (let i = 0; i < names.length; i++) {
- const name = names[i];
- callback(this.#errors.get(name), i);
- }
- }
- // Get the 4-byte selector used by Solidity to identify a function
- /*
- getSelector(fragment: ErrorFragment | FunctionFragment): string {
- if (typeof(fragment) === "string") {
- const matches: Array = [ ];
-
- try { matches.push(this.getFunction(fragment)); } catch (error) { }
- try { matches.push(this.getError(fragment)); } catch (_) { }
-
- if (matches.length === 0) {
- logger.throwArgumentError("unknown fragment", "key", fragment);
- } else if (matches.length > 1) {
- logger.throwArgumentError("ambiguous fragment matches function and error", "key", fragment);
- }
-
- fragment = matches[0];
- }
-
- return dataSlice(id(fragment.format()), 0, 4);
- }
- */
- // Get the 32-byte topic hash used by Solidity to identify an event
- /*
- getEventTopic(fragment: EventFragment): string {
- //if (typeof(fragment) === "string") { fragment = this.getEvent(eventFragment); }
- return id(fragment.format());
- }
- */
- _decodeParams(params, data) {
- return this.#abiCoder.decode(params, data);
- }
- _encodeParams(params, values) {
- return this.#abiCoder.encode(params, values);
- }
- /**
- * Encodes a ``tx.data`` object for deploying the Contract with
- * the %%values%% as the constructor arguments.
- */
- encodeDeploy(values) {
- return this._encodeParams(this.deploy.inputs, values || []);
- }
- /**
- * Decodes the result %%data%% (e.g. from an ``xcb_call``) for the
- * specified error (see [[getError]] for valid values for
- * %%key%%).
- *
- * Most developers should prefer the [[parseCallResult]] method instead,
- * which will automatically detect a ``CALL_EXCEPTION`` and throw the
- * corresponding error.
- */
- decodeErrorResult(fragment, data) {
- if (typeof fragment === "string") {
- const f = this.getError(fragment);
- assertArgument(f, "unknown error", "fragment", fragment);
- fragment = f;
- }
- assertArgument(dataSlice(data, 0, 4) === fragment.selector, `data signature does not match error ${fragment.name}.`, "data", data);
- return this._decodeParams(fragment.inputs, dataSlice(data, 4));
- }
- /**
- * Encodes the transaction revert data for a call result that
- * reverted from the the Contract with the sepcified %%error%%
- * (see [[getError]] for valid values for %%fragment%%) with the %%values%%.
- *
- * This is generally not used by most developers, unless trying to mock
- * a result from a Contract.
- */
- encodeErrorResult(fragment, values) {
- if (typeof fragment === "string") {
- const f = this.getError(fragment);
- assertArgument(f, "unknown error", "fragment", fragment);
- fragment = f;
- }
- return concat([
- fragment.selector,
- this._encodeParams(fragment.inputs, values || []),
- ]);
- }
- /**
- * Decodes the %%data%% from a transaction ``tx.data`` for
- * the function specified (see [[getFunction]] for valid values
- * for %%fragment%%).
- *
- * Most developers should prefer the [[parseTransaction]] method
- * instead, which will automatically detect the fragment.
- */
- decodeFunctionData(fragment, data) {
- if (typeof fragment === "string") {
- const f = this.getFunction(fragment);
- assertArgument(f, "unknown function", "fragment", fragment);
- fragment = f;
- }
- assertArgument(dataSlice(data, 0, 4) === fragment.selector, `data signature does not match function ${fragment.name}.`, "data", data);
- return this._decodeParams(fragment.inputs, dataSlice(data, 4));
- }
- /**
- * Encodes the ``tx.data`` for a transaction that calls the function
- * specified (see [[getFunction]] for valid values for %%fragment%%) with
- * the %%values%%.
- */
- encodeFunctionData(fragment, values) {
- if (typeof fragment === "string") {
- const f = this.getFunction(fragment);
- assertArgument(f, "unknown function", "fragment", fragment);
- fragment = f;
- }
- return concat([
- fragment.selector,
- this._encodeParams(fragment.inputs, values || []),
- ]);
- }
- /**
- * Decodes the result %%data%% (e.g. from an ``xcb_call``) for the
- * specified function (see [[getFunction]] for valid values for
- * %%key%%).
- *
- * Most developers should prefer the [[parseCallResult]] method instead,
- * which will automatically detect a ``CALL_EXCEPTION`` and throw the
- * corresponding error.
- */
- decodeFunctionResult(fragment, data) {
- if (typeof fragment === "string") {
- const f = this.getFunction(fragment);
- assertArgument(f, "unknown function", "fragment", fragment);
- fragment = f;
- }
- let message = "invalid length for result data";
- const bytes = getBytesCopy(data);
- if (bytes.length % 32 === 0) {
- try {
- return this.#abiCoder.decode(fragment.outputs, bytes);
- }
- catch (error) {
- message = "could not decode result data";
- }
- }
- // Call returned data with no error, but the data is junk
- assert(false, message, "BAD_DATA", {
- value: hexlify(bytes),
- info: { method: fragment.name, signature: fragment.format() },
- });
- }
- makeError(_data, tx) {
- const data = getBytes(_data, "data");
- const error = AbiCoder.getBuiltinCallException("call", tx, data);
- // Not a built-in error; try finding a custom error
- const customPrefix = "execution reverted (unknown custom error)";
- if (error.message.startsWith(customPrefix)) {
- const selector = hexlify(data.slice(0, 4));
- const ef = this.getError(selector);
- if (ef) {
- try {
- const args = this.#abiCoder.decode(ef.inputs, data.slice(4));
- error.revert = {
- name: ef.name,
- signature: ef.format(),
- args,
- };
- error.reason = error.revert.signature;
- error.message = `execution reverted: ${error.reason}`;
- }
- catch (e) {
- error.message = `execution reverted (coult not decode custom error)`;
- }
- }
- }
- // Add the invocation, if available
- const parsed = this.parseTransaction(tx);
- if (parsed) {
- error.invocation = {
- method: parsed.name,
- signature: parsed.signature,
- args: parsed.args,
- };
- }
- return error;
- }
- /**
- * Encodes the result data (e.g. from an ``xcb_call``) for the
- * specified function (see [[getFunction]] for valid values
- * for %%fragment%%) with %%values%%.
- *
- * This is generally not used by most developers, unless trying to mock
- * a result from a Contract.
- */
- encodeFunctionResult(fragment, values) {
- if (typeof fragment === "string") {
- const f = this.getFunction(fragment);
- assertArgument(f, "unknown function", "fragment", fragment);
- fragment = f;
- }
- return hexlify(this.#abiCoder.encode(fragment.outputs, values || []));
- }
- /*
- spelunk(inputs: Array, values: ReadonlyArray, processfunc: (type: string, value: any) => Promise): Promise> {
- const promises: Array> = [ ];
- const process = function(type: ParamType, value: any): any {
- if (type.baseType === "array") {
- return descend(type.child
- }
- if (type. === "address") {
- }
- };
-
- const descend = function (inputs: Array, values: ReadonlyArray) {
- if (inputs.length !== values.length) { throw new Error("length mismatch"); }
- };
-
- const result: Array = [ ];
- values.forEach((value, index) => {
- if (value == null) {
- topics.push(null);
- } else if (param.baseType === "array" || param.baseType === "tuple") {
- logger.throwArgumentError("filtering with tuples or arrays not supported", ("contract." + param.name), value);
- } else if (Array.isArray(value)) {
- topics.push(value.map((value) => encodeTopic(param, value)));
- } else {
- topics.push(encodeTopic(param, value));
- }
- });
- }
- */
- // Create the filter for the event with search criteria (e.g. for xcb_filterLog)
- encodeFilterTopics(fragment, values) {
- if (typeof fragment === "string") {
- const f = this.getEvent(fragment);
- assertArgument(f, "unknown event", "eventFragment", fragment);
- fragment = f;
- }
- assert(values.length <= fragment.inputs.length, `too many arguments for ${fragment.format()}`, "UNEXPECTED_ARGUMENT", { count: values.length, expectedCount: fragment.inputs.length });
- const topics = [];
- if (!fragment.anonymous) {
- topics.push(fragment.topicHash);
- }
- // @TODO: Use the coders for this; to properly support tuples, etc.
- const encodeTopic = (param, value) => {
- if (param.type === "string") {
- return id(value);
- }
- else if (param.type === "bytes") {
- return sha256(hexlify(value));
- }
- if (param.type === "bool" && typeof value === "boolean") {
- value = value ? "0x01" : "0x00";
- }
- if (param.type.match(/^u?int/)) {
- value = toBeHex(value);
- }
- // Check addresses are valid
- if (param.type === "address") {
- this.#abiCoder.encode(["address"], [value]);
- }
- return zeroPadValue(hexlify(value), 32);
- //@TOOD should probably be return toHex(value, 32)
- };
- values.forEach((value, index) => {
- const param = fragment.inputs[index];
- if (!param.indexed) {
- assertArgument(value == null, "cannot filter non-indexed parameters; must be null", "contract." + param.name, value);
- return;
- }
- if (value == null) {
- topics.push(null);
- }
- else if (param.baseType === "array" || param.baseType === "tuple") {
- assertArgument(false, "filtering with tuples or arrays not supported", "contract." + param.name, value);
- }
- else if (Array.isArray(value)) {
- topics.push(value.map((value) => encodeTopic(param, value)));
- }
- else {
- topics.push(encodeTopic(param, value));
- }
- });
- // Trim off trailing nulls
- while (topics.length && topics[topics.length - 1] === null) {
- topics.pop();
- }
- return topics;
- }
- encodeEventLog(fragment, values) {
- if (typeof fragment === "string") {
- const f = this.getEvent(fragment);
- assertArgument(f, "unknown event", "eventFragment", fragment);
- fragment = f;
- }
- const topics = [];
- const dataTypes = [];
- const dataValues = [];
- if (!fragment.anonymous) {
- topics.push(fragment.topicHash);
- }
- assertArgument(values.length === fragment.inputs.length, "event arguments/values mismatch", "values", values);
- fragment.inputs.forEach((param, index) => {
- const value = values[index];
- if (param.indexed) {
- if (param.type === "string") {
- topics.push(id(value));
- }
- else if (param.type === "bytes") {
- topics.push(sha256(value));
- }
- else if (param.baseType === "tuple" || param.baseType === "array") {
- // @TODO
- throw new Error("not implemented");
- }
- else {
- topics.push(this.#abiCoder.encode([param.type], [value]));
- }
- }
- else {
- dataTypes.push(param);
- dataValues.push(value);
- }
- });
- return {
- data: this.#abiCoder.encode(dataTypes, dataValues),
- topics: topics,
- };
- }
- // Decode a filter for the event and the search criteria
- decodeEventLog(fragment, data, topics) {
- if (typeof fragment === "string") {
- const f = this.getEvent(fragment);
- assertArgument(f, "unknown event", "eventFragment", fragment);
- fragment = f;
- }
- if (topics != null && !fragment.anonymous) {
- const eventTopic = fragment.topicHash;
- assertArgument(isHexString(topics[0], 32) && topics[0].toLowerCase() === eventTopic, "fragment/topic mismatch", "topics[0]", topics[0]);
- topics = topics.slice(1);
- }
- const indexed = [];
- const nonIndexed = [];
- const dynamic = [];
- fragment.inputs.forEach((param, index) => {
- if (param.indexed) {
- if (param.type === "string" ||
- param.type === "bytes" ||
- param.baseType === "tuple" ||
- param.baseType === "array") {
- indexed.push(ParamType.from({ type: "bytes32", name: param.name }));
- dynamic.push(true);
- }
- else {
- indexed.push(param);
- dynamic.push(false);
- }
- }
- else {
- nonIndexed.push(param);
- dynamic.push(false);
- }
- });
- const resultIndexed = topics != null ? this.#abiCoder.decode(indexed, concat(topics)) : null;
- const resultNonIndexed = this.#abiCoder.decode(nonIndexed, data, true);
- //const result: (Array & { [ key: string ]: any }) = [ ];
- const values = [];
- const keys = [];
- let nonIndexedIndex = 0, indexedIndex = 0;
- fragment.inputs.forEach((param, index) => {
- let value = null;
- if (param.indexed) {
- if (resultIndexed == null) {
- value = new Indexed(null);
- }
- else if (dynamic[index]) {
- value = new Indexed(resultIndexed[indexedIndex++]);
- }
- else {
- try {
- value = resultIndexed[indexedIndex++];
- }
- catch (error) {
- value = error;
- }
- }
- }
- else {
- try {
- value = resultNonIndexed[nonIndexedIndex++];
- }
- catch (error) {
- value = error;
- }
- }
- values.push(value);
- keys.push(param.name || null);
- });
- return Result.fromItems(values, keys);
- }
- /**
- * Parses a transaction, finding the matching function and extracts
- * the parameter values along with other useful function details.
- *
- * If the matching function cannot be found, return null.
- */
- parseTransaction(tx) {
- const data = getBytes(tx.data, "tx.data");
- const value = getBigInt(tx.value != null ? tx.value : 0, "tx.value");
- const fragment = this.getFunction(hexlify(data.slice(0, 4)));
- if (!fragment) {
- return null;
- }
- const args = this.#abiCoder.decode(fragment.inputs, data.slice(4));
- return new TransactionDescription(fragment, fragment.selector, args, value);
- }
- parseCallResult(data) {
- throw new Error("@TODO");
- }
- /**
- * Parses a receipt log, finding the matching event and extracts
- * the parameter values along with other useful event details.
- *
- * If the matching event cannot be found, returns null.
- */
- parseLog(log) {
- const fragment = this.getEvent(log.topics[0]);
- if (!fragment || fragment.anonymous) {
- return null;
- }
- // @TODO: If anonymous, and the only method, and the input count matches, should we parse?
- // Probably not, because just because it is the only event in the ABI does
- // not mean we have the full ABI; maybe just a fragment?
- return new LogDescription(fragment, fragment.topicHash, this.decodeEventLog(fragment, log.data, log.topics));
- }
- /**
- * Parses a revert data, finding the matching error and extracts
- * the parameter values along with other useful error details.
- *
- * If the matching event cannot be found, returns null.
- */
- parseError(data) {
- const hexData = hexlify(data);
- const fragment = this.getError(dataSlice(hexData, 0, 4));
- if (!fragment) {
- return null;
- }
- const args = this.#abiCoder.decode(fragment.inputs, dataSlice(hexData, 4));
- return new ErrorDescription(fragment, fragment.selector, args);
- }
- /**
- * Creates a new [[Interface]] from the ABI %%value%%.
- *
- * The %%value%% may be provided as an existing [[Interface]] object,
- * a JSON-encoded ABI or any Human-Readable ABI format.
- */
- static from(value) {
- // Already an Interface, which is immutable
- if (value instanceof Interface) {
- return value;
- }
- // JSON
- if (typeof value === "string") {
- return new Interface(JSON.parse(value));
- }
- // Maybe an interface from an older version, or from a symlinked copy
- if (typeof value.format === "function") {
- return new Interface(value.format("json"));
- }
- // Array of fragments
- return new Interface(value);
- }
- }
-
- const logger = new Logger("contract-address/0.0.1");
- /**
- * Returns the address that would result from a ``CREATE`` for %%tx%%.
- *
- * This can be used to compute the address a contract will be
- * deployed to by an EOA when sending a deployment transaction (i.e.
- * when the ``to`` address is ``null``).
- *
- * This can also be used to compute the address a contract will be
- * deployed to by a contract, by using the contract's address as the
- * ``to`` and the contract's nonce.
- *
- * @example
- * from = "0x8ba1f109551bD432803012645Ac136ddd64DBA72";
- * nonce = 5;
- *
- * getCreateAddress({ from, nonce });
- * //_result:
- */
- function getCreateAddress(tx) {
- const from = getAddress(tx.from);
- const nonce = getBigInt(tx.nonce, "tx.nonce");
- let nonceHex = nonce.toString(16);
- if (nonceHex === "0") {
- nonceHex = "0x";
- }
- else if (nonceHex.length % 2) {
- nonceHex = "0x0" + nonceHex;
- }
- else {
- nonceHex = "0x" + nonceHex;
- }
- return getAddress(from);
- }
- /**
- * Returns the address that would result from a ``CREATE2`` operation
- * with the given %%from%%, %%salt%% and %%initCodeHash%%.
-
- * For a quick overview and example of ``CREATE2``, see [[link-ricmoo-wisps]].
- *
- * @example
- * // The address of the contract
- * from = "0x8ba1f109551bD432803012645Ac136ddd64DBA72"
- *
- * // The salt
- * salt = id("HelloWorld")
- *
- * getCreate2Address(from, salt, initCodeHash)
- * //_result:
- */
- function getCreate2Address(from, salt, initCodeHash) {
- if (hexDataLength(salt) !== 32) {
- logger.throwArgumentError("salt must be 32 bytes", "salt", salt);
- }
- if (hexDataLength(initCodeHash) !== 32) {
- logger.throwArgumentError("initCodeHash must be 32 bytes", "initCodeHash", initCodeHash);
- }
- const val = hexDataSlice(sha256(concat(["0xff", getAddress(from), salt, initCodeHash])), 12);
- console.log({ "contract-address/74=>should be string": val });
- const prefix = from.substring(2, 4);
- const checksum = calculateCheckSum(val, prefix);
- return "0x" + prefix + checksum + removeHexPrefix(val);
- }
-
- /**
- * Returns true if %%value%% is an object which implements the
- * [[Addressable]] interface.
- *
- * @example:
- * // Wallets and AbstractSigner sub-classes
- * isAddressable(Wallet.createRandom())
- * //_result:
- *
- * // Contracts
- * contract = new Contract("dai.tokens.corebc.eth", [ ], provider)
- * isAddressable(contract)
- * //_result:
- */
- function isAddressable(value) {
- return value && typeof value.getAddress === "function";
- }
- /**
- * Returns true if %%value%% is a valid address.
- *
- * @example:
- * // Valid address
- * isAddress("0x8ba1f109551bD432803012645Ac136ddd64DBA72")
- * //_result:
- *
- * // Valid ICAP address
- * isAddress("XE65GB6LDNXYOFTX0NSV3FUWKOWIXAMJK36")
- * //_result:
- *
- * // Invalid checksum
- * isAddress("0x8Ba1f109551bD432803012645Ac136ddd64DBa72")
- * //_result:
- *
- * // Invalid ICAP checksum
- * isAddress("0x8Ba1f109551bD432803012645Ac136ddd64DBA72")
- * //_result:
- *
- * // Not an address (an ENS name requires a provided and an
- * // asynchronous API to access)
- * isAddress("ricmoo.eth")
- * //_result:
- */
- function isAddress(value) {
- try {
- getAddress(value);
- return true;
- }
- catch (error) { }
- return false;
- }
- async function checkAddress(target, promise) {
- const result = await promise;
- if (result == null ||
- result === "0x0000000000000000000000000000000000000000") {
- assert(typeof target !== "string", "unconfigured name", "UNCONFIGURED_NAME", { value: target });
- assertArgument(false, "invalid AddressLike value; did not resolve to a value address", "target", target);
- }
- return getAddress(result);
- }
- /**
- * Resolves to an address for the %%target%%, which may be any
- * supported address type, an [[Addressable]] or a Promise which
- * resolves to an address.
- *
- * If an ENS name is provided, but that name has not been correctly
- * configured a [[UnconfiguredNameError]] is thrown.
- *
- * @example:
- * addr = "0x6B175474E89094C44Da98b954EedeAC495271d0F"
- *
- * // Addresses are return synchronously
- * resolveAddress(addr, provider)
- * //_result:
- *
- * // Address promises are resolved asynchronously
- * resolveAddress(Promise.resolve(addr))
- * //_result:
- *
- *
- * // Addressable objects are resolved asynchronously
- * contract = new Contract(addr, [ ])
- * resolveAddress(contract, provider)
- * //_result:
- *
- * // Unconfigured ENS names reject
- * resolveAddress("nothing-here.ricmoo.eth", provider)
- * //_error:
- *
- * // ENS names require a NameResolver object passed in
- * // (notice the provider was omitted)
- * resolveAddress("nothing-here.ricmoo.eth")
- * //_error:
- */
- function resolveAddress(target) {
- if (typeof target === "string") {
- return getAddress(target);
- // assert(resolver != null, "ENS resolution requires a provider",
- // "UNSUPPORTED_OPERATION", { operation: "resolveName" });
- // return checkAddress(target, resolver.resolveName(target));
- }
- else if (isAddressable(target)) {
- return checkAddress(target, target.getAddress());
- }
- else if (target && typeof target.then === "function") {
- return checkAddress(target, target);
- }
- assertArgument(false, "unsupported addressable value", "target", target);
- }
-
- const BN_0$2 = BigInt(0);
- // -----------------------
- function getValue(value) {
- if (value == null) {
- return null;
- }
- return value;
- }
- function toJson(value) {
- if (value == null) {
- return null;
- }
- return value.toString();
- }
- // @TODO? implements Required
- /**
- * A **FeeData** wraps all the fee-related values associated with
- * the network.
- */
- class FeeData {
- /**
- * The energy price for legacy networks.
- */
- energyPrice;
- constructor(energyPrice) {
- defineProperties(this, {
- energyPrice: getValue(energyPrice),
- });
- }
- /**
- * Returns a JSON-friendly value.
- */
- toJSON() {
- const { energyPrice } = this;
- return {
- _type: "FeeData",
- energyPrice: toJson(energyPrice),
- };
- }
- }
- function copyRequest(req) {
- const result = {};
- // These could be addresses, ENS names or Addressables
- if (req.to) {
- result.to = req.to;
- }
- if (req.from) {
- result.from = req.from;
- }
- if (req.data) {
- result.data = hexlify(req.data);
- }
- const bigIntKeys = "networkId,energyLimit,energyPrice,value".split(/,/);
- for (const key of bigIntKeys) {
- if (!(key in req) || req[key] == null) {
- continue;
- }
- result[key] = getBigInt(req[key], `request.${key}`);
- }
- const numberKeys = "type,nonce".split(/,/);
- for (const key of numberKeys) {
- if (!(key in req) || req[key] == null) {
- continue;
- }
- result[key] = getNumber(req[key], `request.${key}`);
- }
- if ("blockTag" in req) {
- result.blockTag = req.blockTag;
- }
- if ("enableCcipRead" in req) {
- result.enableCcipReadEnabled = !!req.enableCcipRead;
- }
- if ("customData" in req) {
- result.customData = req.customData;
- }
- return result;
- }
- /**
- * A **Block** represents the data associated with a full block on
- * Core.
- */
- class Block {
- /**
- * The provider connected to the block used to fetch additional details
- * if necessary.
- */
- provider;
- /**
- * The block number, sometimes called the block height. This is a
- * sequential number that is one higher than the parent block.
- */
- number;
- /**
- * The block hash.
- */
- hash;
- /**
- * The timestamp for this block, which is the number of seconds since
- * epoch that this block was included.
- */
- timestamp;
- /**
- * The block hash of the parent block.
- */
- parentHash;
- /**
- * The nonce.
- *
- * On legacy networks, this is the random number inserted which
- * permitted the difficulty target to be reached.
- */
- nonce;
- /**
- * The difficulty target.
- *
- * On legacy networks, this is the proof-of-work target required
- * for a block to meet the protocol rules to be included.
- *
- * On modern networks, this is a random number arrived at using
- * randao. @TODO: Find links?
- */
- difficulty;
- /**
- * The total energy limit for this block.
- */
- energyLimit;
- /**
- * The total energy used in this block.
- */
- energyUsed;
- /**
- * The miner coinbase address, wihch receives any subsidies for
- * including this block.
- */
- miner;
- /**
- * Any extra data the validator wished to include.
- */
- extraData;
- /**
- * The base fee per energy that all transactions in this block were
- * charged.
- *
- * This adjusts after each block, depending on how congested the network
- * is.
- */
- baseFeePerEnergy;
- #transactions;
- /**
- * Create a new **Block** object.
- *
- * This should generally not be necessary as the unless implementing a
- * low-level library.
- */
- constructor(block, provider) {
- this.#transactions = block.transactions.map((tx) => {
- if (typeof tx !== "string") {
- return new TransactionResponse(tx, provider);
- }
- return tx;
- });
- defineProperties(this, {
- provider,
- hash: getValue(block.hash),
- number: block.number,
- timestamp: block.timestamp,
- parentHash: block.parentHash,
- nonce: block.nonce,
- difficulty: block.difficulty,
- energyLimit: block.energyLimit,
- energyUsed: block.energyUsed,
- miner: block.miner,
- extraData: block.extraData,
- baseFeePerEnergy: getValue(block.baseFeePerEnergy),
- });
- }
- /**
- * Returns the list of transaction hashes.
- */
- get transactions() {
- return this.#transactions.map((tx) => {
- if (typeof tx === "string") {
- return tx;
- }
- return tx.hash;
- });
- }
- /**
- * Returns the complete transactions for blocks which
- * prefetched them, by passing ``true`` to %%prefetchTxs%%
- * into [[provider_getBlock]].
- */
- get prefetchedTransactions() {
- const txs = this.#transactions.slice();
- // Doesn't matter...
- if (txs.length === 0) {
- return [];
- }
- // Make sure we prefetched the transactions
- assert(typeof txs[0] === "object", "transactions were not prefetched with block request", "UNSUPPORTED_OPERATION", {
- operation: "transactionResponses()",
- });
- return txs;
- }
- /**
- * Returns a JSON-friendly value.
- */
- toJSON() {
- const { baseFeePerEnergy, difficulty, extraData, energyLimit, energyUsed, hash, miner, nonce, number, parentHash, timestamp, transactions, } = this;
- return {
- _type: "Block",
- baseFeePerEnergy: toJson(baseFeePerEnergy),
- difficulty: toJson(difficulty),
- extraData,
- energyLimit: toJson(energyLimit),
- energyUsed: toJson(energyUsed),
- hash,
- miner,
- nonce,
- number,
- parentHash,
- timestamp,
- transactions,
- };
- }
- [Symbol.iterator]() {
- let index = 0;
- const txs = this.transactions;
- return {
- next: () => {
- if (index < this.length) {
- return {
- value: txs[index++],
- done: false,
- };
- }
- return { value: undefined, done: true };
- },
- };
- }
- /**
- * The number of transactions in this block.
- */
- get length() {
- return this.#transactions.length;
- }
- /**
- * The [[link-js-date]] this block was included at.
- */
- get date() {
- if (this.timestamp == null) {
- return null;
- }
- return new Date(this.timestamp * 1000);
- }
- /**
- * Get the transaction at %%indexe%% within this block.
- */
- async getTransaction(indexOrHash) {
- // Find the internal value by its index or hash
- let tx = undefined;
- if (typeof indexOrHash === "number") {
- tx = this.#transactions[indexOrHash];
- }
- else {
- const hash = indexOrHash.toLowerCase();
- for (const v of this.#transactions) {
- if (typeof v === "string") {
- if (v !== hash) {
- continue;
- }
- tx = v;
- break;
- }
- else {
- if (v.hash === hash) {
- continue;
- }
- tx = v;
- break;
- }
- }
- }
- if (tx == null) {
- throw new Error("no such tx");
- }
- if (typeof tx === "string") {
- return await this.provider.getTransaction(tx);
- }
- else {
- return tx;
- }
- }
- getPrefetchedTransaction(indexOrHash) {
- const txs = this.prefetchedTransactions;
- if (typeof indexOrHash === "number") {
- return txs[indexOrHash];
- }
- indexOrHash = indexOrHash.toLowerCase();
- for (const tx of txs) {
- if (tx.hash === indexOrHash) {
- return tx;
- }
- }
- assertArgument(false, "no matching transaction", "indexOrHash", indexOrHash);
- }
- /**
- * Has this block been mined.
- *
- * If true, the block has been typed-gaurded that all mined
- * properties are non-null.
- */
- isMined() {
- return !!this.hash;
- }
- /**
- *
- */
- isLondon() {
- return !!this.baseFeePerEnergy;
- }
- orphanedEvent() {
- if (!this.isMined()) {
- throw new Error("");
- }
- return createOrphanedBlockFilter(this);
- }
- }
- //////////////////////
- // Log
- class Log {
- provider;
- transactionHash;
- blockHash;
- blockNumber;
- removed;
- address;
- data;
- topics;
- index;
- transactionIndex;
- constructor(log, provider) {
- this.provider = provider;
- const topics = Object.freeze(log.topics.slice());
- defineProperties(this, {
- transactionHash: log.transactionHash,
- blockHash: log.blockHash,
- blockNumber: log.blockNumber,
- removed: log.removed,
- address: log.address,
- data: log.data,
- topics,
- index: log.index,
- transactionIndex: log.transactionIndex,
- });
- }
- toJSON() {
- const { address, blockHash, blockNumber, data, index, removed, topics, transactionHash, transactionIndex, } = this;
- return {
- _type: "log",
- address,
- blockHash,
- blockNumber,
- data,
- index,
- removed,
- topics,
- transactionHash,
- transactionIndex,
- };
- }
- async getBlock() {
- const block = await this.provider.getBlock(this.blockHash);
- assert(!!block, "failed to find transaction", "UNKNOWN_ERROR", {});
- return block;
- }
- async getTransaction() {
- const tx = await this.provider.getTransaction(this.transactionHash);
- assert(!!tx, "failed to find transaction", "UNKNOWN_ERROR", {});
- return tx;
- }
- async getTransactionReceipt() {
- const receipt = await this.provider.getTransactionReceipt(this.transactionHash);
- assert(!!receipt, "failed to find transaction receipt", "UNKNOWN_ERROR", {});
- return receipt;
- }
- removedEvent() {
- return createRemovedLogFilter(this);
- }
- }
- //////////////////////
- // Transaction Receipt
- /*
- export interface LegacyTransactionReceipt {
- byzantium: false;
- status: null;
- root: string;
- }
-
- export interface ByzantiumTransactionReceipt {
- byzantium: true;
- status: number;
- root: null;
- }
- */
- class TransactionReceipt {
- provider;
- to;
- from;
- contractAddress;
- hash;
- index;
- blockHash;
- blockNumber;
- logsBloom;
- energyUsed;
- cumulativeEnergyUsed;
- energyPrice;
- type;
- //readonly byzantium!: boolean;
- status;
- root;
- #logs;
- constructor(tx, provider) {
- this.#logs = Object.freeze(tx.logs.map((log) => {
- return new Log(log, provider);
- }));
- defineProperties(this, {
- provider,
- to: tx.to,
- from: tx.from,
- contractAddress: tx.contractAddress,
- hash: tx.hash,
- index: tx.index,
- blockHash: tx.blockHash,
- blockNumber: tx.blockNumber,
- logsBloom: tx.logsBloom,
- energyUsed: tx.energyUsed,
- cumulativeEnergyUsed: tx.cumulativeEnergyUsed,
- energyPrice: (tx.effectiveEnergyPrice || tx.energyPrice),
- //byzantium: tx.byzantium,
- status: tx.status,
- root: tx.root,
- });
- }
- get logs() {
- return this.#logs;
- }
- toJSON() {
- const { to, from, contractAddress, hash, index, blockHash, blockNumber, logsBloom, logs, //byzantium,
- status, root, } = this;
- return {
- _type: "TransactionReceipt",
- blockHash,
- blockNumber,
- //byzantium,
- contractAddress,
- cumulativeEnergyUsed: toJson(this.cumulativeEnergyUsed),
- from,
- energyPrice: toJson(this.energyPrice),
- energyUsed: toJson(this.energyUsed),
- hash,
- index,
- logs,
- logsBloom,
- root,
- status,
- to,
- };
- }
- get length() {
- return this.logs.length;
- }
- [Symbol.iterator]() {
- let index = 0;
- return {
- next: () => {
- if (index < this.length) {
- return { value: this.logs[index++], done: false };
- }
- return { value: undefined, done: true };
- },
- };
- }
- get fee() {
- return this.energyUsed * this.energyPrice;
- }
- async getBlock() {
- const block = await this.provider.getBlock(this.blockHash);
- if (block == null) {
- throw new Error("TODO");
- }
- return block;
- }
- async getTransaction() {
- const tx = await this.provider.getTransaction(this.hash);
- if (tx == null) {
- throw new Error("TODO");
- }
- return tx;
- }
- async getResult() {
- return await this.provider.getTransactionResult(this.hash);
- }
- async confirmations() {
- return (await this.provider.getBlockNumber()) - this.blockNumber + 1;
- }
- removedEvent() {
- return createRemovedTransactionFilter(this);
- }
- reorderedEvent(other) {
- assert(!other || other.isMined(), "unmined 'other' transction cannot be orphaned", "UNSUPPORTED_OPERATION", { operation: "reorderedEvent(other)" });
- return createReorderedTransactionFilter(this, other);
- }
- }
- /*
- export type ReplacementDetectionSetup = {
- to: string;
- from: string;
- value: bigint;
- data: string;
- nonce: number;
- block: number;
- };
- */
- class TransactionResponse {
- /**
- * The provider this is connected to, which will influence how its
- * methods will resolve its async inspection methods.
- */
- provider;
- /**
- * The block number of the block that this transaction was included in.
- *
- * This is ``null`` for pending transactions.
- */
- blockNumber;
- /**
- * The blockHash of the block that this transaction was included in.
- *
- * This is ``null`` for pending transactions.
- */
- blockHash;
- /**
- * The index within the block that this transaction resides at.
- */
- index;
- /**
- * The transaction hash.
- */
- hash;
- /**
- * The [[link-eip-2718]] transaction envelope type. This is
- * ``0`` for legacy transactions types.
- */
- type;
- /**
- * The receiver of this transaction.
- *
- * If ``null``, then the transaction is an initcode transaction.
- * This means the result of executing the [[data]] will be deployed
- * as a new contract on chain (assuming it does not revert) and the
- * address may be computed using [[getCreateAddress]].
- */
- to;
- /**
- * The sender of this transaction. It is implicitly computed
- * from the transaction pre-image hash (as the digest) and the
- * [[signature]] using ecrecover.
- */
- from;
- /**
- * The nonce, which is used to prevent replay attacks and offer
- * a method to ensure transactions from a given sender are explicitly
- * ordered.
- *
- * When sending a transaction, this must be equal to the number of
- * transactions ever sent by [[from]].
- */
- nonce;
- /**
- * The maximum units of energy this transaction can consume. If execution
- * exceeds this, the entries transaction is reverted and the sender
- * is charged for the full amount, despite not state changes being made.
- */
- energyLimit;
- /**
- * The energy price can have various values, depending on the network.
- *
- * In modern networks, for transactions that are included this is
- * the //effective energy price// (the fee per energy that was actually
- * charged), while for transactions that have not been included yet
- * is the [[maxFeePerEnergy]].
- *
- * For legacy transactions, or transactions on legacy networks, this
- * is the fee that will be charged per unit of energy the transaction
- * consumes.
- */
- energyPrice;
- /**
- * The data.
- */
- data;
- /**
- * The value, in ore. Use [[formatXCB]] to format this value
- * as xcb.
- */
- value;
- /**
- * The chain ID.
- */
- networkId;
- /**
- * The signature.
- */
- signature;
- #startBlock;
- /**
- * Create a new TransactionResponse with %%tx%% parameters
- * connected to %%provider%%.
- */
- constructor(tx, provider) {
- this.provider = provider;
- this.blockNumber = tx.blockNumber != null ? tx.blockNumber : null;
- this.blockHash = tx.blockHash != null ? tx.blockHash : null;
- this.hash = tx.hash;
- this.index = tx.index;
- this.from = tx.from;
- this.to = tx.to || null;
- this.energyLimit = tx.energyLimit;
- this.nonce = tx.nonce;
- this.data = tx.data;
- this.value = tx.value;
- this.energyPrice = tx.energyPrice;
- this.networkId = tx.networkId;
- this.signature = tx.signature;
- this.#startBlock = -1;
- }
- /**
- * Returns a JSON representation of this transaction.
- */
- toJSON() {
- const { index, hash, type, to, from, nonce, data, signature } = this;
- return {
- _type: "TransactionReceipt",
- networkId: toJson(this.networkId),
- data,
- from,
- energyLimit: toJson(this.energyLimit),
- energyPrice: toJson(this.energyPrice),
- hash,
- nonce,
- signature,
- to,
- index,
- type,
- value: toJson(this.value),
- };
- }
- /**
- * Resolves to the Block that this transaction was included in.
- *
- * This will return null if the transaction has not been included yet.
- */
- async getBlock() {
- let blockNumber = this.blockNumber;
- if (blockNumber == null) {
- const tx = await this.getTransaction();
- if (tx) {
- blockNumber = tx.blockNumber;
- }
- }
- if (blockNumber == null) {
- return null;
- }
- const block = this.provider.getBlock(blockNumber);
- if (block == null) {
- throw new Error("TODO");
- }
- return block;
- }
- /**
- * Resolves to this transaction being re-requested from the
- * provider. This can be used if you have an unmined transaction
- * and wish to get an up-to-date populated instance.
- */
- async getTransaction() {
- return this.provider.getTransaction(this.hash);
- }
- /**
- * Resolves once this transaction has been mined and has
- * %%confirms%% blocks including it (default: ``1``) with an
- * optional %%timeout%%.
- *
- * This can resolve to ``null`` only if %%confirms%% is ``0``
- * and the transaction has not been mined, otherwise this will
- * wait until enough confirmations have completed.
- */
- async wait(_confirms, _timeout) {
- const confirms = _confirms == null ? 1 : _confirms;
- const timeout = _timeout == null ? 0 : _timeout;
- let startBlock = this.#startBlock;
- let nextScan = -1;
- let stopScanning = startBlock === -1 ? true : false;
- const checkReplacement = async () => {
- // Get the current transaction count for this sender
- if (stopScanning) {
- return null;
- }
- const { blockNumber, nonce } = await resolveProperties({
- blockNumber: this.provider.getBlockNumber(),
- nonce: this.provider.getTransactionCount(this.from),
- });
- // No transaction or our nonce has not been mined yet; but we
- // can start scanning later when we do start
- if (nonce < this.nonce) {
- startBlock = blockNumber;
- return;
- }
- // We were mined; no replacement
- if (stopScanning) {
- return null;
- }
- const mined = await this.getTransaction();
- if (mined && mined.blockNumber != null) {
- return;
- }
- // We were replaced; start scanning for that transaction
- // Starting to scan; look back a few extra blocks for safety
- if (nextScan === -1) {
- nextScan = startBlock - 3;
- if (nextScan < this.#startBlock) {
- nextScan = this.#startBlock;
- }
- }
- while (nextScan <= blockNumber) {
- // Get the next block to scan
- if (stopScanning) {
- return null;
- }
- const block = await this.provider.getBlock(nextScan, true);
- // This should not happen; but we'll try again shortly
- if (block == null) {
- return;
- }
- // We were mined; no replacement
- for (const hash of block) {
- if (hash === this.hash) {
- return;
- }
- }
- // Search for the transaction that replaced us
- for (let i = 0; i < block.length; i++) {
- const tx = await block.getTransaction(i);
- if (tx.from === this.from && tx.nonce === this.nonce) {
- // Get the receipt
- if (stopScanning) {
- return null;
- }
- const receipt = await this.provider.getTransactionReceipt(tx.hash);
- // This should not happen; but we'll try again shortly
- if (receipt == null) {
- return;
- }
- // We will retry this on the next block (this case could be optimized)
- if (blockNumber - receipt.blockNumber + 1 < confirms) {
- return;
- }
- // The reason we were replaced
- let reason = "replaced";
- if (tx.data === this.data &&
- tx.to === this.to &&
- tx.value === this.value) {
- reason = "repriced";
- }
- else if (tx.data === "0x" &&
- tx.from === tx.to &&
- tx.value === BN_0$2) {
- reason = "cancelled";
- }
- assert(false, "transaction was replaced", "TRANSACTION_REPLACED", {
- cancelled: reason === "replaced" || reason === "cancelled",
- reason,
- replacement: tx.replaceableTransaction(startBlock),
- hash: tx.hash,
- receipt,
- });
- }
- }
- nextScan++;
- }
- return;
- };
- const receipt = await this.provider.getTransactionReceipt(this.hash);
- if (receipt) {
- if ((await receipt.confirmations()) >= confirms) {
- return receipt;
- }
- }
- else {
- // Check for a replacement; throws if a replacement was found
- await checkReplacement();
- // Allow null only when the confirms is 0
- if (confirms === 0) {
- return null;
- }
- }
- const waiter = new Promise((resolve, reject) => {
- // List of things to cancel when we have a result (one way or the other)
- const cancellers = [];
- const cancel = () => {
- cancellers.forEach((c) => c());
- };
- // On cancel, stop scanning for replacements
- cancellers.push(() => {
- stopScanning = true;
- });
- // Set up any timeout requested
- if (timeout > 0) {
- const timer = setTimeout(() => {
- cancel();
- reject(makeError("wait for transaction timeout", "TIMEOUT"));
- }, timeout);
- cancellers.push(() => {
- clearTimeout(timer);
- });
- }
- const txListener = async (receipt) => {
- // Done; return it!
- if ((await receipt.confirmations()) >= confirms) {
- cancel();
- resolve(receipt);
- }
- };
- cancellers.push(() => {
- this.provider.off(this.hash, txListener);
- });
- this.provider.on(this.hash, txListener);
- // We support replacement detection; start checking
- if (startBlock >= 0) {
- const replaceListener = async () => {
- try {
- // Check for a replacement; this throws only if one is found
- await checkReplacement();
- }
- catch (error) {
- // We were replaced (with enough confirms); re-throw the error
- if (isError(error, "TRANSACTION_REPLACED")) {
- cancel();
- reject(error);
- return;
- }
- }
- // Rescheudle a check on the next block
- if (!stopScanning) {
- this.provider.once("block", replaceListener);
- }
- };
- cancellers.push(() => {
- this.provider.off("block", replaceListener);
- });
- this.provider.once("block", replaceListener);
- }
- });
- return await waiter;
- }
- /**
- * Returns ``true`` if this transaction has been included.
- *
- * This is effective only as of the time the TransactionResponse
- * was instantiated. To get up-to-date information, use
- * [[getTransaction]].
- *
- * This provides a Type Guard that this transaction will have
- * non-null property values for properties that are null for
- * unmined transactions.
- */
- isMined() {
- return this.blockHash != null;
- }
- /**
- * Returns true if the transaction is a legacy (i.e. ``type == 0``)
- * transaction.
- *
- * This provides a Type Guard that this transaction will have
- * the ``null``-ness for hardfork-specific properties set correctly.
- */
- isLegacy() {
- return this.type === 0;
- }
- /**
- * Returns a filter which can be used to listen for orphan events
- * that evict this transaction.
- */
- removedEvent() {
- assert(this.isMined(), "unmined transaction canot be orphaned", "UNSUPPORTED_OPERATION", { operation: "removeEvent()" });
- return createRemovedTransactionFilter(this);
- }
- /**
- * Returns a filter which can be used to listen for orphan events
- * that re-order this event against %%other%%.
- */
- reorderedEvent(other) {
- assert(this.isMined(), "unmined transaction canot be orphaned", "UNSUPPORTED_OPERATION", { operation: "removeEvent()" });
- assert(!other || other.isMined(), "unmined 'other' transaction canot be orphaned", "UNSUPPORTED_OPERATION", { operation: "removeEvent()" });
- return createReorderedTransactionFilter(this, other);
- }
- /**
- * Returns a new TransactionResponse instance which has the ability to
- * detect (and throw an error) if the transaction is replaced, which
- * will begin scanning at %%startBlock%%.
- *
- * This should generally not be used by developers and is intended
- * primarily for internal use. Setting an incorrect %%startBlock%% can
- * have devastating performance consequences if used incorrectly.
- */
- replaceableTransaction(startBlock) {
- assertArgument(Number.isInteger(startBlock) && startBlock >= 0, "invalid startBlock", "startBlock", startBlock);
- const tx = new TransactionResponse(this, this.provider);
- tx.#startBlock = startBlock;
- return tx;
- }
- }
- function createOrphanedBlockFilter(block) {
- return { orphan: "drop-block", hash: block.hash, number: block.number };
- }
- function createReorderedTransactionFilter(tx, other) {
- return { orphan: "reorder-transaction", tx, other };
- }
- function createRemovedTransactionFilter(tx) {
- return { orphan: "drop-transaction", tx };
- }
- function createRemovedLogFilter(log) {
- return {
- orphan: "drop-log",
- log: {
- transactionHash: log.transactionHash,
- blockHash: log.blockHash,
- blockNumber: log.blockNumber,
- address: log.address,
- data: log.data,
- topics: Object.freeze(log.topics.slice()),
- index: log.index,
- },
- };
- }
-
- class EventLog extends Log {
- interface;
- fragment;
- args;
- constructor(log, iface, fragment) {
- super(log, log.provider);
- const args = iface.decodeEventLog(fragment, log.data, log.topics);
- defineProperties(this, { args, fragment, interface: iface });
- }
- get eventName() {
- return this.fragment.name;
- }
- get eventSignature() {
- return this.fragment.format();
- }
- }
- class ContractTransactionReceipt extends TransactionReceipt {
- #iface;
- constructor(iface, provider, tx) {
- super(tx, provider);
- this.#iface = iface;
- }
- get logs() {
- return super.logs.map((log) => {
- const fragment = log.topics.length
- ? this.#iface.getEvent(log.topics[0])
- : null;
- if (fragment) {
- return new EventLog(log, this.#iface, fragment);
- }
- else {
- return log;
- }
- });
- }
- }
- class ContractTransactionResponse extends TransactionResponse {
- #iface;
- constructor(iface, provider, tx) {
- super(tx, provider);
- this.#iface = iface;
- }
- async wait(confirms) {
- const receipt = await super.wait();
- if (receipt == null) {
- return null;
- }
- return new ContractTransactionReceipt(this.#iface, this.provider, receipt);
- }
- }
- class ContractUnknownEventPayload extends EventPayload {
- log;
- constructor(contract, listener, filter, log) {
- super(contract, listener, filter);
- defineProperties(this, { log });
- }
- async getBlock() {
- return await this.log.getBlock();
- }
- async getTransaction() {
- return await this.log.getTransaction();
- }
- async getTransactionReceipt() {
- return await this.log.getTransactionReceipt();
- }
- }
- class ContractEventPayload extends ContractUnknownEventPayload {
- constructor(contract, listener, filter, fragment, _log) {
- super(contract, listener, filter, new EventLog(_log, contract.interface, fragment));
- const args = contract.interface.decodeEventLog(fragment, this.log.data, this.log.topics);
- defineProperties(this, { args, fragment });
- }
- get eventName() {
- return this.fragment.name;
- }
- get eventSignature() {
- return this.fragment.format();
- }
- }
-
- const BN_0$1 = BigInt(0);
- function canCall(value) {
- return value && typeof value.call === "function";
- }
- function canEstimate(value) {
- return value && typeof value.estimateEnergy === "function";
- }
- function canResolve(value) {
- return value && typeof value.resolveName === "function";
- }
- function canSend(value) {
- return value && typeof value.sendTransaction === "function";
- }
- class PreparedTopicFilter {
- #filter;
- fragment;
- constructor(contract, fragment, args) {
- defineProperties(this, { fragment });
- if (fragment.inputs.length < args.length) {
- throw new Error("too many arguments");
- }
- // Recursively descend into args and resolve any addresses
- this.#filter = (async function () {
- const resolvedArgs = await Promise.all(fragment.inputs.map((param, index) => {
- const arg = args[index];
- if (arg == null) {
- return null;
- }
- return param.walkAsync(args[index], (type, value) => {
- if (type === "address") {
- return resolveAddress(value);
- }
- return value;
- });
- }));
- return contract.interface.encodeFilterTopics(fragment, resolvedArgs);
- })();
- }
- getTopicFilter() {
- return this.#filter;
- }
- }
- // A = Arguments passed in as a tuple
- // R = The result type of the call (i.e. if only one return type,
- // the qualified type, otherwise Result)
- // D = The type the default call will return (i.e. R for view/pure,
- // TransactionResponse otherwise)
- //export interface ContractMethod = Array, R = any, D extends R | ContractTransactionResponse = ContractTransactionResponse> {
- function getRunner(value, feature) {
- if (value == null) {
- return null;
- }
- if (typeof value[feature] === "function") {
- return value;
- }
- if (value.provider && typeof value.provider[feature] === "function") {
- return value.provider;
- }
- return null;
- }
- function getProvider(value) {
- if (value == null) {
- return null;
- }
- return value.provider || null;
- }
- /**
- * @_ignore:
- */
- async function copyOverrides(arg, allowed) {
- // Create a shallow copy (we'll deep-ify anything needed during normalizing)
- const overrides = copyRequest(Typed.dereference(arg, "overrides"));
- assertArgument(overrides.to == null || (allowed || []).indexOf("to") >= 0, "cannot override to", "overrides.to", overrides.to);
- assertArgument(overrides.data == null || (allowed || []).indexOf("data") >= 0, "cannot override data", "overrides.data", overrides.data);
- // Resolve any from
- if (overrides.from) {
- overrides.from = await resolveAddress(overrides.from);
- }
- return overrides;
- }
- /**
- * @_ignore:
- */
- async function resolveArgs(_runner, inputs, args) {
- // Recursively descend into args and resolve any addresses
- return await Promise.all(inputs.map((param, index) => {
- return param.walkAsync(args[index], (type, value) => {
- value = Typed.dereference(value, type);
- if (type === "address") {
- return resolveAddress(value);
- }
- return value;
- });
- }));
- }
- function buildWrappedFallback(contract) {
- const populateTransaction = async function (overrides) {
- // If an overrides was passed in, copy it and normalize the values
- const tx = (await copyOverrides(overrides, ["data"]));
- tx.to = await contract.getAddress();
- const iface = contract.interface;
- // Only allow payable contracts to set non-zero value
- const payable = iface.receive || (iface.fallback && iface.fallback.payable);
- assertArgument(payable || (tx.value || BN_0$1) === BN_0$1, "cannot send value to non-payable contract", "overrides.value", tx.value);
- // Only allow fallback contracts to set non-empty data
- assertArgument(iface.fallback || (tx.data || "0x") === "0x", "cannot send data to receive-only contract", "overrides.data", tx.data);
- return tx;
- };
- const staticCall = async function (overrides) {
- const runner = getRunner(contract.runner, "call");
- assert(canCall(runner), "contract runner does not support calling", "UNSUPPORTED_OPERATION", { operation: "call" });
- const tx = await populateTransaction(overrides);
- try {
- return await runner.call(tx);
- }
- catch (error) {
- if (isCallException(error) && error.data) {
- throw contract.interface.makeError(error.data, tx);
- }
- throw error;
- }
- };
- const send = async function (overrides) {
- const runner = contract.runner;
- assert(canSend(runner), "contract runner does not support sending transactions", "UNSUPPORTED_OPERATION", { operation: "sendTransaction" });
- const tx = await runner.sendTransaction(await populateTransaction(overrides));
- const provider = getProvider(contract.runner);
- // @TODO: the provider can be null; make a custom dummy provider that will throw a
- // meaningful error
- return new ContractTransactionResponse(contract.interface, provider, tx);
- };
- const estimateEnergy = async function (overrides) {
- const runner = getRunner(contract.runner, "estimateEnergy");
- assert(canEstimate(runner), "contract runner does not support energy estimation", "UNSUPPORTED_OPERATION", { operation: "estimateEnergy" });
- return await runner.estimateEnergy(await populateTransaction(overrides));
- };
- const method = async (overrides) => {
- return await send(overrides);
- };
- defineProperties(method, {
- _contract: contract,
- estimateEnergy,
- populateTransaction,
- send,
- staticCall,
- });
- return method;
- }
- function buildWrappedMethod(contract, key) {
- const getFragment = function (...args) {
- const fragment = contract.interface.getFunction(key, args);
- assert(fragment, "no matching fragment in getFragment", "UNSUPPORTED_OPERATION", {
- operation: "fragment",
- });
- return fragment;
- };
- const populateTransaction = async function (...args) {
- const fragment = getFragment(...args);
- // If an overrides was passed in, copy it and normalize the values
- let overrides = {};
- if (fragment.inputs.length + 1 === args.length) {
- overrides = await copyOverrides(args.pop());
- }
- if (fragment.inputs.length !== args.length) {
- throw new Error("internal error: fragment inputs doesn't match arguments; should not happen");
- }
- const resolvedArgs = await resolveArgs(contract.runner, fragment.inputs, args);
- return Object.assign({}, overrides, await resolveProperties({
- to: contract.getAddress(),
- data: contract.interface.encodeFunctionData(fragment, resolvedArgs),
- }));
- };
- const staticCall = async function (...args) {
- const result = await staticCallResult(...args);
- if (result.length === 1) {
- return result[0];
- }
- return result;
- };
- const send = async function (...args) {
- const runner = contract.runner;
- assert(canSend(runner), "contract runner does not support sending transactions", "UNSUPPORTED_OPERATION", { operation: "sendTransaction" });
- const tx = await runner.sendTransaction(await populateTransaction(...args));
- const provider = getProvider(contract.runner);
- // @TODO: the provider can be null; make a custom dummy provider that will throw a
- // meaningful error
- return new ContractTransactionResponse(contract.interface, provider, tx);
- };
- const estimateEnergy = async function (...args) {
- const runner = getRunner(contract.runner, "estimateEnergy");
- assert(canEstimate(runner), "contract runner does not support energy estimation", "UNSUPPORTED_OPERATION", { operation: "estimateEnergy" });
- return await runner.estimateEnergy(await populateTransaction(...args));
- };
- const staticCallResult = async function (...args) {
- const runner = getRunner(contract.runner, "call");
- assert(canCall(runner), "contract runner does not support calling", "UNSUPPORTED_OPERATION", { operation: "call" });
- const tx = await populateTransaction(...args);
- let result = "0x";
- try {
- result = await runner.call(tx);
- }
- catch (error) {
- if (isCallException(error) && error.data) {
- throw contract.interface.makeError(error.data, tx);
- }
- throw error;
- }
- const fragment = getFragment(...args);
- return contract.interface.decodeFunctionResult(fragment, result);
- };
- const method = async (...args) => {
- const fragment = getFragment(...args);
- if (fragment.constant) {
- return await staticCall(...args);
- }
- return await send(...args);
- };
- defineProperties(method, {
- name: contract.interface.getFunctionName(key),
- _contract: contract,
- _key: key,
- getFragment,
- estimateEnergy,
- populateTransaction,
- send,
- staticCall,
- staticCallResult,
- });
- // Only works on non-ambiguous keys (refined fragment is always non-ambiguous)
- Object.defineProperty(method, "fragment", {
- configurable: false,
- enumerable: true,
- get: () => {
- const fragment = contract.interface.getFunction(key);
- assert(fragment, "no matching fragment in defineProperty", "UNSUPPORTED_OPERATION", {
- operation: "fragment",
- });
- return fragment;
- },
- });
- return method;
- }
- function buildWrappedEvent(contract, key) {
- const getFragment = function (...args) {
- const fragment = contract.interface.getEvent(key, args);
- assert(fragment, "no matching fragment in", "UNSUPPORTED_OPERATION", {
- operation: "fragment",
- });
- return fragment;
- };
- const method = function (...args) {
- return new PreparedTopicFilter(contract, getFragment(...args), args);
- };
- defineProperties(method, {
- name: contract.interface.getEventName(key),
- _contract: contract,
- _key: key,
- getFragment,
- });
- // Only works on non-ambiguous keys (refined fragment is always non-ambiguous)
- Object.defineProperty(method, "fragment", {
- configurable: false,
- enumerable: true,
- get: () => {
- const fragment = contract.interface.getEvent(key);
- assert(fragment, "no matching fragment", "UNSUPPORTED_OPERATION", {
- operation: "fragment",
- });
- return fragment;
- },
- });
- return method;
- }
- // The combination of TypeScrype, Private Fields and Proxies makes
- // the world go boom; so we hide variables with some trickery keeping
- // a symbol attached to each BaseContract which its sub-class (even
- // via a Proxy) can reach and use to look up its internal values.
- const internal = Symbol.for("_corebcInternal_contract");
- const internalValues = new WeakMap();
- function setInternal(contract, values) {
- internalValues.set(contract[internal], values);
- }
- function getInternal(contract) {
- return internalValues.get(contract[internal]);
- }
- function isDeferred(value) {
- return (value &&
- typeof value === "object" &&
- "getTopicFilter" in value &&
- typeof value.getTopicFilter === "function" &&
- value.fragment);
- }
- async function getSubInfo(contract, event) {
- let topics;
- let fragment = null;
- // Convert named events to topicHash and get the fragment for
- // events which need deconstructing.
- if (Array.isArray(event)) {
- const topicHashify = function (name) {
- if (isHexString(name, 32)) {
- return name;
- }
- const fragment = contract.interface.getEvent(name);
- assertArgument(fragment, "unknown fragment", "name", name);
- return fragment.topicHash;
- };
- // Array of Topics and Names; e.g. `[ "0x1234...89ab", "Transfer(address)" ]`
- topics = event.map((e) => {
- if (e == null) {
- return null;
- }
- if (Array.isArray(e)) {
- return e.map(topicHashify);
- }
- return topicHashify(e);
- });
- }
- else if (event === "*") {
- topics = [null];
- }
- else if (typeof event === "string") {
- if (isHexString(event, 32)) {
- // Topic Hash
- topics = [event];
- }
- else {
- // Name or Signature; e.g. `"Transfer", `"Transfer(address)"`
- fragment = contract.interface.getEvent(event);
- assertArgument(fragment, "unknown fragment", "event", event);
- topics = [fragment.topicHash];
- }
- }
- else if (isDeferred(event)) {
- // Deferred Topic Filter; e.g. `contract.filter.Transfer(from)`
- topics = await event.getTopicFilter();
- }
- else if ("fragment" in event) {
- // ContractEvent; e.g. `contract.filter.Transfer`
- fragment = event.fragment;
- topics = [fragment.topicHash];
- }
- else {
- assertArgument(false, "unknown event name", "event", event);
- }
- // Normalize topics and sort TopicSets
- topics = topics.map((t) => {
- if (t == null) {
- return null;
- }
- if (Array.isArray(t)) {
- const items = Array.from(new Set(t.map((t) => t.toLowerCase())).values());
- if (items.length === 1) {
- return items[0];
- }
- items.sort();
- return items;
- }
- return t.toLowerCase();
- });
- const tag = topics
- .map((t) => {
- if (t == null) {
- return "null";
- }
- if (Array.isArray(t)) {
- return t.join("|");
- }
- return t;
- })
- .join("&");
- return { fragment, tag, topics };
- }
- async function hasSub(contract, event) {
- const { subs } = getInternal(contract);
- return subs.get((await getSubInfo(contract, event)).tag) || null;
- }
- async function getSub(contract, operation, event) {
- // Make sure our runner can actually subscribe to events
- const provider = getProvider(contract.runner);
- assert(provider, "contract runner does not support subscribing", "UNSUPPORTED_OPERATION", { operation });
- const { fragment, tag, topics } = await getSubInfo(contract, event);
- const { addr, subs } = getInternal(contract);
- let sub = subs.get(tag);
- if (!sub) {
- const address = addr ? addr : contract;
- const filter = { address, topics };
- const listener = (log) => {
- let foundFragment = fragment;
- if (foundFragment == null) {
- try {
- foundFragment = contract.interface.getEvent(log.topics[0]);
- }
- catch (error) { }
- }
- // If fragment is null, we do not deconstruct the args to emit
- if (foundFragment) {
- const _foundFragment = foundFragment;
- const args = fragment
- ? contract.interface.decodeEventLog(fragment, log.data, log.topics)
- : [];
- emit(contract, event, args, (listener) => {
- return new ContractEventPayload(contract, listener, event, _foundFragment, log);
- });
- }
- else {
- emit(contract, event, [], (listener) => {
- return new ContractUnknownEventPayload(contract, listener, event, log);
- });
- }
- };
- let starting = [];
- const start = () => {
- if (starting.length) {
- return;
- }
- starting.push(provider.on(filter, listener));
- };
- const stop = async () => {
- if (starting.length == 0) {
- return;
- }
- let started = starting;
- starting = [];
- await Promise.all(started);
- provider.off(filter, listener);
- };
- sub = { tag, listeners: [], start, stop };
- subs.set(tag, sub);
- }
- return sub;
- }
- // We use this to ensure one emit resolves before firing the next to
- // ensure correct ordering (note this cannot throw and just adds the
- // notice to the event queu using setTimeout).
- let lastEmit = Promise.resolve();
- async function _emit(contract, event, args, payloadFunc) {
- await lastEmit;
- const sub = await hasSub(contract, event);
- if (!sub) {
- return false;
- }
- const count = sub.listeners.length;
- sub.listeners = sub.listeners.filter(({ listener, once }) => {
- const passArgs = Array.from(args);
- if (payloadFunc) {
- passArgs.push(payloadFunc(once ? null : listener));
- }
- try {
- listener.call(contract, ...passArgs);
- }
- catch (error) { }
- return !once;
- });
- return count > 0;
- }
- async function emit(contract, event, args, payloadFunc) {
- try {
- await lastEmit;
- }
- catch (error) { }
- const resultPromise = _emit(contract, event, args, payloadFunc);
- lastEmit = resultPromise;
- return await resultPromise;
- }
- const passProperties = ["then"];
- class BaseContract {
- target;
- interface;
- runner;
- filters;
- [internal];
- fallback;
- constructor(target, abi, runner, _deployTx) {
- if (runner == null) {
- runner = null;
- }
- const iface = Interface.from(abi);
- defineProperties(this, { target, runner, interface: iface });
- Object.defineProperty(this, internal, { value: {} });
- let addrPromise;
- let addr = null;
- let deployTx = null;
- if (_deployTx) {
- const provider = getProvider(runner);
- // @TODO: the provider can be null; make a custom dummy provider that will throw a
- // meaningful error
- deployTx = new ContractTransactionResponse(this.interface, provider, _deployTx);
- }
- let subs = new Map();
- // Resolve the target as the address
- if (typeof target === "string") {
- if (isHexString(target)) {
- addr = target;
- addrPromise = Promise.resolve(target);
- }
- else {
- const resolver = getRunner(runner, "resolveName");
- if (!canResolve(resolver)) {
- throw makeError("contract runner does not support name resolution", "UNSUPPORTED_OPERATION", {
- operation: "resolveName",
- });
- }
- addrPromise = resolver.resolveName(target).then((addr) => {
- if (addr == null) {
- throw new Error("TODO");
- }
- getInternal(this).addr = addr;
- return addr;
- });
- }
- }
- else {
- addrPromise = target.getAddress().then((addr) => {
- if (addr == null) {
- throw new Error("TODO");
- }
- getInternal(this).addr = addr;
- return addr;
- });
- }
- // Set our private values
- setInternal(this, { addrPromise, addr, deployTx, subs });
- // Add the event filters
- const filters = new Proxy({}, {
- get: (target, _prop, receiver) => {
- // Pass important checks (like `then` for Promise) through
- if (passProperties.indexOf(_prop) >= 0) {
- return Reflect.get(target, _prop, receiver);
- }
- const prop = String(_prop);
- const result = this.getEvent(prop);
- if (result) {
- return result;
- }
- throw new Error(`unknown contract event: ${prop}`);
- },
- has: (target, prop) => {
- // Pass important checks (like `then` for Promise) through
- if (passProperties.indexOf(prop) >= 0) {
- return Reflect.has(target, prop);
- }
- return (Reflect.has(target, prop) || this.interface.hasEvent(String(prop)));
- },
- });
- defineProperties(this, { filters });
- defineProperties(this, {
- fallback: iface.receive || iface.fallback ? buildWrappedFallback(this) : null,
- });
- // Return a Proxy that will respond to functions
- return new Proxy(this, {
- get: (target, _prop, receiver) => {
- if (_prop in target || passProperties.indexOf(_prop) >= 0) {
- return Reflect.get(target, _prop, receiver);
- }
- const prop = String(_prop);
- const result = target.getFunction(prop);
- if (result) {
- return result;
- }
- throw new Error(`unknown contract method: ${prop}`);
- },
- has: (target, prop) => {
- if (prop in target || passProperties.indexOf(prop) >= 0) {
- return Reflect.has(target, prop);
- }
- return target.interface.hasFunction(String(prop));
- },
- });
- }
- connect(runner) {
- return new BaseContract(this.target, this.interface, runner);
- }
- async getAddress() {
- return await getInternal(this).addrPromise;
- }
- async getDeployedCode() {
- const provider = getProvider(this.runner);
- assert(provider, "runner does not support .provider", "UNSUPPORTED_OPERATION", { operation: "getDeployedCode" });
- const code = await provider.getCode(await this.getAddress());
- if (code === "0x") {
- return null;
- }
- return code;
- }
- async waitForDeployment() {
- // We have the deployement transaction; just use that (throws if deployement fails)
- const deployTx = this.deploymentTransaction();
- if (deployTx) {
- await deployTx.wait();
- return this;
- }
- // Check for code
- const code = await this.getDeployedCode();
- if (code != null) {
- return this;
- }
- // Make sure we can subscribe to a provider event
- const provider = getProvider(this.runner);
- assert(provider != null, "contract runner does not support .provider", "UNSUPPORTED_OPERATION", { operation: "waitForDeployment" });
- return new Promise((resolve, reject) => {
- const checkCode = async () => {
- try {
- const code = await this.getDeployedCode();
- if (code != null) {
- return resolve(this);
- }
- provider.once("block", checkCode);
- }
- catch (error) {
- reject(error);
- }
- };
- checkCode();
- });
- }
- deploymentTransaction() {
- return getInternal(this).deployTx;
- }
- getFunction(key) {
- if (typeof key !== "string") {
- key = key.format();
- }
- const func = buildWrappedMethod(this, key);
- return func;
- }
- getEvent(key) {
- if (typeof key !== "string") {
- key = key.format();
- }
- return buildWrappedEvent(this, key);
- }
- async queryTransaction(hash) {
- // Is this useful?
- throw new Error("@TODO");
- }
- async queryFilter(event, fromBlock, toBlock) {
- if (fromBlock == null) {
- fromBlock = 0;
- }
- if (toBlock == null) {
- toBlock = "latest";
- }
- const { addr, addrPromise } = getInternal(this);
- const address = addr ? addr : await addrPromise;
- const { fragment, topics } = await getSubInfo(this, event);
- const filter = { address, topics, fromBlock, toBlock };
- const provider = getProvider(this.runner);
- assert(provider, "contract runner does not have a provider", "UNSUPPORTED_OPERATION", { operation: "queryFilter" });
- return (await provider.getLogs(filter)).map((log) => {
- let foundFragment = fragment;
- if (foundFragment == null) {
- try {
- foundFragment = this.interface.getEvent(log.topics[0]);
- }
- catch (error) { }
- }
- if (foundFragment) {
- return new EventLog(log, this.interface, foundFragment);
- }
- else {
- return new Log(log, provider);
- }
- });
- }
- async on(event, listener) {
- const sub = await getSub(this, "on", event);
- sub.listeners.push({ listener, once: false });
- sub.start();
- return this;
- }
- async once(event, listener) {
- const sub = await getSub(this, "once", event);
- sub.listeners.push({ listener, once: true });
- sub.start();
- return this;
- }
- async emit(event, ...args) {
- return await emit(this, event, args, null);
- }
- async listenerCount(event) {
- if (event) {
- const sub = await hasSub(this, event);
- if (!sub) {
- return 0;
- }
- return sub.listeners.length;
- }
- const { subs } = getInternal(this);
- let total = 0;
- for (const { listeners } of subs.values()) {
- total += listeners.length;
- }
- return total;
- }
- async listeners(event) {
- if (event) {
- const sub = await hasSub(this, event);
- if (!sub) {
- return [];
- }
- return sub.listeners.map(({ listener }) => listener);
- }
- const { subs } = getInternal(this);
- let result = [];
- for (const { listeners } of subs.values()) {
- result = result.concat(listeners.map(({ listener }) => listener));
- }
- return result;
- }
- async off(event, listener) {
- const sub = await hasSub(this, event);
- if (!sub) {
- return this;
- }
- if (listener) {
- const index = sub.listeners
- .map(({ listener }) => listener)
- .indexOf(listener);
- if (index >= 0) {
- sub.listeners.splice(index, 1);
- }
- }
- if (listener == null || sub.listeners.length === 0) {
- sub.stop();
- getInternal(this).subs.delete(sub.tag);
- }
- return this;
- }
- async removeAllListeners(event) {
- if (event) {
- const sub = await hasSub(this, event);
- if (!sub) {
- return this;
- }
- sub.stop();
- getInternal(this).subs.delete(sub.tag);
- }
- else {
- const { subs } = getInternal(this);
- for (const { tag, stop } of subs.values()) {
- stop();
- subs.delete(tag);
- }
- }
- return this;
- }
- // Alias for "on"
- async addListener(event, listener) {
- return await this.on(event, listener);
- }
- // Alias for "off"
- async removeListener(event, listener) {
- return await this.off(event, listener);
- }
- static buildClass(abi) {
- class CustomContract extends BaseContract {
- constructor(address, runner = null) {
- super(address, abi, runner);
- }
- }
- return CustomContract;
- }
- static from(target, abi, runner) {
- if (runner == null) {
- runner = null;
- }
- const contract = new this(target, abi, runner);
- return contract;
- }
- static isIndexed(value) {
- return Indexed.isIndexed(value);
- }
- }
- function _ContractBase() {
- return BaseContract;
- }
- class Contract extends _ContractBase() {
- }
-
- // A = Arguments to the constructor
- // I = Interface of deployed contracts
- class ContractFactory {
- interface;
- bytecode;
- runner;
- constructor(abi, bytecode, runner) {
- const iface = Interface.from(abi);
- // Dereference Solidity bytecode objects and allow a missing `0x`-prefix
- if (bytecode instanceof Uint8Array) {
- bytecode = hexlify(getBytes(bytecode));
- }
- else if (typeof bytecode === "string") {
- bytecode = bytecode;
- }
- else if (isBytes(bytecode)) {
- bytecode = hexlify(bytecode);
- }
- else if (bytecode && typeof bytecode.object === "string") {
- // Allow the bytecode object from the Solidity compiler
- bytecode = bytecode.object;
- }
- else {
- // Crash in the next verification step
- bytecode = "!";
- }
- defineProperties(this, {
- // @ts-ignore
- bytecode,
- interface: iface,
- runner: runner || null,
- });
- }
- async getDeployTransaction(...args) {
- let overrides = {};
- const fragment = this.interface.deploy;
- if (fragment.inputs.length + 1 === args.length) {
- overrides = await copyOverrides(args.pop());
- }
- if (fragment.inputs.length !== args.length) {
- throw new Error("incorrect number of arguments to constructor");
- }
- const resolvedArgs = await resolveArgs(this.runner, fragment.inputs, args);
- const data = concat([
- this.bytecode,
- this.interface.encodeDeploy(resolvedArgs),
- ]);
- return Object.assign({}, overrides, { data });
- }
- async deploy(...args) {
- const tx = await this.getDeployTransaction(...args);
- assert(this.runner && typeof this.runner.sendTransaction === "function", "factory runner does not support sending transactions", "UNSUPPORTED_OPERATION", {
- operation: "sendTransaction",
- });
- const sentTx = await this.runner.sendTransaction(tx);
- const address = getCreateAddress(sentTx);
- return new BaseContract(address, this.interface, this.runner, sentTx);
- }
- connect(runner) {
- return new ContractFactory(this.interface, this.bytecode, runner);
- }
- static fromSolidity(output, runner) {
- assertArgument(output != null, "bad compiler output", "output", output);
- if (typeof output === "string") {
- output = JSON.parse(output);
- }
- const abi = output.abi;
- let bytecode = "";
- if (output.bytecode) {
- bytecode = output.bytecode;
- }
- else if (output.evm && output.evm.bytecode) {
- bytecode = output.evm.bytecode;
- }
- return new this(abi, bytecode, runner);
- }
- }
-
- /**
- * @_ignore
- */
- const BN_0 = BigInt(0);
- function allowNull(format, nullValue) {
- return function (value) {
- if (value == null) {
- return nullValue;
- }
- return format(value);
- };
- }
- function arrayOf(format) {
- return (array) => {
- if (!Array.isArray(array)) {
- throw new Error("not an array");
- }
- return array.map((i) => format(i));
- };
- }
- // Requires an object which matches a fleet of other formatters
- // Any FormatFunc may return `undefined` to have the value omitted
- // from the result object. Calls preserve `this`.
- function object(format, altNames) {
- return (value) => {
- const result = {};
- for (const key in format) {
- let srcKey = key;
- if (altNames && key in altNames && !(srcKey in value)) {
- for (const altKey of altNames[key]) {
- if (altKey in value) {
- srcKey = altKey;
- break;
- }
- }
- }
- try {
- const nv = format[key](value[srcKey]);
- if (nv !== undefined) {
- result[key] = nv;
- }
- }
- catch (error) {
- const message = error instanceof Error ? error.message : "not-an-error";
- assert(false, `invalid value for value.${key} (${message})`, "BAD_DATA", { value });
- }
- }
- return result;
- };
- }
- function formatBoolean(value) {
- switch (value) {
- case true:
- case "true":
- return true;
- case false:
- case "false":
- return false;
- }
- assertArgument(false, `invalid boolean; ${JSON.stringify(value)}`, "value", value);
- }
- function formatData(value) {
- assertArgument(isHexString(value, true), "invalid data", "value", value);
- return value;
- }
- function formatHash(value) {
- assertArgument(isHexString(value, 32), "invalid hash", "value", value);
- return value;
- }
- const _formatLog = object({
- address: getAddress,
- blockHash: formatHash,
- blockNumber: getNumber,
- data: formatData,
- index: getNumber,
- removed: allowNull(formatBoolean, false),
- topics: arrayOf(formatHash),
- transactionHash: formatHash,
- transactionIndex: getNumber,
- }, {
- index: ["logIndex"],
- });
- function formatLog(value) {
- return _formatLog(value);
- }
- const _formatBlock = object({
- hash: allowNull(formatHash),
- parentHash: formatHash,
- number: getNumber,
- timestamp: getNumber,
- nonce: allowNull(formatData),
- difficulty: getBigInt,
- energyLimit: getBigInt,
- energyUsed: getBigInt,
- miner: allowNull(getAddress),
- extraData: formatData,
- baseFeePerEnergy: allowNull(getBigInt),
- });
- function formatBlock(value) {
- const result = _formatBlock(value);
- result.transactions = value.transactions.map((tx) => {
- if (typeof tx === "string") {
- return tx;
- }
- return formatTransactionResponse(tx);
- });
- return result;
- }
- const _formatReceiptLog = object({
- transactionIndex: getNumber,
- blockNumber: getNumber,
- transactionHash: formatHash,
- address: getAddress,
- topics: arrayOf(formatHash),
- data: formatData,
- index: getNumber,
- blockHash: formatHash,
- }, {
- index: ["logIndex"],
- });
- function formatReceiptLog(value) {
- return _formatReceiptLog(value);
- }
- const _formatTransactionReceipt = object({
- to: allowNull(getAddress, null),
- from: allowNull(getAddress, null),
- contractAddress: allowNull(getAddress, null),
- // should be allowNull(hash), but broken-EIP-658 support is handled in receipt
- index: getNumber,
- root: allowNull(hexlify),
- energyUsed: getBigInt,
- logsBloom: allowNull(formatData),
- blockHash: formatHash,
- hash: formatHash,
- logs: arrayOf(formatReceiptLog),
- blockNumber: getNumber,
- //confirmations: allowNull(getNumber, null),
- cumulativeEnergyUsed: getBigInt,
- effectiveEnergyPrice: allowNull(getBigInt),
- status: allowNull(getNumber),
- type: allowNull(getNumber, 0),
- }, {
- effectiveEnergyPrice: ["energyPrice"],
- hash: ["transactionHash"],
- index: ["transactionIndex"],
- });
- function formatTransactionReceipt(value) {
- return _formatTransactionReceipt(value);
- }
- function formatTransactionResponse(value) {
- // Some clients (TestRPC) do strange things like return 0x0 for the
- // 0 address; correct this to be a real address
- if (value.to && !getAddress(value.to) && getBigInt(value.to) === BN_0) {
- value.to = "0x0000000000000000000000000000000000000000";
- }
- const result = object({
- hash: formatHash,
- type: (value) => {
- if (value === "0x" || value == null) {
- return 0;
- }
- return getNumber(value);
- },
- accessList: allowNull(accessListify, null),
- blockHash: allowNull(formatHash, null),
- blockNumber: allowNull(getNumber, null),
- transactionIndex: allowNull(getNumber, null),
- //confirmations: allowNull(getNumber, null),
- from: getAddress,
- maxFeePerEnergy: allowNull(getBigInt),
- energyLimit: getBigInt,
- to: allowNull(getAddress, null),
- value: getBigInt,
- nonce: getNumber,
- data: formatData,
- creates: allowNull(getAddress, null),
- networkId: allowNull(getBigInt, null),
- }, {
- data: ["input"],
- energyLimit: ["energy"],
- })(value);
- // If to and creates are empty, populate the creates from the value
- if (result.to == null && result.creates == null) {
- result.creates = getCreateAddress(result);
- }
- // Compute the signature
- if (value.signature) {
- result.signature = value.signature;
- }
- else {
- result.signature = value;
- }
- // Some backends omit networkId on legacy transactions, but we can compute it
- if (result.networkId == null) {
- const networkId = result.signature.legacynetworkId;
- if (networkId != null) {
- result.networkId = networkId;
- }
- }
- // @TODO: check networkId
- /*
- if (value.networkId != null) {
- let networkId = value.networkId;
-
- if (isHexString(networkId)) {
- networkId = BigNumber.from(networkId).toNumber();
- }
-
- result.networkId = networkId;
-
- } else {
- let networkId = value.networkId;
-
- // geth-etc returns networkId
- if (networkId == null && result.v == null) {
- networkId = value.networkId;
- }
-
- if (isHexString(networkId)) {
- networkId = BigNumber.from(networkId).toNumber();
- }
-
- if (typeof(networkId) !== "number" && result.v != null) {
- networkId = (result.v - 35) / 2;
- if (networkId < 0) { networkId = 0; }
- networkId = parseInt(networkId);
- }
-
- if (typeof(networkId) !== "number") { networkId = 0; }
-
- result.networkId = networkId;
- }
- */
- // 0x0000... should actually be null
- if (result.blockHash && getBigInt(result.blockHash) === BN_0) {
- result.blockHash = null;
- }
- return result;
- }
-
- class NetworkPlugin {
- name;
- constructor(name) {
- defineProperties(this, { name });
- }
- clone() {
- return new NetworkPlugin(this.name);
- }
- }
- class EnergyCostPlugin extends NetworkPlugin {
- effectiveBlock;
- txBase;
- txCreate;
- txDataZero;
- txDataNonzero;
- txAccessListStorageKey;
- txAccessListAddress;
- constructor(effectiveBlock, costs) {
- if (effectiveBlock == null) {
- effectiveBlock = 0;
- }
- super(`org.corebc.network.plugins.EnergyCost#${effectiveBlock || 0}`);
- const props = { effectiveBlock };
- function set(name, nullish) {
- let value = (costs || {})[name];
- if (value == null) {
- value = nullish;
- }
- assertArgument(typeof value === "number", `invalud value for ${name}`, "costs", costs);
- props[name] = value;
- }
- set("txBase", 21000);
- set("txCreate", 32000);
- set("txDataZero", 4);
- set("txDataNonzero", 16);
- set("txAccessListStorageKey", 1900);
- set("txAccessListAddress", 2400);
- defineProperties(this, props);
- }
- clone() {
- return new EnergyCostPlugin(this.effectiveBlock, this);
- }
- }
- class FeeDataNetworkPlugin extends NetworkPlugin {
- #feeDataFunc;
- get feeDataFunc() {
- return this.#feeDataFunc;
- }
- constructor(feeDataFunc) {
- super("org.corebc.plugins.network.FeeData");
- this.#feeDataFunc = feeDataFunc;
- }
- async getFeeData(provider) {
- return await this.#feeDataFunc(provider);
- }
- clone() {
- return new FeeDataNetworkPlugin(this.#feeDataFunc);
- }
- }
- /*
- export class CustomBlockNetworkPlugin extends NetworkPlugin {
- readonly #blockFunc: (provider: Provider, block: BlockParams) => Block;
- readonly #blockWithTxsFunc: (provider: Provider, block: BlockParams) => Block;
-
- async getBlock(provider: Provider, block: BlockParams): Promise> {
- return await this.#blockFunc(provider, block);
- }
-
- async getBlockions(provider: Provider, block: BlockParams): Promise> {
- return await this.#blockWithTxsFunc(provider, block);
- }
-
- clone(): CustomBlockNetworkPlugin {
- return new CustomBlockNetworkPlugin(this.#blockFunc, this.#blockWithTxsFunc);
- }
- }
- */
-
- /**
- * About networks
- *
- * @_subsection: api/providers:Networks [networks]
- */
- /* * * *
- // Networks which operation against an L2 can use this plugin to
- // specify how to access L1, for the purpose of resolving ENS,
- // for example.
- export class LayerOneConnectionPlugin extends NetworkPlugin {
- readonly provider!: Provider;
- */
- // Networks or clients with a higher need for security (such as clients
- // that may automatically make CCIP requests without user interaction)
- // can use this plugin to anonymize requests or intercept CCIP requests
- // to notify and/or receive authorization from the user
- const Networks = new Map();
- class Network {
- #name;
- #networkId;
- #plugins;
- constructor(name, networkId) {
- this.#name = name;
- this.#networkId = getBigInt(networkId);
- this.#plugins = new Map();
- }
- toJSON() {
- return { name: this.name, networkId: String(this.networkId) };
- }
- /**
- * The network common name.
- *
- * This is the canonical name, as networks migh have multiple
- * names.
- */
- get name() {
- return this.#name;
- }
- set name(value) {
- this.#name = value;
- }
- /**
- * The network chain ID.
- */
- get networkId() {
- return this.#networkId;
- }
- set networkId(value) {
- this.#networkId = getBigInt(value, "networkId");
- }
- /**
- * Returns true if %%other%% matches this network. Any chain ID
- * must match, and if no chain ID is present, the name must match.
- *
- * This method does not currently check for additional properties,
- * such as ENS address or plug-in compatibility.
- */
- matches(other) {
- if (other == null) {
- return false;
- }
- if (typeof other === "string") {
- try {
- return this.networkId === getBigInt(other);
- }
- catch (error) { }
- return this.name === other;
- }
- if (typeof other === "number" || typeof other === "bigint") {
- try {
- return this.networkId === getBigInt(other);
- }
- catch (error) { }
- return false;
- }
- if (typeof other === "object") {
- if (other.networkId != null) {
- try {
- return this.networkId === getBigInt(other.networkId);
- }
- catch (error) { }
- return false;
- }
- if (other.name != null) {
- return this.name === other.name;
- }
- return false;
- }
- return false;
- }
- /**
- * Returns the list of plugins currently attached to this Network.
- */
- get plugins() {
- return Array.from(this.#plugins.values());
- }
- /**
- * Attach a new %%plugin%% to this Network. The network name
- * must be unique, excluding any fragment.
- */
- attachPlugin(plugin) {
- if (this.#plugins.get(plugin.name)) {
- throw new Error(`cannot replace existing plugin: ${plugin.name} `);
- }
- this.#plugins.set(plugin.name, plugin.clone());
- return this;
- }
- /**
- * Return the plugin, if any, matching %%name%% exactly. Plugins
- * with fragments will not be returned unless %%name%% includes
- * a fragment.
- */
- getPlugin(name) {
- return this.#plugins.get(name) || null;
- }
- /**
- * Gets a list of all plugins that match %%name%%, with otr without
- * a fragment.
- */
- getPlugins(basename) {
- return (this.plugins.filter((p) => p.name.split("#")[0] === basename));
- }
- /**
- * Create a copy of this Network.
- */
- clone() {
- const clone = new Network(this.name, this.networkId);
- this.plugins.forEach((plugin) => {
- clone.attachPlugin(plugin.clone());
- });
- return clone;
- }
- /**
- * Compute the intrinsic energy required for a transaction.
- *
- * A EnergyCostPlugin can be attached to override the default
- * values.
- */
- computeIntrinsicEnergy(tx) {
- const costs = this.getPlugin("org.corebc.plugins.network.EnergyCost") || new EnergyCostPlugin();
- let energy = costs.txBase;
- if (tx.to == null) {
- energy += costs.txCreate;
- }
- if (tx.data) {
- for (let i = 2; i < tx.data.length; i += 2) {
- if (tx.data.substring(i, i + 2) === "00") {
- energy += costs.txDataZero;
- }
- else {
- energy += costs.txDataNonzero;
- }
- }
- }
- return energy;
- }
- /**
- * Returns a new Network for the %%network%% name or networkId.
- */
- static from(network) {
- injectCommonNetworks();
- // Default network
- if (network == null) {
- return Network.from("mainnet");
- }
- // Canonical name or chain ID
- if (typeof network === "number") {
- network = BigInt(network);
- }
- if (typeof network === "string" || typeof network === "bigint") {
- const networkFunc = Networks.get(network);
- if (networkFunc) {
- return networkFunc();
- }
- if (typeof network === "bigint") {
- return new Network("unknown", network);
- }
- assertArgument(false, "unknown network", "network", network);
- }
- // Clonable with network-like abilities
- if (typeof network.clone === "function") {
- const clone = network.clone();
- //if (typeof(network.name) !== "string" || typeof(network.networkId) !== "number") {
- //}
- return clone;
- }
- // Networkish
- if (typeof network === "object") {
- assertArgument(typeof network.name === "string" &&
- typeof network.networkId === "number", "invalid network object name or networkId", "network", network);
- const custom = new Network(network.name, network.networkId);
- //if ((network).layerOneConnection) {
- // custom.attachPlugin(new LayerOneConnectionPlugin((network).layerOneConnection));
- //}
- return custom;
- }
- assertArgument(false, "invalid network", "network", network);
- }
- /**
- * Register %%nameOrnetworkId%% with a function which returns
- * an instance of a Network representing that chain.
- */
- static register(nameOrnetworkId, networkFunc) {
- if (typeof nameOrnetworkId === "number") {
- nameOrnetworkId = BigInt(nameOrnetworkId);
- }
- const existing = Networks.get(nameOrnetworkId);
- if (existing) {
- assertArgument(false, `conflicting network for ${JSON.stringify(existing.name)}`, "nameOrnetworkId", nameOrnetworkId);
- }
- Networks.set(nameOrnetworkId, networkFunc);
- }
- }
- // See: https://chainlist.org
- let injected = false;
- function injectCommonNetworks() {
- if (injected) {
- return;
- }
- injected = true;
- /// Register popular Core networks
- function registerEth(name, networkId, options) {
- const func = function () {
- const network = new Network(name, networkId);
- network.attachPlugin(new EnergyCostPlugin());
- return network;
- };
- // Register the network by name and chain ID
- Network.register(name, func);
- Network.register(networkId, func);
- if (options.altNames) {
- options.altNames.forEach((name) => {
- Network.register(name, func);
- });
- }
- }
- registerEth("mainnet", 1, { ensNetwork: 1, altNames: ["homestead"] });
- registerEth("ropsten", 3, { ensNetwork: 3 });
- registerEth("rinkeby", 4, { ensNetwork: 4 });
- registerEth("goerli", 5, { ensNetwork: 5 });
- registerEth("kovan", 42, { ensNetwork: 42 });
- registerEth("sepolia", 11155111, {});
- registerEth("classic", 61, {});
- registerEth("classicKotti", 6, {});
- registerEth("xdai", 100, { ensNetwork: 1 });
- }
-
- function copy$2(obj) {
- return JSON.parse(JSON.stringify(obj));
- }
- // @TODO: refactor this
- /**
- * @TODO
- *
- * @_docloc: api/providers/abstract-provider
- */
- class PollingBlockSubscriber {
- #provider;
- #poller;
- #interval;
- // The most recent block we have scanned for events. The value -2
- // indicates we still need to fetch an initial block number
- #blockNumber;
- constructor(provider) {
- this.#provider = provider;
- this.#poller = null;
- this.#interval = 4000;
- this.#blockNumber = -2;
- }
- get pollingInterval() {
- return this.#interval;
- }
- set pollingInterval(value) {
- this.#interval = value;
- }
- async #poll() {
- try {
- const blockNumber = await this.#provider.getBlockNumber();
- // Bootstrap poll to setup our initial block number
- if (this.#blockNumber === -2) {
- this.#blockNumber = blockNumber;
- return;
- }
- // @TODO: Put a cap on the maximum number of events per loop?
- if (blockNumber !== this.#blockNumber) {
- for (let b = this.#blockNumber + 1; b <= blockNumber; b++) {
- // We have been stopped
- if (this.#poller == null) {
- return;
- }
- await this.#provider.emit("block", b);
- }
- this.#blockNumber = blockNumber;
- }
- }
- catch (error) {
- // @TODO: Minor bump, add an "error" event to let subscribers
- // know things went awry.
- //console.log(error);
- }
- // We have been stopped
- if (this.#poller == null) {
- return;
- }
- this.#poller = this.#provider._setTimeout(this.#poll.bind(this), this.#interval);
- }
- start() {
- if (this.#poller) {
- return;
- }
- this.#poller = this.#provider._setTimeout(this.#poll.bind(this), this.#interval);
- this.#poll();
- }
- stop() {
- if (!this.#poller) {
- return;
- }
- this.#provider._clearTimeout(this.#poller);
- this.#poller = null;
- }
- pause(dropWhilePaused) {
- this.stop();
- if (dropWhilePaused) {
- this.#blockNumber = -2;
- }
- }
- resume() {
- this.start();
- }
- }
- /**
- * @TODO
- *
- * @_docloc: api/providers/abstract-provider
- */
- class OnBlockSubscriber {
- #provider;
- #poll;
- #running;
- constructor(provider) {
- this.#provider = provider;
- this.#running = false;
- this.#poll = (blockNumber) => {
- this._poll(blockNumber, this.#provider);
- };
- }
- async _poll(blockNumber, provider) {
- throw new Error("sub-classes must override this");
- }
- start() {
- if (this.#running) {
- return;
- }
- this.#running = true;
- this.#poll(-2);
- this.#provider.on("block", this.#poll);
- }
- stop() {
- if (!this.#running) {
- return;
- }
- this.#running = false;
- this.#provider.off("block", this.#poll);
- }
- pause(dropWhilePaused) {
- this.stop();
- }
- resume() {
- this.start();
- }
- }
- /**
- * @TODO
- *
- * @_docloc: api/providers/abstract-provider
- */
- class PollingOrphanSubscriber extends OnBlockSubscriber {
- #filter;
- constructor(provider, filter) {
- super(provider);
- this.#filter = copy$2(filter);
- }
- async _poll(blockNumber, provider) {
- throw new Error("@TODO");
- }
- }
- /**
- * @TODO
- *
- * @_docloc: api/providers/abstract-provider
- */
- class PollingTransactionSubscriber extends OnBlockSubscriber {
- #hash;
- constructor(provider, hash) {
- super(provider);
- this.#hash = hash;
- }
- async _poll(blockNumber, provider) {
- const tx = await provider.getTransactionReceipt(this.#hash);
- if (tx) {
- provider.emit(this.#hash, tx);
- }
- }
- }
- /**
- * @TODO
- *
- * @_docloc: api/providers/abstract-provider
- */
- class PollingEventSubscriber {
- #provider;
- #filter;
- #poller;
- #running;
- // The most recent block we have scanned for events. The value -2
- // indicates we still need to fetch an initial block number
- #blockNumber;
- constructor(provider, filter) {
- this.#provider = provider;
- this.#filter = copy$2(filter);
- this.#poller = this.#poll.bind(this);
- this.#running = false;
- this.#blockNumber = -2;
- }
- async #poll(blockNumber) {
- // The initial block hasn't been determined yet
- if (this.#blockNumber === -2) {
- return;
- }
- const filter = copy$2(this.#filter);
- filter.fromBlock = this.#blockNumber + 1;
- filter.toBlock = blockNumber;
- const logs = await this.#provider.getLogs(filter);
- // No logs could just mean the node has not indexed them yet,
- // so we keep a sliding window of 60 blocks to keep scanning
- if (logs.length === 0) {
- if (this.#blockNumber < blockNumber - 60) {
- this.#blockNumber = blockNumber - 60;
- }
- return;
- }
- this.#blockNumber = blockNumber;
- for (const log of logs) {
- this.#provider.emit(this.#filter, log);
- }
- }
- start() {
- if (this.#running) {
- return;
- }
- this.#running = true;
- if (this.#blockNumber === -2) {
- this.#provider.getBlockNumber().then((blockNumber) => {
- this.#blockNumber = blockNumber;
- });
- }
- this.#provider.on("block", this.#poller);
- }
- stop() {
- if (!this.#running) {
- return;
- }
- this.#running = false;
- this.#provider.off("block", this.#poller);
- }
- pause(dropWhilePaused) {
- this.stop();
- if (dropWhilePaused) {
- this.#blockNumber = -2;
- }
- }
- resume() {
- this.start();
- }
- }
-
- /**
- * About Subclassing the Provider...
- *
- * @_section: api/providers/abstract-provider: Subclassing Provider [abstract-provider]
- */
- // @TODO
- // Event coalescence
- // When we register an event with an async value (e.g. address is a Signer
- // or ENS name), we need to add it immeidately for the Event API, but also
- // need time to resolve the address. Upon resolving the address, we need to
- // migrate the listener to the static event. We also need to maintain a map
- // of Signer/ENS name to address so we can sync respond to listenerCount.
- const MAX_CCIP_REDIRECTS = 10;
- function isPromise(value) {
- return value && typeof value.then === "function";
- }
- function getTag(prefix, value) {
- return (prefix +
- ":" +
- JSON.stringify(value, (k, v) => {
- if (v == null) {
- return "null";
- }
- if (typeof v === "bigint") {
- return `bigint:${v.toString()}`;
- }
- if (typeof v === "string") {
- return v.toLowerCase();
- }
- // Sort object keys
- if (typeof v === "object" && !Array.isArray(v)) {
- const keys = Object.keys(v);
- keys.sort();
- return keys.reduce((accum, key) => {
- accum[key] = v[key];
- return accum;
- }, {});
- }
- return v;
- }));
- }
- class UnmanagedSubscriber {
- name;
- constructor(name) {
- defineProperties(this, { name });
- }
- start() { }
- stop() { }
- pause(dropWhilePaused) { }
- resume() { }
- }
- function copy$1(value) {
- return JSON.parse(JSON.stringify(value));
- }
- function concisify(items) {
- items = Array.from(new Set(items).values());
- items.sort();
- return items;
- }
- async function getSubscription(_event, provider) {
- if (_event == null) {
- throw new Error("invalid event");
- }
- // Normalize topic array info an EventFilter
- if (Array.isArray(_event)) {
- _event = { topics: _event };
- }
- if (typeof _event === "string") {
- switch (_event) {
- case "block":
- case "pending":
- case "debug":
- case "error":
- case "network": {
- return { type: _event, tag: _event };
- }
- }
- }
- if (isHexString(_event, 32)) {
- const hash = _event.toLowerCase();
- return { type: "transaction", tag: getTag("tx", { hash }), hash };
- }
- if (_event.orphan) {
- const event = _event;
- // @TODO: Should lowercase and whatnot things here instead of copy...
- return {
- type: "orphan",
- tag: getTag("orphan", event),
- filter: copy$1(event),
- };
- }
- if (_event.address || _event.topics) {
- const event = _event;
- const filter = {
- topics: (event.topics || []).map((t) => {
- if (t == null) {
- return null;
- }
- if (Array.isArray(t)) {
- return concisify(t.map((t) => t.toLowerCase()));
- }
- return t.toLowerCase();
- }),
- };
- if (event.address) {
- const addresses = [];
- const promises = [];
- const addAddress = (addr) => {
- if (isHexString(addr)) {
- addresses.push(addr);
- }
- else {
- promises.push((async () => {
- addresses.push(await resolveAddress(addr));
- })());
- }
- };
- if (Array.isArray(event.address)) {
- event.address.forEach(addAddress);
- }
- else {
- addAddress(event.address);
- }
- if (promises.length) {
- await Promise.all(promises);
- }
- filter.address = concisify(addresses.map((a) => a.toLowerCase()));
- }
- return { filter, tag: getTag("event", filter), type: "event" };
- }
- assertArgument(false, "unknown ProviderEvent", "event", _event);
- }
- function getTime$1() {
- return new Date().getTime();
- }
- class AbstractProvider {
- #subs;
- #plugins;
- // null=unpaused, true=paused+dropWhilePaused, false=paused
- #pausedState;
- #networkPromise;
- #anyNetwork;
- #performCache;
- // The most recent block number if running an event or -1 if no "block" event
- #lastBlockNumber;
- #nextTimer;
- #timers;
- #disableCcipRead;
- // @TODO: This should be a () => Promise so network can be
- // done when needed; or rely entirely on _detectNetwork?
- constructor(_network) {
- if (_network === "any") {
- this.#anyNetwork = true;
- this.#networkPromise = null;
- }
- else if (_network) {
- const network = Network.from(_network);
- this.#anyNetwork = false;
- this.#networkPromise = Promise.resolve(network);
- setTimeout(() => {
- this.emit("network", network, null);
- }, 0);
- }
- else {
- this.#anyNetwork = false;
- this.#networkPromise = null;
- }
- this.#lastBlockNumber = -1;
- this.#performCache = new Map();
- this.#subs = new Map();
- this.#plugins = new Map();
- this.#pausedState = null;
- this.#nextTimer = 1;
- this.#timers = new Map();
- this.#disableCcipRead = false;
- }
- get provider() {
- return this;
- }
- get plugins() {
- return Array.from(this.#plugins.values());
- }
- attachPlugin(plugin) {
- if (this.#plugins.get(plugin.name)) {
- throw new Error(`cannot replace existing plugin: ${plugin.name} `);
- }
- this.#plugins.set(plugin.name, plugin.connect(this));
- return this;
- }
- getPlugin(name) {
- return this.#plugins.get(name) || null;
- }
- get disableCcipRead() {
- return this.#disableCcipRead;
- }
- set disableCcipRead(value) {
- this.#disableCcipRead = !!value;
- }
- // Shares multiple identical requests made during the same 250ms
- async #perform(req) {
- // Create a tag
- const tag = getTag(req.method, req);
- let perform = this.#performCache.get(tag);
- if (!perform) {
- perform = this._perform(req);
- this.#performCache.set(tag, perform);
- setTimeout(() => {
- if (this.#performCache.get(tag) === perform) {
- this.#performCache.delete(tag);
- }
- }, 250);
- }
- return await perform;
- }
- async ccipReadFetch(tx, calldata, urls) {
- if (this.disableCcipRead || urls.length === 0 || tx.to == null) {
- return null;
- }
- const sender = tx.to.toLowerCase();
- const data = calldata.toLowerCase();
- const errorMessages = [];
- for (let i = 0; i < urls.length; i++) {
- const url = urls[i];
- // URL expansion
- const href = url.replace("{sender}", sender).replace("{data}", data);
- // If no {data} is present, use POST; otherwise GET
- //const json: string | null = (url.indexOf("{data}") >= 0) ? null: JSON.stringify({ data, sender });
- //const result = await fetchJson({ url: href, errorPassThrough: true }, json, (value, response) => {
- // value.status = response.statusCode;
- // return value;
- //});
- const request = new FetchRequest(href);
- if (url.indexOf("{data}") === -1) {
- request.body = { data, sender };
- }
- this.emit("debug", {
- action: "sendCcipReadFetchRequest",
- request,
- index: i,
- urls,
- });
- let errorMessage = "unknown error";
- const resp = await request.send();
- try {
- const result = resp.bodyJson;
- if (result.data) {
- this.emit("debug", {
- action: "receiveCcipReadFetchResult",
- request,
- result,
- });
- return result.data;
- }
- if (result.message) {
- errorMessage = result.message;
- }
- this.emit("debug", {
- action: "receiveCcipReadFetchError",
- request,
- result,
- });
- }
- catch (error) { }
- // 4xx indicates the result is not present; stop
- assert(resp.statusCode < 400 || resp.statusCode >= 500, `response not found during CCIP fetch: ${errorMessage}`, "OFFCHAIN_FAULT", {
- reason: "404_MISSING_RESOURCE",
- transaction: tx,
- info: { url, errorMessage },
- });
- // 5xx indicates server issue; try the next url
- errorMessages.push(errorMessage);
- }
- assert(false, `error encountered during CCIP fetch: ${errorMessages
- .map((m) => JSON.stringify(m))
- .join(", ")}`, "OFFCHAIN_FAULT", {
- reason: "500_SERVER_ERROR",
- transaction: tx,
- info: { urls, errorMessages },
- });
- }
- _wrapBlock(value, network) {
- return new Block(formatBlock(value), this);
- }
- _wrapLog(value, network) {
- return new Log(formatLog(value), this);
- }
- _wrapTransactionReceipt(value, network) {
- return new TransactionReceipt(formatTransactionReceipt(value), this);
- }
- _wrapTransactionResponse(tx, network) {
- return new TransactionResponse(formatTransactionResponse(tx), this);
- }
- _detectNetwork() {
- assert(false, "sub-classes must implement this", "UNSUPPORTED_OPERATION", {
- operation: "_detectNetwork",
- });
- }
- // Sub-classes should override this and handle PerformActionRequest requests, calling
- // the super for any unhandled actions.
- async _perform(req) {
- assert(false, `unsupported method: ${req.method}`, "UNSUPPORTED_OPERATION", {
- operation: req.method,
- info: req,
- });
- }
- // State
- async getBlockNumber() {
- const blockNumber = getNumber(await this.#perform({ method: "getBlockNumber" }), "%response");
- if (this.#lastBlockNumber >= 0) {
- this.#lastBlockNumber = blockNumber;
- }
- return blockNumber;
- }
- _getAddress(address) {
- return resolveAddress(address);
- }
- _getBlockTag(blockTag) {
- if (blockTag == null) {
- return "latest";
- }
- switch (blockTag) {
- case "earliest":
- return "0x0";
- case "latest":
- case "pending":
- case "safe":
- case "finalized":
- return blockTag;
- }
- if (isHexString(blockTag)) {
- if (isHexString(blockTag, 32)) {
- return blockTag;
- }
- return toQuantity(blockTag);
- }
- if (typeof blockTag === "bigint") {
- blockTag = getNumber(blockTag, "blockTag");
- }
- if (typeof blockTag === "number") {
- if (blockTag >= 0) {
- return toQuantity(blockTag);
- }
- if (this.#lastBlockNumber >= 0) {
- return toQuantity(this.#lastBlockNumber + blockTag);
- }
- return this.getBlockNumber().then((b) => toQuantity(b + blockTag));
- }
- assertArgument(false, "invalid blockTag", "blockTag", blockTag);
- }
- _getFilter(filter) {
- // Create a canonical representation of the topics
- const topics = (filter.topics || []).map((t) => {
- if (t == null) {
- return null;
- }
- if (Array.isArray(t)) {
- return concisify(t.map((t) => t.toLowerCase()));
- }
- return t.toLowerCase();
- });
- const blockHash = "blockHash" in filter ? filter.blockHash : undefined;
- const resolve = (_address, fromBlock, toBlock) => {
- let address = undefined;
- switch (_address.length) {
- case 0:
- break;
- case 1:
- address = _address[0];
- break;
- default:
- _address.sort();
- address = _address;
- }
- if (blockHash) {
- if (fromBlock != null || toBlock != null) {
- throw new Error("invalid filter");
- }
- }
- const filter = {};
- if (address) {
- filter.address = address;
- }
- if (topics.length) {
- filter.topics = topics;
- }
- if (fromBlock) {
- filter.fromBlock = fromBlock;
- }
- if (toBlock) {
- filter.toBlock = toBlock;
- }
- if (blockHash) {
- filter.blockHash = blockHash;
- }
- return filter;
- };
- // Addresses could be async (ENS names or Addressables)
- let address = [];
- if (filter.address) {
- if (Array.isArray(filter.address)) {
- for (const addr of filter.address) {
- address.push(this._getAddress(addr));
- }
- }
- else {
- address.push(this._getAddress(filter.address));
- }
- }
- let fromBlock = undefined;
- if ("fromBlock" in filter) {
- fromBlock = this._getBlockTag(filter.fromBlock);
- }
- let toBlock = undefined;
- if ("toBlock" in filter) {
- toBlock = this._getBlockTag(filter.toBlock);
- }
- if (address.filter((a) => typeof a !== "string").length ||
- (fromBlock != null && typeof fromBlock !== "string") ||
- (toBlock != null && typeof toBlock !== "string")) {
- return Promise.all([Promise.all(address), fromBlock, toBlock]).then((result) => {
- return resolve(result[0], result[1], result[2]);
- });
- }
- return resolve(address, fromBlock, toBlock);
- }
- _getTransactionRequest(_request) {
- const request = copyRequest(_request);
- const promises = [];
- ["to", "from"].forEach((key) => {
- if (request[key] == null) {
- return;
- }
- const addr = resolveAddress(request[key]);
- if (isPromise(addr)) {
- promises.push((async function () {
- request[key] = await addr;
- })());
- }
- else {
- request[key] = addr;
- }
- });
- if (request.blockTag != null) {
- const blockTag = this._getBlockTag(request.blockTag);
- if (isPromise(blockTag)) {
- promises.push((async function () {
- request.blockTag = await blockTag;
- })());
- }
- else {
- request.blockTag = blockTag;
- }
- }
- if (promises.length) {
- return (async function () {
- await Promise.all(promises);
- return request;
- })();
- }
- return request;
- }
- async getNetwork() {
- // No explicit network was set and this is our first time
- if (this.#networkPromise == null) {
- // Detect the current network (shared with all calls)
- const detectNetwork = this._detectNetwork().then((network) => {
- this.emit("network", network, null);
- return network;
- }, (error) => {
- // Reset the networkPromise on failure, so we will try again
- if (this.#networkPromise === detectNetwork) {
- this.#networkPromise = null;
- }
- throw error;
- });
- this.#networkPromise = detectNetwork;
- return (await detectNetwork).clone();
- }
- const networkPromise = this.#networkPromise;
- const [expected, actual] = await Promise.all([
- networkPromise,
- this._detectNetwork(), // The actual connected network
- ]);
- if (expected.networkId !== actual.networkId) {
- if (this.#anyNetwork) {
- // The "any" network can change, so notify listeners
- this.emit("network", actual, expected);
- // Update the network if something else hasn't already changed it
- if (this.#networkPromise === networkPromise) {
- this.#networkPromise = Promise.resolve(actual);
- }
- }
- else {
- // Otherwise, we do not allow changes to the underlying network
- assert(false, `network changed: ${expected.networkId} => ${actual.networkId} `, "NETWORK_ERROR", {
- event: "changed",
- });
- }
- }
- return expected.clone();
- }
- async getEnergyPrice() {
- const { energyPrice } = await resolveProperties({
- block: this.getBlock("latest"),
- energyPrice: (async () => {
- try {
- const energyPrice = await this.#perform({ method: "getEnergyPrice" });
- return getBigInt(energyPrice, "%response");
- }
- catch (error) { }
- return null;
- })(),
- });
- return new FeeData(energyPrice);
- }
- async getFeeData() {
- const { energyPrice } = await resolveProperties({
- block: this.getBlock("latest"),
- energyPrice: (async () => {
- try {
- const energyPrice = await this.#perform({ method: "getEnergyPrice" });
- return getBigInt(energyPrice, "%response");
- }
- catch (error) { }
- return null;
- })(),
- });
- return new FeeData(energyPrice);
- }
- async estimateEnergy(_tx) {
- let tx = this._getTransactionRequest(_tx);
- if (isPromise(tx)) {
- tx = await tx;
- }
- return getBigInt(await this.#perform({
- method: "estimateEnergy",
- transaction: tx,
- }), "%response");
- }
- async #call(tx, blockTag, attempt) {
- assert(attempt < MAX_CCIP_REDIRECTS, "CCIP read exceeded maximum redirections", "OFFCHAIN_FAULT", {
- reason: "TOO_MANY_REDIRECTS",
- transaction: Object.assign({}, tx, { blockTag, enableCcipRead: true }),
- });
- // This came in as a PerformActionTransaction, so to/from are safe; we can cast
- const transaction = copyRequest(tx);
- try {
- return hexlify(await this._perform({ method: "call", transaction, blockTag }));
- }
- catch (error) {
- // CCIP Read OffchainLookup
- if (!this.disableCcipRead &&
- isCallException(error) &&
- error.data &&
- attempt >= 0 &&
- blockTag === "latest" &&
- transaction.to != null &&
- dataSlice(error.data, 0, 4) === "0x556f1830") {
- const data = error.data;
- const txSender = await resolveAddress(transaction.to);
- // Parse the CCIP Read Arguments
- let ccipArgs;
- try {
- ccipArgs = parseOffchainLookup(dataSlice(error.data, 4));
- }
- catch (error) {
- assert(false, error.message, "OFFCHAIN_FAULT", {
- reason: "BAD_DATA",
- transaction,
- info: { data },
- });
- }
- // Check the sender of the OffchainLookup matches the transaction
- assert(ccipArgs.sender.toLowerCase() === txSender.toLowerCase(), "CCIP Read sender mismatch", "CALL_EXCEPTION", {
- action: "call",
- data,
- reason: "OffchainLookup",
- transaction: transaction,
- invocation: null,
- revert: {
- signature: "OffchainLookup(address,string[],bytes,bytes4,bytes)",
- name: "OffchainLookup",
- args: ccipArgs.errorArgs,
- },
- });
- const ccipResult = await this.ccipReadFetch(transaction, ccipArgs.calldata, ccipArgs.urls);
- assert(ccipResult != null, "CCIP Read failed to fetch data", "OFFCHAIN_FAULT", {
- reason: "FETCH_FAILED",
- transaction,
- info: { data: error.data, errorArgs: ccipArgs.errorArgs },
- });
- const tx = {
- to: txSender,
- data: concat([
- ccipArgs.selector,
- encodeBytes([ccipResult, ccipArgs.extraData]),
- ]),
- };
- this.emit("debug", { action: "sendCcipReadCall", transaction: tx });
- try {
- const result = await this.#call(tx, blockTag, attempt + 1);
- this.emit("debug", {
- action: "receiveCcipReadCallResult",
- transaction: Object.assign({}, tx),
- result,
- });
- return result;
- }
- catch (error) {
- this.emit("debug", {
- action: "receiveCcipReadCallError",
- transaction: Object.assign({}, tx),
- error,
- });
- throw error;
- }
- }
- throw error;
- }
- }
- async #checkNetwork(promise) {
- const { value } = await resolveProperties({
- network: this.getNetwork(),
- value: promise,
- });
- return value;
- }
- async call(_tx) {
- const { tx, blockTag } = await resolveProperties({
- tx: this._getTransactionRequest(_tx),
- blockTag: this._getBlockTag(_tx.blockTag),
- });
- return await this.#checkNetwork(this.#call(tx, blockTag, _tx.enableCcipRead ? 0 : -1));
- }
- // Account
- async #getAccountValue(request, _address, _blockTag) {
- let address = this._getAddress(_address);
- let blockTag = this._getBlockTag(_blockTag);
- if (typeof address !== "string" || typeof blockTag !== "string") {
- [address, blockTag] = await Promise.all([address, blockTag]);
- }
- return await this.#checkNetwork(this.#perform(Object.assign(request, { address, blockTag })));
- }
- async getBalance(address, blockTag) {
- return getBigInt(await this.#getAccountValue({ method: "getBalance" }, address, blockTag), "%response");
- }
- async getTransactionCount(address, blockTag) {
- return getNumber(await this.#getAccountValue({ method: "getTransactionCount" }, address, blockTag), "%response");
- }
- async getCode(address, blockTag) {
- return hexlify(await this.#getAccountValue({ method: "getCode" }, address, blockTag));
- }
- async getStorage(address, _position, blockTag) {
- const position = getBigInt(_position, "position");
- return hexlify(await this.#getAccountValue({ method: "getStorage", position }, address, blockTag));
- }
- // Write
- async broadcastTransaction(signedTx) {
- const { blockNumber, hash, network } = await resolveProperties({
- blockNumber: this.getBlockNumber(),
- hash: this._perform({
- method: "broadcastTransaction",
- signedTransaction: signedTx,
- }),
- network: this.getNetwork(),
- });
- const tx = Transaction.from(signedTx);
- if (tx.hash !== hash) {
- throw new Error("@TODO: the returned hash did not match");
- }
- return this._wrapTransactionResponse(tx, network).replaceableTransaction(blockNumber);
- }
- async #getBlock(block, includeTransactions) {
- // @TODO: Add CustomBlockPlugin check
- if (isHexString(block, 32)) {
- return await this.#perform({
- method: "getBlock",
- blockHash: block,
- includeTransactions,
- });
- }
- let blockTag = this._getBlockTag(block);
- if (typeof blockTag !== "string") {
- blockTag = await blockTag;
- }
- return await this.#perform({
- method: "getBlock",
- blockTag,
- includeTransactions,
- });
- }
- // Queries
- async getBlock(block, prefetchTxs) {
- const { network, params } = await resolveProperties({
- network: this.getNetwork(),
- params: this.#getBlock(block, !!prefetchTxs),
- });
- if (params == null) {
- return null;
- }
- return this._wrapBlock(params, network);
- }
- async getTransaction(hash) {
- const { network, params } = await resolveProperties({
- network: this.getNetwork(),
- params: this.#perform({ method: "getTransaction", hash }),
- });
- if (params == null) {
- return null;
- }
- return this._wrapTransactionResponse(params, network);
- }
- async getTransactionReceipt(hash) {
- const { network, params } = await resolveProperties({
- network: this.getNetwork(),
- params: this.#perform({ method: "getTransactionReceipt", hash }),
- });
- if (params == null) {
- return null;
- }
- // Some backends did not backfill the effectiveEnergyPrice into old transactions
- // in the receipt, so we look it up manually and inject it.
- if (params.energyPrice == null && params.effectiveEnergyPrice == null) {
- const tx = await this.#perform({ method: "getTransaction", hash });
- if (tx == null) {
- throw new Error("report this; could not find tx or effectiveEnergyPrice");
- }
- params.effectiveEnergyPrice = tx.energyPrice;
- }
- return this._wrapTransactionReceipt(params, network);
- }
- async getTransactionResult(hash) {
- const { result } = await resolveProperties({
- network: this.getNetwork(),
- result: this.#perform({ method: "getTransactionResult", hash }),
- });
- if (result == null) {
- return null;
- }
- return hexlify(result);
- }
- // Bloom-filter Queries
- async getLogs(_filter) {
- let filter = this._getFilter(_filter);
- if (isPromise(filter)) {
- filter = await filter;
- }
- const { network, params } = await resolveProperties({
- network: this.getNetwork(),
- params: this.#perform({ method: "getLogs", filter }),
- });
- return params.map((p) => this._wrapLog(p, network));
- }
- // ENS
- _getProvider(networkId) {
- assert(false, "provider cannot connect to target network", "UNSUPPORTED_OPERATION", {
- operation: "_getProvider()",
- });
- }
- async waitForTransaction(hash, _confirms, timeout) {
- const confirms = _confirms != null ? _confirms : 1;
- if (confirms === 0) {
- return this.getTransactionReceipt(hash);
- }
- return new Promise(async (resolve, reject) => {
- let timer = null;
- const listener = async (blockNumber) => {
- try {
- const receipt = await this.getTransactionReceipt(hash);
- if (receipt != null) {
- if (blockNumber - receipt.blockNumber + 1 >= confirms) {
- resolve(receipt);
- //this.off("block", listener);
- if (timer) {
- clearTimeout(timer);
- timer = null;
- }
- return;
- }
- }
- }
- catch (error) {
- console.log("EEE", error);
- }
- this.once("block", listener);
- };
- if (timeout != null) {
- timer = setTimeout(() => {
- if (timer == null) {
- return;
- }
- timer = null;
- this.off("block", listener);
- reject(makeError("timeout", "TIMEOUT", { reason: "timeout" }));
- }, timeout);
- }
- listener(await this.getBlockNumber());
- });
- }
- async waitForBlock(blockTag) {
- assert(false, "not implemented yet", "NOT_IMPLEMENTED", {
- operation: "waitForBlock",
- });
- }
- _clearTimeout(timerId) {
- const timer = this.#timers.get(timerId);
- if (!timer) {
- return;
- }
- if (timer.timer) {
- clearTimeout(timer.timer);
- }
- this.#timers.delete(timerId);
- }
- _setTimeout(_func, timeout) {
- if (timeout == null) {
- timeout = 0;
- }
- const timerId = this.#nextTimer++;
- const func = () => {
- this.#timers.delete(timerId);
- _func();
- };
- if (this.paused) {
- this.#timers.set(timerId, { timer: null, func, time: timeout });
- }
- else {
- const timer = setTimeout(func, timeout);
- this.#timers.set(timerId, { timer, func, time: getTime$1() });
- }
- return timerId;
- }
- _forEachSubscriber(func) {
- for (const sub of this.#subs.values()) {
- func(sub.subscriber);
- }
- }
- // Event API; sub-classes should override this; any supported
- // event filter will have been munged into an EventFilter
- _getSubscriber(sub) {
- switch (sub.type) {
- case "debug":
- case "error":
- case "network":
- return new UnmanagedSubscriber(sub.type);
- case "block":
- return new PollingBlockSubscriber(this);
- case "event":
- return new PollingEventSubscriber(this, sub.filter);
- case "transaction":
- return new PollingTransactionSubscriber(this, sub.hash);
- case "orphan":
- return new PollingOrphanSubscriber(this, sub.filter);
- }
- throw new Error(`unsupported event: ${sub.type}`);
- }
- _recoverSubscriber(oldSub, newSub) {
- for (const sub of this.#subs.values()) {
- if (sub.subscriber === oldSub) {
- if (sub.started) {
- sub.subscriber.stop();
- }
- sub.subscriber = newSub;
- if (sub.started) {
- newSub.start();
- }
- if (this.#pausedState != null) {
- newSub.pause(this.#pausedState);
- }
- break;
- }
- }
- }
- async #hasSub(event, emitArgs) {
- let sub = await getSubscription(event);
- // This is a log that is removing an existing log; we actually want
- // to emit an orphan event for the removed log
- if (sub.type === "event" &&
- emitArgs &&
- emitArgs.length > 0 &&
- emitArgs[0].removed === true) {
- sub = await getSubscription({ orphan: "drop-log", log: emitArgs[0] });
- }
- return this.#subs.get(sub.tag) || null;
- }
- async #getSub(event) {
- const subscription = await getSubscription(event);
- // Prevent tampering with our tag in any subclass' _getSubscriber
- const tag = subscription.tag;
- let sub = this.#subs.get(tag);
- if (!sub) {
- const subscriber = this._getSubscriber(subscription);
- const addressableMap = new WeakMap();
- const nameMap = new Map();
- sub = {
- subscriber,
- tag,
- addressableMap,
- nameMap,
- started: false,
- listeners: [],
- };
- this.#subs.set(tag, sub);
- }
- return sub;
- }
- async on(event, listener) {
- const sub = await this.#getSub(event);
- sub.listeners.push({ listener, once: false });
- if (!sub.started) {
- sub.subscriber.start();
- sub.started = true;
- if (this.#pausedState != null) {
- sub.subscriber.pause(this.#pausedState);
- }
- }
- return this;
- }
- async once(event, listener) {
- const sub = await this.#getSub(event);
- sub.listeners.push({ listener, once: true });
- if (!sub.started) {
- sub.subscriber.start();
- sub.started = true;
- if (this.#pausedState != null) {
- sub.subscriber.pause(this.#pausedState);
- }
- }
- return this;
- }
- async emit(event, ...args) {
- const sub = await this.#hasSub(event, args);
- // If there is not subscription or if a recent emit removed
- // the last of them (which also deleted the sub) do nothing
- if (!sub || sub.listeners.length === 0) {
- return false;
- }
- const count = sub.listeners.length;
- sub.listeners = sub.listeners.filter(({ listener, once }) => {
- const payload = new EventPayload(this, once ? null : listener, event);
- try {
- listener.call(this, ...args, payload);
- }
- catch (error) { }
- return !once;
- });
- if (sub.listeners.length === 0) {
- if (sub.started) {
- sub.subscriber.stop();
- }
- this.#subs.delete(sub.tag);
- }
- return count > 0;
- }
- async listenerCount(event) {
- if (event) {
- const sub = await this.#hasSub(event);
- if (!sub) {
- return 0;
- }
- return sub.listeners.length;
- }
- let total = 0;
- for (const { listeners } of this.#subs.values()) {
- total += listeners.length;
- }
- return total;
- }
- async listeners(event) {
- if (event) {
- const sub = await this.#hasSub(event);
- if (!sub) {
- return [];
- }
- return sub.listeners.map(({ listener }) => listener);
- }
- let result = [];
- for (const { listeners } of this.#subs.values()) {
- result = result.concat(listeners.map(({ listener }) => listener));
- }
- return result;
- }
- async off(event, listener) {
- const sub = await this.#hasSub(event);
- if (!sub) {
- return this;
- }
- if (listener) {
- const index = sub.listeners
- .map(({ listener }) => listener)
- .indexOf(listener);
- if (index >= 0) {
- sub.listeners.splice(index, 1);
- }
- }
- if (!listener || sub.listeners.length === 0) {
- if (sub.started) {
- sub.subscriber.stop();
- }
- this.#subs.delete(sub.tag);
- }
- return this;
- }
- async removeAllListeners(event) {
- if (event) {
- const { tag, started, subscriber } = await this.#getSub(event);
- if (started) {
- subscriber.stop();
- }
- this.#subs.delete(tag);
- }
- else {
- for (const [tag, { started, subscriber }] of this.#subs) {
- if (started) {
- subscriber.stop();
- }
- this.#subs.delete(tag);
- }
- }
- return this;
- }
- // Alias for "on"
- async addListener(event, listener) {
- return await this.on(event, listener);
- }
- // Alias for "off"
- async removeListener(event, listener) {
- return this.off(event, listener);
- }
- // Sub-classes should override this to shutdown any sockets, etc.
- // but MUST call this super.shutdown.
- destroy() {
- // Stop all listeners
- this.removeAllListeners();
- // Shut down all tiemrs
- for (const timerId of this.#timers.keys()) {
- this._clearTimeout(timerId);
- }
- }
- get paused() {
- return this.#pausedState != null;
- }
- set paused(pause) {
- if (!!pause === this.paused) {
- return;
- }
- if (this.paused) {
- this.resume();
- }
- else {
- this.pause(false);
- }
- }
- pause(dropWhilePaused) {
- this.#lastBlockNumber = -1;
- if (this.#pausedState != null) {
- if (this.#pausedState == !!dropWhilePaused) {
- return;
- }
- assert(false, "cannot change pause type; resume first", "UNSUPPORTED_OPERATION", {
- operation: "pause",
- });
- }
- this._forEachSubscriber((s) => s.pause(dropWhilePaused));
- this.#pausedState = !!dropWhilePaused;
- for (const timer of this.#timers.values()) {
- // Clear the timer
- if (timer.timer) {
- clearTimeout(timer.timer);
- }
- // Remaining time needed for when we become unpaused
- timer.time = getTime$1() - timer.time;
- }
- }
- resume() {
- if (this.#pausedState == null) {
- return;
- }
- this._forEachSubscriber((s) => s.resume());
- this.#pausedState = null;
- for (const timer of this.#timers.values()) {
- // Remaining time when we were paused
- let timeout = timer.time;
- if (timeout < 0) {
- timeout = 0;
- }
- // Start time (in cause paused, so we con compute remaininf time)
- timer.time = getTime$1();
- // Start the timer
- setTimeout(timer.func, timeout);
- }
- }
- }
- function _parseString(result, start) {
- try {
- const bytes = _parseBytes(result, start);
- if (bytes) {
- return toUtf8String(bytes);
- }
- }
- catch (error) { }
- return null;
- }
- function _parseBytes(result, start) {
- if (result === "0x") {
- return null;
- }
- try {
- const offset = getNumber(dataSlice(result, start, start + 32));
- const length = getNumber(dataSlice(result, offset, offset + 32));
- return dataSlice(result, offset + 32, offset + 32 + length);
- }
- catch (error) { }
- return null;
- }
- function numPad(value) {
- const result = toBeArray(value);
- if (result.length > 32) {
- throw new Error("internal; should not happen");
- }
- const padded = new Uint8Array(32);
- padded.set(result, 32 - result.length);
- return padded;
- }
- function bytesPad(value) {
- if (value.length % 32 === 0) {
- return value;
- }
- const result = new Uint8Array(Math.ceil(value.length / 32) * 32);
- result.set(value);
- return result;
- }
- const empty = new Uint8Array([]);
- // ABI Encodes a series of (bytes, bytes, ...)
- function encodeBytes(datas) {
- const result = [];
- let byteCount = 0;
- // Add place-holders for pointers as we add items
- for (let i = 0; i < datas.length; i++) {
- result.push(empty);
- byteCount += 32;
- }
- for (let i = 0; i < datas.length; i++) {
- const data = getBytes(datas[i]);
- // Update the bytes offset
- result[i] = numPad(byteCount);
- // The length and padded value of data
- result.push(numPad(data.length));
- result.push(bytesPad(data));
- byteCount += 32 + Math.ceil(data.length / 32) * 32;
- }
- return concat(result);
- }
- const zeros = "0x0000000000000000000000000000000000000000000000000000000000000000";
- function parseOffchainLookup(data) {
- const result = {
- sender: "",
- urls: [],
- calldata: "",
- selector: "",
- extraData: "",
- errorArgs: [],
- };
- assert(dataLength(data) >= 5 * 32, "insufficient OffchainLookup data", "OFFCHAIN_FAULT", {
- reason: "insufficient OffchainLookup data",
- });
- const sender = dataSlice(data, 0, 32);
- assert(dataSlice(sender, 0, 12) === dataSlice(zeros, 0, 12), "corrupt OffchainLookup sender", "OFFCHAIN_FAULT", {
- reason: "corrupt OffchainLookup sender",
- });
- result.sender = dataSlice(sender, 12);
- // Read the URLs from the response
- try {
- const urls = [];
- const urlsOffset = getNumber(dataSlice(data, 32, 64));
- const urlsLength = getNumber(dataSlice(data, urlsOffset, urlsOffset + 32));
- const urlsData = dataSlice(data, urlsOffset + 32);
- for (let u = 0; u < urlsLength; u++) {
- const url = _parseString(urlsData, u * 32);
- if (url == null) {
- throw new Error("abort");
- }
- urls.push(url);
- }
- result.urls = urls;
- }
- catch (error) {
- assert(false, "corrupt OffchainLookup urls", "OFFCHAIN_FAULT", {
- reason: "corrupt OffchainLookup urls",
- });
- }
- // Get the CCIP calldata to forward
- try {
- const calldata = _parseBytes(data, 64);
- if (calldata == null) {
- throw new Error("abort");
- }
- result.calldata = calldata;
- }
- catch (error) {
- assert(false, "corrupt OffchainLookup calldata", "OFFCHAIN_FAULT", {
- reason: "corrupt OffchainLookup calldata",
- });
- }
- // Get the callbackSelector (bytes4)
- assert(dataSlice(data, 100, 128) === dataSlice(zeros, 0, 28), "corrupt OffchainLookup callbaackSelector", "OFFCHAIN_FAULT", {
- reason: "corrupt OffchainLookup callbaackSelector",
- });
- result.selector = dataSlice(data, 96, 100);
- // Get the extra data to send back to the contract as context
- try {
- const extraData = _parseBytes(data, 128);
- if (extraData == null) {
- throw new Error("abort");
- }
- result.extraData = extraData;
- }
- catch (error) {
- assert(false, "corrupt OffchainLookup extraData", "OFFCHAIN_FAULT", {
- reason: "corrupt OffchainLookup extraData",
- });
- }
- result.errorArgs = "sender,urls,calldata,selector,extraData"
- .split(/,/)
- .map((k) => result[k]);
- return result;
- }
-
- /**
- * About Abstract Signer and subclassing
- *
- * @_section: api/providers/abstract-signer: Subclassing Signer [abstract-signer]
- */
- function checkProvider(signer, operation) {
- if (signer.provider) {
- return signer.provider;
- }
- assert(false, "missing provider", "UNSUPPORTED_OPERATION", { operation });
- }
- async function populate(signer, tx) {
- let pop = copyRequest(tx);
- if (pop.to != null) {
- pop.to = resolveAddress(pop.to);
- }
- if (pop.from != null) {
- const from = pop.from;
- pop.from = Promise.all([signer.getAddress(), resolveAddress(from)]).then(([address, from]) => {
- assertArgument(address.toLowerCase() === from.toLowerCase(), "transaction from mismatch", "tx.from", from);
- return address;
- });
- }
- else {
- pop.from = signer.getAddress();
- }
- return await resolveProperties(pop);
- }
- class AbstractSigner {
- provider;
- constructor(provider) {
- defineProperties(this, { provider: provider || null });
- }
- async getNonce(blockTag) {
- return checkProvider(this, "getTransactionCount").getTransactionCount(await this.getAddress(), blockTag);
- }
- async populateCall(tx) {
- const pop = await populate(this, tx);
- return pop;
- }
- async populateTransaction(tx) {
- const provider = checkProvider(this, "populateTransaction");
- const pop = await populate(this, tx);
- if (pop.nonce == null) {
- pop.nonce = await this.getNonce("pending");
- }
- if (pop.energyLimit == null) {
- pop.energyLimit = await this.estimateEnergy(pop);
- }
- // Populate the chain ID
- const network = await this.provider.getNetwork();
- if (pop.networkId != null) {
- const networkId = getBigInt(pop.networkId);
- assertArgument(networkId === network.networkId, "transaction networkId mismatch", "tx.networkId", tx.networkId);
- }
- else {
- pop.networkId = network.networkId;
- }
- // We need to get fee data to determine things
- const feeData = await provider.getFeeData();
- // We need to auto-detect the intended type of this transaction...
- if (feeData.energyPrice != null) {
- // Network doesn't support EIP-1559...
- // Populate missing fee data
- if (pop.energyPrice == null) {
- pop.energyPrice = feeData.energyPrice;
- }
- }
- else {
- // getFeeData has failed us.
- assert(false, "failed to get consistent fee data", "UNSUPPORTED_OPERATION", {
- operation: "signer.getFeeData",
- });
- }
- //@TOOD: Don't await all over the place; save them up for
- // the end for better batching
- return await resolveProperties(pop);
- }
- async estimateEnergy(tx) {
- return checkProvider(this, "estimateEnergy").estimateEnergy(await this.populateCall(tx));
- }
- async call(tx) {
- return checkProvider(this, "call").call(await this.populateCall(tx));
- }
- async resolveName(name) {
- return getAddress(name);
- }
- async sendTransaction(tx) {
- const provider = checkProvider(this, "sendTransaction");
- const pop = await this.populateTransaction(tx);
- delete pop.from;
- const txObj = Transaction.from(pop);
- return await provider.broadcastTransaction(await this.signTransaction(txObj));
- }
- }
- class VoidSigner extends AbstractSigner {
- address;
- constructor(address, provider) {
- super(provider);
- defineProperties(this, { address });
- }
- async getAddress() {
- return this.address;
- }
- connect(provider) {
- return new VoidSigner(this.address, provider);
- }
- #throwUnsupported(suffix, operation) {
- assert(false, `VoidSigner cannot sign ${suffix}`, "UNSUPPORTED_OPERATION", {
- operation,
- });
- }
- async signTransaction(tx) {
- this.#throwUnsupported("transactions", "signTransaction");
- }
- async signMessage(message) {
- this.#throwUnsupported("messages", "signMessage");
- }
- async signTypedData(domain, types, value) {
- this.#throwUnsupported("typed-data", "signTypedData");
- }
- }
-
- /**
- * There are many awesome community services that provide Core
- * nodes both for developers just starting out and for large-scale
- * communities.
- *
- * @_section: api/providers/thirdparty: Community Providers [thirdparty]
- */
- // Show the throttle message only once per service
- const shown = new Set();
- /**
- * Displays a warning in tht console when the community resource is
- * being used too heavily by the app, recommending the developer
- * acquire their own credentials instead of using the community
- * credentials.
- *
- * The notification will only occur once per service.
- */
- function showThrottleMessage(service) {
- if (shown.has(service)) {
- return;
- }
- shown.add(service);
- console.log("========= NOTICE =========");
- console.log(`Request-Rate Exceeded for ${service} (this message will not be repeated)`);
- console.log("");
- console.log("The default API keys for each service are provided as a highly-throttled,");
- console.log("community resource for low-traffic projects and early prototyping.");
- console.log("");
- console.log("While your application will continue to function, we highly recommended");
- console.log("signing up for your own API keys to improve performance, increase your");
- console.log("request rate/limit and enable other perks, such as metrics and advanced APIs.");
- console.log("");
- }
-
- function copy(obj) {
- return JSON.parse(JSON.stringify(obj));
- }
- /**
- * Some backends support subscribing to events using a Filter ID.
- *
- * When subscribing with this technique, the node issues a unique
- * //Filter ID//. At this point the node dedicates resources to
- * the filter, so that periodic calls to follow up on the //Filter ID//
- * will receive any events since the last call.
- *
- * @_docloc: api/providers/abstract-provider
- */
- class FilterIdSubscriber {
- #provider;
- #filterIdPromise;
- #poller;
- #running;
- #network;
- #hault;
- constructor(provider) {
- this.#provider = provider;
- this.#filterIdPromise = null;
- this.#poller = this.#poll.bind(this);
- this.#running = false;
- this.#network = null;
- this.#hault = false;
- }
- _subscribe(provider) {
- throw new Error("subclasses must override this");
- }
- _emitResults(provider, result) {
- throw new Error("subclasses must override this");
- }
- _recover(provider) {
- throw new Error("subclasses must override this");
- }
- async #poll(blockNumber) {
- try {
- // Subscribe if necessary
- if (this.#filterIdPromise == null) {
- this.#filterIdPromise = this._subscribe(this.#provider);
- }
- // Get the Filter ID
- let filterId = null;
- try {
- filterId = await this.#filterIdPromise;
- }
- catch (error) {
- if (!isError(error, "UNSUPPORTED_OPERATION") ||
- error.operation !== "xcb_newFilter") {
- throw error;
- }
- }
- // The backend does not support Filter ID; downgrade to
- // polling
- if (filterId == null) {
- this.#filterIdPromise = null;
- this.#provider._recoverSubscriber(this, this._recover(this.#provider));
- return;
- }
- const network = await this.#provider.getNetwork();
- if (!this.#network) {
- this.#network = network;
- }
- if (this.#network.networkId !== network.networkId) {
- throw new Error("chaid changed");
- }
- if (this.#hault) {
- return;
- }
- const result = await this.#provider.send("xcb_getFilterChanges", [
- filterId,
- ]);
- await this._emitResults(this.#provider, result);
- }
- catch (error) {
- console.log("@TODO", error);
- }
- this.#provider.once("block", this.#poller);
- }
- #teardown() {
- const filterIdPromise = this.#filterIdPromise;
- if (filterIdPromise) {
- this.#filterIdPromise = null;
- filterIdPromise.then((filterId) => {
- this.#provider.send("xcb_uninstallFilter", [filterId]);
- });
- }
- }
- start() {
- if (this.#running) {
- return;
- }
- this.#running = true;
- this.#poll(-2);
- }
- stop() {
- if (!this.#running) {
- return;
- }
- this.#running = false;
- this.#hault = true;
- this.#teardown();
- this.#provider.off("block", this.#poller);
- }
- pause(dropWhilePaused) {
- if (dropWhilePaused) {
- this.#teardown();
- }
- this.#provider.off("block", this.#poller);
- }
- resume() {
- this.start();
- }
- }
- /**
- * A **FilterIdSubscriber** for receiving contract events.
- *
- * @_docloc: api/providers/abstract-provider
- */
- class FilterIdEventSubscriber extends FilterIdSubscriber {
- #event;
- constructor(provider, filter) {
- super(provider);
- this.#event = copy(filter);
- }
- _recover(provider) {
- return new PollingEventSubscriber(provider, this.#event);
- }
- async _subscribe(provider) {
- const filterId = await provider.send("xcb_newFilter", [this.#event]);
- return filterId;
- }
- async _emitResults(provider, results) {
- for (const result of results) {
- provider.emit(this.#event, provider._wrapLog(result, provider._network));
- }
- }
- }
- /**
- * A **FilterIdSubscriber** for receiving pending transactions events.
- *
- * @_docloc: api/providers/abstract-provider
- */
- class FilterIdPendingSubscriber extends FilterIdSubscriber {
- async _subscribe(provider) {
- return await provider.send("xcb_newPendingTransactionFilter", []);
- }
- async _emitResults(provider, results) {
- for (const result of results) {
- provider.emit("pending", result);
- }
- }
- }
-
- /**
- * About JSON-RPC...
- *
- * @_section: api/providers/jsonrpc:JSON-RPC Provider [about-jsonrpcProvider]
- */
- // @TODO:
- // - Add the batching API
- const Primitive = "bigint,boolean,function,number,string,symbol".split(/,/g);
- //const Methods = "getAddress,then".split(/,/g);
- function deepCopy(value) {
- if (value == null || Primitive.indexOf(typeof value) >= 0) {
- return value;
- }
- // Keep any Addressable
- if (typeof value.getAddress === "function") {
- return value;
- }
- if (Array.isArray(value)) {
- return value.map(deepCopy);
- }
- if (typeof value === "object") {
- return Object.keys(value).reduce((accum, key) => {
- accum[key] = value[key];
- return accum;
- }, {});
- }
- throw new Error(`should not happen: ${value} (${typeof value})`);
- }
- function stall$3(duration) {
- return new Promise((resolve) => {
- setTimeout(resolve, duration);
- });
- }
- function getLowerCase(value) {
- if (value) {
- return value.toLowerCase();
- }
- return value;
- }
- function isPollable(value) {
- return value && typeof value.pollingInterval === "number";
- }
- const defaultOptions = {
- polling: false,
- staticNetwork: null,
- batchStallTime: 10,
- batchMaxSize: 1 << 20,
- batchMaxCount: 100, // 100 requests
- };
- // @TODO: Unchecked Signers
- class JsonRpcSigner extends AbstractSigner {
- address;
- constructor(provider, address) {
- super(provider);
- address = getAddress(address);
- defineProperties(this, { address });
- }
- connect(provider) {
- assert(false, "cannot reconnect JsonRpcSigner", "UNSUPPORTED_OPERATION", {
- operation: "signer.connect",
- });
- }
- async getAddress() {
- return this.address;
- }
- // JSON-RPC will automatially fill in nonce, etc. so we just check from
- async populateTransaction(tx) {
- return await this.populateCall(tx);
- }
- // Returns just the hash of the transaction after sent, which is what
- // the bare JSON-RPC API does;
- async sendUncheckedTransaction(_tx) {
- const tx = deepCopy(_tx);
- const promises = [];
- // Make sure the from matches the sender
- if (tx.from) {
- const _from = tx.from;
- promises.push((async () => {
- const from = await resolveAddress(_from);
- assertArgument(from != null && from.toLowerCase() === this.address.toLowerCase(), "from address mismatch", "transaction", _tx);
- tx.from = from;
- })());
- }
- else {
- tx.from = this.address;
- }
- // The JSON-RPC for xcb_sendTransaction uses 90000 energy; if the user
- // wishes to use this, it is easy to specify explicitly, otherwise
- // we look it up for them.
- if (tx.energyLimit == null) {
- promises.push((async () => {
- tx.energyLimit = await this.provider.estimateEnergy({
- ...tx,
- from: this.address,
- });
- })());
- }
- // The address may be an ENS name or Addressable
- if (tx.to != null) {
- const _to = tx.to;
- promises.push((async () => {
- tx.to = await resolveAddress(_to);
- })());
- }
- // Wait until all of our properties are filled in
- if (promises.length) {
- await Promise.all(promises);
- }
- const hexTx = this.provider.getRpcTransaction(tx);
- return this.provider.send("xcb_sendTransaction", [hexTx]);
- }
- async sendTransaction(tx) {
- // This cannot be mined any earlier than any recent block
- const blockNumber = await this.provider.getBlockNumber();
- // Send the transaction
- const hash = await this.sendUncheckedTransaction(tx);
- // Unfortunately, JSON-RPC only provides and opaque transaction hash
- // for a response, and we need the actual transaction, so we poll
- // for it; it should show up very quickly
- return await new Promise((resolve, reject) => {
- const timeouts = [1000, 100];
- const checkTx = async () => {
- // Try getting the transaction
- const tx = await this.provider.getTransaction(hash);
- if (tx != null) {
- resolve(tx.replaceableTransaction(blockNumber));
- return;
- }
- // Wait another 4 seconds
- this.provider._setTimeout(() => {
- checkTx();
- }, timeouts.pop() || 4000);
- };
- checkTx();
- });
- }
- async signTransaction(_tx) {
- const tx = deepCopy(_tx);
- // Make sure the from matches the sender
- if (tx.from) {
- const from = await resolveAddress(tx.from);
- assertArgument(from != null && from.toLowerCase() === this.address.toLowerCase(), "from address mismatch", "transaction", _tx);
- tx.from = from;
- }
- else {
- tx.from = this.address;
- }
- const hexTx = this.provider.getRpcTransaction(tx);
- return await this.provider.send("xcb_signTransaction", [hexTx]);
- }
- async signMessage(_message) {
- const message = typeof _message === "string" ? toUtf8Bytes(_message) : _message;
- return await this.provider.send("personal_sign", [
- hexlify(message),
- this.address.toLowerCase(),
- ]);
- }
- async signTypedData(domain, types, _value) {
- const value = deepCopy(_value);
- // Populate any ENS names (in-place)
- const populated = await TypedDataEncoder.resolveNames(domain, types, value, async (value) => {
- const address = await resolveAddress(value);
- assertArgument(address != null, "TypedData does not support null address", "value", value);
- return address;
- });
- return await this.provider.send("xcb_signTypedData_v4", [
- this.address.toLowerCase(),
- JSON.stringify(TypedDataEncoder.getPayload(populated.domain, types, populated.value)),
- ]);
- }
- async unlock(password) {
- return this.provider.send("personal_unlockAccount", [
- this.address.toLowerCase(),
- password,
- null,
- ]);
- }
- async _legacySignMessage(_message) {
- const message = typeof _message === "string" ? toUtf8Bytes(_message) : _message;
- return await this.provider.send("xcb_sign", [
- this.address.toLowerCase(),
- hexlify(message),
- ]);
- }
- }
- /**
- * The JsonRpcApiProvider is an abstract class and **MUST** be
- * sub-classed.
- *
- * It provides the base for all JSON-RPC-based Provider interaction.
- *
- * Sub-classing Notes:
- * - a sub-class MUST override _send
- * - a sub-class MUST call the `_start()` method once connected
- */
- class JsonRpcApiProvider extends AbstractProvider {
- #options;
- // The next ID to use for the JSON-RPC ID field
- #nextId;
- // Payloads are queued and triggered in batches using the drainTimer
- #payloads;
- #drainTimer;
- #notReady;
- #network;
- #scheduleDrain() {
- if (this.#drainTimer) {
- return;
- }
- // If we aren't using batching, no hard in sending it immeidately
- const stallTime = this._getOption("batchMaxCount") === 1
- ? 0
- : this._getOption("batchStallTime");
- this.#drainTimer = setTimeout(() => {
- this.#drainTimer = null;
- const payloads = this.#payloads;
- this.#payloads = [];
- while (payloads.length) {
- // Create payload batches that satisfy our batch constraints
- const batch = [payloads.shift()];
- while (payloads.length) {
- if (batch.length === this.#options.batchMaxCount) {
- break;
- }
- batch.push(payloads.shift());
- const bytes = JSON.stringify(batch.map((p) => p.payload));
- if (bytes.length > this.#options.batchMaxSize) {
- payloads.unshift(batch.pop());
- break;
- }
- }
- // Process the result to each payload
- (async () => {
- const payload = batch.length === 1 ? batch[0].payload : batch.map((p) => p.payload);
- this.emit("debug", { action: "sendRpcPayload", payload });
- try {
- // console.log({payload})
- const result = await this._send(payload);
- // console.log({result})
- this.emit("debug", { action: "receiveRpcResult", result });
- // Process results in batch order
- for (const { resolve, reject, payload } of batch) {
- // Find the matching result
- const resp = result.filter((r) => r.id === payload.id)[0];
- // No result; the node failed us in unexpected ways
- if (resp == null) {
- return reject(makeError("no response from server", "BAD_DATA", {
- value: result,
- info: { payload },
- }));
- }
- // The response is an error
- if ("error" in resp) {
- return reject(this.getRpcError(payload, resp));
- }
- // All good; send the result
- resolve(resp.result);
- }
- }
- catch (error) {
- this.emit("debug", { action: "receiveRpcError", error });
- for (const { reject } of batch) {
- // @TODO: augment the error with the payload
- reject(error);
- }
- }
- })();
- }
- }, stallTime);
- }
- constructor(network, options) {
- super(network);
- this.#nextId = 1;
- this.#options = Object.assign({}, defaultOptions, options || {});
- this.#payloads = [];
- this.#drainTimer = null;
- this.#network = null;
- {
- let resolve = null;
- const promise = new Promise((_resolve) => {
- resolve = _resolve;
- });
- this.#notReady = { promise, resolve };
- }
- // Make sure any static network is compatbile with the provided netwrok
- const staticNetwork = this._getOption("staticNetwork");
- if (staticNetwork) {
- assertArgument(network == null || staticNetwork.matches(network), "staticNetwork MUST match network object", "options", options);
- this.#network = staticNetwork;
- }
- }
- /**
- * Returns the value associated with the option %%key%%.
- *
- * Sub-classes can use this to inquire about configuration options.
- */
- _getOption(key) {
- return this.#options[key];
- }
- /**
- * Gets the [[Network]] this provider has committed to. On each call, the network
- * is detected, and if it has changed, the call will reject.
- */
- get _network() {
- assert(this.#network, "network is not available yet", "NETWORK_ERROR");
- return this.#network;
- }
- /*
- {
- assert(false, "sub-classes must override _send", "UNSUPPORTED_OPERATION", {
- operation: "jsonRpcApiProvider._send"
- });
- }
- */
- /**
- * Resolves to the non-normalized value by performing %%req%%.
- *
- * Sub-classes may override this to modify behavior of actions,
- * and should generally call ``super._perform`` as a fallback.
- */
- async _perform(req) {
- const request = this.getRpcRequest(req);
- if (request != null) {
- return await this.send(request.method, request.args);
- }
- return super._perform(req);
- }
- /**
- * Sub-classes may override this; it detects the *actual* network that
- * we are **currently** connected to.
- *
- * Keep in mind that [[send]] may only be used once [[ready]], otherwise the
- * _send primitive must be used instead.
- */
- async _detectNetwork() {
- const network = this._getOption("staticNetwork");
- if (network) {
- return network;
- }
- // If we are ready, use ``send``, which enabled requests to be batched
- if (this.ready) {
- return Network.from(getBigInt(await this.send("xcb_networkId", [])));
- }
- // We are not ready yet; use the primitive _send
- const payload = {
- id: this.#nextId++,
- method: "xcb_networkId",
- params: [],
- jsonrpc: "2.0",
- };
- this.emit("debug", { action: "sendRpcPayload", payload });
- let result;
- try {
- result = (await this._send(payload))[0];
- }
- catch (error) {
- this.emit("debug", { action: "receiveRpcError", error });
- throw error;
- }
- this.emit("debug", { action: "receiveRpcResult", result });
- if ("result" in result) {
- return Network.from(getBigInt(result.result));
- }
- throw this.getRpcError(payload, result);
- }
- /**
- * Sub-classes **MUST** call this. Until [[_start]] has been called, no calls
- * will be passed to [[_send]] from [[send]]. If it is overridden, then
- * ``super._start()`` **MUST** be called.
- *
- * Calling it multiple times is safe and has no effect.
- */
- _start() {
- if (this.#notReady == null || this.#notReady.resolve == null) {
- return;
- }
- this.#notReady.resolve();
- this.#notReady = null;
- (async () => {
- // Bootstrap the network
- while (this.#network == null) {
- try {
- this.#network = await this._detectNetwork();
- }
- catch (error) {
- console.log("JsonRpcProvider failed to startup; retry in 1s");
- await stall$3(1000);
- }
- }
- // Start dispatching requests
- this.#scheduleDrain();
- })();
- }
- /**
- * Resolves once the [[_start]] has been called. This can be used in
- * sub-classes to defer sending data until the connection has been
- * established.
- */
- async _waitUntilReady() {
- if (this.#notReady == null) {
- return;
- }
- return await this.#notReady.promise;
- }
- /**
- * Return a Subscriber that will manage the %%sub%%.
- *
- * Sub-classes may override this to modify the behavior of
- * subscription management.
- */
- _getSubscriber(sub) {
- // Pending Filters aren't availble via polling
- if (sub.type === "pending") {
- return new FilterIdPendingSubscriber(this);
- }
- if (sub.type === "event") {
- if (this._getOption("polling")) {
- return new PollingEventSubscriber(this, sub.filter);
- }
- return new FilterIdEventSubscriber(this, sub.filter);
- }
- // Orphaned Logs are handled automatically, by the filter, since
- // logs with removed are emitted by it
- if (sub.type === "orphan" && sub.filter.orphan === "drop-log") {
- return new UnmanagedSubscriber("orphan");
- }
- return super._getSubscriber(sub);
- }
- /**
- * Returns true only if the [[_start]] has been called.
- */
- get ready() {
- return this.#notReady == null;
- }
- /**
- * Returns %%tx%% as a normalized JSON-RPC transaction request,
- * which has all values hexlified and any numeric values converted
- * to Quantity values.
- */
- getRpcTransaction(tx) {
- const result = {};
- // JSON-RPC now requires numeric values to be "quantity" values
- [
- "networkId",
- "energyLimit",
- "energyPrice",
- "type",
- "nonce",
- "value",
- ].forEach((key) => {
- if (tx[key] == null) {
- return;
- }
- let dstKey = key;
- if (key === "energyLimit") {
- dstKey = "energy";
- }
- result[dstKey] = toQuantity(getBigInt(tx[key], `tx.${key}`));
- });
- // Make sure addresses and data are lowercase
- ["from", "to", "data"].forEach((key) => {
- if (tx[key] == null) {
- return;
- }
- result[key] = hexlify(tx[key]);
- });
- return result;
- }
- /**
- * Returns the request method and arguments required to perform
- * %%req%%.
- */
- getRpcRequest(req) {
- switch (req.method) {
- case "networkId":
- return { method: "xcb_networkId", args: [] };
- case "getBlockNumber":
- return { method: "xcb_blockNumber", args: [] };
- case "getEnergyPrice":
- return { method: "xcb_energyPrice", args: [] };
- case "getBalance": {
- return {
- method: "xcb_getBalance",
- args: [getLowerCase(req.address), req.blockTag],
- };
- }
- case "getTransactionCount":
- return {
- method: "xcb_getTransactionCount",
- args: [getLowerCase(req.address), req.blockTag],
- };
- case "getCode":
- return {
- method: "xcb_getCode",
- args: [getLowerCase(req.address), req.blockTag],
- };
- case "getStorage":
- return {
- method: "xcb_getStorageAt",
- args: [
- getLowerCase(req.address),
- "0x" + req.position.toString(16),
- req.blockTag,
- ],
- };
- case "broadcastTransaction":
- return {
- method: "xcb_sendRawTransaction",
- args: [req.signedTransaction],
- };
- case "getBlock":
- if ("blockTag" in req) {
- return {
- method: "xcb_getBlockByNumber",
- args: [req.blockTag, !!req.includeTransactions],
- };
- }
- else if ("blockHash" in req) {
- return {
- method: "xcb_getBlockByHash",
- args: [req.blockHash, !!req.includeTransactions],
- };
- }
- break;
- case "getTransaction":
- return {
- method: "xcb_getTransactionByHash",
- args: [req.hash],
- };
- case "getTransactionReceipt":
- return {
- method: "xcb_getTransactionReceipt",
- args: [req.hash],
- };
- case "call":
- return {
- method: "xcb_call",
- args: [this.getRpcTransaction(req.transaction), req.blockTag],
- };
- case "estimateEnergy": {
- return {
- method: "xcb_estimateEnergy",
- args: [this.getRpcTransaction(req.transaction)],
- };
- }
- case "getLogs":
- if (req.filter && req.filter.address != null) {
- if (Array.isArray(req.filter.address)) {
- req.filter.address = req.filter.address.map(getLowerCase);
- }
- else {
- req.filter.address = getLowerCase(req.filter.address);
- }
- }
- return { method: "xcb_getLogs", args: [req.filter] };
- }
- return null;
- }
- /**
- * Returns an CoreBC-style Error for the given JSON-RPC error
- * %%payload%%, coalescing the various strings and error shapes
- * that different nodes return, coercing them into a machine-readable
- * standardized error.
- */
- getRpcError(payload, _error) {
- const { method } = payload;
- const { error } = _error;
- if (method === "xcb_estimateEnergy" && error.message) {
- const msg = error.message;
- if (!msg.match(/revert/i) && msg.match(/insufficient funds/i)) {
- return makeError("insufficient funds", "INSUFFICIENT_FUNDS", {
- transaction: payload.params[0],
- info: { payload, error },
- });
- }
- }
- if (method === "xcb_call" || method === "xcb_estimateEnergy") {
- const result = spelunkData(error);
- const e = AbiCoder.getBuiltinCallException(method === "xcb_call" ? "call" : "estimateEnergy", payload.params[0], result ? result.data : null);
- e.info = { error, payload };
- return e;
- }
- // Only estimateEnergy and call can return arbitrary contract-defined text, so now we
- // we can process text safely.
- const message = JSON.stringify(spelunkMessage(error));
- if (typeof error.message === "string" &&
- error.message.match(/user denied|corebc-user-denied/i)) {
- const actionMap = {
- xcb_sign: "signMessage",
- personal_sign: "signMessage",
- xcb_signTypedData_v4: "signTypedData",
- xcb_signTransaction: "signTransaction",
- xcb_sendTransaction: "sendTransaction",
- xcb_requestAccounts: "requestAccess",
- wallet_requestAccounts: "requestAccess",
- };
- return makeError(`user rejected action`, "ACTION_REJECTED", {
- action: actionMap[method] || "unknown",
- reason: "rejected",
- info: { payload, error },
- });
- }
- if (method === "xcb_sendRawTransaction" ||
- method === "xcb_sendTransaction") {
- const transaction = payload.params[0];
- if (message.match(/insufficient funds|base fee exceeds energy limit/i)) {
- return makeError("insufficient funds for intrinsic transaction cost", "INSUFFICIENT_FUNDS", {
- transaction,
- info: { error },
- });
- }
- if (message.match(/nonce/i) && message.match(/too low/i)) {
- return makeError("nonce has already been used", "NONCE_EXPIRED", {
- transaction,
- info: { error },
- });
- }
- // "replacement transaction underpriced"
- if (message.match(/replacement transaction/i) &&
- message.match(/underpriced/i)) {
- return makeError("replacement fee too low", "REPLACEMENT_UNDERPRICED", {
- transaction,
- info: { error },
- });
- }
- if (message.match(/only replay-protected/i)) {
- return makeError("legacy pre-eip-155 transactions not supported", "UNSUPPORTED_OPERATION", {
- operation: method,
- info: { transaction, info: { error } },
- });
- }
- }
- if (message.match(/the method .* does not exist/i)) {
- return makeError("unsupported operation", "UNSUPPORTED_OPERATION", {
- operation: payload.method,
- info: { error },
- });
- }
- return makeError("could not coalesce error", "UNKNOWN_ERROR", { error });
- }
- /**
- * Requests the %%method%% with %%params%% via the JSON-RPC protocol
- * over the underlying channel. This can be used to call methods
- * on the backend that do not have a high-level API within the Provider
- * API.
- *
- * This method queues requests according to the batch constraints
- * in the options, assigns the request a unique ID.
- *
- * **Do NOT override** this method in sub-classes; instead
- * override [[_send]] or force the options values in the
- * call to the constructor to modify this method's behavior.
- */
- send(method, params) {
- // @TODO: cache networkId?? purge on switch_networks
- const id = this.#nextId++;
- const promise = new Promise((resolve, reject) => {
- this.#payloads.push({
- resolve,
- reject,
- payload: { method, params, id, jsonrpc: "2.0" },
- });
- });
- // If there is not a pending drainTimer, set one
- this.#scheduleDrain();
- return promise;
- }
- /**
- * Resolves to the [[Signer]] account for %%address%% managed by
- * the client.
- *
- * If the %%address%% is a number, it is used as an index in the
- * the accounts from [[listAccounts]].
- *
- * This can only be used on clients which manage accounts (such as
- * Geth with imported account or MetaMask).
- *
- * Throws if the account doesn't exist.
- */
- async getSigner(address) {
- if (address == null) {
- address = 0;
- }
- const accountsPromise = this.send("xcb_accounts", []);
- // Account index
- if (typeof address === "number") {
- const accounts = await accountsPromise;
- if (address >= accounts.length) {
- throw new Error("no such account");
- }
- return new JsonRpcSigner(this, accounts[address]);
- }
- const { accounts } = await resolveProperties({
- network: this.getNetwork(),
- accounts: accountsPromise,
- });
- // Account address
- address = getAddress(address);
- for (const account of accounts) {
- if (getAddress(account) === address) {
- return new JsonRpcSigner(this, address);
- }
- }
- throw new Error("invalid account");
- }
- async listAccounts() {
- const accounts = await this.send("xcb_accounts", []);
- return accounts.map((a) => new JsonRpcSigner(this, a));
- }
- }
- class JsonRpcApiPollingProvider extends JsonRpcApiProvider {
- #pollingInterval;
- constructor(network, options) {
- super(network, options);
- this.#pollingInterval = 4000;
- }
- _getSubscriber(sub) {
- const subscriber = super._getSubscriber(sub);
- if (isPollable(subscriber)) {
- subscriber.pollingInterval = this.#pollingInterval;
- }
- return subscriber;
- }
- /**
- * The polling interval (default: 4000 ms)
- */
- get pollingInterval() {
- return this.#pollingInterval;
- }
- set pollingInterval(value) {
- if (!Number.isInteger(value) || value < 0) {
- throw new Error("invalid interval");
- }
- this.#pollingInterval = value;
- this._forEachSubscriber((sub) => {
- if (isPollable(sub)) {
- sub.pollingInterval = this.#pollingInterval;
- }
- });
- }
- }
- /**
- * The JsonRpcProvider is one of the most common Providers,
- * which performs all operations over HTTP (or HTTPS) requests.
- *
- * Events are processed by polling the backend for the current block
- * number; when it advances, all block-base events are then checked
- * for updates.
- */
- class JsonRpcProvider extends JsonRpcApiPollingProvider {
- #connect;
- constructor(url, network, options) {
- if (url == null) {
- url = "http://localhost:8545";
- }
- super(network, options);
- if (typeof url === "string") {
- this.#connect = new FetchRequest(url);
- }
- else {
- this.#connect = url.clone();
- }
- }
- _getConnection() {
- return this.#connect.clone();
- }
- async send(method, params) {
- // All requests are over HTTP, so we can just start handling requests
- // We do this here rather than the constructor so that we don't send any
- // requests to the network (i.e. xcb_networkId) until we absolutely have to.
- await this._start();
- return await super.send(method, params);
- }
- async _send(payload) {
- // Configure a POST connection for the requested method
- const request = this._getConnection();
- request.body = JSON.stringify(payload);
- request.setHeader("content-type", "application/json");
- const response = await request.send();
- response.assertOk();
- let resp = response.bodyJson;
- if (!Array.isArray(resp)) {
- resp = [resp];
- }
- return resp;
- }
- }
- function spelunkData(value) {
- if (value == null) {
- return null;
- }
- // These *are* the droids we're looking for.
- if (typeof value.message === "string" &&
- value.message.match("reverted") &&
- isHexString(value.data)) {
- return { message: value.message, data: value.data };
- }
- // Spelunk further...
- if (typeof value === "object") {
- for (const key in value) {
- const result = spelunkData(value[key]);
- if (result) {
- return result;
- }
- }
- return null;
- }
- // Might be a JSON string we can further descend...
- if (typeof value === "string") {
- try {
- return spelunkData(JSON.parse(value));
- }
- catch (error) { }
- }
- return null;
- }
- function _spelunkMessage(value, result) {
- if (value == null) {
- return;
- }
- // These *are* the droids we're looking for.
- if (typeof value.message === "string") {
- result.push(value.message);
- }
- // Spelunk further...
- if (typeof value === "object") {
- for (const key in value) {
- _spelunkMessage(value[key], result);
- }
- }
- // Might be a JSON string we can further descend...
- if (typeof value === "string") {
- try {
- return _spelunkMessage(JSON.parse(value), result);
- }
- catch (error) { }
- }
- }
- function spelunkMessage(value) {
- const result = [];
- _spelunkMessage(value, result);
- return result;
- }
-
- /**
- * [[link-ankr]] provides a third-party service for connecting to
- * various blockchains over JSON-RPC.
- *
- * **Supported Networks**
- *
- * - Core Mainnet (``mainnet``)
- * - Goerli Testnet (``goerli``)
- * - Polygon (``matic``)
- * - Arbitrum (``arbitrum``)
- *
- * @_subsection: api/providers/thirdparty:Ankr [providers-ankr]
- */
- const defaultApiKey$1 = "9f7d929b018cdffb338517efa06f58359e86ff1ffd350bc889738523659e7972";
- function getHost$4(name) {
- switch (name) {
- case "mainnet":
- return "rpc.ankr.com/eth";
- case "goerli":
- return "rpc.ankr.com/xcb_goerli";
- case "matic":
- return "rpc.ankr.com/polygon";
- case "arbitrum":
- return "rpc.ankr.com/arbitrum";
- }
- assertArgument(false, "unsupported network", "network", name);
- }
- /**
- * The **AnkrProvider** connects to the [[link-ankr]]
- * JSON-RPC end-points.
- *
- * By default, a highly-throttled API key is used, which is
- * appropriate for quick prototypes and simple scripts. To
- * gain access to an increased rate-limit, it is highly
- * recommended to [sign up here](link-ankr-signup).
- */
- class AnkrProvider extends JsonRpcProvider {
- /**
- * The API key for the Ankr connection.
- */
- apiKey;
- /**
- * Create a new **AnkrProvider**.
- *
- * By default connecting to ``mainnet`` with a highly throttled
- * API key.
- */
- constructor(_network, apiKey) {
- if (_network == null) {
- _network = "mainnet";
- }
- const network = Network.from(_network);
- if (apiKey == null) {
- apiKey = defaultApiKey$1;
- }
- // Ankr does not support filterId, so we force polling
- const options = { polling: true, staticNetwork: network };
- const request = AnkrProvider.getRequest(network, apiKey);
- super(request, network, options);
- defineProperties(this, { apiKey });
- }
- _getProvider(networkId) {
- try {
- return new AnkrProvider(networkId, this.apiKey);
- }
- catch (error) { }
- return super._getProvider(networkId);
- }
- /**
- * Returns a prepared request for connecting to %%network%% with
- * %%apiKey%%.
- */
- static getRequest(network, apiKey) {
- if (apiKey == null) {
- apiKey = defaultApiKey$1;
- }
- const request = new FetchRequest(`https:/\/${getHost$4(network.name)}/${apiKey}`);
- request.allowGzip = true;
- if (apiKey === defaultApiKey$1) {
- request.retryFunc = async (request, response, attempt) => {
- showThrottleMessage("AnkrProvider");
- return true;
- };
- }
- return request;
- }
- getRpcError(payload, error) {
- if (payload.method === "xcb_sendRawTransaction") {
- if (error &&
- error.error &&
- error.error.message === "INTERNAL_ERROR: could not replace existing tx") {
- error.error.message = "replacement transaction underpriced";
- }
- }
- return super.getRpcError(payload, error);
- }
- isCommunityResource() {
- return this.apiKey === defaultApiKey$1;
- }
- }
-
- /**
- * About Alchemy
- *
- * @_subsection: api/providers/thirdparty:Alchemy [providers-alchemy]
- */
- const defaultApiKey = "_gg7wSSi0KMBsdKnGVfHDueq6xMB9EkC";
- function getHost$3(name) {
- switch (name) {
- case "mainnet":
- return "eth-mainnet.alchemyapi.io";
- case "goerli":
- return "eth-goerli.g.alchemy.com";
- case "sepolia":
- return "eth-sepolia.g.alchemy.com";
- case "arbitrum":
- return "arb-mainnet.g.alchemy.com";
- case "arbitrum-goerli":
- return "arb-goerli.g.alchemy.com";
- case "matic":
- return "polygon-mainnet.g.alchemy.com";
- case "matic-mumbai":
- return "polygon-mumbai.g.alchemy.com";
- case "optimism":
- return "opt-mainnet.g.alchemy.com";
- case "optimism-goerli":
- return "opt-goerli.g.alchemy.com";
- }
- assertArgument(false, "unsupported network", "network", name);
- }
- /**
- * The **AlchemyProvider** connects to the [[link-alchemy]]
- * JSON-RPC end-points.
- *
- * By default, a highly-throttled API key is used, which is
- * appropriate for quick prototypes and simple scripts. To
- * gain access to an increased rate-limit, it is highly
- * recommended to [sign up here](link-alchemy-signup).
- *
- * @_docloc: api/providers/thirdparty
- */
- class AlchemyProvider extends JsonRpcProvider {
- apiKey;
- constructor(_network, apiKey) {
- if (_network == null) {
- _network = "mainnet";
- }
- const network = Network.from(_network);
- if (apiKey == null) {
- apiKey = defaultApiKey;
- }
- const request = AlchemyProvider.getRequest(network, apiKey);
- super(request, network, { staticNetwork: network });
- defineProperties(this, { apiKey });
- }
- _getProvider(networkId) {
- try {
- return new AlchemyProvider(networkId, this.apiKey);
- }
- catch (error) { }
- return super._getProvider(networkId);
- }
- async _perform(req) {
- // https://docs.alchemy.com/reference/trace-transaction
- if (req.method === "getTransactionResult") {
- const { trace, tx } = await resolveProperties({
- trace: this.send("trace_transaction", [req.hash]),
- tx: this.getTransaction(req.hash),
- });
- if (trace == null || tx == null) {
- return null;
- }
- let data;
- let error = false;
- try {
- data = trace[0].result.output;
- error = trace[0].error === "Reverted";
- }
- catch (error) { }
- if (data) {
- assert(!error, "an error occurred during transaction executions", "CALL_EXCEPTION", {
- action: "getTransactionResult",
- data,
- reason: null,
- transaction: tx,
- invocation: null,
- revert: null, // @TODO
- });
- return data;
- }
- assert(false, "could not parse trace result", "BAD_DATA", {
- value: trace,
- });
- }
- return await super._perform(req);
- }
- isCommunityResource() {
- return this.apiKey === defaultApiKey;
- }
- static getRequest(network, apiKey) {
- if (apiKey == null) {
- apiKey = defaultApiKey;
- }
- const request = new FetchRequest(`https:/\/${getHost$3(network.name)}/v2/${apiKey}`);
- request.allowGzip = true;
- if (apiKey === defaultApiKey) {
- request.retryFunc = async (request, response, attempt) => {
- showThrottleMessage("alchemy");
- return true;
- };
- }
- return request;
- }
- }
-
- /**
- * About Cloudflare
- *
- * @_subsection: api/providers/thirdparty:Cloudflare [providers-cloudflare]
- */
- /**
- * About Cloudflare...
- */
- class CloudflareProvider extends JsonRpcProvider {
- constructor(_network) {
- if (_network == null) {
- _network = "mainnet";
- }
- const network = Network.from(_network);
- assertArgument(network.name === "mainnet", "unsupported network", "network", _network);
- super("https://cloudflare-eth.com/", network, { staticNetwork: network });
- }
- }
-
- function getGlobal() {
- if (typeof self !== "undefined") {
- return self;
- }
- if (typeof window !== "undefined") {
- return window;
- }
- if (typeof global !== "undefined") {
- return global;
- }
- throw new Error("unable to locate global object");
- }
- const _WebSocket = getGlobal().WebSocket;
-
- /**
- * Generic long-lived socket provider.
- *
- * Sub-classing notes
- * - a sub-class MUST call the `_start()` method once connected
- * - a sub-class MUST override the `_write(string)` method
- * - a sub-class MUST call `_processMessage(string)` for each message
- *
- * @_subsection: api/providers/abstract-provider
- */
- class SocketSubscriber {
- #provider;
- #filter;
- get filter() {
- return JSON.parse(this.#filter);
- }
- #filterId;
- #paused;
- #emitPromise;
- constructor(provider, filter) {
- this.#provider = provider;
- this.#filter = JSON.stringify(filter);
- this.#filterId = null;
- this.#paused = null;
- this.#emitPromise = null;
- }
- start() {
- this.#filterId = this.#provider
- .send("xcb_subscribe", this.filter)
- .then((filterId) => {
- this.#provider._register(filterId, this);
- return filterId;
- });
- }
- stop() {
- this.#filterId.then((filterId) => {
- this.#provider.send("xcb_unsubscribe", [filterId]);
- });
- this.#filterId = null;
- }
- // @TODO: pause should trap the current blockNumber, unsub, and on resume use getLogs
- // and resume
- pause(dropWhilePaused) {
- assert(dropWhilePaused, "preserve logs while paused not supported by SocketSubscriber yet", "UNSUPPORTED_OPERATION", { operation: "pause(false)" });
- this.#paused = !!dropWhilePaused;
- }
- resume() {
- this.#paused = null;
- }
- _handleMessage(message) {
- if (this.#filterId == null) {
- return;
- }
- if (this.#paused === null) {
- let emitPromise = this.#emitPromise;
- if (emitPromise == null) {
- emitPromise = this._emit(this.#provider, message);
- }
- else {
- emitPromise = emitPromise.then(async () => {
- await this._emit(this.#provider, message);
- });
- }
- this.#emitPromise = emitPromise.then(() => {
- if (this.#emitPromise === emitPromise) {
- this.#emitPromise = null;
- }
- });
- }
- }
- async _emit(provider, message) {
- throw new Error("sub-classes must implemente this; _emit");
- }
- }
- class SocketBlockSubscriber extends SocketSubscriber {
- constructor(provider) {
- super(provider, ["newHeads"]);
- }
- async _emit(provider, message) {
- provider.emit("block", parseInt(message.number));
- }
- }
- class SocketPendingSubscriber extends SocketSubscriber {
- constructor(provider) {
- super(provider, ["newPendingTransactions"]);
- }
- async _emit(provider, message) {
- provider.emit("pending", message);
- }
- }
- class SocketEventSubscriber extends SocketSubscriber {
- #logFilter;
- get logFilter() {
- return JSON.parse(this.#logFilter);
- }
- constructor(provider, filter) {
- super(provider, ["logs", filter]);
- this.#logFilter = JSON.stringify(filter);
- }
- async _emit(provider, message) {
- provider.emit(this.logFilter, provider._wrapLog(message, provider._network));
- }
- }
- /**
- * SocketProvider...
- *
- */
- class SocketProvider extends JsonRpcApiProvider {
- #callbacks;
- // Maps each filterId to its subscriber
- #subs;
- // If any events come in before a subscriber has finished
- // registering, queue them
- #pending;
- constructor(network) {
- super(network, { batchMaxCount: 1 });
- this.#callbacks = new Map();
- this.#subs = new Map();
- this.#pending = new Map();
- }
- // This value is only valid after _start has been called
- /*
- get _network(): Network {
- if (this.#network == null) {
- throw new Error("this shouldn't happen");
- }
- return this.#network.clone();
- }
- */
- _getSubscriber(sub) {
- switch (sub.type) {
- case "close":
- return new UnmanagedSubscriber("close");
- case "block":
- return new SocketBlockSubscriber(this);
- case "pending":
- return new SocketPendingSubscriber(this);
- case "event":
- return new SocketEventSubscriber(this, sub.filter);
- case "orphan":
- // Handled auto-matically within AbstractProvider
- // when the log.removed = true
- if (sub.filter.orphan === "drop-log") {
- return new UnmanagedSubscriber("drop-log");
- }
- }
- return super._getSubscriber(sub);
- }
- _register(filterId, subscriber) {
- this.#subs.set(filterId, subscriber);
- const pending = this.#pending.get(filterId);
- if (pending) {
- for (const message of pending) {
- subscriber._handleMessage(message);
- }
- this.#pending.delete(filterId);
- }
- }
- async _send(payload) {
- // WebSocket provider doesn't accept batches
- assertArgument(!Array.isArray(payload), "WebSocket does not support batch send", "payload", payload);
- // @TODO: stringify payloads here and store to prevent mutations
- // Prepare a promise to respond to
- const promise = new Promise((resolve, reject) => {
- this.#callbacks.set(payload.id, { payload, resolve, reject });
- });
- // Wait until the socket is connected before writing to it
- await this._waitUntilReady();
- // Write the request to the socket
- await this._write(JSON.stringify(payload));
- return [await promise];
- }
- // Sub-classes must call this once they are connected
- /*
- async _start(): Promise {
- if (this.#ready) { return; }
-
- for (const { payload } of this.#callbacks.values()) {
- await this._write(JSON.stringify(payload));
- }
-
- this.#ready = (async function() {
- await super._start();
- })();
- }
- */
- // Sub-classes must call this for each message
- async _processMessage(message) {
- const result = (JSON.parse(message));
- if ("id" in result) {
- const callback = this.#callbacks.get(result.id);
- if (callback == null) {
- this.emit("error", makeError("received result for unknown id", "UNKNOWN_ERROR", {
- reasonCode: "UNKNOWN_ID",
- result,
- }));
- return;
- }
- this.#callbacks.delete(result.id);
- callback.resolve(result);
- }
- else if (result.method === "xcb_subscription") {
- const filterId = result.params.subscription;
- const subscriber = this.#subs.get(filterId);
- if (subscriber) {
- subscriber._handleMessage(result.params.result);
- }
- else {
- let pending = this.#pending.get(filterId);
- if (pending == null) {
- pending = [];
- this.#pending.set(filterId, pending);
- }
- pending.push(result.params.result);
- }
- }
- }
- async _write(message) {
- throw new Error("sub-classes must override this");
- }
- }
-
- class WebSocketProvider extends SocketProvider {
- #connect;
- #websocket;
- get websocket() {
- if (this.#websocket == null) {
- throw new Error("websocket closed");
- }
- return this.#websocket;
- }
- constructor(url, network) {
- super(network);
- if (typeof url === "string") {
- this.#connect = () => {
- return new _WebSocket(url);
- };
- this.#websocket = this.#connect();
- }
- else if (typeof url === "function") {
- this.#connect = url;
- this.#websocket = url();
- }
- else {
- this.#connect = null;
- this.#websocket = url;
- }
- this.websocket.onopen = async () => {
- try {
- await this._start();
- this.resume();
- }
- catch (error) {
- console.log("failed to start WebsocketProvider", error);
- // @TODO: now what? Attempt reconnect?
- }
- };
- this.websocket.onmessage = (message) => {
- this._processMessage(message.data);
- };
- /*
- this.websocket.onclose = (event) => {
- // @TODO: What event.code should we reconnect on?
- const reconnect = false;
- if (reconnect) {
- this.pause(true);
- if (this.#connect) {
- this.#websocket = this.#connect();
- this.#websocket.onopen = ...
- // @TODO: this requires the super class to rebroadcast; move it there
- }
- this._reconnect();
- }
- };
- */
- }
- async _write(message) {
- this.websocket.send(message);
- }
- async destroy() {
- if (this.#websocket != null) {
- this.#websocket.close();
- this.#websocket = null;
- }
- super.destroy();
- }
- }
-
- /**
- * [[link-infura]] provides a third-party service for connecting to
- * various blockchains over JSON-RPC.
- *
- * **Supported Networks**
- *
- * - Core Mainnet (``mainnet``)
- * - Goerli Testnet (``goerli``)
- * - Sepolia Testnet (``sepolia``)
- * - Arbitrum (``arbitrum``)
- * - Arbitrum Goerli Testnet (``arbitrum-goerli``)
- * - Optimism (``optimism``)
- * - Optimism Goerli Testnet (``optimism-goerli``)
- * - Polygon (``matic``)
- * - Polygon Mumbai Testnet (``matic-mumbai``)
- *
- * @_subsection: api/providers/thirdparty:INFURA [providers-infura]
- */
- const defaultProjectId = "84842078b09946638c03157f83405213";
- function getHost$2(name) {
- switch (name) {
- case "mainnet":
- return "mainnet.infura.io";
- case "goerli":
- return "goerli.infura.io";
- case "sepolia":
- return "sepolia.infura.io";
- case "arbitrum":
- return "arbitrum-mainnet.infura.io";
- case "arbitrum-goerli":
- return "arbitrum-goerli.infura.io";
- case "matic":
- return "polygon-mainnet.infura.io";
- case "matic-mumbai":
- return "polygon-mumbai.infura.io";
- case "optimism":
- return "optimism-mainnet.infura.io";
- case "optimism-goerli":
- return "optimism-goerli.infura.io";
- }
- assertArgument(false, "unsupported network", "network", name);
- }
- /**
- * The **InfuraWebSocketProvider** connects to the [[link-infura]]
- * WebSocket end-points.
- *
- * By default, a highly-throttled API key is used, which is
- * appropriate for quick prototypes and simple scripts. To
- * gain access to an increased rate-limit, it is highly
- * recommended to [sign up here](link-infura-signup).
- */
- class InfuraWebSocketProvider extends WebSocketProvider {
- /**
- * The Project ID for the INFURA connection.
- */
- projectId;
- /**
- * The Project Secret.
- *
- * If null, no authenticated requests are made. This should not
- * be used outside of private contexts.
- */
- projectSecret;
- /**
- * Creates a new **InfuraWebSocketProvider**.
- */
- constructor(network, projectId) {
- const provider = new InfuraProvider(network, projectId);
- const req = provider._getConnection();
- assert(!req.credentials, "INFURA WebSocket project secrets unsupported", "UNSUPPORTED_OPERATION", { operation: "InfuraProvider.getWebSocketProvider()" });
- const url = req.url.replace(/^http/i, "ws").replace("/v3/", "/ws/v3/");
- super(url, network);
- defineProperties(this, {
- projectId: provider.projectId,
- projectSecret: provider.projectSecret,
- });
- }
- isCommunityResource() {
- return this.projectId === defaultProjectId;
- }
- }
- /**
- * The **InfuraProvider** connects to the [[link-infura]]
- * JSON-RPC end-points.
- *
- * By default, a highly-throttled API key is used, which is
- * appropriate for quick prototypes and simple scripts. To
- * gain access to an increased rate-limit, it is highly
- * recommended to [sign up here](link-infura-signup).
- */
- class InfuraProvider extends JsonRpcProvider {
- /**
- * The Project ID for the INFURA connection.
- */
- projectId;
- /**
- * The Project Secret.
- *
- * If null, no authenticated requests are made. This should not
- * be used outside of private contexts.
- */
- projectSecret;
- /**
- * Creates a new **InfuraProvider**.
- */
- constructor(_network, projectId, projectSecret) {
- if (_network == null) {
- _network = "mainnet";
- }
- const network = Network.from(_network);
- if (projectId == null) {
- projectId = defaultProjectId;
- }
- if (projectSecret == null) {
- projectSecret = null;
- }
- const request = InfuraProvider.getRequest(network, projectId, projectSecret);
- super(request, network, { staticNetwork: network });
- defineProperties(this, { projectId, projectSecret });
- }
- _getProvider(networkId) {
- try {
- return new InfuraProvider(networkId, this.projectId, this.projectSecret);
- }
- catch (error) { }
- return super._getProvider(networkId);
- }
- isCommunityResource() {
- return this.projectId === defaultProjectId;
- }
- /**
- * Creates a new **InfuraWebSocketProvider**.
- */
- static getWebSocketProvider(network, projectId) {
- return new InfuraWebSocketProvider(network, projectId);
- }
- /**
- * Returns a prepared request for connecting to %%network%%
- * with %%projectId%% and %%projectSecret%%.
- */
- static getRequest(network, projectId, projectSecret) {
- if (projectId == null) {
- projectId = defaultProjectId;
- }
- if (projectSecret == null) {
- projectSecret = null;
- }
- const request = new FetchRequest(`https:/\/${getHost$2(network.name)}/v3/${projectId}`);
- request.allowGzip = true;
- if (projectSecret) {
- request.setCredentials("", projectSecret);
- }
- if (projectId === defaultProjectId) {
- request.retryFunc = async (request, response, attempt) => {
- showThrottleMessage("InfuraProvider");
- return true;
- };
- }
- return request;
- }
- }
-
- /**
- * [[link-quicknode]] provides a third-party service for connecting to
- * various blockchains over JSON-RPC.
- *
- * **Supported Networks**
- *
- * - Core Mainnet (``mainnet``)
- * - Goerli Testnet (``goerli``)
- * - Arbitrum (``arbitrum``)
- * - Arbitrum Goerli Testnet (``arbitrum-goerli``)
- * - Optimism (``optimism``)
- * - Optimism Goerli Testnet (``optimism-goerli``)
- * - Polygon (``matic``)
- * - Polygon Mumbai Testnet (``matic-mumbai``)
- *
- * @_subsection: api/providers/thirdparty:QuickNode [providers-quicknode]
- */
- const defaultToken = "919b412a057b5e9c9b6dce193c5a60242d6efadb";
- function getHost$1(name) {
- switch (name) {
- case "mainnet":
- return "corebc.quiknode.pro";
- case "arbitrum":
- return "corebc.arbitrum-mainnet.quiknode.pro";
- case "arbitrum-goerli":
- return "corebc.arbitrum-goerli.quiknode.pro";
- case "matic":
- return "corebc.matic.quiknode.pro";
- case "matic-mumbai":
- return "corebc.matic-testnet.quiknode.pro";
- case "optimism":
- return "corebc.optimism.quiknode.pro";
- case "optimism-goerli":
- return "corebc.optimism-goerli.quiknode.pro";
- }
- assertArgument(false, "unsupported network", "network", name);
- }
- /**
- * The **QuickNodeProvider** connects to the [[link-quicknode]]
- * JSON-RPC end-points.
- *
- * By default, a highly-throttled API token is used, which is
- * appropriate for quick prototypes and simple scripts. To
- * gain access to an increased rate-limit, it is highly
- * recommended to [sign up here](link-quicknode).
- */
- class QuickNodeProvider extends JsonRpcProvider {
- /**
- * The API token.
- */
- token;
- /**
- * Creates a new **QuickNodeProvider**.
- */
- constructor(_network, token) {
- if (_network == null) {
- _network = "mainnet";
- }
- const network = Network.from(_network);
- if (token == null) {
- token = defaultToken;
- }
- const request = QuickNodeProvider.getRequest(network, token);
- super(request, network, { staticNetwork: network });
- defineProperties(this, { token });
- }
- _getProvider(networkId) {
- try {
- return new QuickNodeProvider(networkId, this.token);
- }
- catch (error) { }
- return super._getProvider(networkId);
- }
- isCommunityResource() {
- return this.token === defaultToken;
- }
- /**
- * Returns a new request prepared for %%network%% and the
- * %%token%%.
- */
- static getRequest(network, token) {
- if (token == null) {
- token = defaultToken;
- }
- const request = new FetchRequest(`https:/\/${getHost$1(network.name)}/${token}`);
- request.allowGzip = true;
- //if (projectSecret) { request.setCredentials("", projectSecret); }
- if (token === defaultToken) {
- request.retryFunc = async (request, response, attempt) => {
- showThrottleMessage("QuickNodeProvider");
- return true;
- };
- }
- return request;
- }
- }
-
- /**
- * Explain all the nitty-gritty about the **FallbackProvider**.
- *
- * @_section: api/providers/fallback-provider:Fallback Provider [about-fallback-provider]
- */
- const BN_1 = BigInt("1");
- const BN_2 = BigInt("2");
- function shuffle(array) {
- for (let i = array.length - 1; i > 0; i--) {
- const j = Math.floor(Math.random() * (i + 1));
- const tmp = array[i];
- array[i] = array[j];
- array[j] = tmp;
- }
- }
- function stall$2(duration) {
- return new Promise((resolve) => {
- setTimeout(resolve, duration);
- });
- }
- function getTime() {
- return new Date().getTime();
- }
- function stringify(value) {
- return JSON.stringify(value, (key, value) => {
- if (typeof value === "bigint") {
- return { type: "bigint", value: value.toString() };
- }
- return value;
- });
- }
- const defaultConfig = { stallTimeout: 400, priority: 1, weight: 1 };
- const defaultState = {
- blockNumber: -2,
- requests: 0,
- lateResponses: 0,
- errorResponses: 0,
- outOfSync: -1,
- unsupportedEvents: 0,
- rollingDuration: 0,
- score: 0,
- _network: null,
- _updateNumber: null,
- _totalTime: 0,
- };
- async function waitForSync(config, blockNumber) {
- while (config.blockNumber < 0 || config.blockNumber < blockNumber) {
- if (!config._updateNumber) {
- config._updateNumber = (async () => {
- const blockNumber = await config.provider.getBlockNumber();
- if (blockNumber > config.blockNumber) {
- config.blockNumber = blockNumber;
- }
- config._updateNumber = null;
- })();
- }
- await config._updateNumber;
- config.outOfSync++;
- }
- }
- function _normalize(value) {
- if (value == null) {
- return "null";
- }
- if (Array.isArray(value)) {
- return "[" + value.map(_normalize).join(",") + "]";
- }
- if (typeof value === "object" && typeof value.toJSON === "function") {
- return _normalize(value.toJSON());
- }
- switch (typeof value) {
- case "boolean":
- case "symbol":
- return value.toString();
- case "bigint":
- case "number":
- return BigInt(value).toString();
- case "string":
- return JSON.stringify(value);
- case "object": {
- const keys = Object.keys(value);
- keys.sort();
- return ("{" +
- keys
- .map((k) => `${JSON.stringify(k)}:${_normalize(value[k])}`)
- .join(",") +
- "}");
- }
- }
- console.log("Could not serialize", value);
- throw new Error("Hmm...");
- }
- function normalizeResult(value) {
- if ("error" in value) {
- const error = value.error;
- return { tag: _normalize(error), value: error };
- }
- const result = value.result;
- return { tag: _normalize(result), value: result };
- }
- // This strategy picks the highest weight result, as long as the weight is
- // equal to or greater than quorum
- function checkQuorum(quorum, results) {
- const tally = new Map();
- for (const { value, tag, weight } of results) {
- const t = tally.get(tag) || { value, weight: 0 };
- t.weight += weight;
- tally.set(tag, t);
- }
- let best = null;
- for (const r of tally.values()) {
- if (r.weight >= quorum && (!best || r.weight > best.weight)) {
- best = r;
- }
- }
- if (best) {
- return best.value;
- }
- return undefined;
- }
- function getMedian(quorum, results) {
- let resultWeight = 0;
- const errorMap = new Map();
- let bestError = null;
- const values = [];
- for (const { value, tag, weight } of results) {
- if (value instanceof Error) {
- const e = errorMap.get(tag) || { value, weight: 0 };
- e.weight += weight;
- errorMap.set(tag, e);
- if (bestError == null || e.weight > bestError.weight) {
- bestError = e;
- }
- }
- else {
- values.push(BigInt(value));
- resultWeight += weight;
- }
- }
- if (resultWeight < quorum) {
- // We have quorum for an error
- if (bestError && bestError.weight >= quorum) {
- return bestError.value;
- }
- // We do not have quorum for a result
- return undefined;
- }
- // Get the sorted values
- values.sort((a, b) => (a < b ? -1 : b > a ? 1 : 0));
- const mid = Math.floor(values.length / 2);
- // Odd-length; take the middle value
- if (values.length % 2) {
- return values[mid];
- }
- // Even length; take the ceiling of the mean of the center two values
- return (values[mid - 1] + values[mid] + BN_1) / BN_2;
- }
- function getAnyResult(quorum, results) {
- // If any value or error meets quorum, that is our preferred result
- const result = checkQuorum(quorum, results);
- if (result !== undefined) {
- return result;
- }
- // Otherwise, do we have any result?
- for (const r of results) {
- if (r.value) {
- return r.value;
- }
- }
- // Nope!
- return undefined;
- }
- function getFuzzyMode(quorum, results) {
- if (quorum === 1) {
- return getNumber(getMedian(quorum, results), "%internal");
- }
- const tally = new Map();
- const add = (result, weight) => {
- const t = tally.get(result) || { result, weight: 0 };
- t.weight += weight;
- tally.set(result, t);
- };
- for (const { weight, value } of results) {
- const r = getNumber(value);
- add(r - 1, weight);
- add(r, weight);
- add(r + 1, weight);
- }
- let bestWeight = 0;
- let bestResult = undefined;
- for (const { weight, result } of tally.values()) {
- // Use this result, if this result meets quorum and has either:
- // - a better weight
- // - or equal weight, but the result is larger
- if (weight >= quorum &&
- (weight > bestWeight ||
- (bestResult != null && weight === bestWeight && result > bestResult))) {
- bestWeight = weight;
- bestResult = result;
- }
- }
- return bestResult;
- }
- /**
- * A Fallback Provider.
- *
- */
- class FallbackProvider extends AbstractProvider {
- quorum;
- eventQuorum;
- eventWorkers;
- #configs;
- #height;
- #initialSyncPromise;
- constructor(providers, network) {
- super(network);
- this.#configs = providers.map((p) => {
- if (p instanceof AbstractProvider) {
- return Object.assign({ provider: p }, defaultConfig, defaultState);
- }
- else {
- return Object.assign({}, defaultConfig, p, defaultState);
- }
- });
- this.#height = -2;
- this.#initialSyncPromise = null;
- this.quorum = 2; //Math.ceil(providers.length / 2);
- this.eventQuorum = 1;
- this.eventWorkers = 1;
- assertArgument(this.quorum <= this.#configs.reduce((a, c) => a + c.weight, 0), "quorum exceed provider wieght", "quorum", this.quorum);
- }
- get providerConfigs() {
- return this.#configs.map((c) => {
- const result = Object.assign({}, c);
- for (const key in result) {
- if (key[0] === "_") {
- delete result[key];
- }
- }
- return result;
- });
- }
- async _detectNetwork() {
- return Network.from(getBigInt(await this._perform({ method: "networkId" })));
- }
- // @TODO: Add support to select providers to be the event subscriber
- //_getSubscriber(sub: Subscription): Subscriber {
- // throw new Error("@TODO");
- //}
- async _translatePerform(provider, req) {
- switch (req.method) {
- case "broadcastTransaction":
- return await provider.broadcastTransaction(req.signedTransaction);
- case "call":
- return await provider.call(Object.assign({}, req.transaction, { blockTag: req.blockTag }));
- case "networkId":
- return (await provider.getNetwork()).networkId;
- case "estimateEnergy":
- return await provider.estimateEnergy(req.transaction);
- case "getBalance":
- return await provider.getBalance(req.address, req.blockTag);
- case "getBlock": {
- const block = "blockHash" in req ? req.blockHash : req.blockTag;
- return await provider.getBlock(block, req.includeTransactions);
- }
- case "getBlockNumber":
- return await provider.getBlockNumber();
- case "getCode":
- return await provider.getCode(req.address, req.blockTag);
- case "getEnergyPrice":
- return (await provider.getFeeData()).energyPrice;
- case "getLogs":
- return await provider.getLogs(req.filter);
- case "getStorage":
- return await provider.getStorage(req.address, req.position, req.blockTag);
- case "getTransaction":
- return await provider.getTransaction(req.hash);
- case "getTransactionCount":
- return await provider.getTransactionCount(req.address, req.blockTag);
- case "getTransactionReceipt":
- return await provider.getTransactionReceipt(req.hash);
- case "getTransactionResult":
- return await provider.getTransactionResult(req.hash);
- }
- }
- // Grab the next (random) config that is not already part of
- // the running set
- #getNextConfig(running) {
- // @TODO: Maybe do a check here to favour (heavily) providers that
- // do not require waitForSync and disfavour providers that
- // seem down-ish or are behaving slowly
- const configs = Array.from(running).map((r) => r.config);
- // Shuffle the states, sorted by priority
- const allConfigs = this.#configs.slice();
- shuffle(allConfigs);
- allConfigs.sort((a, b) => b.priority - a.priority);
- for (const config of allConfigs) {
- if (configs.indexOf(config) === -1) {
- return config;
- }
- }
- return null;
- }
- // Adds a new runner (if available) to running.
- #addRunner(running, req) {
- const config = this.#getNextConfig(running);
- // No runners available
- if (config == null) {
- return null;
- }
- // Create a new runner
- const runner = {
- config,
- result: null,
- didBump: false,
- perform: null,
- staller: null,
- };
- const now = getTime();
- // Start performing this operation
- runner.perform = (async () => {
- try {
- config.requests++;
- const result = await this._translatePerform(config.provider, req);
- runner.result = { result };
- }
- catch (error) {
- config.errorResponses++;
- runner.result = { error };
- }
- const dt = getTime() - now;
- config._totalTime += dt;
- config.rollingDuration = 0.95 * config.rollingDuration + 0.05 * dt;
- runner.perform = null;
- })();
- // Start a staller; when this times out, it's time to force
- // kicking off another runner because we are taking too long
- runner.staller = (async () => {
- await stall$2(config.stallTimeout);
- runner.staller = null;
- })();
- running.add(runner);
- return runner;
- }
- // Initializes the blockNumber and network for each runner and
- // blocks until initialized
- async #initialSync() {
- let initialSync = this.#initialSyncPromise;
- if (!initialSync) {
- const promises = [];
- this.#configs.forEach((config) => {
- promises.push(waitForSync(config, 0));
- promises.push((async () => {
- config._network = await config.provider.getNetwork();
- })());
- });
- this.#initialSyncPromise = initialSync = (async () => {
- // Wait for all providers to have a block number and network
- await Promise.all(promises);
- // Check all the networks match
- let networkId = null;
- for (const config of this.#configs) {
- const network = config._network;
- if (networkId == null) {
- networkId = network.networkId;
- }
- else if (network.networkId !== networkId) {
- assert(false, "cannot mix providers on different networks", "UNSUPPORTED_OPERATION", {
- operation: "new FallbackProvider",
- });
- }
- }
- })();
- }
- await initialSync;
- }
- async #checkQuorum(running, req) {
- // Get all the result objects
- const results = [];
- for (const runner of running) {
- if (runner.result != null) {
- const { tag, value } = normalizeResult(runner.result);
- results.push({ tag, value, weight: runner.config.weight });
- }
- }
- // Are there enough results to event meet quorum?
- if (results.reduce((a, r) => a + r.weight, 0) < this.quorum) {
- return undefined;
- }
- switch (req.method) {
- case "getBlockNumber": {
- // We need to get the bootstrap block height
- if (this.#height === -2) {
- this.#height = Math.ceil(getNumber(getMedian(this.quorum, this.#configs.map((c) => ({
- value: c.blockNumber,
- tag: getNumber(c.blockNumber).toString(),
- weight: c.weight,
- })))));
- }
- // Find the mode across all the providers, allowing for
- // a little drift between block heights
- const mode = getFuzzyMode(this.quorum, results);
- if (mode === undefined) {
- return undefined;
- }
- if (mode > this.#height) {
- this.#height = mode;
- }
- return this.#height;
- }
- case "getEnergyPrice":
- case "estimateEnergy":
- return getMedian(this.quorum, results);
- case "getBlock":
- // Pending blocks are in the mempool and already
- // quite untrustworthy; just grab anything
- if ("blockTag" in req && req.blockTag === "pending") {
- return getAnyResult(this.quorum, results);
- }
- return checkQuorum(this.quorum, results);
- case "call":
- case "networkId":
- case "getBalance":
- case "getTransactionCount":
- case "getCode":
- case "getStorage":
- case "getTransaction":
- case "getTransactionReceipt":
- case "getLogs":
- return checkQuorum(this.quorum, results);
- case "broadcastTransaction":
- return getAnyResult(this.quorum, results);
- }
- assert(false, "unsupported method", "UNSUPPORTED_OPERATION", {
- operation: `_perform(${stringify(req.method)})`,
- });
- }
- async #waitForQuorum(running, req) {
- if (running.size === 0) {
- throw new Error("no runners?!");
- }
- // Any promises that are interesting to watch for; an expired stall
- // or a successful perform
- const interesting = [];
- let newRunners = 0;
- for (const runner of running) {
- // No responses, yet; keep an eye on it
- if (runner.perform) {
- interesting.push(runner.perform);
- }
- // Still stalling...
- if (runner.staller) {
- interesting.push(runner.staller);
- continue;
- }
- // This runner has already triggered another runner
- if (runner.didBump) {
- continue;
- }
- // Got a response (result or error) or stalled; kick off another runner
- runner.didBump = true;
- newRunners++;
- }
- // Check if we have reached quorum on a result (or error)
- const value = await this.#checkQuorum(running, req);
- if (value !== undefined) {
- if (value instanceof Error) {
- throw value;
- }
- return value;
- }
- // Add any new runners, because a staller timed out or a result
- // or error response came in.
- for (let i = 0; i < newRunners; i++) {
- this.#addRunner(running, req);
- }
- // All providers have returned, and we have no result
- assert(interesting.length > 0, "quorum not met", "SERVER_ERROR", {
- request: "%sub-requests",
- info: {
- request: req,
- results: Array.from(running).map((r) => stringify(r.result)),
- },
- });
- // Wait for someone to either complete its perform or stall out
- await Promise.race(interesting);
- // This is recursive, but at worst case the depth is 2x the
- // number of providers (each has a perform and a staller)
- return await this.#waitForQuorum(running, req);
- }
- async _perform(req) {
- // Broadcasting a transaction is rare (ish) and already incurs
- // a cost on the user, so spamming is safe-ish. Just send it to
- // every backend.
- if (req.method === "broadcastTransaction") {
- const results = await Promise.all(this.#configs.map(async ({ provider, weight }) => {
- try {
- const result = await provider._perform(req);
- return Object.assign(normalizeResult({ result }), { weight });
- }
- catch (error) {
- return Object.assign(normalizeResult({ error }), { weight });
- }
- }));
- const result = getAnyResult(this.quorum, results);
- assert(result !== undefined, "problem multi-broadcasting", "SERVER_ERROR", {
- request: "%sub-requests",
- info: { request: req, results: results.map(stringify) },
- });
- if (result instanceof Error) {
- throw result;
- }
- return result;
- }
- await this.#initialSync();
- // Bootstrap enough runners to meet quorum
- const running = new Set();
- for (let i = 0; i < this.quorum; i++) {
- this.#addRunner(running, req);
- }
- const result = await this.#waitForQuorum(running, req);
- // Track requests sent to a provider that are still
- // outstanding after quorum has been otherwise found
- for (const runner of running) {
- if (runner.perform && runner.result == null) {
- runner.config.lateResponses++;
- }
- }
- return result;
- }
- async destroy() {
- for (const { provider } of this.#configs) {
- provider.destroy();
- }
- super.destroy();
- }
- }
-
- function isWebSocketLike(value) {
- return (value &&
- typeof value.send === "function" &&
- typeof value.close === "function");
- }
- function getDefaultProvider(network, options) {
- if (options == null) {
- options = {};
- }
- if (typeof network === "string" && network.match(/^https?:/)) {
- return new JsonRpcProvider(network);
- }
- if ((typeof network === "string" && network.match(/^wss?:/)) ||
- isWebSocketLike(network)) {
- return new WebSocketProvider(network);
- }
- const providers = [];
- if (options.alchemy !== "-") {
- try {
- providers.push(new AlchemyProvider(network, options.alchemy));
- }
- catch (error) {
- console.log(error);
- }
- }
- if (options.ankr !== "-" && options.ankr != null) {
- try {
- providers.push(new AnkrProvider(network, options.ankr));
- }
- catch (error) {
- console.log(error);
- }
- }
- if (options.cloudflare !== "-") {
- try {
- providers.push(new CloudflareProvider(network));
- }
- catch (error) {
- console.log(error);
- }
- }
- if (options.infura !== "-") {
- try {
- let projectId = options.infura;
- let projectSecret = undefined;
- if (typeof projectId === "object") {
- projectSecret = projectId.projectSecret;
- projectId = projectId.projectId;
- }
- providers.push(new InfuraProvider(network, projectId, projectSecret));
- }
- catch (error) {
- console.log(error);
- }
- }
- /*
- if (options.pocket !== "-") {
- try {
- let appId = options.pocket;
- let secretKey: undefined | string = undefined;
- let loadBalancer: undefined | boolean = undefined;
- if (typeof(appId) === "object") {
- loadBalancer = !!appId.loadBalancer;
- secretKey = appId.secretKey;
- appId = appId.appId;
- }
- providers.push(new PocketProvider(network, appId, secretKey, loadBalancer));
- } catch (error) { console.log(error); }
- }
- */
- if (options.quicknode !== "-") {
- try {
- let token = options.quicknode;
- providers.push(new QuickNodeProvider(network, token));
- }
- catch (error) {
- console.log(error);
- }
- }
- assert(providers.length, "unsupported default network", "UNSUPPORTED_OPERATION", {
- operation: "getDefaultProvider",
- });
- if (providers.length === 1) {
- return providers[0];
- }
- return new FallbackProvider(providers);
- }
-
- class NonceManager extends AbstractSigner {
- signer;
- #noncePromise;
- #delta;
- constructor(signer) {
- super(signer.provider);
- defineProperties(this, { signer });
- this.#noncePromise = null;
- this.#delta = 0;
- }
- async getAddress() {
- return this.signer.getAddress();
- }
- connect(provider) {
- return new NonceManager(this.signer.connect(provider));
- }
- async getNonce(blockTag) {
- if (blockTag === "pending") {
- if (this.#noncePromise == null) {
- this.#noncePromise = super.getNonce("pending");
- }
- const delta = this.#delta;
- return (await this.#noncePromise) + delta;
- }
- return super.getNonce(blockTag);
- }
- increment() {
- this.#delta++;
- }
- reset() {
- this.#delta = 0;
- this.#noncePromise = null;
- }
- async sendTransaction(tx) {
- const noncePromise = this.getNonce("pending");
- this.increment();
- tx = await this.signer.populateTransaction(tx);
- tx.nonce = await noncePromise;
- // @TODO: Maybe handle interesting/recoverable errors?
- // Like don't increment if the tx was certainly not sent
- return await this.signer.sendTransaction(tx);
- }
- signTransaction(tx) {
- return this.signer.signTransaction(tx);
- }
- signMessage(message) {
- return this.signer.signMessage(message);
- }
- signTypedData(domain, types, value) {
- return this.signer.signTypedData(domain, types, value);
- }
- }
-
- class BrowserProvider extends JsonRpcApiPollingProvider {
- #request;
- constructor(core, network) {
- super(network, { batchMaxCount: 1 });
- this.#request = async (method, params) => {
- const payload = { method, params };
- this.emit("debug", { action: "sendEip1193Request", payload });
- try {
- const result = await core.request(payload);
- this.emit("debug", { action: "receiveEip1193Result", result });
- return result;
- }
- catch (e) {
- const error = new Error(e.message);
- error.code = e.code;
- error.data = e.data;
- error.payload = payload;
- this.emit("debug", { action: "receiveEip1193Error", error });
- throw error;
- }
- };
- }
- async send(method, params) {
- await this._start();
- return await super.send(method, params);
- }
- async _send(payload) {
- assertArgument(!Array.isArray(payload), "EIP-1193 does not support batch request", "payload", payload);
- try {
- const result = await this.#request(payload.method, payload.params || []);
- return [{ id: payload.id, result }];
- }
- catch (e) {
- return [
- {
- id: payload.id,
- error: { code: e.code, data: e.data, message: e.message },
- },
- ];
- }
- }
- getRpcError(payload, error) {
- error = JSON.parse(JSON.stringify(error));
- // EIP-1193 gives us some machine-readable error codes, so rewrite
- // them into
- switch (error.error.code || -1) {
- case 4001:
- error.error.message = `corebc-user-denied: ${error.error.message}`;
- break;
- case 4200:
- error.error.message = `corebc-unsupported: ${error.error.message}`;
- break;
- }
- return super.getRpcError(payload, error);
- }
- async hasSigner(address) {
- if (address == null) {
- address = 0;
- }
- const accounts = await this.send("xcb_accounts", []);
- if (typeof address === "number") {
- return accounts.length > address;
- }
- address = address.toLowerCase();
- return (accounts.filter((a) => a.toLowerCase() === address).length !== 0);
- }
- async getSigner(address) {
- if (address == null) {
- address = 0;
- }
- if (!(await this.hasSigner(address))) {
- try {
- //const resp =
- await this.#request("xcb_requestAccounts", []);
- //console.log("RESP", resp);
- }
- catch (error) {
- const payload = error.payload;
- throw this.getRpcError(payload, { id: payload.id, error });
- }
- }
- return await super.getSigner(address);
- }
- }
-
- /**
- * [[link-pocket]] provides a third-party service for connecting to
- * various blockchains over JSON-RPC.
- *
- * **Supported Networks**
- *
- * - Core Mainnet (``mainnet``)
- * - Goerli Testnet (``goerli``)
- * - Polygon (``matic``)
- * - Arbitrum (``arbitrum``)
- *
- * @_subsection: api/providers/thirdparty:Pocket [providers-pocket]
- */
- const defaultApplicationId = "62e1ad51b37b8e00394bda3b";
- function getHost(name) {
- switch (name) {
- case "mainnet":
- return "eth-mainnet.gateway.pokt.network";
- case "goerli":
- return "eth-goerli.gateway.pokt.network";
- case "matic":
- return "poly-mainnet.gateway.pokt.network";
- case "matic-mumbai":
- return "polygon-mumbai-rpc.gateway.pokt.network";
- }
- assertArgument(false, "unsupported network", "network", name);
- }
- /**
- * The **PocketProvider** connects to the [[link-pocket]]
- * JSON-RPC end-points.
- *
- * By default, a highly-throttled API key is used, which is
- * appropriate for quick prototypes and simple scripts. To
- * gain access to an increased rate-limit, it is highly
- * recommended to [sign up here](link-pocket-signup).
- */
- class PocketProvider extends JsonRpcProvider {
- /**
- * The Application ID for the Pocket connection.
- */
- applicationId;
- /**
- * The Application Secret for making authenticated requests
- * to the Pocket connection.
- */
- applicationSecret;
- /**
- * Create a new **PocketProvider**.
- *
- * By default connecting to ``mainnet`` with a highly throttled
- * API key.
- */
- constructor(_network, applicationId, applicationSecret) {
- if (_network == null) {
- _network = "mainnet";
- }
- const network = Network.from(_network);
- if (applicationId == null) {
- applicationId = defaultApplicationId;
- }
- if (applicationSecret == null) {
- applicationSecret = null;
- }
- const options = { staticNetwork: network };
- const request = PocketProvider.getRequest(network, applicationId, applicationSecret);
- super(request, network, options);
- defineProperties(this, {
- applicationId,
- applicationSecret,
- });
- }
- _getProvider(networkId) {
- try {
- return new PocketProvider(networkId, this.applicationId, this.applicationSecret);
- }
- catch (error) { }
- return super._getProvider(networkId);
- }
- /**
- * Returns a prepared request for connecting to %%network%% with
- * %%applicationId%%.
- */
- static getRequest(network, applicationId, applicationSecret) {
- if (applicationId == null) {
- applicationId = defaultApplicationId;
- }
- const request = new FetchRequest(`https:/\/${getHost(network.name)}/v1/lb/${applicationId}`);
- request.allowGzip = true;
- if (applicationSecret) {
- request.setCredentials("", applicationSecret);
- }
- if (applicationId === defaultApplicationId) {
- request.retryFunc = async (request, response, attempt) => {
- showThrottleMessage("PocketProvider");
- return true;
- };
- }
- return request;
- }
- isCommunityResource() {
- return this.applicationId === defaultApplicationId;
- }
- }
-
- const IpcSocketProvider = undefined;
-
- /**
- * The **BaseWallet** is a stream-lined implementation of a
- * [[Signer]] that operates with a private key.
- *
- * It is preferred to use the [[Wallet]] class, as it offers
- * additional functionality and simplifies loading a variety
- * of JSON formats, Mnemonic Phrases, etc.
- *
- * This class may be of use for those attempting to implement
- * a minimal Signer.
- */
- class BaseWallet extends AbstractSigner {
- /**
- * The wallet address.
- */
- address;
- prefix;
- #signingKey;
- /**
- * Creates a new BaseWallet for %%privateKey%%, optionally
- * connected to %%provider%%.
- *
- * If %%provider%% is not specified, only offline methods can
- * be used.
- */
- constructor({ signingKey, prefix, provider, }) {
- super(provider);
- this.prefix = prefix;
- assertArgument(signingKey && typeof signingKey.sign === "function", "invalid signingKey key", "signingKey", "[ REDACTED ]");
- this.#signingKey = signingKey;
- const address = computeAddress(this.#signingKey, prefix);
- defineProperties(this, { address });
- }
- // Store private values behind getters to reduce visibility
- // in console.log
- /**
- * The [[SigningKey]] used for signing payloads.
- */
- get signingKey() {
- return this.#signingKey;
- }
- /**
- * The private key for this wallet.
- */
- get privateKey() {
- return this.signingKey.privateKey;
- }
- async getAddress() {
- return this.address;
- }
- connect(provider) {
- return new BaseWallet({
- signingKey: this.#signingKey,
- prefix: this.prefix,
- provider,
- });
- }
- async signTransaction(tx) {
- // Replace any Addressable or ENS name with an address
- const { to, from } = await resolveProperties({
- to: tx.to || undefined,
- from: tx.from || undefined,
- });
- if (to != null) {
- tx.to = to;
- }
- if (from != null) {
- tx.from = from;
- }
- if (tx.from != null) {
- assertArgument(getAddress(tx.from) === this.address, "transaction from address mismatch", "tx.from", tx.from);
- delete tx.from;
- }
- // Build the transaction
- const btx = Transaction.from(tx);
- const unSignedSerialized = btx.unsignedSerialized;
- const unsignedHash = sha256(unSignedSerialized);
- // sha256(btx.unsignedSerialized)
- btx.signature = this.signingKey.sign(unsignedHash);
- return btx.serialized;
- }
- async signMessage(message) {
- return this.signMessageSync(message);
- }
- // @TODO: Add a secialized signTx and signTyped sync that enforces
- // all parameters are known?
- /**
- * Returns the signature for %%message%% signed with this wallet.
- */
- signMessageSync(message) {
- return this.signingKey.sign(hashMessage(message));
- }
- async signTypedData(domain, types, value) {
- // Populate any ENS names
- const populated = await TypedDataEncoder.resolveNames(domain, types, value, async (name) => {
- // @TODO: this should use resolveName; addresses don't
- // need a provider
- assert(this.provider != null, "cannot resolve ENS names without a provider", "UNSUPPORTED_OPERATION", {
- operation: "resolveName",
- info: { name },
- });
- const address = getAddress(name);
- assert(address != null, "unconfigured ENS name", "UNCONFIGURED_NAME", {
- value: name,
- });
- return address;
- });
- return this.signingKey.sign(TypedDataEncoder.hash(populated.domain, types, populated.value));
- }
- }
-
- const subsChrs = " !#$%&'()*+,-./<=>?@[]^_`{|}~";
- const Word = /^[a-z]*$/i;
- function unfold(words, sep) {
- let initial = 97;
- return words.reduce((accum, word) => {
- if (word === sep) {
- initial++;
- }
- else if (word.match(Word)) {
- accum.push(String.fromCharCode(initial) + word);
- }
- else {
- initial = 97;
- accum.push(word);
- }
- return accum;
- }, []);
- }
- /**
- * @_ignore
- */
- function decode(data, subs) {
- // Replace all the substitutions with their expanded form
- for (let i = subsChrs.length - 1; i >= 0; i--) {
- data = data.split(subsChrs[i]).join(subs.substring(2 * i, 2 * i + 2));
- }
- // Get all tle clumps; each suffix, first-increment and second-increment
- const clumps = [];
- const leftover = data.replace(/(:|([0-9])|([A-Z][a-z]*))/g, (all, item, semi, word) => {
- if (semi) {
- for (let i = parseInt(semi); i >= 0; i--) {
- clumps.push(";");
- }
- }
- else {
- clumps.push(item.toLowerCase());
- }
- return "";
- });
- /* c8 ignore start */
- if (leftover) {
- throw new Error(`leftovers: ${JSON.stringify(leftover)}`);
- }
- /* c8 ignore stop */
- return unfold(unfold(clumps, ";"), ":");
- }
- /**
- * @_ignore
- */
- function decodeOwl(data) {
- assertArgument(data[0] === "0", "unsupported auwl data", "data", data);
- return decode(data.substring(1 + 2 * subsChrs.length), data.substring(1, 1 + 2 * subsChrs.length));
- }
-
- /**
- * A Wordlist represents a collection of language-specific
- * words used to encode and devoce [[link-bip-39]] encoded data
- * by mapping words to 11-bit values and vice versa.
- */
- class Wordlist {
- locale;
- /**
- * Creates a new Wordlist instance.
- *
- * Sub-classes MUST call this if they provide their own constructor,
- * passing in the locale string of the language.
- *
- * Generally there is no need to create instances of a Wordlist,
- * since each language-specific Wordlist creates an instance and
- * there is no state kept internally, so they are safe to share.
- */
- constructor(locale) {
- defineProperties(this, { locale });
- }
- /**
- * Sub-classes may override this to provide a language-specific
- * method for spliting %%phrase%% into individual words.
- *
- * By default, %%phrase%% is split using any sequences of
- * white-space as defined by regular expressions (i.e. ``/\s+/``).
- */
- split(phrase) {
- return phrase.toLowerCase().split(/\s+/g);
- }
- /**
- * Sub-classes may override this to provider a language-specific
- * method for joining %%words%% into a phrase.
- *
- * By default, %%words%% are joined by a single space.
- */
- join(words) {
- return words.join(" ");
- }
- static check(wordlist) {
- const words = [];
- for (let i = 0; i < 2048; i++) {
- const word = wordlist.getWord(i);
- /* istanbul ignore if */
- if (i !== wordlist.getWordIndex(word)) {
- return "0x";
- }
- words.push(word);
- }
- return id(words.join("\n") + "\n");
- }
- }
-
- // Use the encode-latin.js script to create the necessary
- // data files to be consumed by this class
- /**
- * An OWL format Wordlist is an encoding method that exploits
- * the general locality of alphabetically sorted words to
- * achieve a simple but effective means of compression.
- *
- * This class is generally not useful to most developers as
- * it is used mainly internally to keep Wordlists for languages
- * based on ASCII-7 small.
- *
- * If necessary, there are tools within the ``generation/`` folder
- * to create these necessary data.
- */
- class WordlistOwl extends Wordlist {
- #data;
- #checksum;
- /**
- * Creates a new Wordlist for %%locale%% using the OWL %%data%%
- * and validated against the %%checksum%%.
- */
- constructor(locale, data, checksum) {
- super(locale);
- this.#data = data;
- this.#checksum = checksum;
- this.#words = null;
- }
- get _data() {
- return this.#data;
- }
- _decodeWords() {
- return decodeOwl(this.#data);
- }
- #words;
- #loadWords() {
- if (this.#words == null) {
- const words = this._decodeWords();
- // Verify the computed list matches the official list
- const checksum = id(words.join("\n") + "\n", true);
- /* c8 ignore start */
- if (checksum !== this.#checksum) {
- throw new Error(`BIP39 Wordlist for ${this.locale} FffffAILED`);
- }
- /* c8 ignore stop */
- this.#words = words;
- }
- return this.#words;
- }
- getWord(index) {
- const words = this.#loadWords();
- assertArgument(index >= 0 && index < words.length, `invalid word index: ${index}`, "index", index);
- return words[index];
- }
- getWordIndex(word) {
- return this.#loadWords().indexOf(word);
- }
- }
-
- const words = "0erleonalorenseinceregesticitStanvetearctssi#ch2Athck&tneLl0And#Il.yLeOutO=S|S%b/ra@SurdU'0Ce[Cid|CountCu'Hie=IdOu,-Qui*Ro[TT]T%T*[Tu$0AptDD-tD*[Ju,M.UltV<)Vi)0Rob-0FairF%dRaid0A(EEntRee0Ead0MRRp%tS!_rmBumCoholErtI&LLeyLowMo,O}PhaReadySoT Ways0A>urAz(gOngOuntU'd0Aly,Ch%Ci|G G!GryIm$K!Noun)Nu$O` Sw T&naTiqueXietyY1ArtOlogyPe?P!Pro=Ril1ChCt-EaEnaGueMMedM%MyOundR<+Re,Ri=RowTTefa@Ti,Tw%k0KPe@SaultSetSi,SumeThma0H!>OmTa{T&dT.udeTra@0Ct]D.Gu,NtTh%ToTumn0Era+OcadoOid0AkeA*AyEsomeFulKw?d0Is:ByChel%C#D+GL<)Lc#y~MbooN_{Ad!AftAmA}AshAt AwlAzyEamEd.EekEwI{etImeIspIt-OpO[Ou^OwdUci$UelUi'Umb!Un^UshYY,$2BeLtu*PPbo?dRiousRr|Rta(R=Sh]/omTe3C!:DMa+MpN)Ng R(gShUght WnY3AlBa>BrisCadeCemb CideCl(eC%a>C*a'ErF&'F(eFyG*eLayLiv M3AgramAlAm#dAryCeE'lEtFf G.$Gn.yLemmaNn NosaurRe@RtSag*eScov Sea'ShSmi[S%d Splay/<)V tVideV%)Zzy5Ct%Cum|G~Lph(Ma(Na>NkeyN%OrSeUb!Ve_ftAg#AmaA,-AwEamE[IftIllInkIpI=OpUmY2CkMbNeR(g/T^Ty1Arf1Nam-:G G!RlyRnR`Sily/Sy1HoOlogyOnomy0GeItUca>1F%t0G1GhtTh 2BowD E@r-EgSe0B?kBodyBra)Er+Ot]PloyPow Pty0Ab!A@DD![D%'EmyErgyF%)Ga+G(eH<)JoyLi,OughR-hRollSu*T Ti*TryVelope1Isode0U$Uip0AA'OdeOs]R%Upt0CapeSayS&)Ta>0Ern$H-s1Id&)IlOkeOl=1A@Amp!Ce[Ch<+C.eCludeCu'Ecu>Erci'Hau,Hib.I!I,ItOt-PM&'Mu}Pa@Po'Pro=Pul'0ChCludeComeC*a'DexD-a>Do%Du,ryFN Noc|PutQuirySSue0Em1Ory:CketGu?RZz3AlousAns~yWel9BInKeUr}yY5D+I)MpNg!Ni%Nk/:Ng?oo3EnEpT^upY3CkDD}yNdNgdomSsTT^&TeTt&Wi4EeIfeO{Ow:BBelB%Dd DyKeMpNgua+PtopR+T T(UghUndryVaWWnWsu.Y Zy3Ad AfArnA=Ctu*FtGG$G&dIsu*M#NdNg`NsOp?dSs#Tt Vel3ArB tyBr?yC&'FeFtGhtKeMbM.NkOnQuid/Tt!VeZ?d5AdAnB, C$CkG-NelyNgOpTt yUdUn+VeY$5CkyGga+Mb N?N^Xury3R-s:Ch(eDG-G}tIdIlInJ%KeMm$NNa+Nda>NgoNs]Nu$P!Rb!R^Rg(R(eRketRria+SkSs/ T^T i$ThTrixTt XimumZe3AdowAnAsu*AtCh<-D$DiaLodyLtMb M%yNt]NuRcyR+R.RryShSsa+T$Thod3Dd!DnightLk~]M-NdNimumN%Nu>Rac!Rr%S ySs/akeXXedXtu*5Bi!DelDifyMM|N.%NkeyN, N`OnR$ReRn(gSqu.oTh T]T%Unta(U'VeVie5ChFf(LeLtiplySc!SeumShroomS-/Tu$3Self/ yTh:I=MePk(Rrow/yT]Tu*3ArCkEdGati=G!@I` PhewR=/TTw%kUtr$V WsXt3CeGht5B!I'M(eeOd!Rm$R`SeTab!TeTh(gTi)VelW5C!?Mb R'T:K0EyJe@Li+Scu*S =Ta(Vious0CurEAyEa'Ed+U{UgUn+2EmEtIntL?LeLi)NdNyOlPul?Rt]S.]Ssib!/TatoTt yV tyWd W _@i)Ai'Ed-tEf Epa*Es|EttyEv|I)IdeIm?yIntI%.yIs#Iva>IzeOb!mO)[Odu)Of.OgramOje@Omo>OofOp tyOsp O>@OudOvide2Bl-Dd(g~LpL'Mpk(N^PilPpyR^a'R.yRpo'R'ShTZz!3Ramid:99Al.yAntumArt E,]I{ItIzO>:Bb.Cco#CeCkD?DioIlInI'~yMpN^NdomN+PidReTeTh V&WZ%3AdyAlAs#BelBuildC$lCei=CipeC%dCyc!Du)F!@F%mFu'G]G*tGul?Je@LaxLea'LiefLyMa(Memb M(dMo=Nd NewNtOp&PairPeatPla)P%tQui*ScueSemb!Si,Sour)Sp#'SultTi*T*atTurnUn]Ve$ViewW?d2Y`m0BBb#CeChDeD+F!GhtGidNgOtPp!SkTu$V$V 5AdA,BotBu,CketM<)OfOkieOmSeTa>UghUndU>Y$5Bb DeGLeNNwayR$:DDd!D}[FeIlLadLm#L#LtLu>MeMp!NdTisfyToshiU)Usa+VeY1A!AnA*Att E}HemeHoolI&)I[%sOrp]OutRapRe&RiptRub1AAr^As#AtC#dC*tCt]Cur.yEdEkGm|Le@~M(?Ni%N'Nt&)RiesRvi)Ss]Tt!TupV&_dowAftAllowA*EdEllEriffIeldIftI}IpIv O{OeOotOpOrtOuld O=RimpRugUff!Y0Bl(gCkDeE+GhtGnL|Lk~yLv Mil?Mp!N)NgR&/ Tua>XZe1A>Et^IIllInIrtUll0AbAmEepEnd I)IdeIghtImOgAyEakEelEmEpE*oI{IllIngO{Oma^O}OolOryO=Ra>gyReetRikeR#gRugg!Ud|UffUmb!Y!0Bje@Bm.BwayC)[ChDd&Ff G?G+,ItMm NNnyN'tP PplyP*meReRfa)R+Rpri'RroundR=ySpe@/a(1AllowAmpApArmE?EetIftImIngIt^Ord1MbolMptomRup/em:B!Ck!GIlL|LkNkPeR+tSk/eTtooXi3A^Am~NNGradeHoldOnP Set1BOng::Rd3Ar~ow9UUngU`:3BraRo9NeO";
- const checksum = "0x3c8acc1e7b08d8e76f9fda015ef48dc8c710a73cb7e0f77b2c18a9b5a7adde60";
- let wordlist = null;
- /**
- * The [[link-bip39-en]] for [mnemonic phrases](link-bip-39).
- *
- * @_docloc: api/wordlists
- */
- class LangEn extends WordlistOwl {
- /**
- * Creates a new instance of the English language Wordlist.
- *
- * This should be unnecessary most of the time as the exported
- * [[langEn]] should suffice.
- *
- * @_ignore:
- */
- constructor() {
- super("en", words, checksum);
- }
- /**
- * Returns a singleton instance of a ``LangEn``, creating it
- * if this is the first time being called.
- */
- static wordlist() {
- if (wordlist == null) {
- wordlist = new LangEn();
- }
- return wordlist;
- }
- }
-
- function mnemonicToSeed(mnemonic, password) {
- if (!password) {
- password = "";
- }
- const t = generateSeed(mnemonic, password);
- return t.goldilock;
- }
- const generateSeed = (mnemonic, password) => {
- const goldilockSaltPrefix = "mnemonic";
- const aesSaltPrefix = "mnemonicfortheAESkey";
- const goldilockSalt = utf8.encode(goldilockSaltPrefix + password);
- const aesSalt = utf8.encode(aesSaltPrefix + password);
- const goldilockKey = pbkdf2Sync(Buffer.from(mnemonic), goldilockSalt, 2048, 64, "sha512");
- const aesKeySeed = pbkdf2Sync(Buffer.from(mnemonic), aesSalt, 2048, 64, "sha512");
- return {
- aes: aesKeySeed.toString("hex"),
- goldilock: goldilockKey.toString("hex"),
- };
- };
-
- // Returns a byte with the MSB bits set
- function getUpperMask(bits) {
- return (((1 << bits) - 1) << (8 - bits)) & 0xff;
- }
- // Returns a byte with the LSB bits set
- function getLowerMask(bits) {
- return ((1 << bits) - 1) & 0xff;
- }
- function mnemonicToEntropy(mnemonic, wordlist) {
- assertNormalize("NFKD");
- if (wordlist == null) {
- wordlist = LangEn.wordlist();
- }
- const words = wordlist.split(mnemonic);
- assertArgument(words.length % 3 === 0 && words.length >= 12 && words.length <= 24, "invalid mnemonic length", "mnemonic", "[ REDACTED ]");
- const entropy = new Uint8Array(Math.ceil((11 * words.length) / 8));
- let offset = 0;
- for (let i = 0; i < words.length; i++) {
- let index = wordlist.getWordIndex(words[i].normalize("NFKD"));
- assertArgument(index >= 0, `invalid mnemonic word at index ${i}`, "mnemonic", "[ REDACTED ]");
- for (let bit = 0; bit < 11; bit++) {
- if (index & (1 << (10 - bit))) {
- entropy[offset >> 3] |= 1 << (7 - (offset % 8));
- }
- offset++;
- }
- }
- const entropyBits = (32 * words.length) / 3;
- const checksumBits = words.length / 3;
- const checksumMask = getUpperMask(checksumBits);
- const checksum = getBytes(legacySha256(entropy.slice(0, entropyBits / 8)))[0] & checksumMask;
- assertArgument(checksum === (entropy[entropy.length - 1] & checksumMask), "invalid mnemonic checksum", "mnemonic", "[ REDACTED ]");
- return hexlify(entropy.slice(0, entropyBits / 8));
- }
- function entropyToMnemonic(entropy, wordlist) {
- assertArgument(entropy.length % 4 === 0 && entropy.length >= 16 && entropy.length <= 32, "invalid entropy size", "entropy", "[ REDACTED ]");
- if (wordlist == null) {
- wordlist = LangEn.wordlist();
- }
- const indices = [0];
- let remainingBits = 11;
- for (let i = 0; i < entropy.length; i++) {
- // Consume the whole byte (with still more to go)
- if (remainingBits > 8) {
- indices[indices.length - 1] <<= 8;
- indices[indices.length - 1] |= entropy[i];
- remainingBits -= 8;
- // This byte will complete an 11-bit index
- }
- else {
- indices[indices.length - 1] <<= remainingBits;
- indices[indices.length - 1] |= entropy[i] >> (8 - remainingBits);
- // Start the next word
- indices.push(entropy[i] & getLowerMask(8 - remainingBits));
- remainingBits += 3;
- }
- }
- // Compute the checksum bits
- const checksumBits = entropy.length / 4;
- const checksum = parseInt(legacySha256(entropy).substring(2, 4), 16) &
- getUpperMask(checksumBits);
- // Shift the checksum into the word indices
- indices[indices.length - 1] <<= checksumBits;
- indices[indices.length - 1] |= checksum >> (8 - checksumBits);
- return wordlist.join(indices.map((index) => wordlist.getWord(index)));
- }
- const _guard$1 = {};
- /**
- * A **Mnemonic** wraps all properties required to compute [[link-bip-39]]
- * seeds and convert between phrases and entropy.
- */
- class Mnemonic {
- /**
- * The mnemonic phrase of 12, 15, 18, 21 or 24 words.
- *
- * Use the [[wordlist]] ``split`` method to get the individual words.
- */
- phrase;
- /**
- * The password used for this mnemonic. If no password is used this
- * is the empty string (i.e. ``""``) as per the specification.
- */
- password;
- /**
- * The wordlist for this mnemonic.
- */
- wordlist;
- /**
- * The underlying entropy which the mnemonic encodes.
- */
- entropy;
- /**
- * @private
- */
- constructor(guard, entropy, phrase, password, wordlist) {
- if (password == null) {
- password = "";
- }
- if (wordlist == null) {
- wordlist = LangEn.wordlist();
- }
- assertPrivate(guard, _guard$1, "Mnemonic");
- defineProperties(this, { phrase, password, wordlist, entropy });
- }
- /**
- * Returns the seed for the mnemonic.
- */
- computeSeed() {
- return mnemonicToSeed(this.phrase, this.password);
- }
- /**
- * Creates a new Mnemonic for the %%phrase%%.
- *
- * The default %%password%% is the empty string and the default
- * wordlist is the [English wordlists](LangEn).
- */
- static fromPhrase({ phrase, password, wordlist, }) {
- // Normalize the case and space; throws if invalid
- const entropy = mnemonicToEntropy(phrase, wordlist);
- phrase = entropyToMnemonic(getBytes(entropy), wordlist);
- return new Mnemonic(_guard$1, entropy, phrase, password, wordlist);
- }
- /**
- * Create a new **Mnemonic** from the %%entropy%%.
- *
- * The default %%password%% is the empty string and the default
- * wordlist is the [English wordlists](LangEn).
- */
- static fromEntropy(_entropy, password, wordlist) {
- const entropy = getBytes(_entropy, "entropy");
- const phrase = entropyToMnemonic(entropy, wordlist);
- return new Mnemonic(_guard$1, hexlify(entropy), phrase, password, wordlist);
- }
- /**
- * Returns the phrase for %%mnemonic%%.
- */
- static entropyToPhrase(_entropy, wordlist) {
- const entropy = getBytes(_entropy, "entropy");
- return entropyToMnemonic(entropy, wordlist);
- }
- /**
- * Returns the entropy for %%phrase%%.
- */
- static phraseToEntropy(phrase, wordlist) {
- return mnemonicToEntropy(phrase, wordlist);
- }
- /**
- * Returns true if %%phrase%% is a valid [[link-bip-39]] phrase.
- *
- * This checks all the provided words belong to the %%wordlist%%,
- * that the length is valid and the checksum is correct.
- */
- static isValidMnemonic(phrase, wordlist) {
- try {
- mnemonicToEntropy(phrase, wordlist);
- return true;
- }
- catch (error) { }
- return false;
- }
- }
-
- /**
- * @_ignore
- */
- function looseArrayify(hexString) {
- if (typeof hexString === "string" && !hexString.startsWith("0x")) {
- hexString = "0x" + hexString;
- }
- return getBytesCopy(hexString);
- }
- function zpad(value, length) {
- value = String(value);
- while (value.length < length) {
- value = "0" + value;
- }
- return value;
- }
- function getPassword(password) {
- if (typeof password === "string") {
- return toUtf8Bytes(password, "NFKC");
- }
- return getBytesCopy(password);
- }
- function spelunk(object, _path) {
- const match = _path.match(/^([a-z0-9$_.-]*)(:([a-z]+))?(!)?$/i);
- assertArgument(match != null, "invalid path", "path", _path);
- const path = match[1];
- const type = match[3];
- const reqd = match[4] === "!";
- let cur = object;
- for (const comp of path.toLowerCase().split(".")) {
- // Search for a child object with a case-insensitive matching key
- if (Array.isArray(cur)) {
- if (!comp.match(/^[0-9]+$/)) {
- break;
- }
- cur = cur[parseInt(comp)];
- }
- else if (typeof cur === "object") {
- let found = null;
- for (const key in cur) {
- if (key.toLowerCase() === comp) {
- found = cur[key];
- break;
- }
- }
- cur = found;
- }
- else {
- cur = null;
- }
- if (cur == null) {
- break;
- }
- }
- assertArgument(!reqd || cur != null, "missing required value", "path", path);
- if (type && cur != null) {
- if (type === "int") {
- if (typeof cur === "string" && cur.match(/^-?[0-9]+$/)) {
- return parseInt(cur);
- }
- else if (Number.isSafeInteger(cur)) {
- return cur;
- }
- }
- if (type === "number") {
- if (typeof cur === "string" && cur.match(/^-?[0-9.]*$/)) {
- return parseFloat(cur);
- }
- }
- if (type === "data") {
- if (typeof cur === "string") {
- return looseArrayify(cur);
- }
- }
- if (type === "array" && Array.isArray(cur)) {
- return cur;
- }
- if (type === typeof cur) {
- return cur;
- }
- assertArgument(false, `wrong type found for ${type} `, "path", path);
- }
- return cur;
- }
- /*
- export function follow(object: any, path: string): null | string {
- let currentChild = object;
-
- for (const comp of path.toLowerCase().split('/')) {
-
- // Search for a child object with a case-insensitive matching key
- let matchingChild = null;
- for (const key in currentChild) {
- if (key.toLowerCase() === comp) {
- matchingChild = currentChild[key];
- break;
- }
- }
-
- if (matchingChild === null) { return null; }
-
- currentChild = matchingChild;
- }
-
- return currentChild;
- }
-
- // "path/to/something:type!"
- export function followRequired(data: any, path: string): string {
- const value = follow(data, path);
- if (value != null) { return value; }
- return logger.throwArgumentError("invalid value", `data:${ path }`,
- JSON.stringify(data));
- }
- */
- // See: https://www.ietf.org/rfc/rfc4122.txt (Section 4.4)
- /*
- export function uuidV4(randomBytes: BytesLike): string {
- const bytes = getBytes(randomBytes, "randomBytes");
-
- // Section: 4.1.3:
- // - time_hi_and_version[12:16] = 0b0100
- bytes[6] = (bytes[6] & 0x0f) | 0x40;
-
- // Section 4.4
- // - clock_seq_hi_and_reserved[6] = 0b0
- // - clock_seq_hi_and_reserved[7] = 0b1
- bytes[8] = (bytes[8] & 0x3f) | 0x80;
-
- const value = hexlify(bytes);
-
- return [
- value.substring(2, 10),
- value.substring(10, 14),
- value.substring(14, 18),
- value.substring(18, 22),
- value.substring(22, 34),
- ].join("-");
- }
- */
-
- /**
- * The JSON Wallet formats allow a simple way to store the private
- * keys needed in Core along with related information and allows
- * for extensible forms of encryption.
- *
- * These utilities facilitate decrypting and encrypting the most common
- * JSON Wallet formats.
- *
- * @_subsection: api/wallet:JSON Wallets [json-wallets]
- */
- // @ts-ignore
- const { CTR } = pkg;
- const defaultPath$1 = "m/44'/60'/0'/0/0";
- /**
- * Returns true if %%json%% is a valid JSON Keystore Wallet.
- */
- function isKeystoreJson(json) {
- try {
- const data = JSON.parse(json);
- const version = data.version != null ? parseInt(data.version) : 0;
- if (version === 3) {
- return true;
- }
- }
- catch (error) { }
- return false;
- }
- function decrypt(data, key, ciphertext) {
- const cipher = spelunk(data, "crypto.cipher:string");
- if (cipher === "aes-128-ctr") {
- const iv = spelunk(data, "crypto.cipherparams.iv:data!");
- const aesCtr = new CTR(key, iv);
- return hexlify(aesCtr.decrypt(ciphertext));
- }
- assert(false, "unsupported cipher", "UNSUPPORTED_OPERATION", {
- operation: "decrypt",
- });
- }
- function getAccount(data, _key) {
- const key = getBytes(_key);
- const ciphertext = spelunk(data, "crypto.ciphertext:data!");
- const computedMAC = hexlify(sha256(concat([key.slice(16, 32), ciphertext]))).substring(2);
- assertArgument(computedMAC === spelunk(data, "crypto.mac:string!").toLowerCase(), "incorrect password", "password", "[ REDACTED ]");
- const privateKey = decrypt(data, key.slice(0, 16), ciphertext);
- const address = getAddress(data.address);
- const prefix = extractPrefix(address);
- if (computeAddress(privateKey, prefix) !== address) {
- throw new Error("address mismatch");
- }
- if (data.address) {
- let check = data.address.toLowerCase();
- if (!check.startsWith("0x")) {
- check = "0x" + check;
- }
- assertArgument(getAddress(check) === address, "keystore address/privateKey mismatch", "address", data.address);
- }
- const account = { address, privateKey };
- // Version 0.1 x-corebc metadata must contain an encrypted mnemonic phrase
- const version = spelunk(data, "x-corebc.version:string");
- if (version === "0.1") {
- const mnemonicKey = key.slice(32, 64);
- const mnemonicCiphertext = spelunk(data, "x-corebc.mnemonicCiphertext:data!");
- const mnemonicIv = spelunk(data, "x-corebc.mnemonicCounter:data!");
- const mnemonicAesCtr = new CTR(mnemonicKey, mnemonicIv);
- account.mnemonic = {
- path: spelunk(data, "x-corebc.path:string") || defaultPath$1,
- locale: spelunk(data, "x-corebc.locale:string") || "en",
- entropy: hexlify(getBytes(mnemonicAesCtr.decrypt(mnemonicCiphertext))),
- };
- }
- return account;
- }
- function getDecryptKdfParams(data) {
- const kdf = spelunk(data, "crypto.kdf:string");
- if (kdf && typeof kdf === "string") {
- if (kdf.toLowerCase() === "scrypt") {
- const salt = spelunk(data, "crypto.kdfparams.salt:data!");
- const N = spelunk(data, "crypto.kdfparams.n:int!");
- const r = spelunk(data, "crypto.kdfparams.r:int!");
- const p = spelunk(data, "crypto.kdfparams.p:int!");
- // Make sure N is a power of 2
- assertArgument(N > 0 && (N & (N - 1)) === 0, "invalid kdf.N", "kdf.N", N);
- assertArgument(r > 0 && p > 0, "invalid kdf", "kdf", kdf);
- const dkLen = spelunk(data, "crypto.kdfparams.dklen:int!");
- assertArgument(dkLen === 32, "invalid kdf.dklen", "kdf.dflen", dkLen);
- return { name: "scrypt", salt, N, r, p, dkLen: 64 };
- }
- else if (kdf.toLowerCase() === "pbkdf2") {
- const salt = spelunk(data, "crypto.kdfparams.salt:data!");
- const prf = spelunk(data, "crypto.kdfparams.prf:string!");
- const algorithm = prf.split("-").pop();
- assertArgument(algorithm === "sha256" || algorithm === "sha512", "invalid kdf.pdf", "kdf.pdf", prf);
- const count = spelunk(data, "crypto.kdfparams.c:int!");
- const dkLen = spelunk(data, "crypto.kdfparams.dklen:int!");
- assertArgument(dkLen === 32, "invalid kdf.dklen", "kdf.dklen", dkLen);
- return { name: "pbkdf2", salt, count, dkLen, algorithm };
- }
- }
- assertArgument(false, "unsupported key-derivation function", "kdf", kdf);
- }
- /**
- * Returns the account details for the JSON Keystore Wallet %%json%%
- * using %%password%%.
- *
- * It is preferred to use the [async version](decryptKeystoreJson)
- * instead, which allows a [[ProgressCallback]] to keep the user informed
- * as to the decryption status.
- *
- * This method will block the event loop (freezing all UI) until decryption
- * is complete, which can take quite some time, depending on the wallet
- * paramters and platform.
- */
- function decryptKeystoreJsonSync(json, _password) {
- const data = JSON.parse(json);
- const password = getPassword(_password);
- const params = getDecryptKdfParams(data);
- if (params.name === "pbkdf2") {
- const { salt, count, dkLen, algorithm } = params;
- const key = pbkdf2(password, salt, count, dkLen, algorithm);
- return getAccount(data, key);
- }
- assert(params.name === "scrypt", "cannot be reached", "UNKNOWN_ERROR", {
- params,
- });
- const { salt, N, r, p, dkLen } = params;
- const key = scryptSync(password, salt, N, r, p, dkLen);
- return getAccount(data, key);
- }
- function stall$1(duration) {
- return new Promise((resolve) => {
- setTimeout(() => {
- resolve();
- }, duration);
- });
- }
- /**
- * Resolves to the decrypted JSON Keystore Wallet %%json%% using the
- * %%password%%.
- *
- * If provided, %%progress%% will be called periodically during the
- * decrpytion to provide feedback, and if the function returns
- * ``false`` will halt decryption.
- *
- * The %%progressCallback%% will **always** receive ``0`` before
- * decryption begins and ``1`` when complete.
- */
- async function decryptKeystoreJson(json, _password, progress) {
- const data = JSON.parse(json);
- const password = getPassword(_password);
- const params = getDecryptKdfParams(data);
- if (params.name === "pbkdf2") {
- if (progress) {
- progress(0);
- await stall$1(0);
- }
- const { salt, count, dkLen, algorithm } = params;
- const key = pbkdf2(password, salt, count, dkLen, algorithm);
- if (progress) {
- progress(1);
- await stall$1(0);
- }
- return getAccount(data, key);
- }
- assert(params.name === "scrypt", "cannot be reached", "UNKNOWN_ERROR", {
- params,
- });
- const { salt, N, r, p, dkLen } = params;
- const key = await scrypt(password, salt, N, r, p, dkLen, progress);
- return getAccount(data, key);
- }
- function getEncryptKdfParams(options) {
- // Check/generate the salt
- const salt = options.salt != null
- ? getBytes(options.salt, "options.salt")
- : randomBytes(32);
- // Override the scrypt password-based key derivation function parameters
- let N = 1 << 17, r = 8, p = 1;
- if (options.scrypt) {
- if (options.scrypt.N) {
- N = options.scrypt.N;
- }
- if (options.scrypt.r) {
- r = options.scrypt.r;
- }
- if (options.scrypt.p) {
- p = options.scrypt.p;
- }
- }
- assertArgument(typeof N === "number" &&
- N > 0 &&
- Number.isSafeInteger(N) &&
- (BigInt(N) & BigInt(N - 1)) === BigInt(0), "invalid scrypt N parameter", "options.N", N);
- assertArgument(typeof r === "number" && r > 0 && Number.isSafeInteger(r), "invalid scrypt r parameter", "options.r", r);
- assertArgument(typeof p === "number" && p > 0 && Number.isSafeInteger(p), "invalid scrypt p parameter", "options.p", p);
- return { name: "scrypt", dkLen: 32, salt, N, r, p };
- }
- function _encryptKeystore(key, kdf, account, options) {
- const privateKey = getBytes(account.privateKey, "privateKey");
- // Override initialization vector
- const iv = options.iv != null ? getBytes(options.iv, "options.iv") : randomBytes(16);
- assertArgument(iv.length === 16, "invalid options.iv length", "options.iv", options.iv);
- // Override the uuid
- const uuidRandom = options.uuid != null
- ? getBytes(options.uuid, "options.uuid")
- : randomBytes(16);
- assertArgument(uuidRandom.length === 16, "invalid options.uuid length", "options.uuid", options.iv);
- // This will be used to encrypt the wallet (as per Web3 secret storage)
- // - 32 bytes As normal for the Web3 secret storage (derivedKey, macPrefix)
- // - 32 bytes AES key to encrypt mnemonic with (required here to be corebc Wallet)
- const derivedKey = key.slice(0, 16);
- const macPrefix = key.slice(16, 32);
- // Encrypt the private key
- const aesCtr = new CTR(derivedKey, iv);
- const ciphertext = getBytes(aesCtr.encrypt(privateKey));
- // Compute the message authentication code, used to check the password
- const mac = sha256(concat([macPrefix, ciphertext]));
- const data = {
- address: account.address.substring(2).toLowerCase(),
- id: uuidV4(uuidRandom),
- version: 3,
- Crypto: {
- cipher: "aes-128-ctr",
- cipherparams: {
- iv: hexlify(iv).substring(2),
- },
- ciphertext: hexlify(ciphertext).substring(2),
- kdf: "scrypt",
- kdfparams: {
- salt: hexlify(kdf.salt).substring(2),
- n: kdf.N,
- dklen: 32,
- p: kdf.p,
- r: kdf.r,
- },
- mac: mac.substring(2),
- },
- };
- // If we have a mnemonic, encrypt it into the JSON wallet
- if (account.mnemonic) {
- const client = options.client != null ? options.client : `corebc/${version}`;
- const path = account.mnemonic.path || defaultPath$1;
- const locale = account.mnemonic.locale || "en";
- const mnemonicKey = key.slice(32, 64);
- const entropy = getBytes(account.mnemonic.entropy, "account.mnemonic.entropy");
- const mnemonicIv = randomBytes(16);
- const mnemonicAesCtr = new CTR(mnemonicKey, mnemonicIv);
- const mnemonicCiphertext = getBytes(mnemonicAesCtr.encrypt(entropy));
- const now = new Date();
- const timestamp = now.getUTCFullYear() +
- "-" +
- zpad(now.getUTCMonth() + 1, 2) +
- "-" +
- zpad(now.getUTCDate(), 2) +
- "T" +
- zpad(now.getUTCHours(), 2) +
- "-" +
- zpad(now.getUTCMinutes(), 2) +
- "-" +
- zpad(now.getUTCSeconds(), 2) +
- ".0Z";
- const gethFilename = "UTC--" + timestamp + "--" + data.address;
- data["x-corebc"] = {
- client,
- gethFilename,
- path,
- locale,
- mnemonicCounter: hexlify(mnemonicIv).substring(2),
- mnemonicCiphertext: hexlify(mnemonicCiphertext).substring(2),
- version: "0.1",
- };
- }
- return JSON.stringify(data);
- }
- /**
- * Return the JSON Keystore Wallet for %%account%% encrypted with
- * %%password%%.
- *
- * The %%options%% can be used to tune the password-based key
- * derivation function parameters, explicitly set the random values
- * used. Any provided [[ProgressCallback]] is ignord.
- */
- function encryptKeystoreJsonSync(account, password, options) {
- if (options == null) {
- options = {};
- }
- const passwordBytes = getPassword(password);
- const kdf = getEncryptKdfParams(options);
- const key = scryptSync(passwordBytes, kdf.salt, kdf.N, kdf.r, kdf.p, 64);
- return _encryptKeystore(getBytes(key), kdf, account, options);
- }
- /**
- * Resolved to the JSON Keystore Wallet for %%account%% encrypted
- * with %%password%%.
- *
- * The %%options%% can be used to tune the password-based key
- * derivation function parameters, explicitly set the random values
- * used and provide a [[ProgressCallback]] to receive periodic updates
- * on the completion status..
- */
- async function encryptKeystoreJson(account, password, options) {
- if (options == null) {
- options = {};
- }
- const passwordBytes = getPassword(password);
- const kdf = getEncryptKdfParams(options);
- const key = await scrypt(passwordBytes, kdf.salt, kdf.N, kdf.r, kdf.p, 64, options.progressCallback);
- return _encryptKeystore(getBytes(key), kdf, account, options);
- }
-
- /**
- * Explain HD Wallets..
- *
- * @_subsection: api/wallet:HD Wallets [hd-wallets]
- */
- // import { arrayify,
- // // hexDataSlice
- // } from "../utils/data.js";
- // function sha512Hash(password: BytesLike, salt: BytesLike): Uint8Array {
- // const p = getBytes(password);
- // const s = getBytes(salt);
- // return getBytes(pbkdf2(p, s, 2048, 57, "sha512"));
- // }
- /**
- * The default derivation path for Core HD Nodes. (i.e. ``"m/44'/60'/0'/0/0"``)
- */
- const defaultPath = "m";
- // "Bitcoin seed"
- // const MasterSecret = new Uint8Array([66, 105, 116, 99, 111, 105, 110, 32, 115, 101, 101, 100]);
- const HardenedBit = 0x80000000;
- // function addScalar(a: Uint8Array, b: Uint8Array): Uint8Array {
- // b = getBytes(concat([b.slice(0, 53), "0x00000000"]));
- // b[0] &= 0xfc;
- // const c = new Uint8Array(57);
- // let hold = 0;
- // for (let i = 0; i < 57; i++) {
- // hold += a[i] + b[i];
- // c[i] = hold % 256;
- // hold = Math.floor(hold / 256);
- // }
- // return c;
- // };
- const _guard = {};
- function derivePath(node, path) {
- const components = path.split("/");
- assertArgument(components.length > 0 && (components[0] === "m" || node.depth > 0), "invalid path", "path", path);
- if (components[0] === "m") {
- components.shift();
- }
- let result = node;
- for (let i = 0; i < components.length; i++) {
- const component = components[i];
- if (component.match(/^[0-9]+'$/)) {
- const index = parseInt(component.substring(0, component.length - 1));
- assertArgument(index < HardenedBit, "invalid path index", `path[${i}]`, component);
- result = result.deriveChild(HardenedBit + index);
- }
- else if (component.match(/^[0-9]+$/)) {
- const index = parseInt(component);
- assertArgument(index < HardenedBit, "invalid path index", `path[${i}]`, component);
- result = result.deriveChild(index);
- }
- else {
- assertArgument(false, "invalid path component", `path[${i}]`, component);
- }
- }
- return result;
- }
- /**
- * An **HDNodeWallet** is a [[Signer]] backed by the private key derived
- * from an HD Node using the [[link-bip-32]] stantard.
- *
- * An HD Node forms a hierarchal structure with each HD Node having a
- * private key and the ability to derive child HD Nodes, defined by
- * a path indicating the index of each child.
- */
- class HDNodeWallet extends BaseWallet {
- /**
- * The compressed public key.
- */
- publicKey;
- prefix;
- /**
- * The fingerprint.
- *
- * A fingerprint allows quick qay to detect parent and child nodes,
- * but developers should be prepared to deal with collisions as it
- * is only 4 bytes.
- */
- fingerprint;
- /**
- * The parent fingerprint.
- */
- parentFingerprint;
- /**
- * The mnemonic used to create this HD Node, if available.
- *
- * Sources such as extended keys do not encode the mnemonic, in
- * which case this will be ``null``.
- */
- mnemonic;
- #seed;
- /**
- * The derivation path of this wallet.
- *
- * Since extended keys do not provider full path details, this
- * may be ``null``, if instantiated from a source that does not
- * enocde it.
- */
- path;
- /**
- * The child index of this wallet. Values over ``2 *\* 31`` indicate
- * the node is hardened.
- */
- index;
- /**
- * The depth of this wallet, which is the number of components
- * in its path.
- */
- depth;
- /**
- * @private
- */
- constructor({ guard, seed, signingKey, parentFingerprint, path, index, depth, mnemonic, provider, prefix, }) {
- super({
- signingKey,
- prefix,
- provider,
- });
- assertPrivate(guard, _guard, "HDNodeWallet");
- defineProperties(this, { publicKey: signingKey.publicKey });
- this.prefix = prefix;
- this.#seed = seed;
- const fingerprint = dataSlice(ripemd160(sha256(this.publicKey)), 0, 4);
- defineProperties(this, {
- parentFingerprint,
- fingerprint,
- path,
- index,
- depth,
- });
- defineProperties(this, { mnemonic });
- }
- connect(provider) {
- return new HDNodeWallet({
- guard: _guard,
- signingKey: this.signingKey,
- parentFingerprint: this.parentFingerprint,
- path: this.path,
- index: this.index,
- depth: this.depth,
- seed: this.#seed,
- mnemonic: this.mnemonic,
- provider,
- prefix: this.prefix,
- });
- }
- #account() {
- const account = {
- address: this.address,
- privateKey: this.privateKey,
- };
- const m = this.mnemonic;
- if (this.path && m && m.wordlist.locale === "en" && m.password === "") {
- account.mnemonic = {
- path: this.path,
- locale: "en",
- entropy: m.entropy,
- };
- }
- return account;
- }
- /**
- * Resolves to a [JSON Keystore Wallet](json-wallets) encrypted with
- * %%password%%.
- *
- * If %%progressCallback%% is specified, it will receive periodic
- * updates as the encryption process progreses.
- */
- async encrypt(password, progressCallback) {
- return await encryptKeystoreJson(this.#account(), password, {
- progressCallback,
- });
- }
- /**
- * Returns a [JSON Keystore Wallet](json-wallets) encryped with
- * %%password%%.
- *
- * It is preferred to use the [async version](encrypt) instead,
- * which allows a [[ProgressCallback]] to keep the user informed.
- *
- * This method will block the event loop (freezing all UI) until
- * it is complete, which may be a non-trivial duration.
- */
- encryptSync(password) {
- return encryptKeystoreJsonSync(this.#account(), password);
- }
- /**
- * Returns true if this wallet has a path, providing a Type Guard
- * that the path is non-null.
- */
- hasPath() {
- return this.path != null;
- }
- /**
- * Return the child for %%index%%.
- */
- deriveChild(_index) {
- const newPrivateKey = Ed448Goldilock.HDWalletGenerateKeyFromSeed(this.#seed, Number(_index));
- const newSigningKey = new SigningKey(newPrivateKey);
- // Base path
- let path = this.path;
- if (path) {
- path += "/" + (_index & ~HardenedBit);
- if (_index & HardenedBit) {
- path += "'";
- }
- }
- return new HDNodeWallet({
- guard: _guard,
- signingKey: newSigningKey,
- parentFingerprint: this.fingerprint,
- path,
- index: _index,
- seed: this.#seed,
- depth: this.depth + 1,
- mnemonic: this.mnemonic,
- provider: this.provider,
- prefix: this.prefix,
- });
- }
- /**
- * Return the HDNode for %%path%% from this node.
- */
- derivePath(path) {
- return derivePath(this, path);
- }
- static #fromSeed({ _seed, mnemonic, prefix, path, }) {
- const extendetPrivateKey = Ed448Goldilock.HDWalletGenerateKeyFromSeed(_seed, 0);
- const signingKey = new SigningKey(extendetPrivateKey);
- // console.log({ privateKey, thisKey: signingKey.privateKey,len:tmp.privateKey.length })
- return new HDNodeWallet({
- seed: _seed,
- guard: _guard,
- signingKey,
- parentFingerprint: "0x00000000",
- path: path || defaultPath,
- index: 0,
- depth: 0,
- mnemonic,
- provider: null,
- prefix,
- });
- }
- /**
- * Creates a new random HDNode.
- */
- static createRandom(prefix, password, path, wordlist) {
- if (password == null) {
- password = "";
- }
- if (path == null) {
- path = defaultPath;
- }
- if (wordlist == null) {
- wordlist = LangEn.wordlist();
- }
- const mnemonic = Mnemonic.fromEntropy(randomBytes(32), password, wordlist);
- return HDNodeWallet.#fromSeed({
- _seed: mnemonic.computeSeed(),
- mnemonic,
- prefix,
- }).derivePath(path);
- }
- /**
- * Create am HD Node from %%mnemonic%%.
- */
- static fromMnemonic(mnemonic, prefix, path) {
- if (!path) {
- path = defaultPath;
- }
- return HDNodeWallet.#fromSeed({
- _seed: mnemonic.computeSeed(),
- mnemonic,
- prefix,
- }).derivePath(path);
- }
- static mnemonicToSeed(mnemonic, password) {
- const seed = mnemonicToSeed(mnemonic, password);
- return seed;
- }
- /**
- * Creates an HD Node from a mnemonic %%phrase%%.
- */
- static fromPhrase({ phrase, prefix, password, path, wordlist, }) {
- if (!password) {
- password = "";
- }
- if (!path) {
- path = defaultPath;
- }
- if (!wordlist) {
- wordlist = LangEn.wordlist();
- }
- const mnemonic = Mnemonic.fromPhrase({ phrase, password, wordlist });
- const _seed = mnemonic.computeSeed();
- return HDNodeWallet.#fromSeed({
- _seed,
- mnemonic,
- prefix,
- }).derivePath(path);
- }
- /**
- * Creates an HD Node from a %%seed%%.
- */
- static fromSeed({ seed, prefix, path, }) {
- return HDNodeWallet.#fromSeed({
- _seed: seed,
- mnemonic: null,
- path: path || defaultPath,
- prefix,
- });
- }
- }
- /*
- export class HDNodeWalletManager {
- #root: HDNodeWallet;
-
- constructor(phrase: string, password?: null | string, path?: null | string, locale?: null | Wordlist) {
- if (password == null) { password = ""; }
- if (path == null) { path = "m/44'/60'/0'/0"; }
- if (locale == null) { locale = LangEn.wordlist(); }
- this.#root = HDNodeWallet.fromPhrase(phrase, password, path, locale);
- }
-
- getSigner(index?: number): HDNodeWallet {
- return this.#root.deriveChild((index == null) ? 0: index);
- }
- }
- */
- /**
- * Returns the [[link-bip-32]] path for the acount at %%index%%.
- *
- * This is the pattern used by wallets like Ledger.
- *
- * There is also an [alternate pattern](getIndexedAccountPath) used by
- * some software.
- */
- function getAccountPath(_index) {
- const index = getNumber(_index, "index");
- assertArgument(index >= 0 && index < HardenedBit, "invalid account index", "index", index);
- return `m/44'/60'/${index}'/0/0`;
- }
- /**
- * Returns the path using an alternative pattern for deriving accounts,
- * at %%index%%.
- *
- * This derivation path uses the //index// component rather than the
- * //account// component to derive sequential accounts.
- *
- * This is the pattern used by wallets like MetaMask.
- */
- function getIndexedAccountPath(_index) {
- const index = getNumber(_index, "index");
- assertArgument(index >= 0 && index < HardenedBit, "invalid account index", "index", index);
- return `m/44'/60'/0'/0/${index}`;
- }
-
- /**
- * @_subsection: api/wallet:JSON Wallets [json-wallets]
- */
- // @ts-ignore
- const { CBC, pkcs7Strip } = pkg;
- /**
- * Returns true if %%json%% is a valid JSON Crowdsale wallet.
- */
- function isCrowdsaleJson(json) {
- try {
- const data = JSON.parse(json);
- if (data.encseed) {
- return true;
- }
- }
- catch (error) { }
- return false;
- }
- /**
- * Before Core launched, it was necessary to create a wallet
- * format for backers to use, which would be used to receive xcb
- * as a reward for contributing to the project.
- *
- * The [[link-crowdsale]] format is now obsolete, but it is still
- * useful to support and the additional code is fairly trivial as
- * all the primitives required are used through core portions of
- * the library.
- */
- function decryptCrowdsaleJson(json, _password) {
- const data = JSON.parse(json);
- const password = getPassword(_password);
- // Core Address
- const address = getAddress(spelunk(data, "ethaddr:string!"));
- // Encrypted Seed
- const encseed = looseArrayify(spelunk(data, "encseed:string!"));
- assertArgument(encseed && encseed.length % 16 === 0, "invalid encseed", "json", json);
- const key = getBytes(pbkdf2(password, password, 2000, 32, "sha256")).slice(0, 16);
- const iv = encseed.slice(0, 16);
- const encryptedSeed = encseed.slice(16);
- // Decrypt the seed
- const aesCbc = new CBC(key, iv);
- const seed = pkcs7Strip(getBytes(aesCbc.decrypt(encryptedSeed)));
- // This wallet format is weird... Convert the binary encoded hex to a string.
- let seedHex = "";
- for (let i = 0; i < seed.length; i++) {
- seedHex += String.fromCharCode(seed[i]);
- }
- return { address, privateKey: id(seedHex) };
- }
-
- function stall(duration) {
- return new Promise((resolve) => {
- setTimeout(() => {
- resolve();
- }, duration);
- });
- }
- /**
- * A **Wallet** manages a single private key which is used to sign
- * transactions, messages and other common payloads.
- *
- * This class is generally the main entry point for developers
- * that wish to use a private key directly, as it can create
- * instances from a large variety of common sources, including
- * raw private key, [[link-bip-39]] mnemonics and encrypte JSON
- * wallets.
- */
- class Wallet extends BaseWallet {
- /**
- * Create a new wallet for the %%privateKey%% or %%signingKey%%, optionally connected
- * to %%provider%%.
- */
- constructor({ key, prefix, provider, }) {
- if (typeof key === "string" && !key.startsWith("0x")) {
- key = "0x" + key;
- }
- let signingKey = typeof key === "string" ? new SigningKey(key) : key;
- super({
- signingKey,
- prefix,
- provider,
- });
- }
- connect(provider) {
- return new Wallet({
- key: this.signingKey,
- prefix: this.prefix,
- provider,
- });
- }
- /**
- * Resolves to a [JSON Keystore Wallet](json-wallets) encrypted with
- * %%password%%.
- *
- * If %%progressCallback%% is specified, it will receive periodic
- * updates as the encryption process progreses.
- */
- async encrypt(password, progressCallback) {
- const account = { address: this.address, privateKey: this.privateKey };
- return await encryptKeystoreJson(account, password, { progressCallback });
- }
- /**
- * Returns a [JSON Keystore Wallet](json-wallets) encryped with
- * %%password%%.
- *
- * It is preferred to use the [async version](encrypt) instead,
- * which allows a [[ProgressCallback]] to keep the user informed.
- *
- * This method will block the event loop (freezing all UI) until
- * it is complete, which may be a non-trivial duration.
- */
- encryptSync(password) {
- const account = { address: this.address, privateKey: this.privateKey };
- return encryptKeystoreJsonSync(account, password);
- }
- static #fromAccount(account) {
- assertArgument(account, "invalid JSON wallet", "json", "[ REDACTED ]");
- const address = account.address;
- const prefix = extractPrefix(address);
- if ("mnemonic" in account &&
- account.mnemonic &&
- account.mnemonic.locale === "en") {
- const mnemonic = Mnemonic.fromEntropy(account.mnemonic.entropy);
- const wallet = HDNodeWallet.fromMnemonic(mnemonic, prefix, account.mnemonic.path);
- if (wallet.address === account.address &&
- wallet.privateKey === account.privateKey) {
- return wallet;
- }
- console.log("WARNING: JSON mismatch address/privateKey != mnemonic; fallback onto private key");
- }
- const wallet = new Wallet({
- key: account.privateKey,
- prefix,
- });
- assertArgument(wallet.address === account.address, "address/privateKey mismatch", "json", "[ REDACTED ]");
- return wallet;
- }
- /**
- * Creates (asynchronously) a **Wallet** by decrypting the %%json%%
- * with %%password%%.
- *
- * If %%progress%% is provided, it is called periodically during
- * decryption so that any UI can be updated.
- */
- static async fromEncryptedJson(json, password, progress) {
- let account = null;
- if (isKeystoreJson(json)) {
- account = await decryptKeystoreJson(json, password, progress);
- }
- else if (isCrowdsaleJson(json)) {
- if (progress) {
- progress(0);
- await stall(0);
- }
- account = decryptCrowdsaleJson(json, password);
- if (progress) {
- progress(1);
- await stall(0);
- }
- }
- return Wallet.#fromAccount(account);
- }
- /**
- * Creates a **Wallet** by decrypting the %%json%% with %%password%%.
- *
- * The [[fromEncryptedJson]] method is preferred, as this method
- * will lock up and freeze the UI during decryption, which may take
- * some time.
- */
- static fromEncryptedJsonSync(json, password) {
- let account = null;
- if (isKeystoreJson(json)) {
- account = decryptKeystoreJsonSync(json, password);
- }
- else if (isCrowdsaleJson(json)) {
- account = decryptCrowdsaleJson(json, password);
- }
- else {
- assertArgument(false, "invalid JSON wallet", "json", "[ REDACTED ]");
- }
- return Wallet.#fromAccount(account);
- }
- /**
- * Creates a new random [[HDNodeWallet]] using the avavilable
- * [cryptographic random source](randomBytes).
- *
- * If there is no crytographic random source, this will throw.
- */
- static createRandom(prefix, provider) {
- const wallet = HDNodeWallet.createRandom(prefix, undefined, undefined, undefined);
- if (provider) {
- return wallet.connect(provider);
- }
- return wallet;
- }
- /**
- * Creates a [[HDNodeWallet]] for %%phrase%%.
- */
- static fromPhrase({ phrase, prefix, provider, password, }) {
- const wallet = HDNodeWallet.fromPhrase({
- phrase,
- prefix,
- password,
- });
- if (provider) {
- return wallet.connect(provider);
- }
- return wallet;
- }
- static fromSeed({ seed, prefix, provider, path, }) {
- const wallet = HDNodeWallet.fromSeed({
- seed,
- prefix,
- path: path || defaultPath,
- });
- if (provider) {
- return wallet.connect(provider);
- }
- return wallet;
- }
- }
-
- const Base64 = ")!@#$%^&*(ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_";
- /**
- * @_ignore
- */
- function decodeBits(width, data) {
- const maxValue = (1 << width) - 1;
- const result = [];
- let accum = 0, bits = 0, flood = 0;
- for (let i = 0; i < data.length; i++) {
- // Accumulate 6 bits of data
- accum = (accum << 6) | Base64.indexOf(data[i]);
- bits += 6;
- // While we have enough for a word...
- while (bits >= width) {
- // ...read the word
- const value = accum >> (bits - width);
- accum &= (1 << (bits - width)) - 1;
- bits -= width;
- // A value of 0 indicates we exceeded maxValue, it
- // floods over into the next value
- if (value === 0) {
- flood += maxValue;
- }
- else {
- result.push(value + flood);
- flood = 0;
- }
- }
- }
- return result;
- }
-
- /**
- * @_ignore
- */
- function decodeOwlA(data, accents) {
- let words = decodeOwl(data).join(",");
- // Inject the accents
- accents.split(/,/g).forEach((accent) => {
- const match = accent.match(/^([a-z]*)([0-9]+)([0-9])(.*)$/);
- assertArgument(match !== null, "internal error parsing accents", "accents", accents);
- let posOffset = 0;
- const positions = decodeBits(parseInt(match[3]), match[4]);
- const charCode = parseInt(match[2]);
- const regex = new RegExp(`([${match[1]}])`, "g");
- words = words.replace(regex, (all, letter) => {
- const rem = --positions[posOffset];
- if (rem === 0) {
- letter = String.fromCharCode(letter.charCodeAt(0), charCode);
- posOffset++;
- }
- return letter;
- });
- });
- return words.split(",");
- }
-
- /**
- * An OWL-A format Wordlist extends the OWL format to add an
- * overlay onto an OWL format Wordlist to support diacritic
- * marks.
- *
- * This class is generally not useful to most developers as
- * it is used mainly internally to keep Wordlists for languages
- * based on latin-1 small.
- *
- * If necessary, there are tools within the ``generation/`` folder
- * to create these necessary data.
- */
- class WordlistOwlA extends WordlistOwl {
- #accent;
- constructor(locale, data, accent, checksum) {
- super(locale, data, checksum);
- this.#accent = accent;
- }
- get _accent() {
- return this.#accent;
- }
- _decodeWords() {
- return decodeOwlA(this._data, this._accent);
- }
- }
-
- const wordlists = {
- en: LangEn.wordlist(),
- };
-
- var corebc = /*#__PURE__*/Object.freeze({
- __proto__: null,
- AbiCoder: AbiCoder,
- AbstractProvider: AbstractProvider,
- AbstractSigner: AbstractSigner,
- AlchemyProvider: AlchemyProvider,
- AnkrProvider: AnkrProvider,
- BaseContract: BaseContract,
- BaseWallet: BaseWallet,
- BigNumber: BigNumber,
- Block: Block,
- BrowserProvider: BrowserProvider,
- CloudflareProvider: CloudflareProvider,
- ConstructorFragment: ConstructorFragment,
- Contract: Contract,
- ContractEventPayload: ContractEventPayload,
- ContractFactory: ContractFactory,
- ContractTransactionReceipt: ContractTransactionReceipt,
- ContractTransactionResponse: ContractTransactionResponse,
- ContractUnknownEventPayload: ContractUnknownEventPayload,
- CoreSymbol: CoreSymbol,
- Ed448Goldilock: Ed448Goldilock,
- EnergyCostPlugin: EnergyCostPlugin,
- ErrorDescription: ErrorDescription,
- ErrorFragment: ErrorFragment,
- EventFragment: EventFragment,
- EventLog: EventLog,
- EventPayload: EventPayload,
- FallbackFragment: FallbackFragment,
- FallbackProvider: FallbackProvider,
- FeeData: FeeData,
- FeeDataNetworkPlugin: FeeDataNetworkPlugin,
- FetchCancelSignal: FetchCancelSignal,
- FetchRequest: FetchRequest,
- FetchResponse: FetchResponse,
- FixedNumber: FixedNumber,
- Fragment: Fragment,
- FunctionFragment: FunctionFragment,
- HDNodeWallet: HDNodeWallet,
- Indexed: Indexed,
- InfuraProvider: InfuraProvider,
- InfuraWebSocketProvider: InfuraWebSocketProvider,
- Interface: Interface,
- IpcSocketProvider: IpcSocketProvider,
- JsonRpcApiProvider: JsonRpcApiProvider,
- JsonRpcProvider: JsonRpcProvider,
- JsonRpcSigner: JsonRpcSigner,
- LangEn: LangEn,
- Log: Log,
- LogDescription: LogDescription,
- MaxInt256: MaxInt256,
- MaxUint256: MaxUint256,
- MessagePrefix: MessagePrefix,
- MinInt256: MinInt256,
- Mnemonic: Mnemonic,
- N: N,
- NamedFragment: NamedFragment,
- Network: Network,
- NetworkPlugin: NetworkPlugin,
- NonceManager: NonceManager,
- OrePerXCB: OrePerXCB,
- ParamType: ParamType,
- PocketProvider: PocketProvider,
- QuickNodeProvider: QuickNodeProvider,
- Result: Result,
- Signature: Signature,
- SigningKey: SigningKey,
- SocketBlockSubscriber: SocketBlockSubscriber,
- SocketEventSubscriber: SocketEventSubscriber,
- SocketPendingSubscriber: SocketPendingSubscriber,
- SocketProvider: SocketProvider,
- SocketSubscriber: SocketSubscriber,
- StructFragment: StructFragment,
- Transaction: Transaction,
- TransactionDescription: TransactionDescription,
- TransactionReceipt: TransactionReceipt,
- TransactionResponse: TransactionResponse,
- Typed: Typed,
- TypedDataEncoder: TypedDataEncoder,
- UnmanagedSubscriber: UnmanagedSubscriber,
- Utf8ErrorFuncs: Utf8ErrorFuncs,
- VoidSigner: VoidSigner,
- Wallet: Wallet,
- WebSocketProvider: WebSocketProvider,
- Wordlist: Wordlist,
- WordlistOwl: WordlistOwl,
- WordlistOwlA: WordlistOwlA,
- ZeroAddress: ZeroAddress,
- ZeroHash: ZeroHash,
- accessListify: accessListify,
- arrayify: arrayify,
- assert: assert,
- assertArgument: assertArgument,
- assertArgumentCount: assertArgumentCount,
- assertNormalize: assertNormalize,
- assertPrivate: assertPrivate,
- checkResultErrors: checkResultErrors,
- computeAddress: computeAddress,
- computeHmac: computeHmac,
- concat: concat,
- copyRequest: copyRequest,
- dataLength: dataLength,
- dataSlice: dataSlice,
- decodeBase58: decodeBase58,
- decodeBase64: decodeBase64,
- decodeBytes32String: decodeBytes32String,
- decodeRlp: decodeRlp,
- decryptCrowdsaleJson: decryptCrowdsaleJson,
- decryptKeystoreJson: decryptKeystoreJson,
- decryptKeystoreJsonSync: decryptKeystoreJsonSync,
- defaultPath: defaultPath,
- defineProperties: defineProperties,
- encodeBase58: encodeBase58,
- encodeBase64: encodeBase64,
- encodeBytes32String: encodeBytes32String,
- encodeRlp: encodeRlp,
- encryptKeystoreJson: encryptKeystoreJson,
- encryptKeystoreJsonSync: encryptKeystoreJsonSync,
- formatUnits: formatUnits,
- formatXCB: formatXCB,
- fromTwos: fromTwos,
- getAccountPath: getAccountPath,
- getAddress: getAddress,
- getBigInt: getBigInt,
- getBytes: getBytes,
- getBytesCopy: getBytesCopy,
- getCreate2Address: getCreate2Address,
- getCreateAddress: getCreateAddress,
- getDefaultProvider: getDefaultProvider,
- getIndexedAccountPath: getIndexedAccountPath,
- getNumber: getNumber,
- getUint: getUint,
- hashMessage: hashMessage,
- hexConcat: hexConcat,
- hexlify: hexlify,
- id: id,
- isAddress: isAddress,
- isAddressable: isAddressable,
- isBytesLike: isBytesLike,
- isCallException: isCallException,
- isCrowdsaleJson: isCrowdsaleJson,
- isError: isError,
- isHexString: isHexString,
- isKeystoreJson: isKeystoreJson,
- keccak256: keccak256,
- lock: lock,
- makeError: makeError,
- mask: mask,
- networkIdToPrefix: networkIdToPrefix,
- parseUnits: parseUnits,
- parseXCB: parseXCB,
- pbkdf2: pbkdf2,
- publicToAddress: publicToAddress,
- randomBytes: randomBytes,
- recoverAddress: recoverAddress,
- resolveAddress: resolveAddress,
- resolveProperties: resolveProperties,
- ripemd160: ripemd160,
- scrypt: scrypt,
- scryptSync: scryptSync,
- sha256: sha256,
- sha512: sha512,
- showThrottleMessage: showThrottleMessage,
- solidityPacked: solidityPacked,
- solidityPackedSha256: solidityPackedSha256,
- stripZerosLeft: stripZerosLeft,
- toBeArray: toBeArray,
- toBeHex: toBeHex,
- toBigInt: toBigInt,
- toNumber: toNumber,
- toQuantity: toQuantity,
- toTwos: toTwos,
- toUtf8Bytes: toUtf8Bytes,
- toUtf8CodePoints: toUtf8CodePoints,
- toUtf8String: toUtf8String,
- uuidV4: uuidV4,
- verifyMessage: verifyMessage,
- verifyTypedData: verifyTypedData,
- version: version,
- wordlists: wordlists,
- zeroPadBytes: zeroPadBytes,
- zeroPadValue: zeroPadValue
- });
-
- Object.defineProperty(exports, 'Buffer', {
- enumerable: true,
- get: function () { return buffer.Buffer; }
- });
- exports.AbiCoder = AbiCoder;
- exports.AbstractProvider = AbstractProvider;
- exports.AbstractSigner = AbstractSigner;
- exports.AlchemyProvider = AlchemyProvider;
- exports.AnkrProvider = AnkrProvider;
- exports.BaseContract = BaseContract;
- exports.BaseWallet = BaseWallet;
- exports.BigNumber = BigNumber;
- exports.Block = Block;
- exports.BrowserProvider = BrowserProvider;
- exports.CloudflareProvider = CloudflareProvider;
- exports.ConstructorFragment = ConstructorFragment;
- exports.Contract = Contract;
- exports.ContractEventPayload = ContractEventPayload;
- exports.ContractFactory = ContractFactory;
- exports.ContractTransactionReceipt = ContractTransactionReceipt;
- exports.ContractTransactionResponse = ContractTransactionResponse;
- exports.ContractUnknownEventPayload = ContractUnknownEventPayload;
- exports.CoreSymbol = CoreSymbol;
- exports.Ed448Goldilock = Ed448Goldilock;
- exports.EnergyCostPlugin = EnergyCostPlugin;
- exports.ErrorDescription = ErrorDescription;
- exports.ErrorFragment = ErrorFragment;
- exports.EventFragment = EventFragment;
- exports.EventLog = EventLog;
- exports.EventPayload = EventPayload;
- exports.FallbackFragment = FallbackFragment;
- exports.FallbackProvider = FallbackProvider;
- exports.FeeData = FeeData;
- exports.FeeDataNetworkPlugin = FeeDataNetworkPlugin;
- exports.FetchCancelSignal = FetchCancelSignal;
- exports.FetchRequest = FetchRequest;
- exports.FetchResponse = FetchResponse;
- exports.FixedNumber = FixedNumber;
- exports.Fragment = Fragment;
- exports.FunctionFragment = FunctionFragment;
- exports.HDNodeWallet = HDNodeWallet;
- exports.Indexed = Indexed;
- exports.InfuraProvider = InfuraProvider;
- exports.InfuraWebSocketProvider = InfuraWebSocketProvider;
- exports.Interface = Interface;
- exports.IpcSocketProvider = IpcSocketProvider;
- exports.JsonRpcApiProvider = JsonRpcApiProvider;
- exports.JsonRpcProvider = JsonRpcProvider;
- exports.JsonRpcSigner = JsonRpcSigner;
- exports.LangEn = LangEn;
- exports.Log = Log;
- exports.LogDescription = LogDescription;
- exports.MaxInt256 = MaxInt256;
- exports.MaxUint256 = MaxUint256;
- exports.MessagePrefix = MessagePrefix;
- exports.MinInt256 = MinInt256;
- exports.Mnemonic = Mnemonic;
- exports.N = N;
- exports.NamedFragment = NamedFragment;
- exports.Network = Network;
- exports.NetworkPlugin = NetworkPlugin;
- exports.NonceManager = NonceManager;
- exports.OrePerXCB = OrePerXCB;
- exports.ParamType = ParamType;
- exports.PocketProvider = PocketProvider;
- exports.QuickNodeProvider = QuickNodeProvider;
- exports.Result = Result;
- exports.Signature = Signature;
- exports.SigningKey = SigningKey;
- exports.SocketBlockSubscriber = SocketBlockSubscriber;
- exports.SocketEventSubscriber = SocketEventSubscriber;
- exports.SocketPendingSubscriber = SocketPendingSubscriber;
- exports.SocketProvider = SocketProvider;
- exports.SocketSubscriber = SocketSubscriber;
- exports.StructFragment = StructFragment;
- exports.Transaction = Transaction;
- exports.TransactionDescription = TransactionDescription;
- exports.TransactionReceipt = TransactionReceipt;
- exports.TransactionResponse = TransactionResponse;
- exports.Typed = Typed;
- exports.TypedDataEncoder = TypedDataEncoder;
- exports.UnmanagedSubscriber = UnmanagedSubscriber;
- exports.Utf8ErrorFuncs = Utf8ErrorFuncs;
- exports.VoidSigner = VoidSigner;
- exports.Wallet = Wallet;
- exports.WebSocketProvider = WebSocketProvider;
- exports.Wordlist = Wordlist;
- exports.WordlistOwl = WordlistOwl;
- exports.WordlistOwlA = WordlistOwlA;
- exports.ZeroAddress = ZeroAddress;
- exports.ZeroHash = ZeroHash;
- exports.accessListify = accessListify;
- exports.arrayify = arrayify;
- exports.assert = assert;
- exports.assertArgument = assertArgument;
- exports.assertArgumentCount = assertArgumentCount;
- exports.assertNormalize = assertNormalize;
- exports.assertPrivate = assertPrivate;
- exports.checkResultErrors = checkResultErrors;
- exports.computeAddress = computeAddress;
- exports.computeHmac = computeHmac;
- exports.concat = concat;
- exports.copyRequest = copyRequest;
- exports.corebc = corebc;
- exports.dataLength = dataLength;
- exports.dataSlice = dataSlice;
- exports.decodeBase58 = decodeBase58;
- exports.decodeBase64 = decodeBase64;
- exports.decodeBytes32String = decodeBytes32String;
- exports.decodeRlp = decodeRlp;
- exports.decryptCrowdsaleJson = decryptCrowdsaleJson;
- exports.decryptKeystoreJson = decryptKeystoreJson;
- exports.decryptKeystoreJsonSync = decryptKeystoreJsonSync;
- exports.defaultPath = defaultPath;
- exports.defineProperties = defineProperties;
- exports.encodeBase58 = encodeBase58;
- exports.encodeBase64 = encodeBase64;
- exports.encodeBytes32String = encodeBytes32String;
- exports.encodeRlp = encodeRlp;
- exports.encryptKeystoreJson = encryptKeystoreJson;
- exports.encryptKeystoreJsonSync = encryptKeystoreJsonSync;
- exports.formatUnits = formatUnits;
- exports.formatXCB = formatXCB;
- exports.fromTwos = fromTwos;
- exports.getAccountPath = getAccountPath;
- exports.getAddress = getAddress;
- exports.getBigInt = getBigInt;
- exports.getBytes = getBytes;
- exports.getBytesCopy = getBytesCopy;
- exports.getCreate2Address = getCreate2Address;
- exports.getCreateAddress = getCreateAddress;
- exports.getDefaultProvider = getDefaultProvider;
- exports.getIndexedAccountPath = getIndexedAccountPath;
- exports.getNumber = getNumber;
- exports.getUint = getUint;
- exports.hashMessage = hashMessage;
- exports.hexConcat = hexConcat;
- exports.hexlify = hexlify;
- exports.id = id;
- exports.isAddress = isAddress;
- exports.isAddressable = isAddressable;
- exports.isBytesLike = isBytesLike;
- exports.isCallException = isCallException;
- exports.isCrowdsaleJson = isCrowdsaleJson;
- exports.isError = isError;
- exports.isHexString = isHexString;
- exports.isKeystoreJson = isKeystoreJson;
- exports.keccak256 = keccak256;
- exports.lock = lock;
- exports.makeError = makeError;
- exports.mask = mask;
- exports.networkIdToPrefix = networkIdToPrefix;
- exports.parseUnits = parseUnits;
- exports.parseXCB = parseXCB;
- exports.pbkdf2 = pbkdf2;
- exports.publicToAddress = publicToAddress;
- exports.randomBytes = randomBytes;
- exports.recoverAddress = recoverAddress;
- exports.resolveAddress = resolveAddress;
- exports.resolveProperties = resolveProperties;
- exports.ripemd160 = ripemd160;
- exports.scrypt = scrypt;
- exports.scryptSync = scryptSync;
- exports.sha256 = sha256;
- exports.sha512 = sha512;
- exports.showThrottleMessage = showThrottleMessage;
- exports.solidityPacked = solidityPacked;
- exports.solidityPackedSha256 = solidityPackedSha256;
- exports.stripZerosLeft = stripZerosLeft;
- exports.toBeArray = toBeArray;
- exports.toBeHex = toBeHex;
- exports.toBigInt = toBigInt;
- exports.toNumber = toNumber;
- exports.toQuantity = toQuantity;
- exports.toTwos = toTwos;
- exports.toUtf8Bytes = toUtf8Bytes;
- exports.toUtf8CodePoints = toUtf8CodePoints;
- exports.toUtf8String = toUtf8String;
- exports.uuidV4 = uuidV4;
- exports.verifyMessage = verifyMessage;
- exports.verifyTypedData = verifyTypedData;
- exports.version = version;
- exports.wordlists = wordlists;
- exports.zeroPadBytes = zeroPadBytes;
- exports.zeroPadValue = zeroPadValue;
-
-}));
-//# sourceMappingURL=corebc.umd.js.map
diff --git a/dist/corebc.umd.js.map b/dist/corebc.umd.js.map
deleted file mode 100644
index 3f31b9535..000000000
--- a/dist/corebc.umd.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"corebc.umd.js","sources":["../lib.esm/_version.js","../lib.esm/logger/logger.js","../lib.esm/utils/properties.js","../lib.esm/utils/errors.js","../lib.esm/utils/data.js","../lib.esm/bigNumber/bigNumber.js","../lib.esm/crypto/rlp.js","../node_modules/@noble/hashes/esm/_assert.js","../node_modules/@noble/hashes/esm/utils.js","../node_modules/@noble/hashes/esm/hmac.js","../node_modules/@noble/hashes/esm/pbkdf2.js","../node_modules/@noble/hashes/esm/_sha2.js","../node_modules/@noble/hashes/esm/sha256.js","../node_modules/@noble/hashes/esm/_u64.js","../node_modules/@noble/hashes/esm/sha512.js","../node_modules/@noble/hashes/esm/sha3.js","../lib.esm/utils/maths.js","../lib.esm/utils/base58.js","../lib.esm/utils/base64-browser.js","../lib.esm/utils/events.js","../lib.esm/utils/utf8.js","../lib.esm/utils/geturl-browser.js","../lib.esm/utils/fetch.js","../lib.esm/utils/fixednumber.js","../lib.esm/utils/rlp-decode.js","../lib.esm/utils/rlp-encode.js","../lib.esm/utils/units.js","../lib.esm/utils/uuid.js","../lib.esm/crypto/ed448goldilock-browser.js","../lib.esm/crypto/crypto-browser.js","../lib.esm/crypto/sha3.js","../lib.esm/address/index.js","../lib.esm/crypto/hmac.js","../node_modules/@noble/hashes/esm/ripemd160.js","../lib.esm/crypto/ripemd160.js","../lib.esm/crypto/pbkdf2.js","../lib.esm/crypto/random.js","../node_modules/@noble/hashes/esm/scrypt.js","../lib.esm/crypto/scrypt.js","../lib.esm/crypto/keccak.js","../node_modules/@noble/secp256k1/index.js","../lib.esm/crypto/signing-key.js","../lib.esm/crypto/signature.js","../lib.esm/crypto/index.js","../lib.esm/transaction/address.js","../lib.esm/abi/coders/abstract-coder.js","../lib.esm/abi/typed.js","../lib.esm/abi/coders/address.js","../lib.esm/abi/coders/anonymous.js","../lib.esm/abi/coders/array.js","../lib.esm/abi/coders/boolean.js","../lib.esm/abi/coders/bytes.js","../lib.esm/abi/coders/fixed-bytes.js","../lib.esm/abi/coders/null.js","../lib.esm/abi/coders/number.js","../lib.esm/abi/coders/string.js","../lib.esm/abi/coders/tuple.js","../lib.esm/hash/id.js","../lib.esm/constants/addresses.js","../lib.esm/constants/hashes.js","../lib.esm/constants/numbers.js","../lib.esm/constants/strings.js","../lib.esm/transaction/accesslist.js","../lib.esm/transaction/transaction.js","../lib.esm/hash/message.js","../lib.esm/hash/solidity.js","../lib.esm/hash/typed-data.js","../lib.esm/abi/fragments.js","../lib.esm/abi/abi-coder.js","../lib.esm/abi/bytes32.js","../lib.esm/abi/interface.js","../lib.esm/address/contract-address.js","../lib.esm/address/checks.js","../lib.esm/providers/provider.js","../lib.esm/contract/wrappers.js","../lib.esm/contract/contract.js","../lib.esm/contract/factory.js","../lib.esm/providers/format.js","../lib.esm/providers/plugins-network.js","../lib.esm/providers/network.js","../lib.esm/providers/subscriber-polling.js","../lib.esm/providers/abstract-provider.js","../lib.esm/providers/abstract-signer.js","../lib.esm/providers/community.js","../lib.esm/providers/subscriber-filterid.js","../lib.esm/providers/provider-jsonrpc.js","../lib.esm/providers/provider-ankr.js","../lib.esm/providers/provider-alchemy.js","../lib.esm/providers/provider-cloudflare.js","../lib.esm/providers/ws-browser.js","../lib.esm/providers/provider-socket.js","../lib.esm/providers/provider-websocket.js","../lib.esm/providers/provider-infura.js","../lib.esm/providers/provider-quicknode.js","../lib.esm/providers/provider-fallback.js","../lib.esm/providers/default-provider.js","../lib.esm/providers/signer-noncemanager.js","../lib.esm/providers/provider-browser.js","../lib.esm/providers/provider-pocket.js","../lib.esm/providers/provider-ipcsocket-browser.js","../lib.esm/wallet/base-wallet.js","../lib.esm/wordlists/decode-owl.js","../lib.esm/wordlists/wordlist.js","../lib.esm/wordlists/wordlist-owl.js","../lib.esm/wordlists/lang-en.js","../lib.esm/wallet/mnemonicToSeed.js","../lib.esm/wallet/mnemonic.js","../lib.esm/wallet/utils.js","../lib.esm/wallet/json-keystore.js","../lib.esm/wallet/hdwallet.js","../lib.esm/wallet/json-crowdsale.js","../lib.esm/wallet/wallet.js","../lib.esm/wordlists/bit-reader.js","../lib.esm/wordlists/decode-owla.js","../lib.esm/wordlists/wordlist-owla.js","../lib.esm/wordlists/wordlists-browser.js"],"sourcesContent":["/* Do NOT modify this file; see /src.ts/_admin/update-version.ts */\n/**\n * The current version of corebc.\n */\nexport const version = \"6.4.0\";\n//# sourceMappingURL=_version.js.map","\"use strict\";\nlet _permanentCensorErrors = false;\nlet _censorErrors = false;\nconst LogLevels = {\n debug: 1,\n default: 2,\n info: 2,\n warning: 3,\n error: 4,\n off: 5,\n};\nlet _logLevel = LogLevels[\"default\"];\nlet _globalLogger = null;\nfunction _checkNormalize() {\n try {\n const missing = [];\n // Make sure all forms of normalization are supported\n [\"NFD\", \"NFC\", \"NFKD\", \"NFKC\"].forEach((form) => {\n try {\n if (\"test\".normalize(form) !== \"test\") {\n throw new Error(\"bad normalize\");\n }\n }\n catch (error) {\n missing.push(form);\n }\n });\n if (missing.length) {\n throw new Error(\"missing \" + missing.join(\", \"));\n }\n if (String.fromCharCode(0xe9).normalize(\"NFD\") !==\n String.fromCharCode(0x65, 0x0301)) {\n throw new Error(\"broken implementation\");\n }\n }\n catch (error) {\n return error.message;\n }\n return null;\n}\nconst _normalizeError = _checkNormalize();\nexport var LogLevel;\n(function (LogLevel) {\n LogLevel[\"DEBUG\"] = \"DEBUG\";\n LogLevel[\"INFO\"] = \"INFO\";\n LogLevel[\"WARNING\"] = \"WARNING\";\n LogLevel[\"ERROR\"] = \"ERROR\";\n LogLevel[\"OFF\"] = \"OFF\";\n})(LogLevel || (LogLevel = {}));\nexport var ErrorCode;\n(function (ErrorCode) {\n ///////////////////\n // Generic Errors\n // Unknown Error\n ErrorCode[\"UNKNOWN_ERROR\"] = \"UNKNOWN_ERROR\";\n // Not Implemented\n ErrorCode[\"NOT_IMPLEMENTED\"] = \"NOT_IMPLEMENTED\";\n // Unsupported Operation\n // - operation\n ErrorCode[\"UNSUPPORTED_OPERATION\"] = \"UNSUPPORTED_OPERATION\";\n // Network Error (i.e. Core Network, such as an invalid network ID)\n // - event (\"noNetwork\" is not re-thrown in provider.ready; otherwise thrown)\n ErrorCode[\"NETWORK_ERROR\"] = \"NETWORK_ERROR\";\n // Some sort of bad response from the server\n ErrorCode[\"SERVER_ERROR\"] = \"SERVER_ERROR\";\n // Timeout\n ErrorCode[\"TIMEOUT\"] = \"TIMEOUT\";\n ///////////////////\n // Operational Errors\n // Buffer Overrun\n ErrorCode[\"BUFFER_OVERRUN\"] = \"BUFFER_OVERRUN\";\n // Numeric Fault\n // - operation: the operation being executed\n // - fault: the reason this faulted\n ErrorCode[\"NUMERIC_FAULT\"] = \"NUMERIC_FAULT\";\n ///////////////////\n // Argument Errors\n // Missing new operator to an object\n // - name: The name of the class\n ErrorCode[\"MISSING_NEW\"] = \"MISSING_NEW\";\n // Invalid argument (e.g. value is incompatible with type) to a function:\n // - argument: The argument name that was invalid\n // - value: The value of the argument\n ErrorCode[\"INVALID_ARGUMENT\"] = \"INVALID_ARGUMENT\";\n // Missing argument to a function:\n // - count: The number of arguments received\n // - expectedCount: The number of arguments expected\n ErrorCode[\"MISSING_ARGUMENT\"] = \"MISSING_ARGUMENT\";\n // Too many arguments\n // - count: The number of arguments received\n // - expectedCount: The number of arguments expected\n ErrorCode[\"UNEXPECTED_ARGUMENT\"] = \"UNEXPECTED_ARGUMENT\";\n ///////////////////\n // Blockchain Errors\n // Call exception\n // - transaction: the transaction\n // - address?: the contract address\n // - args?: The arguments passed into the function\n // - method?: The Solidity method signature\n // - errorSignature?: The EIP848 error signature\n // - errorArgs?: The EIP848 error parameters\n // - reason: The reason (only for EIP848 \"Error(string)\")\n ErrorCode[\"CALL_EXCEPTION\"] = \"CALL_EXCEPTION\";\n // Insufficient funds (< value + energyLimit * energyPrice)\n // - transaction: the transaction attempted\n ErrorCode[\"INSUFFICIENT_FUNDS\"] = \"INSUFFICIENT_FUNDS\";\n // Nonce has already been used\n // - transaction: the transaction attempted\n ErrorCode[\"NONCE_EXPIRED\"] = \"NONCE_EXPIRED\";\n // The replacement fee for the transaction is too low\n // - transaction: the transaction attempted\n ErrorCode[\"REPLACEMENT_UNDERPRICED\"] = \"REPLACEMENT_UNDERPRICED\";\n // The energy limit could not be estimated\n // - transaction: the transaction passed to estimateEnergy\n ErrorCode[\"UNPREDICTABLE_ENERGY_LIMIT\"] = \"UNPREDICTABLE_ENERGY_LIMIT\";\n // The transaction was replaced by one with a higher energy price\n // - reason: \"cancelled\", \"replaced\" or \"repriced\"\n // - cancelled: true if reason == \"cancelled\" or reason == \"replaced\")\n // - hash: original transaction hash\n // - replacement: the full TransactionsResponse for the replacement\n // - receipt: the receipt of the replacement\n ErrorCode[\"TRANSACTION_REPLACED\"] = \"TRANSACTION_REPLACED\";\n})(ErrorCode || (ErrorCode = {}));\nconst HEX = \"0123456789abcdef\";\nexport class Logger {\n version = \"0.0.1\";\n static errors = ErrorCode;\n static levels = LogLevel;\n constructor(version) {\n Object.defineProperty(this, \"version\", {\n enumerable: true,\n value: version,\n writable: false,\n });\n }\n _log(logLevel, args) {\n const level = logLevel.toLowerCase();\n if (LogLevels[level] == null) {\n this.throwArgumentError(\"invalid log level name\", \"logLevel\", logLevel);\n }\n if (_logLevel > LogLevels[level]) {\n return;\n }\n console.log.apply(console, args);\n }\n debug(...args) {\n this._log(Logger.levels.DEBUG, args);\n }\n info(...args) {\n this._log(Logger.levels.INFO, args);\n }\n warn(...args) {\n this._log(Logger.levels.WARNING, args);\n }\n makeError(message, code, params) {\n // Errors are being censored\n if (_censorErrors) {\n return this.makeError(\"censored error\", code, {});\n }\n if (!code) {\n code = Logger.errors.UNKNOWN_ERROR;\n }\n if (!params) {\n params = {};\n }\n const messageDetails = [];\n Object.keys(params).forEach((key) => {\n const value = params[key];\n try {\n if (value instanceof Uint8Array) {\n let hex = \"\";\n for (let i = 0; i < value.length; i++) {\n hex += HEX[value[i] >> 4];\n hex += HEX[value[i] & 0x0f];\n }\n messageDetails.push(key + \"=Uint8Array(0x\" + hex + \")\");\n }\n else {\n messageDetails.push(key + \"=\" + JSON.stringify(value));\n }\n }\n catch (error) {\n messageDetails.push(key + \"=\" + JSON.stringify(params[key].toString()));\n }\n });\n messageDetails.push(`code=${code}`);\n messageDetails.push(`version=${this.version}`);\n const reason = message;\n if (messageDetails.length) {\n message += \" (\" + messageDetails.join(\", \") + \")\";\n }\n // @TODO: Any??\n const error = new Error(message);\n error.reason = reason;\n error.code = code;\n Object.keys(params).forEach(function (key) {\n error[key] = params[key];\n });\n return error;\n }\n throwError(message, code, params) {\n throw this.makeError(message, code, params);\n }\n throwArgumentError(message, name, value) {\n return this.throwError(message, Logger.errors.INVALID_ARGUMENT, {\n argument: name,\n value: value,\n });\n }\n assert(condition, message, code, params) {\n if (!!condition) {\n return;\n }\n this.throwError(message, code, params);\n }\n assertArgument(condition, message, name, value) {\n if (!!condition) {\n return;\n }\n this.throwArgumentError(message, name, value);\n }\n checkNormalize(message) {\n if (message == null) {\n message = \"platform missing String.prototype.normalize\";\n }\n if (_normalizeError) {\n this.throwError(\"platform missing String.prototype.normalize\", Logger.errors.UNSUPPORTED_OPERATION, {\n operation: \"String.prototype.normalize\",\n form: _normalizeError,\n });\n }\n }\n checkSafeUint53(value, message) {\n if (typeof value !== \"number\") {\n return;\n }\n if (message == null) {\n message = \"value not safe\";\n }\n if (value < 0 || value >= 0x1fffffffffffff) {\n this.throwError(message, Logger.errors.NUMERIC_FAULT, {\n operation: \"checkSafeInteger\",\n fault: \"out-of-safe-range\",\n value: value,\n });\n }\n if (value % 1) {\n this.throwError(message, Logger.errors.NUMERIC_FAULT, {\n operation: \"checkSafeInteger\",\n fault: \"non-integer\",\n value: value,\n });\n }\n }\n checkArgumentCount(count, expectedCount, message) {\n if (message) {\n message = \": \" + message;\n }\n else {\n message = \"\";\n }\n if (count < expectedCount) {\n this.throwError(\"missing argument\" + message, Logger.errors.MISSING_ARGUMENT, {\n count: count,\n expectedCount: expectedCount,\n });\n }\n if (count > expectedCount) {\n this.throwError(\"too many arguments\" + message, Logger.errors.UNEXPECTED_ARGUMENT, {\n count: count,\n expectedCount: expectedCount,\n });\n }\n }\n checkNew(target, kind) {\n if (target === Object || target == null) {\n this.throwError(\"missing new\", Logger.errors.MISSING_NEW, {\n name: kind.name,\n });\n }\n }\n checkAbstract(target, kind) {\n if (target === kind) {\n this.throwError(\"cannot instantiate abstract class \" +\n JSON.stringify(kind.name) +\n \" directly; use a sub-class\", Logger.errors.UNSUPPORTED_OPERATION, { name: target.name, operation: \"new\" });\n }\n else if (target === Object || target == null) {\n this.throwError(\"missing new\", Logger.errors.MISSING_NEW, {\n name: kind.name,\n });\n }\n }\n static globalLogger() {\n if (!_globalLogger) {\n _globalLogger = new Logger(\"logger/0.0.1\");\n }\n return _globalLogger;\n }\n static setCensorship(censorship, permanent) {\n if (!censorship && permanent) {\n this.globalLogger().throwError(\"cannot permanently disable censorship\", Logger.errors.UNSUPPORTED_OPERATION, {\n operation: \"setCensorship\",\n });\n }\n if (_permanentCensorErrors) {\n if (!censorship) {\n return;\n }\n this.globalLogger().throwError(\"error censorship permanent\", Logger.errors.UNSUPPORTED_OPERATION, {\n operation: \"setCensorship\",\n });\n }\n _censorErrors = !!censorship;\n _permanentCensorErrors = !!permanent;\n }\n static setLogLevel(logLevel) {\n const level = LogLevels[logLevel.toLowerCase()];\n if (level == null) {\n Logger.globalLogger().warn(\"invalid log level - \" + logLevel);\n return;\n }\n _logLevel = level;\n }\n static from(version) {\n return new Logger(version);\n }\n}\n//# sourceMappingURL=logger.js.map","import { Logger } from \"../logger/logger.js\";\n/**\n * Property helper functions.\n *\n * @_subsection api/utils:Properties [about-properties]\n */\nconst logger = new Logger(\"utils/properties/0.0.1\");\nfunction checkType(value, type, name) {\n const types = type.split(\"|\").map((t) => t.trim());\n for (let i = 0; i < types.length; i++) {\n switch (type) {\n case \"any\":\n return;\n case \"bigint\":\n case \"boolean\":\n case \"number\":\n case \"string\":\n if (typeof value === type) {\n return;\n }\n }\n }\n const error = new Error(`invalid value for type ${type}`);\n error.code = \"INVALID_ARGUMENT\";\n error.argument = `value.${name}`;\n error.value = value;\n throw error;\n}\n/**\n * Resolves to a new object that is a copy of %%value%%, but with all\n * values resolved.\n */\nexport async function resolveProperties(value) {\n const keys = Object.keys(value);\n const results = await Promise.all(keys.map((k) => Promise.resolve(value[k])));\n return results.reduce((accum, v, index) => {\n accum[keys[index]] = v;\n return accum;\n }, {});\n}\n/**\n * Assigns the %%values%% to %%target%% as read-only values.\n *\n * It %%types%% is specified, the values are checked.\n */\nexport function defineProperties(target, values, types) {\n for (let key in values) {\n let value = values[key];\n const type = types ? types[key] : null;\n if (type) {\n checkType(value, type, key);\n }\n Object.defineProperty(target, key, {\n enumerable: true,\n value,\n writable: false,\n });\n }\n}\nexport function checkProperties(object, properties) {\n if (!object || typeof object !== \"object\") {\n logger.throwArgumentError(\"invalid object\", \"object\", object);\n }\n Object.keys(object).forEach((key) => {\n if (!properties[key]) {\n logger.throwArgumentError(\"invalid object key - \" + key, \"transaction:\" + key, object);\n }\n });\n}\n//# sourceMappingURL=properties.js.map","/**\n * About Errors.\n *\n * @_section: api/utils/errors:Errors [about-errors]\n */\nimport { version } from \"../_version.js\";\nimport { defineProperties } from \"./properties.js\";\nfunction stringify(value) {\n if (value == null) {\n return \"null\";\n }\n if (Array.isArray(value)) {\n return \"[ \" + value.map(stringify).join(\", \") + \" ]\";\n }\n if (value instanceof Uint8Array) {\n const HEX = \"0123456789abcdef\";\n let result = \"0x\";\n for (let i = 0; i < value.length; i++) {\n result += HEX[value[i] >> 4];\n result += HEX[value[i] & 0xf];\n }\n return result;\n }\n if (typeof value === \"object\" && typeof value.toJSON === \"function\") {\n return stringify(value.toJSON());\n }\n switch (typeof value) {\n case \"boolean\":\n case \"symbol\":\n return value.toString();\n case \"bigint\":\n return BigInt(value).toString();\n case \"number\":\n return value.toString();\n case \"string\":\n return JSON.stringify(value);\n case \"object\": {\n const keys = Object.keys(value);\n keys.sort();\n return (\"{ \" +\n keys.map((k) => `${stringify(k)}: ${stringify(value[k])}`).join(\", \") +\n \" }\");\n }\n }\n return `[ COULD NOT SERIALIZE ]`;\n}\n/**\n * Returns true if the %%error%% matches an error thrown by corebc\n * that matches the error %%code%%.\n *\n * In TypeScript envornoments, this can be used to check that %%error%%\n * matches an corebcError type, which means the expected properties will\n * be set.\n *\n * @See [ErrorCodes](api:ErrorCode)\n * @example\n * try {\n * // code....\n * } catch (e) {\n * if (isError(e, \"CALL_EXCEPTION\")) {\n * // The Type Guard has validated this object\n * console.log(e.data);\n * }\n * }\n */\nexport function isError(error, code) {\n return error && error.code === code;\n}\n/**\n * Returns true if %%error%% is a [[CallExceptionError].\n */\nexport function isCallException(error) {\n return isError(error, \"CALL_EXCEPTION\");\n}\n/**\n * Returns a new Error configured to the format corebc emits errors, with\n * the %%message%%, [[api:ErrorCode]] %%code%% and additioanl properties\n * for the corresponding corebcError.\n *\n * Each error in corebc includes the version of corebc, a\n * machine-readable [[ErrorCode]], and depneding on %%code%%, additional\n * required properties. The error message will also include the %%meeage%%,\n * corebc version, %%code%% and all aditional properties, serialized.\n */\nexport function makeError(message, code, info) {\n {\n const details = [];\n if (info) {\n if (\"message\" in info || \"code\" in info || \"name\" in info) {\n throw new Error(`value will overwrite populated values: ${stringify(info)}`);\n }\n for (const key in info) {\n const value = info[key];\n // try {\n details.push(key + \"=\" + stringify(value));\n // } catch (error: any) {\n // console.log(\"MMM\", error.message);\n // details.push(key + \"=[could not serialize object]\");\n // }\n }\n }\n details.push(`code=${code}`);\n details.push(`version=${version}`);\n if (details.length) {\n message += \" (\" + details.join(\", \") + \")\";\n }\n }\n let error;\n switch (code) {\n case \"INVALID_ARGUMENT\":\n error = new TypeError(message);\n break;\n case \"NUMERIC_FAULT\":\n case \"BUFFER_OVERRUN\":\n error = new RangeError(message);\n break;\n default:\n error = new Error(message);\n }\n defineProperties(error, { code });\n if (info) {\n Object.assign(error, info);\n }\n return error;\n}\n/**\n * Throws an corebcError with %%message%%, %%code%% and additional error\n * %%info%% when %%check%% is falsish..\n *\n * @see [[api:makeError]]\n */\nexport function assert(check, message, code, info) {\n if (!check) {\n throw makeError(message, code, info);\n }\n}\n/**\n * A simple helper to simply ensuring provided arguments match expected\n * constraints, throwing if not.\n *\n * In TypeScript environments, the %%check%% has been asserted true, so\n * any further code does not need additional compile-time checks.\n */\nexport function assertArgument(check, message, name, value) {\n assert(check, message, \"INVALID_ARGUMENT\", { argument: name, value: value });\n}\nexport function assertArgumentCount(count, expectedCount, message) {\n if (message == null) {\n message = \"\";\n }\n if (message) {\n message = \": \" + message;\n }\n assert(count >= expectedCount, \"missing arguemnt\" + message, \"MISSING_ARGUMENT\", {\n count: count,\n expectedCount: expectedCount,\n });\n assert(count <= expectedCount, \"too many arguemnts\" + message, \"UNEXPECTED_ARGUMENT\", {\n count: count,\n expectedCount: expectedCount,\n });\n}\nconst _normalizeForms = [\"NFD\", \"NFC\", \"NFKD\", \"NFKC\"].reduce((accum, form) => {\n try {\n // General test for normalize\n /* c8 ignore start */\n if (\"test\".normalize(form) !== \"test\") {\n throw new Error(\"bad\");\n }\n /* c8 ignore stop */\n if (form === \"NFD\") {\n const check = String.fromCharCode(0xe9).normalize(\"NFD\");\n const expected = String.fromCharCode(0x65, 0x0301);\n /* c8 ignore start */\n if (check !== expected) {\n throw new Error(\"broken\");\n }\n /* c8 ignore stop */\n }\n accum.push(form);\n }\n catch (error) { }\n return accum;\n}, []);\n/**\n * Throws if the normalization %%form%% is not supported.\n */\nexport function assertNormalize(form) {\n assert(_normalizeForms.indexOf(form) >= 0, \"platform missing String.prototype.normalize\", \"UNSUPPORTED_OPERATION\", {\n operation: \"String.prototype.normalize\",\n info: { form },\n });\n}\n/**\n * Many classes use file-scoped values to guard the constructor,\n * making it effectively private. This facilitates that pattern\n * by ensuring the %%givenGaurd%% matches the file-scoped %%guard%%,\n * throwing if not, indicating the %%className%% if provided.\n */\nexport function assertPrivate(givenGuard, guard, className) {\n if (className == null) {\n className = \"\";\n }\n if (givenGuard !== guard) {\n let method = className, operation = \"new\";\n if (className) {\n method += \".\";\n operation += \" \" + className;\n }\n assert(false, `private constructor; use ${method}from* methods`, \"UNSUPPORTED_OPERATION\", {\n operation,\n });\n }\n}\n//# sourceMappingURL=errors.js.map","/**\n * Some data helpers.\n *\n *\n * @_subsection api/utils:Data Helpers [about-data]\n */\nimport { Logger } from \"../logger/logger.js\";\nimport { assert, assertArgument } from \"./errors.js\";\nconst logger = new Logger(\"utils/data/0.0.1\");\nfunction isHexable(value) {\n return !!value.toHexString;\n}\nfunction isInteger(value) {\n return typeof value === \"number\" && value == value && value % 1 === 0;\n}\nexport function isBytes(value) {\n if (value == null) {\n return false;\n }\n if (value.constructor === Uint8Array) {\n return true;\n }\n if (typeof value === \"string\") {\n return false;\n }\n if (!isInteger(value.length) || value.length < 0) {\n return false;\n }\n for (let i = 0; i < value.length; i++) {\n const v = value[i];\n if (!isInteger(v) || v < 0 || v >= 256) {\n return false;\n }\n }\n return true;\n}\nfunction _getBytes(value, name, copy) {\n if (value instanceof Uint8Array) {\n if (copy) {\n return new Uint8Array(value);\n }\n return value;\n }\n if (typeof value === \"string\" && value.match(/^0x([0-9a-f][0-9a-f])*$/i)) {\n const result = new Uint8Array((value.length - 2) / 2);\n let offset = 2;\n for (let i = 0; i < result.length; i++) {\n result[i] = parseInt(value.substring(offset, offset + 2), 16);\n offset += 2;\n }\n return result;\n }\n assertArgument(false, \"invalid BytesLike value\", name || \"value\", value);\n}\n/**\n * Get a typed Uint8Array for %%value%%. If already a Uint8Array\n * the original %%value%% is returned; if a copy is required use\n * [[getBytesCopy]].\n *\n * @see: getBytesCopy\n */\nexport function getBytes(value, name) {\n return _getBytes(value, name, false);\n}\n/**\n * Get a typed Uint8Array for %%value%%, creating a copy if necessary\n * to prevent any modifications of the returned value from being\n * reflected elsewhere.\n *\n * @see: getBytes\n */\nexport function getBytesCopy(value, name) {\n return _getBytes(value, name, true);\n}\n/**\n * Returns true if %%value%% is a valid [[HexString]].\n *\n * If %%length%% is ``true`` or a //number//, it also checks that\n * %%value%% is a valid [[DataHexString]] of %%length%% (if a //number//)\n * bytes of data (e.g. ``0x1234`` is 2 bytes).\n */\nexport function isHexString(value, length) {\n if (typeof value !== \"string\" || !value.match(/^0x[0-9A-Fa-f]*$/)) {\n return false;\n }\n if (typeof length === \"number\" && value.length !== 2 + 2 * length) {\n return false;\n }\n if (length === true && value.length % 2 !== 0) {\n return false;\n }\n return true;\n}\n/**\n * Returns true if %%value%% is a valid representation of arbitrary\n * data (i.e. a valid [[DataHexString]] or a Uint8Array).\n */\nexport function isBytesLike(value) {\n return isHexString(value, true) || value instanceof Uint8Array;\n}\nconst HexCharacters = \"0123456789abcdef\";\n/**\n * Returns a [[DataHexString]] representation of %%data%%.\n */\nexport function hexlify(value, options) {\n if (!options) {\n options = {};\n }\n if (typeof value === \"string\") {\n if (value.includes(\",\") && value.startsWith(\"0x\")) {\n const v = value\n .replace(\"0x\", \"\")\n .split(\",\")\n .map((item) => Number(item));\n // @ts-ignore\n value = new Uint8Array(v);\n }\n }\n if (typeof value === \"number\") {\n logger.checkSafeUint53(value, \"invalid hexlify value\");\n let hex = \"\";\n while (value) {\n hex = HexCharacters[value & 0xf] + hex;\n value = Math.floor(value / 16);\n }\n if (hex.length) {\n if (hex.length % 2) {\n hex = \"0\" + hex;\n }\n return \"0x\" + hex;\n }\n return \"0x00\";\n }\n if (typeof value === \"bigint\") {\n value = value.toString(16);\n if (value.length % 2) {\n return \"0x0\" + value;\n }\n return \"0x\" + value;\n }\n if (options.allowMissingPrefix &&\n typeof value === \"string\" &&\n value.substring(0, 2) !== \"0x\") {\n value = \"0x\" + value;\n }\n if (isHexable(value)) {\n return value.toHexString();\n }\n if (isHexString(value)) {\n if (value.length % 2) {\n if (options.hexPad === \"left\") {\n value = \"0x0\" + value.substring(2);\n }\n else if (options.hexPad === \"right\") {\n value += \"0\";\n }\n else {\n logger.throwArgumentError(\"hex data is odd-length\", \"value\", value);\n }\n }\n return value.toLowerCase();\n }\n if (isBytes(value)) {\n let result = \"0x\";\n for (let i = 0; i < value.length; i++) {\n let v = value[i];\n result += HexCharacters[(v & 0xf0) >> 4] + HexCharacters[v & 0x0f];\n }\n return result;\n }\n return logger.throwArgumentError(\"invalid hexlify value\", \"value\", value);\n}\n/**\n * Returns a [[DataHexString]] by concatenating all values\n * within %%data%%.\n */\nexport function concat(items) {\n return \"0x\" + items.map((d) => hexlify(d).substring(2)).join(\"\");\n}\nexport function hexDataSlice(data, offset, endOffset) {\n if (typeof data !== \"string\") {\n data = hexlify(data);\n }\n else if (!isHexString(data) || data.length % 2) {\n logger.throwArgumentError(\"invalid hexData\", \"value\", data);\n }\n offset = 2 + 2 * offset;\n if (endOffset != null) {\n return \"0x\" + data.substring(offset, 2 + 2 * endOffset);\n }\n return \"0x\" + data.substring(offset);\n}\nexport function hexDataLength(data) {\n if (typeof data !== \"string\") {\n data = hexlify(data);\n }\n else if (!isHexString(data) || data.length % 2) {\n return null;\n }\n return (data.length - 2) / 2;\n}\n/**\n * Returns the length of %%data%%, in bytes.\n */\nexport function dataLength(data) {\n if (isHexString(data, true)) {\n return (data.length - 2) / 2;\n }\n return getBytes(data).length;\n}\n/**\n * Returns a [[DataHexString]] by slicing %%data%% from the %%start%%\n * offset to the %%end%% offset.\n *\n * By default %%start%% is 0 and %%end%% is the length of %%data%%.\n */\nexport function dataSlice(data, start, end) {\n const bytes = getBytes(data);\n if (end != null && end > bytes.length) {\n assert(false, \"cannot slice beyond data bounds\", \"BUFFER_OVERRUN\", {\n buffer: bytes,\n length: bytes.length,\n offset: end,\n });\n }\n return hexlify(bytes.slice(start == null ? 0 : start, end == null ? bytes.length : end));\n}\n/**\n * Return the [[DataHexString]] result by stripping all **leading**\n ** zero bytes from %%data%%.\n */\nexport function stripZerosLeft(data) {\n let bytes = hexlify(data).substring(2);\n while (bytes.startsWith(\"00\")) {\n bytes = bytes.substring(2);\n }\n return \"0x\" + bytes;\n}\nfunction zeroPad(data, length, left) {\n const bytes = getBytes(data);\n assert(length >= bytes.length, \"padding exceeds data length\", \"BUFFER_OVERRUN\", {\n buffer: new Uint8Array(bytes),\n length: length,\n offset: length + 1,\n });\n const result = new Uint8Array(length);\n result.fill(0);\n if (left) {\n result.set(bytes, length - bytes.length);\n }\n else {\n result.set(bytes, 0);\n }\n return hexlify(result);\n}\n/**\n * Return the [[DataHexString]] of %%data%% padded on the **left**\n * to %%length%% bytes.\n *\n * If %%data%% already exceeds %%length%%, a [[BufferOverrunError]] is\n * thrown.\n *\n * This pads data the same as **values** are in Solidity\n * (e.g. ``uint128``).\n */\nexport function zeroPadValue(data, length) {\n return zeroPad(data, length, true);\n}\n/**\n * Return the [[DataHexString]] of %%data%% padded on the **right**\n * to %%length%% bytes.\n *\n * If %%data%% already exceeds %%length%%, a [[BufferOverrunError]] is\n * thrown.\n *\n * This pads data the same as **bytes** are in Solidity\n * (e.g. ``bytes16``).\n */\nexport function zeroPadBytes(data, length) {\n return zeroPad(data, length, false);\n}\nexport function stripZeros(value) {\n let result = arrayify(value);\n if (result.length === 0) {\n return result;\n }\n // Find the first non-zero entry\n let start = 0;\n while (start < result.length && result[start] === 0) {\n start++;\n }\n // If we started with zeros, strip them\n if (start) {\n result = result.slice(start);\n }\n return result;\n}\nexport function arrayify(value, options) {\n if (!options) {\n options = {};\n }\n if (typeof value === \"number\") {\n logger.checkSafeUint53(value, \"invalid arrayify value\");\n const result = [];\n while (value) {\n // @ts-ignore\n result.unshift(value & 0xff);\n value = parseInt(String(value / 256));\n }\n if (result.length === 0) {\n result.push(0);\n }\n return addSlice(new Uint8Array(result));\n }\n if (options.allowMissingPrefix &&\n typeof value === \"string\" &&\n value.substring(0, 2) !== \"0x\") {\n value = \"0x\" + value;\n }\n if (isHexable(value)) {\n value = value.toHexString();\n }\n if (isHexString(value)) {\n let hex = value.substring(2);\n if (hex.length % 2) {\n if (options.hexPad === \"left\") {\n hex = \"0x0\" + hex.substring(2);\n }\n else if (options.hexPad === \"right\") {\n hex += \"0\";\n }\n else {\n logger.throwArgumentError(\"hex data is odd-length\", \"value\", value);\n }\n }\n const result = [];\n for (let i = 0; i < hex.length; i += 2) {\n // @ts-ignore\n result.push(parseInt(hex.substring(i, i + 2), 16));\n }\n return addSlice(new Uint8Array(result));\n }\n if (isBytes(value)) {\n return addSlice(new Uint8Array(value));\n }\n return logger.throwArgumentError(\"invalid arrayify value\", \"value\", value);\n}\nfunction addSlice(array) {\n // @ts-ignore\n if (array.slice) {\n return array;\n }\n array.slice = function () {\n const args = Array.prototype.slice.call(arguments);\n return addSlice(new Uint8Array(Array.prototype.slice.apply(array, args)));\n };\n return array;\n}\nexport function hexConcat(items) {\n let result = \"0x\";\n items.forEach((item) => {\n result += hexlify(item).substring(2);\n });\n return result;\n}\n//# sourceMappingURL=data.js.map","\"use strict\";\n/**\n * BigNumber\n *\n * A wrapper around the BN.js object. We use the BN.js library\n * because it is used by elliptic, so it is required regardless.\n *\n */\nimport _BN from \"bn.js\";\nimport { Logger } from \"../logger/logger.js\";\nimport { isBytes, hexlify, isHexString, } from \"../utils/data.js\";\nvar BN = _BN.BN;\nconst logger = new Logger(\"bigNumber/0.0.1\");\nconst _constructorGuard = {};\nconst MAX_SAFE = 0x1fffffffffffff;\nexport function isBigNumberish(value) {\n return (value != null &&\n (BigNumber.isBigNumber(value) ||\n (typeof value === \"number\" && value % 1 === 0) ||\n (typeof value === \"string\" && !!value.match(/^-?[0-9]+$/)) ||\n isHexString(value) ||\n typeof value === \"bigint\" ||\n isBytes(value)));\n}\n// Only warn about passing 10 into radix once\nlet _warnedToStringRadix = false;\nexport class BigNumber {\n _hex;\n _isBigNumber;\n constructor(constructorGuard, hex) {\n logger.checkNew(new.target, BigNumber);\n if (constructorGuard !== _constructorGuard) {\n logger.throwError(\"cannot call constructor directly; use BigNumber.from\", Logger.errors.UNSUPPORTED_OPERATION, {\n operation: \"new (BigNumber)\",\n });\n }\n this._hex = hex;\n this._isBigNumber = true;\n Object.freeze(this);\n }\n fromTwos(value) {\n return toBigNumber(toBN(this).fromTwos(value));\n }\n toTwos(value) {\n return toBigNumber(toBN(this).toTwos(value));\n }\n abs() {\n if (this._hex[0] === \"-\") {\n return BigNumber.from(this._hex.substring(1));\n }\n return this;\n }\n add(other) {\n return toBigNumber(toBN(this).add(toBN(other)));\n }\n sub(other) {\n return toBigNumber(toBN(this).sub(toBN(other)));\n }\n div(other) {\n const o = BigNumber.from(other);\n if (o.isZero()) {\n throwFault(\"division by zero\", \"div\");\n }\n return toBigNumber(toBN(this).div(toBN(other)));\n }\n mul(other) {\n return toBigNumber(toBN(this).mul(toBN(other)));\n }\n mod(other) {\n const value = toBN(other);\n if (value.isNeg()) {\n throwFault(\"cannot modulo negative values\", \"mod\");\n }\n return toBigNumber(toBN(this).umod(value));\n }\n pow(other) {\n const value = toBN(other);\n if (value.isNeg()) {\n throwFault(\"cannot raise to negative values\", \"pow\");\n }\n return toBigNumber(toBN(this).pow(value));\n }\n and(other) {\n const value = toBN(other);\n if (this.isNegative() || value.isNeg()) {\n throwFault(\"cannot 'and' negative values\", \"and\");\n }\n return toBigNumber(toBN(this).and(value));\n }\n or(other) {\n const value = toBN(other);\n if (this.isNegative() || value.isNeg()) {\n throwFault(\"cannot 'or' negative values\", \"or\");\n }\n return toBigNumber(toBN(this).or(value));\n }\n xor(other) {\n const value = toBN(other);\n if (this.isNegative() || value.isNeg()) {\n throwFault(\"cannot 'xor' negative values\", \"xor\");\n }\n return toBigNumber(toBN(this).xor(value));\n }\n mask(value) {\n if (this.isNegative() || value < 0) {\n throwFault(\"cannot mask negative values\", \"mask\");\n }\n return toBigNumber(toBN(this).maskn(value));\n }\n shl(value) {\n if (this.isNegative() || value < 0) {\n throwFault(\"cannot shift negative values\", \"shl\");\n }\n return toBigNumber(toBN(this).shln(value));\n }\n shr(value) {\n if (this.isNegative() || value < 0) {\n throwFault(\"cannot shift negative values\", \"shr\");\n }\n return toBigNumber(toBN(this).shrn(value));\n }\n eq(other) {\n return toBN(this).eq(toBN(other));\n }\n lt(other) {\n return toBN(this).lt(toBN(other));\n }\n lte(other) {\n return toBN(this).lte(toBN(other));\n }\n gt(other) {\n return toBN(this).gt(toBN(other));\n }\n gte(other) {\n return toBN(this).gte(toBN(other));\n }\n isNegative() {\n return this._hex[0] === \"-\";\n }\n isZero() {\n return toBN(this).isZero();\n }\n toNumber() {\n try {\n return toBN(this).toNumber();\n }\n catch (error) {\n throwFault(\"overflow\", \"toNumber\", this.toString());\n }\n // @ts-ignore\n return null;\n }\n toBigInt() {\n try {\n return BigInt(this.toString());\n }\n catch (e) { }\n return logger.throwError(\"this platform does not support BigInt\", Logger.errors.UNSUPPORTED_OPERATION, {\n value: this.toString(),\n });\n }\n toString() {\n // Lots of people expect this, which we do not support, so check (See: #889)\n if (arguments.length > 0) {\n if (arguments[0] === 10) {\n if (!_warnedToStringRadix) {\n _warnedToStringRadix = true;\n logger.warn(\"BigNumber.toString does not accept any parameters; base-10 is assumed\");\n }\n }\n else if (arguments[0] === 16) {\n logger.throwError(\"BigNumber.toString does not accept any parameters; use bigNumber.toHexString()\", Logger.errors.UNEXPECTED_ARGUMENT, {});\n }\n else {\n logger.throwError(\"BigNumber.toString does not accept parameters\", Logger.errors.UNEXPECTED_ARGUMENT, {});\n }\n }\n return toBN(this).toString(10);\n }\n toHexString() {\n return this._hex;\n }\n toJSON(key) {\n return { type: \"BigNumber\", hex: this.toHexString() };\n }\n static from(value) {\n if (value instanceof BigNumber) {\n return value;\n }\n if (typeof value === \"string\") {\n if (value.match(/^-?0x[0-9a-f]+$/i)) {\n return new BigNumber(_constructorGuard, toHex(value));\n }\n if (value.match(/^-?[0-9]+$/)) {\n return new BigNumber(_constructorGuard, toHex(new BN(value)));\n }\n return logger.throwArgumentError(\"invalid BigNumber string\", \"value\", value);\n }\n if (typeof value === \"number\") {\n if (value % 1) {\n throwFault(\"underflow\", \"BigNumber.from\", value);\n }\n if (value >= MAX_SAFE || value <= -MAX_SAFE) {\n throwFault(\"overflow\", \"BigNumber.from\", value);\n }\n return BigNumber.from(String(value));\n }\n const anyValue = value;\n if (typeof anyValue === \"bigint\") {\n return BigNumber.from(anyValue.toString());\n }\n if (isBytes(anyValue)) {\n return BigNumber.from(hexlify(anyValue));\n }\n if (anyValue) {\n // Hexable interface (takes priority)\n if (anyValue.toHexString) {\n const hex = anyValue.toHexString();\n if (typeof hex === \"string\") {\n return BigNumber.from(hex);\n }\n }\n else {\n // For now, handle legacy JSON-ified values (goes away in v6)\n let hex = anyValue._hex;\n // New-form JSON\n if (hex == null && anyValue.type === \"BigNumber\") {\n hex = anyValue.hex;\n }\n if (typeof hex === \"string\") {\n if (isHexString(hex) ||\n (hex[0] === \"-\" && isHexString(hex.substring(1)))) {\n return BigNumber.from(hex);\n }\n }\n }\n }\n return logger.throwArgumentError(\"invalid BigNumber value\", \"value\", value);\n }\n static isBigNumber(value) {\n return !!(value && value._isBigNumber);\n }\n}\n// Normalize the hex string\n// @ts-ignore\nfunction toHex(value) {\n // For BN, call on the hex string\n if (typeof value !== \"string\") {\n return toHex(value.toString(16));\n }\n // If negative, prepend the negative sign to the normalized positive value\n if (value[0] === \"-\") {\n // Strip off the negative sign\n value = value.substring(1);\n // Cannot have multiple negative signs (e.g. \"--0x04\")\n if (value[0] === \"-\") {\n logger.throwArgumentError(\"invalid hex\", \"value\", value);\n }\n // Call toHex on the positive component\n value = toHex(value);\n // Do not allow \"-0x00\"\n if (value === \"0x00\") {\n return value;\n }\n // Negate the value\n return \"-\" + value;\n }\n // Add a \"0x\" prefix if missing\n if (value.substring(0, 2) !== \"0x\") {\n value = \"0x\" + value;\n }\n // Normalize zero\n if (value === \"0x\") {\n return \"0x00\";\n }\n // Make the string even length\n if (value.length % 2) {\n value = \"0x0\" + value.substring(2);\n }\n // Trim to smallest even-length string\n while (value.length > 4 && value.substring(0, 4) === \"0x00\") {\n value = \"0x\" + value.substring(4);\n }\n return value;\n}\n// @ts-ignore\nfunction toBigNumber(value) {\n return BigNumber.from(toHex(value));\n}\n// @ts-ignore\nfunction toBN(value) {\n const hex = BigNumber.from(value).toHexString();\n if (hex[0] === \"-\") {\n return new BN(\"-\" + hex.substring(3), 16);\n }\n return new BN(hex.substring(2), 16);\n}\nfunction throwFault(fault, operation, value) {\n const params = { fault: fault, operation: operation };\n if (value != null) {\n params.value = value;\n }\n return logger.throwError(fault, Logger.errors.NUMERIC_FAULT, params);\n}\n// value should have no prefix\nexport function _base36To16(value) {\n return new BN(value, 36).toString(16);\n}\n// value should have no prefix\nexport function _base16To36(value) {\n return new BN(value, 16).toString(36);\n}\n//# sourceMappingURL=bigNumber.js.map","\"use strict\";\nimport { Logger } from \"../logger/logger.js\";\nimport { arrayify, hexlify, isBytesLike } from \"../utils/data.js\";\nconst logger = new Logger(\"rlp/0.0.1\");\nfunction arrayifyInteger(value) {\n const result = [];\n while (value) {\n // @ts-ignore\n result.unshift(value & 0xff);\n value >>= 8;\n }\n return result;\n}\nfunction unarrayifyInteger(data, offset, length) {\n let result = 0;\n for (let i = 0; i < length; i++) {\n result = result * 256 + data[offset + i];\n }\n return result;\n}\nfunction _encode(object) {\n if (Array.isArray(object)) {\n let payload = [];\n object.forEach(function (child) {\n payload = payload.concat(_encode(child));\n });\n if (payload.length <= 55) {\n payload.unshift(0xc0 + payload.length);\n return payload;\n }\n const length = arrayifyInteger(payload.length);\n length.unshift(0xf7 + length.length);\n return length.concat(payload);\n }\n if (!isBytesLike(object)) {\n logger.throwArgumentError(\"RLP object must be BytesLike\", \"object\", object);\n }\n const data = Array.prototype.slice.call(arrayify(object));\n if (data.length === 1 && data[0] <= 0x7f) {\n return data;\n }\n else if (data.length <= 55) {\n data.unshift(0x80 + data.length);\n return data;\n }\n const length = arrayifyInteger(data.length);\n length.unshift(0xb7 + length.length);\n return length.concat(data);\n}\nexport function encode(object) {\n return hexlify(_encode(object));\n}\nfunction _decodeChildren(data, offset, childOffset, length) {\n const result = [];\n while (childOffset < offset + 1 + length) {\n const decoded = _decode(data, childOffset);\n result.push(decoded.result);\n childOffset += decoded.consumed;\n if (childOffset > offset + 1 + length) {\n logger.throwError(\"child data too short\", Logger.errors.BUFFER_OVERRUN, {});\n }\n }\n return { consumed: 1 + length, result: result };\n}\n// returns { consumed: number, result: Object }\nfunction _decode(data, offset) {\n if (data.length === 0) {\n logger.throwError(\"data too short\", Logger.errors.BUFFER_OVERRUN, {});\n }\n // Array with extra length prefix\n if (data[offset] >= 0xf8) {\n const lengthLength = data[offset] - 0xf7;\n if (offset + 1 + lengthLength > data.length) {\n logger.throwError(\"data short segment too short\", Logger.errors.BUFFER_OVERRUN, {});\n }\n const length = unarrayifyInteger(data, offset + 1, lengthLength);\n if (offset + 1 + lengthLength + length > data.length) {\n logger.throwError(\"data long segment too short\", Logger.errors.BUFFER_OVERRUN, {});\n }\n return _decodeChildren(data, offset, offset + 1 + lengthLength, lengthLength + length);\n }\n else if (data[offset] >= 0xc0) {\n const length = data[offset] - 0xc0;\n if (offset + 1 + length > data.length) {\n logger.throwError(\"data array too short\", Logger.errors.BUFFER_OVERRUN, {});\n }\n return _decodeChildren(data, offset, offset + 1, length);\n }\n else if (data[offset] >= 0xb8) {\n const lengthLength = data[offset] - 0xb7;\n if (offset + 1 + lengthLength > data.length) {\n logger.throwError(\"data array too short\", Logger.errors.BUFFER_OVERRUN, {});\n }\n const length = unarrayifyInteger(data, offset + 1, lengthLength);\n if (offset + 1 + lengthLength + length > data.length) {\n logger.throwError(\"data array too short\", Logger.errors.BUFFER_OVERRUN, {});\n }\n const result = hexlify(data.slice(offset + 1 + lengthLength, offset + 1 + lengthLength + length));\n return { consumed: 1 + lengthLength + length, result: result };\n }\n else if (data[offset] >= 0x80) {\n const length = data[offset] - 0x80;\n if (offset + 1 + length > data.length) {\n logger.throwError(\"data too short\", Logger.errors.BUFFER_OVERRUN, {});\n }\n const result = hexlify(data.slice(offset + 1, offset + 1 + length));\n return { consumed: 1 + length, result: result };\n }\n return { consumed: 1, result: hexlify(data[offset]) };\n}\nexport function decode(data) {\n const bytes = arrayify(data);\n const decoded = _decode(bytes, 0);\n if (decoded.consumed !== bytes.length) {\n logger.throwArgumentError(\"invalid rlp data\", \"data\", data);\n }\n return decoded.result;\n}\n//# sourceMappingURL=rlp.js.map","function number(n) {\n if (!Number.isSafeInteger(n) || n < 0)\n throw new Error(`Wrong positive integer: ${n}`);\n}\nfunction bool(b) {\n if (typeof b !== 'boolean')\n throw new Error(`Expected boolean, not ${b}`);\n}\nfunction bytes(b, ...lengths) {\n if (!(b instanceof Uint8Array))\n throw new Error('Expected Uint8Array');\n if (lengths.length > 0 && !lengths.includes(b.length))\n throw new Error(`Expected Uint8Array of length ${lengths}, not of length=${b.length}`);\n}\nfunction hash(hash) {\n if (typeof hash !== 'function' || typeof hash.create !== 'function')\n throw new Error('Hash should be wrapped by utils.wrapConstructor');\n number(hash.outputLen);\n number(hash.blockLen);\n}\nfunction exists(instance, checkFinished = true) {\n if (instance.destroyed)\n throw new Error('Hash instance has been destroyed');\n if (checkFinished && instance.finished)\n throw new Error('Hash#digest() has already been called');\n}\nfunction output(out, instance) {\n bytes(out);\n const min = instance.outputLen;\n if (out.length < min) {\n throw new Error(`digestInto() expects output buffer of length at least ${min}`);\n }\n}\nexport { number, bool, bytes, hash, exists, output };\nconst assert = { number, bool, bytes, hash, exists, output };\nexport default assert;\n//# sourceMappingURL=_assert.js.map","/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */\n// We use WebCrypto aka globalThis.crypto, which exists in browsers and node.js 16+.\n// node.js versions earlier than v19 don't declare it in global scope.\n// For node.js, package.json#exports field mapping rewrites import\n// from `crypto` to `cryptoNode`, which imports native module.\n// Makes the utils un-importable in browsers without a bundler.\n// Once node.js 18 is deprecated, we can just drop the import.\nimport { crypto } from '@noble/hashes/crypto';\nconst u8a = (a) => a instanceof Uint8Array;\n// Cast array to different type\nexport const u8 = (arr) => new Uint8Array(arr.buffer, arr.byteOffset, arr.byteLength);\nexport const u32 = (arr) => new Uint32Array(arr.buffer, arr.byteOffset, Math.floor(arr.byteLength / 4));\n// Cast array to view\nexport const createView = (arr) => new DataView(arr.buffer, arr.byteOffset, arr.byteLength);\n// The rotate right (circular right shift) operation for uint32\nexport const rotr = (word, shift) => (word << (32 - shift)) | (word >>> shift);\n// big-endian hardware is rare. Just in case someone still decides to run hashes:\n// early-throw an error because we don't support BE yet.\nexport const isLE = new Uint8Array(new Uint32Array([0x11223344]).buffer)[0] === 0x44;\nif (!isLE)\n throw new Error('Non little-endian hardware is not supported');\nconst hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, '0'));\n/**\n * @example bytesToHex(Uint8Array.from([0xca, 0xfe, 0x01, 0x23])) // 'cafe0123'\n */\nexport function bytesToHex(bytes) {\n if (!u8a(bytes))\n throw new Error('Uint8Array expected');\n // pre-caching improves the speed 6x\n let hex = '';\n for (let i = 0; i < bytes.length; i++) {\n hex += hexes[bytes[i]];\n }\n return hex;\n}\n/**\n * @example hexToBytes('cafe0123') // Uint8Array.from([0xca, 0xfe, 0x01, 0x23])\n */\nexport function hexToBytes(hex) {\n if (typeof hex !== 'string')\n throw new Error('hex string expected, got ' + typeof hex);\n const len = hex.length;\n if (len % 2)\n throw new Error('padded hex string expected, got unpadded hex of length ' + len);\n const array = new Uint8Array(len / 2);\n for (let i = 0; i < array.length; i++) {\n const j = i * 2;\n const hexByte = hex.slice(j, j + 2);\n const byte = Number.parseInt(hexByte, 16);\n if (Number.isNaN(byte) || byte < 0)\n throw new Error('Invalid byte sequence');\n array[i] = byte;\n }\n return array;\n}\n// There is no setImmediate in browser and setTimeout is slow.\n// call of async fn will return Promise, which will be fullfiled only on\n// next scheduler queue processing step and this is exactly what we need.\nexport const nextTick = async () => { };\n// Returns control to thread each 'tick' ms to avoid blocking\nexport async function asyncLoop(iters, tick, cb) {\n let ts = Date.now();\n for (let i = 0; i < iters; i++) {\n cb(i);\n // Date.now() is not monotonic, so in case if clock goes backwards we return return control too\n const diff = Date.now() - ts;\n if (diff >= 0 && diff < tick)\n continue;\n await nextTick();\n ts += diff;\n }\n}\n/**\n * @example utf8ToBytes('abc') // new Uint8Array([97, 98, 99])\n */\nexport function utf8ToBytes(str) {\n if (typeof str !== 'string')\n throw new Error(`utf8ToBytes expected string, got ${typeof str}`);\n return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809\n}\n/**\n * Normalizes (non-hex) string or Uint8Array to Uint8Array.\n * Warning: when Uint8Array is passed, it would NOT get copied.\n * Keep in mind for future mutable operations.\n */\nexport function toBytes(data) {\n if (typeof data === 'string')\n data = utf8ToBytes(data);\n if (!u8a(data))\n throw new Error(`expected Uint8Array, got ${typeof data}`);\n return data;\n}\n/**\n * Copies several Uint8Arrays into one.\n */\nexport function concatBytes(...arrays) {\n const r = new Uint8Array(arrays.reduce((sum, a) => sum + a.length, 0));\n let pad = 0; // walk through each item, ensure they have proper type\n arrays.forEach((a) => {\n if (!u8a(a))\n throw new Error('Uint8Array expected');\n r.set(a, pad);\n pad += a.length;\n });\n return r;\n}\n// For runtime check if class implements interface\nexport class Hash {\n // Safe version that clones internal state\n clone() {\n return this._cloneInto();\n }\n}\nconst toStr = {}.toString;\nexport function checkOpts(defaults, opts) {\n if (opts !== undefined && toStr.call(opts) !== '[object Object]')\n throw new Error('Options should be object or undefined');\n const merged = Object.assign(defaults, opts);\n return merged;\n}\nexport function wrapConstructor(hashCons) {\n const hashC = (msg) => hashCons().update(toBytes(msg)).digest();\n const tmp = hashCons();\n hashC.outputLen = tmp.outputLen;\n hashC.blockLen = tmp.blockLen;\n hashC.create = () => hashCons();\n return hashC;\n}\nexport function wrapConstructorWithOpts(hashCons) {\n const hashC = (msg, opts) => hashCons(opts).update(toBytes(msg)).digest();\n const tmp = hashCons({});\n hashC.outputLen = tmp.outputLen;\n hashC.blockLen = tmp.blockLen;\n hashC.create = (opts) => hashCons(opts);\n return hashC;\n}\nexport function wrapXOFConstructorWithOpts(hashCons) {\n const hashC = (msg, opts) => hashCons(opts).update(toBytes(msg)).digest();\n const tmp = hashCons({});\n hashC.outputLen = tmp.outputLen;\n hashC.blockLen = tmp.blockLen;\n hashC.create = (opts) => hashCons(opts);\n return hashC;\n}\n/**\n * Secure PRNG. Uses `crypto.getRandomValues`, which defers to OS.\n */\nexport function randomBytes(bytesLength = 32) {\n if (crypto && typeof crypto.getRandomValues === 'function') {\n return crypto.getRandomValues(new Uint8Array(bytesLength));\n }\n throw new Error('crypto.getRandomValues must be defined');\n}\n//# sourceMappingURL=utils.js.map","import { hash as assertHash, bytes as assertBytes, exists as assertExists } from './_assert.js';\nimport { Hash, toBytes } from './utils.js';\n// HMAC (RFC 2104)\nexport class HMAC extends Hash {\n constructor(hash, _key) {\n super();\n this.finished = false;\n this.destroyed = false;\n assertHash(hash);\n const key = toBytes(_key);\n this.iHash = hash.create();\n if (typeof this.iHash.update !== 'function')\n throw new Error('Expected instance of class which extends utils.Hash');\n this.blockLen = this.iHash.blockLen;\n this.outputLen = this.iHash.outputLen;\n const blockLen = this.blockLen;\n const pad = new Uint8Array(blockLen);\n // blockLen can be bigger than outputLen\n pad.set(key.length > blockLen ? hash.create().update(key).digest() : key);\n for (let i = 0; i < pad.length; i++)\n pad[i] ^= 0x36;\n this.iHash.update(pad);\n // By doing update (processing of first block) of outer hash here we can re-use it between multiple calls via clone\n this.oHash = hash.create();\n // Undo internal XOR && apply outer XOR\n for (let i = 0; i < pad.length; i++)\n pad[i] ^= 0x36 ^ 0x5c;\n this.oHash.update(pad);\n pad.fill(0);\n }\n update(buf) {\n assertExists(this);\n this.iHash.update(buf);\n return this;\n }\n digestInto(out) {\n assertExists(this);\n assertBytes(out, this.outputLen);\n this.finished = true;\n this.iHash.digestInto(out);\n this.oHash.update(out);\n this.oHash.digestInto(out);\n this.destroy();\n }\n digest() {\n const out = new Uint8Array(this.oHash.outputLen);\n this.digestInto(out);\n return out;\n }\n _cloneInto(to) {\n // Create new instance without calling constructor since key already in state and we don't know it.\n to || (to = Object.create(Object.getPrototypeOf(this), {}));\n const { oHash, iHash, finished, destroyed, blockLen, outputLen } = this;\n to = to;\n to.finished = finished;\n to.destroyed = destroyed;\n to.blockLen = blockLen;\n to.outputLen = outputLen;\n to.oHash = oHash._cloneInto(to.oHash);\n to.iHash = iHash._cloneInto(to.iHash);\n return to;\n }\n destroy() {\n this.destroyed = true;\n this.oHash.destroy();\n this.iHash.destroy();\n }\n}\n/**\n * HMAC: RFC2104 message authentication code.\n * @param hash - function that would be used e.g. sha256\n * @param key - message key\n * @param message - message data\n */\nexport const hmac = (hash, key, message) => new HMAC(hash, key).update(message).digest();\nhmac.create = (hash, key) => new HMAC(hash, key);\n//# sourceMappingURL=hmac.js.map","import { hash as assertHash, number as assertNumber } from './_assert.js';\nimport { hmac } from './hmac.js';\nimport { createView, toBytes, checkOpts, asyncLoop } from './utils.js';\n// Common prologue and epilogue for sync/async functions\nfunction pbkdf2Init(hash, _password, _salt, _opts) {\n assertHash(hash);\n const opts = checkOpts({ dkLen: 32, asyncTick: 10 }, _opts);\n const { c, dkLen, asyncTick } = opts;\n assertNumber(c);\n assertNumber(dkLen);\n assertNumber(asyncTick);\n if (c < 1)\n throw new Error('PBKDF2: iterations (c) should be >= 1');\n const password = toBytes(_password);\n const salt = toBytes(_salt);\n // DK = PBKDF2(PRF, Password, Salt, c, dkLen);\n const DK = new Uint8Array(dkLen);\n // U1 = PRF(Password, Salt + INT_32_BE(i))\n const PRF = hmac.create(hash, password);\n const PRFSalt = PRF._cloneInto().update(salt);\n return { c, dkLen, asyncTick, DK, PRF, PRFSalt };\n}\nfunction pbkdf2Output(PRF, PRFSalt, DK, prfW, u) {\n PRF.destroy();\n PRFSalt.destroy();\n if (prfW)\n prfW.destroy();\n u.fill(0);\n return DK;\n}\n/**\n * PBKDF2-HMAC: RFC 2898 key derivation function\n * @param hash - hash function that would be used e.g. sha256\n * @param password - password from which a derived key is generated\n * @param salt - cryptographic salt\n * @param opts - {c, dkLen} where c is work factor and dkLen is output message size\n */\nexport function pbkdf2(hash, password, salt, opts) {\n const { c, dkLen, DK, PRF, PRFSalt } = pbkdf2Init(hash, password, salt, opts);\n let prfW; // Working copy\n const arr = new Uint8Array(4);\n const view = createView(arr);\n const u = new Uint8Array(PRF.outputLen);\n // DK = T1 + T2 + ⋯ + Tdklen/hlen\n for (let ti = 1, pos = 0; pos < dkLen; ti++, pos += PRF.outputLen) {\n // Ti = F(Password, Salt, c, i)\n const Ti = DK.subarray(pos, pos + PRF.outputLen);\n view.setInt32(0, ti, false);\n // F(Password, Salt, c, i) = U1 ^ U2 ^ ⋯ ^ Uc\n // U1 = PRF(Password, Salt + INT_32_BE(i))\n (prfW = PRFSalt._cloneInto(prfW)).update(arr).digestInto(u);\n Ti.set(u.subarray(0, Ti.length));\n for (let ui = 1; ui < c; ui++) {\n // Uc = PRF(Password, Uc−1)\n PRF._cloneInto(prfW).update(u).digestInto(u);\n for (let i = 0; i < Ti.length; i++)\n Ti[i] ^= u[i];\n }\n }\n return pbkdf2Output(PRF, PRFSalt, DK, prfW, u);\n}\nexport async function pbkdf2Async(hash, password, salt, opts) {\n const { c, dkLen, asyncTick, DK, PRF, PRFSalt } = pbkdf2Init(hash, password, salt, opts);\n let prfW; // Working copy\n const arr = new Uint8Array(4);\n const view = createView(arr);\n const u = new Uint8Array(PRF.outputLen);\n // DK = T1 + T2 + ⋯ + Tdklen/hlen\n for (let ti = 1, pos = 0; pos < dkLen; ti++, pos += PRF.outputLen) {\n // Ti = F(Password, Salt, c, i)\n const Ti = DK.subarray(pos, pos + PRF.outputLen);\n view.setInt32(0, ti, false);\n // F(Password, Salt, c, i) = U1 ^ U2 ^ ⋯ ^ Uc\n // U1 = PRF(Password, Salt + INT_32_BE(i))\n (prfW = PRFSalt._cloneInto(prfW)).update(arr).digestInto(u);\n Ti.set(u.subarray(0, Ti.length));\n await asyncLoop(c - 1, asyncTick, () => {\n // Uc = PRF(Password, Uc−1)\n PRF._cloneInto(prfW).update(u).digestInto(u);\n for (let i = 0; i < Ti.length; i++)\n Ti[i] ^= u[i];\n });\n }\n return pbkdf2Output(PRF, PRFSalt, DK, prfW, u);\n}\n//# sourceMappingURL=pbkdf2.js.map","import { exists, output } from './_assert.js';\nimport { Hash, createView, toBytes } from './utils.js';\n// Polyfill for Safari 14\nfunction setBigUint64(view, byteOffset, value, isLE) {\n if (typeof view.setBigUint64 === 'function')\n return view.setBigUint64(byteOffset, value, isLE);\n const _32n = BigInt(32);\n const _u32_max = BigInt(0xffffffff);\n const wh = Number((value >> _32n) & _u32_max);\n const wl = Number(value & _u32_max);\n const h = isLE ? 4 : 0;\n const l = isLE ? 0 : 4;\n view.setUint32(byteOffset + h, wh, isLE);\n view.setUint32(byteOffset + l, wl, isLE);\n}\n// Base SHA2 class (RFC 6234)\nexport class SHA2 extends Hash {\n constructor(blockLen, outputLen, padOffset, isLE) {\n super();\n this.blockLen = blockLen;\n this.outputLen = outputLen;\n this.padOffset = padOffset;\n this.isLE = isLE;\n this.finished = false;\n this.length = 0;\n this.pos = 0;\n this.destroyed = false;\n this.buffer = new Uint8Array(blockLen);\n this.view = createView(this.buffer);\n }\n update(data) {\n exists(this);\n const { view, buffer, blockLen } = this;\n data = toBytes(data);\n const len = data.length;\n for (let pos = 0; pos < len;) {\n const take = Math.min(blockLen - this.pos, len - pos);\n // Fast path: we have at least one block in input, cast it to view and process\n if (take === blockLen) {\n const dataView = createView(data);\n for (; blockLen <= len - pos; pos += blockLen)\n this.process(dataView, pos);\n continue;\n }\n buffer.set(data.subarray(pos, pos + take), this.pos);\n this.pos += take;\n pos += take;\n if (this.pos === blockLen) {\n this.process(view, 0);\n this.pos = 0;\n }\n }\n this.length += data.length;\n this.roundClean();\n return this;\n }\n digestInto(out) {\n exists(this);\n output(out, this);\n this.finished = true;\n // Padding\n // We can avoid allocation of buffer for padding completely if it\n // was previously not allocated here. But it won't change performance.\n const { buffer, view, blockLen, isLE } = this;\n let { pos } = this;\n // append the bit '1' to the message\n buffer[pos++] = 0b10000000;\n this.buffer.subarray(pos).fill(0);\n // we have less than padOffset left in buffer, so we cannot put length in current block, need process it and pad again\n if (this.padOffset > blockLen - pos) {\n this.process(view, 0);\n pos = 0;\n }\n // Pad until full block byte with zeros\n for (let i = pos; i < blockLen; i++)\n buffer[i] = 0;\n // Note: sha512 requires length to be 128bit integer, but length in JS will overflow before that\n // You need to write around 2 exabytes (u64_max / 8 / (1024**6)) for this to happen.\n // So we just write lowest 64 bits of that value.\n setBigUint64(view, blockLen - 8, BigInt(this.length * 8), isLE);\n this.process(view, 0);\n const oview = createView(out);\n const len = this.outputLen;\n // NOTE: we do division by 4 later, which should be fused in single op with modulo by JIT\n if (len % 4)\n throw new Error('_sha2: outputLen should be aligned to 32bit');\n const outLen = len / 4;\n const state = this.get();\n if (outLen > state.length)\n throw new Error('_sha2: outputLen bigger than state');\n for (let i = 0; i < outLen; i++)\n oview.setUint32(4 * i, state[i], isLE);\n }\n digest() {\n const { buffer, outputLen } = this;\n this.digestInto(buffer);\n const res = buffer.slice(0, outputLen);\n this.destroy();\n return res;\n }\n _cloneInto(to) {\n to || (to = new this.constructor());\n to.set(...this.get());\n const { blockLen, buffer, length, finished, destroyed, pos } = this;\n to.length = length;\n to.pos = pos;\n to.finished = finished;\n to.destroyed = destroyed;\n if (length % blockLen)\n to.buffer.set(buffer);\n return to;\n }\n}\n//# sourceMappingURL=_sha2.js.map","import { SHA2 } from './_sha2.js';\nimport { rotr, wrapConstructor } from './utils.js';\n// SHA2-256 need to try 2^128 hashes to execute birthday attack.\n// BTC network is doing 2^67 hashes/sec as per early 2023.\n// Choice: a ? b : c\nconst Chi = (a, b, c) => (a & b) ^ (~a & c);\n// Majority function, true if any two inpust is true\nconst Maj = (a, b, c) => (a & b) ^ (a & c) ^ (b & c);\n// Round constants:\n// first 32 bits of the fractional parts of the cube roots of the first 64 primes 2..311)\n// prettier-ignore\nconst SHA256_K = /* @__PURE__ */ new Uint32Array([\n 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,\n 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,\n 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,\n 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,\n 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,\n 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,\n 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,\n 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2\n]);\n// Initial state (first 32 bits of the fractional parts of the square roots of the first 8 primes 2..19):\n// prettier-ignore\nconst IV = /* @__PURE__ */ new Uint32Array([\n 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19\n]);\n// Temporary buffer, not used to store anything between runs\n// Named this way because it matches specification.\nconst SHA256_W = /* @__PURE__ */ new Uint32Array(64);\nclass SHA256 extends SHA2 {\n constructor() {\n super(64, 32, 8, false);\n // We cannot use array here since array allows indexing by variable\n // which means optimizer/compiler cannot use registers.\n this.A = IV[0] | 0;\n this.B = IV[1] | 0;\n this.C = IV[2] | 0;\n this.D = IV[3] | 0;\n this.E = IV[4] | 0;\n this.F = IV[5] | 0;\n this.G = IV[6] | 0;\n this.H = IV[7] | 0;\n }\n get() {\n const { A, B, C, D, E, F, G, H } = this;\n return [A, B, C, D, E, F, G, H];\n }\n // prettier-ignore\n set(A, B, C, D, E, F, G, H) {\n this.A = A | 0;\n this.B = B | 0;\n this.C = C | 0;\n this.D = D | 0;\n this.E = E | 0;\n this.F = F | 0;\n this.G = G | 0;\n this.H = H | 0;\n }\n process(view, offset) {\n // Extend the first 16 words into the remaining 48 words w[16..63] of the message schedule array\n for (let i = 0; i < 16; i++, offset += 4)\n SHA256_W[i] = view.getUint32(offset, false);\n for (let i = 16; i < 64; i++) {\n const W15 = SHA256_W[i - 15];\n const W2 = SHA256_W[i - 2];\n const s0 = rotr(W15, 7) ^ rotr(W15, 18) ^ (W15 >>> 3);\n const s1 = rotr(W2, 17) ^ rotr(W2, 19) ^ (W2 >>> 10);\n SHA256_W[i] = (s1 + SHA256_W[i - 7] + s0 + SHA256_W[i - 16]) | 0;\n }\n // Compression function main loop, 64 rounds\n let { A, B, C, D, E, F, G, H } = this;\n for (let i = 0; i < 64; i++) {\n const sigma1 = rotr(E, 6) ^ rotr(E, 11) ^ rotr(E, 25);\n const T1 = (H + sigma1 + Chi(E, F, G) + SHA256_K[i] + SHA256_W[i]) | 0;\n const sigma0 = rotr(A, 2) ^ rotr(A, 13) ^ rotr(A, 22);\n const T2 = (sigma0 + Maj(A, B, C)) | 0;\n H = G;\n G = F;\n F = E;\n E = (D + T1) | 0;\n D = C;\n C = B;\n B = A;\n A = (T1 + T2) | 0;\n }\n // Add the compressed chunk to the current hash value\n A = (A + this.A) | 0;\n B = (B + this.B) | 0;\n C = (C + this.C) | 0;\n D = (D + this.D) | 0;\n E = (E + this.E) | 0;\n F = (F + this.F) | 0;\n G = (G + this.G) | 0;\n H = (H + this.H) | 0;\n this.set(A, B, C, D, E, F, G, H);\n }\n roundClean() {\n SHA256_W.fill(0);\n }\n destroy() {\n this.set(0, 0, 0, 0, 0, 0, 0, 0);\n this.buffer.fill(0);\n }\n}\n// Constants from https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf\nclass SHA224 extends SHA256 {\n constructor() {\n super();\n this.A = 0xc1059ed8 | 0;\n this.B = 0x367cd507 | 0;\n this.C = 0x3070dd17 | 0;\n this.D = 0xf70e5939 | 0;\n this.E = 0xffc00b31 | 0;\n this.F = 0x68581511 | 0;\n this.G = 0x64f98fa7 | 0;\n this.H = 0xbefa4fa4 | 0;\n this.outputLen = 28;\n }\n}\n/**\n * SHA2-256 hash function\n * @param message - data that would be hashed\n */\nexport const sha256 = /* @__PURE__ */ wrapConstructor(() => new SHA256());\nexport const sha224 = /* @__PURE__ */ wrapConstructor(() => new SHA224());\n//# sourceMappingURL=sha256.js.map","const U32_MASK64 = /* @__PURE__ */ BigInt(2 ** 32 - 1);\nconst _32n = /* @__PURE__ */ BigInt(32);\n// We are not using BigUint64Array, because they are extremely slow as per 2022\nfunction fromBig(n, le = false) {\n if (le)\n return { h: Number(n & U32_MASK64), l: Number((n >> _32n) & U32_MASK64) };\n return { h: Number((n >> _32n) & U32_MASK64) | 0, l: Number(n & U32_MASK64) | 0 };\n}\nfunction split(lst, le = false) {\n let Ah = new Uint32Array(lst.length);\n let Al = new Uint32Array(lst.length);\n for (let i = 0; i < lst.length; i++) {\n const { h, l } = fromBig(lst[i], le);\n [Ah[i], Al[i]] = [h, l];\n }\n return [Ah, Al];\n}\nconst toBig = (h, l) => (BigInt(h >>> 0) << _32n) | BigInt(l >>> 0);\n// for Shift in [0, 32)\nconst shrSH = (h, _l, s) => h >>> s;\nconst shrSL = (h, l, s) => (h << (32 - s)) | (l >>> s);\n// Right rotate for Shift in [1, 32)\nconst rotrSH = (h, l, s) => (h >>> s) | (l << (32 - s));\nconst rotrSL = (h, l, s) => (h << (32 - s)) | (l >>> s);\n// Right rotate for Shift in (32, 64), NOTE: 32 is special case.\nconst rotrBH = (h, l, s) => (h << (64 - s)) | (l >>> (s - 32));\nconst rotrBL = (h, l, s) => (h >>> (s - 32)) | (l << (64 - s));\n// Right rotate for shift===32 (just swaps l&h)\nconst rotr32H = (_h, l) => l;\nconst rotr32L = (h, _l) => h;\n// Left rotate for Shift in [1, 32)\nconst rotlSH = (h, l, s) => (h << s) | (l >>> (32 - s));\nconst rotlSL = (h, l, s) => (l << s) | (h >>> (32 - s));\n// Left rotate for Shift in (32, 64), NOTE: 32 is special case.\nconst rotlBH = (h, l, s) => (l << (s - 32)) | (h >>> (64 - s));\nconst rotlBL = (h, l, s) => (h << (s - 32)) | (l >>> (64 - s));\n// JS uses 32-bit signed integers for bitwise operations which means we cannot\n// simple take carry out of low bit sum by shift, we need to use division.\nfunction add(Ah, Al, Bh, Bl) {\n const l = (Al >>> 0) + (Bl >>> 0);\n return { h: (Ah + Bh + ((l / 2 ** 32) | 0)) | 0, l: l | 0 };\n}\n// Addition with more than 2 elements\nconst add3L = (Al, Bl, Cl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0);\nconst add3H = (low, Ah, Bh, Ch) => (Ah + Bh + Ch + ((low / 2 ** 32) | 0)) | 0;\nconst add4L = (Al, Bl, Cl, Dl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0);\nconst add4H = (low, Ah, Bh, Ch, Dh) => (Ah + Bh + Ch + Dh + ((low / 2 ** 32) | 0)) | 0;\nconst add5L = (Al, Bl, Cl, Dl, El) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0) + (El >>> 0);\nconst add5H = (low, Ah, Bh, Ch, Dh, Eh) => (Ah + Bh + Ch + Dh + Eh + ((low / 2 ** 32) | 0)) | 0;\n// prettier-ignore\nexport { fromBig, split, toBig, shrSH, shrSL, rotrSH, rotrSL, rotrBH, rotrBL, rotr32H, rotr32L, rotlSH, rotlSL, rotlBH, rotlBL, add, add3L, add3H, add4L, add4H, add5H, add5L, };\n// prettier-ignore\nconst u64 = {\n fromBig, split, toBig,\n shrSH, shrSL,\n rotrSH, rotrSL, rotrBH, rotrBL,\n rotr32H, rotr32L,\n rotlSH, rotlSL, rotlBH, rotlBL,\n add, add3L, add3H, add4L, add4H, add5H, add5L,\n};\nexport default u64;\n//# sourceMappingURL=_u64.js.map","import { SHA2 } from './_sha2.js';\nimport u64 from './_u64.js';\nimport { wrapConstructor } from './utils.js';\n// Round contants (first 32 bits of the fractional parts of the cube roots of the first 80 primes 2..409):\n// prettier-ignore\nconst [SHA512_Kh, SHA512_Kl] = /* @__PURE__ */ (() => u64.split([\n '0x428a2f98d728ae22', '0x7137449123ef65cd', '0xb5c0fbcfec4d3b2f', '0xe9b5dba58189dbbc',\n '0x3956c25bf348b538', '0x59f111f1b605d019', '0x923f82a4af194f9b', '0xab1c5ed5da6d8118',\n '0xd807aa98a3030242', '0x12835b0145706fbe', '0x243185be4ee4b28c', '0x550c7dc3d5ffb4e2',\n '0x72be5d74f27b896f', '0x80deb1fe3b1696b1', '0x9bdc06a725c71235', '0xc19bf174cf692694',\n '0xe49b69c19ef14ad2', '0xefbe4786384f25e3', '0x0fc19dc68b8cd5b5', '0x240ca1cc77ac9c65',\n '0x2de92c6f592b0275', '0x4a7484aa6ea6e483', '0x5cb0a9dcbd41fbd4', '0x76f988da831153b5',\n '0x983e5152ee66dfab', '0xa831c66d2db43210', '0xb00327c898fb213f', '0xbf597fc7beef0ee4',\n '0xc6e00bf33da88fc2', '0xd5a79147930aa725', '0x06ca6351e003826f', '0x142929670a0e6e70',\n '0x27b70a8546d22ffc', '0x2e1b21385c26c926', '0x4d2c6dfc5ac42aed', '0x53380d139d95b3df',\n '0x650a73548baf63de', '0x766a0abb3c77b2a8', '0x81c2c92e47edaee6', '0x92722c851482353b',\n '0xa2bfe8a14cf10364', '0xa81a664bbc423001', '0xc24b8b70d0f89791', '0xc76c51a30654be30',\n '0xd192e819d6ef5218', '0xd69906245565a910', '0xf40e35855771202a', '0x106aa07032bbd1b8',\n '0x19a4c116b8d2d0c8', '0x1e376c085141ab53', '0x2748774cdf8eeb99', '0x34b0bcb5e19b48a8',\n '0x391c0cb3c5c95a63', '0x4ed8aa4ae3418acb', '0x5b9cca4f7763e373', '0x682e6ff3d6b2b8a3',\n '0x748f82ee5defb2fc', '0x78a5636f43172f60', '0x84c87814a1f0ab72', '0x8cc702081a6439ec',\n '0x90befffa23631e28', '0xa4506cebde82bde9', '0xbef9a3f7b2c67915', '0xc67178f2e372532b',\n '0xca273eceea26619c', '0xd186b8c721c0c207', '0xeada7dd6cde0eb1e', '0xf57d4f7fee6ed178',\n '0x06f067aa72176fba', '0x0a637dc5a2c898a6', '0x113f9804bef90dae', '0x1b710b35131c471b',\n '0x28db77f523047d84', '0x32caab7b40c72493', '0x3c9ebe0a15c9bebc', '0x431d67c49c100d4c',\n '0x4cc5d4becb3e42b6', '0x597f299cfc657e2a', '0x5fcb6fab3ad6faec', '0x6c44198c4a475817'\n].map(n => BigInt(n))))();\n// Temporary buffer, not used to store anything between runs\nconst SHA512_W_H = /* @__PURE__ */ new Uint32Array(80);\nconst SHA512_W_L = /* @__PURE__ */ new Uint32Array(80);\nexport class SHA512 extends SHA2 {\n constructor() {\n super(128, 64, 16, false);\n // We cannot use array here since array allows indexing by variable which means optimizer/compiler cannot use registers.\n // Also looks cleaner and easier to verify with spec.\n // Initial state (first 32 bits of the fractional parts of the square roots of the first 8 primes 2..19):\n // h -- high 32 bits, l -- low 32 bits\n this.Ah = 0x6a09e667 | 0;\n this.Al = 0xf3bcc908 | 0;\n this.Bh = 0xbb67ae85 | 0;\n this.Bl = 0x84caa73b | 0;\n this.Ch = 0x3c6ef372 | 0;\n this.Cl = 0xfe94f82b | 0;\n this.Dh = 0xa54ff53a | 0;\n this.Dl = 0x5f1d36f1 | 0;\n this.Eh = 0x510e527f | 0;\n this.El = 0xade682d1 | 0;\n this.Fh = 0x9b05688c | 0;\n this.Fl = 0x2b3e6c1f | 0;\n this.Gh = 0x1f83d9ab | 0;\n this.Gl = 0xfb41bd6b | 0;\n this.Hh = 0x5be0cd19 | 0;\n this.Hl = 0x137e2179 | 0;\n }\n // prettier-ignore\n get() {\n const { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this;\n return [Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl];\n }\n // prettier-ignore\n set(Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl) {\n this.Ah = Ah | 0;\n this.Al = Al | 0;\n this.Bh = Bh | 0;\n this.Bl = Bl | 0;\n this.Ch = Ch | 0;\n this.Cl = Cl | 0;\n this.Dh = Dh | 0;\n this.Dl = Dl | 0;\n this.Eh = Eh | 0;\n this.El = El | 0;\n this.Fh = Fh | 0;\n this.Fl = Fl | 0;\n this.Gh = Gh | 0;\n this.Gl = Gl | 0;\n this.Hh = Hh | 0;\n this.Hl = Hl | 0;\n }\n process(view, offset) {\n // Extend the first 16 words into the remaining 64 words w[16..79] of the message schedule array\n for (let i = 0; i < 16; i++, offset += 4) {\n SHA512_W_H[i] = view.getUint32(offset);\n SHA512_W_L[i] = view.getUint32((offset += 4));\n }\n for (let i = 16; i < 80; i++) {\n // s0 := (w[i-15] rightrotate 1) xor (w[i-15] rightrotate 8) xor (w[i-15] rightshift 7)\n const W15h = SHA512_W_H[i - 15] | 0;\n const W15l = SHA512_W_L[i - 15] | 0;\n const s0h = u64.rotrSH(W15h, W15l, 1) ^ u64.rotrSH(W15h, W15l, 8) ^ u64.shrSH(W15h, W15l, 7);\n const s0l = u64.rotrSL(W15h, W15l, 1) ^ u64.rotrSL(W15h, W15l, 8) ^ u64.shrSL(W15h, W15l, 7);\n // s1 := (w[i-2] rightrotate 19) xor (w[i-2] rightrotate 61) xor (w[i-2] rightshift 6)\n const W2h = SHA512_W_H[i - 2] | 0;\n const W2l = SHA512_W_L[i - 2] | 0;\n const s1h = u64.rotrSH(W2h, W2l, 19) ^ u64.rotrBH(W2h, W2l, 61) ^ u64.shrSH(W2h, W2l, 6);\n const s1l = u64.rotrSL(W2h, W2l, 19) ^ u64.rotrBL(W2h, W2l, 61) ^ u64.shrSL(W2h, W2l, 6);\n // SHA256_W[i] = s0 + s1 + SHA256_W[i - 7] + SHA256_W[i - 16];\n const SUMl = u64.add4L(s0l, s1l, SHA512_W_L[i - 7], SHA512_W_L[i - 16]);\n const SUMh = u64.add4H(SUMl, s0h, s1h, SHA512_W_H[i - 7], SHA512_W_H[i - 16]);\n SHA512_W_H[i] = SUMh | 0;\n SHA512_W_L[i] = SUMl | 0;\n }\n let { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this;\n // Compression function main loop, 80 rounds\n for (let i = 0; i < 80; i++) {\n // S1 := (e rightrotate 14) xor (e rightrotate 18) xor (e rightrotate 41)\n const sigma1h = u64.rotrSH(Eh, El, 14) ^ u64.rotrSH(Eh, El, 18) ^ u64.rotrBH(Eh, El, 41);\n const sigma1l = u64.rotrSL(Eh, El, 14) ^ u64.rotrSL(Eh, El, 18) ^ u64.rotrBL(Eh, El, 41);\n //const T1 = (H + sigma1 + Chi(E, F, G) + SHA256_K[i] + SHA256_W[i]) | 0;\n const CHIh = (Eh & Fh) ^ (~Eh & Gh);\n const CHIl = (El & Fl) ^ (~El & Gl);\n // T1 = H + sigma1 + Chi(E, F, G) + SHA512_K[i] + SHA512_W[i]\n // prettier-ignore\n const T1ll = u64.add5L(Hl, sigma1l, CHIl, SHA512_Kl[i], SHA512_W_L[i]);\n const T1h = u64.add5H(T1ll, Hh, sigma1h, CHIh, SHA512_Kh[i], SHA512_W_H[i]);\n const T1l = T1ll | 0;\n // S0 := (a rightrotate 28) xor (a rightrotate 34) xor (a rightrotate 39)\n const sigma0h = u64.rotrSH(Ah, Al, 28) ^ u64.rotrBH(Ah, Al, 34) ^ u64.rotrBH(Ah, Al, 39);\n const sigma0l = u64.rotrSL(Ah, Al, 28) ^ u64.rotrBL(Ah, Al, 34) ^ u64.rotrBL(Ah, Al, 39);\n const MAJh = (Ah & Bh) ^ (Ah & Ch) ^ (Bh & Ch);\n const MAJl = (Al & Bl) ^ (Al & Cl) ^ (Bl & Cl);\n Hh = Gh | 0;\n Hl = Gl | 0;\n Gh = Fh | 0;\n Gl = Fl | 0;\n Fh = Eh | 0;\n Fl = El | 0;\n ({ h: Eh, l: El } = u64.add(Dh | 0, Dl | 0, T1h | 0, T1l | 0));\n Dh = Ch | 0;\n Dl = Cl | 0;\n Ch = Bh | 0;\n Cl = Bl | 0;\n Bh = Ah | 0;\n Bl = Al | 0;\n const All = u64.add3L(T1l, sigma0l, MAJl);\n Ah = u64.add3H(All, T1h, sigma0h, MAJh);\n Al = All | 0;\n }\n // Add the compressed chunk to the current hash value\n ({ h: Ah, l: Al } = u64.add(this.Ah | 0, this.Al | 0, Ah | 0, Al | 0));\n ({ h: Bh, l: Bl } = u64.add(this.Bh | 0, this.Bl | 0, Bh | 0, Bl | 0));\n ({ h: Ch, l: Cl } = u64.add(this.Ch | 0, this.Cl | 0, Ch | 0, Cl | 0));\n ({ h: Dh, l: Dl } = u64.add(this.Dh | 0, this.Dl | 0, Dh | 0, Dl | 0));\n ({ h: Eh, l: El } = u64.add(this.Eh | 0, this.El | 0, Eh | 0, El | 0));\n ({ h: Fh, l: Fl } = u64.add(this.Fh | 0, this.Fl | 0, Fh | 0, Fl | 0));\n ({ h: Gh, l: Gl } = u64.add(this.Gh | 0, this.Gl | 0, Gh | 0, Gl | 0));\n ({ h: Hh, l: Hl } = u64.add(this.Hh | 0, this.Hl | 0, Hh | 0, Hl | 0));\n this.set(Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl);\n }\n roundClean() {\n SHA512_W_H.fill(0);\n SHA512_W_L.fill(0);\n }\n destroy() {\n this.buffer.fill(0);\n this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);\n }\n}\nclass SHA512_224 extends SHA512 {\n constructor() {\n super();\n // h -- high 32 bits, l -- low 32 bits\n this.Ah = 0x8c3d37c8 | 0;\n this.Al = 0x19544da2 | 0;\n this.Bh = 0x73e19966 | 0;\n this.Bl = 0x89dcd4d6 | 0;\n this.Ch = 0x1dfab7ae | 0;\n this.Cl = 0x32ff9c82 | 0;\n this.Dh = 0x679dd514 | 0;\n this.Dl = 0x582f9fcf | 0;\n this.Eh = 0x0f6d2b69 | 0;\n this.El = 0x7bd44da8 | 0;\n this.Fh = 0x77e36f73 | 0;\n this.Fl = 0x04c48942 | 0;\n this.Gh = 0x3f9d85a8 | 0;\n this.Gl = 0x6a1d36c8 | 0;\n this.Hh = 0x1112e6ad | 0;\n this.Hl = 0x91d692a1 | 0;\n this.outputLen = 28;\n }\n}\nclass SHA512_256 extends SHA512 {\n constructor() {\n super();\n // h -- high 32 bits, l -- low 32 bits\n this.Ah = 0x22312194 | 0;\n this.Al = 0xfc2bf72c | 0;\n this.Bh = 0x9f555fa3 | 0;\n this.Bl = 0xc84c64c2 | 0;\n this.Ch = 0x2393b86b | 0;\n this.Cl = 0x6f53b151 | 0;\n this.Dh = 0x96387719 | 0;\n this.Dl = 0x5940eabd | 0;\n this.Eh = 0x96283ee2 | 0;\n this.El = 0xa88effe3 | 0;\n this.Fh = 0xbe5e1e25 | 0;\n this.Fl = 0x53863992 | 0;\n this.Gh = 0x2b0199fc | 0;\n this.Gl = 0x2c85b8aa | 0;\n this.Hh = 0x0eb72ddc | 0;\n this.Hl = 0x81c52ca2 | 0;\n this.outputLen = 32;\n }\n}\nclass SHA384 extends SHA512 {\n constructor() {\n super();\n // h -- high 32 bits, l -- low 32 bits\n this.Ah = 0xcbbb9d5d | 0;\n this.Al = 0xc1059ed8 | 0;\n this.Bh = 0x629a292a | 0;\n this.Bl = 0x367cd507 | 0;\n this.Ch = 0x9159015a | 0;\n this.Cl = 0x3070dd17 | 0;\n this.Dh = 0x152fecd8 | 0;\n this.Dl = 0xf70e5939 | 0;\n this.Eh = 0x67332667 | 0;\n this.El = 0xffc00b31 | 0;\n this.Fh = 0x8eb44a87 | 0;\n this.Fl = 0x68581511 | 0;\n this.Gh = 0xdb0c2e0d | 0;\n this.Gl = 0x64f98fa7 | 0;\n this.Hh = 0x47b5481d | 0;\n this.Hl = 0xbefa4fa4 | 0;\n this.outputLen = 48;\n }\n}\nexport const sha512 = /* @__PURE__ */ wrapConstructor(() => new SHA512());\nexport const sha512_224 = /* @__PURE__ */ wrapConstructor(() => new SHA512_224());\nexport const sha512_256 = /* @__PURE__ */ wrapConstructor(() => new SHA512_256());\nexport const sha384 = /* @__PURE__ */ wrapConstructor(() => new SHA384());\n//# sourceMappingURL=sha512.js.map","import { bytes, exists, number, output } from './_assert.js';\nimport { rotlBH, rotlBL, rotlSH, rotlSL, split } from './_u64.js';\nimport { Hash, u32, toBytes, wrapConstructor, wrapXOFConstructorWithOpts, } from './utils.js';\n// SHA3 (keccak) is based on a new design: basically, the internal state is bigger than output size.\n// It's called a sponge function.\n// Various per round constants calculations\nconst [SHA3_PI, SHA3_ROTL, _SHA3_IOTA] = [[], [], []];\nconst _0n = /* @__PURE__ */ BigInt(0);\nconst _1n = /* @__PURE__ */ BigInt(1);\nconst _2n = /* @__PURE__ */ BigInt(2);\nconst _7n = /* @__PURE__ */ BigInt(7);\nconst _256n = /* @__PURE__ */ BigInt(256);\nconst _0x71n = /* @__PURE__ */ BigInt(0x71);\nfor (let round = 0, R = _1n, x = 1, y = 0; round < 24; round++) {\n // Pi\n [x, y] = [y, (2 * x + 3 * y) % 5];\n SHA3_PI.push(2 * (5 * y + x));\n // Rotational\n SHA3_ROTL.push((((round + 1) * (round + 2)) / 2) % 64);\n // Iota\n let t = _0n;\n for (let j = 0; j < 7; j++) {\n R = ((R << _1n) ^ ((R >> _7n) * _0x71n)) % _256n;\n if (R & _2n)\n t ^= _1n << ((_1n << /* @__PURE__ */ BigInt(j)) - _1n);\n }\n _SHA3_IOTA.push(t);\n}\nconst [SHA3_IOTA_H, SHA3_IOTA_L] = /* @__PURE__ */ split(_SHA3_IOTA, true);\n// Left rotation (without 0, 32, 64)\nconst rotlH = (h, l, s) => (s > 32 ? rotlBH(h, l, s) : rotlSH(h, l, s));\nconst rotlL = (h, l, s) => (s > 32 ? rotlBL(h, l, s) : rotlSL(h, l, s));\n// Same as keccakf1600, but allows to skip some rounds\nexport function keccakP(s, rounds = 24) {\n const B = new Uint32Array(5 * 2);\n // NOTE: all indices are x2 since we store state as u32 instead of u64 (bigints to slow in js)\n for (let round = 24 - rounds; round < 24; round++) {\n // Theta θ\n for (let x = 0; x < 10; x++)\n B[x] = s[x] ^ s[x + 10] ^ s[x + 20] ^ s[x + 30] ^ s[x + 40];\n for (let x = 0; x < 10; x += 2) {\n const idx1 = (x + 8) % 10;\n const idx0 = (x + 2) % 10;\n const B0 = B[idx0];\n const B1 = B[idx0 + 1];\n const Th = rotlH(B0, B1, 1) ^ B[idx1];\n const Tl = rotlL(B0, B1, 1) ^ B[idx1 + 1];\n for (let y = 0; y < 50; y += 10) {\n s[x + y] ^= Th;\n s[x + y + 1] ^= Tl;\n }\n }\n // Rho (ρ) and Pi (π)\n let curH = s[2];\n let curL = s[3];\n for (let t = 0; t < 24; t++) {\n const shift = SHA3_ROTL[t];\n const Th = rotlH(curH, curL, shift);\n const Tl = rotlL(curH, curL, shift);\n const PI = SHA3_PI[t];\n curH = s[PI];\n curL = s[PI + 1];\n s[PI] = Th;\n s[PI + 1] = Tl;\n }\n // Chi (χ)\n for (let y = 0; y < 50; y += 10) {\n for (let x = 0; x < 10; x++)\n B[x] = s[y + x];\n for (let x = 0; x < 10; x++)\n s[y + x] ^= ~B[(x + 2) % 10] & B[(x + 4) % 10];\n }\n // Iota (ι)\n s[0] ^= SHA3_IOTA_H[round];\n s[1] ^= SHA3_IOTA_L[round];\n }\n B.fill(0);\n}\nexport class Keccak extends Hash {\n // NOTE: we accept arguments in bytes instead of bits here.\n constructor(blockLen, suffix, outputLen, enableXOF = false, rounds = 24) {\n super();\n this.blockLen = blockLen;\n this.suffix = suffix;\n this.outputLen = outputLen;\n this.enableXOF = enableXOF;\n this.rounds = rounds;\n this.pos = 0;\n this.posOut = 0;\n this.finished = false;\n this.destroyed = false;\n // Can be passed from user as dkLen\n number(outputLen);\n // 1600 = 5x5 matrix of 64bit. 1600 bits === 200 bytes\n if (0 >= this.blockLen || this.blockLen >= 200)\n throw new Error('Sha3 supports only keccak-f1600 function');\n this.state = new Uint8Array(200);\n this.state32 = u32(this.state);\n }\n keccak() {\n keccakP(this.state32, this.rounds);\n this.posOut = 0;\n this.pos = 0;\n }\n update(data) {\n exists(this);\n const { blockLen, state } = this;\n data = toBytes(data);\n const len = data.length;\n for (let pos = 0; pos < len;) {\n const take = Math.min(blockLen - this.pos, len - pos);\n for (let i = 0; i < take; i++)\n state[this.pos++] ^= data[pos++];\n if (this.pos === blockLen)\n this.keccak();\n }\n return this;\n }\n finish() {\n if (this.finished)\n return;\n this.finished = true;\n const { state, suffix, pos, blockLen } = this;\n // Do the padding\n state[pos] ^= suffix;\n if ((suffix & 0x80) !== 0 && pos === blockLen - 1)\n this.keccak();\n state[blockLen - 1] ^= 0x80;\n this.keccak();\n }\n writeInto(out) {\n exists(this, false);\n bytes(out);\n this.finish();\n const bufferOut = this.state;\n const { blockLen } = this;\n for (let pos = 0, len = out.length; pos < len;) {\n if (this.posOut >= blockLen)\n this.keccak();\n const take = Math.min(blockLen - this.posOut, len - pos);\n out.set(bufferOut.subarray(this.posOut, this.posOut + take), pos);\n this.posOut += take;\n pos += take;\n }\n return out;\n }\n xofInto(out) {\n // Sha3/Keccak usage with XOF is probably mistake, only SHAKE instances can do XOF\n if (!this.enableXOF)\n throw new Error('XOF is not possible for this instance');\n return this.writeInto(out);\n }\n xof(bytes) {\n number(bytes);\n return this.xofInto(new Uint8Array(bytes));\n }\n digestInto(out) {\n output(out, this);\n if (this.finished)\n throw new Error('digest() was already called');\n this.writeInto(out);\n this.destroy();\n return out;\n }\n digest() {\n return this.digestInto(new Uint8Array(this.outputLen));\n }\n destroy() {\n this.destroyed = true;\n this.state.fill(0);\n }\n _cloneInto(to) {\n const { blockLen, suffix, outputLen, rounds, enableXOF } = this;\n to || (to = new Keccak(blockLen, suffix, outputLen, enableXOF, rounds));\n to.state32.set(this.state32);\n to.pos = this.pos;\n to.posOut = this.posOut;\n to.finished = this.finished;\n to.rounds = rounds;\n // Suffix can change in cSHAKE\n to.suffix = suffix;\n to.outputLen = outputLen;\n to.enableXOF = enableXOF;\n to.destroyed = this.destroyed;\n return to;\n }\n}\nconst gen = (suffix, blockLen, outputLen) => wrapConstructor(() => new Keccak(blockLen, suffix, outputLen));\nexport const sha3_224 = /* @__PURE__ */ gen(0x06, 144, 224 / 8);\n/**\n * SHA3-256 hash function\n * @param message - that would be hashed\n */\nexport const sha3_256 = /* @__PURE__ */ gen(0x06, 136, 256 / 8);\nexport const sha3_384 = /* @__PURE__ */ gen(0x06, 104, 384 / 8);\nexport const sha3_512 = /* @__PURE__ */ gen(0x06, 72, 512 / 8);\nexport const keccak_224 = /* @__PURE__ */ gen(0x01, 144, 224 / 8);\n/**\n * keccak-256 hash function. Different from SHA3-256.\n * @param message - that would be hashed\n */\nexport const keccak_256 = /* @__PURE__ */ gen(0x01, 136, 256 / 8);\nexport const keccak_384 = /* @__PURE__ */ gen(0x01, 104, 384 / 8);\nexport const keccak_512 = /* @__PURE__ */ gen(0x01, 72, 512 / 8);\nconst genShake = (suffix, blockLen, outputLen) => wrapXOFConstructorWithOpts((opts = {}) => new Keccak(blockLen, suffix, opts.dkLen === undefined ? outputLen : opts.dkLen, true));\nexport const shake128 = /* @__PURE__ */ genShake(0x1f, 168, 128 / 8);\nexport const shake256 = /* @__PURE__ */ genShake(0x1f, 136, 256 / 8);\n//# sourceMappingURL=sha3.js.map","/**\n * Some mathematic operations.\n *\n * @_subsection: api/utils:Math Helpers [about-maths]\n */\nimport { hexlify, isBytesLike } from \"./data.js\";\nimport { assert, assertArgument } from \"./errors.js\";\nconst BN_0 = BigInt(0);\nconst BN_1 = BigInt(1);\n//const BN_Max256 = (BN_1 << BigInt(256)) - BN_1;\n// IEEE 754 support 53-bits of mantissa\nconst maxValue = 0x1fffffffffffff;\n/**\n * Convert %%value%% from a twos-compliment representation of %%width%%\n * bits to its value.\n *\n * If the highest bit is ``1``, the result will be negative.\n */\nexport function fromTwos(_value, _width) {\n const value = getUint(_value, \"value\");\n const width = BigInt(getNumber(_width, \"width\"));\n assert(value >> width === BN_0, \"overflow\", \"NUMERIC_FAULT\", {\n operation: \"fromTwos\",\n fault: \"overflow\",\n value: _value,\n });\n // Top bit set; treat as a negative value\n if (value >> (width - BN_1)) {\n const mask = (BN_1 << width) - BN_1;\n return -((~value & mask) + BN_1);\n }\n return value;\n}\n/**\n * Convert %%value%% to a twos-compliment representation of\n * %%width%% bits.\n *\n * The result will always be positive.\n */\nexport function toTwos(_value, _width) {\n let value = getBigInt(_value, \"value\");\n const width = BigInt(getNumber(_width, \"width\"));\n const limit = BN_1 << (width - BN_1);\n if (value < BN_0) {\n value = -value;\n assert(value <= limit, \"too low\", \"NUMERIC_FAULT\", {\n operation: \"toTwos\",\n fault: \"overflow\",\n value: _value,\n });\n const mask = (BN_1 << width) - BN_1;\n return (~value & mask) + BN_1;\n }\n else {\n assert(value < limit, \"too high\", \"NUMERIC_FAULT\", {\n operation: \"toTwos\",\n fault: \"overflow\",\n value: _value,\n });\n }\n return value;\n}\n/**\n * Mask %%value%% with a bitmask of %%bits%% ones.\n */\nexport function mask(_value, _bits) {\n const value = getUint(_value, \"value\");\n const bits = BigInt(getNumber(_bits, \"bits\"));\n return value & ((BN_1 << bits) - BN_1);\n}\n/**\n * Gets a BigInt from %%value%%. If it is an invalid value for\n * a BigInt, then an ArgumentError will be thrown for %%name%%.\n */\nexport function getBigInt(value, name) {\n switch (typeof value) {\n case \"bigint\":\n return value;\n case \"number\":\n assertArgument(Number.isInteger(value), \"underflow\", name || \"value\", value);\n assertArgument(value >= -maxValue && value <= maxValue, \"overflow\", name || \"value\", value);\n return BigInt(value);\n case \"string\":\n try {\n if (value === \"\") {\n throw new Error(\"empty string\");\n }\n if (value[0] === \"-\" && value[1] !== \"-\") {\n return -BigInt(value.substring(1));\n }\n return BigInt(value);\n }\n catch (e) {\n assertArgument(false, `invalid BigNumberish string: ${e.message}`, name || \"value\", value);\n }\n }\n assertArgument(false, \"invalid BigNumberish value\", name || \"value\", value);\n}\nexport function getUint(value, name) {\n const result = getBigInt(value, name);\n assert(result >= BN_0, \"unsigned value cannot be negative\", \"NUMERIC_FAULT\", {\n fault: \"overflow\",\n operation: \"getUint\",\n value,\n });\n return result;\n}\nconst Nibbles = \"0123456789abcdef\";\n/*\n * Converts %%value%% to a BigInt. If %%value%% is a Uint8Array, it\n * is treated as Big Endian data.\n */\nexport function toBigInt(value) {\n if (value instanceof Uint8Array) {\n let result = \"0x0\";\n for (const v of value) {\n result += Nibbles[v >> 4];\n result += Nibbles[v & 0x0f];\n }\n return BigInt(result);\n }\n return getBigInt(value);\n}\n/**\n * Gets a //number// from %%value%%. If it is an invalid value for\n * a //number//, then an ArgumentError will be thrown for %%name%%.\n */\nexport function getNumber(value, name) {\n switch (typeof value) {\n case \"bigint\":\n assertArgument(value >= -maxValue && value <= maxValue, \"overflow\", name || \"value\", value);\n return Number(value);\n case \"number\":\n assertArgument(Number.isInteger(value), \"underflow\", name || \"value\", value);\n assertArgument(value >= -maxValue && value <= maxValue, \"overflow\", name || \"value\", value);\n return value;\n case \"string\":\n try {\n if (value === \"\") {\n throw new Error(\"empty string\");\n }\n return getNumber(BigInt(value), name);\n }\n catch (e) {\n assertArgument(false, `invalid numeric string: ${e.message}`, name || \"value\", value);\n }\n }\n assertArgument(false, \"invalid numeric value\", name || \"value\", value);\n}\n/**\n * Converts %%value%% to a number. If %%value%% is a Uint8Array, it\n * is treated as Big Endian data. Throws if the value is not safe.\n */\nexport function toNumber(value) {\n return getNumber(toBigInt(value));\n}\n/**\n * Converts %%value%% to a Big Endian hexstring, optionally padded to\n * %%width%% bytes.\n */\nexport function toBeHex(_value, _width) {\n const value = getUint(_value, \"value\");\n let result = value.toString(16);\n if (_width == null) {\n // Ensure the value is of even length\n if (result.length % 2) {\n result = \"0\" + result;\n }\n }\n else {\n const width = getNumber(_width, \"width\");\n assert(width * 2 >= result.length, `value exceeds width (${width} bits)`, \"NUMERIC_FAULT\", {\n operation: \"toBeHex\",\n fault: \"overflow\",\n value: _value,\n });\n // Pad the value to the required width\n while (result.length < width * 2) {\n result = \"0\" + result;\n }\n }\n return \"0x\" + result;\n}\n/**\n * Converts %%value%% to a Big Endian Uint8Array.\n */\nexport function toBeArray(_value) {\n const value = getUint(_value, \"value\");\n if (value === BN_0) {\n return new Uint8Array([]);\n }\n let hex = value.toString(16);\n if (hex.length % 2) {\n hex = \"0\" + hex;\n }\n const result = new Uint8Array(hex.length / 2);\n for (let i = 0; i < result.length; i++) {\n const offset = i * 2;\n result[i] = parseInt(hex.substring(offset, offset + 2), 16);\n }\n return result;\n}\n/**\n * Returns a [[HexString]] for %%value%% safe to use as a //Quantity//.\n *\n * A //Quantity// does not have and leading 0 values unless the value is\n * the literal value `0x0`. This is most commonly used for JSSON-RPC\n * numeric values.\n */\nexport function toQuantity(value) {\n let result = hexlify(isBytesLike(value) ? value : toBeArray(value)).substring(2);\n while (result.startsWith(\"0\")) {\n result = result.substring(1);\n }\n if (result === \"\") {\n result = \"0\";\n }\n return \"0x\" + result;\n}\n//# sourceMappingURL=maths.js.map","/**\n * The [Base58 Encoding](link-base58) scheme allows a **numeric** value\n * to be encoded as a compact string using a radix of 58 using only\n * alpha-numeric characters. Confusingly similar characters are omitted\n * (i.e. ``\"l0O\"``).\n *\n * Note that Base58 encodes a **numeric** value, not arbitrary bytes,\n * since any zero-bytes on the left would get removed. To mitigate this\n * issue most schemes that use Base58 choose specific high-order values\n * to ensure non-zero prefixes.\n *\n * @_subsection: api/utils:Base58 Encoding [about-base58]\n */\nimport { getBytes } from \"./data.js\";\nimport { assertArgument } from \"./errors.js\";\nimport { toBigInt } from \"./maths.js\";\nconst Alphabet = \"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz\";\nlet Lookup = null;\nfunction getAlpha(letter) {\n if (Lookup == null) {\n Lookup = {};\n for (let i = 0; i < Alphabet.length; i++) {\n Lookup[Alphabet[i]] = BigInt(i);\n }\n }\n const result = Lookup[letter];\n assertArgument(result != null, `invalid base58 value`, \"letter\", letter);\n return result;\n}\nconst BN_0 = BigInt(0);\nconst BN_58 = BigInt(58);\n/**\n * Encode %%value%% as a Base58-encoded string.\n */\nexport function encodeBase58(_value) {\n let value = toBigInt(getBytes(_value));\n let result = \"\";\n while (value) {\n result = Alphabet[Number(value % BN_58)] + result;\n value /= BN_58;\n }\n return result;\n}\n/**\n * Decode the Base58-encoded %%value%%.\n */\nexport function decodeBase58(value) {\n let result = BN_0;\n for (let i = 0; i < value.length; i++) {\n result *= BN_58;\n result += getAlpha(value[i]);\n }\n return result;\n}\n//# sourceMappingURL=base58.js.map","// utils/base64-browser\nimport { getBytes } from \"./data.js\";\nexport function decodeBase64(textData) {\n textData = atob(textData);\n const data = new Uint8Array(textData.length);\n for (let i = 0; i < textData.length; i++) {\n data[i] = textData.charCodeAt(i);\n }\n return getBytes(data);\n}\nexport function encodeBase64(_data) {\n const data = getBytes(_data);\n let textData = \"\";\n for (let i = 0; i < data.length; i++) {\n textData += String.fromCharCode(data[i]);\n }\n return btoa(textData);\n}\n//# sourceMappingURL=base64-browser.js.map","/**\n * Explain events...\n *\n * @_section api/utils/events:Events [about-events]\n */\nimport { defineProperties } from \"./properties.js\";\n/**\n * When an [[EventEmitterable]] triggers a [[Listener]], the\n * callback always ahas one additional argument passed, which is\n * an **EventPayload**.\n */\nexport class EventPayload {\n /**\n * The event filter.\n */\n filter;\n /**\n * The **EventEmitterable**.\n */\n emitter;\n #listener;\n /**\n * Create a new **EventPayload** for %%emitter%% with\n * the %%listener%% and for %%filter%%.\n */\n constructor(emitter, listener, filter) {\n this.#listener = listener;\n defineProperties(this, { emitter, filter });\n }\n /**\n * Unregister the triggered listener for future events.\n */\n async removeListener() {\n if (this.#listener == null) {\n return;\n }\n await this.emitter.off(this.filter, this.#listener);\n }\n}\n//# sourceMappingURL=events.js.map","/**\n * Using strings in Core (or any security-basd system) requires\n * additional care. These utilities attempt to mitigate some of the\n * safety issues as well as provide the ability to recover and analyse\n * strings.\n *\n * @_subsection api/utils:Strings and UTF-8 [about-strings]\n */\nimport { getBytes } from \"./data.js\";\nimport { assertArgument, assertNormalize } from \"./errors.js\";\nfunction errorFunc(reason, offset, bytes, output, badCodepoint) {\n assertArgument(false, `invalid codepoint at offset ${offset}; ${reason}`, \"bytes\", bytes);\n}\nfunction ignoreFunc(reason, offset, bytes, output, badCodepoint) {\n // If there is an invalid prefix (including stray continuation), skip any additional continuation bytes\n if (reason === \"BAD_PREFIX\" || reason === \"UNEXPECTED_CONTINUE\") {\n let i = 0;\n for (let o = offset + 1; o < bytes.length; o++) {\n if (bytes[o] >> 6 !== 0x02) {\n break;\n }\n i++;\n }\n return i;\n }\n // This byte runs us past the end of the string, so just jump to the end\n // (but the first byte was read already read and therefore skipped)\n if (reason === \"OVERRUN\") {\n return bytes.length - offset - 1;\n }\n // Nothing to skip\n return 0;\n}\nfunction replaceFunc(reason, offset, bytes, output, badCodepoint) {\n // Overlong representations are otherwise \"valid\" code points; just non-deistingtished\n if (reason === \"OVERLONG\") {\n assertArgument(typeof badCodepoint === \"number\", \"invalid bad code point for replacement\", \"badCodepoint\", badCodepoint);\n output.push(badCodepoint);\n return 0;\n }\n // Put the replacement character into the output\n output.push(0xfffd);\n // Otherwise, process as if ignoring errors\n return ignoreFunc(reason, offset, bytes, output, badCodepoint);\n}\n/**\n * A handful of popular, built-in UTF-8 error handling strategies.\n *\n * **``\"error\"``** - throws on ANY illegal UTF-8 sequence or\n * non-canonical (overlong) codepoints (this is the default)\n *\n * **``\"ignore\"``** - silently drops any illegal UTF-8 sequence\n * and accepts non-canonical (overlong) codepoints\n *\n * **``\"replace\"``** - replace any illegal UTF-8 sequence with the\n * UTF-8 replacement character (i.e. ``\"\\\\ufffd\"``) and accepts\n * non-canonical (overlong) codepoints\n *\n * @returns: Record<\"error\" | \"ignore\" | \"replace\", Utf8ErrorFunc>\n */\nexport const Utf8ErrorFuncs = Object.freeze({\n error: errorFunc,\n ignore: ignoreFunc,\n replace: replaceFunc,\n});\n// http://stackoverflow.com/questions/13356493/decode-utf-8-with-javascript#13691499\nfunction getUtf8CodePoints(_bytes, onError) {\n if (onError == null) {\n onError = Utf8ErrorFuncs.error;\n }\n const bytes = getBytes(_bytes, \"bytes\");\n const result = [];\n let i = 0;\n // Invalid bytes are ignored\n while (i < bytes.length) {\n const c = bytes[i++];\n // 0xxx xxxx\n if (c >> 7 === 0) {\n result.push(c);\n continue;\n }\n // Multibyte; how many bytes left for this character?\n let extraLength = null;\n let overlongMask = null;\n // 110x xxxx 10xx xxxx\n if ((c & 0xe0) === 0xc0) {\n extraLength = 1;\n overlongMask = 0x7f;\n // 1110 xxxx 10xx xxxx 10xx xxxx\n }\n else if ((c & 0xf0) === 0xe0) {\n extraLength = 2;\n overlongMask = 0x7ff;\n // 1111 0xxx 10xx xxxx 10xx xxxx 10xx xxxx\n }\n else if ((c & 0xf8) === 0xf0) {\n extraLength = 3;\n overlongMask = 0xffff;\n }\n else {\n if ((c & 0xc0) === 0x80) {\n i += onError(\"UNEXPECTED_CONTINUE\", i - 1, bytes, result);\n }\n else {\n i += onError(\"BAD_PREFIX\", i - 1, bytes, result);\n }\n continue;\n }\n // Do we have enough bytes in our data?\n if (i - 1 + extraLength >= bytes.length) {\n i += onError(\"OVERRUN\", i - 1, bytes, result);\n continue;\n }\n // Remove the length prefix from the char\n let res = c & ((1 << (8 - extraLength - 1)) - 1);\n for (let j = 0; j < extraLength; j++) {\n let nextChar = bytes[i];\n // Invalid continuation byte\n if ((nextChar & 0xc0) != 0x80) {\n i += onError(\"MISSING_CONTINUE\", i, bytes, result);\n res = null;\n break;\n }\n res = (res << 6) | (nextChar & 0x3f);\n i++;\n }\n // See above loop for invalid continuation byte\n if (res === null) {\n continue;\n }\n // Maximum code point\n if (res > 0x10ffff) {\n i += onError(\"OUT_OF_RANGE\", i - 1 - extraLength, bytes, result, res);\n continue;\n }\n // Reserved for UTF-16 surrogate halves\n if (res >= 0xd800 && res <= 0xdfff) {\n i += onError(\"UTF16_SURROGATE\", i - 1 - extraLength, bytes, result, res);\n continue;\n }\n // Check for overlong sequences (more bytes than needed)\n if (res <= overlongMask) {\n i += onError(\"OVERLONG\", i - 1 - extraLength, bytes, result, res);\n continue;\n }\n result.push(res);\n }\n return result;\n}\n// http://stackoverflow.com/questions/18729405/how-to-convert-utf8-string-to-byte-array\n/**\n * Returns the UTF-8 byte representation of %%str%%.\n *\n * If %%form%% is specified, the string is normalized.\n */\nexport function toUtf8Bytes(str, form) {\n if (form != null) {\n assertNormalize(form);\n str = str.normalize(form);\n }\n let result = [];\n for (let i = 0; i < str.length; i++) {\n const c = str.charCodeAt(i);\n if (c < 0x80) {\n result.push(c);\n }\n else if (c < 0x800) {\n result.push((c >> 6) | 0xc0);\n result.push((c & 0x3f) | 0x80);\n }\n else if ((c & 0xfc00) == 0xd800) {\n i++;\n const c2 = str.charCodeAt(i);\n assertArgument(i < str.length && (c2 & 0xfc00) === 0xdc00, \"invalid surrogate pair\", \"str\", str);\n // Surrogate Pair\n const pair = 0x10000 + ((c & 0x03ff) << 10) + (c2 & 0x03ff);\n result.push((pair >> 18) | 0xf0);\n result.push(((pair >> 12) & 0x3f) | 0x80);\n result.push(((pair >> 6) & 0x3f) | 0x80);\n result.push((pair & 0x3f) | 0x80);\n }\n else {\n result.push((c >> 12) | 0xe0);\n result.push(((c >> 6) & 0x3f) | 0x80);\n result.push((c & 0x3f) | 0x80);\n }\n }\n return new Uint8Array(result);\n}\n//export\nfunction _toUtf8String(codePoints) {\n return codePoints\n .map((codePoint) => {\n if (codePoint <= 0xffff) {\n return String.fromCharCode(codePoint);\n }\n codePoint -= 0x10000;\n return String.fromCharCode(((codePoint >> 10) & 0x3ff) + 0xd800, (codePoint & 0x3ff) + 0xdc00);\n })\n .join(\"\");\n}\n/**\n * Returns the string represented by the UTF-8 data %%bytes%%.\n *\n * When %%onError%% function is specified, it is called on UTF-8\n * errors allowing recovery using the [[Utf8ErrorFunc]] API.\n * (default: [error](Utf8ErrorFuncs))\n */\nexport function toUtf8String(bytes, onError) {\n return _toUtf8String(getUtf8CodePoints(bytes, onError));\n}\n/**\n * Returns the UTF-8 code-points for %%str%%.\n *\n * If %%form%% is specified, the string is normalized.\n */\nexport function toUtf8CodePoints(str, form) {\n return getUtf8CodePoints(toUtf8Bytes(str, form));\n}\n//# sourceMappingURL=utf8.js.map","import { assert } from \"./errors.js\";\n// @TODO: timeout is completely ignored; start a Promise.any with a reject?\n// @ts-ignore\nexport async function getUrl(req, _signal) {\n const protocol = req.url.split(\":\")[0].toLowerCase();\n assert(protocol === \"http\" || protocol === \"https\", `unsupported protocol ${protocol}`, \"UNSUPPORTED_OPERATION\", {\n info: { protocol },\n operation: \"request\",\n });\n assert(protocol === \"https\" || !req.credentials || req.allowInsecureAuthentication, \"insecure authorized connections unsupported\", \"UNSUPPORTED_OPERATION\", {\n operation: \"request\",\n });\n let signal = undefined;\n if (_signal) {\n const controller = new AbortController();\n signal = controller.signal;\n _signal.addListener(() => {\n controller.abort();\n });\n }\n const init = {\n method: req.method,\n headers: new Headers(Array.from(req)),\n body: req.body || undefined,\n signal,\n };\n try {\n const resp = await fetch(req.url, init);\n const headers = {};\n resp.headers.forEach((value, key) => {\n headers[key.toLowerCase()] = value;\n });\n const respBody = await resp.arrayBuffer();\n const body = respBody == null ? null : new Uint8Array(respBody);\n return {\n statusCode: resp.status,\n statusMessage: resp.statusText,\n headers,\n body,\n };\n }\n catch (error) {\n console.log({ error });\n return undefined;\n }\n}\n//# sourceMappingURL=geturl-browser.js.map","/**\n * Explain fetching here...\n *\n * @_section api/utils/fetching:Fetching Web Content [about-fetch]\n */\nimport { decodeBase64, encodeBase64 } from \"./base64.js\";\nimport { hexlify } from \"./data.js\";\nimport { assert, assertArgument } from \"./errors.js\";\nimport { defineProperties } from \"./properties.js\";\nimport { toUtf8Bytes, toUtf8String } from \"./utf8.js\";\nimport { getUrl } from \"./geturl.js\";\nconst MAX_ATTEMPTS = 12;\nconst SLOT_INTERVAL = 250;\n// The global FetchGetUrlFunc implementation.\nlet getUrlFunc = getUrl;\nconst reData = new RegExp(\"^data:([^;:]*)?(;base64)?,(.*)$\", \"i\");\nconst reIpfs = new RegExp(\"^ipfs://(ipfs/)?(.*)$\", \"i\");\n// If locked, new Gateways cannot be added\nlet locked = false;\n// https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URLs\nasync function dataGatewayFunc(url, signal) {\n try {\n const match = url.match(reData);\n if (!match) {\n throw new Error(\"invalid data\");\n }\n return new FetchResponse(200, \"OK\", {\n \"content-type\": match[1] || \"text/plain\",\n }, match[2] ? decodeBase64(match[3]) : unpercent(match[3]));\n }\n catch (error) {\n return new FetchResponse(599, \"BAD REQUEST (invalid data: URI)\", {}, null, new FetchRequest(url));\n }\n}\n/**\n * Returns a [[FetchGatewayFunc]] for fetching content from a standard\n * IPFS gateway hosted at %%baseUrl%%.\n */\nfunction getIpfsGatewayFunc(baseUrl) {\n async function gatewayIpfs(url, signal) {\n try {\n const match = url.match(reIpfs);\n if (!match) {\n throw new Error(\"invalid link\");\n }\n return new FetchRequest(`${baseUrl}${match[2]}`);\n }\n catch (error) {\n return new FetchResponse(599, \"BAD REQUEST (invalid IPFS URI)\", {}, null, new FetchRequest(url));\n }\n }\n return gatewayIpfs;\n}\nconst Gateways = {\n data: dataGatewayFunc,\n ipfs: getIpfsGatewayFunc(\"https://gateway.ipfs.io/ipfs/\"),\n};\nconst fetchSignals = new WeakMap();\n/**\n * @_ignore\n */\nexport class FetchCancelSignal {\n #listeners;\n #cancelled;\n constructor(request) {\n this.#listeners = [];\n this.#cancelled = false;\n fetchSignals.set(request, () => {\n if (this.#cancelled) {\n return;\n }\n this.#cancelled = true;\n for (const listener of this.#listeners) {\n setTimeout(() => {\n listener();\n }, 0);\n }\n this.#listeners = [];\n });\n }\n addListener(listener) {\n assert(!this.#cancelled, \"singal already cancelled\", \"UNSUPPORTED_OPERATION\", {\n operation: \"fetchCancelSignal.addCancelListener\",\n });\n this.#listeners.push(listener);\n }\n get cancelled() {\n return this.#cancelled;\n }\n checkSignal() {\n assert(!this.cancelled, \"cancelled\", \"CANCELLED\", {});\n }\n}\n// Check the signal, throwing if it is cancelled\nfunction checkSignal(signal) {\n if (signal == null) {\n throw new Error(\"missing signal; should not happen\");\n }\n signal.checkSignal();\n return signal;\n}\n/**\n * Represents a request for a resource using a URI.\n *\n * By default, the supported schemes are ``HTTP``, ``HTTPS``, ``data:``,\n * and ``IPFS:``.\n *\n * Additional schemes can be added globally using [[registerGateway]].\n *\n * @example:\n * req = new FetchRequest(\"https://www.ricmoo.com\")\n * resp = await req.send()\n * resp.body.length\n * //_result:\n */\nexport class FetchRequest {\n #allowInsecure;\n #gzip;\n #headers;\n #method;\n #timeout;\n #url;\n #body;\n #bodyType;\n #creds;\n // Hooks\n #preflight;\n #process;\n #retry;\n #signal;\n #throttle;\n /**\n * The fetch URI to requrest.\n */\n get url() {\n return this.#url;\n }\n set url(url) {\n this.#url = String(url);\n }\n /**\n * The fetch body, if any, to send as the request body. //(default: null)//\n *\n * When setting a body, the intrinsic ``Content-Type`` is automatically\n * set and will be used if **not overridden** by setting a custom\n * header.\n *\n * If %%body%% is null, the body is cleared (along with the\n * intrinsic ``Content-Type``) and the .\n *\n * If %%body%% is a string, the intrincis ``Content-Type`` is set to\n * ``text/plain``.\n *\n * If %%body%% is a Uint8Array, the intrincis ``Content-Type`` is set to\n * ``application/octet-stream``.\n *\n * If %%body%% is any other object, the intrincis ``Content-Type`` is\n * set to ``application/json``.\n */\n get body() {\n if (this.#body == null) {\n return null;\n }\n return new Uint8Array(this.#body);\n }\n set body(body) {\n if (body == null) {\n this.#body = undefined;\n this.#bodyType = undefined;\n }\n else if (typeof body === \"string\") {\n this.#body = toUtf8Bytes(body);\n this.#bodyType = \"text/plain\";\n }\n else if (body instanceof Uint8Array) {\n this.#body = body;\n this.#bodyType = \"application/octet-stream\";\n }\n else if (typeof body === \"object\") {\n this.#body = toUtf8Bytes(JSON.stringify(body));\n this.#bodyType = \"application/json\";\n }\n else {\n throw new Error(\"invalid body\");\n }\n }\n /**\n * Returns true if the request has a body.\n */\n hasBody() {\n return this.#body != null;\n }\n /**\n * The HTTP method to use when requesting the URI. If no method\n * has been explicitly set, then ``GET`` is used if the body is\n * null and ``POST`` otherwise.\n */\n get method() {\n if (this.#method) {\n return this.#method;\n }\n if (this.hasBody()) {\n return \"POST\";\n }\n return \"GET\";\n }\n set method(method) {\n if (method == null) {\n method = \"\";\n }\n this.#method = String(method).toUpperCase();\n }\n /**\n * The headers that will be used when requesting the URI. All\n * keys are lower-case.\n *\n * This object is a copy, so any chnages will **NOT** be reflected\n * in the ``FetchRequest``.\n *\n * To set a header entry, use the ``setHeader`` method.\n */\n get headers() {\n const headers = Object.assign({}, this.#headers);\n if (this.#creds) {\n headers[\"authorization\"] = `Basic ${encodeBase64(toUtf8Bytes(this.#creds))}`;\n }\n if (this.allowGzip) {\n headers[\"accept-encoding\"] = \"gzip\";\n }\n if (headers[\"content-type\"] == null && this.#bodyType) {\n headers[\"content-type\"] = this.#bodyType;\n }\n if (this.body) {\n headers[\"content-length\"] = String(this.body.length);\n }\n return headers;\n }\n /**\n * Get the header for %%key%%, ignoring case.\n */\n getHeader(key) {\n return this.headers[key.toLowerCase()];\n }\n /**\n * Set the header for %%key%% to %%value%%. All values are coerced\n * to a string.\n */\n setHeader(key, value) {\n this.#headers[String(key).toLowerCase()] = String(value);\n }\n /**\n * Clear all headers, resetting all intrinsic headers.\n */\n clearHeaders() {\n this.#headers = {};\n }\n [Symbol.iterator]() {\n const headers = this.headers;\n const keys = Object.keys(headers);\n let index = 0;\n return {\n next: () => {\n if (index < keys.length) {\n const key = keys[index++];\n return {\n value: [key, headers[key]],\n done: false,\n };\n }\n return { value: undefined, done: true };\n },\n };\n }\n /**\n * The value that will be sent for the ``Authorization`` header.\n *\n * To set the credentials, use the ``setCredentials`` method.\n */\n get credentials() {\n return this.#creds || null;\n }\n /**\n * Sets an ``Authorization`` for %%username%% with %%password%%.\n */\n setCredentials(username, password) {\n assertArgument(!username.match(/:/), \"invalid basic authentication username\", \"username\", \"[REDACTED]\");\n this.#creds = `${username}:${password}`;\n }\n /**\n * Enable and request gzip-encoded responses. The response will\n * automatically be decompressed. //(default: true)//\n */\n get allowGzip() {\n return this.#gzip;\n }\n set allowGzip(value) {\n this.#gzip = !!value;\n }\n /**\n * Allow ``Authentication`` credentials to be sent over insecure\n * channels. //(default: false)//\n */\n get allowInsecureAuthentication() {\n return !!this.#allowInsecure;\n }\n set allowInsecureAuthentication(value) {\n this.#allowInsecure = !!value;\n }\n /**\n * The timeout (in milliseconds) to wait for a complere response.\n * //(default: 5 minutes)//\n */\n get timeout() {\n return this.#timeout;\n }\n set timeout(timeout) {\n assertArgument(timeout >= 0, \"timeout must be non-zero\", \"timeout\", timeout);\n this.#timeout = timeout;\n }\n /**\n * This function is called prior to each request, for example\n * during a redirection or retry in case of server throttling.\n *\n * This offers an opportunity to populate headers or update\n * content before sending a request.\n */\n get preflightFunc() {\n return this.#preflight || null;\n }\n set preflightFunc(preflight) {\n this.#preflight = preflight;\n }\n /**\n * This function is called after each response, offering an\n * opportunity to provide client-level throttling or updating\n * response data.\n *\n * Any error thrown in this causes the ``send()`` to throw.\n *\n * To schedule a retry attempt (assuming the maximum retry limit\n * has not been reached), use [[response.throwThrottleError]].\n */\n get processFunc() {\n return this.#process || null;\n }\n set processFunc(process) {\n this.#process = process;\n }\n /**\n * This function is called on each retry attempt.\n */\n get retryFunc() {\n return this.#retry || null;\n }\n set retryFunc(retry) {\n this.#retry = retry;\n }\n /**\n * Create a new FetchRequest instance with default values.\n *\n * Once created, each property may be set before issuing a\n * ``.send()`` to make the request.\n */\n constructor(url) {\n this.#url = String(url);\n this.#allowInsecure = false;\n this.#gzip = true;\n this.#headers = {};\n this.#method = \"\";\n this.#timeout = 300000;\n this.#throttle = {\n slotInterval: SLOT_INTERVAL,\n maxAttempts: MAX_ATTEMPTS,\n };\n }\n toString() {\n return ``;\n }\n /**\n * Update the throttle parameters used to determine maximum\n * attempts and exponential-backoff properties.\n */\n setThrottleParams(params) {\n if (params.slotInterval != null) {\n this.#throttle.slotInterval = params.slotInterval;\n }\n if (params.maxAttempts != null) {\n this.#throttle.maxAttempts = params.maxAttempts;\n }\n }\n async #send(attempt, expires, delay, _request, _response) {\n if (attempt >= this.#throttle.maxAttempts) {\n return _response.makeServerError(\"exceeded maximum retry limit\");\n }\n assert(getTime() <= expires, \"timeout\", \"TIMEOUT\", {\n operation: \"request.send\",\n reason: \"timeout\",\n request: _request,\n });\n if (delay > 0) {\n await wait(delay);\n }\n let req = this.clone();\n const scheme = (req.url.split(\":\")[0] || \"\").toLowerCase();\n // Process any Gateways\n if (scheme in Gateways) {\n const result = await Gateways[scheme](req.url, checkSignal(_request.#signal));\n if (result instanceof FetchResponse) {\n let response = result;\n if (this.processFunc) {\n checkSignal(_request.#signal);\n try {\n response = await this.processFunc(req, response);\n }\n catch (error) {\n // Something went wrong during processing; throw a 5xx server error\n if (error.throttle == null || typeof error.stall !== \"number\") {\n response\n .makeServerError(\"error in post-processing function\", error)\n .assertOk();\n }\n // Ignore throttling\n }\n }\n return response;\n }\n req = result;\n }\n // We have a preflight function; update the request\n if (this.preflightFunc) {\n req = await this.preflightFunc(req);\n }\n const resp = await getUrlFunc(req, checkSignal(_request.#signal));\n let response = new FetchResponse(resp.statusCode, resp.statusMessage, resp.headers, resp.body, _request);\n if (response.statusCode === 301 || response.statusCode === 302) {\n // Redirect\n try {\n const location = response.headers.location || \"\";\n return req\n .redirect(location)\n .#send(attempt + 1, expires, 0, _request, response);\n }\n catch (error) { }\n // Things won't get any better on another attempt; abort\n return response;\n }\n else if (response.statusCode === 429) {\n // Throttle\n if (this.retryFunc == null ||\n (await this.retryFunc(req, response, attempt))) {\n const retryAfter = response.headers[\"retry-after\"];\n let delay = this.#throttle.slotInterval *\n Math.trunc(Math.random() * Math.pow(2, attempt));\n if (typeof retryAfter === \"string\" &&\n retryAfter.match(/^[1-9][0-9]*$/)) {\n delay = parseInt(retryAfter);\n }\n return req\n .clone()\n .#send(attempt + 1, expires, delay, _request, response);\n }\n }\n if (this.processFunc) {\n checkSignal(_request.#signal);\n try {\n response = await this.processFunc(req, response);\n }\n catch (error) {\n // Something went wrong during processing; throw a 5xx server error\n if (error.throttle == null || typeof error.stall !== \"number\") {\n response\n .makeServerError(\"error in post-processing function\", error)\n .assertOk();\n }\n // Throttle\n let delay = this.#throttle.slotInterval *\n Math.trunc(Math.random() * Math.pow(2, attempt));\n if (error.stall >= 0) {\n delay = error.stall;\n }\n return req\n .clone()\n .#send(attempt + 1, expires, delay, _request, response);\n }\n }\n return response;\n }\n /**\n * Resolves to the response by sending the request.\n */\n send() {\n assert(this.#signal == null, \"request already sent\", \"UNSUPPORTED_OPERATION\", { operation: \"fetchRequest.send\" });\n this.#signal = new FetchCancelSignal(this);\n return this.#send(0, getTime() + this.timeout, 0, this, new FetchResponse(0, \"\", {}, null, this));\n }\n /**\n * Cancels the inflight response, causing a ``CANCELLED``\n * error to be rejected from the [[send]].\n */\n cancel() {\n assert(this.#signal != null, \"request has not been sent\", \"UNSUPPORTED_OPERATION\", { operation: \"fetchRequest.cancel\" });\n const signal = fetchSignals.get(this);\n if (!signal) {\n throw new Error(\"missing signal; should not happen\");\n }\n signal();\n }\n /**\n * Returns a new [[FetchRequest]] that represents the redirection\n * to %%location%%.\n */\n redirect(location) {\n // Redirection; for now we only support absolute locataions\n const current = this.url.split(\":\")[0].toLowerCase();\n const target = location.split(\":\")[0].toLowerCase();\n // Don't allow redirecting:\n // - non-GET requests\n // - downgrading the security (e.g. https => http)\n // - to non-HTTP (or non-HTTPS) protocols [this could be relaxed?]\n assert(this.method === \"GET\" &&\n (current !== \"https\" || target !== \"http\") &&\n location.match(/^https?:/), `unsupported redirect`, \"UNSUPPORTED_OPERATION\", {\n operation: `redirect(${this.method} ${JSON.stringify(this.url)} => ${JSON.stringify(location)})`,\n });\n // Create a copy of this request, with a new URL\n const req = new FetchRequest(location);\n req.method = \"GET\";\n req.allowGzip = this.allowGzip;\n req.timeout = this.timeout;\n req.#headers = Object.assign({}, this.#headers);\n if (this.#body) {\n req.#body = new Uint8Array(this.#body);\n }\n req.#bodyType = this.#bodyType;\n // Do not forward credentials unless on the same domain; only absolute\n //req.allowInsecure = false;\n // paths are currently supported; may want a way to specify to forward?\n //setStore(req.#props, \"creds\", getStore(this.#pros, \"creds\"));\n return req;\n }\n /**\n * Create a new copy of this request.\n */\n clone() {\n const clone = new FetchRequest(this.url);\n // Preserve \"default method\" (i.e. null)\n clone.#method = this.#method;\n // Preserve \"default body\" with type, copying the Uint8Array is present\n if (this.#body) {\n clone.#body = this.#body;\n }\n clone.#bodyType = this.#bodyType;\n // Preserve \"default headers\"\n clone.#headers = Object.assign({}, this.#headers);\n // Credentials is readonly, so we copy internally\n clone.#creds = this.#creds;\n if (this.allowGzip) {\n clone.allowGzip = true;\n }\n clone.timeout = this.timeout;\n if (this.allowInsecureAuthentication) {\n clone.allowInsecureAuthentication = true;\n }\n clone.#preflight = this.#preflight;\n clone.#process = this.#process;\n clone.#retry = this.#retry;\n return clone;\n }\n /**\n * Locks all static configuration for gateways and FetchGetUrlFunc\n * registration.\n */\n static lockConfig() {\n locked = true;\n }\n /**\n * Get the current Gateway function for %%scheme%%.\n */\n static getGateway(scheme) {\n return Gateways[scheme.toLowerCase()] || null;\n }\n /**\n * Use the %%func%% when fetching URIs using %%scheme%%.\n *\n * This method affects all requests globally.\n *\n * If [[lockConfig]] has been called, no change is made and this\n * throws.\n */\n static registerGateway(scheme, func) {\n scheme = scheme.toLowerCase();\n if (scheme === \"http\" || scheme === \"https\") {\n throw new Error(`cannot intercept ${scheme}; use registerGetUrl`);\n }\n if (locked) {\n throw new Error(\"gateways locked\");\n }\n Gateways[scheme] = func;\n }\n /**\n * Use %%getUrl%% when fetching URIs over HTTP and HTTPS requests.\n *\n * This method affects all requests globally.\n *\n * If [[lockConfig]] has been called, no change is made and this\n * throws.\n */\n static registerGetUrl(getUrl) {\n if (locked) {\n throw new Error(\"gateways locked\");\n }\n getUrlFunc = getUrl;\n }\n /**\n * Creates a function that can \"fetch\" data URIs.\n *\n * Note that this is automatically done internally to support\n * data URIs, so it is not necessary to register it.\n *\n * This is not generally something that is needed, but may\n * be useful in a wrapper to perfom custom data URI functionality.\n */\n static createDataGateway() {\n return dataGatewayFunc;\n }\n /**\n * Creates a function that will fetch IPFS (unvalidated) from\n * a custom gateway baseUrl.\n *\n * The default IPFS gateway used internally is\n * ``\"https:/\\/gateway.ipfs.io/ipfs/\"``.\n */\n static createIpfsGatewayFunc(baseUrl) {\n return getIpfsGatewayFunc(baseUrl);\n }\n}\n/**\n * The response for a FetchREquest.\n */\nexport class FetchResponse {\n #statusCode;\n #statusMessage;\n #headers;\n #body;\n #request;\n #error;\n toString() {\n return ``;\n }\n /**\n * The response status code.\n */\n get statusCode() {\n return this.#statusCode;\n }\n /**\n * The response status message.\n */\n get statusMessage() {\n return this.#statusMessage;\n }\n /**\n * The response headers. All keys are lower-case.\n */\n get headers() {\n return Object.assign({}, this.#headers);\n }\n /**\n * The response body, or ``null`` if there was no body.\n */\n get body() {\n return this.#body == null ? null : new Uint8Array(this.#body);\n }\n /**\n * The response body as a UTF-8 encoded string, or the empty\n * string (i.e. ``\"\"``) if there was no body.\n *\n * An error is thrown if the body is invalid UTF-8 data.\n */\n get bodyText() {\n try {\n return this.#body == null ? \"\" : toUtf8String(this.#body);\n }\n catch (error) {\n assert(false, \"response body is not valid UTF-8 data\", \"UNSUPPORTED_OPERATION\", {\n operation: \"bodyText\",\n info: { response: this },\n });\n }\n }\n /**\n * The response body, decoded as JSON.\n *\n * An error is thrown if the body is invalid JSON-encoded data\n * or if there was no body.\n */\n get bodyJson() {\n try {\n return JSON.parse(this.bodyText);\n }\n catch (error) {\n assert(false, \"response body is not valid JSON\", \"UNSUPPORTED_OPERATION\", {\n operation: \"bodyJson\",\n info: { response: this },\n });\n }\n }\n [Symbol.iterator]() {\n const headers = this.headers;\n const keys = Object.keys(headers);\n let index = 0;\n return {\n next: () => {\n if (index < keys.length) {\n const key = keys[index++];\n return {\n value: [key, headers[key]],\n done: false,\n };\n }\n return { value: undefined, done: true };\n },\n };\n }\n constructor(statusCode, statusMessage, headers, body, request) {\n this.#statusCode = statusCode;\n this.#statusMessage = statusMessage;\n this.#headers = Object.keys(headers).reduce((accum, k) => {\n accum[k.toLowerCase()] = String(headers[k]);\n return accum;\n }, {});\n this.#body = body == null ? null : new Uint8Array(body);\n this.#request = request || null;\n this.#error = { message: \"\" };\n }\n /**\n * Return a Response with matching headers and body, but with\n * an error status code (i.e. 599) and %%message%% with an\n * optional %%error%%.\n */\n makeServerError(message, error) {\n let statusMessage;\n if (!message) {\n message = `${this.statusCode} ${this.statusMessage}`;\n statusMessage = `CLIENT ESCALATED SERVER ERROR (${message})`;\n }\n else {\n statusMessage = `CLIENT ESCALATED SERVER ERROR (${this.statusCode} ${this.statusMessage}; ${message})`;\n }\n const response = new FetchResponse(599, statusMessage, this.headers, this.body, this.#request || undefined);\n response.#error = { message, error };\n return response;\n }\n /**\n * If called within a [request.processFunc](FetchRequest-processFunc)\n * call, causes the request to retry as if throttled for %%stall%%\n * milliseconds.\n */\n throwThrottleError(message, stall) {\n if (stall == null) {\n stall = -1;\n }\n else {\n assertArgument(Number.isInteger(stall) && stall >= 0, \"invalid stall timeout\", \"stall\", stall);\n }\n const error = new Error(message || \"throttling requests\");\n defineProperties(error, { stall, throttle: true });\n throw error;\n }\n /**\n * Get the header value for %%key%%, ignoring case.\n */\n getHeader(key) {\n return this.headers[key.toLowerCase()];\n }\n /**\n * Returns true of the response has a body.\n */\n hasBody() {\n return this.#body != null;\n }\n /**\n * The request made for this response.\n */\n get request() {\n return this.#request;\n }\n /**\n * Returns true if this response was a success statusCode.\n */\n ok() {\n return (this.#error.message === \"\" &&\n this.statusCode >= 200 &&\n this.statusCode < 300);\n }\n /**\n * Throws a ``SERVER_ERROR`` if this response is not ok.\n */\n assertOk() {\n if (this.ok()) {\n return;\n }\n let { message, error } = this.#error;\n if (message === \"\") {\n message = `server response ${this.statusCode} ${this.statusMessage}`;\n }\n assert(false, message, \"SERVER_ERROR\", {\n request: this.request || \"unknown request\",\n response: this,\n error,\n });\n }\n}\nfunction getTime() {\n return new Date().getTime();\n}\nfunction unpercent(value) {\n return toUtf8Bytes(value.replace(/%([0-9a-f][0-9a-f])/gi, (all, code) => {\n return String.fromCharCode(parseInt(code, 16));\n }));\n}\nfunction wait(delay) {\n return new Promise((resolve) => setTimeout(resolve, delay));\n}\n//# sourceMappingURL=fetch.js.map","var _a;\n/**\n * About fixed-point math...\n *\n * @_section: api/utils/fixed-point-math:Fixed-Point Maths [about-fixed-point-math]\n */\nimport { getBytes } from \"./data.js\";\nimport { assert, assertArgument, assertPrivate } from \"./errors.js\";\nimport { getBigInt, fromTwos, mask, toBigInt } from \"./maths.js\";\nimport { defineProperties } from \"./properties.js\";\nconst BN_N1 = BigInt(-1);\nconst BN_0 = BigInt(0);\nconst BN_1 = BigInt(1);\nconst BN_5 = BigInt(5);\nconst _guard = {};\n// Constant to pull zeros from for multipliers\nlet Zeros = \"0000\";\nwhile (Zeros.length < 80) {\n Zeros += Zeros;\n}\n// Returns a string \"1\" followed by decimal \"0\"s\nfunction getTens(decimals) {\n let result = Zeros;\n while (result.length < decimals) {\n result += result;\n }\n return BigInt(\"1\" + result.substring(0, decimals));\n}\nfunction checkValue(val, format, safeOp) {\n const width = BigInt(format.width);\n if (format.signed) {\n const limit = BN_1 << (width - BN_1);\n assert(safeOp == null || (val >= -limit && val < limit), \"overflow\", \"NUMERIC_FAULT\", {\n operation: safeOp,\n fault: \"overflow\",\n value: val,\n });\n if (val > BN_0) {\n val = fromTwos(mask(val, width), width);\n }\n else {\n val = -fromTwos(mask(-val, width), width);\n }\n }\n else {\n const limit = BN_1 << width;\n assert(safeOp == null || (val >= 0 && val < limit), \"overflow\", \"NUMERIC_FAULT\", {\n operation: safeOp,\n fault: \"overflow\",\n value: val,\n });\n val = ((val % limit) + limit) % limit & (limit - BN_1);\n }\n return val;\n}\nfunction getFormat(value) {\n if (typeof value === \"number\") {\n value = `fixed128x${value}`;\n }\n let signed = true;\n let width = 128;\n let decimals = 18;\n if (typeof value === \"string\") {\n // Parse the format string\n if (value === \"fixed\") {\n // defaults...\n }\n else if (value === \"ufixed\") {\n signed = false;\n }\n else {\n const match = value.match(/^(u?)fixed([0-9]+)x([0-9]+)$/);\n assertArgument(match, \"invalid fixed format\", \"format\", value);\n signed = match[1] !== \"u\";\n width = parseInt(match[2]);\n decimals = parseInt(match[3]);\n }\n }\n else if (value) {\n // Extract the values from the object\n const v = value;\n const check = (key, type, defaultValue) => {\n if (v[key] == null) {\n return defaultValue;\n }\n assertArgument(typeof v[key] === type, \"invalid fixed format (\" + key + \" not \" + type + \")\", \"format.\" + key, v[key]);\n return v[key];\n };\n signed = check(\"signed\", \"boolean\", signed);\n width = check(\"width\", \"number\", width);\n decimals = check(\"decimals\", \"number\", decimals);\n }\n assertArgument(width % 8 === 0, \"invalid FixedNumber width (not byte aligned)\", \"format.width\", width);\n assertArgument(decimals <= 80, \"invalid FixedNumber decimals (too large)\", \"format.decimals\", decimals);\n const name = (signed ? \"\" : \"u\") + \"fixed\" + String(width) + \"x\" + String(decimals);\n return { signed, width, decimals, name };\n}\nfunction toString(val, decimals) {\n let negative = \"\";\n if (val < BN_0) {\n negative = \"-\";\n val *= BN_N1;\n }\n let str = val.toString();\n // No decimal point for whole values\n if (decimals === 0) {\n return negative + str;\n }\n // Pad out to the whole component (including a whole digit)\n while (str.length <= decimals) {\n str = Zeros + str;\n }\n // Insert the decimal point\n const index = str.length - decimals;\n str = str.substring(0, index) + \".\" + str.substring(index);\n // Trim the whole component (leaving at least one 0)\n while (str[0] === \"0\" && str[1] !== \".\") {\n str = str.substring(1);\n }\n // Trim the decimal component (leaving at least one 0)\n while (str[str.length - 1] === \"0\" && str[str.length - 2] !== \".\") {\n str = str.substring(0, str.length - 1);\n }\n return negative + str;\n}\n/**\n * A FixedNumber represents a value over its [[FixedFormat]]\n * arithmetic field.\n *\n * A FixedNumber can be used to perform math, losslessly, on\n * values which have decmial places.\n *\n * A FixedNumber has a fixed bit-width to store values in, and stores all\n * values internally by multiplying the value by 10 raised to the power of\n * %%decimals%%.\n *\n * If operations are performed that cause a value to grow too high (close to\n * positive infinity) or too low (close to negative infinity), the value\n * is said to //overflow//.\n *\n * For example, an 8-bit signed value, with 0 decimals may only be within\n * the range ``-128`` to ``127``; so ``-128 - 1`` will overflow and become\n * ``127``. Likewise, ``127 + 1`` will overflow and become ``-127``.\n *\n * Many operation have a normal and //unsafe// variant. The normal variant\n * will throw a [[NumericFaultError]] on any overflow, while the //unsafe//\n * variant will silently allow overflow, corrupting its value value.\n *\n * If operations are performed that cause a value to become too small\n * (close to zero), the value loses precison and is said to //underflow//.\n *\n * For example, an value with 1 decimal place may store a number as small\n * as ``0.1``, but the value of ``0.1 / 2`` is ``0.05``, which cannot fit\n * into 1 decimal place, so underflow occurs which means precision is lost\n * and the value becomes ``0``.\n *\n * Some operations have a normal and //signalling// variant. The normal\n * variant will silently ignore underflow, while the //signalling// variant\n * will thow a [[NumericFaultError]] on underflow.\n */\nexport class FixedNumber {\n /**\n * The specific fixed-point arithmetic field for this value.\n */\n format;\n #format;\n // The actual value (accounting for decimals)\n #val;\n // A base-10 value to multiple values by to maintain the magnitude\n #tens;\n /**\n * This is a property so console.log shows a human-meaningful value.\n *\n * @private\n */\n _value;\n // Use this when changing this file to get some typing info,\n // but then switch to any to mask the internal type\n //constructor(guard: any, value: bigint, format: _FixedFormat) {\n /**\n * @private\n */\n constructor(guard, value, format) {\n assertPrivate(guard, _guard, \"FixedNumber\");\n this.#val = value;\n this.#format = format;\n const _value = toString(value, format.decimals);\n defineProperties(this, { format: format.name, _value });\n this.#tens = getTens(format.decimals);\n }\n /**\n * If true, negative values are permitted, otherwise only\n * positive values and zero are allowed.\n */\n get signed() {\n return this.#format.signed;\n }\n /**\n * The number of bits available to store the value.\n */\n get width() {\n return this.#format.width;\n }\n /**\n * The number of decimal places in the fixed-point arithment field.\n */\n get decimals() {\n return this.#format.decimals;\n }\n /**\n * The value as an integer, based on the smallest unit the\n * [[decimals]] allow.\n */\n get value() {\n return this.#val;\n }\n #checkFormat(other) {\n assertArgument(this.format === other.format, \"incompatible format; use fixedNumber.toFormat\", \"other\", other);\n }\n #checkValue(val, safeOp) {\n /*\n const width = BigInt(this.width);\n if (this.signed) {\n const limit = (BN_1 << (width - BN_1));\n assert(safeOp == null || (val >= -limit && val < limit), \"overflow\", \"NUMERIC_FAULT\", {\n operation: safeOp, fault: \"overflow\", value: val\n });\n \n if (val > BN_0) {\n val = fromTwos(mask(val, width), width);\n } else {\n val = -fromTwos(mask(-val, width), width);\n }\n \n } else {\n const masked = mask(val, width);\n assert(safeOp == null || (val >= 0 && val === masked), \"overflow\", \"NUMERIC_FAULT\", {\n operation: safeOp, fault: \"overflow\", value: val\n });\n val = masked;\n }\n */\n val = checkValue(val, this.#format, safeOp);\n return new _a(_guard, val, this.#format);\n }\n #add(o, safeOp) {\n this.#checkFormat(o);\n return this.#checkValue(this.#val + o.#val, safeOp);\n }\n /**\n * Returns a new [[FixedNumber]] with the result of %%this%% added\n * to %%other%%, ignoring overflow.\n */\n addUnsafe(other) {\n return this.#add(other);\n }\n /**\n * Returns a new [[FixedNumber]] with the result of %%this%% added\n * to %%other%%. A [[NumericFaultError]] is thrown if overflow\n * occurs.\n */\n add(other) {\n return this.#add(other, \"add\");\n }\n #sub(o, safeOp) {\n this.#checkFormat(o);\n return this.#checkValue(this.#val - o.#val, safeOp);\n }\n /**\n * Returns a new [[FixedNumber]] with the result of %%other%% subtracted\n * from %%this%%, ignoring overflow.\n */\n subUnsafe(other) {\n return this.#sub(other);\n }\n /**\n * Returns a new [[FixedNumber]] with the result of %%other%% subtracted\n * from %%this%%. A [[NumericFaultError]] is thrown if overflow\n * occurs.\n */\n sub(other) {\n return this.#sub(other, \"sub\");\n }\n #mul(o, safeOp) {\n this.#checkFormat(o);\n return this.#checkValue((this.#val * o.#val) / this.#tens, safeOp);\n }\n /**\n * Returns a new [[FixedNumber]] with the result of %%this%% multiplied\n * by %%other%%, ignoring overflow and underflow (precision loss).\n */\n mulUnsafe(other) {\n return this.#mul(other);\n }\n /**\n * Returns a new [[FixedNumber]] with the result of %%this%% multiplied\n * by %%other%%. A [[NumericFaultError]] is thrown if overflow\n * occurs.\n */\n mul(other) {\n return this.#mul(other, \"mul\");\n }\n /**\n * Returns a new [[FixedNumber]] with the result of %%this%% multiplied\n * by %%other%%. A [[NumericFaultError]] is thrown if overflow\n * occurs or if underflow (precision loss) occurs.\n */\n mulSignal(other) {\n this.#checkFormat(other);\n const value = this.#val * other.#val;\n assert(value % this.#tens === BN_0, \"precision lost during signalling mul\", \"NUMERIC_FAULT\", {\n operation: \"mulSignal\",\n fault: \"underflow\",\n value: this,\n });\n return this.#checkValue(value / this.#tens, \"mulSignal\");\n }\n #div(o, safeOp) {\n assert(o.#val !== BN_0, \"division by zero\", \"NUMERIC_FAULT\", {\n operation: \"div\",\n fault: \"divide-by-zero\",\n value: this,\n });\n this.#checkFormat(o);\n return this.#checkValue((this.#val * this.#tens) / o.#val, safeOp);\n }\n /**\n * Returns a new [[FixedNumber]] with the result of %%this%% divided\n * by %%other%%, ignoring underflow (precision loss). A\n * [[NumericFaultError]] is thrown if overflow occurs.\n */\n divUnsafe(other) {\n return this.#div(other);\n }\n /**\n * Returns a new [[FixedNumber]] with the result of %%this%% divided\n * by %%other%%, ignoring underflow (precision loss). A\n * [[NumericFaultError]] is thrown if overflow occurs.\n */\n div(other) {\n return this.#div(other, \"div\");\n }\n /**\n * Returns a new [[FixedNumber]] with the result of %%this%% divided\n * by %%other%%. A [[NumericFaultError]] is thrown if underflow\n * (precision loss) occurs.\n */\n divSignal(other) {\n assert(other.#val !== BN_0, \"division by zero\", \"NUMERIC_FAULT\", {\n operation: \"div\",\n fault: \"divide-by-zero\",\n value: this,\n });\n this.#checkFormat(other);\n const value = this.#val * this.#tens;\n assert(value % other.#val === BN_0, \"precision lost during signalling div\", \"NUMERIC_FAULT\", {\n operation: \"divSignal\",\n fault: \"underflow\",\n value: this,\n });\n return this.#checkValue(value / other.#val, \"divSignal\");\n }\n /**\n * Returns a comparison result between %%this%% and %%other%%.\n *\n * This is suitable for use in sorting, where ``-1`` implies %%this%%\n * is smaller, ``1`` implies %%other%% is larger and ``0`` implies\n * both are equal.\n */\n cmp(other) {\n let a = this.value, b = other.value;\n // Coerce a and b to the same magnitude\n const delta = this.decimals - other.decimals;\n if (delta > 0) {\n b *= getTens(delta);\n }\n else if (delta < 0) {\n a *= getTens(-delta);\n }\n // Comnpare\n if (a < b) {\n return -1;\n }\n if (a > b) {\n return -1;\n }\n return 0;\n }\n /**\n * Returns true if %%other%% is equal to %%this%%.\n */\n eq(other) {\n return this.cmp(other) === 0;\n }\n /**\n * Returns true if %%other%% is less than to %%this%%.\n */\n lt(other) {\n return this.cmp(other) < 0;\n }\n /**\n * Returns true if %%other%% is less than or equal to %%this%%.\n */\n lte(other) {\n return this.cmp(other) <= 0;\n }\n /**\n * Returns true if %%other%% is greater than to %%this%%.\n */\n gt(other) {\n return this.cmp(other) > 0;\n }\n /**\n * Returns true if %%other%% is greater than or equal to %%this%%.\n */\n gte(other) {\n return this.cmp(other) >= 0;\n }\n /**\n * Returns a new [[FixedNumber]] which is the largest **integer**\n * that is less than or equal to %%this%%.\n *\n * The decimal component of the result will always be ``0``.\n */\n floor() {\n let val = this.#val;\n if (this.#val < BN_0) {\n val -= this.#tens - BN_1;\n }\n val = (this.#val / this.#tens) * this.#tens;\n return this.#checkValue(val, \"floor\");\n }\n /**\n * Returns a new [[FixedNumber]] which is the smallest **integer**\n * that is greater than or equal to %%this%%.\n *\n * The decimal component of the result will always be ``0``.\n */\n ceiling() {\n let val = this.#val;\n if (this.#val > BN_0) {\n val += this.#tens - BN_1;\n }\n val = (this.#val / this.#tens) * this.#tens;\n return this.#checkValue(val, \"ceiling\");\n }\n /**\n * Returns a new [[FixedNumber]] with the decimal component\n * rounded up on ties at %%decimals%% places.\n */\n round(decimals) {\n if (decimals == null) {\n decimals = 0;\n }\n // Not enough precision to not already be rounded\n if (decimals >= this.decimals) {\n return this;\n }\n const delta = this.decimals - decimals;\n const bump = BN_5 * getTens(delta - 1);\n let value = this.value + bump;\n const tens = getTens(delta);\n value = (value / tens) * tens;\n checkValue(value, this.#format, \"round\");\n return new _a(_guard, value, this.#format);\n }\n /**\n * Returns true if %%this%% is equal to ``0``.\n */\n isZero() {\n return this.#val === BN_0;\n }\n /**\n * Returns true if %%this%% is less than ``0``.\n */\n isNegative() {\n return this.#val < BN_0;\n }\n /**\n * Returns the string representation of %%this%%.\n */\n toString() {\n return this._value;\n }\n /**\n * Returns a float approximation.\n *\n * Due to IEEE 754 precission (or lack thereof), this function\n * can only return an approximation and most values will contain\n * rounding errors.\n */\n toUnsafeFloat() {\n return parseFloat(this.toString());\n }\n /**\n * Return a new [[FixedNumber]] with the same value but has had\n * its field set to %%format%%.\n *\n * This will throw if the value cannot fit into %%format%%.\n */\n toFormat(format) {\n return _a.fromString(this.toString(), format);\n }\n /**\n * Creates a new [[FixedNumber]] for %%value%% divided by\n * %%decimal%% places with %%format%%.\n *\n * This will throw a [[NumericFaultError]] if %%value%% (once adjusted\n * for %%decimals%%) cannot fit in %%format%%, either due to overflow\n * or underflow (precision loss).\n */\n static fromValue(_value, decimals, _format) {\n if (decimals == null) {\n decimals = 0;\n }\n const format = getFormat(_format);\n let value = getBigInt(_value, \"value\");\n const delta = decimals - format.decimals;\n if (delta > 0) {\n const tens = getTens(delta);\n assert(value % tens === BN_0, \"value loses precision for format\", \"NUMERIC_FAULT\", {\n operation: \"fromValue\",\n fault: \"underflow\",\n value: _value,\n });\n value /= tens;\n }\n else if (delta < 0) {\n value *= getTens(-delta);\n }\n checkValue(value, format, \"fromValue\");\n return new _a(_guard, value, format);\n }\n /**\n * Creates a new [[FixedNumber]] for %%value%% with %%format%%.\n *\n * This will throw a [[NumericFaultError]] if %%value%% cannot fit\n * in %%format%%, either due to overflow or underflow (precision loss).\n */\n static fromString(_value, _format) {\n const match = _value.match(/^(-?)([0-9]*)\\.?([0-9]*)$/);\n assertArgument(match && match[2].length + match[3].length > 0, \"invalid FixedNumber string value\", \"value\", _value);\n const format = getFormat(_format);\n let whole = match[2] || \"0\", decimal = match[3] || \"\";\n // Pad out the decimals\n while (decimal.length < format.decimals) {\n decimal += Zeros;\n }\n // Check precision is safe\n assert(decimal.substring(format.decimals).match(/^0*$/), \"too many decimals for format\", \"NUMERIC_FAULT\", {\n operation: \"fromString\",\n fault: \"underflow\",\n value: _value,\n });\n // Remove extra padding\n decimal = decimal.substring(0, format.decimals);\n const value = BigInt(match[1] + whole + decimal);\n checkValue(value, format, \"fromString\");\n return new _a(_guard, value, format);\n }\n /**\n * Creates a new [[FixedNumber]] with the big-endian representation\n * %%value%% with %%format%%.\n *\n * This will throw a [[NumericFaultError]] if %%value%% cannot fit\n * in %%format%% due to overflow.\n */\n static fromBytes(_value, _format) {\n let value = toBigInt(getBytes(_value, \"value\"));\n const format = getFormat(_format);\n if (format.signed) {\n value = fromTwos(value, format.width);\n }\n checkValue(value, format, \"fromBytes\");\n return new _a(_guard, value, format);\n }\n}\n_a = FixedNumber;\n//const f1 = FixedNumber.fromString(\"12.56\", \"fixed16x2\");\n//const f2 = FixedNumber.fromString(\"0.3\", \"fixed16x2\");\n//console.log(f1.divSignal(f2));\n//const BUMP = FixedNumber.from(\"0.5\");\n//# sourceMappingURL=fixednumber.js.map","import { hexlify } from \"./data.js\";\nimport { assert, assertArgument } from \"./errors.js\";\nimport { getBytes } from \"./data.js\";\nfunction hexlifyByte(value) {\n let result = value.toString(16);\n while (result.length < 2) {\n result = \"0\" + result;\n }\n return \"0x\" + result;\n}\nfunction unarrayifyInteger(data, offset, length) {\n let result = 0;\n for (let i = 0; i < length; i++) {\n result = result * 256 + data[offset + i];\n }\n return result;\n}\nfunction _decodeChildren(data, offset, childOffset, length) {\n const result = [];\n while (childOffset < offset + 1 + length) {\n const decoded = _decode(data, childOffset);\n result.push(decoded.result);\n childOffset += decoded.consumed;\n assert(childOffset <= offset + 1 + length, \"child data too short\", \"BUFFER_OVERRUN\", {\n buffer: data,\n length,\n offset,\n });\n }\n return { consumed: 1 + length, result: result };\n}\n// returns { consumed: number, result: Object }\nfunction _decode(data, offset) {\n assert(data.length !== 0, \"data too short\", \"BUFFER_OVERRUN\", {\n buffer: data,\n length: 0,\n offset: 1,\n });\n const checkOffset = (offset) => {\n assert(offset <= data.length, \"data short segment too short\", \"BUFFER_OVERRUN\", {\n buffer: data,\n length: data.length,\n offset,\n });\n };\n // Array with extra length prefix\n if (data[offset] >= 0xf8) {\n const lengthLength = data[offset] - 0xf7;\n checkOffset(offset + 1 + lengthLength);\n const length = unarrayifyInteger(data, offset + 1, lengthLength);\n checkOffset(offset + 1 + lengthLength + length);\n return _decodeChildren(data, offset, offset + 1 + lengthLength, lengthLength + length);\n }\n else if (data[offset] >= 0xc0) {\n const length = data[offset] - 0xc0;\n checkOffset(offset + 1 + length);\n return _decodeChildren(data, offset, offset + 1, length);\n }\n else if (data[offset] >= 0xb8) {\n const lengthLength = data[offset] - 0xb7;\n checkOffset(offset + 1 + lengthLength);\n const length = unarrayifyInteger(data, offset + 1, lengthLength);\n checkOffset(offset + 1 + lengthLength + length);\n const result = hexlify(data.slice(offset + 1 + lengthLength, offset + 1 + lengthLength + length));\n return { consumed: 1 + lengthLength + length, result: result };\n }\n else if (data[offset] >= 0x80) {\n const length = data[offset] - 0x80;\n checkOffset(offset + 1 + length);\n const result = hexlify(data.slice(offset + 1, offset + 1 + length));\n return { consumed: 1 + length, result: result };\n }\n return { consumed: 1, result: hexlifyByte(data[offset]) };\n}\n/**\n * Decodes %%data%% into the structured data it represents.\n */\nexport function decodeRlp(_data) {\n const data = getBytes(_data, \"data\");\n const decoded = _decode(data, 0);\n assertArgument(decoded.consumed === data.length, \"unexpected junk after rlp payload\", \"data\", _data);\n return decoded.result;\n}\n//# sourceMappingURL=rlp-decode.js.map","import { getBytes } from \"./data.js\";\nfunction arrayifyInteger(value) {\n const result = [];\n while (value) {\n result.unshift(value & 0xff);\n value >>= 8;\n }\n return result;\n}\nfunction _encode(object) {\n if (Array.isArray(object)) {\n let payload = [];\n object.forEach(function (child) {\n payload = payload.concat(_encode(child));\n });\n if (payload.length <= 55) {\n payload.unshift(0xc0 + payload.length);\n return payload;\n }\n const length = arrayifyInteger(payload.length);\n length.unshift(0xf7 + length.length);\n return length.concat(payload);\n }\n const data = Array.prototype.slice.call(getBytes(object, \"object\"));\n if (data.length === 1 && data[0] <= 0x7f) {\n return data;\n }\n else if (data.length <= 55) {\n data.unshift(0x80 + data.length);\n return data;\n }\n const length = arrayifyInteger(data.length);\n length.unshift(0xb7 + length.length);\n return length.concat(data);\n}\nconst nibbles = \"0123456789abcdef\";\n/**\n * Encodes %%object%% as an RLP-encoded [[DataHexString]].\n */\nexport function encodeRlp(object) {\n let result = \"0x\";\n for (const v of _encode(object)) {\n result += nibbles[v >> 4];\n result += nibbles[v & 0xf];\n }\n return result;\n}\n//# sourceMappingURL=rlp-encode.js.map","/**\n * Most interactions with Core requires integer values, which use\n * the smallest magnitude unit.\n *\n * For example, imagine dealing with dollars and cents. Since dollars\n * are divisible, non-integer values are possible, such as ``$10.77``.\n * By using the smallest indivisible unit (i.e. cents), the value can\n * be kept as the integer ``1077``.\n *\n * When receiving decimal input from the user (as a decimal string),\n * the value should be converted to an integer and when showing a user\n * a value, the integer value should be converted to a decimal string.\n *\n * This creates a clear distinction, between values to be used by code\n * (integers) and values used for display logic to users (decimals).\n *\n * The native unit in Core, //Core// is divisible to 18 decimal places,\n * where each individual unit is called a //ore//.\n *\n * @_subsection api/utils:Unit Conversion [about-units]\n */\nimport { assertArgument } from \"./errors.js\";\nimport { FixedNumber } from \"./fixednumber.js\";\nimport { getNumber } from \"./maths.js\";\nconst names = [\n ///Ore, the smallest and atomic amount of Core\n \"ore\",\n ///fecore, 1000 ore\n \"fecore\",\n ///Picore, one million ore\n \"picore\",\n ///Nacore, one billion ore. Typically a reasonable unit to measure energy prices.\n \"nacore\",\n ///Μcore, 10^12 ore or 1 μCore\n \"mcore\",\n ///micore, 10^15 ore or 1 mcore\n \"micore\",\n \"core\",\n];\n/**\n * Converts %%value%% into a //decimal string//, assuming %%unit%% decimal\n * places. The %%unit%% may be the number of decimal places or the name of\n * a unit\n *\n */\nexport function formatUnits(value, unit) {\n let decimals = 18;\n if (typeof unit === \"string\") {\n const index = names.indexOf(unit);\n assertArgument(index >= 0, \"invalid unit\", \"unit\", unit);\n decimals = 3 * index;\n }\n else if (unit != null) {\n decimals = getNumber(unit, \"unit\");\n }\n return FixedNumber.fromValue(value, decimals, { decimals }).toString();\n}\n/**\n * Converts the //decimal string// %%value%% to a BigInt, assuming\n * %%unit%% decimal places. The %%unit%% may the number of decimal places\n * or the name of a unit.\n */\nexport const scientificToDecimal = (num) => {\n // @ts-ignore\n var nsign = Math.sign(num);\n //remove the sign\n // @ts-ignore\n num = Math.abs(num);\n //if the number is in scientific notation remove it\n // @ts-ignore\n if (/\\d+\\.?\\d*e[\\+\\-]*\\d+/i.test(num)) {\n var zero = \"0\", \n // @ts-ignore\n parts = String(num).toLowerCase().split(\"e\"), //split into coeff and exponent\n e = parts.pop(), //store the exponential part\n // @ts-ignore\n l = Math.abs(e), //get the number of zeros\n // @ts-ignore\n sign = e / l, coeff_array = parts[0].split(\".\");\n if (sign === -1) {\n l = l - coeff_array[0].length;\n if (l < 0) {\n // @ts-ignore\n num =\n coeff_array[0].slice(0, l) +\n \".\" +\n coeff_array[0].slice(l) +\n (coeff_array.length === 2 ? coeff_array[1] : \"\");\n }\n else {\n // @ts-ignore\n num = zero + \".\" + new Array(l + 1).join(zero) + coeff_array.join(\"\");\n }\n }\n else {\n var dec = coeff_array[1];\n if (dec)\n l = l - dec.length;\n if (l < 0) {\n // @ts-ignore\n num = coeff_array[0] + dec.slice(0, l) + \".\" + dec.slice(l);\n }\n else {\n // @ts-ignore\n num = coeff_array.join(\"\") + new Array(l + 1).join(zero);\n }\n }\n }\n // @ts-ignore\n return nsign < 0 ? \"-\" + num : num;\n};\nexport const trimDecimals = (n, decimals = 18) => {\n n += \"\";\n if (n.indexOf(\".\") === -1)\n return n;\n const arr = n.split(\".\");\n const fraction = arr[1].substr(0, decimals);\n return arr[0] + \".\" + fraction;\n};\nexport function parseUnits(value, unit) {\n assertArgument(typeof value === \"string\", \"value must be a string\", \"value\", value);\n if (value.includes(\"e\")) {\n value = scientificToDecimal(value).toString();\n }\n let decimals = 18;\n if (typeof unit === \"string\") {\n const index = names.indexOf(unit);\n assertArgument(index >= 0, \"invalid unit\", \"unit\", unit);\n decimals = 3 * index;\n value = trimDecimals(value, decimals);\n }\n else if (unit != null) {\n decimals = getNumber(unit, \"unit\");\n value = trimDecimals(value, decimals);\n }\n return FixedNumber.fromString(value, { decimals }).value;\n}\n/**\n * Converts %%value%% into a //decimal string// using 18 decimal places.\n */\nexport function formatXCB(ore) {\n return formatUnits(ore, 18);\n}\n/**\n * Converts the //decimal string// %%xcb%% to a BigInt, using 18\n * decimal places.\n */\nexport function parseXCB(xcb) {\n return parseUnits(xcb, 18);\n}\n//# sourceMappingURL=units.js.map","/**\n * Explain UUID and link to RFC here.\n *\n * @_subsection: api/utils:UUID [about-uuid]\n */\nimport { getBytes, hexlify } from \"./data.js\";\n/**\n * Returns the version 4 [[link-uuid]] for the %%randomBytes%%.\n *\n * @see: https://www.ietf.org/rfc/rfc4122.txt (Section 4.4)\n */\nexport function uuidV4(randomBytes) {\n const bytes = getBytes(randomBytes, \"randomBytes\");\n // Section: 4.1.3:\n // - time_hi_and_version[12:16] = 0b0100\n bytes[6] = (bytes[6] & 0x0f) | 0x40;\n // Section 4.4\n // - clock_seq_hi_and_reserved[6] = 0b0\n // - clock_seq_hi_and_reserved[7] = 0b1\n bytes[8] = (bytes[8] & 0x3f) | 0x80;\n const value = hexlify(bytes);\n return [\n value.substring(2, 10),\n value.substring(10, 14),\n value.substring(14, 18),\n value.substring(18, 22),\n value.substring(22, 34),\n ].join(\"-\");\n}\n//# sourceMappingURL=uuid.js.map","// @ts-ignore\nimport ed448 from \"./browser-ed448.js\";\n// @ts-ignore\nimport pbkdf2 from \"./pbkdf2-browser.js\";\n// @ts-ignore\nimport SHA3_512 from \"bcrypto/lib/sha3-512.js\";\nexport class Ed448Goldilock {\n static _channel = ed448;\n static generatePrivateKey() {\n var privateKey = ed448.privateKeyGenerate();\n privateKey[56] &= 0x7f;\n return privateKey;\n }\n static getPublicKeyFromPrivateKey(privateKey) {\n var secret = Buffer.from(privateKey, \"hex\");\n if (secret[56] > 127) {\n var scalar = secret.slice(0, 56);\n scalar[0] &= 0xfc;\n scalar[55] |= 0x80;\n var publicKey = this._channel.publicKeyFromScalar(scalar);\n return Buffer.from(publicKey).toString(\"hex\");\n }\n else {\n var publicKey = this._channel.publicKeyCreate(secret);\n return Buffer.from(publicKey).toString(\"hex\");\n }\n }\n static signWithPrivateKey(privateKey, msg) {\n var msgToSign = Buffer.from(msg, \"hex\");\n var secret = Buffer.from(privateKey, \"hex\");\n if (secret[56] > 127) {\n var prefix = secret.slice(0, 57);\n prefix[0] &= 0xfc;\n prefix[56] = 0;\n prefix[55] |= 0x80;\n var scalar = prefix.slice(0, 56);\n var signedMessage = this._channel.signWithScalar(msgToSign, scalar, prefix);\n return Buffer.from(signedMessage).toString(\"hex\");\n }\n else {\n var signedMessage = this._channel.sign(msgToSign, secret);\n return Buffer.from(signedMessage).toString(\"hex\");\n }\n }\n static signWithPrivateKeyNConcatPubkey(privateKey, msg) {\n var signedMessage = Ed448Goldilock.signWithPrivateKey(privateKey, msg);\n var publicKey = Ed448Goldilock.getPublicKeyFromPrivateKey(privateKey);\n return signedMessage + publicKey;\n }\n static verifySignature(msgHash, signedMsg, pubKey) {\n return this._channel.verify(msgHash, signedMsg, pubKey);\n }\n static SHA512Hash(password, salt) {\n var p1 = Buffer.from(password, \"hex\");\n var s1 = Buffer.from(salt, \"hex\");\n return Buffer.from(pbkdf2.derive(SHA3_512, p1, s1, 2048, 57)).toString(\"hex\");\n }\n static concatenateAndHex(prefix, key, index, salt) {\n var ind = Buffer.alloc(4);\n var p = Buffer.alloc(1);\n p[0] = prefix % 256;\n var j = index;\n for (let i = 0; i < 4; i++) {\n ind[i] = j % 256;\n j = Math.floor(j / 256);\n }\n var t = p.toString(\"hex\") + key + ind.toString(\"hex\");\n return Ed448Goldilock.SHA512Hash(t, salt);\n }\n static addScalar(a, b) {\n var a1 = Buffer.from(a, \"hex\");\n var b1 = Buffer.from(b.substr(0, 106) + \"00000000\", \"hex\");\n b1[0] &= 0xfc;\n var c = Buffer.alloc(57);\n var hold = 0;\n for (let i = 0; i < 57; i++) {\n hold += a1[i] + b1[i];\n c[i] = hold % 256;\n hold = Math.floor(hold / 256);\n }\n return c.toString(\"hex\");\n }\n static seedToExtendedPrivate(seed) {\n var s1 = Ed448Goldilock.SHA512Hash(seed, \"6d6e656d6f6e6963666f72746865636861696e\");\n var s2 = Ed448Goldilock.SHA512Hash(seed, \"6d6e656d6f6e6963666f727468656b6579\");\n var b = Buffer.from(s2, \"hex\");\n b[56] |= 0x80;\n b[55] |= 0x80;\n b[55] &= 0xbf;\n var s3 = b.toString(\"hex\");\n return s1 + s3;\n }\n static childPrivateToPrivate(s, index) {\n var s0 = s.substr(0, 114);\n var s1 = s.substr(114, 228);\n var r0, r1;\n if (index >= 0x80000000) {\n r0 = Ed448Goldilock.concatenateAndHex(1, s1, index, s0);\n r1 = Ed448Goldilock.concatenateAndHex(0, s1, index, s0);\n return r0 + Ed448Goldilock.addScalar(s1, r1);\n }\n else {\n var pub = Ed448Goldilock.getPublicKeyFromPrivateKey(s1);\n r0 = Ed448Goldilock.concatenateAndHex(3, pub, index, s0);\n r1 = Ed448Goldilock.concatenateAndHex(2, pub, index, s0);\n return r0 + Ed448Goldilock.addScalar(s1, r1);\n }\n }\n static HDWalletGenerateKeyFromSeed(seed, index) {\n var m = Ed448Goldilock.seedToExtendedPrivate(seed);\n var k1 = Ed448Goldilock.childPrivateToPrivate(m, 0x80000000 + 44);\n var k2 = Ed448Goldilock.childPrivateToPrivate(k1, 0x80000000 + 654);\n var k3 = Ed448Goldilock.childPrivateToPrivate(k2, 0x80000000 + 0);\n var k4 = Ed448Goldilock.childPrivateToPrivate(k3, 0x80000000 + 0);\n var k5 = Ed448Goldilock.childPrivateToPrivate(k4, index);\n return k5.substr(114, 228);\n }\n}\n//# sourceMappingURL=ed448goldilock-browser.js.map","/* Browser Crypto Shims */\nimport { hmac } from \"@noble/hashes/hmac\";\nimport { pbkdf2 } from \"@noble/hashes/pbkdf2\";\nimport { sha256 } from \"@noble/hashes/sha256\";\nimport { sha512 } from \"@noble/hashes/sha512\";\nimport { sha3_256, sha3_512 } from \"@noble/hashes/sha3\";\nimport ed448 from \"./browser-ed448.js\";\nimport { assert, assertArgument } from \"../utils/index.js\";\nexport { ed448 };\nexport { Ed448Goldilock } from \"./ed448goldilock-browser.js\";\nfunction getGlobal() {\n if (typeof self !== \"undefined\") {\n return self;\n }\n if (typeof window !== \"undefined\") {\n return window;\n }\n if (typeof global !== \"undefined\") {\n return global;\n }\n throw new Error(\"unable to locate global object\");\n}\nconst anyGlobal = getGlobal();\nconst crypto = anyGlobal.crypto || anyGlobal.msCrypto;\nexport function createHash(algo) {\n switch (algo) {\n case \"sha256\":\n return sha256.create();\n case \"sha512\":\n return sha512.create();\n case \"sha3-256\":\n return sha3_256.create();\n case \"sha3-512\":\n return sha3_512.create();\n }\n assertArgument(false, \"invalid hashing algorithm name\", \"algorithm\", algo);\n}\nexport function createHmac(_algo, key) {\n const algo = { sha256, sha512 }[_algo];\n assertArgument(algo != null, \"invalid hmac algorithm\", \"algorithm\", _algo);\n return hmac.create(algo, key);\n}\nexport function pbkdf2Sync(password, salt, iterations, keylen, _algo) {\n const algo = { sha256, sha512 }[_algo];\n assertArgument(algo != null, \"invalid pbkdf2 algorithm\", \"algorithm\", _algo);\n return pbkdf2(algo, password, salt, { c: iterations, dkLen: keylen });\n}\nexport function randomBytes(length) {\n assert(crypto != null, \"platform does not support secure random numbers\", \"UNSUPPORTED_OPERATION\", {\n operation: \"randomBytes\",\n });\n assertArgument(Number.isInteger(length) && length > 0 && length <= 1024, \"invalid length\", \"length\", length);\n const result = new Uint8Array(length);\n crypto.getRandomValues(result);\n return result;\n}\n//# sourceMappingURL=crypto-browser.js.map","import { Logger } from \"../logger/logger.js\";\nimport { arrayify, getBytes, hexlify } from \"../utils/data.js\";\nimport { createHash, createHmac } from \"./crypto.js\";\nimport { Buffer } from \"buffer\";\nconst logger = new Logger(\"sha3/0.0.1\");\nconst _sha256 = function (data) {\n let v = \"0x\" +\n createHash(\"sha3-256\")\n .update(Buffer.from(arrayify(data)))\n .digest(\"hex\");\n return v;\n};\nconst _sha512 = function (data) {\n let v = \"0x\" +\n createHash(\"sha3-512\")\n .update(Buffer.from(arrayify(data)))\n .digest(\"hex\");\n return v;\n};\n// @ts-ignore\nlet __sha256 = _sha256;\n// @ts-ignore\nlet __sha512 = _sha512;\nlet locked256 = false, locked512 = false;\n/**\n * Compute the cryptographic SHA2-256 hash of %%data%%.\n *\n * @_docloc: api/crypto:Hash Functions\n * @returns DataHexstring\n *\n * @example:\n * sha256(\"0x\")\n * //_result:\n *\n * sha256(\"0x1337\")\n * //_result:\n *\n * sha256(new Uint8Array([ 0x13, 0x37 ]))\n * //_result:\n *\n */\nexport var SupportedAlgorithm;\n(function (SupportedAlgorithm) {\n SupportedAlgorithm[\"sha256\"] = \"sha256\";\n SupportedAlgorithm[\"sha512\"] = \"sha512\";\n})(SupportedAlgorithm || (SupportedAlgorithm = {}));\nexport function ripemd160(data) {\n let createdHash = \"0x\" +\n createHash(\"ripemd160\")\n .update(Buffer.from(arrayify(data)))\n .digest(\"hex\");\n const v = \"0x\" + createdHash;\n if (typeof createdHash !== \"string\") {\n createdHash = hexlify(createdHash);\n return createdHash;\n }\n return v;\n}\nexport function sha256(data) {\n let createdHash = createHash(\"sha3-256\")\n .update(Buffer.from(arrayify(data)))\n .digest(\"hex\");\n const v = \"0x\" + createdHash;\n if (typeof createdHash !== \"string\") {\n createdHash = hexlify(createdHash);\n return createdHash;\n }\n return v;\n}\nexport function legacySha256(data) {\n const _data = getBytes(data, \"data\");\n const hexlified = hexlify(createHash(\"sha256\").update(_data).digest());\n return hexlified;\n}\nexport function computeHmac(algorithm, key, data) {\n const d = Buffer.from(arrayify(data));\n const k = Buffer.from(arrayify(key));\n if (algorithm === SupportedAlgorithm.sha256) {\n return \"0x\" + createHmac(\"sha3-256\", k).update(d).digest(\"hex\");\n }\n else if (algorithm === SupportedAlgorithm.sha512) {\n return \"0x\" + createHmac(\"sha3-512\", k).update(d).digest(\"hex\");\n }\n logger.throwError(\"unsupported algorithm - \" + algorithm, Logger.errors.UNSUPPORTED_OPERATION, {\n operation: \"computeHmac\",\n algorithm: algorithm,\n });\n return \"\";\n}\nsha256._ = _sha256;\nsha256.lock = function () {\n locked256 = true;\n};\nsha256.register = function (func) {\n if (locked256) {\n throw new Error(\"sha256 is locked\");\n }\n __sha256 = func;\n};\nObject.freeze(sha256);\n/**\n * Compute the cryptographic SHA2-512 hash of %%data%%.\n *\n * @_docloc: api/crypto:Hash Functions\n * @returns DataHexstring\n *\n * @example:\n * sha512(\"0x\")\n * //_result:\n *\n * sha512(\"0x1337\")\n * //_result:\n *\n * sha512(new Uint8Array([ 0x13, 0x37 ]))\n * //_result:\n */\nexport function sha512(data) {\n let createdHash = createHash(\"sha3-512\")\n .update(Buffer.from(arrayify(data)))\n .digest(\"hex\");\n const v = \"0x\" + createdHash;\n if (typeof createdHash !== \"string\") {\n createdHash = hexlify(createdHash);\n return createdHash;\n }\n return v;\n}\nsha512._ = _sha512;\nsha512.lock = function () {\n locked512 = true;\n};\nsha512.register = function (func) {\n if (locked512) {\n throw new Error(\"sha512 is locked\");\n }\n __sha512 = func;\n};\nObject.freeze(sha256);\n//# sourceMappingURL=sha3.js.map","/**\n * Addresses are a fundamental part of interacting with Core. They\n * represent the gloabal identity of Externally Owned Accounts (accounts\n * backed by a private key) and contracts.\n *\n * The Core Naming Service (CNS) provides an interconnected ecosystem\n * of contracts, standards and libraries which enable looking up an\n * address for an ENS name.\n *\n * These functions help convert between various formats, validate\n * addresses and safely resolve ENS names.\n *\n * @_section: api/address:Addresses [about-addresses]\n */\nnull;\nimport { BigNumber } from \"../bigNumber/bigNumber.js\";\nimport { encode } from \"../crypto/rlp.js\";\nimport { sha256 } from \"../crypto/sha3.js\";\nimport { Logger } from \"../logger/logger.js\";\nimport { arrayify, getBytes, hexDataSlice, hexlify, stripZeros, } from \"../utils/data.js\";\nconst logger = new Logger(\"address/0.0.1\");\nconst precompiledAddresses = [\n \"0000000000000000000000000000000000000000000000000000000000000000\",\n \"0000000000000000000000000000000000000000000000000000000000000001\",\n \"0000000000000000000000000000000000000000000000000000000000000002\",\n \"0000000000000000000000000000000000000000000000000000000000000003\",\n \"0000000000000000000000000000000000000000000000000000000000000004\",\n \"0000000000000000000000000000000000000000000000000000000000000005\",\n \"0000000000000000000000000000000000000000000000000000000000000006\",\n \"0000000000000000000000000000000000000000000000000000000000000007\",\n \"0000000000000000000000000000000000000000000000000000000000000008\",\n \"0000000000000000000000000000000000000000000000000000000000000009\",\n];\nfunction removeHexPrefix(val) {\n return val.substring(0, 2) === \"0x\" ? val.substring(2) : val;\n}\nfunction calculateCheckSum(_address, _prefix) {\n const address = getBytes(\"0x\" + _address.replace(\"0x\", \"\"));\n const prefix = getBytes(\"0x\" + _prefix.replace(\"0x\", \"\"));\n const tmpConcated = new Uint8Array([...address, ...prefix]);\n const hexedConcat = hexlify(tmpConcated).replace(\"0x\", \"\") + \"00\";\n const mods = Array.from(hexedConcat.toUpperCase(), (c) => {\n const charCode = c.charCodeAt(0);\n return charCode > 64 && charCode < 91\n ? (charCode - 55).toString()\n : (charCode - 48).toString();\n }).join(\"\");\n const bigVal = BigInt(mods);\n const val97 = BigInt(97);\n const val98 = BigInt(98);\n const remainder = bigVal % val97;\n const checkSum = val98 - remainder;\n const result = checkSum > 9 ? checkSum.toString() : \"0\" + checkSum.toString();\n return result;\n}\n// See: https://en.wikipedia.org/wiki/International_Bank_Account_Number\n// Create lookup table\nconst ibanLookup = {};\nfor (let i = 0; i < 10; i++) {\n ibanLookup[String(i)] = String(i);\n}\nfor (let i = 0; i < 26; i++) {\n ibanLookup[String.fromCharCode(65 + i)] = String(10 + i);\n}\n// How many decimal digits can we process? (for 64-bit float, this is 15)\n// i.e. Math.floor(Math.log10(Number.MAX_SAFE_INTEGER));\nconst safeDigits = 15;\nfunction ibanChecksum(address) {\n address = address.toUpperCase();\n address = address.substring(4) + address.substring(0, 2) + \"00\";\n let expanded = address\n .split(\"\")\n .map((c) => {\n return ibanLookup[c];\n })\n .join(\"\");\n // Javascript can handle integers safely up to 15 (decimal) digits\n while (expanded.length >= safeDigits) {\n let block = expanded.substring(0, safeDigits);\n expanded = (parseInt(block, 10) % 97) + expanded.substring(block.length);\n }\n let checksum = String(98 - (parseInt(expanded, 10) % 97));\n while (checksum.length < 2) {\n checksum = \"0\" + checksum;\n }\n return checksum;\n}\n/**\n * Returns a normalized and checksumed address for %%address%%.\n * This accepts non-checksum addresses, checksum addresses and\n * [[getIcapAddress]] formats.\n *\n * The checksum in Core uses the capitalization (upper-case\n * vs lower-case) of the characters within an address to encode\n * its checksum, which offers, on average, a checksum of 15-bits.\n *\n * If %%address%% contains both upper-case and lower-case, it is\n * assumed to already be a checksum address and its checksum is\n * validated, and if the address fails its expected checksum an\n * error is thrown.\n *\n * If you wish the checksum of %%address%% to be ignore, it should\n * be converted to lower-case (i.e. ``.toLowercase()``) before\n * being passed in. This should be a very rare situation though,\n * that you wish to bypass the safegaurds in place to protect\n * against an address that has been incorrectly copied from another\n * source.\n *\n * @example:\n * // Adds the checksum (via upper-casing specific letters)\n * getAddress(\"0x8ba1f109551bd432803012645ac136ddd64dba72\")\n * //_result:\n *\n * // Converts ICAP address and adds checksum\n * getAddress(\"XE65GB6LDNXYOFTX0NSV3FUWKOWIXAMJK36\");\n * //_result:\n *\n * // Throws an error if an address contains mixed case,\n * // but the checksum fails\n * getAddress(\"0x8Ba1f109551bD432803012645Ac136ddd64DBA72\")\n * //_error:\n */\nfunction getAddress(address) {\n if (typeof address !== \"string\") {\n logger.throwArgumentError(\"invalid address\", \"address\", address);\n }\n if (!address.match(/^(0x)?[0-9a-fA-F]{44}$/)) {\n logger.throwArgumentError(\"invalid address\", \"address\", address);\n }\n const raw = removeHexPrefix(address);\n if (precompiledAddresses.includes(raw)) {\n return \"0x\" + raw;\n }\n const prefix = raw.substring(0, 2);\n const val = raw.substring(4);\n const checksum = calculateCheckSum(val, prefix);\n if (checksum !== raw.substring(2, 4)) {\n logger.throwArgumentError(\"bad address checksum\", \"address\", address);\n }\n return \"0x\" + prefix + checksum + val;\n}\n/**\n * The [ICAP Address format](link-icap) format is an early checksum\n * format which attempts to be compatible with the banking\n * industry [IBAN format](link-wiki-iban) for bank accounts.\n *\n * It is no longer common or a recommended format.\n *\n * @example:\n * getIcapAddress(\"0x8ba1f109551bd432803012645ac136ddd64dba72\");\n * //_result:\n *\n * getIcapAddress(\"XE65GB6LDNXYOFTX0NSV3FUWKOWIXAMJK36\");\n * //_result:\n *\n * // Throws an error if the ICAP checksum is wrong\n * getIcapAddress(\"XE65GB6LDNXYOFTX0NSV3FUWKOWIXAMJK37\");\n * //_error:\n */\nfunction getIcapAddress(address) {\n //let base36 = _base16To36(getAddress(address).substring(2)).toUpperCase();\n let base36 = BigInt(getAddress(address)).toString(36).toUpperCase();\n while (base36.length < 30) {\n base36 = \"0\" + base36;\n }\n return \"XE\" + ibanChecksum(\"XE00\" + base36) + base36;\n}\nfunction networkIdToPrefix(networkId) {\n if (networkId == 1) {\n return \"cb\";\n }\n else if (networkId == 3 || networkId == 4) {\n return \"ab\";\n }\n else if (networkId > 10 || networkId == 0) {\n return \"ce\";\n }\n else {\n logger.throwArgumentError(\"bad networkId\", \"networkId\", networkId);\n return \"\";\n }\n}\nfunction getContractAddress(transaction) {\n let from = null;\n try {\n from = getAddress(transaction.from);\n }\n catch (error) {\n logger.throwArgumentError(\"missing from address\", \"transaction\", transaction);\n }\n const nonce = stripZeros(arrayify(BigNumber.from(transaction.nonce).toHexString()));\n const val = hexDataSlice(sha256(encode([from, nonce])), 12);\n const prefix = from.substring(2, 4);\n const checksum = calculateCheckSum(val, prefix);\n return \"0x\" + prefix + checksum + removeHexPrefix(val);\n}\nexport { getAddress, getIcapAddress, calculateCheckSum, networkIdToPrefix, getContractAddress, };\n//# sourceMappingURL=index.js.map","/**\n * An **HMAC** enables verification that a given key was used\n * to authenticate a payload.\n *\n * See: [[link-wiki-hmac]]\n *\n * @_subsection: api/crypto:HMAC [about-hmac]\n */\nimport { createHmac } from \"./crypto.js\";\nimport { getBytes, hexlify } from \"../utils/index.js\";\nlet locked = false;\nconst _computeHmac = function (algorithm, key, data) {\n return createHmac(algorithm, key).update(data).digest();\n};\nlet __computeHmac = _computeHmac;\n/**\n * Return the HMAC for %%data%% using the %%key%% key with the underlying\n * %%algo%% used for compression.\n *\n * @example:\n * key = id(\"some-secret\")\n *\n * // Compute the HMAC\n * computeHmac(\"sha256\", key, \"0x1337\")\n * //_result:\n *\n * // To compute the HMAC of UTF-8 data, the data must be\n * // converted to UTF-8 bytes\n * computeHmac(\"sha256\", key, toUtf8Bytes(\"Hello World\"))\n * //_result:\n *\n */\nexport function computeHmac(algorithm, _key, _data) {\n const key = getBytes(_key, \"key\");\n const data = getBytes(_data, \"data\");\n return hexlify(__computeHmac(algorithm, key, data));\n}\ncomputeHmac._ = _computeHmac;\ncomputeHmac.lock = function () {\n locked = true;\n};\ncomputeHmac.register = function (func) {\n if (locked) {\n throw new Error(\"computeHmac is locked\");\n }\n __computeHmac = func;\n};\nObject.freeze(computeHmac);\n//# sourceMappingURL=hmac.js.map","import { SHA2 } from './_sha2.js';\nimport { wrapConstructor } from './utils.js';\n// https://homes.esat.kuleuven.be/~bosselae/ripemd160.html\n// https://homes.esat.kuleuven.be/~bosselae/ripemd160/pdf/AB-9601/AB-9601.pdf\nconst Rho = /* @__PURE__ */ new Uint8Array([7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8]);\nconst Id = /* @__PURE__ */ Uint8Array.from({ length: 16 }, (_, i) => i);\nconst Pi = /* @__PURE__ */ Id.map((i) => (9 * i + 5) % 16);\nlet idxL = [Id];\nlet idxR = [Pi];\nfor (let i = 0; i < 4; i++)\n for (let j of [idxL, idxR])\n j.push(j[i].map((k) => Rho[k]));\nconst shifts = /* @__PURE__ */ [\n [11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8],\n [12, 13, 11, 15, 6, 9, 9, 7, 12, 15, 11, 13, 7, 8, 7, 7],\n [13, 15, 14, 11, 7, 7, 6, 8, 13, 14, 13, 12, 5, 5, 6, 9],\n [14, 11, 12, 14, 8, 6, 5, 5, 15, 12, 15, 14, 9, 9, 8, 6],\n [15, 12, 13, 13, 9, 5, 8, 6, 14, 11, 12, 11, 8, 6, 5, 5],\n].map((i) => new Uint8Array(i));\nconst shiftsL = /* @__PURE__ */ idxL.map((idx, i) => idx.map((j) => shifts[i][j]));\nconst shiftsR = /* @__PURE__ */ idxR.map((idx, i) => idx.map((j) => shifts[i][j]));\nconst Kl = /* @__PURE__ */ new Uint32Array([\n 0x00000000, 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xa953fd4e,\n]);\nconst Kr = /* @__PURE__ */ new Uint32Array([\n 0x50a28be6, 0x5c4dd124, 0x6d703ef3, 0x7a6d76e9, 0x00000000,\n]);\n// The rotate left (circular left shift) operation for uint32\nconst rotl = (word, shift) => (word << shift) | (word >>> (32 - shift));\n// It's called f() in spec.\nfunction f(group, x, y, z) {\n if (group === 0)\n return x ^ y ^ z;\n else if (group === 1)\n return (x & y) | (~x & z);\n else if (group === 2)\n return (x | ~y) ^ z;\n else if (group === 3)\n return (x & z) | (y & ~z);\n else\n return x ^ (y | ~z);\n}\n// Temporary buffer, not used to store anything between runs\nconst BUF = /* @__PURE__ */ new Uint32Array(16);\nexport class RIPEMD160 extends SHA2 {\n constructor() {\n super(64, 20, 8, true);\n this.h0 = 0x67452301 | 0;\n this.h1 = 0xefcdab89 | 0;\n this.h2 = 0x98badcfe | 0;\n this.h3 = 0x10325476 | 0;\n this.h4 = 0xc3d2e1f0 | 0;\n }\n get() {\n const { h0, h1, h2, h3, h4 } = this;\n return [h0, h1, h2, h3, h4];\n }\n set(h0, h1, h2, h3, h4) {\n this.h0 = h0 | 0;\n this.h1 = h1 | 0;\n this.h2 = h2 | 0;\n this.h3 = h3 | 0;\n this.h4 = h4 | 0;\n }\n process(view, offset) {\n for (let i = 0; i < 16; i++, offset += 4)\n BUF[i] = view.getUint32(offset, true);\n // prettier-ignore\n let al = this.h0 | 0, ar = al, bl = this.h1 | 0, br = bl, cl = this.h2 | 0, cr = cl, dl = this.h3 | 0, dr = dl, el = this.h4 | 0, er = el;\n // Instead of iterating 0 to 80, we split it into 5 groups\n // And use the groups in constants, functions, etc. Much simpler\n for (let group = 0; group < 5; group++) {\n const rGroup = 4 - group;\n const hbl = Kl[group], hbr = Kr[group]; // prettier-ignore\n const rl = idxL[group], rr = idxR[group]; // prettier-ignore\n const sl = shiftsL[group], sr = shiftsR[group]; // prettier-ignore\n for (let i = 0; i < 16; i++) {\n const tl = (rotl(al + f(group, bl, cl, dl) + BUF[rl[i]] + hbl, sl[i]) + el) | 0;\n al = el, el = dl, dl = rotl(cl, 10) | 0, cl = bl, bl = tl; // prettier-ignore\n }\n // 2 loops are 10% faster\n for (let i = 0; i < 16; i++) {\n const tr = (rotl(ar + f(rGroup, br, cr, dr) + BUF[rr[i]] + hbr, sr[i]) + er) | 0;\n ar = er, er = dr, dr = rotl(cr, 10) | 0, cr = br, br = tr; // prettier-ignore\n }\n }\n // Add the compressed chunk to the current hash value\n this.set((this.h1 + cl + dr) | 0, (this.h2 + dl + er) | 0, (this.h3 + el + ar) | 0, (this.h4 + al + br) | 0, (this.h0 + bl + cr) | 0);\n }\n roundClean() {\n BUF.fill(0);\n }\n destroy() {\n this.destroyed = true;\n this.buffer.fill(0);\n this.set(0, 0, 0, 0, 0);\n }\n}\n/**\n * RIPEMD-160 - a hash function from 1990s.\n * @param message - msg that would be hashed\n */\nexport const ripemd160 = /* @__PURE__ */ wrapConstructor(() => new RIPEMD160());\n//# sourceMappingURL=ripemd160.js.map","import { ripemd160 as noble_ripemd160 } from \"@noble/hashes/ripemd160\";\nimport { getBytes, hexlify } from \"../utils/index.js\";\nlet locked = false;\nconst _ripemd160 = function (data) {\n return noble_ripemd160(data);\n};\nlet __ripemd160 = _ripemd160;\n/**\n * Compute the cryptographic RIPEMD-160 hash of %%data%%.\n *\n * @_docloc: api/crypto:Hash Functions\n * @returns DataHexstring\n *\n * @example:\n * ripemd160(\"0x\")\n * //_result:\n *\n * ripemd160(\"0x1337\")\n * //_result:\n *\n * ripemd160(new Uint8Array([ 0x13, 0x37 ]))\n * //_result:\n *\n */\nexport function ripemd160(_data) {\n const data = getBytes(_data, \"data\");\n return hexlify(__ripemd160(data));\n}\nripemd160._ = _ripemd160;\nripemd160.lock = function () {\n locked = true;\n};\nripemd160.register = function (func) {\n if (locked) {\n throw new TypeError(\"ripemd160 is locked\");\n }\n __ripemd160 = func;\n};\nObject.freeze(ripemd160);\n//# sourceMappingURL=ripemd160.js.map","/**\n * A **Password-Based Key-Derivation Function** is designed to create\n * a sequence of bytes suitible as a **key** from a human-rememberable\n * password.\n *\n * @_subsection: api/crypto:Passwords [about-pbkdf]\n */\nimport { pbkdf2Sync } from \"./crypto.js\";\nimport { getBytes, hexlify } from \"../utils/index.js\";\nlet locked = false;\nconst _pbkdf2 = function (password, salt, iterations, keylen, algo) {\n return pbkdf2Sync(password, salt, iterations, keylen, algo);\n};\nlet __pbkdf2 = _pbkdf2;\n/**\n * Return the [[link-pbkdf2]] for %%keylen%% bytes for %%password%% using\n * the %%salt%% and using %%iterations%% of %%algo%%.\n *\n * This PBKDF is outdated and should not be used in new projects, but is\n * required to decrypt older files.\n *\n * @example:\n * // The password must be converted to bytes, and it is generally\n * // best practices to ensure the string has been normalized. Many\n * // formats explicitly indicate the normalization form to use.\n * password = \"hello\"\n * passwordBytes = toUtf8Bytes(password, \"NFKC\")\n *\n * salt = id(\"some-salt\")\n *\n * // Compute the PBKDF2\n * pbkdf2(passwordBytes, salt, 1024, 16, \"sha256\")\n * //_result:\n */\nexport function pbkdf2(_password, _salt, iterations, keylen, algo) {\n const password = getBytes(_password, \"password\");\n const salt = getBytes(_salt, \"salt\");\n return hexlify(__pbkdf2(password, salt, iterations, keylen, algo));\n}\npbkdf2._ = _pbkdf2;\npbkdf2.lock = function () {\n locked = true;\n};\npbkdf2.register = function (func) {\n if (locked) {\n throw new Error(\"pbkdf2 is locked\");\n }\n __pbkdf2 = func;\n};\nObject.freeze(pbkdf2);\n//# sourceMappingURL=pbkdf2.js.map","/**\n * A **Cryptographically Secure Random Value** is one that has been\n * generated with additional care take to prevent side-channels\n * from allowing others to detect it and prevent others from through\n * coincidence generate the same values.\n *\n * @_subsection: api/crypto:Random Values [about-crypto-random]\n */\nimport { randomBytes as crypto_random } from \"./crypto.js\";\nlet locked = false;\nconst _randomBytes = function (length) {\n return new Uint8Array(crypto_random(length));\n};\nlet __randomBytes = _randomBytes;\n/**\n * Return %%length%% bytes of cryptographically secure random data.\n *\n * @example:\n * randomBytes(8)\n * //_result:\n */\nexport function randomBytes(length) {\n return __randomBytes(length);\n}\nrandomBytes._ = _randomBytes;\nrandomBytes.lock = function () {\n locked = true;\n};\nrandomBytes.register = function (func) {\n if (locked) {\n throw new Error(\"randomBytes is locked\");\n }\n __randomBytes = func;\n};\nObject.freeze(randomBytes);\n//# sourceMappingURL=random.js.map","import { number as assertNumber } from './_assert.js';\nimport { sha256 } from './sha256.js';\nimport { pbkdf2 } from './pbkdf2.js';\nimport { asyncLoop, checkOpts, u32 } from './utils.js';\n// RFC 7914 Scrypt KDF\n// Left rotate for uint32\nconst rotl = (a, b) => (a << b) | (a >>> (32 - b));\n// The main Scrypt loop: uses Salsa extensively.\n// Six versions of the function were tried, this is the fastest one.\n// prettier-ignore\nfunction XorAndSalsa(prev, pi, input, ii, out, oi) {\n // Based on https://cr.yp.to/salsa20.html\n // Xor blocks\n let y00 = prev[pi++] ^ input[ii++], y01 = prev[pi++] ^ input[ii++];\n let y02 = prev[pi++] ^ input[ii++], y03 = prev[pi++] ^ input[ii++];\n let y04 = prev[pi++] ^ input[ii++], y05 = prev[pi++] ^ input[ii++];\n let y06 = prev[pi++] ^ input[ii++], y07 = prev[pi++] ^ input[ii++];\n let y08 = prev[pi++] ^ input[ii++], y09 = prev[pi++] ^ input[ii++];\n let y10 = prev[pi++] ^ input[ii++], y11 = prev[pi++] ^ input[ii++];\n let y12 = prev[pi++] ^ input[ii++], y13 = prev[pi++] ^ input[ii++];\n let y14 = prev[pi++] ^ input[ii++], y15 = prev[pi++] ^ input[ii++];\n // Save state to temporary variables (salsa)\n let x00 = y00, x01 = y01, x02 = y02, x03 = y03, x04 = y04, x05 = y05, x06 = y06, x07 = y07, x08 = y08, x09 = y09, x10 = y10, x11 = y11, x12 = y12, x13 = y13, x14 = y14, x15 = y15;\n // Main loop (salsa)\n for (let i = 0; i < 8; i += 2) {\n x04 ^= rotl(x00 + x12 | 0, 7);\n x08 ^= rotl(x04 + x00 | 0, 9);\n x12 ^= rotl(x08 + x04 | 0, 13);\n x00 ^= rotl(x12 + x08 | 0, 18);\n x09 ^= rotl(x05 + x01 | 0, 7);\n x13 ^= rotl(x09 + x05 | 0, 9);\n x01 ^= rotl(x13 + x09 | 0, 13);\n x05 ^= rotl(x01 + x13 | 0, 18);\n x14 ^= rotl(x10 + x06 | 0, 7);\n x02 ^= rotl(x14 + x10 | 0, 9);\n x06 ^= rotl(x02 + x14 | 0, 13);\n x10 ^= rotl(x06 + x02 | 0, 18);\n x03 ^= rotl(x15 + x11 | 0, 7);\n x07 ^= rotl(x03 + x15 | 0, 9);\n x11 ^= rotl(x07 + x03 | 0, 13);\n x15 ^= rotl(x11 + x07 | 0, 18);\n x01 ^= rotl(x00 + x03 | 0, 7);\n x02 ^= rotl(x01 + x00 | 0, 9);\n x03 ^= rotl(x02 + x01 | 0, 13);\n x00 ^= rotl(x03 + x02 | 0, 18);\n x06 ^= rotl(x05 + x04 | 0, 7);\n x07 ^= rotl(x06 + x05 | 0, 9);\n x04 ^= rotl(x07 + x06 | 0, 13);\n x05 ^= rotl(x04 + x07 | 0, 18);\n x11 ^= rotl(x10 + x09 | 0, 7);\n x08 ^= rotl(x11 + x10 | 0, 9);\n x09 ^= rotl(x08 + x11 | 0, 13);\n x10 ^= rotl(x09 + x08 | 0, 18);\n x12 ^= rotl(x15 + x14 | 0, 7);\n x13 ^= rotl(x12 + x15 | 0, 9);\n x14 ^= rotl(x13 + x12 | 0, 13);\n x15 ^= rotl(x14 + x13 | 0, 18);\n }\n // Write output (salsa)\n out[oi++] = (y00 + x00) | 0;\n out[oi++] = (y01 + x01) | 0;\n out[oi++] = (y02 + x02) | 0;\n out[oi++] = (y03 + x03) | 0;\n out[oi++] = (y04 + x04) | 0;\n out[oi++] = (y05 + x05) | 0;\n out[oi++] = (y06 + x06) | 0;\n out[oi++] = (y07 + x07) | 0;\n out[oi++] = (y08 + x08) | 0;\n out[oi++] = (y09 + x09) | 0;\n out[oi++] = (y10 + x10) | 0;\n out[oi++] = (y11 + x11) | 0;\n out[oi++] = (y12 + x12) | 0;\n out[oi++] = (y13 + x13) | 0;\n out[oi++] = (y14 + x14) | 0;\n out[oi++] = (y15 + x15) | 0;\n}\nfunction BlockMix(input, ii, out, oi, r) {\n // The block B is r 128-byte chunks (which is equivalent of 2r 64-byte chunks)\n let head = oi + 0;\n let tail = oi + 16 * r;\n for (let i = 0; i < 16; i++)\n out[tail + i] = input[ii + (2 * r - 1) * 16 + i]; // X ← B[2r−1]\n for (let i = 0; i < r; i++, head += 16, ii += 16) {\n // We write odd & even Yi at same time. Even: 0bXXXXX0 Odd: 0bXXXXX1\n XorAndSalsa(out, tail, input, ii, out, head); // head[i] = Salsa(blockIn[2*i] ^ tail[i-1])\n if (i > 0)\n tail += 16; // First iteration overwrites tmp value in tail\n XorAndSalsa(out, head, input, (ii += 16), out, tail); // tail[i] = Salsa(blockIn[2*i+1] ^ head[i])\n }\n}\n// Common prologue and epilogue for sync/async functions\nfunction scryptInit(password, salt, _opts) {\n // Maxmem - 1GB+1KB by default\n const opts = checkOpts({\n dkLen: 32,\n asyncTick: 10,\n maxmem: 1024 ** 3 + 1024,\n }, _opts);\n const { N, r, p, dkLen, asyncTick, maxmem, onProgress } = opts;\n assertNumber(N);\n assertNumber(r);\n assertNumber(p);\n assertNumber(dkLen);\n assertNumber(asyncTick);\n assertNumber(maxmem);\n if (onProgress !== undefined && typeof onProgress !== 'function')\n throw new Error('progressCb should be function');\n const blockSize = 128 * r;\n const blockSize32 = blockSize / 4;\n if (N <= 1 || (N & (N - 1)) !== 0 || N >= 2 ** (blockSize / 8) || N > 2 ** 32) {\n // NOTE: we limit N to be less than 2**32 because of 32 bit variant of Integrify function\n // There is no JS engines that allows alocate more than 4GB per single Uint8Array for now, but can change in future.\n throw new Error('Scrypt: N must be larger than 1, a power of 2, less than 2^(128 * r / 8) and less than 2^32');\n }\n if (p < 0 || p > ((2 ** 32 - 1) * 32) / blockSize) {\n throw new Error('Scrypt: p must be a positive integer less than or equal to ((2^32 - 1) * 32) / (128 * r)');\n }\n if (dkLen < 0 || dkLen > (2 ** 32 - 1) * 32) {\n throw new Error('Scrypt: dkLen should be positive integer less than or equal to (2^32 - 1) * 32');\n }\n const memUsed = blockSize * (N + p);\n if (memUsed > maxmem) {\n throw new Error(`Scrypt: parameters too large, ${memUsed} (128 * r * (N + p)) > ${maxmem} (maxmem)`);\n }\n // [B0...Bp−1] ← PBKDF2HMAC-SHA256(Passphrase, Salt, 1, blockSize*ParallelizationFactor)\n // Since it has only one iteration there is no reason to use async variant\n const B = pbkdf2(sha256, password, salt, { c: 1, dkLen: blockSize * p });\n const B32 = u32(B);\n // Re-used between parallel iterations. Array(iterations) of B\n const V = u32(new Uint8Array(blockSize * N));\n const tmp = u32(new Uint8Array(blockSize));\n let blockMixCb = () => { };\n if (onProgress) {\n const totalBlockMix = 2 * N * p;\n // Invoke callback if progress changes from 10.01 to 10.02\n // Allows to draw smooth progress bar on up to 8K screen\n const callbackPer = Math.max(Math.floor(totalBlockMix / 10000), 1);\n let blockMixCnt = 0;\n blockMixCb = () => {\n blockMixCnt++;\n if (onProgress && (!(blockMixCnt % callbackPer) || blockMixCnt === totalBlockMix))\n onProgress(blockMixCnt / totalBlockMix);\n };\n }\n return { N, r, p, dkLen, blockSize32, V, B32, B, tmp, blockMixCb, asyncTick };\n}\nfunction scryptOutput(password, dkLen, B, V, tmp) {\n const res = pbkdf2(sha256, password, B, { c: 1, dkLen });\n B.fill(0);\n V.fill(0);\n tmp.fill(0);\n return res;\n}\n/**\n * Scrypt KDF from RFC 7914.\n * @param password - pass\n * @param salt - salt\n * @param opts - parameters\n * - `N` is cpu/mem work factor (power of 2 e.g. 2**18)\n * - `r` is block size (8 is common), fine-tunes sequential memory read size and performance\n * - `p` is parallelization factor (1 is common)\n * - `dkLen` is output key length in bytes e.g. 32.\n * - `asyncTick` - (default: 10) max time in ms for which async function can block execution\n * - `maxmem` - (default: `1024 ** 3 + 1024` aka 1GB+1KB). A limit that the app could use for scrypt\n * - `onProgress` - callback function that would be executed for progress report\n * @returns Derived key\n */\nexport function scrypt(password, salt, opts) {\n const { N, r, p, dkLen, blockSize32, V, B32, B, tmp, blockMixCb } = scryptInit(password, salt, opts);\n for (let pi = 0; pi < p; pi++) {\n const Pi = blockSize32 * pi;\n for (let i = 0; i < blockSize32; i++)\n V[i] = B32[Pi + i]; // V[0] = B[i]\n for (let i = 0, pos = 0; i < N - 1; i++) {\n BlockMix(V, pos, V, (pos += blockSize32), r); // V[i] = BlockMix(V[i-1]);\n blockMixCb();\n }\n BlockMix(V, (N - 1) * blockSize32, B32, Pi, r); // Process last element\n blockMixCb();\n for (let i = 0; i < N; i++) {\n // First u32 of the last 64-byte block (u32 is LE)\n const j = B32[Pi + blockSize32 - 16] % N; // j = Integrify(X) % iterations\n for (let k = 0; k < blockSize32; k++)\n tmp[k] = B32[Pi + k] ^ V[j * blockSize32 + k]; // tmp = B ^ V[j]\n BlockMix(tmp, 0, B32, Pi, r); // B = BlockMix(B ^ V[j])\n blockMixCb();\n }\n }\n return scryptOutput(password, dkLen, B, V, tmp);\n}\n/**\n * Scrypt KDF from RFC 7914.\n */\nexport async function scryptAsync(password, salt, opts) {\n const { N, r, p, dkLen, blockSize32, V, B32, B, tmp, blockMixCb, asyncTick } = scryptInit(password, salt, opts);\n for (let pi = 0; pi < p; pi++) {\n const Pi = blockSize32 * pi;\n for (let i = 0; i < blockSize32; i++)\n V[i] = B32[Pi + i]; // V[0] = B[i]\n let pos = 0;\n await asyncLoop(N - 1, asyncTick, () => {\n BlockMix(V, pos, V, (pos += blockSize32), r); // V[i] = BlockMix(V[i-1]);\n blockMixCb();\n });\n BlockMix(V, (N - 1) * blockSize32, B32, Pi, r); // Process last element\n blockMixCb();\n await asyncLoop(N, asyncTick, () => {\n // First u32 of the last 64-byte block (u32 is LE)\n const j = B32[Pi + blockSize32 - 16] % N; // j = Integrify(X) % iterations\n for (let k = 0; k < blockSize32; k++)\n tmp[k] = B32[Pi + k] ^ V[j * blockSize32 + k]; // tmp = B ^ V[j]\n BlockMix(tmp, 0, B32, Pi, r); // B = BlockMix(B ^ V[j])\n blockMixCb();\n });\n }\n return scryptOutput(password, dkLen, B, V, tmp);\n}\n//# sourceMappingURL=scrypt.js.map","import { scrypt as _nobleSync, scryptAsync as _nobleAsync, } from \"@noble/hashes/scrypt\";\nimport { getBytes, hexlify as H } from \"../utils/index.js\";\nlet lockedSync = false, lockedAsync = false;\nconst _scryptAsync = async function (passwd, salt, N, r, p, dkLen, onProgress) {\n return await _nobleAsync(passwd, salt, { N, r, p, dkLen, onProgress });\n};\nconst _scryptSync = function (passwd, salt, N, r, p, dkLen) {\n return _nobleSync(passwd, salt, { N, r, p, dkLen });\n};\nlet __scryptAsync = _scryptAsync;\nlet __scryptSync = _scryptSync;\n/**\n * The [[link-wiki-scrypt]] uses a memory and cpu hard method of\n * derivation to increase the resource cost to brute-force a password\n * for a given key.\n *\n * This means this algorithm is intentionally slow, and can be tuned to\n * become slower. As computation and memory speed improve over time,\n * increasing the difficulty maintains the cost of an attacker.\n *\n * For example, if a target time of 5 seconds is used, a legitimate user\n * which knows their password requires only 5 seconds to unlock their\n * account. A 6 character password has 68 billion possibilities, which\n * would require an attacker to invest over 10,000 years of CPU time. This\n * is of course a crude example (as password generally aren't random),\n * but demonstrates to value of imposing large costs to decryption.\n *\n * For this reason, if building a UI which involved decrypting or\n * encrypting datsa using scrypt, it is recommended to use a\n * [[ProgressCallback]] (as event short periods can seem lik an eternity\n * if the UI freezes). Including the phrase //\"decrypting\"// in the UI\n * can also help, assuring the user their waiting is for a good reason.\n *\n * @_docloc: api/crypto:Passwords\n *\n * @example:\n * // The password must be converted to bytes, and it is generally\n * // best practices to ensure the string has been normalized. Many\n * // formats explicitly indicate the normalization form to use.\n * password = \"hello\"\n * passwordBytes = toUtf8Bytes(password, \"NFKC\")\n *\n * salt = id(\"some-salt\")\n *\n * // Compute the scrypt\n * scrypt(passwordBytes, salt, 1024, 8, 1, 16)\n * //_result:\n */\nexport async function scrypt(_passwd, _salt, N, r, p, dkLen, progress) {\n const passwd = getBytes(_passwd, \"passwd\");\n const salt = getBytes(_salt, \"salt\");\n return H(await __scryptAsync(passwd, salt, N, r, p, dkLen, progress));\n}\nscrypt._ = _scryptAsync;\nscrypt.lock = function () {\n lockedAsync = true;\n};\nscrypt.register = function (func) {\n if (lockedAsync) {\n throw new Error(\"scrypt is locked\");\n }\n __scryptAsync = func;\n};\nObject.freeze(scrypt);\n/**\n * Provides a synchronous variant of [[scrypt]].\n *\n * This will completely lock up and freeze the UI in a browser and will\n * prevent any event loop from progressing. For this reason, it is\n * preferred to use the [async variant](scrypt).\n *\n * @_docloc: api/crypto:Passwords\n *\n * @example:\n * // The password must be converted to bytes, and it is generally\n * // best practices to ensure the string has been normalized. Many\n * // formats explicitly indicate the normalization form to use.\n * password = \"hello\"\n * passwordBytes = toUtf8Bytes(password, \"NFKC\")\n *\n * salt = id(\"some-salt\")\n *\n * // Compute the scrypt\n * scryptSync(passwordBytes, salt, 1024, 8, 1, 16)\n * //_result:\n */\nexport function scryptSync(_passwd, _salt, N, r, p, dkLen) {\n const passwd = getBytes(_passwd, \"passwd\");\n const salt = getBytes(_salt, \"salt\");\n return H(__scryptSync(passwd, salt, N, r, p, dkLen));\n}\nscryptSync._ = _scryptSync;\nscryptSync.lock = function () {\n lockedSync = true;\n};\nscryptSync.register = function (func) {\n if (lockedSync) {\n throw new Error(\"scryptSync is locked\");\n }\n __scryptSync = func;\n};\nObject.freeze(scryptSync);\n//# sourceMappingURL=scrypt.js.map","/**\n * Cryptographic hashing functions\n *\n * @_subsection: api/crypto:Hash Functions [about-crypto-hashing]\n */\nimport { keccak_256 } from \"@noble/hashes/sha3\";\nimport { getBytes, hexlify } from \"../utils/index.js\";\nlet locked = false;\nconst _keccak256 = function (data) {\n return keccak_256(data);\n};\nlet __keccak256 = _keccak256;\n/**\n * Compute the cryptographic KECCAK256 hash of %%data%%.\n *\n * The %%data%% **must** be a data representation, to compute the\n * hash of UTF-8 data use the [[id]] function.\n *\n * @returns DataHexstring\n * @example:\n * keccak256(\"0x\")\n * //_result:\n *\n * keccak256(\"0x1337\")\n * //_result:\n *\n * keccak256(new Uint8Array([ 0x13, 0x37 ]))\n * //_result:\n *\n * // Strings are assumed to be DataHexString, otherwise it will\n * // throw. To hash UTF-8 data, see the note above.\n * keccak256(\"Hello World\")\n * //_error:\n */\nexport function keccak256(_data) {\n const data = getBytes(_data, \"data\");\n return hexlify(__keccak256(data));\n}\nkeccak256._ = _keccak256;\nkeccak256.lock = function () {\n locked = true;\n};\nkeccak256.register = function (func) {\n if (locked) {\n throw new TypeError(\"keccak256 is locked\");\n }\n __keccak256 = func;\n};\nObject.freeze(keccak256);\n//# sourceMappingURL=keccak.js.map","/*! noble-secp256k1 - MIT License (c) 2019 Paul Miller (paulmillr.com) */\nconst B256 = 2n ** 256n; // secp256k1 is short weierstrass curve\nconst P = B256 - 0x1000003d1n; // curve's field prime\nconst N = B256 - 0x14551231950b75fc4402da1732fc9bebfn; // curve (group) order\nconst Gx = 0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798n; // base point x\nconst Gy = 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8n; // base point y\nconst CURVE = { p: P, n: N, a: 0n, b: 7n, Gx, Gy }; // exported variables incl. a, b\nconst fLen = 32; // field / group byte length\nconst crv = (x) => mod(mod(x * x) * x + CURVE.b); // x³ + ax + b weierstrass formula; no a\nconst err = (m = '') => { throw new Error(m); }; // error helper, messes-up stack trace\nconst big = (n) => typeof n === 'bigint'; // is big integer\nconst str = (s) => typeof s === 'string'; // is string\nconst fe = (n) => big(n) && 0n < n && n < P; // is field element (invertible)\nconst ge = (n) => big(n) && 0n < n && n < N; // is group element\nconst au8 = (a, l) => // is Uint8Array (of specific length)\n !(a instanceof Uint8Array) || (typeof l === 'number' && l > 0 && a.length !== l) ?\n err('Uint8Array expected') : a;\nconst u8n = (data) => new Uint8Array(data); // creates Uint8Array\nconst toU8 = (a, len) => au8(str(a) ? h2b(a) : u8n(a), len); // norm(hex/u8a) to u8a\nconst mod = (a, b = P) => { let r = a % b; return r >= 0n ? r : b + r; }; // mod division\nconst isPoint = (p) => (p instanceof Point ? p : err('Point expected')); // is 3d point\nlet Gpows = undefined; // precomputes for base point G\nclass Point {\n constructor(px, py, pz) {\n this.px = px;\n this.py = py;\n this.pz = pz;\n } //3d=less inversions\n static fromAffine(p) { return new Point(p.x, p.y, 1n); }\n static fromHex(hex) {\n hex = toU8(hex); // convert hex string to Uint8Array\n let p = undefined;\n const head = hex[0], tail = hex.subarray(1); // first byte is prefix, rest is data\n const x = slcNum(tail, 0, fLen), len = hex.length; // next 32 bytes are x coordinate\n if (len === 33 && [0x02, 0x03].includes(head)) { // compressed points: 33b, start\n if (!fe(x))\n err('Point hex invalid: x not FE'); // with byte 0x02 or 0x03. Check if 0 0n; d = d.double(), n >>= 1n) { // double-and-add ladder\n if (n & 1n)\n p = p.add(d); // if bit is present, add to point\n else if (safe)\n f = f.add(d); // if not, add to fake for timing safety\n }\n return p;\n }\n mulAddQUns(R, u1, u2) {\n return this.mul(u1, false).add(R.mul(u2, false)).ok(); // Unsafe: do NOT use for stuff related\n } // to private keys. Doesn't use Shamir trick\n toAffine() {\n const { px: x, py: y, pz: z } = this; // (x, y, z) ∋ (x=x/z, y=y/z)\n if (this.equals(I))\n return { x: 0n, y: 0n }; // fast-path for zero point\n if (z === 1n)\n return { x, y }; // if z is 1, pass affine coordinates as-is\n const iz = inv(z); // z^-1: invert z\n if (mod(z * iz) !== 1n)\n err('invalid inverse'); // (z * z^-1) must be 1, otherwise bad math\n return { x: mod(x * iz), y: mod(y * iz) }; // x = x*z^-1; y = y*z^-1\n }\n assertValidity() {\n const { x, y } = this.aff(); // convert to 2d xy affine point.\n if (!fe(x) || !fe(y))\n err('Point invalid: x or y'); // x and y must be in range 0 < n < P\n return mod(y * y) === crv(x) ? // y² = x³ + ax + b, must be equal\n this : err('Point invalid: not on curve');\n }\n multiply(n) { return this.mul(n); } // Aliases to compress code\n aff() { return this.toAffine(); }\n ok() { return this.assertValidity(); }\n toHex(isCompressed = true) {\n const { x, y } = this.aff(); // convert to 2d xy affine point\n const head = isCompressed ? ((y & 1n) === 0n ? '02' : '03') : '04'; // 0x02, 0x03, 0x04 prefix\n return head + n2h(x) + (isCompressed ? '' : n2h(y)); // prefix||x and ||y\n }\n toRawBytes(isCompressed = true) {\n return h2b(this.toHex(isCompressed)); // re-use toHex(), convert hex to bytes\n }\n}\nPoint.BASE = new Point(Gx, Gy, 1n); // Generator / base point\nPoint.ZERO = new Point(0n, 1n, 0n); // Identity / zero point\nconst { BASE: G, ZERO: I } = Point; // Generator, identity points\nconst padh = (n, pad) => n.toString(16).padStart(pad, '0');\nconst b2h = (b) => Array.from(b).map(e => padh(e, 2)).join(''); // bytes to hex\nconst h2b = (hex) => {\n const l = hex.length; // error if not string,\n if (!str(hex) || l % 2)\n err('hex invalid 1'); // or has odd length like 3, 5.\n const arr = u8n(l / 2); // create result array\n for (let i = 0; i < arr.length; i++) {\n const j = i * 2;\n const h = hex.slice(j, j + 2); // hexByte. slice is faster than substr\n const b = Number.parseInt(h, 16); // byte, created from string part\n if (Number.isNaN(b) || b < 0)\n err('hex invalid 2'); // byte must be valid 0 <= byte < 256\n arr[i] = b;\n }\n return arr;\n};\nconst b2n = (b) => BigInt('0x' + (b2h(b) || '0')); // bytes to number\nconst slcNum = (b, from, to) => b2n(b.slice(from, to)); // slice bytes num\nconst n2b = (num) => {\n return big(num) && num >= 0n && num < B256 ? h2b(padh(num, 2 * fLen)) : err('bigint expected');\n};\nconst n2h = (num) => b2h(n2b(num)); // number to 32b hex\nconst concatB = (...arrs) => {\n const r = u8n(arrs.reduce((sum, a) => sum + au8(a).length, 0)); // create u8a of summed length\n let pad = 0; // walk through each array,\n arrs.forEach(a => { r.set(a, pad); pad += a.length; }); // ensure they have proper type\n return r;\n};\nconst inv = (num, md = P) => {\n if (num === 0n || md <= 0n)\n err('no inverse n=' + num + ' mod=' + md); // no neg exponent for now\n let a = mod(num, md), b = md, x = 0n, y = 1n, u = 1n, v = 0n;\n while (a !== 0n) { // uses euclidean gcd algorithm\n const q = b / a, r = b % a; // not constant-time\n const m = x - u * q, n = y - v * q;\n b = a, a = r, x = u, y = v, u = m, v = n;\n }\n return b === 1n ? mod(x, md) : err('no inverse'); // b is gcd at this point\n};\nconst sqrt = (n) => {\n let r = 1n; // So, a special, fast case. Paper: \"Square Roots from 1;24,51,10 to Dan Shanks\".\n for (let num = n, e = (P + 1n) / 4n; e > 0n; e >>= 1n) { // powMod: modular exponentiation.\n if (e & 1n)\n r = (r * num) % P; // Uses exponentiation by squaring.\n num = (num * num) % P; // Not constant-time.\n }\n return mod(r * r) === n ? r : err('sqrt invalid'); // check if result is valid\n};\nconst toPriv = (p) => {\n if (!big(p))\n p = b2n(toU8(p, fLen)); // convert to bigint when bytes\n return ge(p) ? p : err('private key out of range'); // check if bigint is in range\n};\nconst moreThanHalfN = (n) => n > (N >> 1n); // if a number is bigger than CURVE.n/2\nfunction getPublicKey(privKey, isCompressed = true) {\n return Point.fromPrivateKey(privKey).toRawBytes(isCompressed); // 33b or 65b output\n}\nclass Signature {\n constructor(r, s, recovery) {\n this.r = r;\n this.s = s;\n this.recovery = recovery;\n this.assertValidity(); // recovery bit is optional when\n } // constructed outside.\n static fromCompact(hex) {\n hex = toU8(hex, 64); // compact repr is (32b r)||(32b s)\n return new Signature(slcNum(hex, 0, fLen), slcNum(hex, fLen, 2 * fLen));\n }\n assertValidity() { return ge(this.r) && ge(this.s) ? this : err(); } // 0 < r or s < CURVE.n\n addRecoveryBit(rec) { return new Signature(this.r, this.s, rec); }\n hasHighS() { return moreThanHalfN(this.s); }\n recoverPublicKey(msgh) {\n const { r, s, recovery: rec } = this; // secg.org/sec1-v2.pdf 4.1.6\n if (![0, 1, 2, 3].includes(rec))\n err('recovery id invalid'); // check recovery id\n const h = bits2int_modN(toU8(msgh, 32)); // Truncate hash\n const radj = rec === 2 || rec === 3 ? r + N : r; // If rec was 2 or 3, q.x is bigger than n\n if (radj >= P)\n err('q.x invalid'); // ensure q.x is still a field element\n const head = (rec & 1) === 0 ? '02' : '03'; // head is 0x02 or 0x03\n const R = Point.fromHex(head + n2h(radj)); // concat head + hex repr of r\n const ir = inv(radj, N); // r^-1\n const u1 = mod(-h * ir, N); // -hr^-1\n const u2 = mod(s * ir, N); // sr^-1\n return G.mulAddQUns(R, u1, u2); // (sr^-1)R-(hr^-1)G = -(hr^-1)G + (sr^-1)\n }\n toCompactRawBytes() { return h2b(this.toCompactHex()); } // Uint8Array 64b compact repr\n toCompactHex() { return n2h(this.r) + n2h(this.s); } // hex 64b compact repr\n}\nconst bits2int = (bytes) => {\n const delta = bytes.length * 8 - 256; // RFC suggests optional truncating via bits2octets\n const num = b2n(bytes); // FIPS 186-4 4.6 suggests the leftmost min(nBitLen, outLen) bits, which\n return delta > 0 ? num >> BigInt(delta) : num; // matches bits2int. bits2int can produce res>N.\n};\nconst bits2int_modN = (bytes) => {\n return mod(bits2int(bytes), N); // with 0: BAD for trunc as per RFC vectors\n};\nconst i2o = (num) => n2b(num); // int to octets\nconst cr = () => // We support: 1) browsers 2) node.js 19+ 3) deno, other envs with crypto\n typeof globalThis === 'object' && 'crypto' in globalThis ? globalThis.crypto : undefined;\nlet _hmacSync; // Can be redefined by use in utils; built-ins don't provide it\nconst optS = { lowS: true }; // opts for sign()\nconst optV = { lowS: true }; // standard opts for verify()\nfunction prepSig(msgh, priv, opts = optS) {\n if (['der', 'recovered', 'canonical'].some(k => k in opts)) // Ban legacy options\n err('sign() legacy options not supported');\n let { lowS } = opts; // generates low-s sigs by default\n if (lowS == null)\n lowS = true; // RFC6979 3.2: we skip step A\n const h1i = bits2int_modN(toU8(msgh)); // msg bigint\n const h1o = i2o(h1i); // msg octets\n const d = toPriv(priv); // validate private key, convert to bigint\n const seed = [i2o(d), h1o]; // Step D of RFC6979 3.2\n let ent = opts.extraEntropy; // RFC6979 3.6: additional k' (optional)\n if (ent) { // K = HMAC_K(V || 0x00 || int2octets(x) || bits2octets(h1) || k')\n if (ent === true)\n ent = etc.randomBytes(fLen); // if true, use CSPRNG to generate data\n const e = toU8(ent); // convert Hex|Bytes to Bytes\n if (e.length !== fLen)\n err(); // Expected 32 bytes of extra data\n seed.push(e);\n }\n const m = h1i; // convert msg to bigint\n const k2sig = (kBytes) => {\n const k = bits2int(kBytes); // RFC6979 method.\n if (!ge(k))\n return; // Check 0 < k < CURVE.n\n const ik = inv(k, N); // k^-1 mod n, NOT mod P\n const q = G.mul(k).aff(); // q = Gk\n const r = mod(q.x, N); // r = q.x mod n\n if (r === 0n)\n return; // r=0 invalid\n const s = mod(ik * mod(m + mod(d * r, N), N), N); // s = k^-1(m + rd) mod n\n if (s === 0n)\n return; // s=0 invalid\n let normS = s; // normalized S\n let rec = (q.x === r ? 0 : 2) | Number(q.y & 1n); // recovery bit\n if (lowS && moreThanHalfN(s)) { // if lowS was passed, ensure s is always\n normS = mod(-s, N); // in the bottom half of CURVE.n\n rec ^= 1;\n }\n return new Signature(r, normS, rec); // use normS, not s\n };\n return { seed: concatB(...seed), k2sig };\n}\nfunction hmacDrbg(asynchronous) {\n let v = u8n(fLen); // Minimal non-full-spec HMAC-DRBG from NIST 800-90 for RFC6979 sigs.\n let k = u8n(fLen); // Steps B, C of RFC6979 3.2: set hashLen, in our case always same\n let i = 0; // Iterations counter, will throw when over 1000\n const reset = () => { v.fill(1); k.fill(0); i = 0; };\n const _e = 'drbg: tried 1000 values';\n if (asynchronous) { // asynchronous=true\n const h = (...b) => etc.hmacSha256Async(k, v, ...b); // hmac(k)(v, ...values)\n const reseed = async (seed = u8n()) => {\n k = await h(u8n([0x00]), seed); // k = hmac(K || V || 0x00 || seed)\n v = await h(); // v = hmac(K || V)\n if (seed.length === 0)\n return;\n k = await h(u8n([0x01]), seed); // k = hmac(K || V || 0x01 || seed)\n v = await h(); // v = hmac(K || V)\n };\n const gen = async () => {\n if (i++ >= 1000)\n err(_e);\n v = await h(); // v = hmac(K || V)\n return v;\n };\n return async (seed, pred) => {\n reset(); // the returned fn, don't, it's: 1. slower (JIT). 2. unsafe (async race conditions)\n await reseed(seed); // Steps D-G\n let res = undefined; // Step H: grind until k is in [1..n-1]\n while (!(res = pred(await gen())))\n await reseed(); // test predicate until it returns ok\n reset();\n return res;\n };\n }\n else {\n const h = (...b) => {\n const f = _hmacSync;\n if (!f)\n err('etc.hmacSha256Sync not set');\n return f(k, v, ...b); // hmac(k)(v, ...values)\n };\n const reseed = (seed = u8n()) => {\n k = h(u8n([0x00]), seed); // k = hmac(k || v || 0x00 || seed)\n v = h(); // v = hmac(k || v)\n if (seed.length === 0)\n return;\n k = h(u8n([0x01]), seed); // k = hmac(k || v || 0x01 || seed)\n v = h(); // v = hmac(k || v)\n };\n const gen = () => {\n if (i++ >= 1000)\n err(_e);\n v = h(); // v = hmac(k || v)\n return v;\n };\n return (seed, pred) => {\n reset();\n reseed(seed); // Steps D-G\n let res = undefined; // Step H: grind until k is in [1..n-1]\n while (!(res = pred(gen())))\n reseed(); // test predicate until it returns ok\n reset();\n return res;\n };\n }\n}\n// ECDSA signature generation. via secg.org/sec1-v2.pdf 4.1.2 + RFC6979 deterministic k\nasync function signAsync(msgh, priv, opts = optS) {\n const { seed, k2sig } = prepSig(msgh, priv, opts); // Extract arguments for hmac-drbg\n return hmacDrbg(true)(seed, k2sig); // Re-run hmac-drbg until k2sig returns ok\n}\nfunction sign(msgh, priv, opts = optS) {\n const { seed, k2sig } = prepSig(msgh, priv, opts); // Extract arguments for hmac-drbg\n return hmacDrbg(false)(seed, k2sig); // Re-run hmac-drbg until k2sig returns ok\n}\nfunction verify(sig, msgh, pub, opts = optV) {\n let { lowS } = opts; // ECDSA signature verification\n if (lowS == null)\n lowS = true; // Default lowS=true\n if ('strict' in opts)\n err('verify() legacy options not supported'); // legacy param\n let sig_, h, P; // secg.org/sec1-v2.pdf 4.1.4\n const rs = sig && typeof sig === 'object' && 'r' in sig; // Previous ver supported DER sigs. We\n if (!rs && (toU8(sig).length !== 2 * fLen)) // throw error when DER is suspected now.\n err('signature must be 64 bytes');\n try {\n sig_ = rs ? new Signature(sig.r, sig.s).assertValidity() : Signature.fromCompact(sig);\n h = bits2int_modN(toU8(msgh, fLen)); // Truncate hash\n P = pub instanceof Point ? pub.ok() : Point.fromHex(pub); // Validate public key\n }\n catch (e) {\n return false;\n } // Check sig for validity in both cases\n if (!sig_)\n return false;\n const { r, s } = sig_;\n if (lowS && moreThanHalfN(s))\n return false; // lowS bans sig.s >= CURVE.n/2\n let R;\n try {\n const is = inv(s, N); // s^-1\n const u1 = mod(h * is, N); // u1 = hs^-1 mod n\n const u2 = mod(r * is, N); // u2 = rs^-1 mod n\n R = G.mulAddQUns(P, u1, u2).aff(); // R = u1⋅G + u2⋅P\n }\n catch (error) {\n return false;\n }\n if (!R)\n return false; // stop if R is identity / zero point\n const v = mod(R.x, N); // <== The weird ECDSA part. R.x must be in N's field, not P's\n return v === r; // mod(R.x, n) == r\n}\nfunction getSharedSecret(privA, pubB, isCompressed = true) {\n return Point.fromHex(pubB).mul(toPriv(privA)).toRawBytes(isCompressed); // ECDH\n}\nfunction hashToPrivateKey(hash) {\n hash = toU8(hash); // produces private keys with modulo bias\n const minLen = fLen + 8; // being neglible.\n if (hash.length < minLen || hash.length > 1024)\n err('expected proper params');\n const num = mod(b2n(hash), N - 1n) + 1n; // takes at least n+8 bytes\n return n2b(num);\n}\nconst etc = {\n hexToBytes: h2b, bytesToHex: b2h,\n concatBytes: concatB, bytesToNumberBE: b2n, numberToBytesBE: n2b,\n mod, invert: inv,\n hmacSha256Async: async (key, ...msgs) => {\n const crypto = cr(); // HMAC-SHA256 async. No sync built-in!\n if (!crypto)\n return err('etc.hmacSha256Async not set'); // Uses webcrypto: native cryptography.\n const s = crypto.subtle;\n const k = await s.importKey('raw', key, { name: 'HMAC', hash: { name: 'SHA-256' } }, false, ['sign']);\n return u8n(await s.sign('HMAC', k, concatB(...msgs)));\n },\n hmacSha256Sync: _hmacSync,\n hashToPrivateKey,\n randomBytes: (len) => {\n const crypto = cr(); // Can be shimmed in node.js <= 18 to prevent error:\n // import { webcrypto } from 'node:crypto';\n // if (!globalThis.crypto) globalThis.crypto = webcrypto;\n if (!crypto)\n err('crypto.getRandomValues must be defined');\n return crypto.getRandomValues(u8n(len));\n },\n};\nconst utils = {\n normPrivateKeyToScalar: toPriv,\n isValidPrivateKey: (key) => { try {\n return !!toPriv(key);\n }\n catch (e) {\n return false;\n } },\n randomPrivateKey: () => hashToPrivateKey(etc.randomBytes(fLen + 8)),\n precompute(w = 8, p = G) { p.multiply(3n); return p; }, // no-op\n};\nObject.defineProperties(etc, { hmacSha256Sync: {\n configurable: false, get() { return _hmacSync; }, set(f) { if (!_hmacSync)\n _hmacSync = f; },\n } });\nconst W = 8; // Precomputes-related code. W = window size\nconst precompute = () => {\n const points = []; // 10x sign(), 2x verify(). To achieve this,\n const windows = 256 / W + 1; // app needs to spend 40ms+ to calculate\n let p = G, b = p; // a lot of points related to base point G.\n for (let w = 0; w < windows; w++) { // Points are stored in array and used\n b = p; // any time Gx multiplication is done.\n points.push(b); // They consume 16-32 MiB of RAM.\n for (let i = 1; i < 2 ** (W - 1); i++) {\n b = b.add(p);\n points.push(b);\n }\n p = b.double(); // Precomputes don't speed-up getSharedKey,\n } // which multiplies user point by scalar,\n return points; // when precomputes are using base point\n};\nconst wNAF = (n) => {\n // Compared to other point mult methods,\n const comp = Gpows || (Gpows = precompute()); // stores 2x less points using subtraction\n const neg = (cnd, p) => { let n = p.negate(); return cnd ? n : p; }; // negate\n let p = I, f = G; // f must be G, or could become I in the end\n const windows = 1 + 256 / W; // W=8 17 windows\n const wsize = 2 ** (W - 1); // W=8 128 window size\n const mask = BigInt(2 ** W - 1); // W=8 will create mask 0b11111111\n const maxNum = 2 ** W; // W=8 256\n const shiftBy = BigInt(W); // W=8 8\n for (let w = 0; w < windows; w++) {\n const off = w * wsize;\n let wbits = Number(n & mask); // extract W bits.\n n >>= shiftBy; // shift number by W bits.\n if (wbits > wsize) {\n wbits -= maxNum;\n n += 1n;\n } // split if bits > max: +224 => 256-32\n const off1 = off, off2 = off + Math.abs(wbits) - 1; // offsets, evaluate both\n const cnd1 = w % 2 !== 0, cnd2 = wbits < 0; // conditions, evaluate both\n if (wbits === 0) {\n f = f.add(neg(cnd1, comp[off1])); // bits are 0: add garbage to fake point\n }\n else { // ^ can't add off2, off2 = I\n p = p.add(neg(cnd2, comp[off2])); // bits are 1: add to result point\n }\n }\n return { p, f }; // return both real and fake points for JIT\n}; // !! you can disable precomputes by commenting-out call of the wNAF() inside Point#mul()\nexport { getPublicKey, sign, signAsync, verify, CURVE, // Remove the export to easily use in REPL\ngetSharedSecret, etc, utils, Point as ProjectivePoint, Signature }; // envs like browser console\n","/**\n * Add details about signing here.\n *\n * @_subsection: api/crypto:Signing [about-signing]\n */\nimport * as secp256k1 from \"@noble/secp256k1\";\nimport { dataLength, getBytes, getBytesCopy, hexlify, assertArgument, } from \"../utils/index.js\";\nimport { arrayify, hexConcat } from \"../utils/data.js\";\nimport { Logger } from \"../logger/logger.js\";\nimport { ed448 } from \"./crypto.js\";\nimport { Buffer } from \"buffer\";\nconst logger = new Logger(\"signing-key/0.0.1\");\n//const N = BigInt(\"0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141\");\n// Make noble-secp256k1 sync\n/**\n * A **SigningKey** provides high-level access to the elliptic curve\n * cryptography (ECC) operations and key management.\n */\nexport class SigningKey {\n #privateKey;\n /**\n * Creates a new **SigningKey** for %%privateKey%%.\n */\n constructor(privateKey) {\n let tmp = privateKey;\n if (typeof tmp === \"string\" && tmp.startsWith(\"0x\")) {\n tmp = tmp.replace(\"0x\", \"\");\n }\n assertArgument(dataLength(\"0x\" + tmp) === 57, \"invalid private key\", \"privateKey\", \"[REDACTED]\");\n this.#privateKey = hexlify(\"0x\" + tmp);\n }\n /**\n * The private key.\n */\n get privateKey() {\n return this.#privateKey;\n }\n /**\n * The uncompressed public key.\n *\n * This will always begin with the prefix ``0x04`` and be 132\n * characters long (the ``0x`` prefix and 130 hexadecimal nibbles).\n */\n get publicKey() {\n return SigningKey.computePublicKey(this.#privateKey);\n }\n /**\n * The compressed public key.\n *\n * This will always begin with either the prefix ``0x02`` or ``0x03``\n * and be 68 characters long (the ``0x`` prefix and 33 hexadecimal\n * nibbles)\n */\n get compressedPublicKey() {\n return SigningKey.computePublicKey(this.#privateKey, true);\n }\n /**\n * Return the signature of the signed %%digest%%.\n */\n sign(digest) {\n const key = getBytesCopy(this.#privateKey);\n assertArgument(dataLength(digest) === 32, \"invalid digest length\", \"digest\", digest);\n const keyBuffer = new Uint8Array(arrayify(key));\n if (keyBuffer.length !== 57) {\n logger.throwArgumentError(\"invalid private key\", \"key\", \"[REDACTED]\");\n }\n const digestBuffer = new Uint8Array(arrayify(digest));\n if (digestBuffer.length !== 32) {\n logger.throwArgumentError(\"bad digest length\", \"digest\", digest);\n }\n if (keyBuffer[56] > 127) {\n const prefix = keyBuffer.slice(0, 57);\n prefix[0] &= 0xfc;\n prefix[55] |= 0x80;\n prefix[56] = 0;\n const scalar = prefix.slice(0, 56);\n const bufferDigest = Buffer.from(digestBuffer);\n const bufferPrfx = Buffer.from(prefix);\n const bufferScalar = Buffer.from(scalar);\n const sig = ed448.signWithScalar(bufferDigest, bufferScalar, bufferPrfx);\n const hexlified = hexlify(sig);\n return hexConcat([hexlified, this.publicKey]);\n }\n const sig = ed448.sign(Buffer.from(digestBuffer), Buffer.from(keyBuffer));\n const hexlified = hexlify(sig);\n return hexConcat([hexlified, this.publicKey]);\n }\n /**\n * Returns the [[link-wiki-ecdh]] shared secret between this\n * private key and the %%other%% key.\n *\n * The %%other%% key may be any type of key, a raw public key,\n * a compressed/uncompressed pubic key or aprivate key.\n *\n * Best practice is usually to use a cryptographic hash on the\n * returned value before using it as a symetric secret.\n *\n * @example:\n * sign1 = new SigningKey(id(\"some-secret-1\"))\n * sign2 = new SigningKey(id(\"some-secret-2\"))\n *\n * // Notice that privA.computeSharedSecret(pubB)...\n * sign1.computeSharedSecret(sign2.publicKey)\n * //_result:\n *\n * // ...is equal to privB.computeSharedSecret(pubA).\n * sign2.computeSharedSecret(sign1.publicKey)\n * //_result:\n */\n computeSharedSecret(other) {\n const pubKey = SigningKey.computePublicKey(other);\n return hexlify(secp256k1.getSharedSecret(getBytesCopy(this.#privateKey), getBytes(pubKey)));\n }\n /**\n * Compute the public key for %%key%%, optionally %%compressed%%.\n *\n * The %%key%% may be any type of key, a raw public key, a\n * compressed/uncompressed public key or private key.\n *\n * @example:\n * sign = new SigningKey(id(\"some-secret\"));\n *\n * // Compute the uncompressed public key for a private key\n * SigningKey.computePublicKey(sign.privateKey)\n * //_result:\n *\n * // Compute the compressed public key for a private key\n * SigningKey.computePublicKey(sign.privateKey, true)\n * //_result:\n *\n * // Compute the uncompressed public key\n * SigningKey.computePublicKey(sign.publicKey, false);\n * //_result:\n *\n * // Compute the Compressed a public key\n * SigningKey.computePublicKey(sign.publicKey, true);\n * //_result:\n */\n static computePublicKey(key, compressed) {\n const bytes = Buffer.from(arrayify(key));\n if (bytes.length !== 57) {\n logger.throwArgumentError(\"invalid private key\", \"key\", \"[REDACTED]\");\n }\n if (bytes[56] > 127) {\n const scalar = bytes.slice(0, 56);\n scalar[0] &= 0xfc;\n scalar[55] |= 0x80;\n const pub = ed448.publicKeyFromScalar(scalar);\n return hexlify(pub);\n }\n const pub = ed448.publicKeyCreate(bytes);\n return hexlify(pub);\n }\n /**\n * Returns the public key for the private key which produced the\n * %%signature%% for the given %%digest%%.\n *\n * @example:\n * key = new SigningKey(id(\"some-secret\"))\n * digest = id(\"hello world\")\n * sig = key.sign(digest)\n *\n * // Notice the signer public key...\n * key.publicKey\n * //_result:\n *\n * // ...is equal to the recovered public key\n * SigningKey.recoverPublicKey(digest, sig)\n * //_result:\n *\n */\n static recoverPublicKey(digest, signature) {\n assertArgument(dataLength(digest) === 32, \"invalid digest length\", \"digest\", digest);\n const digestBuffer = Buffer.from(arrayify(digest));\n const sigBuffer = Buffer.from(arrayify(signature));\n if (sigBuffer.length !== 171) {\n logger.throwArgumentError(\"invalid signature\", \"signature\", signature);\n }\n const sig = sigBuffer.slice(0, 114);\n const pub = sigBuffer.slice(114);\n if (ed448.verify(digestBuffer, sig, pub)) {\n return hexlify(pub);\n }\n logger.throwArgumentError(\"invalid signature\", \"signature\", signature);\n return \"\";\n }\n /**\n * Returns the point resulting from adding the ellipic curve points\n * %%p0%% and %%p1%%.\n *\n * This is not a common function most developers should require, but\n * can be useful for certain privacy-specific techniques.\n *\n * For example, it is used by [[HDNodeWallet]] to compute child\n * addresses from parent public keys and chain codes.\n */\n static addPoints(p0, p1, compressed) {\n const pub0 = secp256k1.ProjectivePoint.fromHex(SigningKey.computePublicKey(p0).substring(2));\n const pub1 = secp256k1.ProjectivePoint.fromHex(SigningKey.computePublicKey(p1).substring(2));\n return \"0x\" + pub0.add(pub1).toHex(!!compressed);\n }\n}\n//# sourceMappingURL=signing-key.js.map","import { concat, dataLength, getBigInt, getBytes, getNumber, hexlify, assertArgument, assertPrivate, } from \"../utils/index.js\";\n// Constants\nconst BN_0 = BigInt(0);\nconst BN_1 = BigInt(1);\nconst BN_2 = BigInt(2);\nconst BN_27 = BigInt(27);\nconst BN_28 = BigInt(28);\nconst BN_35 = BigInt(35);\nconst _guard = {};\n/**\n * A Signature @TODO\n *\n *\n * @_docloc: api/crypto:Signing\n */\nexport class Signature {\n #r;\n #s;\n #v;\n #networkV;\n /**\n * The ``r`` value for a signautre.\n *\n * This represents the ``x`` coordinate of a \"reference\" or\n * challenge point, from which the ``y`` can be computed.\n */\n get r() {\n return this.#r;\n }\n set r(value) {\n assertArgument(dataLength(value) === 32, \"invalid r\", \"value\", value);\n this.#r = hexlify(value);\n }\n /**\n * The ``s`` value for a signature.\n */\n get s() {\n return this.#s;\n }\n set s(_value) {\n assertArgument(dataLength(_value) === 32, \"invalid s\", \"value\", _value);\n const value = hexlify(_value);\n assertArgument(parseInt(value.substring(0, 3)) < 8, \"non-canonical s\", \"value\", value);\n this.#s = value;\n }\n /**\n * The ``v`` value for a signature.\n *\n * Since a given ``x`` value for ``r`` has two possible values for\n * its correspondin ``y``, the ``v`` indicates which of the two ``y``\n * values to use.\n *\n * It is normalized to the values ``27`` or ``28`` for legacy\n * purposes.\n */\n get v() {\n return this.#v;\n }\n set v(value) {\n const v = getNumber(value, \"value\");\n assertArgument(v === 27 || v === 28, \"invalid v\", \"v\", value);\n this.#v = v;\n }\n /**\n * The EIP-155 ``v`` for legacy transactions. For non-legacy\n * transactions, this value is ``null``.\n */\n get networkV() {\n return this.#networkV;\n }\n /**\n * The chain ID for EIP-155 legacy transactions. For non-legacy\n * transactions, this value is ``null``.\n */\n get legacynetworkId() {\n const v = this.networkV;\n if (v == null) {\n return null;\n }\n return Signature.getnetworkId(v);\n }\n /**\n * The ``yParity`` for the signature.\n *\n * See ``v`` for more details on how this value is used.\n */\n get yParity() {\n return this.v === 27 ? 0 : 1;\n }\n /**\n * The [[link-eip-2098]] compact representation of the ``yParity``\n * and ``s`` compacted into a single ``bytes32``.\n */\n get yParityAndS() {\n // The EIP-2098 compact representation\n const yParityAndS = getBytes(this.s);\n if (this.yParity) {\n yParityAndS[0] |= 0x80;\n }\n return hexlify(yParityAndS);\n }\n /**\n * The [[link-eip-2098]] compact representation.\n */\n get compactSerialized() {\n return concat([this.r, this.yParityAndS]);\n }\n /**\n * The serialized representation.\n */\n get serialized() {\n return concat([this.r, this.s, this.yParity ? \"0x1c\" : \"0x1b\"]);\n }\n /**\n * @private\n */\n constructor(guard, r, s, v) {\n assertPrivate(guard, _guard, \"Signature\");\n this.#r = r;\n this.#s = s;\n this.#v = v;\n this.#networkV = null;\n }\n [Symbol.for(\"nodejs.util.inspect.custom\")]() {\n return `Signature { r: \"${this.r}\", s: \"${this.s}\", yParity: ${this.yParity}, networkV: ${this.networkV} }`;\n }\n /**\n * Returns a new identical [[Signature]].\n */\n clone() {\n const clone = new Signature(_guard, this.r, this.s, this.v);\n if (this.networkV) {\n clone.#networkV = this.networkV;\n }\n return clone;\n }\n /**\n * Returns a representation that is compatible with ``JSON.stringify``.\n */\n toJSON() {\n const networkV = this.networkV;\n return {\n _type: \"signature\",\n networkV: networkV != null ? networkV.toString() : null,\n r: this.r,\n s: this.s,\n v: this.v,\n };\n }\n /**\n * Compute the chain ID from the ``v`` in a legacy EIP-155 transactions.\n *\n * @example:\n * Signature.getnetworkId(45)\n * //_result:\n *\n * Signature.getnetworkId(46)\n * //_result:\n */\n static getnetworkId(v) {\n const bv = getBigInt(v, \"v\");\n // The v is not an EIP-155 v, so it is the unspecified chain ID\n if (bv == BN_27 || bv == BN_28) {\n return BN_0;\n }\n // Bad value for an EIP-155 v\n assertArgument(bv >= BN_35, \"invalid EIP-155 v\", \"v\", v);\n return (bv - BN_35) / BN_2;\n }\n /**\n * Compute the ``v`` for a chain ID for a legacy EIP-155 transactions.\n *\n * Legacy transactions which use [[link-eip-155]] hijack the ``v``\n * property to include the chain ID.\n *\n * @example:\n * Signature.getnetworkIdV(5, 27)\n * //_result:\n *\n * Signature.getnetworkIdV(5, 28)\n * //_result:\n *\n */\n static getnetworkIdV(networkId, v) {\n return getBigInt(networkId) * BN_2 + BigInt(35 + v - 27);\n }\n /**\n * Compute the normalized legacy transaction ``v`` from a ``yParirty``,\n * a legacy transaction ``v`` or a legacy [[link-eip-155]] transaction.\n *\n * @example:\n * // The values 0 and 1 imply v is actually yParity\n * Signature.getNormalizedV(0)\n * //_result:\n *\n * // Legacy non-EIP-1559 transaction (i.e. 27 or 28)\n * Signature.getNormalizedV(27)\n * //_result:\n *\n * // Legacy EIP-155 transaction (i.e. >= 35)\n * Signature.getNormalizedV(46)\n * //_result:\n *\n * // Invalid values throw\n * Signature.getNormalizedV(5)\n * //_error:\n */\n static getNormalizedV(v) {\n const bv = getBigInt(v);\n if (bv === BN_0 || bv === BN_27) {\n return 27;\n }\n if (bv === BN_1 || bv === BN_28) {\n return 28;\n }\n assertArgument(bv >= BN_35, \"invalid v\", \"v\", v);\n // Otherwise, EIP-155 v means odd is 27 and even is 28\n return bv & BN_1 ? 27 : 28;\n }\n}\n//# sourceMappingURL=signature.js.map","/**\n * A fundamental building block of Core is the underlying\n * cryptographic primitives.\n *\n * @_section: api/crypto:Cryptographic Functions [about-crypto]\n */\nnull;\n// We import all these so we can export lock()\nimport { computeHmac } from \"./hmac.js\";\nimport { ripemd160 } from \"./ripemd160.js\";\nimport { pbkdf2 } from \"./pbkdf2.js\";\nimport { randomBytes } from \"./random.js\";\nimport { scrypt, scryptSync } from \"./scrypt.js\";\nimport { sha256, sha512 } from \"./sha3.js\";\nimport { Ed448Goldilock } from \"./crypto.js\";\nimport { keccak256 } from \"./keccak.js\";\nexport { computeHmac, randomBytes, ripemd160, sha256, sha512, pbkdf2, scrypt, scryptSync, keccak256, Ed448Goldilock, };\nexport { SigningKey } from \"./signing-key.js\";\nexport { Signature } from \"./signature.js\";\nfunction lock() {\n computeHmac.lock();\n pbkdf2.lock();\n randomBytes.lock();\n ripemd160.lock();\n scrypt.lock();\n scryptSync.lock();\n sha256.lock();\n sha512.lock();\n randomBytes.lock();\n}\nexport { lock };\n//# sourceMappingURL=index.js.map","import { getAddress } from \"../address/index.js\";\nimport { sha256, SigningKey } from \"../crypto/index.js\";\nimport { arrayify, hexDataSlice } from \"../utils/data.js\";\nimport { calculateCheckSum } from \"../address/index.js\";\n/**\n * Returns the address for the %%key%%.\n *\n * The key may be any standard form of public key or a private key.\n */\nexport function removeHexPrefix(val) {\n return val.substring(0, 2) === \"0x\" ? val.substring(2) : val;\n}\nexport function publicToAddress(key, prefix) {\n const val = hexDataSlice(sha256(key), 12);\n const checksum = calculateCheckSum(val, prefix);\n return \"0x\" + prefix + checksum + removeHexPrefix(val);\n}\nexport function computeAddress(key, prefix) {\n let pubkey;\n if (typeof key === \"string\") {\n pubkey = SigningKey.computePublicKey(key, false);\n }\n else {\n pubkey = key.publicKey;\n }\n return publicToAddress(pubkey, prefix); // getAddress(sha256(\"0x\" + pubkey.substring(4)).substring(26));\n}\n/**\n * Returns the recovered address for the private key that was\n * used to sign %%digest%% that resulted in %%signature%%.\n */\nexport function recoverAddress(digest, signature, prefix) {\n // return computeAddress(SigningKey.recoverPublicKey(digest, signature));\n const publicKey = SigningKey.recoverPublicKey(arrayify(digest), signature);\n return publicToAddress(publicKey, prefix);\n}\nexport function extractPrefix(address) {\n address = getAddress(address);\n return address.substring(2, 4);\n}\n//# sourceMappingURL=address.js.map","import { defineProperties, concat, getBytesCopy, getNumber, hexlify, toBeArray, toBigInt, toNumber, assert, assertArgument, } from \"../../utils/index.js\";\n/**\n * @_ignore:\n */\nexport const WordSize = 32;\nconst Padding = new Uint8Array(WordSize);\n// Properties used to immediate pass through to the underlying object\n// - `then` is used to detect if an object is a Promise for await\nconst passProperties = [\"then\"];\nconst _guard = {};\nfunction throwError(name, error) {\n const wrapped = new Error(`deferred error during ABI decoding triggered accessing ${name}`);\n wrapped.error = error;\n throw wrapped;\n}\n/**\n * A [[Result]] is a sub-class of Array, which allows accessing any\n * of its values either positionally by its index or, if keys are\n * provided by its name.\n *\n * @_docloc: api/abi\n */\nexport class Result extends Array {\n #names;\n /**\n * @private\n */\n constructor(...args) {\n // To properly sub-class Array so the other built-in\n // functions work, the constructor has to behave fairly\n // well. So, in the event we are created via fromItems()\n // we build the read-only Result object we want, but on\n // any other input, we use the default constructor\n // constructor(guard: any, items: Array, keys?: Array);\n const guard = args[0];\n let items = args[1];\n let names = (args[2] || []).slice();\n let wrap = true;\n if (guard !== _guard) {\n items = args;\n names = [];\n wrap = false;\n }\n // Can't just pass in ...items since an array of length 1\n // is a special case in the super.\n super(items.length);\n items.forEach((item, index) => {\n this[index] = item;\n });\n // Find all unique keys\n const nameCounts = names.reduce((accum, name) => {\n if (typeof name === \"string\") {\n accum.set(name, (accum.get(name) || 0) + 1);\n }\n return accum;\n }, new Map());\n // Remove any key thats not unique\n this.#names = Object.freeze(items.map((item, index) => {\n const name = names[index];\n if (name != null && nameCounts.get(name) === 1) {\n return name;\n }\n return null;\n }));\n if (!wrap) {\n return;\n }\n // A wrapped Result is immutable\n Object.freeze(this);\n // Proxy indices and names so we can trap deferred errors\n return new Proxy(this, {\n get: (target, prop, receiver) => {\n if (typeof prop === \"string\") {\n // Index accessor\n if (prop.match(/^[0-9]+$/)) {\n const index = getNumber(prop, \"%index\");\n if (index < 0 || index >= this.length) {\n throw new RangeError(\"out of result range\");\n }\n const item = target[index];\n if (item instanceof Error) {\n throwError(`index ${index}`, item);\n }\n return item;\n }\n // Pass important checks (like `then` for Promise) through\n if (passProperties.indexOf(prop) >= 0) {\n return Reflect.get(target, prop, receiver);\n }\n const value = target[prop];\n if (value instanceof Function) {\n // Make sure functions work with private variables\n // See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy#no_private_property_forwarding\n return function (...args) {\n return value.apply(this === receiver ? target : this, args);\n };\n }\n else if (!(prop in target)) {\n // Possible name accessor\n return target.getValue.apply(this === receiver ? target : this, [\n prop,\n ]);\n }\n }\n return Reflect.get(target, prop, receiver);\n },\n });\n }\n /**\n * Returns the Result as a normal Array.\n *\n * This will throw if there are any outstanding deferred\n * errors.\n */\n toArray() {\n const result = [];\n this.forEach((item, index) => {\n if (item instanceof Error) {\n throwError(`index ${index}`, item);\n }\n result.push(item);\n });\n return result;\n }\n /**\n * Returns the Result as an Object with each name-value pair.\n *\n * This will throw if any value is unnamed, or if there are\n * any outstanding deferred errors.\n */\n toObject() {\n return this.#names.reduce((accum, name, index) => {\n assert(name != null, \"value at index ${ index } unnamed\", \"UNSUPPORTED_OPERATION\", {\n operation: \"toObject()\",\n });\n // Add values for names that don't conflict\n if (!(name in accum)) {\n accum[name] = this.getValue(name);\n }\n return accum;\n }, {});\n }\n /**\n * @_ignore\n */\n slice(start, end) {\n if (start == null) {\n start = 0;\n }\n if (start < 0) {\n start += this.length;\n if (start < 0) {\n start = 0;\n }\n }\n if (end == null) {\n end = this.length;\n }\n if (end < 0) {\n end += this.length;\n if (end < 0) {\n end = 0;\n }\n }\n if (end > this.length) {\n end = this.length;\n }\n const result = [], names = [];\n for (let i = start; i < end; i++) {\n result.push(this[i]);\n names.push(this.#names[i]);\n }\n return new Result(_guard, result, names);\n }\n /**\n * @_ignore\n */\n filter(callback, thisArg) {\n const result = [], names = [];\n for (let i = 0; i < this.length; i++) {\n const item = this[i];\n if (item instanceof Error) {\n throwError(`index ${i}`, item);\n }\n if (callback.call(thisArg, item, i, this)) {\n result.push(item);\n names.push(this.#names[i]);\n }\n }\n return new Result(_guard, result, names);\n }\n /**\n * Returns the value for %%name%%.\n *\n * Since it is possible to have a key whose name conflicts with\n * a method on a [[Result]] or its superclass Array, or any\n * JavaScript keyword, this ensures all named values are still\n * accessible by name.\n */\n getValue(name) {\n const index = this.#names.indexOf(name);\n if (index === -1) {\n return undefined;\n }\n const value = this[index];\n if (value instanceof Error) {\n throwError(`property ${JSON.stringify(name)}`, value.error);\n }\n return value;\n }\n /**\n * Creates a new [[Result]] for %%items%% with each entry\n * also accessible by its corresponding name in %%keys%%.\n */\n static fromItems(items, keys) {\n return new Result(_guard, items, keys);\n }\n}\n/**\n * Returns all errors found in a [[Result]].\n *\n * Since certain errors encountered when creating a [[Result]] do\n * not impact the ability to continue parsing data, they are\n * deferred until they are actually accessed. Hence a faulty string\n * in an Event that is never used does not impact the program flow.\n *\n * However, sometimes it may be useful to access, identify or\n * validate correctness of a [[Result]].\n *\n * @_docloc api/abi\n */\nexport function checkResultErrors(result) {\n // Find the first error (if any)\n const errors = [];\n const checkErrors = function (path, object) {\n if (!Array.isArray(object)) {\n return;\n }\n for (let key in object) {\n const childPath = path.slice();\n childPath.push(key);\n try {\n checkErrors(childPath, object[key]);\n }\n catch (error) {\n errors.push({ path: childPath, error: error });\n }\n }\n };\n checkErrors([], result);\n return errors;\n}\nfunction getValue(value) {\n let bytes = toBeArray(value);\n assert(bytes.length <= WordSize, \"value out-of-bounds\", \"BUFFER_OVERRUN\", {\n buffer: bytes,\n length: WordSize,\n offset: bytes.length,\n });\n if (bytes.length !== WordSize) {\n bytes = getBytesCopy(concat([Padding.slice(bytes.length % WordSize), bytes]));\n }\n return bytes;\n}\n/**\n * @_ignore\n */\nexport class Coder {\n // The coder name:\n // - address, uint256, tuple, array, etc.\n name;\n // The fully expanded type, including composite types:\n // - address, uint256, tuple(address,bytes), uint256[3][4][], etc.\n type;\n // The localName bound in the signature, in this example it is \"baz\":\n // - tuple(address foo, uint bar) baz\n localName;\n // Whether this type is dynamic:\n // - Dynamic: bytes, string, address[], tuple(boolean[]), etc.\n // - Not Dynamic: address, uint256, boolean[3], tuple(address, uint8)\n dynamic;\n constructor(name, type, localName, dynamic) {\n defineProperties(this, { name, type, localName, dynamic }, {\n name: \"string\",\n type: \"string\",\n localName: \"string\",\n dynamic: \"boolean\",\n });\n }\n _throwError(message, value) {\n assertArgument(false, message, this.localName, value);\n }\n}\n/**\n * @_ignore\n */\nexport class Writer {\n // An array of WordSize lengthed objects to concatenation\n #data;\n #dataLength;\n constructor() {\n this.#data = [];\n this.#dataLength = 0;\n }\n get data() {\n return concat(this.#data);\n }\n get length() {\n return this.#dataLength;\n }\n #writeData(data) {\n this.#data.push(data);\n this.#dataLength += data.length;\n return data.length;\n }\n appendWriter(writer) {\n return this.#writeData(getBytesCopy(writer.data));\n }\n // Arrayish item; pad on the right to *nearest* WordSize\n writeBytes(value) {\n let bytes = getBytesCopy(value);\n const paddingOffset = bytes.length % WordSize;\n if (paddingOffset) {\n bytes = getBytesCopy(concat([bytes, Padding.slice(paddingOffset)]));\n }\n return this.#writeData(bytes);\n }\n // Numeric item; pad on the left *to* WordSize\n writeValue(value) {\n return this.#writeData(getValue(value));\n }\n // Inserts a numeric place-holder, returning a callback that can\n // be used to asjust the value later\n writeUpdatableValue() {\n const offset = this.#data.length;\n this.#data.push(Padding);\n this.#dataLength += WordSize;\n return (value) => {\n this.#data[offset] = getValue(value);\n };\n }\n}\n/**\n * @_ignore\n */\nexport class Reader {\n // Allows incomplete unpadded data to be read; otherwise an error\n // is raised if attempting to overrun the buffer. This is required\n // to deal with an old Solidity bug, in which event data for\n // external (not public thoguh) was tightly packed.\n allowLoose;\n #data;\n #offset;\n constructor(data, allowLoose) {\n defineProperties(this, { allowLoose: !!allowLoose });\n this.#data = getBytesCopy(data);\n this.#offset = 0;\n }\n get data() {\n return hexlify(this.#data);\n }\n get dataLength() {\n return this.#data.length;\n }\n get consumed() {\n return this.#offset;\n }\n get bytes() {\n return new Uint8Array(this.#data);\n }\n #peekBytes(offset, length, loose) {\n let alignedLength = Math.ceil(length / WordSize) * WordSize;\n if (this.#offset + alignedLength > this.#data.length) {\n if (this.allowLoose &&\n loose &&\n this.#offset + length <= this.#data.length) {\n alignedLength = length;\n }\n else {\n assert(false, \"data out-of-bounds\", \"BUFFER_OVERRUN\", {\n buffer: getBytesCopy(this.#data),\n length: this.#data.length,\n offset: this.#offset + alignedLength,\n });\n }\n }\n return this.#data.slice(this.#offset, this.#offset + alignedLength);\n }\n // Create a sub-reader with the same underlying data, but offset\n subReader(offset) {\n return new Reader(this.#data.slice(this.#offset + offset), this.allowLoose);\n }\n // Read bytes\n readBytes(length, loose) {\n let bytes = this.#peekBytes(0, length, !!loose);\n this.#offset += bytes.length;\n // @TODO: Make sure the length..end bytes are all 0?\n return bytes.slice(0, length);\n }\n // Read a numeric values\n readValue() {\n return toBigInt(this.readBytes(WordSize));\n }\n readIndex() {\n return toNumber(this.readBytes(WordSize));\n }\n}\n//# sourceMappingURL=abstract-coder.js.map","/**\n * A Typed object allows a value to have its type explicitly\n * specified.\n *\n * For example, in Solidity, the value ``45`` could represent a\n * ``uint8`` or a ``uint256``. The value ``0x1234`` could represent\n * a ``bytes2`` or ``bytes``.\n *\n * Since JavaScript has no meaningful way to explicitly inform any\n * APIs which what the type is, this allows transparent interoperation\n * with Soldity.\n *\n * @_subsection: api/abi:Typed Values\n */\nimport { assertPrivate, defineProperties } from \"../utils/index.js\";\nconst _gaurd = {};\nfunction n(value, width) {\n let signed = false;\n if (width < 0) {\n signed = true;\n width *= -1;\n }\n // @TODO: Check range is valid for value\n return new Typed(_gaurd, `${signed ? \"\" : \"u\"}int${width}`, value, {\n signed,\n width,\n });\n}\nfunction b(value, size) {\n // @TODO: Check range is valid for value\n return new Typed(_gaurd, `bytes${size ? size : \"\"}`, value, { size });\n}\nconst _typedSymbol = Symbol.for(\"_corebc_typed\");\nexport class Typed {\n type;\n value;\n #options;\n _typedSymbol;\n constructor(gaurd, type, value, options) {\n if (options == null) {\n options = null;\n }\n assertPrivate(_gaurd, gaurd, \"Typed\");\n defineProperties(this, { _typedSymbol, type, value });\n this.#options = options;\n // Check the value is valid\n this.format();\n }\n format() {\n if (this.type === \"array\") {\n throw new Error(\"\");\n }\n else if (this.type === \"dynamicArray\") {\n throw new Error(\"\");\n }\n else if (this.type === \"tuple\") {\n return `tuple(${this.value.map((v) => v.format()).join(\",\")})`;\n }\n return this.type;\n }\n defaultValue() {\n return 0;\n }\n minValue() {\n return 0;\n }\n maxValue() {\n return 0;\n }\n isBigInt() {\n return !!this.type.match(/^u?int[0-9]+$/);\n }\n isData() {\n return this.type.startsWith(\"bytes\");\n }\n isString() {\n return this.type === \"string\";\n }\n get tupleName() {\n if (this.type !== \"tuple\") {\n throw TypeError(\"not a tuple\");\n }\n return this.#options;\n }\n // Returns the length of this type as an array\n // - `null` indicates the length is unforced, it could be dynamic\n // - `-1` indicates the length is dynamic\n // - any other value indicates it is a static array and is its length\n get arrayLength() {\n if (this.type !== \"array\") {\n throw TypeError(\"not an array\");\n }\n if (this.#options === true) {\n return -1;\n }\n if (this.#options === false) {\n return this.value.length;\n }\n return null;\n }\n static from(type, value) {\n return new Typed(_gaurd, type, value);\n }\n static uint8(v) {\n return n(v, 8);\n }\n static uint16(v) {\n return n(v, 16);\n }\n static uint24(v) {\n return n(v, 24);\n }\n static uint32(v) {\n return n(v, 32);\n }\n static uint40(v) {\n return n(v, 40);\n }\n static uint48(v) {\n return n(v, 48);\n }\n static uint56(v) {\n return n(v, 56);\n }\n static uint64(v) {\n return n(v, 64);\n }\n static uint72(v) {\n return n(v, 72);\n }\n static uint80(v) {\n return n(v, 80);\n }\n static uint88(v) {\n return n(v, 88);\n }\n static uint96(v) {\n return n(v, 96);\n }\n static uint104(v) {\n return n(v, 104);\n }\n static uint112(v) {\n return n(v, 112);\n }\n static uint120(v) {\n return n(v, 120);\n }\n static uint128(v) {\n return n(v, 128);\n }\n static uint136(v) {\n return n(v, 136);\n }\n static uint144(v) {\n return n(v, 144);\n }\n static uint152(v) {\n return n(v, 152);\n }\n static uint160(v) {\n return n(v, 160);\n }\n static uint168(v) {\n return n(v, 168);\n }\n static uint176(v) {\n return n(v, 176);\n }\n static uint184(v) {\n return n(v, 184);\n }\n static uint192(v) {\n return n(v, 192);\n }\n static uint200(v) {\n return n(v, 200);\n }\n static uint208(v) {\n return n(v, 208);\n }\n static uint216(v) {\n return n(v, 216);\n }\n static uint224(v) {\n return n(v, 224);\n }\n static uint232(v) {\n return n(v, 232);\n }\n static uint240(v) {\n return n(v, 240);\n }\n static uint248(v) {\n return n(v, 248);\n }\n static uint256(v) {\n return n(v, 256);\n }\n static uint(v) {\n return n(v, 256);\n }\n static int8(v) {\n return n(v, -8);\n }\n static int16(v) {\n return n(v, -16);\n }\n static int24(v) {\n return n(v, -24);\n }\n static int32(v) {\n return n(v, -32);\n }\n static int40(v) {\n return n(v, -40);\n }\n static int48(v) {\n return n(v, -48);\n }\n static int56(v) {\n return n(v, -56);\n }\n static int64(v) {\n return n(v, -64);\n }\n static int72(v) {\n return n(v, -72);\n }\n static int80(v) {\n return n(v, -80);\n }\n static int88(v) {\n return n(v, -88);\n }\n static int96(v) {\n return n(v, -96);\n }\n static int104(v) {\n return n(v, -104);\n }\n static int112(v) {\n return n(v, -112);\n }\n static int120(v) {\n return n(v, -120);\n }\n static int128(v) {\n return n(v, -128);\n }\n static int136(v) {\n return n(v, -136);\n }\n static int144(v) {\n return n(v, -144);\n }\n static int152(v) {\n return n(v, -152);\n }\n static int160(v) {\n return n(v, -160);\n }\n static int168(v) {\n return n(v, -168);\n }\n static int176(v) {\n return n(v, -176);\n }\n static int184(v) {\n return n(v, -184);\n }\n static int192(v) {\n return n(v, -192);\n }\n static int200(v) {\n return n(v, -200);\n }\n static int208(v) {\n return n(v, -208);\n }\n static int216(v) {\n return n(v, -216);\n }\n static int224(v) {\n return n(v, -224);\n }\n static int232(v) {\n return n(v, -232);\n }\n static int240(v) {\n return n(v, -240);\n }\n static int248(v) {\n return n(v, -248);\n }\n static int256(v) {\n return n(v, -256);\n }\n static int(v) {\n return n(v, -256);\n }\n static bytes1(v) {\n return b(v, 1);\n }\n static bytes2(v) {\n return b(v, 2);\n }\n static bytes3(v) {\n return b(v, 3);\n }\n static bytes4(v) {\n return b(v, 4);\n }\n static bytes5(v) {\n return b(v, 5);\n }\n static bytes6(v) {\n return b(v, 6);\n }\n static bytes7(v) {\n return b(v, 7);\n }\n static bytes8(v) {\n return b(v, 8);\n }\n static bytes9(v) {\n return b(v, 9);\n }\n static bytes10(v) {\n return b(v, 10);\n }\n static bytes11(v) {\n return b(v, 11);\n }\n static bytes12(v) {\n return b(v, 12);\n }\n static bytes13(v) {\n return b(v, 13);\n }\n static bytes14(v) {\n return b(v, 14);\n }\n static bytes15(v) {\n return b(v, 15);\n }\n static bytes16(v) {\n return b(v, 16);\n }\n static bytes17(v) {\n return b(v, 17);\n }\n static bytes18(v) {\n return b(v, 18);\n }\n static bytes19(v) {\n return b(v, 19);\n }\n static bytes20(v) {\n return b(v, 20);\n }\n static bytes21(v) {\n return b(v, 21);\n }\n static bytes22(v) {\n return b(v, 22);\n }\n static bytes23(v) {\n return b(v, 23);\n }\n static bytes24(v) {\n return b(v, 24);\n }\n static bytes25(v) {\n return b(v, 25);\n }\n static bytes26(v) {\n return b(v, 26);\n }\n static bytes27(v) {\n return b(v, 27);\n }\n static bytes28(v) {\n return b(v, 28);\n }\n static bytes29(v) {\n return b(v, 29);\n }\n static bytes30(v) {\n return b(v, 30);\n }\n static bytes31(v) {\n return b(v, 31);\n }\n static bytes32(v) {\n return b(v, 32);\n }\n static address(v) {\n return new Typed(_gaurd, \"address\", v);\n }\n static bool(v) {\n return new Typed(_gaurd, \"bool\", !!v);\n }\n static bytes(v) {\n return new Typed(_gaurd, \"bytes\", v);\n }\n static string(v) {\n return new Typed(_gaurd, \"string\", v);\n }\n static array(v, dynamic) {\n throw new Error(\"not implemented yet\");\n return new Typed(_gaurd, \"array\", v, dynamic);\n }\n static tuple(v, name) {\n throw new Error(\"not implemented yet\");\n return new Typed(_gaurd, \"tuple\", v, name);\n }\n static overrides(v) {\n return new Typed(_gaurd, \"overrides\", Object.assign({}, v));\n }\n /**\n * Returns true only if %%value%% is a [[Typed]] instance.\n */\n static isTyped(value) {\n return value && value._typedSymbol === _typedSymbol;\n }\n /**\n * If the value is a [[Typed]] instance, validates the underlying value\n * and returns it, otherwise returns value directly.\n *\n * This is useful for functions that with to accept either a [[Typed]]\n * object or values.\n */\n static dereference(value, type) {\n if (Typed.isTyped(value)) {\n if (value.type !== type) {\n throw new Error(`invalid type: expecetd ${type}, got ${value.type}`);\n }\n return value.value;\n }\n return value;\n }\n}\n//# sourceMappingURL=typed.js.map","import { getAddress } from \"../../address/index.js\";\nimport { toBeHex } from \"../../utils/maths.js\";\nimport { Typed } from \"../typed.js\";\nimport { Coder } from \"./abstract-coder.js\";\n/**\n * @_ignore\n */\nexport class AddressCoder extends Coder {\n constructor(localName) {\n super(\"address\", \"address\", localName, false);\n }\n defaultValue() {\n return \"0x0000000000000000000000000000000000000000\";\n }\n encode(writer, _value) {\n let value = Typed.dereference(_value, \"string\");\n try {\n value = getAddress(value);\n }\n catch (error) {\n return this._throwError(error.message, _value);\n }\n return writer.writeValue(value);\n }\n decode(reader) {\n return getAddress(toBeHex(reader.readValue(), 22));\n }\n}\n//# sourceMappingURL=address.js.map","import { Coder } from \"./abstract-coder.js\";\n/**\n * Clones the functionality of an existing Coder, but without a localName\n *\n * @_ignore\n */\nexport class AnonymousCoder extends Coder {\n coder;\n constructor(coder) {\n super(coder.name, coder.type, \"_\", coder.dynamic);\n this.coder = coder;\n }\n defaultValue() {\n return this.coder.defaultValue();\n }\n encode(writer, value) {\n return this.coder.encode(writer, value);\n }\n decode(reader) {\n return this.coder.decode(reader);\n }\n}\n//# sourceMappingURL=anonymous.js.map","import { defineProperties, isError, assert, assertArgument, assertArgumentCount, } from \"../../utils/index.js\";\nimport { Typed } from \"../typed.js\";\nimport { Coder, Result, WordSize, Writer } from \"./abstract-coder.js\";\nimport { AnonymousCoder } from \"./anonymous.js\";\n/**\n * @_ignore\n */\nexport function pack(writer, coders, values) {\n let arrayValues = [];\n if (Array.isArray(values)) {\n arrayValues = values;\n }\n else if (values && typeof values === \"object\") {\n let unique = {};\n arrayValues = coders.map((coder) => {\n const name = coder.localName;\n assert(name, \"cannot encode object for signature with missing names\", \"INVALID_ARGUMENT\", { argument: \"values\", info: { coder }, value: values });\n assert(!unique[name], \"cannot encode object for signature with duplicate names\", \"INVALID_ARGUMENT\", { argument: \"values\", info: { coder }, value: values });\n unique[name] = true;\n return values[name];\n });\n }\n else {\n assertArgument(false, \"invalid tuple value\", \"tuple\", values);\n }\n assertArgument(coders.length === arrayValues.length, \"types/value length mismatch\", \"tuple\", values);\n let staticWriter = new Writer();\n let dynamicWriter = new Writer();\n let updateFuncs = [];\n coders.forEach((coder, index) => {\n let value = arrayValues[index];\n if (coder.dynamic) {\n // Get current dynamic offset (for the future pointer)\n let dynamicOffset = dynamicWriter.length;\n // Encode the dynamic value into the dynamicWriter\n coder.encode(dynamicWriter, value);\n // Prepare to populate the correct offset once we are done\n let updateFunc = staticWriter.writeUpdatableValue();\n updateFuncs.push((baseOffset) => {\n updateFunc(baseOffset + dynamicOffset);\n });\n }\n else {\n coder.encode(staticWriter, value);\n }\n });\n // Backfill all the dynamic offsets, now that we know the static length\n updateFuncs.forEach((func) => {\n func(staticWriter.length);\n });\n let length = writer.appendWriter(staticWriter);\n length += writer.appendWriter(dynamicWriter);\n return length;\n}\n/**\n * @_ignore\n */\nexport function unpack(reader, coders) {\n let values = [];\n let keys = [];\n // A reader anchored to this base\n let baseReader = reader.subReader(0);\n coders.forEach((coder) => {\n let value = null;\n if (coder.dynamic) {\n let offset = reader.readIndex();\n let offsetReader = baseReader.subReader(offset);\n try {\n value = coder.decode(offsetReader);\n }\n catch (error) {\n // Cannot recover from this\n if (isError(error, \"BUFFER_OVERRUN\")) {\n throw error;\n }\n value = error;\n value.baseType = coder.name;\n value.name = coder.localName;\n value.type = coder.type;\n }\n }\n else {\n try {\n value = coder.decode(reader);\n }\n catch (error) {\n // Cannot recover from this\n if (isError(error, \"BUFFER_OVERRUN\")) {\n throw error;\n }\n value = error;\n value.baseType = coder.name;\n value.name = coder.localName;\n value.type = coder.type;\n }\n }\n if (value == undefined) {\n throw new Error(\"investigate\");\n }\n values.push(value);\n keys.push(coder.localName || null);\n });\n return Result.fromItems(values, keys);\n}\n/**\n * @_ignore\n */\nexport class ArrayCoder extends Coder {\n coder;\n length;\n constructor(coder, length, localName) {\n const type = coder.type + \"[\" + (length >= 0 ? length : \"\") + \"]\";\n const dynamic = length === -1 || coder.dynamic;\n super(\"array\", type, localName, dynamic);\n defineProperties(this, { coder, length });\n }\n defaultValue() {\n // Verifies the child coder is valid (even if the array is dynamic or 0-length)\n const defaultChild = this.coder.defaultValue();\n const result = [];\n for (let i = 0; i < this.length; i++) {\n result.push(defaultChild);\n }\n return result;\n }\n encode(writer, _value) {\n const value = Typed.dereference(_value, \"array\");\n if (!Array.isArray(value)) {\n this._throwError(\"expected array value\", value);\n }\n let count = this.length;\n if (count === -1) {\n count = value.length;\n writer.writeValue(value.length);\n }\n assertArgumentCount(value.length, count, \"coder array\" + (this.localName ? \" \" + this.localName : \"\"));\n let coders = [];\n for (let i = 0; i < value.length; i++) {\n coders.push(this.coder);\n }\n return pack(writer, coders, value);\n }\n decode(reader) {\n let count = this.length;\n if (count === -1) {\n count = reader.readIndex();\n // Check that there is *roughly* enough data to ensure\n // stray random data is not being read as a length. Each\n // slot requires at least 32 bytes for their value (or 32\n // bytes as a link to the data). This could use a much\n // tighter bound, but we are erroring on the side of safety.\n assert(count * WordSize <= reader.dataLength, \"insufficient data length\", \"BUFFER_OVERRUN\", {\n buffer: reader.bytes,\n offset: count * WordSize,\n length: reader.dataLength,\n });\n }\n let coders = [];\n for (let i = 0; i < count; i++) {\n coders.push(new AnonymousCoder(this.coder));\n }\n return unpack(reader, coders);\n }\n}\n//# sourceMappingURL=array.js.map","import { Typed } from \"../typed.js\";\nimport { Coder } from \"./abstract-coder.js\";\n/**\n * @_ignore\n */\nexport class BooleanCoder extends Coder {\n constructor(localName) {\n super(\"bool\", \"bool\", localName, false);\n }\n defaultValue() {\n return false;\n }\n encode(writer, _value) {\n const value = Typed.dereference(_value, \"bool\");\n return writer.writeValue(value ? 1 : 0);\n }\n decode(reader) {\n return !!reader.readValue();\n }\n}\n//# sourceMappingURL=boolean.js.map","import { getBytesCopy, hexlify } from \"../../utils/index.js\";\nimport { Coder } from \"./abstract-coder.js\";\n/**\n * @_ignore\n */\nexport class DynamicBytesCoder extends Coder {\n constructor(type, localName) {\n super(type, type, localName, true);\n }\n defaultValue() {\n return \"0x\";\n }\n encode(writer, value) {\n value = getBytesCopy(value);\n let length = writer.writeValue(value.length);\n length += writer.writeBytes(value);\n return length;\n }\n decode(reader) {\n return reader.readBytes(reader.readIndex(), true);\n }\n}\n/**\n * @_ignore\n */\nexport class BytesCoder extends DynamicBytesCoder {\n constructor(localName) {\n super(\"bytes\", localName);\n }\n decode(reader) {\n return hexlify(super.decode(reader));\n }\n}\n//# sourceMappingURL=bytes.js.map","import { defineProperties, getBytesCopy, hexlify } from \"../../utils/index.js\";\nimport { Typed } from \"../typed.js\";\nimport { Coder } from \"./abstract-coder.js\";\n/**\n * @_ignore\n */\nexport class FixedBytesCoder extends Coder {\n size;\n constructor(size, localName) {\n let name = \"bytes\" + String(size);\n super(name, name, localName, false);\n defineProperties(this, { size }, { size: \"number\" });\n }\n defaultValue() {\n return \"0x0000000000000000000000000000000000000000000000000000000000000000\".substring(0, 2 + this.size * 2);\n }\n encode(writer, _value) {\n let data = getBytesCopy(Typed.dereference(_value, this.type));\n if (data.length !== this.size) {\n this._throwError(\"incorrect data length\", _value);\n }\n return writer.writeBytes(data);\n }\n decode(reader) {\n return hexlify(reader.readBytes(this.size));\n }\n}\n//# sourceMappingURL=fixed-bytes.js.map","import { Coder } from \"./abstract-coder.js\";\nconst Empty = new Uint8Array([]);\n/**\n * @_ignore\n */\nexport class NullCoder extends Coder {\n constructor(localName) {\n super(\"null\", \"\", localName, false);\n }\n defaultValue() {\n return null;\n }\n encode(writer, value) {\n if (value != null) {\n this._throwError(\"not null\", value);\n }\n return writer.writeBytes(Empty);\n }\n decode(reader) {\n reader.readBytes(0);\n return null;\n }\n}\n//# sourceMappingURL=null.js.map","import { defineProperties, fromTwos, getBigInt, mask, toTwos, } from \"../../utils/index.js\";\nimport { Typed } from \"../typed.js\";\nimport { Coder, WordSize } from \"./abstract-coder.js\";\nconst BN_0 = BigInt(0);\nconst BN_1 = BigInt(1);\nconst BN_MAX_UINT256 = BigInt(\"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\");\n/**\n * @_ignore\n */\nexport class NumberCoder extends Coder {\n size;\n signed;\n constructor(size, signed, localName) {\n const name = (signed ? \"int\" : \"uint\") + size * 8;\n super(name, name, localName, false);\n defineProperties(this, { size, signed }, { size: \"number\", signed: \"boolean\" });\n }\n defaultValue() {\n return 0;\n }\n encode(writer, _value) {\n let value = getBigInt(Typed.dereference(_value, this.type));\n // Check bounds are safe for encoding\n let maxUintValue = mask(BN_MAX_UINT256, WordSize * 8);\n if (this.signed) {\n let bounds = mask(maxUintValue, this.size * 8 - 1);\n if (value > bounds || value < -(bounds + BN_1)) {\n this._throwError(\"value out-of-bounds\", _value);\n }\n value = toTwos(value, 8 * WordSize);\n }\n else if (value < BN_0 || value > mask(maxUintValue, this.size * 8)) {\n this._throwError(\"value out-of-bounds\", _value);\n }\n return writer.writeValue(value);\n }\n decode(reader) {\n let value = mask(reader.readValue(), this.size * 8);\n if (this.signed) {\n value = fromTwos(value, this.size * 8);\n }\n return value;\n }\n}\n//# sourceMappingURL=number.js.map","import { toUtf8Bytes, toUtf8String } from \"../../utils/utf8.js\";\nimport { Typed } from \"../typed.js\";\nimport { DynamicBytesCoder } from \"./bytes.js\";\n/**\n * @_ignore\n */\nexport class StringCoder extends DynamicBytesCoder {\n constructor(localName) {\n super(\"string\", localName);\n }\n defaultValue() {\n return \"\";\n }\n encode(writer, _value) {\n return super.encode(writer, toUtf8Bytes(Typed.dereference(_value, \"string\")));\n }\n decode(reader) {\n return toUtf8String(super.decode(reader));\n }\n}\n//# sourceMappingURL=string.js.map","import { defineProperties } from \"../../utils/properties.js\";\nimport { Typed } from \"../typed.js\";\nimport { Coder } from \"./abstract-coder.js\";\nimport { pack, unpack } from \"./array.js\";\n/**\n * @_ignore\n */\nexport class TupleCoder extends Coder {\n coders;\n constructor(coders, localName) {\n let dynamic = false;\n const types = [];\n coders.forEach((coder) => {\n if (coder.dynamic) {\n dynamic = true;\n }\n types.push(coder.type);\n });\n const type = \"tuple(\" + types.join(\",\") + \")\";\n super(\"tuple\", type, localName, dynamic);\n defineProperties(this, {\n coders: Object.freeze(coders.slice()),\n });\n }\n defaultValue() {\n const values = [];\n this.coders.forEach((coder) => {\n values.push(coder.defaultValue());\n });\n // We only output named properties for uniquely named coders\n const uniqueNames = this.coders.reduce((accum, coder) => {\n const name = coder.localName;\n if (name) {\n if (!accum[name]) {\n accum[name] = 0;\n }\n accum[name]++;\n }\n return accum;\n }, {});\n // Add named values\n this.coders.forEach((coder, index) => {\n let name = coder.localName;\n if (!name || uniqueNames[name] !== 1) {\n return;\n }\n if (name === \"length\") {\n name = \"_length\";\n }\n if (values[name] != null) {\n return;\n }\n values[name] = values[index];\n });\n return Object.freeze(values);\n }\n encode(writer, _value) {\n const value = Typed.dereference(_value, \"tuple\");\n return pack(writer, this.coders, value);\n }\n decode(reader) {\n return unpack(reader, this.coders);\n }\n}\n//# sourceMappingURL=tuple.js.map","import { keccak256 } from \"../crypto/keccak.js\";\nimport { sha256 } from \"../crypto/sha3.js\";\nimport { toUtf8Bytes } from \"../utils/index.js\";\n/**\n * A simple hashing function which operates on UTF-8 strings to\n * compute an 32-byte identifier.\n *\n *\n * @example:\n * id(\"hello world\")\n * //_result:\n */\nexport function id(value, useKeccak) {\n if (useKeccak) {\n return keccak256(toUtf8Bytes(value));\n }\n return sha256(toUtf8Bytes(value));\n}\n//# sourceMappingURL=id.js.map","/**\n * A constant for the zero address.\n *\n * (**i.e.** ``\"0x0000000000000000000000000000000000000000\"``)\n */\nexport const ZeroAddress = \"0x0000000000000000000000000000000000000000\";\n//# sourceMappingURL=addresses.js.map","/**\n * A constant for the zero hash.\n *\n * (**i.e.** ``\"0x0000000000000000000000000000000000000000000000000000000000000000\"``)\n */\nexport const ZeroHash = \"0x0000000000000000000000000000000000000000000000000000000000000000\";\n//# sourceMappingURL=hashes.js.map","/**\n * A constant for the order N for the secp256k1 curve.\n *\n * (**i.e.** ``0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141n``)\n */\nexport const N = BigInt(\"0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141\");\n/**\n * A constant for the number of ore in a single xcb.\n *\n * (**i.e.** ``1000000000000000000n``)\n */\nexport const OrePerXCB = BigInt(\"1000000000000000000\");\n/**\n * A constant for the maximum value for a ``uint256``.\n *\n * (**i.e.** ``0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffn``)\n */\nexport const MaxUint256 = BigInt(\"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\");\n/**\n * A constant for the minimum value for an ``int256``.\n *\n * (**i.e.** ``-8000000000000000000000000000000000000000000000000000000000000000n``)\n */\nexport const MinInt256 = BigInt(\"0x8000000000000000000000000000000000000000000000000000000000000000\") *\n BigInt(-1);\n/**\n * A constant for the maximum value for an ``int256``.\n *\n * (**i.e.** ``0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffn``)\n */\nexport const MaxInt256 = BigInt(\"0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\");\nexport const NegativeOne = /*#__PURE__*/ BigInt(-1);\nexport const Zero = /*#__PURE__*/ BigInt(0);\nexport const One = /*#__PURE__*/ BigInt(1);\nexport const Two = /*#__PURE__*/ BigInt(2);\n//# sourceMappingURL=numbers.js.map","// NFKC (composed) // (decomposed)\n/**\n * A constant for the core symbol (normalized using NFKC).\n *\n * (**i.e.** ``\"\\\\u039e\"``)\n */\nexport const CoreSymbol = \"\\u039e\"; // \"\\uD835\\uDF63\";\n/**\n * A constant for the [[link-eip-191]] personal message prefix.\n *\n * (**i.e.** ``\"\\\\x19Core Signed Message:\\\\n\"``)\n */\nexport const MessagePrefix = \"\\x19Core Signed Message:\\n\";\n//# sourceMappingURL=strings.js.map","import { getAddress } from \"../address/index.js\";\nimport { assertArgument, isHexString } from \"../utils/index.js\";\nfunction accessSetify(addr, storageKeys) {\n return {\n address: getAddress(addr),\n storageKeys: storageKeys.map((storageKey, index) => {\n assertArgument(isHexString(storageKey, 32), \"invalid slot\", `storageKeys[${index}]`, storageKey);\n return storageKey.toLowerCase();\n }),\n };\n}\n/**\n * Returns a [[AccessList]] from any corebcsupported access-list structure.\n */\nexport function accessListify(value) {\n if (Array.isArray(value)) {\n return value.map((set, index) => {\n if (Array.isArray(set)) {\n assertArgument(set.length === 2, \"invalid slot set\", `value[${index}]`, set);\n return accessSetify(set[0], set[1]);\n }\n assertArgument(set != null && typeof set === \"object\", \"invalid address-slot set\", \"value\", value);\n return accessSetify(set.address, set.storageKeys);\n });\n }\n assertArgument(value != null && typeof value === \"object\", \"invalid access list\", \"value\", value);\n const result = Object.keys(value).map((addr) => {\n const storageKeys = value[addr].reduce((accum, storageKey) => {\n accum[storageKey] = true;\n return accum;\n }, {});\n return accessSetify(addr, Object.keys(storageKeys).sort());\n });\n result.sort((a, b) => a.address.localeCompare(b.address));\n return result;\n}\n//# sourceMappingURL=accesslist.js.map","import { getAddress } from \"../address/index.js\";\nimport { sha256, SigningKey } from \"../crypto/index.js\";\nimport { getBytes, getBigInt, getNumber, hexlify, assert, assertArgument, } from \"../utils/index.js\";\nimport { recoverAddress } from \"./address.js\";\nimport { checkProperties } from \"../utils/properties.js\";\nimport { arrayify, stripZeros } from \"../utils/data.js\";\nimport { Logger } from \"../logger/logger.js\";\nimport * as RLP from \"../crypto/rlp.js\";\nimport { BigNumber } from \"../bigNumber/bigNumber.js\";\nimport { networkIdToPrefix } from \"../address/index.js\";\nconst logger = new Logger(\"transaction/0.0.1\");\nconst BN_0 = BigInt(0);\nfunction handleAddress(value) {\n if (value === \"0x\") {\n return null;\n }\n return getAddress(value);\n}\nfunction parse(data) {\n const handleNumber = (value) => {\n // @ts-ignore\n if (value === \"0x\") {\n return BigNumber.from(0);\n }\n return BigNumber.from(value);\n };\n const transaction = RLP.decode(data);\n if (transaction.length !== 7 && transaction.length !== 8) {\n logger.throwArgumentError(\"invalid raw transaction\", \"data\", data);\n }\n const isSigned = transaction.length === 8;\n const tx = {\n nonce: Number(handleNumber(transaction[0])),\n energyPrice: handleNumber(transaction[1]).toBigInt(),\n energyLimit: handleNumber(transaction[2]).toBigInt(),\n networkId: handleNumber(transaction[isSigned ? 3 : 6]).toBigInt(),\n to: handleAddress(transaction[isSigned ? 4 : 3]),\n value: handleNumber(transaction[isSigned ? 5 : 4]).toBigInt(),\n data: transaction[isSigned ? 6 : 5],\n };\n if (transaction.length === 8) {\n const prefix = networkIdToPrefix(Number(tx.networkId));\n const digest = sha256(serialize(tx));\n tx.hash = sha256(serialize(tx, transaction[7]));\n tx.from = recoverAddress(digest, transaction[7], prefix);\n tx.signature = transaction[7];\n }\n return tx;\n}\nconst unsignedTransactionFields = [\n { name: \"nonce\", maxLength: 32, numeric: true },\n { name: \"energyPrice\", maxLength: 32, numeric: true },\n { name: \"energyLimit\", maxLength: 32, numeric: true },\n { name: \"to\", length: 22 },\n { name: \"value\", maxLength: 32, numeric: true },\n { name: \"data\" },\n { name: \"networkId\", maxLength: 32, numeric: true },\n];\nconst transactionFields = [\n { name: \"nonce\", maxLength: 32, numeric: true },\n { name: \"energyPrice\", maxLength: 32, numeric: true },\n { name: \"energyLimit\", maxLength: 32, numeric: true },\n { name: \"networkId\", maxLength: 32, numeric: true },\n { name: \"to\", length: 22 },\n { name: \"value\", maxLength: 32, numeric: true },\n { name: \"data\" },\n];\nconst allowedTransactionKeys = {\n networkId: true,\n data: true,\n energyLimit: true,\n energyPrice: true,\n nonce: true,\n to: true,\n value: true,\n};\nfunction serialize(transaction, signature) {\n checkProperties(transaction, allowedTransactionKeys);\n const raw = [];\n (!!signature ? transactionFields : unsignedTransactionFields).forEach(function ({ numeric, maxLength, name, length }) {\n let value = transaction[name] || [];\n const options = {};\n if (numeric) {\n options.hexPad = \"left\";\n }\n const tmpHexlified = hexlify(value, options);\n value = arrayify(tmpHexlified);\n // Fixed-width field\n if (length && value.length !== length && value.length > 0) {\n logger.throwArgumentError(\"invalid length for \" + name, \"transaction:\" + name, value);\n }\n // Variable-width (with a maximum)\n if (maxLength) {\n value = stripZeros(value);\n if (value.length > maxLength) {\n logger.throwArgumentError(\"invalid length for \" + name, \"transaction:\" + name, value);\n }\n }\n const hexlified = hexlify(value);\n raw.push(hexlified);\n });\n if (!!signature) {\n raw.push(hexlify(signature));\n }\n const finalValue = RLP.encode(raw);\n return finalValue;\n}\n/**\n * A **Transaction** describes an operation to be executed on\n * Core by an Externally Owned Account (EOA). It includes\n * who (the [[to]] address), what (the [[data]]) and how much (the\n * [[value]] in corebc) the operation should entail.\n *\n * @example:\n * tx = new Transaction()\n * //_result:\n *\n * tx.data = \"0x1234\";\n * //_result:\n */\nexport class Transaction {\n #to;\n #data;\n #nonce;\n #energyLimit;\n #energyPrice;\n #value;\n #networkId;\n #sig;\n /**\n * The ``to`` address for the transaction or ``null`` if the\n * transaction is an ``init`` transaction.\n */\n get to() {\n return this.#to;\n }\n set to(value) {\n this.#to = value == null ? null : getAddress(value);\n }\n /**\n * The transaction nonce.\n */\n get nonce() {\n return this.#nonce;\n }\n set nonce(value) {\n this.#nonce = getNumber(value, \"value\");\n }\n /**\n * The energy limit.\n */\n get energyLimit() {\n return this.#energyLimit;\n }\n set energyLimit(value) {\n this.#energyLimit = getBigInt(value);\n }\n /**\n * The energy price.\n *\n * On legacy networks this defines the fee that will be paid. On\n * EIP-1559 networks, this should be ``null``.\n */\n get energyPrice() {\n const value = this.#energyPrice;\n if (value == null) {\n return BN_0;\n }\n return value;\n }\n set energyPrice(value) {\n this.#energyPrice = value == null ? null : getBigInt(value, \"energyPrice\");\n }\n /**\n * The transaction data. For ``init`` transactions this is the\n * deployment code.\n */\n get data() {\n return this.#data;\n }\n set data(value) {\n this.#data = hexlify(value);\n }\n /**\n * The amount of xcb (in ore) to send in this transactions.\n */\n get value() {\n return this.#value;\n }\n set value(value) {\n this.#value = getBigInt(value, \"value\");\n }\n /**\n * The chain ID this transaction is valid on.\n */\n get networkId() {\n return this.#networkId;\n }\n set networkId(value) {\n this.#networkId = getBigInt(value);\n }\n /**\n * If signed, the signature for this transaction.\n */\n get signature() {\n return this.#sig || null;\n }\n set signature(value) {\n this.#sig = value == null ? null : value;\n }\n /**\n * Creates a new Transaction with default values.\n */\n constructor() {\n this.#to = null;\n this.#nonce = 0;\n this.#energyLimit = BigInt(0);\n this.#energyPrice = null;\n this.#data = \"0x\";\n this.#value = BigInt(0);\n this.#networkId = BigInt(0);\n this.#sig = null;\n }\n /**\n * The transaction hash, if signed. Otherwise, ``null``.\n */\n get hash() {\n if (this.signature == null) {\n return null;\n }\n return sha256(this.serialized);\n }\n /**\n * The pre-image hash of this transaction.\n *\n * This is the digest that a [[Signer]] must sign to authorize\n * this transaction.\n */\n get unsignedHash() {\n return sha256(this.unsignedSerialized);\n }\n /**\n * The sending address, if signed. Otherwise, ``null``.\n */\n get from() {\n if (this.signature == null) {\n return null;\n }\n const prefix = networkIdToPrefix(Number(this.#networkId));\n return recoverAddress(this.unsignedHash, this.signature, prefix);\n }\n /**\n * The public key of the sender, if signed. Otherwise, ``null``.\n */\n get fromPublicKey() {\n if (this.signature == null) {\n return null;\n }\n return SigningKey.recoverPublicKey(this.unsignedHash, this.signature);\n }\n /**\n * Returns true if signed.\n *\n * This provides a Type Guard that properties requiring a signed\n * transaction are non-null.\n */\n isSigned() {\n //isSigned(): this is SignedTransaction {\n return this.signature != null;\n }\n /**\n * The serialized transaction.\n *\n * This throws if the transaction is unsigned. For the pre-image,\n * use [[unsignedSerialized]].\n */\n get serialized() {\n assert(this.signature != null, \"cannot serialize unsigned transaction; maybe you meant .unsignedSerialized\", \"UNSUPPORTED_OPERATION\", { operation: \".serialized\" });\n return serialize(this, this.signature);\n }\n /**\n * The transaction pre-image.\n *\n * The hash of this is the digest which needs to be signed to\n * authorize this transaction.\n */\n get unsignedSerialized() {\n return serialize(this);\n }\n /**\n * Create a copy of this transaciton.\n */\n clone() {\n return Transaction.from(this);\n }\n /**\n * Return a JSON-friendly object.\n */\n toJSON() {\n const s = (v) => {\n if (v == null) {\n return null;\n }\n return v.toString();\n };\n return {\n to: this.to,\n data: this.data,\n nonce: this.nonce,\n energyLimit: s(this.energyLimit),\n energyPrice: s(this.energyPrice),\n value: s(this.value),\n networkId: s(this.networkId),\n sig: this.signature ? this.signature : null,\n };\n }\n /**\n * Create a **Transaction** from a serialized transaction or a\n * Transaction-like object.\n */\n static from(tx) {\n if (tx == null) {\n return new Transaction();\n }\n if (typeof tx === \"string\") {\n const payload = getBytes(tx);\n return Transaction.from(parse(payload));\n }\n const result = new Transaction();\n if (tx.to != null) {\n result.to = tx.to;\n }\n if (tx.nonce != null) {\n result.nonce = tx.nonce;\n }\n if (tx.energyLimit != null) {\n result.energyLimit = tx.energyLimit;\n }\n if (tx.energyPrice != null) {\n result.energyPrice = tx.energyPrice;\n }\n if (tx.data != null) {\n result.data = tx.data;\n }\n if (tx.value != null) {\n result.value = tx.value;\n }\n if (tx.networkId != null) {\n result.networkId = tx.networkId;\n }\n if (tx.signature != null) {\n result.signature = tx.signature;\n }\n if (tx.hash != null) {\n assertArgument(result.isSigned(), \"unsigned transaction cannot define hash\", \"tx\", tx);\n assertArgument(result.hash === tx.hash, \"hash mismatch\", \"tx\", tx);\n }\n if (tx.from != null) {\n assertArgument(result.isSigned(), \"unsigned transaction cannot define from\", \"tx\", tx);\n assertArgument(result.from.toLowerCase() === (tx.from || \"\").toLowerCase(), \"from mismatch\", \"tx\", tx);\n }\n return result;\n }\n}\n//# sourceMappingURL=transaction.js.map","import { MessagePrefix } from \"../constants/index.js\";\nimport { recoverAddress } from \"../transaction/index.js\";\nimport { concat, toUtf8Bytes } from \"../utils/index.js\";\nimport { sha256 } from \"../crypto/index.js\";\n/**\n * Computes the [[link-eip-191]] personal-sign message digest to sign.\n *\n *\n * If %%message%% is a string, it is converted to its UTF-8 bytes\n * first. To compute the digest of a [[DataHexString]], it must be converted\n * to [bytes](getBytes).\n *\n * @example:\n * hashMessage(\"Hello World\")\n * //_result:\n *\n * // Hashes the SIX (6) string characters, i.e.\n * // [ \"0\", \"x\", \"4\", \"2\", \"4\", \"3\" ]\n * hashMessage(\"0x4243\")\n * //_result:\n *\n * // Hashes the TWO (2) bytes [ 0x42, 0x43 ]...\n * hashMessage(getBytes(\"0x4243\"))\n * //_result:\n *\n * // ...which is equal to using data\n * hashMessage(new Uint8Array([ 0x42, 0x43 ]))\n * //_result:\n *\n */\nexport function hashMessage(message) {\n if (typeof message === \"string\") {\n message = toUtf8Bytes(message);\n }\n return sha256(concat([\n toUtf8Bytes(MessagePrefix),\n toUtf8Bytes(String(message.length)),\n message,\n ]));\n}\n/**\n * Return the address of the private key that produced\n * the signature %%sig%% during signing for %%message%%.\n */\nexport function verifyMessage(message, sig, prefix) {\n const digest = hashMessage(message);\n return recoverAddress(digest, sig, prefix);\n}\n//# sourceMappingURL=message.js.map","import { getAddress } from \"../address/index.js\";\nimport { sha256 as _sha256 } from \"../crypto/index.js\";\nimport { concat, dataLength, getBytes, hexlify, toBeArray, toTwos, toUtf8Bytes, zeroPadBytes, zeroPadValue, assertArgument, } from \"../utils/index.js\";\nconst regexBytes = new RegExp(\"^bytes([0-9]+)$\");\nconst regexNumber = new RegExp(\"^(u?int)([0-9]*)$\");\nconst regexArray = new RegExp(\"^(.*)\\\\[([0-9]*)\\\\]$\");\nfunction _pack(type, value, isArray) {\n switch (type) {\n case \"address\":\n if (isArray) {\n return getBytes(zeroPadValue(value, 32));\n }\n return getBytes(getAddress(value));\n case \"string\":\n return toUtf8Bytes(value);\n case \"bytes\":\n return getBytes(value);\n case \"bool\":\n value = !!value ? \"0x01\" : \"0x00\";\n if (isArray) {\n return getBytes(zeroPadValue(value, 32));\n }\n return getBytes(value);\n }\n let match = type.match(regexNumber);\n if (match) {\n let signed = match[1] === \"int\";\n let size = parseInt(match[2] || \"256\");\n assertArgument((!match[2] || match[2] === String(size)) &&\n size % 8 === 0 &&\n size !== 0 &&\n size <= 256, \"invalid number type\", \"type\", type);\n if (isArray) {\n size = 256;\n }\n if (signed) {\n value = toTwos(value, size);\n }\n return getBytes(zeroPadValue(toBeArray(value), size / 8));\n }\n match = type.match(regexBytes);\n if (match) {\n const size = parseInt(match[1]);\n assertArgument(String(size) === match[1] && size !== 0 && size <= 32, \"invalid bytes type\", \"type\", type);\n assertArgument(dataLength(value) === size, `invalid value for ${type}`, \"value\", value);\n if (isArray) {\n return getBytes(zeroPadBytes(value, 32));\n }\n return value;\n }\n match = type.match(regexArray);\n if (match && Array.isArray(value)) {\n const baseType = match[1];\n const count = parseInt(match[2] || String(value.length));\n assertArgument(count === value.length, `invalid array length for ${type}`, \"value\", value);\n const result = [];\n value.forEach(function (value) {\n result.push(_pack(baseType, value, true));\n });\n return getBytes(concat(result));\n }\n assertArgument(false, \"invalid type\", \"type\", type);\n}\n// @TODO: Array Enum\n/**\n * Computes the [[link-solc-packed]] representation of %%values%%\n * respectively to their %%types%%.\n *\n * @example:\n * addr = \"0x8ba1f109551bd432803012645ac136ddd64dba72\"\n * solidityPacked([ \"address\", \"uint\" ], [ addr, 45 ]);\n * //_result:\n */\nexport function solidityPacked(types, values) {\n assertArgument(types.length === values.length, \"wrong number of values; expected ${ types.length }\", \"values\", values);\n const tight = [];\n types.forEach(function (type, index) {\n tight.push(_pack(type, values[index]));\n });\n return hexlify(concat(tight));\n}\n/**\n * Computes the [[link-solc-packed]] [[sha256]] hash of %%values%%\n * respectively to their %%types%%.\n *\n * @example:\n * addr = \"0x8ba1f109551bd432803012645ac136ddd64dba72\"\n * solidityPackedSha256([ \"address\", \"uint\" ], [ addr, 45 ]);\n * //_result:\n */\nexport function solidityPackedSha256(types, values) {\n return _sha256(solidityPacked(types, values));\n}\n//# sourceMappingURL=solidity.js.map","import { getAddress } from \"../address/index.js\";\nimport { recoverAddress } from \"../transaction/index.js\";\nimport { concat, defineProperties, getBigInt, getBytes, hexlify, isHexString, mask, toBeHex, toQuantity, toTwos, zeroPadValue, assertArgument, } from \"../utils/index.js\";\nimport { id } from \"./id.js\";\nimport { sha256 } from \"../crypto/index.js\";\nconst padding = new Uint8Array(32);\npadding.fill(0);\nconst BN__1 = BigInt(-1);\nconst BN_0 = BigInt(0);\nconst BN_1 = BigInt(1);\nconst BN_MAX_UINT256 = BigInt(\"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\");\nfunction hexPadRight(value) {\n const bytes = getBytes(value);\n const padOffset = bytes.length % 32;\n if (padOffset) {\n return concat([bytes, padding.slice(padOffset)]);\n }\n return hexlify(bytes);\n}\nconst hexTrue = toBeHex(BN_1, 32);\nconst hexFalse = toBeHex(BN_0, 32);\nconst domainFieldTypes = {\n name: \"string\",\n version: \"string\",\n networkId: \"uint256\",\n verifyingContract: \"address\",\n salt: \"bytes32\",\n};\nconst domainFieldNames = [\n \"name\",\n \"version\",\n \"networkId\",\n \"verifyingContract\",\n \"salt\",\n];\nfunction checkString(key) {\n return function (value) {\n assertArgument(typeof value === \"string\", `invalid domain value for ${JSON.stringify(key)}`, `domain.${key}`, value);\n return value;\n };\n}\nconst domainChecks = {\n name: checkString(\"name\"),\n version: checkString(\"version\"),\n networkId: function (_value) {\n const value = getBigInt(_value, \"domain.networkId\");\n assertArgument(value >= 0, \"invalid chain ID\", \"domain.networkId\", _value);\n if (Number.isSafeInteger(value)) {\n return Number(value);\n }\n return toQuantity(value);\n },\n verifyingContract: function (value) {\n try {\n return getAddress(value).toLowerCase();\n }\n catch (error) { }\n assertArgument(false, `invalid domain value \"verifyingContract\"`, \"domain.verifyingContract\", value);\n },\n salt: function (value) {\n const bytes = getBytes(value, \"domain.salt\");\n assertArgument(bytes.length === 32, `invalid domain value \"salt\"`, \"domain.salt\", value);\n return hexlify(bytes);\n },\n};\nfunction getBaseEncoder(type) {\n // intXX and uintXX\n {\n const match = type.match(/^(u?)int(\\d*)$/);\n if (match) {\n const signed = match[1] === \"\";\n const width = parseInt(match[2] || \"256\");\n assertArgument(width % 8 === 0 &&\n width !== 0 &&\n width <= 256 &&\n (match[2] == null || match[2] === String(width)), \"invalid numeric width\", \"type\", type);\n const boundsUpper = mask(BN_MAX_UINT256, signed ? width - 1 : width);\n const boundsLower = signed ? (boundsUpper + BN_1) * BN__1 : BN_0;\n return function (_value) {\n const value = getBigInt(_value, \"value\");\n assertArgument(value >= boundsLower && value <= boundsUpper, `value out-of-bounds for ${type}`, \"value\", value);\n return toBeHex(signed ? toTwos(value, 256) : value, 32);\n };\n }\n }\n // bytesXX\n {\n const match = type.match(/^bytes(\\d+)$/);\n if (match) {\n const width = parseInt(match[1]);\n assertArgument(width !== 0 && width <= 32 && match[1] === String(width), \"invalid bytes width\", \"type\", type);\n return function (value) {\n const bytes = getBytes(value);\n assertArgument(bytes.length === width, `invalid length for ${type}`, \"value\", value);\n return hexPadRight(value);\n };\n }\n }\n switch (type) {\n case \"address\":\n return function (value) {\n return zeroPadValue(getAddress(value), 32);\n };\n case \"bool\":\n return function (value) {\n return !value ? hexFalse : hexTrue;\n };\n case \"bytes\":\n return function (value) {\n return sha256(value);\n };\n case \"string\":\n return function (value) {\n return id(value);\n };\n }\n return null;\n}\nfunction encodeType(name, fields) {\n return `${name}(${fields\n .map(({ name, type }) => type + \" \" + name)\n .join(\",\")})`;\n}\nexport class TypedDataEncoder {\n primaryType;\n #types;\n get types() {\n return JSON.parse(this.#types);\n }\n #fullTypes;\n #encoderCache;\n constructor(types) {\n this.#types = JSON.stringify(types);\n this.#fullTypes = new Map();\n this.#encoderCache = new Map();\n // Link struct types to their direct child structs\n const links = new Map();\n // Link structs to structs which contain them as a child\n const parents = new Map();\n // Link all subtypes within a given struct\n const subtypes = new Map();\n Object.keys(types).forEach((type) => {\n links.set(type, new Set());\n parents.set(type, []);\n subtypes.set(type, new Set());\n });\n for (const name in types) {\n const uniqueNames = new Set();\n for (const field of types[name]) {\n // Check each field has a unique name\n assertArgument(!uniqueNames.has(field.name), `duplicate variable name ${JSON.stringify(field.name)} in ${JSON.stringify(name)}`, \"types\", types);\n uniqueNames.add(field.name);\n // Get the base type (drop any array specifiers)\n const baseType = field.type.match(/^([^\\x5b]*)(\\x5b|$)/)[1] || null;\n assertArgument(baseType !== name, `circular type reference to ${JSON.stringify(baseType)}`, \"types\", types);\n // Is this a base encoding type?\n const encoder = getBaseEncoder(baseType);\n if (encoder) {\n continue;\n }\n assertArgument(parents.has(baseType), `unknown type ${JSON.stringify(baseType)}`, \"types\", types);\n // Add linkage\n parents.get(baseType).push(name);\n links.get(name).add(baseType);\n }\n }\n // Deduce the primary type\n const primaryTypes = Array.from(parents.keys()).filter((n) => parents.get(n).length === 0);\n assertArgument(primaryTypes.length !== 0, \"missing primary type\", \"types\", types);\n assertArgument(primaryTypes.length === 1, `ambiguous primary types or unused types: ${primaryTypes\n .map((t) => JSON.stringify(t))\n .join(\", \")}`, \"types\", types);\n defineProperties(this, { primaryType: primaryTypes[0] });\n // Check for circular type references\n function checkCircular(type, found) {\n assertArgument(!found.has(type), `circular type reference to ${JSON.stringify(type)}`, \"types\", types);\n found.add(type);\n for (const child of links.get(type)) {\n if (!parents.has(child)) {\n continue;\n }\n // Recursively check children\n checkCircular(child, found);\n // Mark all ancestors as having this decendant\n for (const subtype of found) {\n subtypes.get(subtype).add(child);\n }\n }\n found.delete(type);\n }\n checkCircular(this.primaryType, new Set());\n // Compute each fully describe type\n for (const [name, set] of subtypes) {\n const st = Array.from(set);\n st.sort();\n this.#fullTypes.set(name, encodeType(name, types[name]) +\n st.map((t) => encodeType(t, types[t])).join(\"\"));\n }\n }\n getEncoder(type) {\n let encoder = this.#encoderCache.get(type);\n if (!encoder) {\n encoder = this.#getEncoder(type);\n this.#encoderCache.set(type, encoder);\n }\n return encoder;\n }\n #getEncoder(type) {\n // Basic encoder type (address, bool, uint256, etc)\n {\n const encoder = getBaseEncoder(type);\n if (encoder) {\n return encoder;\n }\n }\n // Array\n const match = type.match(/^(.*)(\\x5b(\\d*)\\x5d)$/);\n if (match) {\n const subtype = match[1];\n const subEncoder = this.getEncoder(subtype);\n return (value) => {\n assertArgument(!match[3] || parseInt(match[3]) === value.length, `array length mismatch; expected length ${parseInt(match[3])}`, \"value\", value);\n let result = value.map(subEncoder);\n if (this.#fullTypes.has(subtype)) {\n result = result.map(sha256);\n }\n return sha256(concat(result));\n };\n }\n // Struct\n const fields = this.types[type];\n if (fields) {\n const encodedType = id(this.#fullTypes.get(type));\n return (value) => {\n const values = fields.map(({ name, type }) => {\n const result = this.getEncoder(type)(value[name]);\n if (this.#fullTypes.has(type)) {\n return sha256(result);\n }\n return result;\n });\n values.unshift(encodedType);\n return concat(values);\n };\n }\n assertArgument(false, `unknown type: ${type}`, \"type\", type);\n }\n encodeType(name) {\n const result = this.#fullTypes.get(name);\n assertArgument(result, `unknown type: ${JSON.stringify(name)}`, \"name\", name);\n return result;\n }\n encodeData(type, value) {\n return this.getEncoder(type)(value);\n }\n hashStruct(name, value) {\n return sha256(this.encodeData(name, value));\n }\n encode(value) {\n return this.encodeData(this.primaryType, value);\n }\n hash(value) {\n return this.hashStruct(this.primaryType, value);\n }\n _visit(type, value, callback) {\n // Basic encoder type (address, bool, uint256, etc)\n {\n const encoder = getBaseEncoder(type);\n if (encoder) {\n return callback(type, value);\n }\n }\n // Array\n const match = type.match(/^(.*)(\\x5b(\\d*)\\x5d)$/);\n if (match) {\n assertArgument(!match[3] || parseInt(match[3]) === value.length, `array length mismatch; expected length ${parseInt(match[3])}`, \"value\", value);\n return value.map((v) => this._visit(match[1], v, callback));\n }\n // Struct\n const fields = this.types[type];\n if (fields) {\n return fields.reduce((accum, { name, type }) => {\n accum[name] = this._visit(type, value[name], callback);\n return accum;\n }, {});\n }\n assertArgument(false, `unknown type: ${type}`, \"type\", type);\n }\n visit(value, callback) {\n return this._visit(this.primaryType, value, callback);\n }\n static from(types) {\n return new TypedDataEncoder(types);\n }\n static getPrimaryType(types) {\n return TypedDataEncoder.from(types).primaryType;\n }\n static hashStruct(name, types, value) {\n return TypedDataEncoder.from(types).hashStruct(name, value);\n }\n static hashDomain(domain) {\n const domainFields = [];\n for (const name in domain) {\n if (domain[name] == null) {\n continue;\n }\n const type = domainFieldTypes[name];\n assertArgument(type, `invalid typed-data domain key: ${JSON.stringify(name)}`, \"domain\", domain);\n domainFields.push({ name, type });\n }\n domainFields.sort((a, b) => {\n return (domainFieldNames.indexOf(a.name) - domainFieldNames.indexOf(b.name));\n });\n return TypedDataEncoder.hashStruct(\"EIP712Domain\", { EIP712Domain: domainFields }, domain);\n }\n static encode(domain, types, value) {\n return concat([\n \"0x1901\",\n TypedDataEncoder.hashDomain(domain),\n TypedDataEncoder.from(types).hash(value),\n ]);\n }\n static hash(domain, types, value) {\n return sha256(TypedDataEncoder.encode(domain, types, value));\n }\n // Replaces all address types with ENS names with their looked up address\n static async resolveNames(domain, types, value, resolveName) {\n // Make a copy to isolate it from the object passed in\n domain = Object.assign({}, domain);\n // Allow passing null to ignore value\n for (const key in domain) {\n if (domain[key] == null) {\n delete domain[key];\n }\n }\n // Look up all ENS names\n const ensCache = {};\n // Do we need to look up the domain's verifyingContract?\n if (domain.verifyingContract &&\n !isHexString(domain.verifyingContract, 20)) {\n ensCache[domain.verifyingContract] = \"0x\";\n }\n // We are going to use the encoder to visit all the base values\n const encoder = TypedDataEncoder.from(types);\n // Get a list of all the addresses\n encoder.visit(value, (type, value) => {\n if (type === \"address\" && !isHexString(value, 20)) {\n ensCache[value] = \"0x\";\n }\n return value;\n });\n // Lookup each name\n for (const name in ensCache) {\n ensCache[name] = await resolveName(name);\n }\n // Replace the domain verifyingContract if needed\n if (domain.verifyingContract && ensCache[domain.verifyingContract]) {\n domain.verifyingContract = ensCache[domain.verifyingContract];\n }\n // Replace all ENS names with their address\n value = encoder.visit(value, (type, value) => {\n if (type === \"address\" && ensCache[value]) {\n return ensCache[value];\n }\n return value;\n });\n return { domain, value };\n }\n static getPayload(domain, types, value) {\n // Validate the domain fields\n TypedDataEncoder.hashDomain(domain);\n // Derive the EIP712Domain Struct reference type\n const domainValues = {};\n const domainTypes = [];\n domainFieldNames.forEach((name) => {\n const value = domain[name];\n if (value == null) {\n return;\n }\n domainValues[name] = domainChecks[name](value);\n domainTypes.push({ name, type: domainFieldTypes[name] });\n });\n const encoder = TypedDataEncoder.from(types);\n const typesWithDomain = Object.assign({}, types);\n assertArgument(typesWithDomain.EIP712Domain == null, \"types must not contain EIP712Domain type\", \"types.EIP712Domain\", types);\n typesWithDomain.EIP712Domain = domainTypes;\n // Validate the data structures and types\n encoder.encode(value);\n return {\n types: typesWithDomain,\n domain: domainValues,\n primaryType: encoder.primaryType,\n message: encoder.visit(value, (type, value) => {\n // bytes\n if (type.match(/^bytes(\\d*)/)) {\n return hexlify(getBytes(value));\n }\n // uint or int\n if (type.match(/^u?int/)) {\n return getBigInt(value).toString();\n }\n switch (type) {\n case \"address\":\n return value.toLowerCase();\n case \"bool\":\n return !!value;\n case \"string\":\n assertArgument(typeof value === \"string\", \"invalid string\", \"value\", value);\n return value;\n }\n assertArgument(false, \"unsupported type\", \"type\", type);\n }),\n };\n }\n}\n/**\n * Compute the address used to sign the typed data for the %%signature%%.\n */\nexport function verifyTypedData(domain, types, value, signature, prefix) {\n return recoverAddress(TypedDataEncoder.hash(domain, types, value), signature, prefix);\n}\n//# sourceMappingURL=typed-data.js.map","/**\n * About frgaments...\n *\n * @_subsection api/abi/abi-coder:Fragments [about-fragments]\n */\nvar _a;\nimport { defineProperties, getBigInt, getNumber, assert, assertPrivate, assertArgument, } from \"../utils/index.js\";\nimport { id } from \"../hash/index.js\";\n// [ \"a\", \"b\" ] => { \"a\": 1, \"b\": 1 }\nfunction setify(items) {\n const result = new Set();\n items.forEach((k) => result.add(k));\n return Object.freeze(result);\n}\n// Visibility Keywords\nconst _kwVisib = \"constant external internal payable private public pure view\";\nconst KwVisib = setify(_kwVisib.split(\" \"));\nconst _kwTypes = \"constructor error event fallback function receive struct\";\nconst KwTypes = setify(_kwTypes.split(\" \"));\nconst _kwModifiers = \"calldata memory storage payable indexed\";\nconst KwModifiers = setify(_kwModifiers.split(\" \"));\nconst _kwOther = \"tuple returns\";\n// All Keywords\nconst _keywords = [_kwTypes, _kwModifiers, _kwOther, _kwVisib].join(\" \");\nconst Keywords = setify(_keywords.split(\" \"));\n// Single character tokens\nconst SimpleTokens = {\n \"(\": \"OPEN_PAREN\",\n \")\": \"CLOSE_PAREN\",\n \"[\": \"OPEN_BRACKET\",\n \"]\": \"CLOSE_BRACKET\",\n \",\": \"COMMA\",\n \"@\": \"AT\",\n};\n// Parser regexes to consume the next token\nconst regexWhitespacePrefix = new RegExp(\"^(\\\\s*)\");\nconst regexNumberPrefix = new RegExp(\"^([0-9]+)\");\nconst regexIdPrefix = new RegExp(\"^([a-zA-Z$_][a-zA-Z0-9$_]*)\");\n// Parser regexs to check validity\nconst regexId = new RegExp(\"^([a-zA-Z$_][a-zA-Z0-9$_]*)$\");\nconst regexType = new RegExp(\"^(address|bool|bytes([0-9]*)|string|u?int([0-9]*))$\");\nclass TokenString {\n #offset;\n #tokens;\n get offset() {\n return this.#offset;\n }\n get length() {\n return this.#tokens.length - this.#offset;\n }\n constructor(tokens) {\n this.#offset = 0;\n this.#tokens = tokens.slice();\n }\n clone() {\n return new _a(this.#tokens);\n }\n reset() {\n this.#offset = 0;\n }\n #subTokenString(from = 0, to = 0) {\n return new _a(this.#tokens.slice(from, to).map((t) => {\n return Object.freeze(Object.assign({}, t, {\n match: t.match - from,\n linkBack: t.linkBack - from,\n linkNext: t.linkNext - from,\n }));\n }));\n }\n // Pops and returns the value of the next token, if it is a keyword in allowed; throws if out of tokens\n popKeyword(allowed) {\n const top = this.peek();\n if (top.type !== \"KEYWORD\" || !allowed.has(top.text)) {\n throw new Error(`expected keyword ${top.text}`);\n }\n return this.pop().text;\n }\n // Pops and returns the value of the next token if it is `type`; throws if out of tokens\n popType(type) {\n if (this.peek().type !== type) {\n throw new Error(`expected ${type}; got ${JSON.stringify(this.peek())}`);\n }\n return this.pop().text;\n }\n // Pops and returns a \"(\" TOKENS \")\"\n popParen() {\n const top = this.peek();\n if (top.type !== \"OPEN_PAREN\") {\n throw new Error(\"bad start\");\n }\n const result = this.#subTokenString(this.#offset + 1, top.match + 1);\n this.#offset = top.match + 1;\n return result;\n }\n // Pops and returns the items within \"(\" ITEM1 \",\" ITEM2 \",\" ... \")\"\n popParams() {\n const top = this.peek();\n if (top.type !== \"OPEN_PAREN\") {\n throw new Error(\"bad start\");\n }\n const result = [];\n while (this.#offset < top.match - 1) {\n const link = this.peek().linkNext;\n result.push(this.#subTokenString(this.#offset + 1, link));\n this.#offset = link;\n }\n this.#offset = top.match + 1;\n return result;\n }\n // Returns the top Token, throwing if out of tokens\n peek() {\n if (this.#offset >= this.#tokens.length) {\n throw new Error(\"out-of-bounds\");\n }\n return this.#tokens[this.#offset];\n }\n // Returns the next value, if it is a keyword in `allowed`\n peekKeyword(allowed) {\n const top = this.peekType(\"KEYWORD\");\n return top != null && allowed.has(top) ? top : null;\n }\n // Returns the value of the next token if it is `type`\n peekType(type) {\n if (this.length === 0) {\n return null;\n }\n const top = this.peek();\n return top.type === type ? top.text : null;\n }\n // Returns the next token; throws if out of tokens\n pop() {\n const result = this.peek();\n this.#offset++;\n return result;\n }\n toString() {\n const tokens = [];\n for (let i = this.#offset; i < this.#tokens.length; i++) {\n const token = this.#tokens[i];\n tokens.push(`${token.type}:${token.text}`);\n }\n return ``;\n }\n}\n_a = TokenString;\nfunction lex(text) {\n const tokens = [];\n const throwError = (message) => {\n const token = offset < text.length ? JSON.stringify(text[offset]) : \"$EOI\";\n throw new Error(`invalid token ${token} at ${offset}: ${message}`);\n };\n let brackets = [];\n let commas = [];\n let offset = 0;\n while (offset < text.length) {\n // Strip off any leading whitespace\n let cur = text.substring(offset);\n let match = cur.match(regexWhitespacePrefix);\n if (match) {\n offset += match[1].length;\n cur = text.substring(offset);\n }\n const token = {\n depth: brackets.length,\n linkBack: -1,\n linkNext: -1,\n match: -1,\n type: \"\",\n text: \"\",\n offset,\n value: -1,\n };\n tokens.push(token);\n let type = SimpleTokens[cur[0]] || \"\";\n if (type) {\n token.type = type;\n token.text = cur[0];\n offset++;\n if (type === \"OPEN_PAREN\") {\n brackets.push(tokens.length - 1);\n commas.push(tokens.length - 1);\n }\n else if (type == \"CLOSE_PAREN\") {\n if (brackets.length === 0) {\n throwError(\"no matching open bracket\");\n }\n token.match = brackets.pop();\n tokens[token.match].match = tokens.length - 1;\n token.depth--;\n token.linkBack = commas.pop();\n tokens[token.linkBack].linkNext = tokens.length - 1;\n }\n else if (type === \"COMMA\") {\n token.linkBack = commas.pop();\n tokens[token.linkBack].linkNext = tokens.length - 1;\n commas.push(tokens.length - 1);\n }\n else if (type === \"OPEN_BRACKET\") {\n token.type = \"BRACKET\";\n }\n else if (type === \"CLOSE_BRACKET\") {\n // Remove the CLOSE_BRACKET\n let suffix = tokens.pop().text;\n if (tokens.length > 0 && tokens[tokens.length - 1].type === \"NUMBER\") {\n const value = tokens.pop().text;\n suffix = value + suffix;\n tokens[tokens.length - 1].value =\n getNumber(value);\n }\n if (tokens.length === 0 ||\n tokens[tokens.length - 1].type !== \"BRACKET\") {\n throw new Error(\"missing opening bracket\");\n }\n tokens[tokens.length - 1].text += suffix;\n }\n continue;\n }\n match = cur.match(regexIdPrefix);\n if (match) {\n token.text = match[1];\n offset += token.text.length;\n if (Keywords.has(token.text)) {\n token.type = \"KEYWORD\";\n continue;\n }\n if (token.text.match(regexType)) {\n token.type = \"TYPE\";\n continue;\n }\n token.type = \"ID\";\n continue;\n }\n match = cur.match(regexNumberPrefix);\n if (match) {\n token.text = match[1];\n token.type = \"NUMBER\";\n offset += token.text.length;\n continue;\n }\n throw new Error(`unexpected token ${JSON.stringify(cur[0])} at position ${offset}`);\n }\n return new TokenString(tokens.map((t) => Object.freeze(t)));\n}\n// Check only one of `allowed` is in `set`\nfunction allowSingle(set, allowed) {\n let included = [];\n for (const key in allowed.keys()) {\n if (set.has(key)) {\n included.push(key);\n }\n }\n if (included.length > 1) {\n throw new Error(`conflicting types: ${included.join(\", \")}`);\n }\n}\n// Functions to process a Solidity Signature TokenString from left-to-right for...\n// ...the name with an optional type, returning the name\nfunction consumeName(type, tokens) {\n if (tokens.peekKeyword(KwTypes)) {\n const keyword = tokens.pop().text;\n if (keyword !== type) {\n throw new Error(`expected ${type}, got ${keyword}`);\n }\n }\n return tokens.popType(\"ID\");\n}\n// ...all keywords matching allowed, returning the keywords\nfunction consumeKeywords(tokens, allowed) {\n const keywords = new Set();\n while (true) {\n const keyword = tokens.peekType(\"KEYWORD\");\n if (keyword == null || (allowed && !allowed.has(keyword))) {\n break;\n }\n tokens.pop();\n if (keywords.has(keyword)) {\n throw new Error(`duplicate keywords: ${JSON.stringify(keyword)}`);\n }\n keywords.add(keyword);\n }\n return Object.freeze(keywords);\n}\n// ...all visibility keywords, returning the coalesced mutability\nfunction consumeMutability(tokens) {\n let modifiers = consumeKeywords(tokens, KwVisib);\n // Detect conflicting modifiers\n allowSingle(modifiers, setify(\"constant payable nonpayable\".split(\" \")));\n allowSingle(modifiers, setify(\"pure view payable nonpayable\".split(\" \")));\n // Process mutability states\n if (modifiers.has(\"view\")) {\n return \"view\";\n }\n if (modifiers.has(\"pure\")) {\n return \"pure\";\n }\n if (modifiers.has(\"payable\")) {\n return \"payable\";\n }\n if (modifiers.has(\"nonpayable\")) {\n return \"nonpayable\";\n }\n // Process legacy `constant` last\n if (modifiers.has(\"constant\")) {\n return \"view\";\n }\n return \"nonpayable\";\n}\n// ...a parameter list, returning the ParamType list\nfunction consumeParams(tokens, allowIndexed) {\n return tokens.popParams().map((t) => ParamType.from(t, allowIndexed));\n}\n// ...a energy limit, returning a BigNumber or null if none\nfunction consumeEnergy(tokens) {\n if (tokens.peekType(\"AT\")) {\n tokens.pop();\n if (tokens.peekType(\"NUMBER\")) {\n return getBigInt(tokens.pop().text);\n }\n throw new Error(\"invalid energy\");\n }\n return null;\n}\nfunction consumeEoi(tokens) {\n if (tokens.length) {\n throw new Error(`unexpected tokens: ${tokens.toString()}`);\n }\n}\nconst regexArrayType = new RegExp(/^(.*)\\[([0-9]*)\\]$/);\nfunction verifyBasicType(type) {\n const match = type.match(regexType);\n assertArgument(match, \"invalid type\", \"type\", type);\n if (type === \"uint\") {\n return \"uint256\";\n }\n if (type === \"int\") {\n return \"int256\";\n }\n if (match[2]) {\n // bytesXX\n const length = parseInt(match[2]);\n assertArgument(length !== 0 && length <= 32, \"invalid bytes length\", \"type\", type);\n }\n else if (match[3]) {\n // intXX or uintXX\n const size = parseInt(match[3]);\n assertArgument(size !== 0 && size <= 256 && size % 8 === 0, \"invalid numeric width\", \"type\", type);\n }\n return type;\n}\n// Make the Fragment constructors effectively private\nconst _guard = {};\nconst internal = Symbol.for(\"_corebc_internal\");\nconst ParamTypeInternal = \"_ParamTypeInternal\";\nconst ErrorFragmentInternal = \"_ErrorInternal\";\nconst EventFragmentInternal = \"_EventInternal\";\nconst ConstructorFragmentInternal = \"_ConstructorInternal\";\nconst FallbackFragmentInternal = \"_FallbackInternal\";\nconst FunctionFragmentInternal = \"_FunctionInternal\";\nconst StructFragmentInternal = \"_StructInternal\";\n/**\n * Each input and output of a [[Fragment]] is an Array of **PAramType**.\n */\nexport class ParamType {\n /**\n * The local name of the parameter (or ``\"\"`` if unbound)\n */\n name;\n /**\n * The fully qualified type (e.g. ``\"address\"``, ``\"tuple(address)\"``,\n * ``\"uint256[3][]\"``)\n */\n type;\n /**\n * The base type (e.g. ``\"address\"``, ``\"tuple\"``, ``\"array\"``)\n */\n baseType;\n /**\n * True if the parameters is indexed.\n *\n * For non-indexable types this is ``null``.\n */\n indexed;\n /**\n * The components for the tuple.\n *\n * For non-tuple types this is ``null``.\n */\n components;\n /**\n * The array length, or ``-1`` for dynamic-lengthed arrays.\n *\n * For non-array types this is ``null``.\n */\n arrayLength;\n /**\n * The type of each child in the array.\n *\n * For non-array types this is ``null``.\n */\n arrayChildren;\n /**\n * @private\n */\n constructor(guard, name, type, baseType, indexed, components, arrayLength, arrayChildren) {\n assertPrivate(guard, _guard, \"ParamType\");\n Object.defineProperty(this, internal, { value: ParamTypeInternal });\n if (components) {\n components = Object.freeze(components.slice());\n }\n if (baseType === \"array\") {\n if (arrayLength == null || arrayChildren == null) {\n throw new Error(\"\");\n }\n }\n else if (arrayLength != null || arrayChildren != null) {\n throw new Error(\"\");\n }\n if (baseType === \"tuple\") {\n if (components == null) {\n throw new Error(\"\");\n }\n }\n else if (components != null) {\n throw new Error(\"\");\n }\n defineProperties(this, {\n name,\n type,\n baseType,\n indexed,\n components,\n arrayLength,\n arrayChildren,\n });\n }\n /**\n * Return a string representation of this type.\n *\n * For example,\n *\n * ``sighash\" => \"(uint256,address)\"``\n *\n * ``\"minimal\" => \"tuple(uint256,address) indexed\"``\n *\n * ``\"full\" => \"tuple(uint256 foo, address bar) indexed baz\"``\n */\n format(format) {\n if (format == null) {\n format = \"sighash\";\n }\n if (format === \"json\") {\n let result = {\n type: this.baseType === \"tuple\" ? \"tuple\" : this.type,\n name: this.name || undefined,\n };\n if (typeof this.indexed === \"boolean\") {\n result.indexed = this.indexed;\n }\n if (this.isTuple()) {\n result.components = this.components.map((c) => JSON.parse(c.format(format)));\n }\n return JSON.stringify(result);\n }\n let result = \"\";\n // Array\n if (this.isArray()) {\n result += this.arrayChildren.format(format);\n result += `[${this.arrayLength < 0 ? \"\" : String(this.arrayLength)}]`;\n }\n else {\n if (this.isTuple()) {\n if (format !== \"sighash\") {\n result += this.type;\n }\n result +=\n \"(\" +\n this.components\n .map((comp) => comp.format(format))\n .join(format === \"full\" ? \", \" : \",\") +\n \")\";\n }\n else {\n result += this.type;\n }\n }\n if (format !== \"sighash\") {\n if (this.indexed === true) {\n result += \" indexed\";\n }\n if (format === \"full\" && this.name) {\n result += \" \" + this.name;\n }\n }\n return result;\n }\n /*\n * Returns true if %%value%% is an Array type.\n *\n * This provides a type gaurd ensuring that the\n * [[arrayChildren]] and [[arrayLength]] are non-null.\n */\n //static isArray(value: any): value is { arrayChildren: ParamType, arrayLength: number } {\n // return value && (value.baseType === \"array\")\n //}\n /**\n * Returns true if %%this%% is an Array type.\n *\n * This provides a type gaurd ensuring that [[arrayChildren]]\n * and [[arrayLength]] are non-null.\n */\n isArray() {\n return this.baseType === \"array\";\n }\n /**\n * Returns true if %%this%% is a Tuple type.\n *\n * This provides a type gaurd ensuring that [[components]]\n * is non-null.\n */\n isTuple() {\n return this.baseType === \"tuple\";\n }\n /**\n * Returns true if %%this%% is an Indexable type.\n *\n * This provides a type gaurd ensuring that [[indexed]]\n * is non-null.\n */\n isIndexable() {\n return this.indexed != null;\n }\n /**\n * Walks the **ParamType** with %%value%%, calling %%process%%\n * on each type, destructing the %%value%% recursively.\n */\n walk(value, process) {\n if (this.isArray()) {\n if (!Array.isArray(value)) {\n throw new Error(\"invalid array value\");\n }\n if (this.arrayLength !== -1 && value.length !== this.arrayLength) {\n throw new Error(\"array is wrong length\");\n }\n const _this = this;\n return value.map((v) => _this.arrayChildren.walk(v, process));\n }\n if (this.isTuple()) {\n if (!Array.isArray(value)) {\n throw new Error(\"invalid tuple value\");\n }\n if (value.length !== this.components.length) {\n throw new Error(\"array is wrong length\");\n }\n const _this = this;\n return value.map((v, i) => _this.components[i].walk(v, process));\n }\n return process(this.type, value);\n }\n #walkAsync(promises, value, process, setValue) {\n if (this.isArray()) {\n if (!Array.isArray(value)) {\n throw new Error(\"invalid array value\");\n }\n if (this.arrayLength !== -1 && value.length !== this.arrayLength) {\n throw new Error(\"array is wrong length\");\n }\n const childType = this.arrayChildren;\n const result = value.slice();\n result.forEach((value, index) => {\n childType.#walkAsync(promises, value, process, (value) => {\n result[index] = value;\n });\n });\n setValue(result);\n return;\n }\n if (this.isTuple()) {\n const components = this.components;\n // Convert the object into an array\n let result;\n if (Array.isArray(value)) {\n result = value.slice();\n }\n else {\n if (value == null || typeof value !== \"object\") {\n throw new Error(\"invalid tuple value\");\n }\n result = components.map((param) => {\n if (!param.name) {\n throw new Error(\"cannot use object value with unnamed components\");\n }\n if (!(param.name in value)) {\n throw new Error(`missing value for component ${param.name}`);\n }\n return value[param.name];\n });\n }\n if (result.length !== this.components.length) {\n throw new Error(\"array is wrong length\");\n }\n result.forEach((value, index) => {\n components[index].#walkAsync(promises, value, process, (value) => {\n result[index] = value;\n });\n });\n setValue(result);\n return;\n }\n const result = process(this.type, value);\n if (result.then) {\n promises.push((async function () {\n setValue(await result);\n })());\n }\n else {\n setValue(result);\n }\n }\n /**\n * Walks the **ParamType** with %%value%%, asynchronously calling\n * %%process%% on each type, destructing the %%value%% recursively.\n *\n * This can be used to resolve ENS naes by walking and resolving each\n * ``\"address\"`` type.\n */\n async walkAsync(value, process) {\n const promises = [];\n const result = [value];\n this.#walkAsync(promises, value, process, (value) => {\n result[0] = value;\n });\n if (promises.length) {\n await Promise.all(promises);\n }\n return result[0];\n }\n /**\n * Creates a new **ParamType** for %%obj%%.\n *\n * If %%allowIndexed%% then the ``indexed`` keyword is permitted,\n * otherwise the ``indexed`` keyword will throw an error.\n */\n static from(obj, allowIndexed) {\n if (ParamType.isParamType(obj)) {\n return obj;\n }\n if (typeof obj === \"string\") {\n return ParamType.from(lex(obj), allowIndexed);\n }\n else if (obj instanceof TokenString) {\n let type = \"\", baseType = \"\";\n let comps = null;\n if (consumeKeywords(obj, setify([\"tuple\"])).has(\"tuple\") ||\n obj.peekType(\"OPEN_PAREN\")) {\n // Tuple\n baseType = \"tuple\";\n comps = obj.popParams().map((t) => ParamType.from(t));\n type = `tuple(${comps.map((c) => c.format()).join(\",\")})`;\n }\n else {\n // Normal\n type = verifyBasicType(obj.popType(\"TYPE\"));\n baseType = type;\n }\n // Check for Array\n let arrayChildren = null;\n let arrayLength = null;\n while (obj.length && obj.peekType(\"BRACKET\")) {\n const bracket = obj.pop(); //arrays[i];\n arrayChildren = new ParamType(_guard, \"\", type, baseType, null, comps, arrayLength, arrayChildren);\n arrayLength = bracket.value;\n type += bracket.text;\n baseType = \"array\";\n comps = null;\n }\n let indexed = null;\n const keywords = consumeKeywords(obj, KwModifiers);\n if (keywords.has(\"indexed\")) {\n if (!allowIndexed) {\n throw new Error(\"\");\n }\n indexed = true;\n }\n const name = obj.peekType(\"ID\") ? obj.pop().text : \"\";\n if (obj.length) {\n throw new Error(\"leftover tokens\");\n }\n return new ParamType(_guard, name, type, baseType, indexed, comps, arrayLength, arrayChildren);\n }\n const name = obj.name;\n assertArgument(!name || (typeof name === \"string\" && name.match(regexId)), \"invalid name\", \"obj.name\", name);\n let indexed = obj.indexed;\n if (indexed != null) {\n assertArgument(allowIndexed, \"parameter cannot be indexed\", \"obj.indexed\", obj.indexed);\n indexed = !!indexed;\n }\n let type = obj.type;\n let arrayMatch = type.match(regexArrayType);\n if (arrayMatch) {\n const arrayLength = parseInt(arrayMatch[2] || \"-1\");\n const arrayChildren = ParamType.from({\n type: arrayMatch[1],\n components: obj.components,\n });\n return new ParamType(_guard, name || \"\", type, \"array\", indexed, null, arrayLength, arrayChildren);\n }\n if (type === \"tuple\" ||\n type.startsWith(\"tuple(\" /* fix: ) */) ||\n type.startsWith(\"(\" /* fix: ) */)) {\n const comps = obj.components != null\n ? obj.components.map((c) => ParamType.from(c))\n : null;\n const tuple = new ParamType(_guard, name || \"\", type, \"tuple\", indexed, comps, null, null);\n // @TODO: use lexer to validate and normalize type\n return tuple;\n }\n type = verifyBasicType(obj.type);\n return new ParamType(_guard, name || \"\", type, type, indexed, null, null, null);\n }\n /**\n * Returns true if %%value%% is a **ParamType**.\n */\n static isParamType(value) {\n return value && value[internal] === ParamTypeInternal;\n }\n}\n/**\n * An abstract class to represent An individual fragment from a parse ABI.\n */\nexport class Fragment {\n /**\n * The type of the fragment.\n */\n type;\n /**\n * The inputs for the fragment.\n */\n inputs;\n /**\n * @private\n */\n constructor(guard, type, inputs) {\n assertPrivate(guard, _guard, \"Fragment\");\n inputs = Object.freeze(inputs.slice());\n defineProperties(this, { type, inputs });\n }\n /**\n * Creates a new **Fragment** for %%obj%%, wich can be any supported\n * ABI frgament type.\n */\n static from(obj) {\n if (typeof obj === \"string\") {\n // Try parsing JSON...\n try {\n Fragment.from(JSON.parse(obj));\n }\n catch (e) { }\n // ...otherwise, use the human-readable lexer\n return Fragment.from(lex(obj));\n }\n if (obj instanceof TokenString) {\n // Human-readable ABI (already lexed)\n const type = obj.peekKeyword(KwTypes);\n switch (type) {\n case \"constructor\":\n return ConstructorFragment.from(obj);\n case \"error\":\n return ErrorFragment.from(obj);\n case \"event\":\n return EventFragment.from(obj);\n case \"fallback\":\n case \"receive\":\n return FallbackFragment.from(obj);\n case \"function\":\n return FunctionFragment.from(obj);\n case \"struct\":\n return StructFragment.from(obj);\n }\n }\n else if (typeof obj === \"object\") {\n // JSON ABI\n switch (obj.type) {\n case \"constructor\":\n return ConstructorFragment.from(obj);\n case \"error\":\n return ErrorFragment.from(obj);\n case \"event\":\n return EventFragment.from(obj);\n case \"fallback\":\n case \"receive\":\n return FallbackFragment.from(obj);\n case \"function\":\n return FunctionFragment.from(obj);\n case \"struct\":\n return StructFragment.from(obj);\n }\n assert(false, `unsupported type: ${obj.type}`, \"UNSUPPORTED_OPERATION\", {\n operation: \"Fragment.from\",\n });\n }\n assertArgument(false, \"unsupported frgament object\", \"obj\", obj);\n }\n /**\n * Returns true if %%value%% is a [[ConstructorFragment]].\n */\n static isConstructor(value) {\n return ConstructorFragment.isFragment(value);\n }\n /**\n * Returns true if %%value%% is an [[ErrorFragment]].\n */\n static isError(value) {\n return ErrorFragment.isFragment(value);\n }\n /**\n * Returns true if %%value%% is an [[EventFragment]].\n */\n static isEvent(value) {\n return EventFragment.isFragment(value);\n }\n /**\n * Returns true if %%value%% is a [[FunctionFragment]].\n */\n static isFunction(value) {\n return FunctionFragment.isFragment(value);\n }\n /**\n * Returns true if %%value%% is a [[StructFragment]].\n */\n static isStruct(value) {\n return StructFragment.isFragment(value);\n }\n}\n/**\n * An abstract class to represent An individual fragment\n * which has a name from a parse ABI.\n */\nexport class NamedFragment extends Fragment {\n /**\n * The name of the fragment.\n */\n name;\n /**\n * @private\n */\n constructor(guard, type, name, inputs) {\n super(guard, type, inputs);\n assertArgument(typeof name === \"string\" && name.match(regexId), \"invalid identifier\", \"name\", name);\n inputs = Object.freeze(inputs.slice());\n defineProperties(this, { name });\n }\n}\nfunction joinParams(format, params) {\n return (\"(\" +\n params.map((p) => p.format(format)).join(format === \"full\" ? \", \" : \",\") +\n \")\");\n}\n/**\n * A Fragment which represents a //Custom Error//.\n */\nexport class ErrorFragment extends NamedFragment {\n /**\n * @private\n */\n constructor(guard, name, inputs) {\n super(guard, \"error\", name, inputs);\n Object.defineProperty(this, internal, { value: ErrorFragmentInternal });\n }\n /**\n * The Custom Error selector.\n */\n get selector() {\n return id(this.format(\"sighash\")).substring(0, 10);\n }\n format(format) {\n if (format == null) {\n format = \"sighash\";\n }\n if (format === \"json\") {\n return JSON.stringify({\n type: \"error\",\n name: this.name,\n inputs: this.inputs.map((input) => JSON.parse(input.format(format))),\n });\n }\n const result = [];\n if (format !== \"sighash\") {\n result.push(\"error\");\n }\n result.push(this.name + joinParams(format, this.inputs));\n return result.join(\" \");\n }\n static from(obj) {\n if (ErrorFragment.isFragment(obj)) {\n return obj;\n }\n if (typeof obj === \"string\") {\n return ErrorFragment.from(lex(obj));\n }\n else if (obj instanceof TokenString) {\n const name = consumeName(\"error\", obj);\n const inputs = consumeParams(obj);\n consumeEoi(obj);\n return new ErrorFragment(_guard, name, inputs);\n }\n return new ErrorFragment(_guard, obj.name, obj.inputs ? obj.inputs.map(ParamType.from) : []);\n }\n static isFragment(value) {\n return value && value[internal] === ErrorFragmentInternal;\n }\n}\n/**\n * A Fragment which represents an Event.\n */\nexport class EventFragment extends NamedFragment {\n anonymous;\n /**\n * @private\n */\n constructor(guard, name, inputs, anonymous) {\n super(guard, \"event\", name, inputs);\n Object.defineProperty(this, internal, { value: EventFragmentInternal });\n defineProperties(this, { anonymous });\n }\n /**\n * The Event topic hash.\n */\n get topicHash() {\n return id(this.format(\"sighash\"));\n }\n format(format) {\n if (format == null) {\n format = \"sighash\";\n }\n if (format === \"json\") {\n return JSON.stringify({\n type: \"event\",\n anonymous: this.anonymous,\n name: this.name,\n inputs: this.inputs.map((i) => JSON.parse(i.format(format))),\n });\n }\n const result = [];\n if (format !== \"sighash\") {\n result.push(\"event\");\n }\n result.push(this.name + joinParams(format, this.inputs));\n if (format !== \"sighash\" && this.anonymous) {\n result.push(\"anonymous\");\n }\n return result.join(\" \");\n }\n static getTopicHash(name, params) {\n params = (params || []).map((p) => ParamType.from(p));\n const fragment = new EventFragment(_guard, name, params, false);\n return fragment.topicHash;\n }\n static from(obj) {\n if (EventFragment.isFragment(obj)) {\n return obj;\n }\n if (typeof obj === \"string\") {\n return EventFragment.from(lex(obj));\n }\n else if (obj instanceof TokenString) {\n const name = consumeName(\"event\", obj);\n const inputs = consumeParams(obj, true);\n const anonymous = !!consumeKeywords(obj, setify([\"anonymous\"])).has(\"anonymous\");\n consumeEoi(obj);\n return new EventFragment(_guard, name, inputs, anonymous);\n }\n return new EventFragment(_guard, obj.name, obj.inputs ? obj.inputs.map((p) => ParamType.from(p, true)) : [], !!obj.anonymous);\n }\n static isFragment(value) {\n return value && value[internal] === EventFragmentInternal;\n }\n}\n/**\n * A Fragment which represents a constructor.\n */\nexport class ConstructorFragment extends Fragment {\n payable;\n energy;\n /**\n * @private\n */\n constructor(guard, type, inputs, payable, energy) {\n super(guard, type, inputs);\n Object.defineProperty(this, internal, {\n value: ConstructorFragmentInternal,\n });\n defineProperties(this, { payable, energy });\n }\n format(format) {\n assert(format != null && format !== \"sighash\", \"cannot format a constructor for sighash\", \"UNSUPPORTED_OPERATION\", { operation: \"format(sighash)\" });\n if (format === \"json\") {\n return JSON.stringify({\n type: \"constructor\",\n stateMutability: this.payable ? \"payable\" : \"undefined\",\n payable: this.payable,\n energy: this.energy != null ? this.energy : undefined,\n inputs: this.inputs.map((i) => JSON.parse(i.format(format))),\n });\n }\n const result = [`constructor${joinParams(format, this.inputs)}`];\n result.push(this.payable ? \"payable\" : \"nonpayable\");\n if (this.energy != null) {\n result.push(`@${this.energy.toString()}`);\n }\n return result.join(\" \");\n }\n static from(obj) {\n if (ConstructorFragment.isFragment(obj)) {\n return obj;\n }\n if (typeof obj === \"string\") {\n return ConstructorFragment.from(lex(obj));\n }\n else if (obj instanceof TokenString) {\n consumeKeywords(obj, setify([\"constructor\"]));\n const inputs = consumeParams(obj);\n const payable = !!consumeKeywords(obj, setify([\"payable\"])).has(\"payable\");\n const energy = consumeEnergy(obj);\n consumeEoi(obj);\n return new ConstructorFragment(_guard, \"constructor\", inputs, payable, energy);\n }\n return new ConstructorFragment(_guard, \"constructor\", obj.inputs ? obj.inputs.map(ParamType.from) : [], !!obj.payable, obj.energy != null ? obj.energy : null);\n }\n static isFragment(value) {\n return value && value[internal] === ConstructorFragmentInternal;\n }\n}\n/**\n * A Fragment which represents a method.\n */\nexport class FallbackFragment extends Fragment {\n /**\n * If the function can be sent value during invocation.\n */\n payable;\n constructor(guard, inputs, payable) {\n super(guard, \"fallback\", inputs);\n Object.defineProperty(this, internal, { value: FallbackFragmentInternal });\n defineProperties(this, { payable });\n }\n format(format) {\n const type = this.inputs.length === 0 ? \"receive\" : \"fallback\";\n if (format === \"json\") {\n const stateMutability = this.payable ? \"payable\" : \"nonpayable\";\n return JSON.stringify({ type, stateMutability });\n }\n return `${type}()${this.payable ? \" payable\" : \"\"}`;\n }\n static from(obj) {\n if (FallbackFragment.isFragment(obj)) {\n return obj;\n }\n if (typeof obj === \"string\") {\n return FallbackFragment.from(lex(obj));\n }\n else if (obj instanceof TokenString) {\n const errorObj = obj.toString();\n const topIsValid = obj.peekKeyword(setify([\"fallback\", \"receive\"]));\n assertArgument(topIsValid, \"type must be fallback or receive\", \"obj\", errorObj);\n const type = obj.popKeyword(setify([\"fallback\", \"receive\"]));\n // receive()\n if (type === \"receive\") {\n const inputs = consumeParams(obj);\n assertArgument(inputs.length === 0, `receive cannot have arguments`, \"obj.inputs\", inputs);\n consumeKeywords(obj, setify([\"payable\"]));\n consumeEoi(obj);\n return new FallbackFragment(_guard, [], true);\n }\n // fallback() [payable]\n // fallback(bytes) [payable] returns (bytes)\n let inputs = consumeParams(obj);\n if (inputs.length) {\n assertArgument(inputs.length === 1 && inputs[0].type === \"bytes\", \"invalid fallback inputs\", \"obj.inputs\", inputs.map((i) => i.format(\"minimal\")).join(\", \"));\n }\n else {\n inputs = [ParamType.from(\"bytes\")];\n }\n const mutability = consumeMutability(obj);\n assertArgument(mutability === \"nonpayable\" || mutability === \"payable\", \"fallback cannot be constants\", \"obj.stateMutability\", mutability);\n if (consumeKeywords(obj, setify([\"returns\"])).has(\"returns\")) {\n const outputs = consumeParams(obj);\n assertArgument(outputs.length === 1 && outputs[0].type === \"bytes\", \"invalid fallback outputs\", \"obj.outputs\", outputs.map((i) => i.format(\"minimal\")).join(\", \"));\n }\n consumeEoi(obj);\n return new FallbackFragment(_guard, inputs, mutability === \"payable\");\n }\n if (obj.type === \"receive\") {\n return new FallbackFragment(_guard, [], true);\n }\n if (obj.type === \"fallback\") {\n const inputs = [ParamType.from(\"bytes\")];\n const payable = obj.stateMutability === \"payable\";\n return new FallbackFragment(_guard, inputs, payable);\n }\n assertArgument(false, \"invalid fallback description\", \"obj\", obj);\n }\n static isFragment(value) {\n return value && value[internal] === FallbackFragmentInternal;\n }\n}\n/**\n * A Fragment which represents a method.\n */\nexport class FunctionFragment extends NamedFragment {\n /**\n * If the function is constant (e.g. ``pure`` or ``view`` functions).\n */\n constant;\n /**\n * The returned types for the result of calling this function.\n */\n outputs;\n /**\n * The state mutability (e.g. ``payable``, ``nonpayable``, ``view``\n * or ``pure``)\n */\n stateMutability;\n /**\n * If the function can be sent value during invocation.\n */\n payable;\n /**\n * The amount of energy to send when calling this function\n */\n energy;\n /**\n * @private\n */\n constructor(guard, name, stateMutability, inputs, outputs, energy) {\n super(guard, \"function\", name, inputs);\n Object.defineProperty(this, internal, { value: FunctionFragmentInternal });\n outputs = Object.freeze(outputs.slice());\n const constant = stateMutability === \"view\" || stateMutability === \"pure\";\n const payable = stateMutability === \"payable\";\n defineProperties(this, {\n constant,\n energy,\n outputs,\n payable,\n stateMutability,\n });\n }\n /**\n * The Function selector.\n */\n get selector() {\n return id(this.format(\"sighash\")).substring(0, 10);\n }\n format(format) {\n if (format == null) {\n format = \"sighash\";\n }\n if (format === \"json\") {\n return JSON.stringify({\n type: \"function\",\n name: this.name,\n constant: this.constant,\n stateMutability: this.stateMutability !== \"nonpayable\"\n ? this.stateMutability\n : undefined,\n payable: this.payable,\n energy: this.energy != null ? this.energy : undefined,\n inputs: this.inputs.map((i) => JSON.parse(i.format(format))),\n outputs: this.outputs.map((o) => JSON.parse(o.format(format))),\n });\n }\n const result = [];\n if (format !== \"sighash\") {\n result.push(\"function\");\n }\n result.push(this.name + joinParams(format, this.inputs));\n if (format !== \"sighash\") {\n if (this.stateMutability !== \"nonpayable\") {\n result.push(this.stateMutability);\n }\n if (this.outputs && this.outputs.length) {\n result.push(\"returns\");\n result.push(joinParams(format, this.outputs));\n }\n if (this.energy != null) {\n result.push(`@${this.energy.toString()}`);\n }\n }\n return result.join(\" \");\n }\n static getSelector(name, params) {\n params = (params || []).map((p) => ParamType.from(p));\n const fragment = new FunctionFragment(_guard, name, \"view\", params, [], null);\n return fragment.selector;\n }\n static from(obj) {\n if (FunctionFragment.isFragment(obj)) {\n return obj;\n }\n if (typeof obj === \"string\") {\n return FunctionFragment.from(lex(obj));\n }\n else if (obj instanceof TokenString) {\n const name = consumeName(\"function\", obj);\n const inputs = consumeParams(obj);\n const mutability = consumeMutability(obj);\n let outputs = [];\n if (consumeKeywords(obj, setify([\"returns\"])).has(\"returns\")) {\n outputs = consumeParams(obj);\n }\n const energy = consumeEnergy(obj);\n consumeEoi(obj);\n return new FunctionFragment(_guard, name, mutability, inputs, outputs, energy);\n }\n let stateMutability = obj.stateMutability;\n // Use legacy Solidity ABI logic if stateMutability is missing\n if (stateMutability == null) {\n stateMutability = \"payable\";\n if (typeof obj.constant === \"boolean\") {\n stateMutability = \"view\";\n if (!obj.constant) {\n stateMutability = \"payable\";\n if (typeof obj.payable === \"boolean\" && !obj.payable) {\n stateMutability = \"nonpayable\";\n }\n }\n }\n else if (typeof obj.payable === \"boolean\" && !obj.payable) {\n stateMutability = \"nonpayable\";\n }\n }\n // @TODO: verifyState for stateMutability (e.g. throw if\n // payable: false but stateMutability is \"nonpayable\")\n return new FunctionFragment(_guard, obj.name, stateMutability, obj.inputs ? obj.inputs.map(ParamType.from) : [], obj.outputs ? obj.outputs.map(ParamType.from) : [], obj.energy != null ? obj.energy : null);\n }\n static isFragment(value) {\n return value && value[internal] === FunctionFragmentInternal;\n }\n}\n/**\n * A Fragment which represents a structure.\n */\nexport class StructFragment extends NamedFragment {\n /**\n * @private\n */\n constructor(guard, name, inputs) {\n super(guard, \"struct\", name, inputs);\n Object.defineProperty(this, internal, { value: StructFragmentInternal });\n }\n format() {\n throw new Error(\"@TODO\");\n }\n static from(obj) {\n if (typeof obj === \"string\") {\n return StructFragment.from(lex(obj));\n }\n else if (obj instanceof TokenString) {\n const name = consumeName(\"struct\", obj);\n const inputs = consumeParams(obj);\n consumeEoi(obj);\n return new StructFragment(_guard, name, inputs);\n }\n return new StructFragment(_guard, obj.name, obj.inputs ? obj.inputs.map(ParamType.from) : []);\n }\n static isFragment(value) {\n return value && value[internal] === StructFragmentInternal;\n }\n}\n//# sourceMappingURL=fragments.js.map","/**\n * When sending values to or receiving values from a [[Contract]], the\n * data is generally encoded using the [ABI standard](link-solc-abi).\n *\n * The AbiCoder provides a utility to encode values to ABI data and\n * decode values from ABI data.\n *\n * Most of the time, developers should favour the [[Contract]] class,\n * which further abstracts a lot of the finer details of ABI data.\n *\n * @_section api/abi/abi-coder:ABI Encoding\n */\nimport { assertArgumentCount, assertArgument } from \"../utils/index.js\";\nimport { Reader, Writer } from \"./coders/abstract-coder.js\";\nimport { AddressCoder } from \"./coders/address.js\";\nimport { ArrayCoder } from \"./coders/array.js\";\nimport { BooleanCoder } from \"./coders/boolean.js\";\nimport { BytesCoder } from \"./coders/bytes.js\";\nimport { FixedBytesCoder } from \"./coders/fixed-bytes.js\";\nimport { NullCoder } from \"./coders/null.js\";\nimport { NumberCoder } from \"./coders/number.js\";\nimport { StringCoder } from \"./coders/string.js\";\nimport { TupleCoder } from \"./coders/tuple.js\";\nimport { ParamType } from \"./fragments.js\";\nimport { getAddress } from \"../address/index.js\";\nimport { getBytes, hexlify, makeError } from \"../utils/index.js\";\n// https://docs.soliditylang.org/en/v0.8.17/control-structures.html\nconst PanicReasons = new Map();\nPanicReasons.set(0x00, \"GENERIC_PANIC\");\nPanicReasons.set(0x01, \"ASSERT_FALSE\");\nPanicReasons.set(0x11, \"OVERFLOW\");\nPanicReasons.set(0x12, \"DIVIDE_BY_ZERO\");\nPanicReasons.set(0x21, \"ENUM_RANGE_ERROR\");\nPanicReasons.set(0x22, \"BAD_STORAGE_DATA\");\nPanicReasons.set(0x31, \"STACK_UNDERFLOW\");\nPanicReasons.set(0x32, \"ARRAY_RANGE_ERROR\");\nPanicReasons.set(0x41, \"OUT_OF_MEMORY\");\nPanicReasons.set(0x51, \"UNINITIALIZED_FUNCTION_CALL\");\nconst paramTypeBytes = new RegExp(/^bytes([0-9]*)$/);\nconst paramTypeNumber = new RegExp(/^(u?int)([0-9]*)$/);\nlet defaultCoder = null;\nfunction getBuiltinCallException(action, tx, data, abiCoder) {\n let message = \"missing revert data\";\n let reason = null;\n const invocation = null;\n let revert = null;\n if (data) {\n message = \"execution reverted\";\n const bytes = getBytes(data);\n data = hexlify(data);\n if (bytes.length === 0) {\n message += \" (no data present; likely require(false) occurred\";\n reason = \"require(false)\";\n }\n else if (bytes.length % 32 !== 4) {\n message += \" (could not decode reason; invalid data length)\";\n }\n else if (hexlify(bytes.slice(0, 4)) === \"0x08c379a0\") {\n // Error(string)\n try {\n reason = abiCoder.decode([\"string\"], bytes.slice(4))[0];\n revert = {\n signature: \"Error(string)\",\n name: \"Error\",\n args: [reason],\n };\n message += `: ${JSON.stringify(reason)}`;\n }\n catch (error) {\n message += \" (could not decode reason; invalid string data)\";\n }\n }\n else if (hexlify(bytes.slice(0, 4)) === \"0x4e487b71\") {\n // Panic(uint256)\n try {\n const code = Number(abiCoder.decode([\"uint256\"], bytes.slice(4))[0]);\n revert = {\n signature: \"Panic(uint256)\",\n name: \"Panic\",\n args: [code],\n };\n reason = `Panic due to ${PanicReasons.get(code) || \"UNKNOWN\"}(${code})`;\n message += `: ${reason}`;\n }\n catch (error) {\n message += \" (could not decode panic code)\";\n }\n }\n else {\n message += \" (unknown custom error)\";\n }\n }\n const transaction = {\n to: tx.to ? getAddress(tx.to) : null,\n data: tx.data || \"0x\",\n };\n if (tx.from) {\n transaction.from = getAddress(tx.from);\n }\n return makeError(message, \"CALL_EXCEPTION\", {\n action,\n data,\n reason,\n transaction,\n invocation,\n revert,\n });\n}\n/**\n * About AbiCoder\n */\nexport class AbiCoder {\n #getCoder(param) {\n if (param.isArray()) {\n return new ArrayCoder(this.#getCoder(param.arrayChildren), param.arrayLength, param.name);\n }\n if (param.isTuple()) {\n return new TupleCoder(param.components.map((c) => this.#getCoder(c)), param.name);\n }\n switch (param.baseType) {\n case \"address\":\n return new AddressCoder(param.name);\n case \"bool\":\n return new BooleanCoder(param.name);\n case \"string\":\n return new StringCoder(param.name);\n case \"bytes\":\n return new BytesCoder(param.name);\n case \"\":\n return new NullCoder(param.name);\n }\n // u?int[0-9]*\n let match = param.type.match(paramTypeNumber);\n if (match) {\n let size = parseInt(match[2] || \"256\");\n assertArgument(size !== 0 && size <= 256 && size % 8 === 0, \"invalid \" + match[1] + \" bit length\", \"param\", param);\n return new NumberCoder(size / 8, match[1] === \"int\", param.name);\n }\n // bytes[0-9]+\n match = param.type.match(paramTypeBytes);\n if (match) {\n let size = parseInt(match[1]);\n assertArgument(size !== 0 && size <= 32, \"invalid bytes length\", \"param\", param);\n return new FixedBytesCoder(size, param.name);\n }\n assertArgument(false, \"invalid type\", \"type\", param.type);\n }\n /**\n * Get the default values for the given %%types%%.\n *\n * For example, a ``uint`` is by default ``0`` and ``bool``\n * is by default ``false``.\n */\n getDefaultValue(types) {\n const coders = types.map((type) => this.#getCoder(ParamType.from(type)));\n const coder = new TupleCoder(coders, \"_\");\n return coder.defaultValue();\n }\n /**\n * Encode the %%values%% as the %%types%% into ABI data.\n *\n * @returns DataHexstring\n */\n encode(types, values) {\n assertArgumentCount(values.length, types.length, \"types/values length mismatch\");\n const coders = types.map((type) => this.#getCoder(ParamType.from(type)));\n const coder = new TupleCoder(coders, \"_\");\n const writer = new Writer();\n coder.encode(writer, values);\n return writer.data;\n }\n /**\n * Decode the ABI %%data%% as the %%types%% into values.\n *\n * If %%loose%% decoding is enabled, then strict padding is\n * not enforced. Some older versions of Solidity incorrectly\n * padded event data emitted from ``external`` functions.\n */\n decode(types, data, loose) {\n const coders = types.map((type) => this.#getCoder(ParamType.from(type)));\n const coder = new TupleCoder(coders, \"_\");\n return coder.decode(new Reader(data, loose));\n }\n /**\n * Returns the shared singleton instance of a default [[AbiCoder]].\n *\n * On the first call, the instance is created internally.\n */\n static defaultAbiCoder() {\n if (defaultCoder == null) {\n defaultCoder = new AbiCoder();\n }\n return defaultCoder;\n }\n /**\n * Returns an corebc-compatible [[CallExceptionError]] Error for the given\n * result %%data%% for the [[CallExceptionAction]] %%action%% against\n * the Transaction %%tx%%.\n */\n static getBuiltinCallException(action, tx, data) {\n return getBuiltinCallException(action, tx, data, AbiCoder.defaultAbiCoder());\n }\n}\n//# sourceMappingURL=abi-coder.js.map","/**\n * About bytes32 strings...\n *\n * @_docloc: api/utils:Bytes32 Strings\n */\nimport { getBytes, toUtf8Bytes, toUtf8String, zeroPadBytes, } from \"../utils/index.js\";\n/**\n * Encodes %%text%% as a Bytes32 string.\n */\nexport function encodeBytes32String(text) {\n // Get the bytes\n const bytes = toUtf8Bytes(text);\n // Check we have room for null-termination\n if (bytes.length > 31) {\n throw new Error(\"bytes32 string must be less than 32 bytes\");\n }\n // Zero-pad (implicitly null-terminates)\n return zeroPadBytes(bytes, 32);\n}\n/**\n * Encodes the Bytes32-encoded %%bytes%% into a string.\n */\nexport function decodeBytes32String(_bytes) {\n const data = getBytes(_bytes, \"bytes\");\n // Must be 32 bytes with a null-termination\n if (data.length !== 32) {\n throw new Error(\"invalid bytes32 - not 32 bytes long\");\n }\n if (data[31] !== 0) {\n throw new Error(\"invalid bytes32 string - no null terminator\");\n }\n // Find the null termination\n let length = 31;\n while (data[length - 1] === 0) {\n length--;\n }\n // Determine the string value\n return toUtf8String(data.slice(0, length));\n}\n//# sourceMappingURL=bytes32.js.map","/**\n * About Interface\n *\n * @_subsection api/abi:Interfaces [interfaces]\n */\nimport { id } from \"../hash/index.js\";\nimport { concat, dataSlice, getBigInt, getBytes, getBytesCopy, hexlify, zeroPadValue, isHexString, defineProperties, assertArgument, toBeHex, assert, } from \"../utils/index.js\";\nimport { AbiCoder } from \"./abi-coder.js\";\nimport { checkResultErrors, Result } from \"./coders/abstract-coder.js\";\nimport { ConstructorFragment, ErrorFragment, EventFragment, Fragment, FunctionFragment, ParamType, } from \"./fragments.js\";\nimport { Typed } from \"./typed.js\";\nimport { sha256 } from \"../crypto/sha3.js\";\nexport { checkResultErrors, Result };\nexport class LogDescription {\n fragment;\n name;\n signature;\n topic;\n args;\n constructor(fragment, topic, args) {\n const name = fragment.name, signature = fragment.format();\n defineProperties(this, {\n fragment,\n name,\n signature,\n topic,\n args,\n });\n }\n}\nexport class TransactionDescription {\n fragment;\n name;\n args;\n signature;\n selector;\n value;\n constructor(fragment, selector, args, value) {\n const name = fragment.name, signature = fragment.format();\n defineProperties(this, {\n fragment,\n name,\n args,\n signature,\n selector,\n value,\n });\n }\n}\nexport class ErrorDescription {\n fragment;\n name;\n args;\n signature;\n selector;\n constructor(fragment, selector, args) {\n const name = fragment.name, signature = fragment.format();\n defineProperties(this, {\n fragment,\n name,\n args,\n signature,\n selector,\n });\n }\n}\nexport class Indexed {\n hash;\n _isIndexed;\n static isIndexed(value) {\n return !!(value && value._isIndexed);\n }\n constructor(hash) {\n defineProperties(this, { hash, _isIndexed: true });\n }\n}\n// https://docs.soliditylang.org/en/v0.8.13/control-structures.html?highlight=panic#panic-via-assert-and-error-via-require\nconst PanicReasons = {\n \"0\": \"generic panic\",\n \"1\": \"assert(false)\",\n \"17\": \"arithmetic overflow\",\n \"18\": \"division or modulo by zero\",\n \"33\": \"enum overflow\",\n \"34\": \"invalid encoded storage byte array accessed\",\n \"49\": \"out-of-bounds array access; popping on an empty array\",\n \"50\": \"out-of-bounds access of an array or bytesN\",\n \"65\": \"out of memory\",\n \"81\": \"uninitialized function\",\n};\nconst BuiltinErrors = {\n \"0x08c379a0\": {\n signature: \"Error(string)\",\n name: \"Error\",\n inputs: [\"string\"],\n reason: (message) => {\n return `reverted with reason string ${JSON.stringify(message)}`;\n },\n },\n \"0x4e487b71\": {\n signature: \"Panic(uint256)\",\n name: \"Panic\",\n inputs: [\"uint256\"],\n reason: (code) => {\n let reason = \"unknown panic code\";\n if (code >= 0 && code <= 0xff && PanicReasons[code.toString()]) {\n reason = PanicReasons[code.toString()];\n }\n return `reverted with panic code 0x${code.toString(16)} (${reason})`;\n },\n },\n};\n/**\n * An Interface abstracts many of the low-level details for\n * encoding and decoding the data on the blockchain.\n *\n * An ABI provides information on how to encode data to send to\n * a Contract, how to decode the results and events and how to\n * interpret revert errors.\n *\n * The ABI can be specified by [any supported format](InterfaceAbi).\n */\nexport class Interface {\n /**\n * All the Contract ABI members (i.e. methods, events, errors, etc).\n */\n fragments;\n /**\n * The Contract constructor.\n */\n deploy;\n /**\n * The Fallback method, if any.\n */\n fallback;\n /**\n * If receiving xcb is supported.\n */\n receive;\n #errors;\n #events;\n #functions;\n // #structs: Map;\n #abiCoder;\n /**\n * Create a new Interface for the %%fragments%%.\n */\n constructor(fragments) {\n let abi = [];\n if (typeof fragments === \"string\") {\n abi = JSON.parse(fragments);\n }\n else {\n abi = fragments;\n }\n this.#functions = new Map();\n this.#errors = new Map();\n this.#events = new Map();\n // this.#structs = new Map();\n const frags = [];\n for (const a of abi) {\n try {\n frags.push(Fragment.from(a));\n }\n catch (error) {\n console.log(\"EE\", error);\n }\n }\n defineProperties(this, {\n fragments: Object.freeze(frags),\n });\n let fallback = null;\n let receive = false;\n this.#abiCoder = this.getAbiCoder();\n // Add all fragments by their signature\n this.fragments.forEach((fragment, index) => {\n let bucket;\n switch (fragment.type) {\n case \"constructor\":\n if (this.deploy) {\n console.log(\"duplicate definition - constructor\");\n return;\n }\n //checkNames(fragment, \"input\", fragment.inputs);\n defineProperties(this, {\n deploy: fragment,\n });\n return;\n case \"fallback\":\n if (fragment.inputs.length === 0) {\n receive = true;\n }\n else {\n assertArgument(!fallback ||\n fragment.payable !== fallback.payable, \"conflicting fallback fragments\", `fragments[${index}]`, fragment);\n fallback = fragment;\n receive = fallback.payable;\n }\n return;\n case \"function\":\n //checkNames(fragment, \"input\", fragment.inputs);\n //checkNames(fragment, \"output\", (fragment).outputs);\n bucket = this.#functions;\n break;\n case \"event\":\n //checkNames(fragment, \"input\", fragment.inputs);\n bucket = this.#events;\n break;\n case \"error\":\n bucket = this.#errors;\n break;\n default:\n return;\n }\n // Two identical entries; ignore it\n const signature = fragment.format();\n if (bucket.has(signature)) {\n return;\n }\n bucket.set(signature, fragment);\n });\n // If we do not have a constructor add a default\n if (!this.deploy) {\n defineProperties(this, {\n deploy: ConstructorFragment.from(\"constructor()\"),\n });\n }\n defineProperties(this, { fallback, receive });\n }\n /**\n * Returns the entire Human-Readable ABI, as an array of\n * signatures, optionally as %%minimal%% strings, which\n * removes parameter names and unneceesary spaces.\n */\n format(minimal) {\n const format = minimal ? \"minimal\" : \"full\";\n const abi = this.fragments.map((f) => f.format(format));\n return abi;\n }\n /**\n * Return the JSON-encoded ABI. This is the format Solidiy\n * returns.\n */\n formatJson() {\n const abi = this.fragments.map((f) => f.format(\"json\"));\n // We need to re-bundle the JSON fragments a bit\n return JSON.stringify(abi.map((j) => JSON.parse(j)));\n }\n /**\n * The ABI coder that will be used to encode and decode binary\n * data.\n */\n getAbiCoder() {\n return AbiCoder.defaultAbiCoder();\n }\n // Find a function definition by any means necessary (unless it is ambiguous)\n #getFunction(key, values, forceUnique) {\n // Selector\n if (isHexString(key)) {\n const selector = key.toLowerCase();\n for (const fragment of this.#functions.values()) {\n if (selector === fragment.selector) {\n return fragment;\n }\n }\n return null;\n }\n // It is a bare name, look up the function (will return null if ambiguous)\n if (key.indexOf(\"(\") === -1) {\n const matching = [];\n for (const [name, fragment] of this.#functions) {\n if (name.split(\"(\" /* fix:) */)[0] === key) {\n matching.push(fragment);\n }\n }\n if (values) {\n const lastValue = values.length > 0 ? values[values.length - 1] : null;\n let valueLength = values.length;\n let allowOptions = true;\n if (Typed.isTyped(lastValue) && lastValue.type === \"overrides\") {\n allowOptions = false;\n valueLength--;\n }\n // Remove all matches that don't have a compatible length. The args\n // may contain an overrides, so the match may have n or n - 1 parameters\n for (let i = matching.length - 1; i >= 0; i--) {\n const inputs = matching[i].inputs.length;\n if (inputs !== valueLength &&\n (!allowOptions || inputs !== valueLength - 1)) {\n matching.splice(i, 1);\n }\n }\n // Remove all matches that don't match the Typed signature\n for (let i = matching.length - 1; i >= 0; i--) {\n const inputs = matching[i].inputs;\n for (let j = 0; j < values.length; j++) {\n // Not a typed value\n if (!Typed.isTyped(values[j])) {\n continue;\n }\n // We are past the inputs\n if (j >= inputs.length) {\n if (values[j].type === \"overrides\") {\n continue;\n }\n matching.splice(i, 1);\n break;\n }\n // Make sure the value type matches the input type\n if (values[j].type !== inputs[j].baseType) {\n matching.splice(i, 1);\n break;\n }\n }\n }\n }\n // We found a single matching signature with an overrides, but the\n // last value is something that cannot possibly be an options\n if (matching.length === 1 &&\n values &&\n values.length !== matching[0].inputs.length) {\n const lastArg = values[values.length - 1];\n if (lastArg == null ||\n Array.isArray(lastArg) ||\n typeof lastArg !== \"object\") {\n matching.splice(0, 1);\n }\n }\n if (matching.length === 0) {\n return null;\n }\n if (matching.length > 1 && forceUnique) {\n const matchStr = matching\n .map((m) => JSON.stringify(m.format()))\n .join(\", \");\n assertArgument(false, `ambiguous function description (i.e. matches ${matchStr})`, \"key\", key);\n }\n return matching[0];\n }\n // Normalize the signature and lookup the function\n const result = this.#functions.get(FunctionFragment.from(key).format());\n if (result) {\n return result;\n }\n return null;\n }\n /**\n * Get the function name for %%key%%, which may be a function selector,\n * function name or function signature that belongs to the ABI.\n */\n getFunctionName(key) {\n const fragment = this.#getFunction(key, null, false);\n assertArgument(fragment, \"no matching function\", \"key\", key);\n return fragment.name;\n }\n /**\n * Returns true if %%key%% (a function selector, function name or\n * function signature) is present in the ABI.\n *\n * In the case of a function name, the name may be ambiguous, so\n * accessing the [[FunctionFragment]] may require refinement.\n */\n hasFunction(key) {\n return !!this.#getFunction(key, null, false);\n }\n /**\n * Get the [[FunctionFragment]] for %%key%%, which may be a function\n * selector, function name or function signature that belongs to the ABI.\n *\n * If %%values%% is provided, it will use the Typed API to handle\n * ambiguous cases where multiple functions match by name.\n *\n * If the %%key%% and %%values%% do not refine to a single function in\n * the ABI, this will throw.\n */\n getFunction(key, values) {\n return this.#getFunction(key, values || null, true);\n }\n /**\n * Iterate over all functions, calling %%callback%%, sorted by their name.\n */\n forEachFunction(callback) {\n const names = Array.from(this.#functions.keys());\n names.sort((a, b) => a.localeCompare(b));\n for (let i = 0; i < names.length; i++) {\n const name = names[i];\n callback(this.#functions.get(name), i);\n }\n }\n // Find an event definition by any means necessary (unless it is ambiguous)\n #getEvent(key, values, forceUnique) {\n // EventTopic\n if (isHexString(key)) {\n const eventTopic = key.toLowerCase();\n for (const fragment of this.#events.values()) {\n if (eventTopic === fragment.topicHash) {\n return fragment;\n }\n }\n return null;\n }\n // It is a bare name, look up the function (will return null if ambiguous)\n if (key.indexOf(\"(\") === -1) {\n const matching = [];\n for (const [name, fragment] of this.#events) {\n if (name.split(\"(\" /* fix:) */)[0] === key) {\n matching.push(fragment);\n }\n }\n if (values) {\n // Remove all matches that don't have a compatible length.\n for (let i = matching.length - 1; i >= 0; i--) {\n if (matching[i].inputs.length < values.length) {\n matching.splice(i, 1);\n }\n }\n // Remove all matches that don't match the Typed signature\n for (let i = matching.length - 1; i >= 0; i--) {\n const inputs = matching[i].inputs;\n for (let j = 0; j < values.length; j++) {\n // Not a typed value\n if (!Typed.isTyped(values[j])) {\n continue;\n }\n // Make sure the value type matches the input type\n if (values[j].type !== inputs[j].baseType) {\n matching.splice(i, 1);\n break;\n }\n }\n }\n }\n if (matching.length === 0) {\n return null;\n }\n if (matching.length > 1 && forceUnique) {\n const matchStr = matching\n .map((m) => JSON.stringify(m.format()))\n .join(\", \");\n assertArgument(false, `ambiguous event description (i.e. matches ${matchStr})`, \"key\", key);\n }\n return matching[0];\n }\n // Normalize the signature and lookup the function\n const result = this.#events.get(EventFragment.from(key).format());\n if (result) {\n return result;\n }\n return null;\n }\n /**\n * Get the event name for %%key%%, which may be a topic hash,\n * event name or event signature that belongs to the ABI.\n */\n getEventName(key) {\n const fragment = this.#getEvent(key, null, false);\n assertArgument(fragment, \"no matching event\", \"key\", key);\n return fragment.name;\n }\n /**\n * Returns true if %%key%% (an event topic hash, event name or\n * event signature) is present in the ABI.\n *\n * In the case of an event name, the name may be ambiguous, so\n * accessing the [[EventFragment]] may require refinement.\n */\n hasEvent(key) {\n return !!this.#getEvent(key, null, false);\n }\n /**\n * Get the [[EventFragment]] for %%key%%, which may be a topic hash,\n * event name or event signature that belongs to the ABI.\n *\n * If %%values%% is provided, it will use the Typed API to handle\n * ambiguous cases where multiple events match by name.\n *\n * If the %%key%% and %%values%% do not refine to a single event in\n * the ABI, this will throw.\n */\n getEvent(key, values) {\n return this.#getEvent(key, values || null, true);\n }\n /**\n * Iterate over all events, calling %%callback%%, sorted by their name.\n */\n forEachEvent(callback) {\n const names = Array.from(this.#events.keys());\n names.sort((a, b) => a.localeCompare(b));\n for (let i = 0; i < names.length; i++) {\n const name = names[i];\n callback(this.#events.get(name), i);\n }\n }\n /**\n * Get the [[ErrorFragment]] for %%key%%, which may be an error\n * selector, error name or error signature that belongs to the ABI.\n *\n * If %%values%% is provided, it will use the Typed API to handle\n * ambiguous cases where multiple errors match by name.\n *\n * If the %%key%% and %%values%% do not refine to a single error in\n * the ABI, this will throw.\n */\n getError(key, values) {\n if (isHexString(key)) {\n const selector = key.toLowerCase();\n if (BuiltinErrors[selector]) {\n return ErrorFragment.from(BuiltinErrors[selector].signature);\n }\n for (const fragment of this.#errors.values()) {\n if (selector === fragment.selector) {\n return fragment;\n }\n }\n return null;\n }\n // It is a bare name, look up the function (will return null if ambiguous)\n if (key.indexOf(\"(\") === -1) {\n const matching = [];\n for (const [name, fragment] of this.#errors) {\n if (name.split(\"(\" /* fix:) */)[0] === key) {\n matching.push(fragment);\n }\n }\n if (matching.length === 0) {\n if (key === \"Error\") {\n return ErrorFragment.from(\"error Error(string)\");\n }\n if (key === \"Panic\") {\n return ErrorFragment.from(\"error Panic(uint256)\");\n }\n return null;\n }\n else if (matching.length > 1) {\n const matchStr = matching\n .map((m) => JSON.stringify(m.format()))\n .join(\", \");\n assertArgument(false, `ambiguous error description (i.e. ${matchStr})`, \"name\", key);\n }\n return matching[0];\n }\n // Normalize the signature and lookup the function\n key = ErrorFragment.from(key).format();\n if (key === \"Error(string)\") {\n return ErrorFragment.from(\"error Error(string)\");\n }\n if (key === \"Panic(uint256)\") {\n return ErrorFragment.from(\"error Panic(uint256)\");\n }\n const result = this.#errors.get(key);\n if (result) {\n return result;\n }\n return null;\n }\n /**\n * Iterate over all errors, calling %%callback%%, sorted by their name.\n */\n forEachError(callback) {\n const names = Array.from(this.#errors.keys());\n names.sort((a, b) => a.localeCompare(b));\n for (let i = 0; i < names.length; i++) {\n const name = names[i];\n callback(this.#errors.get(name), i);\n }\n }\n // Get the 4-byte selector used by Solidity to identify a function\n /*\n getSelector(fragment: ErrorFragment | FunctionFragment): string {\n if (typeof(fragment) === \"string\") {\n const matches: Array = [ ];\n \n try { matches.push(this.getFunction(fragment)); } catch (error) { }\n try { matches.push(this.getError(fragment)); } catch (_) { }\n \n if (matches.length === 0) {\n logger.throwArgumentError(\"unknown fragment\", \"key\", fragment);\n } else if (matches.length > 1) {\n logger.throwArgumentError(\"ambiguous fragment matches function and error\", \"key\", fragment);\n }\n \n fragment = matches[0];\n }\n \n return dataSlice(id(fragment.format()), 0, 4);\n }\n */\n // Get the 32-byte topic hash used by Solidity to identify an event\n /*\n getEventTopic(fragment: EventFragment): string {\n //if (typeof(fragment) === \"string\") { fragment = this.getEvent(eventFragment); }\n return id(fragment.format());\n }\n */\n _decodeParams(params, data) {\n return this.#abiCoder.decode(params, data);\n }\n _encodeParams(params, values) {\n return this.#abiCoder.encode(params, values);\n }\n /**\n * Encodes a ``tx.data`` object for deploying the Contract with\n * the %%values%% as the constructor arguments.\n */\n encodeDeploy(values) {\n return this._encodeParams(this.deploy.inputs, values || []);\n }\n /**\n * Decodes the result %%data%% (e.g. from an ``xcb_call``) for the\n * specified error (see [[getError]] for valid values for\n * %%key%%).\n *\n * Most developers should prefer the [[parseCallResult]] method instead,\n * which will automatically detect a ``CALL_EXCEPTION`` and throw the\n * corresponding error.\n */\n decodeErrorResult(fragment, data) {\n if (typeof fragment === \"string\") {\n const f = this.getError(fragment);\n assertArgument(f, \"unknown error\", \"fragment\", fragment);\n fragment = f;\n }\n assertArgument(dataSlice(data, 0, 4) === fragment.selector, `data signature does not match error ${fragment.name}.`, \"data\", data);\n return this._decodeParams(fragment.inputs, dataSlice(data, 4));\n }\n /**\n * Encodes the transaction revert data for a call result that\n * reverted from the the Contract with the sepcified %%error%%\n * (see [[getError]] for valid values for %%fragment%%) with the %%values%%.\n *\n * This is generally not used by most developers, unless trying to mock\n * a result from a Contract.\n */\n encodeErrorResult(fragment, values) {\n if (typeof fragment === \"string\") {\n const f = this.getError(fragment);\n assertArgument(f, \"unknown error\", \"fragment\", fragment);\n fragment = f;\n }\n return concat([\n fragment.selector,\n this._encodeParams(fragment.inputs, values || []),\n ]);\n }\n /**\n * Decodes the %%data%% from a transaction ``tx.data`` for\n * the function specified (see [[getFunction]] for valid values\n * for %%fragment%%).\n *\n * Most developers should prefer the [[parseTransaction]] method\n * instead, which will automatically detect the fragment.\n */\n decodeFunctionData(fragment, data) {\n if (typeof fragment === \"string\") {\n const f = this.getFunction(fragment);\n assertArgument(f, \"unknown function\", \"fragment\", fragment);\n fragment = f;\n }\n assertArgument(dataSlice(data, 0, 4) === fragment.selector, `data signature does not match function ${fragment.name}.`, \"data\", data);\n return this._decodeParams(fragment.inputs, dataSlice(data, 4));\n }\n /**\n * Encodes the ``tx.data`` for a transaction that calls the function\n * specified (see [[getFunction]] for valid values for %%fragment%%) with\n * the %%values%%.\n */\n encodeFunctionData(fragment, values) {\n if (typeof fragment === \"string\") {\n const f = this.getFunction(fragment);\n assertArgument(f, \"unknown function\", \"fragment\", fragment);\n fragment = f;\n }\n return concat([\n fragment.selector,\n this._encodeParams(fragment.inputs, values || []),\n ]);\n }\n /**\n * Decodes the result %%data%% (e.g. from an ``xcb_call``) for the\n * specified function (see [[getFunction]] for valid values for\n * %%key%%).\n *\n * Most developers should prefer the [[parseCallResult]] method instead,\n * which will automatically detect a ``CALL_EXCEPTION`` and throw the\n * corresponding error.\n */\n decodeFunctionResult(fragment, data) {\n if (typeof fragment === \"string\") {\n const f = this.getFunction(fragment);\n assertArgument(f, \"unknown function\", \"fragment\", fragment);\n fragment = f;\n }\n let message = \"invalid length for result data\";\n const bytes = getBytesCopy(data);\n if (bytes.length % 32 === 0) {\n try {\n return this.#abiCoder.decode(fragment.outputs, bytes);\n }\n catch (error) {\n message = \"could not decode result data\";\n }\n }\n // Call returned data with no error, but the data is junk\n assert(false, message, \"BAD_DATA\", {\n value: hexlify(bytes),\n info: { method: fragment.name, signature: fragment.format() },\n });\n }\n makeError(_data, tx) {\n const data = getBytes(_data, \"data\");\n const error = AbiCoder.getBuiltinCallException(\"call\", tx, data);\n // Not a built-in error; try finding a custom error\n const customPrefix = \"execution reverted (unknown custom error)\";\n if (error.message.startsWith(customPrefix)) {\n const selector = hexlify(data.slice(0, 4));\n const ef = this.getError(selector);\n if (ef) {\n try {\n const args = this.#abiCoder.decode(ef.inputs, data.slice(4));\n error.revert = {\n name: ef.name,\n signature: ef.format(),\n args,\n };\n error.reason = error.revert.signature;\n error.message = `execution reverted: ${error.reason}`;\n }\n catch (e) {\n error.message = `execution reverted (coult not decode custom error)`;\n }\n }\n }\n // Add the invocation, if available\n const parsed = this.parseTransaction(tx);\n if (parsed) {\n error.invocation = {\n method: parsed.name,\n signature: parsed.signature,\n args: parsed.args,\n };\n }\n return error;\n }\n /**\n * Encodes the result data (e.g. from an ``xcb_call``) for the\n * specified function (see [[getFunction]] for valid values\n * for %%fragment%%) with %%values%%.\n *\n * This is generally not used by most developers, unless trying to mock\n * a result from a Contract.\n */\n encodeFunctionResult(fragment, values) {\n if (typeof fragment === \"string\") {\n const f = this.getFunction(fragment);\n assertArgument(f, \"unknown function\", \"fragment\", fragment);\n fragment = f;\n }\n return hexlify(this.#abiCoder.encode(fragment.outputs, values || []));\n }\n /*\n spelunk(inputs: Array, values: ReadonlyArray, processfunc: (type: string, value: any) => Promise): Promise> {\n const promises: Array> = [ ];\n const process = function(type: ParamType, value: any): any {\n if (type.baseType === \"array\") {\n return descend(type.child\n }\n if (type. === \"address\") {\n }\n };\n \n const descend = function (inputs: Array, values: ReadonlyArray) {\n if (inputs.length !== values.length) { throw new Error(\"length mismatch\"); }\n };\n \n const result: Array = [ ];\n values.forEach((value, index) => {\n if (value == null) {\n topics.push(null);\n } else if (param.baseType === \"array\" || param.baseType === \"tuple\") {\n logger.throwArgumentError(\"filtering with tuples or arrays not supported\", (\"contract.\" + param.name), value);\n } else if (Array.isArray(value)) {\n topics.push(value.map((value) => encodeTopic(param, value)));\n } else {\n topics.push(encodeTopic(param, value));\n }\n });\n }\n */\n // Create the filter for the event with search criteria (e.g. for xcb_filterLog)\n encodeFilterTopics(fragment, values) {\n if (typeof fragment === \"string\") {\n const f = this.getEvent(fragment);\n assertArgument(f, \"unknown event\", \"eventFragment\", fragment);\n fragment = f;\n }\n assert(values.length <= fragment.inputs.length, `too many arguments for ${fragment.format()}`, \"UNEXPECTED_ARGUMENT\", { count: values.length, expectedCount: fragment.inputs.length });\n const topics = [];\n if (!fragment.anonymous) {\n topics.push(fragment.topicHash);\n }\n // @TODO: Use the coders for this; to properly support tuples, etc.\n const encodeTopic = (param, value) => {\n if (param.type === \"string\") {\n return id(value);\n }\n else if (param.type === \"bytes\") {\n return sha256(hexlify(value));\n }\n if (param.type === \"bool\" && typeof value === \"boolean\") {\n value = value ? \"0x01\" : \"0x00\";\n }\n if (param.type.match(/^u?int/)) {\n value = toBeHex(value);\n }\n // Check addresses are valid\n if (param.type === \"address\") {\n this.#abiCoder.encode([\"address\"], [value]);\n }\n return zeroPadValue(hexlify(value), 32);\n //@TOOD should probably be return toHex(value, 32)\n };\n values.forEach((value, index) => {\n const param = fragment.inputs[index];\n if (!param.indexed) {\n assertArgument(value == null, \"cannot filter non-indexed parameters; must be null\", \"contract.\" + param.name, value);\n return;\n }\n if (value == null) {\n topics.push(null);\n }\n else if (param.baseType === \"array\" || param.baseType === \"tuple\") {\n assertArgument(false, \"filtering with tuples or arrays not supported\", \"contract.\" + param.name, value);\n }\n else if (Array.isArray(value)) {\n topics.push(value.map((value) => encodeTopic(param, value)));\n }\n else {\n topics.push(encodeTopic(param, value));\n }\n });\n // Trim off trailing nulls\n while (topics.length && topics[topics.length - 1] === null) {\n topics.pop();\n }\n return topics;\n }\n encodeEventLog(fragment, values) {\n if (typeof fragment === \"string\") {\n const f = this.getEvent(fragment);\n assertArgument(f, \"unknown event\", \"eventFragment\", fragment);\n fragment = f;\n }\n const topics = [];\n const dataTypes = [];\n const dataValues = [];\n if (!fragment.anonymous) {\n topics.push(fragment.topicHash);\n }\n assertArgument(values.length === fragment.inputs.length, \"event arguments/values mismatch\", \"values\", values);\n fragment.inputs.forEach((param, index) => {\n const value = values[index];\n if (param.indexed) {\n if (param.type === \"string\") {\n topics.push(id(value));\n }\n else if (param.type === \"bytes\") {\n topics.push(sha256(value));\n }\n else if (param.baseType === \"tuple\" || param.baseType === \"array\") {\n // @TODO\n throw new Error(\"not implemented\");\n }\n else {\n topics.push(this.#abiCoder.encode([param.type], [value]));\n }\n }\n else {\n dataTypes.push(param);\n dataValues.push(value);\n }\n });\n return {\n data: this.#abiCoder.encode(dataTypes, dataValues),\n topics: topics,\n };\n }\n // Decode a filter for the event and the search criteria\n decodeEventLog(fragment, data, topics) {\n if (typeof fragment === \"string\") {\n const f = this.getEvent(fragment);\n assertArgument(f, \"unknown event\", \"eventFragment\", fragment);\n fragment = f;\n }\n if (topics != null && !fragment.anonymous) {\n const eventTopic = fragment.topicHash;\n assertArgument(isHexString(topics[0], 32) && topics[0].toLowerCase() === eventTopic, \"fragment/topic mismatch\", \"topics[0]\", topics[0]);\n topics = topics.slice(1);\n }\n const indexed = [];\n const nonIndexed = [];\n const dynamic = [];\n fragment.inputs.forEach((param, index) => {\n if (param.indexed) {\n if (param.type === \"string\" ||\n param.type === \"bytes\" ||\n param.baseType === \"tuple\" ||\n param.baseType === \"array\") {\n indexed.push(ParamType.from({ type: \"bytes32\", name: param.name }));\n dynamic.push(true);\n }\n else {\n indexed.push(param);\n dynamic.push(false);\n }\n }\n else {\n nonIndexed.push(param);\n dynamic.push(false);\n }\n });\n const resultIndexed = topics != null ? this.#abiCoder.decode(indexed, concat(topics)) : null;\n const resultNonIndexed = this.#abiCoder.decode(nonIndexed, data, true);\n //const result: (Array & { [ key: string ]: any }) = [ ];\n const values = [];\n const keys = [];\n let nonIndexedIndex = 0, indexedIndex = 0;\n fragment.inputs.forEach((param, index) => {\n let value = null;\n if (param.indexed) {\n if (resultIndexed == null) {\n value = new Indexed(null);\n }\n else if (dynamic[index]) {\n value = new Indexed(resultIndexed[indexedIndex++]);\n }\n else {\n try {\n value = resultIndexed[indexedIndex++];\n }\n catch (error) {\n value = error;\n }\n }\n }\n else {\n try {\n value = resultNonIndexed[nonIndexedIndex++];\n }\n catch (error) {\n value = error;\n }\n }\n values.push(value);\n keys.push(param.name || null);\n });\n return Result.fromItems(values, keys);\n }\n /**\n * Parses a transaction, finding the matching function and extracts\n * the parameter values along with other useful function details.\n *\n * If the matching function cannot be found, return null.\n */\n parseTransaction(tx) {\n const data = getBytes(tx.data, \"tx.data\");\n const value = getBigInt(tx.value != null ? tx.value : 0, \"tx.value\");\n const fragment = this.getFunction(hexlify(data.slice(0, 4)));\n if (!fragment) {\n return null;\n }\n const args = this.#abiCoder.decode(fragment.inputs, data.slice(4));\n return new TransactionDescription(fragment, fragment.selector, args, value);\n }\n parseCallResult(data) {\n throw new Error(\"@TODO\");\n }\n /**\n * Parses a receipt log, finding the matching event and extracts\n * the parameter values along with other useful event details.\n *\n * If the matching event cannot be found, returns null.\n */\n parseLog(log) {\n const fragment = this.getEvent(log.topics[0]);\n if (!fragment || fragment.anonymous) {\n return null;\n }\n // @TODO: If anonymous, and the only method, and the input count matches, should we parse?\n // Probably not, because just because it is the only event in the ABI does\n // not mean we have the full ABI; maybe just a fragment?\n return new LogDescription(fragment, fragment.topicHash, this.decodeEventLog(fragment, log.data, log.topics));\n }\n /**\n * Parses a revert data, finding the matching error and extracts\n * the parameter values along with other useful error details.\n *\n * If the matching event cannot be found, returns null.\n */\n parseError(data) {\n const hexData = hexlify(data);\n const fragment = this.getError(dataSlice(hexData, 0, 4));\n if (!fragment) {\n return null;\n }\n const args = this.#abiCoder.decode(fragment.inputs, dataSlice(hexData, 4));\n return new ErrorDescription(fragment, fragment.selector, args);\n }\n /**\n * Creates a new [[Interface]] from the ABI %%value%%.\n *\n * The %%value%% may be provided as an existing [[Interface]] object,\n * a JSON-encoded ABI or any Human-Readable ABI format.\n */\n static from(value) {\n // Already an Interface, which is immutable\n if (value instanceof Interface) {\n return value;\n }\n // JSON\n if (typeof value === \"string\") {\n return new Interface(JSON.parse(value));\n }\n // Maybe an interface from an older version, or from a symlinked copy\n if (typeof value.format === \"function\") {\n return new Interface(value.format(\"json\"));\n }\n // Array of fragments\n return new Interface(value);\n }\n}\n//# sourceMappingURL=interface.js.map","import { concat, \n// dataSlice,\ngetBigInt,\n// encodeRlp\n } from \"../utils/index.js\";\nimport { getAddress } from \"./index.js\";\nimport { sha256 } from \"../crypto/sha3.js\";\nimport { hexDataLength, hexDataSlice } from \"../utils/data.js\";\nimport { Logger } from \"../logger/logger.js\";\nimport { removeHexPrefix } from \"../transaction/address.js\";\nimport { calculateCheckSum } from \"./index.js\";\nconst logger = new Logger(\"contract-address/0.0.1\");\n/**\n * Returns the address that would result from a ``CREATE`` for %%tx%%.\n *\n * This can be used to compute the address a contract will be\n * deployed to by an EOA when sending a deployment transaction (i.e.\n * when the ``to`` address is ``null``).\n *\n * This can also be used to compute the address a contract will be\n * deployed to by a contract, by using the contract's address as the\n * ``to`` and the contract's nonce.\n *\n * @example\n * from = \"0x8ba1f109551bD432803012645Ac136ddd64DBA72\";\n * nonce = 5;\n *\n * getCreateAddress({ from, nonce });\n * //_result:\n */\nexport function getCreateAddress(tx) {\n const from = getAddress(tx.from);\n const nonce = getBigInt(tx.nonce, \"tx.nonce\");\n let nonceHex = nonce.toString(16);\n if (nonceHex === \"0\") {\n nonceHex = \"0x\";\n }\n else if (nonceHex.length % 2) {\n nonceHex = \"0x0\" + nonceHex;\n }\n else {\n nonceHex = \"0x\" + nonceHex;\n }\n return getAddress(from);\n}\n/**\n * Returns the address that would result from a ``CREATE2`` operation\n * with the given %%from%%, %%salt%% and %%initCodeHash%%.\n\n * For a quick overview and example of ``CREATE2``, see [[link-ricmoo-wisps]].\n *\n * @example\n * // The address of the contract\n * from = \"0x8ba1f109551bD432803012645Ac136ddd64DBA72\"\n *\n * // The salt\n * salt = id(\"HelloWorld\")\n *\n * getCreate2Address(from, salt, initCodeHash)\n * //_result:\n */\nexport function getCreate2Address(from, salt, initCodeHash) {\n if (hexDataLength(salt) !== 32) {\n logger.throwArgumentError(\"salt must be 32 bytes\", \"salt\", salt);\n }\n if (hexDataLength(initCodeHash) !== 32) {\n logger.throwArgumentError(\"initCodeHash must be 32 bytes\", \"initCodeHash\", initCodeHash);\n }\n const val = hexDataSlice(sha256(concat([\"0xff\", getAddress(from), salt, initCodeHash])), 12);\n console.log({ \"contract-address/74=>should be string\": val });\n const prefix = from.substring(2, 4);\n const checksum = calculateCheckSum(val, prefix);\n return \"0x\" + prefix + checksum + removeHexPrefix(val);\n}\n//# sourceMappingURL=contract-address.js.map","import { assert, assertArgument } from \"../utils/index.js\";\nimport { getAddress } from \"./index.js\";\n/**\n * Returns true if %%value%% is an object which implements the\n * [[Addressable]] interface.\n *\n * @example:\n * // Wallets and AbstractSigner sub-classes\n * isAddressable(Wallet.createRandom())\n * //_result:\n *\n * // Contracts\n * contract = new Contract(\"dai.tokens.corebc.eth\", [ ], provider)\n * isAddressable(contract)\n * //_result:\n */\nexport function isAddressable(value) {\n return value && typeof value.getAddress === \"function\";\n}\n/**\n * Returns true if %%value%% is a valid address.\n *\n * @example:\n * // Valid address\n * isAddress(\"0x8ba1f109551bD432803012645Ac136ddd64DBA72\")\n * //_result:\n *\n * // Valid ICAP address\n * isAddress(\"XE65GB6LDNXYOFTX0NSV3FUWKOWIXAMJK36\")\n * //_result:\n *\n * // Invalid checksum\n * isAddress(\"0x8Ba1f109551bD432803012645Ac136ddd64DBa72\")\n * //_result:\n *\n * // Invalid ICAP checksum\n * isAddress(\"0x8Ba1f109551bD432803012645Ac136ddd64DBA72\")\n * //_result:\n *\n * // Not an address (an ENS name requires a provided and an\n * // asynchronous API to access)\n * isAddress(\"ricmoo.eth\")\n * //_result:\n */\nexport function isAddress(value) {\n try {\n getAddress(value);\n return true;\n }\n catch (error) { }\n return false;\n}\nasync function checkAddress(target, promise) {\n const result = await promise;\n if (result == null ||\n result === \"0x0000000000000000000000000000000000000000\") {\n assert(typeof target !== \"string\", \"unconfigured name\", \"UNCONFIGURED_NAME\", { value: target });\n assertArgument(false, \"invalid AddressLike value; did not resolve to a value address\", \"target\", target);\n }\n return getAddress(result);\n}\n/**\n * Resolves to an address for the %%target%%, which may be any\n * supported address type, an [[Addressable]] or a Promise which\n * resolves to an address.\n *\n * If an ENS name is provided, but that name has not been correctly\n * configured a [[UnconfiguredNameError]] is thrown.\n *\n * @example:\n * addr = \"0x6B175474E89094C44Da98b954EedeAC495271d0F\"\n *\n * // Addresses are return synchronously\n * resolveAddress(addr, provider)\n * //_result:\n *\n * // Address promises are resolved asynchronously\n * resolveAddress(Promise.resolve(addr))\n * //_result:\n *\n *\n * // Addressable objects are resolved asynchronously\n * contract = new Contract(addr, [ ])\n * resolveAddress(contract, provider)\n * //_result:\n *\n * // Unconfigured ENS names reject\n * resolveAddress(\"nothing-here.ricmoo.eth\", provider)\n * //_error:\n *\n * // ENS names require a NameResolver object passed in\n * // (notice the provider was omitted)\n * resolveAddress(\"nothing-here.ricmoo.eth\")\n * //_error:\n */\nexport function resolveAddress(target) {\n if (typeof target === \"string\") {\n return getAddress(target);\n // assert(resolver != null, \"ENS resolution requires a provider\",\n // \"UNSUPPORTED_OPERATION\", { operation: \"resolveName\" });\n // return checkAddress(target, resolver.resolveName(target));\n }\n else if (isAddressable(target)) {\n return checkAddress(target, target.getAddress());\n }\n else if (target && typeof target.then === \"function\") {\n return checkAddress(target, target);\n }\n assertArgument(false, \"unsupported addressable value\", \"target\", target);\n}\n//# sourceMappingURL=checks.js.map","import { defineProperties, getBigInt, getNumber, hexlify, resolveProperties, assert, assertArgument, isError, makeError, } from \"../utils/index.js\";\nconst BN_0 = BigInt(0);\n// -----------------------\nfunction getValue(value) {\n if (value == null) {\n return null;\n }\n return value;\n}\nfunction toJson(value) {\n if (value == null) {\n return null;\n }\n return value.toString();\n}\n// @TODO?