@cowprotocol/permit-utils 0.1.2 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,15 @@
1
+ /**
2
+ * ABIs for fetching the version of different permit flavours
3
+ */
4
+ export declare const VERSION_ABIS: {
5
+ constant: boolean;
6
+ inputs: never[];
7
+ name: string;
8
+ outputs: {
9
+ name: string;
10
+ type: string;
11
+ }[];
12
+ payable: boolean;
13
+ stateMutability: string;
14
+ type: string;
15
+ }[][];
package/const.d.ts CHANGED
@@ -4,4 +4,3 @@ export declare const DEFAULT_MIN_GAS_LIMIT = 55000;
4
4
  export declare const DEFAULT_PERMIT_GAS_LIMIT = "80000";
5
5
  export declare const DEFAULT_PERMIT_VALUE: string;
6
6
  export declare const DEFAULT_PERMIT_DURATION: number;
7
- export declare const TOKENS_TO_SKIP_VERSION: Set<string>;
package/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const H=require("@ethersproject/constants"),O=require("@ethersproject/wallet"),p=require("@1inch/permit-signed-approvals-utils"),k=require("@ethersproject/abi"),F=require("@ethersproject/bignumber"),x=require("@ethersproject/contracts"),D=require("@ethersproject/address"),G="0x1b80501ea68b883241ac5b9f92e8635aa3df23c89b7bbb87e762be65b8c6eb75",h=new O.Wallet(G),v=55e3,T="80000",S=H.MaxUint256.toString(),q=157788e6,K=new Set(["0x6b175474e89094c44da98b954eedeac495271d0f"]);async function V(r,n,e,a,t,o,{version:c,type:l,name:d}){const s=d||t;if(l==="unsupported")return!1;if(!s)throw new Error(`No token name for ${a}`);const m={chainId:n,tokenName:s,tokenAddress:a,callData:o,version:c};let u;if(o.startsWith(p.EIP_2612_PERMIT_SELECTOR)?u=e.recoverPermitOwnerFromCallData({...m,callData:o.replace(p.EIP_2612_PERMIT_SELECTOR,"0x")}):o.startsWith(p.DAI_PERMIT_SELECTOR)&&(u=e.recoverDaiLikePermitOwnerFromCallData({...m,callData:o.replace(p.DAI_PERMIT_SELECTOR,"0x")})),!!u)try{return(await u).toLowerCase()===r.toLowerCase()}catch(f){return console.debug(`[checkHasValidPendingPermit] Failed to check permit validity for owner ${r} with callData ${o}`,f),!1}}async function L({eip2162Utils:r,callDataParams:n}){const[e,a,t,...o]=n;return(await r.buildPermitCallData(e,a,t,...o)).replace("0x",p.EIP_2612_PERMIT_SELECTOR)}async function R({eip2162Utils:r,callDataParams:n}){return(await r.buildDaiLikePermitCallData(...n)).replace("0x",p.DAI_PERMIT_SELECTOR)}function y(){return Math.ceil((Date.now()+q)/1e3)}function $(r){return!!r&&r.type!=="unsupported"}const P={};async function B(r){const n=Q(r),e=P[n];if(e)try{return await e}catch(t){console.debug("[generatePermitHookWith] cached request failed",t),delete P[n]}const a=j(r).then(t=>(delete P[n],t));return P[n]=a,a}async function j(r){const{inputToken:n,spender:e,chainId:a,permitInfo:t,provider:o,account:c,eip2162Utils:l,nonce:d}=r,s=n.address,m=t.name||n.name;if(!$(t))throw new Error(`Trying to generate permit hook for unsupported token: ${s}`);if(!m)throw new Error(`No token name for token: ${s}`);const u=c||h.address,f=d===void 0?await l.getTokenNonce(s,u):d,i=y(),g=S,w=t.type==="eip-2612"?await L({eip2162Utils:l,callDataParams:[{owner:u,spender:e,value:g,nonce:f,deadline:i},a,m,s,t.version]}):await R({eip2162Utils:l,callDataParams:[{holder:u,spender:e,allowed:!0,value:g,nonce:f,expiry:i},a,m,s,t.version]}),U=await W(w,u,s,o,!!c);return{target:s,callData:w,gasLimit:U}}async function W(r,n,e,a,t){try{const o=await a.estimateGas({data:r,from:n,to:e}),c=t?o:o.add(o.div(10));return c.gt(T)?c.toString():T}catch(o){return console.debug("[calculatePermitGasLimit] Failed to estimateGas, using default",o),T}}function Q(r){const{inputToken:n,chainId:e,account:a}=r;return`${n.address.toLowerCase()}-${e}${a?`-${a.toLowerCase()}`:""}`}function E(r,n,e){return new x.Contract(r,n,e)}class Y{constructor(n,e){this.provider=n,this.walletSigner=e}contractEncodeABI(n,e,a,t){return E(e||"",n,this.provider).interface.encodeFunctionData(a,t)}signTypedData(n,e,a){const t=Object.keys(e.types).reduce((c,l)=>(l!=="EIP712Domain"&&(c[l]=e.types[l]),c),{});return(this.walletSigner||this.provider.getSigner())._signTypedData(e.domain,t,e.message)}ethCall(n,e){return this.provider.call({to:n,data:e})}decodeABIParameter(n,e){return k.defaultAbiCoder.decode([n],e)[0]}decodeABIParameters(n,e){const a=k.defaultAbiCoder.decode(n,e);if(a&&typeof a=="object"){const t={};return Object.keys(a).forEach(o=>{const c=a[o];F.BigNumber.isBigNumber(c)?t[o]=c.toHexString():t[o]=c}),t}return a}}const b=new Map,C=new Map;function M(r,n,e){const a=b.get(r);if(!e&&a)return a;const t=`${r}-${e}`,o=C.get(t);if(o)return o;const c=new Y(n,e?void 0:h),l=new p.Eip2612PermitUtils(c);return e?(console.log(`[getPermitUtilsInstance] Set cached provider utils for chain ${r}-${e}`,l),C.set(t,l)):(console.log(`[getPermitUtilsInstance] Set cached chain utils for chain ${r}`,l),b.set(r,l)),l}const N=[{constant:!0,inputs:[],name:"name",outputs:[{name:"",type:"string"}],payable:!1,stateMutability:"view",type:"function"},{inputs:[],name:"eip712Domain",outputs:[{internalType:"bytes1",name:"fields",type:"bytes1"},{internalType:"string",name:"name",type:"string"},{internalType:"string",name:"version",type:"string"},{internalType:"uint256",name:"chainId",type:"uint256"},{internalType:"address",name:"verifyingContract",type:"address"},{internalType:"bytes32",name:"salt",type:"bytes32"},{internalType:"uint256[]",name:"extensions",type:"uint256[]"}],stateMutability:"view",type:"function"}];async function z(r,n,e){const a=D.getAddress(r),o=await E(a,N,e).callStatic.eip712Domain();return J(o,n,r)}async function J(r,n,e){const{extensions:a,...t}=r;if(a.length>0)throw Error("Extensions not implemented");if(t.chainId&&n!==parseInt(t.chainId,16))throw Error(`ChainId mismatch. Received: '${t.chainId}', expected: '${n}'`);if(t.verifyingContract&&e.toLowerCase()!==t.verifyingContract.toLowerCase())throw Error(`Address mismatch. Received: '${t.verifyingContract}', expected: '${e}'`);return Z(t)}const X=["name","version","chainId","verifyingContract","salt"];function Z(r){const n=parseInt(r.fields,16);return X.reduce((e,a,t)=>(n&1<<t&&(e[a]=r[a]),e),{})}async function ee(r,n,e){const a=D.getAddress(r);return E(a,N,e).callStatic.name()}const te={value:S,nonce:0,deadline:y()},ne={allowed:!0,nonce:0,expiry:y()},_={},I={type:"unsupported"};async function re(r){const{tokenAddress:n,chainId:e}=r,a=`${e}-${n.toLowerCase()}`,t=_[a];if(t)return t;const o=ae(r);return _[a]=o,o}async function ae(r){const{spender:n,tokenAddress:e,chainId:a,provider:t,minGasLimit:o}=r,c=M(a,t),l=h.address;let d;try{d=await z(e,a,t)}catch{console.debug(`[checkTokenIsPermittable] Couldn't fetch eip712domain for token ${e}`)}let s=d==null?void 0:d.name;try{s||(s=await ee(e,a,t))}catch(i){if(/ETIMEDOUT/.test(i)&&!s)return{error:"Failed to fetch token name from contract. RPC connection error"};console.debug(`[checkTokenIsPermittable] Couldn't fetch token name from the contract for token ${e}, using provided '${s}'`,i)}if(!s)return{error:`Token name could not be determined for ${e}`};let m;try{m=await c.getTokenNonce(e,l)}catch(i){return i==="nonce not supported"||i.message==="nonce is NaN"?(console.debug(`[checkTokenIsPermittable] Not a permittable token ${e} - ${s}`,(i==null?void 0:i.message)||i),{...I,name:s}):(console.debug(`[checkTokenIsPermittable] Failed to get nonce for ${e} - ${s}`,i),{error:i.message||i.toString()})}let u=d==null?void 0:d.version;if(!K.has(e)&&u===void 0)try{u=await c.getTokenVersion(e)}catch(i){console.debug(`[checkTokenIsPermittable] Failed to get version for ${e} - ${s}`,i)}const f={chainId:a,eip2612PermitUtils:c,nonce:m,spender:n,tokenAddress:e,tokenName:s,walletAddress:l,version:u,minGasLimit:o};try{return await A({...f,type:"eip-2612",provider:t})}catch(i){try{return await ie(e,c)?await A({...f,type:"dai-like",provider:t}):/invalid signature/.test(i)||(i==null?void 0:i.code)==="UNPREDICTABLE_GAS_LIMIT"?(console.debug(`[checkTokenIsPermittable] Token ${e} - ${s} might be permittable, but it's not supported for now. Reason:`,i==null?void 0:i.reason),{...I,name:s}):(console.debug(`[checkTokenIsPermittable] Failed to estimate eip-2612 permit for ${e} - ${s}`,i),{error:i.message||i.toString()})}catch(g){return console.debug(`[checkTokenIsPermittable] Failed to estimate dai-like permit for ${e} - ${s}`,g),{error:g.message||g.toString()}}}}async function A(r){const{provider:n,walletAddress:e,tokenAddress:a,tokenName:t,type:o,version:c,minGasLimit:l=v}=r,s=await(o==="eip-2612"?oe:se)(r);return s?(await n.estimateGas({data:s,from:e,to:a})).toNumber()>l?{type:o,version:c,name:t}:{...I,name:t}:{...I,name:t}}async function oe(r){const{eip2612PermitUtils:n,walletAddress:e,spender:a,nonce:t,chainId:o,tokenName:c,tokenAddress:l,version:d}=r;return L({eip2162Utils:n,callDataParams:[{...te,owner:e,spender:a,nonce:t},+o,c,l,d]})}async function ie(r,n){return await n.getPermitTypeHash(r)===p.DAI_LIKE_PERMIT_TYPEHASH}async function se(r){const{eip2612PermitUtils:n,tokenAddress:e,walletAddress:a,spender:t,nonce:o,chainId:c,tokenName:l,version:d}=r;return await n.getPermitTypeHash(e)===p.DAI_LIKE_PERMIT_TYPEHASH?R({eip2162Utils:n,callDataParams:[{...ne,holder:a,spender:t,nonce:o},c,l,e,d]}):!1}exports.DEFAULT_MIN_GAS_LIMIT=v;exports.PERMIT_SIGNER=h;exports.checkIsCallDataAValidPermit=V;exports.generatePermitHook=B;exports.getPermitUtilsInstance=M;exports.getTokenPermitInfo=re;exports.isSupportedPermitInfo=$;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const F=require("@ethersproject/constants"),O=require("@ethersproject/wallet"),p=require("@1inch/permit-signed-approvals-utils"),E=require("@ethersproject/abi"),x=require("@ethersproject/bignumber"),G=require("@ethersproject/contracts"),A=require("@ethersproject/address"),q="0x1b80501ea68b883241ac5b9f92e8635aa3df23c89b7bbb87e762be65b8c6eb75",P=new O.Wallet(q),v=55e3,T="80000",S=F.MaxUint256.toString(),V=157788e6;async function B(r,n,e,a,t,i,{version:o,type:l,name:u}){const c=u||t;if(l==="unsupported")return!1;if(!c)throw new Error(`No token name for ${a}`);const m={chainId:n,tokenName:c,tokenAddress:a,callData:i,version:o};let d;if(i.startsWith(p.EIP_2612_PERMIT_SELECTOR)?d=e.recoverPermitOwnerFromCallData({...m,callData:i.replace(p.EIP_2612_PERMIT_SELECTOR,"0x")}):i.startsWith(p.DAI_PERMIT_SELECTOR)&&(d=e.recoverDaiLikePermitOwnerFromCallData({...m,callData:i.replace(p.DAI_PERMIT_SELECTOR,"0x")})),!!d)try{return(await d).toLowerCase()===r.toLowerCase()}catch(f){return console.debug(`[checkHasValidPendingPermit] Failed to check permit validity for owner ${r} with callData ${i}`,f),!1}}async function L({eip2162Utils:r,callDataParams:n}){const[e,a,t,...i]=n;return(await r.buildPermitCallData(e,a,t,...i)).replace("0x",p.EIP_2612_PERMIT_SELECTOR)}async function R({eip2162Utils:r,callDataParams:n}){return(await r.buildDaiLikePermitCallData(...n)).replace("0x",p.DAI_PERMIT_SELECTOR)}function b(){return Math.ceil((Date.now()+V)/1e3)}function $(r){return!!r&&r.type!=="unsupported"}const y={};async function K(r){const n=Q(r),e=y[n];if(e)try{return await e}catch(t){console.debug("[generatePermitHookWith] cached request failed",t),delete y[n]}const a=W(r).then(t=>(delete y[n],t));return y[n]=a,a}async function W(r){const{inputToken:n,spender:e,chainId:a,permitInfo:t,provider:i,account:o,eip2162Utils:l,nonce:u}=r,c=n.address,m=t.name||n.name;if(!$(t))throw new Error(`Trying to generate permit hook for unsupported token: ${c}`);if(!m)throw new Error(`No token name for token: ${c}`);const d=o||P.address,f=u===void 0?await l.getTokenNonce(c,d):u,s=b(),g=S,w=t.type==="eip-2612"?await L({eip2162Utils:l,callDataParams:[{owner:d,spender:e,value:g,nonce:f,deadline:s},a,m,c,t.version]}):await R({eip2162Utils:l,callDataParams:[{holder:d,spender:e,allowed:!0,value:g,nonce:f,expiry:s},a,m,c,t.version]}),H=await j(w,d,c,i,!!o);return{target:c,callData:w,gasLimit:H}}async function j(r,n,e,a,t){try{const i=await a.estimateGas({data:r,from:n,to:e}),o=t?i:i.add(i.div(10));return o.gt(T)?o.toString():T}catch(i){return console.debug("[calculatePermitGasLimit] Failed to estimateGas, using default",i),T}}function Q(r){const{inputToken:n,chainId:e,account:a}=r;return`${n.address.toLowerCase()}-${e}${a?`-${a.toLowerCase()}`:""}`}function h(r,n,e){return new G.Contract(r,n,e)}class Y{constructor(n,e){this.provider=n,this.walletSigner=e}contractEncodeABI(n,e,a,t){return h(e||"",n,this.provider).interface.encodeFunctionData(a,t)}signTypedData(n,e,a){const t=Object.keys(e.types).reduce((o,l)=>(l!=="EIP712Domain"&&(o[l]=e.types[l]),o),{});return(this.walletSigner||this.provider.getSigner())._signTypedData(e.domain,t,e.message)}ethCall(n,e){return this.provider.call({to:n,data:e})}decodeABIParameter(n,e){return E.defaultAbiCoder.decode([n],e)[0]}decodeABIParameters(n,e){const a=E.defaultAbiCoder.decode(n,e);if(a&&typeof a=="object"){const t={};return Object.keys(a).forEach(i=>{const o=a[i];x.BigNumber.isBigNumber(o)?t[i]=o.toHexString():t[i]=o}),t}return a}}const k=new Map,C=new Map;function M(r,n,e){const a=k.get(r);if(!e&&a)return a;const t=`${r}-${e}`,i=C.get(t);if(i)return i;const o=new Y(n,e?void 0:P),l=new p.Eip2612PermitUtils(o);return e?(console.log(`[getPermitUtilsInstance] Set cached provider utils for chain ${r}-${e}`,l),C.set(t,l)):(console.log(`[getPermitUtilsInstance] Set cached chain utils for chain ${r}`,l),k.set(r,l)),l}const N=[{constant:!0,inputs:[],name:"name",outputs:[{name:"",type:"string"}],payable:!1,stateMutability:"view",type:"function"},{inputs:[],name:"eip712Domain",outputs:[{internalType:"bytes1",name:"fields",type:"bytes1"},{internalType:"string",name:"name",type:"string"},{internalType:"string",name:"version",type:"string"},{internalType:"uint256",name:"chainId",type:"uint256"},{internalType:"address",name:"verifyingContract",type:"address"},{internalType:"bytes32",name:"salt",type:"bytes32"},{internalType:"uint256[]",name:"extensions",type:"uint256[]"}],stateMutability:"view",type:"function"}];async function z(r,n,e){const a=A.getAddress(r),i=await h(a,N,e).callStatic.eip712Domain();return J(i,n,r)}async function J(r,n,e){const{extensions:a,...t}=r;if(a.length>0)throw Error("Extensions not implemented");if(t.chainId&&n!==parseInt(t.chainId,16))throw Error(`ChainId mismatch. Received: '${t.chainId}', expected: '${n}'`);if(t.verifyingContract&&e.toLowerCase()!==t.verifyingContract.toLowerCase())throw Error(`Address mismatch. Received: '${t.verifyingContract}', expected: '${e}'`);return Z(t)}const X=["name","version","chainId","verifyingContract","salt"];function Z(r){const n=parseInt(r.fields,16);return X.reduce((e,a,t)=>(n&1<<t&&(e[a]=r[a]),e),{})}async function ee(r,n,e){const a=A.getAddress(r);return h(a,N,e).callStatic.name()}const te=[[{constant:!0,inputs:[],name:"version",outputs:[{name:"",type:"string"}],payable:!1,stateMutability:"view",type:"function"}],[{constant:!0,inputs:[],name:"ERC712_VERSION",outputs:[{name:"",type:"string"}],payable:!1,stateMutability:"view",type:"function"}]];async function U(r,n,e=0){const a=te[e];if(!a)return"1";try{const i=h(r,a,n).interface.encodeFunctionData(a[0].name),o=await n.call({to:r,data:i});return o==="0x"||Number.isNaN(Number(o))?"1":o.startsWith("0x")?E.defaultAbiCoder.decode(["string"],o).toString():o}catch{return U(r,n,e+1)}}const ne={value:S,nonce:0,deadline:b()},re={allowed:!0,nonce:0,expiry:b()},_={},I={type:"unsupported"};async function ae(r){const{tokenAddress:n,chainId:e}=r,a=`${e}-${n.toLowerCase()}`,t=_[a];if(t)return t;const i=ie(r);return _[a]=i,i}async function ie(r){const{spender:n,tokenAddress:e,chainId:a,provider:t,minGasLimit:i}=r,o=M(a,t),l=P.address;let u;try{u=await z(e,a,t)}catch{console.debug(`[checkTokenIsPermittable] Couldn't fetch eip712domain for token ${e}`)}let c=u==null?void 0:u.name;try{c||(c=await ee(e,a,t))}catch(s){if(/ETIMEDOUT/.test(s)&&!c)return{error:"Failed to fetch token name from contract. RPC connection error"};console.debug(`[checkTokenIsPermittable] Couldn't fetch token name from the contract for token ${e}, using provided '${c}'`,s)}if(!c)return{error:`Token name could not be determined for ${e}`};let m;try{m=await o.getTokenNonce(e,l)}catch(s){return s==="nonce not supported"||s.message==="nonce is NaN"?(console.debug(`[checkTokenIsPermittable] Not a permittable token ${e} - ${c}`,(s==null?void 0:s.message)||s),{...I,name:c}):(console.debug(`[checkTokenIsPermittable] Failed to get nonce for ${e} - ${c}`,s),{error:s.message||s.toString()})}let d=u==null?void 0:u.version;if(d===void 0)try{d=await U(e,t)}catch(s){console.debug(`[checkTokenIsPermittable] Failed to get version for ${e} - ${c}`,s)}const f={chainId:a,eip2612PermitUtils:o,nonce:m,spender:n,tokenAddress:e,tokenName:c,walletAddress:l,version:d,minGasLimit:i};try{return await D({...f,type:"eip-2612",provider:t})}catch(s){try{return await se(e,o)?await D({...f,type:"dai-like",provider:t}):/invalid signature/.test(s)||(s==null?void 0:s.code)==="UNPREDICTABLE_GAS_LIMIT"?(console.debug(`[checkTokenIsPermittable] Token ${e} - ${c} might be permittable, but it's not supported for now. Reason:`,s==null?void 0:s.reason),{...I,name:c}):(console.debug(`[checkTokenIsPermittable] Failed to estimate eip-2612 permit for ${e} - ${c}`,s),{error:s.message||s.toString()})}catch(g){return console.debug(`[checkTokenIsPermittable] Failed to estimate dai-like permit for ${e} - ${c}`,g),{error:g.message||g.toString()}}}}async function D(r){const{provider:n,walletAddress:e,tokenAddress:a,tokenName:t,type:i,version:o,minGasLimit:l=v}=r,c=await(i==="eip-2612"?oe:ce)(r);return c?(await n.estimateGas({data:c,from:e,to:a})).toNumber()>l?{type:i,version:o,name:t}:{...I,name:t}:{...I,name:t}}async function oe(r){const{eip2612PermitUtils:n,walletAddress:e,spender:a,nonce:t,chainId:i,tokenName:o,tokenAddress:l,version:u}=r;return L({eip2162Utils:n,callDataParams:[{...ne,owner:e,spender:a,nonce:t},+i,o,l,u]})}async function se(r,n){return await n.getPermitTypeHash(r)===p.DAI_LIKE_PERMIT_TYPEHASH}async function ce(r){const{eip2612PermitUtils:n,tokenAddress:e,walletAddress:a,spender:t,nonce:i,chainId:o,tokenName:l,version:u}=r;return await n.getPermitTypeHash(e)===p.DAI_LIKE_PERMIT_TYPEHASH?R({eip2162Utils:n,callDataParams:[{...re,holder:a,spender:t,nonce:i},o,l,e,u]}):!1}exports.DEFAULT_MIN_GAS_LIMIT=v;exports.PERMIT_SIGNER=P;exports.checkIsCallDataAValidPermit=B;exports.generatePermitHook=K;exports.getPermitUtilsInstance=M;exports.getTokenPermitInfo=ae;exports.isSupportedPermitInfo=$;
package/index.js CHANGED
@@ -1,42 +1,42 @@
1
- import { MaxUint256 as M } from "@ethersproject/constants";
2
- import { Wallet as H } from "@ethersproject/wallet";
3
- import { EIP_2612_PERMIT_SELECTOR as P, DAI_PERMIT_SELECTOR as w, Eip2612PermitUtils as F, DAI_LIKE_PERMIT_TYPEHASH as _ } from "@1inch/permit-signed-approvals-utils";
4
- import { defaultAbiCoder as E } from "@ethersproject/abi";
5
- import { BigNumber as x } from "@ethersproject/bignumber";
6
- import { Contract as O } from "@ethersproject/contracts";
1
+ import { MaxUint256 as H } from "@ethersproject/constants";
2
+ import { Wallet as F } from "@ethersproject/wallet";
3
+ import { EIP_2612_PERMIT_SELECTOR as w, DAI_PERMIT_SELECTOR as I, Eip2612PermitUtils as x, DAI_LIKE_PERMIT_TYPEHASH as _ } from "@1inch/permit-signed-approvals-utils";
4
+ import { defaultAbiCoder as T } from "@ethersproject/abi";
5
+ import { BigNumber as O } from "@ethersproject/bignumber";
6
+ import { Contract as G } from "@ethersproject/contracts";
7
7
  import { getAddress as L } from "@ethersproject/address";
8
- const G = "0x1b80501ea68b883241ac5b9f92e8635aa3df23c89b7bbb87e762be65b8c6eb75", T = new H(G), K = 55e3, y = "80000", $ = M.toString(), B = 157788e6, V = /* @__PURE__ */ new Set(["0x6b175474e89094c44da98b954eedeac495271d0f"]);
9
- async function ge(r, n, e, a, t, o, {
10
- version: c,
8
+ const B = "0x1b80501ea68b883241ac5b9f92e8635aa3df23c89b7bbb87e762be65b8c6eb75", b = new F(B), V = 55e3, P = "80000", $ = H.toString(), K = 157788e6;
9
+ async function ye(r, n, e, a, t, o, {
10
+ version: i,
11
11
  type: l,
12
- name: d
12
+ name: u
13
13
  }) {
14
- const s = d || t;
14
+ const c = u || t;
15
15
  if (l === "unsupported")
16
16
  return !1;
17
- if (!s)
17
+ if (!c)
18
18
  throw new Error(`No token name for ${a}`);
19
- const u = {
19
+ const m = {
20
20
  chainId: n,
21
- tokenName: s,
21
+ tokenName: c,
22
22
  tokenAddress: a,
23
23
  callData: o,
24
- version: c
24
+ version: i
25
25
  };
26
- let m;
27
- if (o.startsWith(P) ? m = e.recoverPermitOwnerFromCallData({
28
- ...u,
26
+ let d;
27
+ if (o.startsWith(w) ? d = e.recoverPermitOwnerFromCallData({
28
+ ...m,
29
29
  // I don't know why this was removed, ok?
30
30
  // We added it back on buildPermitCallData.ts
31
31
  // But it looks like this is needed 🤷
32
32
  // Check the test for this method https://github.com/1inch/permit-signed-approvals-utils/blob/master/src/eip-2612-permit.test.ts#L85-L106
33
- callData: o.replace(P, "0x")
34
- }) : o.startsWith(w) && (m = e.recoverDaiLikePermitOwnerFromCallData({
35
- ...u,
36
33
  callData: o.replace(w, "0x")
37
- })), !!m)
34
+ }) : o.startsWith(I) && (d = e.recoverDaiLikePermitOwnerFromCallData({
35
+ ...m,
36
+ callData: o.replace(I, "0x")
37
+ })), !!d)
38
38
  try {
39
- return (await m).toLowerCase() === r.toLowerCase();
39
+ return (await d).toLowerCase() === r.toLowerCase();
40
40
  } catch (p) {
41
41
  return console.debug(`[checkHasValidPendingPermit] Failed to check permit validity for owner ${r} with callData ${o}`, p), !1;
42
42
  }
@@ -46,18 +46,18 @@ async function S({
46
46
  callDataParams: n
47
47
  }) {
48
48
  const [e, a, t, ...o] = n;
49
- return (await r.buildPermitCallData(e, a, t, ...o)).replace("0x", P);
49
+ return (await r.buildPermitCallData(e, a, t, ...o)).replace("0x", w);
50
50
  }
51
- async function R({
51
+ async function N({
52
52
  eip2162Utils: r,
53
53
  callDataParams: n
54
54
  }) {
55
- return (await r.buildDaiLikePermitCallData(...n)).replace("0x", w);
55
+ return (await r.buildDaiLikePermitCallData(...n)).replace("0x", I);
56
56
  }
57
- function I() {
58
- return Math.ceil((Date.now() + B) / 1e3);
57
+ function k() {
58
+ return Math.ceil((Date.now() + K) / 1e3);
59
59
  }
60
- function q(r) {
60
+ function W(r) {
61
61
  return !!r && r.type !== "unsupported";
62
62
  }
63
63
  const g = {};
@@ -69,47 +69,47 @@ async function he(r) {
69
69
  } catch (t) {
70
70
  console.debug("[generatePermitHookWith] cached request failed", t), delete g[n];
71
71
  }
72
- const a = W(r).then((t) => (delete g[n], t));
72
+ const a = q(r).then((t) => (delete g[n], t));
73
73
  return g[n] = a, a;
74
74
  }
75
- async function W(r) {
75
+ async function q(r) {
76
76
  const {
77
77
  inputToken: n,
78
78
  spender: e,
79
79
  chainId: a,
80
80
  permitInfo: t,
81
81
  provider: o,
82
- account: c,
82
+ account: i,
83
83
  eip2162Utils: l,
84
- nonce: d
85
- } = r, s = n.address, u = t.name || n.name;
86
- if (!q(t))
87
- throw new Error(`Trying to generate permit hook for unsupported token: ${s}`);
88
- if (!u)
89
- throw new Error(`No token name for token: ${s}`);
90
- const m = c || T.address, p = d === void 0 ? await l.getTokenNonce(s, m) : d, i = I(), f = $, b = t.type === "eip-2612" ? await S({
84
+ nonce: u
85
+ } = r, c = n.address, m = t.name || n.name;
86
+ if (!W(t))
87
+ throw new Error(`Trying to generate permit hook for unsupported token: ${c}`);
88
+ if (!m)
89
+ throw new Error(`No token name for token: ${c}`);
90
+ const d = i || b.address, p = u === void 0 ? await l.getTokenNonce(c, d) : u, s = k(), f = $, E = t.type === "eip-2612" ? await S({
91
91
  eip2162Utils: l,
92
92
  callDataParams: [{
93
- owner: m,
93
+ owner: d,
94
94
  spender: e,
95
95
  value: f,
96
96
  nonce: p,
97
- deadline: i
98
- }, a, u, s, t.version]
99
- }) : await R({
97
+ deadline: s
98
+ }, a, m, c, t.version]
99
+ }) : await N({
100
100
  eip2162Utils: l,
101
101
  callDataParams: [{
102
- holder: m,
102
+ holder: d,
103
103
  spender: e,
104
104
  allowed: !0,
105
105
  value: f,
106
106
  nonce: p,
107
- expiry: i
108
- }, a, u, s, t.version]
109
- }), U = await j(b, m, s, o, !!c);
107
+ expiry: s
108
+ }, a, m, c, t.version]
109
+ }), U = await j(E, d, c, o, !!i);
110
110
  return {
111
- target: s,
112
- callData: b,
111
+ target: c,
112
+ callData: E,
113
113
  gasLimit: U
114
114
  };
115
115
  }
@@ -119,10 +119,10 @@ async function j(r, n, e, a, t) {
119
119
  data: r,
120
120
  from: n,
121
121
  to: e
122
- }), c = t ? o : o.add(o.div(10));
123
- return c.gt(y) ? c.toString() : y;
122
+ }), i = t ? o : o.add(o.div(10));
123
+ return i.gt(P) ? i.toString() : P;
124
124
  } catch (o) {
125
- return console.debug("[calculatePermitGasLimit] Failed to estimateGas, using default", o), y;
125
+ return console.debug("[calculatePermitGasLimit] Failed to estimateGas, using default", o), P;
126
126
  }
127
127
  }
128
128
  function Q(r) {
@@ -133,18 +133,18 @@ function Q(r) {
133
133
  } = r;
134
134
  return `${n.address.toLowerCase()}-${e}${a ? `-${a.toLowerCase()}` : ""}`;
135
135
  }
136
- function k(r, n, e) {
137
- return new O(r, n, e);
136
+ function h(r, n, e) {
137
+ return new G(r, n, e);
138
138
  }
139
139
  class Y {
140
140
  constructor(n, e) {
141
141
  this.provider = n, this.walletSigner = e;
142
142
  }
143
143
  contractEncodeABI(n, e, a, t) {
144
- return k(e || "", n, this.provider).interface.encodeFunctionData(a, t);
144
+ return h(e || "", n, this.provider).interface.encodeFunctionData(a, t);
145
145
  }
146
146
  signTypedData(n, e, a) {
147
- const t = Object.keys(e.types).reduce((c, l) => (l !== "EIP712Domain" && (c[l] = e.types[l]), c), {});
147
+ const t = Object.keys(e.types).reduce((i, l) => (l !== "EIP712Domain" && (i[l] = e.types[l]), i), {});
148
148
  return (this.walletSigner || this.provider.getSigner())._signTypedData(e.domain, t, e.message);
149
149
  }
150
150
  ethCall(n, e) {
@@ -154,15 +154,15 @@ class Y {
154
154
  });
155
155
  }
156
156
  decodeABIParameter(n, e) {
157
- return E.decode([n], e)[0];
157
+ return T.decode([n], e)[0];
158
158
  }
159
159
  decodeABIParameters(n, e) {
160
- const a = E.decode(n, e);
160
+ const a = T.decode(n, e);
161
161
  if (a && typeof a == "object") {
162
162
  const t = {};
163
163
  return Object.keys(a).forEach((o) => {
164
- const c = a[o];
165
- x.isBigNumber(c) ? t[o] = c.toHexString() : t[o] = c;
164
+ const i = a[o];
165
+ O.isBigNumber(i) ? t[o] = i.toHexString() : t[o] = i;
166
166
  }), t;
167
167
  }
168
168
  return a;
@@ -176,10 +176,10 @@ function z(r, n, e) {
176
176
  const t = `${r}-${e}`, o = v.get(t);
177
177
  if (o)
178
178
  return o;
179
- const c = new Y(n, e ? void 0 : T), l = new F(c);
179
+ const i = new Y(n, e ? void 0 : b), l = new x(i);
180
180
  return e ? (console.log(`[getPermitUtilsInstance] Set cached provider utils for chain ${r}-${e}`, l), v.set(t, l)) : (console.log(`[getPermitUtilsInstance] Set cached chain utils for chain ${r}`, l), C.set(r, l)), l;
181
181
  }
182
- const N = [
182
+ const R = [
183
183
  {
184
184
  constant: !0,
185
185
  inputs: [],
@@ -239,7 +239,7 @@ const N = [
239
239
  }
240
240
  ];
241
241
  async function J(r, n, e) {
242
- const a = L(r), o = await k(a, N, e).callStatic.eip712Domain();
242
+ const a = L(r), o = await h(a, R, e).callStatic.eip712Domain();
243
243
  return X(o, n, r);
244
244
  }
245
245
  async function X(r, n, e) {
@@ -262,84 +262,121 @@ function ee(r) {
262
262
  }
263
263
  async function te(r, n, e) {
264
264
  const a = L(r);
265
- return k(a, N, e).callStatic.name();
265
+ return h(a, R, e).callStatic.name();
266
266
  }
267
- const ne = {
267
+ const ne = [[{
268
+ constant: !0,
269
+ inputs: [],
270
+ name: "version",
271
+ outputs: [{
272
+ name: "",
273
+ type: "string"
274
+ }],
275
+ payable: !1,
276
+ stateMutability: "view",
277
+ type: "function"
278
+ }], [{
279
+ constant: !0,
280
+ inputs: [],
281
+ name: "ERC712_VERSION",
282
+ outputs: [{
283
+ name: "",
284
+ type: "string"
285
+ }],
286
+ payable: !1,
287
+ stateMutability: "view",
288
+ type: "function"
289
+ }]];
290
+ async function M(r, n, e = 0) {
291
+ const a = ne[e];
292
+ if (!a)
293
+ return "1";
294
+ try {
295
+ const o = h(r, a, n).interface.encodeFunctionData(a[0].name), i = await n.call({
296
+ to: r,
297
+ data: o
298
+ });
299
+ return i === "0x" || Number.isNaN(Number(i)) ? "1" : i.startsWith("0x") ? T.decode(["string"], i).toString() : i;
300
+ } catch {
301
+ return M(r, n, e + 1);
302
+ }
303
+ }
304
+ const re = {
268
305
  value: $,
269
306
  nonce: 0,
270
- deadline: I()
271
- }, re = {
307
+ deadline: k()
308
+ }, ae = {
272
309
  allowed: !0,
273
310
  nonce: 0,
274
- expiry: I()
275
- }, D = {}, h = {
311
+ expiry: k()
312
+ }, D = {}, y = {
276
313
  type: "unsupported"
277
314
  };
278
- async function ye(r) {
315
+ async function Pe(r) {
279
316
  const {
280
317
  tokenAddress: n,
281
318
  chainId: e
282
319
  } = r, a = `${e}-${n.toLowerCase()}`, t = D[a];
283
320
  if (t)
284
321
  return t;
285
- const o = ae(r);
322
+ const o = oe(r);
286
323
  return D[a] = o, o;
287
324
  }
288
- async function ae(r) {
325
+ async function oe(r) {
289
326
  const {
290
327
  spender: n,
291
328
  tokenAddress: e,
292
329
  chainId: a,
293
330
  provider: t,
294
331
  minGasLimit: o
295
- } = r, c = z(a, t), l = T.address;
296
- let d;
332
+ } = r, i = z(a, t), l = b.address;
333
+ let u;
297
334
  try {
298
- d = await J(e, a, t);
335
+ u = await J(e, a, t);
299
336
  } catch {
300
337
  console.debug(`[checkTokenIsPermittable] Couldn't fetch eip712domain for token ${e}`);
301
338
  }
302
- let s = d == null ? void 0 : d.name;
339
+ let c = u == null ? void 0 : u.name;
303
340
  try {
304
- s || (s = await te(e, a, t));
305
- } catch (i) {
306
- if (/ETIMEDOUT/.test(i) && !s)
341
+ c || (c = await te(e, a, t));
342
+ } catch (s) {
343
+ if (/ETIMEDOUT/.test(s) && !c)
307
344
  return {
308
345
  error: "Failed to fetch token name from contract. RPC connection error"
309
346
  };
310
- console.debug(`[checkTokenIsPermittable] Couldn't fetch token name from the contract for token ${e}, using provided '${s}'`, i);
347
+ console.debug(`[checkTokenIsPermittable] Couldn't fetch token name from the contract for token ${e}, using provided '${c}'`, s);
311
348
  }
312
- if (!s)
349
+ if (!c)
313
350
  return {
314
351
  error: `Token name could not be determined for ${e}`
315
352
  };
316
- let u;
353
+ let m;
317
354
  try {
318
- u = await c.getTokenNonce(e, l);
319
- } catch (i) {
320
- return i === "nonce not supported" || i.message === "nonce is NaN" ? (console.debug(`[checkTokenIsPermittable] Not a permittable token ${e} - ${s}`, (i == null ? void 0 : i.message) || i), {
321
- ...h,
322
- name: s
323
- }) : (console.debug(`[checkTokenIsPermittable] Failed to get nonce for ${e} - ${s}`, i), {
324
- error: i.message || i.toString()
355
+ m = await i.getTokenNonce(e, l);
356
+ } catch (s) {
357
+ return s === "nonce not supported" || s.message === "nonce is NaN" ? (console.debug(`[checkTokenIsPermittable] Not a permittable token ${e} - ${c}`, (s == null ? void 0 : s.message) || s), {
358
+ ...y,
359
+ name: c
360
+ }) : (console.debug(`[checkTokenIsPermittable] Failed to get nonce for ${e} - ${c}`, s), {
361
+ error: s.message || s.toString()
325
362
  });
326
363
  }
327
- let m = d == null ? void 0 : d.version;
328
- if (!V.has(e) && m === void 0)
364
+ let d = u == null ? void 0 : u.version;
365
+ if (d === void 0)
329
366
  try {
330
- m = await c.getTokenVersion(e);
331
- } catch (i) {
332
- console.debug(`[checkTokenIsPermittable] Failed to get version for ${e} - ${s}`, i);
367
+ d = await M(e, t);
368
+ } catch (s) {
369
+ console.debug(`[checkTokenIsPermittable] Failed to get version for ${e} - ${c}`, s);
333
370
  }
334
371
  const p = {
335
372
  chainId: a,
336
- eip2612PermitUtils: c,
337
- nonce: u,
373
+ eip2612PermitUtils: i,
374
+ nonce: m,
338
375
  spender: n,
339
376
  tokenAddress: e,
340
- tokenName: s,
377
+ tokenName: c,
341
378
  walletAddress: l,
342
- version: m,
379
+ version: d,
343
380
  minGasLimit: o
344
381
  };
345
382
  try {
@@ -348,20 +385,20 @@ async function ae(r) {
348
385
  type: "eip-2612",
349
386
  provider: t
350
387
  });
351
- } catch (i) {
388
+ } catch (s) {
352
389
  try {
353
- return await ie(e, c) ? await A({
390
+ return await se(e, i) ? await A({
354
391
  ...p,
355
392
  type: "dai-like",
356
393
  provider: t
357
- }) : /invalid signature/.test(i) || (i == null ? void 0 : i.code) === "UNPREDICTABLE_GAS_LIMIT" ? (console.debug(`[checkTokenIsPermittable] Token ${e} - ${s} might be permittable, but it's not supported for now. Reason:`, i == null ? void 0 : i.reason), {
358
- ...h,
359
- name: s
360
- }) : (console.debug(`[checkTokenIsPermittable] Failed to estimate eip-2612 permit for ${e} - ${s}`, i), {
361
- error: i.message || i.toString()
394
+ }) : /invalid signature/.test(s) || (s == null ? void 0 : s.code) === "UNPREDICTABLE_GAS_LIMIT" ? (console.debug(`[checkTokenIsPermittable] Token ${e} - ${c} might be permittable, but it's not supported for now. Reason:`, s == null ? void 0 : s.reason), {
395
+ ...y,
396
+ name: c
397
+ }) : (console.debug(`[checkTokenIsPermittable] Failed to estimate eip-2612 permit for ${e} - ${c}`, s), {
398
+ error: s.message || s.toString()
362
399
  });
363
400
  } catch (f) {
364
- return console.debug(`[checkTokenIsPermittable] Failed to estimate dai-like permit for ${e} - ${s}`, f), {
401
+ return console.debug(`[checkTokenIsPermittable] Failed to estimate dai-like permit for ${e} - ${c}`, f), {
365
402
  error: f.message || f.toString()
366
403
  };
367
404
  }
@@ -374,76 +411,76 @@ async function A(r) {
374
411
  tokenAddress: a,
375
412
  tokenName: t,
376
413
  type: o,
377
- version: c,
378
- minGasLimit: l = K
379
- } = r, s = await (o === "eip-2612" ? oe : se)(r);
380
- return s ? (await n.estimateGas({
381
- data: s,
414
+ version: i,
415
+ minGasLimit: l = V
416
+ } = r, c = await (o === "eip-2612" ? ie : ce)(r);
417
+ return c ? (await n.estimateGas({
418
+ data: c,
382
419
  from: e,
383
420
  to: a
384
421
  })).toNumber() > l ? {
385
422
  type: o,
386
- version: c,
423
+ version: i,
387
424
  name: t
388
425
  } : {
389
- ...h,
426
+ ...y,
390
427
  name: t
391
428
  } : {
392
- ...h,
429
+ ...y,
393
430
  name: t
394
431
  };
395
432
  }
396
- async function oe(r) {
433
+ async function ie(r) {
397
434
  const {
398
435
  eip2612PermitUtils: n,
399
436
  walletAddress: e,
400
437
  spender: a,
401
438
  nonce: t,
402
439
  chainId: o,
403
- tokenName: c,
440
+ tokenName: i,
404
441
  tokenAddress: l,
405
- version: d
442
+ version: u
406
443
  } = r;
407
444
  return S({
408
445
  eip2162Utils: n,
409
446
  callDataParams: [{
410
- ...ne,
447
+ ...re,
411
448
  owner: e,
412
449
  spender: a,
413
450
  nonce: t
414
- }, +o, c, l, d]
451
+ }, +o, i, l, u]
415
452
  });
416
453
  }
417
- async function ie(r, n) {
454
+ async function se(r, n) {
418
455
  return await n.getPermitTypeHash(r) === _;
419
456
  }
420
- async function se(r) {
457
+ async function ce(r) {
421
458
  const {
422
459
  eip2612PermitUtils: n,
423
460
  tokenAddress: e,
424
461
  walletAddress: a,
425
462
  spender: t,
426
463
  nonce: o,
427
- chainId: c,
464
+ chainId: i,
428
465
  tokenName: l,
429
- version: d
466
+ version: u
430
467
  } = r;
431
- return await n.getPermitTypeHash(e) === _ ? R({
468
+ return await n.getPermitTypeHash(e) === _ ? N({
432
469
  eip2162Utils: n,
433
470
  callDataParams: [{
434
- ...re,
471
+ ...ae,
435
472
  holder: a,
436
473
  spender: t,
437
474
  nonce: o
438
- }, c, l, e, d]
475
+ }, i, l, e, u]
439
476
  }) : !1;
440
477
  }
441
478
  export {
442
- K as DEFAULT_MIN_GAS_LIMIT,
443
- T as PERMIT_SIGNER,
444
- ge as checkIsCallDataAValidPermit,
479
+ V as DEFAULT_MIN_GAS_LIMIT,
480
+ b as PERMIT_SIGNER,
481
+ ye as checkIsCallDataAValidPermit,
445
482
  he as generatePermitHook,
446
483
  z as getPermitUtilsInstance,
447
- ye as getTokenPermitInfo,
448
- q as isSupportedPermitInfo
484
+ Pe as getTokenPermitInfo,
485
+ W as isSupportedPermitInfo
449
486
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cowprotocol/permit-utils",
3
- "version": "0.1.2",
3
+ "version": "0.2.0",
4
4
  "type": "module",
5
5
  "dependencies": {
6
6
  "ethers": "^5.7.2",
@@ -0,0 +1,2 @@
1
+ import type { JsonRpcProvider } from '@ethersproject/providers';
2
+ export declare function getTokenPermitVersion(tokenAddress: string, provider: JsonRpcProvider, index?: number): Promise<string>;