@pezkuwi/util 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 +49 -0
- package/src/array/chunk.spec.ts +29 -0
- package/src/array/chunk.ts +35 -0
- package/src/array/filter.spec.ts +20 -0
- package/src/array/filter.ts +24 -0
- package/src/array/flatten.spec.ts +33 -0
- package/src/array/flatten.ts +51 -0
- package/src/array/index.ts +14 -0
- package/src/array/range.spec.ts +29 -0
- package/src/array/range.ts +31 -0
- package/src/array/shuffle.spec.ts +39 -0
- package/src/array/shuffle.ts +27 -0
- package/src/array/unzip.spec.ts +14 -0
- package/src/array/unzip.ts +18 -0
- package/src/array/zip.spec.ts +26 -0
- package/src/array/zip.ts +17 -0
- package/src/assert.spec.ts +40 -0
- package/src/assert.ts +50 -0
- package/src/bi/consts.ts +112 -0
- package/src/bi/helpers.ts +23 -0
- package/src/bi/index.ts +16 -0
- package/src/bi/max.spec.ts +32 -0
- package/src/bi/min.spec.ts +26 -0
- package/src/bi/min.ts +16 -0
- package/src/bi/sqrt.spec.ts +59 -0
- package/src/bi/sqrt.ts +43 -0
- package/src/bi/toBigInt.spec.ts +69 -0
- package/src/bi/toBigInt.ts +33 -0
- package/src/bi/toHex.spec.ts +56 -0
- package/src/bi/toHex.ts +16 -0
- package/src/bi/toU8a.spec.ts +99 -0
- package/src/bi/toU8a.ts +72 -0
- package/src/bn/bn.ts +6 -0
- package/src/bn/consts.spec.ts +38 -0
- package/src/bn/consts.ts +112 -0
- package/src/bn/fromHex.spec.ts +15 -0
- package/src/bn/fromHex.ts +4 -0
- package/src/bn/index.ts +18 -0
- package/src/bn/max.spec.ts +32 -0
- package/src/bn/min.spec.ts +26 -0
- package/src/bn/min.ts +36 -0
- package/src/bn/sqrt.spec.ts +37 -0
- package/src/bn/sqrt.ts +50 -0
- package/src/bn/toBn.spec.ts +53 -0
- package/src/bn/toBn.ts +43 -0
- package/src/bn/toHex.spec.ts +50 -0
- package/src/bn/toHex.ts +27 -0
- package/src/bn/toU8a.spec.ts +60 -0
- package/src/bn/toU8a.ts +45 -0
- package/src/buffer/index.ts +8 -0
- package/src/buffer/toU8a.spec.ts +20 -0
- package/src/buffer/toU8a.ts +20 -0
- package/src/bundle.ts +35 -0
- package/src/compact/addLength.spec.ts +14 -0
- package/src/compact/addLength.ts +24 -0
- package/src/compact/defaults.ts +7 -0
- package/src/compact/fromU8a.spec.ts +84 -0
- package/src/compact/fromU8a.ts +109 -0
- package/src/compact/index.ts +28 -0
- package/src/compact/stripLength.spec.ts +17 -0
- package/src/compact/stripLength.ts +26 -0
- package/src/compact/toU8a.spec.ts +59 -0
- package/src/compact/toU8a.ts +53 -0
- package/src/compact/types.ts +4 -0
- package/src/detectPackage.spec.ts +110 -0
- package/src/detectPackage.ts +138 -0
- package/src/extractTime.spec.ts +21 -0
- package/src/extractTime.ts +71 -0
- package/src/float/index.ts +4 -0
- package/src/float/toU8a.spec.ts +52 -0
- package/src/float/toU8a.ts +30 -0
- package/src/format/formatBalance.spec.ts +296 -0
- package/src/format/formatBalance.ts +177 -0
- package/src/format/formatDate.spec.ts +17 -0
- package/src/format/formatDate.ts +22 -0
- package/src/format/formatDecimal.spec.ts +28 -0
- package/src/format/formatDecimal.ts +22 -0
- package/src/format/formatElapsed.spec.ts +44 -0
- package/src/format/formatElapsed.ts +35 -0
- package/src/format/formatNumber.spec.ts +60 -0
- package/src/format/formatNumber.ts +29 -0
- package/src/format/getSeparator.spec.ts +53 -0
- package/src/format/getSeparator.ts +15 -0
- package/src/format/index.ts +9 -0
- package/src/format/si.ts +52 -0
- package/src/has.spec.ts +12 -0
- package/src/has.ts +38 -0
- package/src/hex/addPrefix.spec.ts +32 -0
- package/src/hex/addPrefix.ts +26 -0
- package/src/hex/fixLength.spec.ts +38 -0
- package/src/hex/fixLength.ts +36 -0
- package/src/hex/hasPrefix.spec.ts +32 -0
- package/src/hex/hasPrefix.ts +24 -0
- package/src/hex/index.ts +16 -0
- package/src/hex/stripPrefix.spec.ts +44 -0
- package/src/hex/stripPrefix.ts +30 -0
- package/src/hex/toBigInt.spec.ts +74 -0
- package/src/hex/toBigInt.ts +19 -0
- package/src/hex/toBn.spec.ts +74 -0
- package/src/hex/toBn.ts +40 -0
- package/src/hex/toNumber.spec.ts +20 -0
- package/src/hex/toNumber.ts +24 -0
- package/src/hex/toString.spec.ts +20 -0
- package/src/hex/toString.ts +25 -0
- package/src/hex/toU8a.spec.ts +76 -0
- package/src/hex/toU8a.ts +68 -0
- package/src/hex/toU8aBuffer.spec.ts +38 -0
- package/src/hex/toU8aBuffer.ts +52 -0
- package/src/index.spec.ts +12 -0
- package/src/index.ts +6 -0
- package/src/is/array.spec.ts +20 -0
- package/src/is/array.ts +10 -0
- package/src/is/ascii.spec.ts +49 -0
- package/src/is/ascii.ts +52 -0
- package/src/is/bigInt.spec.ts +26 -0
- package/src/is/bigInt.ts +20 -0
- package/src/is/bn.spec.ts +21 -0
- package/src/is/bn.ts +23 -0
- package/src/is/boolean.spec.ts +26 -0
- package/src/is/boolean.ts +20 -0
- package/src/is/buffer.spec.ts +26 -0
- package/src/is/buffer.ts +28 -0
- package/src/is/childClass.spec.ts +36 -0
- package/src/is/childClass.ts +29 -0
- package/src/is/class.spec.ts +37 -0
- package/src/is/class.ts +12 -0
- package/src/is/codec.spec.ts +52 -0
- package/src/is/codec.ts +26 -0
- package/src/is/compact.spec.ts +27 -0
- package/src/is/compact.ts +19 -0
- package/src/is/error.spec.ts +20 -0
- package/src/is/error.ts +23 -0
- package/src/is/function.spec.ts +20 -0
- package/src/is/function.ts +23 -0
- package/src/is/helpers.ts +23 -0
- package/src/is/hex.spec.ts +77 -0
- package/src/is/hex.ts +36 -0
- package/src/is/index.ts +36 -0
- package/src/is/instanceOf.spec.ts +48 -0
- package/src/is/instanceOf.ts +24 -0
- package/src/is/ip.spec.ts +50 -0
- package/src/is/ip.ts +56 -0
- package/src/is/jsonObject.spec.ts +51 -0
- package/src/is/jsonObject.ts +45 -0
- package/src/is/null.spec.ts +20 -0
- package/src/is/null.ts +20 -0
- package/src/is/number.spec.ts +20 -0
- package/src/is/number.ts +20 -0
- package/src/is/object.spec.ts +32 -0
- package/src/is/object.ts +24 -0
- package/src/is/observable.spec.ts +26 -0
- package/src/is/observable.ts +22 -0
- package/src/is/promise.spec.ts +32 -0
- package/src/is/promise.ts +6 -0
- package/src/is/riscv.spec.ts +36 -0
- package/src/is/riscv.ts +27 -0
- package/src/is/string.spec.ts +32 -0
- package/src/is/string.ts +22 -0
- package/src/is/testChain.spec.ts +25 -0
- package/src/is/testChain.ts +12 -0
- package/src/is/toBigInt.spec.ts +22 -0
- package/src/is/toBigInt.ts +8 -0
- package/src/is/toBn.spec.ts +25 -0
- package/src/is/toBn.ts +8 -0
- package/src/is/u8a.spec.ts +42 -0
- package/src/is/u8a.ts +25 -0
- package/src/is/undefined.spec.ts +23 -0
- package/src/is/undefined.ts +21 -0
- package/src/is/utf8.spec.ts +42 -0
- package/src/is/utf8.ts +207 -0
- package/src/is/wasm.spec.ts +20 -0
- package/src/is/wasm.ts +17 -0
- package/src/lazy.spec.ts +71 -0
- package/src/lazy.ts +63 -0
- package/src/logger.spec.ts +188 -0
- package/src/logger.ts +160 -0
- package/src/memoize.spec.ts +79 -0
- package/src/memoize.ts +49 -0
- package/src/mod.ts +4 -0
- package/src/nextTick.ts +26 -0
- package/src/noop.ts +16 -0
- package/src/number/index.ts +9 -0
- package/src/number/toHex.spec.ts +44 -0
- package/src/number/toHex.ts +27 -0
- package/src/number/toU8a.spec.ts +50 -0
- package/src/number/toU8a.ts +25 -0
- package/src/object/clear.spec.ts +14 -0
- package/src/object/clear.ts +16 -0
- package/src/object/copy.spec.ts +17 -0
- package/src/object/copy.ts +12 -0
- package/src/object/entries.spec.ts +20 -0
- package/src/object/entries.ts +12 -0
- package/src/object/index.ts +10 -0
- package/src/object/keys.spec.ts +19 -0
- package/src/object/keys.ts +10 -0
- package/src/object/property.spec.ts +149 -0
- package/src/object/property.ts +39 -0
- package/src/object/spread.spec.ts +36 -0
- package/src/object/spread.ts +38 -0
- package/src/object/values.spec.ts +19 -0
- package/src/object/values.ts +10 -0
- package/src/packageDetect.ts +13 -0
- package/src/packageInfo.ts +6 -0
- package/src/promisify.spec.ts +50 -0
- package/src/promisify.ts +30 -0
- package/src/string/camelCase.spec.ts +119 -0
- package/src/string/camelCase.ts +79 -0
- package/src/string/index.ts +12 -0
- package/src/string/lowerFirst.spec.ts +41 -0
- package/src/string/lowerFirst.ts +46 -0
- package/src/string/pascalCase.spec.ts +26 -0
- package/src/string/shorten.spec.ts +38 -0
- package/src/string/shorten.ts +24 -0
- package/src/string/toHex.spec.ts +26 -0
- package/src/string/toHex.ts +27 -0
- package/src/string/toU8a.spec.ts +31 -0
- package/src/string/toU8a.ts +28 -0
- package/src/string/upperFirst.spec.ts +41 -0
- package/src/stringify.spec.ts +33 -0
- package/src/stringify.ts +20 -0
- package/src/test/index.ts +4 -0
- package/src/test/performance.ts +92 -0
- package/src/types.ts +100 -0
- package/src/u8a/cmp.spec.ts +62 -0
- package/src/u8a/cmp.ts +50 -0
- package/src/u8a/concat.spec.ts +42 -0
- package/src/u8a/concat.ts +60 -0
- package/src/u8a/concatBuffer.ts +34 -0
- package/src/u8a/empty.spec.ts +46 -0
- package/src/u8a/empty.ts +22 -0
- package/src/u8a/eq.spec.ts +113 -0
- package/src/u8a/eq.ts +46 -0
- package/src/u8a/fixLength.spec.ts +34 -0
- package/src/u8a/fixLength.ts +34 -0
- package/src/u8a/index.ts +22 -0
- package/src/u8a/sorted.spec.ts +20 -0
- package/src/u8a/sorted.ts +22 -0
- package/src/u8a/toBigInt.spec.ts +106 -0
- package/src/u8a/toBigInt.ts +100 -0
- package/src/u8a/toBn.spec.ts +106 -0
- package/src/u8a/toBn.ts +101 -0
- package/src/u8a/toBuffer.spec.ts +20 -0
- package/src/u8a/toBuffer.ts +28 -0
- package/src/u8a/toFloat.spec.ts +86 -0
- package/src/u8a/toFloat.ts +26 -0
- package/src/u8a/toHex.spec.ts +94 -0
- package/src/u8a/toHex.ts +68 -0
- package/src/u8a/toHexBuffer.spec.ts +63 -0
- package/src/u8a/toHexBuffer.ts +30 -0
- package/src/u8a/toNumber.spec.ts +47 -0
- package/src/u8a/toNumber.ts +80 -0
- package/src/u8a/toString.spec.ts +36 -0
- package/src/u8a/toString.ts +26 -0
- package/src/u8a/toU8a.spec.ts +63 -0
- package/src/u8a/toU8a.ts +46 -0
- package/src/u8a/wrap.spec.ts +139 -0
- package/src/u8a/wrap.ts +65 -0
- package/tsconfig.build.json +19 -0
- package/tsconfig.spec.json +17 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/util authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import type { HexString } from '../types.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @name u8aToHex
|
|
8
|
+
* @summary Creates a hex string from a Uint8Array object.
|
|
9
|
+
* @description
|
|
10
|
+
* `UInt8Array` input values return the actual hex string. `null` or `undefined` values returns an `0x` string.
|
|
11
|
+
* @example
|
|
12
|
+
* <BR>
|
|
13
|
+
*
|
|
14
|
+
* ```javascript
|
|
15
|
+
* import { u8aToHex } from '@pezkuwi/util';
|
|
16
|
+
*
|
|
17
|
+
* u8aToHex(new Uint8Array([0x68, 0x65, 0x6c, 0x6c, 0xf])); // 0x68656c0f
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export function u8aToHex (value?: Uint8Array | null, bitLength = -1, isPrefixed = true): HexString {
|
|
21
|
+
const length = Math.ceil(bitLength / 8);
|
|
22
|
+
|
|
23
|
+
return `${isPrefixed ? '0x' : ''}${
|
|
24
|
+
!value?.length
|
|
25
|
+
? ''
|
|
26
|
+
: (bitLength > 0 && value.length > length)
|
|
27
|
+
? `${Buffer.from(value.subarray(0, length / 2)).toString('hex')}…${Buffer.from(value.subarray(value.length - length / 2)).toString('hex')}`
|
|
28
|
+
: Buffer.from(value).toString('hex')
|
|
29
|
+
}` as HexString;
|
|
30
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/util authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
/// <reference types="@polkadot/dev-test/globals.d.ts" />
|
|
5
|
+
|
|
6
|
+
import { TESTS } from '../bi/toU8a.spec.js';
|
|
7
|
+
import { perf } from '../test/index.js';
|
|
8
|
+
import { u8aToNumber } from './index.js';
|
|
9
|
+
|
|
10
|
+
const TESTS_NUM = TESTS.filter(([,, numarr]) => numarr.length <= 6);
|
|
11
|
+
|
|
12
|
+
describe('u8aToNumber', (): void => {
|
|
13
|
+
describe('empty creation', (): void => {
|
|
14
|
+
it('handles unsigned (le)', (): void => {
|
|
15
|
+
expect(
|
|
16
|
+
u8aToNumber(
|
|
17
|
+
new Uint8Array()
|
|
18
|
+
)
|
|
19
|
+
).toBe(0);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('handles signed (le)', (): void => {
|
|
23
|
+
expect(
|
|
24
|
+
u8aToNumber(
|
|
25
|
+
new Uint8Array(),
|
|
26
|
+
{ isNegative: true }
|
|
27
|
+
)
|
|
28
|
+
).toBe(0);
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
describe('conversion tests', (): void => {
|
|
33
|
+
TESTS_NUM.forEach(([isLe, isNegative, numarr, strval], i): void => {
|
|
34
|
+
it(`#${i}: creates ${strval} (bitLength=${numarr.length * 8}, isLe=${isLe}, isNegative=${isNegative})`, (): void => {
|
|
35
|
+
expect(
|
|
36
|
+
u8aToNumber(
|
|
37
|
+
new Uint8Array(numarr),
|
|
38
|
+
{ isLe, isNegative }
|
|
39
|
+
).toString()
|
|
40
|
+
).toBe(strval);
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
perf('u8aToNumber (i32)', 750_000, [[new Uint8Array([0x9c, 0x9c, 0x9c, 0x9c])]], (v: Uint8Array) => u8aToNumber(v, { isNegative: true }));
|
|
46
|
+
perf('u8aToNumber (u32)', 750_000, [[new Uint8Array([0x68, 0x65, 0x6c, 0x6c])]], u8aToNumber);
|
|
47
|
+
});
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/util authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import type { ToBnOptions } from '../types.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @name u8aToNumber
|
|
8
|
+
* @summary Creates a number from a Uint8Array object.
|
|
9
|
+
*/
|
|
10
|
+
export function u8aToNumber (value: Uint8Array, { isLe = true, isNegative = false }: ToBnOptions = {}): number {
|
|
11
|
+
// slice + reverse is expensive, however SCALE is LE by default so this is the path
|
|
12
|
+
// we are most interested in (the BE is added for the sake of being comprehensive)
|
|
13
|
+
if (!isLe) {
|
|
14
|
+
value = value.slice().reverse();
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const count = value.length;
|
|
18
|
+
|
|
19
|
+
// When the value is a i{8, 16, 24, 32, 40, 40} values and the top-most bit
|
|
20
|
+
// indicates a signed value, we use a two's complement conversion. If one of these
|
|
21
|
+
// flags are not set, we just do a normal unsigned conversion (the same shortcut
|
|
22
|
+
// applies in both the u8aTo{BigInt, Bn} conversions as well)
|
|
23
|
+
if (isNegative && count && (value[count - 1] & 0x80)) {
|
|
24
|
+
switch (count) {
|
|
25
|
+
case 0:
|
|
26
|
+
return 0;
|
|
27
|
+
|
|
28
|
+
case 1:
|
|
29
|
+
return (((value[0] ^ 0x0000_00ff) * -1) - 1);
|
|
30
|
+
|
|
31
|
+
case 2:
|
|
32
|
+
return ((((value[0] + (value[1] << 8)) ^ 0x0000_ffff) * -1) - 1);
|
|
33
|
+
|
|
34
|
+
case 3:
|
|
35
|
+
return ((((value[0] + (value[1] << 8) + (value[2] << 16)) ^ 0x00ff_ffff) * -1) - 1);
|
|
36
|
+
|
|
37
|
+
case 4:
|
|
38
|
+
// for the 3rd byte, we don't << 24 - since JS converts all bitwise operators to
|
|
39
|
+
// 32-bit, in the case where the top-most bit is set this yields a negative value
|
|
40
|
+
return ((((value[0] + (value[1] << 8) + (value[2] << 16) + (value[3] * 0x1_00_00_00)) ^ 0xffff_ffff) * -1) - 1);
|
|
41
|
+
|
|
42
|
+
case 5:
|
|
43
|
+
return (((((value[0] + (value[1] << 8) + (value[2] << 16) + (value[3] * 0x1_00_00_00)) ^ 0xffff_ffff) + ((value[4] ^ 0xff) * 0x1_00_00_00_00)) * -1) - 1);
|
|
44
|
+
|
|
45
|
+
case 6:
|
|
46
|
+
return (((((value[0] + (value[1] << 8) + (value[2] << 16) + (value[3] * 0x1_00_00_00)) ^ 0xffff_ffff) + (((value[4] + (value[5] << 8)) ^ 0x0000_ffff) * 0x1_00_00_00_00)) * -1) - 1);
|
|
47
|
+
|
|
48
|
+
default:
|
|
49
|
+
throw new Error('Value more than 48-bits cannot be reliably converted');
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
switch (count) {
|
|
54
|
+
case 0:
|
|
55
|
+
return 0;
|
|
56
|
+
|
|
57
|
+
case 1:
|
|
58
|
+
return value[0];
|
|
59
|
+
|
|
60
|
+
case 2:
|
|
61
|
+
return value[0] + (value[1] << 8);
|
|
62
|
+
|
|
63
|
+
case 3:
|
|
64
|
+
return value[0] + (value[1] << 8) + (value[2] << 16);
|
|
65
|
+
|
|
66
|
+
case 4:
|
|
67
|
+
// for the 3rd byte, we don't << 24 - since JS converts all bitwise operators to
|
|
68
|
+
// 32-bit, in the case where the top-most bit is set this yields a negative value
|
|
69
|
+
return value[0] + (value[1] << 8) + (value[2] << 16) + (value[3] * 0x1_00_00_00);
|
|
70
|
+
|
|
71
|
+
case 5:
|
|
72
|
+
return value[0] + (value[1] << 8) + (value[2] << 16) + ((value[3] + (value[4] << 8)) * 0x1_00_00_00);
|
|
73
|
+
|
|
74
|
+
case 6:
|
|
75
|
+
return value[0] + (value[1] << 8) + (value[2] << 16) + ((value[3] + (value[4] << 8) + (value[5] << 16)) * 0x1_00_00_00);
|
|
76
|
+
|
|
77
|
+
default:
|
|
78
|
+
throw new Error('Value more than 48-bits cannot be reliably converted');
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/util authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
/// <reference types="@polkadot/dev-test/globals.d.ts" />
|
|
5
|
+
|
|
6
|
+
import { u8aToString } from './index.js';
|
|
7
|
+
|
|
8
|
+
describe('u8aToString', (): void => {
|
|
9
|
+
it('decodes to an empty string for undefined', (): void => {
|
|
10
|
+
expect(
|
|
11
|
+
u8aToString()
|
|
12
|
+
).toEqual('');
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('decodes to an empty string for empty buffer', (): void => {
|
|
16
|
+
expect(
|
|
17
|
+
u8aToString(new Uint8Array())
|
|
18
|
+
).toEqual('');
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it('decodes the Uint8Array correctly (ru)', (): void => {
|
|
22
|
+
expect(
|
|
23
|
+
u8aToString(
|
|
24
|
+
new Uint8Array([208, 159, 209, 128, 208, 184, 208, 178, 208, 181, 209, 130, 44, 32, 208, 188, 208, 184, 209, 128, 33])
|
|
25
|
+
)
|
|
26
|
+
).toEqual('Привет, мир!');
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('decodes the Uint8Array correctly (en)', (): void => {
|
|
30
|
+
expect(
|
|
31
|
+
u8aToString(
|
|
32
|
+
new Uint8Array([0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64])
|
|
33
|
+
)
|
|
34
|
+
).toEqual('hello world');
|
|
35
|
+
});
|
|
36
|
+
});
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/util authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import { TextDecoder } from '@pezkuwi/x-textdecoder';
|
|
5
|
+
|
|
6
|
+
const decoder = new TextDecoder('utf-8');
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @name u8aToString
|
|
10
|
+
* @summary Creates a utf-8 string from a Uint8Array object.
|
|
11
|
+
* @description
|
|
12
|
+
* `UInt8Array` input values return the actual decoded utf-8 string. `null` or `undefined` values returns an empty string.
|
|
13
|
+
* @example
|
|
14
|
+
* <BR>
|
|
15
|
+
*
|
|
16
|
+
* ```javascript
|
|
17
|
+
* import { u8aToString } from '@pezkuwi/util';
|
|
18
|
+
*
|
|
19
|
+
* u8aToString(new Uint8Array([0x68, 0x65, 0x6c, 0x6c, 0x6f])); // hello
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export function u8aToString (value?: Uint8Array | null): string {
|
|
23
|
+
return value
|
|
24
|
+
? decoder.decode(value)
|
|
25
|
+
: '';
|
|
26
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/util authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
/// <reference types="@polkadot/dev-test/globals.d.ts" />
|
|
5
|
+
|
|
6
|
+
import type { U8aLike } from '../types.js';
|
|
7
|
+
|
|
8
|
+
import { perf } from '../test/index.js';
|
|
9
|
+
import { u8aToU8a } from './index.js';
|
|
10
|
+
|
|
11
|
+
const TESTS: [input: U8aLike | null | undefined, output: Uint8Array][] = [
|
|
12
|
+
['0x80000a', new Uint8Array([128, 0, 10])],
|
|
13
|
+
['abcde fghij', new Uint8Array([97, 98, 99, 100, 101, 32, 102, 103, 104, 105, 106])],
|
|
14
|
+
[[128, 0, 10, 11, 12], new Uint8Array([128, 0, 10, 11, 12])],
|
|
15
|
+
[Buffer.from([1, 2, 3, 128, 0, 10, 11, 12]), new Uint8Array([1, 2, 3, 128, 0, 10, 11, 12])],
|
|
16
|
+
[Buffer.from('80000a', 'hex'), new Uint8Array([128, 0, 10])],
|
|
17
|
+
// this is where completely invalid data is being passed
|
|
18
|
+
[123 as unknown as Uint8Array, new Uint8Array([49, 50, 51])]
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
describe('u8aToU8a', (): void => {
|
|
22
|
+
it('returns an empty Uint8Array when null/undefined/"" provided', (): void => {
|
|
23
|
+
expect(u8aToU8a(null)).toHaveLength(0);
|
|
24
|
+
expect(
|
|
25
|
+
u8aToU8a()
|
|
26
|
+
).toHaveLength(0);
|
|
27
|
+
expect(
|
|
28
|
+
u8aToU8a('')
|
|
29
|
+
).toHaveLength(0);
|
|
30
|
+
expect(
|
|
31
|
+
u8aToU8a('')
|
|
32
|
+
).toEqual(new Uint8Array());
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it('Throw error on null/undefined values on strict checking', () => {
|
|
36
|
+
expect(() => u8aToU8a(undefined, true)).toThrow('u8aToU8a: Expected non-null, non-undefined value');
|
|
37
|
+
expect(() => u8aToU8a(null, true)).toThrow('u8aToU8a: Expected non-null, non-undefined value');
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it('returns a Uint8Array as-is (u8a input)', (): void => {
|
|
41
|
+
const input = new Uint8Array([128, 0, 10]);
|
|
42
|
+
|
|
43
|
+
expect(
|
|
44
|
+
u8aToU8a(input)
|
|
45
|
+
).toEqual(input);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
describe('conversion tests', (): void => {
|
|
49
|
+
TESTS.forEach(([input, output], i): void => {
|
|
50
|
+
it(`#${i}: converts ${input as string} (typeof=${typeof input})`, (): void => {
|
|
51
|
+
expect(
|
|
52
|
+
u8aToU8a(input)
|
|
53
|
+
).toEqual(
|
|
54
|
+
output
|
|
55
|
+
);
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
perf('u8aToU8a (hex)', 250_000, [['0x1234']], u8aToU8a);
|
|
61
|
+
perf('u8aToU8a (str)', 250_000, [['test']], u8aToU8a);
|
|
62
|
+
perf('u8aToU8a (u8a)', 1_000_000, [[new Uint8Array()]], u8aToU8a);
|
|
63
|
+
});
|
package/src/u8a/toU8a.ts
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/util authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import type { U8aLike } from '../types.js';
|
|
5
|
+
|
|
6
|
+
import { hexToU8a } from '../hex/toU8a.js';
|
|
7
|
+
import { isBuffer } from '../is/buffer.js';
|
|
8
|
+
import { isHex } from '../is/hex.js';
|
|
9
|
+
import { isU8a } from '../is/u8a.js';
|
|
10
|
+
import { stringToU8a } from '../string/toU8a.js';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @name u8aToU8a
|
|
14
|
+
* @summary Creates a Uint8Array value from a Uint8Array, Buffer, string or hex input.
|
|
15
|
+
* @description
|
|
16
|
+
* `null` or `undefined` inputs returns a `[]` result, Uint8Array values returns the value, hex strings returns a Uint8Array representation.
|
|
17
|
+
* If `strict` is true, `null` or `undefined` will throw an error instead of returning an empty array.
|
|
18
|
+
* Supports input types: Uint8Array, Buffer, hex string, string, or number array.
|
|
19
|
+
* @example
|
|
20
|
+
* <BR>
|
|
21
|
+
*
|
|
22
|
+
* ```javascript
|
|
23
|
+
* import { u8aToU8a } from '@pezkuwi/util';
|
|
24
|
+
*
|
|
25
|
+
* u8aToU8a(new Uint8Array([0x12, 0x34]); // => Uint8Array([0x12, 0x34])
|
|
26
|
+
* u8aToU8a(0x1234); // => Uint8Array([0x12, 0x34])
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export function u8aToU8a (value?: U8aLike | null, strict = false): Uint8Array {
|
|
30
|
+
if (strict && (value === null || value === undefined)) {
|
|
31
|
+
throw new Error('u8aToU8a: Expected non-null, non-undefined value');
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return isU8a(value)
|
|
35
|
+
// NOTE isBuffer needs to go here since it actually extends
|
|
36
|
+
// Uint8Array on Node.js environments, so all Buffer are Uint8Array,
|
|
37
|
+
// but Uint8Array is not Buffer
|
|
38
|
+
? isBuffer(value)
|
|
39
|
+
? new Uint8Array(value)
|
|
40
|
+
: value
|
|
41
|
+
: isHex(value)
|
|
42
|
+
? hexToU8a(value)
|
|
43
|
+
: Array.isArray(value)
|
|
44
|
+
? new Uint8Array(value)
|
|
45
|
+
: stringToU8a(value);
|
|
46
|
+
}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/util authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
/// <reference types="@polkadot/dev-test/globals.d.ts" />
|
|
5
|
+
|
|
6
|
+
// Originally from https://github.com/polkadot-js/extension/pull/743
|
|
7
|
+
|
|
8
|
+
import { u8aConcat, u8aEq, u8aToString } from '@pezkuwi/util';
|
|
9
|
+
|
|
10
|
+
import { U8A_WRAP_ETHEREUM, U8A_WRAP_POSTFIX, U8A_WRAP_PREFIX, u8aUnwrapBytes, u8aWrapBytes } from './wrap.js';
|
|
11
|
+
|
|
12
|
+
const TEST_DATA = 'this is just some random message that we expect to be wrapped along the way';
|
|
13
|
+
const TEST_ETH = u8aConcat(U8A_WRAP_ETHEREUM, TEST_DATA);
|
|
14
|
+
const TEST_WRAP_EMPTY = `${u8aToString(U8A_WRAP_PREFIX)}${u8aToString(U8A_WRAP_POSTFIX)}`;
|
|
15
|
+
const TEST_WRAP_FULL = `${u8aToString(U8A_WRAP_PREFIX)}${TEST_DATA}${u8aToString(U8A_WRAP_POSTFIX)}`;
|
|
16
|
+
const TEST_WARP_HALF_PRE = `${u8aToString(U8A_WRAP_PREFIX)}${TEST_DATA}`;
|
|
17
|
+
const TEST_WRAP_HALF_POST = `${TEST_DATA}${u8aToString(U8A_WRAP_POSTFIX)}`;
|
|
18
|
+
|
|
19
|
+
describe('u8aWrapBytes', (): void => {
|
|
20
|
+
it('wraps empty bytes', (): void => {
|
|
21
|
+
expect(
|
|
22
|
+
u8aEq(
|
|
23
|
+
u8aWrapBytes(new Uint8Array()),
|
|
24
|
+
u8aConcat(U8A_WRAP_PREFIX, U8A_WRAP_POSTFIX)
|
|
25
|
+
)
|
|
26
|
+
).toBe(true);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('wraps when no wrapping is detected', (): void => {
|
|
30
|
+
expect(
|
|
31
|
+
u8aToString(
|
|
32
|
+
u8aWrapBytes(TEST_DATA)
|
|
33
|
+
)
|
|
34
|
+
).toEqual(TEST_WRAP_FULL);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('wraps when only start wrap is detected', (): void => {
|
|
38
|
+
expect(
|
|
39
|
+
u8aToString(
|
|
40
|
+
u8aWrapBytes(TEST_WARP_HALF_PRE)
|
|
41
|
+
)
|
|
42
|
+
).toEqual(`${u8aToString(U8A_WRAP_PREFIX)}${TEST_WARP_HALF_PRE}${u8aToString(U8A_WRAP_POSTFIX)}`);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it('wraps when only end wrap is detected', (): void => {
|
|
46
|
+
expect(
|
|
47
|
+
u8aToString(
|
|
48
|
+
u8aWrapBytes(TEST_WRAP_HALF_POST)
|
|
49
|
+
)
|
|
50
|
+
).toEqual(`${u8aToString(U8A_WRAP_PREFIX)}${TEST_WRAP_HALF_POST}${u8aToString(U8A_WRAP_POSTFIX)}`);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it('does not re-wrap when a wrap is already present', (): void => {
|
|
54
|
+
expect(
|
|
55
|
+
u8aToString(
|
|
56
|
+
u8aWrapBytes(TEST_WRAP_FULL)
|
|
57
|
+
)
|
|
58
|
+
).toEqual(TEST_WRAP_FULL);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it('does not re-wrap when a wrap (empty data) is already present', (): void => {
|
|
62
|
+
expect(
|
|
63
|
+
u8aToString(
|
|
64
|
+
u8aWrapBytes(TEST_WRAP_EMPTY)
|
|
65
|
+
)
|
|
66
|
+
).toEqual(TEST_WRAP_EMPTY);
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
describe('unwrapBytes', (): void => {
|
|
71
|
+
it('unwraps empty bytes', (): void => {
|
|
72
|
+
expect(
|
|
73
|
+
u8aEq(
|
|
74
|
+
u8aUnwrapBytes(new Uint8Array()),
|
|
75
|
+
new Uint8Array()
|
|
76
|
+
)
|
|
77
|
+
).toBe(true);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it('unwraps when no wrapping is detected', (): void => {
|
|
81
|
+
expect(
|
|
82
|
+
u8aToString(
|
|
83
|
+
u8aUnwrapBytes(TEST_DATA)
|
|
84
|
+
)
|
|
85
|
+
).toEqual(TEST_DATA);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
it('unwraps when no wrapping is detected (only start)', (): void => {
|
|
89
|
+
expect(
|
|
90
|
+
u8aToString(
|
|
91
|
+
u8aUnwrapBytes(TEST_WARP_HALF_PRE)
|
|
92
|
+
)
|
|
93
|
+
).toEqual(TEST_WARP_HALF_PRE);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
it('unwraps when no wrapping is detected (only end)', (): void => {
|
|
97
|
+
expect(
|
|
98
|
+
u8aToString(
|
|
99
|
+
u8aUnwrapBytes(TEST_WRAP_HALF_POST)
|
|
100
|
+
)
|
|
101
|
+
).toEqual(TEST_WRAP_HALF_POST);
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
it('unwraps when a wrap is present', (): void => {
|
|
105
|
+
expect(
|
|
106
|
+
u8aToString(
|
|
107
|
+
u8aUnwrapBytes(TEST_WRAP_FULL)
|
|
108
|
+
)
|
|
109
|
+
).toEqual(TEST_DATA);
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
it('unwraps when a an empty wrap is present', (): void => {
|
|
113
|
+
expect(
|
|
114
|
+
u8aToString(
|
|
115
|
+
u8aUnwrapBytes(TEST_WRAP_EMPTY)
|
|
116
|
+
)
|
|
117
|
+
).toEqual('');
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
describe('Ethereum-style', (): void => {
|
|
121
|
+
it('does not wrap an Ethereum wrap', (): void => {
|
|
122
|
+
expect(
|
|
123
|
+
u8aEq(
|
|
124
|
+
u8aWrapBytes(TEST_ETH),
|
|
125
|
+
TEST_ETH
|
|
126
|
+
)
|
|
127
|
+
).toBe(true);
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
it('does not unwrap an Ethereum wrap', (): void => {
|
|
131
|
+
expect(
|
|
132
|
+
u8aEq(
|
|
133
|
+
u8aUnwrapBytes(TEST_ETH),
|
|
134
|
+
TEST_ETH
|
|
135
|
+
)
|
|
136
|
+
).toBe(true);
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
});
|
package/src/u8a/wrap.ts
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/util authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
// Originally from https://github.com/polkadot-js/extension/pull/743
|
|
5
|
+
|
|
6
|
+
import type { U8aLike } from '../types.js';
|
|
7
|
+
|
|
8
|
+
import { u8aConcatStrict } from './concat.js';
|
|
9
|
+
import { u8aEq } from './eq.js';
|
|
10
|
+
import { u8aToU8a } from './toU8a.js';
|
|
11
|
+
|
|
12
|
+
/** @internal */
|
|
13
|
+
export const U8A_WRAP_ETHEREUM = /*#__PURE__*/ u8aToU8a('\x19Ethereum Signed Message:\n');
|
|
14
|
+
|
|
15
|
+
/** @internal */
|
|
16
|
+
export const U8A_WRAP_PREFIX = /*#__PURE__*/ u8aToU8a('<Bytes>');
|
|
17
|
+
|
|
18
|
+
/** @internal */
|
|
19
|
+
export const U8A_WRAP_POSTFIX = /*#__PURE__*/ u8aToU8a('</Bytes>');
|
|
20
|
+
|
|
21
|
+
const WRAP_LEN = U8A_WRAP_PREFIX.length + U8A_WRAP_POSTFIX.length;
|
|
22
|
+
|
|
23
|
+
/** @internal */
|
|
24
|
+
export function u8aIsWrapped (u8a: Uint8Array, withEthereum: boolean): boolean {
|
|
25
|
+
return (
|
|
26
|
+
(
|
|
27
|
+
u8a.length >= WRAP_LEN &&
|
|
28
|
+
u8aEq(u8a.subarray(0, U8A_WRAP_PREFIX.length), U8A_WRAP_PREFIX) &&
|
|
29
|
+
u8aEq(u8a.slice(-U8A_WRAP_POSTFIX.length), U8A_WRAP_POSTFIX)
|
|
30
|
+
) ||
|
|
31
|
+
(
|
|
32
|
+
withEthereum &&
|
|
33
|
+
u8a.length >= U8A_WRAP_ETHEREUM.length &&
|
|
34
|
+
u8aEq(u8a.subarray(0, U8A_WRAP_ETHEREUM.length), U8A_WRAP_ETHEREUM)
|
|
35
|
+
)
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* @name u8aUnwrapBytes
|
|
41
|
+
* @description Removes all <Bytes>...</Bytes> wrappers from the supplied value
|
|
42
|
+
*/
|
|
43
|
+
export function u8aUnwrapBytes (bytes: U8aLike): Uint8Array {
|
|
44
|
+
const u8a = u8aToU8a(bytes);
|
|
45
|
+
|
|
46
|
+
// we don't want to unwrap Ethereum-style wraps
|
|
47
|
+
return u8aIsWrapped(u8a, false)
|
|
48
|
+
? u8a.subarray(U8A_WRAP_PREFIX.length, u8a.length - U8A_WRAP_POSTFIX.length)
|
|
49
|
+
: u8a;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* @name u8aWrapBytes
|
|
54
|
+
* @description
|
|
55
|
+
* Adds a <Bytes>...</Bytes> wrapper to the supplied value, if
|
|
56
|
+
* - We don't already have a Bytes wrapper
|
|
57
|
+
* - The message is not an Ethereum-style message
|
|
58
|
+
*/
|
|
59
|
+
export function u8aWrapBytes (bytes: U8aLike): Uint8Array {
|
|
60
|
+
const u8a = u8aToU8a(bytes);
|
|
61
|
+
|
|
62
|
+
return u8aIsWrapped(u8a, true)
|
|
63
|
+
? u8a
|
|
64
|
+
: u8aConcatStrict([U8A_WRAP_PREFIX, u8a, U8A_WRAP_POSTFIX]);
|
|
65
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "../../tsconfig.base.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"baseUrl": "..",
|
|
5
|
+
"outDir": "./build",
|
|
6
|
+
"rootDir": "./src"
|
|
7
|
+
},
|
|
8
|
+
"exclude": [
|
|
9
|
+
"**/*.spec.ts",
|
|
10
|
+
"**/mod.ts"
|
|
11
|
+
],
|
|
12
|
+
"references": [
|
|
13
|
+
{ "path": "../x-bigint/tsconfig.build.json" },
|
|
14
|
+
{ "path": "../x-global/tsconfig.build.json" },
|
|
15
|
+
{ "path": "../x-randomvalues/tsconfig.build.json" },
|
|
16
|
+
{ "path": "../x-textdecoder/tsconfig.build.json" },
|
|
17
|
+
{ "path": "../x-textencoder/tsconfig.build.json" }
|
|
18
|
+
]
|
|
19
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "../../tsconfig.base.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"baseUrl": "..",
|
|
5
|
+
"outDir": "./build",
|
|
6
|
+
"rootDir": "./src",
|
|
7
|
+
"emitDeclarationOnly": false,
|
|
8
|
+
"noEmit": true
|
|
9
|
+
},
|
|
10
|
+
"include": [
|
|
11
|
+
"**/*.spec.ts"
|
|
12
|
+
],
|
|
13
|
+
"references": [
|
|
14
|
+
{ "path": "../util/tsconfig.build.json" },
|
|
15
|
+
{ "path": "../x-randomvalues/tsconfig.build.json" }
|
|
16
|
+
]
|
|
17
|
+
}
|