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
@@ -0,0 +1,55 @@
1
+ import type { Address } from 'abitype'
2
+
3
+ import type { ExactPartial, Prettify } from '../../types/utils.js'
4
+ import type { SiweMessage } from './types.js'
5
+
6
+ /**
7
+ * @description Parses EIP-4361 formatted message into message fields object.
8
+ *
9
+ * @see https://eips.ethereum.org/EIPS/eip-4361
10
+ *
11
+ * @returns EIP-4361 fields object
12
+ */
13
+ export function parseSiweMessage(
14
+ message: string,
15
+ ): Prettify<ExactPartial<SiweMessage>> {
16
+ const { scheme, statement, ...prefix } = (message.match(prefixRegex)
17
+ ?.groups ?? {}) as {
18
+ address: Address
19
+ domain: string
20
+ scheme?: string
21
+ statement?: string
22
+ }
23
+ const { chainId, expirationTime, issuedAt, notBefore, requestId, ...suffix } =
24
+ (message.match(suffixRegex)?.groups ?? {}) as {
25
+ chainId: string
26
+ expirationTime?: string
27
+ issuedAt?: string
28
+ nonce: string
29
+ notBefore?: string
30
+ requestId?: string
31
+ uri: string
32
+ version: '1'
33
+ }
34
+ const resources = message.split('Resources:')[1]?.split('\n- ').slice(1)
35
+ return {
36
+ ...prefix,
37
+ ...suffix,
38
+ ...(chainId ? { chainId: Number(chainId) } : {}),
39
+ ...(expirationTime ? { expirationTime: new Date(expirationTime) } : {}),
40
+ ...(issuedAt ? { issuedAt: new Date(issuedAt) } : {}),
41
+ ...(notBefore ? { notBefore: new Date(notBefore) } : {}),
42
+ ...(requestId ? { requestId } : {}),
43
+ ...(resources ? { resources } : {}),
44
+ ...(scheme ? { scheme } : {}),
45
+ ...(statement ? { statement } : {}),
46
+ }
47
+ }
48
+
49
+ // https://regexr.com/80gdj
50
+ const prefixRegex =
51
+ /^(?:(?<scheme>[a-zA-Z][a-zA-Z0-9+-.]*):\/\/)?(?<domain>[a-zA-Z0-9+-.]*) (?:wants you to sign in with your Ethereum account:\n)(?<address>0x[a-fA-F0-9]{40})\n\n(?:(?<statement>.*)\n\n)?/
52
+
53
+ // https://regexr.com/80gf9
54
+ const suffixRegex =
55
+ /(?:URI: (?<uri>.+))\n(?:Version: (?<version>.+))\n(?:Chain ID: (?<chainId>\d+))\n(?:Nonce: (?<nonce>[a-zA-Z0-9]+))\n(?:Issued At: (?<issuedAt>.+))(?:\nExpiration Time: (?<expirationTime>.+))?(?:\nNot Before: (?<notBefore>.+))?(?:\nRequest ID: (?<requestId>.+))?/
@@ -0,0 +1,61 @@
1
+ import type { Address } from 'abitype'
2
+
3
+ /**
4
+ * @description EIP-4361 message fields
5
+ *
6
+ * @see https://eips.ethereum.org/EIPS/eip-4361
7
+ */
8
+ export type SiweMessage = {
9
+ /**
10
+ * The Ethereum address performing the signing.
11
+ */
12
+ address: Address
13
+ /**
14
+ * The [EIP-155](https://eips.ethereum.org/EIPS/eip-155) Chain ID to which the session is bound,
15
+ */
16
+ chainId: number
17
+ /**
18
+ * [RFC 3986](https://www.rfc-editor.org/rfc/rfc3986) authority that is requesting the signing.
19
+ */
20
+ domain: string
21
+ /**
22
+ * Time when the signed authentication message is no longer valid.
23
+ */
24
+ expirationTime?: Date | undefined
25
+ /**
26
+ * Time when the message was generated, typically the current time.
27
+ */
28
+ issuedAt?: Date | undefined
29
+ /**
30
+ * A random string typically chosen by the relying party and used to prevent replay attacks.
31
+ */
32
+ nonce: string
33
+ /**
34
+ * Time when the signed authentication message will become valid.
35
+ */
36
+ notBefore?: Date | undefined
37
+ /**
38
+ * A system-specific identifier that may be used to uniquely refer to the sign-in request.
39
+ */
40
+ requestId?: string | undefined
41
+ /**
42
+ * A list of information or references to information the user wishes to have resolved as part of authentication by the relying party.
43
+ */
44
+ resources?: string[] | undefined
45
+ /**
46
+ * [RFC 3986](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) URI scheme of the origin of the request.
47
+ */
48
+ scheme?: string | undefined
49
+ /**
50
+ * A human-readable ASCII assertion that the user will sign.
51
+ */
52
+ statement?: string | undefined
53
+ /**
54
+ * [RFC 3986](https://www.rfc-editor.org/rfc/rfc3986) URI referring to the resource that is the subject of the signing (as in the subject of a claim).
55
+ */
56
+ uri: string
57
+ /**
58
+ * The current version of the SIWE Message.
59
+ */
60
+ version: '1'
61
+ }
@@ -0,0 +1,51 @@
1
+ export function isUri(value: string) {
2
+ // based on https://github.com/ogt/valid-url
3
+
4
+ // check for illegal characters
5
+ if (/[^a-z0-9\:\/\?\#\[\]\@\!\$\&\'\(\)\*\+\,\;\=\.\-\_\~\%]/i.test(value))
6
+ return false
7
+
8
+ // check for hex escapes that aren't complete
9
+ if (/%[^0-9a-f]/i.test(value)) return false
10
+ if (/%[0-9a-f](:?[^0-9a-f]|$)/i.test(value)) return false
11
+
12
+ // from RFC 3986
13
+ const splitted = splitUri(value)
14
+ const scheme = splitted[1]
15
+ const authority = splitted[2]
16
+ const path = splitted[3]
17
+ const query = splitted[4]
18
+ const fragment = splitted[5]
19
+
20
+ // scheme and path are required, though the path can be empty
21
+ if (!(scheme?.length && path.length >= 0)) return false
22
+
23
+ // if authority is present, the path must be empty or begin with a /
24
+ if (authority?.length) {
25
+ if (!(path.length === 0 || /^\//.test(path))) return false
26
+ } else {
27
+ // if authority is not present, the path must not start with //
28
+ if (/^\/\//.test(path)) return false
29
+ }
30
+
31
+ // scheme must begin with a letter, then consist of letters, digits, +, ., or -
32
+ if (!/^[a-z][a-z0-9\+\-\.]*$/.test(scheme.toLowerCase())) return false
33
+
34
+ let out = ''
35
+ // re-assemble the URL per section 5.3 in RFC 3986
36
+ out += `${scheme}:`
37
+ if (authority?.length) out += `//${authority}`
38
+
39
+ out += path
40
+
41
+ if (query?.length) out += `?${query}`
42
+ if (fragment?.length) out += `#${fragment}`
43
+
44
+ return out
45
+ }
46
+
47
+ function splitUri(value: string) {
48
+ return value.match(
49
+ /(?:([^:\/?#]+):)?(?:\/\/([^\/?#]*))?([^?#]*)(?:\?([^#]*))?(?:#(.*))?/,
50
+ )!
51
+ }
@@ -0,0 +1,70 @@
1
+ import type { Address } from 'abitype'
2
+
3
+ import type { ExactPartial } from '../../types/utils.js'
4
+ import { isAddressEqual } from '../address/isAddressEqual.js'
5
+ import type { SiweMessage } from './types.js'
6
+
7
+ export type ValidateSiweMessageParameters = {
8
+ /**
9
+ * Ethereum address to check against.
10
+ */
11
+ address?: Address | undefined
12
+ /**
13
+ * [RFC 3986](https://www.rfc-editor.org/rfc/rfc3986) authority to check against.
14
+ */
15
+ domain?: string | undefined
16
+ /**
17
+ * EIP-4361 message fields.
18
+ */
19
+ message: ExactPartial<SiweMessage>
20
+ /**
21
+ * Random string to check against.
22
+ */
23
+ nonce?: string | undefined
24
+ /**
25
+ * [RFC 3986](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) URI scheme to check against.
26
+ */
27
+ scheme?: string | undefined
28
+ /**
29
+ * Current time to check optional `expirationTime` and `notBefore` fields.
30
+ *
31
+ * @default new Date()
32
+ */
33
+ time?: Date | undefined
34
+ }
35
+
36
+ export type ValidateSiweMessageReturnType = boolean
37
+
38
+ /**
39
+ * @description Validates EIP-4361 message.
40
+ *
41
+ * @see https://eips.ethereum.org/EIPS/eip-4361
42
+ */
43
+ export function validateSiweMessage(
44
+ parameters: ValidateSiweMessageParameters,
45
+ ): ValidateSiweMessageReturnType {
46
+ const {
47
+ address,
48
+ domain,
49
+ message,
50
+ nonce,
51
+ scheme,
52
+ time = new Date(),
53
+ } = parameters
54
+
55
+ if (domain && message.domain !== domain) return false
56
+ if (nonce && message.nonce !== nonce) return false
57
+ if (scheme && message.scheme !== scheme) return false
58
+
59
+ if (message.expirationTime && time >= message.expirationTime) return false
60
+ if (message.notBefore && time < message.notBefore) return false
61
+
62
+ try {
63
+ if (!message.address) return false
64
+ if (address && !isAddressEqual(message.address, address)) return false
65
+ } catch {
66
+ return false
67
+ }
68
+
69
+ return true
70
+ }