Introduce key suri (path derivation) (#358)
* Introduce key suri (path derivation) * Errant console.log * let -> const * Add seed derivation from path * Allow new-generation derivation * Add addFromUri to keyring * Use addFromUri in testing keyring * Add suri tests * Prepare for sr25519 derivation * CHANGELOG entry * ed25519 is aligned with substrate * Bump version
This commit is contained in:
@@ -1,3 +1,7 @@
|
||||
# 0.36.1
|
||||
|
||||
- Add `fromUri` to keyring along with hard & soft key derivation.
|
||||
|
||||
# 0.35.1
|
||||
|
||||
- Remove NodeJs-only `syncify` function, not exported by the package (with binary dependency for Node)
|
||||
|
||||
+1
-1
@@ -9,5 +9,5 @@
|
||||
"packages": [
|
||||
"packages/*"
|
||||
],
|
||||
"version": "0.35.10"
|
||||
"version": "0.36.0"
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@polkadot/chainspec",
|
||||
"version": "0.35.10",
|
||||
"version": "0.36.0",
|
||||
"description": "Contains chain specifications for known chains",
|
||||
"main": "index.js",
|
||||
"keywords": [
|
||||
@@ -29,6 +29,6 @@
|
||||
"homepage": "https://github.com/polkadot-js/common/tree/master/packages/chainspec#readme",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.3.4",
|
||||
"@polkadot/util": "^0.35.10"
|
||||
"@polkadot/util": "^0.36.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@polkadot/db",
|
||||
"version": "0.35.10",
|
||||
"version": "0.36.0",
|
||||
"description": "Implementation of a basic sync in-memory and on-disk databases with overlays",
|
||||
"main": "index.js",
|
||||
"keywords": [
|
||||
@@ -29,8 +29,8 @@
|
||||
"homepage": "https://github.com/polkadot-js/common/tree/master/packages/db#readme",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.3.4",
|
||||
"@polkadot/trie-hash": "^0.35.10",
|
||||
"@polkadot/util": "^0.35.10",
|
||||
"@polkadot/trie-hash": "^0.36.0",
|
||||
"@polkadot/util": "^0.36.0",
|
||||
"@types/mkdirp": "^0.5.2",
|
||||
"@types/rimraf": "^2.0.2",
|
||||
"@types/snappy": "^6.0.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@polkadot/keyring",
|
||||
"version": "0.35.10",
|
||||
"version": "0.36.0",
|
||||
"description": "Keyring management",
|
||||
"main": "index.js",
|
||||
"engines": {
|
||||
@@ -31,8 +31,8 @@
|
||||
"homepage": "https://github.com/polkadot-js/common/tree/master/packages/keyring#readme",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.3.4",
|
||||
"@polkadot/util": "^0.35.10",
|
||||
"@polkadot/util-crypto": "^0.35.10",
|
||||
"@polkadot/util": "^0.36.0",
|
||||
"@polkadot/util-crypto": "^0.36.0",
|
||||
"@types/bs58": "^4.0.0",
|
||||
"bs58": "^4.0.1"
|
||||
}
|
||||
|
||||
@@ -2,10 +2,11 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { KeyringInstance, KeyringPair, KeyringPair$Json, KeyringPair$Meta, KeyringOptions, KeyringPairType } from './types';
|
||||
import { KeypairType } from '@polkadot/util-crypto/types';
|
||||
import { KeyringInstance, KeyringPair, KeyringPair$Json, KeyringPair$Meta, KeyringOptions } from './types';
|
||||
|
||||
import { assert, hexToU8a, isNumber } from '@polkadot/util/index';
|
||||
import { mnemonicToSeed , naclKeypairFromSeed as naclFromSeed, schnorrkelKeypairFromSeed as schnorrkelFromSeed } from '@polkadot/util-crypto/index';
|
||||
import { assert, hexToU8a, isNumber, isHex, stringToU8a } from '@polkadot/util/index';
|
||||
import { keyExtract, mnemonicToSeed , naclKeypairFromSeed as naclFromSeed, schnorrkelKeypairFromSeed as schnorrkelFromSeed, mnemonicToMiniSecret, keyFromPath } from '@polkadot/util-crypto/index';
|
||||
|
||||
import { decodeAddress, encodeAddress, setAddressPrefix } from './address';
|
||||
import createPair from './pair';
|
||||
@@ -29,13 +30,15 @@ import Pairs from './pairs';
|
||||
*/
|
||||
export default class Keyring implements KeyringInstance {
|
||||
private _pairs: Pairs;
|
||||
private _type: KeyringPairType;
|
||||
private _type: KeypairType;
|
||||
|
||||
constructor (options: KeyringOptions = {}) {
|
||||
options.type = options.type || 'ed25519';
|
||||
|
||||
constructor (options: KeyringOptions = { type: 'ed25519' }) {
|
||||
assert(options && ['ed25519', 'sr25519'].includes(options.type || 'undefined'), `Expected a keyring type of either 'ed25519' or 'sr25519', found '${options.type}`);
|
||||
|
||||
this._pairs = new Pairs();
|
||||
this._type = options.type as KeyringPairType;
|
||||
this._type = options.type;
|
||||
|
||||
setAddressPrefix(isNumber(options.addressPrefix) ? options.addressPrefix : 42);
|
||||
}
|
||||
@@ -44,6 +47,20 @@ export default class Keyring implements KeyringInstance {
|
||||
encodeAddress = encodeAddress;
|
||||
setAddressPrefix = setAddressPrefix;
|
||||
|
||||
/**
|
||||
* @description True for Ed25519 keyring
|
||||
*/
|
||||
get isEd25519 (): boolean {
|
||||
return this.type === 'ed25519';
|
||||
}
|
||||
|
||||
/**
|
||||
* @description True for Ed25519 keyring
|
||||
*/
|
||||
get isSr25519 (): boolean {
|
||||
return this.type === 'sr25519';
|
||||
}
|
||||
|
||||
/**
|
||||
* @description retrieve the pairs (alias for getPairs)
|
||||
*/
|
||||
@@ -61,7 +78,7 @@ export default class Keyring implements KeyringInstance {
|
||||
/**
|
||||
* @description Returns the type of the keyring, either ed25519 of sr25519
|
||||
*/
|
||||
get type (): KeyringPairType {
|
||||
get type (): KeypairType {
|
||||
return this._type;
|
||||
}
|
||||
|
||||
@@ -81,7 +98,7 @@ export default class Keyring implements KeyringInstance {
|
||||
* of an account backup), and then generates a keyring pair from them that it passes to
|
||||
* `addPair` to stores in a keyring pair dictionary the public key of the generated pair as a key and the pair as the associated value.
|
||||
*/
|
||||
addFromAddress (address: string | Uint8Array, meta: KeyringPair$Meta = {}, encoded: Uint8Array | null = null, type: KeyringPairType = this.type): KeyringPair {
|
||||
addFromAddress (address: string | Uint8Array, meta: KeyringPair$Meta = {}, encoded: Uint8Array | null = null, type: KeypairType = this.type): KeyringPair {
|
||||
return this.addPair(createPair(type, { publicKey: this.decodeAddress(address) }, meta, encoded));
|
||||
}
|
||||
|
||||
@@ -107,7 +124,7 @@ export default class Keyring implements KeyringInstance {
|
||||
* of an account backup), and then generates a keyring pair from it that it passes to
|
||||
* `addPair` to stores in a keyring pair dictionary the public key of the generated pair as a key and the pair as the associated value.
|
||||
*/
|
||||
addFromMnemonic (mnemonic: string, meta: KeyringPair$Meta = {}, type: KeyringPairType = this.type): KeyringPair {
|
||||
addFromMnemonic (mnemonic: string, meta: KeyringPair$Meta = {}, type: KeypairType = this.type): KeyringPair {
|
||||
return this.addFromSeed(mnemonicToSeed(mnemonic), meta, type);
|
||||
}
|
||||
|
||||
@@ -118,14 +135,39 @@ export default class Keyring implements KeyringInstance {
|
||||
* Allows user to provide the account seed as an argument, and then generates a keyring pair from it that it passes to
|
||||
* `addPair` to store in a keyring pair dictionary the public key of the generated pair as a key and the pair as the associated value.
|
||||
*/
|
||||
addFromSeed (seed: Uint8Array, meta: KeyringPair$Meta = {}, type: KeyringPairType = this.type): KeyringPair {
|
||||
const keypair = type === 'sr25519'
|
||||
addFromSeed (seed: Uint8Array, meta: KeyringPair$Meta = {}, type: KeypairType = this.type): KeyringPair {
|
||||
const keypair = this.isSr25519
|
||||
? schnorrkelFromSeed(seed)
|
||||
: naclFromSeed(seed);
|
||||
|
||||
return this.addPair(createPair(type, { ...keypair, seed }, meta, null));
|
||||
}
|
||||
|
||||
/**
|
||||
* @name addFromUri
|
||||
* @summary Creates an account via an suri
|
||||
* @description Extracts the phrase, path and password from a SURI format for specifying secret keys `<secret>/<soft-key>//<hard-key>///<password>` (the `///password` may be omitted, and `/<soft-key>` and `//<hard-key>` maybe repeated and mixed). The secret can be a hex string, mnemonic phrase or a string (to be padded)
|
||||
*/
|
||||
addFromUri (suri: string, meta: KeyringPair$Meta = {}, type: KeypairType = this.type): KeyringPair {
|
||||
const { password, phrase, path } = keyExtract(suri);
|
||||
let seed;
|
||||
|
||||
if (isHex(phrase, 256)) {
|
||||
seed = hexToU8a(phrase);
|
||||
} else {
|
||||
const str = phrase as string;
|
||||
const parts = str.split(' ');
|
||||
|
||||
if ([12, 15, 18, 21, 24].includes(parts.length)) {
|
||||
seed = mnemonicToMiniSecret(phrase, password);
|
||||
} else {
|
||||
seed = stringToU8a(str.padEnd(32));
|
||||
}
|
||||
}
|
||||
|
||||
return this.addFromSeed(keyFromPath(seed, path, type), meta, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* @name getPair
|
||||
* @summary Retrieves an account keyring pair from the Keyring Pair Dictionary, given an account address
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { KeypairType } from '@polkadot/util-crypto/types';
|
||||
import { KeyringPair, KeyringPair$Json, KeyringPair$Meta, KeyringPairType } from '../types';
|
||||
import { Keypair, KeypairType } from '@polkadot/util-crypto/types';
|
||||
import { KeyringPair, KeyringPair$Json, KeyringPair$Meta } from '../types';
|
||||
import { PairInfo } from './types';
|
||||
|
||||
import { naclKeypairFromSeed as naclFromSeed, naclSign, naclVerify, schnorrkelKeypairFromSeed as schnorrkelFromSeed, schnorrkelSign, schnorrkelVerify } from '@polkadot/util-crypto/index';
|
||||
@@ -13,18 +13,21 @@ import decode from './decode';
|
||||
import encode from './encode';
|
||||
import toJson from './toJson';
|
||||
|
||||
const fromSeed = (type: KeyringPairType, seed: Uint8Array) =>
|
||||
type === 'sr25519'
|
||||
const isSr25519 = (type: KeypairType): boolean =>
|
||||
type === 'sr25519';
|
||||
|
||||
const fromSeed = (type: KeypairType, seed: Uint8Array) =>
|
||||
isSr25519(type)
|
||||
? schnorrkelFromSeed(seed)
|
||||
: naclFromSeed(seed);
|
||||
|
||||
const sign = (type: KeyringPairType, message: Uint8Array, pair: Partial<KeypairType>) =>
|
||||
type === 'sr25519'
|
||||
const sign = (type: KeypairType, message: Uint8Array, pair: Partial<Keypair>) =>
|
||||
isSr25519(type)
|
||||
? schnorrkelSign(message, pair)
|
||||
: naclSign(message, pair);
|
||||
|
||||
const verify = (type: KeyringPairType, message: Uint8Array, signature: Uint8Array, publicKey: Uint8Array) =>
|
||||
type === 'sr25519'
|
||||
const verify = (type: KeypairType, message: Uint8Array, signature: Uint8Array, publicKey: Uint8Array) =>
|
||||
isSr25519(type)
|
||||
? schnorrkelVerify(message, signature, publicKey)
|
||||
: naclVerify(message, signature, publicKey);
|
||||
|
||||
@@ -59,7 +62,7 @@ const verify = (type: KeyringPairType, message: Uint8Array, signature: Uint8Arra
|
||||
* an `encoded` property that is assigned with the encoded public key in hex format, and an `encoding`
|
||||
* property that indicates whether the public key value of the `encoded` property is encoded or not.
|
||||
*/
|
||||
export default function createPair (type: KeyringPairType, { publicKey, seed }: PairInfo, meta: KeyringPair$Meta = {}, encoded: Uint8Array | null = null): KeyringPair {
|
||||
export default function createPair (type: KeypairType, { publicKey, seed }: PairInfo, meta: KeyringPair$Meta = {}, encoded: Uint8Array | null = null): KeyringPair {
|
||||
let secretKey: Uint8Array | undefined;
|
||||
|
||||
if (seed) {
|
||||
@@ -98,7 +101,7 @@ export default function createPair (type: KeyringPairType, { publicKey, seed }:
|
||||
sign(type, message, { publicKey, secretKey }),
|
||||
toJson: (passphrase?: string): KeyringPair$Json =>
|
||||
toJson(type, { meta, publicKey }, encode({ publicKey, seed }, passphrase), !!passphrase),
|
||||
toType: (type: KeyringPairType): KeyringPair =>
|
||||
toType: (type: KeypairType): KeyringPair =>
|
||||
createPair(type, { publicKey, seed }, meta, null),
|
||||
verify: (message: Uint8Array, signature: Uint8Array): boolean =>
|
||||
verify(type, message, signature, publicKey)
|
||||
|
||||
@@ -9,6 +9,7 @@ import addressEncode from '../address/encode';
|
||||
const publicKey = new Uint8Array(32);
|
||||
const address = addressEncode(publicKey);
|
||||
const meta = {
|
||||
isTesting: true,
|
||||
name: 'nobody'
|
||||
};
|
||||
const json: KeyringPair$Json = {
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { KeyringPair$Json, KeyringPair$Meta, KeyringPairType } from '../types';
|
||||
import { KeypairType } from '@polkadot/util-crypto/types';
|
||||
import { KeyringPair$Json, KeyringPair$Meta } from '../types';
|
||||
|
||||
import { u8aToHex } from '@polkadot/util/index';
|
||||
|
||||
@@ -12,7 +13,7 @@ type PairStateJson = KeyringPair$Meta & {
|
||||
publicKey: Uint8Array
|
||||
};
|
||||
|
||||
export default function toJson (type: KeyringPairType, { publicKey, meta }: PairStateJson, encoded: Uint8Array, isEncrypted: boolean): KeyringPair$Json {
|
||||
export default function toJson (type: KeypairType, { publicKey, meta }: PairStateJson, encoded: Uint8Array, isEncrypted: boolean): KeyringPair$Json {
|
||||
return {
|
||||
address: encodeAddress(publicKey),
|
||||
encoded: u8aToHex(encoded),
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
// Copyright 2017-2019 @polkadot/keyring authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
// From https://github.com/paritytech/substrate/wiki/Secret-URI-Test-Vectors
|
||||
|
||||
import { u8aToHex } from '@polkadot/util/index';
|
||||
import { cryptoWaitReady } from '@polkadot/util-crypto/index';
|
||||
|
||||
import Keyring from './index';
|
||||
|
||||
const PHRASE = 'bottom drive obey lake curtain smoke basket hold race lonely fit walk';
|
||||
|
||||
const TESTS = [
|
||||
{
|
||||
pk: '0x46ebddef8cd9bb167dc30878d7113b7e168e6f0646beffd77d69d39bad76b47a',
|
||||
ss: '5DfhGyQdFobKM8NsWvEeAKk5EQQgYe9AydgJ7rMB6E1EqAS7',
|
||||
uri: PHRASE
|
||||
},
|
||||
{
|
||||
pk: '0xb69355deefa7a8f33e9297f5af22e680f03597a99d4f4b1c44be47e7a2275802',
|
||||
ss: '5GC6LfpV352HtJPySfAecb5JdePtf4R9Vq49NUU8RhzgBq1z',
|
||||
uri: `${PHRASE}///password`
|
||||
},
|
||||
{
|
||||
pk: '0x40b9675df90efa6069ff623b0fdfcf706cd47ca7452a5056c7ad58194d23440a',
|
||||
ss: '5DXZzrDxHbkQov4QBAY4TjpwnHCMrKXkomTnKSw8UArBESDT',
|
||||
uri: `${PHRASE}/foo`
|
||||
},
|
||||
{
|
||||
pk: '0x545ecfd16d2ccbece3c3d8e284ba21b624d53a010d19673285a02aca92a62724',
|
||||
ss: '5DyL3XpLxWKJgeUYkFFhepm9DWFMHjvW6JKyVst6F6bX1DQw',
|
||||
uri: `${PHRASE}//foo`
|
||||
},
|
||||
{
|
||||
pk: '0xc6755aae1c6a172dc06a8bcf46d119a56ec04b22d7c673255dfc6fb5d7afd250',
|
||||
ss: '5GYvCYSJxHTNRMqtkLX5AGpTYjSiaHeCdVgBQJWp6Jb1eWZR',
|
||||
uri: `${PHRASE}//foo/bar`
|
||||
},
|
||||
{
|
||||
pk: '0xbed7420abfb5398eaa5c1e5ce484bf200c735ee0606ed97048dae9a6e7b1aa59',
|
||||
ss: '5GNvuAdKoC5mHzmSSctsZAC4WkrhZC5W7FBB4G3N5XMCBhMD',
|
||||
uri: `${PHRASE}/foo//bar`
|
||||
},
|
||||
{
|
||||
pk: '0xd0c0cb1e54a54222058552d7bf94a8abaaafd778adae57a30a9bba5afb01f17a',
|
||||
ss: '5GnR66wpdL4hnArhDRyyBCqchgVYXVMQDDSZQWegfSSnAEFh',
|
||||
uri: `${PHRASE}//foo/bar//42/69`
|
||||
},
|
||||
{
|
||||
pk: '0x12dccbb4d851a7bc36bb4f5f6f84a1caaf04c542509b1e3b84f1f47445c1bf08',
|
||||
ss: '5CVSJt82L8jYodrwYKCoP6LtC6V2VYPHYMHtHzjhdNr1KDdu',
|
||||
uri: `${PHRASE}//foo/bar//42/69///password`
|
||||
}
|
||||
];
|
||||
|
||||
// TODO Enable once we have proper schnorrkel support
|
||||
describe.skip('keyring.addFromUri', () => {
|
||||
let keyring: Keyring;
|
||||
|
||||
beforeEach(async () => {
|
||||
keyring = new Keyring({ type: 'sr25519' });
|
||||
|
||||
await cryptoWaitReady();
|
||||
});
|
||||
|
||||
TESTS.forEach(({ pk, ss, uri }) => {
|
||||
it(`creates ${uri}`, () => {
|
||||
const pair = keyring.addFromUri(uri);
|
||||
|
||||
expect(u8aToHex(pair.publicKey())).toEqual(pk);
|
||||
expect(pair.address()).toEqual(ss);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -4,33 +4,10 @@
|
||||
|
||||
import { KeyringInstance, KeyringOptions } from './types';
|
||||
|
||||
import { stringToU8a } from '@polkadot/util/index';
|
||||
|
||||
import Keyring from './index';
|
||||
|
||||
function padSeed (seed: string): Uint8Array {
|
||||
return stringToU8a(seed.padEnd(32));
|
||||
}
|
||||
|
||||
const SEEDS: { [index: string ]: Uint8Array } = {
|
||||
alice:
|
||||
padSeed('Alice'),
|
||||
bob:
|
||||
padSeed('Bob'),
|
||||
charlie:
|
||||
padSeed('Charlie'),
|
||||
dave:
|
||||
padSeed('Dave'),
|
||||
eve:
|
||||
padSeed('Eve'),
|
||||
ferdie:
|
||||
padSeed('Ferdie')
|
||||
// NOTE These were originally part of tests, don't remove completely (yet), first check impact
|
||||
// one:
|
||||
// padSeed('12345678901234567890123456789012'),
|
||||
// two:
|
||||
// hexToU8a('0x9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60')
|
||||
};
|
||||
const DEV_PHRASE = 'bottom drive obey lake curtain smoke basket hold race lonely fit walk';
|
||||
const SEEDS = ['Alice', 'Bob', 'Charlie', 'Dave', 'Eve', 'Ferdie'];
|
||||
|
||||
/**
|
||||
* @name testKeyring
|
||||
@@ -38,21 +15,22 @@ const SEEDS: { [index: string ]: Uint8Array } = {
|
||||
* @description The test accounts (i.e. alice, bob, dave, eve, ferdie)
|
||||
* are available on the dev chain and each test account is initialised with DOT funds.
|
||||
*/
|
||||
export default function testKeyring (options?: KeyringOptions): KeyringInstance {
|
||||
export default function testKeyring (options?: KeyringOptions, isHdKd: boolean = false): KeyringInstance {
|
||||
const keyring = new Keyring(options);
|
||||
|
||||
Object
|
||||
.keys(SEEDS)
|
||||
.forEach((name) => {
|
||||
const pair = keyring.addFromSeed(SEEDS[name], {
|
||||
isTesting: true,
|
||||
name
|
||||
});
|
||||
|
||||
pair.lock = () => {
|
||||
// we don't have lock/unlock functionality here
|
||||
};
|
||||
SEEDS.forEach((entry) => {
|
||||
const phrase = isHdKd
|
||||
? `${DEV_PHRASE}//${entry}`
|
||||
: entry;
|
||||
const pair = keyring.addFromUri(phrase, {
|
||||
isTesting: true,
|
||||
name: entry.toLowerCase()
|
||||
});
|
||||
|
||||
pair.lock = () => {
|
||||
// we don't have lock/unlock functionality here
|
||||
};
|
||||
});
|
||||
|
||||
return keyring;
|
||||
}
|
||||
|
||||
@@ -2,10 +2,26 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import testingPairs from './testingPairs';
|
||||
|
||||
describe('testing', () => {
|
||||
it('creates without failing', () => {
|
||||
expect(
|
||||
require('./testingPairs')
|
||||
).toBeDefined();
|
||||
Object.keys(testingPairs())
|
||||
).toHaveLength(1 + 6);
|
||||
});
|
||||
|
||||
describe('ed25519', () => {
|
||||
it('has the correct address for Alice (non-HDKD)', () => {
|
||||
expect(
|
||||
testingPairs({ type: 'ed25519' }, false).alice.address()
|
||||
).toEqual('5GoKvZWG5ZPYL1WUovuHW3zJBWBP5eT8CbqjdRY4Q6iMaDtZ');
|
||||
});
|
||||
|
||||
it('has the correct address for Alice (HDKD)', () => {
|
||||
expect(
|
||||
testingPairs({ type: 'ed25519' }, true).alice.address()
|
||||
).toEqual('5FA9nQDVg267DEd8m1ZypXLBnvN7SFxYwV7ndqSYGiN9TmTd');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -11,16 +11,15 @@ type TestKeyringMap = {
|
||||
[index: string]: KeyringPair
|
||||
};
|
||||
|
||||
export default function testKeyringPairs (options?: KeyringOptions): TestKeyringMap {
|
||||
const keyring = createKeyring(options);
|
||||
export default function testKeyringPairs (options?: KeyringOptions, isHdKd: boolean = false): TestKeyringMap {
|
||||
const keyring = createKeyring(options, isHdKd);
|
||||
const pairs = keyring.getPairs();
|
||||
|
||||
return pairs.reduce((result, pair) => {
|
||||
const { name } = pair.getMeta();
|
||||
|
||||
// @ts-ignore dunno what the complaint here is about...
|
||||
result[name as string] = pair;
|
||||
|
||||
return result;
|
||||
}, { 'nobody': nobody() });
|
||||
}, { 'nobody': nobody() } as TestKeyringMap);
|
||||
}
|
||||
|
||||
@@ -2,13 +2,12 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { KeypairType } from '@polkadot/util-crypto/types';
|
||||
import { Prefix } from './address/types';
|
||||
|
||||
export type KeyringPairType = 'ed25519' | 'sr25519';
|
||||
|
||||
export type KeyringOptions = {
|
||||
addressPrefix?: Prefix,
|
||||
type?: KeyringPairType
|
||||
type?: KeypairType
|
||||
};
|
||||
|
||||
export type KeyringPair$Meta = {
|
||||
@@ -18,7 +17,7 @@ export type KeyringPair$Meta = {
|
||||
export type KeyringPair$JsonVersion = '0' | '1';
|
||||
|
||||
export type KeyringPair$JsonEncoding = {
|
||||
content: ['pkcs8', KeyringPairType],
|
||||
content: ['pkcs8', KeypairType],
|
||||
type: 'xsalsa20-poly1305' | 'none',
|
||||
version: KeyringPair$JsonVersion
|
||||
};
|
||||
@@ -31,7 +30,7 @@ export type KeyringPair$Json = {
|
||||
};
|
||||
|
||||
export interface KeyringPair {
|
||||
readonly type: KeyringPairType;
|
||||
readonly type: KeypairType;
|
||||
|
||||
address: () => string;
|
||||
decodePkcs8: (passphrase?: string, encoded?: Uint8Array) => void;
|
||||
@@ -43,7 +42,7 @@ export interface KeyringPair {
|
||||
setMeta: (meta: KeyringPair$Meta) => void;
|
||||
sign (message: Uint8Array): Uint8Array;
|
||||
toJson (passphrase?: string): KeyringPair$Json;
|
||||
toType (type: KeyringPairType): KeyringPair;
|
||||
toType (type: KeypairType): KeyringPair;
|
||||
verify (message: Uint8Array, signature: Uint8Array): boolean;
|
||||
}
|
||||
|
||||
@@ -55,19 +54,22 @@ export interface KeyringPairs {
|
||||
}
|
||||
|
||||
export interface KeyringInstance {
|
||||
readonly isEd25519: boolean;
|
||||
readonly isSr25519: boolean;
|
||||
readonly pairs: Array<KeyringPair>;
|
||||
readonly publicKeys: Array<Uint8Array>;
|
||||
readonly type: KeyringPairType;
|
||||
readonly type: KeypairType;
|
||||
|
||||
decodeAddress (encoded: string | Uint8Array): Uint8Array;
|
||||
encodeAddress (key: Uint8Array | string): string;
|
||||
setAddressPrefix (prefix: Prefix): void;
|
||||
|
||||
addPair (pair: KeyringPair): KeyringPair;
|
||||
addFromAddress (address: string | Uint8Array, meta?: KeyringPair$Meta, encoded?: Uint8Array | null, type?: KeyringPairType): KeyringPair;
|
||||
addFromMnemonic (mnemonic: string, meta?: KeyringPair$Meta, type?: KeyringPairType): KeyringPair;
|
||||
addFromSeed (seed: Uint8Array, meta?: KeyringPair$Meta, type?: KeyringPairType): KeyringPair;
|
||||
addFromAddress (address: string | Uint8Array, meta?: KeyringPair$Meta, encoded?: Uint8Array | null, type?: KeypairType): KeyringPair;
|
||||
addFromJson (pair: KeyringPair$Json): KeyringPair;
|
||||
addFromMnemonic (mnemonic: string, meta?: KeyringPair$Meta, type?: KeypairType): KeyringPair;
|
||||
addFromSeed (seed: Uint8Array, meta?: KeyringPair$Meta, type?: KeypairType): KeyringPair;
|
||||
addFromUri (suri: string, meta?: KeyringPair$Meta, type?: KeypairType): KeyringPair;
|
||||
getPair (address: string | Uint8Array): KeyringPair;
|
||||
getPairs (): Array<KeyringPair>;
|
||||
getPublicKeys (): Array<Uint8Array>;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@polkadot/trie-codec",
|
||||
"version": "0.35.10",
|
||||
"version": "0.36.0",
|
||||
"description": "This is an implementation of the codec for Substrate Trie",
|
||||
"main": "index.js",
|
||||
"keywords": [
|
||||
@@ -29,6 +29,6 @@
|
||||
"homepage": "https://github.com/polkadot-js/common/tree/master/packages/trie-codec#readme",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.3.4",
|
||||
"@polkadot/util": "^0.35.10"
|
||||
"@polkadot/util": "^0.36.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@polkadot/trie-db",
|
||||
"version": "0.35.10",
|
||||
"version": "0.36.0",
|
||||
"description": "This is an implementation of the modified merkle patricia tree as specified in Ethereum's yellow paper, adapted for Polkadot",
|
||||
"main": "index.js",
|
||||
"keywords": [
|
||||
@@ -29,15 +29,15 @@
|
||||
"homepage": "https://github.com/polkadot-js/common/tree/master/packages/trie-db#readme",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.3.4",
|
||||
"@polkadot/db": "^0.35.10",
|
||||
"@polkadot/trie-codec": "^0.35.10",
|
||||
"@polkadot/trie-hash": "^0.35.10",
|
||||
"@polkadot/util": "^0.35.10",
|
||||
"@polkadot/util-crypto": "^0.35.10"
|
||||
"@polkadot/db": "^0.36.0",
|
||||
"@polkadot/trie-codec": "^0.36.0",
|
||||
"@polkadot/trie-hash": "^0.36.0",
|
||||
"@polkadot/util": "^0.36.0",
|
||||
"@polkadot/util-crypto": "^0.36.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@polkadot/chainspec": "^0.35.10",
|
||||
"@polkadot/util-rlp": "^0.35.10",
|
||||
"@polkadot/chainspec": "^0.36.0",
|
||||
"@polkadot/util-rlp": "^0.36.0",
|
||||
"ethereumjs-testing": "1.0.4"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@polkadot/trie-hash",
|
||||
"version": "0.35.10",
|
||||
"version": "0.36.0",
|
||||
"description": "Generates trie roots from key-value pairs",
|
||||
"main": "index.js",
|
||||
"keywords": [
|
||||
@@ -29,9 +29,9 @@
|
||||
"homepage": "https://github.com/polkadot-js/common/tree/master/packages/trie-hash#readme",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.3.4",
|
||||
"@polkadot/util": "^0.35.10"
|
||||
"@polkadot/util": "^0.36.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@polkadot/chainspec": "^0.35.10"
|
||||
"@polkadot/chainspec": "^0.36.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@polkadot/util-crypto",
|
||||
"version": "0.35.10",
|
||||
"version": "0.36.0",
|
||||
"description": "A collection of useful crypto utilities for @polkadot",
|
||||
"main": "index.js",
|
||||
"keywords": [
|
||||
@@ -30,7 +30,7 @@
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.3.4",
|
||||
"@polkadot/schnorrkel-js": "^0.1.2-3",
|
||||
"@polkadot/util": "^0.35.10",
|
||||
"@polkadot/util": "^0.36.0",
|
||||
"@types/bip39": "^2.4.2",
|
||||
"@types/pbkdf2": "^3.0.0",
|
||||
"@types/secp256k1": "^3.5.0",
|
||||
|
||||
@@ -6,6 +6,7 @@ import { schnorrkelWaitReady } from './schnorrkel';
|
||||
|
||||
export * from './blake2';
|
||||
export * from './keccak';
|
||||
export * from './key';
|
||||
export * from './mnemonic';
|
||||
export * from './nacl';
|
||||
export * from './random';
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
// Copyright 2017-2019 @polkadot/util-crypto authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import BN from 'bn.js';
|
||||
import { bnToHex, compactAddLength, hexToU8a, isBn, isHex, isNumber, isString, stringToU8a } from '@polkadot/util/index';
|
||||
|
||||
import blake2AsU8a from '../blake2/asU8a';
|
||||
|
||||
const RE_NUMBER = /^\d+$/;
|
||||
|
||||
const JUNCTION_ID_LEN: number = 32;
|
||||
const BN_OPTIONS = {
|
||||
bitLength: 256,
|
||||
isLe: true
|
||||
};
|
||||
|
||||
export default class DeriveJunction {
|
||||
private _chainCode: Uint8Array = new Uint8Array(32);
|
||||
private _isHard: boolean = false;
|
||||
|
||||
static from (value: string): DeriveJunction {
|
||||
const [code, isHard] = value[0] === '/'
|
||||
? [value.substr(1), true]
|
||||
: [value, false];
|
||||
const result = new DeriveJunction();
|
||||
|
||||
result.soft(
|
||||
RE_NUMBER.test(code)
|
||||
? parseInt(code, 10)
|
||||
: code
|
||||
);
|
||||
|
||||
return isHard
|
||||
? result.harden()
|
||||
: result;
|
||||
}
|
||||
|
||||
get chainCode (): Uint8Array {
|
||||
return this._chainCode;
|
||||
}
|
||||
|
||||
get isHard (): boolean {
|
||||
return this._isHard;
|
||||
}
|
||||
|
||||
get isSoft (): boolean {
|
||||
return !this._isHard;
|
||||
}
|
||||
|
||||
hard (value: number | BN | string | Uint8Array): DeriveJunction {
|
||||
return this.soft(value).harden();
|
||||
}
|
||||
|
||||
harden (): DeriveJunction {
|
||||
this._isHard = true;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
soft (value: number | BN | string | Uint8Array): DeriveJunction {
|
||||
if (isNumber(value) || isBn(value)) {
|
||||
return this.soft(bnToHex(value, BN_OPTIONS));
|
||||
} else if (isString(value)) {
|
||||
return isHex(value)
|
||||
? this.soft(hexToU8a(value))
|
||||
: this.soft(compactAddLength(stringToU8a(value)));
|
||||
}
|
||||
|
||||
if (value.length > JUNCTION_ID_LEN) {
|
||||
return this.soft(blake2AsU8a(value));
|
||||
}
|
||||
|
||||
this._chainCode.fill(0);
|
||||
this._chainCode.set(value, 0);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
soften (): DeriveJunction {
|
||||
this._isHard = false;
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
// Copyright 2017-2019 @polkadot/util-crypto authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import keyExtract from './extract';
|
||||
|
||||
describe('keyExtract', () => {
|
||||
it('derives on "hello world"', () => {
|
||||
expect(
|
||||
keyExtract('hello world')
|
||||
).toEqual({
|
||||
path: [],
|
||||
phrase: 'hello world'
|
||||
});
|
||||
});
|
||||
|
||||
it('derives on "hello world/1', () => {
|
||||
expect(
|
||||
keyExtract('hello world/1')
|
||||
).toEqual({
|
||||
path: [
|
||||
{ _isHard: false, _chainCode: Uint8Array.from([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) }
|
||||
],
|
||||
phrase: 'hello world'
|
||||
});
|
||||
});
|
||||
|
||||
it('derives on "hello world/DOT', () => {
|
||||
expect(
|
||||
keyExtract('hello world/DOT')
|
||||
).toEqual({
|
||||
path: [
|
||||
{ _isHard: false, _chainCode: Uint8Array.from([12, 68, 79, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) }
|
||||
],
|
||||
phrase: 'hello world'
|
||||
});
|
||||
});
|
||||
|
||||
it('derives on "hello world//1', () => {
|
||||
expect(
|
||||
keyExtract('hello world//1')
|
||||
).toEqual({
|
||||
path: [
|
||||
{ _isHard: true, _chainCode: Uint8Array.from([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) }
|
||||
],
|
||||
phrase: 'hello world'
|
||||
});
|
||||
});
|
||||
|
||||
it('derives on "hello world//DOT', () => {
|
||||
expect(
|
||||
keyExtract('hello world//DOT')
|
||||
).toEqual({
|
||||
path: [
|
||||
{ _isHard: true, _chainCode: Uint8Array.from([12, 68, 79, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) }
|
||||
],
|
||||
phrase: 'hello world'
|
||||
});
|
||||
});
|
||||
|
||||
it('derives on "hello world//1/DOT', () => {
|
||||
expect(
|
||||
keyExtract('hello world//1/DOT')
|
||||
).toEqual({
|
||||
path: [
|
||||
{ _isHard: true, _chainCode: Uint8Array.from([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) },
|
||||
{ _isHard: false, _chainCode: Uint8Array.from([12, 68, 79, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) }
|
||||
],
|
||||
phrase: 'hello world'
|
||||
});
|
||||
});
|
||||
|
||||
it('derives on "hello world//DOT/1', () => {
|
||||
expect(
|
||||
keyExtract('hello world//DOT/1')
|
||||
).toEqual({
|
||||
path: [
|
||||
{ _isHard: true, _chainCode: Uint8Array.from([12, 68, 79, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) },
|
||||
{ _isHard: false, _chainCode: Uint8Array.from([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) }
|
||||
],
|
||||
phrase: 'hello world'
|
||||
});
|
||||
});
|
||||
|
||||
it('derives on "hello world///password"', () => {
|
||||
expect(
|
||||
keyExtract('hello world///password')
|
||||
).toEqual({
|
||||
password: 'password',
|
||||
path: [],
|
||||
phrase: 'hello world'
|
||||
});
|
||||
});
|
||||
|
||||
it('derives on "hello world//1/DOT///password"', () => {
|
||||
expect(
|
||||
keyExtract('hello world//1/DOT///password')
|
||||
).toEqual({
|
||||
path: [
|
||||
{ _isHard: true, _chainCode: Uint8Array.from([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) },
|
||||
{ _isHard: false, _chainCode: Uint8Array.from([12, 68, 79, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) }
|
||||
],
|
||||
password: 'password',
|
||||
phrase: 'hello world'
|
||||
});
|
||||
});
|
||||
|
||||
it('derives on "hello world/1//DOT///password"', () => {
|
||||
expect(
|
||||
keyExtract('hello world/1//DOT///password')
|
||||
).toEqual({
|
||||
path: [
|
||||
{ _isHard: false, _chainCode: Uint8Array.from([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) },
|
||||
{ _isHard: true, _chainCode: Uint8Array.from([12, 68, 79, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) }
|
||||
],
|
||||
password: 'password',
|
||||
phrase: 'hello world'
|
||||
});
|
||||
});
|
||||
|
||||
it('derives on actual Alice', () => {
|
||||
expect(
|
||||
keyExtract('bottom drive obey lake curtain smoke basket hold race lonely fit walk//Alice')
|
||||
).toEqual({
|
||||
path: [
|
||||
{ _isHard: true, _chainCode: Uint8Array.from([20, 65, 108, 105, 99, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) }
|
||||
],
|
||||
phrase: 'bottom drive obey lake curtain smoke basket hold race lonely fit walk'
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,41 @@
|
||||
// Copyright 2017-2019 @polkadot/util-crypto authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { assert, isNull } from '@polkadot/util/index';
|
||||
|
||||
import DeriveJunction from './DeriveJunction';
|
||||
|
||||
type DeriveResult = {
|
||||
password?: string,
|
||||
path: Array<DeriveJunction>,
|
||||
phrase: string
|
||||
};
|
||||
|
||||
const RE_CAPTURE = /^(\w+( \w+)*)((\/\/?[^\/]+)*)(\/\/\/(.*))?$/;
|
||||
const RE_JUNCTION = /\/(\/?)([^\/]+)/g;
|
||||
|
||||
/**
|
||||
* @description Extracts the phrase, path and password from a SURI format for specifying secret keys `<secret>/<soft-key>//<hard-key>///<password>` (the `///password` may be omitted, and `/<soft-key>` and `//<hard-key>` maybe repeated and mixed).
|
||||
*/
|
||||
export default function keyExtract (suri: string): DeriveResult {
|
||||
const matches = suri.match(RE_CAPTURE);
|
||||
|
||||
assert(!isNull(matches), `Unable to match '${suri}' to a secret URI`);
|
||||
|
||||
const [, phrase, , junctions, , , password] = matches as Array<any>;
|
||||
const parts = junctions.match(RE_JUNCTION);
|
||||
const path: Array<DeriveJunction> = [];
|
||||
|
||||
if (parts) {
|
||||
parts.forEach((value: string) => {
|
||||
path.push(DeriveJunction.from(value.substr(1)));
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
password,
|
||||
path,
|
||||
phrase
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
// Copyright 2017-2019 @polkadot/util-crypto authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { KeypairType } from '../types';
|
||||
|
||||
import DeriveJunction from './DeriveJunction';
|
||||
import keyHdkdEd15519 from './hdkdEd25519';
|
||||
import keyHdkdSr15519 from './hdkdSr25519';
|
||||
|
||||
export default function keyFromPath (seed: Uint8Array, path: Array<DeriveJunction>, type: KeypairType): Uint8Array {
|
||||
return path.reduce((seed, junction) => {
|
||||
return type === 'ed25519'
|
||||
? keyHdkdEd15519(seed, junction)
|
||||
: keyHdkdSr15519(seed, junction);
|
||||
}, seed);
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
// Copyright 2017-2019 @polkadot/util-crypto authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { assert, compactAddLength, stringToU8a, u8aConcat } from '@polkadot/util/index';
|
||||
|
||||
import blake2AsU8a from '../blake2/asU8a';
|
||||
import DeriveJunction from './DeriveJunction';
|
||||
|
||||
const HDKD = compactAddLength(stringToU8a('Ed25519HDKD'));
|
||||
|
||||
export default function keyHdkdEd25519 (seed: Uint8Array, { chainCode, isHard }: DeriveJunction): Uint8Array {
|
||||
assert(isHard, 'A soft key was found in the path (and is unsupported)');
|
||||
|
||||
return blake2AsU8a(
|
||||
u8aConcat(HDKD, seed, chainCode)
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
// Copyright 2017-2019 @polkadot/util-crypto authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { stringToU8a, u8aConcat } from '@polkadot/util/index';
|
||||
|
||||
import blake2AsU8a from '../blake2/asU8a';
|
||||
import DeriveJunction from './DeriveJunction';
|
||||
|
||||
const HDKD = stringToU8a('SchnorrRistrettoHDKD');
|
||||
|
||||
// FIXME This should pull in from schnorrkel and do the magic there
|
||||
export default function keyHdkdSr25519 (seed: Uint8Array, { chainCode }: DeriveJunction): Uint8Array {
|
||||
return blake2AsU8a(
|
||||
u8aConcat(HDKD, seed, chainCode)
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
// Copyright 2017-2019 @polkadot/util-crypto authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
/**
|
||||
* @summary Create keys from paths, seeds and password
|
||||
*/
|
||||
export { default as keyExtract } from './extract';
|
||||
export { default as keyFromPath } from './fromPath';
|
||||
export { default as keyHdkdEd25519 } from './hdkdEd25519';
|
||||
export { default as keyHdkdSr25519 } from './hdkdEd25519';
|
||||
@@ -2,12 +2,12 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { KeypairType } from '../../types';
|
||||
import { Keypair } from '../../types';
|
||||
|
||||
import { naclKeypairFromRandom } from '../index';
|
||||
|
||||
describe('naclKeypairFromRandom', () => {
|
||||
let keypair: KeypairType;
|
||||
let keypair: Keypair;
|
||||
|
||||
beforeEach(() => {
|
||||
keypair = naclKeypairFromRandom();
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { KeypairType } from '../../types';
|
||||
import { Keypair } from '../../types';
|
||||
|
||||
import nacl from 'tweetnacl';
|
||||
|
||||
@@ -20,6 +20,6 @@ import nacl from 'tweetnacl';
|
||||
* naclKeypairFromRandom(); // => { secretKey: [...], publicKey: [...] }
|
||||
* ```
|
||||
*/
|
||||
export default function naclKeypairFromRandom (): KeypairType {
|
||||
export default function naclKeypairFromRandom (): Keypair {
|
||||
return nacl.sign.keyPair();
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { KeypairType } from '../../types';
|
||||
import { Keypair } from '../../types';
|
||||
|
||||
import nacl from 'tweetnacl';
|
||||
|
||||
@@ -20,6 +20,6 @@ import nacl from 'tweetnacl';
|
||||
* naclKeypairFromSecret(...); // => { secretKey: [...], publicKey: [...] }
|
||||
* ```
|
||||
*/
|
||||
export default function naclKeypairFromSecret (secret: Uint8Array): KeypairType {
|
||||
export default function naclKeypairFromSecret (secret: Uint8Array): Keypair {
|
||||
return nacl.sign.keyPair.fromSecretKey(secret);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { KeypairType } from '../../types';
|
||||
import { Keypair } from '../../types';
|
||||
|
||||
import nacl from 'tweetnacl';
|
||||
|
||||
@@ -20,6 +20,6 @@ import nacl from 'tweetnacl';
|
||||
* naclKeypairFromSeed(...); // => { secretKey: [...], publicKey: [...] }
|
||||
* ```
|
||||
*/
|
||||
export default function naclKeypairFromSeed (seed: Uint8Array): KeypairType {
|
||||
export default function naclKeypairFromSeed (seed: Uint8Array): Keypair {
|
||||
return nacl.sign.keyPair.fromSeed(seed);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { KeypairType } from '../../types';
|
||||
import { Keypair } from '../../types';
|
||||
|
||||
import { stringToU8a } from '@polkadot/util/index';
|
||||
|
||||
@@ -23,7 +23,7 @@ import fromSeed from './fromSeed';
|
||||
* naclKeypairFromString('test'); // => { secretKey: [...], publicKey: [...] }
|
||||
* ```
|
||||
*/
|
||||
export default function naclKeypairFromString (value: string): KeypairType {
|
||||
export default function naclKeypairFromString (value: string): Keypair {
|
||||
return fromSeed(
|
||||
blake2AsU8a(
|
||||
stringToU8a(value),
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { KeypairType } from '../types';
|
||||
import { Keypair } from '../types';
|
||||
|
||||
import nacl from 'tweetnacl';
|
||||
import { assert } from '@polkadot/util/index';
|
||||
@@ -21,7 +21,7 @@ import { assert } from '@polkadot/util/index';
|
||||
* naclSign([...], [...]); // => [...]
|
||||
* ```
|
||||
*/
|
||||
export default function naclSign (message: Uint8Array, { secretKey }: Partial<KeypairType>): Uint8Array {
|
||||
export default function naclSign (message: Uint8Array, { secretKey }: Partial<Keypair>): Uint8Array {
|
||||
assert(secretKey && secretKey.length === 64, 'Expected valid secretKey, 64 bytes');
|
||||
|
||||
return nacl.sign.detached(message, secretKey as Uint8Array);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { KeypairType } from '../../types';
|
||||
import { Keypair } from '../../types';
|
||||
|
||||
import schnorrkel from '@polkadot/schnorrkel-js';
|
||||
|
||||
@@ -13,7 +13,7 @@ const PUB_LEN = 32;
|
||||
* @name schnorrkelKeypairFromSeed
|
||||
* @description Returns a object containing a `publicKey` & `secretKey` generated from the supplied seed.
|
||||
*/
|
||||
export default function schnorrkelKeypairFromSeed (seed: Uint8Array): KeypairType {
|
||||
export default function schnorrkelKeypairFromSeed (seed: Uint8Array): Keypair {
|
||||
const full = schnorrkel.keypair_from_seed(seed);
|
||||
|
||||
return {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { KeypairType } from '../types';
|
||||
import { Keypair } from '../types';
|
||||
|
||||
import { assert } from '@polkadot/util/index';
|
||||
|
||||
@@ -12,7 +12,7 @@ import schnorrkel from '@polkadot/schnorrkel-js';
|
||||
* @name schnorrkelSign
|
||||
* @description Returns message signature of `message`, using the supplied pair
|
||||
*/
|
||||
export default function schnorrkelSign (message: Uint8Array, { publicKey, secretKey }: Partial<KeypairType>): Uint8Array {
|
||||
export default function schnorrkelSign (message: Uint8Array, { publicKey, secretKey }: Partial<Keypair>): Uint8Array {
|
||||
assert(publicKey && publicKey.length === 32, 'Expected valid publicKey, 32-bytes');
|
||||
assert(secretKey && secretKey.length === 64, 'Expected valid secretKey, 64-bytes');
|
||||
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
export type KeypairType = {
|
||||
export type Keypair = {
|
||||
publicKey: Uint8Array;
|
||||
secretKey: Uint8Array;
|
||||
};
|
||||
|
||||
export type KeypairType = 'ed25519' | 'sr25519';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@polkadot/util-rlp",
|
||||
"version": "0.35.10",
|
||||
"version": "0.36.0",
|
||||
"description": "RLP encoding and decoding",
|
||||
"main": "index.js",
|
||||
"keywords": [
|
||||
@@ -31,7 +31,7 @@
|
||||
"homepage": "https://github.com/polkadot-js/common/tree/master/packages/util-rlp#readme",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.3.4",
|
||||
"@polkadot/util": "^0.35.10"
|
||||
"@polkadot/util": "^0.36.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"ethereumjs-testing": "1.0.4"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@polkadot/util",
|
||||
"version": "0.35.10",
|
||||
"version": "0.36.0",
|
||||
"description": "A collection of useful utilities for @polkadot",
|
||||
"main": "index.js",
|
||||
"keywords": [
|
||||
|
||||
Reference in New Issue
Block a user