@0xsequence/provider 0.42.8 → 0.42.9

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.
@@ -1719,6 +1719,114 @@ const hexlifyTransaction = (transaction, allowExtra) => {
1719
1719
  return result;
1720
1720
  };
1721
1721
 
1722
+ function messageIsExemptFromEIP191Prefix(message) {
1723
+ return EIP_191_PREFIX_EXCEPTIONS.some(e => e.predicate(message));
1724
+ }
1725
+ const EIP_191_PREFIX_EXCEPTIONS = [// NOTE: Decentraland does not support 191 correctly.
1726
+ {
1727
+ name: 'Decentraland Exception',
1728
+ predicate: isDecentralandLoginMessage
1729
+ }, // NOTE: 0x v3 does not support 191 correctly.
1730
+ // See https://gov.0x.org/t/zeip-proposal-fix-v3-eip-191-non-compliance-when-validating-eip-1271-signatures/3396 for more info.
1731
+ {
1732
+ name: '0x v3 Exception',
1733
+ predicate: isZeroExV3Order
1734
+ }];
1735
+ const DCL_REGEX = /^Decentraland Login\nEphemeral address: 0x[a-fA-F0-9]{40}\nExpiration: (\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)((-(\d{2}):(\d{2})|Z)?)$/;
1736
+ function isDecentralandLoginMessage(bytes) {
1737
+ try {
1738
+ const stringified = ethers.ethers.utils.toUtf8String(bytes);
1739
+ return DCL_REGEX.test(stringified);
1740
+ } catch (_unused) {
1741
+ return false;
1742
+ }
1743
+ } // try to interpret bytes as abi-encoded 0x v3 OrderWithHash -
1744
+ // see https://github.com/0xProject/0x-protocol-specification/blob/master/v3/v3-specification.md
1745
+
1746
+ function isZeroExV3Order(bytes) {
1747
+ const abi = new ethers.ethers.utils.Interface(ZeroXV3EIP1271OrderWithHashAbi);
1748
+
1749
+ try {
1750
+ abi.decodeFunctionData('OrderWithHash', bytes);
1751
+ return true;
1752
+ } catch (err) {
1753
+ // failed to decode ABI, so it's not a v3 order.
1754
+ return false;
1755
+ }
1756
+ }
1757
+ const ZeroXV3EIP1271OrderWithHashAbi = [{
1758
+ inputs: [{
1759
+ components: [{
1760
+ internalType: 'address',
1761
+ name: 'makerAddress',
1762
+ type: 'address'
1763
+ }, {
1764
+ internalType: 'address',
1765
+ name: 'takerAddress',
1766
+ type: 'address'
1767
+ }, {
1768
+ internalType: 'address',
1769
+ name: 'feeRecipientAddress',
1770
+ type: 'address'
1771
+ }, {
1772
+ internalType: 'address',
1773
+ name: 'senderAddress',
1774
+ type: 'address'
1775
+ }, {
1776
+ internalType: 'uint256',
1777
+ name: 'makerAssetAmount',
1778
+ type: 'uint256'
1779
+ }, {
1780
+ internalType: 'uint256',
1781
+ name: 'takerAssetAmount',
1782
+ type: 'uint256'
1783
+ }, {
1784
+ internalType: 'uint256',
1785
+ name: 'makerFee',
1786
+ type: 'uint256'
1787
+ }, {
1788
+ internalType: 'uint256',
1789
+ name: 'takerFee',
1790
+ type: 'uint256'
1791
+ }, {
1792
+ internalType: 'uint256',
1793
+ name: 'expirationTimeSeconds',
1794
+ type: 'uint256'
1795
+ }, {
1796
+ internalType: 'uint256',
1797
+ name: 'salt',
1798
+ type: 'uint256'
1799
+ }, {
1800
+ internalType: 'bytes',
1801
+ name: 'makerAssetData',
1802
+ type: 'bytes'
1803
+ }, {
1804
+ internalType: 'bytes',
1805
+ name: 'takerAssetData',
1806
+ type: 'bytes'
1807
+ }, {
1808
+ internalType: 'bytes',
1809
+ name: 'makerFeeAssetData',
1810
+ type: 'bytes'
1811
+ }, {
1812
+ internalType: 'bytes',
1813
+ name: 'takerFeeAssetData',
1814
+ type: 'bytes'
1815
+ }],
1816
+ internalType: 'struct IEIP1271Data.Order',
1817
+ name: 'order',
1818
+ type: 'tuple'
1819
+ }, {
1820
+ internalType: 'bytes32',
1821
+ name: 'orderHash',
1822
+ type: 'bytes32'
1823
+ }],
1824
+ name: 'OrderWithHash',
1825
+ outputs: [],
1826
+ stateMutability: 'pure',
1827
+ type: 'function'
1828
+ }];
1829
+
1722
1830
  const eip191prefix = ethers.ethers.utils.toUtf8Bytes('\x19Ethereum Signed Message:\n');
1723
1831
  const messageToBytes = message => {
1724
1832
  if (ethers.ethers.utils.isBytes(message) || ethers.ethers.utils.isHexString(message)) {
@@ -1729,7 +1837,12 @@ const messageToBytes = message => {
1729
1837
  };
1730
1838
  const prefixEIP191Message = message => {
1731
1839
  const messageBytes = messageToBytes(message);
1732
- return ethers.ethers.utils.concat([eip191prefix, ethers.ethers.utils.toUtf8Bytes(String(messageBytes.length)), messageBytes]);
1840
+
1841
+ if (messageIsExemptFromEIP191Prefix(messageBytes)) {
1842
+ return messageBytes;
1843
+ } else {
1844
+ return ethers.ethers.utils.concat([eip191prefix, ethers.ethers.utils.toUtf8Bytes(String(messageBytes.length)), messageBytes]);
1845
+ }
1733
1846
  };
1734
1847
  const isValidSignature = async (address, digest, sig, provider, chainId, walletContext) => {
1735
1848
  if (!chainId) {
@@ -1719,6 +1719,114 @@ const hexlifyTransaction = (transaction, allowExtra) => {
1719
1719
  return result;
1720
1720
  };
1721
1721
 
1722
+ function messageIsExemptFromEIP191Prefix(message) {
1723
+ return EIP_191_PREFIX_EXCEPTIONS.some(e => e.predicate(message));
1724
+ }
1725
+ const EIP_191_PREFIX_EXCEPTIONS = [// NOTE: Decentraland does not support 191 correctly.
1726
+ {
1727
+ name: 'Decentraland Exception',
1728
+ predicate: isDecentralandLoginMessage
1729
+ }, // NOTE: 0x v3 does not support 191 correctly.
1730
+ // See https://gov.0x.org/t/zeip-proposal-fix-v3-eip-191-non-compliance-when-validating-eip-1271-signatures/3396 for more info.
1731
+ {
1732
+ name: '0x v3 Exception',
1733
+ predicate: isZeroExV3Order
1734
+ }];
1735
+ const DCL_REGEX = /^Decentraland Login\nEphemeral address: 0x[a-fA-F0-9]{40}\nExpiration: (\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)((-(\d{2}):(\d{2})|Z)?)$/;
1736
+ function isDecentralandLoginMessage(bytes) {
1737
+ try {
1738
+ const stringified = ethers.ethers.utils.toUtf8String(bytes);
1739
+ return DCL_REGEX.test(stringified);
1740
+ } catch (_unused) {
1741
+ return false;
1742
+ }
1743
+ } // try to interpret bytes as abi-encoded 0x v3 OrderWithHash -
1744
+ // see https://github.com/0xProject/0x-protocol-specification/blob/master/v3/v3-specification.md
1745
+
1746
+ function isZeroExV3Order(bytes) {
1747
+ const abi = new ethers.ethers.utils.Interface(ZeroXV3EIP1271OrderWithHashAbi);
1748
+
1749
+ try {
1750
+ abi.decodeFunctionData('OrderWithHash', bytes);
1751
+ return true;
1752
+ } catch (err) {
1753
+ // failed to decode ABI, so it's not a v3 order.
1754
+ return false;
1755
+ }
1756
+ }
1757
+ const ZeroXV3EIP1271OrderWithHashAbi = [{
1758
+ inputs: [{
1759
+ components: [{
1760
+ internalType: 'address',
1761
+ name: 'makerAddress',
1762
+ type: 'address'
1763
+ }, {
1764
+ internalType: 'address',
1765
+ name: 'takerAddress',
1766
+ type: 'address'
1767
+ }, {
1768
+ internalType: 'address',
1769
+ name: 'feeRecipientAddress',
1770
+ type: 'address'
1771
+ }, {
1772
+ internalType: 'address',
1773
+ name: 'senderAddress',
1774
+ type: 'address'
1775
+ }, {
1776
+ internalType: 'uint256',
1777
+ name: 'makerAssetAmount',
1778
+ type: 'uint256'
1779
+ }, {
1780
+ internalType: 'uint256',
1781
+ name: 'takerAssetAmount',
1782
+ type: 'uint256'
1783
+ }, {
1784
+ internalType: 'uint256',
1785
+ name: 'makerFee',
1786
+ type: 'uint256'
1787
+ }, {
1788
+ internalType: 'uint256',
1789
+ name: 'takerFee',
1790
+ type: 'uint256'
1791
+ }, {
1792
+ internalType: 'uint256',
1793
+ name: 'expirationTimeSeconds',
1794
+ type: 'uint256'
1795
+ }, {
1796
+ internalType: 'uint256',
1797
+ name: 'salt',
1798
+ type: 'uint256'
1799
+ }, {
1800
+ internalType: 'bytes',
1801
+ name: 'makerAssetData',
1802
+ type: 'bytes'
1803
+ }, {
1804
+ internalType: 'bytes',
1805
+ name: 'takerAssetData',
1806
+ type: 'bytes'
1807
+ }, {
1808
+ internalType: 'bytes',
1809
+ name: 'makerFeeAssetData',
1810
+ type: 'bytes'
1811
+ }, {
1812
+ internalType: 'bytes',
1813
+ name: 'takerFeeAssetData',
1814
+ type: 'bytes'
1815
+ }],
1816
+ internalType: 'struct IEIP1271Data.Order',
1817
+ name: 'order',
1818
+ type: 'tuple'
1819
+ }, {
1820
+ internalType: 'bytes32',
1821
+ name: 'orderHash',
1822
+ type: 'bytes32'
1823
+ }],
1824
+ name: 'OrderWithHash',
1825
+ outputs: [],
1826
+ stateMutability: 'pure',
1827
+ type: 'function'
1828
+ }];
1829
+
1722
1830
  const eip191prefix = ethers.ethers.utils.toUtf8Bytes('\x19Ethereum Signed Message:\n');
1723
1831
  const messageToBytes = message => {
1724
1832
  if (ethers.ethers.utils.isBytes(message) || ethers.ethers.utils.isHexString(message)) {
@@ -1729,7 +1837,12 @@ const messageToBytes = message => {
1729
1837
  };
1730
1838
  const prefixEIP191Message = message => {
1731
1839
  const messageBytes = messageToBytes(message);
1732
- return ethers.ethers.utils.concat([eip191prefix, ethers.ethers.utils.toUtf8Bytes(String(messageBytes.length)), messageBytes]);
1840
+
1841
+ if (messageIsExemptFromEIP191Prefix(messageBytes)) {
1842
+ return messageBytes;
1843
+ } else {
1844
+ return ethers.ethers.utils.concat([eip191prefix, ethers.ethers.utils.toUtf8Bytes(String(messageBytes.length)), messageBytes]);
1845
+ }
1733
1846
  };
1734
1847
  const isValidSignature = async (address, digest, sig, provider, chainId, walletContext) => {
1735
1848
  if (!chainId) {
@@ -1715,6 +1715,114 @@ const hexlifyTransaction = (transaction, allowExtra) => {
1715
1715
  return result;
1716
1716
  };
1717
1717
 
1718
+ function messageIsExemptFromEIP191Prefix(message) {
1719
+ return EIP_191_PREFIX_EXCEPTIONS.some(e => e.predicate(message));
1720
+ }
1721
+ const EIP_191_PREFIX_EXCEPTIONS = [// NOTE: Decentraland does not support 191 correctly.
1722
+ {
1723
+ name: 'Decentraland Exception',
1724
+ predicate: isDecentralandLoginMessage
1725
+ }, // NOTE: 0x v3 does not support 191 correctly.
1726
+ // See https://gov.0x.org/t/zeip-proposal-fix-v3-eip-191-non-compliance-when-validating-eip-1271-signatures/3396 for more info.
1727
+ {
1728
+ name: '0x v3 Exception',
1729
+ predicate: isZeroExV3Order
1730
+ }];
1731
+ const DCL_REGEX = /^Decentraland Login\nEphemeral address: 0x[a-fA-F0-9]{40}\nExpiration: (\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)((-(\d{2}):(\d{2})|Z)?)$/;
1732
+ function isDecentralandLoginMessage(bytes) {
1733
+ try {
1734
+ const stringified = ethers.utils.toUtf8String(bytes);
1735
+ return DCL_REGEX.test(stringified);
1736
+ } catch (_unused) {
1737
+ return false;
1738
+ }
1739
+ } // try to interpret bytes as abi-encoded 0x v3 OrderWithHash -
1740
+ // see https://github.com/0xProject/0x-protocol-specification/blob/master/v3/v3-specification.md
1741
+
1742
+ function isZeroExV3Order(bytes) {
1743
+ const abi = new ethers.utils.Interface(ZeroXV3EIP1271OrderWithHashAbi);
1744
+
1745
+ try {
1746
+ abi.decodeFunctionData('OrderWithHash', bytes);
1747
+ return true;
1748
+ } catch (err) {
1749
+ // failed to decode ABI, so it's not a v3 order.
1750
+ return false;
1751
+ }
1752
+ }
1753
+ const ZeroXV3EIP1271OrderWithHashAbi = [{
1754
+ inputs: [{
1755
+ components: [{
1756
+ internalType: 'address',
1757
+ name: 'makerAddress',
1758
+ type: 'address'
1759
+ }, {
1760
+ internalType: 'address',
1761
+ name: 'takerAddress',
1762
+ type: 'address'
1763
+ }, {
1764
+ internalType: 'address',
1765
+ name: 'feeRecipientAddress',
1766
+ type: 'address'
1767
+ }, {
1768
+ internalType: 'address',
1769
+ name: 'senderAddress',
1770
+ type: 'address'
1771
+ }, {
1772
+ internalType: 'uint256',
1773
+ name: 'makerAssetAmount',
1774
+ type: 'uint256'
1775
+ }, {
1776
+ internalType: 'uint256',
1777
+ name: 'takerAssetAmount',
1778
+ type: 'uint256'
1779
+ }, {
1780
+ internalType: 'uint256',
1781
+ name: 'makerFee',
1782
+ type: 'uint256'
1783
+ }, {
1784
+ internalType: 'uint256',
1785
+ name: 'takerFee',
1786
+ type: 'uint256'
1787
+ }, {
1788
+ internalType: 'uint256',
1789
+ name: 'expirationTimeSeconds',
1790
+ type: 'uint256'
1791
+ }, {
1792
+ internalType: 'uint256',
1793
+ name: 'salt',
1794
+ type: 'uint256'
1795
+ }, {
1796
+ internalType: 'bytes',
1797
+ name: 'makerAssetData',
1798
+ type: 'bytes'
1799
+ }, {
1800
+ internalType: 'bytes',
1801
+ name: 'takerAssetData',
1802
+ type: 'bytes'
1803
+ }, {
1804
+ internalType: 'bytes',
1805
+ name: 'makerFeeAssetData',
1806
+ type: 'bytes'
1807
+ }, {
1808
+ internalType: 'bytes',
1809
+ name: 'takerFeeAssetData',
1810
+ type: 'bytes'
1811
+ }],
1812
+ internalType: 'struct IEIP1271Data.Order',
1813
+ name: 'order',
1814
+ type: 'tuple'
1815
+ }, {
1816
+ internalType: 'bytes32',
1817
+ name: 'orderHash',
1818
+ type: 'bytes32'
1819
+ }],
1820
+ name: 'OrderWithHash',
1821
+ outputs: [],
1822
+ stateMutability: 'pure',
1823
+ type: 'function'
1824
+ }];
1825
+
1718
1826
  const eip191prefix = ethers.utils.toUtf8Bytes('\x19Ethereum Signed Message:\n');
1719
1827
  const messageToBytes = message => {
1720
1828
  if (ethers.utils.isBytes(message) || ethers.utils.isHexString(message)) {
@@ -1725,7 +1833,12 @@ const messageToBytes = message => {
1725
1833
  };
1726
1834
  const prefixEIP191Message = message => {
1727
1835
  const messageBytes = messageToBytes(message);
1728
- return ethers.utils.concat([eip191prefix, ethers.utils.toUtf8Bytes(String(messageBytes.length)), messageBytes]);
1836
+
1837
+ if (messageIsExemptFromEIP191Prefix(messageBytes)) {
1838
+ return messageBytes;
1839
+ } else {
1840
+ return ethers.utils.concat([eip191prefix, ethers.utils.toUtf8Bytes(String(messageBytes.length)), messageBytes]);
1841
+ }
1729
1842
  };
1730
1843
  const isValidSignature = async (address, digest, sig, provider, chainId, walletContext) => {
1731
1844
  if (!chainId) {
@@ -0,0 +1,3 @@
1
+ export declare function messageIsExemptFromEIP191Prefix(message: Uint8Array): boolean;
2
+ export declare function isDecentralandLoginMessage(bytes: Uint8Array): boolean;
3
+ export declare function isZeroExV3Order(bytes: Uint8Array): boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@0xsequence/provider",
3
- "version": "0.42.8",
3
+ "version": "0.42.9",
4
4
  "description": "provider sub-package for Sequence",
5
5
  "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/provider",
6
6
  "source": "src/index.ts",
@@ -9,17 +9,18 @@
9
9
  "author": "Horizon Blockchain Games",
10
10
  "license": "Apache-2.0",
11
11
  "scripts": {
12
- "test": "echo",
12
+ "test": "yarn test:file tests/**/*.spec.ts",
13
+ "test:file": "TS_NODE_PROJECT=../../tsconfig.test.json mocha -r ts-node/register --timeout 30000",
13
14
  "typecheck": "tsc --noEmit"
14
15
  },
15
16
  "dependencies": {
16
- "@0xsequence/abi": "^0.42.8",
17
- "@0xsequence/auth": "^0.42.8",
18
- "@0xsequence/config": "^0.42.8",
19
- "@0xsequence/network": "^0.42.8",
20
- "@0xsequence/transactions": "^0.42.8",
21
- "@0xsequence/utils": "^0.42.8",
22
- "@0xsequence/wallet": "^0.42.8",
17
+ "@0xsequence/abi": "^0.42.9",
18
+ "@0xsequence/auth": "^0.42.9",
19
+ "@0xsequence/config": "^0.42.9",
20
+ "@0xsequence/network": "^0.42.9",
21
+ "@0xsequence/transactions": "^0.42.9",
22
+ "@0xsequence/utils": "^0.42.9",
23
+ "@0xsequence/wallet": "^0.42.9",
23
24
  "@ethersproject/abstract-signer": "^5.5.0",
24
25
  "@ethersproject/hash": "^5.5.0",
25
26
  "@ethersproject/providers": "^5.5.1",
@@ -34,4 +35,4 @@
34
35
  "src",
35
36
  "dist"
36
37
  ]
37
- }
38
+ }
@@ -0,0 +1,137 @@
1
+ import { ethers } from 'ethers'
2
+
3
+ export function messageIsExemptFromEIP191Prefix(message: Uint8Array): boolean {
4
+ return EIP_191_PREFIX_EXCEPTIONS.some(e => e.predicate(message))
5
+ }
6
+
7
+ const EIP_191_PREFIX_EXCEPTIONS: Array<{
8
+ name: string
9
+ predicate: (message: Uint8Array) => boolean
10
+ }> = [
11
+ // NOTE: Decentraland does not support 191 correctly.
12
+ {
13
+ name: 'Decentraland Exception',
14
+ predicate: isDecentralandLoginMessage
15
+ },
16
+
17
+ // NOTE: 0x v3 does not support 191 correctly.
18
+ // See https://gov.0x.org/t/zeip-proposal-fix-v3-eip-191-non-compliance-when-validating-eip-1271-signatures/3396 for more info.
19
+ { name: '0x v3 Exception', predicate: isZeroExV3Order }
20
+ ]
21
+
22
+ const DCL_REGEX =
23
+ /^Decentraland Login\nEphemeral address: 0x[a-fA-F0-9]{40}\nExpiration: (\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)((-(\d{2}):(\d{2})|Z)?)$/
24
+ export function isDecentralandLoginMessage(bytes: Uint8Array): boolean {
25
+ try {
26
+ const stringified = ethers.utils.toUtf8String(bytes)
27
+ return DCL_REGEX.test(stringified)
28
+ } catch {
29
+ return false
30
+ }
31
+ }
32
+
33
+ // try to interpret bytes as abi-encoded 0x v3 OrderWithHash -
34
+ // see https://github.com/0xProject/0x-protocol-specification/blob/master/v3/v3-specification.md
35
+ export function isZeroExV3Order(bytes: Uint8Array): boolean {
36
+ const abi = new ethers.utils.Interface(ZeroXV3EIP1271OrderWithHashAbi)
37
+ try {
38
+ abi.decodeFunctionData('OrderWithHash', bytes)
39
+ return true
40
+ } catch (err) {
41
+ // failed to decode ABI, so it's not a v3 order.
42
+ return false
43
+ }
44
+ }
45
+
46
+ const ZeroXV3EIP1271OrderWithHashAbi = [
47
+ {
48
+ inputs: [
49
+ {
50
+ components: [
51
+ {
52
+ internalType: 'address',
53
+ name: 'makerAddress',
54
+ type: 'address'
55
+ },
56
+ {
57
+ internalType: 'address',
58
+ name: 'takerAddress',
59
+ type: 'address'
60
+ },
61
+ {
62
+ internalType: 'address',
63
+ name: 'feeRecipientAddress',
64
+ type: 'address'
65
+ },
66
+ {
67
+ internalType: 'address',
68
+ name: 'senderAddress',
69
+ type: 'address'
70
+ },
71
+ {
72
+ internalType: 'uint256',
73
+ name: 'makerAssetAmount',
74
+ type: 'uint256'
75
+ },
76
+ {
77
+ internalType: 'uint256',
78
+ name: 'takerAssetAmount',
79
+ type: 'uint256'
80
+ },
81
+ {
82
+ internalType: 'uint256',
83
+ name: 'makerFee',
84
+ type: 'uint256'
85
+ },
86
+ {
87
+ internalType: 'uint256',
88
+ name: 'takerFee',
89
+ type: 'uint256'
90
+ },
91
+ {
92
+ internalType: 'uint256',
93
+ name: 'expirationTimeSeconds',
94
+ type: 'uint256'
95
+ },
96
+ {
97
+ internalType: 'uint256',
98
+ name: 'salt',
99
+ type: 'uint256'
100
+ },
101
+ {
102
+ internalType: 'bytes',
103
+ name: 'makerAssetData',
104
+ type: 'bytes'
105
+ },
106
+ {
107
+ internalType: 'bytes',
108
+ name: 'takerAssetData',
109
+ type: 'bytes'
110
+ },
111
+ {
112
+ internalType: 'bytes',
113
+ name: 'makerFeeAssetData',
114
+ type: 'bytes'
115
+ },
116
+ {
117
+ internalType: 'bytes',
118
+ name: 'takerFeeAssetData',
119
+ type: 'bytes'
120
+ }
121
+ ],
122
+ internalType: 'struct IEIP1271Data.Order',
123
+ name: 'order',
124
+ type: 'tuple'
125
+ },
126
+ {
127
+ internalType: 'bytes32',
128
+ name: 'orderHash',
129
+ type: 'bytes32'
130
+ }
131
+ ],
132
+ name: 'OrderWithHash',
133
+ outputs: [],
134
+ stateMutability: 'pure',
135
+ type: 'function'
136
+ }
137
+ ]
@@ -113,7 +113,13 @@ export class WalletUtils {
113
113
  walletContext?: WalletContext
114
114
  ): Promise<WalletConfig> => {
115
115
  walletContext = walletContext || (await this.wallet.getWalletContext())
116
- return recoverWalletConfig(address, encodeMessageDigest(prefixEIP191Message(message)), signature, chainId, walletContext)
116
+ return recoverWalletConfig(
117
+ address,
118
+ encodeMessageDigest(prefixEIP191Message(message)),
119
+ signature,
120
+ chainId,
121
+ walletContext
122
+ )
117
123
  }
118
124
 
119
125
  // Recover the WalletConfig from a signature of a typedData object
package/src/utils.ts CHANGED
@@ -4,6 +4,7 @@ import { WalletConfig, addressOf, DecodedSignature, isConfigEqual } from '@0xseq
4
4
  import { packMessageData, encodeMessageDigest, TypedData, encodeTypedDataDigest } from '@0xsequence/utils'
5
5
  import { Web3Provider } from './provider'
6
6
  import { isValidSignature as _isValidSignature, recoverConfig, Signer } from '@0xsequence/wallet'
7
+ import { messageIsExemptFromEIP191Prefix } from './eip191exceptions'
7
8
 
8
9
  const eip191prefix = ethers.utils.toUtf8Bytes('\x19Ethereum Signed Message:\n')
9
10
 
@@ -17,7 +18,11 @@ export const messageToBytes = (message: BytesLike): Uint8Array => {
17
18
 
18
19
  export const prefixEIP191Message = (message: BytesLike): Uint8Array => {
19
20
  const messageBytes = messageToBytes(message)
20
- return ethers.utils.concat([eip191prefix, ethers.utils.toUtf8Bytes(String(messageBytes.length)), messageBytes])
21
+ if (messageIsExemptFromEIP191Prefix(messageBytes)) {
22
+ return messageBytes
23
+ } else {
24
+ return ethers.utils.concat([eip191prefix, ethers.utils.toUtf8Bytes(String(messageBytes.length)), messageBytes])
25
+ }
21
26
  }
22
27
 
23
28
  export const isValidSignature = async (