@cowprotocol/permit-utils 0.0.1-RC.1 → 0.0.1

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