voltaire-effect 0.2.23 → 0.2.24

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 (264) hide show
  1. package/dist/KZGService-B7PJerOb.d.ts +146 -0
  2. package/dist/{X25519Test-DGsk1V9o.d.ts → X25519Test-C8Cicdd_.d.ts} +2 -139
  3. package/dist/crypto/index.d.ts +3 -2
  4. package/dist/{index-IgkEHjBe.d.ts → index-DsFjN_a3.d.ts} +17633 -11961
  5. package/dist/index.d.ts +3104 -938
  6. package/dist/index.js +4467 -2446
  7. package/dist/native/index.d.ts +14 -5
  8. package/dist/native/index.js +4489 -2468
  9. package/dist/primitives/index.d.ts +12 -4
  10. package/dist/primitives/index.js +3980 -2411
  11. package/package.json +2 -2
  12. package/src/crypto/Keccak256/index.ts +1 -0
  13. package/src/index.ts +2 -2
  14. package/src/primitives/Abi/decode.test.ts +38 -0
  15. package/src/primitives/Abi/decode.ts +67 -0
  16. package/src/primitives/Abi/decodeData.test.ts +37 -0
  17. package/src/primitives/Abi/decodeData.ts +77 -0
  18. package/src/primitives/Abi/decodeLog.test.ts +32 -0
  19. package/src/primitives/Abi/decodeLog.ts +81 -0
  20. package/src/primitives/Abi/decodeWrappedError.test.ts +41 -0
  21. package/src/primitives/Abi/decodeWrappedError.ts +68 -0
  22. package/src/primitives/Abi/encode.test.ts +43 -0
  23. package/src/primitives/Abi/encode.ts +67 -0
  24. package/src/primitives/Abi/encodePacked.test.ts +35 -0
  25. package/src/primitives/Abi/encodePacked.ts +62 -0
  26. package/src/primitives/Abi/encodeWrappedError.test.ts +21 -0
  27. package/src/primitives/Abi/encodeWrappedError.ts +64 -0
  28. package/src/primitives/Abi/findSelectorCollisions.test.ts +50 -0
  29. package/src/primitives/Abi/findSelectorCollisions.ts +83 -0
  30. package/src/primitives/Abi/index.ts +33 -7
  31. package/src/primitives/Abi/parseLogs.test.ts +37 -0
  32. package/src/primitives/Abi/parseLogs.ts +62 -0
  33. package/src/primitives/AccessList/AccessList.test.ts +229 -0
  34. package/src/primitives/AccessList/AccessListTypeSchema.ts +16 -0
  35. package/src/primitives/AccessList/addressCount.ts +21 -0
  36. package/src/primitives/AccessList/assertValid.ts +37 -0
  37. package/src/primitives/AccessList/create.ts +19 -0
  38. package/src/primitives/AccessList/deduplicate.ts +23 -0
  39. package/src/primitives/AccessList/from.ts +39 -0
  40. package/src/primitives/AccessList/fromBytes.ts +36 -0
  41. package/src/primitives/AccessList/gasCost.ts +22 -0
  42. package/src/primitives/AccessList/gasSavings.ts +26 -0
  43. package/src/primitives/AccessList/hasSavings.ts +23 -0
  44. package/src/primitives/AccessList/includesAddress.ts +25 -0
  45. package/src/primitives/AccessList/includesStorageKey.ts +28 -0
  46. package/src/primitives/AccessList/index.ts +99 -19
  47. package/src/primitives/AccessList/is.ts +23 -0
  48. package/src/primitives/AccessList/isEmpty.ts +23 -0
  49. package/src/primitives/AccessList/isItem.ts +22 -0
  50. package/src/primitives/AccessList/keysFor.ts +29 -0
  51. package/src/primitives/AccessList/merge.ts +24 -0
  52. package/src/primitives/AccessList/storageKeyCount.ts +21 -0
  53. package/src/primitives/AccessList/toBytes.ts +23 -0
  54. package/src/primitives/AccessList/withAddress.ts +27 -0
  55. package/src/primitives/AccessList/withStorageKey.ts +30 -0
  56. package/src/primitives/Address/Address.test.ts +146 -0
  57. package/src/primitives/Address/assert.ts +51 -0
  58. package/src/primitives/Address/calculateCreate2Address.ts +33 -0
  59. package/src/primitives/Address/calculateCreateAddress.ts +30 -0
  60. package/src/primitives/Address/deduplicateAddresses.ts +20 -0
  61. package/src/primitives/Address/from.ts +41 -0
  62. package/src/primitives/Address/fromAbiEncoded.ts +35 -0
  63. package/src/primitives/Address/fromBase64.ts +25 -0
  64. package/src/primitives/Address/fromBytes.ts +25 -0
  65. package/src/primitives/Address/fromHex.ts +31 -0
  66. package/src/primitives/Address/fromNumber.ts +25 -0
  67. package/src/primitives/Address/fromPrivateKey.ts +25 -0
  68. package/src/primitives/Address/fromPublicKey.ts +56 -0
  69. package/src/primitives/Address/index.ts +99 -35
  70. package/src/primitives/Address/is.ts +20 -0
  71. package/src/primitives/Address/isAddress.ts +22 -0
  72. package/src/primitives/Address/sortAddresses.ts +19 -0
  73. package/src/primitives/Address/toChecksummed.ts +32 -0
  74. package/src/primitives/Address/toHex.ts +18 -0
  75. package/src/primitives/Address/zero.ts +18 -0
  76. package/src/primitives/Base64/Base64.test.ts +75 -0
  77. package/src/primitives/Base64/convert.ts +37 -0
  78. package/src/primitives/Base64/decode.ts +59 -0
  79. package/src/primitives/Base64/encode.ts +42 -0
  80. package/src/primitives/Base64/from.ts +39 -0
  81. package/src/primitives/Base64/index.ts +81 -1
  82. package/src/primitives/Base64/size.ts +16 -0
  83. package/src/primitives/Base64/validation.ts +16 -0
  84. package/src/primitives/Blob/Blob.test.ts +292 -0
  85. package/src/primitives/Blob/calculateGas.ts +30 -0
  86. package/src/primitives/Blob/estimateBlobCount.ts +30 -0
  87. package/src/primitives/Blob/from.ts +38 -0
  88. package/src/primitives/Blob/fromData.ts +36 -0
  89. package/src/primitives/Blob/index.ts +99 -12
  90. package/src/primitives/Blob/isValidVersion.ts +27 -0
  91. package/src/primitives/Blob/joinData.ts +43 -0
  92. package/src/primitives/Blob/splitData.ts +36 -0
  93. package/src/primitives/Blob/toCommitment.ts +43 -0
  94. package/src/primitives/Blob/toProof.ts +50 -0
  95. package/src/primitives/Blob/toVersionedHash.ts +35 -0
  96. package/src/primitives/Blob/verify.ts +49 -0
  97. package/src/primitives/Blob/verifyBatch.ts +119 -0
  98. package/src/primitives/BloomFilter/BloomFilter.test.ts +138 -0
  99. package/src/primitives/BloomFilter/add.ts +23 -0
  100. package/src/primitives/BloomFilter/combine.ts +21 -0
  101. package/src/primitives/BloomFilter/contains.ts +26 -0
  102. package/src/primitives/BloomFilter/create.ts +35 -0
  103. package/src/primitives/BloomFilter/density.ts +22 -0
  104. package/src/primitives/BloomFilter/expectedFalsePositiveRate.ts +25 -0
  105. package/src/primitives/BloomFilter/fromHex.ts +37 -0
  106. package/src/primitives/BloomFilter/hash.ts +43 -0
  107. package/src/primitives/BloomFilter/index.ts +59 -37
  108. package/src/primitives/BloomFilter/isEmpty.ts +22 -0
  109. package/src/primitives/BloomFilter/merge.ts +24 -0
  110. package/src/primitives/BloomFilter/toHex.ts +22 -0
  111. package/src/primitives/Bytecode/analyze.ts +58 -0
  112. package/src/primitives/Bytecode/detectFusions.ts +10 -0
  113. package/src/primitives/Bytecode/equals.ts +10 -0
  114. package/src/primitives/Bytecode/extractRuntime.ts +12 -0
  115. package/src/primitives/Bytecode/format.ts +16 -0
  116. package/src/primitives/Bytecode/from.ts +16 -0
  117. package/src/primitives/Bytecode/fromHex.ts +14 -0
  118. package/src/primitives/Bytecode/getBlock.ts +12 -0
  119. package/src/primitives/Bytecode/getNextPc.ts +12 -0
  120. package/src/primitives/Bytecode/getPushSize.ts +8 -0
  121. package/src/primitives/Bytecode/hasMetadata.ts +10 -0
  122. package/src/primitives/Bytecode/hash.ts +9 -0
  123. package/src/primitives/Bytecode/index.ts +103 -13
  124. package/src/primitives/Bytecode/isPush.ts +8 -0
  125. package/src/primitives/Bytecode/isTerminator.ts +8 -0
  126. package/src/primitives/Bytecode/isValidJumpDest.ts +12 -0
  127. package/src/primitives/Bytecode/parseInstructions.ts +10 -0
  128. package/src/primitives/Bytecode/prettyPrint.ts +12 -0
  129. package/src/primitives/Bytecode/scan.ts +20 -0
  130. package/src/primitives/Bytecode/size.ts +9 -0
  131. package/src/primitives/Bytecode/stripMetadata.ts +10 -0
  132. package/src/primitives/Bytecode/toAbi.ts +10 -0
  133. package/src/primitives/Bytecode/toHex.ts +10 -0
  134. package/src/primitives/Bytecode/types.ts +23 -0
  135. package/src/primitives/Bytecode/validate.ts +9 -0
  136. package/src/primitives/Ens/Ens.test.ts +71 -0
  137. package/src/primitives/Ens/convert.ts +13 -0
  138. package/src/primitives/Ens/from.ts +32 -0
  139. package/src/primitives/Ens/hash.ts +46 -0
  140. package/src/primitives/Ens/index.ts +86 -4
  141. package/src/primitives/Ens/normalize.ts +45 -0
  142. package/src/primitives/Ens/validation.ts +38 -0
  143. package/src/primitives/EventLog/accessors.ts +32 -0
  144. package/src/primitives/EventLog/clone.ts +17 -0
  145. package/src/primitives/EventLog/create.ts +46 -0
  146. package/src/primitives/EventLog/filtering.ts +48 -0
  147. package/src/primitives/EventLog/index.ts +96 -6
  148. package/src/primitives/EventLog/status.ts +17 -0
  149. package/src/primitives/EventLog/toRpc.ts +49 -0
  150. package/src/primitives/Hardfork/HardforkSchema.ts +3 -3
  151. package/src/primitives/Hardfork/allIds.ts +13 -0
  152. package/src/primitives/Hardfork/allNames.ts +13 -0
  153. package/src/primitives/Hardfork/compare.ts +17 -0
  154. package/src/primitives/Hardfork/comparisons.ts +45 -0
  155. package/src/primitives/Hardfork/equals.ts +17 -0
  156. package/src/primitives/Hardfork/features.ts +61 -0
  157. package/src/primitives/Hardfork/fromString.ts +16 -0
  158. package/src/primitives/Hardfork/index.ts +128 -18
  159. package/src/primitives/Hardfork/isValidName.ts +14 -0
  160. package/src/primitives/Hardfork/minMax.ts +23 -0
  161. package/src/primitives/Hardfork/range.ts +19 -0
  162. package/src/primitives/Hardfork/toString.ts +16 -0
  163. package/src/primitives/Hash/Hash.test.ts +104 -0
  164. package/src/primitives/Hash/from.ts +47 -0
  165. package/src/primitives/Hash/fromBytes.ts +46 -0
  166. package/src/primitives/Hash/fromHex.ts +44 -0
  167. package/src/primitives/Hash/index.ts +45 -8
  168. package/src/primitives/Hash/isHash.ts +31 -0
  169. package/src/primitives/Hash/toHex.ts +29 -0
  170. package/src/primitives/Hex/Hex.test.ts +266 -155
  171. package/src/primitives/Hex/assertSize.ts +41 -0
  172. package/src/primitives/Hex/concat.ts +37 -0
  173. package/src/primitives/Hex/from.ts +38 -0
  174. package/src/primitives/Hex/fromBigInt.ts +40 -0
  175. package/src/primitives/Hex/fromBoolean.ts +29 -0
  176. package/src/primitives/Hex/fromNumber.ts +41 -0
  177. package/src/primitives/Hex/fromString.ts +28 -0
  178. package/src/primitives/Hex/index.ts +68 -37
  179. package/src/primitives/Hex/pad.ts +40 -0
  180. package/src/primitives/Hex/padRight.ts +39 -0
  181. package/src/primitives/Hex/size.ts +29 -0
  182. package/src/primitives/Hex/slice.ts +42 -0
  183. package/src/primitives/Hex/toBigInt.ts +27 -0
  184. package/src/primitives/Hex/toBoolean.ts +38 -0
  185. package/src/primitives/Hex/toNumber.ts +37 -0
  186. package/src/primitives/Hex/toStringHex.ts +39 -0
  187. package/src/primitives/Hex/trim.ts +27 -0
  188. package/src/primitives/Hex/validate.ts +37 -0
  189. package/src/primitives/Hex/xor.ts +39 -0
  190. package/src/primitives/Opcode/OpcodeSchema.ts +1 -1
  191. package/src/primitives/Opcode/disassemble.ts +15 -0
  192. package/src/primitives/Opcode/dupPosition.ts +15 -0
  193. package/src/primitives/Opcode/format.ts +15 -0
  194. package/src/primitives/Opcode/getters.ts +54 -0
  195. package/src/primitives/Opcode/index.ts +301 -11
  196. package/src/primitives/Opcode/info.ts +18 -0
  197. package/src/primitives/Opcode/jumpDests.ts +15 -0
  198. package/src/primitives/Opcode/logTopics.ts +15 -0
  199. package/src/primitives/Opcode/name.ts +15 -0
  200. package/src/primitives/Opcode/parse.ts +15 -0
  201. package/src/primitives/Opcode/predicates.ts +72 -0
  202. package/src/primitives/Opcode/pushBytes.ts +15 -0
  203. package/src/primitives/Opcode/pushOpcode.ts +15 -0
  204. package/src/primitives/Opcode/swapPosition.ts +15 -0
  205. package/src/primitives/Rlp/decodeBatch.ts +46 -0
  206. package/src/primitives/Rlp/decodeObject.ts +46 -0
  207. package/src/primitives/Rlp/decodeValue.ts +51 -0
  208. package/src/primitives/Rlp/encodeBatch.ts +50 -0
  209. package/src/primitives/Rlp/encodeObject.ts +48 -0
  210. package/src/primitives/Rlp/encodeVariadic.ts +49 -0
  211. package/src/primitives/Rlp/equals.ts +22 -0
  212. package/src/primitives/Rlp/from.ts +44 -0
  213. package/src/primitives/Rlp/fromJSON.ts +45 -0
  214. package/src/primitives/Rlp/getEncodedLength.ts +47 -0
  215. package/src/primitives/Rlp/getLength.ts +44 -0
  216. package/src/primitives/Rlp/index.ts +67 -14
  217. package/src/primitives/Rlp/isBytesData.ts +21 -0
  218. package/src/primitives/Rlp/isCanonical.ts +32 -0
  219. package/src/primitives/Rlp/isData.ts +21 -0
  220. package/src/primitives/Rlp/isList.ts +46 -0
  221. package/src/primitives/Rlp/isListData.ts +21 -0
  222. package/src/primitives/Rlp/isString.ts +46 -0
  223. package/src/primitives/Rlp/toJSON.ts +20 -0
  224. package/src/primitives/Rlp/toRaw.ts +31 -0
  225. package/src/primitives/Signature/Signature.test.ts +217 -0
  226. package/src/primitives/Signature/from.ts +38 -0
  227. package/src/primitives/Signature/fromBytes.ts +31 -0
  228. package/src/primitives/Signature/fromCompact.ts +33 -0
  229. package/src/primitives/Signature/fromDER.ts +35 -0
  230. package/src/primitives/Signature/fromEd25519.ts +24 -0
  231. package/src/primitives/Signature/fromHex.ts +29 -0
  232. package/src/primitives/Signature/fromP256.ts +25 -0
  233. package/src/primitives/Signature/fromRpc.ts +38 -0
  234. package/src/primitives/Signature/fromSecp256k1.ts +29 -0
  235. package/src/primitives/Signature/fromTuple.ts +33 -0
  236. package/src/primitives/Signature/getR.ts +24 -0
  237. package/src/primitives/Signature/getS.ts +24 -0
  238. package/src/primitives/Signature/getV.ts +24 -0
  239. package/src/primitives/Signature/index.ts +61 -11
  240. package/src/primitives/Signature/toDER.ts +24 -0
  241. package/src/primitives/Signature/toHex.ts +24 -0
  242. package/src/primitives/Signature/toRpc.ts +35 -0
  243. package/src/primitives/Signature/toTuple.ts +29 -0
  244. package/src/primitives/Signature/verify.ts +31 -0
  245. package/src/primitives/Siwe/create.ts +56 -0
  246. package/src/primitives/Siwe/hash.ts +27 -0
  247. package/src/primitives/Siwe/index.ts +57 -21
  248. package/src/primitives/Siwe/parse.ts +24 -0
  249. package/src/primitives/Siwe/verify.ts +47 -0
  250. package/src/primitives/Transaction/index.ts +467 -2
  251. package/src/primitives/Uint/Uint.test.ts +200 -0
  252. package/src/primitives/Uint/dividedBy.ts +34 -0
  253. package/src/primitives/Uint/from.ts +35 -0
  254. package/src/primitives/Uint/fromAbiEncoded.ts +29 -0
  255. package/src/primitives/Uint/fromBigInt.ts +30 -0
  256. package/src/primitives/Uint/fromBytes.ts +32 -0
  257. package/src/primitives/Uint/fromHex.ts +32 -0
  258. package/src/primitives/Uint/fromNumber.ts +30 -0
  259. package/src/primitives/Uint/index.ts +90 -45
  260. package/src/primitives/Uint/isUint256.ts +25 -0
  261. package/src/primitives/Uint/isValid.ts +25 -0
  262. package/src/primitives/Uint/modulo.ts +34 -0
  263. package/src/primitives/Uint/toHex.ts +31 -0
  264. package/src/primitives/Uint/tryFrom.ts +30 -0
@@ -1,5 +1,7 @@
1
+ import { Effect, Exit } from "effect";
1
2
  import * as S from "effect/Schema";
2
3
  import { describe, expect, it } from "vitest";
4
+ import type { HexType } from "@tevm/voltaire/Hex";
3
5
  import * as Hex from "./index.js";
4
6
 
5
7
  describe("Hex.String", () => {
@@ -159,62 +161,48 @@ describe("Hex.Bytes", () => {
159
161
  });
160
162
  });
161
163
 
162
- describe("pure functions", () => {
164
+ describe("pure functions (infallible)", () => {
163
165
  describe("isHex", () => {
164
166
  it("returns true for valid hex with prefix", () => {
165
- const result = Hex.isHex("0x1234");
166
- expect(result).toBe(true);
167
+ expect(Hex.isHex("0x1234")).toBe(true);
167
168
  });
168
169
 
169
170
  it("returns false for empty hex 0x", () => {
170
- const result = Hex.isHex("0x");
171
- expect(result).toBe(false);
171
+ expect(Hex.isHex("0x")).toBe(false);
172
172
  });
173
173
 
174
174
  it("returns false for hex without prefix", () => {
175
- const result = Hex.isHex("1234");
176
- expect(result).toBe(false);
175
+ expect(Hex.isHex("1234")).toBe(false);
177
176
  });
178
177
 
179
178
  it("returns false for invalid hex characters", () => {
180
- const result = Hex.isHex("0xZZZZ");
181
- expect(result).toBe(false);
179
+ expect(Hex.isHex("0xZZZZ")).toBe(false);
182
180
  });
183
181
 
184
182
  it("returns true for odd-length hex", () => {
185
- const result = Hex.isHex("0xabc");
186
- expect(result).toBe(true);
187
- });
188
-
189
- it("returns false for non-hex string", () => {
190
- const result = Hex.isHex("hello");
191
- expect(result).toBe(false);
183
+ expect(Hex.isHex("0xabc")).toBe(true);
192
184
  });
193
185
  });
194
186
 
195
187
  describe("isSized", () => {
196
188
  it("returns true for correct size", () => {
197
189
  const hex = S.decodeSync(Hex.String)("0x1234");
198
- const result = Hex.isSized(hex, 2);
199
- expect(result).toBe(true);
190
+ expect(Hex.isSized(hex, 2)).toBe(true);
200
191
  });
201
192
 
202
193
  it("returns false for incorrect size", () => {
203
194
  const hex = S.decodeSync(Hex.String)("0x1234");
204
- const result = Hex.isSized(hex, 4);
205
- expect(result).toBe(false);
195
+ expect(Hex.isSized(hex, 4)).toBe(false);
206
196
  });
207
197
 
208
198
  it("returns true for empty hex with size 0", () => {
209
199
  const hex = S.decodeSync(Hex.String)("0x");
210
- const result = Hex.isSized(hex, 0);
211
- expect(result).toBe(true);
200
+ expect(Hex.isSized(hex, 0)).toBe(true);
212
201
  });
213
202
 
214
203
  it("checks 32-byte hex correctly", () => {
215
204
  const hex = S.decodeSync(Hex.String)(`0x${"ab".repeat(32)}`);
216
- const result = Hex.isSized(hex, 32);
217
- expect(result).toBe(true);
205
+ expect(Hex.isSized(hex, 32)).toBe(true);
218
206
  });
219
207
  });
220
208
 
@@ -248,11 +236,6 @@ describe("pure functions", () => {
248
236
  expect(result).toBe(`0x${"00".repeat(32)}`);
249
237
  expect(result.length).toBe(66);
250
238
  });
251
-
252
- it("creates 1-byte zero hex", () => {
253
- const result = Hex.zero(1);
254
- expect(result).toBe("0x00");
255
- });
256
239
  });
257
240
 
258
241
  describe("random", () => {
@@ -278,201 +261,329 @@ describe("pure functions", () => {
278
261
  expect(result).toMatch(/^0x[0-9a-f]{16}$/);
279
262
  });
280
263
  });
281
- });
282
264
 
283
- describe("edge cases", () => {
284
- it("handles maximum safe integer bytes", () => {
285
- const hex = S.decodeSync(Hex.String)("0xffffffffffffff");
286
- const sized = Hex.isSized(hex, 7);
287
- expect(sized).toBe(true);
265
+ describe("equals", () => {
266
+ it("returns true for equal hex", () => {
267
+ const a = S.decodeSync(Hex.String)("0xdeadbeef");
268
+ const b = S.decodeSync(Hex.String)("0xdeadbeef");
269
+ expect(Hex.equals(a, b)).toBe(true);
270
+ });
271
+
272
+ it("returns false for different hex", () => {
273
+ const a = S.decodeSync(Hex.String)("0xdeadbeef");
274
+ const b = S.decodeSync(Hex.String)("0x12345678");
275
+ expect(Hex.equals(a, b)).toBe(false);
276
+ });
288
277
  });
289
278
 
290
- it("handles all zeros", () => {
291
- const hex = S.decodeSync(Hex.String)("0x0000000000");
292
- expect(hex).toBe("0x0000000000");
279
+ describe("size", () => {
280
+ it("returns correct size for hex", () => {
281
+ const hex = S.decodeSync(Hex.String)("0xdeadbeef");
282
+ expect(Hex.size(hex)).toBe(4);
283
+ });
284
+
285
+ it("returns 0 for empty hex", () => {
286
+ const hex = S.decodeSync(Hex.String)("0x");
287
+ expect(Hex.size(hex)).toBe(0);
288
+ });
289
+
290
+ it("returns correct size for 32-byte hex", () => {
291
+ const hex = S.decodeSync(Hex.String)(`0x${"ab".repeat(32)}`);
292
+ expect(Hex.size(hex)).toBe(32);
293
+ });
293
294
  });
294
295
 
295
- it("handles all ones (ff)", () => {
296
- const hex = S.decodeSync(Hex.String)("0xffffffffff");
297
- expect(hex).toBe("0xffffffffff");
296
+ describe("trim", () => {
297
+ it("trims leading zeros", () => {
298
+ const hex = "0x00001234" as HexType;
299
+ expect(Hex.trim(hex)).toBe("0x1234");
300
+ });
301
+
302
+ it("preserves non-zero hex", () => {
303
+ const hex = "0xdeadbeef" as HexType;
304
+ expect(Hex.trim(hex)).toBe("0xdeadbeef");
305
+ });
298
306
  });
299
307
 
300
- it("preserves case for uppercase hex", () => {
301
- const hex = S.decodeSync(Hex.String)("0xABCDEF");
302
- expect(hex).toBe("0xABCDEF");
308
+ describe("fromBoolean", () => {
309
+ it("converts true to 0x01", () => {
310
+ expect(Hex.fromBoolean(true)).toBe("0x01");
311
+ });
312
+
313
+ it("converts false to 0x00", () => {
314
+ expect(Hex.fromBoolean(false)).toBe("0x00");
315
+ });
303
316
  });
304
- });
305
317
 
306
- describe("error cases", () => {
307
- describe("Hex.String errors", () => {
308
- it("fails on null", () => {
309
- expect(() =>
310
- S.decodeSync(Hex.String)(null as unknown as string),
311
- ).toThrow();
318
+ describe("fromString", () => {
319
+ it("encodes string to hex", () => {
320
+ expect(Hex.fromString("hello")).toBe("0x68656c6c6f");
312
321
  });
313
322
 
314
- it("fails on undefined", () => {
315
- expect(() =>
316
- S.decodeSync(Hex.String)(undefined as unknown as string),
317
- ).toThrow();
323
+ it("encodes empty string", () => {
324
+ expect(Hex.fromString("")).toBe("0x");
318
325
  });
326
+ });
319
327
 
320
- it("fails on object", () => {
321
- expect(() => S.decodeSync(Hex.String)({} as unknown as string)).toThrow();
328
+ describe("toBigInt", () => {
329
+ it("converts hex to bigint", () => {
330
+ const hex = S.decodeSync(Hex.String)("0xff");
331
+ expect(Hex.toBigInt(hex)).toBe(255n);
322
332
  });
323
333
 
324
- it("fails on array", () => {
325
- expect(() => S.decodeSync(Hex.String)([] as unknown as string)).toThrow();
334
+ it("handles large values", () => {
335
+ const hex = S.decodeSync(Hex.String)("0xde0b6b3a7640000");
336
+ expect(Hex.toBigInt(hex)).toBe(1000000000000000000n);
326
337
  });
338
+ });
339
+ });
327
340
 
328
- it("fails on empty string", () => {
329
- expect(() => S.decodeSync(Hex.String)("")).toThrow();
341
+ describe("Effect functions (fallible)", () => {
342
+ describe("from", () => {
343
+ it("parses valid hex string", async () => {
344
+ const result = await Effect.runPromise(Hex.from("0xdeadbeef"));
345
+ expect(result).toBe("0xdeadbeef");
330
346
  });
331
347
 
332
- it("fails on whitespace", () => {
333
- expect(() => S.decodeSync(Hex.String)(" ")).toThrow();
348
+ it("parses bytes", async () => {
349
+ const result = await Effect.runPromise(
350
+ Hex.from(new Uint8Array([0xde, 0xad])),
351
+ );
352
+ expect(result).toBe("0xdead");
334
353
  });
335
354
 
336
- it("fails on 0x with spaces", () => {
337
- expect(() => S.decodeSync(Hex.String)("0x 12")).toThrow();
355
+ it("fails on invalid hex", async () => {
356
+ const exit = await Effect.runPromiseExit(Hex.from("invalid"));
357
+ expect(Exit.isFailure(exit)).toBe(true);
358
+ });
359
+ });
360
+
361
+ describe("fromNumber", () => {
362
+ it("converts number to hex", async () => {
363
+ const result = await Effect.runPromise(Hex.fromNumber(255));
364
+ expect(result).toBe("0xff");
338
365
  });
339
366
 
340
- it("fails on special characters", () => {
341
- expect(() => S.decodeSync(Hex.String)("0x!@#$")).toThrow();
367
+ it("pads to size", async () => {
368
+ const result = await Effect.runPromise(Hex.fromNumber(255, 2));
369
+ expect(result).toBe("0x00ff");
370
+ });
371
+
372
+ it("fails on negative number", async () => {
373
+ const exit = await Effect.runPromiseExit(Hex.fromNumber(-1));
374
+ expect(Exit.isFailure(exit)).toBe(true);
342
375
  });
343
376
  });
344
377
 
345
- describe("Hex.Bytes errors", () => {
346
- it("fails on null", () => {
347
- expect(() =>
348
- S.decodeSync(Hex.Bytes)(null as unknown as Uint8Array),
349
- ).toThrow();
378
+ describe("fromBigInt", () => {
379
+ it("converts bigint to hex", async () => {
380
+ const result = await Effect.runPromise(Hex.fromBigInt(255n));
381
+ expect(result).toBe("0xff");
350
382
  });
351
383
 
352
- it("fails on string input", () => {
353
- expect(() =>
354
- S.decodeSync(Hex.Bytes)("0xab" as unknown as Uint8Array),
355
- ).toThrow();
384
+ it("pads to size", async () => {
385
+ const result = await Effect.runPromise(Hex.fromBigInt(255n, 2));
386
+ expect(result).toBe("0x00ff");
387
+ });
388
+
389
+ it("fails on negative bigint", async () => {
390
+ const exit = await Effect.runPromiseExit(Hex.fromBigInt(-1n));
391
+ expect(Exit.isFailure(exit)).toBe(true);
392
+ });
393
+ });
394
+
395
+ describe("toNumber", () => {
396
+ it("converts hex to number", async () => {
397
+ const hex = S.decodeSync(Hex.String)("0xff");
398
+ const result = await Effect.runPromise(Hex.toNumber(hex));
399
+ expect(result).toBe(255);
356
400
  });
357
401
  });
358
- });
359
402
 
360
- describe("additional edge cases", () => {
361
- describe("isHex edge cases", () => {
362
- it("returns true for single char hex", () => {
363
- const result = Hex.isHex("0xa");
403
+ describe("toBoolean", () => {
404
+ it("converts 0x01 to true", async () => {
405
+ const hex = "0x01" as HexType;
406
+ const result = await Effect.runPromise(Hex.toBoolean(hex));
364
407
  expect(result).toBe(true);
365
408
  });
366
409
 
367
- it("returns false for just 0x prefix", () => {
368
- const result = Hex.isHex("0x");
410
+ it("converts 0x00 to false", async () => {
411
+ const hex = "0x00" as HexType;
412
+ const result = await Effect.runPromise(Hex.toBoolean(hex));
369
413
  expect(result).toBe(false);
370
414
  });
371
415
 
372
- it("returns false for string without prefix", () => {
373
- const result = Hex.isHex("abcd");
374
- expect(result).toBe(false);
416
+ it("fails on invalid boolean hex", async () => {
417
+ const hex = "0xff" as HexType;
418
+ const exit = await Effect.runPromiseExit(Hex.toBoolean(hex));
419
+ expect(Exit.isFailure(exit)).toBe(true);
375
420
  });
376
421
  });
377
422
 
378
- describe("isSized edge cases", () => {
379
- it("returns false for odd-length hex size calculation", () => {
380
- const hex = S.decodeSync(Hex.String)("0xabc");
381
- const result = Hex.isSized(hex, 1);
382
- expect(result).toBe(false);
423
+ describe("toStringHex", () => {
424
+ it("decodes hex to string", async () => {
425
+ const hex = "0x68656c6c6f" as HexType;
426
+ const result = await Effect.runPromise(Hex.toStringHex(hex));
427
+ expect(result).toBe("hello");
383
428
  });
429
+ });
384
430
 
385
- it("handles large sizes", () => {
386
- const hex = S.decodeSync(Hex.String)(`0x${"ab".repeat(1000)}`);
387
- const result = Hex.isSized(hex, 1000);
388
- expect(result).toBe(true);
431
+ describe("concat", () => {
432
+ it("concatenates hex strings", async () => {
433
+ const a = "0x1234" as HexType;
434
+ const b = "0x5678" as HexType;
435
+ const result = await Effect.runPromise(Hex.concat(a, b));
436
+ expect(result).toBe("0x12345678");
389
437
  });
390
- });
391
438
 
392
- describe("zero edge cases", () => {
393
- it("creates large zero hex", () => {
394
- const result = Hex.zero(100);
395
- expect(result).toBe(`0x${"00".repeat(100)}`);
439
+ it("concatenates multiple hex strings", async () => {
440
+ const a = "0x12" as HexType;
441
+ const b = "0x34" as HexType;
442
+ const c = "0x56" as HexType;
443
+ const result = await Effect.runPromise(Hex.concat(a, b, c));
444
+ expect(result).toBe("0x123456");
396
445
  });
397
446
  });
398
447
 
399
- describe("random edge cases", () => {
400
- it("random of size 1 produces valid hex", () => {
401
- const result = Hex.random(1);
402
- expect(result.length).toBe(4);
403
- expect(result.startsWith("0x")).toBe(true);
448
+ describe("pad", () => {
449
+ it("left-pads hex to size", async () => {
450
+ const hex = "0x12" as HexType;
451
+ const result = await Effect.runPromise(Hex.pad(hex, 4));
452
+ expect(result).toBe("0x00000012");
404
453
  });
405
454
 
406
- it("random produces lowercase hex", () => {
407
- const result = Hex.random(32);
408
- expect(result).toMatch(/^0x[0-9a-f]+$/);
455
+ it("fails when hex exceeds target size", async () => {
456
+ const hex = "0x12345678" as HexType;
457
+ const exit = await Effect.runPromiseExit(Hex.pad(hex, 2));
458
+ expect(Exit.isFailure(exit)).toBe(true);
409
459
  });
410
460
  });
411
461
 
412
- describe("clone edge cases", () => {
413
- it("clones very long hex", () => {
414
- const original = S.decodeSync(Hex.String)(`0x${"ab".repeat(1000)}`);
415
- const cloned = Hex.clone(original);
416
- expect(cloned).toBe(original);
462
+ describe("padRight", () => {
463
+ it("right-pads hex to size", async () => {
464
+ const hex = "0x12" as HexType;
465
+ const result = await Effect.runPromise(Hex.padRight(hex, 4));
466
+ expect(result).toBe("0x12000000");
417
467
  });
418
468
  });
419
469
 
420
- describe("Bytes schema edge cases", () => {
421
- it("decodes from large byte array", () => {
422
- const bytes = new Uint8Array(10000).fill(0xab);
423
- const hex = S.decodeSync(Hex.Bytes)(bytes);
424
- expect(hex.length).toBe(20002);
470
+ describe("slice", () => {
471
+ it("slices hex from start", async () => {
472
+ const hex = "0x123456" as HexType;
473
+ const result = await Effect.runPromise(Hex.slice(hex, 1));
474
+ expect(result).toBe("0x3456");
425
475
  });
426
476
 
427
- it("encodes to bytes preserves values", () => {
428
- const hex = S.decodeSync(Hex.String)(
429
- "0x000102030405060708090a0b0c0d0e0f",
430
- );
431
- const bytes = S.encodeSync(Hex.Bytes)(hex);
432
- for (let i = 0; i < 16; i++) {
433
- expect(bytes[i]).toBe(i);
434
- }
477
+ it("slices hex with range", async () => {
478
+ const hex = "0x123456" as HexType;
479
+ const result = await Effect.runPromise(Hex.slice(hex, 0, 1));
480
+ expect(result).toBe("0x12");
435
481
  });
436
482
  });
437
- });
438
483
 
439
- describe("API consistency - infallible ops return directly", () => {
440
- it("clone returns HexType directly, not Effect", () => {
441
- const hex = S.decodeSync(Hex.String)("0xdeadbeef");
442
- const result = Hex.clone(hex);
443
- // Direct value, not Effect
444
- expect(typeof result).toBe("string");
445
- expect(result.startsWith("0x")).toBe(true);
484
+ describe("validate", () => {
485
+ it("validates valid hex", async () => {
486
+ const result = await Effect.runPromise(Hex.validate("0x1234"));
487
+ expect(result).toBe("0x1234");
488
+ });
489
+
490
+ it("fails on invalid hex", async () => {
491
+ const exit = await Effect.runPromiseExit(Hex.validate("invalid"));
492
+ expect(Exit.isFailure(exit)).toBe(true);
493
+ });
446
494
  });
447
495
 
448
- it("isHex returns boolean directly, not Effect", () => {
449
- const result = Hex.isHex("0x1234");
450
- expect(typeof result).toBe("boolean");
496
+ describe("xor", () => {
497
+ it("xors two hex strings", async () => {
498
+ const a = "0xff00" as HexType;
499
+ const b = "0x00ff" as HexType;
500
+ const result = await Effect.runPromise(Hex.xor(a, b));
501
+ expect(result).toBe("0xffff");
502
+ });
451
503
  });
452
504
 
453
- it("isSized returns boolean directly, not Effect", () => {
454
- const hex = S.decodeSync(Hex.String)("0x1234");
455
- const result = Hex.isSized(hex, 2);
456
- expect(typeof result).toBe("boolean");
505
+ describe("assertSize", () => {
506
+ it("succeeds when size matches", async () => {
507
+ const hex = "0x1234" as HexType;
508
+ const result = await Effect.runPromise(Hex.assertSize(hex, 2));
509
+ expect(result).toBe("0x1234");
510
+ });
511
+
512
+ it("fails when size doesn't match", async () => {
513
+ const hex = "0x1234" as HexType;
514
+ const exit = await Effect.runPromiseExit(Hex.assertSize(hex, 4));
515
+ expect(Exit.isFailure(exit)).toBe(true);
516
+ });
457
517
  });
518
+ });
458
519
 
459
- it("zero returns HexType directly, not Effect", () => {
460
- const result = Hex.zero(4);
461
- expect(typeof result).toBe("string");
462
- expect(result).toBe("0x00000000");
520
+ describe("API consistency", () => {
521
+ it("infallible ops return directly, not Effect", () => {
522
+ const hex = S.decodeSync(Hex.String)("0xdeadbeef");
523
+
524
+ expect(typeof Hex.clone(hex)).toBe("string");
525
+ expect(typeof Hex.isHex("0x1234")).toBe("boolean");
526
+ expect(typeof Hex.isSized(hex, 4)).toBe("boolean");
527
+ expect(typeof Hex.zero(4)).toBe("string");
528
+ expect(typeof Hex.random(8)).toBe("string");
529
+ expect(typeof Hex.equals(hex, hex)).toBe("boolean");
530
+ expect(typeof Hex.size(hex)).toBe("number");
531
+ expect(typeof Hex.trim(hex)).toBe("string");
532
+ expect(typeof Hex.fromBoolean(true)).toBe("string");
533
+ expect(typeof Hex.fromString("hello")).toBe("string");
463
534
  });
535
+ });
464
536
 
465
- it("random returns HexType directly, not Effect", () => {
466
- const result = Hex.random(8);
467
- expect(typeof result).toBe("string");
468
- expect(result.startsWith("0x")).toBe(true);
537
+ describe("error cases", () => {
538
+ describe("Hex.String errors", () => {
539
+ it("fails on null", () => {
540
+ expect(() =>
541
+ S.decodeSync(Hex.String)(null as unknown as string),
542
+ ).toThrow();
543
+ });
544
+
545
+ it("fails on undefined", () => {
546
+ expect(() =>
547
+ S.decodeSync(Hex.String)(undefined as unknown as string),
548
+ ).toThrow();
549
+ });
550
+
551
+ it("fails on object", () => {
552
+ expect(() => S.decodeSync(Hex.String)({} as unknown as string)).toThrow();
553
+ });
554
+
555
+ it("fails on array", () => {
556
+ expect(() => S.decodeSync(Hex.String)([] as unknown as string)).toThrow();
557
+ });
558
+
559
+ it("fails on empty string", () => {
560
+ expect(() => S.decodeSync(Hex.String)("")).toThrow();
561
+ });
562
+
563
+ it("fails on whitespace", () => {
564
+ expect(() => S.decodeSync(Hex.String)(" ")).toThrow();
565
+ });
566
+
567
+ it("fails on 0x with spaces", () => {
568
+ expect(() => S.decodeSync(Hex.String)("0x 12")).toThrow();
569
+ });
570
+
571
+ it("fails on special characters", () => {
572
+ expect(() => S.decodeSync(Hex.String)("0x!@#$")).toThrow();
573
+ });
469
574
  });
470
575
 
471
- it("equals returns boolean directly, not Effect", () => {
472
- const a = S.decodeSync(Hex.String)("0xdeadbeef");
473
- const b = S.decodeSync(Hex.String)("0xdeadbeef");
474
- const result = Hex.equals(a, b);
475
- expect(typeof result).toBe("boolean");
476
- expect(result).toBe(true);
576
+ describe("Hex.Bytes errors", () => {
577
+ it("fails on null", () => {
578
+ expect(() =>
579
+ S.decodeSync(Hex.Bytes)(null as unknown as Uint8Array),
580
+ ).toThrow();
581
+ });
582
+
583
+ it("fails on string input", () => {
584
+ expect(() =>
585
+ S.decodeSync(Hex.Bytes)("0xab" as unknown as Uint8Array),
586
+ ).toThrow();
587
+ });
477
588
  });
478
589
  });
@@ -0,0 +1,41 @@
1
+ /**
2
+ * @fileoverview Effect wrapper for Hex.assertSize.
3
+ * Asserts that Hex is exactly the specified size.
4
+ * @module voltaire-effect/primitives/Hex/assertSize
5
+ * @since 0.1.0
6
+ */
7
+
8
+ import {
9
+ type HexType,
10
+ type Sized,
11
+ Hex as VoltaireHex,
12
+ InvalidLengthError,
13
+ } from "@tevm/voltaire/Hex";
14
+ import { Effect } from "effect";
15
+
16
+ /**
17
+ * Assert that Hex is exactly the specified size.
18
+ *
19
+ * @param hex - Hex string to check
20
+ * @param targetSize - Expected size in bytes
21
+ * @returns Effect that succeeds with Sized<T> or fails with InvalidLengthError
22
+ *
23
+ * @example
24
+ * ```ts
25
+ * import * as Hex from 'voltaire-effect/primitives/Hex'
26
+ * import { Effect } from 'effect'
27
+ *
28
+ * const sized = yield* Hex.assertSize('0x1234', 2) // succeeds with Sized<2>
29
+ * yield* Hex.assertSize('0x1234', 4) // fails with InvalidLengthError
30
+ * ```
31
+ *
32
+ * @since 0.1.0
33
+ */
34
+ export const assertSize = <TSize extends number>(
35
+ hex: HexType,
36
+ targetSize: TSize,
37
+ ): Effect.Effect<Sized<TSize>, InvalidLengthError> =>
38
+ Effect.try({
39
+ try: () => VoltaireHex.assertSize(hex, targetSize),
40
+ catch: (e) => e as InvalidLengthError,
41
+ });
@@ -0,0 +1,37 @@
1
+ /**
2
+ * @fileoverview Effect wrapper for Hex.concat.
3
+ * Concatenates multiple Hex strings.
4
+ * @module voltaire-effect/primitives/Hex/concat
5
+ * @since 0.1.0
6
+ */
7
+
8
+ import {
9
+ type HexType,
10
+ Hex as VoltaireHex,
11
+ InvalidFormatError,
12
+ } from "@tevm/voltaire/Hex";
13
+ import { Effect } from "effect";
14
+
15
+ /**
16
+ * Concatenate multiple Hex strings.
17
+ *
18
+ * @param hexes - Hex strings to concatenate
19
+ * @returns Effect with combined HexType or InvalidFormatError
20
+ *
21
+ * @example
22
+ * ```ts
23
+ * import * as Hex from 'voltaire-effect/primitives/Hex'
24
+ * import { Effect } from 'effect'
25
+ *
26
+ * const combined = yield* Hex.concat('0x1234', '0x5678') // '0x12345678'
27
+ * ```
28
+ *
29
+ * @since 0.1.0
30
+ */
31
+ export const concat = (
32
+ ...hexes: readonly HexType[]
33
+ ): Effect.Effect<HexType, InvalidFormatError> =>
34
+ Effect.try({
35
+ try: () => VoltaireHex.concat(...hexes),
36
+ catch: (e) => e as InvalidFormatError,
37
+ });
@@ -0,0 +1,38 @@
1
+ /**
2
+ * @fileoverview Effect wrapper for Hex.from.
3
+ * Parses any input to a validated Hex string.
4
+ * @module voltaire-effect/primitives/Hex/from
5
+ * @since 0.1.0
6
+ */
7
+
8
+ import {
9
+ type HexType,
10
+ Hex as VoltaireHex,
11
+ InvalidFormatError,
12
+ } from "@tevm/voltaire/Hex";
13
+ import { Effect } from "effect";
14
+
15
+ /**
16
+ * Parse any input (string or Uint8Array) to Hex.
17
+ *
18
+ * @param value - String or bytes to convert
19
+ * @returns Effect with HexType or InvalidFormatError
20
+ *
21
+ * @example
22
+ * ```ts
23
+ * import * as Hex from 'voltaire-effect/primitives/Hex'
24
+ * import { Effect } from 'effect'
25
+ *
26
+ * const hex = yield* Hex.from('0xdeadbeef')
27
+ * const fromBytes = yield* Hex.from(new Uint8Array([0xde, 0xad]))
28
+ * ```
29
+ *
30
+ * @since 0.1.0
31
+ */
32
+ export const from = (
33
+ value: string | Uint8Array,
34
+ ): Effect.Effect<HexType, InvalidFormatError> =>
35
+ Effect.try({
36
+ try: () => VoltaireHex.from(value),
37
+ catch: (e) => e as InvalidFormatError,
38
+ });