Compare commits
522
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7f23d0a609
|
||
|
|
49f3442e5c
|
||
|
|
b39241c840
|
||
|
|
74e1e0cc6a
|
||
|
|
e55352aa4e
|
||
|
|
f7dc72e32c
|
||
|
|
506b77351c
|
||
|
|
2bffbc62bc
|
||
|
|
c616a0d949
|
||
|
|
6ed8b1ea6d
|
||
|
|
9281daa14c | ||
|
|
c7ed69fe55 | ||
|
|
22a1246672 | ||
|
|
4a5b6acc78 | ||
|
|
152d4609a4 | ||
|
|
4ab957e568 | ||
|
|
610c8bb15f | ||
|
|
372d460f1a | ||
|
|
a8732a99aa | ||
|
|
8d3cb0eb6b | ||
|
|
fe0886be23 | ||
|
|
bac357ae10 | ||
|
|
4ab7a5bfe0 | ||
|
|
440b146a24 | ||
|
|
ae0735ccda | ||
|
|
57551b38a0 | ||
|
|
bf63a0ebf6 | ||
|
|
d78344d000 | ||
|
|
169a702c88 | ||
|
|
b4d73ef49a | ||
|
|
21ef853fbd | ||
|
|
a4d940cb69 | ||
|
|
6423537dbe | ||
|
|
61125b3582 | ||
|
|
7d77f89f34 | ||
|
|
bee7204f95 | ||
|
|
bb0715ec2f | ||
|
|
2212f31f9a | ||
|
|
047840319e | ||
|
|
3fbf0b98c2 | ||
|
|
e6b0411e9c | ||
|
|
6e8199bab7 | ||
|
|
8ca4525570 | ||
|
|
0c3a71145a | ||
|
|
9c1be4f19b | ||
|
|
e5e6bdd814 | ||
|
|
55a3201bd5 | ||
|
|
de2538c18d | ||
|
|
e8dced9fed | ||
|
|
0afe1144d1 | ||
|
|
5a04d67bb2 | ||
|
|
41481c1e3a | ||
|
|
8a8b583f81 | ||
|
|
03c8169cd9 | ||
|
|
f9ee358442 | ||
|
|
ef5cfc728c | ||
|
|
88b8a54018 | ||
|
|
8c666725b2 | ||
|
|
daabdfac45 | ||
|
|
538359fd49 | ||
|
|
df044669e2 | ||
|
|
60374f417a | ||
|
|
5235009f4c | ||
|
|
21bfff5a51 | ||
|
|
963025daab | ||
|
|
ec7ef17b64 | ||
|
|
ef94fed1fe | ||
|
|
43ac361806 | ||
|
|
2bc18cfdbb | ||
|
|
be7df03e7c | ||
|
|
0ae44ed34e | ||
|
|
09d54ea200 | ||
|
|
457ea1a0b7 | ||
|
|
972363a5bb | ||
|
|
e59fe6fd22 | ||
|
|
35f9f4468b | ||
|
|
802174d6ad | ||
|
|
d690abea02 | ||
|
|
26a762ae2e | ||
|
|
9d49bcde75 | ||
|
|
8b0f5bf46e | ||
|
|
a75d8761da | ||
|
|
a58fb0bbff | ||
|
|
0467c410c8 | ||
|
|
095095074e | ||
|
|
18a6764841 | ||
|
|
0e0de687c3 | ||
|
|
6197a897aa | ||
|
|
0f7954a89b | ||
|
|
e056618d2e | ||
|
|
82a485cc9c | ||
|
|
2cbea7bf8d | ||
|
|
748f670351 | ||
|
|
5b2749073f | ||
|
|
a328ab4409 | ||
|
|
e25bb48ba9 | ||
|
|
8456870148 | ||
|
|
6f8caad80f | ||
|
|
25fe5f4e27 | ||
|
|
da2edf0aa0 | ||
|
|
eb7b24f9aa | ||
|
|
f4e93cf2c2 | ||
|
|
85b2da734c | ||
|
|
5d03be1084 | ||
|
|
2261862097 | ||
|
|
20d3af56ec | ||
|
|
367633a612 | ||
|
|
b127f678e9 | ||
|
|
3404ad2945 | ||
|
|
4059615d66 | ||
|
|
be9739ee9f | ||
|
|
6ec09907a2 | ||
|
|
677a778833 | ||
|
|
fa90f0a747 | ||
|
|
e721c4f508 | ||
|
|
7f5bd09322 | ||
|
|
5d6244fc0b | ||
|
|
58f12c4257 | ||
|
|
038d20b5e7 | ||
|
|
c9d8c52567 | ||
|
|
3b85773636 | ||
|
|
269740b775 | ||
|
|
fc732b8c44 | ||
|
|
2c4deb3f9d | ||
|
|
ebcb6857ad | ||
|
|
0ff31d7980 | ||
|
|
d897f25546 | ||
|
|
3c431d5a01 | ||
|
|
55ae71125d | ||
|
|
fcd8cee7f6 | ||
|
|
8aa4e60c4c | ||
|
|
85665dfa20 | ||
|
|
5f8f3e6309 | ||
|
|
166845e367 | ||
|
|
7c7233efd1 | ||
|
|
cb7f0da916 | ||
|
|
7d654c236f | ||
|
|
6b4d9aac29 | ||
|
|
4f863ddc29 | ||
|
|
a4a85a3a5d | ||
|
|
2a6669c25d | ||
|
|
cb4c9fd90a | ||
|
|
28beb44374 | ||
|
|
4a4847b032 | ||
|
|
506c20a900 | ||
|
|
736656f34f | ||
|
|
31274916f9 | ||
|
|
6e1afdc2f8 | ||
|
|
fd26d223be | ||
|
|
86d8c81c27 | ||
|
|
2de22cbb31 | ||
|
|
c1b8098b9e | ||
|
|
ee0ed25a83 | ||
|
|
7ef452bdf0 | ||
|
|
eb41ab5bed | ||
|
|
6947b1e4d9 | ||
|
|
527b4f0eeb | ||
|
|
44f7443d13 | ||
|
|
2b800577a5 | ||
|
|
c9ca01e96b | ||
|
|
ca93f3337f | ||
|
|
557a681fe9 | ||
|
|
97b1fdf089 | ||
|
|
9971684972 | ||
|
|
04ab9dd77d | ||
|
|
b2bf9f4d53 | ||
|
|
4d629fd8ce | ||
|
|
37fa211fdb | ||
|
|
a4a9a3dead | ||
|
|
e025195a9b | ||
|
|
744e4c72d5 | ||
|
|
f23f0944a8 | ||
|
|
6e28612f34 | ||
|
|
57b0601f9b | ||
|
|
ee9d76639c | ||
|
|
db25938ad7 | ||
|
|
175b0ef307 | ||
|
|
944c50d015 | ||
|
|
191db8ea10 | ||
|
|
095db555ba | ||
|
|
a23989ca9d | ||
|
|
a82ebdf6f9 | ||
|
|
e6fbf01aa1 | ||
|
|
00876f0b64 | ||
|
|
22aab4a4e6 | ||
|
|
6971012f4a | ||
|
|
fc217b66ce | ||
|
|
fb42e8f7ee | ||
|
|
b4e3ed0a42 | ||
|
|
e1218157a3 | ||
|
|
2dc171639d | ||
|
|
4da1e8ba62 | ||
|
|
d498ad4424 | ||
|
|
9a9650261b | ||
|
|
6dfff0d40c | ||
|
|
0770bed5fd | ||
|
|
6fde7bc5a0 | ||
|
|
f55e88c116 | ||
|
|
abd4cfdd1f | ||
|
|
f261ea2924 | ||
|
|
f14d2681b1 | ||
|
|
b9be030f12 | ||
|
|
bc103d9479 | ||
|
|
c76c754741 | ||
|
|
bd21e730b3 | ||
|
|
a2cfdb8ca7 | ||
|
|
4857de9f38 | ||
|
|
d525b8c92d | ||
|
|
2afbce2652 | ||
|
|
3c7525649e | ||
|
|
6ebcc2dd6d | ||
|
|
120438d7e6 | ||
|
|
f5f1bc6f4f | ||
|
|
28d5302fd6 | ||
|
|
773cc29b11 | ||
|
|
a20c7eb2e5 | ||
|
|
487d0d9a57 | ||
|
|
a910e9ce6f | ||
|
|
1062de7aa8 | ||
|
|
4cabc67b24 | ||
|
|
13bc84e30b | ||
|
|
67fe7738d8 | ||
|
|
13c6b4e553 | ||
|
|
9306f9db92 | ||
|
|
62a30f258e | ||
|
|
81609aba59 | ||
|
|
301d73d13f | ||
|
|
92abf4463d | ||
|
|
b018f78b77 | ||
|
|
608117f04a | ||
|
|
2ac00565b0 | ||
|
|
673a59af58 | ||
|
|
aa394fe7cd | ||
|
|
ee7f2cc7f5 | ||
|
|
da6efc821e | ||
|
|
a3b884d437 | ||
|
|
560c054750 | ||
|
|
09621d0010 | ||
|
|
37a81d9594 | ||
|
|
62182bae03 | ||
|
|
2ee03a5f81 | ||
|
|
7a5a88a135 | ||
|
|
f4e0e2111f | ||
|
|
aac902011e | ||
|
|
a030330808 | ||
|
|
d108beafd4 | ||
|
|
90e20ed4d2 | ||
|
|
723ec10fa1 | ||
|
|
cf9082e03a | ||
|
|
3dce4fe04a | ||
|
|
55ebc4f0d9 | ||
|
|
ce2122e9fa | ||
|
|
0fb55fe633 | ||
|
|
adca13bc8c | ||
|
|
b939c3593c | ||
|
|
aa70b81a89 | ||
|
|
f3e1d6beda | ||
|
|
754bc4dc21 | ||
|
|
a8df82dfe0 | ||
|
|
4ff56f5cfe | ||
|
|
1fd9f04458 | ||
|
|
a28306f487 | ||
|
|
19941bcb61 | ||
|
|
2cb85866ab | ||
|
|
8556de1fa2 | ||
|
|
143d070d21 | ||
|
|
2a53b1121e | ||
|
|
0733137f79 | ||
|
|
cc918660cb | ||
|
|
3527f8c7d9 | ||
|
|
41caf2fd6d | ||
|
|
d407513dd1 | ||
|
|
bd76349552 | ||
|
|
0ec894b732 | ||
|
|
be4cb52dd3 | ||
|
|
456eaeeb94 | ||
|
|
0ec50b6159 | ||
|
|
98336fd2e5 | ||
|
|
7b3bbd3ef2 | ||
|
|
49afd1fe09 | ||
|
|
0df17104d5 | ||
|
|
db8434559e | ||
|
|
eaf9d97ae3 | ||
|
|
3e6d86b768 | ||
|
|
8aab41648e | ||
|
|
4a535c08c7 | ||
|
|
715486d54e | ||
|
|
1073dc14aa | ||
|
|
5cca95e855 | ||
|
|
942b623273 | ||
|
|
eea99656ad | ||
|
|
04b6df9ac5 | ||
|
|
d5132b56de | ||
|
|
1fdc2c8dae | ||
|
|
b6a2693e5f | ||
|
|
8b3687e062 | ||
|
|
3a8429b687 | ||
|
|
26e9b01198 | ||
|
|
76d71d946d | ||
|
|
0ebc7bd374 | ||
|
|
d94c126744 | ||
|
|
86597dcb17 | ||
|
|
1be682827b | ||
|
|
081b6b4f2b | ||
|
|
7dc38e78cf | ||
|
|
dcf214f250 | ||
|
|
2e82528e1b | ||
|
|
090b91910f | ||
|
|
058d197646 | ||
|
|
0fca8904e6 | ||
|
|
0bf7bc416a | ||
|
|
ea08763307 | ||
|
|
5272645abe | ||
|
|
e5373c35c8 | ||
|
|
b73b96e412 | ||
|
|
18d24bf509 | ||
|
|
fe230f143f | ||
|
|
6357c1e040 | ||
|
|
1876efe13e | ||
|
|
9de142b5f6 | ||
|
|
e5cb0ba2b4 | ||
|
|
dba5d3e7b3 | ||
|
|
8ccfecfff8 | ||
|
|
f2e79ffe67 | ||
|
|
e7f595a11f | ||
|
|
770471aef0 | ||
|
|
6b1ff0036e | ||
|
|
fee81b89ac | ||
|
|
c4d5b8e1ae | ||
|
|
5674b1df67 | ||
|
|
5ccb3e85f8 | ||
|
|
785a23433d | ||
|
|
bead42ca5f | ||
|
|
2d2a1a5989 | ||
|
|
db4dde0a57 | ||
|
|
b5d83f8836 | ||
|
|
cdf6cc6096 | ||
|
|
dfd07e04d4 | ||
|
|
f5a3a6fd73 | ||
|
|
51a7263d38 | ||
|
|
e3b11360ab | ||
|
|
b4bed3d801 | ||
|
|
1f8b573d81 | ||
|
|
a0e5d48208 | ||
|
|
6ce32b8039 | ||
|
|
3ee810904e | ||
|
|
ed73a7912b | ||
|
|
4ec2cf9e43 | ||
|
|
38ac05203e | ||
|
|
bb6a2b4468 | ||
|
|
3c9b20e902 | ||
|
|
e1a2ea49cb | ||
|
|
892004563f | ||
|
|
efe4ce8d9d | ||
|
|
f0f561e243 | ||
|
|
56e34586b3 | ||
|
|
667fe8fb17 | ||
|
|
3fd8074877 | ||
|
|
91a2eac220 | ||
|
|
455ae2ccde | ||
|
|
9d43b787fd | ||
|
|
29551e46b0 | ||
|
|
103745f845 | ||
|
|
cd7a32cf1f | ||
|
|
5004d1d79f | ||
|
|
2607203925 | ||
|
|
5abab5bf13 | ||
|
|
a990b4e40f | ||
|
|
997f8f6a51 | ||
|
|
23e055869c | ||
|
|
de85d063a4 | ||
|
|
5964f790b5 | ||
|
|
a767ef68ca | ||
|
|
c096a4981d | ||
|
|
7dcdef17c3 | ||
|
|
ef839a7a42 | ||
|
|
7bf1706994 | ||
|
|
2999987fb0 | ||
|
|
6ba45086b5 | ||
|
|
e3c51d4b6b | ||
|
|
1295c85df3 | ||
|
|
14d66c32de | ||
|
|
b794d22ac4 | ||
|
|
edb62407e2 | ||
|
|
45b040fbf8 | ||
|
|
777b823317 | ||
|
|
c5ef717398 | ||
|
|
98f0933da5 | ||
|
|
493d0df0c1 | ||
|
|
5d8e92f17c | ||
|
|
2ce178cad2 | ||
|
|
9ccac88372 | ||
|
|
0aa441de96 | ||
|
|
78941a3cde | ||
|
|
514570a5fb | ||
|
|
ad2da94408 | ||
|
|
803edbb8cc | ||
|
|
94692cbbb4 | ||
|
|
0a27c23439 | ||
|
|
0a1cfb15ef | ||
|
|
cd494d7de0 | ||
|
|
4f5029118e | ||
|
|
2df8d01186 | ||
|
|
f1b3240728 | ||
|
|
748b26924e | ||
|
|
26f6572f29 | ||
|
|
8e3a75ed8d | ||
|
|
c13d1b4ae6 | ||
|
|
17388b7865 | ||
|
|
85785be8cf | ||
|
|
211af1f999 | ||
|
|
b8116fcf5a | ||
|
|
79593b0a70 | ||
|
|
4ecf53dcf4 | ||
|
|
5652023c5a | ||
|
|
f6e667df26 | ||
|
|
aeac277590 | ||
|
|
dca3f17b1c | ||
|
|
b22b225252 | ||
|
|
6d1944bef9 | ||
|
|
357b5feb2e | ||
|
|
354a2a4eaa | ||
|
|
3fd61e678a | ||
|
|
71d2802f00 | ||
|
|
816e30fb0a | ||
|
|
77c6177c9a | ||
|
|
9f97924d33 | ||
|
|
d7d8edcc9b | ||
|
|
d6047e38d3 | ||
|
|
5f44768796 | ||
|
|
9c224f5076 | ||
|
|
bcb7861d88 | ||
|
|
0b85a4d5e2 | ||
|
|
c17ef47548 | ||
|
|
df7f533491 | ||
|
|
500a38e1ab | ||
|
|
3437fb65cd | ||
|
|
3d43aba4a1 | ||
|
|
7cd5204fb7 | ||
|
|
3fdf3b5523 | ||
|
|
8fd0fe846f | ||
|
|
130a59fb02 | ||
|
|
e6aec6d178 | ||
|
|
6fb73f3124 | ||
|
|
ea96abc1a4 | ||
|
|
9c08fa6206 | ||
|
|
8edb2abe30 | ||
|
|
3e2c3a6ed8 | ||
|
|
1e35c5cd25 | ||
|
|
40dc599acc | ||
|
|
d1d6fc631c | ||
|
|
28c6139068 | ||
|
|
b00d8573fd | ||
|
|
6afebd70d0 | ||
|
|
1f4d423682 | ||
|
|
57718cacfb | ||
|
|
b51d4e13fb | ||
|
|
08af19e2d5 | ||
|
|
9830457c9a | ||
|
|
4619ab6668 | ||
|
|
d886c02b23 | ||
|
|
7d745661b7 | ||
|
|
da9c2bc10b | ||
|
|
eab8d44487 | ||
|
|
19ecae37dd | ||
|
|
3d3e46cb77 | ||
|
|
e09027e83d | ||
|
|
c544e0b478 | ||
|
|
f914061365 | ||
|
|
55e4e8209e | ||
|
|
193c9ebb37 | ||
|
|
5d67d92454 | ||
|
|
3a0d566f60 | ||
|
|
675f1e71b5 | ||
|
|
4bbf38c7e4 | ||
|
|
fd76246c11 | ||
|
|
0b14539a98 | ||
|
|
09b1a0e6e3 | ||
|
|
03e64c9120 | ||
|
|
f848c87fde | ||
|
|
46a05b6a60 | ||
|
|
a9f671b501 | ||
|
|
f1187f5981 | ||
|
|
4134bf8a85 | ||
|
|
4709a62c0b | ||
|
|
900cf21bc5 | ||
|
|
fa8229de06 | ||
|
|
913bf65dab | ||
|
|
769b953983 | ||
|
|
2949e12c55 | ||
|
|
1664a8d8a2 | ||
|
|
ab71a25b96 | ||
|
|
02c1a95ea1 | ||
|
|
3ee6830c0e | ||
|
|
642724ab6d | ||
|
|
022756e6dd | ||
|
|
e29003f51e | ||
|
|
e5c2f8f529 | ||
|
|
f7ce22b158 | ||
|
|
0028d212e4 | ||
|
|
719c48f8f2 | ||
|
|
b137f8ec8b | ||
|
|
e93b7a3626 | ||
|
|
7bf2d220dd | ||
|
|
7efa20c066 | ||
|
|
f2afcfc1a7 | ||
|
|
45e2a560a9 | ||
|
|
5b5cdae9ff | ||
|
|
5147f64a64 | ||
|
|
0116a3f1f7 | ||
|
|
01839b5f63 | ||
|
|
18d02f49fd | ||
|
|
12e2a44935 | ||
|
|
9c47980c68 | ||
|
|
14f7a5c0bb | ||
|
|
f512f4aa27 | ||
|
|
4b9d4fa935 | ||
|
|
35288e81e1 | ||
|
|
f95fa2e60d | ||
|
|
0c62a8a676 | ||
|
|
346989211c | ||
|
|
ba2453457d |
@@ -1,2 +0,0 @@
|
||||
packages/x-noble-hashes/**/*.ts
|
||||
packages/x-noble-secp256k1/**/*.ts
|
||||
@@ -1,22 +0,0 @@
|
||||
// Copyright 2017-2023 @polkadot/util authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
const base = require('@polkadot/dev/config/eslint.cjs');
|
||||
|
||||
module.exports = {
|
||||
...base,
|
||||
ignorePatterns: [
|
||||
...base.ignorePatterns
|
||||
],
|
||||
parserOptions: {
|
||||
...base.parserOptions,
|
||||
project: [
|
||||
'./tsconfig.eslint.json'
|
||||
]
|
||||
},
|
||||
rules: {
|
||||
...base.rules,
|
||||
// this seems very broken atm, false positives
|
||||
'@typescript-eslint/unbound-method': 'off'
|
||||
}
|
||||
};
|
||||
@@ -9,8 +9,8 @@ jobs:
|
||||
if: "! startsWith(github.event.head_commit.message, '[CI Skip]') && (!github.event.pull_request || github.event.pull_request.head.repo.full_name == github.repository)"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: jacogr/action-approve@9d6ce78d26f23ad29d009d034822cf773f2cb50e
|
||||
- uses: jacogr/action-approve@795afd1dd096a2071d7ec98740661af4e853b7da
|
||||
with:
|
||||
authors: jacogr
|
||||
authors: jacogr, TarikGul
|
||||
labels: -auto
|
||||
token: ${{ secrets.GH_PAT_BOT }}
|
||||
|
||||
@@ -8,9 +8,9 @@ jobs:
|
||||
merge:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: jacogr/action-merge@3b4b49af8a8644bf5cbb5409ee236abe04eeb1b0
|
||||
- uses: jacogr/action-merge@d2d64b4545acd93b0a9575177d3d215ae3f92029
|
||||
with:
|
||||
checks: build,lint,test
|
||||
checks: pr (build),pr (lint),pr (test)
|
||||
labels: -auto
|
||||
strategy: squash
|
||||
token: ${{ secrets.GH_PAT_BOT }}
|
||||
|
||||
@@ -10,16 +10,16 @@ jobs:
|
||||
env:
|
||||
YARN_ENABLE_SCRIPTS: false
|
||||
steps:
|
||||
- uses: dessant/lock-threads@f1a42f0f44eb83361d617a014663e1a76cf282d2
|
||||
- uses: dessant/lock-threads@c1b35aecc5cdb1a34539d14196df55838bb2f836
|
||||
with:
|
||||
github-token: ${{ secrets.GH_PAT_BOT }}
|
||||
issue-lock-inactive-days: '7'
|
||||
issue-lock-comment: >
|
||||
issue-inactive-days: '7'
|
||||
issue-comment: >
|
||||
This thread has been automatically locked since there has not been
|
||||
any recent activity after it was closed. Please open a new issue
|
||||
if you think you have a related problem or query.
|
||||
pr-lock-inactive-days: '2'
|
||||
pr-lock-comment: >
|
||||
pr-inactive-days: '2'
|
||||
pr-comment: >
|
||||
This pull request has been automatically locked since there
|
||||
has not been any recent activity after it was closed.
|
||||
Please open a new issue for related bugs.
|
||||
|
||||
@@ -3,21 +3,26 @@ on: [pull_request]
|
||||
|
||||
jobs:
|
||||
pr:
|
||||
continue-on-error: true
|
||||
strategy:
|
||||
matrix:
|
||||
step: ['lint', 'test', 'build', 'deno']
|
||||
name: ${{ matrix.step }}
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
YARN_ENABLE_SCRIPTS: false
|
||||
CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
|
||||
steps:
|
||||
- uses: actions/checkout@7884fcad6b5d53d10323aee724dc68d8b9096a2e
|
||||
- uses: denoland/setup-deno@004814556e37c54a2f6e31384c9e18e983317366
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
deno-version: vx.x.x
|
||||
node-version: 'lts/*'
|
||||
- uses: denoland/setup-deno@v1
|
||||
with:
|
||||
# Deno v2 throws errors with specific types therefore we set it to the last version before v2
|
||||
deno-version: v1.46.3
|
||||
- name: ${{ matrix.step }}
|
||||
if: always()
|
||||
run: |
|
||||
yarn install --immutable | grep -v 'YN0013'
|
||||
deno --version
|
||||
yarn install --immutable
|
||||
yarn ${{ matrix.step }}
|
||||
|
||||
@@ -10,7 +10,6 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
step: ['build:release']
|
||||
name: ${{ matrix.step }}
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
YARN_ENABLE_SCRIPTS: false
|
||||
@@ -19,11 +18,14 @@ jobs:
|
||||
GH_RELEASE_GITHUB_API_TOKEN: ${{ secrets.GH_PAT_BOT }}
|
||||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
steps:
|
||||
- uses: actions/checkout@7884fcad6b5d53d10323aee724dc68d8b9096a2e
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
token: ${{ secrets.GH_PAT_BOT }}
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 'lts/*'
|
||||
- name: ${{ matrix.step }}
|
||||
run: |
|
||||
yarn install --immutable | grep -v 'YN0013'
|
||||
yarn install --immutable
|
||||
yarn ${{ matrix.step }}
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
name: 'Close stale issues and PRs'
|
||||
on:
|
||||
schedule:
|
||||
- cron: '50 1/3 * * *'
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
YARN_ENABLE_SCRIPTS: false
|
||||
steps:
|
||||
- uses: actions/stale@98ed4cb500039dbcccf4bd9bedada4d0187f2757
|
||||
with:
|
||||
repo-token: ${{ secrets.GH_PAT_BOT }}
|
||||
stale-issue-message: 'This issue has been open for 21 days with no activity and is not labelled as an enhancement. It will be closed in 7 days.'
|
||||
stale-issue-label: 'stale'
|
||||
exempt-issue-labels: '-size-l,-size-m,-size-s,-size-xl,-size-xs,[bug],ci'
|
||||
days-before-stale: 21
|
||||
days-before-close: 7
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// Copyright 2017-2023 @polkadot/dev authors & contributors
|
||||
// Copyright 2017-2026 @polkadot/util authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
module.exports = require('@polkadot/dev/config/prettier.cjs');
|
||||
|
||||
Vendored
-363
File diff suppressed because one or more lines are too long
-550
File diff suppressed because one or more lines are too long
Vendored
-785
File diff suppressed because one or more lines are too long
+948
File diff suppressed because one or more lines are too long
+17
-6
@@ -1,13 +1,24 @@
|
||||
compressionLevel: mixed
|
||||
|
||||
enableGlobalCache: false
|
||||
|
||||
enableImmutableInstalls: false
|
||||
|
||||
enableProgressBars: false
|
||||
|
||||
logFilters:
|
||||
- code: YN0013
|
||||
level: discard
|
||||
|
||||
nodeLinker: node-modules
|
||||
|
||||
plugins:
|
||||
- path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs
|
||||
spec: "@yarnpkg/plugin-interactive-tools"
|
||||
- path: .yarn/plugins/@yarnpkg/plugin-version.cjs
|
||||
spec: "@yarnpkg/plugin-version"
|
||||
yarnPath: .yarn/releases/yarn-4.9.1.cjs
|
||||
|
||||
yarnPath: .yarn/releases/yarn-3.2.0.cjs
|
||||
# @quantus packages come from the Gitea registry. Safe as a whole-scope route
|
||||
# because we own every name in it — unlike @polkadot, where routing the scope
|
||||
# would send yarn looking for dozens of unforked packages that are not there.
|
||||
#
|
||||
# Reads are anonymous; publishing needs `pass gitea/package-publisher-token`.
|
||||
npmScopes:
|
||||
quantus:
|
||||
npmRegistryServer: "https://git.lair.cafe/api/packages/quantus/npm/"
|
||||
|
||||
+444
@@ -1,5 +1,449 @@
|
||||
# CHANGELOG
|
||||
|
||||
## 14.0.3 Mar 23, 2026
|
||||
|
||||
Changes:
|
||||
|
||||
- Fix(hw-ledger): reset transport on operation errors and add explicit disconnect API ([#2024](https://github.com/polkadot-js/common/pull/2024))
|
||||
|
||||
|
||||
## 14.0.2 Mar 16, 2026
|
||||
|
||||
Changes:
|
||||
|
||||
- Set headers to 2026 ([#2021](https://github.com/polkadot-js/common/pull/2021))
|
||||
|
||||
Contributed:
|
||||
|
||||
- fix(util-crypto): use correct x/y getters in secp256k1Expand ([#2018](https://github.com/polkadot-js/common/pull/2018)) (Thanks to https://github.com/AndreasGassmann)
|
||||
|
||||
|
||||
## 14.0.1 Dec 9, 2025
|
||||
|
||||
Changes:
|
||||
|
||||
- fix(x-randomvalues): prioritize native RN modules over polyfilled crypto ([#2013](https://github.com/polkadot-js/common/pull/2013))
|
||||
- sr25519: switch from wasm to micro-sr25519 ([#1971](https://github.com/polkadot-js/common/pull/1971))
|
||||
|
||||
|
||||
## 13.5.9 Nov 25, 2025
|
||||
|
||||
Changes:
|
||||
|
||||
- Bump polkadot dependencies ([#2011](https://github.com/polkadot-js/common/pull/2011))
|
||||
|
||||
|
||||
## 13.5.8 Nov 11, 2025
|
||||
|
||||
Changes:
|
||||
|
||||
- Bump @polkadot dependencies ([#2009](https://github.com/polkadot-js/common/pull/2009))
|
||||
|
||||
|
||||
## 13.5.7 Oct 13, 2025
|
||||
|
||||
Changes:
|
||||
|
||||
- Revert "Set pbkdf2Encode rounds to default to 210,000" ([#2007](https://github.com/polkadot-js/common/pull/2007))
|
||||
|
||||
|
||||
## 13.5.6 Aug 26, 2025
|
||||
|
||||
Changes:
|
||||
|
||||
- Set pbkdf2Encode rounds to default to 210,000 ([#1983](https://github.com/polkadot-js/common/pull/1983))
|
||||
- Bump @polkadot/wasm deps ([#2002](https://github.com/polkadot-js/common/pull/2002))
|
||||
|
||||
Contributed:
|
||||
|
||||
- Add DENTNet to generic Polkadot app supported chains ([#1942](https://github.com/polkadot-js/common/pull/1942))
|
||||
|
||||
## 13.5.5 Aug 11, 2025
|
||||
|
||||
Changes:
|
||||
|
||||
- Add ledger support for Mythos ([#1969](https://github.com/polkadot-js/common/pull/1969))
|
||||
|
||||
## 13.5.4 July 28, 2025
|
||||
|
||||
Changes:
|
||||
|
||||
- Add Creditcoin3 support to Generic Ledger App ([#1985](https://github.com/polkadot-js/common/pull/1985))
|
||||
|
||||
## 13.5.3 July 1, 2025
|
||||
|
||||
Changes:
|
||||
|
||||
- Update polkadot dependencies ([#1995](https://github.com/polkadot-js/common/pull/1995))
|
||||
- Add Optional Strict Input Checking to u8aToU8a ([#1994](https://github.com/polkadot-js/common/pull/1994))
|
||||
- Update scrypt parameter validation ([#1993](https://github.com/polkadot-js/common/pull/1993))
|
||||
|
||||
## 13.5.2 Jun 17, 2025
|
||||
|
||||
Changes:
|
||||
|
||||
- fix: enhance error handling for secure random number generation in React Native ([#1991](https://github.com/polkadot-js/common/pull/1991))
|
||||
- Add input length validation in scryptFromU8a function ([#1990](https://github.com/polkadot-js/common/pull/1990))
|
||||
|
||||
Contributed:
|
||||
|
||||
- Add Liberland support to Generic Ledger App ([#1989](https://github.com/polkadot-js/common/pull/1989))
|
||||
|
||||
## 13.5.1 May 19, 2025
|
||||
|
||||
Changes:
|
||||
|
||||
- Ledger ECDSA signing support ([#1986](https://github.com/polkadot-js/common/pull/1986))
|
||||
- Bump yarn to 4.9.1 ([#1987](https://github.com/polkadot-js/common/pull/1987))
|
||||
|
||||
|
||||
## 13.4.4 Apr 14, 2025
|
||||
|
||||
Changes:
|
||||
|
||||
- Improve objectSpread function property handling ([#1982](https://github.com/polkadot-js/common/pull/1982))
|
||||
|
||||
|
||||
## 13.4.3 Feb 17, 2025
|
||||
|
||||
Changes:
|
||||
|
||||
- Rollback ws change in x-ws ([#1980](https://github.com/polkadot-js/common/pull/1980))
|
||||
NOTE: this rollbacks changes made in ([#1976](https://github.com/polkadot-js/common/pull/1976)) to ensure websocket usage doesnt break in any downstream libs.
|
||||
|
||||
|
||||
## 13.4.2 Feb 17, 2025
|
||||
|
||||
Changes:
|
||||
|
||||
- Cast ws as global.WebSocket ([#1978](https://github.com/polkadot-js/common/pull/1978))
|
||||
|
||||
|
||||
## 13.4.1 Feb 16, 2025
|
||||
|
||||
Changes:
|
||||
|
||||
- Enable KeyringPair Creation with Custom Mnemonic Wordlists ([#1974](https://github.com/polkadot-js/common/pull/1974))
|
||||
- Use ws library in Node.js 22+ for Better WebSocket Error Handling ([#1976](https://github.com/polkadot-js/common/pull/1976))
|
||||
- Fix Misclassification of ECDSA Signatures in `verifyMultisig` ([#1973](https://github.com/polkadot-js/common/pull/1973))
|
||||
- Bump dev to 0.83.2 ([#1972](https://github.com/polkadot-js/common/pull/1972))
|
||||
- Bump yarn to 4.6.0 ([#1967](https://github.com/polkadot-js/common/pull/1967))
|
||||
|
||||
|
||||
## 13.3.1 Jan 6, 2025
|
||||
|
||||
Changes:
|
||||
|
||||
- Give compatibility for nodejs v22
|
||||
- Fix `getSeparator` which fixes toLocaleString ([#1965](https://github.com/polkadot-js/common/pull/1965))
|
||||
- 2025 Headers ([#1963](https://github.com/polkadot-js/common/pull/1963))
|
||||
|
||||
|
||||
## 13.2.3 Nov 11, 2024
|
||||
|
||||
Contributed:
|
||||
|
||||
- Add Vara support to the Generic Ledger App ([#1958](https://github.com/polkadot-js/common/pull/1958)) (Thanks to https://github.com/breathx)
|
||||
|
||||
Changes:
|
||||
|
||||
- Bump Dev to 0.82.1 ([#1959](https://github.com/polkadot-js/common/pull/1959))
|
||||
|
||||
|
||||
## 13.2.2 Oct 28, 2024
|
||||
|
||||
Contributed:
|
||||
|
||||
- Add Polimec support to the Generic Ledger App ([#1945](https://github.com/polkadot-js/common/pull/1945)) (Thanks to https://github.com/lrazovic)
|
||||
- Add Frequency to the Generic Ledger App ([#1955](https://github.com/polkadot-js/common/pull/1955)) (Thanks to https://github.com/wilwade)
|
||||
|
||||
Changes:
|
||||
|
||||
- Bump yarn to 4.5.1 ([#1953](https://github.com/polkadot-js/common/pull/1953))
|
||||
|
||||
|
||||
## 13.2.1 Oct 21, 2024
|
||||
|
||||
Contributed:
|
||||
|
||||
- Add bittensor to genericLedgerApps (Thanks to https://github.com/camfairchild) ([#1941](https://github.com/polkadot-js/common/pull/1941))
|
||||
|
||||
Changes:
|
||||
|
||||
- Fix Deno CI Build ([#1947](https://github.com/polkadot-js/common/pull/1947))
|
||||
- Bump yarn to 4.5.0 ([#1946](https://github.com/polkadot-js/common/pull/1946))
|
||||
- Update Ledger Deps ([#1948](https://github.com/polkadot-js/common/pull/1948))
|
||||
- Update WS and deps ([#1949](https://github.com/polkadot-js/common/pull/1949))
|
||||
- Bump polkadot/wasm to 7.4.1 ([#1950](https://github.com/polkadot-js/common/pull/1950))
|
||||
- Bump dev to 0.81.2 ([#1951](https://github.com/polkadot-js/common/pull/1951))
|
||||
- Allows for CJS target in build
|
||||
|
||||
|
||||
## 13.1.1 Sep 16, 2024
|
||||
|
||||
Contributed:
|
||||
|
||||
HydraDx - Hydration Rebrand Thanks to (https://github.com/jak-pan) ([#1923](https://github.com/polkadot-js/common/pull/1923))
|
||||
|
||||
Changes:
|
||||
|
||||
- Update all deps that have patch releases ([#1934](https://github.com/polkadot-js/common/pull/1934))
|
||||
- Bump yarn to 4.4.1 ([#1940](https://github.com/polkadot-js/common/pull/1940))
|
||||
- Update ss58-registry to 1.50.0 ([#1937](https://github.com/polkadot-js/common/pull/1937))
|
||||
- Update dev and typescript ([#1936](https://github.com/polkadot-js/common/pull/1936))
|
||||
- Add Encointer and Integritee to Ledger, and adjust tests ([#1939](https://github.com/polkadot-js/common/pull/1939))
|
||||
- This PR added the addition of `genericLedgerApps` and `prevLedgerRecord` objects. They both combine into `ledgerApps` in `hw-ledger/defaults`.
|
||||
|
||||
|
||||
## 13.0.2 July 12, 2024
|
||||
|
||||
Contributed:
|
||||
|
||||
- Add peaq support for ledger (Thanks to https://github.com/lavish0000)
|
||||
|
||||
|
||||
## 13.0.1 July 12, 2024
|
||||
|
||||
Breaking Changes:
|
||||
|
||||
- Add Support for latest Ledger App
|
||||
- This deprecates `class Ledger` in favor of `class LedgerGeneric`
|
||||
- More info in the following PR ([#1925](https://github.com/polkadot-js/common/pull/1925))
|
||||
|
||||
Changes:
|
||||
|
||||
- Bump dev to 0.79.1
|
||||
- Comments around pair encode/decode 1-3
|
||||
- Bump ws, react-native, ss58Registry
|
||||
- Bump yarn to 4.3.1
|
||||
- Update CI to checkout and setup_node v4
|
||||
|
||||
|
||||
## 12.6.2 Dec 18, 2023
|
||||
|
||||
Changes:
|
||||
|
||||
- Update to latest `@polkadot/wasm-crypto`
|
||||
- Upgrade dependencies to latest versions
|
||||
|
||||
|
||||
## 12.6.1 Nov 18, 2023
|
||||
|
||||
Contributed:
|
||||
|
||||
- Ledger support for Quartz (Thanks to https://github.com/CertainLach)
|
||||
- Add flag to disable same-version esm/cjs warnings (Thanks to https://github.com/forgetso)
|
||||
|
||||
Changes:
|
||||
|
||||
- Adjust logger check for `process.env`
|
||||
- Adjust `isRiscV` helper to check for `PVM\0` bytes
|
||||
- Drop support for Node 16 (EOL 11 Sep 2023)
|
||||
- Upgrade dependencies to latest stable versions
|
||||
|
||||
|
||||
## 12.5.1 Sep 15, 2023
|
||||
|
||||
Contributed:
|
||||
|
||||
- Add `isRiskV` helper (Thanks to https://github.com/peetzweg)
|
||||
- Ledger support for Enjin & Matrixchain (Thanks to https://github.com/leonardocustodio)
|
||||
|
||||
Changes:
|
||||
|
||||
- Expand interface type comments (assists in-editor helpers)
|
||||
- Upgrade dependencies to latest stable versions
|
||||
|
||||
|
||||
## 12.4.2 Aug 23, 2023
|
||||
|
||||
Changes:
|
||||
|
||||
- Fix `u8aTo{BigInt, Bn, Number}` for non-negative `i{8, 16, 32...}` inputs
|
||||
- Extend `u8aToBuffer` with `hasBuffer` check
|
||||
- Adjust util tests (extract input/output arrays)
|
||||
|
||||
|
||||
## 12.4.1 Aug 17, 2023
|
||||
|
||||
Changes:
|
||||
|
||||
- Add support for Ledger `signRaw`, as exposed by lower-level
|
||||
- Update code to use `?.` shortcuts where appropriate
|
||||
- Adjust `u8aToBuffer` & `isBuffer` typings to not require `Buffer`
|
||||
- Use `stringify/import.meta.url` helpers in specs
|
||||
- Upgrade dependencies to latest stable versions
|
||||
|
||||
|
||||
## 12.3.2 Jun 12, 2023
|
||||
|
||||
Changes:
|
||||
|
||||
- Adjust `SubstrateNetwork` typing with `HexString` genesisHash
|
||||
- Re-export `Constructor<T>` type (deprecated, replaced with `Class<T>`)
|
||||
|
||||
|
||||
## 12.3.1 Jun 11, 2023
|
||||
|
||||
Changes:
|
||||
|
||||
- Only allow padding characters in base64 strings
|
||||
- Expand typings for keyring meta with known keys
|
||||
- Adjust object index access for stricter tsconfig settings
|
||||
|
||||
|
||||
## 12.2.2 Jun 4, 2023
|
||||
|
||||
Changes:
|
||||
|
||||
- Apply missing count assignment for `for (...)` loops
|
||||
- Remove unused `@types/*` dev dependencies
|
||||
- Upgrade dependencies to latest stable versions
|
||||
|
||||
|
||||
## 12.2.1 May 13, 2023
|
||||
|
||||
Changes:
|
||||
|
||||
- Align `u8aToBigInt` tests with `u8aToBn`
|
||||
- Unroll loops on most-frequently used paths for `u8aToBigInt`
|
||||
- Add `module` to `package.json` export map (ESM-only)
|
||||
- Upgrade dependencies to latest stable versions
|
||||
|
||||
|
||||
## 12.1.2 May 1, 2023
|
||||
|
||||
Changes:
|
||||
|
||||
- Adjust typing for `isChildClass` & `Constructor` usage
|
||||
|
||||
|
||||
## 12.1.1 Apr 29, 2023
|
||||
|
||||
Changes:
|
||||
|
||||
- Add shareable `identity` & `noop` functions
|
||||
- Flatten `Buffer | Uint8Array` types (as used) to base-only `Uint8Array`
|
||||
- Apply `readonly` specifiers to private class fields where applicable
|
||||
- Adjust compilation output for `__internal__` class fields
|
||||
- Remove unused types from `util`
|
||||
- Upgrade dependencies to latest stable versions
|
||||
|
||||
|
||||
## 12.0.1 Apr 22, 2023
|
||||
|
||||
Contributed:
|
||||
|
||||
- Add Cere genesisHash (Thanks to https://github.com/shamilkhan)
|
||||
|
||||
Changes:
|
||||
|
||||
- Swap secp256k1 functionality to `@noble/curves`
|
||||
- Swap ed25519 functionality to `@noble/curves`
|
||||
- Replace `tweetnacl` secretbox usage with slimmer local version
|
||||
- Adjust `isCodec` helper with closer API alignment
|
||||
- Initial steps to multi-language bip39 support
|
||||
- Use Node webcrypto for Node `getRandomValues` support
|
||||
- Upgrade dependencies to latest stable versions
|
||||
- Drop support for Node 14 (EOL 30 Apr 2023)
|
||||
|
||||
|
||||
## 11.1.3 Apr 1, 2023
|
||||
|
||||
Contributed:
|
||||
|
||||
- Add Bittensor genesisHash (Thanks to https://github.com/camfairchild)
|
||||
|
||||
Changes:
|
||||
|
||||
- Allow empty string as valid base32/base58/base64 decoder input
|
||||
- Add additional/missing `/*#__PURE__*/` annotations
|
||||
- Upgrade dependencies to latest stable versions
|
||||
|
||||
|
||||
## 11.1.2 Mar 25, 2023
|
||||
|
||||
Changes:
|
||||
|
||||
- Expand error details for invalid publicKeys in secp256k1 compress/expand operations
|
||||
- Expand `@polkadot/hw-ledger` with specific per-method JSDoc
|
||||
- Upgrade dependencies to latest stable versions
|
||||
|
||||
|
||||
## 11.1.1 Mar 18, 2023
|
||||
|
||||
Contributed:
|
||||
|
||||
- Add 3DPass genesisHash (Thanks to https://github.com/fedosov)
|
||||
|
||||
Changes:
|
||||
|
||||
- Remove support for encrypt/decrypt functionality on keypair
|
||||
- Upgrade dependencies to latest stable versions
|
||||
|
||||
|
||||
## 11.0.2 Mar 11, 2023
|
||||
|
||||
Changes:
|
||||
|
||||
- Use consistent `.js` imports in source files (TS moduleResolution)
|
||||
- Remove TS resolveJsonModule option
|
||||
- Upgrade to `@polkadot/wasm-crypto` 7.0.3
|
||||
|
||||
|
||||
## 11.0.1 Mar 4, 2023
|
||||
|
||||
Changes:
|
||||
|
||||
- Change `@polkadot/x-ws` to use [ws](https://www.npmjs.com/package/ws) package (previous: `websocket`)
|
||||
- Add `/*#__PURE__*/` annotations for `@polkadot/x-*` packages
|
||||
- Swap TS -> JS compiler to use tsc (from babel)
|
||||
- Adjust all tests to use `node:test` runner (ESM variants)
|
||||
- Move `cryptoWaitReady()` top-level in test files
|
||||
- Upgrade to `@polkadot/wasm-crypto` 7.0.1
|
||||
|
||||
|
||||
## 10.4.2 Feb 19, 2023
|
||||
|
||||
Contributed:
|
||||
|
||||
- Ledger support for Pendulum (Thanks to https://github.com/carlosala)
|
||||
|
||||
Changes:
|
||||
|
||||
- Ensure `u8aToU8a` correctly unwraps Buffer value (check ordering)
|
||||
- Upgrade dependencies to latest stable versions
|
||||
|
||||
|
||||
## 10.4.1 Feb 12, 2023
|
||||
|
||||
Contributed:
|
||||
|
||||
- Locale support for number formatting (Thanks to https://github.com/alko89)
|
||||
- Ledger support for Picasso (Thanks to https://github.com/carlosala)
|
||||
|
||||
Changes:
|
||||
|
||||
- Add `isClass` helper (checks if input is actual Class Constructor)
|
||||
- Adjust `isChildClass` to rely on new `isClass`
|
||||
- Upgrade dependencies to latest stable versions
|
||||
|
||||
|
||||
## 10.3.1 Jan 28, 2023
|
||||
|
||||
Contributed:
|
||||
|
||||
- Ledger support for Ternoa (Thanks to https://github.com/mohsinriaz17)
|
||||
|
||||
Changes:
|
||||
|
||||
- Expand `arrayChunk` tests
|
||||
- Adjust output for Ledger sanity checks
|
||||
- Expand exported `bigint` constants to match with those in `BN`
|
||||
- Adjust internal character maps to operate on `Uint8Array` instad of `Array<number>`
|
||||
- Upgrade dependencies to latest stable versions
|
||||
|
||||
|
||||
## 10.2.6 Jan 13, 2023
|
||||
|
||||
Changes:
|
||||
|
||||
+27
-4
@@ -1,13 +1,18 @@
|
||||
1509 Jaco Drop stray `console.error` log (#1707)
|
||||
10 Carlo Sala feat(networks): support ledger for ajuna (#1682)
|
||||
1674 Jaco Bump deps (#1912)
|
||||
47 Tarik Gul 14.0.3 (#2025)
|
||||
13 Carlo Sala feat(networks): add zeitgeist Ledger support (#1840)
|
||||
11 Valentin Fernandez 13.5.7 (#2008)
|
||||
9 Antoine Estienne Add eth uri keyring test (#1291)
|
||||
9 rajk93 14.0.1 (#2014)
|
||||
6 Amaury Martiny Add tests from Rust (#283)
|
||||
5 Jakub Pánik Add HydraDX parachain to genesis (#1583)
|
||||
6 Jakub Pánik HydraDX -> Hydration rebrand (#1923)
|
||||
5 Arjun Porwal 13.5.6 (#2004)
|
||||
5 kwingram25 Add BN consts and timeToString (#610)
|
||||
4 Adam Dossa Update Polymesh Genesis Hash (#1193)
|
||||
4 pan add bifrost kusama (#1626)
|
||||
3 AndreasGassmann fix(util-crypto): use correct x/y getters in secp256k1Expand (#2018)
|
||||
3 Luke Schoen docs: Fix example in readme since we use default imports (#243)
|
||||
2 AndreasGassmann feat(dependencies): remove moment.js (#530)
|
||||
2 Cameron Fairchild Add bittensor details (#1783)
|
||||
2 Gav Wood Fix stake:unstake (#182)
|
||||
2 Hyungsuk Kang Add cross client Encryption/Decryption (#496)
|
||||
2 Jared Norris Add Sora network (#1306)
|
||||
@@ -16,6 +21,7 @@
|
||||
2 Nantian fix bigint type (#1079)
|
||||
2 Stefanie Doll Add missing dependencies to util-crypto (#424)
|
||||
1 Agustinus Theodorus docs: fix typo in naclSeal docs. (#1005)
|
||||
1 Aleš Ferlan feat: allow setting of thousand/decimal separators (#1722)
|
||||
1 Alex Sedighi fix Nodle's known network name (#1699)
|
||||
1 Alexander Krupenkin Added ECDSA keypair support (#589)
|
||||
1 alexdniep added equilibrium slip44; added equilibrium genesis hash (#984)
|
||||
@@ -23,32 +29,49 @@
|
||||
1 Axel Chalon Simplify @polkadot/keyring KeyringPair (#419)
|
||||
1 Brad Larson [FIX] Adjust error message (#646)
|
||||
1 Carlos Medeiros add hydradx to knownLedger (#1647)
|
||||
1 Chris Get rid of warnings for dual esm and cjs packages of the same version (#1890)
|
||||
1 Dmitrii Novikov Add `Vara` support to Generic Ledger App (#1958)
|
||||
1 Eliott Teissonniere add nodle ledger specs (#1089)
|
||||
1 Francis O'Brien Fix(hw-ledger): reset transport on operation errors and add explicit disconnect API (#2024)
|
||||
1 Guilane DENGUIR feat(VTB): Added support for VTB blockchain (#1651)
|
||||
1 h4x3rotab Throws an error when signing with a locked keypair (#578)
|
||||
1 Harry Liu Update README.md (#446)
|
||||
1 henrikdent Add DENTNet ledger support (via generic Polkadot app) (#1942)
|
||||
1 Hoon Kim replace plasm genesis with astar (#1397)
|
||||
1 Hussein Ait-Lahcen Add Picasso Genesis Hash (#1261)
|
||||
1 Igor Support genshiro network (#1148)
|
||||
1 Jake Naviasky Add evmToAddress and addressToEvm crypto utils. (#705)
|
||||
1 JesseAbram added check if valid address to docs (#440)
|
||||
1 joe petrowski Add example for multisig address creation (#590)
|
||||
1 José Molina Colmenero Add ledger support for Mythos (#1969)
|
||||
1 kaelnew add ledger support for stafi (#1569)
|
||||
1 Leonardo Custodio Ledger support (#1879)
|
||||
1 Leonardo Razovic feat: add Polimec (#1945)
|
||||
1 Lezek123 logger - wildcard include/exclude with DEBUG env (#932)
|
||||
1 Lovish Arora Add peaq support for ledger (#1928)
|
||||
1 Mario Neises remove redudant export (#257)
|
||||
1 Miguel Hervas Add CFG Ledger Support (#1057)
|
||||
1 Mikhail Fedosov feat: add 3dpass network (#1769)
|
||||
1 Mohsan Riaz Add Ternoa for ledger hardware support (#1711)
|
||||
1 nahuseyoum Reserving 65 for Aventus based on the new extended range (#871)
|
||||
1 Nantian add acala ledger config (#1485)
|
||||
1 Paul Miller sr25519: switch from wasm to micro-sr25519 (#1971)
|
||||
1 peetzweg/ adds `isRiscV` guard function similar to isWasm (#1878)
|
||||
1 qwer951123 Add acala genesis (#1161)
|
||||
1 Radek Bochenek feat: add Liberland support to Generic Ledger App (#1989)
|
||||
1 Raoul Millais Fix yarn add instructions in x-global README (#873)
|
||||
1 Raymond Zhong Add Edgeware ledger app (#1006)
|
||||
1 Reto Trinkler Adding 4 as address type of ss58 for Katal Chain (#639)
|
||||
1 Rocco Musolino remove doc broken link (#697)
|
||||
1 Salina Add Creditcoin3 support to Generic Ledger App (#1985)
|
||||
1 Shamilkhan Add genesis hash for Cere Network (#1806)
|
||||
1 Song Zhou Add in ability to encrypt/decrypt msg with keyring (#1070)
|
||||
1 Thibaut Sardan add hasLedgerSupport prop to networks (#835)
|
||||
1 Tomokazu Kozuma fix comment (#1119)
|
||||
1 Tore19 Add stafi genesis hash (#1096)
|
||||
1 Wei Tang ss58: add Kulupu prefix to the list (#595)
|
||||
1 Wil Wade Add Frequency to the Generic Ledger App (#1955)
|
||||
1 WoeOm Handing high precision scenes (#450)
|
||||
1 xx network Add xxnetwork genesis hash and ledger app (#1463)
|
||||
1 Yaroslav Bolyukin Add quartz support for ledger, update unique slip-0044 identifier (#1882)
|
||||
1 Yuri Extra check for process for browser bundles (#923)
|
||||
@@ -1,4 +0,0 @@
|
||||
// Copyright 2017-2023 @polkadot/util authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
module.exports = require('@polkadot/dev/config/babel-config-cjs.cjs');
|
||||
@@ -0,0 +1,8 @@
|
||||
// Copyright 2017-2026 @polkadot/util authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import baseConfig from '@polkadot/dev/config/eslint';
|
||||
|
||||
export default [
|
||||
...baseConfig
|
||||
];
|
||||
@@ -1,19 +0,0 @@
|
||||
// Copyright 2017-2023 @polkadot/util authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
const config = require('@polkadot/dev/config/jest.cjs');
|
||||
|
||||
module.exports = Object.assign({}, config, {
|
||||
moduleNameMapper: {
|
||||
'@polkadot/hw-ledger-transports(.*)$': '<rootDir>/packages/hw-ledger-transports/src/node',
|
||||
// eslint-disable-next-line sort-keys
|
||||
'@polkadot/hw-ledger(.*)$': '<rootDir>/packages/hw-ledger/src/$1',
|
||||
'@polkadot/keyring(.*)$': '<rootDir>/packages/keyring/src/$1',
|
||||
'@polkadot/networks(.*)$': '<rootDir>/packages/networks/src/$1',
|
||||
'@polkadot/util-(crypto)(.*)$': '<rootDir>/packages/util-$1/src/$2',
|
||||
// eslint-disable-next-line sort-keys
|
||||
'@polkadot/util(.*)$': '<rootDir>/packages/util/src/$1',
|
||||
'@polkadot/x-(bigint|global)(.*)$': '<rootDir>/packages/x-$1/src/$2',
|
||||
'@polkadot/x-(fetch|randomvalues|textdecoder|textencoder|ws)(.*)$': '<rootDir>/packages/x-$1/src/node'
|
||||
}
|
||||
});
|
||||
+15
-12
@@ -1,9 +1,12 @@
|
||||
{
|
||||
"author": "Jaco Greeff <jacogr@gmail.com>",
|
||||
"bugs": "https://github.com/polkadot-js/common/issues",
|
||||
"engines": {
|
||||
"node": ">=18.14"
|
||||
},
|
||||
"homepage": "https://github.com/polkadot-js/common#readme",
|
||||
"license": "Apache-2.0",
|
||||
"packageManager": "yarn@3.2.0",
|
||||
"packageManager": "yarn@4.9.1",
|
||||
"private": true,
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -11,33 +14,33 @@
|
||||
},
|
||||
"sideEffects": false,
|
||||
"type": "module",
|
||||
"version": "10.2.6",
|
||||
"version": "14.0.3",
|
||||
"versions": {
|
||||
"git": "10.2.6",
|
||||
"npm": "10.2.6"
|
||||
"git": "14.0.3",
|
||||
"npm": "14.0.3"
|
||||
},
|
||||
"workspaces": [
|
||||
"packages/*"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "polkadot-dev-build-ts",
|
||||
"build:networks": "yarn test:one packages/networks/src",
|
||||
"build:networks": "polkadot-dev-run-test packages/networks/src",
|
||||
"build:release": "polkadot-ci-ghact-build",
|
||||
"build:rollup": "polkadot-exec-rollup --config",
|
||||
"clean": "polkadot-dev-clean-build",
|
||||
"deno": "yarn polkadot-dev-deno-map && yarn build && deno check --import-map=import_map.json mod.ts",
|
||||
"lint": "polkadot-dev-run-lint",
|
||||
"postinstall": "polkadot-dev-yarn-only",
|
||||
"test": "NODE_OPTIONS=--experimental-vm-modules polkadot-dev-run-test --coverage --runInBand --testPathIgnorePatterns crosscheck --testPathIgnorePatterns toMiniSecretCmp",
|
||||
"test:mnemonicCmp": "polkadot-dev-run-test packages/util-crypto/src/mnemonic/toMiniSecretCmp.spec.ts",
|
||||
"test:one": "polkadot-dev-run-test --runInBand"
|
||||
"test": "polkadot-dev-run-test --env browser ^mnemonic/toMiniSecretCmp",
|
||||
"test:mnemonicCmp": "polkadot-dev-run-test --env browser mnemonic/toMiniSecretCmp",
|
||||
"test:node": "polkadot-dev-run-test --env browser ^mnemonic/toMiniSecretCmp",
|
||||
"test:one": "polkadot-dev-run-test --env browser"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.20.12",
|
||||
"@polkadot/dev": "^0.67.178",
|
||||
"@types/jest": "^29.2.5"
|
||||
"@polkadot/dev": "^0.83.3",
|
||||
"@types/node": "^22.7.5"
|
||||
},
|
||||
"resolutions": {
|
||||
"typescript": "^4.9.4"
|
||||
"typescript": "^5.5.4"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,201 +0,0 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
@@ -1,13 +1,11 @@
|
||||
{
|
||||
"author": "Jaco Greeff <jacogr@gmail.com>",
|
||||
"bugs": "https://github.com/polkadot-js/common/issues",
|
||||
"contributors": [],
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
"node": ">=18"
|
||||
},
|
||||
"homepage": "https://github.com/polkadot-js/common/tree/master/packages/hw-ledger-transports#readme",
|
||||
"license": "Apache-2.0",
|
||||
"maintainers": [],
|
||||
"name": "@polkadot/hw-ledger-transports",
|
||||
"repository": {
|
||||
"directory": "packages/hw-ledger-transports",
|
||||
@@ -16,18 +14,18 @@
|
||||
},
|
||||
"sideEffects": false,
|
||||
"type": "module",
|
||||
"version": "10.2.6",
|
||||
"version": "14.0.3",
|
||||
"browser": "browser.js",
|
||||
"main": "node.js",
|
||||
"react-native": "react-native.js",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.20.7",
|
||||
"@ledgerhq/hw-transport": "^6.27.9",
|
||||
"@ledgerhq/hw-transport-webhid": "^6.27.9",
|
||||
"@ledgerhq/hw-transport-webusb": "^6.27.9",
|
||||
"@polkadot/util": "10.2.6"
|
||||
"@ledgerhq/hw-transport": "^6.31.4",
|
||||
"@ledgerhq/hw-transport-webhid": "^6.29.4",
|
||||
"@ledgerhq/hw-transport-webusb": "^6.29.4",
|
||||
"@polkadot/util": "14.0.3",
|
||||
"tslib": "^2.8.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@ledgerhq/hw-transport-node-hid-singleton": "^6.28.6"
|
||||
"@ledgerhq/hw-transport-node-hid-singleton": "^6.31.5"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,23 +1,11 @@
|
||||
// Copyright 2017-2023 @polkadot/hw-ledger authors & contributors
|
||||
// Copyright 2017-2026 @polkadot/hw-ledger authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type Transport from '@ledgerhq/hw-transport';
|
||||
import type { TransportDef } from './types';
|
||||
import LedgerHid from '@ledgerhq/hw-transport-webhid';
|
||||
import LedgerUsb from '@ledgerhq/hw-transport-webusb';
|
||||
|
||||
import LedgerWebHid from '@ledgerhq/hw-transport-webhid';
|
||||
import LedgerWebUsb from '@ledgerhq/hw-transport-webusb';
|
||||
import { createDefs } from './util.js';
|
||||
|
||||
export { packageInfo } from './packageInfo';
|
||||
export { packageInfo } from './packageInfo.js';
|
||||
|
||||
export const transports: TransportDef[] = [
|
||||
{
|
||||
create: (): Promise<Transport> =>
|
||||
LedgerWebUsb.create(),
|
||||
type: 'webusb'
|
||||
},
|
||||
{
|
||||
create: (): Promise<Transport> =>
|
||||
LedgerWebHid.create(),
|
||||
type: 'hid'
|
||||
}
|
||||
];
|
||||
export const transports = /*#__PURE__*/ createDefs(['webusb', LedgerUsb], ['hid', LedgerHid]);
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
// Copyright 2017-2023 @polkadot/hw-ledger authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
export default [];
|
||||
@@ -1,11 +0,0 @@
|
||||
// Copyright 2017-2023 @polkadot/hw-ledger-transports authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Do not edit, auto-generated by @polkadot/dev
|
||||
|
||||
import { detectPackage } from '@polkadot/util';
|
||||
|
||||
import others from './detectOther';
|
||||
import { packageInfo } from './packageInfo';
|
||||
|
||||
detectPackage(packageInfo, null, others);
|
||||
@@ -1,8 +1,8 @@
|
||||
// Copyright 2017-2023 @polkadot/hw-ledger authors & contributors
|
||||
// Copyright 2017-2026 @polkadot/hw-ledger authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { TransportDef } from './types';
|
||||
import { createDefs } from './util.js';
|
||||
|
||||
export { packageInfo } from './packageInfo';
|
||||
export { packageInfo } from './packageInfo.js';
|
||||
|
||||
export const transports: TransportDef[] = [];
|
||||
export const transports = /*#__PURE__*/ createDefs();
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2017-2023 @polkadot/hw-ledger authors & contributors
|
||||
// Copyright 2017-2026 @polkadot/hw-ledger authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
export * from './empty';
|
||||
export * from './empty.js';
|
||||
|
||||
@@ -1,17 +1,10 @@
|
||||
// Copyright 2017-2023 @polkadot/hw-ledger authors & contributors
|
||||
// Copyright 2017-2026 @polkadot/hw-ledger authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type Transport from '@ledgerhq/hw-transport';
|
||||
import type { TransportDef } from './types';
|
||||
|
||||
import LedgerHid from '@ledgerhq/hw-transport-node-hid-singleton';
|
||||
|
||||
export { packageInfo } from './packageInfo';
|
||||
import { createDefs } from './util.js';
|
||||
|
||||
export const transports: TransportDef[] = [
|
||||
{
|
||||
create: (): Promise<Transport> =>
|
||||
LedgerHid.create(),
|
||||
type: 'hid'
|
||||
}
|
||||
];
|
||||
export { packageInfo } from './packageInfo.js';
|
||||
|
||||
export const transports = /*#__PURE__*/ createDefs(['hid', LedgerHid]);
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
// Copyright 2017-2026 @polkadot/hw-ledger-transports authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Do not edit, auto-generated by @polkadot/dev
|
||||
// (packageInfo imports will be kept as-is, user-editable)
|
||||
|
||||
import { detectPackage } from '@polkadot/util';
|
||||
|
||||
import { packageInfo } from './packageInfo.js';
|
||||
|
||||
detectPackage(packageInfo, null, []);
|
||||
@@ -1,6 +1,6 @@
|
||||
// Copyright 2017-2023 @polkadot/hw-ledger-transports authors & contributors
|
||||
// Copyright 2017-2026 @polkadot/hw-ledger-transports authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Do not edit, auto-generated by @polkadot/dev
|
||||
|
||||
export const packageInfo = { name: '@polkadot/hw-ledger-transports', path: 'auto', type: 'auto', version: '10.2.6' };
|
||||
export const packageInfo = { name: '@polkadot/hw-ledger-transports', path: 'auto', type: 'auto', version: '14.0.3' };
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2017-2023 @polkadot/hw-ledger authors & contributors
|
||||
// Copyright 2017-2026 @polkadot/hw-ledger authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
export * from './empty';
|
||||
export * from './empty.js';
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
// Copyright 2017-2023 @polkadot/hw-ledger authors & contributors
|
||||
// Copyright 2017-2026 @polkadot/hw-ledger authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import Transport from '@ledgerhq/hw-transport';
|
||||
// CJS, so we use import * syntax
|
||||
import type * as HwTransport from '@ledgerhq/hw-transport';
|
||||
|
||||
export type LedgerTypes = 'hid' | 'u2f' | 'webusb';
|
||||
// u2f is deprecated an therefore not added
|
||||
export type TransportType = 'hid' | 'webusb';
|
||||
|
||||
export type Transport = HwTransport.default;
|
||||
|
||||
export interface TransportDef {
|
||||
/** Create a transport to be used in Ledger operations */
|
||||
create (): Promise<Transport>;
|
||||
/** The type of the underlying transport definition */
|
||||
type: LedgerTypes;
|
||||
type: TransportType;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
// Copyright 2017-2026 @polkadot/hw-ledger authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { Transport, TransportDef, TransportType } from './types.js';
|
||||
|
||||
export function createDefs (...items: readonly [type: TransportType, Clazz: unknown][]): TransportDef[] {
|
||||
return items.map(([type, Clazz]): TransportDef => ({
|
||||
create: (): Promise<Transport> =>
|
||||
(Clazz as Pick<TransportDef, 'create'>).create(),
|
||||
type
|
||||
}));
|
||||
}
|
||||
@@ -5,6 +5,9 @@
|
||||
"outDir": "./build",
|
||||
"rootDir": "./src"
|
||||
},
|
||||
"exclude": [
|
||||
"**/mod.ts"
|
||||
],
|
||||
"references": [
|
||||
{ "path": "../util/tsconfig.build.json" }
|
||||
]
|
||||
|
||||
@@ -1,201 +0,0 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
@@ -1,13 +1,11 @@
|
||||
{
|
||||
"author": "Jaco Greeff <jacogr@gmail.com>",
|
||||
"bugs": "https://github.com/polkadot-js/common/issues",
|
||||
"contributors": [],
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
"node": ">=18"
|
||||
},
|
||||
"homepage": "https://github.com/polkadot-js/common/tree/master/packages/hw-ledger#readme",
|
||||
"license": "Apache-2.0",
|
||||
"maintainers": [],
|
||||
"name": "@polkadot/hw-ledger",
|
||||
"repository": {
|
||||
"directory": "packages/hw-ledger",
|
||||
@@ -15,17 +13,16 @@
|
||||
"url": "https://github.com/polkadot-js/common.git"
|
||||
},
|
||||
"sideEffects": [
|
||||
"./detectPackage.js",
|
||||
"./detectPackage.cjs"
|
||||
"./packageDetect.js",
|
||||
"./packageDetect.cjs"
|
||||
],
|
||||
"type": "module",
|
||||
"version": "10.2.6",
|
||||
"version": "14.0.3",
|
||||
"main": "index.js",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.20.7",
|
||||
"@ledgerhq/hw-transport": "^6.27.9",
|
||||
"@polkadot/hw-ledger-transports": "10.2.6",
|
||||
"@polkadot/util": "10.2.6",
|
||||
"@zondax/ledger-substrate": "^0.40.3"
|
||||
"@polkadot/hw-ledger-transports": "14.0.3",
|
||||
"@polkadot/util": "14.0.3",
|
||||
"@zondax/ledger-substrate": "1.1.1",
|
||||
"tslib": "^2.8.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,169 @@
|
||||
// Copyright 2017-2026 @polkadot/hw-ledger authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { SubstrateApp } from '@zondax/ledger-substrate';
|
||||
import type { Transport, TransportDef, TransportType } from '@polkadot/hw-ledger-transports/types';
|
||||
import type { AccountOptions, LedgerAddress, LedgerSignature, LedgerVersion } from './types.js';
|
||||
|
||||
import { newSubstrateApp } from '@zondax/ledger-substrate';
|
||||
|
||||
import { transports } from '@polkadot/hw-ledger-transports';
|
||||
import { hexAddPrefix, u8aToBuffer, u8aWrapBytes } from '@polkadot/util';
|
||||
|
||||
import { LEDGER_DEFAULT_ACCOUNT, LEDGER_DEFAULT_CHANGE, LEDGER_DEFAULT_INDEX, LEDGER_SUCCESS_CODE } from './constants.js';
|
||||
import { ledgerApps } from './defaults.js';
|
||||
|
||||
export { packageInfo } from './packageInfo.js';
|
||||
|
||||
type Chain = keyof typeof ledgerApps;
|
||||
|
||||
type WrappedResult = Awaited<ReturnType<SubstrateApp['getAddress' | 'getVersion' | 'sign']>>;
|
||||
|
||||
/** @internal Wraps a SubstrateApp call, checking the result for any errors which result in a rejection */
|
||||
async function wrapError <T extends WrappedResult> (promise: Promise<T>): Promise<T> {
|
||||
const result = await promise;
|
||||
|
||||
if (result.return_code !== LEDGER_SUCCESS_CODE) {
|
||||
throw new Error(result.error_message);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/** @internal Best-effort transport cleanup after failed operations */
|
||||
async function closeTransport (transport: Transport | null): Promise<void> {
|
||||
if (transport) {
|
||||
try {
|
||||
await transport.close();
|
||||
} catch {
|
||||
// Ignore cleanup errors so the original failure is preserved.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @internal Wraps a sign/signRaw call and returns the associated signature */
|
||||
function sign (method: 'sign' | 'signRaw', message: Uint8Array, accountOffset = 0, addressOffset = 0, { account = LEDGER_DEFAULT_ACCOUNT, addressIndex = LEDGER_DEFAULT_INDEX, change = LEDGER_DEFAULT_CHANGE }: Partial<AccountOptions> = {}): (app: SubstrateApp) => Promise<LedgerSignature> {
|
||||
return async (app: SubstrateApp): Promise<LedgerSignature> => {
|
||||
const { signature } = await wrapError(app[method](account + accountOffset, change, addressIndex + addressOffset, u8aToBuffer(message)));
|
||||
|
||||
return {
|
||||
signature: hexAddPrefix(signature.toString('hex'))
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @name Ledger
|
||||
*
|
||||
* @description
|
||||
* Legacy wrapper for a ledger app -
|
||||
* - it connects automatically on use, creating an underlying interface as required
|
||||
* - Promises reject with errors (unwrapped errors from @zondax/ledger-substrate)
|
||||
* @deprecated Use LedgerGeneric for up to date integration with ledger
|
||||
*/
|
||||
export class Ledger {
|
||||
readonly #ledgerName: string;
|
||||
readonly #transportDef: TransportDef;
|
||||
|
||||
#app: SubstrateApp | null = null;
|
||||
|
||||
constructor (transport: TransportType, chain: Chain) {
|
||||
const ledgerName = ledgerApps[chain];
|
||||
const transportDef = transports.find(({ type }) => type === transport);
|
||||
|
||||
if (!ledgerName) {
|
||||
throw new Error(`Unsupported Ledger chain ${chain}`);
|
||||
} else if (!transportDef) {
|
||||
throw new Error(`Unsupported Ledger transport ${transport}`);
|
||||
}
|
||||
|
||||
this.#ledgerName = ledgerName;
|
||||
this.#transportDef = transportDef;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the address associated with a specific account & address offset. Optionally
|
||||
* asks for on-device confirmation
|
||||
*/
|
||||
public async getAddress (confirm = false, accountOffset = 0, addressOffset = 0, { account = LEDGER_DEFAULT_ACCOUNT, addressIndex = LEDGER_DEFAULT_INDEX, change = LEDGER_DEFAULT_CHANGE }: Partial<AccountOptions> = {}): Promise<LedgerAddress> {
|
||||
return this.withApp(async (app: SubstrateApp): Promise<LedgerAddress> => {
|
||||
const { address, pubKey } = await wrapError(app.getAddress(account + accountOffset, change, addressIndex + addressOffset, confirm));
|
||||
|
||||
return {
|
||||
address,
|
||||
publicKey: hexAddPrefix(pubKey)
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the version of the Ledger application on the device
|
||||
*/
|
||||
public async getVersion (): Promise<LedgerVersion> {
|
||||
return this.withApp(async (app: SubstrateApp): Promise<LedgerVersion> => {
|
||||
const { device_locked: isLocked, major, minor, patch, test_mode: isTestMode } = await wrapError(app.getVersion());
|
||||
|
||||
return {
|
||||
isLocked,
|
||||
isTestMode,
|
||||
version: [major, minor, patch]
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Signs a transaction on the Ledger device
|
||||
*/
|
||||
public async sign (message: Uint8Array, accountOffset?: number, addressOffset?: number, options?: Partial<AccountOptions>): Promise<LedgerSignature> {
|
||||
return this.withApp(sign('sign', message, accountOffset, addressOffset, options));
|
||||
}
|
||||
|
||||
/**
|
||||
* Signs a message (non-transactional) on the Ledger device
|
||||
*/
|
||||
public async signRaw (message: Uint8Array, accountOffset?: number, addressOffset?: number, options?: Partial<AccountOptions>): Promise<LedgerSignature> {
|
||||
return this.withApp(sign('signRaw', u8aWrapBytes(message), accountOffset, addressOffset, options));
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes any active transport connection
|
||||
*/
|
||||
public async disconnect (): Promise<void> {
|
||||
const app = this.#app;
|
||||
|
||||
this.#app = null;
|
||||
|
||||
await closeTransport(app?.transport || null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* Returns a created SubstrateApp to perform operations against. Generally
|
||||
* this is only used internally, to ensure consistent behavior.
|
||||
*/
|
||||
async withApp <T> (fn: (app: SubstrateApp) => Promise<T>): Promise<T> {
|
||||
let transport: Transport | null = null;
|
||||
|
||||
try {
|
||||
if (!this.#app) {
|
||||
transport = await this.#transportDef.create();
|
||||
|
||||
// We need this override for the actual type passing - the Deno environment
|
||||
// is quite a bit stricter and it yields invalids between the two (specifically
|
||||
// since we mangle the imports from .default in the types for CJS/ESM and between
|
||||
// esm.sh versions this yields problematic outputs)
|
||||
//
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-explicit-any
|
||||
this.#app = newSubstrateApp(transport as any, this.#ledgerName);
|
||||
}
|
||||
|
||||
return await fn(this.#app);
|
||||
} catch (error) {
|
||||
await closeTransport(this.#app?.transport || transport);
|
||||
this.#app = null;
|
||||
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,300 @@
|
||||
// Copyright 2017-2026 @polkadot/hw-ledger authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { Transport, TransportDef, TransportType } from '@polkadot/hw-ledger-transports/types';
|
||||
import type { AccountOptionsGeneric, LedgerAddress, LedgerSignature, LedgerVersion } from './types.js';
|
||||
|
||||
import { PolkadotGenericApp } from '@zondax/ledger-substrate';
|
||||
|
||||
import { transports } from '@polkadot/hw-ledger-transports';
|
||||
import { hexAddPrefix, u8aToBuffer, u8aWrapBytes } from '@polkadot/util';
|
||||
|
||||
import { ledgerApps } from './defaults.js';
|
||||
|
||||
export { packageInfo } from './packageInfo.js';
|
||||
|
||||
type Chain = keyof typeof ledgerApps;
|
||||
|
||||
type WrappedResult = Awaited<ReturnType<PolkadotGenericApp['getAddress' | 'getVersion' | 'sign' | 'signWithMetadata']>>;
|
||||
|
||||
// FIXME This type is a copy of the `class ResponseError`
|
||||
// imported from `@zondax/ledger-js`. Happens because ledger-js includes
|
||||
// circular dependencies. This is a hack to avoid versioning issues
|
||||
// with Deno.
|
||||
interface ResponseError {
|
||||
errorMessage: string
|
||||
returnCode: number
|
||||
}
|
||||
|
||||
/** @internal Wraps a PolkadotGenericApp call, checking the result for any errors which result in a rejection */
|
||||
async function wrapError <T extends WrappedResult> (promise: Promise<T>): Promise<T> {
|
||||
let result: T;
|
||||
|
||||
try {
|
||||
result = await promise;
|
||||
} catch (e: unknown) {
|
||||
// We check to see if the propagated error is the newer ResponseError type.
|
||||
// The response code use to be part of the result, but with the latest breaking changes from 0.42.x
|
||||
// the interface and it's types have completely changed.
|
||||
if ((e as ResponseError).returnCode) {
|
||||
throw new Error(`${(e as ResponseError).returnCode}: ${(e as ResponseError).errorMessage}`);
|
||||
}
|
||||
|
||||
throw new Error((e as Error).message);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/** @internal Best-effort transport cleanup after failed operations */
|
||||
async function closeTransport (transport: Transport | null): Promise<void> {
|
||||
if (transport) {
|
||||
try {
|
||||
await transport.close();
|
||||
} catch {
|
||||
// Ignore cleanup errors so the original failure is preserved.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @internal Wraps a signEd25519/signRawEd25519 call and returns the associated signature */
|
||||
function sign (method: 'signEd25519' | 'signRawEd25519', message: Uint8Array, slip44: number, accountIndex = 0, addressOffset = 0): (app: PolkadotGenericApp) => Promise<LedgerSignature> {
|
||||
const bip42Path = `m/44'/${slip44}'/${accountIndex}'/${0}'/${addressOffset}'`;
|
||||
|
||||
return async (app: PolkadotGenericApp): Promise<LedgerSignature> => {
|
||||
const { signature } = await wrapError(app[method](bip42Path, u8aToBuffer(message)));
|
||||
|
||||
return {
|
||||
signature: hexAddPrefix(signature.toString('hex'))
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
/** @internal Wraps a signEcdsa/signRawEcdsa call and returns the associated signature */
|
||||
function signEcdsa (method: 'signEcdsa' | 'signRawEcdsa', message: Uint8Array, slip44: number, accountIndex = 0, addressOffset = 0): (app: PolkadotGenericApp) => Promise<LedgerSignature> {
|
||||
const bip42Path = `m/44'/${slip44}'/${accountIndex}'/${0}'/${addressOffset}'`;
|
||||
|
||||
return async (app: PolkadotGenericApp): Promise<LedgerSignature> => {
|
||||
const { r, s, v } = await wrapError(app[method](bip42Path, u8aToBuffer(message)));
|
||||
|
||||
const signature = Buffer.concat([r, s, v]);
|
||||
|
||||
return {
|
||||
signature: hexAddPrefix(signature.toString('hex'))
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
/** @internal Wraps a signWithMetadataEd25519 call and returns the associated signature */
|
||||
function signWithMetadata (message: Uint8Array, slip44: number, accountIndex = 0, addressOffset = 0, { metadata }: Partial<AccountOptionsGeneric> = {}): (app: PolkadotGenericApp) => Promise<LedgerSignature> {
|
||||
const bip42Path = `m/44'/${slip44}'/${accountIndex}'/${0}'/${addressOffset}'`;
|
||||
|
||||
return async (app: PolkadotGenericApp): Promise<LedgerSignature> => {
|
||||
if (!metadata) {
|
||||
throw new Error('The metadata option must be present when using signWithMetadata');
|
||||
}
|
||||
|
||||
const bufferMsg = Buffer.from(message);
|
||||
|
||||
const { signature } = await wrapError(app.signWithMetadataEd25519(bip42Path, bufferMsg, metadata));
|
||||
|
||||
return {
|
||||
signature: hexAddPrefix(signature.toString('hex'))
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
/** @internal Wraps a signWithMetadataEcdsa call and returns the associated signature */
|
||||
function signWithMetadataEcdsa (message: Uint8Array, slip44: number, accountIndex = 0, addressOffset = 0, { metadata }: Partial<AccountOptionsGeneric> = {}): (app: PolkadotGenericApp) => Promise<LedgerSignature> {
|
||||
const bip42Path = `m/44'/${slip44}'/${accountIndex}'/${0}'/${addressOffset}'`;
|
||||
|
||||
return async (app: PolkadotGenericApp): Promise<LedgerSignature> => {
|
||||
if (!metadata) {
|
||||
throw new Error('The metadata option must be present when using signWithMetadata');
|
||||
}
|
||||
|
||||
const bufferMsg = Buffer.from(message);
|
||||
|
||||
const { r, s, v } = await wrapError(app.signWithMetadataEcdsa(bip42Path, bufferMsg, metadata));
|
||||
|
||||
const signature = Buffer.concat([r, s, v]);
|
||||
|
||||
return {
|
||||
signature: hexAddPrefix(signature.toString('hex'))
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @name Ledger
|
||||
*
|
||||
* @description
|
||||
* A very basic wrapper for a ledger app -
|
||||
* - it connects automatically on use, creating an underlying interface as required
|
||||
* - Promises reject with errors (unwrapped errors from @zondax/ledger-substrate-js)
|
||||
*/
|
||||
export class LedgerGeneric {
|
||||
readonly #transportDef: TransportDef;
|
||||
readonly #slip44: number;
|
||||
/**
|
||||
* The chainId is represented by the chains token in all lowercase. Example: Polkadot -> dot
|
||||
*/
|
||||
readonly #chainId?: string;
|
||||
/**
|
||||
* The metaUrl is seen as a server url that the underlying `PolkadotGenericApp` will use to
|
||||
* retrieve the signature given a tx blob, and a chainId. It is important to note that if you would like to avoid
|
||||
* having any network calls made, use `signWithMetadata`, and avoid `sign`.
|
||||
*/
|
||||
readonly #metaUrl?: string;
|
||||
|
||||
#app: PolkadotGenericApp | null = null;
|
||||
|
||||
constructor (transport: TransportType, chain: Chain, slip44: number, chainId?: string, metaUrl?: string) {
|
||||
const ledgerName = ledgerApps[chain];
|
||||
const transportDef = transports.find(({ type }) => type === transport);
|
||||
|
||||
if (!ledgerName) {
|
||||
throw new Error(`Unsupported Ledger chain ${chain}`);
|
||||
} else if (!transportDef) {
|
||||
throw new Error(`Unsupported Ledger transport ${transport}`);
|
||||
}
|
||||
|
||||
this.#metaUrl = metaUrl;
|
||||
this.#chainId = chainId;
|
||||
this.#slip44 = slip44;
|
||||
this.#transportDef = transportDef;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Returns the address associated with a specific Ed25519 account & address offset. Optionally
|
||||
* asks for on-device confirmation
|
||||
*/
|
||||
public async getAddress (ss58Prefix: number, confirm = false, accountIndex = 0, addressOffset = 0): Promise<LedgerAddress> {
|
||||
const bip42Path = `m/44'/${this.#slip44}'/${accountIndex}'/${0}'/${addressOffset}'`;
|
||||
|
||||
return this.withApp(async (app: PolkadotGenericApp): Promise<LedgerAddress> => {
|
||||
const { address, pubKey } = await wrapError(app.getAddressEd25519(bip42Path, ss58Prefix, confirm));
|
||||
|
||||
return {
|
||||
address,
|
||||
publicKey: hexAddPrefix(pubKey)
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Returns the address associated with a specific ecdsa account & address offset. Optionally
|
||||
* asks for on-device confirmation
|
||||
*/
|
||||
public async getAddressEcdsa (confirm = false, accountIndex = 0, addressOffset = 0) {
|
||||
const bip42Path = `m/44'/${this.#slip44}'/${accountIndex}'/${0}'/${addressOffset}'`;
|
||||
|
||||
return this.withApp(async (app: PolkadotGenericApp): Promise<LedgerAddress> => {
|
||||
const { address, pubKey } = await wrapError(app.getAddressEcdsa(bip42Path, confirm));
|
||||
|
||||
return {
|
||||
address,
|
||||
publicKey: hexAddPrefix(pubKey)
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Returns the version of the Ledger application on the device
|
||||
*/
|
||||
public async getVersion (): Promise<LedgerVersion> {
|
||||
return this.withApp(async (app: PolkadotGenericApp): Promise<LedgerVersion> => {
|
||||
const { deviceLocked: isLocked, major, minor, patch, testMode: isTestMode } = await wrapError(app.getVersion());
|
||||
|
||||
return {
|
||||
isLocked: !!isLocked,
|
||||
isTestMode: !!isTestMode,
|
||||
version: [major || 0, minor || 0, patch || 0]
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Signs a transaction on the Ledger device. This requires the LedgerGeneric class to be instantiated with `chainId`, and `metaUrl`
|
||||
*/
|
||||
public async sign (message: Uint8Array, accountIndex?: number, addressOffset?: number): Promise<LedgerSignature> {
|
||||
return this.withApp(sign('signEd25519', message, this.#slip44, accountIndex, addressOffset));
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Signs a message (non-transactional) on the Ledger device
|
||||
*/
|
||||
public async signRaw (message: Uint8Array, accountIndex?: number, addressOffset?: number): Promise<LedgerSignature> {
|
||||
return this.withApp(sign('signRawEd25519', u8aWrapBytes(message), this.#slip44, accountIndex, addressOffset));
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Signs a transaction on the Ledger device with Ecdsa. This requires the LedgerGeneric class to be instantiated with `chainId`, and `metaUrl`
|
||||
*/
|
||||
public async signEcdsa (message: Uint8Array, accountIndex?: number, addressOffset?: number): Promise<LedgerSignature> {
|
||||
return this.withApp(signEcdsa('signEcdsa', u8aWrapBytes(message), this.#slip44, accountIndex, addressOffset));
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Signs a message with Ecdsa (non-transactional) on the Ledger device
|
||||
*/
|
||||
public async signRawEcdsa (message: Uint8Array, accountIndex?: number, addressOffset?: number): Promise<LedgerSignature> {
|
||||
return this.withApp(signEcdsa('signRawEcdsa', u8aWrapBytes(message), this.#slip44, accountIndex, addressOffset));
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Signs a transaction on the ledger device provided some metadata.
|
||||
*/
|
||||
public async signWithMetadata (message: Uint8Array, accountIndex?: number, addressOffset?: number, options?: Partial<AccountOptionsGeneric>): Promise<LedgerSignature> {
|
||||
return this.withApp(signWithMetadata(message, this.#slip44, accountIndex, addressOffset, options));
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Signs a transaction on the ledger device for an ecdsa signature provided some metadata.
|
||||
*/
|
||||
public async signWithMetadataEcdsa (message: Uint8Array, accountIndex?: number, addressOffset?: number, options?: Partial<AccountOptionsGeneric>) {
|
||||
return this.withApp(signWithMetadataEcdsa(message, this.#slip44, accountIndex, addressOffset, options));
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes any active transport connection
|
||||
*/
|
||||
public async disconnect (): Promise<void> {
|
||||
const app = this.#app;
|
||||
|
||||
this.#app = null;
|
||||
|
||||
await closeTransport(app?.transport || null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* Returns a created PolkadotGenericApp to perform operations against. Generally
|
||||
* this is only used internally, to ensure consistent bahavior.
|
||||
*/
|
||||
async withApp <T> (fn: (app: PolkadotGenericApp) => Promise<T>): Promise<T> {
|
||||
let transport: Transport | null = null;
|
||||
|
||||
try {
|
||||
if (!this.#app) {
|
||||
transport = await this.#transportDef.create();
|
||||
|
||||
// We need this override for the actual type passing - the Deno environment
|
||||
// is quite a bit stricter and it yields invalids between the two (specifically
|
||||
// since we mangle the imports from .default in the types for CJS/ESM and between
|
||||
// esm.sh versions this yields problematic outputs)
|
||||
//
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-explicit-any
|
||||
this.#app = new PolkadotGenericApp(transport as any, this.#chainId, this.#metaUrl);
|
||||
}
|
||||
|
||||
return await fn(this.#app);
|
||||
} catch (error) {
|
||||
await closeTransport(this.#app?.transport || transport);
|
||||
this.#app = null;
|
||||
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,115 +1,8 @@
|
||||
// Copyright 2017-2023 @polkadot/hw-ledger authors & contributors
|
||||
// Copyright 2017-2026 @polkadot/hw-ledger authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { SubstrateApp } from '@zondax/ledger-substrate';
|
||||
import type { AccountOptions, LedgerAddress, LedgerSignature, LedgerTypes, LedgerVersion } from './types';
|
||||
|
||||
import { newSubstrateApp } from '@zondax/ledger-substrate';
|
||||
|
||||
import { transports } from '@polkadot/hw-ledger-transports';
|
||||
import { hexAddPrefix, u8aToBuffer } from '@polkadot/util';
|
||||
|
||||
import { LEDGER_DEFAULT_ACCOUNT, LEDGER_DEFAULT_CHANGE, LEDGER_DEFAULT_INDEX, LEDGER_SUCCESS_CODE } from './constants';
|
||||
import { ledgerApps } from './defaults';
|
||||
|
||||
export { packageInfo } from './packageInfo';
|
||||
|
||||
type Chain = keyof typeof ledgerApps;
|
||||
|
||||
type WrappedResult = Awaited<ReturnType<SubstrateApp['getAddress' | 'getVersion' | 'sign']>>;
|
||||
|
||||
/** @internal Wraps a SubstrateApp call, checking the result for any errors which result in a rejection */
|
||||
async function wrapError <T extends WrappedResult> (promise: Promise<T>): Promise<T> {
|
||||
const result = await promise;
|
||||
|
||||
if (result.return_code !== LEDGER_SUCCESS_CODE) {
|
||||
throw new Error(result.error_message);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// A very basic wrapper for a ledger app -
|
||||
// - it connects automatically, creating an app as required
|
||||
// - Promises return errors (instead of wrapper errors)
|
||||
export class Ledger {
|
||||
#app: SubstrateApp | null = null;
|
||||
|
||||
#chain: Chain;
|
||||
|
||||
#transport: LedgerTypes;
|
||||
|
||||
constructor (transport: LedgerTypes, chain: Chain) {
|
||||
// u2f is deprecated
|
||||
if (!['hid', 'webusb'].includes(transport)) {
|
||||
throw new Error(`Unsupported transport ${transport}`);
|
||||
} else if (!Object.keys(ledgerApps).includes(chain)) {
|
||||
throw new Error(`Unsupported chain ${chain}`);
|
||||
}
|
||||
|
||||
this.#chain = chain;
|
||||
this.#transport = transport;
|
||||
}
|
||||
|
||||
public async getAddress (confirm = false, accountOffset = 0, addressOffset = 0, { account = LEDGER_DEFAULT_ACCOUNT, addressIndex = LEDGER_DEFAULT_INDEX, change = LEDGER_DEFAULT_CHANGE }: Partial<AccountOptions> = {}): Promise<LedgerAddress> {
|
||||
return this.#withApp(async (app: SubstrateApp): Promise<LedgerAddress> => {
|
||||
const { address, pubKey } = await wrapError(app.getAddress(account + accountOffset, change, addressIndex + addressOffset, confirm));
|
||||
|
||||
return {
|
||||
address,
|
||||
publicKey: hexAddPrefix(pubKey)
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
public async getVersion (): Promise<LedgerVersion> {
|
||||
return this.#withApp(async (app: SubstrateApp): Promise<LedgerVersion> => {
|
||||
const { device_locked: isLocked, major, minor, patch, test_mode: isTestMode } = await wrapError(app.getVersion());
|
||||
|
||||
return {
|
||||
isLocked,
|
||||
isTestMode,
|
||||
version: [major, minor, patch]
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
public async sign (message: Uint8Array, accountOffset = 0, addressOffset = 0, { account = LEDGER_DEFAULT_ACCOUNT, addressIndex = LEDGER_DEFAULT_INDEX, change = LEDGER_DEFAULT_CHANGE }: Partial<AccountOptions> = {}): Promise<LedgerSignature> {
|
||||
return this.#withApp(async (app: SubstrateApp): Promise<LedgerSignature> => {
|
||||
const buffer = u8aToBuffer(message);
|
||||
const { signature } = await wrapError(app.sign(account + accountOffset, change, addressIndex + addressOffset, buffer));
|
||||
|
||||
return {
|
||||
signature: hexAddPrefix(signature.toString('hex'))
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
#getApp = async (): Promise<SubstrateApp> => {
|
||||
if (!this.#app) {
|
||||
const def = transports.find(({ type }) => type === this.#transport);
|
||||
|
||||
if (!def) {
|
||||
throw new Error(`Unable to find a transport for ${this.#transport}`);
|
||||
}
|
||||
|
||||
const transport = await def.create();
|
||||
|
||||
this.#app = newSubstrateApp(transport, ledgerApps[this.#chain]);
|
||||
}
|
||||
|
||||
return this.#app;
|
||||
};
|
||||
|
||||
#withApp = async <T> (fn: (app: SubstrateApp) => Promise<T>): Promise<T> => {
|
||||
try {
|
||||
const app = await this.#getApp();
|
||||
|
||||
return await fn(app);
|
||||
} catch (error) {
|
||||
this.#app = null;
|
||||
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
}
|
||||
// This is necessary to ensure users still have access to class Ledger even though its deprecated.
|
||||
//
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
export { Ledger } from './Ledger.js';
|
||||
export { LedgerGeneric } from './LedgerGeneric.js';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2017-2023 @polkadot/hw-ledger authors & contributors
|
||||
// Copyright 2017-2026 @polkadot/hw-ledger authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
export const LEDGER_DEFAULT_ACCOUNT = 0x80000000;
|
||||
|
||||
@@ -1,16 +1,20 @@
|
||||
// Copyright 2017-2023 @polkadot/hw-ledger authors & contributors
|
||||
// Copyright 2017-2026 @polkadot/hw-ledger authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
/// <reference types="@polkadot/dev-test/globals.d.ts" />
|
||||
|
||||
import { supportedApps } from '@zondax/ledger-substrate';
|
||||
|
||||
import { ledgerApps } from './defaults';
|
||||
import { prevLedgerRecord } from './defaults.js';
|
||||
|
||||
describe('ledgerApps', (): void => {
|
||||
it.each(Object.keys(ledgerApps))('%s is known', (k): void => {
|
||||
expect(
|
||||
supportedApps.find(({ name }) =>
|
||||
name === ledgerApps[k]
|
||||
)
|
||||
).toBeDefined();
|
||||
});
|
||||
for (const k of Object.keys(prevLedgerRecord)) {
|
||||
it(`${k} is available in @zondax/ledger-substrate`, (): void => {
|
||||
expect(
|
||||
supportedApps.find(({ name }) =>
|
||||
name === prevLedgerRecord[k]
|
||||
)
|
||||
).toBeDefined();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
// Copyright 2017-2023 @polkadot/hw-ledger authors & contributors
|
||||
// Copyright 2017-2026 @polkadot/hw-ledger authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// These match up with the keys of the knownLedger object in the @polkadot/networks/defaults/ledger.ts
|
||||
// and maps to the known name in the @zondax/ledger-substrate/supported_apps package
|
||||
export const ledgerApps: Record<string, string> = {
|
||||
// These map to the known name in the @zondax/ledger-substrate/supported_apps package
|
||||
// but they do not reflect all ledger apps that are supported. Since ledger now has support for all
|
||||
// substrate chains via the PolkadotGenericApp, any new chains that need ledger support can be added to
|
||||
// `genericLedgerApps` below.
|
||||
export const prevLedgerRecord: Record<string, string> = {
|
||||
acala: 'Acala',
|
||||
ajuna: 'Ajuna',
|
||||
'aleph-node': 'AlephZero',
|
||||
@@ -15,6 +17,7 @@ export const ledgerApps: Record<string, string> = {
|
||||
darwinia: 'Darwinia',
|
||||
'dock-mainnet': 'Dock',
|
||||
edgeware: 'Edgeware',
|
||||
enjin: 'Enjin',
|
||||
equilibrium: 'Equilibrium',
|
||||
genshiro: 'Genshiro',
|
||||
hydradx: 'HydraDX',
|
||||
@@ -22,18 +25,45 @@ export const ledgerApps: Record<string, string> = {
|
||||
karura: 'Karura',
|
||||
khala: 'Khala',
|
||||
kusama: 'Kusama',
|
||||
matrixchain: 'Matrixchain',
|
||||
nodle: 'Nodle',
|
||||
origintrail: 'OriginTrail',
|
||||
parallel: 'Parallel',
|
||||
peaq: 'Peaq',
|
||||
pendulum: 'Pendulum',
|
||||
phala: 'Phala',
|
||||
picasso: 'Picasso',
|
||||
polkadex: 'Polkadex',
|
||||
polkadot: 'Polkadot',
|
||||
polymesh: 'Polymesh',
|
||||
quartz: 'Quartz',
|
||||
sora: 'Sora',
|
||||
stafi: 'Stafi',
|
||||
statemine: 'Statemine',
|
||||
statemint: 'Statemint',
|
||||
ternoa: 'Ternoa',
|
||||
unique: 'Unique',
|
||||
vtb: 'VTB',
|
||||
xxnetwork: 'XXNetwork'
|
||||
xxnetwork: 'XXNetwork',
|
||||
zeitgeist: 'Zeitgeist'
|
||||
};
|
||||
|
||||
// Any chains moving forward that are supported by the PolkadotGenericApp from ledger will input their names below.
|
||||
export const genericLedgerApps = {
|
||||
bittensor: 'Bittensor',
|
||||
creditcoin3: 'Creditcoin3',
|
||||
dentnet: 'DENTNet',
|
||||
encointer: 'Encointer',
|
||||
frequency: 'Frequency',
|
||||
integritee: 'Integritee',
|
||||
liberland: 'Liberland',
|
||||
mythos: 'Mythos',
|
||||
polimec: 'Polimec',
|
||||
vara: 'Vara'
|
||||
};
|
||||
|
||||
// These match up with the keys of the knownLedger object in the @polkadot/networks/defaults/ledger.ts
|
||||
export const ledgerApps: Record<string, string> = {
|
||||
...prevLedgerRecord,
|
||||
...genericLedgerApps
|
||||
};
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
// Copyright 2017-2023 @polkadot/hw-ledger authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { packageInfo as transportInfo } from '@polkadot/hw-ledger-transports/packageInfo';
|
||||
import { packageInfo as utilInfo } from '@polkadot/util/packageInfo';
|
||||
|
||||
export default [transportInfo, utilInfo];
|
||||
@@ -1,11 +0,0 @@
|
||||
// Copyright 2017-2023 @polkadot/hw-ledger authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Do not edit, auto-generated by @polkadot/dev
|
||||
|
||||
import { detectPackage } from '@polkadot/util';
|
||||
|
||||
import others from './detectOther';
|
||||
import { packageInfo } from './packageInfo';
|
||||
|
||||
detectPackage(packageInfo, null, others);
|
||||
@@ -1,6 +1,6 @@
|
||||
// Copyright 2017-2023 @polkadot/hw-ledger authors & contributors
|
||||
// Copyright 2017-2026 @polkadot/hw-ledger authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import './detectPackage';
|
||||
import './packageDetect.js';
|
||||
|
||||
export * from './bundle';
|
||||
export * from './bundle.js';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2017-2023 @polkadot/hw-ledger authors & contributors
|
||||
// Copyright 2017-2026 @polkadot/hw-ledger authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
export * from './index';
|
||||
export * from './index.js';
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
// Copyright 2017-2026 @polkadot/hw-ledger authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Do not edit, auto-generated by @polkadot/dev
|
||||
// (packageInfo imports will be kept as-is, user-editable)
|
||||
|
||||
import { packageInfo as transportInfo } from '@polkadot/hw-ledger-transports/packageInfo';
|
||||
import { detectPackage } from '@polkadot/util';
|
||||
import { packageInfo as utilInfo } from '@polkadot/util/packageInfo';
|
||||
|
||||
import { packageInfo } from './packageInfo.js';
|
||||
|
||||
detectPackage(packageInfo, null, [transportInfo, utilInfo]);
|
||||
@@ -1,6 +1,6 @@
|
||||
// Copyright 2017-2023 @polkadot/hw-ledger authors & contributors
|
||||
// Copyright 2017-2026 @polkadot/hw-ledger authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Do not edit, auto-generated by @polkadot/dev
|
||||
|
||||
export const packageInfo = { name: '@polkadot/hw-ledger', path: 'auto', type: 'auto', version: '10.2.6' };
|
||||
export const packageInfo = { name: '@polkadot/hw-ledger', path: 'auto', type: 'auto', version: '14.0.3' };
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
// Copyright 2017-2023 @polkadot/hw-ledger authors & contributors
|
||||
// Copyright 2017-2026 @polkadot/hw-ledger authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { HexString } from '@polkadot/util/types';
|
||||
|
||||
export type LedgerTypes = 'hid' | 'u2f' | 'webusb';
|
||||
|
||||
/**
|
||||
* Legacy Type that works with the `Ledger` class.
|
||||
*/
|
||||
export interface AccountOptions {
|
||||
/** The index of the account */
|
||||
account: number;
|
||||
@@ -14,6 +15,11 @@ export interface AccountOptions {
|
||||
change: number;
|
||||
}
|
||||
|
||||
export interface AccountOptionsGeneric extends AccountOptions {
|
||||
/** Option for PolkadotGenericApp.signWithMetadata */
|
||||
metadata: Buffer;
|
||||
}
|
||||
|
||||
export interface LedgerAddress {
|
||||
/** The ss58 encoded address */
|
||||
address: string;
|
||||
|
||||
@@ -5,6 +5,10 @@
|
||||
"outDir": "./build",
|
||||
"rootDir": "./src"
|
||||
},
|
||||
"exclude": [
|
||||
"**/*.spec.ts",
|
||||
"**/mod.ts"
|
||||
],
|
||||
"references": [
|
||||
{ "path": "../hw-ledger-transports/tsconfig.build.json" },
|
||||
{ "path": "../util/tsconfig.build.json" }
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"baseUrl": "..",
|
||||
"outDir": "./build",
|
||||
"rootDir": "./src",
|
||||
"emitDeclarationOnly": false,
|
||||
"noEmit": true
|
||||
},
|
||||
"include": [
|
||||
"**/*.spec.ts"
|
||||
],
|
||||
"references": [
|
||||
{ "path": "../hw-ledger/tsconfig.build.json" }
|
||||
]
|
||||
}
|
||||
@@ -1,201 +0,0 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
@@ -1,14 +1,12 @@
|
||||
{
|
||||
"author": "Jaco Greeff <jacogr@gmail.com>",
|
||||
"bugs": "https://github.com/polkadot-js/common/issues",
|
||||
"contributors": [],
|
||||
"description": "Keyring management",
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
"node": ">=18"
|
||||
},
|
||||
"homepage": "https://github.com/polkadot-js/common/tree/master/packages/keyring#readme",
|
||||
"license": "Apache-2.0",
|
||||
"maintainers": [],
|
||||
"name": "@polkadot/keyring",
|
||||
"repository": {
|
||||
"directory": "packages/keyring",
|
||||
@@ -16,19 +14,20 @@
|
||||
"url": "https://github.com/polkadot-js/common.git"
|
||||
},
|
||||
"sideEffects": [
|
||||
"./detectPackage.js",
|
||||
"./detectPackage.cjs"
|
||||
"./packageDetect.js",
|
||||
"./packageDetect.cjs"
|
||||
],
|
||||
"type": "module",
|
||||
"version": "10.2.6",
|
||||
"version": "14.0.3-quantus.2",
|
||||
"main": "index.js",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.20.7",
|
||||
"@polkadot/util": "10.2.6",
|
||||
"@polkadot/util-crypto": "10.2.6"
|
||||
"@polkadot/util": "14.0.3",
|
||||
"@polkadot/util-crypto": "14.0.3-quantus.2",
|
||||
"@quantus/crypto": "^0.1.0",
|
||||
"tslib": "^2.8.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@polkadot/util": "10.2.6",
|
||||
"@polkadot/util-crypto": "10.2.6"
|
||||
"@polkadot/util": "14.0.3",
|
||||
"@polkadot/util-crypto": "14.0.3"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
// Copyright 2017-2023 @polkadot/keyring authors & contributors
|
||||
// Copyright 2017-2026 @polkadot/keyring authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { Keyring } from './keyring';
|
||||
|
||||
// all external
|
||||
// eslint-disable-next-line deprecation/deprecation
|
||||
export { decodeAddress, encodeAddress, setSS58Format } from '@polkadot/util-crypto';
|
||||
|
||||
export * from './defaults';
|
||||
export { createPair } from './pair';
|
||||
export { packageInfo } from './packageInfo';
|
||||
export { createTestKeyring } from './testing';
|
||||
export { createTestPairs } from './testingPairs';
|
||||
// all named
|
||||
export { Keyring } from './keyring.js';
|
||||
export { packageInfo } from './packageInfo.js';
|
||||
export { createPair } from './pair/index.js';
|
||||
export { createTestKeyring } from './testing.js';
|
||||
export { createTestPairs } from './testingPairs.js';
|
||||
|
||||
export { Keyring };
|
||||
// all starred
|
||||
export * from './defaults.js';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2017-2023 @polkadot/keyring authors & contributors
|
||||
// Copyright 2017-2026 @polkadot/keyring authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// default substrate dev phrase
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
// Copyright 2017-2023 @polkadot/keyring authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { packageInfo as utilInfo } from '@polkadot/util/packageInfo';
|
||||
import { packageInfo as cryptoInfo } from '@polkadot/util-crypto/packageInfo';
|
||||
|
||||
export default [utilInfo, cryptoInfo];
|
||||
@@ -1,11 +0,0 @@
|
||||
// Copyright 2017-2023 @polkadot/keyring authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Do not edit, auto-generated by @polkadot/dev
|
||||
|
||||
import { detectPackage } from '@polkadot/util';
|
||||
|
||||
import others from './detectOther';
|
||||
import { packageInfo } from './packageInfo';
|
||||
|
||||
detectPackage(packageInfo, null, others);
|
||||
@@ -1,19 +1,20 @@
|
||||
// Copyright 2017-2023 @polkadot/keyring authors & contributors
|
||||
// Copyright 2017-2026 @polkadot/keyring authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { KeyringPair$Json } from './types';
|
||||
/// <reference types="@polkadot/dev-test/globals.d.ts" />
|
||||
|
||||
import type { KeyringPair$Json } from './types.js';
|
||||
|
||||
import { hexToU8a, stringToU8a } from '@polkadot/util';
|
||||
import { base64Decode, cryptoWaitReady, encodeAddress, randomAsU8a, setSS58Format } from '@polkadot/util-crypto';
|
||||
import { base64Decode, cryptoWaitReady, encodeAddress, mnemonicGenerate, randomAsU8a, setSS58Format } from '@polkadot/util-crypto';
|
||||
import * as languages from '@polkadot/util-crypto/mnemonic/wordlists/index';
|
||||
|
||||
import { decodePair } from './pair/decode';
|
||||
import Keyring from '.';
|
||||
import { decodePair } from './pair/decode.js';
|
||||
import Keyring from './index.js';
|
||||
|
||||
await cryptoWaitReady();
|
||||
|
||||
describe('keypair', (): void => {
|
||||
beforeEach(async (): Promise<void> => {
|
||||
await cryptoWaitReady();
|
||||
});
|
||||
|
||||
describe('ed25519', (): void => {
|
||||
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]);
|
||||
@@ -574,4 +575,35 @@ describe('keypair', (): void => {
|
||||
expect(pair.address).toBe('FLiSDPCcJ6auZUGXALLj6jpahcP6adVFDBUQznPXUQ7yoqH');
|
||||
});
|
||||
});
|
||||
|
||||
describe('wordlist', (): void => {
|
||||
it('creates keypair from different wordlists mnemonics', (): void => {
|
||||
Object.keys(languages).forEach((language) => {
|
||||
const mnemonic = mnemonicGenerate(12, languages[language as keyof typeof languages]);
|
||||
const keyring = new Keyring({
|
||||
type: 'ed25519'
|
||||
});
|
||||
|
||||
expect(keyring.addFromMnemonic(
|
||||
mnemonic,
|
||||
{},
|
||||
'ed25519',
|
||||
languages[language as keyof typeof languages]
|
||||
)).toBeDefined();
|
||||
});
|
||||
});
|
||||
it('cannot create from invalid wordlist', (): void => {
|
||||
const mnemonic = mnemonicGenerate(12, languages.japanese);
|
||||
const keyring = new Keyring({
|
||||
type: 'ed25519'
|
||||
});
|
||||
|
||||
expect(() => keyring.addFromMnemonic(
|
||||
mnemonic,
|
||||
{},
|
||||
'ed25519',
|
||||
languages.english
|
||||
)).toThrow('Invalid bip39 mnemonic specified');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
// Copyright 2017-2023 @polkadot/keyring authors & contributors
|
||||
// Copyright 2017-2026 @polkadot/keyring authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import './detectPackage';
|
||||
import './packageDetect.js';
|
||||
|
||||
import { Keyring } from './bundle';
|
||||
import { Keyring } from './bundle.js';
|
||||
|
||||
export * from './bundle';
|
||||
export * from './bundle.js';
|
||||
|
||||
export default Keyring;
|
||||
|
||||
@@ -1,17 +1,29 @@
|
||||
// Copyright 2017-2023 @polkadot/keyring authors & contributors
|
||||
// Copyright 2017-2026 @polkadot/keyring authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { EncryptedJsonEncoding, Keypair, KeypairType } from '@polkadot/util-crypto/types';
|
||||
import type { KeyringInstance, KeyringOptions, KeyringPair, KeyringPair$Json, KeyringPair$Meta } from './types';
|
||||
import type { KeyringInstance, KeyringOptions, KeyringPair, KeyringPair$Json, KeyringPair$Meta } from './types.js';
|
||||
|
||||
import { hexToU8a, isHex, stringToU8a } from '@polkadot/util';
|
||||
import { base64Decode, decodeAddress, ed25519PairFromSeed as ed25519FromSeed, encodeAddress, ethereumEncode, hdEthereum, keyExtractSuri, keyFromPath, mnemonicToLegacySeed, mnemonicToMiniSecret, secp256k1PairFromSeed as secp256k1FromSeed, sr25519PairFromSeed as sr25519FromSeed } from '@polkadot/util-crypto';
|
||||
import { base64Decode, decodeAddress, dilithiumPairFromMnemonic, dilithiumPairFromSeed, dilithiumPathFromSuri, ed25519PairFromSeed as ed25519FromSeed, encodeAddress, ethereumEncode, hdEthereum, isDilithium, keyExtractSuri, keyFromPath, mnemonicToLegacySeed, mnemonicToMiniSecret, secp256k1PairFromSeed as secp256k1FromSeed, sr25519PairFromSeed as sr25519FromSeed } from '@polkadot/util-crypto';
|
||||
|
||||
import { DEV_PHRASE } from './defaults';
|
||||
import { createPair } from './pair';
|
||||
import { Pairs } from './pairs';
|
||||
import { createPair } from './pair/index.js';
|
||||
import { DEV_PHRASE } from './defaults.js';
|
||||
import { Pairs } from './pairs.js';
|
||||
|
||||
/**
|
||||
* Every keypair type this keyring will construct.
|
||||
*
|
||||
* Was two separate inline arrays, both of which a widened `KeypairType` silently
|
||||
* walked past — the union is compile-time and these checks are not. Named once so
|
||||
* the next change to the union has one place to look, and so the error message
|
||||
* cannot drift from the check.
|
||||
*/
|
||||
const KEYPAIR_TYPES: KeypairType[] = ['dilithium65', 'dilithium87', 'ecdsa', 'ed25519', 'ethereum', 'sr25519'];
|
||||
|
||||
const PairFromSeed = {
|
||||
dilithium65: (seed: Uint8Array): Keypair => dilithiumPairFromSeed(seed, 'dilithium65'),
|
||||
dilithium87: (seed: Uint8Array): Keypair => dilithiumPairFromSeed(seed, 'dilithium87'),
|
||||
ecdsa: (seed: Uint8Array): Keypair => secp256k1FromSeed(seed),
|
||||
ed25519: (seed: Uint8Array): Keypair => ed25519FromSeed(seed),
|
||||
ethereum: (seed: Uint8Array): Keypair => secp256k1FromSeed(seed),
|
||||
@@ -43,15 +55,18 @@ export class Keyring implements KeyringInstance {
|
||||
|
||||
readonly #type: KeypairType;
|
||||
|
||||
#ss58?: number;
|
||||
#ss58?: number | undefined;
|
||||
|
||||
public decodeAddress = decodeAddress;
|
||||
|
||||
constructor (options: KeyringOptions = {}) {
|
||||
options.type = options.type || 'ed25519';
|
||||
|
||||
if (!['ecdsa', 'ethereum', 'ed25519', 'sr25519'].includes(options.type || 'undefined')) {
|
||||
throw new Error(`Expected a keyring type of either 'ed25519', 'sr25519', 'ethereum' or 'ecdsa', found '${options.type || 'unknown'}`);
|
||||
// A runtime whitelist behind the KeypairType union, so widening the type
|
||||
// alone was not enough — the compiler cannot see this one, and it fails at
|
||||
// construction rather than at use.
|
||||
if (!KEYPAIR_TYPES.includes(options.type || ('undefined' as KeypairType))) {
|
||||
throw new Error(`Expected a keyring type of one of ${KEYPAIR_TYPES.map((t) => `'${t}'`).join(', ')}, found '${options.type || 'unknown'}'`);
|
||||
}
|
||||
|
||||
this.#pairs = new Pairs();
|
||||
@@ -121,8 +136,8 @@ export 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.
|
||||
*/
|
||||
public addFromMnemonic (mnemonic: string, meta: KeyringPair$Meta = {}, type: KeypairType = this.type): KeyringPair {
|
||||
return this.addFromUri(mnemonic, meta, type);
|
||||
public addFromMnemonic (mnemonic: string, meta: KeyringPair$Meta = {}, type: KeypairType = this.type, wordlist?: string[]): KeyringPair {
|
||||
return this.addFromUri(mnemonic, meta, type, wordlist);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -153,9 +168,9 @@ export class Keyring implements KeyringInstance {
|
||||
* @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)
|
||||
*/
|
||||
public addFromUri (suri: string, meta: KeyringPair$Meta = {}, type: KeypairType = this.type): KeyringPair {
|
||||
public addFromUri (suri: string, meta: KeyringPair$Meta = {}, type: KeypairType = this.type, wordlist?: string[]): KeyringPair {
|
||||
return this.addPair(
|
||||
this.createFromUri(suri, meta, type)
|
||||
this.createFromUri(suri, meta, type, wordlist)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -175,19 +190,35 @@ export class Keyring implements KeyringInstance {
|
||||
? [type]
|
||||
: type;
|
||||
|
||||
if (!['ed25519', 'sr25519', 'ecdsa', 'ethereum'].includes(cryptoType)) {
|
||||
// Same list, second copy — this one guards JSON coming in from a file the
|
||||
// user chose, so it is the guard that will matter most once quantus/common#6
|
||||
// narrows the union and imports of quantum-unsafe keys have to be refused
|
||||
// with a message explaining why rather than "unknown crypto type".
|
||||
if (!KEYPAIR_TYPES.includes(cryptoType as KeypairType)) {
|
||||
throw new Error(`Unknown crypto type ${cryptoType}`);
|
||||
}
|
||||
|
||||
// Here the address and publicKey are 32 bytes and isomorphic. This is why the address field needs to be the public key for ethereum type pairs
|
||||
const publicKey = isHex(address)
|
||||
// For the curve schemes the address and publicKey are 32 bytes and
|
||||
// isomorphic, which is why the address field holds the public key for
|
||||
// ethereum pairs and why this works at all.
|
||||
const raw = isHex(address)
|
||||
? hexToU8a(address)
|
||||
: this.decodeAddress(address, ignoreChecksum);
|
||||
const decoded = isHex(encoded)
|
||||
? hexToU8a(encoded)
|
||||
: base64Decode(encoded);
|
||||
|
||||
return createPair({ toSS58: this.encodeAddress, type: cryptoType as KeypairType }, { publicKey, secretKey: new Uint8Array() }, meta, decoded, encType);
|
||||
// ML-DSA breaks the isomorphism: the account id is a one-way Poseidon2 hash
|
||||
// and the 1952/2592-byte public key is inside `decoded`, which is encrypted
|
||||
// and stays that way until someone supplies a password. So pass the account
|
||||
// id as an account id rather than pretending it is a key — createPair uses
|
||||
// it for the address while locked, and checks it against the real public key
|
||||
// the moment `decodePkcs8` produces one.
|
||||
const info = isDilithium(cryptoType as KeypairType)
|
||||
? { accountId: raw, publicKey: new Uint8Array(), secretKey: new Uint8Array() }
|
||||
: { publicKey: raw, secretKey: new Uint8Array() };
|
||||
|
||||
return createPair({ toSS58: this.encodeAddress, type: cryptoType as KeypairType }, info, meta, decoded, encType);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -203,7 +234,7 @@ export class Keyring implements KeyringInstance {
|
||||
* @summary Creates a Keypair from an suri
|
||||
* @description This creates a pair from the suri, but does not add it to the keyring
|
||||
*/
|
||||
public createFromUri (_suri: string, meta: KeyringPair$Meta = {}, type: KeypairType = this.type): KeyringPair {
|
||||
public createFromUri (_suri: string, meta: KeyringPair$Meta = {}, type: KeypairType = this.type, wordlist?: string[]): KeyringPair {
|
||||
// here we only aut-add the dev phrase if we have a hard-derived path
|
||||
const suri = _suri.startsWith('//')
|
||||
? `${DEV_PHRASE}${_suri}`
|
||||
@@ -212,6 +243,33 @@ export class Keyring implements KeyringInstance {
|
||||
let seed: Uint8Array;
|
||||
const isPhraseHex = isHex(phrase, 256);
|
||||
|
||||
// ML-DSA derives from the mnemonic itself along a hardened BIP44 path, not
|
||||
// from a seed along a junction chain — lattice keys have no public
|
||||
// derivability, so there is no soft junction to emulate and the chain's own
|
||||
// Pair::derive refuses for the same reason. Handled before the seeding below
|
||||
// because that seeding (mnemonicToMiniSecret) is the wrong one for us and
|
||||
// would produce a valid key for an account nobody owns.
|
||||
if (isDilithium(type)) {
|
||||
if (isPhraseHex) {
|
||||
// A raw 32-byte seed goes straight into keygen, which is how the
|
||||
// dev-genesis accounts are defined. Combining one with a derivation path
|
||||
// is ambiguous — is the seed the master, or already derived? — so refuse
|
||||
// rather than pick.
|
||||
if (derivePath) {
|
||||
throw new Error('A derivation path cannot be combined with a raw seed for post-quantum pairs');
|
||||
}
|
||||
|
||||
return createPair({ toSS58: this.encodeAddress, type }, PairFromSeed[type](hexToU8a(phrase)), meta, null);
|
||||
}
|
||||
|
||||
return createPair(
|
||||
{ toSS58: this.encodeAddress, type },
|
||||
dilithiumPairFromMnemonic(phrase, password || '', dilithiumPathFromSuri(type, derivePath), type),
|
||||
meta,
|
||||
null
|
||||
);
|
||||
}
|
||||
|
||||
if (isPhraseHex) {
|
||||
seed = hexToU8a(phrase);
|
||||
} else {
|
||||
@@ -220,7 +278,7 @@ export class Keyring implements KeyringInstance {
|
||||
if ([12, 15, 18, 21, 24].includes(parts.length)) {
|
||||
seed = type === 'ethereum'
|
||||
? mnemonicToLegacySeed(phrase, '', false, 64)
|
||||
: mnemonicToMiniSecret(phrase, password);
|
||||
: mnemonicToMiniSecret(phrase, password, wordlist);
|
||||
} else {
|
||||
if (phrase.length > 32) {
|
||||
throw new Error('specified phrase is not a valid mnemonic and is invalid as a raw seed at > 32 bytes');
|
||||
@@ -246,7 +304,7 @@ export class Keyring implements KeyringInstance {
|
||||
public encodeAddress = (address: Uint8Array | string, ss58Format?: number): string => {
|
||||
return this.type === 'ethereum'
|
||||
? ethereumEncode(address)
|
||||
: encodeAddress(address, ss58Format === undefined ? this.#ss58 : ss58Format);
|
||||
: encodeAddress(address, ss58Format ?? this.#ss58);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2017-2023 @polkadot/keyring authors & contributors
|
||||
// Copyright 2017-2026 @polkadot/keyring authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
export * from './index';
|
||||
export * from './index.js';
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
// Copyright 2017-2026 @polkadot/keyring authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Do not edit, auto-generated by @polkadot/dev
|
||||
// (packageInfo imports will be kept as-is, user-editable)
|
||||
|
||||
import { detectPackage } from '@polkadot/util';
|
||||
import { packageInfo as utilInfo } from '@polkadot/util/packageInfo';
|
||||
import { packageInfo as cryptoInfo } from '@polkadot/util-crypto/packageInfo';
|
||||
|
||||
import { packageInfo } from './packageInfo.js';
|
||||
|
||||
detectPackage(packageInfo, null, [cryptoInfo, utilInfo]);
|
||||
@@ -1,6 +1,6 @@
|
||||
// Copyright 2017-2023 @polkadot/keyring authors & contributors
|
||||
// Copyright 2017-2026 @polkadot/keyring authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Do not edit, auto-generated by @polkadot/dev
|
||||
|
||||
export const packageInfo = { name: '@polkadot/keyring', path: 'auto', type: 'auto', version: '10.2.6' };
|
||||
export const packageInfo = { name: '@polkadot/keyring', path: 'auto', type: 'auto', version: '14.0.3-quantus.2' };
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
// Copyright 2017-2023 @polkadot/keyring authors & contributors
|
||||
// Copyright 2017-2026 @polkadot/keyring authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { createTestPairs } from '../testingPairs';
|
||||
/// <reference types="@polkadot/dev-test/globals.d.ts" />
|
||||
|
||||
import { createTestPairs } from '../testingPairs.js';
|
||||
|
||||
const keyring = createTestPairs({ type: 'ed25519' }, false);
|
||||
|
||||
|
||||
@@ -1,47 +1,81 @@
|
||||
// Copyright 2017-2023 @polkadot/keyring authors & contributors
|
||||
// Copyright 2017-2026 @polkadot/keyring authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { EncryptedJsonEncoding } from '@polkadot/util-crypto/types';
|
||||
import type { PairInfo } from './types';
|
||||
|
||||
import { u8aEq } from '@polkadot/util';
|
||||
import { jsonDecryptData } from '@polkadot/util-crypto';
|
||||
|
||||
import { PKCS8_DIVIDER, PKCS8_HEADER, PUB_LENGTH, SEC_LENGTH, SEED_LENGTH } from './defaults';
|
||||
import { PAIR_DIV, PAIR_HDR, PUB_LENGTH, SEC_LENGTH, SEED_LENGTH } from './defaults.js';
|
||||
|
||||
const SEED_OFFSET = PKCS8_HEADER.length;
|
||||
const SEED_OFFSET = PAIR_HDR.length;
|
||||
|
||||
type DecodeResult = PairInfo & {
|
||||
secretKey: Uint8Array;
|
||||
};
|
||||
|
||||
export function decodePair (passphrase?: string, encrypted?: Uint8Array | null, _encType?: EncryptedJsonEncoding | EncryptedJsonEncoding[]): DecodeResult {
|
||||
/**
|
||||
* Decode a pair, taking into account the generation-specific formats and headers
|
||||
*
|
||||
* For divisor/headers, don't rely on the magic being static. These will
|
||||
* change between generations, aka with the long-awaited 4th generation
|
||||
* of the format. The external decode interface is the only way to use and decode these.
|
||||
*
|
||||
* `secretLength` exists for keys that are not 32 or 64 bytes. The body is
|
||||
* `HDR ‖ secretKey ‖ DIV ‖ publicKey`, and upstream located the divider by
|
||||
* trying the two lengths every curve scheme uses. An ML-DSA secret is 4032 or
|
||||
* 4896 bytes, so neither offset matches and the decode throws "Invalid encoding
|
||||
* divider found in body" — a stored account that cannot be read back.
|
||||
*
|
||||
* The caller passes the length rather than this function searching for the
|
||||
* divider. Searching would work almost always and fail catastrophically when it
|
||||
* did not: PAIR_DIV is five bytes, so a 4032-byte secret contains a false match
|
||||
* about once in 270 million keys, and the result would be a silently wrong key
|
||||
* rather than an error. The caller knows the type, so it knows the length.
|
||||
**/
|
||||
export function decodePair (passphrase?: string, encrypted?: Uint8Array | null, _encType?: EncryptedJsonEncoding | EncryptedJsonEncoding[], secretLength?: number): { publicKey: Uint8Array; secretKey: Uint8Array } {
|
||||
const encType = Array.isArray(_encType) || _encType === undefined
|
||||
? _encType
|
||||
: [_encType];
|
||||
const decrypted = jsonDecryptData(encrypted, passphrase, encType);
|
||||
const header = decrypted.subarray(0, PKCS8_HEADER.length);
|
||||
const header = decrypted.subarray(0, PAIR_HDR.length);
|
||||
|
||||
if (!u8aEq(header, PKCS8_HEADER)) {
|
||||
throw new Error('Invalid Pkcs8 header found in body');
|
||||
// check the start header (generations 1-3)
|
||||
if (!u8aEq(header, PAIR_HDR)) {
|
||||
throw new Error('Invalid encoding header found in body');
|
||||
}
|
||||
|
||||
// an explicitly-sized secret (ML-DSA); there is one offset and it either
|
||||
// matches or the blob is not what the caller said it was
|
||||
if (secretLength) {
|
||||
const divOffset = SEED_OFFSET + secretLength;
|
||||
|
||||
if (!u8aEq(decrypted.subarray(divOffset, divOffset + PAIR_DIV.length), PAIR_DIV)) {
|
||||
throw new Error('Invalid encoding divider found in body');
|
||||
}
|
||||
|
||||
return {
|
||||
// the public key is the remainder: its length varies by scheme and the
|
||||
// body ends here, so there is nothing to read past it
|
||||
publicKey: decrypted.subarray(divOffset + PAIR_DIV.length),
|
||||
secretKey: decrypted.subarray(SEED_OFFSET, divOffset)
|
||||
};
|
||||
}
|
||||
|
||||
// setup for generation 3 format
|
||||
let secretKey = decrypted.subarray(SEED_OFFSET, SEED_OFFSET + SEC_LENGTH);
|
||||
let divOffset = SEED_OFFSET + SEC_LENGTH;
|
||||
let divider = decrypted.subarray(divOffset, divOffset + PKCS8_DIVIDER.length);
|
||||
let divider = decrypted.subarray(divOffset, divOffset + PAIR_DIV.length);
|
||||
|
||||
// old-style, we have the seed here
|
||||
if (!u8aEq(divider, PKCS8_DIVIDER)) {
|
||||
// old-style (generation 1 & 2), we have the seed here
|
||||
if (!u8aEq(divider, PAIR_DIV)) {
|
||||
divOffset = SEED_OFFSET + SEED_LENGTH;
|
||||
secretKey = decrypted.subarray(SEED_OFFSET, divOffset);
|
||||
divider = decrypted.subarray(divOffset, divOffset + PKCS8_DIVIDER.length);
|
||||
divider = decrypted.subarray(divOffset, divOffset + PAIR_DIV.length);
|
||||
|
||||
if (!u8aEq(divider, PKCS8_DIVIDER)) {
|
||||
throw new Error('Invalid Pkcs8 divider found in body');
|
||||
// check the divisior at this point (already checked for generation 3)
|
||||
if (!u8aEq(divider, PAIR_DIV)) {
|
||||
throw new Error('Invalid encoding divider found in body');
|
||||
}
|
||||
}
|
||||
|
||||
const pubOffset = divOffset + PKCS8_DIVIDER.length;
|
||||
const pubOffset = divOffset + PAIR_DIV.length;
|
||||
const publicKey = decrypted.subarray(pubOffset, pubOffset + PUB_LENGTH);
|
||||
|
||||
return {
|
||||
|
||||
@@ -1,9 +1,20 @@
|
||||
// Copyright 2017-2023 @polkadot/keyring authors & contributors
|
||||
// Copyright 2017-2026 @polkadot/keyring authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
export const PKCS8_DIVIDER = new Uint8Array([161, 35, 3, 33, 0]);
|
||||
export const PKCS8_HEADER = new Uint8Array([48, 83, 2, 1, 1, 48, 5, 6, 3, 43, 101, 112, 4, 34, 4, 32]);
|
||||
/** public/secret section divider (generation 1-3, will change in 4, don't rely on value) */
|
||||
export const PAIR_DIV = new Uint8Array([161, 35, 3, 33, 0]);
|
||||
|
||||
/** public/secret start block (generation 1-3, will change in 4, don't rely on value) */
|
||||
export const PAIR_HDR = new Uint8Array([48, 83, 2, 1, 1, 48, 5, 6, 3, 43, 101, 112, 4, 34, 4, 32]);
|
||||
|
||||
/** length of a public key */
|
||||
export const PUB_LENGTH = 32;
|
||||
|
||||
/** length of a salt */
|
||||
export const SALT_LENGTH = 32;
|
||||
|
||||
/** length of a secret key */
|
||||
export const SEC_LENGTH = 64;
|
||||
|
||||
/** length of a user-input seed */
|
||||
export const SEED_LENGTH = 32;
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
// Copyright 2017-2026 @polkadot/keyring authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
/// <reference types="@polkadot/dev-test/globals.d.ts" />
|
||||
|
||||
import { contextForSpec, Scheme, sizes } from '@quantus/crypto';
|
||||
|
||||
import { dilithiumVerify } from '@polkadot/util-crypto';
|
||||
|
||||
import { Keyring } from '../keyring.js';
|
||||
|
||||
// crystal_alice, from the chain's dev genesis: a raw 32-byte seed straight into
|
||||
// ML-DSA-87 keygen, no HD derivation. The expected address is what
|
||||
// `quantus developer create-test-wallets` prints — an independent implementation,
|
||||
// not this one.
|
||||
const ALICE_ADDRESS = 'qzk1Nxai3dZD9Cn5kwGcgL6mKxsfxwqdis7kDQJ52aJS2vSn7';
|
||||
|
||||
const MESSAGE = new Uint8Array([0x74, 0x68, 0x65, 0x20, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64]);
|
||||
|
||||
describe('dilithium pairs', (): void => {
|
||||
const keyring = new Keyring({ ss58Format: 189, type: 'dilithium87' });
|
||||
const alice = keyring.addFromSeed(new Uint8Array(32), { name: 'crystal_alice' }, 'dilithium87');
|
||||
const context = contextForSpec(148);
|
||||
const s87 = sizes(Scheme.MlDsa87);
|
||||
const s65 = sizes(Scheme.MlDsa65);
|
||||
|
||||
it('derives the address quantus-cli derives', (): void => {
|
||||
expect(alice.address).toEqual(ALICE_ADDRESS);
|
||||
});
|
||||
|
||||
// The assumption this whole fork exists to break. Everywhere else in this
|
||||
// package `addressRaw` and `publicKey` are the same 32 bytes.
|
||||
it('has an addressRaw that is not the publicKey', (): void => {
|
||||
expect(alice.addressRaw.length).toEqual(32);
|
||||
expect(alice.publicKey.length).toEqual(s87.publicKey);
|
||||
});
|
||||
|
||||
it('signs to the wire form the runtime reads', (): void => {
|
||||
const signature = alice.sign(MESSAGE, { context });
|
||||
|
||||
expect(signature.length).toEqual(s87.signatureWithPublicKey);
|
||||
});
|
||||
|
||||
// `withType` prepends the signature enum's variant index. For the curve types
|
||||
// that enum is Substrate's MultiSignature; here it is the runtime's
|
||||
// DilithiumSignatureScheme, reached by the same mechanism.
|
||||
it('prepends the chain variant byte with withType', (): void => {
|
||||
const signed87 = alice.sign(MESSAGE, { context, withType: true });
|
||||
const k65 = keyring.addFromSeed(new Uint8Array(32).fill(9), {}, 'dilithium65');
|
||||
const signed65 = k65.sign(MESSAGE, { context, withType: true });
|
||||
|
||||
expect(signed87[0]).toEqual(0);
|
||||
expect(signed87.length).toEqual(s87.signatureWithPublicKey + 1);
|
||||
expect(signed65[0]).toEqual(1);
|
||||
expect(signed65.length).toEqual(s65.signatureWithPublicKey + 1);
|
||||
});
|
||||
|
||||
it('verifies against the account id', (): void => {
|
||||
const signature = alice.sign(MESSAGE, { context });
|
||||
|
||||
expect(dilithiumVerify(MESSAGE, signature, alice.addressRaw, 'dilithium87', context)).toEqual(true);
|
||||
});
|
||||
|
||||
// The spec-148 boundary. A signature made under the wrong context is
|
||||
// cryptographically valid and rejected by the chain, so this is the only place
|
||||
// it can be caught locally.
|
||||
it('does not verify under the wrong context', (): void => {
|
||||
const signature = alice.sign(MESSAGE, { context });
|
||||
|
||||
expect(dilithiumVerify(MESSAGE, signature, alice.addressRaw, 'dilithium87', contextForSpec(147))).toEqual(false);
|
||||
});
|
||||
|
||||
// Verification checks the embedded public key hashes to the account being
|
||||
// verified against, not merely that the signature is valid for *some* key.
|
||||
it('does not verify another account signature', (): void => {
|
||||
const bob = keyring.addFromSeed(new Uint8Array(32).fill(1), {}, 'dilithium87');
|
||||
const signature = bob.sign(MESSAGE, { context });
|
||||
|
||||
expect(dilithiumVerify(MESSAGE, signature, alice.addressRaw, 'dilithium87', context)).toEqual(false);
|
||||
});
|
||||
|
||||
it('refuses to sign without a context', (): void => {
|
||||
expect(() => alice.sign(MESSAGE)).toThrow(/signing context is required/);
|
||||
});
|
||||
|
||||
// There is no ML-DSA VRF, and faking one from an ordinary signature would
|
||||
// produce output that looks like a VRF proof and cannot be verified as one.
|
||||
it('refuses to VRF sign', (): void => {
|
||||
expect(() => alice.vrfSign(MESSAGE)).toThrow(/not available for dilithium87/);
|
||||
});
|
||||
|
||||
// The classical paths must be untouched — this is what a careless rebase
|
||||
// breaks, and it would break silently.
|
||||
it('leaves sr25519 unchanged', (): void => {
|
||||
const sr = new Keyring({ type: 'sr25519' }).addFromUri('//Alice');
|
||||
|
||||
expect(sr.address).toEqual('5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY');
|
||||
expect(sr.sign(MESSAGE).length).toEqual(64);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,104 @@
|
||||
// Copyright 2017-2026 @polkadot/keyring authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
/// <reference types="@polkadot/dev-test/globals.d.ts" />
|
||||
|
||||
import { dilithiumPath } from '@polkadot/util-crypto';
|
||||
|
||||
import { Keyring } from '../keyring.js';
|
||||
|
||||
// The well-known Substrate development phrase — public by design, so pinning it
|
||||
// commits no secret. Any account it derives is assumed compromised.
|
||||
const DEV_PHRASE = 'bottom drive obey lake curtain smoke basket hold race lonely fit walk';
|
||||
|
||||
// What `quantus wallet import --mnemonic-file <DEV_PHRASE> --scheme <s>` prints.
|
||||
// An independent implementation, not this one.
|
||||
const EXPECT_65 = 'qzq29m9WvneDAeXbtgueKCREtNe1rVVs6bXSMLmjr6shqvwq6';
|
||||
const EXPECT_87 = 'qzjrYTUnnE5NduTZKxe9dESCMTZg7nTueKM3bwhnkRdD1iYV4';
|
||||
|
||||
// crystal_alice — a raw 32-byte seed straight into keygen, no derivation.
|
||||
const ALICE = 'qzk1Nxai3dZD9Cn5kwGcgL6mKxsfxwqdis7kDQJ52aJS2vSn7';
|
||||
|
||||
describe('dilithium derivation', (): void => {
|
||||
const keyring = new Keyring({ ss58Format: 189, type: 'dilithium65' });
|
||||
|
||||
it('builds the paths quantus-cli uses', (): void => {
|
||||
expect(dilithiumPath('dilithium65')).toEqual("m/44'/189189'/0'/0'/1'");
|
||||
expect(dilithiumPath('dilithium87')).toEqual("m/44'/189189'/0'/0'/0'");
|
||||
expect(dilithiumPath('dilithium65', 3)).toEqual("m/44'/189189'/3'/0'/1'");
|
||||
});
|
||||
|
||||
// The whole derivation chain at once: BIP39 to a 64-byte seed (not Substrate's
|
||||
// mnemonicToMiniSecret), the HMAC-SHA512 walk keyed with "Dilithium seed", the
|
||||
// trailing hardened index carrying the scheme, and the Poseidon2 account hash.
|
||||
it('derives what quantus-cli derives, both schemes', (): void => {
|
||||
expect(keyring.createFromUri(DEV_PHRASE, {}, 'dilithium65').address).toEqual(EXPECT_65);
|
||||
expect(keyring.createFromUri(DEV_PHRASE, {}, 'dilithium87').address).toEqual(EXPECT_87);
|
||||
});
|
||||
|
||||
it('defaults to account index 0', (): void => {
|
||||
expect(keyring.createFromUri(`${DEV_PHRASE}//0`, {}, 'dilithium65').address).toEqual(EXPECT_65);
|
||||
});
|
||||
|
||||
it('derives distinct accounts per index', (): void => {
|
||||
const zero = keyring.createFromUri(`${DEV_PHRASE}//0`, {}, 'dilithium65').address;
|
||||
const one = keyring.createFromUri(`${DEV_PHRASE}//1`, {}, 'dilithium65').address;
|
||||
|
||||
expect(zero).not.toEqual(one);
|
||||
});
|
||||
|
||||
it('accepts an explicit hardened path', (): void => {
|
||||
const byIndex = keyring.createFromUri(`${DEV_PHRASE}//2`, {}, 'dilithium65').address;
|
||||
const byPath = keyring.createFromUri(`${DEV_PHRASE}//m/44'/189189'/2'/0'/1'`, {}, 'dilithium65').address;
|
||||
|
||||
expect(byPath).toEqual(byIndex);
|
||||
});
|
||||
|
||||
// The suri syntax was built for curve junctions, where `/foo` is a soft
|
||||
// derivation over arbitrary bytes. Neither form exists for ML-DSA, and quietly
|
||||
// reinterpreting one would hand back an address no other tool derives.
|
||||
it('refuses soft derivation', (): void => {
|
||||
expect(() => keyring.createFromUri(`${DEV_PHRASE}/0`, {}, 'dilithium65')).toThrow(/Soft derivation is not possible/);
|
||||
});
|
||||
|
||||
it('refuses a named junction', (): void => {
|
||||
expect(() => keyring.createFromUri(`${DEV_PHRASE}//Alice`, {}, 'dilithium65')).toThrow(/Unsupported derivation path/);
|
||||
});
|
||||
|
||||
it('refuses an unhardened level in an explicit path', (): void => {
|
||||
expect(() => keyring.createFromUri(`${DEV_PHRASE}//m/44'/189189'/0'/0'/1`, {}, 'dilithium65')).toThrow(/Unhardened derivation/);
|
||||
});
|
||||
|
||||
// A raw seed is already key material. Whether it is the master or something
|
||||
// already derived is unanswerable, so combining it with a path is refused
|
||||
// rather than guessed.
|
||||
it('takes a raw hex seed underived, and refuses to derive from one', (): void => {
|
||||
const seed = `0x${'00'.repeat(32)}`;
|
||||
|
||||
expect(keyring.createFromUri(seed, {}, 'dilithium87').address).toEqual(ALICE);
|
||||
expect(() => keyring.createFromUri(`${seed}//1`, {}, 'dilithium87')).toThrow(/cannot be combined with a raw seed/);
|
||||
});
|
||||
|
||||
it('honours a BIP39 passphrase', (): void => {
|
||||
const plain = keyring.createFromUri(DEV_PHRASE, {}, 'dilithium65').address;
|
||||
const withPass = keyring.createFromUri(`${DEV_PHRASE}///hunter2`, {}, 'dilithium65').address;
|
||||
|
||||
expect(plain).not.toEqual(withPass);
|
||||
});
|
||||
|
||||
// Deriving a child *from a pair* is not merely unimplemented here, it is
|
||||
// impossible: ML-DSA keys are not derivable from one another, and the Quantus
|
||||
// tree derives each account from the mnemonic independently.
|
||||
it('refuses to derive from an existing pair', (): void => {
|
||||
const pair = keyring.createFromUri(DEV_PHRASE, {}, 'dilithium65');
|
||||
|
||||
expect(() => pair.derive('//1')).toThrow(/derive from the mnemonic with createFromUri/);
|
||||
});
|
||||
|
||||
it('leaves sr25519 junction derivation unchanged', (): void => {
|
||||
const sr = new Keyring({ type: 'sr25519' });
|
||||
|
||||
expect(sr.createFromUri('//Alice').address).toEqual('5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY');
|
||||
expect(sr.createFromUri('//Bob').address).toEqual('5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,114 @@
|
||||
// Copyright 2017-2026 @polkadot/keyring authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
/// <reference types="@polkadot/dev-test/globals.d.ts" />
|
||||
|
||||
import { contextForSpec } from '@quantus/crypto';
|
||||
|
||||
import { dilithiumVerify } from '@polkadot/util-crypto';
|
||||
|
||||
import { Keyring } from '../keyring.js';
|
||||
|
||||
// The address `quantus developer create-test-wallets` prints for crystal_alice.
|
||||
const ALICE_ADDRESS = 'qzk1Nxai3dZD9Cn5kwGcgL6mKxsfxwqdis7kDQJ52aJS2vSn7';
|
||||
const PASSWORD = 'not a good password';
|
||||
const MESSAGE = new Uint8Array([0x6a, 0x73, 0x6f, 0x6e]);
|
||||
|
||||
describe('dilithium account JSON', (): void => {
|
||||
const keyring = new Keyring({ ss58Format: 189, type: 'dilithium87' });
|
||||
const context = contextForSpec(148);
|
||||
|
||||
const backup = (type: 'dilithium65' | 'dilithium87', fill = 0) => {
|
||||
const pair = keyring.addFromSeed(new Uint8Array(32).fill(fill), { name: 'backed up' }, type);
|
||||
|
||||
return { json: pair.toJson(PASSWORD), original: pair };
|
||||
};
|
||||
|
||||
// The whole point. Before this worked, an exported Quantus account could not be
|
||||
// imported by anything — decodePair looked for its divider at one of two fixed
|
||||
// offsets and an ML-DSA secret is at neither, so restore threw "Invalid
|
||||
// encoding divider found in body". That is a data-durability bug, not a
|
||||
// convenience one: it had to land before any build let a user create an account.
|
||||
it('round-trips an ML-DSA-87 account', (): void => {
|
||||
const { json, original } = backup('dilithium87');
|
||||
const restored = keyring.createFromJson(json);
|
||||
|
||||
restored.decodePkcs8(PASSWORD);
|
||||
|
||||
expect(restored.address).toEqual(original.address);
|
||||
expect(restored.publicKey).toEqual(original.publicKey);
|
||||
expect(restored.isLocked).toEqual(false);
|
||||
});
|
||||
|
||||
it('round-trips an ML-DSA-65 account', (): void => {
|
||||
const { json, original } = backup('dilithium65', 5);
|
||||
const restored = keyring.createFromJson(json);
|
||||
|
||||
restored.decodePkcs8(PASSWORD);
|
||||
|
||||
expect(restored.address).toEqual(original.address);
|
||||
expect(restored.publicKey).toEqual(original.publicKey);
|
||||
});
|
||||
|
||||
// A restored pair is locked, and callers read `pair.address` off it long before
|
||||
// any password appears. For every other scheme that works because the address
|
||||
// *is* the public key; here the key is still encrypted, so the account id has
|
||||
// to be carried as data until decodePkcs8 supplies the real one.
|
||||
it('reports the same address before and after unlock', (): void => {
|
||||
const { json } = backup('dilithium87');
|
||||
const restored = keyring.createFromJson(json);
|
||||
|
||||
expect(restored.isLocked).toEqual(true);
|
||||
expect(restored.address).toEqual(ALICE_ADDRESS);
|
||||
|
||||
restored.decodePkcs8(PASSWORD);
|
||||
|
||||
expect(restored.address).toEqual(ALICE_ADDRESS);
|
||||
});
|
||||
|
||||
it('restores a pair that can still sign', (): void => {
|
||||
const { json, original } = backup('dilithium87');
|
||||
const restored = keyring.createFromJson(json);
|
||||
|
||||
restored.decodePkcs8(PASSWORD);
|
||||
|
||||
const signature = restored.sign(MESSAGE, { context });
|
||||
|
||||
expect(dilithiumVerify(MESSAGE, signature, original.addressRaw, 'dilithium87', context)).toEqual(true);
|
||||
});
|
||||
|
||||
it('fails cleanly on a wrong password', (): void => {
|
||||
const { json } = backup('dilithium87');
|
||||
const restored = keyring.createFromJson(json);
|
||||
|
||||
expect(() => restored.decodePkcs8('wrong')).toThrow();
|
||||
// and must not have half-applied anything
|
||||
expect(restored.isLocked).toEqual(true);
|
||||
expect(restored.address).toEqual(ALICE_ADDRESS);
|
||||
});
|
||||
|
||||
// For every other scheme a tampered `address` field cannot decode at all,
|
||||
// because the address is the public key. Here it decodes perfectly and yields a
|
||||
// pair reporting an address its key does not control — a user would see someone
|
||||
// else's address in their own wallet and believe they held it.
|
||||
it('rejects JSON whose address does not match its key', (): void => {
|
||||
const { json } = backup('dilithium87');
|
||||
const other = keyring.addFromSeed(new Uint8Array(32).fill(2), {}, 'dilithium87');
|
||||
const tampered = { ...json, address: other.address };
|
||||
const restored = keyring.createFromJson(tampered);
|
||||
|
||||
expect(restored.address).toEqual(other.address);
|
||||
expect(() => restored.decodePkcs8(PASSWORD)).toThrow(/does not match the address/);
|
||||
});
|
||||
|
||||
it('leaves sr25519 JSON round-tripping unchanged', (): void => {
|
||||
const sr = new Keyring({ type: 'sr25519' });
|
||||
const pair = sr.addFromUri('//Alice');
|
||||
const restored = sr.createFromJson(pair.toJson(PASSWORD));
|
||||
|
||||
restored.decodePkcs8(PASSWORD);
|
||||
|
||||
expect(restored.address).toEqual(pair.address);
|
||||
expect(restored.publicKey).toEqual(pair.publicKey);
|
||||
});
|
||||
});
|
||||
@@ -1,13 +1,15 @@
|
||||
// Copyright 2017-2023 @polkadot/keyring authors & contributors
|
||||
// Copyright 2017-2026 @polkadot/keyring authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
/// <reference types="@polkadot/dev-test/globals.d.ts" />
|
||||
|
||||
import { NONCE_LENGTH, SCRYPT_LENGTH } from '@polkadot/util-crypto/json/constants';
|
||||
|
||||
import { createTestPairs } from '../testingPairs';
|
||||
import { PKCS8_DIVIDER, PKCS8_HEADER, PUB_LENGTH, SEC_LENGTH } from './defaults';
|
||||
import { createTestPairs } from '../testingPairs.js';
|
||||
import { PAIR_DIV, PAIR_HDR, PUB_LENGTH, SEC_LENGTH } from './defaults.js';
|
||||
|
||||
const PKCS8_LENGTH = PKCS8_DIVIDER.length + PKCS8_HEADER.length + PUB_LENGTH + SEC_LENGTH;
|
||||
const ENCODED_LENGTH = 16 + PKCS8_LENGTH + NONCE_LENGTH + SCRYPT_LENGTH;
|
||||
const DECODED_LENGTH = PAIR_DIV.length + PAIR_HDR.length + PUB_LENGTH + SEC_LENGTH;
|
||||
const ENCODED_LENGTH = 16 + DECODED_LENGTH + NONCE_LENGTH + SCRYPT_LENGTH;
|
||||
|
||||
const keyring = createTestPairs({ type: 'ed25519' }, false);
|
||||
|
||||
@@ -15,7 +17,7 @@ describe('encode', (): void => {
|
||||
it('returns PKCS8 when no passphrase supplied', (): void => {
|
||||
expect(
|
||||
keyring.alice.encodePkcs8()
|
||||
).toHaveLength(PKCS8_LENGTH);
|
||||
).toHaveLength(DECODED_LENGTH);
|
||||
});
|
||||
|
||||
it('returns encoded PKCS8 when passphrase supplied', (): void => {
|
||||
|
||||
@@ -1,29 +1,28 @@
|
||||
// Copyright 2017-2023 @polkadot/keyring authors & contributors
|
||||
// Copyright 2017-2026 @polkadot/keyring authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { PairInfo } from './types';
|
||||
import type { PairInfo } from './types.js';
|
||||
|
||||
import { u8aConcat } from '@polkadot/util';
|
||||
import { naclEncrypt, scryptEncode, scryptToU8a } from '@polkadot/util-crypto';
|
||||
|
||||
import { PKCS8_DIVIDER, PKCS8_HEADER } from './defaults';
|
||||
import { PAIR_DIV, PAIR_HDR } from './defaults.js';
|
||||
|
||||
/**
|
||||
* Encode a pair with the latest generation format (generation 3)
|
||||
**/
|
||||
export function encodePair ({ publicKey, secretKey }: PairInfo, passphrase?: string): Uint8Array {
|
||||
if (!secretKey) {
|
||||
throw new Error('Expected a valid secretKey to be passed to encode');
|
||||
}
|
||||
|
||||
const encoded = u8aConcat(
|
||||
PKCS8_HEADER,
|
||||
secretKey,
|
||||
PKCS8_DIVIDER,
|
||||
publicKey
|
||||
);
|
||||
const encoded = u8aConcat(PAIR_HDR, secretKey, PAIR_DIV, publicKey);
|
||||
|
||||
if (!passphrase) {
|
||||
return encoded;
|
||||
}
|
||||
|
||||
// this is only for generation 3 (previous generations are only handled in decoding)
|
||||
const { params, password, salt } = scryptEncode(passphrase);
|
||||
const { encrypted, nonce } = naclEncrypt(encoded, password.subarray(0, 32));
|
||||
|
||||
|
||||
@@ -1,27 +1,23 @@
|
||||
// Copyright 2017-2023 @polkadot/keyring authors & contributors
|
||||
// Copyright 2017-2026 @polkadot/keyring authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
/// <reference types="@polkadot/dev-test/globals.d.ts" />
|
||||
|
||||
import { hexToU8a, u8aToHex } from '@polkadot/util';
|
||||
import { cryptoWaitReady, encodeAddress as toSS58, setSS58Format } from '@polkadot/util-crypto';
|
||||
|
||||
import { PAIRSSR25519 } from '../testing';
|
||||
import { createTestPairs } from '../testingPairs';
|
||||
import { createPair } from '.';
|
||||
import { PAIRSSR25519 } from '../testing.js';
|
||||
import { createTestPairs } from '../testingPairs.js';
|
||||
import { createPair } from './index.js';
|
||||
|
||||
const keyring = createTestPairs({ type: 'ed25519' }, false);
|
||||
|
||||
const TEST_ADDRESS = '0x4119b2e6c3Cb618F4f0B93ac77f9BeeC7FF02887';
|
||||
|
||||
await cryptoWaitReady();
|
||||
|
||||
describe('pair', (): void => {
|
||||
beforeEach(async (): Promise<void> => {
|
||||
await cryptoWaitReady();
|
||||
});
|
||||
|
||||
const SIGNATURE = new Uint8Array([80, 191, 198, 147, 225, 207, 75, 88, 126, 39, 129, 109, 191, 38, 72, 181, 75, 254, 81, 143, 244, 79, 237, 38, 236, 141, 28, 252, 134, 26, 169, 234, 79, 33, 153, 158, 151, 34, 175, 188, 235, 20, 35, 135, 83, 120, 139, 211, 233, 130, 1, 208, 201, 215, 73, 80, 56, 98, 185, 196, 11, 8, 193, 14]);
|
||||
const ENCRYPTED = new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 132, 59, 53, 85, 227, 40, 107, 48, 234, 198, 238, 157, 238, 224, 235, 179, 75, 153, 241, 142, 254]);
|
||||
|
||||
// the last byte is changed from 254 -> 253
|
||||
const ENCRYPTED_CHANGED = new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 132, 59, 53, 85, 227, 40, 107, 48, 234, 198, 238, 157, 238, 224, 235, 179, 75, 153, 241, 142, 253]);
|
||||
|
||||
it('has a publicKey', (): void => {
|
||||
expect(
|
||||
@@ -98,93 +94,6 @@ describe('pair', (): void => {
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
it('allows encrypting', (): void => {
|
||||
const message = new Uint8Array([0x61, 0x62, 0x63, 0x64, 0x65]);
|
||||
|
||||
expect(
|
||||
keyring.alice.encryptMessage(
|
||||
message,
|
||||
keyring.bob.publicKey,
|
||||
new Uint8Array(24)
|
||||
)
|
||||
).toEqual(ENCRYPTED);
|
||||
});
|
||||
|
||||
it('validates a correctly encrypted message', (): void => {
|
||||
const message = new Uint8Array([0x61, 0x62, 0x63, 0x64, 0x65]);
|
||||
|
||||
expect(
|
||||
keyring.bob.decryptMessage(
|
||||
ENCRYPTED,
|
||||
keyring.alice.publicKey
|
||||
)
|
||||
).toEqual(message);
|
||||
});
|
||||
|
||||
it('fails a correctly encrypted message (message changed)', (): void => {
|
||||
expect(
|
||||
keyring.bob.decryptMessage(
|
||||
ENCRYPTED_CHANGED,
|
||||
keyring.alice.publicKey
|
||||
)
|
||||
).toEqual(null);
|
||||
});
|
||||
|
||||
it('fails a correctly encrypted message (sender changed)', (): void => {
|
||||
expect(
|
||||
keyring.bob.decryptMessage(
|
||||
ENCRYPTED,
|
||||
keyring.charlie.publicKey
|
||||
)
|
||||
).toEqual(null);
|
||||
});
|
||||
|
||||
it('fails a correctly encrypted message (receiver changed)', (): void => {
|
||||
expect(
|
||||
keyring.charlie.decryptMessage(
|
||||
ENCRYPTED,
|
||||
keyring.alice.publicKey
|
||||
)
|
||||
).toEqual(null);
|
||||
});
|
||||
|
||||
it('validates encryption between ed25519 & sr25519 key pairs', (): void => {
|
||||
const PASS = 'testing';
|
||||
const encodedA = keyring.alice.encodePkcs8(PASS);
|
||||
const encodedB = keyring.bob.encodePkcs8(PASS);
|
||||
|
||||
const pairA = createPair({ toSS58, type: 'sr25519' }, { publicKey: keyring.alice.publicKey });
|
||||
const pairB = createPair({ toSS58, type: 'sr25519' }, { publicKey: keyring.bob.publicKey });
|
||||
|
||||
pairA.decodePkcs8(PASS, encodedA);
|
||||
pairB.decodePkcs8(PASS, encodedB);
|
||||
const message = new Uint8Array([0x61, 0x62, 0x63, 0x64, 0x65]);
|
||||
|
||||
// alice-sr25519 -> bob-ed25519
|
||||
const encrypted1 = pairA.encryptMessage(message, keyring.bob.publicKey);
|
||||
|
||||
// alice-sr25519 -> bob-sr25519
|
||||
const encrypted2 = pairA.encryptMessage(message, pairB.publicKey);
|
||||
|
||||
// alice-ed25519 -> bob-sr25519
|
||||
const encrypted3 = keyring.alice.encryptMessage(message, pairB.publicKey);
|
||||
|
||||
// decrypt: Bob-ed25519 - use alice-ed25519 pubkey
|
||||
expect(
|
||||
keyring.bob.decryptMessage(encrypted3, keyring.alice.publicKey)
|
||||
).toEqual(message);
|
||||
|
||||
// decrypt: Bob-ed25519 - use alice-sr25519 pubkey
|
||||
expect(
|
||||
keyring.bob.decryptMessage(encrypted1, pairA.publicKey)
|
||||
).toEqual(message);
|
||||
|
||||
// decrypt: Bob-sr25519 - use alice-sr25519 pubkey
|
||||
expect(
|
||||
pairB.decryptMessage(encrypted2, pairA.publicKey)
|
||||
).toEqual(message);
|
||||
});
|
||||
|
||||
it('allows setting/getting of meta', (): void => {
|
||||
keyring.bob.setMeta({ foo: 'bar', something: 'else' });
|
||||
|
||||
@@ -276,22 +185,5 @@ describe('pair', (): void => {
|
||||
});
|
||||
expect(json.address).toEqual(u8aToHex(PUBLICDERIVED));
|
||||
});
|
||||
|
||||
it('denies access to encryptMessage/decryptMessage API', (): void => {
|
||||
const PASS = 'testing';
|
||||
const encoded = keyring.alice.encodePkcs8(PASS);
|
||||
|
||||
const pair = createPair({ toSS58, type: 'ethereum' }, { publicKey: keyring.alice.publicKey });
|
||||
|
||||
pair.decodePkcs8(PASS, encoded);
|
||||
|
||||
expect(
|
||||
() => pair.encryptMessage(
|
||||
new Uint8Array(4), // null message
|
||||
keyring.bob.publicKey,
|
||||
new Uint8Array(24)
|
||||
)
|
||||
).toThrow('Secp256k1 not supported yet');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
// Copyright 2017-2023 @polkadot/keyring authors & contributors
|
||||
// Copyright 2017-2026 @polkadot/keyring authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { HexString } from '@polkadot/util/types';
|
||||
import type { EncryptedJsonEncoding, Keypair, KeypairType } from '@polkadot/util-crypto/types';
|
||||
import type { KeyringPair, KeyringPair$Json, KeyringPair$Meta, SignOptions } from '../types';
|
||||
import type { PairInfo } from './types';
|
||||
import type { KeyringPair, KeyringPair$Json, KeyringPair$Meta, SignOptions } from '../types.js';
|
||||
import type { PairInfo } from './types.js';
|
||||
|
||||
import { objectSpread, u8aConcat, u8aEmpty, u8aEq, u8aToHex, u8aToU8a } from '@polkadot/util';
|
||||
import { blake2AsU8a, convertPublicKeyToCurve25519, convertSecretKeyToCurve25519, ed25519PairFromSeed as ed25519FromSeed, ed25519Sign, ethereumEncode, keccakAsU8a, keyExtractPath, keyFromPath, naclOpen, naclSeal, secp256k1Compress, secp256k1Expand, secp256k1PairFromSeed as secp256k1FromSeed, secp256k1Sign, signatureVerify, sr25519PairFromSeed as sr25519FromSeed, sr25519Sign, sr25519VrfSign, sr25519VrfVerify } from '@polkadot/util-crypto';
|
||||
import { blake2AsU8a, dilithiumAccountFromPublic, dilithiumPairFromSeed, dilithiumSign, dilithiumSizes, ed25519PairFromSeed as ed25519FromSeed, ed25519Sign, ethereumEncode, isDilithium, keccakAsU8a, keyExtractPath, keyFromPath, secp256k1Compress, secp256k1Expand, secp256k1PairFromSeed as secp256k1FromSeed, secp256k1Sign, signatureVerify, sr25519PairFromSeed as sr25519FromSeed, sr25519Sign, sr25519VrfSign, sr25519VrfVerify } from '@polkadot/util-crypto';
|
||||
|
||||
import { decodePair } from './decode';
|
||||
import { encodePair } from './encode';
|
||||
import { pairToJson } from './toJson';
|
||||
import { decodePair } from './decode.js';
|
||||
import { encodePair } from './encode.js';
|
||||
import { pairToJson } from './toJson.js';
|
||||
|
||||
interface Setup {
|
||||
toSS58: (publicKey: Uint8Array) => string;
|
||||
@@ -21,27 +20,70 @@ interface Setup {
|
||||
const SIG_TYPE_NONE = new Uint8Array();
|
||||
|
||||
const TYPE_FROM_SEED = {
|
||||
dilithium65: (seed: Uint8Array) => dilithiumPairFromSeed(seed, 'dilithium65'),
|
||||
dilithium87: (seed: Uint8Array) => dilithiumPairFromSeed(seed, 'dilithium87'),
|
||||
ecdsa: secp256k1FromSeed,
|
||||
ed25519: ed25519FromSeed,
|
||||
ethereum: secp256k1FromSeed,
|
||||
sr25519: sr25519FromSeed
|
||||
};
|
||||
|
||||
// For the curve types these index Substrate's `MultiSignature`. For the ML-DSA
|
||||
// types they index the Quantus runtime's `DilithiumSignatureScheme`, where
|
||||
// `Dilithium87` is variant 0 and `Dilithium65` is variant 1 — a different enum
|
||||
// that happens to be reached by the same `withType` mechanism, so no special
|
||||
// casing is needed anywhere upstream of here.
|
||||
const TYPE_PREFIX = {
|
||||
dilithium65: new Uint8Array([1]),
|
||||
dilithium87: new Uint8Array([0]),
|
||||
ecdsa: new Uint8Array([2]),
|
||||
ed25519: new Uint8Array([0]),
|
||||
ethereum: new Uint8Array([2]),
|
||||
sr25519: new Uint8Array([1])
|
||||
};
|
||||
|
||||
const TYPE_SIGNATURE = {
|
||||
ecdsa: (m: Uint8Array, p: Partial<Keypair>) => secp256k1Sign(m, p, 'blake2'),
|
||||
ed25519: ed25519Sign,
|
||||
ethereum: (m: Uint8Array, p: Partial<Keypair>) => secp256k1Sign(m, p, 'keccak'),
|
||||
sr25519: sr25519Sign
|
||||
// The ML-DSA arms take a context; the curve arms ignore the extra argument. The
|
||||
// signature is written out because TypeScript would otherwise infer the narrowest
|
||||
// common shape — the two-argument curve arms — and reject passing a context at all.
|
||||
type SignFn = (message: Uint8Array, pair: Partial<Keypair>, context?: Uint8Array) => Uint8Array;
|
||||
|
||||
const TYPE_SIGNATURE: Record<KeypairType, SignFn> = {
|
||||
dilithium65: (m, p, ctx) => dilithiumSign(m, p, 'dilithium65', requireContext(ctx)),
|
||||
dilithium87: (m, p, ctx) => dilithiumSign(m, p, 'dilithium87', requireContext(ctx)),
|
||||
ecdsa: (m, p) => secp256k1Sign(m, p, 'blake2'),
|
||||
// Wrapped rather than passed directly: ed25519Sign and sr25519Sign take a
|
||||
// third argument of their own (`onlyJs`), and letting it line up with the
|
||||
// context slot would silently reinterpret a Uint8Array as a boolean.
|
||||
ed25519: (m, p) => ed25519Sign(m, p),
|
||||
ethereum: (m, p) => secp256k1Sign(m, p, 'keccak'),
|
||||
sr25519: (m, p) => sr25519Sign(m, p)
|
||||
};
|
||||
|
||||
/**
|
||||
* A post-quantum pair will not sign without being told which context to use.
|
||||
*
|
||||
* See `SignOptions.context`. The alternative — defaulting to the extrinsic
|
||||
* context — produces a valid signature that a spec-147 chain rejects, with
|
||||
* nothing local able to explain why.
|
||||
*/
|
||||
function requireContext (context?: Uint8Array): Uint8Array {
|
||||
if (!context) {
|
||||
throw new Error('A signing context is required for post-quantum keypairs; pass options.context (see contextForSpec)');
|
||||
}
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
// Every curve arm here is identity or a cheap re-encoding, because on Substrate
|
||||
// the address *is* the public key. The ML-DSA arms are the exception that the
|
||||
// rest of this file has to be read in light of: 1952 or 2592 bytes in, 32 out,
|
||||
// and no way back. `ecdsa` already hints at the shape — it hashes when given an
|
||||
// uncompressed key — but it stays reversible in the sense that matters, since
|
||||
// the signature carries a recoverable key. ML-DSA does not, which is why its
|
||||
// signatures carry the public key explicitly.
|
||||
const TYPE_ADDRESS = {
|
||||
dilithium65: dilithiumAccountFromPublic,
|
||||
dilithium87: dilithiumAccountFromPublic,
|
||||
ecdsa: (p: Uint8Array) => p.length > 32 ? blake2AsU8a(p) : p,
|
||||
ed25519: (p: Uint8Array) => p,
|
||||
ethereum: (p: Uint8Array) => p.length === 20 ? p : keccakAsU8a(secp256k1Expand(p)),
|
||||
@@ -87,11 +129,21 @@ function vrfHash (proof: Uint8Array, context?: string | Uint8Array, extra?: stri
|
||||
* 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 function createPair ({ toSS58, type }: Setup, { publicKey, secretKey }: PairInfo, meta: KeyringPair$Meta = {}, encoded: Uint8Array | null = null, encTypes?: EncryptedJsonEncoding[]): KeyringPair {
|
||||
export function createPair ({ toSS58, type }: Setup, { accountId, publicKey, secretKey }: PairInfo, meta: KeyringPair$Meta = {}, encoded: Uint8Array | null = null, encTypes?: EncryptedJsonEncoding[]): KeyringPair {
|
||||
const decodePkcs8 = (passphrase?: string, userEncoded?: Uint8Array | null): void => {
|
||||
const decoded = decodePair(passphrase, userEncoded || encoded, encTypes);
|
||||
// ML-DSA secrets are 4032/4896 bytes, which is neither of the two lengths
|
||||
// decodePair would otherwise try. It has to be told.
|
||||
const decoded = decodePair(passphrase, userEncoded || encoded, encTypes, isDilithium(type)
|
||||
? dilithiumSizes(type).secretKey
|
||||
: undefined
|
||||
);
|
||||
|
||||
if (decoded.secretKey.length === 64) {
|
||||
// Upstream decides "is this a secret key or a seed?" by length, because for
|
||||
// the curve schemes a 64-byte blob is a secret and a 32-byte one is a seed.
|
||||
// An ML-DSA secret is neither, and would take the seed branch and be fed to
|
||||
// keygen as entropy — producing a valid, wrong key in silence. The type
|
||||
// knows the answer, so ask it.
|
||||
if (isDilithium(type) || decoded.secretKey.length === 64) {
|
||||
publicKey = decoded.publicKey;
|
||||
secretKey = decoded.secretKey;
|
||||
} else {
|
||||
@@ -100,6 +152,25 @@ export function createPair ({ toSS58, type }: Setup, { publicKey, secretKey }: P
|
||||
publicKey = pair.publicKey;
|
||||
secretKey = pair.secretKey;
|
||||
}
|
||||
|
||||
// The public key has only now arrived. If the pair was constructed from JSON
|
||||
// it has been reporting an address carried as data since then, so check the
|
||||
// two agree.
|
||||
//
|
||||
// This is not a paranoid check. For every other scheme the address *is* the
|
||||
// public key, so a JSON file whose `address` field has been edited cannot
|
||||
// decode at all. Here it decodes perfectly and yields a pair that reports an
|
||||
// address its key does not control — a user would see the attacker's address
|
||||
// in their own wallet and believe they held it.
|
||||
if (accountId) {
|
||||
const derived = TYPE_ADDRESS[type](publicKey);
|
||||
|
||||
if (!u8aEq(derived, accountId)) {
|
||||
throw new Error('Decoded public key does not match the address in the account JSON');
|
||||
}
|
||||
|
||||
accountId = undefined;
|
||||
}
|
||||
};
|
||||
|
||||
const recode = (passphrase?: string): Uint8Array => {
|
||||
@@ -111,8 +182,15 @@ export function createPair ({ toSS58, type }: Setup, { publicKey, secretKey }: P
|
||||
return encoded;
|
||||
};
|
||||
|
||||
// While an ML-DSA pair restored from JSON is locked, its public key is still
|
||||
// inside the encrypted blob and the account id cannot be computed — so use the
|
||||
// one carried alongside. `decodePkcs8` clears it once the real key arrives and
|
||||
// has been checked against it.
|
||||
const addressRawOf = (): Uint8Array =>
|
||||
accountId ?? TYPE_ADDRESS[type](publicKey);
|
||||
|
||||
const encodeAddress = (): string => {
|
||||
const raw = TYPE_ADDRESS[type](publicKey);
|
||||
const raw = addressRawOf();
|
||||
|
||||
return type === 'ethereum'
|
||||
? ethereumEncode(raw)
|
||||
@@ -124,7 +202,7 @@ export function createPair ({ toSS58, type }: Setup, { publicKey, secretKey }: P
|
||||
return encodeAddress();
|
||||
},
|
||||
get addressRaw (): Uint8Array {
|
||||
const raw = TYPE_ADDRESS[type](publicKey);
|
||||
const raw = addressRawOf();
|
||||
|
||||
return type === 'ethereum'
|
||||
? raw.slice(-20)
|
||||
@@ -144,25 +222,16 @@ export function createPair ({ toSS58, type }: Setup, { publicKey, secretKey }: P
|
||||
},
|
||||
// eslint-disable-next-line sort-keys
|
||||
decodePkcs8,
|
||||
decryptMessage: (encryptedMessageWithNonce: HexString | string | Uint8Array, senderPublicKey: HexString | string | Uint8Array): Uint8Array | null => {
|
||||
if (isLocked(secretKey)) {
|
||||
throw new Error('Cannot encrypt with a locked key pair');
|
||||
} else if (['ecdsa', 'ethereum'].includes(type)) {
|
||||
throw new Error('Secp256k1 not supported yet');
|
||||
}
|
||||
|
||||
const messageU8a = u8aToU8a(encryptedMessageWithNonce);
|
||||
|
||||
return naclOpen(
|
||||
messageU8a.slice(24, messageU8a.length),
|
||||
messageU8a.slice(0, 24),
|
||||
convertPublicKeyToCurve25519(u8aToU8a(senderPublicKey)),
|
||||
convertSecretKeyToCurve25519(secretKey)
|
||||
);
|
||||
},
|
||||
derive: (suri: string, meta?: KeyringPair$Meta): KeyringPair => {
|
||||
if (type === 'ethereum') {
|
||||
throw new Error('Unable to derive on this keypair');
|
||||
} else if (isDilithium(type)) {
|
||||
// Not "not implemented" — not possible. A child here would have to come
|
||||
// from this pair's key material, and ML-DSA keys are not derivable from
|
||||
// one another at all; the Quantus tree derives every account from the
|
||||
// mnemonic independently. So the caller needs the mnemonic, not this
|
||||
// pair, and saying that is more use than a generic refusal.
|
||||
throw new Error(`Unable to derive from an existing ${type} pair; derive from the mnemonic with createFromUri instead`);
|
||||
} else if (isLocked(secretKey)) {
|
||||
throw new Error('Cannot derive on a locked keypair');
|
||||
}
|
||||
@@ -175,24 +244,13 @@ export function createPair ({ toSS58, type }: Setup, { publicKey, secretKey }: P
|
||||
encodePkcs8: (passphrase?: string): Uint8Array => {
|
||||
return recode(passphrase);
|
||||
},
|
||||
encryptMessage: (message: HexString | string | Uint8Array, recipientPublicKey: HexString | string | Uint8Array, nonceIn?: Uint8Array): Uint8Array => {
|
||||
if (isLocked(secretKey)) {
|
||||
throw new Error('Cannot encrypt with a locked key pair');
|
||||
} else if (['ecdsa', 'ethereum'].includes(type)) {
|
||||
throw new Error('Secp256k1 not supported yet');
|
||||
}
|
||||
|
||||
const { nonce, sealed } = naclSeal(u8aToU8a(message), convertSecretKeyToCurve25519(secretKey), convertPublicKeyToCurve25519(u8aToU8a(recipientPublicKey)), nonceIn);
|
||||
|
||||
return u8aConcat(nonce, sealed);
|
||||
},
|
||||
lock: (): void => {
|
||||
secretKey = new Uint8Array();
|
||||
},
|
||||
setMeta: (additional: KeyringPair$Meta): void => {
|
||||
meta = objectSpread({}, meta, additional);
|
||||
},
|
||||
sign: (message: HexString | string | Uint8Array, options: SignOptions = {}): Uint8Array => {
|
||||
sign: (message: string | Uint8Array, options: SignOptions = {}): Uint8Array => {
|
||||
if (isLocked(secretKey)) {
|
||||
throw new Error('Cannot sign with a locked key pair');
|
||||
}
|
||||
@@ -201,7 +259,7 @@ export function createPair ({ toSS58, type }: Setup, { publicKey, secretKey }: P
|
||||
options.withType
|
||||
? TYPE_PREFIX[type]
|
||||
: SIG_TYPE_NONE,
|
||||
TYPE_SIGNATURE[type](u8aToU8a(message), { publicKey, secretKey })
|
||||
TYPE_SIGNATURE[type](u8aToU8a(message), { publicKey, secretKey }, options.context)
|
||||
);
|
||||
},
|
||||
toJson: (passphrase?: string): KeyringPair$Json => {
|
||||
@@ -219,10 +277,10 @@ export function createPair ({ toSS58, type }: Setup, { publicKey, secretKey }: P
|
||||
unlock: (passphrase?: string): void => {
|
||||
return decodePkcs8(passphrase);
|
||||
},
|
||||
verify: (message: HexString | string | Uint8Array, signature: HexString | string | Uint8Array, signerPublic: HexString | string | Uint8Array): boolean => {
|
||||
verify: (message: string | Uint8Array, signature: string | Uint8Array, signerPublic: string | Uint8Array): boolean => {
|
||||
return signatureVerify(message, signature, TYPE_ADDRESS[type](u8aToU8a(signerPublic))).isValid;
|
||||
},
|
||||
vrfSign: (message: HexString | string | Uint8Array, context?: HexString | string | Uint8Array, extra?: string | Uint8Array): Uint8Array => {
|
||||
vrfSign: (message: string | Uint8Array, context?: string | Uint8Array, extra?: string | Uint8Array): Uint8Array => {
|
||||
if (isLocked(secretKey)) {
|
||||
throw new Error('Cannot sign with a locked key pair');
|
||||
}
|
||||
@@ -231,11 +289,20 @@ export function createPair ({ toSS58, type }: Setup, { publicKey, secretKey }: P
|
||||
return sr25519VrfSign(message, { secretKey }, context, extra);
|
||||
}
|
||||
|
||||
// There is no ML-DSA VRF. The construction below fakes one out of an
|
||||
// ordinary signature, which is sound only because the underlying schemes
|
||||
// are deterministic and unique — properties ML-DSA's signature does not
|
||||
// have in the form this needs. Refuse rather than produce something that
|
||||
// looks like a VRF output and is not verifiable as one.
|
||||
if (isDilithium(type)) {
|
||||
throw new Error(`VRF signing is not available for ${type}`);
|
||||
}
|
||||
|
||||
const proof = TYPE_SIGNATURE[type](u8aToU8a(message), { publicKey, secretKey });
|
||||
|
||||
return u8aConcat(vrfHash(proof, context, extra), proof);
|
||||
},
|
||||
vrfVerify: (message: HexString | string | Uint8Array, vrfResult: Uint8Array, signerPublic: HexString | Uint8Array | string, context?: HexString | string | Uint8Array, extra?: HexString | string | Uint8Array): boolean => {
|
||||
vrfVerify: (message: string | Uint8Array, vrfResult: Uint8Array, signerPublic: Uint8Array | string, context?: string | Uint8Array, extra?: string | Uint8Array): boolean => {
|
||||
if (type === 'sr25519') {
|
||||
return sr25519VrfVerify(message, vrfResult, publicKey, context, extra);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright 2017-2023 @polkadot/keyring authors & contributors
|
||||
// Copyright 2017-2026 @polkadot/keyring authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { KeyringPair, KeyringPair$Json, KeyringPair$Meta } from '../types';
|
||||
import type { KeyringPair, KeyringPair$Json, KeyringPair$Meta } from '../types.js';
|
||||
|
||||
// empty publicKey
|
||||
const publicKey = new Uint8Array(32);
|
||||
@@ -28,48 +28,32 @@ const json: KeyringPair$Json = {
|
||||
const pair: KeyringPair = {
|
||||
address,
|
||||
addressRaw: publicKey,
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
decodePkcs8: (passphrase?: string, encoded?: Uint8Array): void =>
|
||||
decodePkcs8: (_passphrase?: string, _encoded?: Uint8Array): void =>
|
||||
undefined,
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
decryptMessage: (encryptedMessageWithNonce: string | Uint8Array, senderPublicKey: string | Uint8Array): Uint8Array | null =>
|
||||
null,
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
derive: (suri: string, meta?: KeyringPair$Meta): KeyringPair =>
|
||||
derive: (_suri: string, _meta?: KeyringPair$Meta): KeyringPair =>
|
||||
pair,
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
encodePkcs8: (passphrase?: string): Uint8Array =>
|
||||
encodePkcs8: (_passphrase?: string): Uint8Array =>
|
||||
new Uint8Array(0),
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
encryptMessage: (message: string | Uint8Array, recipientPublicKey: string | Uint8Array, _nonce?: Uint8Array): Uint8Array =>
|
||||
new Uint8Array(),
|
||||
isLocked: true,
|
||||
lock: (): void => {
|
||||
// no locking, it is always locked
|
||||
},
|
||||
meta,
|
||||
publicKey,
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
setMeta: (meta: KeyringPair$Meta): void =>
|
||||
setMeta: (_meta: KeyringPair$Meta): void =>
|
||||
undefined,
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
sign: (message: Uint8Array): Uint8Array =>
|
||||
sign: (_message: Uint8Array): Uint8Array =>
|
||||
new Uint8Array(64),
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
toJson: (passphrase?: string): KeyringPair$Json =>
|
||||
toJson: (_passphrase?: string): KeyringPair$Json =>
|
||||
json,
|
||||
type: 'ed25519',
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
unlock: (passphrase?: string): void =>
|
||||
unlock: (_passphrase?: string): void =>
|
||||
undefined,
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
verify: (message: Uint8Array, signature: Uint8Array): boolean =>
|
||||
verify: (_message: Uint8Array, _signature: Uint8Array): boolean =>
|
||||
false,
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
vrfSign: (message: Uint8Array, context?: string | Uint8Array, extra?: string | Uint8Array): Uint8Array =>
|
||||
vrfSign: (_message: Uint8Array, _context?: string | Uint8Array, _extra?: string | Uint8Array): Uint8Array =>
|
||||
new Uint8Array(96),
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
vrfVerify: (message: Uint8Array, vrfResult: Uint8Array, context?: string | Uint8Array, extra?: string | Uint8Array): boolean =>
|
||||
vrfVerify: (_message: Uint8Array, _vrfResult: Uint8Array, _context?: string | Uint8Array, _extra?: string | Uint8Array): boolean =>
|
||||
false
|
||||
};
|
||||
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
// Copyright 2017-2023 @polkadot/keyring authors & contributors
|
||||
// Copyright 2017-2026 @polkadot/keyring authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { createTestPairs } from '../testingPairs';
|
||||
/// <reference types="@polkadot/dev-test/globals.d.ts" />
|
||||
|
||||
import { createTestPairs } from '../testingPairs.js';
|
||||
|
||||
const keyring = createTestPairs({ type: 'ed25519' }, false);
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// Copyright 2017-2023 @polkadot/keyring authors & contributors
|
||||
// Copyright 2017-2026 @polkadot/keyring authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { KeypairType } from '@polkadot/util-crypto/types';
|
||||
import type { KeyringPair$Json, KeyringPair$Meta } from '../types';
|
||||
import type { KeyringPair$Json, KeyringPair$Meta } from '../types.js';
|
||||
|
||||
import { objectSpread } from '@polkadot/util';
|
||||
import { jsonEncryptFormat } from '@polkadot/util-crypto';
|
||||
|
||||
@@ -1,8 +1,23 @@
|
||||
// Copyright 2017-2023 @polkadot/keyring authors & contributors
|
||||
// Copyright 2017-2026 @polkadot/keyring authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
export interface PairInfo {
|
||||
/**
|
||||
* The 32-byte account id, when it cannot be derived from `publicKey`.
|
||||
*
|
||||
* Only ML-DSA pairs need this, and only while locked. Everywhere else the
|
||||
* address is a cheap function of the public key, so a pair restored from JSON
|
||||
* can report its address before anyone supplies a password. A Quantus account
|
||||
* id is a one-way Poseidon2 hash, and the public key lives inside the
|
||||
* encrypted blob — so between `createFromJson` and `decodePkcs8` there is
|
||||
* nothing to compute it from, and callers read `pair.address` in exactly that
|
||||
* window.
|
||||
*
|
||||
* Carried as data rather than derived, and checked against the real public key
|
||||
* once that arrives.
|
||||
*/
|
||||
accountId?: Uint8Array | undefined;
|
||||
publicKey: Uint8Array;
|
||||
secretKey?: Uint8Array;
|
||||
secretKey?: Uint8Array | undefined;
|
||||
seed?: Uint8Array | null;
|
||||
}
|
||||
|
||||
@@ -1,29 +1,23 @@
|
||||
// Copyright 2017-2023 @polkadot/keyring authors & contributors
|
||||
// Copyright 2017-2026 @polkadot/keyring authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { KeyringPair } from '../types';
|
||||
/// <reference types="@polkadot/dev-test/globals.d.ts" />
|
||||
|
||||
import { u8aToHex } from '@polkadot/util';
|
||||
import { cryptoWaitReady, ed25519PairFromSeed, encodeAddress as toSS58, randomAsU8a, secp256k1PairFromSeed, sr25519PairFromSeed } from '@polkadot/util-crypto';
|
||||
|
||||
import { createPair } from '.';
|
||||
import { createPair } from './index.js';
|
||||
|
||||
const MESSAGE = 'this is a test message';
|
||||
const CONTEXT = 'some context';
|
||||
|
||||
await cryptoWaitReady();
|
||||
|
||||
const ecdsa = createPair({ toSS58, type: 'ecdsa' }, secp256k1PairFromSeed(randomAsU8a()));
|
||||
const ed25519 = createPair({ toSS58, type: 'ed25519' }, ed25519PairFromSeed(randomAsU8a()));
|
||||
const sr25519 = createPair({ toSS58, type: 'sr25519' }, sr25519PairFromSeed(randomAsU8a()));
|
||||
|
||||
describe('vrf', (): void => {
|
||||
let ecdsa: KeyringPair;
|
||||
let ed25519: KeyringPair;
|
||||
let sr25519: KeyringPair;
|
||||
|
||||
beforeAll(async (): Promise<void> => {
|
||||
await cryptoWaitReady();
|
||||
|
||||
ecdsa = createPair({ toSS58, type: 'ecdsa' }, secp256k1PairFromSeed(randomAsU8a()));
|
||||
ed25519 = createPair({ toSS58, type: 'ed25519' }, ed25519PairFromSeed(randomAsU8a()));
|
||||
sr25519 = createPair({ toSS58, type: 'sr25519' }, sr25519PairFromSeed(randomAsU8a()));
|
||||
});
|
||||
|
||||
it('has deterministic signature values for ecdsa', (): void => {
|
||||
const sig1 = ecdsa.vrfSign(MESSAGE, CONTEXT);
|
||||
const sig2 = ecdsa.vrfSign(MESSAGE, CONTEXT);
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
// Copyright 2017-2023 @polkadot/keyring authors & contributors
|
||||
// Copyright 2017-2026 @polkadot/keyring authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { HexString } from '@polkadot/util/types';
|
||||
import type { KeyringPair, KeyringPairs } from './types';
|
||||
import type { KeyringPair, KeyringPairs } from './types.js';
|
||||
|
||||
import { isHex, isU8a, u8aToHex, u8aToU8a } from '@polkadot/util';
|
||||
import { decodeAddress } from '@polkadot/util-crypto';
|
||||
@@ -22,7 +21,7 @@ export class Pairs implements KeyringPairs {
|
||||
return Object.values(this.#map);
|
||||
}
|
||||
|
||||
public get (address: HexString | string | Uint8Array): KeyringPair {
|
||||
public get (address: string | Uint8Array): KeyringPair {
|
||||
const pair = this.#map[decodeAddress(address).toString()];
|
||||
|
||||
if (!pair) {
|
||||
@@ -36,7 +35,7 @@ export class Pairs implements KeyringPairs {
|
||||
return pair;
|
||||
}
|
||||
|
||||
public remove (address: HexString | string | Uint8Array): void {
|
||||
public remove (address: string | Uint8Array): void {
|
||||
delete this.#map[decodeAddress(address).toString()];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
// Copyright 2017-2023 @polkadot/keyring authors & contributors
|
||||
// Copyright 2017-2026 @polkadot/keyring authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
/// <reference types="@polkadot/dev-test/globals.d.ts" />
|
||||
|
||||
// From https://github.com/paritytech/substrate/wiki/Secret-URI-Test-Vectors
|
||||
|
||||
import type { KeypairType } from '@polkadot/util-crypto/types';
|
||||
@@ -8,7 +10,7 @@ import type { KeypairType } from '@polkadot/util-crypto/types';
|
||||
import { u8aToHex } from '@polkadot/util';
|
||||
import { cryptoWaitReady } from '@polkadot/util-crypto';
|
||||
|
||||
import Keyring from '.';
|
||||
import Keyring from './index.js';
|
||||
|
||||
const PHRASE = 'bottom drive obey lake curtain smoke basket hold race lonely fit walk';
|
||||
const ETHEREUM_PHRASE = 'seed sock milk update focus rotate barely fade car face mechanic mercy';
|
||||
@@ -87,15 +89,13 @@ const TESTS = {
|
||||
]
|
||||
};
|
||||
|
||||
await cryptoWaitReady();
|
||||
|
||||
describe('keyring.addFromUri', (): void => {
|
||||
Object.entries(TESTS).forEach(([type, tests]): void => {
|
||||
for (const [type, tests] of Object.entries(TESTS)) {
|
||||
const keyring = new Keyring({ type: type as KeypairType });
|
||||
|
||||
beforeEach(async (): Promise<void> => {
|
||||
await cryptoWaitReady();
|
||||
});
|
||||
|
||||
describe(type, (): void => {
|
||||
describe(`${type}`, (): void => {
|
||||
tests.forEach(({ pk, ss, uri }): void => {
|
||||
it(`creates ${uri}`, (): void => {
|
||||
const pair = keyring.addFromUri(uri, {}, type as KeypairType);
|
||||
@@ -105,5 +105,5 @@ describe('keyring.addFromUri', (): void => {
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
// Copyright 2017-2023 @polkadot/keyring authors & contributors
|
||||
// Copyright 2017-2026 @polkadot/keyring authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { HexString } from '@polkadot/util/types';
|
||||
import type { KeypairType } from '@polkadot/util-crypto/types';
|
||||
import type { KeyringInstance, KeyringOptions } from './types';
|
||||
import type { KeyringInstance, KeyringOptions } from './types.js';
|
||||
|
||||
import { hexToU8a } from '@polkadot/util';
|
||||
|
||||
import { Keyring } from './keyring';
|
||||
import { createPair } from './pair';
|
||||
import { createPair } from './pair/index.js';
|
||||
import { Keyring } from './keyring.js';
|
||||
|
||||
interface PairDef {
|
||||
name?: string;
|
||||
@@ -119,7 +119,7 @@ function createMeta (name?: string, seed?: string) {
|
||||
|
||||
return {
|
||||
isTesting: true,
|
||||
name: name || (seed && seed.replace('//', '_').toLowerCase())
|
||||
name: name || seed?.replace('//', '_').toLowerCase()
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
// Copyright 2017-2023 @polkadot/keyring authors & contributors
|
||||
// Copyright 2017-2026 @polkadot/keyring authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
/// <reference types="@polkadot/dev-test/globals.d.ts" />
|
||||
|
||||
import { u8aToHex } from '@polkadot/util';
|
||||
import { cryptoWaitReady } from '@polkadot/util-crypto';
|
||||
|
||||
import { createTestPairs } from './testingPairs';
|
||||
import Keyring from '.';
|
||||
import Keyring from './index.js';
|
||||
import { createTestPairs } from './testingPairs.js';
|
||||
|
||||
const TEST_ADD = '0xf24FF3a9CF04c71Dbc94D0b566f7A27B94566cac';
|
||||
|
||||
describe('testingPairs', (): void => {
|
||||
beforeEach(async (): Promise<void> => {
|
||||
await cryptoWaitReady();
|
||||
});
|
||||
await cryptoWaitReady();
|
||||
|
||||
describe('testingPairs', (): void => {
|
||||
it('creates without failing', (): void => {
|
||||
expect(
|
||||
Object.keys(createTestPairs())
|
||||
@@ -42,12 +42,10 @@ describe('testingPairs', (): void => {
|
||||
const keyring = new Keyring({ type: 'ethereum' });
|
||||
const pair = keyring.createFromUri('0x5fb92d6e98884f76de468fa3f6278f8807c48bebc13595d45af5bdc4da702133');
|
||||
|
||||
expect(
|
||||
pair && pair.address
|
||||
).toEqual(TEST_ADD);
|
||||
expect(pair?.address).toEqual(TEST_ADD);
|
||||
});
|
||||
|
||||
it('checks eth test addresses', (): void => {
|
||||
describe('checks eth test addresses', (): void => {
|
||||
const ring = createTestPairs({ type: 'ethereum' });
|
||||
const keyring = new Keyring({ type: 'ethereum' });
|
||||
// priv keys generated by ganache-cli --mnemonic "bottom drive obey lake curtain smoke basket hold race lonely fit walk"
|
||||
@@ -62,12 +60,20 @@ describe('testingPairs', (): void => {
|
||||
'0x4c42532034540267bf568198ccec4cb822a025da542861fcb146a5fab6433ff8',
|
||||
'0x94c49300a58d576011096bcb006aa06f5a91b34b4383891e8029c21dc39fbb8b'];
|
||||
|
||||
// @ts-expect-error We should not delete from the maps, however this is a test
|
||||
delete ring.nobody;
|
||||
|
||||
Object.keys(ring).forEach((testKeyring, i) => {
|
||||
if (i < 6) {
|
||||
expect(u8aToHex(ring[testKeyring].publicKey)).toEqual(u8aToHex(keyring.createFromUri(privKeys[i]).publicKey));
|
||||
}
|
||||
});
|
||||
Object
|
||||
.keys(ring)
|
||||
.filter((_, i) => i < 6)
|
||||
.forEach((testKeyring, i) => {
|
||||
it(`checks #${i}`, (): void => {
|
||||
expect(
|
||||
u8aToHex(ring[testKeyring].publicKey)
|
||||
).toEqual(
|
||||
u8aToHex(keyring.createFromUri(privKeys[i]).publicKey)
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,23 +1,56 @@
|
||||
// Copyright 2017-2023 @polkadot/keyring authors & contributors
|
||||
// Copyright 2017-2026 @polkadot/keyring authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { KeyringOptions, KeyringPair } from './types';
|
||||
import type { KeypairType } from '@polkadot/util-crypto/types';
|
||||
import type { KeyringOptions, KeyringPair } from './types.js';
|
||||
|
||||
import { nobody } from './pair/nobody';
|
||||
import { createTestKeyring } from './testing';
|
||||
import { nobody } from './pair/nobody.js';
|
||||
import { createTestKeyring } from './testing.js';
|
||||
|
||||
export interface TestKeyringMap {
|
||||
nobody: KeyringPair;
|
||||
|
||||
[index: string]: KeyringPair;
|
||||
}
|
||||
|
||||
export function createTestPairs (options?: KeyringOptions, isDerived = true): TestKeyringMap {
|
||||
export interface TestKeyringMapSubstrate extends TestKeyringMap {
|
||||
alice: KeyringPair;
|
||||
bob: KeyringPair;
|
||||
charlie: KeyringPair;
|
||||
dave: KeyringPair;
|
||||
eve: KeyringPair;
|
||||
ferdie: KeyringPair;
|
||||
}
|
||||
|
||||
export interface TestKeyringMapEthereum extends TestKeyringMap {
|
||||
Alith: KeyringPair;
|
||||
Baltathar: KeyringPair;
|
||||
Charleth: KeyringPair;
|
||||
Dorothy: KeyringPair;
|
||||
Ethan: KeyringPair;
|
||||
Faith: KeyringPair;
|
||||
}
|
||||
|
||||
export type DetectMap<O extends KeyringOptions | undefined> = DetectPairType<O> extends 'ethereum'
|
||||
? TestKeyringMapEthereum
|
||||
: TestKeyringMapSubstrate;
|
||||
|
||||
export type DetectPairType<O extends KeyringOptions | undefined> = O extends KeyringOptions
|
||||
? O['type'] extends KeypairType
|
||||
? O['type']
|
||||
: 'sr25519'
|
||||
: 'sr25519';
|
||||
|
||||
export function createTestPairs <O extends KeyringOptions, M = DetectMap<O>> (options?: O, isDerived = true): M {
|
||||
const keyring = createTestKeyring(options, isDerived);
|
||||
const pairs = keyring.getPairs();
|
||||
const map: TestKeyringMap = { nobody: nobody() };
|
||||
|
||||
for (const p of pairs) {
|
||||
map[p.meta.name as string] = p;
|
||||
if (p.meta.name) {
|
||||
map[p.meta.name] = p;
|
||||
}
|
||||
}
|
||||
|
||||
return map;
|
||||
return map as M;
|
||||
}
|
||||
|
||||
@@ -1,33 +1,89 @@
|
||||
// Copyright 2017-2023 @polkadot/keyring authors & contributors
|
||||
// Copyright 2017-2026 @polkadot/keyring authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { HexString } from '@polkadot/util/types';
|
||||
import type { EncryptedJson, Keypair, KeypairType, Prefix } from '@polkadot/util-crypto/types';
|
||||
|
||||
export interface KeyringOptions {
|
||||
/**
|
||||
* @description The ss58Format to use for address encoding (defaults to 42)
|
||||
*/
|
||||
/** The ss58Format to use for address encoding (defaults to 42) */
|
||||
ss58Format?: Prefix;
|
||||
/**
|
||||
* @description The type of keyring to create (defaults to ed25519)
|
||||
*/
|
||||
/** The type of keyring to create (defaults to ed25519) */
|
||||
type?: KeypairType;
|
||||
}
|
||||
|
||||
export type KeyringPair$Meta = Record<string, unknown>;
|
||||
export interface KeyringPair$MetaHardware {
|
||||
accountIndex?: number;
|
||||
accountOffset?: number;
|
||||
addressOffset?: number;
|
||||
hardwareType?: 'ledger';
|
||||
}
|
||||
|
||||
export interface KeyringPair$MetaFlags {
|
||||
isDefaultAuthSelected?: boolean;
|
||||
isExternal?: boolean;
|
||||
isHardware?: boolean;
|
||||
isHidden?: boolean;
|
||||
isInjected?: boolean;
|
||||
isMultisig?: boolean;
|
||||
isProxied?: boolean;
|
||||
isRecent?: boolean;
|
||||
isTesting?: boolean;
|
||||
}
|
||||
|
||||
export interface KeyringPair$MetaContract {
|
||||
abi: string;
|
||||
genesisHash?: HexString | null;
|
||||
}
|
||||
|
||||
export interface KeyringPair$MetaExtension {
|
||||
source?: string;
|
||||
}
|
||||
|
||||
export interface KeyringPair$MetaMultisig {
|
||||
threshold?: number;
|
||||
who?: string[];
|
||||
}
|
||||
|
||||
export interface KeyringPair$MetaParent {
|
||||
parentAddress?: string;
|
||||
parentName?: string;
|
||||
}
|
||||
|
||||
export interface KeyringPair$Meta extends KeyringPair$MetaExtension, KeyringPair$MetaFlags, KeyringPair$MetaHardware, KeyringPair$MetaMultisig, KeyringPair$MetaParent {
|
||||
address?: string;
|
||||
contract?: KeyringPair$MetaContract;
|
||||
genesisHash?: HexString | null;
|
||||
name?: string;
|
||||
suri?: string;
|
||||
tags?: string[];
|
||||
type?: KeypairType;
|
||||
whenCreated?: number;
|
||||
whenEdited?: number;
|
||||
whenUsed?: number;
|
||||
|
||||
[key: string]: unknown;
|
||||
}
|
||||
|
||||
export interface KeyringPair$Json extends EncryptedJson {
|
||||
/** The ss58 encoded address or the hex-encoded version (the latter is for ETH-compat chains) */
|
||||
address: string | HexString;
|
||||
address: string;
|
||||
/** The underlying metadata associated with the keypair */
|
||||
meta: KeyringPair$Meta;
|
||||
}
|
||||
|
||||
export interface SignOptions {
|
||||
/**
|
||||
* @description Create a MultiSignature-compatible output with an indicator type
|
||||
**/
|
||||
* The FIPS 204 domain-separation context, for post-quantum pairs.
|
||||
*
|
||||
* Mandatory for `dilithium65`/`dilithium87` and ignored by every other type.
|
||||
* There is deliberately no default: Quantus extrinsics on spec >= 148 are
|
||||
* verified under `QUANTUS_EXTRINSIC` and earlier ones under the empty context,
|
||||
* and a signature made under the wrong one is cryptographically valid, rejected
|
||||
* by the chain, and locally indistinguishable from a correct one. Only the
|
||||
* caller knows the spec version, so only the caller can answer.
|
||||
*/
|
||||
context?: Uint8Array;
|
||||
/** Create a MultiSignature-compatible output with an indicator type */
|
||||
withType?: boolean;
|
||||
}
|
||||
|
||||
@@ -44,14 +100,12 @@ export interface KeyringPair {
|
||||
encodePkcs8 (passphrase?: string): Uint8Array;
|
||||
lock (): void;
|
||||
setMeta (meta: KeyringPair$Meta): void;
|
||||
sign (message: HexString | string | Uint8Array, options?: SignOptions): Uint8Array;
|
||||
sign (message: string | Uint8Array, options?: SignOptions): Uint8Array;
|
||||
toJson (passphrase?: string): KeyringPair$Json;
|
||||
unlock (passphrase?: string): void;
|
||||
encryptMessage (message: HexString | string | Uint8Array, recipientPublicKey: HexString | string | Uint8Array, nonce?: Uint8Array): Uint8Array;
|
||||
decryptMessage (encryptedMessageWithNonce: HexString | string | Uint8Array, senderPublicKey: HexString | string | Uint8Array): Uint8Array | null;
|
||||
verify (message: HexString | string | Uint8Array, signature: Uint8Array, signerPublic: HexString | string | Uint8Array): boolean;
|
||||
vrfSign (message: HexString | string | Uint8Array, context?: HexString | string | Uint8Array, extra?: HexString | string | Uint8Array): Uint8Array;
|
||||
vrfVerify (message: HexString | string | Uint8Array, vrfResult: Uint8Array, signerPublic: HexString | Uint8Array | string, context?: HexString | string | Uint8Array, extra?: HexString | string | Uint8Array): boolean;
|
||||
verify (message: string | Uint8Array, signature: Uint8Array, signerPublic: string | Uint8Array): boolean;
|
||||
vrfSign (message: string | Uint8Array, context?: string | Uint8Array, extra?: string | Uint8Array): Uint8Array;
|
||||
vrfVerify (message: string | Uint8Array, vrfResult: Uint8Array, signerPublic: string | Uint8Array, context?: string | Uint8Array, extra?: string | Uint8Array): boolean;
|
||||
}
|
||||
|
||||
export interface KeyringPairs {
|
||||
@@ -73,13 +127,13 @@ export interface KeyringInstance {
|
||||
addPair (pair: KeyringPair): KeyringPair;
|
||||
addFromAddress (address: string | Uint8Array, meta?: KeyringPair$Meta, encoded?: Uint8Array | null, type?: KeypairType, ignoreChecksum?: boolean): KeyringPair;
|
||||
addFromJson (pair: KeyringPair$Json, ignoreChecksum?: boolean): KeyringPair;
|
||||
addFromMnemonic (mnemonic: string, meta?: KeyringPair$Meta, type?: KeypairType): KeyringPair;
|
||||
addFromMnemonic (mnemonic: string, meta?: KeyringPair$Meta, type?: KeypairType, wordlist?: string[]): KeyringPair;
|
||||
addFromPair (pair: Keypair, meta?: KeyringPair$Meta, type?: KeypairType): KeyringPair
|
||||
addFromSeed (seed: Uint8Array, meta?: KeyringPair$Meta, type?: KeypairType): KeyringPair;
|
||||
addFromUri (suri: string, meta?: KeyringPair$Meta, type?: KeypairType): KeyringPair;
|
||||
addFromUri (suri: string, meta?: KeyringPair$Meta, type?: KeypairType, wordlist?: string[]): KeyringPair;
|
||||
createFromJson (json: KeyringPair$Json, ignoreChecksum?: boolean): KeyringPair;
|
||||
createFromPair (pair: Keypair, meta: KeyringPair$Meta, type: KeypairType): KeyringPair
|
||||
createFromUri (suri: string, meta?: KeyringPair$Meta, type?: KeypairType): KeyringPair;
|
||||
createFromUri (suri: string, meta?: KeyringPair$Meta, type?: KeypairType, wordlist?: string[]): KeyringPair;
|
||||
getPair (address: string | Uint8Array): KeyringPair;
|
||||
getPairs (): KeyringPair[];
|
||||
getPublicKeys (): Uint8Array[];
|
||||
|
||||
@@ -5,6 +5,10 @@
|
||||
"outDir": "./build",
|
||||
"rootDir": "./src"
|
||||
},
|
||||
"exclude": [
|
||||
"**/*.spec.ts",
|
||||
"**/mod.ts"
|
||||
],
|
||||
"references": [
|
||||
{ "path": "../util/tsconfig.build.json" },
|
||||
{ "path": "../util-crypto/tsconfig.build.json" }
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"baseUrl": "..",
|
||||
"outDir": "./build",
|
||||
"rootDir": "./src",
|
||||
"emitDeclarationOnly": false,
|
||||
"noEmit": true
|
||||
},
|
||||
"include": [
|
||||
"**/*.spec.ts"
|
||||
],
|
||||
"references": [
|
||||
{ "path": "../keyring/tsconfig.build.json" },
|
||||
{ "path": "../util/tsconfig.build.json" },
|
||||
{ "path": "../util-crypto/tsconfig.build.json" }
|
||||
]
|
||||
}
|
||||
@@ -1,201 +0,0 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
@@ -1,14 +1,12 @@
|
||||
{
|
||||
"author": "Jaco Greeff <jacogr@gmail.com>",
|
||||
"bugs": "https://github.com/polkadot-js/common/issues",
|
||||
"contributors": [],
|
||||
"description": "A list of all available Substrate networks and their applicable prefixes",
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
"node": ">=18"
|
||||
},
|
||||
"homepage": "https://github.com/polkadot-js/common/tree/master/packages/networks#readme",
|
||||
"license": "Apache-2.0",
|
||||
"maintainers": [],
|
||||
"name": "@polkadot/networks",
|
||||
"repository": {
|
||||
"directory": "packages/networks",
|
||||
@@ -17,14 +15,14 @@
|
||||
},
|
||||
"sideEffects": false,
|
||||
"type": "module",
|
||||
"version": "10.2.6",
|
||||
"version": "14.0.3-quantus.2",
|
||||
"main": "index.js",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.20.7",
|
||||
"@polkadot/util": "10.2.6",
|
||||
"@substrate/ss58-registry": "^1.37.0"
|
||||
"@polkadot/util": "14.0.3",
|
||||
"@substrate/ss58-registry": "^1.51.0",
|
||||
"tslib": "^2.8.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@polkadot/hw-ledger": "10.2.6"
|
||||
"@polkadot/hw-ledger": "14.0.3"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,25 +1,43 @@
|
||||
// Copyright 2017-2023 @polkadot/networks authors & contributors
|
||||
// Copyright 2017-2026 @polkadot/networks authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
/// <reference types="@polkadot/dev-test/globals.d.ts" />
|
||||
|
||||
import { ledgerApps } from '@polkadot/hw-ledger/defaults';
|
||||
import { isHex } from '@polkadot/util';
|
||||
|
||||
import { knownGenesis, knownLedger } from './defaults';
|
||||
import { knownGenesis, knownLedger, knownTestnet } from './defaults/index.js';
|
||||
|
||||
describe('defaults', (): void => {
|
||||
const genesisKeys = Object.keys(knownGenesis);
|
||||
const ledgerKeys = Object.keys(knownLedger);
|
||||
|
||||
describe('genesis', (): void => {
|
||||
it('has hex values for all genesis chains', (): void => {
|
||||
expect(
|
||||
Object.keys(knownGenesis).filter((network) =>
|
||||
genesisKeys.filter((network) =>
|
||||
!knownGenesis[network].length ||
|
||||
knownGenesis[network].some((g) => !isHex(g, 256))
|
||||
)
|
||||
).toEqual([]);
|
||||
});
|
||||
|
||||
// Upstream asserted the opposite: that no testnet appears in knownGenesis.
|
||||
// This fork carries Quantus testnets deliberately — a wallet for a chain
|
||||
// under development has to reach its testnet — so the assertion becomes that
|
||||
// any testnet listed here is one we meant to list. See defaults/genesis.ts.
|
||||
it('has genesis entries only for testnets we deliberately support', (): void => {
|
||||
expect(
|
||||
genesisKeys.filter((network) =>
|
||||
knownTestnet[network] &&
|
||||
!network.startsWith('quantus')
|
||||
)
|
||||
).toEqual([]);
|
||||
});
|
||||
|
||||
it('has genesis for all Ledger chains', (): void => {
|
||||
expect(
|
||||
Object.keys(knownLedger).filter((network) =>
|
||||
ledgerKeys.filter((network) =>
|
||||
!knownGenesis[network]
|
||||
)
|
||||
).toEqual([]);
|
||||
@@ -29,7 +47,7 @@ describe('defaults', (): void => {
|
||||
describe('Ledger', (): void => {
|
||||
it('has entries for each of the apps (hwledger -> networks)', (): void => {
|
||||
expect(
|
||||
Object.keys(knownLedger).filter((network) =>
|
||||
ledgerKeys.filter((network) =>
|
||||
!ledgerApps[network]
|
||||
)
|
||||
).toEqual([]);
|
||||
|
||||
@@ -1,12 +1,27 @@
|
||||
// Copyright 2017-2023 @polkadot/networks authors & contributors
|
||||
// Copyright 2017-2026 @polkadot/networks authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { KnownGenesis } from '../types';
|
||||
import type { KnownGenesis } from '../types.js';
|
||||
|
||||
// NOTE: In the case where the network was hard-spooned and multiple genesisHashes
|
||||
// are provided, it needs to be in reverse order, i.e. most-recent first, oldest
|
||||
// last. This make lookups for the current a simple genesisHash[0]
|
||||
// (See Kusama as an example)
|
||||
// In the case where the network was hard-spooned and multiple genesisHashes
|
||||
// are provided, it needs to be in reverse order, i.e. most-recent goes first,
|
||||
// oldest goes last. This make lookups for the current a simple genesisHash[0]
|
||||
// where the latest ios always the first entry (See Kusama as an example)
|
||||
//
|
||||
// UPSTREAM SAID: "Apart from the test relays, this list is limited to live
|
||||
// parachains and live production networks. It does not and should not contain
|
||||
// any testnets, either stand-alone or connected to test relays such as
|
||||
// Westend/Rococo"
|
||||
//
|
||||
// THIS FORK DOES NOT. That rule keeps testnets out of polkadot-js/apps' chain
|
||||
// picker, which is a sensible product decision for a production explorer and the
|
||||
// wrong one for us. Quantus is a chain under active development, and a wallet
|
||||
// that cannot talk to its testnet is a wallet that cannot be tested against
|
||||
// anything but real funds. Testnets are first-class here.
|
||||
//
|
||||
// `isTestnet` is still set honestly, so a consumer that wants to hide them can;
|
||||
// what changed is that we no longer make that choice on the consumer's behalf.
|
||||
// See `toExpanded` in ../interfaces.ts.
|
||||
export const knownGenesis: KnownGenesis = {
|
||||
acala: [
|
||||
'0xfc41b9bd8ef8fe53d58c7ea67c794c7ec9a73daf05e6d54b14ff6342c99ba64c'
|
||||
@@ -29,16 +44,30 @@ export const knownGenesis: KnownGenesis = {
|
||||
'bifrost-kusama': [
|
||||
'0x9f28c6a68e0fc9646eff64935684f6eeeece527e37bbe1f213d22caa1d9d6bed'
|
||||
],
|
||||
bittensor: [
|
||||
'0x2f0555cc76fc2840a25a6ea3b9637146806f1f44b090c175ffde2a7e5ab36c03'
|
||||
],
|
||||
centrifuge: [
|
||||
'0xb3db41421702df9a7fcac62b53ffeac85f7853cc4e689e0b93aeb3db18c09d82',
|
||||
'0x67dddf2673b69e5f875f6f25277495834398eafd67f492e09f3f3345e003d1b5'
|
||||
],
|
||||
cere: [
|
||||
'0x81443836a9a24caaa23f1241897d1235717535711d1d3fe24eae4fdc942c092c'
|
||||
],
|
||||
composable: [
|
||||
'0xdaab8df776eb52ec604a5df5d388bb62a050a0aaec4556a64265b9d42755552d'
|
||||
],
|
||||
creditcoin3: [
|
||||
'0x4436a7d64e363df85e065a894721002a86643283f9707338bf195d360ba2ee71', // cc3 mainnet
|
||||
'0xfc4ec97a1c1f119c4353aecb4a17c7c0cf7b40d5d660143d8bad9117e9866572', // cc3 testnet/drynet
|
||||
'0xfc9df99a665f964aed6649f275055e54df5e3420489538ed31d7788f53d11ef6' // cc3 devnet
|
||||
],
|
||||
darwinia: [
|
||||
'0xe71578b37a7c799b0ab4ee87ffa6f059a6b98f71f06fb8c84a8d88013a548ad6'
|
||||
],
|
||||
dentnet: [
|
||||
'0x0313f6a011d128d22f996703cbab05162e2fdc9e031493314fe6db79979c5ca7'
|
||||
],
|
||||
'dock-mainnet': [
|
||||
'0x6bfe24dca2a3be10f22212678ac13a6446ec764103c0f3471c71609eac384aae',
|
||||
'0xf73467c6544aa68df2ee546b135f955c46b90fa627e9b5d7935f41061bb8a5a9'
|
||||
@@ -46,19 +75,32 @@ export const knownGenesis: KnownGenesis = {
|
||||
edgeware: [
|
||||
'0x742a2ca70c2fda6cee4f8df98d64c4c670a052d9568058982dad9d5a7a135c5b'
|
||||
],
|
||||
encointer: [
|
||||
'0x7dd99936c1e9e6d1ce7d90eb6f33bea8393b4bf87677d675aa63c9cb3e8c5b5b'
|
||||
],
|
||||
enjin: [
|
||||
'0xd8761d3c88f26dc12875c00d3165f7d67243d56fc85b4cf19937601a7916e5a9'
|
||||
],
|
||||
equilibrium: [
|
||||
'0x6f1a800de3daff7f5e037ddf66ab22ce03ab91874debeddb1086f5f7dbd48925'
|
||||
],
|
||||
frequency: [
|
||||
'0x4a587bf17a404e3572747add7aab7bbe56e805a5479c6c436f07f36fcc8d3ae1'
|
||||
],
|
||||
genshiro: [
|
||||
'0x9b8cefc0eb5c568b527998bdd76c184e2b76ae561be76e4667072230217ea243'
|
||||
],
|
||||
hydradx: [
|
||||
'0xafdc188f45c71dacbaa0b62e16a91f726c7b8699a9748cdf715459de6b7f366d', // HydraDX Parachain
|
||||
'0xafdc188f45c71dacbaa0b62e16a91f726c7b8699a9748cdf715459de6b7f366d', // Hydration | HydraDX Parachain
|
||||
'0xd2a620c27ec5cbc5621ff9a522689895074f7cca0d08e7134a7804e1a3ba86fc', // Snakenet Gen3-1
|
||||
'0x10af6e84234477d84dc572bac0789813b254aa490767ed06fb9591191d1073f9', // Snakenet Gen3
|
||||
'0x3d75507dd46301767e601265791da1d9cb47b6ebc94e87347b635e5bf58bd047', // Snakenet Gen2
|
||||
'0x0ed32bfcab4a83517fac88f2aa7cbc2f88d3ab93be9a12b6188a036bf8a943c2' // Snakenet Gen1
|
||||
],
|
||||
integritee: [
|
||||
'0xcdedc8eadbfa209d3f207bba541e57c3c58a667b05a2e1d1e86353c9000758da', // on Kusama
|
||||
'0xe13e7af377c64e83f95e0d70d5e5c3c01d697a84538776c5b9bbe0e7d7b6034c' // on Polkadot
|
||||
],
|
||||
'interlay-parachain': [
|
||||
'0xbf88efe70e9e0e916416e8bed61f2b45717f517d7f3523e33c7b001e5ffcbc72'
|
||||
],
|
||||
@@ -76,21 +118,43 @@ export const knownGenesis: KnownGenesis = {
|
||||
'0xe3777fa922cafbff200cadeaea1a76bd7898ad5b89f7848999058b50e715f636', // Kusama CC2
|
||||
'0x3fd7b9eb6a00376e5be61f01abb429ffb0b104be05eaff4d458da48fcd425baf' // Kusama CC1
|
||||
],
|
||||
liberland: [
|
||||
'0x6bd89e052d67a45bb60a9a23e8581053d5e0d619f15cb9865946937e690c42d6'
|
||||
],
|
||||
matrixchain: [
|
||||
'0x3af4ff48ec76d2efc8476730f423ac07e25ad48f5f4c9dc39c778b164d808615'
|
||||
],
|
||||
mythos: [
|
||||
'0xf6ee56e9c5277df5b4ce6ae9983ee88f3cbed27d31beeb98f9f84f997a1ab0b9'
|
||||
],
|
||||
nodle: [
|
||||
'0x97da7ede98d7bad4e36b4d734b6055425a3be036da2a332ea5a7037656427a21'
|
||||
],
|
||||
origintrail: [
|
||||
'0xe7e0962324a3b86c83404dbea483f25fb5dab4c224791c81b756cfc948006174'
|
||||
],
|
||||
p3d: [
|
||||
'0x6c5894837ad89b6d92b114a2fb3eafa8fe3d26a54848e3447015442cd6ef4e66'
|
||||
],
|
||||
parallel: [
|
||||
'0xe61a41c53f5dcd0beb09df93b34402aada44cb05117b71059cce40a2723a4e97'
|
||||
],
|
||||
peaq: [
|
||||
'0xd2a5d385932d1f650dae03ef8e2748983779ee342c614f80854d32b8cd8fa48c'
|
||||
],
|
||||
pendulum: [
|
||||
'0x5d3c298622d5634ed019bf61ea4b71655030015bde9beb0d6a24743714462c86'
|
||||
],
|
||||
phala: [
|
||||
'0x1bb969d85965e4bb5a651abbedf21a54b6b31a21f66b5401cc3f1e286268d736'
|
||||
],
|
||||
picasso: [
|
||||
'0x6811a339673c9daa897944dcdac99c6e2939cc88245ed21951a0a3c9a2be75bc',
|
||||
'0xe8e7f0f4c4f5a00720b4821dbfddefea7490bcf0b19009961cc46957984e2c1c'
|
||||
],
|
||||
polimec: [
|
||||
'0x7eb9354488318e7549c722669dcbdcdc526f1fef1420e7944667212f3601fdbd'
|
||||
],
|
||||
polkadex: [
|
||||
'0x3920bcb4960a1eef5580cd5367ff3f430eef052774f78468852f7b9cb39f8a3c'
|
||||
],
|
||||
@@ -100,6 +164,21 @@ export const knownGenesis: KnownGenesis = {
|
||||
polymesh: [
|
||||
'0x6fbd74e5e1d0a61d52ccfe9d4adaed16dd3a7caa37c6bc4d0c2fa12e8b2f4063'
|
||||
],
|
||||
// Quantus mainnet, read from the node with `chain_getBlockHash(0)` on
|
||||
// 2026-09-09, the day it launched. Not the staging chain, which is
|
||||
// `0xb0e90ed9f291a9194f79…` and which telemetry confusingly calls
|
||||
// "Quantus Staging Mainnet".
|
||||
quantus: [
|
||||
'0xfb5487c0be6ae4ade2d41d16e50465129861636c2b8d61fa94d7a19631626fba'
|
||||
],
|
||||
// Heisenberg, the public Quantus testnet. A testnet carrying a genesis hash is
|
||||
// a deliberate departure from upstream — see the note above.
|
||||
'quantus-heisenberg': [
|
||||
'0xa5aa9e5c84d4a3722c152295e7973c9af522f2fb1ef7db5afaa3d5f4dc8d3b4f'
|
||||
],
|
||||
quartz: [
|
||||
'0xcd4d732201ebe5d6b014edda071c4203e16867305332301dc8d092044b28e554'
|
||||
],
|
||||
rococo: [
|
||||
'0x6408de7737c59c238890533af25896a2c20608d8b380bb01029acb392781063e',
|
||||
'0xaaf2cd1b74b5f726895921259421b534124726263982522174147046b8827897',
|
||||
@@ -129,9 +208,15 @@ export const knownGenesis: KnownGenesis = {
|
||||
subsocial: [
|
||||
'0x0bd72c1c305172e1275278aaeb3f161e02eccb7a819e63f62d47bd53a28189f8'
|
||||
],
|
||||
ternoa: [
|
||||
'0x6859c81ca95ef624c9dfe4dc6e3381c33e5d6509e35e147092bfbc780f777c4e'
|
||||
],
|
||||
unique: [
|
||||
'0x84322d9cddbf35088f1e54e9a85c967a41a56a4f43445768125e61af166c7d31'
|
||||
],
|
||||
vara: [
|
||||
'0xfe1b4c55fd4d668101126434206571a7838a8b6b93a6d1b95d607e78e6c53763'
|
||||
],
|
||||
vtb: [
|
||||
'0x286bc8414c7000ce1d6ee6a834e29a54c1784814b76243eb77ed0b2c5573c60f',
|
||||
'0x7483b89572fb2bd687c7b9a93b242d0b237f9aba463aba07ec24503931038aaa'
|
||||
@@ -141,5 +226,8 @@ export const knownGenesis: KnownGenesis = {
|
||||
],
|
||||
xxnetwork: [
|
||||
'0x50dd5d206917bf10502c68fb4d18a59fc8aa31586f4e8856b493e43544aa82aa'
|
||||
],
|
||||
zeitgeist: [
|
||||
'0x1bf2a2ecb4a868de66ea8610f2ce7c8c43706561b6476031315f6640fe38e060'
|
||||
]
|
||||
};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright 2017-2023 @polkadot/networks authors & contributors
|
||||
// Copyright 2017-2026 @polkadot/networks authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { KnownIcon } from '../types';
|
||||
import type { KnownIcon } from '../types.js';
|
||||
|
||||
// these are icon overrides
|
||||
export const knownIcon: KnownIcon = {
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
// Copyright 2017-2023 @polkadot/networks authors & contributors
|
||||
// Copyright 2017-2026 @polkadot/networks authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
export { knownGenesis } from './genesis';
|
||||
export { knownIcon } from './icons';
|
||||
export { knownLedger } from './ledger';
|
||||
export { knownTestnet } from './testnets';
|
||||
export { knownGenesis } from './genesis.js';
|
||||
export { knownIcon } from './icons.js';
|
||||
export { knownLedger } from './ledger.js';
|
||||
export { knownQuantus } from './quantus.js';
|
||||
export { exposedTestnet, knownTestnet } from './testnets.js';
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright 2017-2023 @polkadot/networks authors & contributors
|
||||
// Copyright 2017-2026 @polkadot/networks authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { KnownLedger } from '../types';
|
||||
import type { KnownLedger } from '../types.js';
|
||||
|
||||
// These match up with the keys of the ledgerApps object in the @polkadot/hw-ledger/defaults.ts
|
||||
// and maps to the known slip44 (minus the `0x8` hard derivation flag)
|
||||
@@ -14,30 +14,48 @@ export const knownLedger: KnownLedger = {
|
||||
astar: 0x0000032a,
|
||||
bifrost: 0x00000314,
|
||||
'bifrost-kusama': 0x00000314,
|
||||
bittensor: 0x00000162,
|
||||
centrifuge: 0x000002eb,
|
||||
composable: 0x00000162,
|
||||
creditcoin3: 0x00000162,
|
||||
darwinia: 0x00000162,
|
||||
dentnet: 0x000002de,
|
||||
'dock-mainnet': 0x00000252,
|
||||
edgeware: 0x0000020b,
|
||||
encointer: 0x000001b2,
|
||||
enjin: 0x00000483,
|
||||
equilibrium: 0x05f5e0fd,
|
||||
frequency: 0x0000082b,
|
||||
genshiro: 0x05f5e0fc,
|
||||
hydradx: 0x00000162,
|
||||
integritee: 0x000007df,
|
||||
'interlay-parachain': 0x00000162,
|
||||
karura: 0x000002ae,
|
||||
khala: 0x000001b2,
|
||||
kusama: 0x000001b2,
|
||||
liberland: 0x000002ff,
|
||||
matrixchain: 0x00000483,
|
||||
mythos: 0x0000003c,
|
||||
nodle: 0x000003eb,
|
||||
origintrail: 0x00000162,
|
||||
parallel: 0x00000162,
|
||||
peaq: 0x00000d0a,
|
||||
pendulum: 0x00000162,
|
||||
phala: 0x00000162,
|
||||
picasso: 0x000001b2,
|
||||
polimec: 0x00000d10,
|
||||
polkadex: 0x0000031f,
|
||||
polkadot: 0x00000162,
|
||||
polymesh: 0x00000253,
|
||||
quartz: 0x00000277,
|
||||
sora: 0x00000269,
|
||||
stafi: 0x0000038b,
|
||||
statemine: 0x000001b2, // common-good on Kusama, shares derivation
|
||||
statemint: 0x00000162, // common-good on Polkadot, shares derivation
|
||||
unique: 0x00000162,
|
||||
ternoa: 0x00003e3,
|
||||
unique: 0x00000295,
|
||||
vara: 0x00001370,
|
||||
vtb: 0x000002b6,
|
||||
xxnetwork: 0x000007a3
|
||||
xxnetwork: 0x000007a3,
|
||||
zeitgeist: 0x00000162
|
||||
};
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
// Copyright 2017-2026 @polkadot/networks authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { KnownSubstrate } from '../types.js';
|
||||
|
||||
// Quantus networks, which `@substrate/ss58-registry` does not carry.
|
||||
//
|
||||
// Prefix 189 is unclaimed in that registry — nothing occupies 185..195 at all —
|
||||
// so this is an addition rather than an override. It lives in this fork because
|
||||
// the registry is Parity-curated and post-quantum support has not landed
|
||||
// upstream; see the standing convention in quantus/extension#1.
|
||||
//
|
||||
// `standardAccount: 'ml-dsa'` is a value upstream's type does not allow, which
|
||||
// is why `KnownSubstrate` is widened in ../types.ts. It is load-bearing: a null
|
||||
// or missing `standardAccount` makes `toExpanded` mark the network `isIgnored`
|
||||
// and it disappears from `availableNetworks`.
|
||||
export const knownQuantus: KnownSubstrate[] = [
|
||||
{
|
||||
decimals: [12],
|
||||
displayName: 'Quantus',
|
||||
network: 'quantus',
|
||||
prefix: 189,
|
||||
standardAccount: 'ml-dsa',
|
||||
symbols: ['QTC'],
|
||||
website: 'https://quantus.com'
|
||||
},
|
||||
{
|
||||
decimals: [12],
|
||||
displayName: 'Quantus Heisenberg',
|
||||
network: 'quantus-heisenberg',
|
||||
prefix: 189,
|
||||
standardAccount: 'ml-dsa',
|
||||
// HEI, not QTC — confirmed from the chain itself via system_properties on
|
||||
// a1-heisenberg.quantus.cat. A testnet token that displayed as the mainnet
|
||||
// symbol would be a good way to confuse play money for real.
|
||||
symbols: ['HEI'],
|
||||
website: 'https://quantus.com'
|
||||
}
|
||||
];
|
||||
@@ -1,9 +1,10 @@
|
||||
// Copyright 2017-2023 @polkadot/networks authors & contributors
|
||||
// Copyright 2017-2026 @polkadot/networks authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { KnownTestnet } from '../types';
|
||||
import type { KnownTestnet } from '../types.js';
|
||||
|
||||
// testnets should not allow selection
|
||||
// Marks a network as a testnet. Purely descriptive — see `exposedTestnet` below
|
||||
// for which of them this fork actually offers.
|
||||
export const knownTestnet: KnownTestnet = {
|
||||
'': true, // this is the default non-network entry
|
||||
'cess-testnet': true,
|
||||
@@ -11,6 +12,24 @@ export const knownTestnet: KnownTestnet = {
|
||||
jupiter: true,
|
||||
'mathchain-testnet': true,
|
||||
p3dt: true,
|
||||
'quantus-heisenberg': true,
|
||||
subspace_testnet: true,
|
||||
'zero-alphaville': true
|
||||
};
|
||||
|
||||
// Testnets this fork exposes anyway, despite upstream's rule that a testnet is
|
||||
// never offered.
|
||||
//
|
||||
// That rule keeps testnets out of polkadot-js/apps' chain picker, which is right
|
||||
// for a production explorer and wrong for us: Quantus is under active
|
||||
// development, and a wallet that cannot reach its testnet can only be tested
|
||||
// against real funds.
|
||||
//
|
||||
// An explicit allowlist rather than dropping the rule wholesale. Dropping it
|
||||
// exposed all fifteen of upstream's testnets too, which is a change we have no
|
||||
// reason to make and no way to have thought about — it moved the tail of the
|
||||
// sorted list from 'ZERO' to 'ZERO Alphaville' and would have surprised anyone
|
||||
// reading `availableNetworks`. Opting in one network at a time says what we mean.
|
||||
export const exposedTestnet: KnownTestnet = {
|
||||
'quantus-heisenberg': true
|
||||
};
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
// Copyright 2017-2023 @polkadot/networks authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
export default [];
|
||||
@@ -1,11 +0,0 @@
|
||||
// Copyright 2017-2023 @polkadot/networks authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Do not edit, auto-generated by @polkadot/dev
|
||||
|
||||
import { detectPackage } from '@polkadot/util';
|
||||
|
||||
import others from './detectOther';
|
||||
import { packageInfo } from './packageInfo';
|
||||
|
||||
detectPackage(packageInfo, null, others);
|
||||
@@ -1,18 +1,20 @@
|
||||
// Copyright 2017-2023 @polkadot/networks authors & contributors
|
||||
// Copyright 2017-2026 @polkadot/networks authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { SubstrateNetwork } from './types';
|
||||
/// <reference types="@polkadot/dev-test/globals.d.ts" />
|
||||
|
||||
import { knownGenesis, knownIcon, knownLedger, knownTestnet } from './defaults';
|
||||
import { allNetworks, availableNetworks, selectableNetworks } from '.';
|
||||
import type { SubstrateNetwork } from './types.js';
|
||||
|
||||
import { knownGenesis, knownIcon, knownLedger, knownTestnet } from './defaults/index.js';
|
||||
import { allNetworks, availableNetworks, isQuantumSafe, selectableNetworks } from './index.js';
|
||||
|
||||
describe('availableNetworks', (): void => {
|
||||
it('has the correct starting order', (): void => {
|
||||
expect(availableNetworks.slice(0, 3).map(({ prefix }) => prefix)).toEqual([0, 2, 42]);
|
||||
});
|
||||
|
||||
it.skip('has a sorted list (first external, last external)', (): void => {
|
||||
expect(availableNetworks[3].displayName).toEqual('Acala');
|
||||
it('has a sorted list (first external, last external)', (): void => {
|
||||
expect(availableNetworks[3].displayName).toEqual('3DP network');
|
||||
expect(availableNetworks[availableNetworks.length - 1].displayName).toEqual('ZERO');
|
||||
});
|
||||
|
||||
@@ -49,16 +51,40 @@ describe('availableNetworks', (): void => {
|
||||
).toEqual([]);
|
||||
});
|
||||
|
||||
it('has no testnets exposed', (): void => {
|
||||
// Upstream asserted that no testnet reaches availableNetworks at all. This
|
||||
// fork exposes the Quantus ones deliberately — see exposedTestnet — so what is
|
||||
// worth pinning is that an exposed testnet is still *labelled* one. Losing the
|
||||
// label is the failure that matters: a user cannot tell play money from real
|
||||
// money by looking at an address.
|
||||
it('labels every exposed testnet as a testnet', (): void => {
|
||||
expect(
|
||||
Object.keys(knownTestnet).filter((network) =>
|
||||
availableNetworks.some((a) =>
|
||||
a.network === network
|
||||
)
|
||||
availableNetworks.some((a) => a.network === network && !a.isTestnet)
|
||||
)
|
||||
).toEqual([]);
|
||||
});
|
||||
|
||||
it('exposes no testnets except the ones we opted into', (): void => {
|
||||
expect(
|
||||
availableNetworks
|
||||
.filter((a) => a.isTestnet && !a.network.startsWith('quantus'))
|
||||
.map((a) => a.network)
|
||||
).toEqual([]);
|
||||
});
|
||||
|
||||
// These lists stay complete on purpose. An earlier version of this fork
|
||||
// filtered them to post-quantum chains, which broke @polkadot/types-known — it
|
||||
// looks up every chain it holds upgrade history for and throws when one is
|
||||
// missing, so @polkadot/api failed at import. Gating what a wallet offers is
|
||||
// the wallet's job; isQuantumSafe is exported for it and the extension applies
|
||||
// it in its own chain list.
|
||||
it('identifies which chains are post-quantum', (): void => {
|
||||
expect(isQuantumSafe('ml-dsa')).toEqual(true);
|
||||
expect(isQuantumSafe('Sr25519')).toEqual(false);
|
||||
expect(isQuantumSafe(null)).toEqual(false);
|
||||
expect(availableNetworks.filter((n) => isQuantumSafe(n.standardAccount)).map((n) => n.network)).toEqual(['quantus', 'quantus-heisenberg']);
|
||||
});
|
||||
|
||||
it('has allNetworks icons, except for overrides', (): void => {
|
||||
expect(
|
||||
availableNetworks.filter(({ icon, network }) =>
|
||||
@@ -90,14 +116,20 @@ describe('availableNetworks', (): void => {
|
||||
});
|
||||
|
||||
describe('allNetworks', (): void => {
|
||||
it('has no ss58 duplicates', (): void => {
|
||||
// Upstream asserted one network per SS58 prefix. That stops holding the moment
|
||||
// a chain has a testnet: Quantus mainnet and Heisenberg are both 189, because
|
||||
// they are the same chain at two deployments and an address is valid on
|
||||
// either. Consumers key on genesisHash, so sharing a prefix costs nothing.
|
||||
it('has no ss58 duplicates, except deployments of the same chain', (): void => {
|
||||
const dupes: SubstrateNetwork[] = [];
|
||||
const uniques: SubstrateNetwork[] = [];
|
||||
|
||||
allNetworks.forEach((a): void => {
|
||||
if (uniques.some((u) => u.prefix === a.prefix)) {
|
||||
const clash = uniques.find((u) => u.prefix === a.prefix);
|
||||
|
||||
if (clash && clash.network.split('-')[0] !== a.network.split('-')[0]) {
|
||||
dupes.push(a);
|
||||
} else {
|
||||
} else if (!clash) {
|
||||
uniques.push(a);
|
||||
}
|
||||
});
|
||||
@@ -112,7 +144,7 @@ describe('selectableNetworks', (): void => {
|
||||
});
|
||||
|
||||
it('has a sorted list (first external, last external)', (): void => {
|
||||
expect(selectableNetworks[3].displayName).toEqual('Acala');
|
||||
expect(selectableNetworks[selectableNetworks.length - 1].displayName).toEqual('xx network');
|
||||
expect(selectableNetworks[3].displayName).toEqual('3DP network');
|
||||
expect(selectableNetworks[selectableNetworks.length - 1].displayName).toEqual('Zeitgeist');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
// Copyright 2017-2023 @polkadot/networks authors & contributors
|
||||
// Copyright 2017-2026 @polkadot/networks authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// TODO: This was removed, really cannot recall the reason...
|
||||
// ... put it back, but keep it removed
|
||||
// import './detectPackage';
|
||||
// import './packageDetect.js';
|
||||
|
||||
export * from './interfaces';
|
||||
export { packageInfo } from './packageInfo';
|
||||
export * from './interfaces.js';
|
||||
export { packageInfo } from './packageInfo.js';
|
||||
export { isQuantumSafe } from './quantumSafe.js';
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user