Compare commits

..
42 Commits
Author SHA1 Message Date
Github Actions 2ee863becc [CI Skip] release/stable 5.9.1
skip-checks: true
2021-02-28 07:53:49 +00:00
Jaco Greeff b343c31317 5.9 (#906) 2021-02-28 08:47:35 +01:00
Github Actions 04759e563e [CI Skip] release/beta 5.8.2-5
skip-checks: true
2021-02-27 14:04:34 +00:00
Jaco Greeff 6a5478919c Bump deps (#905)
* Bump deps

* Display mismatches when no dupes are detected

* test expectation

* adjust

* One less ||
2021-02-27 14:59:31 +01:00
Github Actions ac828b31e6 [CI Skip] release/beta 5.8.2-4
skip-checks: true
2021-02-27 12:52:10 +00:00
Jaco Greeff 86f17113e3 Dependency version checks (#904)
* Dependency version checks

* Add depndecy detection for all

* Cleanup util detectPackage

* Single detectPackage

* Update packages/hw-ledger/src/detectPackage.ts

* Update packages/util/src/detectPackage.ts

* non-indexed imports
2021-02-27 13:46:07 +01:00
Github Actions cb0429fae9 [CI Skip] release/beta 5.8.2-3
skip-checks: true
2021-02-27 11:16:06 +00:00
Jaco Greeff f23418ad84 Cleanup exports (#903)
* Cleanup exports

* No buffer conversion on base 58

* Buffer conversion
2021-02-27 12:10:13 +01:00
Github Actions 8386a70bfe [CI Skip] release/beta 5.8.2-2
skip-checks: true
2021-02-27 10:36:03 +00:00
Jaco Greeff 843cb3d00a Formatting cleanups for nested conditionals (#902)
* Formatting cleanups for nested conditionals

* Transports
2021-02-27 11:30:18 +01:00
Github Actions 3143e9df1c [CI Skip] release/beta 5.8.2-1
skip-checks: true
2021-02-26 12:41:35 +00:00
Jaco Greeff b76bdb5ed5 Remove class for key extraction (#898) 2021-02-26 13:36:06 +01:00
Github Actions 0e80e88456 [CI Skip] release/beta 5.8.2-0
skip-checks: true
2021-02-26 09:49:28 +00:00
Jaco Greeff 46bfe643a6 Additional tests for hdValidatePath (#897)
* Additional tests for hdValidatePath

* Additional

* slip for Polkadot
2021-02-26 10:43:55 +01:00
Github Actions 2e0b8e4d11 [CI Skip] release/stable 5.8.1
skip-checks: true
2021-02-26 07:13:30 +00:00
Jaco Greeff a8668c3c44 5.8 (#896)
* 5.8

* Update comments
2021-02-26 08:07:45 +01:00
Github Actions 11431f0e68 [CI Skip] release/beta 5.7.2-8
skip-checks: true
2021-02-25 19:38:32 +00:00
Jaco Greeff 6c664498dd Share hdValidatePath (Ledger & Ethereum) (#895)
* Share hsValidatePath (Ledger & Ethereum)

* Adjust

* Cleanup hdEthereum

* Cleanups

* Renames
2021-02-25 20:32:29 +01:00
Antoine Estienne 7721ac722d Fix eth derivation (#894)
* added gerald test address

* added test for toJson

* fix toJson

* lint

* fix ecdsa
2021-02-25 19:18:03 +01:00
Github Actions 0070f33089 [CI Skip] release/beta 5.7.2-7
skip-checks: true
2021-02-25 16:45:20 +00:00
Jaco Greeff a1267eb891 Revert toJSON changes (#893)
* Revert toJSON changes

* Fix tests

* Decoding test

* Add NOTE on encoding (so it stays in-tact)
2021-02-25 17:38:42 +01:00
Jaco Greeff 1803ba6a8e Expand ETH derivation tests (#892) 2021-02-25 17:38:22 +01:00
Github Actions ae4b166c2f [CI Skip] release/beta 5.7.2-6
skip-checks: true
2021-02-25 13:04:22 +00:00
Jaco Greeff 38d6136aa8 Base64 without Buffer (#891) 2021-02-25 13:58:28 +01:00
Github Actions 02fea57a48 [CI Skip] release/beta 5.7.2-5
skip-checks: true
2021-02-25 12:40:07 +00:00
Jaco Greeff 882826a7e3 ETH derive to u8a (#890)
* ETH derive to u8a

* assert

* Extract hash

* link

* hdEthereum

* Adjust tests

* cosmetics

* Remove unused parts
2021-02-25 13:34:01 +01:00
Github Actions 56a7788e28 [CI Skip] release/beta 5.7.2-4
skip-checks: true
2021-02-25 09:39:38 +00:00
Jaco Greeff 82c4b75a12 Cleanup elliptic imports (#889)
* Cleanup elliptic imports

* Additional

* Cleanups

* HydraDX

* Flatten
2021-02-25 10:34:37 +01:00
Github Actions ca3c932701 [CI Skip] release/beta 5.7.2-3
skip-checks: true
2021-02-24 16:34:21 +00:00
Jaco Greeff 76b155c269 Bump deps (#888) 2021-02-24 17:28:53 +01:00
Github Actions faed35e208 [CI Skip] release/beta 5.7.2-2
skip-checks: true
2021-02-24 14:56:42 +00:00
Antoine EstienneandJaco Greeff c46cd5030e Implement first eth hd derivation test (#858)
* implement first eth hd test

* lint

* added gerald test address

* test now passes

* started implementing sith local secp256k1

* Pass publicKey through on verify

* Some test fixes

* renamed tweakadd

* added suggestions

* remove logs and complete test for tweakAdd

* lint

* reviewed

* solve linting problems

* relocate hd package

* Apply suggestions from code review

Co-authored-by: Jaco Greeff <jacogr@gmail.com>

* added asset for tolegacyseed

* yarn.lock and linting

* remove isUint8 util

* fix tests and added tests

* fixed test

Co-authored-by: Jaco Greeff <jacogr@gmail.com>
2021-02-24 15:50:12 +01:00
Github Actions c7e474cdc6 [CI Skip] release/beta 5.7.2-1
skip-checks: true
2021-02-24 08:14:27 +00:00
Jaco Greeff ac7a678a30 Bump deps (#887)
* Bump deps

* Add missing ss58
2021-02-24 09:08:49 +01:00
Github Actions f956759865 [CI Skip] release/beta 5.7.2-0
skip-checks: true
2021-02-24 07:14:06 +00:00
Jaco Greeff 2768b70d43 Run ss58 check multiple times (update existing) (#880)
* Run ss58 check multiple times (update existing)

* Update .github/workflows/ss58-check.yml
2021-02-24 08:08:23 +01:00
Github Actions cc4a579905 [CI Skip] release/stable 5.7.1
skip-checks: true
2021-02-21 08:13:58 +00:00
Jaco Greeff 450b7b8e8b 5.7 (#885)
* 5.7

* Update CHANGELOG.md
2021-02-21 09:08:07 +01:00
Github Actions a248bc9f96 [CI Skip] release/beta 5.6.4-1
skip-checks: true
2021-02-20 10:56:44 +00:00
Jaco Greeff 35f677f2e9 Additional substrate test vectors for ss58 (#884) 2021-02-20 11:50:56 +01:00
Github Actions fccba5d93d [CI Skip] release/beta 5.6.4-0
skip-checks: true
2021-02-19 09:48:00 +00:00
Jaco Greeff ae172e2c53 Pass publicKey through on verify (#883)
* Pass publicKey through on verify

* Some test fixes

* Adjust tests

* Explicit public

* Additional failing tests
2021-02-19 10:43:19 +01:00
100 changed files with 1532 additions and 884 deletions
+2 -1
View File
@@ -1,7 +1,7 @@
name: SS58
on:
schedule:
- cron: '45 3 * * *'
- cron: '15 4/6 * * *'
jobs:
ss58:
@@ -22,3 +22,4 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GH_PAT_BOT }}
with:
filename: .github/ss58-check.md
update_existing: true
+39
View File
@@ -1,5 +1,44 @@
# CHANGELOG
## 5.9.1 Feb 28, 2021
Changes:
- Expand `detectPackage` with optional param allowing checks for monorepo versions
- Export logger `format` function directly as `loggerFormat`
- Expand tests and checks for `hdValidatePath`
- Remove `hdEthereum` class-based approach, simplify
- Cleanup formatting on nested conditionals in the `@polkadot/x-` packages
- All packages now export `packageInfo` from the root
## 5.8.1 Feb 26, 2021
Contributed:
- Add ss58 information for HydraDX (Thanks to https://github.com/jak-pan)
- HD derivation for Ethereum (Thanks to https://github.com/joelamouche)
Changes:
- Adjust base64 encoding/decoding to not rely on Buffer being available
- Rework Ethereum derivation to only use Uint8Array internally
- Shared HD path validation for Ledger & Ethereum
- Additional derivation, encoding and decoding tests on keyring
- Align networks with upstream ss58 registry
- `@polkadot/wasm-crypto` 3.2.4
## 5.7.1 Feb 21, 2021
**Breaking change** The signature of `pair.verify` now requires the signer public key as a parameter. If using `pair.verify` pass the publicKey (hex or Uint8Array) of the signer.
Changes:
- The signature on the keyring for `.verify` now explicitly requires the `publicKey` of the signer. Previously it only verified against an own public key.
- Add additional ss58 test vectors (against chains with >63 prefixes in the Substrate registry)
## 5.6.3 Feb 16, 2021
Contributed:
+3 -3
View File
@@ -20,10 +20,10 @@
"test:one": "polkadot-dev-run-test"
},
"devDependencies": {
"@babel/core": "^7.12.16",
"@polkadot/dev": "^0.61.26",
"@babel/core": "^7.13.8",
"@polkadot/dev": "^0.61.30",
"@polkadot/ts": "^0.3.59",
"@types/jest": "^26.0.20"
},
"version": "5.6.3"
"version": "5.9.1"
}
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@polkadot/hw-ledger-transports",
"version": "5.6.3",
"version": "5.9.1",
"repository": "github:polkadot-js/common",
"author": "Jaco Greeff <jacogr@gmail.com>",
"maintainers": [],
@@ -11,7 +11,7 @@
"react-native": "react-native.js",
"sideEffects": false,
"dependencies": {
"@babel/runtime": "^7.12.13",
"@babel/runtime": "^7.13.8",
"@ledgerhq/hw-transport-webusb": "^5.43.0"
},
"devDependencies": {
+3 -3
View File
@@ -6,7 +6,9 @@ import type { TransportDef } from './types';
import LedgerWebUSB from '@ledgerhq/hw-transport-webusb';
const transports: TransportDef[] = [
export { packageInfo } from './packageInfo';
export const transports: TransportDef[] = [
// deprecated
// import LedgerU2F from '@ledgerhq/hw-transport-u2f';
// {
@@ -20,5 +22,3 @@ const transports: TransportDef[] = [
type: 'webusb'
}
];
export { transports };
+3 -3
View File
@@ -6,12 +6,12 @@ import type { TransportDef } from './types';
import LedgerHid from '@ledgerhq/hw-transport-node-hid-singleton';
const transports: TransportDef[] = [
export { packageInfo } from './packageInfo';
export const transports: TransportDef[] = [
{
create: (): Promise<Transport> =>
LedgerHid.create(),
type: 'hid'
}
];
export { transports };
@@ -3,4 +3,4 @@
// Auto-generated by @polkadot/dev, do not edit
export const packageInfo = { name: '@polkadot/hw-ledger-transports', version: '5.6.3' };
export const packageInfo = { name: '@polkadot/hw-ledger-transports', version: '5.9.1' };
@@ -3,6 +3,6 @@
import type { TransportDef } from './types';
const transports: TransportDef[] = [];
export { packageInfo } from './packageInfo';
export { transports };
export const transports: TransportDef[] = [];
+8 -5
View File
@@ -1,17 +1,20 @@
{
"name": "@polkadot/hw-ledger",
"version": "5.6.3",
"version": "5.9.1",
"repository": "github:polkadot-js/common",
"author": "Jaco Greeff <jacogr@gmail.com>",
"maintainers": [],
"contributors": [],
"license": "Apache-2.0",
"main": "index.js",
"sideEffects": false,
"sideEffects": [
"./detectPackage.js",
"./detectPackage.mjs"
],
"dependencies": {
"@babel/runtime": "^7.12.13",
"@polkadot/hw-ledger-transports": "5.6.3",
"@polkadot/util": "^5.6.3",
"@babel/runtime": "^7.13.8",
"@polkadot/hw-ledger-transports": "5.9.1",
"@polkadot/util": "^5.9.1",
"@zondax/ledger-polkadot": "^0.13.1"
}
}
+9
View File
@@ -0,0 +1,9 @@
// Copyright 2017-2021 @polkadot/hw-ledger authors & contributors
// SPDX-License-Identifier: Apache-2.0
import { packageInfo as transportInfo } from '@polkadot/hw-ledger-transports/packageInfo';
import { detectPackage, packageInfo as utilInfo } from '@polkadot/util';
import { packageInfo } from './packageInfo';
detectPackage(packageInfo, typeof __dirname !== 'undefined' && __dirname, [transportInfo, utilInfo]);
+6 -2
View File
@@ -1,13 +1,17 @@
// Copyright 2017-2021 @polkadot/hw-ledger authors & contributors
// SPDX-License-Identifier: Apache-2.0
import './detectPackage';
import type Transport from '@ledgerhq/hw-transport';
import type { AccountOptions, LedgerAddress, LedgerSignature, LedgerTypes, LedgerVersion } from './types';
import { newDockApp, newKusamaApp, newPolkadotApp, newPolymeshApp, ResponseBase, SubstrateApp } from '@zondax/ledger-polkadot';
import { transports } from '@polkadot/hw-ledger-transports';
import { assert, bufferToU8a, u8aToBuffer, u8aToHex } from '@polkadot/util';
import { assert, u8aToBuffer } from '@polkadot/util';
export { packageInfo } from './packageInfo';
export const LEDGER_DEFAULT_ACCOUNT = 0x80000000;
@@ -77,7 +81,7 @@ export class Ledger {
const { signature } = await this.#wrapError(app.sign(account + accountOffset, change, addressIndex + addressOffset, buffer));
return {
signature: u8aToHex(bufferToU8a(signature))
signature: `0x${signature.toString('hex')}`
};
});
}
+1 -1
View File
@@ -3,4 +3,4 @@
// Auto-generated by @polkadot/dev, do not edit
export const packageInfo = { name: '@polkadot/hw-ledger', version: '5.6.3' };
export const packageInfo = { name: '@polkadot/hw-ledger', version: '5.9.1' };
+6 -6
View File
@@ -1,6 +1,6 @@
{
"name": "@polkadot/keyring",
"version": "5.6.3",
"version": "5.9.1",
"description": "Keyring management",
"author": "Jaco Greeff <jacogr@gmail.com>",
"maintainers": [],
@@ -15,12 +15,12 @@
"bugs": "https://github.com/polkadot-js/common/issues",
"homepage": "https://github.com/polkadot-js/common/tree/master/packages/keyring#readme",
"dependencies": {
"@babel/runtime": "^7.12.13",
"@polkadot/util": "5.6.3",
"@polkadot/util-crypto": "5.6.3"
"@babel/runtime": "^7.13.8",
"@polkadot/util": "5.9.1",
"@polkadot/util-crypto": "5.9.1"
},
"peerDependencies": {
"@polkadot/util": "5.6.3",
"@polkadot/util-crypto": "5.6.3"
"@polkadot/util": "5.9.1",
"@polkadot/util-crypto": "5.9.1"
}
}
+2 -7
View File
@@ -2,12 +2,7 @@
// SPDX-License-Identifier: Apache-2.0
// default substrate dev phrase
const DEV_PHRASE = 'bottom drive obey lake curtain smoke basket hold race lonely fit walk';
export const DEV_PHRASE = 'bottom drive obey lake curtain smoke basket hold race lonely fit walk';
// seed from the above phrase
const DEV_SEED = '0xfac7959dbfe72f052e5a0c3c8d6530f202b02fd8f9f5ca3580ec8deb7797479e';
export {
DEV_PHRASE,
DEV_SEED
};
export const DEV_SEED = '0xfac7959dbfe72f052e5a0c3c8d6530f202b02fd8f9f5ca3580ec8deb7797479e';
+3 -19
View File
@@ -1,25 +1,9 @@
// Copyright 2017-2021 @polkadot/keyring authors & contributors
// SPDX-License-Identifier: Apache-2.0
// For esm, this should be import.meta.url or to get the same behavior as __dirname, we can use
//
// new URL(import.meta.url).pathname)
//
// The issue is the WP4 has "some" issues with import.meta.url. So because of bundlers, we can't have
// nice things... In this case it is even worse since import.meta.url won't even make it compile, so
// there is a complete dead end with usage thereof
//
// When that is fixed, a solution is to have both .js & .mjs files, with the following content -
//
// cjs: util.detectPackage(packageInfo, () => __dirname);
// esm: detectPackage(packageInfo, () => import.meta.url);
//
// With the above we additionally need a .d.ts to just export the packageInfo
import { detectPackage } from '@polkadot/util';
import { detectPackage, packageInfo as utilInfo } from '@polkadot/util';
import { packageInfo as cryptoInfo } from '@polkadot/util-crypto/packageInfo';
import { packageInfo } from './packageInfo';
detectPackage(packageInfo, typeof __dirname !== 'undefined' && __dirname);
export { packageInfo };
detectPackage(packageInfo, typeof __dirname !== 'undefined' && __dirname, [utilInfo, cryptoInfo]);
+88 -23
View File
@@ -2,7 +2,7 @@
// SPDX-License-Identifier: Apache-2.0
import { hexToU8a, stringToU8a } from '@polkadot/util';
import { cryptoWaitReady, encodeAddress, setSS58Format } from '@polkadot/util-crypto';
import { cryptoWaitReady, encodeAddress, randomAsU8a, setSS58Format } from '@polkadot/util-crypto';
import Keyring from '.';
@@ -83,8 +83,9 @@ describe('keypair', (): void => {
const pair = keyring.getPair(publicKeyOne);
const signature = pair.sign(MESSAGE);
expect(pair.verify(MESSAGE, signature)).toBe(true);
expect(pair.verify(new Uint8Array(), signature)).toBe(false);
expect(pair.verify(MESSAGE, signature, pair.publicKey)).toBe(true);
expect(pair.verify(MESSAGE, signature, randomAsU8a())).toBe(false);
expect(pair.verify(new Uint8Array(), signature, pair.publicKey)).toBe(false);
});
it('signs and verifies (withType)', (): void => {
@@ -92,8 +93,9 @@ describe('keypair', (): void => {
const pair = keyring.getPair(publicKeyOne);
const signature = pair.sign(MESSAGE, { withType: true });
expect(pair.verify(MESSAGE, signature)).toBe(true);
expect(pair.verify(new Uint8Array(), signature)).toBe(false);
expect(pair.verify(MESSAGE, signature, pair.publicKey)).toBe(true);
expect(pair.verify(MESSAGE, signature, randomAsU8a())).toBe(false);
expect(pair.verify(new Uint8Array(), signature, pair.publicKey)).toBe(false);
});
});
@@ -159,8 +161,9 @@ describe('keypair', (): void => {
const pair = keyring.getPair(publicKeyOne);
const signature = pair.sign(MESSAGE);
expect(pair.verify(MESSAGE, signature)).toBe(true);
expect(pair.verify(new Uint8Array(), signature)).toBe(false);
expect(pair.verify(MESSAGE, signature, pair.publicKey)).toBe(true);
expect(pair.verify(MESSAGE, signature, randomAsU8a())).toBe(false);
expect(pair.verify(new Uint8Array(), signature, pair.publicKey)).toBe(false);
});
it('signs and verifies (withType)', (): void => {
@@ -168,8 +171,9 @@ describe('keypair', (): void => {
const pair = keyring.getPair(publicKeyOne);
const signature = pair.sign(MESSAGE, { withType: true });
expect(pair.verify(MESSAGE, signature)).toBe(true);
expect(pair.verify(new Uint8Array(), signature)).toBe(false);
expect(pair.verify(MESSAGE, signature, pair.publicKey)).toBe(true);
expect(pair.verify(MESSAGE, signature, randomAsU8a())).toBe(false);
expect(pair.verify(new Uint8Array(), signature, pair.publicKey)).toBe(false);
});
});
@@ -259,13 +263,33 @@ describe('keypair', (): void => {
).not.toThrow();
});
it('encodes a pair toJSON (and decodes)', (): void => {
const pair = keyring.createFromUri('moral movie very draw assault whisper awful rebuild speed purity repeat card');
const json = pair.toJson('password');
expect(json.address).toEqual('0x03ddca309bd5fedd01f914d6fb76f23aa848a2a520802159215dba5085d7863619');
expect(json.encoding).toEqual({
content: ['pkcs8', 'ecdsa'],
type: ['scrypt', 'xsalsa20-poly1305'],
version: '3'
});
const newPair = keyring.createFromJson(json);
expect(newPair.publicKey).toEqual(pair.publicKey);
expect(
() => newPair.unlock('password')
).not.toThrow();
});
it('signs and verifies', (): void => {
const MESSAGE = stringToU8a('this is a message');
const pair = keyring.getPair(addressKeyOne);
const signature = pair.sign(MESSAGE);
expect(pair.verify(MESSAGE, signature)).toBe(true);
expect(pair.verify(new Uint8Array(), signature)).toBe(false);
expect(pair.verify(MESSAGE, signature, pair.publicKey)).toBe(true);
expect(pair.verify(MESSAGE, signature, randomAsU8a())).toBe(false);
expect(pair.verify(new Uint8Array(), signature, pair.publicKey)).toBe(false);
});
it('signs and verifies (withType)', (): void => {
@@ -273,36 +297,69 @@ describe('keypair', (): void => {
const pair = keyring.getPair(addressKeyOne);
const signature = pair.sign(MESSAGE, { withType: true });
expect(pair.verify(MESSAGE, signature)).toBe(true);
expect(pair.verify(new Uint8Array(), signature)).toBe(false);
expect(pair.verify(MESSAGE, signature, pair.publicKey)).toBe(true);
expect(pair.verify(MESSAGE, signature, randomAsU8a())).toBe(false);
expect(pair.verify(new Uint8Array(), signature, pair.publicKey)).toBe(false);
});
});
describe('ethereum', (): void => {
const PHRASE = 'seed sock milk update focus rotate barely fade car face mechanic mercy';
// combine mnemonic with derivation path
const PHRASE = 'seed sock milk update focus rotate barely fade car face mechanic mercy' + '/m/44\'/60\'/0\'/0/0';
const ETH_ADDRESS_ONE = '0x31ea8795EE32D782C8ff41a5C68Dcbf0F5B27f6d';
let keyring: Keyring;
beforeEach((): void => {
keyring = new Keyring({ type: 'ethereum' });
});
it('adds a pair with the correct address', (): void => {
it('creates with dev phrase with derivation path specified', (): void => {
const pair = keyring.createFromUri(PHRASE);
expect(pair.publicKey).toEqual(hexToU8a('0x03b9dc646dd71118e5f7fda681ad9eca36eb3ee96f344f582fbe7b5bcdebb13077'));
expect(pair.address).toEqual('0x4119b2e6c3Cb618F4f0B93ac77f9BeeC7FF02887');
expect(
pair.address
).toEqual(ETH_ADDRESS_ONE);
});
it('encodes a pair toJSON', (): void => {
it('creates with dev phrase with derivation path specified - addFromUri', (): void => {
expect(
keyring.addFromUri(PHRASE).address
).toEqual(ETH_ADDRESS_ONE);
});
it('encodes a pair toJSON (and decodes)', (): void => {
const pair = keyring.createFromUri(PHRASE);
const json = pair.toJson('password');
expect(json.address).toEqual('0x03b9dc646dd71118e5f7fda681ad9eca36eb3ee96f344f582fbe7b5bcdebb13077');
expect(json.address).toEqual('0x0381351b1b46d2602b0992bb5d5531f9c1696b0812feb2534b6884adc47e2e1d8b'); // this is the public key (different from address for ethereum)
expect(json.encoding).toEqual({
content: ['pkcs8', 'ethereum'],
type: ['scrypt', 'xsalsa20-poly1305'],
version: '3'
});
const newPair = keyring.createFromJson(json);
expect(newPair.publicKey).toEqual(pair.publicKey);
expect(
() => newPair.unlock('password')
).not.toThrow();
});
it('encodes a pair toJSON and back', (): void => {
const pairOriginal = keyring.createFromUri(PHRASE);
const json = pairOriginal.toJson('password');
const pair = keyring.addFromJson(
json
);
expect(pair.address).toEqual(ETH_ADDRESS_ONE);
pair.decodePkcs8('password');
expect(pair.isLocked).toBe(false);
expect(pair.address).toBe(ETH_ADDRESS_ONE);
});
it('allows adding from JSON', (): void => {
@@ -328,9 +385,13 @@ describe('keypair', (): void => {
);
const signature = signer.sign(MESSAGE);
const dummyPublic = verifier.publicKey.slice();
expect(verifier.verify(MESSAGE, signature)).toBe(true);
expect(verifier.verify(new Uint8Array(), signature)).toBe(false);
dummyPublic[dummyPublic.length - 1] = 0;
expect(verifier.verify(MESSAGE, signature, signer.publicKey)).toBe(true);
expect(verifier.verify(MESSAGE, signature, dummyPublic)).toBe(false);
expect(verifier.verify(new Uint8Array(), signature, signer.publicKey)).toBe(false);
});
it('allows for signing/verification (withType)', (): void => {
@@ -341,9 +402,13 @@ describe('keypair', (): void => {
);
const signature = signer.sign(MESSAGE, { withType: true });
const dummyPublic = verifier.publicKey.slice();
expect(verifier.verify(MESSAGE, signature)).toBe(true);
expect(verifier.verify(new Uint8Array(), signature)).toBe(false);
dummyPublic[dummyPublic.length - 1] = 0;
expect(verifier.verify(MESSAGE, signature, signer.publicKey)).toBe(true);
expect(verifier.verify(MESSAGE, signature, dummyPublic)).toBe(false);
expect(verifier.verify(new Uint8Array(), signature, signer.publicKey)).toBe(false);
});
});
+2
View File
@@ -7,6 +7,8 @@ import { Keyring } from './keyring';
export { decodeAddress, encodeAddress, setSS58Format } from '@polkadot/util-crypto';
export { packageInfo } from './packageInfo';
export default Keyring;
export { Keyring };
+11 -7
View File
@@ -5,7 +5,7 @@ import type { Keypair, KeypairType } from '@polkadot/util-crypto/types';
import type { KeyringInstance, KeyringOptions, KeyringPair, KeyringPair$Json, KeyringPair$JsonEncodingTypes, KeyringPair$Meta } from './types';
import { assert, hexToU8a, isHex, isUndefined, stringToU8a } from '@polkadot/util';
import { base64Decode, decodeAddress, encodeAddress, keyExtractSuri, keyFromPath, mnemonicToLegacySeed, mnemonicToMiniSecret, naclKeypairFromSeed as naclFromSeed, schnorrkelKeypairFromSeed as schnorrkelFromSeed, secp256k1KeypairFromSeed as secp256k1FromSeed } from '@polkadot/util-crypto';
import { base64Decode, decodeAddress, encodeAddress, ethereumEncode, hdEthereum, keyExtractSuri, keyFromPath, mnemonicToLegacySeed, mnemonicToMiniSecret, naclKeypairFromSeed as naclFromSeed, schnorrkelKeypairFromSeed as schnorrkelFromSeed, secp256k1KeypairFromSeed as secp256k1FromSeed } from '@polkadot/util-crypto';
import { DEV_PHRASE } from './defaults';
import { createPair } from './pair';
@@ -46,7 +46,7 @@ export class Keyring implements KeyringInstance {
constructor (options: KeyringOptions = {}) {
options.type = options.type || 'ed25519';
assert(options && ['ecdsa', 'ethereum', 'ed25519', 'sr25519'].includes(options.type || 'undefined'), `Expected a keyring type of either 'ed25519', 'sr25519' or 'ecdsa', found '${options.type}`);
assert(options && ['ecdsa', 'ethereum', 'ed25519', 'sr25519'].includes(options.type || 'undefined'), `Expected a keyring type of either 'ed25519', 'sr25519', 'ethereum' or 'ecdsa', found '${options.type}`);
this.#pairs = new Pairs();
this.#ss58 = options.ss58Format;
@@ -152,6 +152,7 @@ export class Keyring implements KeyringInstance {
const encType = !Array.isArray(type)
? [type]
: type;
// Here the address and publicKey are 32 bytes and isomorphic. This is why the address field needs to be the public key for ethereum type pairs
const publicKey = isHex(address)
? hexToU8a(address)
: this.decodeAddress(address, ignoreChecksum);
@@ -172,7 +173,7 @@ export class Keyring implements KeyringInstance {
const suri = _suri.startsWith('//')
? `${DEV_PHRASE}${_suri}`
: _suri;
const { password, path, phrase } = keyExtractSuri(suri);
const { derivePath, password, path, phrase } = keyExtractSuri(suri);
let seed: Uint8Array;
if (isHex(phrase, 256)) {
@@ -183,7 +184,7 @@ export class Keyring implements KeyringInstance {
if ([12, 15, 18, 21, 24].includes(parts.length)) {
seed = type === 'ethereum'
? mnemonicToLegacySeed(phrase)
? mnemonicToLegacySeed(phrase, '', false, 64)
: mnemonicToMiniSecret(phrase, password);
} else {
assert(str.length <= 32, 'specified phrase is not a valid mnemonic and is invalid as a raw seed at > 32 bytes');
@@ -192,8 +193,9 @@ export class Keyring implements KeyringInstance {
}
}
// FIXME Need to support Ethereum-type derivation paths
const derived = keyFromPath(keypairFromSeed[type](seed), path, type);
const derived = type === 'ethereum'
? hdEthereum(seed, derivePath.substring(1))
: keyFromPath(keypairFromSeed[type](seed), path, type);
return createPair({ toSS58: this.encodeAddress, type }, derived, meta, null);
}
@@ -203,7 +205,9 @@ export class Keyring implements KeyringInstance {
* @description Encodes the input into an ss58 representation
*/
public encodeAddress = (address: Uint8Array | string, ss58Format?: number): string => {
return encodeAddress(address, isUndefined(ss58Format) ? this.#ss58 : ss58Format);
return this.type === 'ethereum'
? ethereumEncode(address)
: encodeAddress(address, isUndefined(ss58Format) ? this.#ss58 : ss58Format);
}
/**
+1 -1
View File
@@ -3,4 +3,4 @@
// Auto-generated by @polkadot/dev, do not edit
export const packageInfo = { name: '@polkadot/keyring', version: '5.6.3' };
export const packageInfo = { name: '@polkadot/keyring', version: '5.9.1' };
+9 -21
View File
@@ -3,24 +3,12 @@
import type { KeyringPair$JsonEncodingTypes } from '../types';
const ENCODING: KeyringPair$JsonEncodingTypes[] = ['scrypt', 'xsalsa20-poly1305'];
const NONCE_LENGTH = 24;
const PKCS8_DIVIDER = new Uint8Array([161, 35, 3, 33, 0]);
const PKCS8_HEADER = new Uint8Array([48, 83, 2, 1, 1, 48, 5, 6, 3, 43, 101, 112, 4, 34, 4, 32]);
const PUB_LENGTH = 32;
const SALT_LENGTH = 32;
const SEC_LENGTH = 64;
const SEED_LENGTH = 32;
const SCRYPT_LENGTH = SALT_LENGTH + (3 * 4);
export {
ENCODING,
NONCE_LENGTH,
PKCS8_DIVIDER,
PKCS8_HEADER,
PUB_LENGTH,
SALT_LENGTH,
SEC_LENGTH,
SEED_LENGTH,
SCRYPT_LENGTH
};
export const ENCODING: KeyringPair$JsonEncodingTypes[] = ['scrypt', 'xsalsa20-poly1305'];
export const NONCE_LENGTH = 24;
export const PKCS8_DIVIDER = new Uint8Array([161, 35, 3, 33, 0]);
export const PKCS8_HEADER = new Uint8Array([48, 83, 2, 1, 1, 48, 5, 6, 3, 43, 101, 112, 4, 34, 4, 32]);
export const PUB_LENGTH = 32;
export const SALT_LENGTH = 32;
export const SEC_LENGTH = 64;
export const SEED_LENGTH = 32;
export const SCRYPT_LENGTH = SALT_LENGTH + (3 * 4);
+64 -7
View File
@@ -1,10 +1,10 @@
// Copyright 2017-2021 @polkadot/keyring authors & contributors
// SPDX-License-Identifier: Apache-2.0
import { hexToU8a } from '@polkadot/util';
import { hexToU8a, u8aToHex } from '@polkadot/util';
import { cryptoWaitReady, encodeAddress as toSS58, setSS58Format } from '@polkadot/util-crypto';
import { PAIRS } from '../testing';
import { PAIRSSR25519 } from '../testing';
import { createTestPairs } from '../testingPairs';
import { createPair } from '.';
@@ -42,16 +42,28 @@ describe('pair', (): void => {
expect(
keyring.alice.verify(
new Uint8Array([0x61, 0x62, 0x63, 0x64]),
SIGNATURE
SIGNATURE,
keyring.alice.publicKey
)
).toEqual(true);
});
it('fails a correctly signed message (signer changed)', (): void => {
expect(
keyring.alice.verify(
new Uint8Array([0x61, 0x62, 0x63, 0x64, 0x65]),
SIGNATURE,
keyring.bob.publicKey
)
).toEqual(false);
});
it('fails a correctly signed message (message changed)', (): void => {
expect(
keyring.alice.verify(
new Uint8Array([0x61, 0x62, 0x63, 0x64, 0x65]),
SIGNATURE
SIGNATURE,
keyring.alice.publicKey
)
).toEqual(false);
});
@@ -62,11 +74,24 @@ describe('pair', (): void => {
expect(
keyring.alice.vrfVerify(
message,
keyring.alice.vrfSign(message)
keyring.alice.vrfSign(message),
keyring.alice.publicKey
)
).toBe(true);
});
it('fails vrf sign and verify (publicKey changed)', (): void => {
const message = new Uint8Array([0x61, 0x62, 0x63, 0x64, 0x65]);
expect(
keyring.alice.vrfVerify(
message,
keyring.alice.vrfSign(message),
keyring.bob.publicKey
)
).toBe(false);
});
it('allows setting/getting of meta', (): void => {
keyring.bob.setMeta({ foo: 'bar', something: 'else' });
@@ -99,11 +124,11 @@ describe('pair', (): void => {
});
it('allows derivation on the pair', (): void => {
const alice = createPair({ toSS58, type: 'sr25519' }, { publicKey: PAIRS[0].publicKey, secretKey: PAIRS[0].secretKey }, {});
const alice = createPair({ toSS58, type: 'sr25519' }, { publicKey: PAIRSSR25519[0].publicKey, secretKey: PAIRSSR25519[0].secretKey }, {});
const stash = alice.derive('//stash');
const soft = alice.derive('//funding/0');
expect(stash.publicKey).toEqual(PAIRS[1].publicKey);
expect(stash.publicKey).toEqual(PAIRSSR25519[1].publicKey);
expect(soft.address).toEqual('5ECQNn7UueWHPFda5qUi4fTmTtyCnPvGnuoyVVSj5CboJh9J');
});
@@ -117,11 +142,43 @@ describe('pair', (): void => {
});
describe('ethereum', (): void => {
const PUBLICDERIVED = new Uint8Array([
3, 129, 53, 27, 27, 70, 210, 96,
43, 9, 146, 187, 93, 85, 49, 249,
193, 105, 107, 8, 18, 254, 178, 83,
75, 104, 132, 173, 196, 126, 46, 29,
139
]);
const SECRETDERIVED = new Uint8Array([
7, 13, 195, 17, 115, 0, 1, 25,
24, 226, 107, 2, 23, 105, 69, 204,
21, 195, 213, 72, 207, 73, 253, 132,
24, 217, 127, 147, 175, 105, 158, 70
]);
it('has a valid address from a known public', (): void => {
const pair = createPair({ toSS58, type: 'ethereum' }, { publicKey: hexToU8a('0x03b9dc646dd71118e5f7fda681ad9eca36eb3ee96f344f582fbe7b5bcdebb13077') });
expect(pair.address).toEqual('0x4119b2e6c3Cb618F4f0B93ac77f9BeeC7FF02887');
expect(pair.addressRaw).toEqual(hexToU8a('0x4119b2e6c3Cb618F4f0B93ac77f9BeeC7FF02887'));
});
it('converts to json', (): void => {
const pair = createPair({ toSS58, type: 'ethereum' }, { publicKey: PUBLICDERIVED, secretKey: SECRETDERIVED });
const json = pair.toJson('password');
expect(json.encoding).toEqual({
content: ['pkcs8', 'ethereum'],
type: ['scrypt', 'xsalsa20-poly1305'],
version: '3'
});
expect(json.address).toEqual(u8aToHex(PUBLICDERIVED));
});
it('has Gerald as test address for Ethereum type parachains', (): void => {
const keyringEthereum = createTestPairs({ type: 'ethereum' }, false);
expect(keyringEthereum.Gerald.address).toEqual('0x6Be02d1d3665660d22FF9624b7BE0551ee1Ac91b');
});
});
});
+15 -9
View File
@@ -145,6 +145,7 @@ export function createPair ({ toSS58, type }: Setup, { publicKey, secretKey }: P
// eslint-disable-next-line sort-keys
decodePkcs8,
derive: (suri: string, meta?: KeyringPair$Meta): KeyringPair => {
assert(type !== 'ethereum', 'Unable to derive on this keypair');
assert(!isLocked(secretKey), 'Cannot derive on a locked keypair');
const { path } = keyExtractPath(suri);
@@ -172,6 +173,8 @@ export function createPair ({ toSS58, type }: Setup, { publicKey, secretKey }: P
);
},
toJson: (passphrase?: string): KeyringPair$Json => {
// NOTE: For ecdsa and ethereum, the publicKey cannot be extracted from the address. For these
// pass the hex-encoded publicKey through to the address portion of the JSON (before decoding)
const address = ['ecdsa', 'ethereum'].includes(type)
? u8aToHex(secp256k1Compress(publicKey))
: encodeAddress();
@@ -181,8 +184,8 @@ export function createPair ({ toSS58, type }: Setup, { publicKey, secretKey }: P
unlock: (passphrase?: string): void => {
return decodePkcs8(passphrase);
},
verify: (message: string | Uint8Array, signature: Uint8Array): boolean => {
return signatureVerify(message, signature, TYPE_ADDRESS[type](publicKey)).isValid;
verify: (message: string | Uint8Array, signature: Uint8Array, _signerPublic: string | Uint8Array): boolean => {
return signatureVerify(message, signature, TYPE_ADDRESS[type](u8aToU8a(_signerPublic))).isValid;
},
vrfSign: (message: string | Uint8Array, context?: string | Uint8Array, extra?: string | Uint8Array): Uint8Array => {
assert(!isLocked(secretKey), 'Cannot sign with a locked key pair');
@@ -195,13 +198,16 @@ export function createPair ({ toSS58, type }: Setup, { publicKey, secretKey }: P
return u8aConcat(vrfHash(proof, context, extra), proof);
},
vrfVerify: (message: string | Uint8Array, vrfResult: Uint8Array, context?: string | Uint8Array, extra?: string | Uint8Array): boolean => {
return type === 'sr25519'
? schnorrkelVrfVerify(message, vrfResult, publicKey, context, extra)
: (
signatureVerify(message, u8aConcat(TYPE_PREFIX[type], vrfResult.subarray(32)), TYPE_ADDRESS[type](publicKey)).isValid &&
u8aEq(vrfResult.subarray(0, 32), vrfHash(vrfResult.subarray(32), context, extra))
);
vrfVerify: (message: string | Uint8Array, vrfResult: Uint8Array, _signerPublic: Uint8Array | string, context?: string | Uint8Array, extra?: string | Uint8Array): boolean => {
const signerPublic = TYPE_ADDRESS[type](u8aToU8a(_signerPublic));
if (type === 'sr25519') {
return schnorrkelVrfVerify(message, vrfResult, publicKey, context, extra);
}
const result = signatureVerify(message, u8aConcat(TYPE_PREFIX[type], vrfResult.subarray(32)), signerPublic);
return result.isValid && u8aEq(vrfResult.subarray(0, 32), vrfHash(vrfResult.subarray(32), context, extra));
}
};
}
+6 -6
View File
@@ -29,8 +29,8 @@ describe('vrf', (): void => {
const sig2 = ecdsa.vrfSign(MESSAGE, CONTEXT);
expect(u8aToHex(sig1)).toEqual(u8aToHex(sig2));
expect(ecdsa.vrfVerify(MESSAGE, sig1, CONTEXT)).toEqual(true);
expect(ecdsa.vrfVerify(MESSAGE, sig2, CONTEXT)).toEqual(true);
expect(ecdsa.vrfVerify(MESSAGE, sig1, ecdsa.publicKey, CONTEXT)).toEqual(true);
expect(ecdsa.vrfVerify(MESSAGE, sig2, ecdsa.publicKey, CONTEXT)).toEqual(true);
});
it('has deterministic signature values for ed25519', (): void => {
@@ -38,8 +38,8 @@ describe('vrf', (): void => {
const sig2 = ed25519.vrfSign(MESSAGE, CONTEXT);
expect(u8aToHex(sig1)).toEqual(u8aToHex(sig2));
expect(ed25519.vrfVerify(MESSAGE, sig1, CONTEXT)).toEqual(true);
expect(ed25519.vrfVerify(MESSAGE, sig2, CONTEXT)).toEqual(true);
expect(ed25519.vrfVerify(MESSAGE, sig1, ed25519.publicKey, CONTEXT)).toEqual(true);
expect(ed25519.vrfVerify(MESSAGE, sig2, ed25519.publicKey, CONTEXT)).toEqual(true);
});
it('has deterministic signature values for sr25519', (): void => {
@@ -47,7 +47,7 @@ describe('vrf', (): void => {
const sig2 = sr25519.vrfSign(MESSAGE, CONTEXT);
expect(u8aToHex(sig1.slice(0, 32))).toEqual(u8aToHex(sig2.slice(0, 32)));
expect(sr25519.vrfVerify(MESSAGE, sig1, CONTEXT)).toEqual(true);
expect(sr25519.vrfVerify(MESSAGE, sig2, CONTEXT)).toEqual(true);
expect(sr25519.vrfVerify(MESSAGE, sig1, sr25519.publicKey, CONTEXT)).toEqual(true);
expect(sr25519.vrfVerify(MESSAGE, sig2, sr25519.publicKey, CONTEXT)).toEqual(true);
});
});
+7
View File
@@ -18,6 +18,13 @@ const TESTS = {
uri: `${PHRASE}//Alice`
}
],
ethereum: [
{
pk: '0x0381351b1b46d2602b0992bb5d5531f9c1696b0812feb2534b6884adc47e2e1d8b',
ss: '0x31ea8795EE32D782C8ff41a5C68Dcbf0F5B27f6d',
uri: "seed sock milk update focus rotate barely fade car face mechanic mercy/m/44'/60'/0'/0/0"
}
],
sr25519: [
{
pk: '0x46ebddef8cd9bb167dc30878d7113b7e168e6f0646beffd77d69d39bad76b47a',
+35 -11
View File
@@ -4,6 +4,7 @@
import type { KeyringInstance, KeyringOptions } from './types';
import { hexToU8a } from '@polkadot/util';
import { KeypairType } from '@polkadot/util-crypto/types';
import { createPair } from './pair';
import Keyring from '.';
@@ -13,53 +14,75 @@ interface PairDef {
publicKey: Uint8Array;
seed: string;
secretKey?: Uint8Array;
type?: 'ed25519' | 'sr25519';
type: KeypairType
}
// NOTE This is not great since we have the secretKey here explicitly, but a testing
// keyring is for testing - what happens is that in most cases the keyring is initialises
// before anything else. Since the sr25519 crypto is async, this creates problems with
// adding the keys when only the keyring is used.
export const PAIRS: PairDef[] = [
export const PAIRSSR25519: PairDef[] = [
{
publicKey: hexToU8a('0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d'),
secretKey: hexToU8a('0x98319d4ff8a9508c4bb0cf0b5a78d760a0b2082c02775e6e82370816fedfff48925a225d97aa00682d6a59b95b18780c10d7032336e88f3442b42361f4a66011'),
seed: 'Alice'
seed: 'Alice',
type: 'sr25519'
},
{
publicKey: hexToU8a('0xbe5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f'),
secretKey: hexToU8a('0xe8da6c9d810e020f5e3c7f5af2dea314cbeaa0d72bc6421e92c0808a0c584a6046ab28e97c3ffc77fe12b5a4d37e8cd4afbfebbf2391ffc7cb07c0f38c023efd'),
seed: 'Alice//stash'
seed: 'Alice//stash',
type: 'sr25519'
},
{
publicKey: hexToU8a('0x8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48'),
secretKey: hexToU8a('0x081ff694633e255136bdb456c20a5fc8fed21f8b964c11bb17ff534ce80ebd5941ae88f85d0c1bfc37be41c904e1dfc01de8c8067b0d6d5df25dd1ac0894a325'),
seed: 'Bob'
seed: 'Bob',
type: 'sr25519'
},
{
publicKey: hexToU8a('0xfe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e'),
secretKey: hexToU8a('0xc006507cdfc267a21532394c49ca9b754ca71de21e15a1cdf807c7ceab6d0b6c3ed408d9d35311540dcd54931933e67cf1ea10d46f75408f82b789d9bd212fde'),
seed: 'Bob//stash'
seed: 'Bob//stash',
type: 'sr25519'
},
{
publicKey: hexToU8a('0x90b5ab205c6974c9ea841be688864633dc9ca8a357843eeacf2314649965fe22'),
secretKey: hexToU8a('0xa8f2d83016052e5d6d77b2f6fd5d59418922a09024cda701b3c34369ec43a7668faf12ff39cd4e5d92bb773972f41a7a5279ebc2ed92264bed8f47d344f8f18c'),
seed: 'Charlie'
seed: 'Charlie',
type: 'sr25519'
},
{
publicKey: hexToU8a('0x306721211d5404bd9da88e0204360a1a9ab8b87c66c1bc2fcdd37f3c2222cc20'),
secretKey: hexToU8a('0x20e05482ca4677e0edbc58ae9a3a59f6ed3b1a9484ba17e64d6fe8688b2b7b5d108c4487b9323b98b11fe36cb301b084e920f7b7895536809a6d62a451b25568'),
seed: 'Dave'
seed: 'Dave',
type: 'sr25519'
},
{
publicKey: hexToU8a('0xe659a7a1628cdd93febc04a4e0646ea20e9f5f0ce097d9a05290d4a9e054df4e'),
secretKey: hexToU8a('0x683576abfd5dc35273e4264c23095a1bf21c14517bece57c7f0cc5c0ed4ce06a3dbf386b7828f348abe15d76973a72009e6ef86a5c91db2990cb36bb657c6587'),
seed: 'Eve'
seed: 'Eve',
type: 'sr25519'
},
{
publicKey: hexToU8a('0x1cbd2d43530a44705ad088af313e18f80b53ef16b36177cd4b77b846f2a5f07c'),
secretKey: hexToU8a('0xb835c20f450079cf4f513900ae9faf8df06ad86c681884122c752a4b2bf74d4303e4f21bc6cc62bb4eeed5a9cce642c25e2d2ac1464093b50f6196d78e3a7426'),
seed: 'Ferdie'
seed: 'Ferdie',
type: 'sr25519'
}
];
export const PAIRSETHEREUM: PairDef[] = [
{
name: 'Gerald',
publicKey: new Uint8Array([3, 98, 79, 114, 14, 174, 103, 106,
4, 17, 22, 49, 201, 202, 51, 140,
17, 208, 245, 168, 14, 228, 34, 16,
198, 190, 114, 152, 60, 235, 98, 15,
191]),
secretKey: hexToU8a('0x99b3c12287537e38c90a9219d4cb074a89a16e9cdb20bf85728ebd97c343e342'),
seed: 'Gerald',
type: 'ethereum'
}
];
@@ -71,8 +94,9 @@ export const PAIRS: PairDef[] = [
*/
export function createTestKeyring (options: KeyringOptions = {}, isDerived = true): KeyringInstance {
const keyring = new Keyring(options);
const pairs: PairDef[] = (options.type && options.type === 'ethereum') ? PAIRSETHEREUM : PAIRSSR25519;
PAIRS.forEach(({ name, publicKey, secretKey, seed, type = 'sr25519' }): void => {
pairs.forEach(({ name, publicKey, secretKey, seed, type }): void => {
const meta = {
isTesting: true,
name: name || seed.replace('//', '_').toLowerCase()
+2 -2
View File
@@ -48,9 +48,9 @@ export interface KeyringPair {
sign (message: string | Uint8Array, options?: SignOptions): Uint8Array;
toJson (passphrase?: string): KeyringPair$Json;
unlock (passphrase?: string): void;
verify (message: string | Uint8Array, signature: Uint8Array): boolean;
verify (message: string | Uint8Array, signature: Uint8Array, signerPublic: string | Uint8Array): boolean;
vrfSign (message: string | Uint8Array, context?: string | Uint8Array, extra?: string | Uint8Array): Uint8Array;
vrfVerify (message: string | Uint8Array, vrfResult: Uint8Array, context?: string | Uint8Array, extra?: string | Uint8Array): boolean;
vrfVerify (message: string | Uint8Array, vrfResult: Uint8Array, signerPublic: Uint8Array | string, context?: string | Uint8Array, extra?: string | Uint8Array): boolean;
}
export interface KeyringPairs {
+8 -5
View File
@@ -1,9 +1,12 @@
{
"name": "@polkadot/networks",
"version": "5.6.3",
"version": "5.9.1",
"description": "A list of all available Substrate networks and their applicable prefixes",
"main": "index.js",
"sideEffects": false,
"sideEffects": [
"./detectPackage.js",
"./detectPackage.mjs"
],
"repository": "github:polkadot-js/common",
"author": "Jaco Greeff <jacogr@gmail.com>",
"maintainers": [],
@@ -12,10 +15,10 @@
"bugs": "https://github.com/polkadot-js/common/issues",
"homepage": "https://github.com/polkadot-js/common/tree/master/packages/networks#readme",
"dependencies": {
"@babel/runtime": "^7.12.13"
"@babel/runtime": "^7.13.8"
},
"devDependencies": {
"@polkadot/util": "5.6.3",
"@polkadot/x-fetch": "5.6.3"
"@polkadot/util": "5.9.1",
"@polkadot/x-fetch": "5.9.1"
}
}
+9
View File
@@ -0,0 +1,9 @@
// Copyright 2017-2021 @polkadot/keyring authors & contributors
// SPDX-License-Identifier: Apache-2.0
import { detectPackage, packageInfo as utilInfo } from '@polkadot/util';
import { packageInfo as fetchInfo } from '@polkadot/x-fetch';
import { packageInfo } from './packageInfo';
detectPackage(packageInfo, typeof __dirname !== 'undefined' && __dirname, [utilInfo, fetchInfo]);
+25 -7
View File
@@ -6,8 +6,12 @@
//
// Once the above is published as a package, the duplication here can be removed
import './detectPackage';
import type { Network, NetworkFromSubstrate, NetworkFromSubstrateNamed } from './types';
export { packageInfo } from './packageInfo';
// These are known prefixes that are not sorted
const UNSORTED = [0, 2, 42];
@@ -27,7 +31,7 @@ const createReserved = (prefix: number, displayName: string, network: string | n
website: null
});
const all: NetworkFromSubstrate[] = [
export const all: NetworkFromSubstrate[] = [
{
decimals: [10],
displayName: 'Polkadot Relay Chain',
@@ -447,6 +451,24 @@ const all: NetworkFromSubstrate[] = [
},
createReserved(46, 'This prefix is reserved.', 'reserved46'),
createReserved(47, 'This prefix is reserved.', 'reserved47'),
{
decimals: [12],
displayName: 'Neatcoin Mainnet',
network: 'neatcoin',
prefix: 48,
standardAccount: '*25519',
symbols: ['NEAT'],
website: 'https://neatcoin.org'
},
{
decimals: [12],
displayName: 'HydraDX',
network: 'hydradx',
prefix: 63,
standardAccount: '*25519',
symbols: ['HDX'],
website: 'https://hydradx.io'
},
{
decimals: [18],
displayName: 'AvN Mainnet',
@@ -472,7 +494,7 @@ const all: NetworkFromSubstrate[] = [
// - we only include those where we have a standardAccount
// - when no icon has been specified, default to substrate
// - sort by name, however we keep 0, 2, 42 first in the list
const available: Network[] = all
export const available: Network[] = all
.filter((n): n is NetworkFromSubstrateNamed => !n.isIgnored && !!n.network)
.map((n) => ({ ...n, genesisHash: n.genesisHash || [], icon: n.icon || 'substrate' }))
.sort((a, b) =>
@@ -486,8 +508,4 @@ const available: Network[] = all
);
// A filtered list of those chains we have details about (genesisHashes)
const filtered: Network[] = available.filter((n) => n.genesisHash.length || n.prefix === 42);
export { all, available };
export default filtered;
export default available.filter((n) => n.genesisHash.length || n.prefix === 42);
+1 -1
View File
@@ -3,4 +3,4 @@
// Auto-generated by @polkadot/dev, do not edit
export const packageInfo = { name: '@polkadot/networks', version: '5.6.3' };
export const packageInfo = { name: '@polkadot/networks', version: '5.9.1' };
+8 -7
View File
@@ -1,6 +1,6 @@
{
"name": "@polkadot/util-crypto",
"version": "5.6.3",
"version": "5.9.1",
"description": "A collection of useful crypto utilities for @polkadot",
"main": "index.js",
"sideEffects": [
@@ -15,12 +15,13 @@
"bugs": "https://github.com/polkadot-js/common/issues",
"homepage": "https://github.com/polkadot-js/common/tree/master/packages/util-crypto#readme",
"dependencies": {
"@babel/runtime": "^7.12.13",
"@polkadot/networks": "5.6.3",
"@polkadot/util": "5.6.3",
"@polkadot/wasm-crypto": "^3.2.3",
"@polkadot/x-randomvalues": "5.6.3",
"@babel/runtime": "^7.13.8",
"@polkadot/networks": "5.9.1",
"@polkadot/util": "5.9.1",
"@polkadot/wasm-crypto": "^3.2.4",
"@polkadot/x-randomvalues": "5.9.1",
"base-x": "^3.0.8",
"base64-js": "^1.5.1",
"blakejs": "^1.1.0",
"bn.js": "^4.11.9",
"create-hash": "^1.2.0",
@@ -39,6 +40,6 @@
"@types/xxhashjs": "^0.2.2"
},
"peerDependencies": {
"@polkadot/util": "5.6.3"
"@polkadot/util": "5.9.1"
}
}
@@ -11,7 +11,13 @@ describe('checkAddressChecksum', (): void => {
).toEqual([true, 33, 1, 2]);
});
it('correctly extracts the info from a 2-byte-prefix address', (): void => {
it('correctly extracts the info from a 2-byte-prefix address (66)', (): void => {
expect(
checkAddressChecksum(base58Decode('cTGShekJ1L1UKFZR9xmv9UTJod7vqjFAPo4sDhXih2c3y1yLS'))
).toEqual([true, 34, 2, 66]);
});
it('correctly extracts the info from a 2-byte-prefix address (255)', (): void => {
expect(
checkAddressChecksum(base58Decode('yGHU8YKprxHbHdEv7oUK4rzMZXtsdhcXVG2CAMyC9WhzhjH2k'))
).toEqual([true, 34, 2, 255]);
@@ -81,7 +81,15 @@ describe('decodeAddress', (): void => {
);
});
it('decodes a 2-byte prefix', (): void => {
it('decodes a 2-byte prefix (65)', (): void => {
expect(
decodeAddress('cLtA6nCDyvwKcEHH4QkZDSHMhS9s78BvUJUsKUbUAn1Jc2SCF')
).toEqual(
hexToU8a('0x08e8969768fc14399930d4b8d693f68a2ff6c6a597325d6946095e5e9d9d1b0e')
);
});
it('decodes a 2-byte prefix (255)', (): void => {
expect(
decodeAddress('yGHU8YKprxHbHdEv7oUK4rzMZXtsdhcXVG2CAMyC9WhzhjH2k')
).toEqual(
@@ -9,10 +9,23 @@ const keyring = createTestPairs({ type: 'ed25519' }, false);
const SUBKEY = [
{
// substrate default
address: '5DA4D4GL5iakrn22h5uKoevgvo18Pqj5BcdEUv8etEDPdijA',
publicKey: '0x3050f8456519829fe03302da802d22d3233a5f4037b9a3e2bcc403ccfcb2d735',
ss58Format: 42
},
{
// aventus
address: 'cLtA6nCDyvwKcEHH4QkZDSHMhS9s78BvUJUsKUbUAn1Jc2SCF',
publicKey: '0x08e8969768fc14399930d4b8d693f68a2ff6c6a597325d6946095e5e9d9d1b0e',
ss58Format: 65
},
{
// crust
address: 'cTGShekJ1L1UKFZR9xmv9UTJod7vqjFAPo4sDhXih2c3y1yLS',
publicKey: '0x04a047d52fe542484c69bc528990cfeaf3a663dded0638ee1b51cf78bacd1072',
ss58Format: 66
},
{
// ecdsa
address: '4pbsSkWcBaYoFHrKJZp5fDVUKbqSYD9dhZZGvpp3vQ5ysVs5ybV',
@@ -121,7 +134,7 @@ describe('encode', (): void => {
});
SUBKEY.forEach(({ address, publicKey, ss58Format }, index): void => {
it(`encodes with Subkey equality (${index})`, (): void => {
it(`encodes with Subkey equality (${index} - ${ss58Format})`, (): void => {
expect(
encodeAddress(publicKey, ss58Format)
).toEqual(address);
+2 -7
View File
@@ -2,10 +2,5 @@
// SPDX-License-Identifier: Apache-2.0
// https://github.com/multiformats/js-multibase/blob/master/src/constants.js
const BASE32_ALPHABET = 'abcdefghijklmnopqrstuvwxyz234567';
const BITS_PER_CHAR = 5;
export {
BASE32_ALPHABET,
BITS_PER_CHAR
};
export const BASE32_ALPHABET = 'abcdefghijklmnopqrstuvwxyz234567';
export const BITS_PER_CHAR = 5;
+2 -7
View File
@@ -4,11 +4,6 @@
import baseX from 'base-x';
// https://github.com/cryptocoinjs/base-x#alphabets
const BASE58_ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';
export const BASE58_ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';
const bs58 = baseX(BASE58_ALPHABET);
export {
BASE58_ALPHABET,
bs58
};
export const bs58 = baseX(BASE58_ALPHABET);
+2 -4
View File
@@ -1,7 +1,7 @@
// Copyright 2017-2021 @polkadot/util-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0
import { u8aToBuffer, u8aToU8a } from '@polkadot/util';
import { u8aToU8a } from '@polkadot/util';
import { bs58 } from './bs58';
@@ -12,9 +12,7 @@ import { bs58 } from './bs58';
* From the provided input, create the base58 and return the result as a string.
*/
export function base58Encode (value: Uint8Array | string | Buffer | number[], ipfsCompat?: boolean): string {
const out = bs58.encode(
u8aToBuffer(u8aToU8a(value))
);
const out = bs58.encode(u8aToU8a(value));
return ipfsCompat
? `z${out}`
+2 -2
View File
@@ -1,7 +1,7 @@
// Copyright 2017-2021 @polkadot/util-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0
import { bufferToU8a } from '@polkadot/util';
import base64 from 'base64-js';
import { base64Validate } from './validate';
@@ -14,5 +14,5 @@ import { base64Validate } from './validate';
export function base64Decode (value: string): Uint8Array {
base64Validate(value);
return bufferToU8a(Buffer.from(value, 'base64'));
return base64.toByteArray(value);
}
+4 -2
View File
@@ -1,7 +1,9 @@
// Copyright 2017-2021 @polkadot/util-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0
import { u8aToBuffer, u8aToU8a } from '@polkadot/util';
import base64 from 'base64-js';
import { u8aToU8a } from '@polkadot/util';
/**
* @name base64Encode
@@ -10,5 +12,5 @@ import { u8aToBuffer, u8aToU8a } from '@polkadot/util';
* From the provided input, create the base64 and return the result as a string.
*/
export function base64Encode (value: Uint8Array | string | Buffer | number[]): string {
return u8aToBuffer(u8aToU8a(value)).toString('base64');
return base64.fromByteArray(u8aToU8a(value));
}
+4 -19
View File
@@ -1,25 +1,10 @@
// Copyright 2017-2021 @polkadot/util-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0
// For esm, this should be import.meta.url or to get the same behavior as __dirname, we can use
//
// new URL(import.meta.url).pathname)
//
// The issue is the WP4 has "some" issues with import.meta.url. So because of bundlers, we can't have
// nice things... In this case it is even worse since import.meta.url won't even make it compile, so
// there is a complete dead end with usage thereof
//
// When that is fixed, a solution is to have both .js & .mjs files, with the following content -
//
// cjs: util.detectPackage(packageInfo, () => __dirname);
// esm: detectPackage(packageInfo, () => import.meta.url);
//
// With the above we additionally need a .d.ts to just export the packageInfo
import { detectPackage } from '@polkadot/util';
import { packageInfo as netInfo } from '@polkadot/networks/packageInfo';
import { detectPackage, packageInfo as utilInfo } from '@polkadot/util';
import { packageInfo as randomInfo } from '@polkadot/x-randomvalues';
import { packageInfo } from './packageInfo';
detectPackage(packageInfo, typeof __dirname !== 'undefined' && __dirname);
export { packageInfo };
detectPackage(packageInfo, typeof __dirname !== 'undefined' && __dirname, [netInfo, utilInfo, randomInfo]);
@@ -0,0 +1,52 @@
// Copyright 2017-2021 @polkadot/util-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0
import { mnemonicToLegacySeed } from '@polkadot/util-crypto';
import { hdEthereum } from '.';
describe('hdEthereum', (): void => {
const PHRASE = 'seed sock milk update focus rotate barely fade car face mechanic mercy';
const derivationPath = 'm/44\'/60\'/0\'/0/0';
const PUBLIC = new Uint8Array([
3, 118, 64, 77, 247, 27, 4, 157,
236, 206, 251, 221, 230, 244, 154, 147,
189, 131, 249, 169, 102, 78, 3, 185,
153, 19, 89, 40, 24, 25, 139, 131,
93
]);
const SECRET = new Uint8Array([
166, 162, 203, 17, 2, 206, 110, 176,
18, 102, 230, 144, 90, 158, 25, 232,
43, 180, 176, 49, 189, 149, 3, 71,
243, 228, 223, 104, 125, 132, 58, 228
]
);
const PUBLICDERIVED = new Uint8Array([
3, 129, 53, 27, 27, 70, 210, 96,
43, 9, 146, 187, 93, 85, 49, 249,
193, 105, 107, 8, 18, 254, 178, 83,
75, 104, 132, 173, 196, 126, 46, 29,
139
]);
const SECRETDERIVED = new Uint8Array([
7, 13, 195, 17, 115, 0, 1, 25,
24, 226, 107, 2, 23, 105, 69, 204,
21, 195, 213, 72, 207, 73, 253, 132,
24, 217, 127, 147, 175, 105, 158, 70
]);
it('derives the right key pair from a mnemonic', (): void => {
const key = hdEthereum(mnemonicToLegacySeed(PHRASE, '', false, 64));
expect(key.publicKey).toEqual(PUBLIC);
expect(key.secretKey).toEqual(SECRET);
});
it('derives the right key pair from a mnemonic and a derivation path', (): void => {
const key = hdEthereum(mnemonicToLegacySeed(PHRASE, '', false, 64), derivationPath);
expect(key.publicKey).toEqual(PUBLICDERIVED);
expect(key.secretKey).toEqual(SECRETDERIVED);
});
});
@@ -0,0 +1,67 @@
// Copyright 2017-2021 @polkadot/util-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type { Keypair } from '../../types';
import { assert, bnToU8a, stringToU8a, u8aConcat } from '@polkadot/util';
import { hmacSha512 } from '../../hmac';
import { secp256k1KeypairFromSeed, secp256k1PrivateKeyTweakAdd } from '../../secp256k1';
import { HARDENED, hdValidatePath } from '../validatePath';
interface CodedKeypair extends Keypair {
chainCode: Uint8Array;
}
const MASTER_SECRET = stringToU8a('Bitcoin seed');
function createCoded (secretKey: Uint8Array, chainCode: Uint8Array): CodedKeypair {
return {
chainCode,
publicKey: secp256k1KeypairFromSeed(secretKey).publicKey,
secretKey
};
}
function deriveChild (hd: CodedKeypair, index: number): CodedKeypair {
const indexBuffer = bnToU8a(index, { bitLength: 32, isLe: false });
const data = index >= HARDENED
? u8aConcat(new Uint8Array(1), hd.secretKey, indexBuffer)
: u8aConcat(hd.publicKey, indexBuffer);
try {
const I = hmacSha512(hd.chainCode, data);
return createCoded(
secp256k1PrivateKeyTweakAdd(hd.secretKey, I.slice(0, 32)),
I.slice(32)
);
} catch (err) {
// In case parse256(IL) >= n or ki == 0, proceed with the next value for i
return deriveChild(hd, index + 1);
}
}
export function hdEthereum (seed: Uint8Array, path = ''): Keypair {
const I = hmacSha512(MASTER_SECRET, seed);
const hd = createCoded(I.slice(0, 32), I.slice(32));
if (!path || path === 'm' || path === 'M' || path === "m'" || path === "M'") {
return hd;
}
assert(hdValidatePath(path), 'Invalid derivation path');
return path
.split('/')
.slice(1)
.reduce((hd: CodedKeypair, c): CodedKeypair =>
deriveChild(
hd, parseInt(c, 10) + (
(c.length > 1) && c.endsWith("'")
? HARDENED
: 0
)
), hd
);
}
+2
View File
@@ -1,4 +1,6 @@
// Copyright 2017-2021 @polkadot/util-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0
export { hdEthereum } from './ethereum';
export { hdLedger } from './ledger';
export { hdValidatePath } from './validatePath';
@@ -30,7 +30,7 @@ const TESTS = {
]
},
Polkadot: {
slip44: 0x80000162,
slip44: 0x0162,
tests: [
{
ed25519: '0xe8c68348586d53e4e8d1a864b0e4e17c75e4eb06e0c63c1432bef2ba29e69d41',
+2 -4
View File
@@ -7,15 +7,13 @@ import { assert } from '@polkadot/util';
import { mnemonicValidate } from '../../mnemonic';
import { naclKeypairFromSeed } from '../../nacl';
import { HARDENED, hdValidatePath } from '../validatePath';
import { ledgerDerivePrivate } from './derivePrivate';
import { ledgerMaster } from './master';
import { ledgerValidatePath } from './validatePath';
const HARDENED = 0x80000000;
export function hdLedger (mnemonic: string, path: string): Keypair {
assert(mnemonicValidate(mnemonic), 'Invalid mnemonic passed to ledger derivation');
assert(ledgerValidatePath(path), 'Invalid derivation path');
assert(hdValidatePath(path), 'Invalid derivation path');
return naclKeypairFromSeed(
path
@@ -1,14 +0,0 @@
// Copyright 2017-2021 @polkadot/util-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0
export function ledgerValidatePath (path: string): boolean {
if (!path.startsWith('m/')) {
return false;
}
return !path
.split('/')
.slice(1)
.map((n) => parseInt(n.replace("'", ''), 10))
.some((n) => isNaN(n));
}
@@ -0,0 +1,28 @@
// Copyright 2017-2021 @polkadot/util-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0
import { hdValidatePath } from '.';
const VECTORS: [string, boolean][] = [
["m/44'/60'/0'/0/0", true],
['m/0', true],
["m/123'", true],
["n/44'/60'/0'/0/0", false],
['m', false],
['m/', false],
["m/xyz'", false],
['m/123x', false],
['m/123"', false],
["m/123''", false],
["m/123'0'", false],
[`m/${0x80000000}`, false],
['m/-1', false]
];
describe('hdValidatePath', (): void => {
VECTORS.forEach(([path, result]): void => {
it(`validates ${path} as ${result.toString()}`, (): void => {
expect(hdValidatePath(path)).toEqual(result);
});
});
});
@@ -0,0 +1,18 @@
// Copyright 2017-2021 @polkadot/util-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0
export const HARDENED = 0x80000000;
export function hdValidatePath (path: string): boolean {
if (!path.startsWith('m/')) {
return false;
}
const parts = path.split('/').slice(1);
return parts.every((n) => /^\d+'?$/.test(n)) && (
!parts
.map((n) => parseInt(n.replace("'", ''), 10))
.some((n) => isNaN(n) || (n >= HARDENED) || (n < 0))
);
}
+2
View File
@@ -4,6 +4,8 @@
import './cryptoInit';
import './detectPackage';
export { packageInfo } from './packageInfo';
// all internal exports
export * from './address';
export * from './base32';
@@ -7,6 +7,7 @@ import { DeriveJunction } from './DeriveJunction';
import { keyExtractPath } from './extractPath';
export interface ExtractResult {
derivePath: string,
password?: string;
path: DeriveJunction[];
phrase: string;
@@ -27,6 +28,7 @@ export function keyExtractSuri (suri: string): ExtractResult {
const { path } = keyExtractPath(derivePath);
return {
derivePath,
password,
path,
phrase
@@ -7,7 +7,8 @@ import { waitReady } from '@polkadot/wasm-crypto';
import { mnemonicToLegacySeed } from './';
const MNEMONIC = 'seed sock milk update focus rotate barely fade car face mechanic mercy';
const SEED = '0x3c121e20de068083b49c2315697fb59a2d9e8643c24e5ea7628132c58969a027';
const SEED_32 = '0x3c121e20de068083b49c2315697fb59a2d9e8643c24e5ea7628132c58969a027';
const SEED_64 = '0x3c121e20de068083b49c2315697fb59a2d9e8643c24e5ea7628132c58969a0275693dd5bd9d4cc9e648475eba9613ed4678f4d62560a9c42f75bac04022ded25';
describe('mnemonicToLegacySeed', (): void => {
beforeEach(async (): Promise<void> => {
@@ -26,10 +27,18 @@ describe('mnemonicToLegacySeed', (): void => {
});
[false, true].forEach((onlyJs): void => {
it(`generates a valid seed (onlyJs = ${onlyJs.toString()})`, (): void => {
it(`generates a valid 64bytes seed (onlyJs = ${onlyJs.toString()})`, (): void => {
expect(
u8aToHex(mnemonicToLegacySeed(MNEMONIC, undefined, onlyJs, 64))
).toEqual(SEED_64);
});
});
[false, true].forEach((onlyJs): void => {
it(`generates a valid 32bytes seed (onlyJs = ${onlyJs.toString()})`, (): void => {
expect(
u8aToHex(mnemonicToLegacySeed(MNEMONIC, undefined, onlyJs))
).toEqual(SEED);
).toEqual(SEED_32);
});
});
@@ -24,10 +24,17 @@ import { mnemonicValidate } from './validate';
* }
* ```
*/
export function mnemonicToLegacySeed (mnemonic: string, password = '', onlyJs = false): Uint8Array {
export function mnemonicToLegacySeed (mnemonic: string, password = '', onlyJs = false, byteLength: 32 | 64 = 32): Uint8Array {
assert(mnemonicValidate(mnemonic), 'Invalid bip39 mnemonic specified');
assert([32, 64].includes(byteLength), `Invalid seed length ${byteLength}, expected 32 or 64`);
return isReady() && !onlyJs
? bip39ToSeed(mnemonic, password)
: mnemonicToSeedSync(mnemonic, password).subarray(0, 32);
if (byteLength && byteLength === 32) {
return isReady() && !onlyJs
? bip39ToSeed(mnemonic, password)
: mnemonicToSeedSync(mnemonic, password).subarray(0, 32);
} else if (byteLength === 64) {
return mnemonicToSeedSync(mnemonic, password);
} else {
return new Uint8Array();
}
}
+1 -1
View File
@@ -3,4 +3,4 @@
// Auto-generated by @polkadot/dev, do not edit
export const packageInfo = { name: '@polkadot/util-crypto', version: '5.6.3' };
export const packageInfo = { name: '@polkadot/util-crypto', version: '5.9.1' };
+1 -3
View File
@@ -1,10 +1,8 @@
// Copyright 2017-2021 @polkadot/util-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0
const DEFAULT_PARAMS = {
export const DEFAULT_PARAMS = {
N: 1 << 15,
p: 1,
r: 8
};
export { DEFAULT_PARAMS };
@@ -6,4 +6,5 @@ export { secp256k1Expand } from './expand';
export { secp256k1KeypairFromSeed } from './keypair/fromSeed';
export { secp256k1Recover } from './recover';
export { secp256k1Sign } from './sign';
export { secp256k1PrivateKeyTweakAdd } from './tweakAdd';
export { secp256k1Verify } from './verify';
@@ -0,0 +1,31 @@
// Copyright 2017-2021 @polkadot/util-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0
import { secp256k1PrivateKeyTweakAdd } from './tweakAdd';
describe('TweakAdd', (): void => {
describe('PrivateKey TweakAdd', (): void => {
it('succeeds for a simple case', (): void => {
const A = new Uint8Array([0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1]);
const B = new Uint8Array([3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3]);
expect(
secp256k1PrivateKeyTweakAdd(A, B)
).toEqual(new Uint8Array([
3, 4, 3, 4, 3, 4, 3, 4, 3,
4, 3, 4, 3, 4, 3, 4, 3, 4,
3, 4, 3, 4, 3, 4, 3, 4, 3,
4, 3, 4, 3, 4
]));
});
it('fails for wrong array length', (): void => {
const A = new Uint8Array([0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1]);
const B = new Uint8Array([3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3]);
expect(
() => secp256k1PrivateKeyTweakAdd(A, B)
).toThrow(/Expected tweak to be an Uint8Array/);
});
});
});
@@ -0,0 +1,29 @@
// Copyright 2017-2021 @polkadot/util-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0
import BN from 'bn.js';
import { assert, bnToU8a, isU8a } from '@polkadot/util';
import { secp256k1 } from './secp256k1';
const ecparams = secp256k1.curve as { n: BN };
export function secp256k1PrivateKeyTweakAdd (seckey: Uint8Array, tweak: Uint8Array): Uint8Array {
assert(isU8a(seckey) && seckey.length === 32, 'Expected seckey to be an Uint8Array with length 32');
assert(isU8a(tweak) && tweak.length === 32, 'Expected tweak to be an Uint8Array with length 32');
const bn = new BN(tweak);
assert(bn.cmp(ecparams.n) < 0, 'Tweak parameter is out of range');
bn.iadd(new BN(seckey));
if (bn.cmp(ecparams.n) >= 0) {
bn.isub(ecparams.n);
}
assert(!bn.isZero(), 'Invalid resulting private key');
return bnToU8a(bn, { bitLength: 256, isLe: false });
}
@@ -36,21 +36,24 @@ describe('signatureVerify', (): void => {
it('verifies an ed25519 signature', (): void => {
expect(signatureVerify(MESSAGE, SIG_ED, ADDR_ED)).toEqual({
crypto: 'ed25519',
isValid: true
isValid: true,
publicKey: decodeAddress(ADDR_ED)
});
});
it('verifies an ecdsa signature', (): void => {
expect(signatureVerify(MESSAGE, SIG_EC, ADDR_EC)).toEqual({
crypto: 'ecdsa',
isValid: true
isValid: true,
publicKey: decodeAddress(ADDR_EC)
});
});
it('verifies an ethereum signature', (): void => {
expect(signatureVerify(MESSAGE, SIG_ET, ADDR_ET)).toEqual({
crypto: 'ethereum',
isValid: true
isValid: true,
publicKey: hexToU8a(ADDR_ET)
});
});
@@ -63,35 +66,40 @@ describe('signatureVerify', (): void => {
'0x002309df96687e44280bb72c3818358faeeb699c'
)).toEqual({
crypto: 'ethereum',
isValid: true
isValid: true,
publicKey: hexToU8a('0x002309df96687e44280bb72c3818358faeeb699c')
});
});
it('fails on invalid ethereum signature', (): void => {
expect(signatureVerify(MESSAGE, SIG_EC, ADDR_ET)).toEqual({
crypto: 'none',
isValid: false
isValid: false,
publicKey: hexToU8a(ADDR_ET)
});
});
it('verifies an sr25519 signature', (): void => {
expect(signatureVerify(MESSAGE, SIG_SR, ADDR_SR)).toEqual({
crypto: 'sr25519',
isValid: true
isValid: true,
publicKey: decodeAddress(ADDR_SR)
});
});
it('allows various inputs', (): void => {
expect(signatureVerify(stringToU8a(MESSAGE), hexToU8a(SIG_ED), decodeAddress(ADDR_ED))).toEqual({
crypto: 'ed25519',
isValid: true
isValid: true,
publicKey: decodeAddress(ADDR_ED)
});
});
it('fails on an invalid signature', (): void => {
expect(signatureVerify(MESSAGE, SIG_SR, ADDR_ED)).toEqual({
crypto: 'none',
isValid: false
isValid: false,
publicKey: decodeAddress(ADDR_ED)
});
});
});
@@ -100,35 +108,40 @@ describe('signatureVerify', (): void => {
it('verifies an ed25519 signature', (): void => {
expect(signatureVerify(MESSAGE, MUL_ED, ADDR_ED)).toEqual({
crypto: 'ed25519',
isValid: true
isValid: true,
publicKey: decodeAddress(ADDR_ED)
});
});
it('verifies an ecdsa signature', (): void => {
expect(signatureVerify(MESSAGE, MUL_EC, ADDR_EC)).toEqual({
crypto: 'ecdsa',
isValid: true
isValid: true,
publicKey: decodeAddress(ADDR_EC)
});
});
it('verifies an ethereum signature', (): void => {
expect(signatureVerify(MESSAGE, MUL_ET, ADDR_ET)).toEqual({
crypto: 'ethereum',
isValid: true
isValid: true,
publicKey: hexToU8a(ADDR_ET)
});
});
it('verifies an sr25519 signature', (): void => {
expect(signatureVerify(MESSAGE, MUL_SR, ADDR_SR)).toEqual({
crypto: 'sr25519',
isValid: true
isValid: true,
publicKey: decodeAddress(ADDR_SR)
});
});
it('fails on an invalid signature', (): void => {
expect(signatureVerify(MESSAGE, MUL_SR, ADDR_ED)).toEqual({
crypto: 'sr25519',
isValid: false
isValid: false,
publicKey: new Uint8Array([61, 12, 55, 211, 0, 211, 97, 199, 4, 37, 17, 213, 81, 175, 166, 23, 251, 199, 144, 210, 19, 83, 186, 1, 196, 231, 14, 156, 171, 46, 141, 146])
});
});
});
+1 -1
View File
@@ -79,9 +79,9 @@ export function signatureVerify (message: Uint8Array | string, signature: Uint8A
assert([64, 65, 66].includes(signatureU8a.length), `Invalid signature length, expected [64..66] bytes, found ${signatureU8a.length}`);
const result: VerifyResult = { crypto: 'none', isValid: false };
const publicKey = decodeAddress(addressOrPublicKey);
const input = { message, publicKey, signature: signatureU8a };
const result: VerifyResult = { crypto: 'none', isValid: false, publicKey };
return [0, 1, 2].includes(signatureU8a[0]) && [65, 66].includes(signatureU8a.length)
? verifyMultisig(result, input)
+1
View File
@@ -16,4 +16,5 @@ export type KeypairType = 'ed25519' | 'sr25519' | 'ecdsa' | 'ethereum';
export interface VerifyResult {
crypto: 'none' | KeypairType;
isValid: boolean;
publicKey: Uint8Array;
}
+8 -5
View File
@@ -1,9 +1,12 @@
{
"name": "@polkadot/util",
"version": "5.6.3",
"version": "5.9.1",
"description": "A collection of useful utilities for @polkadot",
"main": "index.js",
"sideEffects": false,
"sideEffects": [
"./detectPackage.js",
"./detectPackage.mjs"
],
"author": "Jaco Greeff <jacogr@gmail.com>",
"maintainers": [],
"contributors": [],
@@ -12,9 +15,9 @@
"bugs": "https://github.com/polkadot-js/common/issues",
"homepage": "https://github.com/polkadot-js/common/tree/master/packages/util#readme",
"dependencies": {
"@babel/runtime": "^7.12.13",
"@polkadot/x-textdecoder": "5.6.3",
"@polkadot/x-textencoder": "5.6.3",
"@babel/runtime": "^7.13.8",
"@polkadot/x-textdecoder": "5.9.1",
"@polkadot/x-textencoder": "5.9.1",
"@types/bn.js": "^4.11.6",
"bn.js": "^4.11.9",
"camelcase": "^5.3.1",
-38
View File
@@ -1,38 +0,0 @@
// Copyright 2017-2021 @polkadot/util authors & contributors
// SPDX-License-Identifier: Apache-2.0
import { detectPackage } from '.';
describe('assertSingletonPackage', (): void => {
const PKG = '@polkadot/util';
const VER1 = '9.8.0-beta.45';
const VER2 = '9.7.1';
const VER3 = '9.6.1';
const PATH = '/Users/jaco/Projects/polkadot-js/api/node_modules/@polkadot/util';
const RES2 = `Multiple instances of @polkadot/util detected, ensure that there is only one package in your dependency tree.\n\t${VER1}\t${PATH}/01\n\t${VER2} \t${PATH}/02`;
const RES3 = `${RES2}\n\t${VER3} \t${PATH}/03`;
it('should not log the first time', (): void => {
const spy = jest.spyOn(console, 'warn');
detectPackage({ name: PKG, version: VER1 }, `${PATH}/01`);
expect(spy).not.toHaveBeenCalled();
spy.mockRestore();
});
it('should log the second time', (): void => {
const spy = jest.spyOn(console, 'warn');
detectPackage({ name: PKG, version: VER2 }, `${PATH}/02`);
expect(spy).toHaveBeenCalledWith(RES2);
spy.mockRestore();
});
it('should allow for function use', (): void => {
const spy = jest.spyOn(console, 'warn');
detectPackage({ name: PKG, version: VER3 }, () => `${PATH}/03`);
expect(spy).toHaveBeenCalledWith(RES3);
spy.mockRestore();
});
});
+19 -85
View File
@@ -1,91 +1,25 @@
// Copyright 2017-2021 @polkadot/util authors & contributors
// SPDX-License-Identifier: Apache-2.0
import { xglobal } from '@polkadot/x-global';
// For esm, this should be import.meta.url or to get the same behavior as __dirname, we can use
//
// new URL(import.meta.url).pathname)
//
// The issue is the WP4 has "some" issues with import.meta.url. So because of bundlers, we can't have
// nice things... In this case it is even worse since import.meta.url won't even make it compile, so
// there is a complete dead end with usage thereof
//
// When that is fixed, a solution is to have both .js & .mjs files, with the following content -
//
// cjs: util.detectPackage(packageInfo, () => __dirname);
// esm: detectPackage(packageInfo, () => import.meta.url);
//
// With the above we additionally need a .d.ts to just export the packageInfo
import { isFunction } from './is/function';
import { isString } from './is/string';
import { assert } from './assert';
import { packageInfo as decoderInfo } from '@polkadot/x-textdecoder';
import { packageInfo as encoderInfo } from '@polkadot/x-textencoder';
// eslint-disable-next-line no-undef
type This = typeof globalThis;
import { packageInfo } from './packageInfo';
import { detectPackage } from './versionDetect';
interface PackageJson {
name: string;
version: string;
}
interface VersionPath {
path?: string;
version: string;
}
interface PjsChecks extends This {
__polkadotjs: Record<string, VersionPath[]>;
}
type PjsWindow = (Window & This) & PjsChecks;
type FnString = () => string | undefined;
/** @internal */
function expandPath (path?: string): string {
return (!path || path.length < 5) ? '<unknown>' : path;
}
/** @internal */
function getEntry (name: string): VersionPath[] {
const _global = xglobal as PjsWindow;
if (!_global.__polkadotjs) {
_global.__polkadotjs = {};
}
if (!_global.__polkadotjs[name]) {
_global.__polkadotjs[name] = [];
}
return _global.__polkadotjs[name];
}
/** @internal */
function flattenVersions (entry: VersionPath[]): string {
const all = entry.map((version: VersionPath | string): VersionPath =>
isString(version)
? { version }
: version
);
const verLength = all.reduce((max, { version }) => Math.max(max, version.length), 0);
return all
.map(({ path, version }) => `\t${version.padEnd(verLength)}\t${expandPath(path)}`)
.join('\n');
}
/** @internal */
function getPath (pathOrFn?: FnString | string | false): false | string | undefined {
if (isFunction(pathOrFn)) {
try {
return pathOrFn();
} catch (error) {
return undefined;
}
}
return pathOrFn;
}
/**
* @name detectPackage
* @summary Checks that a specific package is only imported once
*/
export function detectPackage ({ name, version }: PackageJson, pathOrFn?: FnString | string | false): void {
assert(name.startsWith('@polkadot'), `Invalid package descriptor ${name}`);
const entry = getEntry(name);
entry.push({ path: getPath(pathOrFn) || '', version });
if (entry.length !== 1) {
console.warn(`Multiple instances of ${name} detected, ensure that there is only one package in your dependency tree.\n${flattenVersions(entry)}`);
}
}
detectPackage(packageInfo, typeof __dirname !== 'undefined' && __dirname, [decoderInfo, encoderInfo]);
+9 -7
View File
@@ -1,24 +1,26 @@
// Copyright 2017-2021 @polkadot/util authors & contributors
// SPDX-License-Identifier: Apache-2.0
import './detectPackage';
/**
* @summary Utility methods for this package are split into groups
*/
export { assert, assertReturn } from './assert';
export { detectPackage } from './detectPackage';
export { extractTime } from './extractTime';
export { logger } from './logger';
export { memoize } from './memoize';
export { promisify } from './promisify';
export { packageInfo } from './packageInfo';
export * from './array';
export * from './assert';
export * from './bn';
export * from './buffer';
export * from './compact';
export * from './extractTime';
export * from './format';
export * from './hex';
export * from './is';
export * from './logger';
export * from './memoize';
export * from './number';
export * from './promisify';
export * from './string';
export * from './u8a';
export * from './versionDetect';
+4 -5
View File
@@ -5,8 +5,7 @@ import type { Logger } from './types';
import BN from 'bn.js';
import { format } from './logger';
import { logger } from '.';
import { logger, loggerFormat } from '.';
describe('logger', (): void => {
let dateMatch: unknown;
@@ -44,13 +43,13 @@ describe('logger', (): void => {
jest.restoreAllMocks();
});
describe('format', (): void => {
describe('loggerFormat', (): void => {
it('returns null as-is', (): void => {
expect(format(null)).toEqual(null);
expect(loggerFormat(null)).toEqual(null);
});
it('returns undefined as-is', (): void => {
expect(format(undefined)).toEqual(undefined);
expect(loggerFormat(undefined)).toEqual(undefined);
});
});
+4 -4
View File
@@ -25,7 +25,7 @@ const logTo = {
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]);
result[key] = loggerFormat(value[key]);
return result;
}, {});
@@ -34,9 +34,9 @@ function formatOther (value: unknown): unknown {
return value;
}
export function format (value: unknown): unknown {
export function loggerFormat (value: unknown): unknown {
if (Array.isArray(value)) {
return value.map(format);
return value.map(loggerFormat);
} else if (isBn(value)) {
return value.toString();
} else if (isU8a(value) || isBuffer(value)) {
@@ -57,7 +57,7 @@ function apply (log: LogType, type: string, values: Logger$Data, maxSize = -1):
formatDate(new Date()),
type,
...values
.map(format)
.map(loggerFormat)
.map((v) => {
if (maxSize <= 0) {
return v;
+1 -1
View File
@@ -3,4 +3,4 @@
// Auto-generated by @polkadot/dev, do not edit
export const packageInfo = { name: '@polkadot/util', version: '5.6.3' };
export const packageInfo = { name: '@polkadot/util', version: '5.9.1' };
+70
View File
@@ -0,0 +1,70 @@
// Copyright 2017-2021 @polkadot/util authors & contributors
// SPDX-License-Identifier: Apache-2.0
import { detectPackage } from './versionDetect';
describe('detectPackage', (): void => {
const PKG = '@polkadot/util';
const VER1 = '9.8.0-beta.45';
const VER2 = '9.7.1';
const VER3 = '9.6.1';
const PATH = '/Users/jaco/Projects/polkadot-js/api/node_modules/@polkadot/util';
const MISMATCH = `@polkadot/util has multiple versions, ensure that there is only one installed.
Either remove and explicitly install matching versions or deupe using your package manager.
The following conflicting packages were found:
\t${VER1}\t${PATH}/01
\t${VER2} \t${PATH}/02`;
it('should not log the first time', (): void => {
const spy = jest.spyOn(console, 'warn');
detectPackage({ name: PKG, version: VER1 }, `${PATH}/01`);
expect(spy).not.toHaveBeenCalled();
spy.mockRestore();
});
it('should log the second time', (): void => {
const spy = jest.spyOn(console, 'warn');
detectPackage({ name: PKG, version: VER2 }, `${PATH}/02`);
expect(spy).toHaveBeenCalledWith(MISMATCH);
spy.mockRestore();
});
it('should allow for function use', (): void => {
const spy = jest.spyOn(console, 'warn');
detectPackage({ name: PKG, version: VER3 }, () => `${PATH}/03`);
expect(spy).toHaveBeenCalledWith(`${MISMATCH}
\t${VER3} \t${PATH}/03`);
spy.mockRestore();
});
});
describe('detectPackageDeps', (): void => {
const DEP0 = { name: '@polkadot/keyring', version: '1.1.1' };
const DEP1 = { name: '@polkadot/util', version: '1.1.2' };
const DEP2 = { name: '@polkadot/util-crypto', version: '1.1.3' };
const DEP3 = { name: '@polkadot/networks', version: '1.1.1' };
it('should not log when no mismatches are found', (): void => {
const spy = jest.spyOn(console, 'warn');
detectPackage({ name: '@polkadot/one', version: '1.1.1' }, false, [DEP0, DEP3]);
expect(spy).not.toHaveBeenCalled();
spy.mockRestore();
});
it('should log when mismatches are found', (): void => {
const spy = jest.spyOn(console, 'warn');
detectPackage({ name: '@polkadot/two', version: '1.1.1' }, false, [DEP0, DEP1, DEP2, DEP3]);
expect(spy).toHaveBeenCalledWith(`@polkadot/two requires direct dependencies exactly matching version 1.1.1.
Either remove and explicitly install matching versions or deupe using your package manager.
The following conflicting packages were found:
\t1.1.2\t@polkadot/util
\t1.1.3\t@polkadot/util-crypto`);
spy.mockRestore();
});
});
+106
View File
@@ -0,0 +1,106 @@
// Copyright 2017-2021 @polkadot/util authors & contributors
// SPDX-License-Identifier: Apache-2.0
import { xglobal } from '@polkadot/x-global';
import { isFunction } from './is/function';
import { isString } from './is/string';
import { assert } from './assert';
type This = typeof globalThis;
interface PackageJson {
name: string;
version: string;
}
interface VersionPath {
path?: string;
version: string;
}
interface PjsChecks extends This {
__polkadotjs: Record<string, VersionPath[]>;
}
type PjsWindow = (Window & This) & PjsChecks;
type FnString = () => string | undefined;
const DEDUPE = 'Either remove and explicitly install matching versions or deupe using your package manager.\nThe following conflicting packages were found:';
/** @internal */
function getEntry (name: string): VersionPath[] {
const _global = xglobal as PjsWindow;
if (!_global.__polkadotjs) {
_global.__polkadotjs = {};
}
if (!_global.__polkadotjs[name]) {
_global.__polkadotjs[name] = [];
}
return _global.__polkadotjs[name];
}
function getVersionLength (all: { version: string }[]): number {
return all.reduce((max, { version }) => Math.max(max, version.length), 0);
}
/** @internal */
function flattenInfos (all: PackageJson[]): string {
const verLength = getVersionLength(all);
return all
.map(({ name, version }) => `\t${version.padEnd(verLength)}\t${name}`)
.join('\n');
}
/** @internal */
function flattenVersions (entry: VersionPath[]): string {
const all = entry.map((version: VersionPath | string): VersionPath =>
isString(version)
? { version }
: version
);
const verLength = getVersionLength(all);
return all
.map(({ path, version }) => `\t${version.padEnd(verLength)}\t${(!path || path.length < 5) ? '<unknown>' : path}`)
.join('\n');
}
/** @internal */
function getPath (pathOrFn?: FnString | string | false): string {
if (isFunction(pathOrFn)) {
try {
return pathOrFn() || '';
} catch (error) {
return '';
}
}
return pathOrFn || '';
}
/**
* @name detectPackage
* @summary Checks that a specific package is only imported once
*/
export function detectPackage ({ name, version }: PackageJson, pathOrFn?: FnString | string | false, deps: PackageJson[] = []): void {
assert(name.startsWith('@polkadot'), `Invalid package descriptor ${name}`);
const entry = getEntry(name);
entry.push({ path: getPath(pathOrFn), version });
if (entry.length !== 1) {
console.warn(`${name} has multiple versions, ensure that there is only one installed.\n${DEDUPE}\n${flattenVersions(entry)}`);
} else {
const mismatches = deps.filter((d) => d && d.version !== version);
if (mismatches.length) {
console.warn(`${name} requires direct dependencies exactly matching version ${version}.\n${DEDUPE}\n${flattenInfos(mismatches)}`);
}
}
}
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@polkadot/x-fetch",
"version": "5.6.3",
"version": "5.9.1",
"description": "A cross-environment fetch replacement",
"browser": "browser.js",
"main": "node.js",
@@ -14,8 +14,8 @@
"bugs": "https://github.com/polkadot-js/common/issues",
"homepage": "https://github.com/polkadot-js/common/tree/master/packages/x-fetch#readme",
"dependencies": {
"@babel/runtime": "^7.12.13",
"@polkadot/x-global": "5.6.3",
"@babel/runtime": "^7.13.8",
"@polkadot/x-global": "5.9.1",
"@types/node-fetch": "^2.5.8",
"node-fetch": "^2.6.1"
}
+2
View File
@@ -3,4 +3,6 @@
import { xglobal } from '@polkadot/x-global';
export { packageInfo } from './packageInfo';
export const fetch = xglobal.fetch;
+7 -3
View File
@@ -5,6 +5,10 @@ import nodeFetch from 'node-fetch';
import { xglobal } from '@polkadot/x-global';
export const fetch = typeof xglobal.fetch === 'undefined'
? nodeFetch as unknown as typeof global.fetch
: xglobal.fetch;
export { packageInfo } from './packageInfo';
export const fetch = (
typeof xglobal.fetch === 'undefined'
? nodeFetch as unknown as typeof global.fetch
: xglobal.fetch
);
+1 -1
View File
@@ -3,4 +3,4 @@
// Auto-generated by @polkadot/dev, do not edit
export const packageInfo = { name: '@polkadot/x-fetch', version: '5.6.3' };
export const packageInfo = { name: '@polkadot/x-fetch', version: '5.9.1' };
+1 -1
View File
@@ -1,4 +1,4 @@
// Copyright 2017-2021 @polkadot/x-fetch authors & contributors
// SPDX-License-Identifier: Apache-2.0
export { fetch } from './browser';
export { fetch, packageInfo } from './browser';
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@polkadot/x-global",
"version": "5.6.3",
"version": "5.9.1",
"description": "A cross-environment global replacement",
"main": "index.js",
"sideEffects": false,
@@ -12,7 +12,7 @@
"bugs": "https://github.com/polkadot-js/common/issues",
"homepage": "https://github.com/polkadot-js/common/tree/master/packages/x-global#readme",
"dependencies": {
"@babel/runtime": "^7.12.13",
"@babel/runtime": "^7.13.8",
"@types/node-fetch": "^2.5.8",
"node-fetch": "^2.6.1"
}
+11 -7
View File
@@ -1,10 +1,14 @@
// Copyright 2017-2021 @polkadot/x-fetch authors & contributors
// SPDX-License-Identifier: Apache-2.0
export const xglobal = typeof global !== 'undefined'
? global
: typeof self !== 'undefined'
? self
: typeof window !== 'undefined'
? window
: this as unknown as (Window & typeof globalThis);
export { packageInfo } from './packageInfo';
export const xglobal = (
typeof global !== 'undefined'
? global
: typeof self !== 'undefined'
? self
: typeof window !== 'undefined'
? window
: this as unknown as (Window & typeof globalThis)
);
+1 -1
View File
@@ -3,4 +3,4 @@
// Auto-generated by @polkadot/dev, do not edit
export const packageInfo = { name: '@polkadot/x-global', version: '5.6.3' };
export const packageInfo = { name: '@polkadot/x-global', version: '5.9.1' };
+4 -4
View File
@@ -1,6 +1,6 @@
{
"name": "@polkadot/x-randomvalues",
"version": "5.6.3",
"version": "5.9.1",
"description": "A cross-environment window.crypto.getRandomValues replacement",
"browser": "browser.js",
"main": "node.js",
@@ -14,10 +14,10 @@
"bugs": "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.13",
"@polkadot/x-global": "5.6.3"
"@babel/runtime": "^7.13.8",
"@polkadot/x-global": "5.9.1"
},
"devDependencies": {
"@types/react-native": "^0.63.49"
"@types/react-native": "^0.63.50"
}
}
+2
View File
@@ -1,6 +1,8 @@
// Copyright 2017-2021 @polkadot/x-randomvalues authors & contributors
// SPDX-License-Identifier: Apache-2.0
export { packageInfo } from './packageInfo';
export function getRandomValues <T extends Uint8Array> (arr: T): T {
return crypto.getRandomValues(arr);
}
+2
View File
@@ -3,6 +3,8 @@
import crypto from 'crypto';
export { packageInfo } from './packageInfo';
export function getRandomValues <T extends Uint8Array> (arr: T): T {
return crypto.randomBytes(arr.length).reduce((arr, value, index) => {
arr[index] = value;
+1 -1
View File
@@ -3,4 +3,4 @@
// Auto-generated by @polkadot/dev, do not edit
export const packageInfo = { name: '@polkadot/x-randomvalues', version: '5.6.3' };
export const packageInfo = { name: '@polkadot/x-randomvalues', version: '5.9.1' };
+10 -6
View File
@@ -11,6 +11,8 @@ import { xglobal } from '@polkadot/x-global';
import { insecureRandomValues } from './fallback';
export { packageInfo } from './packageInfo';
interface RNExt {
RNGetRandomValues: {
getRandomBase64: (length: number) => string;
@@ -31,9 +33,11 @@ function getRandomValuesGlobal <T extends Uint8Array> (arr: T): T {
return crypto.getRandomValues(arr);
}
export const getRandomValues = typeof xglobal.crypto === 'object' && typeof xglobal.crypto.getRandomValues === 'function'
? getRandomValuesGlobal
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-explicit-any
: (typeof (xglobal as any).nativeCallSyncHook === 'undefined' || !NativeModules.ExpoRandom)
? insecureRandomValues
: getRandomValuesNative;
export const getRandomValues = (
typeof xglobal.crypto === 'object' && typeof xglobal.crypto.getRandomValues === 'function'
? getRandomValuesGlobal
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-explicit-any
: (typeof (xglobal as any).nativeCallSyncHook === 'undefined' || !NativeModules.ExpoRandom)
? insecureRandomValues
: getRandomValuesNative
);
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@polkadot/x-rxjs",
"version": "5.6.3",
"version": "5.9.1",
"description": "A pass-through interface for RxJs (allowing node + mjs usage)",
"main": "index.js",
"sideEffects": false,
@@ -12,7 +12,7 @@
"bugs": "https://github.com/polkadot-js/common/issues",
"homepage": "https://github.com/polkadot-js/common/tree/master/packages/x-rxjs#readme",
"dependencies": {
"@babel/runtime": "^7.12.13",
"rxjs": "^6.6.3"
"@babel/runtime": "^7.13.8",
"rxjs": "^6.6.6"
}
}
+1 -1
View File
@@ -3,4 +3,4 @@
// Auto-generated by @polkadot/dev, do not edit
export const packageInfo = { name: '@polkadot/x-rxjs', version: '5.6.3' };
export const packageInfo = { name: '@polkadot/x-rxjs', version: '5.9.1' };
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@polkadot/x-textdecoder",
"version": "5.6.3",
"version": "5.9.1",
"description": "A TextDecoder replacement",
"browser": "browser.js",
"main": "node.js",
@@ -14,7 +14,7 @@
"bugs": "https://github.com/polkadot-js/common/issues",
"homepage": "https://github.com/polkadot-js/common/tree/master/packages/x-textdecoder#readme",
"dependencies": {
"@babel/runtime": "^7.12.13",
"@polkadot/x-global": "5.6.3"
"@babel/runtime": "^7.13.8",
"@polkadot/x-global": "5.9.1"
}
}
+7 -3
View File
@@ -5,6 +5,10 @@ import { xglobal } from '@polkadot/x-global';
import { TextDecoder as Fallback } from './fallback';
export const TextDecoder = typeof xglobal.TextDecoder === 'undefined'
? Fallback as unknown as typeof xglobal.TextDecoder
: xglobal.TextDecoder;
export { packageInfo } from './packageInfo';
export const TextDecoder = (
typeof xglobal.TextDecoder === 'undefined'
? Fallback as unknown as typeof xglobal.TextDecoder
: xglobal.TextDecoder
);
+7 -3
View File
@@ -5,6 +5,10 @@ import util from 'util';
import { xglobal } from '@polkadot/x-global';
export const TextDecoder = typeof xglobal.TextDecoder === 'undefined'
? util.TextDecoder as unknown as typeof xglobal.TextDecoder
: xglobal.TextDecoder;
export { packageInfo } from './packageInfo';
export const TextDecoder = (
typeof xglobal.TextDecoder === 'undefined'
? util.TextDecoder as unknown as typeof xglobal.TextDecoder
: xglobal.TextDecoder
);
+1 -1
View File
@@ -3,4 +3,4 @@
// Auto-generated by @polkadot/dev, do not edit
export const packageInfo = { name: '@polkadot/x-textdecoder', version: '5.6.3' };
export const packageInfo = { name: '@polkadot/x-textdecoder', version: '5.9.1' };
+1 -1
View File
@@ -1,4 +1,4 @@
// Copyright 2017-2021 @polkadot/x-textencoder authors & contributors
// SPDX-License-Identifier: Apache-2.0
export { TextDecoder } from './browser';
export { TextDecoder, packageInfo } from './browser';
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@polkadot/x-textencoder",
"version": "5.6.3",
"version": "5.9.1",
"description": "A TextDecoder replacement",
"browser": "browser.js",
"main": "node.js",
@@ -14,7 +14,7 @@
"bugs": "https://github.com/polkadot-js/common/issues",
"homepage": "https://github.com/polkadot-js/common/tree/master/packages/x-textencoder#readme",
"dependencies": {
"@babel/runtime": "^7.12.13",
"@polkadot/x-global": "5.6.3"
"@babel/runtime": "^7.13.8",
"@polkadot/x-global": "5.9.1"
}
}
+7 -3
View File
@@ -5,6 +5,10 @@ import { xglobal } from '@polkadot/x-global';
import { TextEncoder as Fallback } from './fallback';
export const TextEncoder = typeof xglobal.TextEncoder === 'undefined'
? Fallback as unknown as typeof xglobal.TextEncoder
: xglobal.TextEncoder;
export { packageInfo } from './packageInfo';
export const TextEncoder = (
typeof xglobal.TextEncoder === 'undefined'
? Fallback as unknown as typeof xglobal.TextEncoder
: xglobal.TextEncoder
);
+7 -3
View File
@@ -5,6 +5,8 @@ import util from 'util';
import { xglobal } from '@polkadot/x-global';
export { packageInfo } from './packageInfo';
class NodeFallback {
#encoder: util.TextEncoder;
@@ -20,6 +22,8 @@ class NodeFallback {
}
}
export const TextEncoder = typeof xglobal.TextEncoder === 'undefined'
? NodeFallback as unknown as typeof xglobal.TextEncoder
: xglobal.TextEncoder;
export const TextEncoder = (
typeof xglobal.TextEncoder === 'undefined'
? NodeFallback as unknown as typeof xglobal.TextEncoder
: xglobal.TextEncoder
);
+1 -1
View File
@@ -3,4 +3,4 @@
// Auto-generated by @polkadot/dev, do not edit
export const packageInfo = { name: '@polkadot/x-textencoder', version: '5.6.3' };
export const packageInfo = { name: '@polkadot/x-textencoder', version: '5.9.1' };
+1 -1
View File
@@ -1,4 +1,4 @@
// Copyright 2017-2021 @polkadot/x-textencoder authors & contributors
// SPDX-License-Identifier: Apache-2.0
export { TextEncoder } from './browser';
export { TextEncoder, packageInfo } from './browser';
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@polkadot/x-ws",
"version": "5.6.3",
"version": "5.9.1",
"description": "A cross-environment WebSocket replacement",
"browser": "browser.js",
"main": "node.js",
@@ -14,8 +14,8 @@
"bugs": "https://github.com/polkadot-js/common/issues",
"homepage": "https://github.com/polkadot-js/common/tree/master/packages/x-ws#readme",
"dependencies": {
"@babel/runtime": "^7.12.13",
"@polkadot/x-global": "5.6.3",
"@babel/runtime": "^7.13.8",
"@polkadot/x-global": "5.9.1",
"@types/websocket": "^1.0.1",
"websocket": "^1.0.33"
}
+2
View File
@@ -3,4 +3,6 @@
import { xglobal } from '@polkadot/x-global';
export { packageInfo } from './packageInfo';
export const WebSocket = xglobal.WebSocket;
+7 -3
View File
@@ -5,6 +5,10 @@ import ws from 'websocket';
import { xglobal } from '@polkadot/x-global';
export const WebSocket = typeof xglobal.WebSocket === 'undefined'
? ws.w3cwebsocket as unknown as typeof xglobal.WebSocket
: xglobal.WebSocket;
export { packageInfo } from './packageInfo';
export const WebSocket = (
typeof xglobal.WebSocket === 'undefined'
? ws.w3cwebsocket as unknown as typeof xglobal.WebSocket
: xglobal.WebSocket
);
+1 -1
View File
@@ -3,4 +3,4 @@
// Auto-generated by @polkadot/dev, do not edit
export const packageInfo = { name: '@polkadot/x-ws', version: '5.6.3' };
export const packageInfo = { name: '@polkadot/x-ws', version: '5.9.1' };
+1 -1
View File
@@ -1,4 +1,4 @@
// Copyright 2017-2021 @polkadot/x-ws authors & contributors
// SPDX-License-Identifier: Apache-2.0
export { WebSocket } from './browser';
export { WebSocket, packageInfo } from './browser';
+493 -426
View File
File diff suppressed because it is too large Load Diff