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
@@ -0,0 +1,36 @@
1
+ /**
2
+ * @module splitData
3
+ * @description Split large data into multiple blobs
4
+ * @since 0.1.0
5
+ */
6
+ import { BrandedBlob as BlobNamespace } from "@tevm/voltaire";
7
+ import { Effect } from "effect";
8
+ import type { InvalidBlobDataSizeError } from "@tevm/voltaire/Blob";
9
+
10
+ type BrandedBlob = BlobNamespace.BrandedBlob;
11
+
12
+ /**
13
+ * Split large data into multiple blobs.
14
+ *
15
+ * Each blob holds up to 126972 bytes of data (max 6 blobs per transaction).
16
+ *
17
+ * @param data - Data to split
18
+ * @returns Effect yielding array of blobs or failing with InvalidBlobDataSizeError
19
+ * @throws {InvalidBlobDataSizeError} If data requires more than 6 blobs
20
+ * @example
21
+ * ```typescript
22
+ * import * as Blob from 'voltaire-effect/primitives/Blob'
23
+ * import * as Effect from 'effect/Effect'
24
+ *
25
+ * const largeData = new Uint8Array(300000)
26
+ * const blobs = await Effect.runPromise(Blob.splitData(largeData)) // [blob1, blob2, blob3]
27
+ * ```
28
+ * @since 0.1.0
29
+ */
30
+ export const splitData = (
31
+ data: Uint8Array,
32
+ ): Effect.Effect<BrandedBlob[], InvalidBlobDataSizeError> =>
33
+ Effect.try({
34
+ try: () => BlobNamespace.splitData(data),
35
+ catch: (e) => e as InvalidBlobDataSizeError,
36
+ });
@@ -0,0 +1,43 @@
1
+ /**
2
+ * @module toCommitment
3
+ * @description Compute KZG commitment for blob using KZGService
4
+ * @since 0.1.0
5
+ */
6
+ import type { BrandedBlob as BlobNamespace } from "@tevm/voltaire";
7
+ import { Effect } from "effect";
8
+ import {
9
+ type KZGError,
10
+ KZGService,
11
+ } from "../../crypto/KZG/KZGService.js";
12
+
13
+ type BrandedBlob = BlobNamespace.BrandedBlob;
14
+ type Commitment = BlobNamespace.Commitment;
15
+
16
+ /**
17
+ * Compute KZG commitment for blob.
18
+ *
19
+ * Requires KZGService to be provided in the Effect context.
20
+ *
21
+ * @param blob - 128KB blob data
22
+ * @returns Effect yielding 48-byte commitment, requiring KZGService
23
+ * @example
24
+ * ```typescript
25
+ * import * as Blob from 'voltaire-effect/primitives/Blob'
26
+ * import { KZGLive } from 'voltaire-effect/crypto/KZG'
27
+ * import * as Effect from 'effect/Effect'
28
+ *
29
+ * const program = Blob.toCommitment(blob).pipe(Effect.provide(KZGLive))
30
+ * const commitment = await Effect.runPromise(program)
31
+ * ```
32
+ * @since 0.1.0
33
+ */
34
+ export const toCommitment = (
35
+ blob: BrandedBlob,
36
+ ): Effect.Effect<Commitment, KZGError, KZGService> =>
37
+ Effect.gen(function* () {
38
+ const kzg = yield* KZGService;
39
+ const commitment = yield* kzg.blobToKzgCommitment(
40
+ blob as unknown as import("@tevm/voltaire").KzgBlobType,
41
+ );
42
+ return commitment as unknown as Commitment;
43
+ });
@@ -0,0 +1,50 @@
1
+ /**
2
+ * @module toProof
3
+ * @description Generate KZG proof for blob using KZGService
4
+ * @since 0.1.0
5
+ */
6
+ import type { BrandedBlob as BlobNamespace } from "@tevm/voltaire";
7
+ import { Effect } from "effect";
8
+ import {
9
+ type KZGError,
10
+ KZGService,
11
+ } from "../../crypto/KZG/KZGService.js";
12
+
13
+ type BrandedBlob = BlobNamespace.BrandedBlob;
14
+ type Commitment = BlobNamespace.Commitment;
15
+ type Proof = BlobNamespace.Proof;
16
+
17
+ /**
18
+ * Generate KZG proof for blob and commitment.
19
+ *
20
+ * Requires KZGService to be provided in the Effect context.
21
+ *
22
+ * @param blob - 128KB blob data
23
+ * @param commitment - 48-byte KZG commitment
24
+ * @returns Effect yielding 48-byte proof, requiring KZGService
25
+ * @example
26
+ * ```typescript
27
+ * import * as Blob from 'voltaire-effect/primitives/Blob'
28
+ * import { KZGLive } from 'voltaire-effect/crypto/KZG'
29
+ * import * as Effect from 'effect/Effect'
30
+ *
31
+ * const program = Effect.gen(function* () {
32
+ * const commitment = yield* Blob.toCommitment(blob)
33
+ * const proof = yield* Blob.toProof(blob, commitment)
34
+ * return proof
35
+ * }).pipe(Effect.provide(KZGLive))
36
+ * ```
37
+ * @since 0.1.0
38
+ */
39
+ export const toProof = (
40
+ blob: BrandedBlob,
41
+ commitment: Commitment,
42
+ ): Effect.Effect<Proof, KZGError, KZGService> =>
43
+ Effect.gen(function* () {
44
+ const kzg = yield* KZGService;
45
+ const proof = yield* kzg.computeBlobKzgProof(
46
+ blob as unknown as import("@tevm/voltaire").KzgBlobType,
47
+ commitment as unknown as import("@tevm/voltaire").KzgCommitmentType,
48
+ );
49
+ return proof as unknown as Proof;
50
+ });
@@ -0,0 +1,35 @@
1
+ /**
2
+ * @module toVersionedHash
3
+ * @description Create versioned hash from commitment
4
+ * @since 0.1.0
5
+ */
6
+ import { BrandedBlob as BlobNamespace } from "@tevm/voltaire";
7
+ import type { InvalidCommitmentSizeError } from "@tevm/voltaire/Blob";
8
+ import { Effect } from "effect";
9
+
10
+ type Commitment = BlobNamespace.Commitment;
11
+ type VersionedHash = BlobNamespace.VersionedHash;
12
+
13
+ /**
14
+ * Create versioned hash from commitment.
15
+ *
16
+ * Formula: BLOB_COMMITMENT_VERSION_KZG (0x01) || sha256(commitment)[1:]
17
+ *
18
+ * @param commitment - 48-byte KZG commitment
19
+ * @returns Effect yielding 32-byte versioned hash or failing with InvalidCommitmentSizeError
20
+ * @example
21
+ * ```typescript
22
+ * import * as Blob from 'voltaire-effect/primitives/Blob'
23
+ * import * as Effect from 'effect/Effect'
24
+ *
25
+ * const hash = await Effect.runPromise(Blob.toVersionedHash(commitment))
26
+ * ```
27
+ * @since 0.1.0
28
+ */
29
+ export const toVersionedHash = (
30
+ commitment: Commitment,
31
+ ): Effect.Effect<VersionedHash, InvalidCommitmentSizeError> =>
32
+ Effect.try({
33
+ try: () => BlobNamespace.toVersionedHash(commitment),
34
+ catch: (e) => e as InvalidCommitmentSizeError,
35
+ });
@@ -0,0 +1,49 @@
1
+ /**
2
+ * @module verify
3
+ * @description Verify KZG proof for blob using KZGService
4
+ * @since 0.1.0
5
+ */
6
+ import type { BrandedBlob as BlobNamespace } from "@tevm/voltaire";
7
+ import { Effect } from "effect";
8
+ import {
9
+ type KZGError,
10
+ KZGService,
11
+ } from "../../crypto/KZG/KZGService.js";
12
+
13
+ type BrandedBlob = BlobNamespace.BrandedBlob;
14
+ type Commitment = BlobNamespace.Commitment;
15
+ type Proof = BlobNamespace.Proof;
16
+
17
+ /**
18
+ * Verify KZG proof for blob and commitment.
19
+ *
20
+ * Requires KZGService to be provided in the Effect context.
21
+ *
22
+ * @param blob - 128KB blob data
23
+ * @param commitment - 48-byte KZG commitment
24
+ * @param proof - 48-byte KZG proof
25
+ * @returns Effect yielding boolean (true if valid), requiring KZGService
26
+ * @example
27
+ * ```typescript
28
+ * import * as Blob from 'voltaire-effect/primitives/Blob'
29
+ * import { KZGLive } from 'voltaire-effect/crypto/KZG'
30
+ * import * as Effect from 'effect/Effect'
31
+ *
32
+ * const program = Blob.verify(blob, commitment, proof).pipe(Effect.provide(KZGLive))
33
+ * const isValid = await Effect.runPromise(program)
34
+ * ```
35
+ * @since 0.1.0
36
+ */
37
+ export const verify = (
38
+ blob: BrandedBlob,
39
+ commitment: Commitment,
40
+ proof: Proof,
41
+ ): Effect.Effect<boolean, KZGError, KZGService> =>
42
+ Effect.gen(function* () {
43
+ const kzg = yield* KZGService;
44
+ return yield* kzg.verifyBlobKzgProof(
45
+ blob as unknown as import("@tevm/voltaire").KzgBlobType,
46
+ commitment as unknown as import("@tevm/voltaire").KzgCommitmentType,
47
+ proof as unknown as import("@tevm/voltaire").KzgProofType,
48
+ );
49
+ });
@@ -0,0 +1,119 @@
1
+ /**
2
+ * @module verifyBatch
3
+ * @description Verify batch of KZG proofs for blobs
4
+ * @since 0.1.0
5
+ */
6
+ import type { BrandedBlob as BlobNamespace } from "@tevm/voltaire";
7
+ import {
8
+ BlobArrayLengthMismatchError,
9
+ BlobNotImplementedError,
10
+ InvalidBlobCountError,
11
+ InvalidBlobSizeError,
12
+ InvalidCommitmentSizeError,
13
+ InvalidProofSizeError,
14
+ MAX_PER_TRANSACTION,
15
+ SIZE,
16
+ } from "@tevm/voltaire/Blob";
17
+ import { Effect } from "effect";
18
+
19
+ type BrandedBlob = BlobNamespace.BrandedBlob;
20
+ type Commitment = BlobNamespace.Commitment;
21
+ type Proof = BlobNamespace.Proof;
22
+
23
+ type VerifyBatchError =
24
+ | BlobArrayLengthMismatchError
25
+ | InvalidBlobCountError
26
+ | InvalidBlobSizeError
27
+ | InvalidCommitmentSizeError
28
+ | InvalidProofSizeError
29
+ | BlobNotImplementedError;
30
+
31
+ /**
32
+ * Verify batch of KZG proofs for blobs.
33
+ *
34
+ * Note: Batch verification is not yet implemented. This function validates
35
+ * inputs and throws BlobNotImplementedError.
36
+ *
37
+ * @param blobs - Array of 128KB blobs
38
+ * @param commitments - Array of 48-byte commitments
39
+ * @param proofs - Array of 48-byte proofs
40
+ * @returns Effect failing with BlobNotImplementedError (not yet implemented)
41
+ * @throws {BlobArrayLengthMismatchError} If array lengths don't match
42
+ * @throws {InvalidBlobCountError} If too many blobs
43
+ * @throws {InvalidBlobSizeError} If blob size is invalid
44
+ * @throws {InvalidCommitmentSizeError} If commitment size is invalid
45
+ * @throws {InvalidProofSizeError} If proof size is invalid
46
+ * @throws {BlobNotImplementedError} Always (not yet implemented)
47
+ * @example
48
+ * ```typescript
49
+ * import * as Blob from 'voltaire-effect/primitives/Blob'
50
+ * import * as Effect from 'effect/Effect'
51
+ *
52
+ * const program = Blob.verifyBatch(blobs, commitments, proofs)
53
+ * // Will fail with BlobNotImplementedError
54
+ * ```
55
+ * @since 0.1.0
56
+ */
57
+ export const verifyBatch = (
58
+ blobs: readonly BrandedBlob[],
59
+ commitments: readonly Commitment[],
60
+ proofs: readonly Proof[],
61
+ ): Effect.Effect<boolean, VerifyBatchError> =>
62
+ Effect.try({
63
+ try: (): boolean => {
64
+ if (
65
+ blobs.length !== commitments.length ||
66
+ blobs.length !== proofs.length
67
+ ) {
68
+ throw new BlobArrayLengthMismatchError("Arrays must have same length", {
69
+ value: {
70
+ blobs: blobs.length,
71
+ commitments: commitments.length,
72
+ proofs: proofs.length,
73
+ },
74
+ expected: "equal array lengths",
75
+ });
76
+ }
77
+ if (blobs.length > MAX_PER_TRANSACTION) {
78
+ throw new InvalidBlobCountError("Too many blobs", {
79
+ value: blobs.length,
80
+ expected: `max ${MAX_PER_TRANSACTION} blobs`,
81
+ });
82
+ }
83
+ for (let i = 0; i < blobs.length; i++) {
84
+ const blob = blobs[i] as Uint8Array;
85
+ if (blob.length !== SIZE) {
86
+ throw new InvalidBlobSizeError("Invalid blob size", {
87
+ value: blob.length,
88
+ expected: `${SIZE} bytes`,
89
+ context: { index: i },
90
+ });
91
+ }
92
+ }
93
+ for (let i = 0; i < commitments.length; i++) {
94
+ const commitment = commitments[i] as unknown as Uint8Array;
95
+ if (commitment.length !== 48) {
96
+ throw new InvalidCommitmentSizeError("Invalid commitment size", {
97
+ value: commitment.length,
98
+ expected: "48 bytes",
99
+ context: { index: i },
100
+ });
101
+ }
102
+ }
103
+ for (let i = 0; i < proofs.length; i++) {
104
+ const proof = proofs[i] as unknown as Uint8Array;
105
+ if (proof.length !== 48) {
106
+ throw new InvalidProofSizeError("Invalid proof size", {
107
+ value: proof.length,
108
+ expected: "48 bytes",
109
+ context: { index: i },
110
+ });
111
+ }
112
+ }
113
+ throw new BlobNotImplementedError("Not implemented", {
114
+ value: "verifyBatch",
115
+ expected: "implementation",
116
+ });
117
+ },
118
+ catch: (e) => e as VerifyBatchError,
119
+ });
@@ -0,0 +1,138 @@
1
+ import { describe, expect, it } from "@effect/vitest";
2
+ import * as Effect from "effect/Effect";
3
+ import * as BloomFilter from "./index.js";
4
+
5
+ describe("BloomFilter.create", () => {
6
+ it("creates a filter with valid parameters", async () => {
7
+ const program = BloomFilter.create(2048, 3);
8
+ const filter = await Effect.runPromise(program);
9
+ expect(filter).toBeInstanceOf(Uint8Array);
10
+ expect(filter.length).toBe(256); // 2048 bits / 8
11
+ expect(filter.m).toBe(2048);
12
+ expect(filter.k).toBe(3);
13
+ });
14
+
15
+ it("fails on invalid parameters (m <= 0)", async () => {
16
+ const program = BloomFilter.create(0, 3);
17
+ const result = await Effect.runPromiseExit(program);
18
+ expect(result._tag).toBe("Failure");
19
+ });
20
+
21
+ it("fails on invalid parameters (k <= 0)", async () => {
22
+ const program = BloomFilter.create(2048, 0);
23
+ const result = await Effect.runPromiseExit(program);
24
+ expect(result._tag).toBe("Failure");
25
+ });
26
+ });
27
+
28
+ describe("BloomFilter.fromHex", () => {
29
+ it("creates filter from valid hex", async () => {
30
+ const hex = "0x" + "00".repeat(256);
31
+ const program = BloomFilter.fromHex(hex, 2048, 3);
32
+ const filter = await Effect.runPromise(program);
33
+ expect(filter.length).toBe(256);
34
+ expect(filter.m).toBe(2048);
35
+ expect(filter.k).toBe(3);
36
+ });
37
+
38
+ it("fails on wrong hex length", async () => {
39
+ const hex = "0x" + "00".repeat(128);
40
+ const program = BloomFilter.fromHex(hex, 2048, 3);
41
+ const result = await Effect.runPromiseExit(program);
42
+ expect(result._tag).toBe("Failure");
43
+ });
44
+ });
45
+
46
+ describe("BloomFilter pure functions", () => {
47
+ it("add and contains", async () => {
48
+ const filter = await Effect.runPromise(BloomFilter.create(2048, 3));
49
+ const item = new Uint8Array([1, 2, 3, 4, 5]);
50
+
51
+ expect(BloomFilter.contains(filter, item)).toBe(false);
52
+ BloomFilter.add(filter, item);
53
+ expect(BloomFilter.contains(filter, item)).toBe(true);
54
+ });
55
+
56
+ it("isEmpty", async () => {
57
+ const filter = await Effect.runPromise(BloomFilter.create(2048, 3));
58
+ expect(BloomFilter.isEmpty(filter)).toBe(true);
59
+
60
+ BloomFilter.add(filter, new Uint8Array([1, 2, 3]));
61
+ expect(BloomFilter.isEmpty(filter)).toBe(false);
62
+ });
63
+
64
+ it("density", async () => {
65
+ const filter = await Effect.runPromise(BloomFilter.create(2048, 3));
66
+ expect(BloomFilter.density(filter)).toBe(0);
67
+
68
+ BloomFilter.add(filter, new Uint8Array([1, 2, 3]));
69
+ expect(BloomFilter.density(filter)).toBeGreaterThan(0);
70
+ });
71
+
72
+ it("toHex", async () => {
73
+ const filter = await Effect.runPromise(BloomFilter.create(2048, 3));
74
+ const hex = BloomFilter.toHex(filter);
75
+ expect(hex).toMatch(/^0x[0-9a-f]+$/i);
76
+ expect(hex.length).toBe(514); // 0x + 512 hex chars
77
+ });
78
+
79
+ it("merge", async () => {
80
+ const filter1 = await Effect.runPromise(BloomFilter.create(2048, 3));
81
+ const filter2 = await Effect.runPromise(BloomFilter.create(2048, 3));
82
+
83
+ BloomFilter.add(filter1, new Uint8Array([1, 2, 3]));
84
+ BloomFilter.add(filter2, new Uint8Array([4, 5, 6]));
85
+
86
+ const merged = BloomFilter.merge(filter1, filter2);
87
+ expect(BloomFilter.contains(merged, new Uint8Array([1, 2, 3]))).toBe(true);
88
+ expect(BloomFilter.contains(merged, new Uint8Array([4, 5, 6]))).toBe(true);
89
+ });
90
+
91
+ it("combine", async () => {
92
+ const filter1 = await Effect.runPromise(BloomFilter.create(2048, 3));
93
+ const filter2 = await Effect.runPromise(BloomFilter.create(2048, 3));
94
+ const filter3 = await Effect.runPromise(BloomFilter.create(2048, 3));
95
+
96
+ BloomFilter.add(filter1, new Uint8Array([1]));
97
+ BloomFilter.add(filter2, new Uint8Array([2]));
98
+ BloomFilter.add(filter3, new Uint8Array([3]));
99
+
100
+ const combined = BloomFilter.combine(filter1, filter2, filter3);
101
+ expect(BloomFilter.contains(combined, new Uint8Array([1]))).toBe(true);
102
+ expect(BloomFilter.contains(combined, new Uint8Array([2]))).toBe(true);
103
+ expect(BloomFilter.contains(combined, new Uint8Array([3]))).toBe(true);
104
+ });
105
+
106
+ it("hash", () => {
107
+ const item = new Uint8Array([1, 2, 3, 4, 5]);
108
+ const h = BloomFilter.hash(item, 0, 2048);
109
+ expect(h).toBeGreaterThanOrEqual(0);
110
+ expect(h).toBeLessThan(2048);
111
+ });
112
+
113
+ it("hashFromKeccak", () => {
114
+ const keccakHash = new Uint8Array(32).fill(0xff);
115
+ const h = BloomFilter.hashFromKeccak(keccakHash, 0, 2048);
116
+ expect(h).toBeGreaterThanOrEqual(0);
117
+ expect(h).toBeLessThan(2048);
118
+ });
119
+
120
+ it("expectedFalsePositiveRate", async () => {
121
+ const filter = await Effect.runPromise(BloomFilter.create(2048, 3));
122
+ const rate = BloomFilter.expectedFalsePositiveRate(filter, 100);
123
+ expect(rate).toBeGreaterThanOrEqual(0);
124
+ expect(rate).toBeLessThanOrEqual(1);
125
+ });
126
+ });
127
+
128
+ describe("BloomFilter round-trip", () => {
129
+ it("fromHex(toHex(filter)) preserves data", async () => {
130
+ const filter = await Effect.runPromise(BloomFilter.create(2048, 3));
131
+ BloomFilter.add(filter, new Uint8Array([1, 2, 3]));
132
+
133
+ const hex = BloomFilter.toHex(filter);
134
+ const restored = await Effect.runPromise(BloomFilter.fromHex(hex, 2048, 3));
135
+
136
+ expect(BloomFilter.contains(restored, new Uint8Array([1, 2, 3]))).toBe(true);
137
+ });
138
+ });
@@ -0,0 +1,23 @@
1
+ /**
2
+ * @module add
3
+ * @description Add item to BloomFilter (pure, in-place mutation)
4
+ * @since 0.1.0
5
+ */
6
+ import { BloomFilter, type BloomFilterType } from "@tevm/voltaire/BloomFilter";
7
+
8
+ /**
9
+ * Add an item to a BloomFilter (mutates in place)
10
+ *
11
+ * @param filter - The bloom filter
12
+ * @param item - Item to add (Uint8Array)
13
+ * @example
14
+ * ```typescript
15
+ * import * as BloomFilter from 'voltaire-effect/primitives/BloomFilter'
16
+ * import * as Effect from 'effect/Effect'
17
+ *
18
+ * const filter = await Effect.runPromise(BloomFilter.create(2048, 3))
19
+ * BloomFilter.add(filter, new Uint8Array([1, 2, 3]))
20
+ * ```
21
+ */
22
+ export const add = (filter: BloomFilterType, item: Uint8Array): void =>
23
+ BloomFilter.add(filter, item);
@@ -0,0 +1,21 @@
1
+ /**
2
+ * @module combine
3
+ * @description Combine multiple BloomFilters into one (pure)
4
+ * @since 0.1.0
5
+ */
6
+ import { BloomFilter, type BloomFilterType } from "@tevm/voltaire/BloomFilter";
7
+
8
+ /**
9
+ * Combine multiple BloomFilters into a single filter
10
+ *
11
+ * @param filters - Filters to combine
12
+ * @returns Combined bloom filter
13
+ * @example
14
+ * ```typescript
15
+ * import * as BloomFilter from 'voltaire-effect/primitives/BloomFilter'
16
+ *
17
+ * const combined = BloomFilter.combine(filter1, filter2, filter3)
18
+ * ```
19
+ */
20
+ export const combine = (...filters: BloomFilterType[]): BloomFilterType =>
21
+ BloomFilter.combine(...filters);
@@ -0,0 +1,26 @@
1
+ /**
2
+ * @module contains
3
+ * @description Check if BloomFilter may contain an item (pure predicate)
4
+ * @since 0.1.0
5
+ */
6
+ import { BloomFilter, type BloomFilterType } from "@tevm/voltaire/BloomFilter";
7
+
8
+ /**
9
+ * Check if a BloomFilter might contain an item
10
+ *
11
+ * False positives are possible, false negatives are not.
12
+ *
13
+ * @param filter - The bloom filter
14
+ * @param item - Item to check
15
+ * @returns true if item might be in filter, false if definitely not
16
+ * @example
17
+ * ```typescript
18
+ * import * as BloomFilter from 'voltaire-effect/primitives/BloomFilter'
19
+ *
20
+ * if (BloomFilter.contains(filter, item)) {
21
+ * console.log('Item might be in filter')
22
+ * }
23
+ * ```
24
+ */
25
+ export const contains = (filter: BloomFilterType, item: Uint8Array): boolean =>
26
+ BloomFilter.contains(filter, item);
@@ -0,0 +1,35 @@
1
+ /**
2
+ * @module create
3
+ * @description Create BloomFilter with Effect error handling
4
+ * @since 0.1.0
5
+ */
6
+ import { Effect } from "effect";
7
+ import {
8
+ BloomFilter,
9
+ type BloomFilterType,
10
+ InvalidBloomFilterParameterError,
11
+ } from "@tevm/voltaire/BloomFilter";
12
+
13
+ /**
14
+ * Create a new BloomFilter with specified parameters
15
+ *
16
+ * @param m - Number of bits in the filter
17
+ * @param k - Number of hash functions
18
+ * @returns Effect yielding BloomFilterType or failing with InvalidBloomFilterParameterError
19
+ * @example
20
+ * ```typescript
21
+ * import * as BloomFilter from 'voltaire-effect/primitives/BloomFilter'
22
+ * import * as Effect from 'effect/Effect'
23
+ *
24
+ * const program = BloomFilter.create(2048, 3)
25
+ * const filter = await Effect.runPromise(program)
26
+ * ```
27
+ */
28
+ export const create = (
29
+ m: number,
30
+ k: number,
31
+ ): Effect.Effect<BloomFilterType, InvalidBloomFilterParameterError> =>
32
+ Effect.try({
33
+ try: () => BloomFilter.create(m, k),
34
+ catch: (e) => e as InvalidBloomFilterParameterError,
35
+ });
@@ -0,0 +1,22 @@
1
+ /**
2
+ * @module density
3
+ * @description Calculate BloomFilter bit density (pure)
4
+ * @since 0.1.0
5
+ */
6
+ import { BloomFilter, type BloomFilterType } from "@tevm/voltaire/BloomFilter";
7
+
8
+ /**
9
+ * Calculate the density (fill ratio) of a BloomFilter
10
+ *
11
+ * @param filter - The bloom filter
12
+ * @returns Density as a number between 0 and 1
13
+ * @example
14
+ * ```typescript
15
+ * import * as BloomFilter from 'voltaire-effect/primitives/BloomFilter'
16
+ *
17
+ * const d = BloomFilter.density(filter)
18
+ * console.log(d) // e.g. 0.15
19
+ * ```
20
+ */
21
+ export const density = (filter: BloomFilterType): number =>
22
+ BloomFilter.density(filter);
@@ -0,0 +1,25 @@
1
+ /**
2
+ * @module expectedFalsePositiveRate
3
+ * @description Calculate expected false positive rate (pure)
4
+ * @since 0.1.0
5
+ */
6
+ import { BloomFilter, type BloomFilterType } from "@tevm/voltaire/BloomFilter";
7
+
8
+ /**
9
+ * Calculate the expected false positive rate for a given item count
10
+ *
11
+ * @param filter - The bloom filter
12
+ * @param itemCount - Number of items in the filter
13
+ * @returns Expected false positive rate (0 to 1)
14
+ * @example
15
+ * ```typescript
16
+ * import * as BloomFilter from 'voltaire-effect/primitives/BloomFilter'
17
+ *
18
+ * const rate = BloomFilter.expectedFalsePositiveRate(filter, 100)
19
+ * console.log(rate) // e.g. 0.001
20
+ * ```
21
+ */
22
+ export const expectedFalsePositiveRate = (
23
+ filter: BloomFilterType,
24
+ itemCount: number,
25
+ ): number => BloomFilter.expectedFalsePositiveRate(filter, itemCount);
@@ -0,0 +1,37 @@
1
+ /**
2
+ * @module fromHex
3
+ * @description Create BloomFilter from hex string with Effect error handling
4
+ * @since 0.1.0
5
+ */
6
+ import { Effect } from "effect";
7
+ import {
8
+ BloomFilter,
9
+ type BloomFilterType,
10
+ InvalidBloomFilterLengthError,
11
+ } from "@tevm/voltaire/BloomFilter";
12
+
13
+ /**
14
+ * Create BloomFilter from hex string
15
+ *
16
+ * @param hex - Hex string (with or without 0x prefix)
17
+ * @param m - Number of bits
18
+ * @param k - Number of hash functions
19
+ * @returns Effect yielding BloomFilterType or failing with InvalidBloomFilterLengthError
20
+ * @example
21
+ * ```typescript
22
+ * import * as BloomFilter from 'voltaire-effect/primitives/BloomFilter'
23
+ * import * as Effect from 'effect/Effect'
24
+ *
25
+ * const program = BloomFilter.fromHex('0x00...', 2048, 3)
26
+ * const filter = await Effect.runPromise(program)
27
+ * ```
28
+ */
29
+ export const fromHex = (
30
+ hex: string,
31
+ m: number,
32
+ k: number,
33
+ ): Effect.Effect<BloomFilterType, InvalidBloomFilterLengthError> =>
34
+ Effect.try({
35
+ try: () => BloomFilter.fromHex(hex, m, k),
36
+ catch: (e) => e as InvalidBloomFilterLengthError,
37
+ });