viem 2.11.1 → 2.12.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (161) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/README.md +3 -3
  3. package/_cjs/actions/public/verifyMessage.js.map +1 -1
  4. package/_cjs/actions/siwe/verifySiweMessage.js +32 -0
  5. package/_cjs/actions/siwe/verifySiweMessage.js.map +1 -0
  6. package/_cjs/chains/definitions/flowPreviewnet.js +6 -0
  7. package/_cjs/chains/definitions/flowPreviewnet.js.map +1 -1
  8. package/_cjs/chains/definitions/jbcTestnet.js +0 -4
  9. package/_cjs/chains/definitions/jbcTestnet.js.map +1 -1
  10. package/_cjs/chains/definitions/l3x.js +24 -0
  11. package/_cjs/chains/definitions/l3x.js.map +1 -0
  12. package/_cjs/chains/definitions/l3xTestnet.js +24 -0
  13. package/_cjs/chains/definitions/l3xTestnet.js.map +1 -0
  14. package/_cjs/chains/definitions/metis.js +5 -0
  15. package/_cjs/chains/definitions/metis.js.map +1 -1
  16. package/_cjs/chains/definitions/thaiChain.js +29 -0
  17. package/_cjs/chains/definitions/thaiChain.js.map +1 -0
  18. package/_cjs/chains/definitions/zkSync.js +4 -0
  19. package/_cjs/chains/definitions/zkSync.js.map +1 -1
  20. package/_cjs/chains/definitions/zkSyncSepoliaTestnet.js +5 -1
  21. package/_cjs/chains/definitions/zkSyncSepoliaTestnet.js.map +1 -1
  22. package/_cjs/chains/index.js +10 -4
  23. package/_cjs/chains/index.js.map +1 -1
  24. package/_cjs/clients/decorators/public.js +2 -0
  25. package/_cjs/clients/decorators/public.js.map +1 -1
  26. package/_cjs/errors/siwe.js +22 -0
  27. package/_cjs/errors/siwe.js.map +1 -0
  28. package/_cjs/errors/version.js +1 -1
  29. package/_cjs/siwe/index.js +16 -0
  30. package/_cjs/siwe/index.js.map +1 -0
  31. package/_cjs/utils/address/isAddress.js +4 -3
  32. package/_cjs/utils/address/isAddress.js.map +1 -1
  33. package/_cjs/utils/siwe/createSiweMessage.js +126 -0
  34. package/_cjs/utils/siwe/createSiweMessage.js.map +1 -0
  35. package/_cjs/utils/siwe/generateSiweNonce.js +9 -0
  36. package/_cjs/utils/siwe/generateSiweNonce.js.map +1 -0
  37. package/_cjs/utils/siwe/parseSiweMessage.js +25 -0
  38. package/_cjs/utils/siwe/parseSiweMessage.js.map +1 -0
  39. package/_cjs/utils/siwe/types.js +3 -0
  40. package/_cjs/utils/siwe/types.js.map +1 -0
  41. package/_cjs/utils/siwe/utils.js +44 -0
  42. package/_cjs/utils/siwe/utils.js.map +1 -0
  43. package/_cjs/utils/siwe/validateSiweMessage.js +29 -0
  44. package/_cjs/utils/siwe/validateSiweMessage.js.map +1 -0
  45. package/_esm/actions/public/verifyMessage.js.map +1 -1
  46. package/_esm/actions/siwe/verifySiweMessage.js +39 -0
  47. package/_esm/actions/siwe/verifySiweMessage.js.map +1 -0
  48. package/_esm/chains/definitions/flowPreviewnet.js +6 -0
  49. package/_esm/chains/definitions/flowPreviewnet.js.map +1 -1
  50. package/_esm/chains/definitions/jbcTestnet.js +0 -4
  51. package/_esm/chains/definitions/jbcTestnet.js.map +1 -1
  52. package/_esm/chains/definitions/l3x.js +21 -0
  53. package/_esm/chains/definitions/l3x.js.map +1 -0
  54. package/_esm/chains/definitions/l3xTestnet.js +21 -0
  55. package/_esm/chains/definitions/l3xTestnet.js.map +1 -0
  56. package/_esm/chains/definitions/metis.js +5 -0
  57. package/_esm/chains/definitions/metis.js.map +1 -1
  58. package/_esm/chains/definitions/thaiChain.js +26 -0
  59. package/_esm/chains/definitions/thaiChain.js.map +1 -0
  60. package/_esm/chains/definitions/zkSync.js +4 -0
  61. package/_esm/chains/definitions/zkSync.js.map +1 -1
  62. package/_esm/chains/definitions/zkSyncSepoliaTestnet.js +5 -1
  63. package/_esm/chains/definitions/zkSyncSepoliaTestnet.js.map +1 -1
  64. package/_esm/chains/index.js +3 -0
  65. package/_esm/chains/index.js.map +1 -1
  66. package/_esm/clients/decorators/public.js +2 -0
  67. package/_esm/clients/decorators/public.js.map +1 -1
  68. package/_esm/errors/siwe.js +18 -0
  69. package/_esm/errors/siwe.js.map +1 -0
  70. package/_esm/errors/version.js +1 -1
  71. package/_esm/node/trustedSetups.js +7 -1
  72. package/_esm/node/trustedSetups.js.map +1 -1
  73. package/_esm/node/trustedSetups_cjs.js +4 -0
  74. package/_esm/node/trustedSetups_cjs.js.map +1 -0
  75. package/_esm/siwe/index.js +7 -0
  76. package/_esm/siwe/index.js.map +1 -0
  77. package/_esm/utils/address/isAddress.js +4 -3
  78. package/_esm/utils/address/isAddress.js.map +1 -1
  79. package/_esm/utils/siwe/createSiweMessage.js +141 -0
  80. package/_esm/utils/siwe/createSiweMessage.js.map +1 -0
  81. package/_esm/utils/siwe/generateSiweNonce.js +15 -0
  82. package/_esm/utils/siwe/generateSiweNonce.js.map +1 -0
  83. package/_esm/utils/siwe/parseSiweMessage.js +30 -0
  84. package/_esm/utils/siwe/parseSiweMessage.js.map +1 -0
  85. package/_esm/utils/siwe/types.js +2 -0
  86. package/_esm/utils/siwe/types.js.map +1 -0
  87. package/_esm/utils/siwe/utils.js +49 -0
  88. package/_esm/utils/siwe/utils.js.map +1 -0
  89. package/_esm/utils/siwe/validateSiweMessage.js +30 -0
  90. package/_esm/utils/siwe/validateSiweMessage.js.map +1 -0
  91. package/_types/actions/public/verifyMessage.d.ts +3 -2
  92. package/_types/actions/public/verifyMessage.d.ts.map +1 -1
  93. package/_types/actions/siwe/verifySiweMessage.d.ts +34 -0
  94. package/_types/actions/siwe/verifySiweMessage.d.ts.map +1 -0
  95. package/_types/chains/definitions/flowPreviewnet.d.ts +6 -8
  96. package/_types/chains/definitions/flowPreviewnet.d.ts.map +1 -1
  97. package/_types/chains/definitions/jbcTestnet.d.ts +0 -4
  98. package/_types/chains/definitions/jbcTestnet.d.ts.map +1 -1
  99. package/_types/chains/definitions/l3x.d.ts +37 -0
  100. package/_types/chains/definitions/l3x.d.ts.map +1 -0
  101. package/_types/chains/definitions/l3xTestnet.d.ts +37 -0
  102. package/_types/chains/definitions/l3xTestnet.d.ts.map +1 -0
  103. package/_types/chains/definitions/metis.d.ts +5 -0
  104. package/_types/chains/definitions/metis.d.ts.map +1 -1
  105. package/_types/chains/definitions/thaiChain.d.ts +34 -0
  106. package/_types/chains/definitions/thaiChain.d.ts.map +1 -0
  107. package/_types/chains/definitions/zkSync.d.ts +4 -0
  108. package/_types/chains/definitions/zkSync.d.ts.map +1 -1
  109. package/_types/chains/definitions/zkSyncSepoliaTestnet.d.ts +5 -1
  110. package/_types/chains/definitions/zkSyncSepoliaTestnet.d.ts.map +1 -1
  111. package/_types/chains/index.d.ts +3 -0
  112. package/_types/chains/index.d.ts.map +1 -1
  113. package/_types/clients/decorators/public.d.ts +30 -0
  114. package/_types/clients/decorators/public.d.ts.map +1 -1
  115. package/_types/errors/siwe.d.ts +13 -0
  116. package/_types/errors/siwe.d.ts.map +1 -0
  117. package/_types/errors/version.d.ts +1 -1
  118. package/_types/node/trustedSetups.d.ts.map +1 -1
  119. package/_types/node/trustedSetups_cjs.d.ts +3 -0
  120. package/_types/node/trustedSetups_cjs.d.ts.map +1 -0
  121. package/_types/siwe/index.d.ts +8 -0
  122. package/_types/siwe/index.d.ts.map +1 -0
  123. package/_types/utils/address/isAddress.d.ts.map +1 -1
  124. package/_types/utils/siwe/createSiweMessage.d.ts +24 -0
  125. package/_types/utils/siwe/createSiweMessage.d.ts.map +1 -0
  126. package/_types/utils/siwe/generateSiweNonce.d.ts +12 -0
  127. package/_types/utils/siwe/generateSiweNonce.d.ts.map +1 -0
  128. package/_types/utils/siwe/parseSiweMessage.d.ts +11 -0
  129. package/_types/utils/siwe/parseSiweMessage.d.ts.map +1 -0
  130. package/_types/utils/siwe/types.d.ts +61 -0
  131. package/_types/utils/siwe/types.d.ts.map +1 -0
  132. package/_types/utils/siwe/utils.d.ts +2 -0
  133. package/_types/utils/siwe/utils.d.ts.map +1 -0
  134. package/_types/utils/siwe/validateSiweMessage.d.ts +39 -0
  135. package/_types/utils/siwe/validateSiweMessage.d.ts.map +1 -0
  136. package/actions/public/verifyMessage.ts +11 -8
  137. package/actions/siwe/verifySiweMessage.ts +90 -0
  138. package/chains/definitions/flowPreviewnet.ts +6 -0
  139. package/chains/definitions/jbcTestnet.ts +0 -4
  140. package/chains/definitions/l3x.ts +21 -0
  141. package/chains/definitions/l3xTestnet.ts +21 -0
  142. package/chains/definitions/metis.ts +6 -0
  143. package/chains/definitions/thaiChain.ts +26 -0
  144. package/chains/definitions/zkSync.ts +4 -0
  145. package/chains/definitions/zkSyncSepoliaTestnet.ts +5 -1
  146. package/chains/index.ts +3 -0
  147. package/clients/decorators/public.ts +37 -0
  148. package/errors/siwe.ts +20 -0
  149. package/errors/version.ts +1 -1
  150. package/node/trustedSetups.ts +9 -1
  151. package/node/trustedSetups_cjs.ts +11 -0
  152. package/package.json +9 -1
  153. package/siwe/index.ts +29 -0
  154. package/siwe/package.json +6 -0
  155. package/utils/address/isAddress.ts +3 -2
  156. package/utils/siwe/createSiweMessage.ts +178 -0
  157. package/utils/siwe/generateSiweNonce.ts +15 -0
  158. package/utils/siwe/parseSiweMessage.ts +55 -0
  159. package/utils/siwe/types.ts +61 -0
  160. package/utils/siwe/utils.ts +51 -0
  161. package/utils/siwe/validateSiweMessage.ts +70 -0
@@ -10,6 +10,7 @@ import type {
10
10
  SignableMessage,
11
11
  Signature,
12
12
  } from '../../types/misc.js'
13
+ import type { Prettify } from '../../types/utils.js'
13
14
  import { hashMessage } from '../../utils/signature/hashMessage.js'
14
15
  import type { HashMessageErrorType } from '../../utils/signature/hashMessage.js'
15
16
  import {
@@ -18,14 +19,16 @@ import {
18
19
  verifyHash,
19
20
  } from './verifyHash.js'
20
21
 
21
- export type VerifyMessageParameters = Omit<VerifyHashParameters, 'hash'> & {
22
- /** The address that signed the original message. */
23
- address: Address
24
- /** The message to be verified. */
25
- message: SignableMessage
26
- /** The signature that was generated by signing the message with the address's private key. */
27
- signature: Hex | ByteArray | Signature
28
- }
22
+ export type VerifyMessageParameters = Prettify<
23
+ Omit<VerifyHashParameters, 'hash'> & {
24
+ /** The address that signed the original message. */
25
+ address: Address
26
+ /** The message to be verified. */
27
+ message: SignableMessage
28
+ /** The signature that was generated by signing the message with the address's private key. */
29
+ signature: Hex | ByteArray | Signature
30
+ }
31
+ >
29
32
 
30
33
  export type VerifyMessageReturnType = boolean
31
34
 
@@ -0,0 +1,90 @@
1
+ import type { Client } from '../../clients/createClient.js'
2
+ import type { Transport } from '../../clients/transports/createTransport.js'
3
+ import type { ErrorType } from '../../errors/utils.js'
4
+ import type { Chain } from '../../types/chain.js'
5
+ import type { Hex } from '../../types/misc.js'
6
+ import type { Prettify } from '../../types/utils.js'
7
+ import { hashMessage } from '../../utils/signature/hashMessage.js'
8
+ import type { HashMessageErrorType } from '../../utils/signature/hashMessage.js'
9
+ import { parseSiweMessage } from '../../utils/siwe/parseSiweMessage.js'
10
+ import {
11
+ type ValidateSiweMessageParameters,
12
+ validateSiweMessage,
13
+ } from '../../utils/siwe/validateSiweMessage.js'
14
+ import {
15
+ type VerifyHashErrorType,
16
+ type VerifyHashParameters,
17
+ verifyHash,
18
+ } from '../public/verifyHash.js'
19
+
20
+ export type VerifySiweMessageParameters = Prettify<
21
+ Pick<VerifyHashParameters, 'blockNumber' | 'blockTag'> &
22
+ Pick<
23
+ ValidateSiweMessageParameters,
24
+ 'address' | 'domain' | 'nonce' | 'scheme' | 'time'
25
+ > & {
26
+ /**
27
+ * EIP-4361 formatted message.
28
+ */
29
+ message: string
30
+ /**
31
+ * Signature to check against.
32
+ */
33
+ signature: Hex
34
+ }
35
+ >
36
+
37
+ export type VerifySiweMessageReturnType = boolean
38
+
39
+ export type VerifySiweMessageErrorType =
40
+ | HashMessageErrorType
41
+ | VerifyHashErrorType
42
+ | ErrorType
43
+
44
+ /**
45
+ * Verifies [EIP-4361](https://eips.ethereum.org/EIPS/eip-4361) formatted message was signed.
46
+ *
47
+ * Compatible with Smart Contract Accounts & Externally Owned Accounts via [ERC-6492](https://eips.ethereum.org/EIPS/eip-6492).
48
+ *
49
+ * - Docs {@link https://viem.sh/docs/siwe/actions/verifySiweMessage}
50
+ *
51
+ * @param client - Client to use.
52
+ * @param parameters - {@link VerifySiweMessageParameters}
53
+ * @returns Whether or not the signature is valid. {@link VerifySiweMessageReturnType}
54
+ */
55
+ export async function verifySiweMessage<chain extends Chain | undefined>(
56
+ client: Client<Transport, chain>,
57
+ parameters: VerifySiweMessageParameters,
58
+ ): Promise<VerifySiweMessageReturnType> {
59
+ const {
60
+ address,
61
+ domain,
62
+ message,
63
+ nonce,
64
+ scheme,
65
+ signature,
66
+ time = new Date(),
67
+ ...callRequest
68
+ } = parameters
69
+
70
+ const parsed = parseSiweMessage(message)
71
+ if (!parsed.address) return false
72
+
73
+ const isValid = validateSiweMessage({
74
+ address,
75
+ domain,
76
+ message: parsed,
77
+ nonce,
78
+ scheme,
79
+ time,
80
+ })
81
+ if (!isValid) return false
82
+
83
+ const hash = hashMessage(message)
84
+ return verifyHash(client, {
85
+ address: parsed.address,
86
+ hash,
87
+ signature,
88
+ ...callRequest,
89
+ })
90
+ }
@@ -19,4 +19,10 @@ export const flowPreviewnet = /*#__PURE__*/ defineChain({
19
19
  url: 'https://previewnet.flowdiver.io',
20
20
  },
21
21
  },
22
+ contracts: {
23
+ multicall3: {
24
+ address: '0xca11bde05977b3631167028862be2a173976ca11',
25
+ blockCreated: 6205,
26
+ },
27
+ },
22
28
  })
@@ -3,15 +3,11 @@ import { defineChain } from '../../utils/chain/defineChain.js'
3
3
  export const jbcTestnet = /*#__PURE__*/ defineChain({
4
4
  id: 88991,
5
5
  name: 'Jibchain Testnet',
6
- network: 'jbcTestnet',
7
6
  nativeCurrency: { name: 'tJBC', symbol: 'tJBC', decimals: 18 },
8
7
  rpcUrls: {
9
8
  default: {
10
9
  http: ['https://rpc.testnet.jibchain.net'],
11
10
  },
12
- public: {
13
- http: ['https://rpc.testnet.jibchain.net'],
14
- },
15
11
  },
16
12
  blockExplorers: {
17
13
  default: {
@@ -0,0 +1,21 @@
1
+ import { defineChain } from '../../utils/chain/defineChain.js'
2
+
3
+ export const l3x = /*#__PURE__*/ defineChain({
4
+ id: 12324,
5
+ name: 'L3X Protocol',
6
+ nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 },
7
+ rpcUrls: {
8
+ default: {
9
+ http: ['https://rpc-mainnet.l3x.com'],
10
+ webSocket: ['wss://rpc-mainnet.l3x.com'],
11
+ },
12
+ },
13
+ blockExplorers: {
14
+ default: {
15
+ name: 'L3X Mainnet Explorer',
16
+ url: 'https://explorer.l3x.com',
17
+ apiUrl: 'https://explorer.l3x.com/api/v2',
18
+ },
19
+ },
20
+ testnet: false,
21
+ })
@@ -0,0 +1,21 @@
1
+ import { defineChain } from '../../utils/chain/defineChain.js'
2
+
3
+ export const l3xTestnet = /*#__PURE__*/ defineChain({
4
+ id: 12325,
5
+ name: 'L3X Protocol Testnet',
6
+ nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 },
7
+ rpcUrls: {
8
+ default: {
9
+ http: ['https://rpc-testnet.l3x.com'],
10
+ webSocket: ['wss://rpc-testnet.l3x.com'],
11
+ },
12
+ },
13
+ blockExplorers: {
14
+ default: {
15
+ name: 'L3X Testnet Explorer',
16
+ url: 'https://explorer-testnet.l3x.com',
17
+ apiUrl: 'https://explorer-testnet.l3x.com/api/v2',
18
+ },
19
+ },
20
+ testnet: true,
21
+ })
@@ -13,6 +13,12 @@ export const metis = /*#__PURE__*/ defineChain({
13
13
  },
14
14
  blockExplorers: {
15
15
  default: {
16
+ name: 'Metis Explorer',
17
+ url: 'https://explorer.metis.io',
18
+ apiUrl:
19
+ 'https://api.routescan.io/v2/network/mainnet/evm/43114/etherscan/api',
20
+ },
21
+ blockscout: {
16
22
  name: 'Andromeda Explorer',
17
23
  url: 'https://andromeda-explorer.metis.io',
18
24
  apiUrl: 'https://andromeda-explorer.metis.io/api',
@@ -0,0 +1,26 @@
1
+ import { defineChain } from '../../utils/chain/defineChain.js'
2
+
3
+ export const thaiChain = /*#__PURE__*/ defineChain({
4
+ id: 7,
5
+ name: 'ThaiChain',
6
+ nativeCurrency: { name: 'TCH', symbol: 'TCH', decimals: 18 },
7
+ rpcUrls: {
8
+ default: {
9
+ http: ['https://rpc.thaichain.org'],
10
+ },
11
+ },
12
+ blockExplorers: {
13
+ default: {
14
+ name: 'Blockscout',
15
+ url: 'https://exp.thaichain.org',
16
+ apiUrl: 'https://exp.thaichain.org/api',
17
+ },
18
+ },
19
+ contracts: {
20
+ multicall3: {
21
+ address: '0x0DaD6130e832c21719C5CE3bae93454E16A84826',
22
+ blockCreated: 4806386,
23
+ },
24
+ },
25
+ testnet: false,
26
+ })
@@ -23,6 +23,10 @@ export const zkSync = /*#__PURE__*/ defineChain({
23
23
  url: 'https://era.zksync.network/',
24
24
  apiUrl: 'https://api-era.zksync.network/api',
25
25
  },
26
+ native: {
27
+ name: 'zkSync Explorer',
28
+ url: 'https://explorer.zksync.io/',
29
+ },
26
30
  },
27
31
  contracts: {
28
32
  multicall3: {
@@ -15,7 +15,11 @@ export const zkSyncSepoliaTestnet = /*#__PURE__*/ defineChain({
15
15
  },
16
16
  blockExplorers: {
17
17
  default: {
18
- name: 'zkExplorer',
18
+ name: 'Etherscan',
19
+ url: 'https://sepolia-era.zksync.network/',
20
+ },
21
+ native: {
22
+ name: 'zkSync Explorer',
19
23
  url: 'https://sepolia.explorer.zksync.io/',
20
24
  },
21
25
  },
package/chains/index.ts CHANGED
@@ -124,6 +124,8 @@ export { klaytn } from './definitions/klaytn.js'
124
124
  export { klaytnBaobab } from './definitions/klaytnBaobab.js'
125
125
  export { kroma } from './definitions/kroma.js'
126
126
  export { kromaSepolia } from './definitions/kromaSepolia.js'
127
+ export { l3x } from './definitions/l3x.js'
128
+ export { l3xTestnet } from './definitions/l3xTestnet.js'
127
129
  export { lightlinkPegasus } from './definitions/lightlinkPegasus.js'
128
130
  export { lightlinkPhoenix } from './definitions/lightlinkPhoenix.js'
129
131
  export { linea } from './definitions/linea.js'
@@ -246,6 +248,7 @@ export { telcoinTestnet } from './definitions/telcoinTestnet.js'
246
248
  export { telos } from './definitions/telos.js'
247
249
  export { telosTestnet } from './definitions/telosTestnet.js'
248
250
  export { tenet } from './definitions/tenet.js'
251
+ export { thaiChain } from './definitions/thaiChain.js'
249
252
  export { thunderTestnet } from './definitions/thunderTestnet.js'
250
253
  export { vechain } from './definitions/vechain.js'
251
254
  export { wanchain } from './definitions/wanchain.js'
@@ -220,6 +220,11 @@ import {
220
220
  type WatchPendingTransactionsReturnType,
221
221
  watchPendingTransactions,
222
222
  } from '../../actions/public/watchPendingTransactions.js'
223
+ import {
224
+ type VerifySiweMessageParameters,
225
+ type VerifySiweMessageReturnType,
226
+ verifySiweMessage,
227
+ } from '../../actions/siwe/verifySiweMessage.js'
223
228
  import {
224
229
  type PrepareTransactionRequestParameters,
225
230
  type PrepareTransactionRequestRequest,
@@ -1511,9 +1516,40 @@ export type PublicActions<
1511
1516
  accountOverride
1512
1517
  >
1513
1518
  >
1519
+ /**
1520
+ * Verify that a message was signed by the provided address.
1521
+ *
1522
+ * Compatible with Smart Contract Accounts & Externally Owned Accounts via [ERC-6492](https://eips.ethereum.org/EIPS/eip-6492).
1523
+ *
1524
+ * - Docs {@link https://viem.sh/docs/actions/public/verifyMessage}
1525
+ *
1526
+ * @param parameters - {@link VerifyMessageParameters}
1527
+ * @returns Whether or not the signature is valid. {@link VerifyMessageReturnType}
1528
+ */
1514
1529
  verifyMessage: (
1515
1530
  args: VerifyMessageParameters,
1516
1531
  ) => Promise<VerifyMessageReturnType>
1532
+ /**
1533
+ * Verifies [EIP-4361](https://eips.ethereum.org/EIPS/eip-4361) formatted message was signed.
1534
+ *
1535
+ * Compatible with Smart Contract Accounts & Externally Owned Accounts via [ERC-6492](https://eips.ethereum.org/EIPS/eip-6492).
1536
+ *
1537
+ * - Docs {@link https://viem.sh/docs/siwe/actions/verifySiweMessage}
1538
+ *
1539
+ * @param parameters - {@link VerifySiweMessageParameters}
1540
+ * @returns Whether or not the signature is valid. {@link VerifySiweMessageReturnType}
1541
+ */
1542
+ verifySiweMessage: (
1543
+ args: VerifySiweMessageParameters,
1544
+ ) => Promise<VerifySiweMessageReturnType>
1545
+ /**
1546
+ * Verify that typed data was signed by the provided address.
1547
+ *
1548
+ * - Docs {@link https://viem.sh/docs/actions/public/verifyTypedData}
1549
+ *
1550
+ * @param parameters - {@link VerifyTypedDataParameters}
1551
+ * @returns Whether or not the signature is valid. {@link VerifyTypedDataReturnType}
1552
+ */
1517
1553
  verifyTypedData: (
1518
1554
  args: VerifyTypedDataParameters,
1519
1555
  ) => Promise<VerifyTypedDataReturnType>
@@ -1807,6 +1843,7 @@ export function publicActions<
1807
1843
  sendRawTransaction: (args) => sendRawTransaction(client, args),
1808
1844
  simulateContract: (args) => simulateContract(client, args),
1809
1845
  verifyMessage: (args) => verifyMessage(client, args),
1846
+ verifySiweMessage: (args) => verifySiweMessage(client, args),
1810
1847
  verifyTypedData: (args) => verifyTypedData(client, args),
1811
1848
  uninstallFilter: (args) => uninstallFilter(client, args),
1812
1849
  waitForTransactionReceipt: (args) =>
package/errors/siwe.ts ADDED
@@ -0,0 +1,20 @@
1
+ import { BaseError } from './base.js'
2
+
3
+ export type SiweInvalidMessageFieldErrorType = SiweInvalidMessageFieldError & {
4
+ name: 'SiweInvalidMessageFieldError'
5
+ }
6
+ export class SiweInvalidMessageFieldError extends BaseError {
7
+ override name = 'SiweInvalidMessageFieldError'
8
+ constructor(parameters: {
9
+ docsPath?: string | undefined
10
+ field: string
11
+ metaMessages?: string[] | undefined
12
+ }) {
13
+ const { docsPath, field, metaMessages } = parameters
14
+ super(`Invalid Sign-In with Ethereum message field "${field}".`, {
15
+ docsPath,
16
+ docsSlug: 'TODO',
17
+ metaMessages,
18
+ })
19
+ }
20
+ }
package/errors/version.ts CHANGED
@@ -1 +1 @@
1
- export const version = '2.11.1'
1
+ export const version = '2.12.1'
@@ -1,4 +1,12 @@
1
- import { resolve } from 'node:path'
1
+ import { dirname, resolve } from 'node:path'
2
+ import { fileURLToPath } from 'node:url'
3
+
4
+ const __filename = fileURLToPath(
5
+ // import.meta' meta-property is only allowed when the '--module' option is 'es2020', 'es2022', 'esnext', 'system', 'node16', or 'nodenext'
6
+ // @ts-ignore
7
+ import.meta.url,
8
+ )
9
+ const __dirname = dirname(__filename)
2
10
 
3
11
  export const mainnetTrustedSetupPath = resolve(
4
12
  __dirname,
@@ -0,0 +1,11 @@
1
+ import { resolve } from 'node:path'
2
+
3
+ export const mainnetTrustedSetupPath = resolve(
4
+ __dirname,
5
+ '../trusted-setups/mainnet.json',
6
+ )
7
+
8
+ export const minimalTrustedSetupPath = resolve(
9
+ __dirname,
10
+ '../trusted-setups/mainnet.json',
11
+ )
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "viem",
3
3
  "description": "TypeScript Interface for Ethereum",
4
- "version": "2.11.1",
4
+ "version": "2.12.1",
5
5
  "main": "./_cjs/index.js",
6
6
  "module": "./_esm/index.js",
7
7
  "types": "./_types/index.d.ts",
@@ -68,6 +68,11 @@
68
68
  "import": "./_esm/op-stack/index.js",
69
69
  "default": "./_cjs/op-stack/index.js"
70
70
  },
71
+ "./siwe": {
72
+ "types": "./_types/siwe/index.d.ts",
73
+ "import": "./_esm/siwe/index.js",
74
+ "default": "./_cjs/siwe/index.js"
75
+ },
71
76
  "./utils": {
72
77
  "types": "./_types/utils/index.d.ts",
73
78
  "import": "./_esm/utils/index.js",
@@ -114,6 +119,9 @@
114
119
  "op-stack": [
115
120
  "./_types/op-stack/index.d.ts"
116
121
  ],
122
+ "siwe": [
123
+ "./_types/siwe/index.d.ts"
124
+ ],
117
125
  "utils": [
118
126
  "./_types/utils/index.d.ts"
119
127
  ],
package/siwe/index.ts ADDED
@@ -0,0 +1,29 @@
1
+ export {
2
+ verifySiweMessage,
3
+ type VerifySiweMessageParameters,
4
+ type VerifySiweMessageReturnType,
5
+ type VerifySiweMessageErrorType,
6
+ } from '../actions/siwe/verifySiweMessage.js'
7
+
8
+ export {
9
+ createSiweMessage,
10
+ type CreateSiweMessageParameters,
11
+ type CreateSiweMessageReturnType,
12
+ type CreateSiweMessageErrorType,
13
+ } from '../utils/siwe/createSiweMessage.js'
14
+
15
+ export { generateSiweNonce } from '../utils/siwe/generateSiweNonce.js'
16
+ export { parseSiweMessage } from '../utils/siwe/parseSiweMessage.js'
17
+
18
+ export {
19
+ validateSiweMessage,
20
+ type ValidateSiweMessageParameters,
21
+ type ValidateSiweMessageReturnType,
22
+ } from '../utils/siwe/validateSiweMessage.js'
23
+
24
+ export type { SiweMessage } from '../utils/siwe/types.js'
25
+
26
+ export {
27
+ type SiweInvalidMessageFieldErrorType,
28
+ SiweInvalidMessageFieldError,
29
+ } from '../errors/siwe.js'
@@ -0,0 +1,6 @@
1
+ {
2
+ "type": "module",
3
+ "types": "../_types/siwe/index.d.ts",
4
+ "module": "../_esm/siwe/index.js",
5
+ "main": "../_cjs/siwe/index.js"
6
+ }
@@ -23,8 +23,9 @@ export function isAddress(
23
23
  options?: IsAddressOptions | undefined,
24
24
  ): address is Address {
25
25
  const { strict = true } = options ?? {}
26
+ const cacheKey = `${address}.${strict}`
26
27
 
27
- if (isAddressCache.has(address)) return isAddressCache.get(address)!
28
+ if (isAddressCache.has(cacheKey)) return isAddressCache.get(cacheKey)!
28
29
 
29
30
  const result = (() => {
30
31
  if (!addressRegex.test(address)) return false
@@ -32,6 +33,6 @@ export function isAddress(
32
33
  if (strict) return checksumAddress(address as Address) === address
33
34
  return true
34
35
  })()
35
- isAddressCache.set(address, result)
36
+ isAddressCache.set(cacheKey, result)
36
37
  return result
37
38
  }
@@ -0,0 +1,178 @@
1
+ import {
2
+ SiweInvalidMessageFieldError,
3
+ type SiweInvalidMessageFieldErrorType,
4
+ } from '../../errors/siwe.js'
5
+ import type { ErrorType } from '../../errors/utils.js'
6
+ import { type GetAddressErrorType, getAddress } from '../address/getAddress.js'
7
+ import type { SiweMessage } from './types.js'
8
+ import { isUri } from './utils.js'
9
+
10
+ export type CreateSiweMessageParameters = SiweMessage
11
+
12
+ export type CreateSiweMessageReturnType = string
13
+
14
+ export type CreateSiweMessageErrorType =
15
+ | GetAddressErrorType
16
+ | SiweInvalidMessageFieldErrorType
17
+ | ErrorType
18
+
19
+ /**
20
+ * @description Creates EIP-4361 formatted message.
21
+ *
22
+ * @example
23
+ * const message = createMessage({
24
+ * address: '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e',
25
+ * chainId: 1,
26
+ * domain: 'example.com',
27
+ * nonce: 'foobarbaz',
28
+ * uri: 'https://example.com/path',
29
+ * version: '1',
30
+ * })
31
+ *
32
+ * @see https://eips.ethereum.org/EIPS/eip-4361
33
+ */
34
+ export function createSiweMessage(
35
+ parameters: CreateSiweMessageParameters,
36
+ ): CreateSiweMessageReturnType {
37
+ const {
38
+ chainId,
39
+ domain,
40
+ expirationTime,
41
+ issuedAt = new Date(),
42
+ nonce,
43
+ notBefore,
44
+ requestId,
45
+ resources,
46
+ scheme,
47
+ uri,
48
+ version,
49
+ } = parameters
50
+
51
+ // Validate fields
52
+ {
53
+ // Required fields
54
+ if (chainId !== Math.floor(chainId))
55
+ throw new SiweInvalidMessageFieldError({
56
+ field: 'chainId',
57
+ metaMessages: [
58
+ '- Chain ID must be a EIP-155 chain ID.',
59
+ '- See https://eips.ethereum.org/EIPS/eip-155',
60
+ '',
61
+ `Provided value: ${chainId}`,
62
+ ],
63
+ })
64
+ if (
65
+ !(
66
+ domainRegex.test(domain) ||
67
+ ipRegex.test(domain) ||
68
+ localhostRegex.test(domain)
69
+ )
70
+ )
71
+ throw new SiweInvalidMessageFieldError({
72
+ field: 'domain',
73
+ metaMessages: [
74
+ '- Domain must be an RFC 3986 authority.',
75
+ '- See https://www.rfc-editor.org/rfc/rfc3986',
76
+ '',
77
+ `Provided value: ${domain}`,
78
+ ],
79
+ })
80
+ if (!nonceRegex.test(nonce))
81
+ throw new SiweInvalidMessageFieldError({
82
+ field: 'nonce',
83
+ metaMessages: [
84
+ '- Nonce must be at least 8 characters.',
85
+ '- Nonce must be alphanumeric.',
86
+ '',
87
+ `Provided value: ${nonce}`,
88
+ ],
89
+ })
90
+ if (!isUri(uri))
91
+ throw new SiweInvalidMessageFieldError({
92
+ field: 'uri',
93
+ metaMessages: [
94
+ '- URI must be a RFC 3986 URI referring to the resource that is the subject of the signing.',
95
+ '- See https://www.rfc-editor.org/rfc/rfc3986',
96
+ '',
97
+ `Provided value: ${uri}`,
98
+ ],
99
+ })
100
+ if (version !== '1')
101
+ throw new SiweInvalidMessageFieldError({
102
+ field: 'version',
103
+ metaMessages: [
104
+ "- Version must be '1'.",
105
+ '',
106
+ `Provided value: ${version}`,
107
+ ],
108
+ })
109
+
110
+ // Optional fields
111
+ if (scheme && !schemeRegex.test(scheme))
112
+ throw new SiweInvalidMessageFieldError({
113
+ field: 'scheme',
114
+ metaMessages: [
115
+ '- Scheme must be an RFC 3986 URI scheme.',
116
+ '- See https://www.rfc-editor.org/rfc/rfc3986#section-3.1',
117
+ '',
118
+ `Provided value: ${scheme}`,
119
+ ],
120
+ })
121
+ const statement = parameters.statement
122
+ if (statement?.includes('\n'))
123
+ throw new SiweInvalidMessageFieldError({
124
+ field: 'statement',
125
+ metaMessages: [
126
+ "- Statement must not include '\\n'.",
127
+ '',
128
+ `Provided value: ${statement}`,
129
+ ],
130
+ })
131
+ }
132
+
133
+ // Construct message
134
+ const address = getAddress(parameters.address)
135
+ const origin = (() => {
136
+ if (scheme) return `${scheme}://${domain}`
137
+ return domain
138
+ })()
139
+ const statement = (() => {
140
+ if (!parameters.statement) return ''
141
+ return `\n${parameters.statement}\n`
142
+ })()
143
+ const prefix = `${origin} wants you to sign in with your Ethereum account:\n${address}\n${statement}`
144
+
145
+ let suffix = `URI: ${uri}\nVersion: ${version}\nChain ID: ${chainId}\nNonce: ${nonce}\nIssued At: ${issuedAt.toISOString()}`
146
+
147
+ if (expirationTime)
148
+ suffix += `\nExpiration Time: ${expirationTime.toISOString()}`
149
+ if (notBefore) suffix += `\nNot Before: ${notBefore.toISOString()}`
150
+ if (requestId) suffix += `\nRequest ID: ${requestId}`
151
+ if (resources) {
152
+ let content = '\nResources:'
153
+ for (const resource of resources) {
154
+ if (!isUri(resource))
155
+ throw new SiweInvalidMessageFieldError({
156
+ field: 'resources',
157
+ metaMessages: [
158
+ '- Every resource must be a RFC 3986 URI.',
159
+ '- See https://www.rfc-editor.org/rfc/rfc3986',
160
+ '',
161
+ `Provided value: ${resource}`,
162
+ ],
163
+ })
164
+ content += `\n- ${resource}`
165
+ }
166
+ suffix += content
167
+ }
168
+
169
+ return `${prefix}\n${suffix}`
170
+ }
171
+
172
+ const domainRegex =
173
+ /^([a-zA-Z0-9][-a-zA-Z0-9]{0,61}[a-zA-Z0-9])\.[a-zA-Z]{2,}(:[0-9]{1,5})?$/
174
+ const ipRegex =
175
+ /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(:[0-9]{1,5})?$/
176
+ const localhostRegex = /^localhost(:[0-9]{1,5})?$/
177
+ const nonceRegex = /^[a-zA-Z0-9]{8,}$/
178
+ const schemeRegex = /^([a-zA-Z][a-zA-Z0-9+-.]*)$/
@@ -0,0 +1,15 @@
1
+ import { uid } from '../../utils/uid.js'
2
+
3
+ /**
4
+ * @description Generates random EIP-4361 nonce.
5
+ *
6
+ * @example
7
+ * const nonce = generateNonce()
8
+ *
9
+ * @see https://eips.ethereum.org/EIPS/eip-4361
10
+ *
11
+ * @returns A randomly generated EIP-4361 nonce.
12
+ */
13
+ export function generateSiweNonce(): string {
14
+ return uid(96)
15
+ }