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