@prosopo/keyring 2.10.0 → 2.10.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build$colon$cjs.log +3 -6
- package/.turbo/turbo-build$colon$tsc.log +11 -14
- package/.turbo/turbo-build.log +4 -10
- package/CHANGELOG.md +44 -0
- package/LICENSE +201 -0
- package/dist/accounts/testAccounts.d.ts.map +1 -1
- package/dist/accounts/testAccounts.js +23 -8
- package/dist/accounts/testAccounts.js.map +1 -1
- package/dist/accounts/testAccounts.test.js +33 -4
- package/dist/accounts/testAccounts.test.js.map +1 -1
- package/dist/cjs/accounts/testAccounts.cjs +23 -8
- package/package.json +59 -60
- package/src/accounts/getPair.test.ts +0 -142
- package/src/accounts/getPair.ts +0 -63
- package/src/accounts/index.ts +0 -16
- package/src/accounts/mnemonic.test.ts +0 -103
- package/src/accounts/mnemonic.ts +0 -45
- package/src/accounts/testAccounts.test.ts +0 -102
- package/src/accounts/testAccounts.ts +0 -66
- package/src/index.ts +0 -16
- package/src/keyring/index.ts +0 -15
- package/src/keyring/keyring.test.ts +0 -373
- package/src/keyring/keyring.ts +0 -411
- package/src/keyring/pairs.test.ts +0 -133
- package/src/keyring/pairs.ts +0 -44
- package/src/keyring/testing.test.ts +0 -146
- package/src/keyring/testing.ts +0 -119
- package/src/keyring/testingPairs.ts +0 -61
- package/src/keyring.test-d.ts +0 -134
- package/src/pair/decode.spec.ts +0 -25
- package/src/pair/decode.ts +0 -64
- package/src/pair/defaults.ts +0 -22
- package/src/pair/encode.spec.ts +0 -30
- package/src/pair/encode.ts +0 -32
- package/src/pair/index.ts +0 -304
- package/src/pair/nobody.test.ts +0 -127
- package/src/pair/nobody.ts +0 -79
- package/src/pair/toJson.spec.ts +0 -46
- package/src/pair/toJson.ts +0 -28
- package/tsconfig.cjs.json +0 -30
- package/tsconfig.json +0 -33
- package/tsconfig.tsbuildinfo +0 -1
- package/tsconfig.types.json +0 -9
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
// Copyright 2021-2026 Prosopo (UK) Ltd.
|
|
2
|
-
//
|
|
3
|
-
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
-
// you may not use this file except in compliance with the License.
|
|
5
|
-
// You may obtain a copy of the License at
|
|
6
|
-
//
|
|
7
|
-
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
-
//
|
|
9
|
-
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
-
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
-
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
-
// See the License for the specific language governing permissions and
|
|
13
|
-
// limitations under the License.
|
|
14
|
-
|
|
15
|
-
import { u8aToHex } from "@polkadot/util";
|
|
16
|
-
import { describe, expect, it } from "vitest";
|
|
17
|
-
import { PAIRSSR25519, createTestKeyring } from "./testing.js";
|
|
18
|
-
import { createTestPairs } from "./testingPairs.js";
|
|
19
|
-
|
|
20
|
-
// Key derivation runs scrypt/pbkdf2 with production parameters and takes
|
|
21
|
-
// seconds per call, so these suites need more than the 10s default.
|
|
22
|
-
const SLOW = { timeout: 60000 };
|
|
23
|
-
|
|
24
|
-
describe("createTestKeyring", SLOW, () => {
|
|
25
|
-
it("adds a pair for every well-known dev account", () => {
|
|
26
|
-
expect(createTestKeyring().getPairs()).toHaveLength(PAIRSSR25519.length);
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
it("names each pair after its seed, lowercased with the path flattened", () => {
|
|
30
|
-
// `Alice//stash` becomes `alice_stash`, which is the name the rest of
|
|
31
|
-
// the stack looks pairs up by.
|
|
32
|
-
const names = createTestKeyring()
|
|
33
|
-
.getPairs()
|
|
34
|
-
.map((pair) => pair.meta.name);
|
|
35
|
-
expect(names).toEqual([
|
|
36
|
-
"alice",
|
|
37
|
-
"alice_stash",
|
|
38
|
-
"bob",
|
|
39
|
-
"bob_stash",
|
|
40
|
-
"charlie",
|
|
41
|
-
"dave",
|
|
42
|
-
"eve",
|
|
43
|
-
"ferdie",
|
|
44
|
-
]);
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
it("marks every pair as a testing pair", () => {
|
|
48
|
-
for (const pair of createTestKeyring().getPairs()) {
|
|
49
|
-
expect(pair.meta.isTesting).toBe(true);
|
|
50
|
-
}
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
it("uses the hard-coded public keys, not derivation, by default", () => {
|
|
54
|
-
const keyring = createTestKeyring();
|
|
55
|
-
for (const { p } of PAIRSSR25519) {
|
|
56
|
-
expect(u8aToHex(keyring.getPair(p).publicKey)).toBe(p);
|
|
57
|
-
}
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
it("replaces lock with a no-op so the fixtures stay usable", () => {
|
|
61
|
-
// The pairs carry their secret in the clear; locking them would make
|
|
62
|
-
// every downstream test fail to sign.
|
|
63
|
-
const pair = createTestKeyring().getPairs()[0];
|
|
64
|
-
expect(pair).toBeDefined();
|
|
65
|
-
if (!pair) return;
|
|
66
|
-
expect(() => pair.lock()).not.toThrow();
|
|
67
|
-
expect(pair.isLocked).toBe(false);
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
it("produces signable pairs", () => {
|
|
71
|
-
const pair = createTestKeyring().getPair(PAIRSSR25519[0]?.p ?? "0x");
|
|
72
|
-
const message = new TextEncoder().encode("hello");
|
|
73
|
-
expect(pair.verify(message, pair.sign(message), pair.publicKey)).toBe(true);
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
it("honours a requested ss58 format", () => {
|
|
77
|
-
const alice = PAIRSSR25519[0]?.p ?? "0x";
|
|
78
|
-
expect(
|
|
79
|
-
createTestKeyring({ ss58Format: 42 }).getPair(alice).address,
|
|
80
|
-
).not.toBe(createTestKeyring({ ss58Format: 2 }).getPair(alice).address);
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
it("derives different keys when asked to, because the seeds are bare names", () => {
|
|
84
|
-
// The `isDerived = false` branch feeds the seed straight to
|
|
85
|
-
// `addFromUri`, and the seeds are names like "Alice" rather than
|
|
86
|
-
// "//Alice". They are therefore padded raw phrases, not dev-phrase
|
|
87
|
-
// derivations, so the pairs are NOT the well-known dev accounts.
|
|
88
|
-
// Anything relying on Alice's address must use the default mode.
|
|
89
|
-
const derived = createTestKeyring({}, false);
|
|
90
|
-
expect(derived.getPairs()).toHaveLength(PAIRSSR25519.length);
|
|
91
|
-
for (const { p } of PAIRSSR25519) {
|
|
92
|
-
expect(() => derived.getPair(p)).toThrow("Unable to retrieve keypair");
|
|
93
|
-
}
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
it("rejects a keyring type it cannot support", () => {
|
|
97
|
-
expect(() => createTestKeyring({ type: "ed25519" })).toThrow(
|
|
98
|
-
"Expected a keyring type of either 'sr25519'",
|
|
99
|
-
);
|
|
100
|
-
});
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
describe("createTestPairs", SLOW, () => {
|
|
104
|
-
it("exposes every named pair plus nobody", () => {
|
|
105
|
-
const pairs = createTestPairs();
|
|
106
|
-
for (const name of [
|
|
107
|
-
"nobody",
|
|
108
|
-
"alice",
|
|
109
|
-
"alice_stash",
|
|
110
|
-
"bob",
|
|
111
|
-
"bob_stash",
|
|
112
|
-
"charlie",
|
|
113
|
-
"dave",
|
|
114
|
-
"eve",
|
|
115
|
-
"ferdie",
|
|
116
|
-
]) {
|
|
117
|
-
expect(pairs[name], name).toBeDefined();
|
|
118
|
-
}
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
it("maps alice to the well-known Alice public key", () => {
|
|
122
|
-
expect(
|
|
123
|
-
u8aToHex(createTestPairs().alice?.publicKey ?? new Uint8Array()),
|
|
124
|
-
).toBe(PAIRSSR25519[0]?.p);
|
|
125
|
-
});
|
|
126
|
-
|
|
127
|
-
it("includes nobody, which cannot verify anything", () => {
|
|
128
|
-
const nobodyPair = createTestPairs().nobody;
|
|
129
|
-
expect(nobodyPair).toBeDefined();
|
|
130
|
-
expect(nobodyPair?.isLocked).toBe(true);
|
|
131
|
-
expect(
|
|
132
|
-
nobodyPair?.verify(
|
|
133
|
-
new Uint8Array(1),
|
|
134
|
-
new Uint8Array(64),
|
|
135
|
-
nobodyPair.publicKey,
|
|
136
|
-
),
|
|
137
|
-
).toBe(false);
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
it("returns independent maps so one test cannot poison another", () => {
|
|
141
|
-
const first = createTestPairs();
|
|
142
|
-
const second = createTestPairs();
|
|
143
|
-
expect(first).not.toBe(second);
|
|
144
|
-
expect(first.alice).not.toBe(second.alice);
|
|
145
|
-
});
|
|
146
|
-
});
|
package/src/keyring/testing.ts
DELETED
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
// Copyright 2017-2025 @polkadot/keyring authors & contributors
|
|
2
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
-
|
|
4
|
-
import type { HexString } from "@polkadot/util/types";
|
|
5
|
-
import type { KeyringInstance, KeyringOptions } from "@prosopo/types";
|
|
6
|
-
|
|
7
|
-
import { hexToU8a } from "@polkadot/util";
|
|
8
|
-
|
|
9
|
-
import type { KeypairType } from "@prosopo/util-crypto";
|
|
10
|
-
import { createPair } from "../pair/index.js";
|
|
11
|
-
import { Keyring } from "./keyring.js";
|
|
12
|
-
|
|
13
|
-
interface PairDef {
|
|
14
|
-
name?: string;
|
|
15
|
-
p: HexString;
|
|
16
|
-
s: HexString;
|
|
17
|
-
seed?: string;
|
|
18
|
-
type: KeypairType;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
// NOTE This is not great since we have the secretKey here explicitly, but a testing
|
|
22
|
-
// keyring is for testing - what happens is that in most cases the keyring is initialises
|
|
23
|
-
// before anything else. Since the sr25519 crypto is async, this creates problems with
|
|
24
|
-
// adding the keys when only the keyring is used.
|
|
25
|
-
export const PAIRSSR25519: PairDef[] = [
|
|
26
|
-
{
|
|
27
|
-
p: "0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d",
|
|
28
|
-
s: "0x98319d4ff8a9508c4bb0cf0b5a78d760a0b2082c02775e6e82370816fedfff48925a225d97aa00682d6a59b95b18780c10d7032336e88f3442b42361f4a66011", // nosemgrep
|
|
29
|
-
seed: "Alice",
|
|
30
|
-
type: "sr25519",
|
|
31
|
-
},
|
|
32
|
-
{
|
|
33
|
-
p: "0xbe5ddb1579b72e84524fc29e78609e3caf42e85aa118ebfe0b0ad404b5bdd25f",
|
|
34
|
-
s: "0xe8da6c9d810e020f5e3c7f5af2dea314cbeaa0d72bc6421e92c0808a0c584a6046ab28e97c3ffc77fe12b5a4d37e8cd4afbfebbf2391ffc7cb07c0f38c023efd", // nosemgrep
|
|
35
|
-
seed: "Alice//stash",
|
|
36
|
-
type: "sr25519",
|
|
37
|
-
},
|
|
38
|
-
{
|
|
39
|
-
p: "0x8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48",
|
|
40
|
-
s: "0x081ff694633e255136bdb456c20a5fc8fed21f8b964c11bb17ff534ce80ebd5941ae88f85d0c1bfc37be41c904e1dfc01de8c8067b0d6d5df25dd1ac0894a325", // nosemgrep
|
|
41
|
-
seed: "Bob",
|
|
42
|
-
type: "sr25519",
|
|
43
|
-
},
|
|
44
|
-
{
|
|
45
|
-
p: "0xfe65717dad0447d715f660a0a58411de509b42e6efb8375f562f58a554d5860e",
|
|
46
|
-
s: "0xc006507cdfc267a21532394c49ca9b754ca71de21e15a1cdf807c7ceab6d0b6c3ed408d9d35311540dcd54931933e67cf1ea10d46f75408f82b789d9bd212fde", // nosemgrep
|
|
47
|
-
seed: "Bob//stash",
|
|
48
|
-
type: "sr25519",
|
|
49
|
-
},
|
|
50
|
-
{
|
|
51
|
-
p: "0x90b5ab205c6974c9ea841be688864633dc9ca8a357843eeacf2314649965fe22",
|
|
52
|
-
s: "0xa8f2d83016052e5d6d77b2f6fd5d59418922a09024cda701b3c34369ec43a7668faf12ff39cd4e5d92bb773972f41a7a5279ebc2ed92264bed8f47d344f8f18c", // nosemgrep
|
|
53
|
-
seed: "Charlie",
|
|
54
|
-
type: "sr25519",
|
|
55
|
-
},
|
|
56
|
-
{
|
|
57
|
-
p: "0x306721211d5404bd9da88e0204360a1a9ab8b87c66c1bc2fcdd37f3c2222cc20",
|
|
58
|
-
s: "0x20e05482ca4677e0edbc58ae9a3a59f6ed3b1a9484ba17e64d6fe8688b2b7b5d108c4487b9323b98b11fe36cb301b084e920f7b7895536809a6d62a451b25568", // nosemgrep
|
|
59
|
-
seed: "Dave",
|
|
60
|
-
type: "sr25519",
|
|
61
|
-
},
|
|
62
|
-
{
|
|
63
|
-
p: "0xe659a7a1628cdd93febc04a4e0646ea20e9f5f0ce097d9a05290d4a9e054df4e",
|
|
64
|
-
s: "0x683576abfd5dc35273e4264c23095a1bf21c14517bece57c7f0cc5c0ed4ce06a3dbf386b7828f348abe15d76973a72009e6ef86a5c91db2990cb36bb657c6587", // nosemgrep
|
|
65
|
-
seed: "Eve",
|
|
66
|
-
type: "sr25519",
|
|
67
|
-
},
|
|
68
|
-
{
|
|
69
|
-
p: "0x1cbd2d43530a44705ad088af313e18f80b53ef16b36177cd4b77b846f2a5f07c",
|
|
70
|
-
s: "0xb835c20f450079cf4f513900ae9faf8df06ad86c681884122c752a4b2bf74d4303e4f21bc6cc62bb4eeed5a9cce642c25e2d2ac1464093b50f6196d78e3a7426", // nosemgrep
|
|
71
|
-
seed: "Ferdie",
|
|
72
|
-
type: "sr25519",
|
|
73
|
-
},
|
|
74
|
-
];
|
|
75
|
-
|
|
76
|
-
function createMeta(name?: string, seed?: string) {
|
|
77
|
-
if (!name && !seed) {
|
|
78
|
-
throw new Error("Testing pair should have either a name or a seed");
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
return {
|
|
82
|
-
isTesting: true,
|
|
83
|
-
name: name || seed?.replace("//", "_").toLowerCase(),
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* @name testKeyring
|
|
89
|
-
* @summary Create an instance of Keyring pre-populated with locked test accounts
|
|
90
|
-
* @description The test accounts (i.e. alice, bob, dave, eve, ferdie)
|
|
91
|
-
* are available on the dev chain and each test account is initialized with DOT funds.
|
|
92
|
-
*/
|
|
93
|
-
export function createTestKeyring(
|
|
94
|
-
options: KeyringOptions = {},
|
|
95
|
-
isDerived = true,
|
|
96
|
-
): KeyringInstance {
|
|
97
|
-
const keyring = new Keyring(options);
|
|
98
|
-
const pairs = PAIRSSR25519;
|
|
99
|
-
|
|
100
|
-
for (const { name, p, s, seed, type } of pairs) {
|
|
101
|
-
const meta = createMeta(name, seed);
|
|
102
|
-
const pair =
|
|
103
|
-
!isDerived && !name && seed
|
|
104
|
-
? keyring.addFromUri(seed, meta, options.type)
|
|
105
|
-
: keyring.addPair(
|
|
106
|
-
createPair(
|
|
107
|
-
{ toSS58: keyring.encodeAddress, type },
|
|
108
|
-
{ publicKey: hexToU8a(p), secretKey: hexToU8a(s) },
|
|
109
|
-
meta,
|
|
110
|
-
),
|
|
111
|
-
);
|
|
112
|
-
|
|
113
|
-
pair.lock = (): void => {
|
|
114
|
-
// we don't have lock/unlock functionality here
|
|
115
|
-
};
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
return keyring;
|
|
119
|
-
}
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
// Copyright 2017-2025 @polkadot/keyring authors & contributors
|
|
2
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
-
|
|
4
|
-
import type { KeyringOptions, KeyringPair } from "@prosopo/types";
|
|
5
|
-
import type { KeypairType } from "@prosopo/util-crypto";
|
|
6
|
-
|
|
7
|
-
import { nobody } from "../pair/nobody.js";
|
|
8
|
-
import { createTestKeyring } from "./testing.js";
|
|
9
|
-
|
|
10
|
-
export interface TestKeyringMap {
|
|
11
|
-
nobody: KeyringPair;
|
|
12
|
-
|
|
13
|
-
[index: string]: KeyringPair;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export interface TestKeyringMapSubstrate extends TestKeyringMap {
|
|
17
|
-
alice: KeyringPair;
|
|
18
|
-
bob: KeyringPair;
|
|
19
|
-
charlie: KeyringPair;
|
|
20
|
-
dave: KeyringPair;
|
|
21
|
-
eve: KeyringPair;
|
|
22
|
-
ferdie: KeyringPair;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export interface TestKeyringMapEthereum extends TestKeyringMap {
|
|
26
|
-
Alith: KeyringPair;
|
|
27
|
-
Baltathar: KeyringPair;
|
|
28
|
-
Charleth: KeyringPair;
|
|
29
|
-
Dorothy: KeyringPair;
|
|
30
|
-
Ethan: KeyringPair;
|
|
31
|
-
Faith: KeyringPair;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export type DetectMap<O extends KeyringOptions | undefined> =
|
|
35
|
-
DetectPairType<O> extends "ethereum"
|
|
36
|
-
? TestKeyringMapEthereum
|
|
37
|
-
: TestKeyringMapSubstrate;
|
|
38
|
-
|
|
39
|
-
export type DetectPairType<O extends KeyringOptions | undefined> =
|
|
40
|
-
O extends KeyringOptions
|
|
41
|
-
? O["type"] extends KeypairType
|
|
42
|
-
? O["type"]
|
|
43
|
-
: "sr25519"
|
|
44
|
-
: "sr25519";
|
|
45
|
-
|
|
46
|
-
export function createTestPairs<O extends KeyringOptions, M = DetectMap<O>>(
|
|
47
|
-
options?: O,
|
|
48
|
-
isDerived = true,
|
|
49
|
-
): M {
|
|
50
|
-
const keyring = createTestKeyring(options, isDerived);
|
|
51
|
-
const pairs = keyring.getPairs();
|
|
52
|
-
const map: TestKeyringMap = { nobody: nobody() };
|
|
53
|
-
|
|
54
|
-
for (const p of pairs) {
|
|
55
|
-
if (p.meta.name) {
|
|
56
|
-
map[p.meta.name] = p;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
return map as M;
|
|
61
|
-
}
|
package/src/keyring.test-d.ts
DELETED
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
// Copyright 2021-2026 Prosopo (UK) Ltd.
|
|
2
|
-
//
|
|
3
|
-
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
-
// you may not use this file except in compliance with the License.
|
|
5
|
-
// You may obtain a copy of the License at
|
|
6
|
-
//
|
|
7
|
-
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
-
//
|
|
9
|
-
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
-
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
-
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
-
// See the License for the specific language governing permissions and
|
|
13
|
-
// limitations under the License.
|
|
14
|
-
|
|
15
|
-
import type {
|
|
16
|
-
IProviderAccount,
|
|
17
|
-
ISite,
|
|
18
|
-
KeyringInstance,
|
|
19
|
-
KeyringPair,
|
|
20
|
-
KeyringPair$Json,
|
|
21
|
-
} from "@prosopo/types";
|
|
22
|
-
import { assertType, describe, expectTypeOf, it } from "vitest";
|
|
23
|
-
import {
|
|
24
|
-
Keyring,
|
|
25
|
-
generateMiniSecret,
|
|
26
|
-
generateMnemonic,
|
|
27
|
-
getDefaultProviders,
|
|
28
|
-
getDefaultSiteKeys,
|
|
29
|
-
getPair,
|
|
30
|
-
} from "./index.js";
|
|
31
|
-
// The testing helpers and `nobody` are deliberately not re-exported from the
|
|
32
|
-
// package barrel, so they are imported from their modules directly.
|
|
33
|
-
import type {
|
|
34
|
-
DetectMap,
|
|
35
|
-
DetectPairType,
|
|
36
|
-
TestKeyringMapEthereum,
|
|
37
|
-
TestKeyringMapSubstrate,
|
|
38
|
-
} from "./keyring/testingPairs.js";
|
|
39
|
-
import { nobody } from "./pair/nobody.js";
|
|
40
|
-
|
|
41
|
-
describe("Keyring types", () => {
|
|
42
|
-
it("implements the shared KeyringInstance contract", () => {
|
|
43
|
-
expectTypeOf<Keyring>().toExtend<KeyringInstance>();
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
it("returns KeyringPair from every add and create method", () => {
|
|
47
|
-
const keyring = new Keyring();
|
|
48
|
-
expectTypeOf(keyring.addFromUri("//Alice")).toEqualTypeOf<KeyringPair>();
|
|
49
|
-
expectTypeOf(keyring.addFromMnemonic("x")).toEqualTypeOf<KeyringPair>();
|
|
50
|
-
expectTypeOf(
|
|
51
|
-
keyring.addFromSeed(new Uint8Array()),
|
|
52
|
-
).toEqualTypeOf<KeyringPair>();
|
|
53
|
-
expectTypeOf(keyring.addFromAddress("x")).toEqualTypeOf<KeyringPair>();
|
|
54
|
-
expectTypeOf(keyring.getPair("x")).toEqualTypeOf<KeyringPair>();
|
|
55
|
-
expectTypeOf(keyring.getPairs()).toEqualTypeOf<KeyringPair[]>();
|
|
56
|
-
expectTypeOf(keyring.publicKeys).toEqualTypeOf<Uint8Array[]>();
|
|
57
|
-
expectTypeOf(keyring.toJson("x")).toEqualTypeOf<KeyringPair$Json>();
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
it("accepts an address as either a string or raw bytes", () => {
|
|
61
|
-
const keyring = new Keyring();
|
|
62
|
-
assertType(keyring.getPair("5abc"));
|
|
63
|
-
assertType(keyring.getPair(new Uint8Array(32)));
|
|
64
|
-
// @ts-expect-error a number is not an address
|
|
65
|
-
assertType(keyring.getPair(1));
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
it("rejects a keyring option object with an unknown key", () => {
|
|
69
|
-
// @ts-expect-error `curve` is not an option
|
|
70
|
-
new Keyring({ curve: "sr25519" });
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
it("has a readonly type", () => {
|
|
74
|
-
expectTypeOf<Keyring["type"]>().toEqualTypeOf<
|
|
75
|
-
import("@prosopo/util-crypto").KeypairType
|
|
76
|
-
>();
|
|
77
|
-
});
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
describe("account helper types", () => {
|
|
81
|
-
it("returns a pair from getPair with every argument optional", () => {
|
|
82
|
-
expectTypeOf(getPair).returns.toEqualTypeOf<KeyringPair>();
|
|
83
|
-
assertType(getPair());
|
|
84
|
-
assertType(getPair("secret", "account", "sr25519", 42));
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
it("returns the mnemonic and address as a tuple", () => {
|
|
88
|
-
expectTypeOf(generateMnemonic).returns.resolves.toEqualTypeOf<
|
|
89
|
-
[string, string]
|
|
90
|
-
>();
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
it("returns the mini secret as bytes paired with an address", () => {
|
|
94
|
-
expectTypeOf(generateMiniSecret).returns.resolves.toEqualTypeOf<
|
|
95
|
-
[Uint8Array, string]
|
|
96
|
-
>();
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
it("describes the dev fixtures with the shared account types", () => {
|
|
100
|
-
expectTypeOf(getDefaultSiteKeys()).toEqualTypeOf<ISite[]>();
|
|
101
|
-
expectTypeOf(getDefaultProviders()).toEqualTypeOf<IProviderAccount[]>();
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
it("returns a real KeyringPair for nobody", () => {
|
|
105
|
-
expectTypeOf(nobody()).toEqualTypeOf<KeyringPair>();
|
|
106
|
-
});
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
describe("test keyring map inference", () => {
|
|
110
|
-
it("defaults to the substrate map when no options are given", () => {
|
|
111
|
-
expectTypeOf<DetectPairType<undefined>>().toEqualTypeOf<"sr25519">();
|
|
112
|
-
expectTypeOf<
|
|
113
|
-
DetectMap<undefined>
|
|
114
|
-
>().toEqualTypeOf<TestKeyringMapSubstrate>();
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
it("selects the ethereum map only for an ethereum keyring", () => {
|
|
118
|
-
expectTypeOf<
|
|
119
|
-
DetectMap<{ type: "ethereum" }>
|
|
120
|
-
>().toEqualTypeOf<TestKeyringMapEthereum>();
|
|
121
|
-
expectTypeOf<
|
|
122
|
-
DetectMap<{ type: "sr25519" }>
|
|
123
|
-
>().toEqualTypeOf<TestKeyringMapSubstrate>();
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
it("indexes the map by arbitrary names, always yielding a pair", () => {
|
|
127
|
-
expectTypeOf<
|
|
128
|
-
TestKeyringMapSubstrate["alice"]
|
|
129
|
-
>().toEqualTypeOf<KeyringPair>();
|
|
130
|
-
expectTypeOf<
|
|
131
|
-
TestKeyringMapSubstrate["anything-else"]
|
|
132
|
-
>().toEqualTypeOf<KeyringPair>();
|
|
133
|
-
});
|
|
134
|
-
});
|
package/src/pair/decode.spec.ts
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
// Copyright 2017-2025 @polkadot/keyring authors & contributors
|
|
2
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
-
|
|
4
|
-
import { describe, expect, it } from "vitest";
|
|
5
|
-
import { createTestPairs } from "../keyring/testingPairs.js";
|
|
6
|
-
|
|
7
|
-
const keyring = createTestPairs({ type: "sr25519" }, false);
|
|
8
|
-
|
|
9
|
-
describe("decode", (): void => {
|
|
10
|
-
it("fails when no data provided", (): void => {
|
|
11
|
-
expect((): void => keyring.alice.decodePkcs8()).toThrow(
|
|
12
|
-
/(No encrypted data available|Password required)/,
|
|
13
|
-
);
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
// scrypt with the production parameters takes several seconds, which
|
|
17
|
-
// overruns the 10s default on a loaded CI runner.
|
|
18
|
-
it("returns correct publicKey from encoded", { timeout: 60000 }, (): void => {
|
|
19
|
-
const PASS = "testing";
|
|
20
|
-
|
|
21
|
-
expect((): void =>
|
|
22
|
-
keyring.alice.decodePkcs8(PASS, keyring.alice.encodePkcs8(PASS)),
|
|
23
|
-
).not.toThrow();
|
|
24
|
-
});
|
|
25
|
-
});
|
package/src/pair/decode.ts
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
// Copyright 2017-2025 @polkadot/keyring authors & contributors
|
|
2
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
-
|
|
4
|
-
import { u8aEq } from "@polkadot/util";
|
|
5
|
-
import type { EncryptedJsonEncoding } from "@prosopo/util-crypto";
|
|
6
|
-
import { jsonDecryptData } from "@prosopo/util-crypto";
|
|
7
|
-
|
|
8
|
-
import {
|
|
9
|
-
PAIR_DIV,
|
|
10
|
-
PAIR_HDR,
|
|
11
|
-
PUB_LENGTH,
|
|
12
|
-
SEC_LENGTH,
|
|
13
|
-
SEED_LENGTH,
|
|
14
|
-
} from "./defaults.js";
|
|
15
|
-
|
|
16
|
-
const SEED_OFFSET = PAIR_HDR.length;
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Decode a pair, taking into account the generation-specific formats and headers
|
|
20
|
-
*
|
|
21
|
-
* For divisor/headers, don't rely on the magic being static. These will
|
|
22
|
-
* change between generations, aka with the long-awaited 4th generation
|
|
23
|
-
* of the format. The external decode interface is the only way to use and decode these.
|
|
24
|
-
**/
|
|
25
|
-
export function decodePair(
|
|
26
|
-
passphrase?: string,
|
|
27
|
-
encrypted?: Uint8Array | null,
|
|
28
|
-
_encType?: EncryptedJsonEncoding | EncryptedJsonEncoding[],
|
|
29
|
-
): { publicKey: Uint8Array; secretKey: Uint8Array } {
|
|
30
|
-
const encType =
|
|
31
|
-
Array.isArray(_encType) || _encType === undefined ? _encType : [_encType];
|
|
32
|
-
const decrypted = jsonDecryptData(encrypted, passphrase, encType);
|
|
33
|
-
const header = decrypted.subarray(0, PAIR_HDR.length);
|
|
34
|
-
|
|
35
|
-
// check the start header (generations 1-3)
|
|
36
|
-
if (!u8aEq(header, PAIR_HDR)) {
|
|
37
|
-
throw new Error("Invalid encoding header found in body");
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
// setup for generation 3 format
|
|
41
|
-
let secretKey = decrypted.subarray(SEED_OFFSET, SEED_OFFSET + SEC_LENGTH);
|
|
42
|
-
let divOffset = SEED_OFFSET + SEC_LENGTH;
|
|
43
|
-
let divider = decrypted.subarray(divOffset, divOffset + PAIR_DIV.length);
|
|
44
|
-
|
|
45
|
-
// old-style (generation 1 & 2), we have the seed here
|
|
46
|
-
if (!u8aEq(divider, PAIR_DIV)) {
|
|
47
|
-
divOffset = SEED_OFFSET + SEED_LENGTH;
|
|
48
|
-
secretKey = decrypted.subarray(SEED_OFFSET, divOffset);
|
|
49
|
-
divider = decrypted.subarray(divOffset, divOffset + PAIR_DIV.length);
|
|
50
|
-
|
|
51
|
-
// check the divisior at this point (already checked for generation 3)
|
|
52
|
-
if (!u8aEq(divider, PAIR_DIV)) {
|
|
53
|
-
throw new Error("Invalid encoding divider found in body");
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
const pubOffset = divOffset + PAIR_DIV.length;
|
|
58
|
-
const publicKey = decrypted.subarray(pubOffset, pubOffset + PUB_LENGTH);
|
|
59
|
-
|
|
60
|
-
return {
|
|
61
|
-
publicKey,
|
|
62
|
-
secretKey,
|
|
63
|
-
};
|
|
64
|
-
}
|
package/src/pair/defaults.ts
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
// Copyright 2017-2025 @polkadot/keyring authors & contributors
|
|
2
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
-
|
|
4
|
-
/** public/secret section divider (generation 1-3, will change in 4, don't rely on value) */
|
|
5
|
-
export const PAIR_DIV = new Uint8Array([161, 35, 3, 33, 0]);
|
|
6
|
-
|
|
7
|
-
/** public/secret start block (generation 1-3, will change in 4, don't rely on value) */
|
|
8
|
-
export const PAIR_HDR = new Uint8Array([
|
|
9
|
-
48, 83, 2, 1, 1, 48, 5, 6, 3, 43, 101, 112, 4, 34, 4, 32,
|
|
10
|
-
]);
|
|
11
|
-
|
|
12
|
-
/** length of a public key */
|
|
13
|
-
export const PUB_LENGTH = 32;
|
|
14
|
-
|
|
15
|
-
/** length of a salt */
|
|
16
|
-
export const SALT_LENGTH = 32;
|
|
17
|
-
|
|
18
|
-
/** length of a secret key */
|
|
19
|
-
export const SEC_LENGTH = 64;
|
|
20
|
-
|
|
21
|
-
/** length of a user-input seed */
|
|
22
|
-
export const SEED_LENGTH = 32;
|
package/src/pair/encode.spec.ts
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
// Copyright 2017-2025 @polkadot/keyring authors & contributors
|
|
2
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
-
|
|
4
|
-
import { NONCE_LENGTH, SCRYPT_LENGTH } from "@prosopo/util-crypto";
|
|
5
|
-
import { describe, expect, it } from "vitest";
|
|
6
|
-
|
|
7
|
-
import { createTestPairs } from "../keyring/testingPairs.js";
|
|
8
|
-
import { PAIR_DIV, PAIR_HDR, PUB_LENGTH, SEC_LENGTH } from "./defaults.js";
|
|
9
|
-
|
|
10
|
-
const DECODED_LENGTH =
|
|
11
|
-
PAIR_DIV.length + PAIR_HDR.length + PUB_LENGTH + SEC_LENGTH;
|
|
12
|
-
const ENCODED_LENGTH = 16 + DECODED_LENGTH + NONCE_LENGTH + SCRYPT_LENGTH;
|
|
13
|
-
|
|
14
|
-
const keyring = createTestPairs({ type: "sr25519" }, false);
|
|
15
|
-
|
|
16
|
-
describe("encode", (): void => {
|
|
17
|
-
it("returns PKCS8 when no passphrase supplied", (): void => {
|
|
18
|
-
expect(keyring.alice.encodePkcs8()).toHaveLength(DECODED_LENGTH);
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
// scrypt with the production parameters takes several seconds, which
|
|
22
|
-
// overruns the 10s default on a loaded CI runner.
|
|
23
|
-
it(
|
|
24
|
-
"returns encoded PKCS8 when passphrase supplied",
|
|
25
|
-
{ timeout: 60000 },
|
|
26
|
-
(): void => {
|
|
27
|
-
expect(keyring.alice.encodePkcs8("testing")).toHaveLength(ENCODED_LENGTH);
|
|
28
|
-
},
|
|
29
|
-
);
|
|
30
|
-
});
|
package/src/pair/encode.ts
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
// Copyright 2017-2025 @polkadot/keyring authors & contributors
|
|
2
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
-
|
|
4
|
-
import { u8aConcat } from "@polkadot/util";
|
|
5
|
-
import type { PairInfo } from "@prosopo/types";
|
|
6
|
-
import { naclEncrypt, scryptEncode, scryptToU8a } from "@prosopo/util-crypto";
|
|
7
|
-
|
|
8
|
-
import { PAIR_DIV, PAIR_HDR } from "./defaults.js";
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Encode a pair with the latest generation format (generation 3)
|
|
12
|
-
**/
|
|
13
|
-
export function encodePair(
|
|
14
|
-
{ publicKey, secretKey }: PairInfo,
|
|
15
|
-
passphrase?: string,
|
|
16
|
-
): Uint8Array {
|
|
17
|
-
if (!secretKey) {
|
|
18
|
-
throw new Error("Expected a valid secretKey to be passed to encode");
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
const encoded = u8aConcat(PAIR_HDR, secretKey, PAIR_DIV, publicKey);
|
|
22
|
-
|
|
23
|
-
if (!passphrase) {
|
|
24
|
-
return encoded;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
// this is only for generation 3 (previous generations are only handled in decoding)
|
|
28
|
-
const { params, password, salt } = scryptEncode(passphrase);
|
|
29
|
-
const { encrypted, nonce } = naclEncrypt(encoded, password.subarray(0, 32));
|
|
30
|
-
|
|
31
|
-
return u8aConcat(scryptToU8a(salt, params), nonce, encrypted);
|
|
32
|
-
}
|