viem 0.4.0-main.20230418T011420 → 0.4.0-main.20230419T210450

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.
Files changed (127) hide show
  1. package/README.md +6 -0
  2. package/dist/cjs/actions/public/call.js +97 -10
  3. package/dist/cjs/actions/public/call.js.map +1 -1
  4. package/dist/cjs/actions/public/simulateContract.js +1 -0
  5. package/dist/cjs/actions/public/simulateContract.js.map +1 -1
  6. package/dist/cjs/chains.js +1 -24
  7. package/dist/cjs/chains.js.map +1 -1
  8. package/dist/cjs/clients/createPublicClient.js +2 -1
  9. package/dist/cjs/clients/createPublicClient.js.map +1 -1
  10. package/dist/cjs/constants/contract.js +5 -0
  11. package/dist/cjs/constants/contract.js.map +1 -0
  12. package/dist/cjs/constants/index.js +3 -1
  13. package/dist/cjs/constants/index.js.map +1 -1
  14. package/dist/cjs/errors/chain.js +13 -1
  15. package/dist/cjs/errors/chain.js.map +1 -1
  16. package/dist/cjs/errors/contract.js +1 -1
  17. package/dist/cjs/errors/contract.js.map +1 -1
  18. package/dist/cjs/errors/encoding.js +13 -1
  19. package/dist/cjs/errors/encoding.js.map +1 -1
  20. package/dist/cjs/errors/index.js +5 -2
  21. package/dist/cjs/errors/index.js.map +1 -1
  22. package/dist/cjs/errors/version.js +1 -1
  23. package/dist/cjs/index.js +5 -4
  24. package/dist/cjs/index.js.map +1 -1
  25. package/dist/cjs/utils/encoding/fromBytes.js +29 -12
  26. package/dist/cjs/utils/encoding/fromBytes.js.map +1 -1
  27. package/dist/cjs/utils/encoding/fromHex.js +32 -10
  28. package/dist/cjs/utils/encoding/fromHex.js.map +1 -1
  29. package/dist/cjs/utils/encoding/toBytes.js +31 -15
  30. package/dist/cjs/utils/encoding/toBytes.js.map +1 -1
  31. package/dist/cjs/utils/encoding/toHex.js +31 -20
  32. package/dist/cjs/utils/encoding/toHex.js.map +1 -1
  33. package/dist/cjs/utils/errors/getContractError.js +7 -5
  34. package/dist/cjs/utils/errors/getContractError.js.map +1 -1
  35. package/dist/cjs/utils/promise/createBatchScheduler.js +47 -0
  36. package/dist/cjs/utils/promise/createBatchScheduler.js.map +1 -0
  37. package/dist/cjs/utils/promise/index.js +3 -1
  38. package/dist/cjs/utils/promise/index.js.map +1 -1
  39. package/dist/esm/actions/public/call.js +91 -4
  40. package/dist/esm/actions/public/call.js.map +1 -1
  41. package/dist/esm/actions/public/simulateContract.js +1 -0
  42. package/dist/esm/actions/public/simulateContract.js.map +1 -1
  43. package/dist/esm/clients/createPublicClient.js +2 -1
  44. package/dist/esm/clients/createPublicClient.js.map +1 -1
  45. package/dist/esm/constants/contract.js +2 -0
  46. package/dist/esm/constants/contract.js.map +1 -0
  47. package/dist/esm/constants/index.js +1 -0
  48. package/dist/esm/constants/index.js.map +1 -1
  49. package/dist/esm/errors/chain.js +11 -0
  50. package/dist/esm/errors/chain.js.map +1 -1
  51. package/dist/esm/errors/contract.js +1 -1
  52. package/dist/esm/errors/contract.js.map +1 -1
  53. package/dist/esm/errors/encoding.js +11 -0
  54. package/dist/esm/errors/encoding.js.map +1 -1
  55. package/dist/esm/errors/index.js +2 -2
  56. package/dist/esm/errors/index.js.map +1 -1
  57. package/dist/esm/errors/version.js +1 -1
  58. package/dist/esm/index.js +1 -1
  59. package/dist/esm/index.js.map +1 -1
  60. package/dist/esm/utils/encoding/fromBytes.js +30 -13
  61. package/dist/esm/utils/encoding/fromBytes.js.map +1 -1
  62. package/dist/esm/utils/encoding/fromHex.js +31 -10
  63. package/dist/esm/utils/encoding/fromHex.js.map +1 -1
  64. package/dist/esm/utils/encoding/toBytes.js +31 -15
  65. package/dist/esm/utils/encoding/toBytes.js.map +1 -1
  66. package/dist/esm/utils/encoding/toHex.js +28 -17
  67. package/dist/esm/utils/encoding/toHex.js.map +1 -1
  68. package/dist/esm/utils/errors/getContractError.js +7 -5
  69. package/dist/esm/utils/errors/getContractError.js.map +1 -1
  70. package/dist/esm/utils/promise/createBatchScheduler.js +43 -0
  71. package/dist/esm/utils/promise/createBatchScheduler.js.map +1 -0
  72. package/dist/esm/utils/promise/index.js +1 -0
  73. package/dist/esm/utils/promise/index.js.map +1 -1
  74. package/dist/types/actions/public/call.d.ts +1 -0
  75. package/dist/types/actions/public/call.d.ts.map +1 -1
  76. package/dist/types/actions/public/simulateContract.d.ts +1 -1
  77. package/dist/types/actions/public/simulateContract.d.ts.map +1 -1
  78. package/dist/types/clients/createPublicClient.d.ts +15 -3
  79. package/dist/types/clients/createPublicClient.d.ts.map +1 -1
  80. package/dist/types/constants/contract.d.ts +2 -0
  81. package/dist/types/constants/contract.d.ts.map +1 -0
  82. package/dist/types/constants/index.d.ts +1 -0
  83. package/dist/types/constants/index.d.ts.map +1 -1
  84. package/dist/types/errors/chain.d.ts +4 -0
  85. package/dist/types/errors/chain.d.ts.map +1 -1
  86. package/dist/types/errors/encoding.d.ts +7 -0
  87. package/dist/types/errors/encoding.d.ts.map +1 -1
  88. package/dist/types/errors/index.d.ts +2 -2
  89. package/dist/types/errors/index.d.ts.map +1 -1
  90. package/dist/types/errors/version.d.ts +1 -1
  91. package/dist/types/index.d.ts +1 -1
  92. package/dist/types/index.d.ts.map +1 -1
  93. package/dist/types/types/eip1193.d.ts +1 -1
  94. package/dist/types/types/eip1193.d.ts.map +1 -1
  95. package/dist/types/utils/encoding/fromBytes.d.ts +95 -10
  96. package/dist/types/utils/encoding/fromBytes.d.ts.map +1 -1
  97. package/dist/types/utils/encoding/fromHex.d.ts +122 -12
  98. package/dist/types/utils/encoding/fromHex.d.ts.map +1 -1
  99. package/dist/types/utils/encoding/toBytes.d.ts +113 -9
  100. package/dist/types/utils/encoding/toBytes.d.ts.map +1 -1
  101. package/dist/types/utils/encoding/toHex.d.ts +120 -10
  102. package/dist/types/utils/encoding/toHex.d.ts.map +1 -1
  103. package/dist/types/utils/errors/getContractError.d.ts.map +1 -1
  104. package/dist/types/utils/promise/createBatchScheduler.d.ts +15 -0
  105. package/dist/types/utils/promise/createBatchScheduler.d.ts.map +1 -0
  106. package/dist/types/utils/promise/index.d.ts +1 -0
  107. package/dist/types/utils/promise/index.d.ts.map +1 -1
  108. package/package.json +1 -1
  109. package/src/actions/public/call.ts +141 -7
  110. package/src/actions/public/simulateContract.ts +2 -1
  111. package/src/clients/createPublicClient.ts +17 -1
  112. package/src/constants/contract.ts +1 -0
  113. package/src/constants/index.ts +2 -0
  114. package/src/errors/chain.ts +8 -0
  115. package/src/errors/contract.ts +1 -1
  116. package/src/errors/encoding.ts +9 -0
  117. package/src/errors/index.ts +2 -0
  118. package/src/errors/version.ts +1 -1
  119. package/src/index.ts +1 -0
  120. package/src/types/eip1193.ts +1 -1
  121. package/src/utils/encoding/fromBytes.ts +147 -18
  122. package/src/utils/encoding/fromHex.ts +162 -19
  123. package/src/utils/encoding/toBytes.ts +148 -18
  124. package/src/utils/encoding/toHex.ts +151 -26
  125. package/src/utils/errors/getContractError.ts +9 -5
  126. package/src/utils/promise/createBatchScheduler.ts +82 -0
  127. package/src/utils/promise/index.ts +1 -0
@@ -1,62 +1,192 @@
1
1
  import { BaseError } from '../../errors/index.js'
2
2
  import type { ByteArray, Hex } from '../../types/index.js'
3
3
  import { isHex } from '../data/isHex.js'
4
+ import { pad } from '../data/pad.js'
5
+ import { assertSize } from './fromHex.js'
4
6
  import type { NumberToHexOpts } from './toHex.js'
5
7
  import { numberToHex } from './toHex.js'
6
8
 
7
9
  const encoder = new TextEncoder()
8
10
 
9
- /** @description Encodes a UTF-8 string, hex value, bigint, number or boolean to a byte array. */
11
+ export type ToBytesParameters = {
12
+ /** Size of the output bytes. */
13
+ size?: number
14
+ }
15
+
16
+ /**
17
+ * Encodes a UTF-8 string, hex value, bigint, number or boolean to a byte array.
18
+ *
19
+ * - Docs: https://viem.sh/docs/utilities/toBytes.html
20
+ * - Example: https://viem.sh/docs/utilities/toBytes.html#usage
21
+ *
22
+ * @param value Value to encode.
23
+ * @param opts Options.
24
+ * @returns Byte array value.
25
+ *
26
+ * @example
27
+ * import { toBytes } from 'viem'
28
+ * const data = toBytes('Hello world')
29
+ * // Uint8Array([72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33])
30
+ *
31
+ * @example
32
+ * import { toBytes } from 'viem'
33
+ * const data = toBytes(420)
34
+ * // Uint8Array([1, 164])
35
+ *
36
+ * @example
37
+ * import { toBytes } from 'viem'
38
+ * const data = toBytes(420, { size: 4 })
39
+ * // Uint8Array([0, 0, 1, 164])
40
+ */
10
41
  export function toBytes(
11
42
  value: string | bigint | number | boolean | Hex,
43
+ opts: ToBytesParameters = {},
12
44
  ): ByteArray {
13
45
  if (typeof value === 'number' || typeof value === 'bigint')
14
- return numberToBytes(value)
15
- if (typeof value === 'boolean') return boolToBytes(value)
16
- if (isHex(value)) return hexToBytes(value)
17
- return stringToBytes(value)
46
+ return numberToBytes(value, opts)
47
+ if (typeof value === 'boolean') return boolToBytes(value, opts)
48
+ if (isHex(value)) return hexToBytes(value, opts)
49
+ return stringToBytes(value, opts)
50
+ }
51
+
52
+ export type BoolToHexOpts = {
53
+ /** Size of the output bytes. */
54
+ size?: number
18
55
  }
19
56
 
20
57
  /**
21
- * @description Encodes a boolean into a byte array.
58
+ * Encodes a boolean into a byte array.
59
+ *
60
+ * - Docs: https://viem.sh/docs/utilities/toBytes.html#booltobytes
61
+ *
62
+ * @param value Boolean value to encode.
63
+ * @param opts Options.
64
+ * @returns Byte array value.
65
+ *
66
+ * @example
67
+ * import { boolToBytes } from 'viem'
68
+ * const data = boolToBytes(true)
69
+ * // Uint8Array([1])
70
+ *
71
+ * @example
72
+ * import { boolToBytes } from 'viem'
73
+ * const data = boolToBytes(true, { size: 32 })
74
+ * // Uint8Array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1])
22
75
  */
23
- export function boolToBytes(value: boolean) {
76
+ export function boolToBytes(value: boolean, opts: BoolToHexOpts = {}) {
24
77
  const bytes = new Uint8Array(1)
25
78
  bytes[0] = Number(value)
79
+ if (typeof opts.size === 'number') {
80
+ assertSize(bytes, { size: opts.size })
81
+ return pad(bytes, { size: opts.size })
82
+ }
26
83
  return bytes
27
84
  }
28
85
 
86
+ export type HexToBytesOpts = {
87
+ /** Size of the output bytes. */
88
+ size?: number
89
+ }
90
+
29
91
  /**
30
- * @description Encodes a hex string into a byte array.
92
+ * Encodes a hex string into a byte array.
93
+ *
94
+ * - Docs: https://viem.sh/docs/utilities/toBytes.html#hextobytes
95
+ *
96
+ * @param hex Hex string to encode.
97
+ * @param opts Options.
98
+ * @returns Byte array value.
99
+ *
100
+ * @example
101
+ * import { hexToBytes } from 'viem'
102
+ * const data = hexToBytes('0x48656c6c6f20776f726c6421')
103
+ * // Uint8Array([72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33])
104
+ *
105
+ * @example
106
+ * import { hexToBytes } from 'viem'
107
+ * const data = hexToBytes('0x48656c6c6f20776f726c6421', { size: 32 })
108
+ * // Uint8Array([72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
31
109
  */
32
- export function hexToBytes(hex_: Hex): ByteArray {
33
- let hex = hex_.slice(2) as string
110
+ export function hexToBytes(hex_: Hex, opts: HexToBytesOpts = {}): ByteArray {
111
+ let hex = hex_
112
+ if (opts.size) {
113
+ assertSize(hex, { size: opts.size })
114
+ hex = pad(hex, { dir: 'right', size: opts.size })
115
+ }
34
116
 
35
- if (hex.length % 2) hex = `0${hex}`
117
+ let hexString = hex.slice(2) as string
118
+ if (hexString.length % 2) hexString = `0${hexString}`
36
119
 
37
- const bytes = new Uint8Array(hex.length / 2)
120
+ const bytes = new Uint8Array(hexString.length / 2)
38
121
  for (let index = 0; index < bytes.length; index++) {
39
122
  const start = index * 2
40
- const hexByte = hex.slice(start, start + 2)
123
+ const hexByte = hexString.slice(start, start + 2)
41
124
  const byte = Number.parseInt(hexByte, 16)
42
125
  if (Number.isNaN(byte) || byte < 0)
43
- throw new BaseError(`Invalid byte sequence ("${hexByte}" in "${hex}").`)
126
+ throw new BaseError(
127
+ `Invalid byte sequence ("${hexByte}" in "${hexString}").`,
128
+ )
44
129
  bytes[index] = byte
45
130
  }
46
131
  return bytes
47
132
  }
48
133
 
49
134
  /**
50
- * @description Encodes a number into a byte array.
135
+ * Encodes a number into a byte array.
136
+ *
137
+ * - Docs: https://viem.sh/docs/utilities/toBytes.html#numbertobytes
138
+ *
139
+ * @param value Number to encode.
140
+ * @param opts Options.
141
+ * @returns Byte array value.
142
+ *
143
+ * @example
144
+ * import { numberToBytes } from 'viem'
145
+ * const data = numberToBytes(420)
146
+ * // Uint8Array([1, 164])
147
+ *
148
+ * @example
149
+ * import { numberToBytes } from 'viem'
150
+ * const data = numberToBytes(420, { size: 4 })
151
+ * // Uint8Array([0, 0, 1, 164])
51
152
  */
52
153
  export function numberToBytes(value: bigint | number, opts?: NumberToHexOpts) {
53
154
  const hex = numberToHex(value, opts)
54
155
  return hexToBytes(hex)
55
156
  }
56
157
 
158
+ export type StringToBytesOpts = {
159
+ /** Size of the output bytes. */
160
+ size?: number
161
+ }
162
+
57
163
  /**
58
- * @description Encodes a UTF-8 string into a byte array.
164
+ * Encodes a UTF-8 string into a byte array.
165
+ *
166
+ * - Docs: https://viem.sh/docs/utilities/toBytes.html#stringtobytes
167
+ *
168
+ * @param value String to encode.
169
+ * @param opts Options.
170
+ * @returns Byte array value.
171
+ *
172
+ * @example
173
+ * import { stringToBytes } from 'viem'
174
+ * const data = stringToBytes('Hello world!')
175
+ * // Uint8Array([72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 33])
176
+ *
177
+ * @example
178
+ * import { stringToBytes } from 'viem'
179
+ * const data = stringToBytes('Hello world!', { size: 32 })
180
+ * // Uint8Array([72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
59
181
  */
60
- export function stringToBytes(value: string): ByteArray {
61
- return encoder.encode(value)
182
+ export function stringToBytes(
183
+ value: string,
184
+ opts: StringToBytesOpts = {},
185
+ ): ByteArray {
186
+ const bytes = encoder.encode(value)
187
+ if (typeof opts.size === 'number') {
188
+ assertSize(bytes, { size: opts.size })
189
+ return pad(bytes, { dir: 'right', size: opts.size })
190
+ }
191
+ return bytes
62
192
  }
@@ -1,58 +1,162 @@
1
1
  import { pad } from '../data/index.js'
2
2
  import type { ByteArray, Hex } from '../../types/index.js'
3
3
  import { IntegerOutOfRangeError } from '../../errors/index.js'
4
+ import { assertSize } from './fromHex.js'
4
5
 
5
6
  const hexes = Array.from({ length: 256 }, (_v, i) =>
6
7
  i.toString(16).padStart(2, '0'),
7
8
  )
8
9
 
10
+ export type ToHexParameters = {
11
+ /** The size (in bytes) of the output hex value. */
12
+ size?: number
13
+ }
14
+
9
15
  /**
10
- * @description Encodes a boolean into a hex string
16
+ * Encodes a string, number, bigint, or ByteArray into a hex string
17
+ *
18
+ * - Docs: https://viem.sh/docs/utilities/toHex.html
19
+ * - Example: https://viem.sh/docs/utilities/toHex.html#usage
20
+ *
21
+ * @param value Value to encode.
22
+ * @param opts Options.
23
+ * @returns Hex value.
24
+ *
25
+ * @example
26
+ * import { toHex } from 'viem'
27
+ * const data = toHex('Hello world')
28
+ * // '0x48656c6c6f20776f726c6421'
29
+ *
30
+ * @example
31
+ * import { toHex } from 'viem'
32
+ * const data = toHex(420)
33
+ * // '0x1a4'
34
+ *
35
+ * @example
36
+ * import { toHex } from 'viem'
37
+ * const data = toHex('Hello world', { size: 32 })
38
+ * // '0x48656c6c6f20776f726c64210000000000000000000000000000000000000000'
11
39
  */
12
- export function boolToHex(value: boolean): Hex {
13
- return `0x${Number(value)}`
40
+ export function toHex(
41
+ value: string | number | bigint | boolean | ByteArray,
42
+ opts: ToHexParameters = {},
43
+ ): Hex {
44
+ if (typeof value === 'number' || typeof value === 'bigint')
45
+ return numberToHex(value, opts)
46
+ if (typeof value === 'string') {
47
+ return stringToHex(value, opts)
48
+ }
49
+ if (typeof value === 'boolean') return boolToHex(value, opts)
50
+ return bytesToHex(value, opts)
51
+ }
52
+
53
+ export type BoolToHexOpts = {
54
+ /** The size (in bytes) of the output hex value. */
55
+ size?: number
14
56
  }
15
57
 
16
58
  /**
17
- * @description Encodes a bytes array into a hex string
59
+ * Encodes a boolean into a hex string
60
+ *
61
+ * - Docs: https://viem.sh/docs/utilities/toHex.html#booltohex
62
+ *
63
+ * @param value Value to encode.
64
+ * @param opts Options.
65
+ * @returns Hex value.
66
+ *
67
+ * @example
68
+ * import { boolToHex } from 'viem'
69
+ * const data = boolToHex(true)
70
+ * // '0x1'
71
+ *
72
+ * @example
73
+ * import { boolToHex } from 'viem'
74
+ * const data = boolToHex(false)
75
+ * // '0x0'
76
+ *
77
+ * @example
78
+ * import { boolToHex } from 'viem'
79
+ * const data = boolToHex(true, { size: 32 })
80
+ * // '0x0000000000000000000000000000000000000000000000000000000000000001'
18
81
  */
19
- export function bytesToHex(value: ByteArray): Hex {
20
- let hex = ''
21
- for (let i = 0; i < value.length; i++) {
22
- hex += hexes[value[i]]
82
+ export function boolToHex(value: boolean, opts: BoolToHexOpts = {}): Hex {
83
+ const hex: Hex = `0x${Number(value)}`
84
+ if (typeof opts.size === 'number') {
85
+ assertSize(hex, { size: opts.size })
86
+ return pad(hex, { size: opts.size })
23
87
  }
24
- return `0x${hex}`
88
+ return hex
89
+ }
90
+
91
+ export type BytesToHexOpts = {
92
+ /** The size (in bytes) of the output hex value. */
93
+ size?: number
25
94
  }
26
95
 
27
96
  /**
28
- * @description Encodes a string, number, bigint, or ByteArray into a hex string
97
+ * Encodes a bytes array into a hex string
98
+ *
99
+ * - Docs: https://viem.sh/docs/utilities/toHex.html#bytestohex
100
+ *
101
+ * @param value Value to encode.
102
+ * @param opts Options.
103
+ * @returns Hex value.
104
+ *
105
+ * @example
106
+ * import { bytesToHex } from 'viem'
107
+ * const data = bytesToHex(Uint8Array.from([72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33])
108
+ * // '0x48656c6c6f20576f726c6421'
109
+ *
110
+ * @example
111
+ * import { bytesToHex } from 'viem'
112
+ * const data = bytesToHex(Uint8Array.from([72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33]), { size: 32 })
113
+ * // '0x48656c6c6f20576f726c64210000000000000000000000000000000000000000'
29
114
  */
30
- export function toHex(
31
- value: string | number | bigint | boolean | ByteArray,
32
- ): Hex {
33
- if (typeof value === 'number' || typeof value === 'bigint')
34
- return numberToHex(value)
35
- if (typeof value === 'string') {
36
- return stringToHex(value)
115
+ export function bytesToHex(value: ByteArray, opts: BytesToHexOpts = {}): Hex {
116
+ let hexString = ''
117
+ for (let i = 0; i < value.length; i++) {
118
+ hexString += hexes[value[i]]
119
+ }
120
+
121
+ const hex: Hex = `0x${hexString}`
122
+ if (typeof opts.size === 'number') {
123
+ assertSize(hex, { size: opts.size })
124
+ return pad(hex, { dir: 'right', size: opts.size })
37
125
  }
38
- if (typeof value === 'boolean') return boolToHex(value)
39
- return bytesToHex(value)
126
+ return hex
40
127
  }
41
128
 
42
129
  export type NumberToHexOpts =
43
130
  | {
44
- // Whether or not the number of a signed representation.
131
+ /** Whether or not the number of a signed representation. */
45
132
  signed?: boolean
46
- // The size of the output hex (in bytes).
133
+ /** The size (in bytes) of the output hex value. */
47
134
  size: number
48
135
  }
49
136
  | {
50
137
  signed?: never
51
- size?: never
138
+ /** The size (in bytes) of the output hex value. */
139
+ size?: number
52
140
  }
53
141
 
54
142
  /**
55
- * @description Encodes a number or bigint into a hex string
143
+ * Encodes a number or bigint into a hex string
144
+ *
145
+ * - Docs: https://viem.sh/docs/utilities/toHex.html#numbertohex
146
+ *
147
+ * @param value Value to encode.
148
+ * @param opts Options.
149
+ * @returns Hex value.
150
+ *
151
+ * @example
152
+ * import { numberToHex } from 'viem'
153
+ * const data = numberToHex(420)
154
+ * // '0x1a4'
155
+ *
156
+ * @example
157
+ * import { numberToHex } from 'viem'
158
+ * const data = numberToHex(420, { size: 32 })
159
+ * // '0x00000000000000000000000000000000000000000000000000000000000001a4'
56
160
  */
57
161
  export function numberToHex(
58
162
  value_: number | bigint,
@@ -91,12 +195,33 @@ export function numberToHex(
91
195
  return hex
92
196
  }
93
197
 
198
+ export type StringToHexOpts = {
199
+ /** The size (in bytes) of the output hex value. */
200
+ size?: number
201
+ }
202
+
94
203
  const encoder = new TextEncoder()
95
204
 
96
205
  /**
97
- * @description Encodes a UTF-8 string into a hex string
206
+ * Encodes a UTF-8 string into a hex string
207
+ *
208
+ * - Docs: https://viem.sh/docs/utilities/toHex.html#stringtohex
209
+ *
210
+ * @param value Value to encode.
211
+ * @param opts Options.
212
+ * @returns Hex value.
213
+ *
214
+ * @example
215
+ * import { stringToHex } from 'viem'
216
+ * const data = stringToHex('Hello World!')
217
+ * // '0x48656c6c6f20576f726c6421'
218
+ *
219
+ * @example
220
+ * import { stringToHex } from 'viem'
221
+ * const data = stringToHex('Hello World!', { size: 32 })
222
+ * // '0x48656c6c6f20576f726c64210000000000000000000000000000000000000000'
98
223
  */
99
- export function stringToHex(value_: string): Hex {
224
+ export function stringToHex(value_: string, opts: StringToHexOpts = {}): Hex {
100
225
  const value = encoder.encode(value_)
101
- return toHex(value)
226
+ return bytesToHex(value, opts)
102
227
  }
@@ -33,11 +33,12 @@ export function getContractError(
33
33
  sender?: Address
34
34
  },
35
35
  ) {
36
- const { code, data, message } = (
36
+ const { code, data, message, shortMessage } = (
37
37
  err instanceof RawContractError
38
38
  ? err
39
- : err instanceof CallExecutionError ||
40
- err instanceof EstimateGasExecutionError
39
+ : !(err.cause && 'data' in (err.cause as BaseError)) &&
40
+ (err instanceof CallExecutionError ||
41
+ err instanceof EstimateGasExecutionError)
41
42
  ? ((err.cause as BaseError)?.cause as BaseError)?.cause || {}
42
43
  : err.cause || {}
43
44
  ) as RawContractError
@@ -45,12 +46,15 @@ export function getContractError(
45
46
  let cause = err
46
47
  if (err instanceof AbiDecodingZeroDataError) {
47
48
  cause = new ContractFunctionZeroDataError({ functionName })
48
- } else if (code === EXECUTION_REVERTED_ERROR_CODE && (data || message)) {
49
+ } else if (
50
+ code === EXECUTION_REVERTED_ERROR_CODE &&
51
+ (data || message || shortMessage)
52
+ ) {
49
53
  cause = new ContractFunctionRevertedError({
50
54
  abi,
51
55
  data,
52
56
  functionName,
53
- message,
57
+ message: shortMessage ?? message,
54
58
  })
55
59
  }
56
60
 
@@ -0,0 +1,82 @@
1
+ type Resolved<TReturnType extends readonly unknown[] = any> = [
2
+ result: TReturnType[number],
3
+ results: TReturnType,
4
+ ]
5
+
6
+ type PendingPromise<TReturnType extends readonly unknown[] = any> = {
7
+ resolve?: (data: Resolved<TReturnType>) => void
8
+ reject?: (reason?: unknown) => void
9
+ }
10
+
11
+ type SchedulerItem = { args: unknown; pendingPromise: PendingPromise }
12
+
13
+ const schedulerCache = new Map<number | string, SchedulerItem[]>()
14
+
15
+ export function createBatchScheduler<
16
+ TParameters,
17
+ TReturnType extends readonly unknown[],
18
+ >({
19
+ fn,
20
+ id,
21
+ shouldSplitBatch,
22
+ wait = 0,
23
+ }: {
24
+ fn: (args: TParameters[]) => Promise<TReturnType>
25
+ id: number | string
26
+ shouldSplitBatch?: (args: TParameters[]) => boolean
27
+ wait?: number
28
+ }) {
29
+ const exec = async () => {
30
+ const scheduler = getScheduler()
31
+ flush()
32
+
33
+ const args = scheduler.map(({ args }) => args)
34
+
35
+ if (args.length === 0) return
36
+
37
+ fn(args as TParameters[])
38
+ .then((data) => {
39
+ scheduler.forEach(({ pendingPromise }, i) =>
40
+ pendingPromise.resolve?.([data[i], data]),
41
+ )
42
+ })
43
+ .catch((err) => {
44
+ scheduler.forEach(({ pendingPromise }) => pendingPromise.reject?.(err))
45
+ })
46
+ }
47
+
48
+ const flush = () => schedulerCache.delete(id)
49
+
50
+ const getBatchedArgs = () =>
51
+ getScheduler().map(({ args }) => args) as TParameters[]
52
+
53
+ const getScheduler = () => schedulerCache.get(id) || []
54
+
55
+ const setScheduler = (item: SchedulerItem) =>
56
+ schedulerCache.set(id, [...getScheduler(), item])
57
+
58
+ return {
59
+ flush,
60
+ async schedule(args: TParameters) {
61
+ const pendingPromise: PendingPromise<TReturnType> = {}
62
+ const promise = new Promise<Resolved<TReturnType>>((resolve, reject) => {
63
+ pendingPromise.resolve = resolve
64
+ pendingPromise.reject = reject
65
+ })
66
+
67
+ const split = shouldSplitBatch?.([...getBatchedArgs(), args])
68
+
69
+ if (split) exec()
70
+
71
+ const hasActiveScheduler = getScheduler().length > 0
72
+ if (hasActiveScheduler) {
73
+ setScheduler({ args, pendingPromise })
74
+ return promise
75
+ }
76
+
77
+ setScheduler({ args, pendingPromise })
78
+ setTimeout(exec, wait)
79
+ return promise
80
+ },
81
+ }
82
+ }
@@ -1,3 +1,4 @@
1
+ export { createBatchScheduler } from './createBatchScheduler.js'
1
2
  export { getCache, withCache } from './withCache.js'
2
3
  export { withRetry } from './withRetry.js'
3
4
  export { withTimeout } from './withTimeout.js'