Compare commits

...
23 Commits
Author SHA1 Message Date
Github Actions f431f02f11 [CI Skip] release/stable 4.0.1
skip-checks: true
2020-11-08 12:49:18 +00:00
Jaco Greeff 2063183f50 4.0 (#752)
* 4.0

* Exact deps
2020-11-08 13:45:10 +01:00
Github Actions 8280af08a6 [CI Skip] release/beta 4.0.0-11
skip-checks: true
2020-11-08 11:15:38 +00:00
Jaco Greeff 8029a54508 Additional complexity adjustments (#751)
* Adjust encoder/decoder fallbacks

* Dep-dup is functions

* Complexity cleanups

* More complexity adjustments
2020-11-08 12:10:29 +01:00
Github Actions 9e5478e0c0 [CI Skip] release/beta 4.0.0-10
skip-checks: true
2020-11-08 10:25:06 +00:00
Jaco Greeff c67c1966d7 Adjust encoder/decoder fallbacks (#750)
* Adjust encoder/decoder fallbacks

* Dep-dup is functions

* Complexity cleanups
2020-11-08 11:20:22 +01:00
Github Actions e1aa096cef [CI Skip] release/beta 4.0.0-9
skip-checks: true
2020-11-07 16:16:46 +00:00
Jaco Greeff 7135941b6a Cleanups to signature verification (#749) 2020-11-07 17:11:49 +01:00
Github Actions dc24fb82a8 [CI Skip] release/beta 4.0.0-8
skip-checks: true
2020-11-07 15:05:33 +00:00
Jaco Greeff 32cfe3707e Remove jest getRandomValues polyfill (#748)
* Remove jest getRandomValues polyfill

* react-native in all x-*
2020-11-07 15:59:56 +01:00
Github Actions 97378be94e [CI Skip] release/beta 4.0.0-7
skip-checks: true
2020-11-07 14:27:52 +00:00
Jaco Greeff db0559e9c9 RN-specific getRandomValues (no node crypto) (#747)
* RN-specific getRandomValues (no node crypto)

* Use polyfilled as available

* === object
2020-11-07 15:22:42 +01:00
Github Actions 94d6a900f7 [CI Skip] release/beta 4.0.0-6
skip-checks: true
2020-11-07 10:22:24 +00:00
Jaco Greeff d751c03d45 Bump wasm-crypto (#745)
* Bump wasm-crypto

* Use x-randomvalues for randomAsU8a
2020-11-07 11:18:06 +01:00
Github Actions aef8003d50 [CI Skip] release/beta 4.0.0-5
skip-checks: true
2020-11-05 15:05:27 +00:00
Jaco Greeff 2810b35d6c Add Synesthesia to networks (#744)
* Add Synesthesia to networks

* Add networks:crosscheck to steps for PR

* Add notifications team
2020-11-05 15:59:47 +01:00
Github Actions 6148932389 [CI Skip] release/beta 4.0.0-4
skip-checks: true
2020-11-05 14:43:13 +00:00
Jaco Greeff f4889a36d4 Bump wasm (#743) 2020-11-05 15:37:38 +01:00
Github Actions e8879c0ffc [CI Skip] release/beta 4.0.0-3
skip-checks: true
2020-11-03 12:09:33 +00:00
Jaco Greeff ed64514415 Bump wasm-crypto 2020-11-03 13:04:10 +01:00
Github Actions fcc25ee2c8 [CI Skip] release/beta 4.0.0-2
skip-checks: true
2020-11-03 09:34:06 +00:00
Jaco Greeff 695e19a8a7 Remove polyfills (#739)
* Remove polyfills

* CHANGELOG

* jestConfig

* Adjust jest

* Revert explicit overrides (from base)

* Fix dev

* 4.0.0

* Bump wasm-crypto

* min/max duplication

* Split tests, update dev

* startChar

* validate params

* complexity?

* secp256k1Verify options

* sign Options

* hasher extraction
2020-11-03 10:29:22 +01:00
Jaco Greeff 384bf9a41a CodeClimate exclusions 2020-11-01 15:08:35 +01:00
79 changed files with 1057 additions and 955 deletions
+2 -1
View File
@@ -1,4 +1,5 @@
exclude_patterns:
- "**/*.spec.js"
- "**/*.spec.ts"
- "docs/**/*.js"
- "packages/networks/src/index.ts"
- "packages/util/src/is/utf8.ts"
+1 -2
View File
@@ -1,10 +1,9 @@
---
assignees: ['jacogr']
title: SS58 registry is outdated
labels: ['ci', '@networks']
---
cc @jacogr
cc @polkadot-js/notifications
Discrepancies detected between https://github.com/paritytech/substrate/blob/master/ss58-registry.json and https://github.com/polkadot-js/common/blob/master/packages/networks/src/index.ts
+1 -1
View File
@@ -5,7 +5,7 @@ jobs:
pr:
strategy:
matrix:
step: ['lint', 'test', 'build']
step: ['lint', 'test', 'build', 'networks:crosscheck']
name: ${{ matrix.step }}
runs-on: ubuntu-latest
steps:
+12
View File
@@ -1,5 +1,17 @@
# CHANGELOG
## 4.0.1 Nov 8, 2020
- **Breaking change** Polyfills are not injected by these libraries anymore to avoid clobbering external globals, the user should provide them if their environment is missing base functionality.
Changes:
- Remove built-in utility polyfills for `Array.fill`, `String.padStart`, `String.padEnd` as well as `Object.setPrototypeOf`. These should be provided by the actual user of the libraries if so required.
- Update `@polkadot/wasm-crypto` library (under-the-hood cleanups)
- Remove explicit crypto polyfill injection (aligning with updated `@polkadot/wasm-crypto`)
- Add cross-environment `@polkadot/x-randomvalues` (for use in `@polkadot/wasm-crypto`)
## 3.7.1 Nov 1, 2020
Changes:
+2 -1
View File
@@ -10,7 +10,7 @@ module.exports = Object.assign({}, config, {
'@polkadot/util-(crypto)(.*)$': '<rootDir>/packages/util-$1/src/$2',
// eslint-disable-next-line sort-keys
'@polkadot/util(.*)$': '<rootDir>/packages/util/src/$1',
'@polkadot/x-(fetch|textdecoder|textencoder|ws)(.*)$': '<rootDir>/packages/x-$1/src/node'
'@polkadot/x-(fetch|randomvalues|textdecoder|textencoder|ws)(.*)$': '<rootDir>/packages/x-$1/src/node'
},
modulePathIgnorePatterns: [
'<rootDir>/packages/keyring/build',
@@ -18,6 +18,7 @@ module.exports = Object.assign({}, config, {
'<rootDir>/packages/util/build',
'<rootDir>/packages/util-crypto/build',
'<rootDir>/packages/x-fetch/build',
'<rootDir>/packages/x-randomvalues/build',
'<rootDir>/packages/x-textdecoder/build',
'<rootDir>/packages/x-textencoder/build',
'<rootDir>/packages/x-ws/build'
+2 -3
View File
@@ -7,7 +7,6 @@
"packages/*"
],
"resolutions": {
"babel-core": "^7.0.0-bridge.0",
"typescript": "^4.0.5"
},
"scripts": {
@@ -22,9 +21,9 @@
},
"devDependencies": {
"@babel/core": "^7.12.3",
"@polkadot/dev": "^0.59.12",
"@polkadot/dev": "^0.59.20",
"@polkadot/ts": "^0.3.53",
"@types/jest": "^26.0.15"
},
"version": "3.7.1"
"version": "4.0.1"
}
+7 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@polkadot/keyring",
"version": "3.7.1",
"version": "4.0.1",
"description": "Keyring management",
"main": "index.js",
"publishConfig": {
@@ -28,7 +28,11 @@
"homepage": "https://github.com/polkadot-js/common/tree/master/packages/keyring#readme",
"dependencies": {
"@babel/runtime": "^7.12.1",
"@polkadot/util": "^3.7.1",
"@polkadot/util-crypto": "^3.7.1"
"@polkadot/util": "4.0.1",
"@polkadot/util-crypto": "4.0.1"
},
"peerDependencies": {
"@polkadot/util": "4.0.1",
"@polkadot/util-crypto": "4.0.1"
}
}
+2 -2
View File
@@ -34,9 +34,9 @@ const TYPE_PREFIX = {
};
const TYPE_SIGNATURE = {
ecdsa: (m: Uint8Array, p: Partial<Keypair>) => secp256k1Sign(m, p, 'blake2'),
ecdsa: (m: Uint8Array, p: Partial<Keypair>) => secp256k1Sign(m, p, { hashType: 'blake2' }),
ed25519: naclSign,
ethereum: (m: Uint8Array, p: Partial<Keypair>) => secp256k1Sign(m, p, 'keccak'),
ethereum: (m: Uint8Array, p: Partial<Keypair>) => secp256k1Sign(m, p, { hashType: 'keccak' }),
sr25519: schnorrkelSign
};
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@polkadot/networks",
"version": "3.7.1",
"version": "4.0.1",
"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.7.1",
"@polkadot/x-fetch": "^3.7.1"
"@polkadot/util": "4.0.1",
"@polkadot/x-fetch": "4.0.1"
}
}
+9
View File
@@ -151,6 +151,15 @@ const all: NetworkFromSubstrate[] = [
symbols: ['XTX'],
website: 'https://totemaccounting.com'
},
{
decimals: [12],
displayName: 'Synesthesia',
network: 'synesthesia',
prefix: 15,
standardAccount: '*25519',
symbols: ['SYN'],
website: 'https://synesthesia.network/'
},
{
decimals: [12],
displayName: 'Kulupu',
+8 -4
View File
@@ -1,6 +1,6 @@
{
"name": "@polkadot/util-crypto",
"version": "3.7.1",
"version": "4.0.1",
"description": "A collection of useful crypto utilities for @polkadot",
"main": "index.js",
"keywords": [
@@ -26,9 +26,10 @@
"homepage": "https://github.com/polkadot-js/common/tree/master/packages/util-crypto#readme",
"dependencies": {
"@babel/runtime": "^7.12.1",
"@polkadot/networks": "^3.7.1",
"@polkadot/util": "^3.7.1",
"@polkadot/wasm-crypto": "^1.4.1",
"@polkadot/networks": "4.0.1",
"@polkadot/util": "4.0.1",
"@polkadot/wasm-crypto": "^2.0.1",
"@polkadot/x-randomvalues": "4.0.1",
"base-x": "^3.0.8",
"blakejs": "^1.1.0",
"bn.js": "^5.1.3",
@@ -47,5 +48,8 @@
"@types/pbkdf2": "^3.1.0",
"@types/scryptsy": "^2.0.0",
"@types/xxhashjs": "^0.2.2"
},
"peerDependencies": {
"@polkadot/util": "4.0.1"
}
}
+6 -2
View File
@@ -3,10 +3,14 @@
import validate from './validate';
export default function isBase32 (value?: string | null): boolean {
export function testValidator (validate: (value?: string | null, ipfsCompat?: boolean) => boolean, value?: string | null, ipfsCompat?: boolean): boolean {
try {
return validate(value);
return validate(value, ipfsCompat);
} catch (error) {
return false;
}
}
export default function isBase32 (value?: string | null, ipfsCompat?: boolean): boolean {
return testValidator(validate, value, ipfsCompat);
}
+4 -2
View File
@@ -4,12 +4,14 @@
import { validateChars } from '../base58/validate';
import { BASE32_ALPHABET } from './bs32';
const BASE_CONFIG = { alphabet: BASE32_ALPHABET, ipfsChar: 'b', type: 'base32' };
/**
* @name base32Validate
* @summary Validates a base32 value.
* @description
* Validates the the supplied value is valid base32
*/
export default function base32Validate (value?: string | null, ipfsCompat = false): true {
return validateChars('base32', BASE32_ALPHABET, value, ipfsCompat ? 'b' : undefined);
export default function base32Validate (value?: string | null, ipfsCompat?: boolean): true {
return validateChars(BASE_CONFIG, value, ipfsCompat);
}
+2 -5
View File
@@ -1,12 +1,9 @@
// Copyright 2017-2020 @polkadot/util-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0
import { testValidator } from '../base32/is';
import validate from './validate';
export default function isBase58 (value?: string | null, ipfsCompat?: boolean): boolean {
try {
return validate(value, ipfsCompat);
} catch (error) {
return false;
}
return testValidator(validate, value, ipfsCompat);
}
+14 -6
View File
@@ -5,11 +5,19 @@ import { assert } from '@polkadot/util';
import { BASE58_ALPHABET } from './bs58';
export function validateChars (type: string, alphabet: string, value?: string | null, startChar?: string): true {
assert(value, `Expected non-null, non-empty ${type} input`);
assert(!startChar || value[0] === startChar, `Expected ${type} to start with '${startChar || ''}'`);
interface CheckConfig {
alphabet: string;
ipfsChar: string;
type: string;
}
for (let i = (startChar ? 1 : 0); i < value.length; i++) {
const BASE_CONFIG = { alphabet: BASE58_ALPHABET, ipfsChar: 'z', type: 'base58' };
export function validateChars ({ alphabet, ipfsChar, type }: CheckConfig, value?: string | null, ipfsCompat?: boolean): true {
assert(value, `Expected non-null, non-empty ${type} input`);
assert(!ipfsCompat || value[0] === ipfsChar, `Expected ${type} to start with '${ipfsChar}'`);
for (let i = (ipfsCompat ? 1 : 0); i < value.length; i++) {
assert(alphabet.includes(value[i]), `Invalid ${type} character "${value[i]}" (0x${value.charCodeAt(i).toString(16)}) at index ${i}`);
}
@@ -22,6 +30,6 @@ export function validateChars (type: string, alphabet: string, value?: string |
* @description
* Validates the the supplied value is valid base58
*/
export default function base58Validate (value?: string | null, ipfsCompat = false): true {
return validateChars('base58', BASE58_ALPHABET, value, ipfsCompat ? 'z' : undefined);
export default function base58Validate (value?: string | null, ipfsCompat?: boolean): true {
return validateChars(BASE_CONFIG, value, ipfsCompat);
}
@@ -5,15 +5,16 @@ import { u8aToHex } from '@polkadot/util';
import { keccakAsU8a } from '../keccak';
function isInvalidChar (char: string, byte: number): boolean {
return (byte > 7 && char !== char.toUpperCase()) || (byte <= 7 && char !== char.toLowerCase());
}
export default function isEthereumChecksum (_address: string): boolean {
const address = _address.replace('0x', '');
const hash = u8aToHex(keccakAsU8a(address.toLowerCase()), -1, false);
for (let index = 0; index < 40; index++) {
const char = address[index];
const hashval = parseInt(hash[index], 16);
if ((hashval > 7 && char !== char.toUpperCase()) || (hashval <= 7 && char !== char.toLowerCase())) {
if (isInvalidChar(address[index], parseInt(hash[index], 16))) {
return false;
}
}
@@ -7,7 +7,7 @@ const ADDRESS = '0x00a329c0648769A73afAc7F9381E08FB43dBEA72';
describe('isEthereumChecksum', () => {
it('returns false on invalid address', () => {
expect(isEthereumChecksum('0xinvalid')).toBe(false);
expect(isEthereumChecksum('0x00a329c0648769')).toBe(false);
});
it('returns false on non-checksum address', () => {
-3
View File
@@ -1,9 +1,6 @@
// Copyright 2017-2020 @polkadot/util-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0
// polyfills
import './polyfill';
// out of order and early in the chain, this also kicks off initialization on require
export * from './init';
@@ -16,9 +16,9 @@ describe('mnemonicGenerate', (): void => {
).toEqual(true);
});
([12, 15, 18, 21, 24] as WordCount[]).forEach((num: WordCount): void => {
it(`generates a valid mnemonic (${num} words)`, (): void => {
[false, true].forEach((onlyJs): void => {
[false, true].forEach((onlyJs): void => {
([12, 15, 18, 21, 24] as WordCount[]).forEach((num: WordCount): void => {
it(`generates a valid mnemonic (${num} words, onlyJs=${onlyJs.toString()})`, (): void => {
const mnemonic = generate(num, onlyJs);
const isValid = validate(mnemonic);
@@ -27,4 +27,17 @@ describe('mnemonicGenerate', (): void => {
});
});
});
[true, false].forEach((onlyJs): void => {
it(`generates not deterministic (onlyJs=${onlyJs.toString()})`, (): void => {
[false, true].forEach((onlyJs): void => {
const m1 = generate(24, onlyJs);
const m2 = generate(24, onlyJs);
expect(m1 === m2).toEqual(false);
expect(validate(m1)).toEqual(true);
expect(validate(m2)).toEqual(true);
});
});
});
});
@@ -1,8 +1,6 @@
// Copyright 2017-2020 @polkadot/util-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0
import '../polyfill';
import { bip39Generate, isReady } from '@polkadot/wasm-crypto';
import { generateMnemonic } from './bip39';
@@ -1,8 +1,6 @@
// Copyright 2017-2020 @polkadot/util-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0
import '../polyfill';
/**
* @summary Create valid mnemonic strings, validate them using BIP39, and convert them to valid seeds
*/
@@ -1,8 +1,6 @@
// Copyright 2017-2020 @polkadot/util-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0
import '../polyfill';
import { bip39ToEntropy, isReady } from '@polkadot/wasm-crypto';
import { mnemonicToEntropy } from './bip39';
@@ -1,8 +1,6 @@
// Copyright 2017-2020 @polkadot/util-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0
import '../polyfill';
import { pbkdf2Sync } from 'pbkdf2';
import { bufferToU8a, stringToU8a, u8aToBuffer } from '@polkadot/util';
import { bip39ToMiniSecret, isReady } from '@polkadot/wasm-crypto';
@@ -1,8 +1,6 @@
// Copyright 2017-2020 @polkadot/util-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0
import '../polyfill';
import { bip39Validate, isReady } from '@polkadot/wasm-crypto';
import { validateMnemonic } from './bip39';
-4
View File
@@ -1,4 +0,0 @@
// Copyright 2017-2020 @polkadot/util-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0
import '@polkadot/wasm-crypto/crypto-polyfill';
+2 -2
View File
@@ -1,7 +1,7 @@
// Copyright 2017-2020 @polkadot/util-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0
import nacl from 'tweetnacl';
import getRandomValues from '@polkadot/x-randomvalues';
/**
* @name randomAsU8a
@@ -18,5 +18,5 @@ import nacl from 'tweetnacl';
* ```
*/
export default function randomAsU8a (length = 32): Uint8Array {
return nacl.randomBytes(length);
return getRandomValues(new Uint8Array(length));
}
@@ -3,8 +3,6 @@
import { Keypair } from '../types';
import '../polyfill';
import { sr25519DeriveKeypairHard } from '@polkadot/wasm-crypto';
import keypairFromU8a from './keypair/fromU8a';
@@ -1,8 +1,6 @@
// Copyright 2017-2020 @polkadot/util-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0
import '../polyfill';
import { sr25519DerivePublicSoft } from '@polkadot/wasm-crypto';
export default function deriveSoft (publicKey: Uint8Array, chainCode: Uint8Array): Uint8Array {
@@ -3,8 +3,6 @@
import { Keypair } from '../types';
import '../polyfill';
import { sr25519DeriveKeypairSoft } from '@polkadot/wasm-crypto';
import keypairFromU8a from './keypair/fromU8a';
@@ -1,8 +1,6 @@
// Copyright 2017-2020 @polkadot/util-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0
import '../polyfill';
export { default as schnorrkelDeriveHard } from './deriveHard';
export { default as schnorrkelDerivePublic } from './derivePublic';
export { default as schnorrkelDeriveSoft } from './deriveSoft';
@@ -3,8 +3,6 @@
import { Keypair } from '../../types';
import '../../polyfill';
import { sr25519KeypairFromSeed } from '@polkadot/wasm-crypto';
import keypairFromU8a from './fromU8a';
@@ -3,8 +3,6 @@
import { Keypair } from '../types';
import '../polyfill';
import { assert, u8aToU8a } from '@polkadot/util';
import { sr25519Sign } from '@polkadot/wasm-crypto';
@@ -1,8 +1,6 @@
// Copyright 2017-2020 @polkadot/util-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0
import '../polyfill';
import { assert, u8aToU8a } from '@polkadot/util';
import { sr25519Verify } from '@polkadot/wasm-crypto';
+5 -1
View File
@@ -9,13 +9,17 @@ import { assert, bnToU8a, u8aConcat } from '@polkadot/util';
import hasher from './hasher';
interface Options {
hashType: HashType;
}
const ec = new EC('secp256k1');
/**
* @name secp256k1Sign
* @description Returns message signature of `message`, using the supplied pair
*/
export default function secp256k1Sign (message: Uint8Array | string, { secretKey }: Partial<Keypair>, hashType: HashType = 'blake2'): Uint8Array {
export default function secp256k1Sign (message: Uint8Array | string, { secretKey }: Partial<Keypair>, { hashType = 'blake2' }: Partial<Options> = {}): Uint8Array {
assert(secretKey?.length === 32, 'Expected valid secp256k1 secretKey, 32-bytes');
const key = ec.keyFromPrivate(secretKey);
@@ -36,18 +36,18 @@ describe('sign and verify', (): void => {
it('signs/verifies a message by random key (keccak)', (): void => {
const pair = pairFromSeed(randomAsU8a());
const signature = sign(MESSAGE, pair, 'keccak');
const signature = sign(MESSAGE, pair, { hashType: 'keccak' });
const address = hasher('keccak', pair.publicKey);
expect(verify(MESSAGE, signature, address, 'keccak')).toBe(true);
expect(verify(MESSAGE, signature, address, { hashType: 'keccak' })).toBe(true);
});
it('fails verification on hasher mismatches', (): void => {
const pair = pairFromSeed(randomAsU8a());
const signature = sign(MESSAGE, pair, 'keccak');
const signature = sign(MESSAGE, pair, { hashType: 'keccak' });
const address = hasher('keccak', pair.publicKey);
expect(verify(MESSAGE, signature, address, 'blake2')).toBe(false);
expect(verify(MESSAGE, signature, address, { hashType: 'blake2' })).toBe(false);
});
it('works over a range of random keys (blake2)', (): void => {
@@ -55,7 +55,7 @@ describe('sign and verify', (): void => {
const pair = pairFromSeed(randomAsU8a());
try {
expect(verify(MESSAGE, sign(MESSAGE, pair, 'blake2'), hasher('blake2', pair.publicKey), 'blake2')).toBe(true);
expect(verify(MESSAGE, sign(MESSAGE, pair, { hashType: 'blake2' }), hasher('blake2', pair.publicKey), { hashType: 'blake2' })).toBe(true);
} catch (error) {
console.error(`blake2 failed on #${i}`);
throw error;
@@ -68,7 +68,7 @@ describe('sign and verify', (): void => {
const pair = pairFromSeed(randomAsU8a());
try {
expect(verify(MESSAGE, sign(MESSAGE, pair, 'keccak'), hasher('keccak', pair.publicKey), 'keccak')).toBe(true);
expect(verify(MESSAGE, sign(MESSAGE, pair, { hashType: 'keccak' }), hasher('keccak', pair.publicKey), { hashType: 'keccak' })).toBe(true);
} catch (error) {
console.error(`keccak failed on #${i}`);
throw error;
+6 -1
View File
@@ -9,13 +9,18 @@ import { assert, u8aEq, u8aToU8a } from '@polkadot/util';
import secp256k1Expand from './expand';
import hasher from './hasher';
interface Options {
hashType: HashType;
isExpanded: boolean;
}
const ec = new EC('secp256k1');
/**
* @name secp256k1Verify
* @description Verifies the signature of `message`, using the supplied pair
*/
export default function secp256k1Verify (message: Uint8Array | string, signature: Uint8Array | string, address: Uint8Array | string, hashType: HashType = 'blake2', isExpanded = false): boolean {
export default function secp256k1Verify (message: Uint8Array | string, signature: Uint8Array | string, address: Uint8Array | string, { hashType = 'blake2', isExpanded = false }: Partial<Options> = {}): boolean {
const u8a = u8aToU8a(signature);
assert(u8a.length === 65, `Expected signature with 65 bytes, ${u8a.length} found instead`);
+19 -16
View File
@@ -10,19 +10,21 @@ import naclVerify from '../nacl/verify';
import schnorrkelVerify from '../schnorrkel/verify';
import secp256k1Verify from '../secp256k1/verify';
type Verifier = [KeypairType, (message: Uint8Array | string, signature: Uint8Array | string, publicKey: Uint8Array | string, isExpanded?: boolean) => boolean];
interface VerifyInput {
message: Uint8Array | string;
publicKey: Uint8Array;
signature: Uint8Array;
}
type Verifier = [KeypairType, (message: Uint8Array | string, signature: Uint8Array, publicKey: Uint8Array, isExpanded?: boolean) => boolean];
const secp256k1VerifyHasher = (hashType: 'blake2' | 'keccak') =>
(message: Uint8Array | string, signature: Uint8Array, publicKey: Uint8Array, isExpanded?: boolean) =>
secp256k1Verify(message, signature, publicKey, { hashType, isExpanded });
const VERIFIERS_ECDSA: Verifier[] = [
[
'ecdsa',
(message: Uint8Array | string, signature: Uint8Array | string, publicKey: Uint8Array | string, isExpanded?: boolean) =>
secp256k1Verify(message, signature, publicKey, 'blake2', isExpanded)
],
[
'ethereum',
(message: Uint8Array | string, signature: Uint8Array | string, publicKey: Uint8Array | string, isExpanded?: boolean) =>
secp256k1Verify(message, signature, publicKey, 'keccak', isExpanded)
]
['ecdsa', secp256k1VerifyHasher('blake2')],
['ethereum', secp256k1VerifyHasher('keccak')]
];
const VERIFIERS: Verifier[] = [
@@ -33,7 +35,7 @@ const VERIFIERS: Verifier[] = [
const CRYPTO_TYPES: ('ed25519' | 'sr25519' | 'ecdsa')[] = ['ed25519', 'sr25519', 'ecdsa'];
function verifyDetect (result: VerifyResult, message: Uint8Array | string, signature: Uint8Array, publicKey: Uint8Array, isExpanded?: boolean, verifiers = VERIFIERS): VerifyResult {
function verifyDetect (result: VerifyResult, { message, publicKey, signature }: VerifyInput, isExpanded?: boolean, verifiers = VERIFIERS): VerifyResult {
result.isValid = verifiers.some(([crypto, verify]): boolean => {
try {
if (verify(message, signature, publicKey, isExpanded)) {
@@ -51,7 +53,7 @@ function verifyDetect (result: VerifyResult, message: Uint8Array | string, signa
return result;
}
function verifyMultisig (result: VerifyResult, message: Uint8Array | string, signature: Uint8Array, publicKey: Uint8Array, isExpanded?: boolean): VerifyResult {
function verifyMultisig (result: VerifyResult, { message, publicKey, signature }: VerifyInput, isExpanded?: boolean): VerifyResult {
assert([0, 1, 2].includes(signature[0]), `Unknown crypto type, expected signature prefix [0..2], found ${signature[0]}`);
const type = CRYPTO_TYPES[signature[0]] || 'none';
@@ -60,7 +62,7 @@ function verifyMultisig (result: VerifyResult, message: Uint8Array | string, sig
try {
result.isValid = {
ecdsa: () => verifyDetect(result, message, signature.subarray(1), publicKey, isExpanded, VERIFIERS_ECDSA).isValid,
ecdsa: () => verifyDetect(result, { message, publicKey, signature: signature.subarray(1) }, isExpanded, VERIFIERS_ECDSA).isValid,
ed25519: () => naclVerify(message, signature.subarray(1), publicKey),
none: () => { throw Error('no verify for `none` crypto type'); },
sr25519: () => schnorrkelVerify(message, signature.subarray(1), publicKey)
@@ -79,8 +81,9 @@ export default function signatureVerify (message: Uint8Array | string, signature
const result: VerifyResult = { crypto: 'none', isValid: false };
const publicKey = addressDecode(addressOrPublicKey);
const input = { message, publicKey, signature: signatureU8a };
return [0, 1, 2].includes(signatureU8a[0]) && [65, 66].includes(signatureU8a.length)
? verifyMultisig(result, message, signatureU8a, publicKey, isExpanded)
: verifyDetect(result, message, signatureU8a, publicKey, isExpanded);
? verifyMultisig(result, input, isExpanded)
: verifyDetect(result, input, isExpanded);
}
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@polkadot/util",
"version": "3.7.1",
"version": "4.0.1",
"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.7.1",
"@polkadot/x-textencoder": "^3.7.1",
"@polkadot/x-textdecoder": "4.0.1",
"@polkadot/x-textencoder": "4.0.1",
"@types/bn.js": "^4.11.6",
"bn.js": "^5.1.3",
"camelcase": "^5.3.1",
+2 -4
View File
@@ -3,7 +3,7 @@
import BN from 'bn.js';
import assert from '../assert';
import { checkMaxMin } from './util';
/**
* @name bnMax
@@ -19,7 +19,5 @@ import assert from '../assert';
* ```
*/
export default function max (...items: BN[]): BN {
assert(items && items.length >= 1, 'Must provide one or more BN arguments');
return items.reduce((acc: BN, val: BN) => BN.max(acc, val), items[0]);
return checkMaxMin('max', items);
}
+2 -4
View File
@@ -3,7 +3,7 @@
import BN from 'bn.js';
import assert from '../assert';
import { checkMaxMin } from './util';
/**
* @name bnMin
@@ -19,7 +19,5 @@ import assert from '../assert';
* ```
*/
export default function min (...items: BN[]): BN {
assert(items && items.length >= 1, 'Must provide one or more BN arguments');
return items.reduce((acc: BN, val: BN) => BN.min(acc, val), items[0]);
return checkMaxMin('min', items);
}
+9 -5
View File
@@ -10,6 +10,14 @@ import isToBn from '../is/toBn';
import isHex from '../is/hex';
import hexToBn from '../hex/toBn';
function numberToBn <ExtToBn extends ToBn> (value: number | ExtToBn | BN): BN {
return BN.isBN(value)
? value
: isToBn(value)
? value.toBn()
: new BN(value);
}
/**
* @name bnToBn
* @summary Creates a BN value from a BN, BigInt, string (base 10 or hex) or number input.
@@ -35,9 +43,5 @@ export default function bnToBn <ExtToBn extends ToBn> (value?: ExtToBn | BN | Bi
return new BN(value.toString());
}
return BN.isBN(value)
? value
: isToBn(value)
? value.toBn()
: new BN(value);
return numberToBn(value);
}
+9 -5
View File
@@ -12,7 +12,13 @@ interface Options extends ToBnOptions {
bitLength?: number;
}
function setBn (valueBn: BN, byteLength: number, { isLe, isNegative }: Options): Uint8Array {
function createEmpty (byteLength: number, options: Options): Uint8Array {
return options.bitLength === -1
? new Uint8Array()
: new Uint8Array(byteLength);
}
function createValue (valueBn: BN, byteLength: number, { isLe, isNegative }: Options): Uint8Array {
const output = new Uint8Array(byteLength);
const bn = isNegative ? valueBn.toTwos(byteLength * 8) : valueBn;
@@ -51,10 +57,8 @@ function bnToU8a <ExtToBn extends ToBn> (value?: ExtToBn | BN | BigInt | number
: Math.ceil((options.bitLength || 0) / 8);
return value
? setBn(valueBn, byteLength, options)
: options.bitLength === -1
? new Uint8Array()
: new Uint8Array(byteLength);
? createValue(valueBn, byteLength, options)
: createEmpty(byteLength, options);
}
export default bnToU8a;
+12
View File
@@ -0,0 +1,12 @@
// Copyright 2017-2020 @polkadot/util authors & contributors
// SPDX-License-Identifier: Apache-2.0
import BN from 'bn.js';
import assert from '../assert';
export function checkMaxMin (type: 'max' | 'min', items: BN[]): BN {
assert(items.length >= 1, 'Must provide one or more BN arguments');
return items.reduce((acc: BN, val: BN) => BN[type](acc, val), items[0]);
}
+43 -27
View File
@@ -23,6 +23,48 @@ function addTime (a: Time, b: Time): Time {
const ZERO = { days: 0, hours: 0, milliseconds: 0, minutes: 0, seconds: 0 };
function extractDays (milliseconds: number, hrs: number): Time {
const days = Math.floor(hrs / 24);
return addTime({ ...ZERO, days }, extractTime(milliseconds - (days * DAY * 1000)));
}
function extractHrs (milliseconds: number, mins: number): Time {
const hrs = mins / 60;
if (hrs < 24) {
const hours = Math.floor(hrs);
return addTime({ ...ZERO, hours }, extractTime(milliseconds - (hours * HRS * 1000)));
}
return extractDays(milliseconds, hrs);
}
function extractMins (milliseconds: number, secs: number): Time {
const mins = secs / 60;
if (mins < 60) {
const minutes = Math.floor(mins);
return addTime({ ...ZERO, minutes }, extractTime(milliseconds - (minutes * 60 * 1000)));
}
return extractHrs(milliseconds, mins);
}
function extractSecs (milliseconds: number): Time {
const secs = milliseconds / 1000;
if (secs < 60) {
const seconds = Math.floor(secs);
return addTime({ ...ZERO, seconds }, extractTime(milliseconds - (seconds * 1000)));
}
return extractMins(milliseconds, secs);
}
/**
* @name extractTime
* @summary Convert a quantity of seconds to Time array representing accumulated {days, minutes, hours, seconds, milliseconds}
@@ -42,31 +84,5 @@ export default function extractTime (milliseconds?: number): Time {
return { ...ZERO, milliseconds };
}
const secs = milliseconds / 1000;
if (secs < 60) {
const seconds = Math.floor(secs);
return addTime({ ...ZERO, seconds }, extractTime(milliseconds - (seconds * 1000)));
}
const mins = secs / 60;
if (mins < 60) {
const minutes = Math.floor(mins);
return addTime({ ...ZERO, minutes }, extractTime(milliseconds - (minutes * 60 * 1000)));
}
const hrs = mins / 60;
if (hrs < 24) {
const hours = Math.floor(hrs);
return addTime({ ...ZERO, hours }, extractTime(milliseconds - (hours * HRS * 1000)));
}
const days = Math.floor(hrs / 24);
return addTime({ ...ZERO, days }, extractTime(milliseconds - (days * DAY * 1000)));
return extractSecs(milliseconds);
}
+8 -22
View File
@@ -5,19 +5,7 @@ import { ToBn } from '../types';
import BN from 'bn.js';
import isToBn from '../is/toBn';
function getValue <ExtToBn extends ToBn> (value?: BN | ExtToBn | Date | number | null): number {
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 || 0;
}
import bnToBn from '../bn/toBn';
function formatValue (elapsed: number): string {
if (elapsed < 15) {
@@ -31,15 +19,13 @@ function formatValue (elapsed: number): string {
return `${elapsed / 3600 | 0}h`;
}
export default function formatElapsed <ExtToBn extends ToBn> (now?: Date | null, value?: BN | ExtToBn | Date | number | null): string {
export default function formatElapsed <ExtToBn extends ToBn> (now?: Date | null, value?: BigInt | BN | ExtToBn | Date | number | null): string {
const tsNow = (now && now.getTime()) || 0;
const tsValue = getValue(value);
const tsValue = value instanceof Date
? value.getTime()
: bnToBn(value).toNumber();
if (tsNow && tsValue) {
const elapsed = Math.max(Math.abs(tsNow - tsValue), 0) / 1000;
return formatValue(elapsed);
}
return '0.0s';
return (tsNow && tsValue)
? formatValue(Math.max(Math.abs(tsNow - tsValue), 0) / 1000)
: '0.0s';
}
-2
View File
@@ -1,8 +1,6 @@
// Copyright 2017-2020 @polkadot/util authors & contributors
// SPDX-License-Identifier: Apache-2.0
import './polyfill';
/**
* @summary Utility methods for this package are split into groups
*/
+9 -9
View File
@@ -22,14 +22,16 @@ const logTo = {
warn: 'warn'
};
function formatObject (value: Record<string, unknown>): Record<string, unknown> {
const result: Record<string, unknown> = {};
function formatOther (value: unknown): unknown {
if (value && isObject(value) && value.constructor === Object) {
return Object.keys(value).reduce((result: Record<string, unknown>, key): Record<string, unknown> => {
result[key] = format(value[key]);
return Object.keys(value).reduce((result, key): Record<string, unknown> => {
result[key] = format(value[key]);
return result;
}, {});
}
return result;
}, result);
return value;
}
export function format (value: unknown): unknown {
@@ -39,11 +41,9 @@ export function format (value: unknown): unknown {
return value.toString();
} else if (isU8a(value) || isBuffer(value)) {
return u8aToHex(u8aToU8a(value));
} else if (value && isObject(value) && value.constructor === Object) {
return formatObject(value);
}
return value;
return formatOther(value);
}
function apply (log: LogType, type: string, values: Logger$Data): void {
-39
View File
@@ -1,39 +0,0 @@
// Copyright 2017-2020 @polkadot/util authors & contributors
// SPDX-License-Identifier: Apache-2.0
/* eslint-disable no-extend-native */
/* eslint-disable @typescript-eslint/unbound-method */
describe('Array.fill', (): void => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let arrayFill: (value: any, start?: number | undefined, end?: number | undefined) => any[];
let u8aFill: (value: number, start?: number | undefined, end?: number | undefined) => Uint8Array;
beforeEach((): void => {
arrayFill = Array.prototype.fill;
u8aFill = Uint8Array.prototype.fill;
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
Array.prototype.fill = null;
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
Uint8Array.prototype.fill = null;
require('./fill');
});
afterEach((): void => {
Array.prototype.fill = arrayFill;
Uint8Array.prototype.fill = u8aFill;
});
it('uses the polyfills', (): void => {
expect(
[1, 2, 3, 4, 5, 6, 7, 8].fill(5, 3)
).toEqual([1, 2, 3, 5, 5, 5, 5, 5]);
expect(
new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8]).fill(5, 3)
).toEqual(new Uint8Array([1, 2, 3, 5, 5, 5, 5, 5]));
});
});
-37
View File
@@ -1,37 +0,0 @@
// Copyright 2017-2020 @polkadot/util authors & contributors
// SPDX-License-Identifier: Apache-2.0
/* eslint-disable no-extend-native */
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
Array.prototype.fill = function fill <T> (value: T, start = 0, end?: number): T[] {
assert(this, 'this is null or not defined');
const A = Object(this) as T[];
const relativeEnd = end ?? A.length;
const final = getOffset(relativeEnd, A.length);
let k = getOffset(start, A.length);
while (k < final) {
A[k] = value;
k++;
}
return A;
};
}
if (!Uint8Array.prototype.fill) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
Uint8Array.prototype.fill = Array.prototype.fill;
}
-7
View File
@@ -1,7 +0,0 @@
// Copyright 2017-2020 @polkadot/util authors & contributors
// SPDX-License-Identifier: Apache-2.0
import './fill';
import './padEnd';
import './padStart';
import './setPrototypeOf';
-27
View File
@@ -1,27 +0,0 @@
// Copyright 2017-2020 @polkadot/util authors & contributors
// SPDX-License-Identifier: Apache-2.0
/* eslint-disable @typescript-eslint/unbound-method */
describe('String padEnd', (): void => {
let stringEnd: (length: number, fill?: string) => string;
beforeEach((): void => {
stringEnd = String.prototype.padEnd;
// eslint-disable-next-line no-extend-native,@typescript-eslint/no-explicit-any,@typescript-eslint/no-unsafe-assignment
String.prototype.padEnd = null as any;
require('./padEnd');
});
afterEach((): void => {
// eslint-disable-next-line no-extend-native
String.prototype.padEnd = stringEnd;
});
it('does padding', (): void => {
expect('test'.padEnd(8, 'A')).toEqual('testAAAA');
expect('test'.padEnd(8)).toEqual('test ');
});
});
-17
View File
@@ -1,17 +0,0 @@
// Copyright 2017-2020 @polkadot/util authors & contributors
// SPDX-License-Identifier: Apache-2.0
/* eslint-disable no-extend-native */
/* eslint-disable @typescript-eslint/unbound-method */
if (!String.prototype.padEnd) {
String.prototype.padEnd = function padEnd (length: number, char = ' '): string {
let result = String(this);
while (result.length < length) {
result = result + char;
}
return result;
};
}
@@ -1,27 +0,0 @@
// Copyright 2017-2020 @polkadot/util authors & contributors
// SPDX-License-Identifier: Apache-2.0
/* eslint-disable @typescript-eslint/unbound-method */
describe('String padStart', (): void => {
let stringStart: (length: number, fill?: string) => string;
beforeEach((): void => {
stringStart = String.prototype.padStart;
// eslint-disable-next-line no-extend-native,@typescript-eslint/no-explicit-any,@typescript-eslint/no-unsafe-assignment
String.prototype.padStart = null as any;
require('./padStart');
});
afterEach((): void => {
// eslint-disable-next-line no-extend-native
String.prototype.padStart = stringStart;
});
it('does padding', (): void => {
expect('test'.padStart(8, 'A')).toEqual('AAAAtest');
expect('test'.padStart(8)).toEqual(' test');
});
});
-17
View File
@@ -1,17 +0,0 @@
// Copyright 2017-2020 @polkadot/util authors & contributors
// SPDX-License-Identifier: Apache-2.0
/* eslint-disable no-extend-native */
/* eslint-disable @typescript-eslint/unbound-method */
if (!String.prototype.padStart) {
String.prototype.padStart = function padStart (length: number, char = ' '): string {
let result = String(this);
while (result.length < length) {
result = char + result;
}
return result;
};
}
@@ -1,30 +0,0 @@
// Copyright 2017-2020 @polkadot/util authors & contributors
// SPDX-License-Identifier: Apache-2.0
/* eslint-disable no-proto */
describe('setPrototypeOf', (): void => {
let orig: (o: Record<string, unknown>, proto: Record<string, unknown> | null) => Record<string, unknown>;
beforeEach((): void => {
orig = Object.setPrototypeOf;
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
Object.setPrototypeOf = null;
require('./setPrototypeOf');
});
afterEach((): void => {
Object.setPrototypeOf = orig;
});
it('polyfills with no exceptions', (): void => {
const obj = {};
const proto = { foo: 'bar' };
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
expect(Object.setPrototypeOf(obj, proto).__proto__).toBe(proto);
});
});
@@ -1,12 +0,0 @@
// Copyright 2017-2020 @polkadot/util authors & contributors
// SPDX-License-Identifier: Apache-2.0
// React Native does not have Object.setPrototypeOf
if (!Object.setPrototypeOf) {
Object.setPrototypeOf = function (obj: Record<string, unknown>, proto: Record<string, unknown> | null): Record<string, unknown> {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access,no-proto
obj.__proto__ = proto;
return obj;
};
}
+1 -5
View File
@@ -1,11 +1,7 @@
// Copyright 2017-2020 @polkadot/util authors & contributors
// SPDX-License-Identifier: Apache-2.0
const ALPHABET = new Array(256) as string[];
for (let n = 0; n < 256; ++n) {
ALPHABET[n] = n.toString(16).padStart(2, '0');
}
const ALPHABET = new Array(256).fill(0).map((_, n) => n.toString(16).padStart(2, '0'));
/** @internal */
function extract (value: Uint8Array): string {
+14 -6
View File
@@ -8,6 +8,18 @@ import bufferToU8a from '../buffer/toU8a';
import hexToU8a from '../hex/toU8a';
import stringToU8a from '../string/toU8a';
function convertArray (value: number[] | Uint8Array): Uint8Array {
return Array.isArray(value)
? Uint8Array.from(value)
: value;
}
function convertString (value: string): Uint8Array {
return isHex(value)
? hexToU8a(value)
: stringToU8a(value);
}
/**
* @name u8aToU8a
* @summary Creates a Uint8Array value from a Uint8Array, Buffer, string or hex input.
@@ -29,12 +41,8 @@ export default function u8aToU8a (value?: number[] | Buffer | Uint8Array | strin
} else if (isBuffer(value)) {
return bufferToU8a(value);
} else if (isString(value)) {
return isHex(value)
? hexToU8a(value)
: stringToU8a(value);
return convertString(value);
}
return Array.isArray(value)
? Uint8Array.from(value)
: value;
return convertArray(value);
}
+2 -1
View File
@@ -1,9 +1,10 @@
{
"name": "@polkadot/x-fetch",
"version": "3.7.1",
"version": "4.0.1",
"description": "A cross-environment fetch replacement",
"browser": "browser.js",
"main": "node.js",
"react-native": "react-native.js",
"author": "Jaco Greeff <jacogr@gmail.com>",
"maintainers": [
"Jaco Greeff <jacogr@gmail.com>"
+6
View File
@@ -0,0 +1,6 @@
// Copyright 2017-2020 @polkadot/x-fetch authors & contributors
// SPDX-License-Identifier: Apache-2.0
import browser from './browser';
export default browser;
+3
View File
@@ -0,0 +1,3 @@
# @polkadot/x-randomvalues
A cross-environment `window.crypto.getRandomValues`.
+32
View File
@@ -0,0 +1,32 @@
{
"name": "@polkadot/x-randomvalues",
"version": "4.0.1",
"description": "A cross-environment window.crypto.getRandomValues replacement",
"browser": "browser.js",
"main": "node.js",
"react-native": "react-native.js",
"author": "Jaco Greeff <jacogr@gmail.com>",
"maintainers": [
"Jaco Greeff <jacogr@gmail.com>"
],
"contributors": [],
"license": "Apache-2.0",
"publishConfig": {
"access": "public",
"registry": "https://registry.npmjs.org"
},
"repository": {
"type": "git",
"url": "git+https://github.com/polkadot-js/common.git"
},
"bugs": {
"url": "https://github.com/polkadot-js/common/issues"
},
"homepage": "https://github.com/polkadot-js/common/tree/master/packages/x-randomvalues#readme",
"dependencies": {
"@babel/runtime": "^7.12.1"
},
"devDependencies": {
"@types/react-native": "^0.63.33"
}
}
+6
View File
@@ -0,0 +1,6 @@
// Copyright 2017-2020 @polkadot/x-randomvalues authors & contributors
// SPDX-License-Identifier: Apache-2.0
export default function getRandomValues <T extends Uint8Array> (arr: T): T {
return crypto.getRandomValues(arr);
}
@@ -0,0 +1,20 @@
// Copyright 2017-2020 @polkadot/x-randomvalues authors & contributors
// SPDX-License-Identifier: Apache-2.0
import fallback from './fallback';
describe('fallback (insecure)', (): void => {
it('subsequent results does not match', (): void => {
expect(
fallback(new Uint8Array(32)).toString()
).not.toEqual(
fallback(new Uint8Array(32)).toString()
);
});
it('generates with the supplied length', (): void => {
expect(
fallback(new Uint8Array(128))
).toHaveLength(128);
});
});
+27
View File
@@ -0,0 +1,27 @@
// Copyright 2017-2020 @polkadot/x-randomvalues authors & contributors
// SPDX-License-Identifier: Apache-2.0
// Adapted from https://github.com/LinusU/react-native-get-random-values/blob/85f48393821c23b83b89a8177f56d3a81dc8b733/index.js
// Copyright (c) 2018, 2020 Linus Unnebäck
// SPDX-License-Identifier: MIT
let warned = false;
export default function insecureRandomValues <T extends Uint8Array> (arr: T): T {
if (!warned) {
console.warn('Using an insecure random number generator, this should only happen when running in a debugger without support for crypto.getRandomValues');
warned = true;
}
let r = 0;
for (let i = 0; i < arr.length; i++) {
if ((i & 0b11) === 0) {
r = Math.random() * 0x100000000;
}
arr[i] = (r >>> ((i & 0b11) << 3)) & 0xff;
}
return arr;
}
+12
View File
@@ -0,0 +1,12 @@
// Copyright 2017-2020 @polkadot/x-randomvalues authors & contributors
// SPDX-License-Identifier: Apache-2.0
import crypto from 'crypto';
export default function getRandomValues <T extends Uint8Array> (arr: T): T {
return crypto.randomBytes(arr.length).reduce((arr, value, index) => {
arr[index] = value;
return arr;
}, arr);
}
@@ -0,0 +1,37 @@
// Copyright 2017-2020 @polkadot/x-randomvalues authors & contributors
// SPDX-License-Identifier: Apache-2.0
// Adapted from https://github.com/LinusU/react-native-get-random-values/blob/85f48393821c23b83b89a8177f56d3a81dc8b733/index.js
// Copyright (c) 2018, 2020 Linus Unnebäck
// SPDX-License-Identifier: MIT
import { NativeModules } from 'react-native';
import insecureRandomValues from './fallback';
interface RNExt {
RNGetRandomValues: {
getRandomBase64: (length: number) => string;
}
}
function getRandomValuesNative <T extends Uint8Array> (arr: T): T {
return Buffer
.from((NativeModules as RNExt).RNGetRandomValues.getRandomBase64(arr.length), 'base64')
.reduce((arr, byte, index): T => {
arr[index] = byte;
return arr;
}, arr);
}
function getRandomValuesGlobal <T extends Uint8Array> (arr: T): T {
return crypto.getRandomValues(arr);
}
export default typeof global.crypto === 'object' && typeof global.crypto.getRandomValues === 'function'
? getRandomValuesGlobal
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-explicit-any
: (typeof (global as any).nativeCallSyncHook === 'undefined' || !NativeModules.ExpoRandom)
? insecureRandomValues
: getRandomValuesNative;
+2 -1
View File
@@ -1,9 +1,10 @@
{
"name": "@polkadot/x-textdecoder",
"version": "3.7.1",
"version": "4.0.1",
"description": "A TextDecoder replacement",
"browser": "browser.js",
"main": "node.js",
"react-native": "react-native.js",
"author": "Jaco Greeff <jacogr@gmail.com>",
"maintainers": [
"Jaco Greeff <jacogr@gmail.com>"
+3 -12
View File
@@ -1,17 +1,8 @@
// Copyright 2017-2020 @polkadot/x-textencoder authors & contributors
// SPDX-License-Identifier: Apache-2.0
export default typeof TextDecoder === 'undefined'
? class {
// eslint-disable-next-line @typescript-eslint/no-unused-vars,no-useless-constructor
constructor (_: 'utf-8') {
// nothing
}
import Fallback from './fallback';
decode (value: Uint8Array): string {
return value.reduce((str, code): string => {
return str + String.fromCharCode(code);
}, '');
}
}
export default typeof TextDecoder === 'undefined'
? Fallback as unknown as typeof TextDecoder
: TextDecoder;
+16
View File
@@ -0,0 +1,16 @@
// Copyright 2017-2020 @polkadot/x-textencoder authors & contributors
// SPDX-License-Identifier: Apache-2.0
// This is very limited, only handling Ascii values
export default class TextDecoder {
// eslint-disable-next-line @typescript-eslint/no-unused-vars,no-useless-constructor
constructor (_: 'utf-8') {
// nothing
}
decode (value: Uint8Array): string {
return value.reduce((str, code): string => {
return str + String.fromCharCode(code);
}, '');
}
}
@@ -0,0 +1,6 @@
// Copyright 2017-2020 @polkadot/x-textencoder authors & contributors
// SPDX-License-Identifier: Apache-2.0
import browser from './browser';
export default browser;
+2 -1
View File
@@ -1,9 +1,10 @@
{
"name": "@polkadot/x-textencoder",
"version": "3.7.1",
"version": "4.0.1",
"description": "A TextDecoder replacement",
"browser": "browser.js",
"main": "node.js",
"react-native": "react-native.js",
"author": "Jaco Greeff <jacogr@gmail.com>",
"maintainers": [
"Jaco Greeff <jacogr@gmail.com>"
+3 -11
View File
@@ -1,16 +1,8 @@
// Copyright 2017-2020 @polkadot/x-textencoder authors & contributors
// SPDX-License-Identifier: Apache-2.0
import Fallback from './fallback';
export default typeof TextEncoder === 'undefined'
? class {
encode (value: string): Uint8Array {
const u8a = new Uint8Array(value.length);
for (let i = 0; i < value.length; i++) {
u8a[i] = value.charCodeAt(i);
}
return u8a;
}
}
? Fallback as unknown as typeof TextEncoder
: TextEncoder;
+15
View File
@@ -0,0 +1,15 @@
// Copyright 2017-2020 @polkadot/x-textencoder authors & contributors
// SPDX-License-Identifier: Apache-2.0
// This is very limited, only handling Ascii values
export default class TextEncoder {
encode (value: string): Uint8Array {
const u8a = new Uint8Array(value.length);
for (let i = 0; i < value.length; i++) {
u8a[i] = value.charCodeAt(i);
}
return u8a;
}
}
+16 -14
View File
@@ -3,19 +3,21 @@
import { TextEncoder as NodeTextEncoder } from 'util';
class NodeFallback {
#encoder: NodeTextEncoder;
constructor () {
this.#encoder = new NodeTextEncoder();
}
// For a Jest 26.0.1 environment, Buffer !== Uint8Array
encode (value: string): Uint8Array {
const encoded = this.#encoder.encode(value);
return Uint8Array.from(encoded);
}
}
export default typeof TextEncoder === 'undefined'
? class {
#encoder: NodeTextEncoder;
constructor () {
this.#encoder = new NodeTextEncoder();
}
// For a Jest 26.0.1 environment, Buffer !== Uint8Array
encode (value: string): Uint8Array {
const encoded = this.#encoder.encode(value);
return Uint8Array.from(encoded);
}
} as unknown as typeof TextEncoder
? NodeFallback as unknown as typeof TextEncoder
: TextEncoder;
@@ -0,0 +1,6 @@
// Copyright 2017-2020 @polkadot/x-textencoder authors & contributors
// SPDX-License-Identifier: Apache-2.0
import browser from './browser';
export default browser;
+2 -1
View File
@@ -1,9 +1,10 @@
{
"name": "@polkadot/x-ws",
"version": "3.7.1",
"version": "4.0.1",
"description": "A cross-environment WebSocket replacement",
"browser": "browser.js",
"main": "node.js",
"react-native": "react-native.js",
"author": "Jaco Greeff <jacogr@gmail.com>",
"maintainers": [
"Jaco Greeff <jacogr@gmail.com>"
+6
View File
@@ -0,0 +1,6 @@
// Copyright 2017-2020 @polkadot/x-ws authors & contributors
// SPDX-License-Identifier: Apache-2.0
import browser from './browser';
export default browser;
+588 -509
View File
File diff suppressed because it is too large Load Diff