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.
- package/CHANGELOG.md +62 -0
- package/dist/core/Base64.d.ts +10 -21
- package/dist/core/Base64.d.ts.map +1 -1
- package/dist/core/Base64.js +8 -127
- package/dist/core/Base64.js.map +1 -1
- package/dist/core/BinaryStateTree.d.ts.map +1 -1
- package/dist/core/BinaryStateTree.js +2 -2
- package/dist/core/BinaryStateTree.js.map +1 -1
- package/dist/core/Bls.d.ts.map +1 -1
- package/dist/core/Bls.js +19 -44
- package/dist/core/Bls.js.map +1 -1
- package/dist/core/Ed25519.d.ts.map +1 -1
- package/dist/core/Ed25519.js +7 -6
- package/dist/core/Ed25519.js.map +1 -1
- package/dist/core/Engine.d.ts +124 -0
- package/dist/core/Engine.d.ts.map +1 -0
- package/dist/core/Engine.js +180 -0
- package/dist/core/Engine.js.map +1 -0
- package/dist/core/Hash.d.ts +4 -4
- package/dist/core/Hash.d.ts.map +1 -1
- package/dist/core/Hash.js +9 -12
- package/dist/core/Hash.js.map +1 -1
- package/dist/core/Keystore.d.ts.map +1 -1
- package/dist/core/Keystore.js +15 -10
- package/dist/core/Keystore.js.map +1 -1
- package/dist/core/Mnemonic.d.ts.map +1 -1
- package/dist/core/Mnemonic.js +3 -2
- package/dist/core/Mnemonic.js.map +1 -1
- package/dist/core/P256.d.ts.map +1 -1
- package/dist/core/P256.js +8 -9
- package/dist/core/P256.js.map +1 -1
- package/dist/core/Secp256k1.d.ts.map +1 -1
- package/dist/core/Secp256k1.js +8 -9
- package/dist/core/Secp256k1.js.map +1 -1
- package/dist/core/WebCryptoP256.d.ts.map +1 -1
- package/dist/core/WebCryptoP256.js +2 -2
- package/dist/core/WebCryptoP256.js.map +1 -1
- package/dist/core/X25519.d.ts.map +1 -1
- package/dist/core/X25519.js +4 -3
- package/dist/core/X25519.js.map +1 -1
- package/dist/core/internal/bls.d.ts +12 -0
- package/dist/core/internal/bls.d.ts.map +1 -0
- package/dist/core/internal/bls.js +79 -0
- package/dist/core/internal/bls.js.map +1 -0
- package/dist/core/internal/codec/base64.d.ts +84 -0
- package/dist/core/internal/codec/base64.d.ts.map +1 -0
- package/dist/core/internal/codec/base64.js +177 -0
- package/dist/core/internal/codec/base64.js.map +1 -0
- package/dist/core/internal/codec/hex.d.ts +49 -4
- package/dist/core/internal/codec/hex.d.ts.map +1 -1
- package/dist/core/internal/codec/hex.js +109 -35
- package/dist/core/internal/codec/hex.js.map +1 -1
- package/dist/core/internal/curves.d.ts +17 -0
- package/dist/core/internal/curves.d.ts.map +1 -0
- package/dist/core/internal/curves.js +17 -0
- package/dist/core/internal/curves.js.map +1 -0
- package/dist/core/internal/ed25519.d.ts +14 -0
- package/dist/core/internal/ed25519.d.ts.map +1 -0
- package/dist/core/internal/ed25519.js +29 -0
- package/dist/core/internal/ed25519.js.map +1 -0
- package/dist/core/internal/engine.d.ts +278 -0
- package/dist/core/internal/engine.d.ts.map +1 -0
- package/dist/core/internal/engine.js +131 -0
- package/dist/core/internal/engine.js.map +1 -0
- package/dist/core/internal/hash.d.ts +12 -0
- package/dist/core/internal/hash.d.ts.map +1 -0
- package/dist/core/internal/hash.js +30 -0
- package/dist/core/internal/hash.js.map +1 -0
- package/dist/core/internal/keystore.d.ts +14 -0
- package/dist/core/internal/keystore.d.ts.map +1 -0
- package/dist/core/internal/keystore.js +32 -0
- package/dist/core/internal/keystore.js.map +1 -0
- package/dist/core/internal/mnemonic.d.ts +4 -0
- package/dist/core/internal/mnemonic.d.ts.map +1 -0
- package/dist/core/internal/mnemonic.js +14 -0
- package/dist/core/internal/mnemonic.js.map +1 -0
- package/dist/core/internal/p256.d.ts +14 -0
- package/dist/core/internal/p256.d.ts.map +1 -0
- package/dist/core/internal/p256.js +36 -0
- package/dist/core/internal/p256.js.map +1 -0
- package/dist/core/internal/secp256k1.d.ts +14 -0
- package/dist/core/internal/secp256k1.d.ts.map +1 -0
- package/dist/core/internal/secp256k1.js +36 -0
- package/dist/core/internal/secp256k1.js.map +1 -0
- package/dist/core/internal/x25519.d.ts +8 -0
- package/dist/core/internal/x25519.d.ts.map +1 -0
- package/dist/core/internal/x25519.js +20 -0
- package/dist/core/internal/x25519.js.map +1 -0
- package/dist/index.d.ts +35 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.docs.d.ts +2 -0
- package/dist/index.docs.d.ts.map +1 -1
- package/dist/index.docs.js +2 -0
- package/dist/index.docs.js.map +1 -1
- package/dist/index.js +35 -0
- package/dist/index.js.map +1 -1
- package/dist/node/Engine.d.ts +55 -0
- package/dist/node/Engine.d.ts.map +1 -0
- package/dist/node/Engine.js +51 -0
- package/dist/node/Engine.js.map +1 -0
- package/dist/node/Hash.d.ts +39 -0
- package/dist/node/Hash.d.ts.map +1 -0
- package/dist/node/Hash.js +37 -0
- package/dist/node/Hash.js.map +1 -0
- package/dist/node/index.d.ts +39 -0
- package/dist/node/index.d.ts.map +1 -0
- package/dist/node/index.js +39 -0
- package/dist/node/index.js.map +1 -0
- package/dist/tempo/VirtualMaster.d.ts +2 -0
- package/dist/tempo/VirtualMaster.d.ts.map +1 -1
- package/dist/tempo/VirtualMaster.js +19 -5
- package/dist/tempo/VirtualMaster.js.map +1 -1
- package/dist/tempo/ZoneId.d.ts +35 -17
- package/dist/tempo/ZoneId.d.ts.map +1 -1
- package/dist/tempo/ZoneId.js +41 -16
- package/dist/tempo/ZoneId.js.map +1 -1
- package/dist/tempo/index.d.ts +5 -6
- package/dist/tempo/index.d.ts.map +1 -1
- package/dist/tempo/index.js +5 -6
- package/dist/tempo/index.js.map +1 -1
- package/dist/tempo/internal/mine.wasm.d.ts +2 -4
- package/dist/tempo/internal/mine.wasm.d.ts.map +1 -1
- package/dist/tempo/internal/mine.wasm.js +7 -12
- package/dist/tempo/internal/mine.wasm.js.map +1 -1
- package/dist/tempo/internal/virtualMasterPool.js +4 -1
- package/dist/tempo/internal/virtualMasterPool.js.map +1 -1
- package/dist/wasm/Engine.d.ts +62 -0
- package/dist/wasm/Engine.d.ts.map +1 -0
- package/dist/wasm/Engine.js +57 -0
- package/dist/wasm/Engine.js.map +1 -0
- package/dist/wasm/Hash.d.ts +49 -0
- package/dist/wasm/Hash.d.ts.map +1 -0
- package/dist/wasm/Hash.js +70 -0
- package/dist/wasm/Hash.js.map +1 -0
- package/dist/wasm/index.d.ts +46 -0
- package/dist/wasm/index.d.ts.map +1 -0
- package/dist/wasm/index.js +46 -0
- package/dist/wasm/index.js.map +1 -0
- package/dist/wasm/internal/hash.d.ts +9 -0
- package/dist/wasm/internal/hash.d.ts.map +1 -0
- package/dist/wasm/internal/hash.js +26 -0
- package/dist/wasm/internal/hash.js.map +1 -0
- package/dist/wasm/internal/hashes.wasm.d.ts +5 -0
- package/dist/wasm/internal/hashes.wasm.d.ts.map +1 -0
- package/dist/wasm/internal/hashes.wasm.js +12 -0
- package/dist/wasm/internal/hashes.wasm.js.map +1 -0
- package/dist/wasm/internal/instantiate.d.ts +56 -0
- package/dist/wasm/internal/instantiate.d.ts.map +1 -0
- package/dist/wasm/internal/instantiate.js +92 -0
- package/dist/wasm/internal/instantiate.js.map +1 -0
- package/dist/zod/TypedData.d.ts +12 -12
- package/package.json +36 -1
- package/src/core/Base64.ts +19 -166
- package/src/core/BinaryStateTree.ts +2 -3
- package/src/core/Bls.ts +27 -77
- package/src/core/Ed25519.ts +7 -7
- package/src/core/Engine.ts +235 -0
- package/src/core/Hash.ts +9 -12
- package/src/core/Keystore.ts +17 -17
- package/src/core/Mnemonic.ts +3 -6
- package/src/core/P256.ts +15 -24
- package/src/core/Rlp_tx.bench.ts +2 -4
- package/src/core/Secp256k1.ts +9 -14
- package/src/core/TxEnvelopeEip1559.bench.ts +0 -5
- package/src/core/WebCryptoP256.ts +2 -2
- package/src/core/X25519.ts +4 -3
- package/src/core/_test/AbiParameters.adversarial.fuzz.ts +1 -2
- package/src/core/_test/AbiParameters.fuzz.ts +1 -2
- package/src/core/_test/Base.fuzz.ts +1 -2
- package/src/core/_test/Cbor.fuzz.ts +1 -2
- package/src/core/_test/Engine.fuzz.ts +293 -0
- package/src/core/_test/Engine.test-d.ts +84 -0
- package/src/core/_test/Engine.test.ts +523 -0
- package/src/core/_test/Hash.vectors.test.ts +56 -0
- package/src/core/_test/Hex.fuzz.ts +1 -2
- package/src/core/_test/Rlp.fuzz.ts +1 -2
- package/src/core/_test/Signature.fuzz.ts +1 -2
- package/src/core/_test/curves.test.ts +7 -0
- package/src/core/_test/index.test.ts +1 -0
- package/src/core/internal/bls.ts +121 -0
- package/src/core/internal/codec/_test/base64.conformance.ts +156 -0
- package/src/core/internal/codec/_test/hex.conformance.ts +204 -0
- package/src/core/internal/codec/_test/hex.fuzz.ts +234 -0
- package/src/core/internal/codec/_test/hex.test.ts +124 -0
- package/src/core/internal/codec/base64.ts +222 -0
- package/src/core/internal/codec/hex.ts +115 -34
- package/src/core/internal/curves.ts +18 -0
- package/src/core/internal/ed25519.ts +64 -0
- package/src/core/internal/engine.ts +410 -0
- package/src/core/internal/hash.ts +48 -0
- package/src/core/internal/keystore.ts +107 -0
- package/src/core/internal/mnemonic.ts +18 -0
- package/src/core/internal/p256.ts +91 -0
- package/src/core/internal/secp256k1.ts +91 -0
- package/src/core/internal/x25519.ts +40 -0
- package/src/index.docs.ts +2 -0
- package/src/index.ts +36 -0
- package/src/node/Engine.ts +69 -0
- package/src/node/Hash.ts +56 -0
- package/src/node/_test/Engine.test.ts +62 -0
- package/src/node/_test/Hash.test-d.ts +26 -0
- package/src/node/_test/Hash.test.ts +102 -0
- package/src/node/index.ts +40 -0
- package/src/tempo/VirtualMaster.test.ts +75 -0
- package/src/tempo/VirtualMaster.ts +28 -6
- package/src/tempo/ZoneId.test-d.ts +16 -0
- package/src/tempo/ZoneId.test.ts +48 -13
- package/src/tempo/ZoneId.ts +55 -19
- package/src/tempo/index.ts +5 -6
- package/src/tempo/internal/mine.wasm.ts +7 -13
- package/src/tempo/internal/virtualMasterPool.ts +4 -1
- package/src/tsconfig.json +2 -1
- package/src/version.ts +1 -1
- package/src/wasm/Engine.ts +76 -0
- package/src/wasm/Hash.bench.ts +60 -0
- package/src/wasm/Hash.ts +109 -0
- package/src/wasm/_test/Engine.test.ts +62 -0
- package/src/wasm/_test/Hash.browser.test.ts +50 -0
- package/src/wasm/_test/Hash.fuzz.ts +188 -0
- package/src/wasm/_test/Hash.test-d.ts +28 -0
- package/src/wasm/_test/Hash.test.ts +211 -0
- package/src/wasm/_test/Hash.vectors.test.ts +117 -0
- package/src/wasm/_test/Runtime.test.ts +21 -0
- package/src/wasm/_test/runtime.wasm.ts +11 -0
- package/src/wasm/index.ts +47 -0
- package/src/wasm/internal/hash.ts +50 -0
- package/src/wasm/internal/hashes.wasm.ts +14 -0
- package/src/wasm/internal/instantiate.ts +135 -0
- package/src/zod/tempo/_test/ZoneId.test.ts +2 -2
- package/src/tempo/internal/mine.c +0 -182
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { blake3 as noble_blake3 } from '@noble/hashes/blake3.js'
|
|
2
|
+
import { hmac } from '@noble/hashes/hmac.js'
|
|
3
|
+
import { ripemd160 as noble_ripemd160 } from '@noble/hashes/legacy.js'
|
|
4
|
+
import { sha256 as noble_sha256 } from '@noble/hashes/sha2.js'
|
|
5
|
+
import { keccak_256 as noble_keccak256 } from '@noble/hashes/sha3.js'
|
|
6
|
+
import { type Complete, type Hash, overrides } from './engine.js'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Resolvers for the `Hash` slot, and ox's defaults for it, backed by
|
|
10
|
+
* `@noble/hashes`.
|
|
11
|
+
*
|
|
12
|
+
* Declaring the defaults against the slot contract is what keeps them honest: a
|
|
13
|
+
* default that goes missing, or whose signature drifts, fails to compile rather
|
|
14
|
+
* than failing at the call site.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
const blake3Default: Complete<Hash>['blake3'] = (input) => noble_blake3(input)
|
|
18
|
+
|
|
19
|
+
const hmacSha256Default: Complete<Hash>['hmacSha256'] = (key, message) =>
|
|
20
|
+
hmac(noble_sha256, key, message)
|
|
21
|
+
|
|
22
|
+
const keccak256Default: Complete<Hash>['keccak256'] = (input) =>
|
|
23
|
+
noble_keccak256(input)
|
|
24
|
+
|
|
25
|
+
const ripemd160Default: Complete<Hash>['ripemd160'] = (input) =>
|
|
26
|
+
noble_ripemd160(input)
|
|
27
|
+
|
|
28
|
+
const sha256Default: Complete<Hash>['sha256'] = (input) => noble_sha256(input)
|
|
29
|
+
|
|
30
|
+
/** @internal */
|
|
31
|
+
export const blake3: Complete<Hash>['blake3'] = (input) =>
|
|
32
|
+
(overrides.Hash?.blake3 ?? blake3Default)(input)
|
|
33
|
+
|
|
34
|
+
/** @internal */
|
|
35
|
+
export const hmacSha256: Complete<Hash>['hmacSha256'] = (key, message) =>
|
|
36
|
+
(overrides.Hash?.hmacSha256 ?? hmacSha256Default)(key, message)
|
|
37
|
+
|
|
38
|
+
/** @internal */
|
|
39
|
+
export const keccak256: Complete<Hash>['keccak256'] = (input) =>
|
|
40
|
+
(overrides.Hash?.keccak256 ?? keccak256Default)(input)
|
|
41
|
+
|
|
42
|
+
/** @internal */
|
|
43
|
+
export const ripemd160: Complete<Hash>['ripemd160'] = (input) =>
|
|
44
|
+
(overrides.Hash?.ripemd160 ?? ripemd160Default)(input)
|
|
45
|
+
|
|
46
|
+
/** @internal */
|
|
47
|
+
export const sha256: Complete<Hash>['sha256'] = (input) =>
|
|
48
|
+
(overrides.Hash?.sha256 ?? sha256Default)(input)
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { ctr } from '@noble/ciphers/aes.js'
|
|
2
|
+
import {
|
|
3
|
+
pbkdf2 as pbkdf2_noble,
|
|
4
|
+
pbkdf2Async as pbkdf2Async_noble,
|
|
5
|
+
} from '@noble/hashes/pbkdf2.js'
|
|
6
|
+
import {
|
|
7
|
+
scrypt as scrypt_noble,
|
|
8
|
+
scryptAsync as scryptAsync_noble,
|
|
9
|
+
} from '@noble/hashes/scrypt.js'
|
|
10
|
+
import { sha256 } from '@noble/hashes/sha2.js'
|
|
11
|
+
import { type Complete, type Keystore, overrides } from './engine.js'
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Resolvers for the `Keystore` slot, and ox's defaults for it, backed by
|
|
15
|
+
* `@noble/ciphers` and `@noble/hashes`.
|
|
16
|
+
*
|
|
17
|
+
* Declaring the defaults against the slot contract is what keeps them honest: a
|
|
18
|
+
* default that goes missing, or whose signature drifts, fails to compile rather
|
|
19
|
+
* than failing at the call site.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
const aesCtrDecryptDefault: Complete<Keystore>['aesCtrDecrypt'] = (
|
|
23
|
+
key,
|
|
24
|
+
iv,
|
|
25
|
+
data,
|
|
26
|
+
) => ctr(key, iv).decrypt(data)
|
|
27
|
+
|
|
28
|
+
const aesCtrEncryptDefault: Complete<Keystore>['aesCtrEncrypt'] = (
|
|
29
|
+
key,
|
|
30
|
+
iv,
|
|
31
|
+
data,
|
|
32
|
+
) => ctr(key, iv).encrypt(data)
|
|
33
|
+
|
|
34
|
+
const pbkdf2Sha256Default: Complete<Keystore>['pbkdf2Sha256'] = (
|
|
35
|
+
password,
|
|
36
|
+
salt,
|
|
37
|
+
options,
|
|
38
|
+
) => pbkdf2_noble(sha256, password, salt, options)
|
|
39
|
+
|
|
40
|
+
const pbkdf2Sha256AsyncDefault: Complete<Keystore>['pbkdf2Sha256Async'] = (
|
|
41
|
+
password,
|
|
42
|
+
salt,
|
|
43
|
+
options,
|
|
44
|
+
) => pbkdf2Async_noble(sha256, password, salt, options)
|
|
45
|
+
|
|
46
|
+
const scryptDefault: Complete<Keystore>['scrypt'] = (password, salt, options) =>
|
|
47
|
+
scrypt_noble(password, salt, options)
|
|
48
|
+
|
|
49
|
+
const scryptAsyncDefault: Complete<Keystore>['scryptAsync'] = (
|
|
50
|
+
password,
|
|
51
|
+
salt,
|
|
52
|
+
options,
|
|
53
|
+
) => scryptAsync_noble(password, salt, options)
|
|
54
|
+
|
|
55
|
+
/** @internal */
|
|
56
|
+
export const aesCtrDecrypt: Complete<Keystore>['aesCtrDecrypt'] = (
|
|
57
|
+
key,
|
|
58
|
+
iv,
|
|
59
|
+
data,
|
|
60
|
+
) => (overrides.Keystore?.aesCtrDecrypt ?? aesCtrDecryptDefault)(key, iv, data)
|
|
61
|
+
|
|
62
|
+
/** @internal */
|
|
63
|
+
export const aesCtrEncrypt: Complete<Keystore>['aesCtrEncrypt'] = (
|
|
64
|
+
key,
|
|
65
|
+
iv,
|
|
66
|
+
data,
|
|
67
|
+
) => (overrides.Keystore?.aesCtrEncrypt ?? aesCtrEncryptDefault)(key, iv, data)
|
|
68
|
+
|
|
69
|
+
/** @internal */
|
|
70
|
+
export const pbkdf2Sha256: Complete<Keystore>['pbkdf2Sha256'] = (
|
|
71
|
+
password,
|
|
72
|
+
salt,
|
|
73
|
+
options,
|
|
74
|
+
) =>
|
|
75
|
+
(overrides.Keystore?.pbkdf2Sha256 ?? pbkdf2Sha256Default)(
|
|
76
|
+
password,
|
|
77
|
+
salt,
|
|
78
|
+
options,
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
/** @internal */
|
|
82
|
+
export const pbkdf2Sha256Async: Complete<Keystore>['pbkdf2Sha256Async'] = (
|
|
83
|
+
password,
|
|
84
|
+
salt,
|
|
85
|
+
options,
|
|
86
|
+
) =>
|
|
87
|
+
(overrides.Keystore?.pbkdf2Sha256Async ?? pbkdf2Sha256AsyncDefault)(
|
|
88
|
+
password,
|
|
89
|
+
salt,
|
|
90
|
+
options,
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
/** @internal */
|
|
94
|
+
export const scrypt: Complete<Keystore>['scrypt'] = (password, salt, options) =>
|
|
95
|
+
(overrides.Keystore?.scrypt ?? scryptDefault)(password, salt, options)
|
|
96
|
+
|
|
97
|
+
/** @internal */
|
|
98
|
+
export const scryptAsync: Complete<Keystore>['scryptAsync'] = (
|
|
99
|
+
password,
|
|
100
|
+
salt,
|
|
101
|
+
options,
|
|
102
|
+
) =>
|
|
103
|
+
(overrides.Keystore?.scryptAsync ?? scryptAsyncDefault)(
|
|
104
|
+
password,
|
|
105
|
+
salt,
|
|
106
|
+
options,
|
|
107
|
+
)
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { mnemonicToSeedSync } from '@scure/bip39'
|
|
2
|
+
import { type Complete, type Mnemonic, overrides } from './engine.js'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Resolvers for the `Mnemonic` slot, and ox's defaults for it, backed by
|
|
6
|
+
* `@scure/bip39`.
|
|
7
|
+
*
|
|
8
|
+
* Declaring the defaults against the slot contract is what keeps them honest: a
|
|
9
|
+
* default that goes missing, or whose signature drifts, fails to compile rather
|
|
10
|
+
* than failing at the call site.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
const toSeedDefault: Complete<Mnemonic>['toSeed'] = (mnemonic, passphrase) =>
|
|
14
|
+
mnemonicToSeedSync(mnemonic, passphrase)
|
|
15
|
+
|
|
16
|
+
/** @internal */
|
|
17
|
+
export const toSeed: Complete<Mnemonic>['toSeed'] = (mnemonic, passphrase) =>
|
|
18
|
+
(overrides.Mnemonic?.toSeed ?? toSeedDefault)(mnemonic, passphrase)
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { p256 } from '@noble/curves/nist.js'
|
|
2
|
+
import { type Complete, type Ecdsa, overrides } from './engine.js'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Resolvers for the `P256` slot, and ox's defaults for it, backed by
|
|
6
|
+
* `@noble/curves`.
|
|
7
|
+
*
|
|
8
|
+
* Declaring the defaults against the slot contract is what keeps them honest: a
|
|
9
|
+
* default that goes missing, or whose signature drifts, fails to compile rather
|
|
10
|
+
* than failing at the call site. `lowS` and the recovered signature format are
|
|
11
|
+
* pinned here rather than in the contract, so an engine cannot opt out of them.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
const getPublicKeyDefault: Complete<Ecdsa>['getPublicKey'] = (privateKey) =>
|
|
15
|
+
p256.getPublicKey(privateKey, false)
|
|
16
|
+
|
|
17
|
+
const getSharedSecretDefault: Complete<Ecdsa>['getSharedSecret'] = (
|
|
18
|
+
privateKey,
|
|
19
|
+
publicKey,
|
|
20
|
+
) => p256.getSharedSecret(privateKey, publicKey, true)
|
|
21
|
+
|
|
22
|
+
const randomSecretKeyDefault: Complete<Ecdsa>['randomSecretKey'] = () =>
|
|
23
|
+
p256.utils.randomSecretKey()
|
|
24
|
+
|
|
25
|
+
const recoverPublicKeyDefault: Complete<Ecdsa>['recoverPublicKey'] = (
|
|
26
|
+
signature,
|
|
27
|
+
payload,
|
|
28
|
+
) =>
|
|
29
|
+
p256.Signature.fromBytes(signature, 'recovered')
|
|
30
|
+
.recoverPublicKey(payload)
|
|
31
|
+
.toBytes(false)
|
|
32
|
+
|
|
33
|
+
const signDefault: Complete<Ecdsa>['sign'] = (payload, privateKey, options) =>
|
|
34
|
+
p256.sign(payload, privateKey, {
|
|
35
|
+
...options,
|
|
36
|
+
format: 'recovered',
|
|
37
|
+
lowS: true,
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
const verifyDefault: Complete<Ecdsa>['verify'] = (
|
|
41
|
+
signature,
|
|
42
|
+
payload,
|
|
43
|
+
publicKey,
|
|
44
|
+
options,
|
|
45
|
+
) => p256.verify(signature, payload, publicKey, { ...options, lowS: true })
|
|
46
|
+
|
|
47
|
+
/** @internal */
|
|
48
|
+
export const getPublicKey: Complete<Ecdsa>['getPublicKey'] = (privateKey) =>
|
|
49
|
+
(overrides.P256?.getPublicKey ?? getPublicKeyDefault)(privateKey)
|
|
50
|
+
|
|
51
|
+
/** @internal */
|
|
52
|
+
export const getSharedSecret: Complete<Ecdsa>['getSharedSecret'] = (
|
|
53
|
+
privateKey,
|
|
54
|
+
publicKey,
|
|
55
|
+
) =>
|
|
56
|
+
(overrides.P256?.getSharedSecret ?? getSharedSecretDefault)(
|
|
57
|
+
privateKey,
|
|
58
|
+
publicKey,
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
/** @internal */
|
|
62
|
+
export const randomSecretKey: Complete<Ecdsa>['randomSecretKey'] = () =>
|
|
63
|
+
(overrides.P256?.randomSecretKey ?? randomSecretKeyDefault)()
|
|
64
|
+
|
|
65
|
+
/** @internal */
|
|
66
|
+
export const recoverPublicKey: Complete<Ecdsa>['recoverPublicKey'] = (
|
|
67
|
+
signature,
|
|
68
|
+
payload,
|
|
69
|
+
) =>
|
|
70
|
+
(overrides.P256?.recoverPublicKey ?? recoverPublicKeyDefault)(
|
|
71
|
+
signature,
|
|
72
|
+
payload,
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
/** @internal */
|
|
76
|
+
export const sign: Complete<Ecdsa>['sign'] = (payload, privateKey, options) =>
|
|
77
|
+
(overrides.P256?.sign ?? signDefault)(payload, privateKey, options)
|
|
78
|
+
|
|
79
|
+
/** @internal */
|
|
80
|
+
export const verify: Complete<Ecdsa>['verify'] = (
|
|
81
|
+
signature,
|
|
82
|
+
payload,
|
|
83
|
+
publicKey,
|
|
84
|
+
options,
|
|
85
|
+
) =>
|
|
86
|
+
(overrides.P256?.verify ?? verifyDefault)(
|
|
87
|
+
signature,
|
|
88
|
+
payload,
|
|
89
|
+
publicKey,
|
|
90
|
+
options,
|
|
91
|
+
)
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { secp256k1 } from '@noble/curves/secp256k1.js'
|
|
2
|
+
import { type Complete, type Ecdsa, overrides } from './engine.js'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Resolvers for the `Secp256k1` slot, and ox's defaults for it, backed by
|
|
6
|
+
* `@noble/curves`.
|
|
7
|
+
*
|
|
8
|
+
* Declaring the defaults against the slot contract is what keeps them honest: a
|
|
9
|
+
* default that goes missing, or whose signature drifts, fails to compile rather
|
|
10
|
+
* than failing at the call site. `lowS` and the recovered signature format are
|
|
11
|
+
* pinned here rather than in the contract, so an engine cannot opt out of them.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
const getPublicKeyDefault: Complete<Ecdsa>['getPublicKey'] = (privateKey) =>
|
|
15
|
+
secp256k1.getPublicKey(privateKey, false)
|
|
16
|
+
|
|
17
|
+
const getSharedSecretDefault: Complete<Ecdsa>['getSharedSecret'] = (
|
|
18
|
+
privateKey,
|
|
19
|
+
publicKey,
|
|
20
|
+
) => secp256k1.getSharedSecret(privateKey, publicKey, true)
|
|
21
|
+
|
|
22
|
+
const randomSecretKeyDefault: Complete<Ecdsa>['randomSecretKey'] = () =>
|
|
23
|
+
secp256k1.utils.randomSecretKey()
|
|
24
|
+
|
|
25
|
+
const recoverPublicKeyDefault: Complete<Ecdsa>['recoverPublicKey'] = (
|
|
26
|
+
signature,
|
|
27
|
+
payload,
|
|
28
|
+
) =>
|
|
29
|
+
secp256k1.Signature.fromBytes(signature, 'recovered')
|
|
30
|
+
.recoverPublicKey(payload)
|
|
31
|
+
.toBytes(false)
|
|
32
|
+
|
|
33
|
+
const signDefault: Complete<Ecdsa>['sign'] = (payload, privateKey, options) =>
|
|
34
|
+
secp256k1.sign(payload, privateKey, {
|
|
35
|
+
...options,
|
|
36
|
+
format: 'recovered',
|
|
37
|
+
lowS: true,
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
const verifyDefault: Complete<Ecdsa>['verify'] = (
|
|
41
|
+
signature,
|
|
42
|
+
payload,
|
|
43
|
+
publicKey,
|
|
44
|
+
options,
|
|
45
|
+
) => secp256k1.verify(signature, payload, publicKey, { ...options, lowS: true })
|
|
46
|
+
|
|
47
|
+
/** @internal */
|
|
48
|
+
export const getPublicKey: Complete<Ecdsa>['getPublicKey'] = (privateKey) =>
|
|
49
|
+
(overrides.Secp256k1?.getPublicKey ?? getPublicKeyDefault)(privateKey)
|
|
50
|
+
|
|
51
|
+
/** @internal */
|
|
52
|
+
export const getSharedSecret: Complete<Ecdsa>['getSharedSecret'] = (
|
|
53
|
+
privateKey,
|
|
54
|
+
publicKey,
|
|
55
|
+
) =>
|
|
56
|
+
(overrides.Secp256k1?.getSharedSecret ?? getSharedSecretDefault)(
|
|
57
|
+
privateKey,
|
|
58
|
+
publicKey,
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
/** @internal */
|
|
62
|
+
export const randomSecretKey: Complete<Ecdsa>['randomSecretKey'] = () =>
|
|
63
|
+
(overrides.Secp256k1?.randomSecretKey ?? randomSecretKeyDefault)()
|
|
64
|
+
|
|
65
|
+
/** @internal */
|
|
66
|
+
export const recoverPublicKey: Complete<Ecdsa>['recoverPublicKey'] = (
|
|
67
|
+
signature,
|
|
68
|
+
payload,
|
|
69
|
+
) =>
|
|
70
|
+
(overrides.Secp256k1?.recoverPublicKey ?? recoverPublicKeyDefault)(
|
|
71
|
+
signature,
|
|
72
|
+
payload,
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
/** @internal */
|
|
76
|
+
export const sign: Complete<Ecdsa>['sign'] = (payload, privateKey, options) =>
|
|
77
|
+
(overrides.Secp256k1?.sign ?? signDefault)(payload, privateKey, options)
|
|
78
|
+
|
|
79
|
+
/** @internal */
|
|
80
|
+
export const verify: Complete<Ecdsa>['verify'] = (
|
|
81
|
+
signature,
|
|
82
|
+
payload,
|
|
83
|
+
publicKey,
|
|
84
|
+
options,
|
|
85
|
+
) =>
|
|
86
|
+
(overrides.Secp256k1?.verify ?? verifyDefault)(
|
|
87
|
+
signature,
|
|
88
|
+
payload,
|
|
89
|
+
publicKey,
|
|
90
|
+
options,
|
|
91
|
+
)
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { x25519 } from '@noble/curves/ed25519.js'
|
|
2
|
+
import { type Complete, type Ecdh, overrides } from './engine.js'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Resolvers for the `X25519` slot, and ox's defaults for it, backed by
|
|
6
|
+
* `@noble/curves`.
|
|
7
|
+
*
|
|
8
|
+
* Declaring the defaults against the slot contract is what keeps them honest: a
|
|
9
|
+
* default that goes missing, or whose signature drifts, fails to compile rather
|
|
10
|
+
* than failing at the call site.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
const getPublicKeyDefault: Complete<Ecdh>['getPublicKey'] = (privateKey) =>
|
|
14
|
+
x25519.getPublicKey(privateKey)
|
|
15
|
+
|
|
16
|
+
const getSharedSecretDefault: Complete<Ecdh>['getSharedSecret'] = (
|
|
17
|
+
privateKey,
|
|
18
|
+
publicKey,
|
|
19
|
+
) => x25519.getSharedSecret(privateKey, publicKey)
|
|
20
|
+
|
|
21
|
+
const randomSecretKeyDefault: Complete<Ecdh>['randomSecretKey'] = () =>
|
|
22
|
+
x25519.utils.randomSecretKey()
|
|
23
|
+
|
|
24
|
+
/** @internal */
|
|
25
|
+
export const getPublicKey: Complete<Ecdh>['getPublicKey'] = (privateKey) =>
|
|
26
|
+
(overrides.X25519?.getPublicKey ?? getPublicKeyDefault)(privateKey)
|
|
27
|
+
|
|
28
|
+
/** @internal */
|
|
29
|
+
export const getSharedSecret: Complete<Ecdh>['getSharedSecret'] = (
|
|
30
|
+
privateKey,
|
|
31
|
+
publicKey,
|
|
32
|
+
) =>
|
|
33
|
+
(overrides.X25519?.getSharedSecret ?? getSharedSecretDefault)(
|
|
34
|
+
privateKey,
|
|
35
|
+
publicKey,
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
/** @internal */
|
|
39
|
+
export const randomSecretKey: Complete<Ecdh>['randomSecretKey'] = () =>
|
|
40
|
+
(overrides.X25519?.randomSecretKey ?? randomSecretKeyDefault)()
|
package/src/index.docs.ts
CHANGED
|
@@ -7,6 +7,8 @@ export * from './erc6492/index.js'
|
|
|
7
7
|
export * from './erc7821/index.js'
|
|
8
8
|
export * from './erc8010/index.js'
|
|
9
9
|
export * from './erc8021/index.js'
|
|
10
|
+
export * from './node/index.js'
|
|
10
11
|
export * from './webauthn/index.js'
|
|
11
12
|
export * from './tempo/index.js'
|
|
13
|
+
export * from './wasm/index.js'
|
|
12
14
|
export * from './zod/index.js'
|
package/src/index.ts
CHANGED
|
@@ -1520,6 +1520,42 @@ export * as CoseKey from './core/CoseKey.js'
|
|
|
1520
1520
|
*/
|
|
1521
1521
|
export * as Ed25519 from './core/Ed25519.js'
|
|
1522
1522
|
|
|
1523
|
+
/**
|
|
1524
|
+
* Functions for delegating ox's cryptography to a different implementation.
|
|
1525
|
+
*
|
|
1526
|
+
* Ox uses [`@noble`](https://github.com/paulmillr/noble-hashes) and
|
|
1527
|
+
* [`@scure`](https://github.com/paulmillr/scure-bip32) by default. An engine
|
|
1528
|
+
* replaces those implementations with your own — for example a WASM build of an
|
|
1529
|
+
* audited C library.
|
|
1530
|
+
*
|
|
1531
|
+
* @example
|
|
1532
|
+
* ### Installing an Engine
|
|
1533
|
+
*
|
|
1534
|
+
* Engine slots are named after ox modules, and everything is optional: any slot
|
|
1535
|
+
* or function you leave out keeps using ox's default implementation.
|
|
1536
|
+
*
|
|
1537
|
+
* ```ts twoslash
|
|
1538
|
+
* // @noErrors
|
|
1539
|
+
* import { Engine } from 'ox/wasm'
|
|
1540
|
+
*
|
|
1541
|
+
* await Engine.load()
|
|
1542
|
+
* ```
|
|
1543
|
+
*
|
|
1544
|
+
* @example
|
|
1545
|
+
* ### Overriding a Single Primitive
|
|
1546
|
+
*
|
|
1547
|
+
* ```ts twoslash
|
|
1548
|
+
* import { Engine } from 'ox'
|
|
1549
|
+
*
|
|
1550
|
+
* Engine.set({
|
|
1551
|
+
* Hash: { keccak256: () => new Uint8Array(32) }
|
|
1552
|
+
* })
|
|
1553
|
+
* ```
|
|
1554
|
+
*
|
|
1555
|
+
* @category Crypto
|
|
1556
|
+
*/
|
|
1557
|
+
export * as Engine from './core/Engine.js'
|
|
1558
|
+
|
|
1523
1559
|
/**
|
|
1524
1560
|
* Utility functions for working with ENS names.
|
|
1525
1561
|
*
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import * as CoreEngine from '../core/Engine.js'
|
|
2
|
+
import type * as Errors from '../core/Errors.js'
|
|
3
|
+
import * as Hash from './Hash.js'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Creates and installs every Node.js implementation this entrypoint provides.
|
|
7
|
+
*
|
|
8
|
+
* The function is asynchronous to match the `ox/wasm` entrypoint, even though
|
|
9
|
+
* Node's built-in cryptography needs no compilation. Call it once during
|
|
10
|
+
* startup, before any cryptographic operation.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```ts twoslash
|
|
14
|
+
* // @noErrors
|
|
15
|
+
* import { Hash } from 'ox'
|
|
16
|
+
* import { Engine } from 'ox/node'
|
|
17
|
+
*
|
|
18
|
+
* await Engine.load()
|
|
19
|
+
*
|
|
20
|
+
* Hash.sha256('0xdeadbeef')
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* @returns The engine that was installed.
|
|
24
|
+
*/
|
|
25
|
+
export async function load(): Promise<load.ReturnType> {
|
|
26
|
+
const engine = await create()
|
|
27
|
+
CoreEngine.set(engine)
|
|
28
|
+
return engine
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export declare namespace load {
|
|
32
|
+
type ReturnType = create.ReturnType
|
|
33
|
+
|
|
34
|
+
type ErrorType =
|
|
35
|
+
| create.ErrorType
|
|
36
|
+
| CoreEngine.set.ErrorType
|
|
37
|
+
| Errors.GlobalErrorType
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Creates every Node.js implementation this entrypoint provides, without
|
|
42
|
+
* installing it.
|
|
43
|
+
*
|
|
44
|
+
* Reach for this where an engine has to exist as a value, such as a benchmark
|
|
45
|
+
* or an [`Engine.with`](/api/Engine/with) scope.
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```ts twoslash
|
|
49
|
+
* // @noErrors
|
|
50
|
+
* import { Engine, Hash } from 'ox'
|
|
51
|
+
* import { Engine as NodeEngine } from 'ox/node'
|
|
52
|
+
*
|
|
53
|
+
* const node = await NodeEngine.create()
|
|
54
|
+
*
|
|
55
|
+
* Engine.with(node, () => Hash.sha256('0xdeadbeef'))
|
|
56
|
+
* ```
|
|
57
|
+
*
|
|
58
|
+
* @returns An engine, ready to install.
|
|
59
|
+
*/
|
|
60
|
+
export async function create(): Promise<create.ReturnType> {
|
|
61
|
+
return { ...(await Hash.create()) }
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export declare namespace create {
|
|
65
|
+
/** Every slot this entrypoint supplies, each with its primitives present. */
|
|
66
|
+
type ReturnType = Hash.create.ReturnType
|
|
67
|
+
|
|
68
|
+
type ErrorType = Hash.create.ErrorType | Errors.GlobalErrorType
|
|
69
|
+
}
|
package/src/node/Hash.ts
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import * as crypto from 'node:crypto'
|
|
2
|
+
import type * as Engine from '../core/Engine.js'
|
|
3
|
+
import type * as Errors from '../core/Errors.js'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Creates Node.js implementations of the [`Hash`](/api/Hash) primitives, without
|
|
7
|
+
* installing them.
|
|
8
|
+
*
|
|
9
|
+
* Most callers want {@link ox#Engine.load} instead, which installs every
|
|
10
|
+
* implementation this entrypoint provides. Reach for this to take the `Hash`
|
|
11
|
+
* slot on its own, or to hold the implementation without touching the
|
|
12
|
+
* installed engine.
|
|
13
|
+
*
|
|
14
|
+
* Node's `sha3-256` is not Ethereum Keccak256, so this engine deliberately
|
|
15
|
+
* omits `keccak256`. Any earlier override remains installed; otherwise Ox uses
|
|
16
|
+
* its default implementation.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```ts twoslash
|
|
20
|
+
* // @noErrors
|
|
21
|
+
* import { Engine, Hash } from 'ox'
|
|
22
|
+
* import * as NodeHash from 'ox/node/Hash'
|
|
23
|
+
*
|
|
24
|
+
* Engine.set(await NodeHash.create())
|
|
25
|
+
*
|
|
26
|
+
* Hash.sha256('0xdeadbeef')
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* @returns An engine supplying the `Hash` slot.
|
|
30
|
+
*/
|
|
31
|
+
export function create(): Promise<create.ReturnType> {
|
|
32
|
+
return Promise.resolve({
|
|
33
|
+
Hash: {
|
|
34
|
+
hmacSha256: (key, message) =>
|
|
35
|
+
new Uint8Array(
|
|
36
|
+
crypto.createHmac('sha256', key).update(message).digest(),
|
|
37
|
+
),
|
|
38
|
+
ripemd160: (input) =>
|
|
39
|
+
new Uint8Array(crypto.hash('ripemd160', input, 'buffer')),
|
|
40
|
+
sha256: (input) => new Uint8Array(crypto.hash('sha256', input, 'buffer')),
|
|
41
|
+
},
|
|
42
|
+
})
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export declare namespace create {
|
|
46
|
+
/** The `Hash` slot, carrying every primitive this module implements. */
|
|
47
|
+
type ReturnType = {
|
|
48
|
+
Hash: {
|
|
49
|
+
[key in 'hmacSha256' | 'ripemd160' | 'sha256']-?: NonNullable<
|
|
50
|
+
Engine.Hash[key]
|
|
51
|
+
>
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
type ErrorType = Errors.GlobalErrorType
|
|
56
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { Engine as CoreEngine, Hash } from 'ox'
|
|
2
|
+
import { Engine } from 'ox/node'
|
|
3
|
+
import { describe, expect, test } from 'vp/test'
|
|
4
|
+
|
|
5
|
+
describe('create', () => {
|
|
6
|
+
test('behavior: does not install', async () => {
|
|
7
|
+
const engine = await Engine.create()
|
|
8
|
+
|
|
9
|
+
expect(Object.keys(engine)).toMatchInlineSnapshot(`
|
|
10
|
+
[
|
|
11
|
+
"Hash",
|
|
12
|
+
]
|
|
13
|
+
`)
|
|
14
|
+
expect(CoreEngine.get()).toMatchInlineSnapshot('{}')
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
test('behavior: installs for the duration of a call', async () => {
|
|
18
|
+
const node = await Engine.create()
|
|
19
|
+
const digest = CoreEngine.with(node, () => Hash.sha256('0xdeadbeef'))
|
|
20
|
+
|
|
21
|
+
expect(digest).toMatchInlineSnapshot(
|
|
22
|
+
`"0x5f78c33274e43fa9de5659265c1d917e25c03722dcb0b8d27db8d5feaa813953"`,
|
|
23
|
+
)
|
|
24
|
+
expect(CoreEngine.get()).toMatchInlineSnapshot('{}')
|
|
25
|
+
})
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
describe('load', () => {
|
|
29
|
+
test('behavior: installs and returns what it installed', async () => {
|
|
30
|
+
const engine = await Engine.load()
|
|
31
|
+
|
|
32
|
+
expect(Object.keys(CoreEngine.get())).toEqual(Object.keys(engine))
|
|
33
|
+
expect(Object.keys(CoreEngine.get().Hash ?? {}).sort())
|
|
34
|
+
.toMatchInlineSnapshot(`
|
|
35
|
+
[
|
|
36
|
+
"hmacSha256",
|
|
37
|
+
"ripemd160",
|
|
38
|
+
"sha256",
|
|
39
|
+
]
|
|
40
|
+
`)
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
test('behavior: leaves unsupported primitives on the default', async () => {
|
|
44
|
+
await Engine.load()
|
|
45
|
+
|
|
46
|
+
expect(Hash.keccak256('0xdeadbeef')).toMatchInlineSnapshot(
|
|
47
|
+
`"0xd4fd4e189132273036449fc9e11198c739161b4c0116a9a2dccdfa1c492006f1"`,
|
|
48
|
+
)
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
test('behavior: merges with later engines', async () => {
|
|
52
|
+
await Engine.load()
|
|
53
|
+
CoreEngine.set({ Mnemonic: { toSeed: () => new Uint8Array(64) } })
|
|
54
|
+
|
|
55
|
+
expect(Object.keys(CoreEngine.get()).sort()).toMatchInlineSnapshot(`
|
|
56
|
+
[
|
|
57
|
+
"Hash",
|
|
58
|
+
"Mnemonic",
|
|
59
|
+
]
|
|
60
|
+
`)
|
|
61
|
+
})
|
|
62
|
+
})
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { Engine } from 'ox'
|
|
2
|
+
import { Hash as NodeHash } from 'ox/node'
|
|
3
|
+
import { expectTypeOf, test } from 'vp/test'
|
|
4
|
+
|
|
5
|
+
type Created = Awaited<ReturnType<typeof NodeHash.create>>
|
|
6
|
+
|
|
7
|
+
test('every implemented primitive is present', () => {
|
|
8
|
+
expectTypeOf<Created['Hash']['hmacSha256']>().toEqualTypeOf<
|
|
9
|
+
(key: Uint8Array, message: Uint8Array) => Uint8Array
|
|
10
|
+
>()
|
|
11
|
+
expectTypeOf<Created['Hash']['ripemd160']>().toEqualTypeOf<
|
|
12
|
+
(input: Uint8Array) => Uint8Array
|
|
13
|
+
>()
|
|
14
|
+
expectTypeOf<Created['Hash']['sha256']>().toEqualTypeOf<
|
|
15
|
+
(input: Uint8Array) => Uint8Array
|
|
16
|
+
>()
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
test('unsupported primitives are absent', () => {
|
|
20
|
+
expectTypeOf<Created['Hash']>().not.toHaveProperty('blake3')
|
|
21
|
+
expectTypeOf<Created['Hash']>().not.toHaveProperty('keccak256')
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
test('the result is still an engine', () => {
|
|
25
|
+
expectTypeOf<Created>().toExtend<Engine.Engine>()
|
|
26
|
+
})
|