@pezkuwi/util-crypto 14.0.1

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 (234) hide show
  1. package/README.md +17 -0
  2. package/package.json +45 -0
  3. package/src/address/addressToEvm.spec.ts +16 -0
  4. package/src/address/addressToEvm.ts +12 -0
  5. package/src/address/check.spec.ts +44 -0
  6. package/src/address/check.ts +34 -0
  7. package/src/address/checksum.spec.ts +45 -0
  8. package/src/address/checksum.ts +25 -0
  9. package/src/address/decode.spec.ts +138 -0
  10. package/src/address/decode.ts +41 -0
  11. package/src/address/defaults.ts +12 -0
  12. package/src/address/derive.spec.ts +26 -0
  13. package/src/address/derive.ts +36 -0
  14. package/src/address/encode.spec.ts +177 -0
  15. package/src/address/encode.ts +43 -0
  16. package/src/address/encodeDerived.spec.ts +14 -0
  17. package/src/address/encodeDerived.ts +19 -0
  18. package/src/address/encodeMulti.spec.ts +18 -0
  19. package/src/address/encodeMulti.ts +18 -0
  20. package/src/address/eq.spec.ts +45 -0
  21. package/src/address/eq.ts +24 -0
  22. package/src/address/evmToAddress.spec.ts +20 -0
  23. package/src/address/evmToAddress.ts +24 -0
  24. package/src/address/index.ts +21 -0
  25. package/src/address/is.spec.ts +113 -0
  26. package/src/address/is.ts +14 -0
  27. package/src/address/keyDerived.spec.ts +24 -0
  28. package/src/address/keyDerived.ts +22 -0
  29. package/src/address/keyMulti.spec.ts +20 -0
  30. package/src/address/keyMulti.ts +23 -0
  31. package/src/address/setSS58Format.spec.ts +21 -0
  32. package/src/address/setSS58Format.ts +20 -0
  33. package/src/address/sort.spec.ts +22 -0
  34. package/src/address/sort.ts +17 -0
  35. package/src/address/sshash.ts +12 -0
  36. package/src/address/types.ts +6 -0
  37. package/src/address/util.ts +8 -0
  38. package/src/address/validate.spec.ts +113 -0
  39. package/src/address/validate.ts +10 -0
  40. package/src/base32/bs32.ts +53 -0
  41. package/src/base32/decode.spec.ts +34 -0
  42. package/src/base32/encode.spec.ts +30 -0
  43. package/src/base32/helpers.ts +93 -0
  44. package/src/base32/index.ts +8 -0
  45. package/src/base32/is.spec.ts +32 -0
  46. package/src/base32/validate.spec.ts +44 -0
  47. package/src/base58/bs58.ts +43 -0
  48. package/src/base58/decode.spec.ts +31 -0
  49. package/src/base58/encode.spec.ts +26 -0
  50. package/src/base58/index.ts +8 -0
  51. package/src/base58/validate.spec.ts +20 -0
  52. package/src/base64/bs64.ts +43 -0
  53. package/src/base64/decode.spec.ts +42 -0
  54. package/src/base64/encode.spec.ts +14 -0
  55. package/src/base64/index.ts +10 -0
  56. package/src/base64/pad.spec.ts +14 -0
  57. package/src/base64/pad.ts +10 -0
  58. package/src/base64/trim.spec.ts +14 -0
  59. package/src/base64/trim.ts +14 -0
  60. package/src/base64/validate.spec.ts +32 -0
  61. package/src/blake2/asHex.spec.ts +57 -0
  62. package/src/blake2/asU8a.spec.ts +74 -0
  63. package/src/blake2/asU8a.ts +40 -0
  64. package/src/blake2/index.ts +8 -0
  65. package/src/bn.ts +15 -0
  66. package/src/bundle.ts +33 -0
  67. package/src/bundleInit.ts +11 -0
  68. package/src/crypto.spec.ts +18 -0
  69. package/src/crypto.ts +18 -0
  70. package/src/ed25519/deriveHard.ts +18 -0
  71. package/src/ed25519/index.ts +13 -0
  72. package/src/ed25519/pair/fromRandom.spec.ts +28 -0
  73. package/src/ed25519/pair/fromRandom.ts +25 -0
  74. package/src/ed25519/pair/fromSecret.spec.ts +33 -0
  75. package/src/ed25519/pair/fromSecret.ts +29 -0
  76. package/src/ed25519/pair/fromSeed.spec.ts +42 -0
  77. package/src/ed25519/pair/fromSeed.ts +41 -0
  78. package/src/ed25519/pair/fromString.spec.ts +17 -0
  79. package/src/ed25519/pair/fromString.ts +31 -0
  80. package/src/ed25519/sign.spec.ts +40 -0
  81. package/src/ed25519/sign.ts +38 -0
  82. package/src/ed25519/verify.spec.ts +84 -0
  83. package/src/ed25519/verify.ts +41 -0
  84. package/src/ethereum/encode.spec.ts +59 -0
  85. package/src/ethereum/encode.ts +39 -0
  86. package/src/ethereum/index.ts +6 -0
  87. package/src/ethereum/isAddress.spec.ts +34 -0
  88. package/src/ethereum/isAddress.ts +16 -0
  89. package/src/ethereum/isChecksum.ts +27 -0
  90. package/src/ethereum/isCheksum.spec.ts +30 -0
  91. package/src/hd/ethereum/index.spec.ts +54 -0
  92. package/src/hd/ethereum/index.ts +69 -0
  93. package/src/hd/index.ts +6 -0
  94. package/src/hd/ledger/derivePrivate.ts +34 -0
  95. package/src/hd/ledger/index.spec.ts +64 -0
  96. package/src/hd/ledger/index.ts +42 -0
  97. package/src/hd/ledger/master.spec.ts +19 -0
  98. package/src/hd/ledger/master.ts +26 -0
  99. package/src/hd/validatePath.spec.ts +30 -0
  100. package/src/hd/validatePath.ts +24 -0
  101. package/src/helpers.ts +38 -0
  102. package/src/hmac/index.ts +4 -0
  103. package/src/hmac/shaAsU8a.spec.ts +45 -0
  104. package/src/hmac/shaAsU8a.ts +48 -0
  105. package/src/index.ts +6 -0
  106. package/src/json/constants.ts +11 -0
  107. package/src/json/decrypt.ts +25 -0
  108. package/src/json/decryptData.ts +45 -0
  109. package/src/json/encrypt.ts +25 -0
  110. package/src/json/encryptFormat.ts +20 -0
  111. package/src/json/index.ts +7 -0
  112. package/src/json/types.ts +22 -0
  113. package/src/keccak/asHex.spec.ts +30 -0
  114. package/src/keccak/asU8a.spec.ts +56 -0
  115. package/src/keccak/asU8a.ts +45 -0
  116. package/src/keccak/index.ts +8 -0
  117. package/src/key/DeriveJunction.ts +79 -0
  118. package/src/key/extractPath.spec.ts +51 -0
  119. package/src/key/extractPath.ts +37 -0
  120. package/src/key/extractSuri.spec.ts +147 -0
  121. package/src/key/extractSuri.ts +40 -0
  122. package/src/key/fromPath.ts +28 -0
  123. package/src/key/hdkdDerive.ts +17 -0
  124. package/src/key/hdkdEcdsa.ts +8 -0
  125. package/src/key/hdkdEd25519.ts +7 -0
  126. package/src/key/hdkdSr25519.ts +14 -0
  127. package/src/key/index.ts +12 -0
  128. package/src/mnemonic/bip39.spec.ts +80 -0
  129. package/src/mnemonic/bip39.ts +127 -0
  130. package/src/mnemonic/generate.spec.ts +58 -0
  131. package/src/mnemonic/generate.ts +25 -0
  132. package/src/mnemonic/index.ts +11 -0
  133. package/src/mnemonic/toEntropy.spec.ts +36 -0
  134. package/src/mnemonic/toEntropy.ts +13 -0
  135. package/src/mnemonic/toLegacySeed.spec.ts +52 -0
  136. package/src/mnemonic/toLegacySeed.ts +39 -0
  137. package/src/mnemonic/toMiniSecret.spec.ts +67 -0
  138. package/src/mnemonic/toMiniSecret.ts +23 -0
  139. package/src/mnemonic/toMiniSecretCmp.spec.ts +64 -0
  140. package/src/mnemonic/validate.spec.ts +39 -0
  141. package/src/mnemonic/validate.ts +26 -0
  142. package/src/mnemonic/wordlists/en.ts +7 -0
  143. package/src/mnemonic/wordlists/es.ts +7 -0
  144. package/src/mnemonic/wordlists/fr.ts +7 -0
  145. package/src/mnemonic/wordlists/index.ts +11 -0
  146. package/src/mnemonic/wordlists/it.ts +7 -0
  147. package/src/mnemonic/wordlists/jp.ts +7 -0
  148. package/src/mnemonic/wordlists/ko.ts +7 -0
  149. package/src/mnemonic/wordlists/zh-s.ts +7 -0
  150. package/src/mnemonic/wordlists/zh-t.ts +7 -0
  151. package/src/mod.ts +4 -0
  152. package/src/nacl/decrypt.spec.ts +26 -0
  153. package/src/nacl/decrypt.ts +22 -0
  154. package/src/nacl/encrypt.spec.ts +20 -0
  155. package/src/nacl/encrypt.ts +31 -0
  156. package/src/nacl/index.ts +8 -0
  157. package/src/nacl/tweetnacl-secretbox-data.spec.ts +4629 -0
  158. package/src/nacl/tweetnacl-secretbox.spec.ts +161 -0
  159. package/src/nacl/tweetnacl.ts +1159 -0
  160. package/src/networks.ts +5 -0
  161. package/src/packageDetect.ts +14 -0
  162. package/src/packageInfo.ts +6 -0
  163. package/src/pbkdf2/encode.spec.ts +54 -0
  164. package/src/pbkdf2/encode.ts +29 -0
  165. package/src/pbkdf2/index.ts +4 -0
  166. package/src/random/asHex.spec.ts +38 -0
  167. package/src/random/asNumber.spec.ts +16 -0
  168. package/src/random/asNumber.ts +28 -0
  169. package/src/random/asU8a.spec.ts +36 -0
  170. package/src/random/asU8a.ts +30 -0
  171. package/src/random/index.ts +9 -0
  172. package/src/scrypt/defaults.ts +19 -0
  173. package/src/scrypt/encode.spec.ts +43 -0
  174. package/src/scrypt/encode.ts +30 -0
  175. package/src/scrypt/fromU8a.ts +44 -0
  176. package/src/scrypt/index.ts +6 -0
  177. package/src/scrypt/toU8a.ts +17 -0
  178. package/src/scrypt/types.ts +9 -0
  179. package/src/secp256k1/compress.spec.ts +47 -0
  180. package/src/secp256k1/compress.ts +21 -0
  181. package/src/secp256k1/deriveHard.ts +17 -0
  182. package/src/secp256k1/expand.spec.ts +47 -0
  183. package/src/secp256k1/expand.ts +30 -0
  184. package/src/secp256k1/hasher.spec.ts +24 -0
  185. package/src/secp256k1/hasher.ts +13 -0
  186. package/src/secp256k1/index.ts +10 -0
  187. package/src/secp256k1/pair/fromSeed.spec.ts +75 -0
  188. package/src/secp256k1/pair/fromSeed.ts +42 -0
  189. package/src/secp256k1/recover.spec.ts +35 -0
  190. package/src/secp256k1/recover.ts +36 -0
  191. package/src/secp256k1/sign.spec.ts +39 -0
  192. package/src/secp256k1/sign.ts +37 -0
  193. package/src/secp256k1/signVerify.spec.ts +94 -0
  194. package/src/secp256k1/tweakAdd.spec.ts +35 -0
  195. package/src/secp256k1/tweakAdd.ts +65 -0
  196. package/src/secp256k1/types.ts +4 -0
  197. package/src/secp256k1/verify.spec.ts +81 -0
  198. package/src/secp256k1/verify.ts +32 -0
  199. package/src/sha/asU8a.ts +30 -0
  200. package/src/sha/asU8a256.spec.ts +55 -0
  201. package/src/sha/asU8a512.spec.ts +33 -0
  202. package/src/sha/index.ts +8 -0
  203. package/src/signature/index.ts +8 -0
  204. package/src/signature/verify.spec.ts +230 -0
  205. package/src/signature/verify.ts +114 -0
  206. package/src/sr25519/agreement.spec.ts +31 -0
  207. package/src/sr25519/agreement.ts +23 -0
  208. package/src/sr25519/derive.ts +21 -0
  209. package/src/sr25519/deriveHard.ts +9 -0
  210. package/src/sr25519/derivePublic.ts +18 -0
  211. package/src/sr25519/deriveSoft.ts +9 -0
  212. package/src/sr25519/index.ts +12 -0
  213. package/src/sr25519/pair/fromSeed.spec.ts +35 -0
  214. package/src/sr25519/pair/fromSeed.ts +28 -0
  215. package/src/sr25519/pair/fromU8a.ts +23 -0
  216. package/src/sr25519/pair/testing.spec.ts +161 -0
  217. package/src/sr25519/pair/toU8a.ts +10 -0
  218. package/src/sr25519/sign.spec.ts +28 -0
  219. package/src/sr25519/sign.ts +22 -0
  220. package/src/sr25519/verify.spec.ts +42 -0
  221. package/src/sr25519/verify.ts +23 -0
  222. package/src/sr25519/vrfSign.ts +24 -0
  223. package/src/sr25519/vrfSignVerify.spec.ts +73 -0
  224. package/src/sr25519/vrfVerify.ts +25 -0
  225. package/src/test/index.ts +8 -0
  226. package/src/test/performance.ts +17 -0
  227. package/src/types.ts +33 -0
  228. package/src/xxhash/asHex.spec.ts +36 -0
  229. package/src/xxhash/asU8a.spec.ts +48 -0
  230. package/src/xxhash/asU8a.ts +45 -0
  231. package/src/xxhash/index.ts +8 -0
  232. package/src/xxhash/xxhash64.ts +155 -0
  233. package/tsconfig.build.json +18 -0
  234. package/tsconfig.spec.json +20 -0
@@ -0,0 +1,113 @@
1
+ // Copyright 2017-2025 @polkadot/util-crypto authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ /// <reference types="@polkadot/dev-test/globals.d.ts" />
5
+
6
+ import { validateAddress } from './index.js';
7
+
8
+ describe('validateAddress', (): void => {
9
+ it('decodes an address', (): void => {
10
+ expect(
11
+ validateAddress('5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY')
12
+ ).toEqual(true);
13
+ });
14
+
15
+ it('decodes the council address', (): void => {
16
+ expect(
17
+ validateAddress('F3opxRbN5ZbjJNU511Kj2TLuzFcDq9BGduA9TgiECafpg29')
18
+ ).toEqual(true);
19
+ });
20
+
21
+ it('converts a publicKey (hex) as-is', (): void => {
22
+ expect(
23
+ validateAddress('0x01020304')
24
+ ).toEqual(true);
25
+ });
26
+
27
+ it('decodes a short address', (): void => {
28
+ expect(
29
+ validateAddress('F7NZ')
30
+ ).toEqual(true);
31
+ });
32
+
33
+ it('decodes a 1-byte accountId (with prefix)', (): void => {
34
+ expect(
35
+ validateAddress('g4b', false, 2)
36
+ ).toEqual(true);
37
+ });
38
+
39
+ it('decodes a 2-byte accountId', (): void => {
40
+ expect(
41
+ validateAddress('3xygo', false, 2)
42
+ ).toEqual(true);
43
+ });
44
+
45
+ it('encodes a 4-byte address', (): void => {
46
+ expect(
47
+ validateAddress('zswfoZa', false, 2)
48
+ ).toEqual(true);
49
+ });
50
+
51
+ it('decodes a 8-byte address', (): void => {
52
+ expect(
53
+ validateAddress('848Gh2GcGaZia', false, 2)
54
+ ).toEqual(true);
55
+ });
56
+
57
+ it('decodes a 33-byte address', (): void => {
58
+ expect(
59
+ validateAddress('KWCv1L3QX9LDPwY4VzvLmarEmXjVJidUzZcinvVnmxAJJCBou')
60
+ ).toEqual(true);
61
+ });
62
+
63
+ it('decodes a 2-byte prefix (65)', (): void => {
64
+ expect(
65
+ validateAddress('cLtA6nCDyvwKcEHH4QkZDSHMhS9s78BvUJUsKUbUAn1Jc2SCF')
66
+ ).toEqual(true);
67
+ });
68
+
69
+ it('decodes a 2-byte prefix (69)', (): void => {
70
+ expect(
71
+ validateAddress('cnUaoo5wodnTVA4bnr4woSweto8hWZADUvLFXkR9Q6U7BRsbF')
72
+ ).toEqual(true);
73
+ });
74
+
75
+ it('decodes a 2-byte prefix (252)', (): void => {
76
+ expect(
77
+ validateAddress('xw9Hca4RJTmBRgzJT4ieJBh7XCK9gE3NXBDSEmgGHd4TCrbnG')
78
+ ).toEqual(true);
79
+ });
80
+
81
+ it('decodes a 2-byte prefix (255)', (): void => {
82
+ expect(
83
+ validateAddress('yGHU8YKprxHbHdEv7oUK4rzMZXtsdhcXVG2CAMyC9WhzhjH2k')
84
+ ).toEqual(true);
85
+ });
86
+
87
+ it('decodes a 2-byte prefix (ecdsa, from Substrate)', (): void => {
88
+ expect(
89
+ validateAddress('4pbsSkWcBaYoFHrKJZp5fDVUKbqSYD9dhZZGvpp3vQ5ysVs5ybV')
90
+ ).toEqual(true);
91
+ });
92
+
93
+ it('fails when length is invalid', (): void => {
94
+ expect(
95
+ () => validateAddress('y9EMHt34JJo4rWLSaxoLGdYXvjgSXEd4zHUnQgfNzwES8b')
96
+ ).toThrow(/address length/);
97
+ });
98
+
99
+ it('fails when the checksum does not match', (): void => {
100
+ expect(
101
+ () => validateAddress('5GoKvZWG5ZPYL1WUovuHW3zJBWBP5eT8CbqjdRY4Q6iMa9cj')
102
+ ).toThrow(/address checksum/);
103
+ expect(
104
+ () => validateAddress('5GoKvZWG5ZPYL1WUovuHW3zJBWBP5eT8CbqjdRY4Q6iMaDwU')
105
+ ).toThrow(/address checksum/);
106
+ });
107
+
108
+ it('fails when invalid base58 encoded address is found', (): void => {
109
+ expect(
110
+ () => validateAddress('F3opIRbN5ZbjJNU511Kj2TLuzFcDq9BGduA9TgiECafpg29')
111
+ ).toThrow(/Decoding F3opIRbN5ZbjJNU511Kj2TLuzFcDq9BGduA9TgiECafpg29: Invalid base58 character "I" \(0x49\) at index 4/);
112
+ });
113
+ });
@@ -0,0 +1,10 @@
1
+ // Copyright 2017-2025 @polkadot/util-crypto authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import type { Prefix } from './types.js';
5
+
6
+ import { decodeAddress } from './decode.js';
7
+
8
+ export function validateAddress (encoded?: string | null, ignoreChecksum?: boolean, ss58Format?: Prefix): encoded is string {
9
+ return !!decodeAddress(encoded, ignoreChecksum, ss58Format);
10
+ }
@@ -0,0 +1,53 @@
1
+ // Copyright 2017-2025 @polkadot/util-crypto authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { utils } from '@scure/base';
5
+
6
+ import { createDecode, createEncode, createIs, createValidate } from './helpers.js';
7
+
8
+ const chars = 'abcdefghijklmnopqrstuvwxyz234567';
9
+
10
+ const config = {
11
+ chars,
12
+ coder: utils.chain(
13
+ // We define our own chain, the default base32 has padding
14
+ utils.radix2(5),
15
+ utils.alphabet(chars),
16
+ {
17
+ decode: (input: string) => input.split(''),
18
+ encode: (input: string[]) => input.join('')
19
+ }
20
+ ),
21
+ ipfs: 'b',
22
+ type: 'base32'
23
+ };
24
+
25
+ /**
26
+ * @name base32Validate
27
+ * @summary Validates a base32 value.
28
+ * @description
29
+ * Validates that the supplied value is valid base32, throwing exceptions if not
30
+ */
31
+ export const base32Validate = /*#__PURE__*/ createValidate(config);
32
+
33
+ /**
34
+ * @name isBase32
35
+ * @description Checks if the input is in base32, returning true/false
36
+ */
37
+ export const isBase32 = /*#__PURE__*/ createIs(base32Validate);
38
+
39
+ /**
40
+ * @name base32Decode
41
+ * @summary Delookup a base32 value.
42
+ * @description
43
+ * From the provided input, decode the base32 and return the result as an `Uint8Array`.
44
+ */
45
+ export const base32Decode = /*#__PURE__*/ createDecode(config, base32Validate);
46
+
47
+ /**
48
+ * @name base32Encode
49
+ * @summary Creates a base32 value.
50
+ * @description
51
+ * From the provided input, create the base32 and return the result as a string.
52
+ */
53
+ export const base32Encode = /*#__PURE__*/ createEncode(config);
@@ -0,0 +1,34 @@
1
+ // Copyright 2017-2025 @polkadot/util-crypto authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ /// <reference types="@polkadot/dev-test/globals.d.ts" />
5
+
6
+ import { u8aToString } from '@pezkuwi/util';
7
+
8
+ import { base32Decode } from './index.js';
9
+
10
+ describe('base32Decode', (): void => {
11
+ it('decodes an empty string)', (): void => {
12
+ expect(
13
+ u8aToString(
14
+ base32Decode('')
15
+ )
16
+ ).toEqual('');
17
+ });
18
+
19
+ it('decodes a base32', (): void => {
20
+ expect(
21
+ u8aToString(
22
+ base32Decode('irswgzloorzgc3djpjssazlwmvzhs5dinfxgoijb')
23
+ )
24
+ ).toEqual('Decentralize everything!!');
25
+ });
26
+
27
+ it('decodes a base32 (ipfsCompat)', (): void => {
28
+ expect(
29
+ u8aToString(
30
+ base32Decode('birswgzloorzgc3djpjssazlwmvzhs5dinfxgoijb', true)
31
+ )
32
+ ).toEqual('Decentralize everything!!');
33
+ });
34
+ });
@@ -0,0 +1,30 @@
1
+ // Copyright 2017-2025 @polkadot/util-crypto authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ /// <reference types="@polkadot/dev-test/globals.d.ts" />
5
+
6
+ import { base58Decode } from '../base58/index.js';
7
+ import { base32Encode } from './index.js';
8
+
9
+ describe('base32Encode', (): void => {
10
+ it('encodes to a base32', (): void => {
11
+ expect(
12
+ base32Encode('Decentralize everything!!')
13
+ ).toEqual('irswgzloorzgc3djpjssazlwmvzhs5dinfxgoijb');
14
+ });
15
+
16
+ it('encodes to a base32 (ipfs-compat)', (): void => {
17
+ expect(
18
+ base32Encode('Decentralize everything!!', true)
19
+ ).toEqual('birswgzloorzgc3djpjssazlwmvzhs5dinfxgoijb');
20
+ });
21
+
22
+ it('encodes a base58 to a base32', (): void => {
23
+ expect(
24
+ base32Encode(
25
+ base58Decode('zb2rhk6GMPQF3hfzwXTaNYFLKomMeC6UXdUt6jZKPpeVirLtV', true),
26
+ true
27
+ )
28
+ ).toEqual('bafkreigh2akiscaildcqabsyg3dfr6chu3fgpregiymsck7e7aqa4s52zy');
29
+ });
30
+ });
@@ -0,0 +1,93 @@
1
+ // Copyright 2017-2025 @polkadot/util-crypto authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import type { U8aLike } from '@pezkuwi/util/types';
5
+
6
+ import { u8aToU8a } from '@pezkuwi/util';
7
+
8
+ // re-export the type so *.d.ts files don't have ../src imports
9
+ export type { U8aLike } from '@pezkuwi/util/types';
10
+
11
+ interface Coder {
12
+ decode: (value: string) => Uint8Array;
13
+ encode: (value: Uint8Array) => string;
14
+ }
15
+
16
+ interface Config {
17
+ chars: string;
18
+ coder: Coder;
19
+ ipfs?: string;
20
+ regex?: RegExp;
21
+ type: string;
22
+ withPadding?: boolean;
23
+ }
24
+
25
+ type DecodeFn = (value: string, ipfsCompat?: boolean) => Uint8Array;
26
+
27
+ type EncodeFn = (value: U8aLike, ipfsCompat?: boolean) => string;
28
+
29
+ type ValidateFn = (value?: unknown, ipfsCompat?: boolean) => value is string;
30
+
31
+ /** @internal */
32
+ export function createDecode ({ coder, ipfs }: Config, validate: ValidateFn): DecodeFn {
33
+ return (value: string, ipfsCompat?: boolean): Uint8Array => {
34
+ validate(value, ipfsCompat);
35
+
36
+ return coder.decode(
37
+ ipfs && ipfsCompat
38
+ ? value.substring(1)
39
+ : value
40
+ );
41
+ };
42
+ }
43
+
44
+ /** @internal */
45
+ export function createEncode ({ coder, ipfs }: Config): EncodeFn {
46
+ return (value: U8aLike, ipfsCompat?: boolean): string => {
47
+ const out = coder.encode(u8aToU8a(value));
48
+
49
+ return ipfs && ipfsCompat
50
+ ? `${ipfs}${out}`
51
+ : out;
52
+ };
53
+ }
54
+
55
+ /** @internal */
56
+ export function createIs (validate: ValidateFn): ValidateFn {
57
+ return (value?: unknown, ipfsCompat?: boolean): value is string => {
58
+ try {
59
+ return validate(value, ipfsCompat);
60
+ } catch {
61
+ return false;
62
+ }
63
+ };
64
+ }
65
+
66
+ /** @internal */
67
+ export function createValidate ({ chars, ipfs, type, withPadding }: Config): ValidateFn {
68
+ return (value?: unknown, ipfsCompat?: boolean): value is string => {
69
+ if (typeof value !== 'string') {
70
+ throw new Error(`Expected ${type} string input`);
71
+ } else if (ipfs && ipfsCompat && !value.startsWith(ipfs)) {
72
+ throw new Error(`Expected ipfs-compatible ${type} to start with '${ipfs}'`);
73
+ }
74
+
75
+ for (let i = (ipfsCompat ? 1 : 0), count = value.length; i < count; i++) {
76
+ if (chars.includes(value[i])) {
77
+ // all ok, character found
78
+ } else if (withPadding && value[i] === '=') {
79
+ if (i === count - 1) {
80
+ // last character, everything ok
81
+ } else if (value[i + 1] === '=') {
82
+ // next one is also padding, sequence ok
83
+ } else {
84
+ throw new Error(`Invalid ${type} padding sequence "${value[i]}${value[i + 1]}" at index ${i}`);
85
+ }
86
+ } else {
87
+ throw new Error(`Invalid ${type} character "${value[i]}" (0x${value.charCodeAt(i).toString(16)}) at index ${i}`);
88
+ }
89
+ }
90
+
91
+ return true;
92
+ };
93
+ }
@@ -0,0 +1,8 @@
1
+ // Copyright 2017-2025 @polkadot/util-crypto authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ /**
5
+ * @summary Encode and decode base32 values
6
+ */
7
+
8
+ export { base32Decode, base32Encode, base32Validate, isBase32 } from './bs32.js';
@@ -0,0 +1,32 @@
1
+ // Copyright 2017-2025 @polkadot/util-crypto authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ /// <reference types="@polkadot/dev-test/globals.d.ts" />
5
+
6
+ import { isBase32 } from './index.js';
7
+
8
+ describe('isBase32', (): void => {
9
+ it('validates encoded', (): void => {
10
+ expect(
11
+ isBase32('afkreigh2akiscaildcqabsyg3dfr6chu3fgpregiymsck7e7aqa4s52zy', false)
12
+ ).toEqual(true);
13
+ });
14
+
15
+ it('validates ipfs-compat encoded', (): void => {
16
+ expect(
17
+ isBase32('bafkreigh2akiscaildcqabsyg3dfr6chu3fgpregiymsck7e7aqa4s52zy', false)
18
+ ).toEqual(true);
19
+ });
20
+
21
+ it('fails on invalid', (): void => {
22
+ expect(
23
+ isBase32('not in base32')
24
+ ).toEqual(false);
25
+ });
26
+
27
+ it('fails on non-ipfs', (): void => {
28
+ expect(
29
+ isBase32('afkreigh2akiscaildcqabsyg3dfr6chu3fgpregiymsck7e7aqa4s52zy', true)
30
+ ).toEqual(false);
31
+ });
32
+ });
@@ -0,0 +1,44 @@
1
+ // Copyright 2017-2025 @polkadot/util-crypto authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ /// <reference types="@polkadot/dev-test/globals.d.ts" />
5
+
6
+ import { base32Validate } from './index.js';
7
+
8
+ describe('base32Validate', (): void => {
9
+ it('validates encoded', (): void => {
10
+ expect(
11
+ base32Validate('afkreigh2akiscaildcqabsyg3dfr6chu3fgpregiymsck7e7aqa4s52zy', false)
12
+ ).toEqual(true);
13
+ });
14
+
15
+ it('validates ipfs-compat encoded', (): void => {
16
+ expect(
17
+ base32Validate('bafkreigh2akiscaildcqabsyg3dfr6chu3fgpregiymsck7e7aqa4s52zy', true)
18
+ ).toEqual(true);
19
+ });
20
+
21
+ it('does not fail on empty', (): void => {
22
+ expect(
23
+ base32Validate('')
24
+ ).toEqual(true);
25
+ });
26
+
27
+ it('fails on non-string', (): void => {
28
+ expect(
29
+ () => base32Validate(true)
30
+ ).toThrow(/Expected/);
31
+ });
32
+
33
+ it('fails on invalid', (): void => {
34
+ expect(
35
+ () => base32Validate('not in base32')
36
+ ).toThrow(/Invalid/);
37
+ });
38
+
39
+ it('fails on non-ipfs', (): void => {
40
+ expect(
41
+ () => base32Validate('afkreigh2akiscaildcqabsyg3dfr6chu3fgpregiymsck7e7aqa4s52zy', true)
42
+ ).toThrow(/Expected/);
43
+ });
44
+ });
@@ -0,0 +1,43 @@
1
+ // Copyright 2017-2025 @polkadot/util-crypto authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { base58 } from '@scure/base';
5
+
6
+ import { createDecode, createEncode, createIs, createValidate } from '../base32/helpers.js';
7
+
8
+ const config = {
9
+ chars: '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz',
10
+ coder: base58,
11
+ ipfs: 'z',
12
+ type: 'base58'
13
+ };
14
+
15
+ /**
16
+ * @name base58Validate
17
+ * @summary Validates a base58 value.
18
+ * @description
19
+ * Validates that the supplied value is valid base58, throwing exceptions if not
20
+ */
21
+ export const base58Validate = /*#__PURE__*/ createValidate(config);
22
+
23
+ /**
24
+ * @name base58Decode
25
+ * @summary Decodes a base58 value.
26
+ * @description
27
+ * From the provided input, decode the base58 and return the result as an `Uint8Array`.
28
+ */
29
+ export const base58Decode = /*#__PURE__*/ createDecode(config, base58Validate);
30
+
31
+ /**
32
+ * @name base58Encode
33
+ * @summary Creates a base58 value.
34
+ * @description
35
+ * From the provided input, create the base58 and return the result as a string.
36
+ */
37
+ export const base58Encode = /*#__PURE__*/ createEncode(config);
38
+
39
+ /**
40
+ * @name isBase58
41
+ * @description Checks if the input is in base58, returning true/false
42
+ */
43
+ export const isBase58 = /*#__PURE__*/ createIs(base58Validate);
@@ -0,0 +1,31 @@
1
+ // Copyright 2017-2025 @polkadot/util-crypto authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ /// <reference types="@polkadot/dev-test/globals.d.ts" />
5
+
6
+ import { base32Decode } from '../base32/index.js';
7
+ import { base58Decode } from './index.js';
8
+
9
+ describe('base58Encode', (): void => {
10
+ it('decodes an empty string)', (): void => {
11
+ expect(
12
+ base58Decode('')
13
+ ).toEqual(new Uint8Array());
14
+ });
15
+
16
+ it('encodes a base58 to a base32', (): void => {
17
+ expect(
18
+ base58Decode('b2rhk6GMPQF3hfzwXTaNYFLKomMeC6UXdUt6jZKPpeVirLtV')
19
+ ).toEqual(
20
+ base32Decode('afkreigh2akiscaildcqabsyg3dfr6chu3fgpregiymsck7e7aqa4s52zy')
21
+ );
22
+ });
23
+
24
+ it('encodes a base58 to a base32 (ipfs-compat)', (): void => {
25
+ expect(
26
+ base58Decode('zb2rhk6GMPQF3hfzwXTaNYFLKomMeC6UXdUt6jZKPpeVirLtV', true)
27
+ ).toEqual(
28
+ base32Decode('bafkreigh2akiscaildcqabsyg3dfr6chu3fgpregiymsck7e7aqa4s52zy', true)
29
+ );
30
+ });
31
+ });
@@ -0,0 +1,26 @@
1
+ // Copyright 2017-2025 @polkadot/util-crypto authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ /// <reference types="@polkadot/dev-test/globals.d.ts" />
5
+
6
+ import { base32Decode } from '../base32/index.js';
7
+ import { base58Encode } from './index.js';
8
+
9
+ describe('base58Encode', (): void => {
10
+ it('encodes a base32 to a base58', (): void => {
11
+ expect(
12
+ base58Encode(
13
+ base32Decode('bafkreigh2akiscaildcqabsyg3dfr6chu3fgpregiymsck7e7aqa4s52zy', true)
14
+ )
15
+ ).toEqual('b2rhk6GMPQF3hfzwXTaNYFLKomMeC6UXdUt6jZKPpeVirLtV');
16
+ });
17
+
18
+ it('encodes a base32 to a base58 (ipfs-compat)', (): void => {
19
+ expect(
20
+ base58Encode(
21
+ base32Decode('bafkreigh2akiscaildcqabsyg3dfr6chu3fgpregiymsck7e7aqa4s52zy', true),
22
+ true
23
+ )
24
+ ).toEqual('zb2rhk6GMPQF3hfzwXTaNYFLKomMeC6UXdUt6jZKPpeVirLtV');
25
+ });
26
+ });
@@ -0,0 +1,8 @@
1
+ // Copyright 2017-2025 @polkadot/util-crypto authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ /**
5
+ * @summary Encode and decode base58 values
6
+ */
7
+
8
+ export { base58Decode, base58Encode, base58Validate, isBase58 } from './bs58.js';
@@ -0,0 +1,20 @@
1
+ // Copyright 2017-2025 @polkadot/util-crypto authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ /// <reference types="@polkadot/dev-test/globals.d.ts" />
5
+
6
+ import { base58Validate } from './index.js';
7
+
8
+ describe('base58Validate', (): void => {
9
+ it('validates encoded', (): void => {
10
+ expect(
11
+ base58Validate('a1UbyspTdnyZXLUQaQbciCxrCWWxz24kgSwGXSQnkbs', false)
12
+ ).toEqual(true);
13
+ });
14
+
15
+ it('fails on string with extra padding', (): void => {
16
+ expect(
17
+ () => base58Validate('a1UbyspTdnyZXLUQaQbciCxrCWWxz24kgSwGXSQnkbs=', false)
18
+ ).toThrow(/Invalid base58 character "="/);
19
+ });
20
+ });
@@ -0,0 +1,43 @@
1
+ // Copyright 2017-2025 @polkadot/util-crypto authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { base64 } from '@scure/base';
5
+
6
+ import { createDecode, createEncode, createIs, createValidate } from '../base32/helpers.js';
7
+
8
+ const config = {
9
+ chars: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',
10
+ coder: base64,
11
+ type: 'base64',
12
+ withPadding: true
13
+ };
14
+
15
+ /**
16
+ * @name base64Validate
17
+ * @summary Validates a base64 value.
18
+ * @description
19
+ * Validates that the supplied value is valid base64
20
+ */
21
+ export const base64Validate = /*#__PURE__*/ createValidate(config);
22
+
23
+ /**
24
+ * @name isBase64
25
+ * @description Checks if the input is in base64, returning true/false
26
+ */
27
+ export const isBase64 = /*#__PURE__*/ createIs(base64Validate);
28
+
29
+ /**
30
+ * @name base64Decode
31
+ * @summary Decodes a base64 value.
32
+ * @description
33
+ * From the provided input, decode the base64 and return the result as an `Uint8Array`.
34
+ */
35
+ export const base64Decode = /*#__PURE__*/ createDecode(config, base64Validate);
36
+
37
+ /**
38
+ * @name base64Encode
39
+ * @summary Creates a base64 value.
40
+ * @description
41
+ * From the provided input, create the base64 and return the result as a string.
42
+ */
43
+ export const base64Encode = /*#__PURE__*/ createEncode(config);
@@ -0,0 +1,42 @@
1
+ // Copyright 2017-2025 @polkadot/util-crypto authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ /// <reference types="@polkadot/dev-test/globals.d.ts" />
5
+
6
+ import { stringToU8a } from '@pezkuwi/util';
7
+
8
+ import { base64Decode } from './index.js';
9
+
10
+ describe('base64Decode', (): void => {
11
+ it('decodes an empty string)', (): void => {
12
+ expect(
13
+ base64Decode('')
14
+ ).toEqual(
15
+ stringToU8a('')
16
+ );
17
+ });
18
+
19
+ it('decodes a mixed base64 utf8 string (1)', (): void => {
20
+ expect(
21
+ base64Decode('aGVsbG8gd29ybGQg0J/RgNC40LLQtdGC0YHRgtCy0YPRjiDQvNC4IOS9oOWlvQ==')
22
+ ).toEqual(
23
+ stringToU8a('hello world Приветствую ми 你好')
24
+ );
25
+ });
26
+
27
+ it('decodes a mixed base64 utf8 string (2)', (): void => {
28
+ expect(
29
+ base64Decode('4pyTIMOgIGxhIG1vZGU=')
30
+ ).toEqual(
31
+ stringToU8a('✓ à la mode')
32
+ );
33
+ });
34
+
35
+ it('decodes a mixed base64 utf8 string (3)', (): void => {
36
+ expect(
37
+ base64Decode('SGVsbG8gV29ybGQh')
38
+ ).toEqual(
39
+ stringToU8a('Hello World!')
40
+ );
41
+ });
42
+ });
@@ -0,0 +1,14 @@
1
+ // Copyright 2017-2025 @polkadot/util-crypto authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ /// <reference types="@polkadot/dev-test/globals.d.ts" />
5
+
6
+ import { base64Encode } from './index.js';
7
+
8
+ describe('base64Encode', (): void => {
9
+ it('encodes a mixed base64 utf8 string', (): void => {
10
+ expect(
11
+ base64Encode('hello world Приветствую ми 你好')
12
+ ).toEqual('aGVsbG8gd29ybGQg0J/RgNC40LLQtdGC0YHRgtCy0YPRjiDQvNC4IOS9oOWlvQ==');
13
+ });
14
+ });
@@ -0,0 +1,10 @@
1
+ // Copyright 2017-2025 @polkadot/util-crypto authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ /**
5
+ * @summary Encode and decode base64 values
6
+ */
7
+
8
+ export { base64Decode, base64Encode, base64Validate, isBase64 } from './bs64.js';
9
+ export { base64Pad } from './pad.js';
10
+ export { base64Trim } from './trim.js';