* 3.7

* Update new rules

* RegExp

* formatBalance cleanups

* Revert

* Formatting

* fill

* format test fix

* cleanups

* Cleanups

* Expand bip39 tests

* Cleanups

* Cleanups
This commit is contained in:
Jaco Greeff
2020-11-01 14:44:14 +01:00
committed by GitHub
parent 4a0fa7f615
commit 3230663ae1
37 changed files with 345 additions and 2434 deletions
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@polkadot/keyring",
"version": "3.6.2-12",
"version": "3.7.0",
"description": "Keyring management",
"main": "index.js",
"publishConfig": {
@@ -28,7 +28,7 @@
"homepage": "https://github.com/polkadot-js/common/tree/master/packages/keyring#readme",
"dependencies": {
"@babel/runtime": "^7.12.1",
"@polkadot/util": "^3.6.2-12",
"@polkadot/util-crypto": "^3.6.2-12"
"@polkadot/util": "^3.7.0",
"@polkadot/util-crypto": "^3.7.0"
}
}
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@polkadot/networks",
"version": "3.6.2-12",
"version": "3.7.0",
"description": "A list of all available Substrate networks and their applicable prefixes",
"main": "index.js",
"publishConfig": {
@@ -29,7 +29,7 @@
"@babel/runtime": "^7.12.1"
},
"devDependencies": {
"@polkadot/util": "^3.6.2-12",
"@polkadot/x-fetch": "^3.6.2-12"
"@polkadot/util": "^3.7.0",
"@polkadot/x-fetch": "^3.7.0"
}
}
+19 -57
View File
@@ -11,6 +11,16 @@ const UNSORTED = [0, 2, 42];
// last. This make lookups for the current a simple genesisHash[0]
// (See Kusama as an example)
const createReserved = (prefix: number, displayName = 'This prefix is reserved.'): NetworkFromSubstrate => ({
decimals: null,
displayName,
network: `reserved${prefix}`,
prefix,
standardAccount: null,
symbols: null,
website: null
});
const all: NetworkFromSubstrate[] = [
{
decimals: [10],
@@ -23,15 +33,7 @@ const all: NetworkFromSubstrate[] = [
symbols: ['DOT'],
website: 'https://polkadot.network'
},
{
decimals: null,
displayName: 'This prefix is reserved.',
network: 'reserved1',
prefix: 1,
standardAccount: null,
symbols: null,
website: null
},
createReserved(1),
{
decimals: [12],
displayName: 'Kusama Relay Chain',
@@ -47,15 +49,7 @@ const all: NetworkFromSubstrate[] = [
symbols: ['KSM'],
website: 'https://kusama.network'
},
{
decimals: null,
displayName: 'This prefix is reserved.',
network: 'reserved3',
prefix: 3,
standardAccount: null,
symbols: null,
website: null
},
createReserved(3),
{
decimals: null,
displayName: 'Katal Chain',
@@ -195,14 +189,14 @@ const all: NetworkFromSubstrate[] = [
website: 'https://geekcash.org'
},
{
decimals: null,
decimals: [12],
displayName: 'Stafi',
genesisHash: ['0x290a4149f09ea0e402c74c1c7e96ae4239588577fe78932f94f5404c68243d80'],
network: 'stafi',
prefix: 20,
standardAccount: '*25519',
symbols: null,
website: null
symbols: ['FIS'],
website: 'https://stafi.io'
},
{
decimals: [6],
@@ -333,15 +327,7 @@ const all: NetworkFromSubstrate[] = [
symbols: null,
website: 'https://substrate.dev/'
},
{
decimals: null,
displayName: 'This prefix is reserved.',
network: 'reserved43',
prefix: 43,
standardAccount: null,
symbols: null,
website: null
},
createReserved(43),
{
decimals: [8],
displayName: 'ChainX',
@@ -351,33 +337,9 @@ const all: NetworkFromSubstrate[] = [
symbols: ['PCX'],
website: 'https://chainx.org/'
},
{
decimals: null,
displayName: 'This prefix is reserved.',
network: 'reserved46',
prefix: 46,
standardAccount: null,
symbols: null,
website: null
},
{
decimals: null,
displayName: 'This prefix is reserved.',
network: 'reserved47',
prefix: 47,
standardAccount: null,
symbols: null,
website: null
},
{
decimals: null,
displayName: 'All prefixes 48 and higher are reserved and cannot be allocated.',
network: 'reserved48',
prefix: 48,
standardAccount: null,
symbols: null,
website: null
}
createReserved(46),
createReserved(47),
createReserved(48, 'All prefixes 48 and higher are reserved and cannot be allocated.')
];
// The list of available/claimed prefixes
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@polkadot/util-crypto",
"version": "3.6.2-12",
"version": "3.7.0",
"description": "A collection of useful crypto utilities for @polkadot",
"main": "index.js",
"keywords": [
@@ -26,8 +26,8 @@
"homepage": "https://github.com/polkadot-js/common/tree/master/packages/util-crypto#readme",
"dependencies": {
"@babel/runtime": "^7.12.1",
"@polkadot/networks": "^3.6.2-12",
"@polkadot/util": "^3.6.2-12",
"@polkadot/networks": "^3.7.0",
"@polkadot/util": "^3.7.0",
"@polkadot/wasm-crypto": "^1.4.1",
"base-x": "^3.0.8",
"blakejs": "^1.1.0",
+26 -15
View File
@@ -17,6 +17,25 @@ const LOOKUP = BASE32_ALPHABET
return lookup;
}, {});
/** @internal */
function decode (output: Uint8Array, input: string, offset: number): [Uint8Array, number, number] {
let bits = 0;
let buffer = 0;
let written = 0;
for (let i = offset; i < input.length; i++) {
buffer = (buffer << BITS_PER_CHAR) | LOOKUP[input[i]];
bits += BITS_PER_CHAR;
if (bits >= 8) {
bits -= 8;
output[written++] = 0xff & (buffer >> bits);
}
}
return [output, bits, buffer];
}
/**
* @name base32Decode
* @summary Delookup a base32 value.
@@ -26,22 +45,14 @@ const LOOKUP = BASE32_ALPHABET
export default function base32Decode (value: string, ipfsCompat = false): Uint8Array {
validate(value, ipfsCompat);
const out = new Uint8Array(((value.length - (ipfsCompat ? 1 : 0)) * BITS_PER_CHAR / 8) | 0);
let bits = 0;
let buffer = 0;
let written = 0;
for (let i = (ipfsCompat ? 1 : 0); i < value.length; ++i) {
buffer = (buffer << BITS_PER_CHAR) | LOOKUP[value[i]];
bits += BITS_PER_CHAR;
if (bits >= 8) {
bits -= 8;
out[written++] = 0xff & (buffer >> bits);
}
}
const offset = (ipfsCompat ? 1 : 0);
const [output, bits, buffer] = decode(
new Uint8Array(((value.length - offset) * BITS_PER_CHAR / 8) | 0),
value,
offset
);
assert(!(bits >= BITS_PER_CHAR || 0xff & (buffer << (8 - bits))), 'Unexpected end of data');
return out;
return output;
}
File diff suppressed because one or more lines are too long
+17 -50
View File
@@ -15,6 +15,7 @@
import createHash from 'create-hash';
import { pbkdf2Sync } from 'pbkdf2';
import { assert, u8aToU8a } from '@polkadot/util';
import randomAsU8a from '../random/asU8a';
import DEFAULT_WORDLIST from './bip39-en';
@@ -56,26 +57,20 @@ export function mnemonicToSeedSync (mnemonic: string, password?: string): Buffer
return pbkdf2Sync(mnemonicBuffer, saltBuffer, 2048, 64, 'sha512');
}
export function mnemonicToEntropy (mnemonic: string): string {
export function mnemonicToEntropy (mnemonic: string): Uint8Array {
const words = normalize(mnemonic).split(' ');
if (words.length % 3 !== 0) {
throw new Error(INVALID_MNEMONIC);
}
assert(words.length % 3 === 0, INVALID_MNEMONIC);
// convert word indices to 11 bit binary strings
const bits = words
.map(
(word: string): string => {
const index = DEFAULT_WORDLIST.indexOf(word);
.map((word): string => {
const index = DEFAULT_WORDLIST.indexOf(word);
if (index === -1) {
throw new Error(INVALID_MNEMONIC);
}
assert(index !== -1, INVALID_MNEMONIC);
return index.toString(2).padStart(11, '0');
}
)
return index.toString(2).padStart(11, '0');
})
.join('');
// split the binary string into ENT/CS
@@ -86,62 +81,34 @@ export function mnemonicToEntropy (mnemonic: string): string {
// calculate the checksum and compare
const entropyBytes = entropyBits.match(/(.{1,8})/g)?.map(binaryToByte);
if (!entropyBytes || entropyBytes.length < 16) {
throw new Error(INVALID_ENTROPY);
} else if (entropyBytes.length > 32) {
throw new Error(INVALID_ENTROPY);
} else if (entropyBytes.length % 4 !== 0) {
throw new Error(INVALID_ENTROPY);
}
assert(entropyBytes && entropyBytes.length % 4 === 0 && entropyBytes.length >= 16 && entropyBytes.length <= 32, INVALID_ENTROPY);
const entropy = Buffer.from(entropyBytes);
const entropy = u8aToU8a(entropyBytes);
const newChecksum = deriveChecksumBits(entropy);
if (newChecksum !== checksumBits) {
throw new Error(INVALID_CHECKSUM);
}
assert(newChecksum === checksumBits, INVALID_CHECKSUM);
return entropy.toString('hex');
return entropy;
}
export function entropyToMnemonic (entropy: Uint8Array): string {
// 128 <= ENT <= 256
if (entropy.length < 16) {
throw new TypeError(INVALID_ENTROPY);
}
if (entropy.length > 32) {
throw new TypeError(INVALID_ENTROPY);
} else if (entropy.length % 4 !== 0) {
throw new TypeError(INVALID_ENTROPY);
}
assert(entropy.length % 4 === 0 && entropy.length >= 16 && entropy.length <= 32, INVALID_ENTROPY);
const entropyBits = bytesToBinary(Array.from(entropy));
const checksumBits = deriveChecksumBits(entropy);
const bits = entropyBits + checksumBits;
// we just set it prior, so this is a safe check
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const chunks = bits.match(/(.{1,11})/g)!;
const words = chunks.map(
(binary: string): string => {
const index = binaryToByte(binary);
return DEFAULT_WORDLIST[index];
}
);
return words.join(' ');
return (entropyBits + checksumBits).match(/(.{1,11})/g)!
.map((binary) => DEFAULT_WORDLIST[binaryToByte(binary)])
.join(' ');
}
export function generateMnemonic (strength?: number): string {
strength = strength || 128;
if (strength % 32 !== 0) {
throw new TypeError(INVALID_ENTROPY);
}
assert(strength % 32 === 0, INVALID_ENTROPY);
return entropyToMnemonic(randomAsU8a(strength / 8));
}
@@ -11,24 +11,20 @@ describe('mnemonicGenerate', (): void => {
});
it('generates a valid mnemonic (default strength)', (): void => {
const mnemonic = generate();
console.error(mnemonic);
expect(
validate(mnemonic)
validate(generate())
).toEqual(true);
});
([12, 15, 18, 21, 24] as WordCount[]).forEach((num: WordCount): void => {
it(`generates a valid mnemonic (${num} words)`, (): void => {
const mnemonic = generate(num);
const isValid = validate(mnemonic);
[false, true].forEach((onlyJs): void => {
const mnemonic = generate(num, onlyJs);
const isValid = validate(mnemonic);
console.error(mnemonic);
expect(mnemonic.split(' ')).toHaveLength(num);
expect(isValid).toEqual(true);
expect(mnemonic.split(' ')).toHaveLength(num);
expect(isValid).toEqual(true);
});
});
});
});
@@ -30,8 +30,8 @@ const STRENGTH_MAP = {
* const mnemonic = mnemonicGenerate(); // => string
* ```
*/
export default function mnemonicGenerate (numWords: WordCount = 12): string {
return isReady()
export default function mnemonicGenerate (numWords: WordCount = 12, onlyJs = false): string {
return isReady() && !onlyJs
? bip39Generate(numWords)
: generateMnemonic(STRENGTH_MAP[numWords]);
}
@@ -15,6 +15,7 @@ describe('mnemonicToEntropy', (): void => {
tests.forEach(([mnemonic, entropy], index): void => {
it(`Created correct entropy for ${index}`, (): void => {
expect(u8aToHex(toEntropy(mnemonic))).toEqual(entropy);
expect(u8aToHex(toEntropy(mnemonic, true))).toEqual(entropy);
});
});
});
@@ -3,17 +3,12 @@
import '../polyfill';
import { hexAddPrefix, hexToU8a } from '@polkadot/util';
import { bip39ToEntropy, isReady } from '@polkadot/wasm-crypto';
import { mnemonicToEntropy } from './bip39';
export default function toEntropy (mnemonic: string): Uint8Array {
return isReady()
export default function toEntropy (mnemonic: string, onlyJs = false): Uint8Array {
return isReady() && !onlyJs
? bip39ToEntropy(mnemonic)
: hexToU8a(
hexAddPrefix(
mnemonicToEntropy(mnemonic)
)
);
: mnemonicToEntropy(mnemonic);
}
@@ -6,22 +6,20 @@ import { waitReady } from '@polkadot/wasm-crypto';
import { mnemonicToLegacySeed } from './';
const MENMONIC = 'seed sock milk update focus rotate barely fade car face mechanic mercy';
const SEED = '0x3c121e20de068083b49c2315697fb59a2d9e8643c24e5ea7628132c58969a027';
describe('mnemonicToLegacySeed', (): void => {
beforeEach(async (): Promise<void> => {
await waitReady();
});
it('generates a valid seed', (): void => {
expect(
u8aToHex(
mnemonicToLegacySeed('seed sock milk update focus rotate barely fade car face mechanic mercy')
)
).toEqual('0x3c121e20de068083b49c2315697fb59a2d9e8643c24e5ea7628132c58969a027');
});
it('generates the seed via WASM', async (): Promise<void> => {
await waitReady();
u8aToHex(mnemonicToLegacySeed(MENMONIC))
).toEqual(SEED);
expect(
u8aToHex(
mnemonicToLegacySeed('seed sock milk update focus rotate barely fade car face mechanic mercy')
)
).toEqual('0x3c121e20de068083b49c2315697fb59a2d9e8643c24e5ea7628132c58969a027');
u8aToHex(mnemonicToLegacySeed(MENMONIC, undefined, true))
).toEqual(SEED);
});
});
@@ -24,8 +24,8 @@ import { mnemonicToSeedSync } from './bip39';
* }
* ```
*/
export default function toLegacy (mnemonic: string, password = ''): Uint8Array {
return isReady()
export default function toLegacy (mnemonic: string, password = '', onlyJs = false): Uint8Array {
return isReady() && !onlyJs
? bip39ToSeed(mnemonic, password)
: bufferToU8a(mnemonicToSeedSync(mnemonic, password)).subarray(0, 32);
}
@@ -7,6 +7,9 @@ import mnemonicToMiniSecret from './toMiniSecret';
import tests from '../schnorrkel/keypair/testing';
import { cryptoWaitReady } from '..';
const MNEMONIC = 'seed sock milk update focus rotate barely fade car face mechanic mercy';
const SEED = '0x4d1ab2a57929edfd018aaa974e62ed557e3f54b4104acabedf73c8f5a1dbb029';
describe('mnemonicToMiniSecret', (): void => {
beforeEach(async (): Promise<void> => {
await cryptoWaitReady();
@@ -14,8 +17,11 @@ describe('mnemonicToMiniSecret', (): void => {
it('generates a valid seed', (): void => {
expect(
u8aToHex(mnemonicToMiniSecret('seed sock milk update focus rotate barely fade car face mechanic mercy'))
).toEqual('0x4d1ab2a57929edfd018aaa974e62ed557e3f54b4104acabedf73c8f5a1dbb029');
u8aToHex(mnemonicToMiniSecret(MNEMONIC))
).toEqual(SEED);
expect(
u8aToHex(mnemonicToMiniSecret(MNEMONIC, undefined, true))
).toEqual(SEED);
});
tests.forEach(([mnemonic, , seed], index): void => {
@@ -26,6 +32,12 @@ describe('mnemonicToMiniSecret', (): void => {
// mini returned here, only check first 32-bytes (64 hex + 2 prefix)
seed.substr(0, 66)
);
expect(
u8aToHex(mnemonicToMiniSecret(mnemonic, 'Substrate', true))
).toEqual(
// mini returned here, only check first 32-bytes (64 hex + 2 prefix)
seed.substr(0, 66)
);
});
});
});
@@ -9,8 +9,8 @@ import { bip39ToMiniSecret, isReady } from '@polkadot/wasm-crypto';
import toEntropy from './toEntropy';
export default function toMiniSecret (mnemonic: string, password = ''): Uint8Array {
if (isReady()) {
export default function toMiniSecret (mnemonic: string, password = '', onlyJs = false): Uint8Array {
if (isReady() && !onlyJs) {
return bip39ToMiniSecret(mnemonic, password);
}
@@ -13,11 +13,17 @@ describe('mnemonicValidate', (): void => {
expect(
validate('seed sock milk update focus rotate barely fade car face mechanic mercy')
).toEqual(true);
expect(
validate('seed sock milk update focus rotate barely fade car face mechanic mercy', true)
).toEqual(true);
});
it('returns false on invalid', (): void => {
expect(
validate('wine photo extra cushion basket dwarf humor cloud truck job boat submit')
).toEqual(false);
expect(
validate('wine photo extra cushion basket dwarf humor cloud truck job boat submit', true)
).toEqual(false);
});
});
@@ -20,8 +20,8 @@ import { validateMnemonic } from './bip39';
* const isValidMnemonic = mnemonicValidate(mnemonic); // => boolean
* ```
*/
export default function mnemonicValidate (mnemonic: string): boolean {
return isReady()
export default function mnemonicValidate (mnemonic: string, onlyJs = false): boolean {
return isReady() && !onlyJs
? bip39Validate(mnemonic)
: validateMnemonic(mnemonic);
}
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@polkadot/util",
"version": "3.6.2-12",
"version": "3.7.0",
"description": "A collection of useful utilities for @polkadot",
"main": "index.js",
"keywords": [
@@ -26,8 +26,8 @@
"homepage": "https://github.com/polkadot-js/common/tree/master/packages/util#readme",
"dependencies": {
"@babel/runtime": "^7.12.1",
"@polkadot/x-textdecoder": "^3.6.2-12",
"@polkadot/x-textencoder": "^3.6.2-12",
"@polkadot/x-textdecoder": "^3.7.0",
"@polkadot/x-textencoder": "^3.7.0",
"@types/bn.js": "^4.11.6",
"bn.js": "^5.1.3",
"camelcase": "^5.3.1",
+15 -16
View File
@@ -12,6 +12,15 @@ interface Options extends ToBnOptions {
bitLength?: number;
}
function setBn (valueBn: BN, byteLength: number, { isLe, isNegative }: Options): Uint8Array {
const output = new Uint8Array(byteLength);
const bn = isNegative ? valueBn.toTwos(byteLength * 8) : valueBn;
output.set(bn.toArray(isLe ? 'le' : 'be', byteLength), 0);
return output;
}
/**
* @name bnToU8a
* @summary Creates a Uint8Array object from a BN.
@@ -29,7 +38,7 @@ interface Options extends ToBnOptions {
function bnToU8a <ExtToBn extends ToBn> (value?: ExtToBn | BN | BigInt | number | null, options?: Options): Uint8Array;
function bnToU8a <ExtToBn extends ToBn> (value?: ExtToBn | BN | BigInt | number | null, bitLength?: number, isLe?: boolean): Uint8Array;
function bnToU8a <ExtToBn extends ToBn> (value?: ExtToBn | BN | BigInt | number | null, arg1: number | Options = { bitLength: -1, isLe: true, isNegative: false }, arg2?: boolean): Uint8Array {
const _options: Options = {
const options: Options = {
bitLength: -1,
isLe: true,
isNegative: false,
@@ -37,25 +46,15 @@ function bnToU8a <ExtToBn extends ToBn> (value?: ExtToBn | BN | BigInt | number
};
const valueBn = bnToBn(value);
const byteLength = _options.bitLength === -1
const byteLength = options.bitLength === -1
? Math.ceil(valueBn.bitLength() / 8)
: Math.ceil((_options.bitLength || 0) / 8);
: Math.ceil((options.bitLength || 0) / 8);
if (!value) {
return _options.bitLength === -1
return value
? setBn(valueBn, byteLength, options)
: options.bitLength === -1
? new Uint8Array()
: new Uint8Array(byteLength);
}
const output = new Uint8Array(byteLength);
const bn = _options.isNegative ? valueBn.toTwos(byteLength * 8) : valueBn;
output.set(
bn.toArray(_options.isLe ? 'le' : 'be', byteLength),
0
);
return output;
}
export default bnToU8a;
@@ -20,6 +20,12 @@ describe('formatBalance', (): void => {
).toEqual('123.4567 µUnit');
});
it('formats 123,456 (decimals=0)', (): void => {
expect(
formatBalance(123456, { decimals: 0, withSi: true })
).toEqual('123.4560 kUnit');
});
it('formats BigInt numbers', (): void => {
expect(
formatBalance(123456789000n, { decimals: 15, withSi: true })
+2 -2
View File
@@ -61,8 +61,8 @@ function _formatBalance <ExtToBn extends ToBn> (input?: number | string | BN | B
: options;
// NOTE We start at midpoint (8) minus 1 - this means that values display as
// 123.456 instead of 0.123k (so always 6 relevant). Additionally we us ceil
// so there are at most 3 decimal before the decimal seperator
// 123.456 instead of 0.123k (so always 6 relevant). Additionally we use ceil
// so there are at most 3 decimal before the decimal separator
const si = calcSi(text, decimals, forceUnit);
const mid = text.length - (decimals + si.power);
const prefix = text.substr(0, mid);
@@ -1,6 +1,7 @@
// Copyright 2017-2020 @polkadot/util authors & contributors
// SPDX-License-Identifier: Apache-2.0
// eslint-disable-next-line prefer-regex-literals
const NUMBER_REGEX = new RegExp('(\\d+?)(?=(\\d{3})+(?!\\d)|$)', 'g');
export default function formatDecimal (value: string): string {
+21 -20
View File
@@ -8,37 +8,38 @@ import BN from 'bn.js';
import isToBn from '../is/toBn';
function getValue <ExtToBn extends ToBn> (value?: BN | ExtToBn | Date | number | null): number {
if (value) {
if (isToBn(value)) {
return getValue(value.toBn());
} else if (value instanceof Date) {
return getValue(value.getTime());
} else if (value instanceof BN) {
return getValue(value.toNumber());
}
if (isToBn(value)) {
return getValue(value.toBn());
} else if (value instanceof Date) {
return getValue(value.getTime());
} else if (value instanceof BN) {
return getValue(value.toNumber());
}
return (value as number) || 0;
return value || 0;
}
function formatValue (elapsed: number): string {
if (elapsed < 15) {
return `${elapsed.toFixed(1)}s`;
} else if (elapsed < 60) {
return `${elapsed | 0}s`;
} else if (elapsed < 3600) {
return `${elapsed / 60 | 0}m`;
}
return `${elapsed / 3600 | 0}h`;
}
export default function formatElapsed <ExtToBn extends ToBn> (now?: Date | null, value?: BN | ExtToBn | Date | number | null): string {
const tsNow = (now && now.getTime()) || 0;
const tsValue = getValue(value);
let display = '0.0s';
if (tsNow && tsValue) {
const elapsed = Math.max(Math.abs(tsNow - tsValue), 0) / 1000;
if (elapsed < 15) {
display = `${elapsed.toFixed(1)}s`;
} else if (elapsed < 60) {
display = `${elapsed | 0}s`;
} else if (elapsed < 3600) {
display = `${elapsed / 60 | 0}m`;
} else {
display = `${elapsed / 3600 | 0}h`;
}
return formatValue(elapsed);
}
return display;
return '0.0s';
}
+1 -1
View File
@@ -8,7 +8,7 @@ import hexStripPrefix from './stripPrefix';
import { ToBnOptions } from '../types';
function reverse (value: string): string {
return (value.match(new RegExp('.{1,2}', 'g')) || [])
return (value.match(/.{1,2}/g) || [])
.reverse()
.join('');
}
+3 -7
View File
@@ -13,11 +13,7 @@ const FORMAT = [9, 10, 13];
* Checks to see if the input string or Uint8Array is printable ASCII, 32-127 + formatters
*/
export default function isAscii (value?: number[] | Buffer | Uint8Array | string | null): boolean {
if (!value) {
return isString(value);
}
const u8a = u8aToU8a(value);
return !u8a.some((byte) => (byte >= 127) || (byte < 32 && !FORMAT.includes(byte)));
return value
? !u8aToU8a(value).some((byte) => (byte >= 127) || (byte < 32 && !FORMAT.includes(byte)))
: isString(value);
}
+1 -1
View File
@@ -1,7 +1,7 @@
// Copyright 2017-2020 @polkadot/util authors & contributors
// SPDX-License-Identifier: Apache-2.0
const re = new RegExp('(Development|Local Testnet)$');
const re = /(Development|Local Testnet)$/;
export default function isTestChain (chain?: string | null): boolean {
if (!chain) {
+7 -3
View File
@@ -3,6 +3,8 @@
import { Logger } from './types';
import BN from 'bn.js';
import { logger } from '.';
import { format } from './logger';
@@ -62,15 +64,17 @@ describe('logger', (): void => {
);
});
it('logs with mulptiple values', (): void => {
l.log('test', 'a', 2);
it('logs with multiple values', (): void => {
l.log('test', 'a', 2, new BN('12345678900987654321'), Buffer.from([0, 1, 2, 3]));
expect(spy.log).toHaveBeenCalledWith(
dateMatch,
prefixMatch,
expect.stringMatching('test'),
expect.stringMatching('a'),
2
2,
expect.stringMatching('12345678900987654321'),
expect.stringMatching('0x00010203')
);
});
+6 -15
View File
@@ -5,11 +5,12 @@ import { Logger, Logger$Data } from './types';
import formatDate from './format/formatDate';
import isBn from './is/bn';
import isBuffer from './is/buffer';
import isFunction from './is/function';
import isObject from './is/object';
import isU8a from './is/u8a';
import u8aToHex from './u8a/toHex';
import u8aToU8a from './u8a/toU8a';
import { isBuffer } from './is';
type ConsoleType = 'error' | 'log' | 'warn';
type LogType = ConsoleType | 'debug';
@@ -34,21 +35,11 @@ function formatObject (value: Record<string, unknown>): Record<string, unknown>
export function format (value: unknown): unknown {
if (Array.isArray(value)) {
return value.map(format);
}
if (isBn(value)) {
} else if (isBn(value)) {
return value.toString();
}
if (isBuffer(value)) {
return `0x${value.toString('hex')}`;
}
if (isU8a(value)) {
return u8aToHex(value);
}
if (value && isObject(value) && value.constructor === Object) {
} else if (isU8a(value) || isBuffer(value)) {
return u8aToHex(u8aToU8a(value));
} else if (value && isObject(value) && value.constructor === Object) {
return formatObject(value);
}
+15 -35
View File
@@ -2,50 +2,30 @@
// SPDX-License-Identifier: Apache-2.0
/* eslint-disable no-extend-native */
/* eslint-disable @typescript-eslint/unbound-method */
import assert from '../assert';
function getOffset (value: number, length: number): number {
return value < 0
? Math.max(length + value, 0)
: Math.min(value, length);
}
if (!Array.prototype.fill) {
// eslint-disable-next-line no-extend-native,@typescript-eslint/no-explicit-any
Array.prototype.fill = function fill (value: any, start = 0, end?: number): any[] {
// Steps 1-2.
if (!this) {
throw new TypeError('this is null or not defined');
}
// eslint-disable-next-line no-extend-native
Array.prototype.fill = function fill <T> (value: T, start = 0, end?: number): T[] {
assert(this, 'this is null or not defined');
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const A = Object(this);
const A = Object(this) as T[];
const relativeEnd = end ?? A.length;
const final = getOffset(relativeEnd, A.length);
let k = getOffset(start, A.length);
// Steps 3-5.
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
const len = A.length >>> 0;
// Steps 6-7.
const relativeStart = start >> 0;
// Step 8.
let k = relativeStart < 0
? Math.max(len + relativeStart, 0)
: Math.min(relativeStart, len);
// Steps 9-10.
const relativeEnd = end === undefined
? len
: end >> 0;
// Step 11.
const final = relativeEnd < 0
? Math.max(len + relativeEnd, 0)
: Math.min(relativeEnd, len);
// Step 12.
while (k < final) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access
A[k] = value;
k++;
}
// Step 13.
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
return A;
};
}
+20 -13
View File
@@ -7,6 +7,22 @@ for (let n = 0; n < 256; ++n) {
ALPHABET[n] = n.toString(16).padStart(2, '0');
}
/** @internal */
function extract (value: Uint8Array): string {
const result = new Array(value.length) as string[];
for (let i = 0; i < value.length; i++) {
result[i] = ALPHABET[value[i]];
}
return result.join('');
}
/** @internal */
function trim (value: Uint8Array, halfLength: number): string {
return `${u8aToHex(value.subarray(0, halfLength), -1, false)}…${u8aToHex(value.subarray(value.length - halfLength), -1, false)}`;
}
/**
* @name u8aToHex
* @summary Creates a hex string from a Uint8Array object.
@@ -32,17 +48,8 @@ export default function u8aToHex (value?: Uint8Array | null, bitLength = -1, isP
const byteLength = Math.ceil(bitLength / 8);
if (byteLength > 0 && value.length > byteLength) {
const halfLength = Math.ceil(byteLength / 2);
return `${u8aToHex(value.subarray(0, halfLength), -1, isPrefixed)}…${u8aToHex(value.subarray(value.length - halfLength), -1, false)}`;
}
const result = new Array(value.length) as string[];
for (let i = 0; i < value.length; i++) {
result[i] = ALPHABET[value[i]];
}
return prefix + result.join('');
return prefix + ((byteLength > 0 && value.length > byteLength)
? trim(value, Math.ceil(byteLength / 2))
: extract(value)
);
}
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@polkadot/x-fetch",
"version": "3.6.2-12",
"version": "3.7.0",
"description": "A cross-environment fetch replacement",
"browser": "browser.js",
"main": "node.js",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@polkadot/x-textdecoder",
"version": "3.6.2-12",
"version": "3.7.0",
"description": "A TextDecoder replacement",
"browser": "browser.js",
"main": "node.js",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@polkadot/x-textencoder",
"version": "3.6.2-12",
"version": "3.7.0",
"description": "A TextDecoder replacement",
"browser": "browser.js",
"main": "node.js",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@polkadot/x-ws",
"version": "3.6.2-12",
"version": "3.7.0",
"description": "A cross-environment WebSocket replacement",
"browser": "browser.js",
"main": "node.js",