@ordao/ethers-decode-error
Version:
Decode ethers.js smart contract errors into human-readable messages
3 lines (2 loc) • 5.44 kB
JavaScript
import{Result as r,ErrorDescription as e,AbiCoder as a,ErrorFragment as n,Interface as t}from"ethers";var o;function s(){return s=Object.assign?Object.assign.bind():function(r){for(var e=1;e<arguments.length;e++){var a=arguments[e];for(var n in a)({}).hasOwnProperty.call(a,n)&&(r[n]=a[n])}return r},s.apply(null,arguments)}!function(r){r.EmptyError="EmptyError",r.RevertError="RevertError",r.PanicError="PanicError",r.CustomError="CustomError",r.UserRejectError="UserRejectError",r.RpcError="RpcError",r.UnknownError="UnknownError"}(o||(o={}));const l="0x08c379a0",c="0x4e487b71",i=(r,e)=>r&&""!==r.trim()?r:e,d=({type:a,data:n,reason:t,fragment:o,args:l,selector:c,name:d})=>{let u={type:a,reason:i(t,null),data:null!=n?n:null,fragment:null,args:null!=l?l:new r,selector:null!=c?c:null,name:null!=d?d:null,signature:null};return o&&(u=s({},u,new e(o,o.selector,l))),u},u=({data:r,reason:e,name:a})=>d({type:o.UnknownError,reason:i(e,"Unknown error"),data:r,name:a});class m{predicate(r){return"0x"===r}handle(r){return(({data:r})=>d({type:o.EmptyError,data:r}))({data:r})}}class g{predicate(r){return null==r?void 0:r.startsWith(l)}handle(r){const e=r.slice(10),t=new a;try{const a=n.from("Error(string)"),s=t.decode(a.inputs,`0x${e}`);return(({data:r,reason:e,fragment:a,args:n})=>d({type:o.RevertError,reason:e,data:r,fragment:a,args:n}))({data:r,fragment:a,reason:s[0],args:s})}catch(e){return u({reason:"Unknown error returned",data:r})}}}class p{predicate(r){return null==r?void 0:r.startsWith(c)}handle(r){const e=r.slice(10),t=new a;try{var s;const a=n.from("Panic(uint256)"),l=t.decode(a.inputs,`0x${e}`);return(({data:r,reason:e,args:a})=>d({type:o.PanicError,reason:e,data:r,args:a}))({data:r,fragment:a,reason:null!=(s=(r=>{switch(r){case 0x0n:return"Generic compiler inserted panic";case 0x1n:return"Assertion error";case 0x11n:return"Arithmetic operation underflowed or overflowed outside of an unchecked block";case 0x12n:return"Division or modulo division by zero";case 0x21n:return"Tried to convert a value into an enum, but the value was too big or negative";case 0x22n:return"Incorrectly encoded storage byte array";case 0x31n:return".pop() was called on an empty array";case 0x32n:return"Array accessed at an out-of-bounds or negative index";case 0x41n:return"Too much memory was allocated, or an array was created that is too large";case 0x51n:return"Called a zero-initialized variable of internal function type"}})(l[0]))?s:"Unknown panic code",args:l})}catch(e){return u({reason:"Unknown panic error",data:r})}}}class f{predicate(r){return r&&"0x"!==r&&!(null!=r&&r.startsWith(l))&&!(null!=r&&r.startsWith(c))}handle(r,{errorInterface:e}){let a={data:r};if(e){const n=e.parseError(r);if(n){const{fragment:r,args:e,name:t}=n;a=s({},a,{fragment:r,reason:t,args:e})}}return(({data:r,reason:e,fragment:a,args:n})=>{const t=r.slice(0,10);return d({type:o.CustomError,reason:i(e,`No ABI for custom error ${t}`),data:r,fragment:a,args:n,selector:t,name:t})})(a)}}class v{predicate(r,e){var a;return!r&&(null==e||null==(a=e.message)?void 0:a.includes("rejected transaction"))}handle(r,{error:e}){var a;return(({data:r=null,reason:e})=>d({type:o.UserRejectError,reason:i(e,"User has rejected the transaction"),data:r}))({data:null,reason:null!=(a=e.message)?a:"The transaction was rejected"})}}class h{predicate(r,e){var a;return!r&&e.message&&!(null!=e&&null!=(a=e.message)&&a.includes("rejected transaction"))&&void 0!==e.code}handle(r,{error:e}){var a,n,t;const s=null!=(a=null!=(n=null==(t=e.info)||null==(t=t.error)?void 0:t.message)?n:e.shortMessage)?a:e.message;return(({reason:r,name:e})=>{var a;return d({type:o.RpcError,reason:i(r,"Error from JSON RPC provider"),data:null,name:null!=(a=null==e?void 0:e.toString())?a:null})})({data:null,name:e.code,reason:s})}}class E{constructor(r,e){this.errorInterface=void 0,this.errorHandlers=[],this.errorInterface=e,this.errorHandlers=r.map(r=>({predicate:r.predicate,handle:r.handle}))}async getContractOrTransactionError(r){const e=r.receipt;return e&&await this.getTransactionError(e)||r}async getTransactionError(r){if(!r||0!==r.status)return;const e=r.hash,a=r.provider,n=await a.getTransaction(e);try{return await a.call(s({},n,{maxFeePerGas:void 0,maxPriorityFeePerGas:void 0})),null}catch(r){return r}}getDataFromError(r){var e,a;const n=null!=(e=r.data)?e:null==(a=r.error)?void 0:a.data;if(void 0===n)return;let t="string"==typeof n?n:n.data;return"object"==typeof t&&t.data&&(t=t.data),void 0!==t&&"string"==typeof t?t:void 0}decodeError(r,e){var a;for(const{predicate:a,handle:n}of this.errorHandlers)if(a(r,e))return n(r,{errorInterface:this.errorInterface,error:e});return u({data:r,reason:null!=(a=null==e?void 0:e.message)?a:"Unexpected error",name:null==e?void 0:e.name})}decodeReturnData(r){return this.decodeError(r,new Error)}async decode(r){var e;if(!(r instanceof Error))return u({data:void 0,reason:null!=(e=r.message)?e:"Invalid error"});const a=await this.getContractOrTransactionError(r),n=this.getDataFromError(a);return this.decodeError(n,a)}static create(r,e={}){const{additionalErrorHandlers:a}=e;let o;if(r){const e=r.flatMap(r=>r instanceof t?r.fragments.filter(r=>n.isFragment(r)):r.filter(r=>"error"===r.type||n.isFragment(r)));o=new t(e)}const s=[new m,new g,new p,new f,new v,new h,...null!=a?a:[]];return new E(s,o)}}const y="1.2.2";export{E as ErrorDecoder,o as ErrorType,y as PACKAGE_VERSION};
//# sourceMappingURL=index.modern.mjs.map