@cowprotocol/permit-utils 0.0.2 → 0.1.1-RC.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.
package/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const f=require("@cowprotocol/cow-sdk"),U=require("@ethersproject/constants"),H=require("@ethersproject/wallet"),p=require("@1inch/permit-signed-approvals-utils"),C=require("@ethersproject/abi"),O=require("@ethersproject/bignumber"),F=require("@ethersproject/contracts"),G=require("@ethersproject/address"),q="0x4dae303b820e9878cafeb0f84edcc015e8a81b1bff510e824e4fc27544e458dd",h=new H.Wallet(q),x={[f.SupportedChainId.MAINNET]:55e3,[f.SupportedChainId.GNOSIS_CHAIN]:55e3,[f.SupportedChainId.SEPOLIA]:55e3,[f.SupportedChainId.GOERLI]:36e3},T="80000",A=U.MaxUint256.toString(),K=157788e6,V=new Set(["0x6b175474e89094c44da98b954eedeac495271d0f"]);function D(t){return t==="USD//C"?"USD Coin":t}async function B(t,n,e,o,a,r,{version:i,type:c,name:d}){const l=d||a;if(c==="unsupported")return!1;if(!l)throw new Error(`No token name for ${o}`);const m={chainId:n,tokenName:D(l),tokenAddress:o,callData:r,version:i};let u;if(r.startsWith(p.EIP_2612_PERMIT_SELECTOR)?u=e.recoverPermitOwnerFromCallData({...m,callData:r.replace(p.EIP_2612_PERMIT_SELECTOR,"0x")}):r.startsWith(p.DAI_PERMIT_SELECTOR)&&(u=e.recoverDaiLikePermitOwnerFromCallData({...m,callData:r.replace(p.DAI_PERMIT_SELECTOR,"0x")})),!!u)try{return(await u).toLowerCase()===t.toLowerCase()}catch(s){return console.debug(`[checkHasValidPendingPermit] Failed to check permit validity for owner ${t} with callData ${r}`,s),!1}}async function R({eip2162Utils:t,callDataParams:n}){const[e,o,a,...r]=n;return(await t.buildPermitCallData(e,o,D(a),...r)).replace("0x",p.EIP_2612_PERMIT_SELECTOR)}async function v({eip2162Utils:t,callDataParams:n}){return(await t.buildDaiLikePermitCallData(...n)).replace("0x",p.DAI_PERMIT_SELECTOR)}function E(){return Math.ceil((Date.now()+K)/1e3)}function L(t){return!!t&&t.type!=="unsupported"}const I={};async function j(t){const n=Y(t),e=I[n];if(e)try{return await e}catch(a){console.debug("[generatePermitHookWith] cached request failed",a),delete I[n]}const o=W(t).then(a=>(delete I[n],a));return I[n]=o,o}async function W(t){const{inputToken:n,spender:e,chainId:o,permitInfo:a,provider:r,account:i,eip2162Utils:c,nonce:d}=t,l=n.address,m=a.name||n.name;if(!L(a))throw new Error(`Trying to generate permit hook for unsupported token: ${l}`);if(!m)throw new Error(`No token name for token: ${l}`);const u=i||h.address,s=d===void 0?await c.getTokenNonce(l,u):d,P=E(),k=A,w=a.type==="eip-2612"?await R({eip2162Utils:c,callDataParams:[{owner:u,spender:e,value:k,nonce:s,deadline:P},o,m,l,a.version]}):await v({eip2162Utils:c,callDataParams:[{holder:u,spender:e,allowed:!0,value:k,nonce:s,expiry:P},o,m,l,a.version]}),M=await Q(w,u,l,r,!!i);return{target:l,callData:w,gasLimit:M}}async function Q(t,n,e,o,a){try{const r=await o.estimateGas({data:t,from:n,to:e}),i=a?r:r.add(r.div(10));return i.gt(T)?i.toString():T}catch(r){return console.debug("[calculatePermitGasLimit] Failed to estimateGas, using default",r),T}}function Y(t){const{inputToken:n,chainId:e,account:o}=t;return`${n.address.toLowerCase()}-${e}${o?`-${o.toLowerCase()}`:""}`}function N(t,n,e){return new F.Contract(t,n,e)}class z{constructor(n,e){this.provider=n,this.walletSigner=e}contractEncodeABI(n,e,o,a){return N(e||"",n,this.provider).interface.encodeFunctionData(o,a)}signTypedData(n,e,o){const a=Object.keys(e.types).reduce((i,c)=>(c!=="EIP712Domain"&&(i[c]=e.types[c]),i),{});return(this.walletSigner||this.provider.getSigner())._signTypedData(e.domain,a,e.message)}ethCall(n,e){return this.provider.call({to:n,data:e})}decodeABIParameter(n,e){return C.defaultAbiCoder.decode([n],e)[0]}decodeABIParameters(n,e){const o=C.defaultAbiCoder.decode(n,e);if(o&&typeof o=="object"){const a={};return Object.keys(o).forEach(r=>{const i=o[r];O.BigNumber.isBigNumber(i)?a[r]=i.toHexString():a[r]=i}),a}return o}}const _=new Map,S=new Map;function $(t,n,e){const o=_.get(t);if(!e&&o)return o;const a=`${t}-${e}`,r=S.get(a);if(r)return r;const i=new z(n,e?void 0:h),c=new p.Eip2612PermitUtils(i);return e?(console.log(`[getPermitUtilsInstance] Set cached provider utils for chain ${t}-${e}`,c),S.set(a,c)):(console.log(`[getPermitUtilsInstance] Set cached chain utils for chain ${t}`,c),_.set(t,c)),c}const J=[{constant:!0,inputs:[],name:"name",outputs:[{name:"",type:"string"}],payable:!1,stateMutability:"view",type:"function"}];async function X(t,n,e){const o=G.getAddress(t);return N(o,J,e).callStatic.name()}const Z={value:A,nonce:0,deadline:E()},ee={allowed:!0,nonce:0,expiry:E()},y={},g={type:"unsupported"};async function te(t){const{tokenAddress:n,chainId:e}=t,o=`${e}-${n.toLowerCase()}`,a=y[o];if(a)return a;const r=ne(t);return y[o]=r,r}async function ne(t){const{spender:n,tokenAddress:e,tokenName:o,chainId:a,provider:r}=t,i=$(a,r),c=h.address;let d=o;try{d=await X(e,a,r)}catch(s){if(/ETIMEDOUT/.test(s)&&!d)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 '${d}'`,s)}if(!d)return{error:`Token name could not be determined for ${e}`};let l;try{l=await i.getTokenNonce(e,c)}catch(s){return s==="nonce not supported"||s.message==="nonce is NaN"?(console.debug(`[checkTokenIsPermittable] Not a permittable token ${e} - ${d}`,s?.message||s),{...g,name:d}):(console.debug(`[checkTokenIsPermittable] Failed to get nonce for ${e} - ${d}`,s),{error:s.message||s.toString()})}let m;if(!V.has(e))try{m=await i.getTokenVersion(e)}catch(s){console.debug(`[checkTokenIsPermittable] Failed to get version for ${e} - ${d}`,s)}const u={chainId:a,eip2612PermitUtils:i,nonce:l,spender:n,tokenAddress:e,tokenName:d,walletAddress:c,version:m};try{return await b({...u,type:"eip-2612",provider:r})}catch(s){try{return await oe(e,i)?await b({...u,type:"dai-like",provider:r}):/invalid signature/.test(s)||s?.code==="UNPREDICTABLE_GAS_LIMIT"?(console.debug(`[checkTokenIsPermittable] Token ${e} - ${d} might be permittable, but it's not supported for now. Reason:`,s?.reason),{...g,name:d}):(console.debug(`[checkTokenIsPermittable] Failed to estimate eip-2612 permit for ${e} - ${d}`,s),{error:s.message||s.toString()})}catch(P){return console.debug(`[checkTokenIsPermittable] Failed to estimate dai-like permit for ${e} - ${d}`,P),{error:P.message||P.toString()}}}}async function b(t){const{provider:n,chainId:e,walletAddress:o,tokenAddress:a,tokenName:r,type:i,version:c}=t,l=await(i==="eip-2612"?re:ae)(t);return l?(await n.estimateGas({data:l,from:o,to:a})).toNumber()>x[e]?{type:i,version:c,name:r}:{...g,name:r}:{...g,name:r}}async function re(t){const{eip2612PermitUtils:n,walletAddress:e,spender:o,nonce:a,chainId:r,tokenName:i,tokenAddress:c,version:d}=t;return R({eip2162Utils:n,callDataParams:[{...Z,owner:e,spender:o,nonce:a},+r,i,c,d]})}async function oe(t,n){return await n.getPermitTypeHash(t)===p.DAI_LIKE_PERMIT_TYPEHASH}async function ae(t){const{eip2612PermitUtils:n,tokenAddress:e,walletAddress:o,spender:a,nonce:r,chainId:i,tokenName:c,version:d}=t;return await n.getPermitTypeHash(e)===p.DAI_LIKE_PERMIT_TYPEHASH?v({eip2162Utils:n,callDataParams:[{...ee,holder:o,spender:a,nonce:r},i,c,e,d]}):!1}exports.PERMIT_SIGNER=h;exports.checkIsCallDataAValidPermit=B;exports.generatePermitHook=j;exports.getPermitUtilsInstance=$;exports.getTokenPermitInfo=te;exports.isSupportedPermitInfo=L;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const I=require("@cowprotocol/cow-sdk"),O=require("@ethersproject/constants"),F=require("@ethersproject/wallet"),p=require("@1inch/permit-signed-approvals-utils"),b=require("@ethersproject/abi"),x=require("@ethersproject/bignumber"),G=require("@ethersproject/contracts"),v=require("@ethersproject/address"),q="0x4dae303b820e9878cafeb0f84edcc015e8a81b1bff510e824e4fc27544e458dd",P=new F.Wallet(q),T=55e3,K={[I.SupportedChainId.MAINNET]:T,[I.SupportedChainId.GNOSIS_CHAIN]:T,[I.SupportedChainId.SEPOLIA]:T,[I.SupportedChainId.GOERLI]:36e3},E="80000",L=O.MaxUint256.toString(),V=157788e6,B=new Set(["0x6b175474e89094c44da98b954eedeac495271d0f"]);async function j(r,t,e,a,n,o,{version:c,type:s,name:d}){const l=d||n;if(s==="unsupported")return!1;if(!l)throw new Error(`No token name for ${a}`);const m={chainId:t,tokenName:l,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(i){return console.debug(`[checkHasValidPendingPermit] Failed to check permit validity for owner ${r} with callData ${o}`,i),!1}}async function R({eip2162Utils:r,callDataParams:t}){const[e,a,n,...o]=t;return(await r.buildPermitCallData(e,a,n,...o)).replace("0x",p.EIP_2612_PERMIT_SELECTOR)}async function $({eip2162Utils:r,callDataParams:t}){return(await r.buildDaiLikePermitCallData(...t)).replace("0x",p.DAI_PERMIT_SELECTOR)}function y(){return Math.ceil((Date.now()+V)/1e3)}function M(r){return!!r&&r.type!=="unsupported"}const g={};async function W(r){const t=z(r),e=g[t];if(e)try{return await e}catch(n){console.debug("[generatePermitHookWith] cached request failed",n),delete g[t]}const a=Q(r).then(n=>(delete g[t],n));return g[t]=a,a}async function Q(r){const{inputToken:t,spender:e,chainId:a,permitInfo:n,provider:o,account:c,eip2162Utils:s,nonce:d}=r,l=t.address,m=n.name||t.name;if(!M(n))throw new Error(`Trying to generate permit hook for unsupported token: ${l}`);if(!m)throw new Error(`No token name for token: ${l}`);const u=c||P.address,i=d===void 0?await s.getTokenNonce(l,u):d,f=y(),k=L,C=n.type==="eip-2612"?await R({eip2162Utils:s,callDataParams:[{owner:u,spender:e,value:k,nonce:i,deadline:f},a,m,l,n.version]}):await $({eip2162Utils:s,callDataParams:[{holder:u,spender:e,allowed:!0,value:k,nonce:i,expiry:f},a,m,l,n.version]}),H=await Y(C,u,l,o,!!c);return{target:l,callData:C,gasLimit:H}}async function Y(r,t,e,a,n){try{const o=await a.estimateGas({data:r,from:t,to:e}),c=n?o:o.add(o.div(10));return c.gt(E)?c.toString():E}catch(o){return console.debug("[calculatePermitGasLimit] Failed to estimateGas, using default",o),E}}function z(r){const{inputToken:t,chainId:e,account:a}=r;return`${t.address.toLowerCase()}-${e}${a?`-${a.toLowerCase()}`:""}`}function w(r,t,e){return new G.Contract(r,t,e)}class J{constructor(t,e){this.provider=t,this.walletSigner=e}contractEncodeABI(t,e,a,n){return w(e||"",t,this.provider).interface.encodeFunctionData(a,n)}signTypedData(t,e,a){const n=Object.keys(e.types).reduce((c,s)=>(s!=="EIP712Domain"&&(c[s]=e.types[s]),c),{});return(this.walletSigner||this.provider.getSigner())._signTypedData(e.domain,n,e.message)}ethCall(t,e){return this.provider.call({to:t,data:e})}decodeABIParameter(t,e){return b.defaultAbiCoder.decode([t],e)[0]}decodeABIParameters(t,e){const a=b.defaultAbiCoder.decode(t,e);if(a&&typeof a=="object"){const n={};return Object.keys(a).forEach(o=>{const c=a[o];x.BigNumber.isBigNumber(c)?n[o]=c.toHexString():n[o]=c}),n}return a}}const _=new Map,A=new Map;function N(r,t,e){const a=_.get(r);if(!e&&a)return a;const n=`${r}-${e}`,o=A.get(n);if(o)return o;const c=new J(t,e?void 0:P),s=new p.Eip2612PermitUtils(c);return e?(console.log(`[getPermitUtilsInstance] Set cached provider utils for chain ${r}-${e}`,s),A.set(n,s)):(console.log(`[getPermitUtilsInstance] Set cached chain utils for chain ${r}`,s),_.set(r,s)),s}const U=[{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 X(r,t,e){const a=v.getAddress(r),o=await w(a,U,e).callStatic.eip712Domain();return Z(o,t,r)}async function Z(r,t,e){const{extensions:a,...n}=r;if(a.length>0)throw Error("Extensions not implemented");if(n.chainId&&t!==parseInt(n.chainId,16))throw Error(`ChainId mismatch. Received: '${n.chainId}', expected: '${t}'`);if(n.verifyingContract&&e.toLowerCase()!==n.verifyingContract.toLowerCase())throw Error(`Address mismatch. Received: '${n.verifyingContract}', expected: '${e}'`);return te(n)}const ee=["name","version","chainId","verifyingContract","salt"];function te(r){const t=parseInt(r.fields,16);return ee.reduce((e,a,n)=>(t&1<<n&&(e[a]=r[a]),e),{})}async function ne(r,t,e){const a=v.getAddress(r);return w(a,U,e).callStatic.name()}const re={value:L,nonce:0,deadline:y()},ae={allowed:!0,nonce:0,expiry:y()},S={},h={type:"unsupported"};async function oe(r){const{tokenAddress:t,chainId:e}=r,a=`${e}-${t.toLowerCase()}`,n=S[a];if(n)return n;const o=ie(r);return S[a]=o,o}async function ie(r){const{spender:t,tokenAddress:e,chainId:a,provider:n}=r,o=N(a,n),c=P.address;let s;try{s=await X(e,a,n)}catch(i){console.debug(`[checkTokenIsPermittable] Couldn't fetch eip712domain for token ${e}`,i)}let d=s==null?void 0:s.name;try{d||(d=await ne(e,a,n))}catch(i){if(/ETIMEDOUT/.test(i)&&!d)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 '${d}'`,i)}if(!d)return{error:`Token name could not be determined for ${e}`};let l;try{l=await o.getTokenNonce(e,c)}catch(i){return i==="nonce not supported"||i.message==="nonce is NaN"?(console.debug(`[checkTokenIsPermittable] Not a permittable token ${e} - ${d}`,(i==null?void 0:i.message)||i),{...h,name:d}):(console.debug(`[checkTokenIsPermittable] Failed to get nonce for ${e} - ${d}`,i),{error:i.message||i.toString()})}let m=s==null?void 0:s.version;if(!B.has(e)&&m===void 0)try{m=await o.getTokenVersion(e)}catch(i){console.debug(`[checkTokenIsPermittable] Failed to get version for ${e} - ${d}`,i)}const u={chainId:a,eip2612PermitUtils:o,nonce:l,spender:t,tokenAddress:e,tokenName:d,walletAddress:c,version:m};try{return await D({...u,type:"eip-2612",provider:n})}catch(i){try{return await ce(e,o)?await D({...u,type:"dai-like",provider:n}):/invalid signature/.test(i)||(i==null?void 0:i.code)==="UNPREDICTABLE_GAS_LIMIT"?(console.debug(`[checkTokenIsPermittable] Token ${e} - ${d} might be permittable, but it's not supported for now. Reason:`,i==null?void 0:i.reason),{...h,name:d}):(console.debug(`[checkTokenIsPermittable] Failed to estimate eip-2612 permit for ${e} - ${d}`,i),{error:i.message||i.toString()})}catch(f){return console.debug(`[checkTokenIsPermittable] Failed to estimate dai-like permit for ${e} - ${d}`,f),{error:f.message||f.toString()}}}}async function D(r){const{provider:t,chainId:e,walletAddress:a,tokenAddress:n,tokenName:o,type:c,version:s}=r,l=await(c==="eip-2612"?se:de)(r);return l?(await t.estimateGas({data:l,from:a,to:n})).toNumber()>K[e]?{type:c,version:s,name:o}:{...h,name:o}:{...h,name:o}}async function se(r){const{eip2612PermitUtils:t,walletAddress:e,spender:a,nonce:n,chainId:o,tokenName:c,tokenAddress:s,version:d}=r;return R({eip2162Utils:t,callDataParams:[{...re,owner:e,spender:a,nonce:n},+o,c,s,d]})}async function ce(r,t){return await t.getPermitTypeHash(r)===p.DAI_LIKE_PERMIT_TYPEHASH}async function de(r){const{eip2612PermitUtils:t,tokenAddress:e,walletAddress:a,spender:n,nonce:o,chainId:c,tokenName:s,version:d}=r;return await t.getPermitTypeHash(e)===p.DAI_LIKE_PERMIT_TYPEHASH?$({eip2162Utils:t,callDataParams:[{...ae,holder:a,spender:n,nonce:o},c,s,e,d]}):!1}exports.PERMIT_SIGNER=P;exports.checkIsCallDataAValidPermit=j;exports.generatePermitHook=W;exports.getPermitUtilsInstance=N;exports.getTokenPermitInfo=oe;exports.isSupportedPermitInfo=M;
package/index.js CHANGED
@@ -1,194 +1,191 @@
1
1
  import { SupportedChainId as f } from "@cowprotocol/cow-sdk";
2
- import { MaxUint256 as M } from "@ethersproject/constants";
3
- import { Wallet as H } from "@ethersproject/wallet";
4
- import { EIP_2612_PERMIT_SELECTOR as k, DAI_PERMIT_SELECTOR as I, Eip2612PermitUtils as O, DAI_LIKE_PERMIT_TYPEHASH as S } from "@1inch/permit-signed-approvals-utils";
5
- import { defaultAbiCoder as C } from "@ethersproject/abi";
6
- import { BigNumber as F } from "@ethersproject/bignumber";
7
- import { Contract as G } from "@ethersproject/contracts";
8
- import { getAddress as x } from "@ethersproject/address";
9
- const K = "0x4dae303b820e9878cafeb0f84edcc015e8a81b1bff510e824e4fc27544e458dd", T = new H(K), V = {
10
- [f.MAINNET]: 55e3,
11
- [f.GNOSIS_CHAIN]: 55e3,
12
- [f.SEPOLIA]: 55e3,
2
+ import { MaxUint256 as O } from "@ethersproject/constants";
3
+ import { Wallet as F } from "@ethersproject/wallet";
4
+ import { EIP_2612_PERMIT_SELECTOR as P, DAI_PERMIT_SELECTOR as T, Eip2612PermitUtils as x, DAI_LIKE_PERMIT_TYPEHASH as L } from "@1inch/permit-signed-approvals-utils";
5
+ import { defaultAbiCoder as v } from "@ethersproject/abi";
6
+ import { BigNumber as G } from "@ethersproject/bignumber";
7
+ import { Contract as K } from "@ethersproject/contracts";
8
+ import { getAddress as $ } from "@ethersproject/address";
9
+ const B = "0x4dae303b820e9878cafeb0f84edcc015e8a81b1bff510e824e4fc27544e458dd", w = new F(B), y = 55e3, V = {
10
+ [f.MAINNET]: y,
11
+ [f.GNOSIS_CHAIN]: y,
12
+ [f.SEPOLIA]: y,
13
13
  [f.GOERLI]: 36e3
14
- }, h = "80000", v = M.toString(), B = 157788e6, q = /* @__PURE__ */ new Set(["0x6b175474e89094c44da98b954eedeac495271d0f"]);
15
- function L(t) {
16
- return t === "USD//C" ? "USD Coin" : t;
17
- }
18
- async function fe(t, n, e, o, a, r, {
19
- version: i,
20
- type: c,
14
+ }, I = "80000", N = O.toString(), q = 157788e6, W = /* @__PURE__ */ new Set(["0x6b175474e89094c44da98b954eedeac495271d0f"]);
15
+ async function Ie(r, t, e, o, n, a, {
16
+ version: c,
17
+ type: s,
21
18
  name: l
22
19
  }) {
23
- const d = l || a;
24
- if (c === "unsupported")
20
+ const d = l || n;
21
+ if (s === "unsupported")
25
22
  return !1;
26
23
  if (!d)
27
24
  throw new Error(`No token name for ${o}`);
28
25
  const u = {
29
- chainId: n,
30
- tokenName: L(d),
26
+ chainId: t,
27
+ tokenName: d,
31
28
  tokenAddress: o,
32
- callData: r,
33
- version: i
29
+ callData: a,
30
+ version: c
34
31
  };
35
32
  let m;
36
- if (r.startsWith(k) ? m = e.recoverPermitOwnerFromCallData({
33
+ if (a.startsWith(P) ? m = e.recoverPermitOwnerFromCallData({
37
34
  ...u,
38
35
  // I don't know why this was removed, ok?
39
36
  // We added it back on buildPermitCallData.ts
40
37
  // But it looks like this is needed 🤷
41
38
  // Check the test for this method https://github.com/1inch/permit-signed-approvals-utils/blob/master/src/eip-2612-permit.test.ts#L85-L106
42
- callData: r.replace(k, "0x")
43
- }) : r.startsWith(I) && (m = e.recoverDaiLikePermitOwnerFromCallData({
39
+ callData: a.replace(P, "0x")
40
+ }) : a.startsWith(T) && (m = e.recoverDaiLikePermitOwnerFromCallData({
44
41
  ...u,
45
- callData: r.replace(I, "0x")
42
+ callData: a.replace(T, "0x")
46
43
  })), !!m)
47
44
  try {
48
- return (await m).toLowerCase() === t.toLowerCase();
49
- } catch (s) {
50
- return console.debug(`[checkHasValidPendingPermit] Failed to check permit validity for owner ${t} with callData ${r}`, s), !1;
45
+ return (await m).toLowerCase() === r.toLowerCase();
46
+ } catch (i) {
47
+ return console.debug(`[checkHasValidPendingPermit] Failed to check permit validity for owner ${r} with callData ${a}`, i), !1;
51
48
  }
52
49
  }
53
- async function N({
54
- eip2162Utils: t,
55
- callDataParams: n
50
+ async function R({
51
+ eip2162Utils: r,
52
+ callDataParams: t
56
53
  }) {
57
- const [e, o, a, ...r] = n;
58
- return (await t.buildPermitCallData(e, o, L(a), ...r)).replace("0x", k);
54
+ const [e, o, n, ...a] = t;
55
+ return (await r.buildPermitCallData(e, o, n, ...a)).replace("0x", P);
59
56
  }
60
- async function $({
61
- eip2162Utils: t,
62
- callDataParams: n
57
+ async function M({
58
+ eip2162Utils: r,
59
+ callDataParams: t
63
60
  }) {
64
- return (await t.buildDaiLikePermitCallData(...n)).replace("0x", I);
61
+ return (await r.buildDaiLikePermitCallData(...t)).replace("0x", T);
65
62
  }
66
- function w() {
67
- return Math.ceil((Date.now() + B) / 1e3);
63
+ function k() {
64
+ return Math.ceil((Date.now() + q) / 1e3);
68
65
  }
69
- function W(t) {
70
- return !!t && t.type !== "unsupported";
66
+ function j(r) {
67
+ return !!r && r.type !== "unsupported";
71
68
  }
72
- const g = {};
73
- async function ge(t) {
74
- const n = Y(t), e = g[n];
69
+ const h = {};
70
+ async function Pe(r) {
71
+ const t = z(r), e = h[t];
75
72
  if (e)
76
73
  try {
77
74
  return await e;
78
- } catch (a) {
79
- console.debug("[generatePermitHookWith] cached request failed", a), delete g[n];
75
+ } catch (n) {
76
+ console.debug("[generatePermitHookWith] cached request failed", n), delete h[t];
80
77
  }
81
- const o = j(t).then((a) => (delete g[n], a));
82
- return g[n] = o, o;
78
+ const o = Q(r).then((n) => (delete h[t], n));
79
+ return h[t] = o, o;
83
80
  }
84
- async function j(t) {
81
+ async function Q(r) {
85
82
  const {
86
- inputToken: n,
83
+ inputToken: t,
87
84
  spender: e,
88
85
  chainId: o,
89
- permitInfo: a,
90
- provider: r,
91
- account: i,
92
- eip2162Utils: c,
86
+ permitInfo: n,
87
+ provider: a,
88
+ account: c,
89
+ eip2162Utils: s,
93
90
  nonce: l
94
- } = t, d = n.address, u = a.name || n.name;
95
- if (!W(a))
91
+ } = r, d = t.address, u = n.name || t.name;
92
+ if (!j(n))
96
93
  throw new Error(`Trying to generate permit hook for unsupported token: ${d}`);
97
94
  if (!u)
98
95
  throw new Error(`No token name for token: ${d}`);
99
- const m = i || T.address, s = l === void 0 ? await c.getTokenNonce(d, m) : l, p = w(), E = v, y = a.type === "eip-2612" ? await N({
100
- eip2162Utils: c,
96
+ const m = c || w.address, i = l === void 0 ? await s.getTokenNonce(d, m) : l, p = k(), C = N, b = n.type === "eip-2612" ? await R({
97
+ eip2162Utils: s,
101
98
  callDataParams: [{
102
99
  owner: m,
103
100
  spender: e,
104
- value: E,
105
- nonce: s,
101
+ value: C,
102
+ nonce: i,
106
103
  deadline: p
107
- }, o, u, d, a.version]
108
- }) : await $({
109
- eip2162Utils: c,
104
+ }, o, u, d, n.version]
105
+ }) : await M({
106
+ eip2162Utils: s,
110
107
  callDataParams: [{
111
108
  holder: m,
112
109
  spender: e,
113
110
  allowed: !0,
114
- value: E,
115
- nonce: s,
111
+ value: C,
112
+ nonce: i,
116
113
  expiry: p
117
- }, o, u, d, a.version]
118
- }), U = await Q(y, m, d, r, !!i);
114
+ }, o, u, d, n.version]
115
+ }), H = await Y(b, m, d, a, !!c);
119
116
  return {
120
117
  target: d,
121
- callData: y,
122
- gasLimit: U
118
+ callData: b,
119
+ gasLimit: H
123
120
  };
124
121
  }
125
- async function Q(t, n, e, o, a) {
122
+ async function Y(r, t, e, o, n) {
126
123
  try {
127
- const r = await o.estimateGas({
128
- data: t,
129
- from: n,
124
+ const a = await o.estimateGas({
125
+ data: r,
126
+ from: t,
130
127
  to: e
131
- }), i = a ? r : r.add(r.div(10));
132
- return i.gt(h) ? i.toString() : h;
133
- } catch (r) {
134
- return console.debug("[calculatePermitGasLimit] Failed to estimateGas, using default", r), h;
128
+ }), c = n ? a : a.add(a.div(10));
129
+ return c.gt(I) ? c.toString() : I;
130
+ } catch (a) {
131
+ return console.debug("[calculatePermitGasLimit] Failed to estimateGas, using default", a), I;
135
132
  }
136
133
  }
137
- function Y(t) {
134
+ function z(r) {
138
135
  const {
139
- inputToken: n,
136
+ inputToken: t,
140
137
  chainId: e,
141
138
  account: o
142
- } = t;
143
- return `${n.address.toLowerCase()}-${e}${o ? `-${o.toLowerCase()}` : ""}`;
139
+ } = r;
140
+ return `${t.address.toLowerCase()}-${e}${o ? `-${o.toLowerCase()}` : ""}`;
144
141
  }
145
- function R(t, n, e) {
146
- return new G(t, n, e);
142
+ function E(r, t, e) {
143
+ return new K(r, t, e);
147
144
  }
148
- class z {
149
- constructor(n, e) {
150
- this.provider = n, this.walletSigner = e;
145
+ class J {
146
+ constructor(t, e) {
147
+ this.provider = t, this.walletSigner = e;
151
148
  }
152
- contractEncodeABI(n, e, o, a) {
153
- return R(e || "", n, this.provider).interface.encodeFunctionData(o, a);
149
+ contractEncodeABI(t, e, o, n) {
150
+ return E(e || "", t, this.provider).interface.encodeFunctionData(o, n);
154
151
  }
155
- signTypedData(n, e, o) {
156
- const a = Object.keys(e.types).reduce((i, c) => (c !== "EIP712Domain" && (i[c] = e.types[c]), i), {});
157
- return (this.walletSigner || this.provider.getSigner())._signTypedData(e.domain, a, e.message);
152
+ signTypedData(t, e, o) {
153
+ const n = Object.keys(e.types).reduce((c, s) => (s !== "EIP712Domain" && (c[s] = e.types[s]), c), {});
154
+ return (this.walletSigner || this.provider.getSigner())._signTypedData(e.domain, n, e.message);
158
155
  }
159
- ethCall(n, e) {
156
+ ethCall(t, e) {
160
157
  return this.provider.call({
161
- to: n,
158
+ to: t,
162
159
  data: e
163
160
  });
164
161
  }
165
- decodeABIParameter(n, e) {
166
- return C.decode([n], e)[0];
162
+ decodeABIParameter(t, e) {
163
+ return v.decode([t], e)[0];
167
164
  }
168
- decodeABIParameters(n, e) {
169
- const o = C.decode(n, e);
165
+ decodeABIParameters(t, e) {
166
+ const o = v.decode(t, e);
170
167
  if (o && typeof o == "object") {
171
- const a = {};
172
- return Object.keys(o).forEach((r) => {
173
- const i = o[r];
174
- F.isBigNumber(i) ? a[r] = i.toHexString() : a[r] = i;
175
- }), a;
168
+ const n = {};
169
+ return Object.keys(o).forEach((a) => {
170
+ const c = o[a];
171
+ G.isBigNumber(c) ? n[a] = c.toHexString() : n[a] = c;
172
+ }), n;
176
173
  }
177
174
  return o;
178
175
  }
179
176
  }
180
- const b = /* @__PURE__ */ new Map(), A = /* @__PURE__ */ new Map();
181
- function J(t, n, e) {
182
- const o = b.get(t);
177
+ const D = /* @__PURE__ */ new Map(), A = /* @__PURE__ */ new Map();
178
+ function X(r, t, e) {
179
+ const o = D.get(r);
183
180
  if (!e && o)
184
181
  return o;
185
- const a = `${t}-${e}`, r = A.get(a);
186
- if (r)
187
- return r;
188
- const i = new z(n, e ? void 0 : T), c = new O(i);
189
- return e ? (console.log(`[getPermitUtilsInstance] Set cached provider utils for chain ${t}-${e}`, c), A.set(a, c)) : (console.log(`[getPermitUtilsInstance] Set cached chain utils for chain ${t}`, c), b.set(t, c)), c;
182
+ const n = `${r}-${e}`, a = A.get(n);
183
+ if (a)
184
+ return a;
185
+ const c = new J(t, e ? void 0 : w), s = new x(c);
186
+ return e ? (console.log(`[getPermitUtilsInstance] Set cached provider utils for chain ${r}-${e}`, s), A.set(n, s)) : (console.log(`[getPermitUtilsInstance] Set cached chain utils for chain ${r}`, s), D.set(r, s)), s;
190
187
  }
191
- const X = [
188
+ const U = [
192
189
  {
193
190
  constant: !0,
194
191
  inputs: [],
@@ -202,50 +199,120 @@ const X = [
202
199
  payable: !1,
203
200
  stateMutability: "view",
204
201
  type: "function"
202
+ },
203
+ {
204
+ inputs: [],
205
+ name: "eip712Domain",
206
+ outputs: [
207
+ {
208
+ internalType: "bytes1",
209
+ name: "fields",
210
+ type: "bytes1"
211
+ },
212
+ {
213
+ internalType: "string",
214
+ name: "name",
215
+ type: "string"
216
+ },
217
+ {
218
+ internalType: "string",
219
+ name: "version",
220
+ type: "string"
221
+ },
222
+ {
223
+ internalType: "uint256",
224
+ name: "chainId",
225
+ type: "uint256"
226
+ },
227
+ {
228
+ internalType: "address",
229
+ name: "verifyingContract",
230
+ type: "address"
231
+ },
232
+ {
233
+ internalType: "bytes32",
234
+ name: "salt",
235
+ type: "bytes32"
236
+ },
237
+ {
238
+ internalType: "uint256[]",
239
+ name: "extensions",
240
+ type: "uint256[]"
241
+ }
242
+ ],
243
+ stateMutability: "view",
244
+ type: "function"
205
245
  }
206
246
  ];
207
- async function Z(t, n, e) {
208
- const o = x(t);
209
- return R(o, X, e).callStatic.name();
247
+ async function Z(r, t, e) {
248
+ const o = $(r), a = await E(o, U, e).callStatic.eip712Domain();
249
+ return ee(a, t, r);
250
+ }
251
+ async function ee(r, t, e) {
252
+ const {
253
+ extensions: o,
254
+ ...n
255
+ } = r;
256
+ if (o.length > 0)
257
+ throw Error("Extensions not implemented");
258
+ if (n.chainId && t !== parseInt(n.chainId, 16))
259
+ throw Error(`ChainId mismatch. Received: '${n.chainId}', expected: '${t}'`);
260
+ if (n.verifyingContract && e.toLowerCase() !== n.verifyingContract.toLowerCase())
261
+ throw Error(`Address mismatch. Received: '${n.verifyingContract}', expected: '${e}'`);
262
+ return ne(n);
263
+ }
264
+ const te = ["name", "version", "chainId", "verifyingContract", "salt"];
265
+ function ne(r) {
266
+ const t = parseInt(r.fields, 16);
267
+ return te.reduce((e, o, n) => (t & 1 << n && (e[o] = r[o]), e), {});
210
268
  }
211
- const ee = {
212
- value: v,
269
+ async function re(r, t, e) {
270
+ const o = $(r);
271
+ return E(o, U, e).callStatic.name();
272
+ }
273
+ const oe = {
274
+ value: N,
213
275
  nonce: 0,
214
- deadline: w()
215
- }, te = {
276
+ deadline: k()
277
+ }, ae = {
216
278
  allowed: !0,
217
279
  nonce: 0,
218
- expiry: w()
219
- }, D = {}, P = {
280
+ expiry: k()
281
+ }, _ = {}, g = {
220
282
  type: "unsupported"
221
283
  };
222
- async function Pe(t) {
284
+ async function Te(r) {
223
285
  const {
224
- tokenAddress: n,
286
+ tokenAddress: t,
225
287
  chainId: e
226
- } = t, o = `${e}-${n.toLowerCase()}`, a = D[o];
227
- if (a)
228
- return a;
229
- const r = ne(t);
230
- return D[o] = r, r;
288
+ } = r, o = `${e}-${t.toLowerCase()}`, n = _[o];
289
+ if (n)
290
+ return n;
291
+ const a = ie(r);
292
+ return _[o] = a, a;
231
293
  }
232
- async function ne(t) {
294
+ async function ie(r) {
233
295
  const {
234
- spender: n,
296
+ spender: t,
235
297
  tokenAddress: e,
236
- tokenName: o,
237
- chainId: a,
238
- provider: r
239
- } = t, i = J(a, r), c = T.address;
240
- let l = o;
298
+ chainId: o,
299
+ provider: n
300
+ } = r, a = X(o, n), c = w.address;
301
+ let s;
302
+ try {
303
+ s = await Z(e, o, n);
304
+ } catch (i) {
305
+ console.debug(`[checkTokenIsPermittable] Couldn't fetch eip712domain for token ${e}`, i);
306
+ }
307
+ let l = s == null ? void 0 : s.name;
241
308
  try {
242
- l = await Z(e, a, r);
243
- } catch (s) {
244
- if (/ETIMEDOUT/.test(s) && !l)
309
+ l || (l = await re(e, o, n));
310
+ } catch (i) {
311
+ if (/ETIMEDOUT/.test(i) && !l)
245
312
  return {
246
313
  error: "Failed to fetch token name from contract. RPC connection error"
247
314
  };
248
- console.debug(`[checkTokenIsPermittable] Couldn't fetch token name from the contract for token ${e}, using provided '${l}'`, s);
315
+ console.debug(`[checkTokenIsPermittable] Couldn't fetch token name from the contract for token ${e}, using provided '${l}'`, i);
249
316
  }
250
317
  if (!l)
251
318
  return {
@@ -253,49 +320,49 @@ async function ne(t) {
253
320
  };
254
321
  let d;
255
322
  try {
256
- d = await i.getTokenNonce(e, c);
257
- } catch (s) {
258
- return s === "nonce not supported" || s.message === "nonce is NaN" ? (console.debug(`[checkTokenIsPermittable] Not a permittable token ${e} - ${l}`, s?.message || s), {
259
- ...P,
323
+ d = await a.getTokenNonce(e, c);
324
+ } catch (i) {
325
+ return i === "nonce not supported" || i.message === "nonce is NaN" ? (console.debug(`[checkTokenIsPermittable] Not a permittable token ${e} - ${l}`, (i == null ? void 0 : i.message) || i), {
326
+ ...g,
260
327
  name: l
261
- }) : (console.debug(`[checkTokenIsPermittable] Failed to get nonce for ${e} - ${l}`, s), {
262
- error: s.message || s.toString()
328
+ }) : (console.debug(`[checkTokenIsPermittable] Failed to get nonce for ${e} - ${l}`, i), {
329
+ error: i.message || i.toString()
263
330
  });
264
331
  }
265
- let u;
266
- if (!q.has(e))
332
+ let u = s == null ? void 0 : s.version;
333
+ if (!W.has(e) && u === void 0)
267
334
  try {
268
- u = await i.getTokenVersion(e);
269
- } catch (s) {
270
- console.debug(`[checkTokenIsPermittable] Failed to get version for ${e} - ${l}`, s);
335
+ u = await a.getTokenVersion(e);
336
+ } catch (i) {
337
+ console.debug(`[checkTokenIsPermittable] Failed to get version for ${e} - ${l}`, i);
271
338
  }
272
339
  const m = {
273
- chainId: a,
274
- eip2612PermitUtils: i,
340
+ chainId: o,
341
+ eip2612PermitUtils: a,
275
342
  nonce: d,
276
- spender: n,
343
+ spender: t,
277
344
  tokenAddress: e,
278
345
  tokenName: l,
279
346
  walletAddress: c,
280
347
  version: u
281
348
  };
282
349
  try {
283
- return await _({
350
+ return await S({
284
351
  ...m,
285
352
  type: "eip-2612",
286
- provider: r
353
+ provider: n
287
354
  });
288
- } catch (s) {
355
+ } catch (i) {
289
356
  try {
290
- return await oe(e, i) ? await _({
357
+ return await ce(e, a) ? await S({
291
358
  ...m,
292
359
  type: "dai-like",
293
- provider: r
294
- }) : /invalid signature/.test(s) || s?.code === "UNPREDICTABLE_GAS_LIMIT" ? (console.debug(`[checkTokenIsPermittable] Token ${e} - ${l} might be permittable, but it's not supported for now. Reason:`, s?.reason), {
295
- ...P,
360
+ provider: n
361
+ }) : /invalid signature/.test(i) || (i == null ? void 0 : i.code) === "UNPREDICTABLE_GAS_LIMIT" ? (console.debug(`[checkTokenIsPermittable] Token ${e} - ${l} might be permittable, but it's not supported for now. Reason:`, i == null ? void 0 : i.reason), {
362
+ ...g,
296
363
  name: l
297
- }) : (console.debug(`[checkTokenIsPermittable] Failed to estimate eip-2612 permit for ${e} - ${l}`, s), {
298
- error: s.message || s.toString()
364
+ }) : (console.debug(`[checkTokenIsPermittable] Failed to estimate eip-2612 permit for ${e} - ${l}`, i), {
365
+ error: i.message || i.toString()
299
366
  });
300
367
  } catch (p) {
301
368
  return console.debug(`[checkTokenIsPermittable] Failed to estimate dai-like permit for ${e} - ${l}`, p), {
@@ -304,82 +371,82 @@ async function ne(t) {
304
371
  }
305
372
  }
306
373
  }
307
- async function _(t) {
374
+ async function S(r) {
308
375
  const {
309
- provider: n,
376
+ provider: t,
310
377
  chainId: e,
311
378
  walletAddress: o,
312
- tokenAddress: a,
313
- tokenName: r,
314
- type: i,
315
- version: c
316
- } = t, d = await (i === "eip-2612" ? re : ae)(t);
317
- return d ? (await n.estimateGas({
379
+ tokenAddress: n,
380
+ tokenName: a,
381
+ type: c,
382
+ version: s
383
+ } = r, d = await (c === "eip-2612" ? se : le)(r);
384
+ return d ? (await t.estimateGas({
318
385
  data: d,
319
386
  from: o,
320
- to: a
387
+ to: n
321
388
  })).toNumber() > V[e] ? {
322
- type: i,
323
- version: c,
324
- name: r
389
+ type: c,
390
+ version: s,
391
+ name: a
325
392
  } : {
326
- ...P,
327
- name: r
393
+ ...g,
394
+ name: a
328
395
  } : {
329
- ...P,
330
- name: r
396
+ ...g,
397
+ name: a
331
398
  };
332
399
  }
333
- async function re(t) {
400
+ async function se(r) {
334
401
  const {
335
- eip2612PermitUtils: n,
402
+ eip2612PermitUtils: t,
336
403
  walletAddress: e,
337
404
  spender: o,
338
- nonce: a,
339
- chainId: r,
340
- tokenName: i,
341
- tokenAddress: c,
405
+ nonce: n,
406
+ chainId: a,
407
+ tokenName: c,
408
+ tokenAddress: s,
342
409
  version: l
343
- } = t;
344
- return N({
345
- eip2162Utils: n,
410
+ } = r;
411
+ return R({
412
+ eip2162Utils: t,
346
413
  callDataParams: [{
347
- ...ee,
414
+ ...oe,
348
415
  owner: e,
349
416
  spender: o,
350
- nonce: a
351
- }, +r, i, c, l]
417
+ nonce: n
418
+ }, +a, c, s, l]
352
419
  });
353
420
  }
354
- async function oe(t, n) {
355
- return await n.getPermitTypeHash(t) === S;
421
+ async function ce(r, t) {
422
+ return await t.getPermitTypeHash(r) === L;
356
423
  }
357
- async function ae(t) {
424
+ async function le(r) {
358
425
  const {
359
- eip2612PermitUtils: n,
426
+ eip2612PermitUtils: t,
360
427
  tokenAddress: e,
361
428
  walletAddress: o,
362
- spender: a,
363
- nonce: r,
364
- chainId: i,
365
- tokenName: c,
429
+ spender: n,
430
+ nonce: a,
431
+ chainId: c,
432
+ tokenName: s,
366
433
  version: l
367
- } = t;
368
- return await n.getPermitTypeHash(e) === S ? $({
369
- eip2162Utils: n,
434
+ } = r;
435
+ return await t.getPermitTypeHash(e) === L ? M({
436
+ eip2162Utils: t,
370
437
  callDataParams: [{
371
- ...te,
438
+ ...ae,
372
439
  holder: o,
373
- spender: a,
374
- nonce: r
375
- }, i, c, e, l]
440
+ spender: n,
441
+ nonce: a
442
+ }, c, s, e, l]
376
443
  }) : !1;
377
444
  }
378
445
  export {
379
- T as PERMIT_SIGNER,
380
- fe as checkIsCallDataAValidPermit,
381
- ge as generatePermitHook,
382
- J as getPermitUtilsInstance,
383
- Pe as getTokenPermitInfo,
384
- W as isSupportedPermitInfo
446
+ w as PERMIT_SIGNER,
447
+ Ie as checkIsCallDataAValidPermit,
448
+ Pe as generatePermitHook,
449
+ X as getPermitUtilsInstance,
450
+ Te as getTokenPermitInfo,
451
+ j as isSupportedPermitInfo
385
452
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cowprotocol/permit-utils",
3
- "version": "0.0.2",
3
+ "version": "0.1.1-RC.0",
4
4
  "type": "module",
5
5
  "dependencies": {
6
6
  "ethers": "^5.7.2",
package/types.d.ts CHANGED
@@ -38,7 +38,6 @@ export type BuildDaiLikePermitCallDataParams = BasePermitCallDataParams & {
38
38
  export type GetTokenPermitInfoParams = {
39
39
  spender: string;
40
40
  tokenAddress: string;
41
- tokenName?: string | undefined;
42
41
  chainId: number;
43
42
  provider: JsonRpcProvider;
44
43
  };
@@ -0,0 +1,13 @@
1
+ import type { JsonRpcProvider } from '@ethersproject/providers';
2
+ export declare function getEip712Domain(tokenAddress: string, chainId: number, provider: JsonRpcProvider): Promise<Eip712Domain>;
3
+ type Eip5267Return = {
4
+ fields: string;
5
+ name?: string;
6
+ version?: string;
7
+ chainId?: string;
8
+ verifyingContract?: string;
9
+ salt?: string;
10
+ extensions?: string[];
11
+ };
12
+ export type Eip712Domain = Omit<Eip5267Return, 'fields' | 'extensions'>;
13
+ export {};
@@ -1 +0,0 @@
1
- export declare function fixTokenName(tokenName: string): string;