Add @polkadot/util-keyring (#99)
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
// Copyright 2017-2018 Jaco Greeff
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the ISC license. See the LICENSE file for details.
|
||||
// @flow
|
||||
|
||||
import type { KeyringInstance, KeyringPair } from './types';
|
||||
|
||||
type KeyringPairMap = {
|
||||
[string]: KeyringPair
|
||||
};
|
||||
|
||||
const naclKeypairFromSeed = require('@polkadot/util-crypto/nacl/keypair/fromSeed');
|
||||
const u8aToString = require('@polkadot/util/u8a/toString');
|
||||
|
||||
const createPair = require('./pair');
|
||||
|
||||
module.exports = function keyring (): KeyringInstance {
|
||||
const pairs: KeyringPairMap = {};
|
||||
const getPairs = (): Array<KeyringPair> =>
|
||||
// flowlint-next-line unclear-type:off
|
||||
((Object.values(pairs): any): Array<KeyringPair>);
|
||||
|
||||
return {
|
||||
addFromSeed: (seed: Uint8Array | string): KeyringPair => {
|
||||
const pair = createPair(naclKeypairFromSeed(seed));
|
||||
|
||||
pairs[pair.id] = pair;
|
||||
|
||||
return pair;
|
||||
},
|
||||
getPair: (publicKey: Uint8Array): ?KeyringPair =>
|
||||
pairs[u8aToString(publicKey)],
|
||||
getPairs,
|
||||
getPublicKeys: (): Array<Uint8Array> =>
|
||||
getPairs().map(({ publicKey }) => publicKey)
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,43 @@
|
||||
// Copyright 2017-2018 Jaco Greeff
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the ISC license. See the LICENSE file for details.
|
||||
|
||||
const index = require('./index');
|
||||
|
||||
describe('keypair', () => {
|
||||
const publicKeyOne = new Uint8Array([47, 140, 97, 41, 216, 22, 207, 81, 195, 116, 188, 127, 8, 195, 230, 62, 209, 86, 207, 120, 174, 251, 74, 101, 80, 217, 123, 135, 153, 121, 119, 238]);
|
||||
const publicKeyTwo = new Uint8Array([215, 90, 152, 1, 130, 177, 10, 183, 213, 75, 254, 211, 201, 100, 7, 58, 14, 225, 114, 243, 218, 166, 35, 37, 175, 2, 26, 104, 247, 7, 81, 26]);
|
||||
const seedOne = '12345678901234567890123456789012';
|
||||
const seedTwo = '0x9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60';
|
||||
let keypair;
|
||||
|
||||
beforeEach(() => {
|
||||
keypair = index();
|
||||
|
||||
keypair.addFromSeed(seedOne);
|
||||
});
|
||||
|
||||
it('adds the pair', () => {
|
||||
expect(
|
||||
keypair.addFromSeed(seedTwo)
|
||||
).toMatchObject({
|
||||
publicKey: publicKeyTwo
|
||||
});
|
||||
});
|
||||
|
||||
it('allows publicKeys retrieval', () => {
|
||||
keypair.addFromSeed(seedTwo);
|
||||
|
||||
expect(
|
||||
keypair.getPublicKeys()
|
||||
).toEqual([ publicKeyOne, publicKeyTwo ]);
|
||||
});
|
||||
|
||||
it('allows retrieval of a specific item', () => {
|
||||
expect(
|
||||
keypair.getPair(publicKeyOne)
|
||||
).toMatchObject({
|
||||
publicKey: publicKeyOne
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,22 @@
|
||||
// Copyright 2017-2018 Jaco Greeff
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the ISC license. See the LICENSE file for details.
|
||||
// @flow
|
||||
|
||||
import type { KeypairType } from '@polkadot/util-crypto/types';
|
||||
import type { KeyringPair } from './types';
|
||||
|
||||
const naclSign = require('@polkadot/util-crypto/nacl/sign');
|
||||
const naclVerify = require('@polkadot/util-crypto/nacl/verify');
|
||||
const u8aToString = require('@polkadot/util/u8a/toString');
|
||||
|
||||
module.exports = function pair ({ publicKey, secretKey }: KeypairType): KeyringPair {
|
||||
return {
|
||||
id: u8aToString(publicKey),
|
||||
publicKey,
|
||||
sign: (message: Uint8Array): Uint8Array =>
|
||||
naclSign(message, secretKey),
|
||||
verify: (message: Uint8Array, signature: Uint8Array): boolean =>
|
||||
naclVerify(message, signature, publicKey)
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,44 @@
|
||||
// Copyright 2017-2018 Jaco Greeff
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the ISC license. See the LICENSE file for details.
|
||||
|
||||
const keyring = require('./testing')();
|
||||
|
||||
// aligned with @polkadot/util-crypto tests
|
||||
describe('pair', () => {
|
||||
const SIGNATURE = new Uint8Array([28, 58, 206, 239, 249, 70, 59, 191, 166, 40, 219, 218, 235, 170, 25, 79, 10, 94, 9, 197, 34, 126, 1, 150, 246, 68, 28, 238, 36, 26, 172, 163, 168, 90, 202, 211, 126, 246, 57, 212, 43, 24, 88, 197, 240, 113, 118, 76, 37, 81, 91, 110, 236, 50, 144, 134, 100, 223, 220, 238, 34, 185, 211, 7]);
|
||||
|
||||
it('has a publicKey', () => {
|
||||
expect(
|
||||
keyring.one.publicKey
|
||||
).toEqual(
|
||||
new Uint8Array([47, 140, 97, 41, 216, 22, 207, 81, 195, 116, 188, 127, 8, 195, 230, 62, 209, 86, 207, 120, 174, 251, 74, 101, 80, 217, 123, 135, 153, 121, 119, 238])
|
||||
);
|
||||
});
|
||||
|
||||
it('allows signing', () => {
|
||||
expect(
|
||||
keyring.one.sign(
|
||||
new Uint8Array([0x61, 0x62, 0x63, 0x64])
|
||||
)
|
||||
).toEqual(SIGNATURE);
|
||||
});
|
||||
|
||||
it('validates a correctly signed message', () => {
|
||||
expect(
|
||||
keyring.one.verify(
|
||||
new Uint8Array([0x61, 0x62, 0x63, 0x64]),
|
||||
SIGNATURE
|
||||
)
|
||||
).toEqual(true);
|
||||
});
|
||||
|
||||
it('fails a correctly signed message (message changed)', () => {
|
||||
expect(
|
||||
keyring.one.verify(
|
||||
new Uint8Array([0x61, 0x62, 0x63, 0x64, 0x65]),
|
||||
SIGNATURE
|
||||
)
|
||||
).toEqual(false);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,43 @@
|
||||
// Copyright 2017-2018 Jaco Greeff
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the ISC license. See the LICENSE file for details.
|
||||
// @flow
|
||||
|
||||
import type { KeyringPair } from './types';
|
||||
|
||||
type TestKeyring = {
|
||||
[string]: KeyringPair
|
||||
};
|
||||
|
||||
const createKeyring = require('./index');
|
||||
|
||||
const SEEDS = {
|
||||
alice:
|
||||
'Alice ',
|
||||
bob:
|
||||
'Bob ',
|
||||
charlie:
|
||||
'Charlie ',
|
||||
dave:
|
||||
'Dave ',
|
||||
eve:
|
||||
'Eve ',
|
||||
ferdie:
|
||||
'Ferdie ',
|
||||
one:
|
||||
'12345678901234567890123456789012',
|
||||
two:
|
||||
'0x9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60'
|
||||
};
|
||||
|
||||
module.exports = function testKeyring (): TestKeyring {
|
||||
const keyring = createKeyring();
|
||||
|
||||
return Object
|
||||
.keys(SEEDS)
|
||||
.reduce((result, key) => {
|
||||
result[key] = keyring.addFromSeed(SEEDS[key]);
|
||||
|
||||
return result;
|
||||
}, {});
|
||||
};
|
||||
@@ -0,0 +1,19 @@
|
||||
// Copyright 2017-2018 Jaco Greeff
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the ISC license. See the LICENSE file for details.
|
||||
// @flow
|
||||
|
||||
export type KeyringPair = {
|
||||
id: string,
|
||||
publicKey: Uint8Array,
|
||||
|
||||
sign (message: Uint8Array): Uint8Array,
|
||||
verify (message: Uint8Array, signature: Uint8Array): boolean
|
||||
};
|
||||
|
||||
export type KeyringInstance = {
|
||||
addFromSeed (seed: Uint8Array | string): KeyringPair,
|
||||
getPair (publicKey: Uint8Array): ?KeyringPair,
|
||||
getPairs (): Array<KeyringPair>,
|
||||
getPublicKeys (): Array<Uint8Array>
|
||||
};
|
||||
Reference in New Issue
Block a user