@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.
- package/README.md +17 -0
- package/package.json +45 -0
- package/src/address/addressToEvm.spec.ts +16 -0
- package/src/address/addressToEvm.ts +12 -0
- package/src/address/check.spec.ts +44 -0
- package/src/address/check.ts +34 -0
- package/src/address/checksum.spec.ts +45 -0
- package/src/address/checksum.ts +25 -0
- package/src/address/decode.spec.ts +138 -0
- package/src/address/decode.ts +41 -0
- package/src/address/defaults.ts +12 -0
- package/src/address/derive.spec.ts +26 -0
- package/src/address/derive.ts +36 -0
- package/src/address/encode.spec.ts +177 -0
- package/src/address/encode.ts +43 -0
- package/src/address/encodeDerived.spec.ts +14 -0
- package/src/address/encodeDerived.ts +19 -0
- package/src/address/encodeMulti.spec.ts +18 -0
- package/src/address/encodeMulti.ts +18 -0
- package/src/address/eq.spec.ts +45 -0
- package/src/address/eq.ts +24 -0
- package/src/address/evmToAddress.spec.ts +20 -0
- package/src/address/evmToAddress.ts +24 -0
- package/src/address/index.ts +21 -0
- package/src/address/is.spec.ts +113 -0
- package/src/address/is.ts +14 -0
- package/src/address/keyDerived.spec.ts +24 -0
- package/src/address/keyDerived.ts +22 -0
- package/src/address/keyMulti.spec.ts +20 -0
- package/src/address/keyMulti.ts +23 -0
- package/src/address/setSS58Format.spec.ts +21 -0
- package/src/address/setSS58Format.ts +20 -0
- package/src/address/sort.spec.ts +22 -0
- package/src/address/sort.ts +17 -0
- package/src/address/sshash.ts +12 -0
- package/src/address/types.ts +6 -0
- package/src/address/util.ts +8 -0
- package/src/address/validate.spec.ts +113 -0
- package/src/address/validate.ts +10 -0
- package/src/base32/bs32.ts +53 -0
- package/src/base32/decode.spec.ts +34 -0
- package/src/base32/encode.spec.ts +30 -0
- package/src/base32/helpers.ts +93 -0
- package/src/base32/index.ts +8 -0
- package/src/base32/is.spec.ts +32 -0
- package/src/base32/validate.spec.ts +44 -0
- package/src/base58/bs58.ts +43 -0
- package/src/base58/decode.spec.ts +31 -0
- package/src/base58/encode.spec.ts +26 -0
- package/src/base58/index.ts +8 -0
- package/src/base58/validate.spec.ts +20 -0
- package/src/base64/bs64.ts +43 -0
- package/src/base64/decode.spec.ts +42 -0
- package/src/base64/encode.spec.ts +14 -0
- package/src/base64/index.ts +10 -0
- package/src/base64/pad.spec.ts +14 -0
- package/src/base64/pad.ts +10 -0
- package/src/base64/trim.spec.ts +14 -0
- package/src/base64/trim.ts +14 -0
- package/src/base64/validate.spec.ts +32 -0
- package/src/blake2/asHex.spec.ts +57 -0
- package/src/blake2/asU8a.spec.ts +74 -0
- package/src/blake2/asU8a.ts +40 -0
- package/src/blake2/index.ts +8 -0
- package/src/bn.ts +15 -0
- package/src/bundle.ts +33 -0
- package/src/bundleInit.ts +11 -0
- package/src/crypto.spec.ts +18 -0
- package/src/crypto.ts +18 -0
- package/src/ed25519/deriveHard.ts +18 -0
- package/src/ed25519/index.ts +13 -0
- package/src/ed25519/pair/fromRandom.spec.ts +28 -0
- package/src/ed25519/pair/fromRandom.ts +25 -0
- package/src/ed25519/pair/fromSecret.spec.ts +33 -0
- package/src/ed25519/pair/fromSecret.ts +29 -0
- package/src/ed25519/pair/fromSeed.spec.ts +42 -0
- package/src/ed25519/pair/fromSeed.ts +41 -0
- package/src/ed25519/pair/fromString.spec.ts +17 -0
- package/src/ed25519/pair/fromString.ts +31 -0
- package/src/ed25519/sign.spec.ts +40 -0
- package/src/ed25519/sign.ts +38 -0
- package/src/ed25519/verify.spec.ts +84 -0
- package/src/ed25519/verify.ts +41 -0
- package/src/ethereum/encode.spec.ts +59 -0
- package/src/ethereum/encode.ts +39 -0
- package/src/ethereum/index.ts +6 -0
- package/src/ethereum/isAddress.spec.ts +34 -0
- package/src/ethereum/isAddress.ts +16 -0
- package/src/ethereum/isChecksum.ts +27 -0
- package/src/ethereum/isCheksum.spec.ts +30 -0
- package/src/hd/ethereum/index.spec.ts +54 -0
- package/src/hd/ethereum/index.ts +69 -0
- package/src/hd/index.ts +6 -0
- package/src/hd/ledger/derivePrivate.ts +34 -0
- package/src/hd/ledger/index.spec.ts +64 -0
- package/src/hd/ledger/index.ts +42 -0
- package/src/hd/ledger/master.spec.ts +19 -0
- package/src/hd/ledger/master.ts +26 -0
- package/src/hd/validatePath.spec.ts +30 -0
- package/src/hd/validatePath.ts +24 -0
- package/src/helpers.ts +38 -0
- package/src/hmac/index.ts +4 -0
- package/src/hmac/shaAsU8a.spec.ts +45 -0
- package/src/hmac/shaAsU8a.ts +48 -0
- package/src/index.ts +6 -0
- package/src/json/constants.ts +11 -0
- package/src/json/decrypt.ts +25 -0
- package/src/json/decryptData.ts +45 -0
- package/src/json/encrypt.ts +25 -0
- package/src/json/encryptFormat.ts +20 -0
- package/src/json/index.ts +7 -0
- package/src/json/types.ts +22 -0
- package/src/keccak/asHex.spec.ts +30 -0
- package/src/keccak/asU8a.spec.ts +56 -0
- package/src/keccak/asU8a.ts +45 -0
- package/src/keccak/index.ts +8 -0
- package/src/key/DeriveJunction.ts +79 -0
- package/src/key/extractPath.spec.ts +51 -0
- package/src/key/extractPath.ts +37 -0
- package/src/key/extractSuri.spec.ts +147 -0
- package/src/key/extractSuri.ts +40 -0
- package/src/key/fromPath.ts +28 -0
- package/src/key/hdkdDerive.ts +17 -0
- package/src/key/hdkdEcdsa.ts +8 -0
- package/src/key/hdkdEd25519.ts +7 -0
- package/src/key/hdkdSr25519.ts +14 -0
- package/src/key/index.ts +12 -0
- package/src/mnemonic/bip39.spec.ts +80 -0
- package/src/mnemonic/bip39.ts +127 -0
- package/src/mnemonic/generate.spec.ts +58 -0
- package/src/mnemonic/generate.ts +25 -0
- package/src/mnemonic/index.ts +11 -0
- package/src/mnemonic/toEntropy.spec.ts +36 -0
- package/src/mnemonic/toEntropy.ts +13 -0
- package/src/mnemonic/toLegacySeed.spec.ts +52 -0
- package/src/mnemonic/toLegacySeed.ts +39 -0
- package/src/mnemonic/toMiniSecret.spec.ts +67 -0
- package/src/mnemonic/toMiniSecret.ts +23 -0
- package/src/mnemonic/toMiniSecretCmp.spec.ts +64 -0
- package/src/mnemonic/validate.spec.ts +39 -0
- package/src/mnemonic/validate.ts +26 -0
- package/src/mnemonic/wordlists/en.ts +7 -0
- package/src/mnemonic/wordlists/es.ts +7 -0
- package/src/mnemonic/wordlists/fr.ts +7 -0
- package/src/mnemonic/wordlists/index.ts +11 -0
- package/src/mnemonic/wordlists/it.ts +7 -0
- package/src/mnemonic/wordlists/jp.ts +7 -0
- package/src/mnemonic/wordlists/ko.ts +7 -0
- package/src/mnemonic/wordlists/zh-s.ts +7 -0
- package/src/mnemonic/wordlists/zh-t.ts +7 -0
- package/src/mod.ts +4 -0
- package/src/nacl/decrypt.spec.ts +26 -0
- package/src/nacl/decrypt.ts +22 -0
- package/src/nacl/encrypt.spec.ts +20 -0
- package/src/nacl/encrypt.ts +31 -0
- package/src/nacl/index.ts +8 -0
- package/src/nacl/tweetnacl-secretbox-data.spec.ts +4629 -0
- package/src/nacl/tweetnacl-secretbox.spec.ts +161 -0
- package/src/nacl/tweetnacl.ts +1159 -0
- package/src/networks.ts +5 -0
- package/src/packageDetect.ts +14 -0
- package/src/packageInfo.ts +6 -0
- package/src/pbkdf2/encode.spec.ts +54 -0
- package/src/pbkdf2/encode.ts +29 -0
- package/src/pbkdf2/index.ts +4 -0
- package/src/random/asHex.spec.ts +38 -0
- package/src/random/asNumber.spec.ts +16 -0
- package/src/random/asNumber.ts +28 -0
- package/src/random/asU8a.spec.ts +36 -0
- package/src/random/asU8a.ts +30 -0
- package/src/random/index.ts +9 -0
- package/src/scrypt/defaults.ts +19 -0
- package/src/scrypt/encode.spec.ts +43 -0
- package/src/scrypt/encode.ts +30 -0
- package/src/scrypt/fromU8a.ts +44 -0
- package/src/scrypt/index.ts +6 -0
- package/src/scrypt/toU8a.ts +17 -0
- package/src/scrypt/types.ts +9 -0
- package/src/secp256k1/compress.spec.ts +47 -0
- package/src/secp256k1/compress.ts +21 -0
- package/src/secp256k1/deriveHard.ts +17 -0
- package/src/secp256k1/expand.spec.ts +47 -0
- package/src/secp256k1/expand.ts +30 -0
- package/src/secp256k1/hasher.spec.ts +24 -0
- package/src/secp256k1/hasher.ts +13 -0
- package/src/secp256k1/index.ts +10 -0
- package/src/secp256k1/pair/fromSeed.spec.ts +75 -0
- package/src/secp256k1/pair/fromSeed.ts +42 -0
- package/src/secp256k1/recover.spec.ts +35 -0
- package/src/secp256k1/recover.ts +36 -0
- package/src/secp256k1/sign.spec.ts +39 -0
- package/src/secp256k1/sign.ts +37 -0
- package/src/secp256k1/signVerify.spec.ts +94 -0
- package/src/secp256k1/tweakAdd.spec.ts +35 -0
- package/src/secp256k1/tweakAdd.ts +65 -0
- package/src/secp256k1/types.ts +4 -0
- package/src/secp256k1/verify.spec.ts +81 -0
- package/src/secp256k1/verify.ts +32 -0
- package/src/sha/asU8a.ts +30 -0
- package/src/sha/asU8a256.spec.ts +55 -0
- package/src/sha/asU8a512.spec.ts +33 -0
- package/src/sha/index.ts +8 -0
- package/src/signature/index.ts +8 -0
- package/src/signature/verify.spec.ts +230 -0
- package/src/signature/verify.ts +114 -0
- package/src/sr25519/agreement.spec.ts +31 -0
- package/src/sr25519/agreement.ts +23 -0
- package/src/sr25519/derive.ts +21 -0
- package/src/sr25519/deriveHard.ts +9 -0
- package/src/sr25519/derivePublic.ts +18 -0
- package/src/sr25519/deriveSoft.ts +9 -0
- package/src/sr25519/index.ts +12 -0
- package/src/sr25519/pair/fromSeed.spec.ts +35 -0
- package/src/sr25519/pair/fromSeed.ts +28 -0
- package/src/sr25519/pair/fromU8a.ts +23 -0
- package/src/sr25519/pair/testing.spec.ts +161 -0
- package/src/sr25519/pair/toU8a.ts +10 -0
- package/src/sr25519/sign.spec.ts +28 -0
- package/src/sr25519/sign.ts +22 -0
- package/src/sr25519/verify.spec.ts +42 -0
- package/src/sr25519/verify.ts +23 -0
- package/src/sr25519/vrfSign.ts +24 -0
- package/src/sr25519/vrfSignVerify.spec.ts +73 -0
- package/src/sr25519/vrfVerify.ts +25 -0
- package/src/test/index.ts +8 -0
- package/src/test/performance.ts +17 -0
- package/src/types.ts +33 -0
- package/src/xxhash/asHex.spec.ts +36 -0
- package/src/xxhash/asU8a.spec.ts +48 -0
- package/src/xxhash/asU8a.ts +45 -0
- package/src/xxhash/index.ts +8 -0
- package/src/xxhash/xxhash64.ts +155 -0
- package/tsconfig.build.json +18 -0
- 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,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,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';
|