@prosopo/keyring 2.9.61 → 2.9.63
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 +2 -2
- package/.turbo/turbo-build$colon$tsc.log +11 -11
- package/.turbo/turbo-build.log +3 -3
- package/CHANGELOG.md +14 -0
- package/dist/accounts/getPair.test.d.ts +2 -0
- package/dist/accounts/getPair.test.d.ts.map +1 -0
- package/dist/accounts/getPair.test.js +86 -0
- package/dist/accounts/getPair.test.js.map +1 -0
- package/dist/accounts/mnemonic.test.d.ts +2 -0
- package/dist/accounts/mnemonic.test.d.ts.map +1 -0
- package/dist/accounts/mnemonic.test.js +64 -0
- package/dist/accounts/mnemonic.test.js.map +1 -0
- package/dist/accounts/testAccounts.test.d.ts +2 -0
- package/dist/accounts/testAccounts.test.d.ts.map +1 -0
- package/dist/accounts/testAccounts.test.js +66 -0
- package/dist/accounts/testAccounts.test.js.map +1 -0
- package/dist/keyring/keyring.test.d.ts +2 -0
- package/dist/keyring/keyring.test.d.ts.map +1 -0
- package/dist/keyring/keyring.test.js +239 -0
- package/dist/keyring/keyring.test.js.map +1 -0
- package/dist/keyring/pairs.test.d.ts +2 -0
- package/dist/keyring/pairs.test.d.ts.map +1 -0
- package/dist/keyring/pairs.test.js +84 -0
- package/dist/keyring/pairs.test.js.map +1 -0
- package/dist/keyring/testing.test.d.ts +2 -0
- package/dist/keyring/testing.test.d.ts.map +1 -0
- package/dist/keyring/testing.test.js +97 -0
- package/dist/keyring/testing.test.js.map +1 -0
- package/dist/keyring.test-d.d.ts +2 -0
- package/dist/keyring.test-d.d.ts.map +1 -0
- package/dist/keyring.test-d.js +66 -0
- package/dist/keyring.test-d.js.map +1 -0
- package/dist/pair/decode.spec.js +1 -1
- package/dist/pair/decode.spec.js.map +1 -1
- package/dist/pair/encode.spec.js +1 -1
- package/dist/pair/encode.spec.js.map +1 -1
- package/dist/pair/nobody.test.d.ts +2 -0
- package/dist/pair/nobody.test.d.ts.map +1 -0
- package/dist/pair/nobody.test.js +77 -0
- package/dist/pair/nobody.test.js.map +1 -0
- package/dist/pair/toJson.spec.js +1 -1
- package/dist/pair/toJson.spec.js.map +1 -1
- package/package.json +3 -3
- package/src/accounts/getPair.test.ts +142 -0
- package/src/accounts/mnemonic.test.ts +103 -0
- package/src/accounts/testAccounts.test.ts +100 -0
- package/src/keyring/keyring.test.ts +373 -0
- package/src/keyring/pairs.test.ts +133 -0
- package/src/keyring/testing.test.ts +146 -0
- package/src/keyring.test-d.ts +134 -0
- package/src/pair/decode.spec.ts +3 -1
- package/src/pair/encode.spec.ts +9 -3
- package/src/pair/nobody.test.ts +127 -0
- package/src/pair/toJson.spec.ts +18 -12
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
> @prosopo/keyring@2.9.
|
|
2
|
+
> @prosopo/keyring@2.9.63 build:cjs
|
|
3
3
|
> NODE_ENV=${NODE_ENV:-development}; vite build --config vite.cjs.config.ts --mode $NODE_ENV
|
|
4
4
|
|
|
5
5
|
ViteCommonJSConfig: .
|
|
@@ -44,4 +44,4 @@ dist/cjs/pair/decode.cjs 1.77 kB │ gzip: 0.70 kB
|
|
|
44
44
|
dist/cjs/pair/index.cjs 7.26 kB │ gzip: 2.12 kB
|
|
45
45
|
dist/cjs/keyring/keyring.cjs 11.14 kB │ gzip: 3.05 kB
|
|
46
46
|
|
|
47
|
-
[32m✓ built in
|
|
47
|
+
[32m✓ built in 80ms[39m
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
|
|
2
|
-
> @prosopo/keyring@2.9.
|
|
2
|
+
> @prosopo/keyring@2.9.63 build:tsc
|
|
3
3
|
> tsc --build --verbose
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
11:09:59 AM - Projects in this build:
|
|
6
6
|
* ../../dev/config/tsconfig.json
|
|
7
7
|
* ../locale/tsconfig.json
|
|
8
8
|
* ../util/tsconfig.json
|
|
@@ -12,21 +12,21 @@
|
|
|
12
12
|
* ../common/tsconfig.json
|
|
13
13
|
* tsconfig.json
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
11:09:59 AM - Project '../../dev/config/tsconfig.json' is up to date because newest input '../../dev/config/src/webpack/webpack.config.ts' is older than output '../../dev/config/tsconfig.tsbuildinfo'
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
11:09:59 AM - Project '../locale/tsconfig.json' is up to date because newest input '../locale/src/translationKey.ts' is older than output '../locale/tsconfig.tsbuildinfo'
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
11:09:59 AM - Project '../util/tsconfig.json' is up to date because newest input '../util/src/url.ts' is older than output '../util/tsconfig.tsbuildinfo'
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
11:10:00 AM - Project '../logger/tsconfig.json' is up to date because newest input '../logger/src/index.ts' is older than output '../logger/tsconfig.tsbuildinfo'
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
11:10:00 AM - Project '../util-crypto/tsconfig.json' is up to date because newest input '../util-crypto/src/types.ts' is older than output '../util-crypto/tsconfig.tsbuildinfo'
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
11:10:00 AM - Project '../types/tsconfig.json' is up to date because newest input '../types/src/types.test-d.ts' is older than output '../types/tsconfig.tsbuildinfo'
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
11:10:00 AM - Project '../common/tsconfig.json' is up to date because newest input '../common/src/tests/utils/batches.unit.test.ts' is older than output '../common/tsconfig.tsbuildinfo'
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
11:10:00 AM - Project 'tsconfig.json' is out of date because output file 'tsconfig.tsbuildinfo' does not exist
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
11:10:00 AM - Building project '/home/runner/work/captcha/captcha/packages/keyring/tsconfig.json'...
|
|
32
32
|
|
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
|
|
2
|
-
> @prosopo/keyring@2.9.
|
|
2
|
+
> @prosopo/keyring@2.9.63 build
|
|
3
3
|
> npm run build:cross-env -- --mode ${NODE_ENV:-development}
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
> @prosopo/keyring@2.9.
|
|
6
|
+
> @prosopo/keyring@2.9.63 build:cross-env
|
|
7
7
|
> vite build --config vite.esm.config.ts --mode production
|
|
8
8
|
|
|
9
9
|
ViteEsmConfig: .
|
|
@@ -49,4 +49,4 @@ dist/pair/decode.js 1.48 kB │ gzip: 0.66 kB
|
|
|
49
49
|
dist/pair/index.js 6.96 kB │ gzip: 2.09 kB
|
|
50
50
|
dist/keyring/keyring.js 10.74 kB │ gzip: 2.99 kB
|
|
51
51
|
|
|
52
|
-
[32m✓ built in
|
|
52
|
+
[32m✓ built in 78ms[39m
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# @prosopo/keyring
|
|
2
2
|
|
|
3
|
+
## 2.9.63
|
|
4
|
+
### Patch Changes
|
|
5
|
+
|
|
6
|
+
- Updated dependencies [787017b]
|
|
7
|
+
- Updated dependencies [787017b]
|
|
8
|
+
- Updated dependencies [787017b]
|
|
9
|
+
- Updated dependencies [6f19cde]
|
|
10
|
+
- @prosopo/types@5.0.0
|
|
11
|
+
|
|
12
|
+
## 2.9.62
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- 71a5952: Add unit and type tests for the keyring: pair encode/decode, mnemonic handling, account derivation, the testing keyring and the nobody pair. No behaviour changes.
|
|
16
|
+
|
|
3
17
|
## 2.9.61
|
|
4
18
|
### Patch Changes
|
|
5
19
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getPair.test.d.ts","sourceRoot":"","sources":["../../src/accounts/getPair.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { u8aToHex } from "@polkadot/util";
|
|
2
|
+
import { encodeAddress, sr25519FromSeed } from "@prosopo/util-crypto";
|
|
3
|
+
import { describe, expect, it } from "vitest";
|
|
4
|
+
import { DEV_PHRASE, Keyring } from "../keyring/index.js";
|
|
5
|
+
import { getPair } from "./getPair.js";
|
|
6
|
+
const SEED_32 = new Uint8Array(32).fill(7);
|
|
7
|
+
const SEED_HEX = u8aToHex(SEED_32);
|
|
8
|
+
const ALICE_PUBLIC = "0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d";
|
|
9
|
+
const pairJson = (overrides = {}) => ({
|
|
10
|
+
address: encodeAddress(new Uint8Array(32).fill(8), 42),
|
|
11
|
+
encoded: "0x00",
|
|
12
|
+
encoding: { content: ["pkcs8", "sr25519"], type: ["none"], version: "3" },
|
|
13
|
+
meta: {},
|
|
14
|
+
...overrides,
|
|
15
|
+
});
|
|
16
|
+
const SLOW = { timeout: 60000 };
|
|
17
|
+
describe("getPair secret handling", SLOW, () => {
|
|
18
|
+
it("derives from a mnemonic", () => {
|
|
19
|
+
expect(getPair(DEV_PHRASE).address).toBe(new Keyring({ ss58Format: 42 }).addFromMnemonic(DEV_PHRASE).address);
|
|
20
|
+
});
|
|
21
|
+
it("derives from a hex seed", () => {
|
|
22
|
+
expect(u8aToHex(getPair(SEED_HEX).publicKey)).toBe(u8aToHex(sr25519FromSeed(SEED_32).publicKey));
|
|
23
|
+
});
|
|
24
|
+
it("derives from a suri with a hard derivation path", () => {
|
|
25
|
+
expect(u8aToHex(getPair(`${DEV_PHRASE}//Alice`).publicKey)).toBe(ALICE_PUBLIC);
|
|
26
|
+
});
|
|
27
|
+
it("prefers the mnemonic branch over the suri branch", () => {
|
|
28
|
+
const suri = `${DEV_PHRASE}//1`;
|
|
29
|
+
expect(getPair(suri).address).not.toBe(getPair(DEV_PHRASE).address);
|
|
30
|
+
});
|
|
31
|
+
it("parses a JSON string, taking the crypto type from its encoding", () => {
|
|
32
|
+
const pair = getPair(JSON.stringify(pairJson()));
|
|
33
|
+
expect(pair.type).toBe("sr25519");
|
|
34
|
+
expect(u8aToHex(pair.publicKey)).toBe(u8aToHex(new Uint8Array(32).fill(8)));
|
|
35
|
+
});
|
|
36
|
+
it("accepts a JSON object directly", () => {
|
|
37
|
+
expect(getPair(pairJson()).type).toBe("sr25519");
|
|
38
|
+
});
|
|
39
|
+
it("reports a missing secret when the string is neither key nor JSON", () => {
|
|
40
|
+
expect(() => getPair("this is not a secret")).toThrow();
|
|
41
|
+
});
|
|
42
|
+
it("reports a missing secret for JSON without an encoding block", () => {
|
|
43
|
+
expect(() => getPair('{"address":"x"}')).toThrow();
|
|
44
|
+
});
|
|
45
|
+
it("throws when neither a secret nor an account is given", () => {
|
|
46
|
+
expect(() => getPair()).toThrow();
|
|
47
|
+
});
|
|
48
|
+
it("throws when the secret is an empty string and no account is given", () => {
|
|
49
|
+
expect(() => getPair("")).toThrow();
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
describe("getPair account handling", SLOW, () => {
|
|
53
|
+
it("builds a watch-only pair from an address when no secret is given", () => {
|
|
54
|
+
const address = getPair(DEV_PHRASE).address;
|
|
55
|
+
const watchOnly = getPair(undefined, address);
|
|
56
|
+
expect(watchOnly.address).toBe(address);
|
|
57
|
+
expect(watchOnly.isLocked).toBe(true);
|
|
58
|
+
});
|
|
59
|
+
it("accepts a raw public key as the account", () => {
|
|
60
|
+
const pair = getPair(DEV_PHRASE);
|
|
61
|
+
expect(getPair(undefined, pair.publicKey).address).toBe(pair.address);
|
|
62
|
+
});
|
|
63
|
+
it("ignores the account once a secret is supplied", () => {
|
|
64
|
+
const other = getPair(`${DEV_PHRASE}//other`).address;
|
|
65
|
+
expect(getPair(DEV_PHRASE, other).address).toBe(getPair(DEV_PHRASE).address);
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
describe("getPair defaults", SLOW, () => {
|
|
69
|
+
it("defaults to sr25519 and ss58 format 42", () => {
|
|
70
|
+
const pair = getPair(DEV_PHRASE);
|
|
71
|
+
expect(pair.type).toBe("sr25519");
|
|
72
|
+
expect(pair.address).toBe(encodeAddress(pair.publicKey, 42));
|
|
73
|
+
});
|
|
74
|
+
it("honours an explicit ss58 format", () => {
|
|
75
|
+
const pair = getPair(DEV_PHRASE, undefined, "sr25519", 2);
|
|
76
|
+
expect(pair.address).toBe(encodeAddress(pair.publicKey, 2));
|
|
77
|
+
});
|
|
78
|
+
it("rejects a pair type the keyring does not support", () => {
|
|
79
|
+
expect(() => getPair(DEV_PHRASE, undefined, "ed25519")).toThrow("Expected a keyring type of either 'sr25519'");
|
|
80
|
+
});
|
|
81
|
+
it("treats ss58 format 0 as unset, because it is falsy", () => {
|
|
82
|
+
const pair = getPair(DEV_PHRASE, undefined, "sr25519", 0);
|
|
83
|
+
expect(pair.address).toBe(encodeAddress(pair.publicKey, 42));
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
//# sourceMappingURL=getPair.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getPair.test.js","sourceRoot":"","sources":["../../src/accounts/getPair.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mnemonic.test.d.ts","sourceRoot":"","sources":["../../src/accounts/mnemonic.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { u8aToHex } from "@polkadot/util";
|
|
2
|
+
import { mnemonicToMiniSecret, mnemonicValidate, sr25519FromSeed, } from "@prosopo/util-crypto";
|
|
3
|
+
import { describe, expect, it } from "vitest";
|
|
4
|
+
import { Keyring } from "../keyring/index.js";
|
|
5
|
+
import { generateMiniSecret, generateMnemonic } from "./mnemonic.js";
|
|
6
|
+
const SLOW = { timeout: 60000 };
|
|
7
|
+
describe("generateMnemonic", SLOW, () => {
|
|
8
|
+
it("returns a valid twelve word mnemonic and its address", async () => {
|
|
9
|
+
const [mnemonic, address] = await generateMnemonic();
|
|
10
|
+
expect(mnemonic.split(" ")).toHaveLength(12);
|
|
11
|
+
expect(mnemonicValidate(mnemonic)).toBe(true);
|
|
12
|
+
expect(address).toBe(new Keyring().addFromMnemonic(mnemonic).address);
|
|
13
|
+
});
|
|
14
|
+
it("generates a fresh mnemonic each call", async () => {
|
|
15
|
+
const [first] = await generateMnemonic();
|
|
16
|
+
const [second] = await generateMnemonic();
|
|
17
|
+
expect(second).not.toBe(first);
|
|
18
|
+
});
|
|
19
|
+
it("adds the account to a keyring it is given", async () => {
|
|
20
|
+
const keyring = new Keyring();
|
|
21
|
+
const [, address] = await generateMnemonic(keyring);
|
|
22
|
+
expect(keyring.getPairs()).toHaveLength(1);
|
|
23
|
+
expect(keyring.getPair(address).address).toBe(address);
|
|
24
|
+
});
|
|
25
|
+
it("uses a fresh keyring when none is passed, leaving no shared state", async () => {
|
|
26
|
+
const keyring = new Keyring();
|
|
27
|
+
await generateMnemonic();
|
|
28
|
+
expect(keyring.getPairs()).toEqual([]);
|
|
29
|
+
});
|
|
30
|
+
it("honours the requested pair type when it creates the keyring", async () => {
|
|
31
|
+
const [, address] = await generateMnemonic(undefined, "sr25519");
|
|
32
|
+
expect(typeof address).toBe("string");
|
|
33
|
+
await expect(generateMnemonic(undefined, "ed25519")).rejects.toThrow("Expected a keyring type of either 'sr25519'");
|
|
34
|
+
});
|
|
35
|
+
it("ignores the pair type when a keyring is supplied", async () => {
|
|
36
|
+
const keyring = new Keyring({ type: "sr25519" });
|
|
37
|
+
await expect(generateMnemonic(keyring, "ed25519")).resolves.toBeDefined();
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
describe("generateMiniSecret", SLOW, () => {
|
|
41
|
+
it("returns the 32 byte mini secret for the generated mnemonic", async () => {
|
|
42
|
+
const keyring = new Keyring();
|
|
43
|
+
const [secret, address] = await generateMiniSecret(keyring);
|
|
44
|
+
expect(secret).toHaveLength(32);
|
|
45
|
+
expect(u8aToHex(sr25519FromSeed(secret).publicKey)).toBe(u8aToHex(keyring.getPair(address).publicKey));
|
|
46
|
+
});
|
|
47
|
+
it("derives the secret from the same mnemonic it registered", async () => {
|
|
48
|
+
const keyring = new Keyring();
|
|
49
|
+
const [secret] = await generateMiniSecret(keyring);
|
|
50
|
+
const registered = keyring.getPairs()[0];
|
|
51
|
+
expect(registered).toBeDefined();
|
|
52
|
+
expect(u8aToHex(secret)).not.toBe(u8aToHex(new Uint8Array(32)));
|
|
53
|
+
});
|
|
54
|
+
it("agrees with mnemonicToMiniSecret for a known phrase", async () => {
|
|
55
|
+
const phrase = "bottom drive obey lake curtain smoke basket hold race lonely fit walk";
|
|
56
|
+
expect(u8aToHex(mnemonicToMiniSecret(phrase))).toHaveLength(66);
|
|
57
|
+
});
|
|
58
|
+
it("generates a fresh secret each call", async () => {
|
|
59
|
+
const [first] = await generateMiniSecret();
|
|
60
|
+
const [second] = await generateMiniSecret();
|
|
61
|
+
expect(u8aToHex(second)).not.toBe(u8aToHex(first));
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
//# sourceMappingURL=mnemonic.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mnemonic.test.js","sourceRoot":"","sources":["../../src/accounts/mnemonic.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"testAccounts.test.d.ts","sourceRoot":"","sources":["../../src/accounts/testAccounts.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { CaptchaType } from "@prosopo/types";
|
|
2
|
+
import { describe, expect, it } from "vitest";
|
|
3
|
+
import { DEV_PHRASE } from "../keyring/index.js";
|
|
4
|
+
import { getPair } from "./getPair.js";
|
|
5
|
+
import { getDefaultProviders, getDefaultSiteKeys } from "./testAccounts.js";
|
|
6
|
+
const SLOW = { timeout: 60000 };
|
|
7
|
+
describe("getDefaultSiteKeys", SLOW, () => {
|
|
8
|
+
it("provides one site per captcha type, in a stable order", () => {
|
|
9
|
+
expect(getDefaultSiteKeys().map((site) => site.settings.captchaType)).toEqual([
|
|
10
|
+
CaptchaType.image,
|
|
11
|
+
CaptchaType.pow,
|
|
12
|
+
CaptchaType.frictionless,
|
|
13
|
+
CaptchaType.puzzle,
|
|
14
|
+
]);
|
|
15
|
+
});
|
|
16
|
+
it("derives each site key from the dev phrase and its captcha type", () => {
|
|
17
|
+
for (const site of getDefaultSiteKeys()) {
|
|
18
|
+
expect(site.secret).toBe(`${DEV_PHRASE}//${site.settings.captchaType}`);
|
|
19
|
+
expect(site.address).toBe(getPair(site.secret).address);
|
|
20
|
+
expect(site.pair?.address).toBe(site.address);
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
it("gives every site a distinct address", () => {
|
|
24
|
+
const addresses = getDefaultSiteKeys().map((site) => site.address);
|
|
25
|
+
expect(new Set(addresses).size).toBe(addresses.length);
|
|
26
|
+
});
|
|
27
|
+
it("writes the settings explicitly rather than leaning on schema defaults", () => {
|
|
28
|
+
for (const site of getDefaultSiteKeys()) {
|
|
29
|
+
expect(site.settings.domains).toEqual(["localhost"]);
|
|
30
|
+
expect(site.settings.imageMaxRounds).toBe(2);
|
|
31
|
+
expect(site.settings.frictionlessThreshold).toBe(0.8);
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
it("returns a fresh array each call, so callers cannot corrupt the seed", () => {
|
|
35
|
+
const first = getDefaultSiteKeys();
|
|
36
|
+
const second = getDefaultSiteKeys();
|
|
37
|
+
expect(first).not.toBe(second);
|
|
38
|
+
first.pop();
|
|
39
|
+
expect(second).toHaveLength(4);
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
describe("getDefaultProviders", SLOW, () => {
|
|
43
|
+
it("provides a single local provider with a matching pair and address", () => {
|
|
44
|
+
const providers = getDefaultProviders();
|
|
45
|
+
expect(providers).toHaveLength(1);
|
|
46
|
+
const provider = providers[0];
|
|
47
|
+
expect(provider).toBeDefined();
|
|
48
|
+
if (!provider)
|
|
49
|
+
return;
|
|
50
|
+
expect(provider.url).toBe("https://localhost:9229");
|
|
51
|
+
expect(provider.address).toBe(provider.pair?.address);
|
|
52
|
+
});
|
|
53
|
+
it("points at the checked-in dev dataset", () => {
|
|
54
|
+
const provider = getDefaultProviders()[0];
|
|
55
|
+
expect(provider?.datasetFile).toBe("./dev/data/captchas.json");
|
|
56
|
+
expect(provider?.captchaDatasetId).toMatch(/^0x[0-9a-f]{64}$/);
|
|
57
|
+
});
|
|
58
|
+
it("is deterministic across calls", () => {
|
|
59
|
+
expect(getDefaultProviders()[0]?.address).toBe(getDefaultProviders()[0]?.address);
|
|
60
|
+
});
|
|
61
|
+
it("does not reuse a site key as the provider key", () => {
|
|
62
|
+
const siteAddresses = new Set(getDefaultSiteKeys().map((site) => site.address));
|
|
63
|
+
expect(siteAddresses.has(getDefaultProviders()[0]?.address ?? "")).toBe(false);
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
//# sourceMappingURL=testAccounts.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"testAccounts.test.js","sourceRoot":"","sources":["../../src/accounts/testAccounts.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keyring.test.d.ts","sourceRoot":"","sources":["../../src/keyring/keyring.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
import { u8aToHex } from "@polkadot/util";
|
|
2
|
+
import { decodeAddress, encodeAddress, mnemonicToMiniSecret, sr25519FromSeed, } from "@prosopo/util-crypto";
|
|
3
|
+
import { describe, expect, it } from "vitest";
|
|
4
|
+
import { DEV_PHRASE, Keyring } from "./keyring.js";
|
|
5
|
+
const ALICE_SURI = `${DEV_PHRASE}//Alice`;
|
|
6
|
+
const ALICE_PUBLIC = "0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d";
|
|
7
|
+
const SEED_32 = new Uint8Array(32).fill(1);
|
|
8
|
+
const SLOW = { timeout: 60000 };
|
|
9
|
+
describe("Keyring construction", SLOW, () => {
|
|
10
|
+
it("defaults to sr25519", () => {
|
|
11
|
+
expect(new Keyring().type).toBe("sr25519");
|
|
12
|
+
expect(new Keyring({}).type).toBe("sr25519");
|
|
13
|
+
});
|
|
14
|
+
it("accepts an explicit sr25519 type", () => {
|
|
15
|
+
expect(new Keyring({ type: "sr25519" }).type).toBe("sr25519");
|
|
16
|
+
});
|
|
17
|
+
it("rejects every other curve, naming what it found", () => {
|
|
18
|
+
for (const type of ["ed25519", "ecdsa", "ethereum"]) {
|
|
19
|
+
expect(() => new Keyring({ type })).toThrow(`Expected a keyring type of either 'sr25519', found '${type}`);
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
it("starts with no pairs", () => {
|
|
23
|
+
const keyring = new Keyring();
|
|
24
|
+
expect(keyring.pairs).toEqual([]);
|
|
25
|
+
expect(keyring.getPairs()).toEqual([]);
|
|
26
|
+
expect(keyring.publicKeys).toEqual([]);
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
describe("Keyring address encoding", SLOW, () => {
|
|
30
|
+
it("uses the configured ss58 format", () => {
|
|
31
|
+
const publicKey = new Uint8Array(32).fill(2);
|
|
32
|
+
expect(new Keyring({ ss58Format: 42 }).encodeAddress(publicKey)).toBe(encodeAddress(publicKey, 42));
|
|
33
|
+
expect(new Keyring({ ss58Format: 2 }).encodeAddress(publicKey)).toBe(encodeAddress(publicKey, 2));
|
|
34
|
+
});
|
|
35
|
+
it("lets an explicit format override the configured one", () => {
|
|
36
|
+
const publicKey = new Uint8Array(32).fill(3);
|
|
37
|
+
expect(new Keyring({ ss58Format: 42 }).encodeAddress(publicKey, 2)).toBe(encodeAddress(publicKey, 2));
|
|
38
|
+
});
|
|
39
|
+
it("applies a format set after construction to new pairs", () => {
|
|
40
|
+
const keyring = new Keyring({ ss58Format: 42 });
|
|
41
|
+
const before = keyring.addFromUri(ALICE_SURI).address;
|
|
42
|
+
keyring.setSS58Format(2);
|
|
43
|
+
const after = keyring.addFromUri(ALICE_SURI).address;
|
|
44
|
+
expect(after).not.toBe(before);
|
|
45
|
+
expect(decodeAddress(after).toString()).toBe(decodeAddress(before).toString());
|
|
46
|
+
});
|
|
47
|
+
it("exposes decodeAddress as the inverse of its own encoding", () => {
|
|
48
|
+
const keyring = new Keyring({ ss58Format: 42 });
|
|
49
|
+
const publicKey = new Uint8Array(32).fill(4);
|
|
50
|
+
expect(keyring.decodeAddress(keyring.encodeAddress(publicKey))).toEqual(publicKey);
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
describe("Keyring.createFromUri", SLOW, () => {
|
|
54
|
+
it("derives the well-known Alice key from the dev phrase", () => {
|
|
55
|
+
const pair = new Keyring().createFromUri(ALICE_SURI);
|
|
56
|
+
expect(u8aToHex(pair.publicKey)).toBe(ALICE_PUBLIC);
|
|
57
|
+
});
|
|
58
|
+
it("expands a bare hard-derivation path against the dev phrase", () => {
|
|
59
|
+
expect(u8aToHex(new Keyring().createFromUri("//Alice").publicKey)).toBe(ALICE_PUBLIC);
|
|
60
|
+
});
|
|
61
|
+
it("does not create the pair in the keyring", () => {
|
|
62
|
+
const keyring = new Keyring();
|
|
63
|
+
keyring.createFromUri(ALICE_SURI);
|
|
64
|
+
expect(keyring.getPairs()).toEqual([]);
|
|
65
|
+
});
|
|
66
|
+
it("treats a 256-bit hex phrase as a raw seed", () => {
|
|
67
|
+
const seedHex = u8aToHex(SEED_32);
|
|
68
|
+
expect(u8aToHex(new Keyring().createFromUri(seedHex).publicKey)).toBe(u8aToHex(sr25519FromSeed(SEED_32).publicKey));
|
|
69
|
+
});
|
|
70
|
+
it("pads a short non-mnemonic phrase out to 32 bytes", () => {
|
|
71
|
+
const pair = new Keyring().createFromUri("hello");
|
|
72
|
+
const padded = new Uint8Array(32).fill(32);
|
|
73
|
+
padded.set(new TextEncoder().encode("hello"));
|
|
74
|
+
expect(u8aToHex(pair.publicKey)).toBe(u8aToHex(sr25519FromSeed(padded).publicKey));
|
|
75
|
+
});
|
|
76
|
+
it("rejects a phrase that is neither a mnemonic nor short enough to pad", () => {
|
|
77
|
+
expect(() => new Keyring().createFromUri("x".repeat(33))).toThrow("specified phrase is not a valid mnemonic and is invalid as a raw seed at > 32 bytes");
|
|
78
|
+
});
|
|
79
|
+
it("accepts a 32 character phrase at the padding boundary", () => {
|
|
80
|
+
expect(() => new Keyring().createFromUri("x".repeat(32))).not.toThrow();
|
|
81
|
+
});
|
|
82
|
+
it("derives a 12 word mnemonic through the mini secret rather than padding", () => {
|
|
83
|
+
expect(u8aToHex(new Keyring().createFromUri(DEV_PHRASE).publicKey)).toBe(u8aToHex(sr25519FromSeed(mnemonicToMiniSecret(DEV_PHRASE)).publicKey));
|
|
84
|
+
});
|
|
85
|
+
it("treats a word count outside the mnemonic set as a raw phrase", () => {
|
|
86
|
+
expect(() => new Keyring().createFromUri(`${DEV_PHRASE} extra`)).toThrow("is not a valid mnemonic");
|
|
87
|
+
});
|
|
88
|
+
it("gives a different key for a different password", () => {
|
|
89
|
+
const plain = new Keyring().createFromUri(DEV_PHRASE);
|
|
90
|
+
const withPassword = new Keyring().createFromUri(`${DEV_PHRASE}///pass`);
|
|
91
|
+
expect(u8aToHex(withPassword.publicKey)).not.toBe(u8aToHex(plain.publicKey));
|
|
92
|
+
});
|
|
93
|
+
it("distinguishes soft and hard derivation of the same name", () => {
|
|
94
|
+
const soft = new Keyring().createFromUri(`${DEV_PHRASE}/Alice`);
|
|
95
|
+
const hard = new Keyring().createFromUri(ALICE_SURI);
|
|
96
|
+
expect(u8aToHex(soft.publicKey)).not.toBe(u8aToHex(hard.publicKey));
|
|
97
|
+
});
|
|
98
|
+
it("carries meta through to the pair", () => {
|
|
99
|
+
const pair = new Keyring().createFromUri(ALICE_SURI, { name: "alice" });
|
|
100
|
+
expect(pair.meta.name).toBe("alice");
|
|
101
|
+
});
|
|
102
|
+
it("refuses ethereum derivation for a mnemonic", () => {
|
|
103
|
+
expect(() => new Keyring().createFromUri(DEV_PHRASE, {}, "ethereum")).toThrow("Not implemented - Prosopo Keyring supports sr25519 only");
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
describe("Keyring add* methods", SLOW, () => {
|
|
107
|
+
it("stores a pair created from a uri and returns it on lookup", () => {
|
|
108
|
+
const keyring = new Keyring();
|
|
109
|
+
const pair = keyring.addFromUri(ALICE_SURI);
|
|
110
|
+
expect(keyring.getPairs()).toEqual([pair]);
|
|
111
|
+
expect(keyring.getPair(pair.address)).toBe(pair);
|
|
112
|
+
expect(keyring.getPair(pair.publicKey)).toBe(pair);
|
|
113
|
+
});
|
|
114
|
+
it("treats addFromMnemonic as addFromUri", () => {
|
|
115
|
+
const fromMnemonic = new Keyring().addFromMnemonic(DEV_PHRASE);
|
|
116
|
+
const fromUri = new Keyring().addFromUri(DEV_PHRASE);
|
|
117
|
+
expect(fromMnemonic.address).toBe(fromUri.address);
|
|
118
|
+
});
|
|
119
|
+
it("derives a pair from a raw seed", () => {
|
|
120
|
+
const pair = new Keyring().addFromSeed(SEED_32);
|
|
121
|
+
expect(u8aToHex(pair.publicKey)).toBe(u8aToHex(sr25519FromSeed(SEED_32).publicKey));
|
|
122
|
+
});
|
|
123
|
+
it("refuses a seed for an unimplemented curve", () => {
|
|
124
|
+
expect(() => new Keyring().addFromSeed(SEED_32, {}, "ed25519")).toThrow("Not Implemented");
|
|
125
|
+
});
|
|
126
|
+
it("adds an address-only pair that has no secret and cannot sign", () => {
|
|
127
|
+
const keyring = new Keyring();
|
|
128
|
+
const address = keyring.addFromUri(ALICE_SURI).address;
|
|
129
|
+
const watchOnly = new Keyring().addFromAddress(address);
|
|
130
|
+
expect(watchOnly.address).toBe(address);
|
|
131
|
+
expect(watchOnly.isLocked).toBe(true);
|
|
132
|
+
expect(() => watchOnly.sign(new Uint8Array([1]))).toThrow();
|
|
133
|
+
});
|
|
134
|
+
it("adds a pair from an explicit keypair", () => {
|
|
135
|
+
const keypair = sr25519FromSeed(SEED_32);
|
|
136
|
+
const keyring = new Keyring();
|
|
137
|
+
const pair = keyring.addFromPair(keypair, { name: "explicit" });
|
|
138
|
+
expect(u8aToHex(pair.publicKey)).toBe(u8aToHex(keypair.publicKey));
|
|
139
|
+
expect(pair.meta.name).toBe("explicit");
|
|
140
|
+
expect(keyring.getPairs()).toEqual([pair]);
|
|
141
|
+
});
|
|
142
|
+
it("exposes public keys for every stored pair", () => {
|
|
143
|
+
const keyring = new Keyring();
|
|
144
|
+
const first = keyring.addFromUri(ALICE_SURI);
|
|
145
|
+
const second = keyring.addFromUri(`${DEV_PHRASE}//Bob`);
|
|
146
|
+
expect(keyring.publicKeys).toEqual([first.publicKey, second.publicKey]);
|
|
147
|
+
});
|
|
148
|
+
it("removes a pair", () => {
|
|
149
|
+
const keyring = new Keyring();
|
|
150
|
+
const pair = keyring.addFromUri(ALICE_SURI);
|
|
151
|
+
keyring.removePair(pair.address);
|
|
152
|
+
expect(keyring.pairs).toEqual([]);
|
|
153
|
+
expect(() => keyring.getPair(pair.address)).toThrow("Unable to retrieve keypair");
|
|
154
|
+
});
|
|
155
|
+
it("keeps addPair and the pairs getter in agreement", () => {
|
|
156
|
+
const keyring = new Keyring();
|
|
157
|
+
const pair = keyring.createFromUri(ALICE_SURI);
|
|
158
|
+
expect(keyring.addPair(pair)).toBe(pair);
|
|
159
|
+
expect(keyring.pairs).toEqual(keyring.getPairs());
|
|
160
|
+
});
|
|
161
|
+
});
|
|
162
|
+
describe("Keyring.createFromJson", SLOW, () => {
|
|
163
|
+
const json = (overrides = {}) => ({
|
|
164
|
+
address: encodeAddress(new Uint8Array(32).fill(5), 42),
|
|
165
|
+
encoded: "0x00",
|
|
166
|
+
encoding: {
|
|
167
|
+
content: ["pkcs8", "sr25519"],
|
|
168
|
+
type: ["none"],
|
|
169
|
+
version: "3",
|
|
170
|
+
},
|
|
171
|
+
meta: { name: "from-json" },
|
|
172
|
+
...overrides,
|
|
173
|
+
});
|
|
174
|
+
it("round trips address, meta and type", () => {
|
|
175
|
+
const pair = new Keyring().createFromJson(json());
|
|
176
|
+
expect(pair.meta.name).toBe("from-json");
|
|
177
|
+
expect(pair.type).toBe("sr25519");
|
|
178
|
+
expect(u8aToHex(pair.publicKey)).toBe(u8aToHex(new Uint8Array(32).fill(5)));
|
|
179
|
+
});
|
|
180
|
+
it("accepts a hex address as the public key directly", () => {
|
|
181
|
+
const pair = new Keyring().createFromJson(json({ address: ALICE_PUBLIC }));
|
|
182
|
+
expect(u8aToHex(pair.publicKey)).toBe(ALICE_PUBLIC);
|
|
183
|
+
});
|
|
184
|
+
it("rejects a v3 file that is not pkcs8", () => {
|
|
185
|
+
expect(() => new Keyring().createFromJson(json({
|
|
186
|
+
encoding: {
|
|
187
|
+
content: ["none", "sr25519"],
|
|
188
|
+
type: ["none"],
|
|
189
|
+
version: "3",
|
|
190
|
+
},
|
|
191
|
+
}))).toThrow("Unable to decode non-pkcs8 type");
|
|
192
|
+
});
|
|
193
|
+
it("falls back to the keyring type for a v0 file", () => {
|
|
194
|
+
const pair = new Keyring().createFromJson(json({
|
|
195
|
+
encoding: {
|
|
196
|
+
content: ["pkcs8", "ed25519"],
|
|
197
|
+
type: ["none"],
|
|
198
|
+
version: "0",
|
|
199
|
+
},
|
|
200
|
+
}));
|
|
201
|
+
expect(pair.type).toBe("sr25519");
|
|
202
|
+
});
|
|
203
|
+
it("rejects a crypto type this keyring cannot handle", () => {
|
|
204
|
+
expect(() => new Keyring().createFromJson(json({
|
|
205
|
+
encoding: {
|
|
206
|
+
content: ["pkcs8", "ed25519"],
|
|
207
|
+
type: ["none"],
|
|
208
|
+
version: "3",
|
|
209
|
+
},
|
|
210
|
+
}))).toThrow("Unknown crypto type ed25519");
|
|
211
|
+
});
|
|
212
|
+
it("normalises a single encoding type into a list", () => {
|
|
213
|
+
expect(() => new Keyring().createFromJson(json({
|
|
214
|
+
encoding: {
|
|
215
|
+
content: ["pkcs8", "sr25519"],
|
|
216
|
+
type: "none",
|
|
217
|
+
version: "3",
|
|
218
|
+
},
|
|
219
|
+
}))).not.toThrow();
|
|
220
|
+
});
|
|
221
|
+
it("stores the pair when added rather than created", () => {
|
|
222
|
+
const keyring = new Keyring();
|
|
223
|
+
const pair = keyring.addFromJson(json());
|
|
224
|
+
expect(keyring.getPairs()).toEqual([pair]);
|
|
225
|
+
});
|
|
226
|
+
});
|
|
227
|
+
describe("Keyring.toJson", SLOW, () => {
|
|
228
|
+
it("delegates to the stored pair", () => {
|
|
229
|
+
const keyring = new Keyring();
|
|
230
|
+
const pair = keyring.addFromUri(ALICE_SURI);
|
|
231
|
+
const asJson = keyring.toJson(pair.address);
|
|
232
|
+
expect(asJson.address).toBe(pair.address);
|
|
233
|
+
expect(asJson.encoding.content).toContain("sr25519");
|
|
234
|
+
});
|
|
235
|
+
it("throws for an address it does not hold", () => {
|
|
236
|
+
expect(() => new Keyring().toJson(encodeAddress(new Uint8Array(32).fill(6), 42))).toThrow("Unable to retrieve keypair");
|
|
237
|
+
});
|
|
238
|
+
});
|
|
239
|
+
//# sourceMappingURL=keyring.test.js.map
|