ox 1.0.4 → 1.1.0

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 (230) hide show
  1. package/CHANGELOG.md +62 -0
  2. package/dist/core/Base64.d.ts +10 -21
  3. package/dist/core/Base64.d.ts.map +1 -1
  4. package/dist/core/Base64.js +8 -127
  5. package/dist/core/Base64.js.map +1 -1
  6. package/dist/core/BinaryStateTree.d.ts.map +1 -1
  7. package/dist/core/BinaryStateTree.js +2 -2
  8. package/dist/core/BinaryStateTree.js.map +1 -1
  9. package/dist/core/Bls.d.ts.map +1 -1
  10. package/dist/core/Bls.js +19 -44
  11. package/dist/core/Bls.js.map +1 -1
  12. package/dist/core/Ed25519.d.ts.map +1 -1
  13. package/dist/core/Ed25519.js +7 -6
  14. package/dist/core/Ed25519.js.map +1 -1
  15. package/dist/core/Engine.d.ts +124 -0
  16. package/dist/core/Engine.d.ts.map +1 -0
  17. package/dist/core/Engine.js +180 -0
  18. package/dist/core/Engine.js.map +1 -0
  19. package/dist/core/Hash.d.ts +4 -4
  20. package/dist/core/Hash.d.ts.map +1 -1
  21. package/dist/core/Hash.js +9 -12
  22. package/dist/core/Hash.js.map +1 -1
  23. package/dist/core/Keystore.d.ts.map +1 -1
  24. package/dist/core/Keystore.js +15 -10
  25. package/dist/core/Keystore.js.map +1 -1
  26. package/dist/core/Mnemonic.d.ts.map +1 -1
  27. package/dist/core/Mnemonic.js +3 -2
  28. package/dist/core/Mnemonic.js.map +1 -1
  29. package/dist/core/P256.d.ts.map +1 -1
  30. package/dist/core/P256.js +8 -9
  31. package/dist/core/P256.js.map +1 -1
  32. package/dist/core/Secp256k1.d.ts.map +1 -1
  33. package/dist/core/Secp256k1.js +8 -9
  34. package/dist/core/Secp256k1.js.map +1 -1
  35. package/dist/core/WebCryptoP256.d.ts.map +1 -1
  36. package/dist/core/WebCryptoP256.js +2 -2
  37. package/dist/core/WebCryptoP256.js.map +1 -1
  38. package/dist/core/X25519.d.ts.map +1 -1
  39. package/dist/core/X25519.js +4 -3
  40. package/dist/core/X25519.js.map +1 -1
  41. package/dist/core/internal/bls.d.ts +12 -0
  42. package/dist/core/internal/bls.d.ts.map +1 -0
  43. package/dist/core/internal/bls.js +79 -0
  44. package/dist/core/internal/bls.js.map +1 -0
  45. package/dist/core/internal/codec/base64.d.ts +84 -0
  46. package/dist/core/internal/codec/base64.d.ts.map +1 -0
  47. package/dist/core/internal/codec/base64.js +177 -0
  48. package/dist/core/internal/codec/base64.js.map +1 -0
  49. package/dist/core/internal/codec/hex.d.ts +49 -4
  50. package/dist/core/internal/codec/hex.d.ts.map +1 -1
  51. package/dist/core/internal/codec/hex.js +109 -35
  52. package/dist/core/internal/codec/hex.js.map +1 -1
  53. package/dist/core/internal/curves.d.ts +17 -0
  54. package/dist/core/internal/curves.d.ts.map +1 -0
  55. package/dist/core/internal/curves.js +17 -0
  56. package/dist/core/internal/curves.js.map +1 -0
  57. package/dist/core/internal/ed25519.d.ts +14 -0
  58. package/dist/core/internal/ed25519.d.ts.map +1 -0
  59. package/dist/core/internal/ed25519.js +29 -0
  60. package/dist/core/internal/ed25519.js.map +1 -0
  61. package/dist/core/internal/engine.d.ts +278 -0
  62. package/dist/core/internal/engine.d.ts.map +1 -0
  63. package/dist/core/internal/engine.js +131 -0
  64. package/dist/core/internal/engine.js.map +1 -0
  65. package/dist/core/internal/hash.d.ts +12 -0
  66. package/dist/core/internal/hash.d.ts.map +1 -0
  67. package/dist/core/internal/hash.js +30 -0
  68. package/dist/core/internal/hash.js.map +1 -0
  69. package/dist/core/internal/keystore.d.ts +14 -0
  70. package/dist/core/internal/keystore.d.ts.map +1 -0
  71. package/dist/core/internal/keystore.js +32 -0
  72. package/dist/core/internal/keystore.js.map +1 -0
  73. package/dist/core/internal/mnemonic.d.ts +4 -0
  74. package/dist/core/internal/mnemonic.d.ts.map +1 -0
  75. package/dist/core/internal/mnemonic.js +14 -0
  76. package/dist/core/internal/mnemonic.js.map +1 -0
  77. package/dist/core/internal/p256.d.ts +14 -0
  78. package/dist/core/internal/p256.d.ts.map +1 -0
  79. package/dist/core/internal/p256.js +36 -0
  80. package/dist/core/internal/p256.js.map +1 -0
  81. package/dist/core/internal/secp256k1.d.ts +14 -0
  82. package/dist/core/internal/secp256k1.d.ts.map +1 -0
  83. package/dist/core/internal/secp256k1.js +36 -0
  84. package/dist/core/internal/secp256k1.js.map +1 -0
  85. package/dist/core/internal/x25519.d.ts +8 -0
  86. package/dist/core/internal/x25519.d.ts.map +1 -0
  87. package/dist/core/internal/x25519.js +20 -0
  88. package/dist/core/internal/x25519.js.map +1 -0
  89. package/dist/index.d.ts +35 -0
  90. package/dist/index.d.ts.map +1 -1
  91. package/dist/index.docs.d.ts +2 -0
  92. package/dist/index.docs.d.ts.map +1 -1
  93. package/dist/index.docs.js +2 -0
  94. package/dist/index.docs.js.map +1 -1
  95. package/dist/index.js +35 -0
  96. package/dist/index.js.map +1 -1
  97. package/dist/node/Engine.d.ts +55 -0
  98. package/dist/node/Engine.d.ts.map +1 -0
  99. package/dist/node/Engine.js +51 -0
  100. package/dist/node/Engine.js.map +1 -0
  101. package/dist/node/Hash.d.ts +39 -0
  102. package/dist/node/Hash.d.ts.map +1 -0
  103. package/dist/node/Hash.js +37 -0
  104. package/dist/node/Hash.js.map +1 -0
  105. package/dist/node/index.d.ts +39 -0
  106. package/dist/node/index.d.ts.map +1 -0
  107. package/dist/node/index.js +39 -0
  108. package/dist/node/index.js.map +1 -0
  109. package/dist/tempo/VirtualMaster.d.ts +2 -0
  110. package/dist/tempo/VirtualMaster.d.ts.map +1 -1
  111. package/dist/tempo/VirtualMaster.js +19 -5
  112. package/dist/tempo/VirtualMaster.js.map +1 -1
  113. package/dist/tempo/ZoneId.d.ts +35 -17
  114. package/dist/tempo/ZoneId.d.ts.map +1 -1
  115. package/dist/tempo/ZoneId.js +41 -16
  116. package/dist/tempo/ZoneId.js.map +1 -1
  117. package/dist/tempo/index.d.ts +5 -6
  118. package/dist/tempo/index.d.ts.map +1 -1
  119. package/dist/tempo/index.js +5 -6
  120. package/dist/tempo/index.js.map +1 -1
  121. package/dist/tempo/internal/mine.wasm.d.ts +2 -4
  122. package/dist/tempo/internal/mine.wasm.d.ts.map +1 -1
  123. package/dist/tempo/internal/mine.wasm.js +7 -12
  124. package/dist/tempo/internal/mine.wasm.js.map +1 -1
  125. package/dist/tempo/internal/virtualMasterPool.js +4 -1
  126. package/dist/tempo/internal/virtualMasterPool.js.map +1 -1
  127. package/dist/wasm/Engine.d.ts +62 -0
  128. package/dist/wasm/Engine.d.ts.map +1 -0
  129. package/dist/wasm/Engine.js +57 -0
  130. package/dist/wasm/Engine.js.map +1 -0
  131. package/dist/wasm/Hash.d.ts +49 -0
  132. package/dist/wasm/Hash.d.ts.map +1 -0
  133. package/dist/wasm/Hash.js +70 -0
  134. package/dist/wasm/Hash.js.map +1 -0
  135. package/dist/wasm/index.d.ts +46 -0
  136. package/dist/wasm/index.d.ts.map +1 -0
  137. package/dist/wasm/index.js +46 -0
  138. package/dist/wasm/index.js.map +1 -0
  139. package/dist/wasm/internal/hash.d.ts +9 -0
  140. package/dist/wasm/internal/hash.d.ts.map +1 -0
  141. package/dist/wasm/internal/hash.js +26 -0
  142. package/dist/wasm/internal/hash.js.map +1 -0
  143. package/dist/wasm/internal/hashes.wasm.d.ts +5 -0
  144. package/dist/wasm/internal/hashes.wasm.d.ts.map +1 -0
  145. package/dist/wasm/internal/hashes.wasm.js +12 -0
  146. package/dist/wasm/internal/hashes.wasm.js.map +1 -0
  147. package/dist/wasm/internal/instantiate.d.ts +56 -0
  148. package/dist/wasm/internal/instantiate.d.ts.map +1 -0
  149. package/dist/wasm/internal/instantiate.js +92 -0
  150. package/dist/wasm/internal/instantiate.js.map +1 -0
  151. package/dist/zod/TypedData.d.ts +12 -12
  152. package/package.json +36 -1
  153. package/src/core/Base64.ts +19 -166
  154. package/src/core/BinaryStateTree.ts +2 -3
  155. package/src/core/Bls.ts +27 -77
  156. package/src/core/Ed25519.ts +7 -7
  157. package/src/core/Engine.ts +235 -0
  158. package/src/core/Hash.ts +9 -12
  159. package/src/core/Keystore.ts +17 -17
  160. package/src/core/Mnemonic.ts +3 -6
  161. package/src/core/P256.ts +15 -24
  162. package/src/core/Rlp_tx.bench.ts +2 -4
  163. package/src/core/Secp256k1.ts +9 -14
  164. package/src/core/TxEnvelopeEip1559.bench.ts +0 -5
  165. package/src/core/WebCryptoP256.ts +2 -2
  166. package/src/core/X25519.ts +4 -3
  167. package/src/core/_test/AbiParameters.adversarial.fuzz.ts +1 -2
  168. package/src/core/_test/AbiParameters.fuzz.ts +1 -2
  169. package/src/core/_test/Base.fuzz.ts +1 -2
  170. package/src/core/_test/Cbor.fuzz.ts +1 -2
  171. package/src/core/_test/Engine.fuzz.ts +293 -0
  172. package/src/core/_test/Engine.test-d.ts +84 -0
  173. package/src/core/_test/Engine.test.ts +523 -0
  174. package/src/core/_test/Hash.vectors.test.ts +56 -0
  175. package/src/core/_test/Hex.fuzz.ts +1 -2
  176. package/src/core/_test/Rlp.fuzz.ts +1 -2
  177. package/src/core/_test/Signature.fuzz.ts +1 -2
  178. package/src/core/_test/curves.test.ts +7 -0
  179. package/src/core/_test/index.test.ts +1 -0
  180. package/src/core/internal/bls.ts +121 -0
  181. package/src/core/internal/codec/_test/base64.conformance.ts +156 -0
  182. package/src/core/internal/codec/_test/hex.conformance.ts +204 -0
  183. package/src/core/internal/codec/_test/hex.fuzz.ts +234 -0
  184. package/src/core/internal/codec/_test/hex.test.ts +124 -0
  185. package/src/core/internal/codec/base64.ts +222 -0
  186. package/src/core/internal/codec/hex.ts +115 -34
  187. package/src/core/internal/curves.ts +18 -0
  188. package/src/core/internal/ed25519.ts +64 -0
  189. package/src/core/internal/engine.ts +410 -0
  190. package/src/core/internal/hash.ts +48 -0
  191. package/src/core/internal/keystore.ts +107 -0
  192. package/src/core/internal/mnemonic.ts +18 -0
  193. package/src/core/internal/p256.ts +91 -0
  194. package/src/core/internal/secp256k1.ts +91 -0
  195. package/src/core/internal/x25519.ts +40 -0
  196. package/src/index.docs.ts +2 -0
  197. package/src/index.ts +36 -0
  198. package/src/node/Engine.ts +69 -0
  199. package/src/node/Hash.ts +56 -0
  200. package/src/node/_test/Engine.test.ts +62 -0
  201. package/src/node/_test/Hash.test-d.ts +26 -0
  202. package/src/node/_test/Hash.test.ts +102 -0
  203. package/src/node/index.ts +40 -0
  204. package/src/tempo/VirtualMaster.test.ts +75 -0
  205. package/src/tempo/VirtualMaster.ts +28 -6
  206. package/src/tempo/ZoneId.test-d.ts +16 -0
  207. package/src/tempo/ZoneId.test.ts +48 -13
  208. package/src/tempo/ZoneId.ts +55 -19
  209. package/src/tempo/index.ts +5 -6
  210. package/src/tempo/internal/mine.wasm.ts +7 -13
  211. package/src/tempo/internal/virtualMasterPool.ts +4 -1
  212. package/src/tsconfig.json +2 -1
  213. package/src/version.ts +1 -1
  214. package/src/wasm/Engine.ts +76 -0
  215. package/src/wasm/Hash.bench.ts +60 -0
  216. package/src/wasm/Hash.ts +109 -0
  217. package/src/wasm/_test/Engine.test.ts +62 -0
  218. package/src/wasm/_test/Hash.browser.test.ts +50 -0
  219. package/src/wasm/_test/Hash.fuzz.ts +188 -0
  220. package/src/wasm/_test/Hash.test-d.ts +28 -0
  221. package/src/wasm/_test/Hash.test.ts +211 -0
  222. package/src/wasm/_test/Hash.vectors.test.ts +117 -0
  223. package/src/wasm/_test/Runtime.test.ts +21 -0
  224. package/src/wasm/_test/runtime.wasm.ts +11 -0
  225. package/src/wasm/index.ts +47 -0
  226. package/src/wasm/internal/hash.ts +50 -0
  227. package/src/wasm/internal/hashes.wasm.ts +14 -0
  228. package/src/wasm/internal/instantiate.ts +135 -0
  229. package/src/zod/tempo/_test/ZoneId.test.ts +2 -2
  230. package/src/tempo/internal/mine.c +0 -182
@@ -0,0 +1,102 @@
1
+ import { Hash as CoreHash, Hex } from 'ox'
2
+ import { Hash } from 'ox/node'
3
+ import { describe, expect, test } from 'vp/test'
4
+
5
+ describe('create', () => {
6
+ test('behavior: exposes the supported primitives', async () => {
7
+ const engine = await Hash.create()
8
+
9
+ expect(Object.keys(engine.Hash).sort()).toMatchInlineSnapshot(`
10
+ [
11
+ "hmacSha256",
12
+ "ripemd160",
13
+ "sha256",
14
+ ]
15
+ `)
16
+ })
17
+
18
+ test('behavior: matches published empty-input vectors', async () => {
19
+ const { hmacSha256, ripemd160, sha256 } = (await Hash.create()).Hash
20
+ const empty = new Uint8Array()
21
+
22
+ expect(Hex.fromBytes(sha256(empty))).toMatchInlineSnapshot(
23
+ `"0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"`,
24
+ )
25
+ expect(Hex.fromBytes(ripemd160(empty))).toMatchInlineSnapshot(
26
+ `"0x9c1185a5c5e9fc54612808977ee8f548b2258d31"`,
27
+ )
28
+ expect(Hex.fromBytes(hmacSha256(empty, empty))).toMatchInlineSnapshot(
29
+ `"0xb613679a0814d9ec772f95d778c35fc5ff1697c493715653c6c712144292c5ad"`,
30
+ )
31
+ })
32
+
33
+ test('behavior: agrees with the default across block boundaries', async () => {
34
+ const node = (await Hash.create()).Hash
35
+
36
+ for (const size of [0, 1, 55, 56, 63, 64, 65, 127, 128, 129]) {
37
+ const input = Uint8Array.from({ length: size }, (_, index) => index % 251)
38
+ expect(node.sha256(input)).toEqual(
39
+ CoreHash.sha256(input, { as: 'Bytes' }),
40
+ )
41
+ expect(node.ripemd160(input)).toEqual(
42
+ CoreHash.ripemd160(input, { as: 'Bytes' }),
43
+ )
44
+ }
45
+ })
46
+
47
+ test('behavior: agrees with the default across HMAC key sizes', async () => {
48
+ const { hmacSha256 } = (await Hash.create()).Hash
49
+ const message = Uint8Array.from({ length: 65 }, (_, index) => index % 251)
50
+
51
+ for (const size of [0, 1, 32, 63, 64, 65, 200]) {
52
+ const key = Uint8Array.from({ length: size }, (_, index) => index % 239)
53
+ expect(hmacSha256(key, message)).toEqual(
54
+ CoreHash.hmac256(key, message, { as: 'Bytes' }),
55
+ )
56
+ }
57
+ })
58
+
59
+ test('behavior: respects typed-array offsets', async () => {
60
+ const node = (await Hash.create()).Hash
61
+ const input = Uint8Array.from(
62
+ { length: 80 },
63
+ (_, index) => (index * 17) % 251,
64
+ ).subarray(7, 71)
65
+ const key = Uint8Array.from(
66
+ { length: 48 },
67
+ (_, index) => (index * 29) % 239,
68
+ ).subarray(5, 37)
69
+
70
+ expect(node.sha256(input)).toEqual(CoreHash.sha256(input, { as: 'Bytes' }))
71
+ expect(node.ripemd160(input)).toEqual(
72
+ CoreHash.ripemd160(input, { as: 'Bytes' }),
73
+ )
74
+ expect(node.hmacSha256(key, input)).toEqual(
75
+ CoreHash.hmac256(key, input, { as: 'Bytes' }),
76
+ )
77
+ })
78
+
79
+ test('behavior: returns a fresh engine', async () => {
80
+ const first = await Hash.create()
81
+ const second = await Hash.create()
82
+
83
+ expect(first === second).toMatchInlineSnapshot('false')
84
+ expect(first.Hash === second.Hash).toMatchInlineSnapshot('false')
85
+ })
86
+
87
+ test('behavior: returns owned Uint8Array values', async () => {
88
+ const { hmacSha256, ripemd160, sha256 } = (await Hash.create()).Hash
89
+ const input = Uint8Array.of(1, 2, 3)
90
+ const outputs = [hmacSha256(input, input), ripemd160(input), sha256(input)]
91
+
92
+ expect(outputs.map((output) => output.constructor === Uint8Array))
93
+ .toMatchInlineSnapshot(`
94
+ [
95
+ true,
96
+ true,
97
+ true,
98
+ ]
99
+ `)
100
+ expect(sha256(input) === sha256(input)).toMatchInlineSnapshot('false')
101
+ })
102
+ })
@@ -0,0 +1,40 @@
1
+ /** @entrypointCategory Node */
2
+
3
+ /**
4
+ * Node.js implementations of Ox's hash primitives, backed by `node:crypto`.
5
+ *
6
+ * Import this entrypoint only in Node.js. Its static `node:crypto` dependency
7
+ * is intentionally kept outside Ox's runtime-neutral entrypoint.
8
+ *
9
+ * @example
10
+ * ```ts twoslash
11
+ * // @noErrors
12
+ * import { Hash } from 'ox'
13
+ * import { Engine } from 'ox/node'
14
+ *
15
+ * await Engine.load()
16
+ *
17
+ * Hash.sha256('0xdeadbeef')
18
+ * ```
19
+ *
20
+ * @category Crypto
21
+ */
22
+ export * as Engine from './Engine.js'
23
+
24
+ /**
25
+ * Node.js implementations of Ox's supported hash primitives.
26
+ *
27
+ * @example
28
+ * ```ts twoslash
29
+ * // @noErrors
30
+ * import { Engine, Hash } from 'ox'
31
+ * import * as NodeHash from 'ox/node/Hash'
32
+ *
33
+ * Engine.set(await NodeHash.create())
34
+ *
35
+ * Hash.sha256('0xdeadbeef')
36
+ * ```
37
+ *
38
+ * @category Crypto
39
+ */
40
+ export * as Hash from './Hash.js'
@@ -1,5 +1,8 @@
1
+ import { Bytes } from 'ox'
1
2
  import { VirtualMaster } from 'ox/tempo'
2
3
  import { describe, expect, test } from 'vp/test'
4
+ import { instantiate } from '../wasm/internal/instantiate.js'
5
+ import { wasmBase64 } from './internal/mine.wasm.js'
3
6
 
4
7
  const address = '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266'
5
8
  const salt =
@@ -123,6 +126,32 @@ describe('mineSaltAsync', () => {
123
126
  `)
124
127
  })
125
128
 
129
+ // `workerCount` is `min(workers, ceil(count / chunkSize))`, so the cases
130
+ // above collapse to one worker and take the JavaScript fallback. Only a
131
+ // chunk size small enough to need two workers reaches the WASM, which is how
132
+ // a miner writing over its own Keccak constants went unnoticed.
133
+ test('agrees with the fallback once the WASM actually runs', async () => {
134
+ const viaFallback = await VirtualMaster.mineSaltAsync({
135
+ address,
136
+ count: 16,
137
+ start: 0xabf52ba0n,
138
+ workers: 1,
139
+ })
140
+
141
+ const viaWasm = await VirtualMaster.mineSaltAsync({
142
+ address,
143
+ chunkSize: 8,
144
+ count: 16,
145
+ start: 0xabf52ba0n,
146
+ workers: 2,
147
+ })
148
+
149
+ expect(viaWasm).toEqual(viaFallback)
150
+ expect(viaWasm?.salt).toMatchInlineSnapshot(
151
+ `"0x00000000000000000000000000000000000000000000000000000000abf52baf"`,
152
+ )
153
+ })
154
+
126
155
  test('finds the same salt with workers', async () => {
127
156
  const result = await VirtualMaster.mineSaltAsync({
128
157
  address,
@@ -150,6 +179,52 @@ describe('mineSaltAsync', () => {
150
179
  expect(result).toBeUndefined()
151
180
  })
152
181
 
182
+ test.each([
183
+ 0,
184
+ -1,
185
+ 1.5,
186
+ Number.NaN,
187
+ Number.POSITIVE_INFINITY,
188
+ 2 ** 32,
189
+ Number.MAX_SAFE_INTEGER + 1,
190
+ ])('rejects chunk size %s outside the uint32 ABI', async (chunkSize) => {
191
+ await expect(
192
+ VirtualMaster.mineSaltAsync({
193
+ address,
194
+ chunkSize,
195
+ count: 1,
196
+ workers: 1,
197
+ }),
198
+ ).rejects.toThrow(
199
+ `Chunk size "${chunkSize}" is invalid. Expected a positive safe integer no greater than 4294967295.`,
200
+ )
201
+ })
202
+
203
+ test('accepts the maximum uint32 chunk size', async () => {
204
+ await expect(
205
+ VirtualMaster.mineSaltAsync({
206
+ address,
207
+ chunkSize: 2 ** 32 - 1,
208
+ count: 1,
209
+ start: 0n,
210
+ workers: 1,
211
+ }),
212
+ ).resolves.toBeUndefined()
213
+ })
214
+
215
+ test('treats the raw WASM count as unsigned', async () => {
216
+ type Exports = { mine(count: number): number }
217
+ const module = await instantiate<Exports>(wasmBase64)
218
+ module.reserve(84)
219
+ module.view().set(Bytes.fromHex(address), module.heapBase)
220
+ module.view().set(Bytes.fromHex(salt), module.heapBase + 20)
221
+
222
+ // 2 ** 31 has its sign bit set in the i32 passed by JavaScript. The first
223
+ // salt is already known to match, so unsigned C returns immediately; the old
224
+ // signed ABI interpreted the count as negative and skipped the loop.
225
+ expect(module.exports.mine(2 ** 31)).toBe(1)
226
+ })
227
+
153
228
  test('reports progress', async () => {
154
229
  const progressCalls: VirtualMaster.mineSaltAsync.Progress[] = []
155
230
 
@@ -1,14 +1,15 @@
1
- import { keccak_256 } from '@noble/hashes/sha3.js'
2
1
  import * as Address from '../core/Address.js'
3
2
  import * as Bytes from '../core/Bytes.js'
4
3
  import * as Errors from '../core/Errors.js'
5
4
  import type * as Hash from '../core/Hash.js'
5
+ import * as hash_ from '../core/internal/hash.js'
6
6
  import * as Hex from '../core/Hex.js'
7
7
  import * as VirtualMasterPool from './internal/virtualMasterPool.js'
8
8
  import * as VirtualAddress from './VirtualAddress.js'
9
9
 
10
10
  const tip20Prefix = '0x20c000000000000000000000'
11
11
  const zeroAddress = '0x0000000000000000000000000000000000000000'
12
+ const maxUint32 = 2 ** 32 - 1
12
13
 
13
14
  /** A valid salt input for TIP-1022 master registration. */
14
15
  export type Salt = Hex.Hex | Bytes.Bytes | number | bigint
@@ -203,7 +204,7 @@ export function mineSalt(
203
204
  saltView.set(toFixedBytes(value.start ?? 0n, 32))
204
205
 
205
206
  for (let i = 0; i < count; i++) {
206
- const hash = keccak_256(input)
207
+ const hash = hash_.keccak256(input)
207
208
 
208
209
  if (hash[0] === 0 && hash[1] === 0 && hash[2] === 0 && hash[3] === 0) {
209
210
  return {
@@ -289,13 +290,14 @@ export async function mineSaltAsync(
289
290
  workers = getDefaultWorkerCount(),
290
291
  } = parameters
291
292
 
292
- const address = resolveAddress(parameters.address)
293
- const start = toFixedHex(start_, 32)
294
-
293
+ assertChunkSize(chunkSize)
295
294
  assertCount(count)
296
295
  if (workers !== undefined) assertWorkers(workers)
297
296
  throwIfAborted(signal)
298
297
 
298
+ const address = resolveAddress(parameters.address)
299
+ const start = toFixedHex(start_, 32)
300
+
299
301
  const workerCount = Math.max(
300
302
  1,
301
303
  Math.min(workers, Math.ceil(count / chunkSize)),
@@ -341,6 +343,8 @@ export declare namespace mineSaltAsync {
341
343
  /**
342
344
  * Number of salts each worker processes before sending a progress update.
343
345
  *
346
+ * Must be a positive integer no greater than 2 ** 32 - 1.
347
+ *
344
348
  * @default 100_000
345
349
  */
346
350
  chunkSize?: number | undefined
@@ -576,6 +580,24 @@ function assertWorkers(workers: number) {
576
580
  )
577
581
  }
578
582
 
583
+ /**
584
+ * Asserts that `chunkSize` fits the miner's unsigned 32-bit WASM ABI.
585
+ *
586
+ * @internal
587
+ */
588
+ function assertChunkSize(chunkSize: number) {
589
+ if (
590
+ Number.isSafeInteger(chunkSize) &&
591
+ chunkSize > 0 &&
592
+ chunkSize <= maxUint32
593
+ )
594
+ return
595
+
596
+ throw new Errors.BaseError(
597
+ `Chunk size "${chunkSize}" is invalid. Expected a positive safe integer no greater than ${maxUint32}.`,
598
+ )
599
+ }
600
+
579
601
  /**
580
602
  * Extracts or creates an error from an `AbortSignal`.
581
603
  *
@@ -679,7 +701,7 @@ function buildRegistrationDigest(
679
701
  const addressBytes = Bytes.fromHex(resolveAddress(address))
680
702
  buffer.set(addressBytes)
681
703
  buffer.set(toFixedBytes(salt, 32), addressBytes.length)
682
- return keccak_256(buffer)
704
+ return hash_.keccak256(buffer)
683
705
  }
684
706
 
685
707
  /**
@@ -0,0 +1,16 @@
1
+ import { expectTypeOf, test } from 'vp/test'
2
+ import * as ZoneId from './ZoneId.js'
3
+
4
+ test('accepts supported source IDs', () => {
5
+ expectTypeOf(ZoneId.fromChainId(421_700_001)).toEqualTypeOf<number>()
6
+ expectTypeOf(
7
+ ZoneId.fromChainId(1_424_310_001, 42_431),
8
+ ).toEqualTypeOf<number>()
9
+ expectTypeOf(ZoneId.toChainId(1)).toEqualTypeOf<number>()
10
+ expectTypeOf(ZoneId.toChainId(1, 42_431)).toEqualTypeOf<number>()
11
+
12
+ // @ts-expect-error Unsupported source ID.
13
+ ZoneId.fromChainId(421_700_001, 1)
14
+ // @ts-expect-error Unsupported source ID.
15
+ ZoneId.toChainId(1, 1)
16
+ })
@@ -3,40 +3,75 @@ import * as ZoneId from './ZoneId.js'
3
3
 
4
4
  describe('fromChainId', () => {
5
5
  test('default', () => {
6
- expect(ZoneId.fromChainId(4_217_000_006)).toBe(6)
6
+ expect(ZoneId.chainIdBase).toMatchInlineSnapshot(`421700000`)
7
+ expect(ZoneId.fromChainId(421_700_001)).toMatchInlineSnapshot(`1`)
7
8
  })
8
9
 
9
- test('zone 1', () => {
10
- expect(ZoneId.fromChainId(4_217_000_001)).toBe(1)
10
+ test('Moderato', () => {
11
+ expect(ZoneId.fromChainId(1_424_310_028, 42_431)).toMatchInlineSnapshot(
12
+ `28`,
13
+ )
11
14
  })
12
15
 
13
- test('zone 28', () => {
14
- expect(ZoneId.fromChainId(4_217_000_028)).toBe(28)
16
+ test('unsupported source id', () => {
17
+ expect(() =>
18
+ // @ts-expect-error Unsupported source ID.
19
+ ZoneId.fromChainId(421_700_001, 1),
20
+ ).toThrowErrorMatchingInlineSnapshot(`
21
+ [ZoneId.UnsupportedSourceIdError: Source chain ID "1" is not supported.
22
+
23
+ Supported source chain IDs: 4217, 42431.]
24
+ `)
15
25
  })
16
26
  })
17
27
 
18
28
  describe('toChainId', () => {
19
29
  test('default', () => {
20
- expect(ZoneId.toChainId(6)).toBe(4_217_000_006)
30
+ expect(ZoneId.toChainId(1)).toMatchInlineSnapshot(`421700001`)
31
+ })
32
+
33
+ test('Moderato', () => {
34
+ expect(ZoneId.toChainId(28, 42_431)).toMatchInlineSnapshot(`1424310028`)
21
35
  })
22
36
 
23
- test('zone 1', () => {
24
- expect(ZoneId.toChainId(1)).toBe(4_217_000_001)
37
+ test('wraps within the source chain range', () => {
38
+ expect(ZoneId.toChainId(1_002_610_001)).toMatchInlineSnapshot(`421700001`)
39
+ expect(ZoneId.toChainId(723_173_649, 42_431)).toMatchInlineSnapshot(
40
+ `1424310001`,
41
+ )
25
42
  })
26
43
 
27
- test('zone 28', () => {
28
- expect(ZoneId.toChainId(28)).toBe(4_217_000_028)
44
+ test('unsupported source id', () => {
45
+ expect(() =>
46
+ // @ts-expect-error Unsupported source ID.
47
+ ZoneId.toChainId(1, 1),
48
+ ).toThrowErrorMatchingInlineSnapshot(`
49
+ [ZoneId.UnsupportedSourceIdError: Source chain ID "1" is not supported.
50
+
51
+ Supported source chain IDs: 4217, 42431.]
52
+ `)
29
53
  })
30
54
  })
31
55
 
32
56
  describe('roundtrip', () => {
33
57
  test('fromChainId → toChainId', () => {
34
- const chainId = 4_217_000_006
35
- expect(ZoneId.toChainId(ZoneId.fromChainId(chainId))).toBe(chainId)
58
+ const chainId = 421_700_006
59
+ expect(ZoneId.toChainId(ZoneId.fromChainId(chainId))).toMatchInlineSnapshot(
60
+ `421700006`,
61
+ )
36
62
  })
37
63
 
38
64
  test('toChainId → fromChainId', () => {
39
65
  const zoneId = 42
40
- expect(ZoneId.fromChainId(ZoneId.toChainId(zoneId))).toBe(zoneId)
66
+ expect(ZoneId.fromChainId(ZoneId.toChainId(zoneId))).toMatchInlineSnapshot(
67
+ `42`,
68
+ )
69
+ })
70
+
71
+ test('Moderato', () => {
72
+ const zoneId = 42
73
+ const sourceId = 42_431
74
+ const chainId = ZoneId.toChainId(zoneId, sourceId)
75
+ expect(ZoneId.fromChainId(chainId, sourceId)).toMatchInlineSnapshot(`42`)
41
76
  })
42
77
  })
@@ -1,58 +1,94 @@
1
- import type * as Errors from '../core/Errors.js'
1
+ import * as Errors from '../core/Errors.js'
2
+
3
+ const chainIdConfig = {
4
+ 4_217: {
5
+ base: 421_700_000,
6
+ range: 1_002_610_000,
7
+ },
8
+ 42_431: {
9
+ base: 1_424_310_000,
10
+ range: 723_173_648,
11
+ },
12
+ } as const
13
+
14
+ const defaultSourceId = 4_217
2
15
 
3
16
  /**
4
- * Base offset for deriving zone chain IDs.
5
- *
6
- * Zone chain IDs are computed as `chainIdBase + zoneId`.
17
+ * Base offset for deriving Presto zone chain IDs.
7
18
  */
8
- export const chainIdBase = 4_217_000_000 as const
19
+ export const chainIdBase = chainIdConfig[defaultSourceId].base
20
+
21
+ /** Tempo source chain ID. */
22
+ export type SourceId = keyof typeof chainIdConfig
9
23
 
10
24
  /**
11
25
  * Derives a zone ID from a zone chain ID.
12
26
  *
13
- * Zone chain IDs follow the formula `4_217_000_000 + zoneId`, so a chain ID
14
- * of `4217000006` corresponds to zone ID `6`.
27
+ * Zone chain IDs use the base assigned to their Tempo source chain.
15
28
  *
16
29
  * @example
17
30
  * ```ts twoslash
18
31
  * import { ZoneId } from 'ox/tempo'
19
32
  *
20
- * const zoneId = ZoneId.fromChainId(4_217_000_006)
21
- * // @log: 6
33
+ * const zoneId = ZoneId.fromChainId(421_700_001)
34
+ * // @log: 1
22
35
  * ```
23
36
  *
24
37
  * @param chainId - The zone chain ID.
38
+ * @param sourceId - The Tempo source chain ID. Defaults to `4217` (Presto).
25
39
  * @returns The zone ID.
26
40
  */
27
- export function fromChainId(chainId: number): number {
28
- return chainId - chainIdBase
41
+ export function fromChainId(
42
+ chainId: number,
43
+ sourceId: SourceId = defaultSourceId,
44
+ ): number {
45
+ return chainId - getChainIdConfig(sourceId).base
29
46
  }
30
47
 
31
48
  export declare namespace fromChainId {
32
- type ErrorType = Errors.GlobalErrorType
49
+ type ErrorType = typeof UnsupportedSourceIdError | Errors.GlobalErrorType
33
50
  }
34
51
 
35
52
  /**
36
53
  * Derives a zone chain ID from a zone ID.
37
54
  *
38
- * Zone chain IDs follow the formula `4_217_000_000 + zoneId`, so zone ID
39
- * `6` corresponds to chain ID `4217000006`.
55
+ * Zone chain IDs use the base and range assigned to their Tempo source chain.
40
56
  *
41
57
  * @example
42
58
  * ```ts twoslash
43
59
  * import { ZoneId } from 'ox/tempo'
44
60
  *
45
- * const chainId = ZoneId.toChainId(6)
46
- * // @log: 4217000006
61
+ * const chainId = ZoneId.toChainId(1)
62
+ * // @log: 421700001
47
63
  * ```
48
64
  *
49
65
  * @param zoneId - The zone ID.
66
+ * @param sourceId - The Tempo source chain ID. Defaults to `4217` (Presto).
50
67
  * @returns The zone chain ID.
51
68
  */
52
- export function toChainId(zoneId: number): number {
53
- return chainIdBase + zoneId
69
+ export function toChainId(
70
+ zoneId: number,
71
+ sourceId: SourceId = defaultSourceId,
72
+ ): number {
73
+ const { base, range } = getChainIdConfig(sourceId)
74
+ return base + (zoneId % range)
54
75
  }
55
76
 
56
77
  export declare namespace toChainId {
57
- type ErrorType = Errors.GlobalErrorType
78
+ type ErrorType = typeof UnsupportedSourceIdError | Errors.GlobalErrorType
79
+ }
80
+
81
+ /** Thrown when a Tempo source chain ID is unsupported. */
82
+ export class UnsupportedSourceIdError extends Errors.BaseError {
83
+ override readonly name = 'ZoneId.UnsupportedSourceIdError'
84
+ constructor({ sourceId }: { sourceId: number }) {
85
+ super(`Source chain ID "${sourceId}" is not supported.`, {
86
+ metaMessages: ['Supported source chain IDs: 4217, 42431.'],
87
+ })
88
+ }
89
+ }
90
+
91
+ function getChainIdConfig(sourceId: number) {
92
+ if (sourceId === 4_217 || sourceId === 42_431) return chainIdConfig[sourceId]
93
+ throw new UnsupportedSourceIdError({ sourceId })
58
94
  }
@@ -532,18 +532,17 @@ export * as VirtualMaster from './VirtualMaster.js'
532
532
  /**
533
533
  * Zone ID utilities for converting between zone IDs and zone chain IDs.
534
534
  *
535
- * Zone chain IDs are deterministically derived from zone IDs using the formula
536
- * `421_700_000 + zoneId`. This module provides helpers to convert between them.
535
+ * Zone chain IDs use the base and range assigned to their Tempo source chain.
537
536
  *
538
537
  * @example
539
538
  * ```ts twoslash
540
539
  * import { ZoneId } from 'ox/tempo'
541
540
  *
542
- * const zoneId = ZoneId.fromChainId(421_700_026)
543
- * // @log: 26
541
+ * const zoneId = ZoneId.fromChainId(421_700_001)
542
+ * // @log: 1
544
543
  *
545
- * const chainId = ZoneId.toChainId(26)
546
- * // @log: 421700026
544
+ * const chainId = ZoneId.toChainId(1)
545
+ * // @log: 421700001
547
546
  * ```
548
547
  *
549
548
  * @category Reference
@@ -1,17 +1,11 @@
1
- // Embedded TIP-1022 WASM keccak256 salt miner (compiled from mine.c).
1
+ // Generated by `pnpm wasm:build --target=mine`. Do not edit.
2
2
  //
3
- // Memory layout at offset 1024:
4
- // [0..19] address (20 bytes, set by JS)
5
- // [20..51] salt (32 bytes, set/read by JS, incremented in-place)
6
- // [52..83] hash out (32 bytes, written on match)
3
+ // Compiled from wasm/src/mine.c, wasm/src/ox_rt.c
4
+ // with wasi-sdk 25.0 + binaryen 123.
7
5
  //
8
- // Exported: mine(count: i32) -> i32 returns 1 if found, 0 if not.
9
- //
10
- // Generated by: pnpm tsx scripts/build-mine-wasm.ts
6
+ // `pnpm wasm:check` rebuilds this file and fails if the bytes differ, so any
7
+ // change to the C or to `wasm/targets.ts` must be followed by `pnpm wasm:build`.
11
8
 
12
- /** Base64-encoded WASM binary for the TIP-1022 salt miner. */
9
+ /** Base64-encoded WASM binary. */
13
10
  export const wasmBase64 =
14
- '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'
15
-
16
- /** Byte offset in WASM linear memory where mining I/O begins. */
17
- export const dataOffset = 1024
11
+ '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'
@@ -185,7 +185,6 @@ main().catch(function(error) {
185
185
  */
186
186
  function getWorkerMineLoop(): string {
187
187
  return `
188
- var dataOffset = 1024
189
188
 
190
189
  function hexToBytes(hex) {
191
190
  var h = hex.startsWith('0x') ? hex.slice(2) : hex
@@ -218,6 +217,10 @@ function mineLoop(data, wasm, mem, postMessage) {
218
217
  var workerIndex = data.workerIndex
219
218
  var startBigInt = BigInt(data.start)
220
219
 
220
+ // Asked of the module rather than baked in: the buffer starts past the
221
+ // static data, wherever the linker put its end.
222
+ var dataOffset = wasm.heap_base()
223
+
221
224
  mem.set(addressBytes, dataOffset)
222
225
 
223
226
  for (
package/src/tsconfig.json CHANGED
@@ -10,6 +10,7 @@
10
10
  "./**/*.bench.ts",
11
11
  "./**/*.bench-d.ts",
12
12
  "./**/*.snap-d.ts",
13
- "./**/*.browser.test.ts"
13
+ "./**/*.browser.test.ts",
14
+ "./**/*.fuzz.ts"
14
15
  ]
15
16
  }
package/src/version.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  /** @internal */
2
- export const version = '1.0.4'
2
+ export const version = '1.1.0'