diff --git a/packages/util-crypto/package.json b/packages/util-crypto/package.json index f847023c0..c541eb124 100644 --- a/packages/util-crypto/package.json +++ b/packages/util-crypto/package.json @@ -28,7 +28,7 @@ "@babel/runtime": "^7.12.1", "@polkadot/networks": "^4.0.0-6", "@polkadot/util": "^4.0.0-6", - "@polkadot/wasm-crypto": "^2.0.0-8", + "@polkadot/wasm-crypto": "^2.0.0-9", "@polkadot/x-randomvalues": "^4.0.0-6", "base-x": "^3.0.8", "blakejs": "^1.1.0", diff --git a/packages/x-randomvalues/package.json b/packages/x-randomvalues/package.json index 62f0c4294..cd9541077 100644 --- a/packages/x-randomvalues/package.json +++ b/packages/x-randomvalues/package.json @@ -25,5 +25,8 @@ "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" } } diff --git a/packages/x-randomvalues/src/fallback.ts b/packages/x-randomvalues/src/fallback.ts new file mode 100644 index 000000000..ffed5c922 --- /dev/null +++ b/packages/x-randomvalues/src/fallback.ts @@ -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 (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 & 0x03) === 0) { + r = Math.random() * 0x100000000; + } + + arr[i] = (r >>> ((i & 0x03) << 3)) & 0xff; + } + + return arr; +} diff --git a/packages/x-randomvalues/src/react-native.ts b/packages/x-randomvalues/src/react-native.ts index d455e56c2..f9321e864 100644 --- a/packages/x-randomvalues/src/react-native.ts +++ b/packages/x-randomvalues/src/react-native.ts @@ -1,6 +1,40 @@ // Copyright 2017-2020 @polkadot/x-randomvalues authors & contributors // SPDX-License-Identifier: Apache-2.0 -import getRandomValues from './node'; +// 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 -export default getRandomValues; +import { NativeModules } from 'react-native'; + +import insecureRandomValues from './fallback'; + +interface RNExt { + RNGetRandomValues: { + getRandomBase64: (length: number) => string; + } +} + +function getRandomValuesNative (arr: T): T { + // We may want to use a base64 decoder here, but we certainly have an issue where we + // want/need this part as lean as possible. Since Buffer is already needed elsewhere + // (an generally prevalent in JS), we rather use it as-is. + return Buffer + .from((NativeModules as RNExt).RNGetRandomValues.getRandomBase64(arr.length), 'base64') + .reduce((arr, byte, index): T => { + arr[index] = byte; + + return arr; + }, arr); +} + +function getRandomValuesGlobal (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; diff --git a/packages/x-textdecoder/src/browser.ts b/packages/x-textdecoder/src/browser.ts index 386f74689..a914b06d2 100644 --- a/packages/x-textdecoder/src/browser.ts +++ b/packages/x-textdecoder/src/browser.ts @@ -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 : TextDecoder; diff --git a/packages/x-textdecoder/src/fallback.ts b/packages/x-textdecoder/src/fallback.ts new file mode 100644 index 000000000..dad31b2c2 --- /dev/null +++ b/packages/x-textdecoder/src/fallback.ts @@ -0,0 +1,15 @@ +// Copyright 2017-2020 @polkadot/x-textencoder authors & contributors +// SPDX-License-Identifier: Apache-2.0 + +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); + }, ''); + } +} diff --git a/yarn.lock b/yarn.lock index 03304fc7c..4afe3aedf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1861,7 +1861,7 @@ __metadata: "@babel/runtime": ^7.12.1 "@polkadot/networks": ^4.0.0-6 "@polkadot/util": ^4.0.0-6 - "@polkadot/wasm-crypto": ^2.0.0-8 + "@polkadot/wasm-crypto": ^2.0.0-9 "@polkadot/x-randomvalues": ^4.0.0-6 "@types/bn.js": ^4.11.6 "@types/create-hash": ^1.2.2 @@ -1896,12 +1896,13 @@ __metadata: languageName: unknown linkType: soft -"@polkadot/wasm-crypto@npm:^2.0.0-8": - version: 2.0.0-8 - resolution: "@polkadot/wasm-crypto@npm:2.0.0-8" +"@polkadot/wasm-crypto@npm:^2.0.0-9": + version: 2.0.0-9 + resolution: "@polkadot/wasm-crypto@npm:2.0.0-9" peerDependencies: "@polkadot/util": "*" - checksum: ae064e32aaeff796cf1b24365e8a03bbe3f1c8612562095105b5b7391ee8ac138b9b8720dca192ccb870eb5e180f06a64ea0a405e177187cc1941e745975ca91 + "@polkadot/x-randomvalues": "*" + checksum: 7bbe141f926f4cd4d0d03b0d187fb6ab8efb668a0bc28f489bd6a60316136d300d02a6c85b8ddc9466c7ee06abd4a347f1255c9d96feb82bd421f7a7e39b7111 languageName: node linkType: hard @@ -1920,6 +1921,7 @@ __metadata: resolution: "@polkadot/x-randomvalues@workspace:packages/x-randomvalues" dependencies: "@babel/runtime": ^7.12.1 + "@types/react-native": ^0.63.33 languageName: unknown linkType: soft @@ -2198,6 +2200,32 @@ __metadata: languageName: node linkType: hard +"@types/prop-types@npm:*": + version: 15.7.3 + resolution: "@types/prop-types@npm:15.7.3" + checksum: bd0eab69d5120ad3784d0c9985f902653d5924707a7f2b3702a330e762dfd61b6494954cb54ad0c52b918ffd6f1e7e27c9270e4442bc15250de348596f2f60cb + languageName: node + linkType: hard + +"@types/react-native@npm:^0.63.33": + version: 0.63.33 + resolution: "@types/react-native@npm:0.63.33" + dependencies: + "@types/react": "*" + checksum: ac6f202902f2d2e2c938b120a3175fd1f61e337c709373ad6c1d7e716ad6e863ee71693744cf73cb0f75b311f86497bcaea06ea15cb896e684138327e14bae65 + languageName: node + linkType: hard + +"@types/react@npm:*": + version: 16.9.56 + resolution: "@types/react@npm:16.9.56" + dependencies: + "@types/prop-types": "*" + csstype: ^3.0.2 + checksum: 139867e2b3d577723b9361234f105d0cf1b143202f51fef207355332f972dd74030cfb3918037cb311eefd203ee06e0a370c37755204eefdd35734f0fde070a1 + languageName: node + linkType: hard + "@types/responselike@npm:^1.0.0": version: 1.0.0 resolution: "@types/responselike@npm:1.0.0" @@ -3674,6 +3702,13 @@ __metadata: languageName: node linkType: hard +"csstype@npm:^3.0.2": + version: 3.0.4 + resolution: "csstype@npm:3.0.4" + checksum: 90cd2ff9aced9049010c5c69470b30643761d511b4250f6ce2bbdbab23229822c325fd841be6066a94a9ba800112026e3c046be879cd44a066e8705991cdc700 + languageName: node + linkType: hard + "cuint@npm:^0.2.2": version: 0.2.2 resolution: "cuint@npm:0.2.2"