Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a5fd5e2c85 | ||
|
|
b58c77d774 | ||
|
|
5e8ec185cb | ||
|
|
bbdf5659df | ||
|
|
f8cc8d07e1 | ||
|
|
e3eb76762c | ||
|
|
114e75a4b4 | ||
|
|
5ca641c758 | ||
|
|
ded2528836 | ||
|
|
70fa61916d | ||
|
|
c9a2d3b6d7 | ||
|
|
4927120403 | ||
|
|
36f53f6b82 | ||
|
|
24548e84e1 | ||
|
|
337deab526 | ||
|
|
4a9f0326e7 | ||
|
|
81811510f4 | ||
|
|
f09867d90f | ||
|
|
709e1ab3c1 | ||
|
|
ae2d7518b2 | ||
|
|
5337f1dca9 | ||
|
|
cc9b8630ff | ||
|
|
e6e266a4c0 | ||
|
|
3b96d87f7f | ||
|
|
c1949a21be | ||
|
|
7f0a6b0ce9 | ||
|
|
6b644025b0 | ||
|
|
6ea1ee555b | ||
|
|
d582b2e180 | ||
|
|
c2d04155f9 | ||
|
|
5a4dc97498 | ||
|
|
f1aeda10ee | ||
|
|
70a3aebce3 | ||
|
|
31dd2ced0e | ||
|
|
98ad1199f3 | ||
|
|
30225ceb40 | ||
|
|
194b8ced5b | ||
|
|
81ed8cfc6c | ||
|
|
51598b00c0 | ||
|
|
1684bd3161 | ||
|
|
a53e1b8aa4 | ||
|
|
89f2925d89 | ||
|
|
c29a226279 | ||
|
|
b8d1ab95c6 | ||
|
|
bcddcab03e | ||
|
|
bfe2c5bd38 | ||
|
|
c243c4c59a | ||
|
|
c8db1347d0 | ||
|
|
9952f90261 | ||
|
|
48fcd8b4ff | ||
|
|
10a09253f8 | ||
|
|
7b435f7a89 | ||
|
|
392150e412 | ||
|
|
4ac2366a97 | ||
|
|
017fb5e738 | ||
|
|
81a5ccc0ca | ||
|
|
fbe688ff4e | ||
|
|
9a58dc61eb | ||
|
|
d7bd59a699 | ||
|
|
41ef37e92e | ||
|
|
8031a4472e | ||
|
|
31be56226d | ||
|
|
902ff47337 | ||
|
|
dc06b87cdd | ||
|
|
1e25accdad | ||
|
|
67dbc4d7f7 | ||
|
|
ab3268407c | ||
|
|
470b43578e | ||
|
|
038b50455e | ||
|
|
5c3fa682a9 | ||
|
|
e677acd1ed | ||
|
|
68cd6e2dfb | ||
|
|
7130ff6f71 | ||
|
|
a6d5d0dcdc | ||
|
|
a3b738f91d | ||
|
|
b66d2e39f4 | ||
|
|
0ef761e899 | ||
|
|
7d09f0892a | ||
|
|
972f15c774 | ||
|
|
fa11195d4a | ||
|
|
f437d3aae1 | ||
|
|
04a28967c7 | ||
|
|
47c831d672 | ||
|
|
3c4c2cf540 | ||
|
|
f383487764 | ||
|
|
d900dec667 | ||
|
|
49d200fb85 | ||
|
|
2f9d117cc6 | ||
|
|
ef44de3ebe | ||
|
|
76d03bb504 | ||
|
|
b58543237f | ||
|
|
4859157264 | ||
|
|
a5f3ce20ae | ||
|
|
14fe54d2af | ||
|
|
f2d611e26d | ||
|
|
700774b207 | ||
|
|
770446c052 | ||
|
|
f576b99c5c | ||
|
|
678e888a4a | ||
|
|
3335215866 | ||
|
|
d4a64e7a5a | ||
|
|
d778157d5a | ||
|
|
3d0f6dafa5 | ||
|
|
374a6ba5d6 | ||
|
|
eee6160060 | ||
|
|
5202b3febb | ||
|
|
a0d48fdb48 | ||
|
|
831fddafd7 | ||
|
|
278a30cd7d | ||
|
|
55b65b202e | ||
|
|
e1b6456a14 | ||
|
|
4f285c989d | ||
|
|
7cc946e19f | ||
|
|
bc783be346 | ||
|
|
a156a2da82 | ||
|
|
0131915253 | ||
|
|
97cb8a76f1 | ||
|
|
80129ae1b7 | ||
|
|
3f4ac9e8aa | ||
|
|
8707810690 | ||
|
|
88edb9103f | ||
|
|
849546e97c | ||
|
|
d6959738db | ||
|
|
f70a125b18 | ||
|
|
fe7f6baee4 | ||
|
|
2d264b5fba | ||
|
|
74bbbe02d9 | ||
|
|
a6cd04a441 | ||
|
|
f7884093ca | ||
|
|
e327fd3e51 | ||
|
|
ade6cf7ac0 | ||
|
|
3404015fc3 | ||
|
|
f91911e9f7 | ||
|
|
a3631278df | ||
|
|
a0eab88134 | ||
|
|
45795a5d11 | ||
|
|
4bb3efa25c | ||
|
|
783a76932c | ||
|
|
006eb3c76e | ||
|
|
2326d26de9 | ||
|
|
7c9f69ea20 | ||
|
|
0107f7af42 | ||
|
|
4e2e133790 | ||
|
|
0d42250171 | ||
|
|
599c81cf94 | ||
|
|
d11e393007 | ||
|
|
c6879f779b | ||
|
|
d17b8f0bd6 | ||
|
|
238ba6a462 | ||
|
|
566b6730bc | ||
|
|
09aa042606 | ||
|
|
acd09c3024 | ||
|
|
0cbb06a6da | ||
|
|
9992feaa7b | ||
|
|
bb968d51b0 | ||
|
|
b6001796d7 | ||
|
|
8ab9387076 | ||
|
|
f9fd0eeda3 | ||
|
|
f2cee9c33d | ||
|
|
a860b09638 | ||
|
|
be3e83f4e3 | ||
|
|
5788df3f57 | ||
|
|
ec286a57d1 | ||
|
|
655eb9f128 | ||
|
|
37d95fe314 | ||
|
|
830a2c69d8 | ||
|
|
ead94a4493 | ||
|
|
cff15f9027 | ||
|
|
13d7dcfef5 | ||
|
|
259bb1a0ca | ||
|
|
d0fb629217 | ||
|
|
ab55c37a33 | ||
|
|
93a0a194bc | ||
|
|
3df71c9943 | ||
|
|
4d4e3988ab | ||
|
|
1bfabae65b | ||
|
|
eb08291de2 | ||
|
|
d63d92e488 | ||
|
|
bd047063ef | ||
|
|
d725bf21ae | ||
|
|
f7699edaaf | ||
|
|
47501aee7a | ||
|
|
e4f526bdda | ||
|
|
29bf23cd18 | ||
|
|
39d6da414d | ||
|
|
e7233de48f | ||
|
|
255d6ef66c | ||
|
|
b41e27d7c3 | ||
|
|
e3c858ac01 | ||
|
|
014075c313 | ||
|
|
eb3e77c572 | ||
|
|
512ae89fea | ||
|
|
7f57d05281 | ||
|
|
5892f70c83 | ||
|
|
699f775141 | ||
|
|
a09e06898f | ||
|
|
565314ff5f | ||
|
|
bd669f333f | ||
|
|
829d8bc985 | ||
|
|
218dba5623 | ||
|
|
b8bf2fed0d | ||
|
|
d505dc1072 | ||
|
|
20148b05c4 | ||
|
|
2516309b93 | ||
|
|
92d3a2e208 | ||
|
|
286d7a036e | ||
|
|
4556822a8a | ||
|
|
be227926c8 | ||
|
|
42626a780c | ||
|
|
afd8a9610f | ||
|
|
393334409f | ||
|
|
0fb52a929d | ||
|
|
50b10e214c | ||
|
|
bbadfbebfa | ||
|
|
a52a6253b5 | ||
|
|
4ca010cc99 | ||
|
|
a136d938df | ||
|
|
132ba0128d | ||
|
|
6b705a9838 | ||
|
|
f3381b0aae | ||
|
|
ba086159ad | ||
|
|
3a98323e8b | ||
|
|
1de30914c2 | ||
|
|
984bb7c04f | ||
|
|
6140b7f799 | ||
|
|
3dc98a3790 | ||
|
|
ab7345f017 | ||
|
|
ef57c7fea4 | ||
|
|
efb013db4a | ||
|
|
cd1c0df3cd | ||
|
|
9d08827ccf | ||
|
|
5083de2941 | ||
|
|
b266d9f742 | ||
|
|
ea187707c8 | ||
|
|
1b334d570e | ||
|
|
eb0537471e | ||
|
|
fa2c949eda | ||
|
|
f5fd07d6e7 | ||
|
|
be1a2ebf8c | ||
|
|
31cd173b0d | ||
|
|
5408064ff5 | ||
|
|
482aee3a1a | ||
|
|
95f3ac667c | ||
|
|
1e0a7ba0d6 | ||
|
|
57865e53dd | ||
|
|
d6617f33dd | ||
|
|
1e778b0cc4 | ||
|
|
6ceb58e5d3 | ||
|
|
e7e8244323 | ||
|
|
03a3cabe41 | ||
|
|
480002c5f1 | ||
|
|
0126584a7d | ||
|
|
3f76e4a0dd | ||
|
|
890cf5cbfd | ||
|
|
a951e844bf | ||
|
|
568815bf4a | ||
|
|
f18293ffe9 | ||
|
|
003dc8d247 | ||
|
|
f259de2679 | ||
|
|
b0f783f54b | ||
|
|
4fbdbcf8c5 | ||
|
|
ac5c993b27 | ||
|
|
e05dcf7383 | ||
|
|
c9ea3ab1ae | ||
|
|
4b097dcaef | ||
|
|
2a9cca5f1b | ||
|
|
8ce3a40c66 | ||
|
|
958a13384d | ||
|
|
e25545c39f | ||
|
|
bca1e0c5c4 | ||
|
|
bf36024568 | ||
|
|
1292a270e0 | ||
|
|
68fe800f63 | ||
|
|
ceb1575e1a | ||
|
|
4916d63832 | ||
|
|
d2176485b9 | ||
|
|
e9dd421b62 | ||
|
|
802c241820 | ||
|
|
a3b5ced423 | ||
|
|
b975766d35 | ||
|
|
eb460570ac | ||
|
|
a8658d5b60 | ||
|
|
fbe462e2e3 | ||
|
|
04bbf28a57 | ||
|
|
47b79675da | ||
|
|
4ed83e737c | ||
|
|
2ee863becc | ||
|
|
b343c31317 | ||
|
|
04759e563e | ||
|
|
6a5478919c | ||
|
|
ac828b31e6 | ||
|
|
86f17113e3 | ||
|
|
cb0429fae9 | ||
|
|
f23418ad84 | ||
|
|
8386a70bfe | ||
|
|
843cb3d00a | ||
|
|
3143e9df1c | ||
|
|
b76bdb5ed5 | ||
|
|
0e80e88456 | ||
|
|
46bfe643a6 | ||
|
|
2e0b8e4d11 | ||
|
|
a8668c3c44 | ||
|
|
11431f0e68 | ||
|
|
6c664498dd | ||
|
|
7721ac722d | ||
|
|
0070f33089 | ||
|
|
a1267eb891 | ||
|
|
1803ba6a8e | ||
|
|
ae4b166c2f | ||
|
|
38d6136aa8 | ||
|
|
02fea57a48 | ||
|
|
882826a7e3 | ||
|
|
56a7788e28 | ||
|
|
82c4b75a12 | ||
|
|
ca3c932701 | ||
|
|
76b155c269 | ||
|
|
faed35e208 | ||
|
|
c46cd5030e | ||
|
|
c7e474cdc6 | ||
|
|
ac7a678a30 | ||
|
|
f956759865 | ||
|
|
2768b70d43 | ||
|
|
cc4a579905 | ||
|
|
450b7b8e8b | ||
|
|
a248bc9f96 | ||
|
|
35f677f2e9 | ||
|
|
fccba5d93d | ||
|
|
ae172e2c53 | ||
|
|
aa9bf0780b | ||
|
|
11f1d8057b | ||
|
|
e2f1e7c033 | ||
|
|
bb213425f8 | ||
|
|
162596ed93 | ||
|
|
aa3ba246a7 | ||
|
|
baf65438fe | ||
|
|
8b443dfa4b | ||
|
|
12f3f8695f | ||
|
|
964d308491 | ||
|
|
a1bf03e40e | ||
|
|
ff940e5d26 | ||
|
|
e2fa0ad11f | ||
|
|
654e44aa99 | ||
|
|
476689f615 | ||
|
|
fc1582aa70 | ||
|
|
a616b84045 | ||
|
|
73708b72c7 | ||
|
|
8f0807ddbe | ||
|
|
5547f885be | ||
|
|
5f8d521c6a | ||
|
|
51a169a88a | ||
|
|
ad89ed5f3d | ||
|
|
ca1362c595 | ||
|
|
9621d90613 | ||
|
|
50efeb06d1 | ||
|
|
e236acc29d | ||
|
|
1062ace58d | ||
|
|
298a901921 | ||
|
|
c2f453481c | ||
|
|
54e6b61972 | ||
|
|
c52a7b1e64 | ||
|
|
749cd2e381 | ||
|
|
24b1790c99 | ||
|
|
62823635b0 | ||
|
|
bc84220108 | ||
|
|
5158951326 | ||
|
|
500b739ddd | ||
|
|
b741d228ac | ||
|
|
437ff8b51d | ||
|
|
354dd0a7a4 | ||
|
|
3804123ca6 | ||
|
|
bbc752e475 | ||
|
|
80f69b88b2 | ||
|
|
a02eab478e | ||
|
|
22fdb9a1f9 | ||
|
|
496d2123ed | ||
|
|
15a2e6c6cf | ||
|
|
62a9a7aeb5 | ||
|
|
8541088893 | ||
|
|
e558cf8f7f | ||
|
|
01827deaf5 | ||
|
|
6d71677c17 | ||
|
|
ee42a717aa | ||
|
|
cfa8ab7ab6 | ||
|
|
4ecd14c187 | ||
|
|
d9318bc917 | ||
|
|
6f6db63580 | ||
|
|
ebd1e64694 | ||
|
|
f12aa92383 | ||
|
|
2df0638b19 | ||
|
|
542f484703 | ||
|
|
f9dbedb93a | ||
|
|
2492ae5d60 | ||
|
|
c5ab1c0e1a | ||
|
|
fa9a7c197b | ||
|
|
05b9f13a45 | ||
|
|
b4511920b0 | ||
|
|
4d6ee85071 | ||
|
|
3f96caf54d | ||
|
|
0b804ff776 | ||
|
|
0b1cec4e2d | ||
|
|
dd4bf9feba | ||
|
|
4d41bbcf04 | ||
|
|
04780bda5c | ||
|
|
becc991dc8 | ||
|
|
815756d168 | ||
|
|
c960cee703 | ||
|
|
c7da06215d | ||
|
|
55053f76a9 | ||
|
|
19fb9dafc9 | ||
|
|
f0f0dec8ea | ||
|
|
649b2f5e4a | ||
|
|
af06ec22c5 | ||
|
|
bb976e746a | ||
|
|
814f8418f2 | ||
|
|
a00dd1e4ca | ||
|
|
66e24c3750 | ||
|
|
1ff4c58fe3 | ||
|
|
5ff15b18a1 | ||
|
|
83975e9235 | ||
|
|
3adf475ef4 | ||
|
|
ccc6edebbb | ||
|
|
0d7ed7420d | ||
|
|
dbf1837b97 | ||
|
|
9ae738ac51 | ||
|
|
a4000efc43 | ||
|
|
7871a17942 | ||
|
|
5aad1d09b2 | ||
|
|
4eb5d7dfd3 | ||
|
|
0a841e8f4a | ||
|
|
53ffd0c9f0 | ||
|
|
5d3a9f2e2e | ||
|
|
9d6f38edb3 | ||
|
|
9e5e032e1d | ||
|
|
31426858c6 | ||
|
|
46b4ca0c91 | ||
|
|
f4cb68c567 | ||
|
|
ab4b234510 | ||
|
|
d5151c4f01 | ||
|
|
6df4689aa3 | ||
|
|
9727a6a9a5 | ||
|
|
7f00182fd9 | ||
|
|
261b0add27 | ||
|
|
5d6e753384 | ||
|
|
15c2e79e6e | ||
|
|
f763a66219 | ||
|
|
1061df6e4a | ||
|
|
4c121e6f50 | ||
|
|
74b3a04c4a | ||
|
|
e4488463ba | ||
|
|
c6fd67b5d5 | ||
|
|
e5dc596867 | ||
|
|
a28f8dad37 | ||
|
|
7855658bfd | ||
|
|
de14a85817 | ||
|
|
de2206bb27 | ||
|
|
451a7aecde | ||
|
|
5170194105 | ||
|
|
b2286ac06a | ||
|
|
57cc6d6d46 | ||
|
|
6e1b5901b3 | ||
|
|
203db7467f | ||
|
|
aa7d4838c7 | ||
|
|
b778f606c5 | ||
|
|
45146efce8 | ||
|
|
9229f9f295 | ||
|
|
2e1c29a5a8 | ||
|
|
79f925b589 | ||
|
|
572c2789cc | ||
|
|
913f9636ba | ||
|
|
83e5592305 | ||
|
|
b7e579f6b8 | ||
|
|
c211b811a6 | ||
|
|
4c02b25a2d | ||
|
|
28b2435019 | ||
|
|
a0e5d60a0a | ||
|
|
311eceec0d | ||
|
|
cf24dcdf22 | ||
|
|
ead3eceef4 | ||
|
|
59df9aefc4 | ||
|
|
cb97cc1786 | ||
|
|
cf18ecf193 | ||
|
|
6e6b13f29a | ||
|
|
f75a16159d | ||
|
|
b8fe6be9cc | ||
|
|
9993325679 | ||
|
|
ce8fe9f49d | ||
|
|
408a6706b1 | ||
|
|
79c7fa3b75 | ||
|
|
e9713b6c93 | ||
|
|
706a3e0cc2 | ||
|
|
b1a40516c1 | ||
|
|
7cf449074d | ||
|
|
2ce7a79263 | ||
|
|
cfa5660d54 | ||
|
|
1256f2a54a | ||
|
|
2695afa68e | ||
|
|
af71673c7b | ||
|
|
7f489e1a99 | ||
|
|
10fb33877c | ||
|
|
731def1f56 | ||
|
|
06057da172 | ||
|
|
af3e79e70a | ||
|
|
9e5ee72adf | ||
|
|
6a8344020f | ||
|
|
a1ad6f1dd0 | ||
|
|
71f2b64868 | ||
|
|
ad7e949c8c | ||
|
|
d24241d656 | ||
|
|
91d2e9bbbd | ||
|
|
8acc5680ac | ||
|
|
4d54ce4686 | ||
|
|
441e89edd7 | ||
|
|
f1da9f05fb | ||
|
|
464d2d38b4 | ||
|
|
1ea282c803 | ||
|
|
974559bf2e | ||
|
|
c353003c70 | ||
|
|
623bde1a61 | ||
|
|
67234fc013 | ||
|
|
4a6d6d647a | ||
|
|
b375b6c2d5 | ||
|
|
1c6fd4558c | ||
|
|
3800ffd61a | ||
|
|
d447ed8fc9 | ||
|
|
abb1062462 | ||
|
|
c6bdf78606 | ||
|
|
7687d5bf00 | ||
|
|
5b246891d7 | ||
|
|
3b9617faf4 | ||
|
|
aa57da0806 | ||
|
|
66841bba88 | ||
|
|
7d963e3602 | ||
|
|
82b25aecfb | ||
|
|
9b204fc660 | ||
|
|
68bcce7a27 | ||
|
|
3a57c7da69 | ||
|
|
055c4f82f5 | ||
|
|
12d8b07ff1 | ||
|
|
f07d66562b | ||
|
|
80f28da707 | ||
|
|
1aec77922f | ||
|
|
f431f02f11 | ||
|
|
2063183f50 | ||
|
|
8280af08a6 | ||
|
|
8029a54508 | ||
|
|
9e5478e0c0 | ||
|
|
c67c1966d7 | ||
|
|
e1aa096cef | ||
|
|
7135941b6a | ||
|
|
dc24fb82a8 | ||
|
|
32cfe3707e | ||
|
|
97378be94e | ||
|
|
db0559e9c9 | ||
|
|
94d6a900f7 | ||
|
|
d751c03d45 | ||
|
|
aef8003d50 | ||
|
|
2810b35d6c | ||
|
|
6148932389 | ||
|
|
f4889a36d4 | ||
|
|
e8879c0ffc | ||
|
|
ed64514415 | ||
|
|
fcc25ee2c8 | ||
|
|
695e19a8a7 | ||
|
|
384bf9a41a | ||
|
|
8f24a2758e | ||
|
|
3230663ae1 | ||
|
|
4a0fa7f615 | ||
|
|
0f05954dc5 | ||
|
|
55f442f9fa | ||
|
|
7e5edc46a3 | ||
|
|
d500f98fb4 | ||
|
|
7b8902ce3f | ||
|
|
98b3ad642f | ||
|
|
14466e27ac | ||
|
|
16ffd1b467 | ||
|
|
ca52fd7e5b | ||
|
|
ea5d3df64c | ||
|
|
b51ed71796 | ||
|
|
bf28507ae8 | ||
|
|
6715bef24a | ||
|
|
badbbd76cb | ||
|
|
253776a510 | ||
|
|
e1ef295bfa | ||
|
|
73c89f4e3c | ||
|
|
a52e0dfb16 | ||
|
|
9f8ed7bb50 | ||
|
|
a932f9408a | ||
|
|
7907ce6dbf | ||
|
|
230d510491 | ||
|
|
415fd1b2d1 | ||
|
|
89c954216d | ||
|
|
b689796b25 | ||
|
|
c4c18d324b | ||
|
|
b7bf500343 | ||
|
|
e5c6baf425 | ||
|
|
0127899c5e | ||
|
|
f23611cad6 | ||
|
|
a74df109b0 | ||
|
|
9582013bfa | ||
|
|
6c148dcb3b | ||
|
|
65488bbff8 | ||
|
|
40cbb81d1e | ||
|
|
77b896054f | ||
|
|
89c717bd11 | ||
|
|
b22f5643a9 | ||
|
|
8d68ed3117 | ||
|
|
65b1c81c21 | ||
|
|
28cd140cfb | ||
|
|
73b553fbd2 | ||
|
|
f12075798d | ||
|
|
323db21306 | ||
|
|
d54302eacc | ||
|
|
9a98d5b6e4 | ||
|
|
5ec613adf9 | ||
|
|
567ce7955a | ||
|
|
b185dcb072 | ||
|
|
79010f83dc | ||
|
|
5354f93946 | ||
|
|
e787e66ef9 | ||
|
|
440e826fed | ||
|
|
d2e5e1d441 | ||
|
|
32fc32f414 | ||
|
|
0a7b2a7a9f | ||
|
|
c315e6fdaa | ||
|
|
b5d9ed36e1 | ||
|
|
f24c7983c8 | ||
|
|
3447cd40bf | ||
|
|
95f4702e26 | ||
|
|
506142da8a | ||
|
|
34f6eac538 | ||
|
|
ae1a37cdf7 | ||
|
|
fab087bbe5 | ||
|
|
8608098996 | ||
|
|
220f4029b1 | ||
|
|
d21daf1434 | ||
|
|
1a4c16f797 | ||
|
|
975103fd3c | ||
|
|
fb84ac7c25 | ||
|
|
13ae8665d5 | ||
|
|
4e8b2beb0b | ||
|
|
dd1220ac97 | ||
|
|
b46308fa8f | ||
|
|
c366e637e9 | ||
|
|
81acc81ef7 | ||
|
|
eb7270ff3f | ||
|
|
30198d1a6d | ||
|
|
2fc078d994 | ||
|
|
bd1735cafb | ||
|
|
ca73e5bc4d | ||
|
|
aff78c2e30 | ||
|
|
fbd454eb5a | ||
|
|
ce964d2f12 | ||
|
|
2c26bc61da | ||
|
|
4111122cba | ||
|
|
e1e95dc6b3 | ||
|
|
e7c665e5da | ||
|
|
301eb587cb | ||
|
|
5c886b0f81 | ||
|
|
56a79924a0 | ||
|
|
beef1b38ed | ||
|
|
ce46a68187 | ||
|
|
94dc2d76b3 | ||
|
|
dcdde1cf4b | ||
|
|
e3a9099b58 | ||
|
|
fb03ff3994 | ||
|
|
1d42fbf2bf | ||
|
|
c0e4b1b93e | ||
|
|
139f3f90b0 | ||
|
|
cf6fae8e1d | ||
|
|
f8d69736c1 | ||
|
|
a4322cb99a | ||
|
|
9445006127 | ||
|
|
aeeaa91752 | ||
|
|
52fb4ac863 | ||
|
|
2a000a2a14 | ||
|
|
97fe3b2ea3 | ||
|
|
9b8a782d58 | ||
|
|
b56e40ea5b | ||
|
|
37d1bcb6eb | ||
|
|
f2b8c1fb4e | ||
|
|
92cc8fc4e3 | ||
|
|
701bd9335d | ||
|
|
d176c74715 | ||
|
|
0bf7c799f3 | ||
|
|
2f7d5cd4e1 | ||
|
|
c42b517293 | ||
|
|
e5dd55e419 | ||
|
|
83fdd11c59 | ||
|
|
08de8ce25a | ||
|
|
800bafc00c | ||
|
|
3b383b97ca | ||
|
|
b381c09ecf | ||
|
|
a53008fd67 | ||
|
|
899056c5a2 | ||
|
|
8554d47030 | ||
|
|
9808f58540 | ||
|
|
7228100835 | ||
|
|
08c1b413d2 | ||
|
|
27ae11860d | ||
|
|
9cc984e8ae | ||
|
|
d352782927 | ||
|
|
6e4a5281ed | ||
|
|
d11f6d9307 | ||
|
|
61b57687af | ||
|
|
3ab1623a40 | ||
|
|
f5acd60253 | ||
|
|
c4d368d2b5 | ||
|
|
e487d0a454 | ||
|
|
99ffcc52ec | ||
|
|
64510af8d3 | ||
|
|
52b14db475 | ||
|
|
c5fe5cd8d4 | ||
|
|
bdfc614ad5 | ||
|
|
0d03eac307 | ||
|
|
6c84edcb9d | ||
|
|
9d145e72b8 | ||
|
|
4529bc37b5 | ||
|
|
038ef42fe5 | ||
|
|
1871d36a97 | ||
|
|
45c2afae07 | ||
|
|
51edae2f67 | ||
|
|
437314e5ea | ||
|
|
ce6f9d8bc8 | ||
|
|
0cf65e1671 | ||
|
|
a0251ff650 | ||
|
|
9696badcd1 | ||
|
|
08817d199d | ||
|
|
df69a02e6f | ||
|
|
e845132d89 | ||
|
|
21e9b9a033 | ||
|
|
db61ea3077 | ||
|
|
d4a3d2392e | ||
|
|
88ecda706d | ||
|
|
184fb1f12e | ||
|
|
91340577df | ||
|
|
36729678e2 | ||
|
|
1c6b4bfc34 | ||
|
|
bbfd175579 | ||
|
|
0a6bd41444 | ||
|
|
ab21274c36 | ||
|
|
d4e6ad5553 | ||
|
|
49dbd757df | ||
|
|
20e82cc45b | ||
|
|
6a7fa80c55 | ||
|
|
12e34cd3e8 | ||
|
|
0a598fdf92 | ||
|
|
659b896ee7 | ||
|
|
7cda007a30 | ||
|
|
2288c4da8a | ||
|
|
fbfc21be1c | ||
|
|
787beb2aea | ||
|
|
6234e16c37 | ||
|
|
e9cbc0a0d9 | ||
|
|
166eeb8852 | ||
|
|
b321f92161 | ||
|
|
cf7d9d9ff5 | ||
|
|
fb5b3c1663 | ||
|
|
46bbc45145 | ||
|
|
dc8b4a6447 | ||
|
|
8ec38eca4a | ||
|
|
24b533689c | ||
|
|
5421e06fc9 | ||
|
|
7115efd94f | ||
|
|
92f88222c4 | ||
|
|
bc7aba71a6 | ||
|
|
1d8b8b3204 | ||
|
|
4a2e090ef8 | ||
|
|
8cf8d5b7e8 | ||
|
|
8d355ff6fc | ||
|
|
72456bb2bd | ||
|
|
87f3fd2827 | ||
|
|
7254aab68d | ||
|
|
95d7160ad0 |
+18
-2
@@ -1,2 +1,18 @@
|
||||
5
|
||||
2.6.22.12.2
|
||||
8
|
||||
2.6.2
|
||||
2.12.2
|
||||
5.2.2
|
||||
5.2.3
|
||||
5.4.2
|
||||
5.4.3
|
||||
5.4.4
|
||||
5.5.2
|
||||
5.6.2
|
||||
5.6.3
|
||||
5.9.2
|
||||
6.0.2
|
||||
6.0.3
|
||||
6.0.4
|
||||
6.0.5
|
||||
|
||||
7.0.2
|
||||
@@ -1 +0,0 @@
|
||||
module.exports = require('./babel.config.js');
|
||||
+2
-1
@@ -1,4 +1,5 @@
|
||||
exclude_patterns:
|
||||
- "**/*.spec.js"
|
||||
- "**/*.spec.ts"
|
||||
- "docs/**/*.js"
|
||||
- "packages/networks/src/substrate.ts"
|
||||
- "packages/util/src/is/utf8.ts"
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
.eslintrc.js
|
||||
**/build/*
|
||||
**/coverage/*
|
||||
**/node_modules/*
|
||||
+18
-1
@@ -1,11 +1,28 @@
|
||||
const base = require('@polkadot/dev/config/eslint');
|
||||
// Copyright 2017-2021 @polkadot/util authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
const base = require('@polkadot/dev/config/eslint.cjs');
|
||||
|
||||
module.exports = {
|
||||
...base,
|
||||
ignorePatterns: [
|
||||
'.eslintrc.js',
|
||||
'.github/**',
|
||||
'.vscode/**',
|
||||
'.yarn/**',
|
||||
'**/build/*',
|
||||
'**/coverage/*',
|
||||
'**/node_modules/*'
|
||||
],
|
||||
parserOptions: {
|
||||
...base.parserOptions,
|
||||
project: [
|
||||
'./tsconfig.json'
|
||||
]
|
||||
},
|
||||
rules: {
|
||||
...base.rules,
|
||||
// this seems very broken atm, false positives
|
||||
'@typescript-eslint/unbound-method': 'off'
|
||||
}
|
||||
};
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
title: SS58 registry is outdated
|
||||
labels: ['ci', '@networks']
|
||||
---
|
||||
|
||||
cc @polkadot-js/notifications
|
||||
|
||||
Discrepancies detected between https://github.com/paritytech/substrate/blob/master/ss58-registry.json and https://github.com/polkadot-js/common/blob/master/packages/networks/src/substrate.ts
|
||||
|
||||
Check the nightly cron output (or via `yarn networks:crosscheck` locally) and run `yarn networks:sync` to update. The output as found from the test includes:
|
||||
@@ -0,0 +1,23 @@
|
||||
name: 'Lock Threads'
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '30 1/2 * * *'
|
||||
|
||||
jobs:
|
||||
lock:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: dessant/lock-threads@v2
|
||||
with:
|
||||
github-token: ${{ secrets.GH_PAT_BOT }}
|
||||
issue-lock-inactive-days: '7'
|
||||
issue-lock-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: >
|
||||
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.
|
||||
@@ -5,11 +5,11 @@ jobs:
|
||||
pr:
|
||||
strategy:
|
||||
matrix:
|
||||
step: ['lint', 'test', 'build', 'docs']
|
||||
step: ['lint', 'test', 'build']
|
||||
name: ${{ matrix.step }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- uses: actions/checkout@v2
|
||||
- name: ${{ matrix.step }}
|
||||
env:
|
||||
CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
|
||||
|
||||
@@ -6,30 +6,22 @@ on:
|
||||
|
||||
jobs:
|
||||
master:
|
||||
if: "! startsWith(github.event.head_commit.message, '[CI Skip]')"
|
||||
strategy:
|
||||
matrix:
|
||||
step: ['build:release', 'docs:release']
|
||||
step: ['build:release']
|
||||
name: ${{ matrix.step }}
|
||||
if: "! startsWith(github.event.head_commit.message, '[CI Skip]') && github.repository == 'polkadot-js/common'"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
token: ${{ secrets.GH_PAT }}
|
||||
- name: ${{ matrix.step }}
|
||||
env:
|
||||
CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
|
||||
GH_PAGES_SRC: build-docs
|
||||
GH_PAT: ${{ secrets.GH_PAT }}
|
||||
GH_RELEASE_GITHUB_API_TOKEN: ${{ secrets.GH_PAT }}
|
||||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
run: |
|
||||
yarn install --immutable | grep -v 'YN0013'
|
||||
yarn ${{ matrix.step }}
|
||||
|
||||
dummy:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: dummy
|
||||
run: |
|
||||
echo "Dummy skip step"
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
name: Semgrep
|
||||
on:
|
||||
pull_request: {}
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
check:
|
||||
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: actions/checkout@v2
|
||||
- uses: returntocorp/semgrep-action@v1
|
||||
with:
|
||||
auditOn: push
|
||||
publishToken: ${{ secrets.SEMGREP_APP_TOKEN }}
|
||||
publishDeployment: 1395
|
||||
@@ -0,0 +1,25 @@
|
||||
name: SS58
|
||||
on:
|
||||
schedule:
|
||||
- cron: '15 4/6 * * *'
|
||||
|
||||
jobs:
|
||||
ss58:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: check
|
||||
env:
|
||||
CI_LOG: 123
|
||||
run: |
|
||||
yarn install --immutable | grep -v 'YN0013'
|
||||
yarn networks:crosscheck
|
||||
|
||||
- name: issue
|
||||
if: ${{ failure() }}
|
||||
uses: JasonEtco/create-an-issue@v2
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GH_PAT_BOT }}
|
||||
with:
|
||||
filename: .github/ss58-check.md
|
||||
update_existing: true
|
||||
@@ -0,0 +1,17 @@
|
||||
name: 'Close stale issues and PRs'
|
||||
on:
|
||||
schedule:
|
||||
- cron: '30 2/2 * * *'
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/stale@v3
|
||||
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
|
||||
@@ -0,0 +1,3 @@
|
||||
build
|
||||
coverage
|
||||
packages
|
||||
@@ -0,0 +1,4 @@
|
||||
// Copyright 2017-2021 @polkadot/dev authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
module.exports = require('@polkadot/dev/config/prettier.cjs');
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+75
File diff suppressed because one or more lines are too long
+591
File diff suppressed because one or more lines are too long
Vendored
-56
File diff suppressed because one or more lines are too long
+4
-2
@@ -5,7 +5,9 @@ enableProgressBars: false
|
||||
nodeLinker: node-modules
|
||||
|
||||
plugins:
|
||||
- path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.js
|
||||
- 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-rc.js
|
||||
yarnPath: .yarn/releases/yarn-3.0.0-rc.2.cjs
|
||||
|
||||
+711
-48
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,4 @@
|
||||
// Copyright 2017-2021 @polkadot/util authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
module.exports = require('@polkadot/dev/config/babel-config-cjs.cjs');
|
||||
@@ -1,5 +0,0 @@
|
||||
// Copyright 2017-2020 @polkadot/util authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
module.exports = require('@polkadot/dev/config/babel');
|
||||
@@ -1,17 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
function copy_folder () {
|
||||
SRC="packages/$1/build"
|
||||
DST="../apps/node_modules/@polkadot/$1"
|
||||
|
||||
echo "** Copying $SRC to $DST"
|
||||
|
||||
rm -rf $DST
|
||||
cp -r $SRC $DST
|
||||
}
|
||||
|
||||
yarn polkadot-dev-build-ts
|
||||
|
||||
copy_folder "keyring"
|
||||
copy_folder "util"
|
||||
copy_folder "util-crypto"
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
module.exports = {
|
||||
base: '/common/',
|
||||
title: 'polkadot-js/common',
|
||||
description: 'Common utilities and libraries that are in use accross all @polkadot projects',
|
||||
markdown: {
|
||||
lineNumbers: true
|
||||
},
|
||||
themeConfig: {
|
||||
displayAllHeaders: true,
|
||||
nav: [
|
||||
{ text: 'Polkadot/Substrate Apps', link: 'https://polkadot.js.org/apps/' },
|
||||
{ text: 'Project family', link: 'https://polkadot.js.org/' },
|
||||
{
|
||||
text: 'Documentation',
|
||||
items: [
|
||||
{ text: 'API Reference', link: 'https://polkadot.js.org/api/' },
|
||||
{ text: 'Utility Reference (this)', link: 'https://polkadot.js.org/common/' },
|
||||
{ text: 'UI Libs Reference', link: 'https://polkadot.js.org/ui/' },
|
||||
]
|
||||
},
|
||||
{ text: 'GitHub', link: 'https://github.com/polkadot-js/common' }
|
||||
],
|
||||
search: false,
|
||||
sidebar: [
|
||||
{
|
||||
title: 'Examples (keyring)',
|
||||
path: '/examples/keyring/',
|
||||
collapsable: false,
|
||||
sidebarDepth: 1,
|
||||
children: [
|
||||
['/examples/keyring/01_create_account/', 'Create account'],
|
||||
['/examples/keyring/02_load_accounts/', 'Load Accounts']
|
||||
]
|
||||
},
|
||||
['/util/', '@polkadot/util'],
|
||||
['/util-crypto/', '@polkadot/util-crypto'],
|
||||
['/keyring/', '@polkadot/keyring'],
|
||||
'/CONTRIBUTING.md'
|
||||
]
|
||||
}
|
||||
};
|
||||
@@ -1,9 +0,0 @@
|
||||
$accentColor = #fd8824
|
||||
$textColor = #2c3e50
|
||||
|
||||
.home .hero .description,
|
||||
.home .feature h2,
|
||||
.home .feature p {
|
||||
color: $textColor
|
||||
opacity: 0.75
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="initial-scale=0.5, maximum-scale=1">
|
||||
<meta http-equiv="refresh" content="0;URL='https://polkadot.js.org/docs/'" />
|
||||
<title>Redirecting to https://polkadot.js.org/docs/</title>
|
||||
</head>
|
||||
<body>
|
||||
Redirecting to <a href="https://polkadot.js.org/docs/">https://polkadot.js.org/docs/</a>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,51 +0,0 @@
|
||||
---
|
||||
home: true
|
||||
heroText:
|
||||
tagline:
|
||||
# Bringing JavaScript to the Polkadot world.
|
||||
# actionText: Repository Overview
|
||||
# actionLink: /REPOS.md
|
||||
features:
|
||||
- title: Keyring
|
||||
details: Manage user keys allowing for signing, encryption and decryption.
|
||||
- title: Utilities
|
||||
details: Various user utilities to work with data and perform check on it.
|
||||
- title: Crypto
|
||||
details: A thin and easy-to-use wrapper around cryptographic and hashing libraries.
|
||||
|
||||
footer: Apache-2 Licensed | Copyright © 2017-2019 polkadot-js authors and contributors
|
||||
---
|
||||
|
||||
## Welcome
|
||||
|
||||
Various useful utility functions that are used across all projects in the [@polkadot](https://polkadot.js.org) namespace. It provides utility functions with additional safety checks, allowing not only for consistent coding, but also reducing the general boilerplate.
|
||||
|
||||
::: tip Examples
|
||||
In a rush and just want examples? [Jump right in](/examples/keyring/) and get a handle on using the various components in your projects.
|
||||
:::
|
||||
|
||||
## Available packages
|
||||
|
||||
It is split up into a number of internal packages, namely utilities -
|
||||
|
||||
- [keyring](keyring/README.md) Keyring management
|
||||
- [util](util/README.md) General utilities
|
||||
- [util-crypto](util-crypto/README.md) Crypto and hashing utilities
|
||||
|
||||
## The Polkadot Project
|
||||
|
||||
You can read more about the Polkadot Network at [https://polkadot.network/](https://polkadot.network/)
|
||||
|
||||
## Github repositories
|
||||
|
||||
You can find the Polkadot repositories at:
|
||||
|
||||
- [https://github.com/polkadot-js](https://github.com/polkadot-js)
|
||||
- [https://github.com/paritytech/polkadot](https://github.com/paritytech/polkadot)
|
||||
- [https://github.com/paritytech/substrate](https://github.com/paritytech/substrate)
|
||||
|
||||
This documentation is generated from [https://github.com/polkadot-js/common](https://github.com/polkadot-js/common)
|
||||
|
||||
## Contributing
|
||||
|
||||
Contribution to Polkadot JS Common are more than welcome. You can [report issues](https://github.com/polkadot-js/common/issues/new) and [log feature requests](https://github.com/polkadot-js/common/issues/new).
|
||||
@@ -1 +0,0 @@
|
||||
yarn.lock
|
||||
@@ -1,5 +0,0 @@
|
||||
# Create Account
|
||||
|
||||
The following example shows how to create and account with keyring.
|
||||
|
||||
<<< @/docs/examples/keyring/01_create_account/index.js
|
||||
@@ -1,22 +0,0 @@
|
||||
/* eslint-disable header/header */
|
||||
/* eslint-disable @typescript-eslint/require-await */
|
||||
/* eslint-disable @typescript-eslint/unbound-method */
|
||||
|
||||
// Import Keyring class and utility function
|
||||
const Keyring = require('@polkadot/keyring').default;
|
||||
const stringToU8a = require('@polkadot/util/string/toU8a').default;
|
||||
|
||||
async function main () {
|
||||
// Create account seed for Alice
|
||||
const ALICE_SEED = 'Alice'.padEnd(32, ' ');
|
||||
|
||||
// Create an instance of the Keyring
|
||||
const keyring = new Keyring();
|
||||
|
||||
// Create pair and add Alice to keyring pair dictionary (with account seed)
|
||||
const pairAlice = keyring.addFromSeed(stringToU8a(ALICE_SEED));
|
||||
|
||||
console.log(`Created keyring pair for Alice with address: ${keyring.getPair(pairAlice.address).address}`);
|
||||
}
|
||||
|
||||
main().catch(console.error).finally(() => process.exit());
|
||||
@@ -1,19 +0,0 @@
|
||||
{
|
||||
"name": "01_create_account",
|
||||
"version": "0.1.0",
|
||||
"description": "Example showing how to create an account",
|
||||
"main": "index.js",
|
||||
"author": "ltfschoen",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"clean": "rimraf node_modules",
|
||||
"start": "node index.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@polkadot/util": "^0.32.10",
|
||||
"@polkadot/keyring": "^0.32.10"
|
||||
},
|
||||
"devDependencies": {
|
||||
"rimraf": "^2.6.2"
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
# Load Accounts
|
||||
|
||||
The following example shows how to load all accounts from the keyring as pairs and convert them into JSON format.
|
||||
|
||||
<<< @/docs/examples/keyring/02_load_accounts/index.js
|
||||
@@ -1,34 +0,0 @@
|
||||
/* eslint-disable header/header */
|
||||
/* eslint-disable @typescript-eslint/require-await */
|
||||
/* eslint-disable @typescript-eslint/unbound-method */
|
||||
|
||||
// Import Keyring class and utility function
|
||||
const Keyring = require('@polkadot/keyring').default;
|
||||
const stringToU8a = require('@polkadot/util/string/toU8a').default;
|
||||
|
||||
async function main () {
|
||||
// Create account seed for Alice and Bob
|
||||
const ALICE_SEED = 'Alice'.padEnd(32, ' ');
|
||||
const BOB_SEED = 'Bob'.padEnd(32, ' ');
|
||||
|
||||
// Create an instance of the Keyring
|
||||
const keyring = new Keyring();
|
||||
|
||||
// Create their pairs with account seeds. Add to keyring pair dictionary
|
||||
keyring.addFromSeed(stringToU8a(ALICE_SEED));
|
||||
keyring.addFromSeed(stringToU8a(BOB_SEED));
|
||||
|
||||
// Note that we did not use `addFromAddress` since it does not add the
|
||||
// secret key to memory so we cannot later retrieve it with `getPairs`
|
||||
|
||||
// Retrieve all keyring pairs from the keyring pair dictionary
|
||||
keyring
|
||||
.getPairs()
|
||||
.forEach((pair, index) => {
|
||||
const { address } = pair;
|
||||
|
||||
console.log(`\nAccount with index #${index} has json: `, JSON.stringify(keyring.toJson(address), null, 2));
|
||||
});
|
||||
}
|
||||
|
||||
main().catch(console.error).finally(() => process.exit());
|
||||
@@ -1,19 +0,0 @@
|
||||
{
|
||||
"name": "02_load_accounts",
|
||||
"version": "0.1.0",
|
||||
"description": "Example showing how to load accounts",
|
||||
"main": "index.js",
|
||||
"author": "ltfschoen",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"clean": "rimraf node_modules",
|
||||
"start": "node index.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@polkadot/util": "^0.32.10",
|
||||
"@polkadot/keyring": "^0.32.10"
|
||||
},
|
||||
"devDependencies": {
|
||||
"rimraf": "^2.6.2"
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
# Validate Adress
|
||||
|
||||
- This function will return true if the address is a legitamate Polkadot address and false if it is not
|
||||
|
||||
- Works both with Ed25519 and Sr25519 key types
|
||||
@@ -1,24 +0,0 @@
|
||||
/* eslint-disable header/header */
|
||||
|
||||
const { decodeAddress, encodeAddress } = require('@polkadot/keyring');
|
||||
const { hexToU8a, isHex } = require('@polkadot/util');
|
||||
|
||||
const address = '5GrpknVvGGrGH3EFuURXeMrWHvbpj3VfER1oX5jFtuGbfzCE';
|
||||
|
||||
const isValidAddressPolkadotAddress = () => {
|
||||
try {
|
||||
encodeAddress(
|
||||
isHex(address)
|
||||
? hexToU8a(address)
|
||||
: decodeAddress(address)
|
||||
);
|
||||
|
||||
return true;
|
||||
} catch (error) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
const isValid = isValidAddressPolkadotAddress();
|
||||
|
||||
console.log(isValid);
|
||||
@@ -1,18 +0,0 @@
|
||||
{
|
||||
"name": "03_validate_address",
|
||||
"version": "0.1.0",
|
||||
"description": "Example showing how to validate a polkadot address",
|
||||
"main": "index.js",
|
||||
"author": "Jesse",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"clean": "rimraf node_modules",
|
||||
"start": "node index.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@polkadot/keyring": "*"
|
||||
},
|
||||
"devDependencies": {
|
||||
"rimraf": "^2.6.2"
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
# Keyring Examples
|
||||
|
||||
Here you will find a list of examples that takes you through the basics of connecting to a local node, retrieving data from the Node and chain and execute transactions on the chain.
|
||||
|
||||
## Running the examples
|
||||
|
||||
From within each folder run the following to install required dependencies and to execute the example:
|
||||
```shell
|
||||
yarn;
|
||||
yarn start
|
||||
```
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
# Encrypt & Decrypt Message using NaCl
|
||||
|
||||
The following example shows how to encrypt and decrypt a message with NaCl (pronouced "salt"), which is a Networking and Cryptography library used in util-crypto.
|
||||
|
||||
[include](index.js)
|
||||
@@ -1,27 +0,0 @@
|
||||
/* eslint-disable header/header */
|
||||
/* eslint-disable @typescript-eslint/require-await */
|
||||
/* eslint-disable @typescript-eslint/unbound-method */
|
||||
|
||||
const { naclDecrypt, naclEncrypt } = require('@polkadot/util-crypto');
|
||||
|
||||
async function main () {
|
||||
const secret = new Uint8Array(32);
|
||||
const messagePreEncryption = new Uint8Array([1, 2, 3, 4, 5, 4, 3, 2, 1]);
|
||||
const noncePreEncryption = new Uint8Array(24);
|
||||
|
||||
// Encrypt the message
|
||||
const { encrypted, nonce } = naclEncrypt(messagePreEncryption, secret, noncePreEncryption);
|
||||
|
||||
// Show contents of the encrypted message
|
||||
console.log(`Encrypted message: ${JSON.stringify(encrypted, null, 2)}`);
|
||||
|
||||
// Decrypt the message
|
||||
const messageDecrypted = naclDecrypt(encrypted, nonce, secret);
|
||||
// Convert each Uint8Array to a string for comparison
|
||||
const isMatch = messagePreEncryption.toString === messageDecrypted.toString;
|
||||
|
||||
// Verify that the decrypted message matches the original message
|
||||
console.log(`Does the decrypted message match the original message? ${isMatch}`);
|
||||
}
|
||||
|
||||
main().catch(console.error).finally(() => process.exit());
|
||||
@@ -1,18 +0,0 @@
|
||||
{
|
||||
"name": "01_encrypt_decrypt_message_nacl",
|
||||
"version": "0.1.0",
|
||||
"description": "Example showing how to encrypt and decrypt a message using NaCl",
|
||||
"main": "index.js",
|
||||
"author": "ltfschoen",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"clean": "rimraf node_modules",
|
||||
"start": "node index.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@polkadot/util-crypto": "^0.32.10"
|
||||
},
|
||||
"devDependencies": {
|
||||
"rimraf": "^2.6.2"
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
# Sign & Verify Message using NaCl
|
||||
|
||||
The following example shows how to sign and verify a message with NaCl (pronouced "salt"), which is a Networking and Cryptography library used in util-crypto.
|
||||
|
||||
[include](index.js)
|
||||
@@ -1,33 +0,0 @@
|
||||
/* eslint-disable header/header */
|
||||
/* eslint-disable @typescript-eslint/require-await */
|
||||
/* eslint-disable @typescript-eslint/unbound-method */
|
||||
|
||||
const { stringToU8a, u8aToHex } = require('@polkadot/util');
|
||||
const { naclEncrypt, naclKeypairFromSeed, naclSign, naclVerify, randomAsU8a } = require('@polkadot/util-crypto');
|
||||
|
||||
async function main () {
|
||||
// Create account seed for Alice as fallback if generated mnemonic not valid
|
||||
const seedAlice = 'Alice'.padEnd(32, ' ');
|
||||
|
||||
// Generate new public/secret keypair for Alice from the supplied seed
|
||||
const { publicKey, secretKey } = naclKeypairFromSeed(stringToU8a(seedAlice));
|
||||
|
||||
// Encrypt message. Create Uint8Array's filled with random bytes of specified length
|
||||
const secret = randomAsU8a(32);
|
||||
const messagePreEncryption = stringToU8a('please send me DOTs');
|
||||
const noncePreEncryption = randomAsU8a(24);
|
||||
|
||||
const { encrypted } = naclEncrypt(messagePreEncryption, secret, noncePreEncryption);
|
||||
|
||||
// Sign the message with a valid signature
|
||||
const messageSignature = naclSign(encrypted, secretKey);
|
||||
|
||||
console.log(`Message signature: ${u8aToHex(messageSignature)}`);
|
||||
|
||||
// Validate that the message was correctly signed
|
||||
const isValidSignature = naclVerify(encrypted, messageSignature, publicKey);
|
||||
|
||||
console.log(`Was the message correctly signed? ${isValidSignature}`);
|
||||
}
|
||||
|
||||
main().catch(console.error).finally(() => process.exit());
|
||||
@@ -1,18 +0,0 @@
|
||||
{
|
||||
"name": "02_sign_verify_message_nacl",
|
||||
"version": "0.1.0",
|
||||
"description": "Example showing how to sign and verify a message using NaCl",
|
||||
"main": "index.js",
|
||||
"author": "ltfschoen",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"clean": "rimraf node_modules",
|
||||
"start": "node index.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@polkadot/util-crypto": "^0.32.10"
|
||||
},
|
||||
"devDependencies": {
|
||||
"rimraf": "^2.6.2"
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
# Create & Generate Mnemonic using BIP39
|
||||
|
||||
The following example shows how to create and generate mnemonics using BIP39.
|
||||
|
||||
[include](index.js)
|
||||
@@ -1,29 +0,0 @@
|
||||
/* eslint-disable header/header */
|
||||
/* eslint-disable @typescript-eslint/unbound-method */
|
||||
/* eslint-disable @typescript-eslint/require-await */
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||
|
||||
const { mnemonicGenerate, mnemonicToSeed, mnemonicValidate, naclKeypairFromSeed } = require('@polkadot/util-crypto');
|
||||
|
||||
async function main () {
|
||||
// Create mnemonic string for Alice using BIP39
|
||||
const mnemonicAlice = mnemonicGenerate();
|
||||
|
||||
console.log(`Generated mnemonic: ${mnemonicAlice}`);
|
||||
|
||||
// Validate the mnemic string that was generated
|
||||
const isValidMnemonic = mnemonicValidate(mnemonicAlice);
|
||||
|
||||
console.log(`isValidMnemonic: ${isValidMnemonic}`);
|
||||
|
||||
// Create valid seed from mnemonic as u8a and convert it to a string
|
||||
// FIXME - Replace with mnemonicToSeed once exposed
|
||||
const seedAlice = mnemonicToSeed(mnemonicAlice);
|
||||
|
||||
// Generate new public/secret keypair for Alice from the supplied seed
|
||||
const { publicKey, secretKey } = naclKeypairFromSeed(seedAlice);
|
||||
|
||||
// Encrypt, Sign and Validate the message. See Example 'Sign & Verify Message'
|
||||
}
|
||||
|
||||
main().catch(console.error).finally(() => process.exit());
|
||||
@@ -1,18 +0,0 @@
|
||||
{
|
||||
"name": "03_mnemonic_generate_validate_bip39",
|
||||
"version": "0.1.0",
|
||||
"description": "Example showing how to sign and verify a message using NaCl",
|
||||
"main": "index.js",
|
||||
"author": "ltfschoen",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"clean": "rimraf node_modules",
|
||||
"start": "node index.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@polkadot/util-crypto": "^0.32.10"
|
||||
},
|
||||
"devDependencies": {
|
||||
"rimraf": "^2.6.2"
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
# Generate a Multisig Account
|
||||
|
||||
Substrate provides a multisig dispatch function in its
|
||||
[Utility pallet](https://crates.parity.io/pallet_utility/index.html). This example generates the
|
||||
address that would correspond to a set of addresses and threshold.
|
||||
@@ -1,40 +0,0 @@
|
||||
/* eslint-disable header/header */
|
||||
import { createKeyMulti, encodeAddress, sortAddresses } from '@polkadot/util-crypto';
|
||||
|
||||
const SS58Prefix = 0;
|
||||
|
||||
// Input the addresses that will make up the multisig account.
|
||||
const addresses = [
|
||||
'1nUC7afqmo7zwRFWxDjrUQu9skk6fk99pafb4SiyGSRc8z3',
|
||||
'1ZX2XntfLEHrBPy73DpfQp9rG7pbLyvrFjEpi7mNKQgyga5',
|
||||
'14b1kB7CrqzRUeMsKc26FJ73f8FCpxAX6sNieu9gfYSfJuoL'
|
||||
];
|
||||
|
||||
// The number of accounts that must approve. Must be greater than 0 and less than
|
||||
// or equal to the total number of addresses.
|
||||
const threshold = 2;
|
||||
|
||||
// The address (as index in `addresses`) that will submit a transaction.
|
||||
const index = 0;
|
||||
|
||||
function main () {
|
||||
// Address as a byte array.
|
||||
const multiAddress = createKeyMulti(addresses, threshold);
|
||||
|
||||
// Convert byte array to SS58 encoding.
|
||||
const Ss58Address = encodeAddress(multiAddress, SS58Prefix);
|
||||
|
||||
console.log(`\nMultisig Address: ${Ss58Address}`);
|
||||
|
||||
// Take addresses and remove the sender.
|
||||
const otherSignatories = addresses.filter((who) => who !== addresses[index]);
|
||||
|
||||
// Sort them by public key.
|
||||
const otherSignatoriesSorted = sortAddresses(otherSignatories, SS58Prefix);
|
||||
|
||||
console.log(`\nOther Signatories: ${otherSignatoriesSorted}\n`);
|
||||
|
||||
process.exit();
|
||||
}
|
||||
|
||||
main();
|
||||
@@ -1,14 +0,0 @@
|
||||
{
|
||||
"name": "04_generate_multisig_address",
|
||||
"version": "0.1.0",
|
||||
"description": "Example showing how to generate a multisig address for Substrate's Utility pallet",
|
||||
"main": "index.js",
|
||||
"author": "joepetrowski",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"start": "node index.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@polkadot/util-crypto": "^2.9.0-beta.1"
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
# Util-Crypto Examples
|
||||
|
||||
Here you will find a list of examples that takes you through the basics of encrypting and decrypting messages using NaCl, signing a message with a seed and verifying it using NaCl, and generating and validating mnemonics for account seeds.
|
||||
|
||||
## Running the examples
|
||||
|
||||
From within each folder run the following to install required dependencies and to execute the example:
|
||||
```shell
|
||||
yarn;
|
||||
yarn start
|
||||
```
|
||||
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="initial-scale=0.5, maximum-scale=1">
|
||||
<meta http-equiv="refresh" content="0;URL='https://polkadot.js.org/docs/'" />
|
||||
<title>Redirecting to https://polkadot.js.org/docs/</title>
|
||||
</head>
|
||||
<body>
|
||||
Redirecting to <a href="https://polkadot.js.org/docs/">https://polkadot.js.org/docs/</a>
|
||||
</body>
|
||||
</html>
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 7.3 KiB |
@@ -0,0 +1,36 @@
|
||||
// Copyright 2017-2021 @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-(fetch|randomvalues|textdecoder|textencoder|ws)(.*)$': '<rootDir>/packages/x-$1/src/node',
|
||||
'@polkadot/x-global(.*)$': '<rootDir>/packages/x-global/src/$1',
|
||||
'@polkadot/x-rxjs(.*)$': '<rootDir>/packages/x-rxjs/src/$1'
|
||||
},
|
||||
modulePathIgnorePatterns: [
|
||||
'<rootDir>/packages/hw-ledger/build',
|
||||
'<rootDir>/packages/hw-ledger-transports/build',
|
||||
'<rootDir>/packages/keyring/build',
|
||||
'<rootDir>/packages/networks/build',
|
||||
'<rootDir>/packages/util/build',
|
||||
'<rootDir>/packages/util-crypto/build',
|
||||
'<rootDir>/packages/x-fetch/build',
|
||||
'<rootDir>/packages/x-global/build',
|
||||
'<rootDir>/packages/x-randomvalues/build',
|
||||
'<rootDir>/packages/x-rxjs/build',
|
||||
'<rootDir>/packages/x-textdecoder/build',
|
||||
'<rootDir>/packages/x-textencoder/build',
|
||||
'<rootDir>/packages/x-ws/build'
|
||||
],
|
||||
transformIgnorePatterns: ['/node_modules/(?!@polkadot)']
|
||||
});
|
||||
@@ -1,20 +0,0 @@
|
||||
// Copyright 2017-2020 @polkadot/util authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
const config = require('@polkadot/dev/config/jest');
|
||||
|
||||
module.exports = Object.assign({}, config, {
|
||||
moduleNameMapper: {
|
||||
'@polkadot/keyring(.*)$': '<rootDir>/packages/keyring/src/$1',
|
||||
'@polkadot/util-(crypto)(.*)$': '<rootDir>/packages/util-$1/src/$2',
|
||||
// eslint-disable-next-line sort-keys
|
||||
'@polkadot/util(.*)$': '<rootDir>/packages/util/src/$1'
|
||||
},
|
||||
modulePathIgnorePatterns: [
|
||||
'<rootDir>/packages/keyring/build',
|
||||
'<rootDir>/packages/util/build',
|
||||
'<rootDir>/packages/util-crypto/build'
|
||||
],
|
||||
resolver: './jest.resolver.js'
|
||||
});
|
||||
@@ -1,11 +0,0 @@
|
||||
// Copyright 2017-2020 @polkadot/util authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
const path = require('path');
|
||||
|
||||
module.exports = function resolver (file, config) {
|
||||
return file.includes('package.json')
|
||||
? path.join(config.basedir.replace('/src', '/'), file)
|
||||
: config.defaultResolver(file, config);
|
||||
};
|
||||
-13
@@ -1,13 +0,0 @@
|
||||
{
|
||||
"npmClient": "yarn",
|
||||
"useWorkspaces": true,
|
||||
"command": {
|
||||
"publish": {
|
||||
"allowBranch": "master"
|
||||
}
|
||||
},
|
||||
"packages": [
|
||||
"packages/*"
|
||||
],
|
||||
"version": "2.14.1"
|
||||
}
|
||||
+12
-10
@@ -7,24 +7,26 @@
|
||||
"packages/*"
|
||||
],
|
||||
"resolutions": {
|
||||
"babel-core": "^7.0.0-bridge.0"
|
||||
"typescript": "^4.3.5"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "polkadot-dev-build-ts",
|
||||
"build:release": "polkadot-ci-ghact-build",
|
||||
"docs": "polkadot-dev-build-docs",
|
||||
"docs:release": "polkadot-ci-ghact-docs",
|
||||
"build:rollup": "polkadot-exec-rollup --config",
|
||||
"lint": "polkadot-dev-run-lint",
|
||||
"clean": "polkadot-dev-clean-build",
|
||||
"networks:crosscheck": "polkadot-dev-run-test packages/networks/src/crosscheck",
|
||||
"networks:sync": "node packages/networks/scripts/fromSubstrate.mjs",
|
||||
"postinstall": "polkadot-dev-yarn-only",
|
||||
"test": "polkadot-dev-run-test --coverage --runInBand",
|
||||
"test:one": "polkadot-dev-run-test"
|
||||
"test": "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"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.10.2",
|
||||
"@polkadot/dev": "^0.55.10",
|
||||
"@polkadot/ts": "^0.3.26",
|
||||
"@types/jest": "^26.0.0"
|
||||
"@babel/core": "^7.14.6",
|
||||
"@polkadot/dev": "^0.62.57",
|
||||
"@polkadot/ts": "^0.4.4",
|
||||
"@types/jest": "^26.0.24"
|
||||
},
|
||||
"version": "2.14.1"
|
||||
"version": "7.0.2"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,201 @@
|
||||
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.
|
||||
@@ -0,0 +1,2 @@
|
||||
# @polkadot/hw-ledger-transports
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"name": "@polkadot/hw-ledger-transports",
|
||||
"version": "7.0.2",
|
||||
"type": "module",
|
||||
"repository": "github:polkadot-js/common",
|
||||
"author": "Jaco Greeff <jacogr@gmail.com>",
|
||||
"maintainers": [],
|
||||
"contributors": [],
|
||||
"license": "Apache-2.0",
|
||||
"main": "node.js",
|
||||
"browser": "browser.js",
|
||||
"react-native": "react-native.js",
|
||||
"sideEffects": false,
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.14.6",
|
||||
"@ledgerhq/hw-transport": "^6.1.0",
|
||||
"@ledgerhq/hw-transport-webhid": "^6.1.0",
|
||||
"@ledgerhq/hw-transport-webusb": "^6.1.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@ledgerhq/hw-transport-node-hid-singleton": "^6.1.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
// Copyright 2017-2021 @polkadot/hw-ledger authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type Transport from '@ledgerhq/hw-transport';
|
||||
import type { TransportDef } from './types';
|
||||
|
||||
import LedgerWebHid from '@ledgerhq/hw-transport-webhid';
|
||||
import LedgerWebUsb from '@ledgerhq/hw-transport-webusb';
|
||||
|
||||
export { packageInfo } from './packageInfo';
|
||||
|
||||
export const transports: TransportDef[] = [
|
||||
// deprecated
|
||||
// import LedgerU2F from '@ledgerhq/hw-transport-u2f';
|
||||
// {
|
||||
// create: (): Promise<Transport> =>
|
||||
// LedgerU2F.create(),
|
||||
// type: 'u2f'
|
||||
// },
|
||||
{
|
||||
create: (): Promise<Transport> =>
|
||||
LedgerWebUsb.create(),
|
||||
type: 'webusb'
|
||||
},
|
||||
{
|
||||
create: (): Promise<Transport> =>
|
||||
LedgerWebHid.create(),
|
||||
type: 'hid'
|
||||
}
|
||||
];
|
||||
@@ -0,0 +1,17 @@
|
||||
// Copyright 2017-2021 @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';
|
||||
|
||||
export const transports: TransportDef[] = [
|
||||
{
|
||||
create: (): Promise<Transport> =>
|
||||
LedgerHid.create(),
|
||||
type: 'hid'
|
||||
}
|
||||
];
|
||||
@@ -0,0 +1,6 @@
|
||||
// Copyright 2017-2021 @polkadot/hw-ledger-transports authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Auto-generated by @polkadot/dev, do not edit
|
||||
|
||||
export const packageInfo = { name: '@polkadot/hw-ledger-transports', version: '7.0.2' };
|
||||
@@ -0,0 +1,8 @@
|
||||
// Copyright 2017-2021 @polkadot/hw-ledger authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { TransportDef } from './types';
|
||||
|
||||
export { packageInfo } from './packageInfo';
|
||||
|
||||
export const transports: TransportDef[] = [];
|
||||
@@ -0,0 +1,11 @@
|
||||
// Copyright 2017-2021 @polkadot/hw-ledger authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import Transport from '@ledgerhq/hw-transport';
|
||||
|
||||
export type LedgerTypes = 'hid' | 'u2f' | 'webusb';
|
||||
|
||||
export interface TransportDef {
|
||||
create (): Promise<Transport>;
|
||||
type: LedgerTypes;
|
||||
}
|
||||
@@ -0,0 +1,201 @@
|
||||
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.
|
||||
@@ -0,0 +1,2 @@
|
||||
# @polkadot/hw-ledger
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"name": "@polkadot/hw-ledger",
|
||||
"version": "7.0.2",
|
||||
"type": "module",
|
||||
"repository": "github:polkadot-js/common",
|
||||
"author": "Jaco Greeff <jacogr@gmail.com>",
|
||||
"maintainers": [],
|
||||
"contributors": [],
|
||||
"license": "Apache-2.0",
|
||||
"main": "index.js",
|
||||
"sideEffects": [
|
||||
"./detectPackage.js",
|
||||
"./detectPackage.cjs"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.14.6",
|
||||
"@polkadot/hw-ledger-transports": "7.0.2",
|
||||
"@polkadot/util": "^7.0.2",
|
||||
"@zondax/ledger-substrate": "^0.16.2"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
// Copyright 2017-2021 @polkadot/hw-ledger authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { ResponseBase, SubstrateApp } from '@zondax/ledger-substrate';
|
||||
import type { AccountOptions, LedgerAddress, LedgerSignature, LedgerTypes, LedgerVersion } from './types';
|
||||
|
||||
import { transports } from '@polkadot/hw-ledger-transports';
|
||||
import { assert, 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;
|
||||
|
||||
// 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
|
||||
assert(['hid', 'webusb'].includes(transport), () => `Unsupported transport ${transport}`);
|
||||
assert(Object.keys(ledgerApps).includes(chain), () => `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 this.#wrapError(app.getAddress(account + accountOffset, change, addressIndex + addressOffset, confirm));
|
||||
|
||||
return {
|
||||
address,
|
||||
publicKey: `0x${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 this.#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 this.#wrapError(app.sign(account + accountOffset, change, addressIndex + addressOffset, buffer));
|
||||
|
||||
return {
|
||||
signature: `0x${signature.toString('hex')}`
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
#getApp = async (): Promise<SubstrateApp> => {
|
||||
if (!this.#app) {
|
||||
const def = transports.find(({ type }) => type === this.#transport);
|
||||
|
||||
assert(def, () => `Unable to find a transport for ${this.#transport}`);
|
||||
|
||||
const transport = await def.create();
|
||||
|
||||
this.#app = ledgerApps[this.#chain](transport);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
#wrapError = async <T extends ResponseBase> (promise: Promise<T>): Promise<T> => {
|
||||
const result = await promise;
|
||||
|
||||
assert(result.return_code === LEDGER_SUCCESS_CODE, () => result.error_message);
|
||||
|
||||
return result;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// Copyright 2017-2021 @polkadot/hw-ledger authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
export const LEDGER_DEFAULT_ACCOUNT = 0x80000000;
|
||||
|
||||
export const LEDGER_DEFAULT_CHANGE = 0x80000000;
|
||||
|
||||
export const LEDGER_DEFAULT_INDEX = 0x80000000;
|
||||
|
||||
export const LEDGER_SUCCESS_CODE = 0x9000;
|
||||
@@ -0,0 +1,24 @@
|
||||
// Copyright 2017-2021 @polkadot/hw-ledger authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { knownLedger } from '@polkadot/networks/defaults';
|
||||
|
||||
import { ledgerApps } from './defaults';
|
||||
|
||||
describe('defaults', (): void => {
|
||||
it('has entries for each of the apps (hwledger -> networks)', (): void => {
|
||||
expect(
|
||||
Object.keys(knownLedger).filter((network) =>
|
||||
!ledgerApps[network]
|
||||
)
|
||||
).toEqual([]);
|
||||
});
|
||||
|
||||
it('has entries for each of the apps (networks -> hwledger)', (): void => {
|
||||
expect(
|
||||
Object.keys(ledgerApps).filter((network) =>
|
||||
!knownLedger[network]
|
||||
)
|
||||
).toEqual([]);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,19 @@
|
||||
// Copyright 2017-2021 @polkadot/hw-ledger authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type Transport from '@ledgerhq/hw-transport';
|
||||
import type { SubstrateApp } from '@zondax/ledger-substrate';
|
||||
|
||||
import { newCentrifugeApp, newDockApp, newEdgewareApp, newEquilibriumApp, newKusamaApp, newPolkadotApp, newPolymeshApp, newStatemineApp } from '@zondax/ledger-substrate';
|
||||
|
||||
// These match up with the keys of the knownLedger object in the @polkadot/networks/defaults.ts
|
||||
export const ledgerApps: Record<string, (transport: Transport) => SubstrateApp> = {
|
||||
centrifuge: newCentrifugeApp,
|
||||
'dock-mainnet': newDockApp,
|
||||
edgeware: newEdgewareApp,
|
||||
equilibrium: newEquilibriumApp,
|
||||
kusama: newKusamaApp,
|
||||
polkadot: newPolkadotApp,
|
||||
polymesh: newPolymeshApp,
|
||||
statemine: newStatemineApp
|
||||
};
|
||||
@@ -0,0 +1,9 @@
|
||||
// Copyright 2017-2021 @polkadot/hw-ledger authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { packageInfo as transportInfo } from '@polkadot/hw-ledger-transports/packageInfo';
|
||||
import { detectPackage, packageInfo as utilInfo } from '@polkadot/util';
|
||||
|
||||
import { packageInfo } from './packageInfo';
|
||||
|
||||
detectPackage(packageInfo, typeof __dirname !== 'undefined' && __dirname, [transportInfo, utilInfo]);
|
||||
@@ -0,0 +1,6 @@
|
||||
// Copyright 2017-2021 @polkadot/hw-ledger authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import './detectPackage';
|
||||
|
||||
export * from './bundle';
|
||||
@@ -0,0 +1,6 @@
|
||||
// Copyright 2017-2021 @polkadot/hw-ledger authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Auto-generated by @polkadot/dev, do not edit
|
||||
|
||||
export const packageInfo = { name: '@polkadot/hw-ledger', version: '7.0.2' };
|
||||
@@ -0,0 +1,25 @@
|
||||
// Copyright 2017-2021 @polkadot/hw-ledger authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
export type LedgerTypes = 'hid' | 'u2f' | 'webusb';
|
||||
|
||||
export interface AccountOptions {
|
||||
account: number;
|
||||
addressIndex: number;
|
||||
change: number;
|
||||
}
|
||||
|
||||
export interface LedgerAddress {
|
||||
address: string;
|
||||
publicKey: string;
|
||||
}
|
||||
|
||||
export interface LedgerSignature {
|
||||
signature: string;
|
||||
}
|
||||
|
||||
export interface LedgerVersion {
|
||||
isLocked: boolean;
|
||||
isTestMode: boolean;
|
||||
version: [number, number, number];
|
||||
}
|
||||
@@ -15,7 +15,3 @@ Classes and Functions can be imported as follows:
|
||||
```js
|
||||
import Keyring from '@polkadot/keyring';
|
||||
```
|
||||
|
||||
## Utilities
|
||||
|
||||
[Utilities](SUMMARY.md)
|
||||
|
||||
@@ -1,34 +1,30 @@
|
||||
{
|
||||
"name": "@polkadot/keyring",
|
||||
"version": "2.14.1",
|
||||
"version": "7.0.2",
|
||||
"type": "module",
|
||||
"description": "Keyring management",
|
||||
"main": "index.js",
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
"registry": "https://registry.npmjs.org"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/polkadot-js/common.git"
|
||||
},
|
||||
"keywords": [
|
||||
"Polkadot",
|
||||
"Keyring",
|
||||
"ed25519"
|
||||
],
|
||||
"author": "Jaco Greeff <jacogr@gmail.com>",
|
||||
"maintainers": [
|
||||
"Jaco Greeff <jacogr@gmail.com>"
|
||||
],
|
||||
"maintainers": [],
|
||||
"contributors": [],
|
||||
"license": "Apache-2.0",
|
||||
"bugs": {
|
||||
"url": "https://github.com/polkadot-js/common/issues"
|
||||
"main": "index.js",
|
||||
"sideEffects": [
|
||||
"./detectPackage.js",
|
||||
"./detectPackage.cjs"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"repository": "github:polkadot-js/common",
|
||||
"bugs": "https://github.com/polkadot-js/common/issues",
|
||||
"homepage": "https://github.com/polkadot-js/common/tree/master/packages/keyring#readme",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.10.2",
|
||||
"@polkadot/util": "2.14.1",
|
||||
"@polkadot/util-crypto": "2.14.1"
|
||||
"@babel/runtime": "^7.14.6",
|
||||
"@polkadot/util": "7.0.2",
|
||||
"@polkadot/util-crypto": "7.0.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@polkadot/util": "7.0.2",
|
||||
"@polkadot/util-crypto": "7.0.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
// Copyright 2017-2021 @polkadot/keyring authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { Keyring } from './keyring';
|
||||
|
||||
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';
|
||||
|
||||
export { Keyring };
|
||||
@@ -1,14 +1,8 @@
|
||||
// Copyright 2017-2020 @polkadot/keyring authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
// Copyright 2017-2021 @polkadot/keyring authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// default substrate dev phrase
|
||||
const DEV_PHRASE = 'bottom drive obey lake curtain smoke basket hold race lonely fit walk';
|
||||
export const DEV_PHRASE = 'bottom drive obey lake curtain smoke basket hold race lonely fit walk';
|
||||
|
||||
// seed from the above phrase
|
||||
const DEV_SEED = '0xfac7959dbfe72f052e5a0c3c8d6530f202b02fd8f9f5ca3580ec8deb7797479e';
|
||||
|
||||
export {
|
||||
DEV_PHRASE,
|
||||
DEV_SEED
|
||||
};
|
||||
export const DEV_SEED = '0xfac7959dbfe72f052e5a0c3c8d6530f202b02fd8f9f5ca3580ec8deb7797479e';
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
// Copyright 2017-2021 @polkadot/keyring authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { detectPackage, packageInfo as utilInfo } from '@polkadot/util';
|
||||
import { packageInfo as cryptoInfo } from '@polkadot/util-crypto/packageInfo';
|
||||
|
||||
import { packageInfo } from './packageInfo';
|
||||
|
||||
detectPackage(packageInfo, typeof __dirname !== 'undefined' && __dirname, [utilInfo, cryptoInfo]);
|
||||
@@ -1,10 +1,12 @@
|
||||
// Copyright 2017-2020 @polkadot/keyring authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
// Copyright 2017-2021 @polkadot/keyring authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { KeyringPair$Json } from './types';
|
||||
|
||||
import { hexToU8a, stringToU8a } from '@polkadot/util';
|
||||
import { cryptoWaitReady, setSS58Format, encodeAddress } from '@polkadot/util-crypto';
|
||||
import { base64Decode, cryptoWaitReady, encodeAddress, randomAsU8a, setSS58Format } from '@polkadot/util-crypto';
|
||||
|
||||
import { decodePair } from './pair/decode';
|
||||
import Keyring from '.';
|
||||
|
||||
describe('keypair', (): void => {
|
||||
@@ -31,6 +33,12 @@ describe('keypair', (): void => {
|
||||
).toEqual(publicKeyTwo);
|
||||
});
|
||||
|
||||
it('creates via a dev seed', (): void => {
|
||||
expect(
|
||||
keyring.addFromUri('//Alice').address
|
||||
).toEqual('5FA9nQDVg267DEd8m1ZypXLBnvN7SFxYwV7ndqSYGiN9TTpu');
|
||||
});
|
||||
|
||||
it('creates a ed25519 pair via mnemonicToSeed', (): void => {
|
||||
expect(
|
||||
keyring.addFromUri(
|
||||
@@ -41,11 +49,11 @@ describe('keypair', (): void => {
|
||||
|
||||
it('adds from a mnemonic, with correct ss58', (): void => {
|
||||
setSS58Format(20); // this would not be used
|
||||
keyring.setSS58Format(68); // this would be used
|
||||
keyring.setSS58Format(2); // this would be used
|
||||
|
||||
const pair = keyring.addFromMnemonic('moral movie very draw assault whisper awful rebuild speed purity repeat card', {});
|
||||
|
||||
expect(pair.address).toEqual('7sPsxWPE5DzAyPT3VuoJYw5NTGscx9QYN9oddQx4kALKC3hH');
|
||||
expect(pair.address).toEqual('HSLu2eci2GCfWkRimjjdTXKoFSDL3rBv5Ey2JWCBj68cVZj');
|
||||
expect(encodeAddress(pair.publicKey)).toEqual('35cDYtPsdG1HUa2n2MaARgJyRz1WKMBZK1DL6c5cX7nugQh1');
|
||||
});
|
||||
|
||||
@@ -78,7 +86,19 @@ describe('keypair', (): void => {
|
||||
const pair = keyring.getPair(publicKeyOne);
|
||||
const signature = pair.sign(MESSAGE);
|
||||
|
||||
expect(pair.verify(MESSAGE, signature)).toBe(true);
|
||||
expect(pair.verify(MESSAGE, signature, pair.publicKey)).toBe(true);
|
||||
expect(pair.verify(MESSAGE, signature, randomAsU8a())).toBe(false);
|
||||
expect(pair.verify(new Uint8Array(), signature, pair.publicKey)).toBe(false);
|
||||
});
|
||||
|
||||
it('signs and verifies (withType)', (): void => {
|
||||
const MESSAGE = stringToU8a('this is a message');
|
||||
const pair = keyring.getPair(publicKeyOne);
|
||||
const signature = pair.sign(MESSAGE, { withType: true });
|
||||
|
||||
expect(pair.verify(MESSAGE, signature, pair.publicKey)).toBe(true);
|
||||
expect(pair.verify(MESSAGE, signature, randomAsU8a())).toBe(false);
|
||||
expect(pair.verify(new Uint8Array(), signature, pair.publicKey)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -101,6 +121,14 @@ describe('keypair', (): void => {
|
||||
).toEqual('5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY');
|
||||
});
|
||||
|
||||
it('creates via dev seed (2-byte encoding)', (): void => {
|
||||
keyring.setSS58Format(252);
|
||||
|
||||
expect(
|
||||
keyring.addFromUri('//Alice').address
|
||||
).toEqual('xw8P6urbSAronL3zZFB7dg8p7LLSgKCUFDUgjohnf1iP434ic');
|
||||
});
|
||||
|
||||
it('adds the pair', (): void => {
|
||||
expect(
|
||||
keyring.addFromSeed(seedTwo, {}).publicKey
|
||||
@@ -108,11 +136,11 @@ describe('keypair', (): void => {
|
||||
});
|
||||
|
||||
it('adds from a mnemonic', (): void => {
|
||||
keyring.setSS58Format(68);
|
||||
keyring.setSS58Format(2);
|
||||
|
||||
expect(
|
||||
keyring.addFromMnemonic('moral movie very draw assault whisper awful rebuild speed purity repeat card', {}).address
|
||||
).toEqual('7qQGarA4PWjPPVHG4USn1yuuVZvEHN7XZz8o7EbAp48jayZQ');
|
||||
).toEqual('FSjXNRT2K1R5caeHLPD6WMrqYUpfGZB7ua8W89JFctZ1YqV');
|
||||
});
|
||||
|
||||
it('allows publicKeys retrieval', (): void => {
|
||||
@@ -144,7 +172,19 @@ describe('keypair', (): void => {
|
||||
const pair = keyring.getPair(publicKeyOne);
|
||||
const signature = pair.sign(MESSAGE);
|
||||
|
||||
expect(pair.verify(MESSAGE, signature)).toBe(true);
|
||||
expect(pair.verify(MESSAGE, signature, pair.publicKey)).toBe(true);
|
||||
expect(pair.verify(MESSAGE, signature, randomAsU8a())).toBe(false);
|
||||
expect(pair.verify(new Uint8Array(), signature, pair.publicKey)).toBe(false);
|
||||
});
|
||||
|
||||
it('signs and verifies (withType)', (): void => {
|
||||
const MESSAGE = stringToU8a('this is a message');
|
||||
const pair = keyring.getPair(publicKeyOne);
|
||||
const signature = pair.sign(MESSAGE, { withType: true });
|
||||
|
||||
expect(pair.verify(MESSAGE, signature, pair.publicKey)).toBe(true);
|
||||
expect(pair.verify(MESSAGE, signature, randomAsU8a())).toBe(false);
|
||||
expect(pair.verify(new Uint8Array(), signature, pair.publicKey)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -175,11 +215,11 @@ describe('keypair', (): void => {
|
||||
});
|
||||
|
||||
it('adds from a mnemonic', (): void => {
|
||||
keyring.setSS58Format(68);
|
||||
keyring.setSS58Format(2);
|
||||
|
||||
expect(
|
||||
keyring.addFromMnemonic('moral movie very draw assault whisper awful rebuild speed purity repeat card').address
|
||||
).toEqual('7ooxHV3mz4nnWbK8v7Mxcb71QMpof268eL1A2VrYWUNWJk8P');
|
||||
).toEqual('DrRE1KAcs4pCicX8yJPh7YxkLPQ2vXnCFSVRPQfx38KjEFe');
|
||||
});
|
||||
|
||||
it('allows publicKeys retrieval', (): void => {
|
||||
@@ -204,12 +244,313 @@ describe('keypair', (): void => {
|
||||
).toEqual('5DzMsaYFhmpRdErWrP6K6PD7UXzYoeETToSBUrZSvxasqWRz');
|
||||
});
|
||||
|
||||
it('allows creation from JSON', (): void => {
|
||||
keyring.setSS58Format(2);
|
||||
const pair = keyring.createFromJson(
|
||||
JSON.parse('{"address":"0x02fde629668eb2bcc7d748f40a7e597f7c7b363498ff3db31f03ce4854937883ad","encoded":"qIhAhKqtf2iyEoWEr8nmBdksSI8EHHCpgJHToqd6Pl8AgAAAAQAAAAgAAADDZ//fj/BRRj+0+bl1KAlYgoPJp6nEUwiw0fVqO2BW4mjEgQ+iWwJEgDf1JUtecbzOlfhTXBzqX/dIYzLgUADrF4EFEPpboCWiU1iN7W/3DM1cOTRVvTGcbdIqW//z3axhz961qzeJVUIFgllwGe/euLUPIlKbIkiN/CsRYdQ=","encoding":{"content":["pkcs8","ecdsa"],"type":["scrypt","xsalsa20-poly1305"],"version":"3"},"meta":{"genesisHash":"0xb0a8d493285c2df73290dfb7e61f870f17b41801197a149ca93654499ea3dafe","name":"ecdsa","tags":[],"whenCreated":1600925898271}}')
|
||||
);
|
||||
|
||||
expect(pair.address).toEqual('DHL8HKFuTTR55JzzLmkJRCAfPBbuevKaT9cXikxbEV97Ko8');
|
||||
expect(pair.publicKey).toEqual(hexToU8a('0x02fde629668eb2bcc7d748f40a7e597f7c7b363498ff3db31f03ce4854937883ad'));
|
||||
});
|
||||
|
||||
it('fails toJson() when password is incorrect', (): void => {
|
||||
const pair = keyring.createFromJson(
|
||||
JSON.parse('{"address":"0x02fde629668eb2bcc7d748f40a7e597f7c7b363498ff3db31f03ce4854937883ad","encoded":"qIhAhKqtf2iyEoWEr8nmBdksSI8EHHCpgJHToqd6Pl8AgAAAAQAAAAgAAADDZ//fj/BRRj+0+bl1KAlYgoPJp6nEUwiw0fVqO2BW4mjEgQ+iWwJEgDf1JUtecbzOlfhTXBzqX/dIYzLgUADrF4EFEPpboCWiU1iN7W/3DM1cOTRVvTGcbdIqW//z3axhz961qzeJVUIFgllwGe/euLUPIlKbIkiN/CsRYdQ=","encoding":{"content":["pkcs8","ecdsa"],"type":["scrypt","xsalsa20-poly1305"],"version":"3"},"meta":{"genesisHash":"0xb0a8d493285c2df73290dfb7e61f870f17b41801197a149ca93654499ea3dafe","name":"ecdsa","tags":[],"whenCreated":1600925898271}}')
|
||||
);
|
||||
|
||||
expect(
|
||||
() => pair.toJson('invalid')
|
||||
).toThrow(/Unable to decode using the supplied passphrase/);
|
||||
});
|
||||
|
||||
it('pass toJson() when password is correct', (): void => {
|
||||
const pair = keyring.createFromJson(
|
||||
JSON.parse('{"address":"0x02fde629668eb2bcc7d748f40a7e597f7c7b363498ff3db31f03ce4854937883ad","encoded":"qIhAhKqtf2iyEoWEr8nmBdksSI8EHHCpgJHToqd6Pl8AgAAAAQAAAAgAAADDZ//fj/BRRj+0+bl1KAlYgoPJp6nEUwiw0fVqO2BW4mjEgQ+iWwJEgDf1JUtecbzOlfhTXBzqX/dIYzLgUADrF4EFEPpboCWiU1iN7W/3DM1cOTRVvTGcbdIqW//z3axhz961qzeJVUIFgllwGe/euLUPIlKbIkiN/CsRYdQ=","encoding":{"content":["pkcs8","ecdsa"],"type":["scrypt","xsalsa20-poly1305"],"version":"3"},"meta":{"genesisHash":"0xb0a8d493285c2df73290dfb7e61f870f17b41801197a149ca93654499ea3dafe","name":"ecdsa","tags":[],"whenCreated":1600925898271}}')
|
||||
);
|
||||
|
||||
expect(
|
||||
() => pair.toJson('testing')
|
||||
).not.toThrow();
|
||||
});
|
||||
|
||||
it('encodes a pair toJSON (and decodes)', (): void => {
|
||||
const pair = keyring.createFromUri('moral movie very draw assault whisper awful rebuild speed purity repeat card');
|
||||
const json = pair.toJson('password');
|
||||
|
||||
expect(json.address).toEqual('0x03ddca309bd5fedd01f914d6fb76f23aa848a2a520802159215dba5085d7863619');
|
||||
expect(json.encoding).toEqual({
|
||||
content: ['pkcs8', 'ecdsa'],
|
||||
type: ['scrypt', 'xsalsa20-poly1305'],
|
||||
version: '3'
|
||||
});
|
||||
|
||||
const newPair = keyring.createFromJson(json);
|
||||
|
||||
expect(newPair.publicKey).toEqual(pair.publicKey);
|
||||
expect(
|
||||
() => newPair.unlock('password')
|
||||
).not.toThrow();
|
||||
});
|
||||
|
||||
it('signs and verifies', (): void => {
|
||||
const MESSAGE = stringToU8a('this is a message');
|
||||
const pair = keyring.getPair(addressKeyOne);
|
||||
const signature = pair.sign(MESSAGE);
|
||||
|
||||
expect(pair.verify(MESSAGE, signature)).toBe(true);
|
||||
expect(pair.verify(MESSAGE, signature, pair.publicKey)).toBe(true);
|
||||
expect(pair.verify(MESSAGE, signature, randomAsU8a())).toBe(false);
|
||||
expect(pair.verify(new Uint8Array(), signature, pair.publicKey)).toBe(false);
|
||||
});
|
||||
|
||||
it('signs and verifies (withType)', (): void => {
|
||||
const MESSAGE = stringToU8a('this is a message');
|
||||
const pair = keyring.getPair(addressKeyOne);
|
||||
const signature = pair.sign(MESSAGE, { withType: true });
|
||||
|
||||
expect(pair.verify(MESSAGE, signature, pair.publicKey)).toBe(true);
|
||||
expect(pair.verify(MESSAGE, signature, randomAsU8a())).toBe(false);
|
||||
expect(pair.verify(new Uint8Array(), signature, pair.publicKey)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('ethereum', (): void => {
|
||||
// combine mnemonic with derivation path
|
||||
const PHRASE = 'seed sock milk update focus rotate barely fade car face mechanic mercy' + '/m/44\'/60\'/0\'/0/0';
|
||||
const PRIV_KEY_ONE = '0x070dc3117300011918e26b02176945cc15c3d548cf49fd8418d97f93af699e46';
|
||||
const ETH_ADDRESS_ONE = '0x31ea8795EE32D782C8ff41a5C68Dcbf0F5B27f6d';
|
||||
const ETH_ADDRESS_TWO = '0x4119b2e6c3Cb618F4f0B93ac77f9BeeC7FF02887';
|
||||
|
||||
let keyring: Keyring;
|
||||
|
||||
beforeEach((): void => {
|
||||
keyring = new Keyring({ type: 'ethereum' });
|
||||
});
|
||||
|
||||
it('creates with dev phrase from the private key', (): void => {
|
||||
const pair = keyring.addFromSeed(hexToU8a(PRIV_KEY_ONE));
|
||||
|
||||
expect(
|
||||
pair.address
|
||||
).toEqual(ETH_ADDRESS_ONE);
|
||||
});
|
||||
|
||||
it('creates with dev phrase from the private key in createFromUri', (): void => {
|
||||
const pair = keyring.createFromUri(PRIV_KEY_ONE);
|
||||
|
||||
expect(
|
||||
pair.address
|
||||
).toEqual(ETH_ADDRESS_ONE);
|
||||
});
|
||||
|
||||
it('creates with dev phrase with derivation path specified', (): void => {
|
||||
const pair = keyring.createFromUri(PHRASE);
|
||||
|
||||
expect(
|
||||
pair.address
|
||||
).toEqual(ETH_ADDRESS_ONE);
|
||||
});
|
||||
|
||||
it('creates with dev phrase with derivation path specified - addFromUri', (): void => {
|
||||
expect(
|
||||
keyring.addFromUri(PHRASE).address
|
||||
).toEqual(ETH_ADDRESS_ONE);
|
||||
});
|
||||
|
||||
it('encodes a pair toJSON (and decodes)', (): void => {
|
||||
const pair = keyring.createFromUri(PHRASE);
|
||||
const json = pair.toJson('password');
|
||||
|
||||
expect(json.address).toEqual('0x0381351b1b46d2602b0992bb5d5531f9c1696b0812feb2534b6884adc47e2e1d8b'); // this is the public key (different from address for ethereum)
|
||||
expect(json.encoding).toEqual({
|
||||
content: ['pkcs8', 'ethereum'],
|
||||
type: ['scrypt', 'xsalsa20-poly1305'],
|
||||
version: '3'
|
||||
});
|
||||
|
||||
const newPair = keyring.createFromJson(json);
|
||||
|
||||
expect(newPair.publicKey).toEqual(pair.publicKey);
|
||||
expect(
|
||||
() => newPair.unlock('password')
|
||||
).not.toThrow();
|
||||
});
|
||||
|
||||
it('encodes a pair toJSON and back', (): void => {
|
||||
const pairOriginal = keyring.createFromUri(PHRASE);
|
||||
const json = pairOriginal.toJson('password');
|
||||
const pair = keyring.addFromJson(
|
||||
json
|
||||
);
|
||||
|
||||
expect(pair.address).toEqual(ETH_ADDRESS_ONE);
|
||||
|
||||
pair.decodePkcs8('password');
|
||||
|
||||
expect(pair.isLocked).toBe(false);
|
||||
expect(pair.address).toBe(ETH_ADDRESS_ONE);
|
||||
});
|
||||
|
||||
it('allows adding from JSON', (): void => {
|
||||
const pair = keyring.addFromJson(
|
||||
JSON.parse('{"address":"KWCv1L3QX9LDPwY4VzvLmarEmXjVJidUzZcinvVnmxAJJCBou","encoded":"U8qFEaghhmNV2PgFhjqzmhyUy37Ok7abfFU2MNsBd0sAgAAAAQAAAAgAAAA3+NniKogzNphiMNueB1X0sGA07B6CaXWfpXPx45iSXoTTprwzU5mOoSqUWO0GKHROI72LN+uJ8Yfv6Ll6JOOV3VPKfoVoFmYm+zDrrMPa0gk5E5kUuSijxADcE6zUrliPVr0Ix/qaghu5SJ7RtWDQLBf4Hp86SJ8Gg6gTSSk=","encoding":{"content":["pkcs8","ethereum"],"type":["scrypt","xsalsa20-poly1305"],"version":"3"},"meta":{}}')
|
||||
);
|
||||
|
||||
expect(pair.publicKey).toEqual(hexToU8a('0x03b9dc646dd71118e5f7fda681ad9eca36eb3ee96f344f582fbe7b5bcdebb13077'));
|
||||
expect(pair.address).toEqual(ETH_ADDRESS_TWO);
|
||||
|
||||
pair.decodePkcs8('password');
|
||||
|
||||
expect(pair.isLocked).toBe(false);
|
||||
expect(pair.publicKey).toEqual(hexToU8a('0x03b9dc646dd71118e5f7fda681ad9eca36eb3ee96f344f582fbe7b5bcdebb13077'));
|
||||
expect(pair.address).toBe(ETH_ADDRESS_TWO);
|
||||
});
|
||||
|
||||
it('allows for signing/verification', (): void => {
|
||||
const MESSAGE = stringToU8a('just some test message');
|
||||
const signer = keyring.createFromUri(PHRASE);
|
||||
const verifier = keyring.addFromJson(
|
||||
JSON.parse('{"address":"KWCv1L3QX9LDPwY4VzvLmarEmXjVJidUzZcinvVnmxAJJCBou","encoded":"U8qFEaghhmNV2PgFhjqzmhyUy37Ok7abfFU2MNsBd0sAgAAAAQAAAAgAAAA3+NniKogzNphiMNueB1X0sGA07B6CaXWfpXPx45iSXoTTprwzU5mOoSqUWO0GKHROI72LN+uJ8Yfv6Ll6JOOV3VPKfoVoFmYm+zDrrMPa0gk5E5kUuSijxADcE6zUrliPVr0Ix/qaghu5SJ7RtWDQLBf4Hp86SJ8Gg6gTSSk=","encoding":{"content":["pkcs8","ethereum"],"type":["scrypt","xsalsa20-poly1305"],"version":"3"},"meta":{}}')
|
||||
);
|
||||
|
||||
const signature = signer.sign(MESSAGE);
|
||||
const dummyPublic = verifier.publicKey.slice();
|
||||
|
||||
dummyPublic[dummyPublic.length - 1] = 0;
|
||||
|
||||
expect(verifier.verify(MESSAGE, signature, signer.publicKey)).toBe(true);
|
||||
expect(verifier.verify(MESSAGE, signature, dummyPublic)).toBe(false);
|
||||
expect(verifier.verify(new Uint8Array(), signature, signer.publicKey)).toBe(false);
|
||||
});
|
||||
|
||||
it('allows for signing/verification (withType)', (): void => {
|
||||
const MESSAGE = stringToU8a('just some test message');
|
||||
const signer = keyring.createFromUri(PHRASE);
|
||||
const verifier = keyring.addFromJson(
|
||||
JSON.parse('{"address":"KWCv1L3QX9LDPwY4VzvLmarEmXjVJidUzZcinvVnmxAJJCBou","encoded":"U8qFEaghhmNV2PgFhjqzmhyUy37Ok7abfFU2MNsBd0sAgAAAAQAAAAgAAAA3+NniKogzNphiMNueB1X0sGA07B6CaXWfpXPx45iSXoTTprwzU5mOoSqUWO0GKHROI72LN+uJ8Yfv6Ll6JOOV3VPKfoVoFmYm+zDrrMPa0gk5E5kUuSijxADcE6zUrliPVr0Ix/qaghu5SJ7RtWDQLBf4Hp86SJ8Gg6gTSSk=","encoding":{"content":["pkcs8","ethereum"],"type":["scrypt","xsalsa20-poly1305"],"version":"3"},"meta":{}}')
|
||||
);
|
||||
|
||||
const signature = signer.sign(MESSAGE, { withType: true });
|
||||
const dummyPublic = verifier.publicKey.slice();
|
||||
|
||||
dummyPublic[dummyPublic.length - 1] = 0;
|
||||
|
||||
expect(verifier.verify(MESSAGE, signature, signer.publicKey)).toBe(true);
|
||||
expect(verifier.verify(MESSAGE, signature, dummyPublic)).toBe(false);
|
||||
expect(verifier.verify(new Uint8Array(), signature, signer.publicKey)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('raw pair add/create', (): void => {
|
||||
const json = JSON.parse('{"address":"5PjeoaQzCoYbSi42aQRKB3Sx18StCaEAzCbGEEbWbZyfKS3H","encoded":"JQUl8ZpoXv2OMkL9TPylLmcIye2cYhaS9INICbFgZTsAgAAAAQAAAAgAAAAr/0hJOOzokIdBG71TstigLABX9D5xGD7L37ySxtjDrVRg26LL90jLQ47quT9o3bq6ppXMVL6USk7Q4p3WU66bojTFuCDyhpYRhNbUqU6s0rD3S4bhv9lG+pG9vQ4eD5PVQUvxdANmJpYuDg45nrTmsMC5AHGdFGkHW/LHnkmbFid1cvPYkdiBoef5CIEdoly512pxMupVxnJWF1NT","encoding":{"content":["pkcs8","sr25519"],"type":["scrypt","xsalsa20-poly1305"],"version":"3"},"meta":{"name":"hello"}}') as KeyringPair$Json;
|
||||
const decoded = decodePair('1', base64Decode(json.encoded), json.encoding.type);
|
||||
const keyring = new Keyring({ ss58Format: 44 });
|
||||
|
||||
it('creates a pair from a private/public combo', (): void => {
|
||||
const pair = keyring.createFromPair(decoded, json.meta, 'sr25519');
|
||||
|
||||
expect(pair.address).toEqual('5PjeoaQzCoYbSi42aQRKB3Sx18StCaEAzCbGEEbWbZyfKS3H');
|
||||
expect(pair.isLocked).toEqual(false);
|
||||
expect(pair.meta.name).toEqual('hello');
|
||||
});
|
||||
|
||||
it('adds a pair from a private/public combo', (): void => {
|
||||
keyring.addFromPair(decoded, json.meta, 'sr25519');
|
||||
|
||||
const pair = keyring.getPairs()[0];
|
||||
|
||||
expect(pair.address).toEqual('5PjeoaQzCoYbSi42aQRKB3Sx18StCaEAzCbGEEbWbZyfKS3H');
|
||||
expect(pair.isLocked).toEqual(false);
|
||||
expect(pair.meta.name).toEqual('hello');
|
||||
});
|
||||
});
|
||||
|
||||
describe('util', (): void => {
|
||||
let keyring: Keyring;
|
||||
|
||||
beforeEach((): void => {
|
||||
keyring = new Keyring({ ss58Format: 42 });
|
||||
});
|
||||
|
||||
it('can re-encode an address to Polkadot live', (): void => {
|
||||
expect(
|
||||
keyring.encodeAddress('5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY', 0)
|
||||
).toEqual('15oF4uVJwmo4TdGW7VfQxNLavjCXviqxT9S1MgbjMNHr6Sp5');
|
||||
});
|
||||
|
||||
it('can re-encode an address to keyring default', (): void => {
|
||||
expect(
|
||||
keyring.encodeAddress('15oF4uVJwmo4TdGW7VfQxNLavjCXviqxT9S1MgbjMNHr6Sp5')
|
||||
).toEqual('5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY');
|
||||
});
|
||||
});
|
||||
|
||||
describe('version 2 JSON', (): void => {
|
||||
const PAIR = '{"address":"5CczAE5AmGrZ93MeVhha3Ywam7j9dKB7cArnH7gtrXcMFJvu","encoded":"0xee8f236e2ac3217ce689692a4afc612220dc77fddaed0482f8f95136a7c3e034cccfbc495410a6e9b2439904974ed1d207abeca536ff6985ceb78edeeb3dc343e561c184c488101af8811d1331430b4ccf0e96ef507132e5132964e8564232e7100d973c5bee7b231dd0c8ad5273f3501515a422c8d7ed9d20a73c0ed17c98ee4588e54844bb73052dcad81f7a1094613d63c162fec7446c88b1fae70e","encoding":{"content":["pkcs8","sr25519"],"type":"xsalsa20-poly1305","version":"2"},"meta":{"genesisHash":"0xe143f23803ac50e8f6f8e62695d1ce9e4e1d68aa36c1cd2cfd15340213f3423e","name":"json v2","tags":[],"whenCreated":1595243159596}}';
|
||||
const PASS2 = 'versionTwo';
|
||||
const PASS3 = 'versionThree';
|
||||
let keyring: Keyring;
|
||||
|
||||
beforeEach((): void => {
|
||||
keyring = new Keyring({ ss58Format: 42 });
|
||||
});
|
||||
|
||||
it('can decode from a version 2 JSON file', (): void => {
|
||||
const pair = keyring.addFromJson(JSON.parse(PAIR));
|
||||
|
||||
pair.decodePkcs8(PASS2);
|
||||
|
||||
const json = pair.toJson(PASS3);
|
||||
|
||||
expect(pair.isLocked).toBe(false);
|
||||
expect(pair.address).toBe('5CczAE5AmGrZ93MeVhha3Ywam7j9dKB7cArnH7gtrXcMFJvu');
|
||||
expect(json.encoding).toEqual({
|
||||
content: ['pkcs8', 'sr25519'],
|
||||
type: ['scrypt', 'xsalsa20-poly1305'],
|
||||
version: '3'
|
||||
});
|
||||
|
||||
pair.decodePkcs8(PASS3);
|
||||
|
||||
expect(pair.address).toEqual('5CczAE5AmGrZ93MeVhha3Ywam7j9dKB7cArnH7gtrXcMFJvu');
|
||||
});
|
||||
});
|
||||
|
||||
describe('version 3 JSON (hex)', (): void => {
|
||||
const PAIR = '{"address":"FLiSDPCcJ6auZUGXALLj6jpahcP6adVFDBUQznPXUQ7yoqH","encoded":"0xcd238963070cc4d6806053ee1ac500c7add9c28732bb5d434a332f84a91d9be0008000000100000008000000cf630a1113941b350ddd06697e50399183162e5e9a0e893eafc7f5f4893a223dca5055706b9925b56fdb4304192143843da718e11717daf89cf4f4781f94fb443f61432f782d54280af9eec90bd3069c3cc2d957a42b7c18dc2e9497f623735518e0e49b58f8e4db2c09da3a45dbb935659d015fc94b946cba75b606a6ff7f4e823f6b049e2e6892026b49de02d6dbbd64646fe0933f537d9ea53a70be","encoding":{"content":["pkcs8","sr25519"],"type":["scrypt","xsalsa20-poly1305"],"version":"3"},"meta":{"genesisHash":"0xb0a8d493285c2df73290dfb7e61f870f17b41801197a149ca93654499ea3dafe","name":"version3","tags":[],"whenCreated":1595277797639}}';
|
||||
const PASS3 = 'version3';
|
||||
let keyring: Keyring;
|
||||
|
||||
beforeEach((): void => {
|
||||
keyring = new Keyring({ ss58Format: 2 });
|
||||
});
|
||||
|
||||
it('can decode from a version 3 JSON file', (): void => {
|
||||
const pair = keyring.addFromJson(JSON.parse(PAIR));
|
||||
|
||||
pair.decodePkcs8(PASS3);
|
||||
|
||||
expect(pair.isLocked).toBe(false);
|
||||
expect(pair.address).toBe('FLiSDPCcJ6auZUGXALLj6jpahcP6adVFDBUQznPXUQ7yoqH');
|
||||
});
|
||||
});
|
||||
|
||||
describe('version 3 JSON (base64)', (): void => {
|
||||
const PAIR = '{"address":"FLiSDPCcJ6auZUGXALLj6jpahcP6adVFDBUQznPXUQ7yoqH","encoded":"ILjSgYaGvq1zaCz/kx+aqfLaHBjLXz0Qsmr6RnkOVU4AgAAAAQAAAAgAAAB5R2hm5kgXyc0NQYFxvMU4zCdjB+ugs/ibEooqCvuudbaeKn3Ee47NkCqU1ecOJV+eeaVn4W4dRvIpj5kGmQOGsewR+MiQ/B0G9NFh7JXV0qcPlk2QMNW1/mbJrTO4miqL448BSkP7ZOhUV6HFUpMt3B9HwjiRLN8RORcFp0ID/Azs4Jl/xOpXNzbgQGIffWgCIKTxN9N1ku6tdlG4","encoding":{"content":["pkcs8","sr25519"],"type":["scrypt","xsalsa20-poly1305"],"version":"3"},"meta":{"genesisHash":"0xb0a8d493285c2df73290dfb7e61f870f17b41801197a149ca93654499ea3dafe","name":"version3","tags":[],"whenCreated":1595277797639,"whenEdited":1595278378596}}';
|
||||
const PASS3 = 'version3';
|
||||
let keyring: Keyring;
|
||||
|
||||
beforeEach((): void => {
|
||||
keyring = new Keyring({ ss58Format: 2 });
|
||||
});
|
||||
|
||||
it('can decode from a version 3 JSON file', (): void => {
|
||||
const pair = keyring.addFromJson(JSON.parse(PAIR));
|
||||
|
||||
pair.decodePkcs8(PASS3);
|
||||
|
||||
expect(pair.isLocked).toBe(false);
|
||||
expect(pair.address).toBe('FLiSDPCcJ6auZUGXALLj6jpahcP6adVFDBUQznPXUQ7yoqH');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,20 +1,10 @@
|
||||
// Copyright 2017-2020 @polkadot/keyring authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
// Copyright 2017-2021 @polkadot/keyring authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { detectPackage } from '@polkadot/util';
|
||||
import { decodeAddress, encodeAddress, setSS58Format } from '@polkadot/util-crypto';
|
||||
import './detectPackage';
|
||||
|
||||
import Keyring from './keyring';
|
||||
import { Keyring } from './bundle';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
detectPackage(require('./package.json'), typeof __dirname !== 'undefined' && __dirname);
|
||||
export * from './bundle';
|
||||
|
||||
export default Keyring;
|
||||
|
||||
export {
|
||||
Keyring,
|
||||
decodeAddress,
|
||||
encodeAddress,
|
||||
setSS58Format
|
||||
};
|
||||
|
||||
@@ -1,16 +1,23 @@
|
||||
// Copyright 2017-2020 @polkadot/keyring authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
// Copyright 2017-2021 @polkadot/keyring authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { KeypairType, Keypair } from '@polkadot/util-crypto/types';
|
||||
import { KeyringInstance, KeyringPair, KeyringPair$Json, KeyringPair$Meta, KeyringOptions } from './types';
|
||||
import type { EncryptedJsonEncoding } from '@polkadot/util-crypto/json/types';
|
||||
import type { Keypair, KeypairType } from '@polkadot/util-crypto/types';
|
||||
import type { KeyringInstance, KeyringOptions, KeyringPair, KeyringPair$Json, KeyringPair$Meta } from './types';
|
||||
|
||||
import { assert, hexToU8a, isHex, stringToU8a } from '@polkadot/util';
|
||||
import { decodeAddress, encodeAddress, keyExtractSuri, keyFromPath, naclKeypairFromSeed as naclFromSeed, schnorrkelKeypairFromSeed as schnorrkelFromSeed, secp256k1KeypairFromSeed as secp256k1FromSeed, mnemonicToMiniSecret } from '@polkadot/util-crypto';
|
||||
import { assert, hexToU8a, isHex, isUndefined, stringToU8a } from '@polkadot/util';
|
||||
import { base64Decode, decodeAddress, encodeAddress, ethereumEncode, hdEthereum, keyExtractSuri, keyFromPath, mnemonicToLegacySeed, mnemonicToMiniSecret, naclKeypairFromSeed as naclFromSeed, schnorrkelKeypairFromSeed as schnorrkelFromSeed, secp256k1KeypairFromSeed as secp256k1FromSeed } from '@polkadot/util-crypto';
|
||||
|
||||
import { DEV_PHRASE } from './defaults';
|
||||
import createPair from './pair';
|
||||
import Pairs from './pairs';
|
||||
import { createPair } from './pair';
|
||||
import { Pairs } from './pairs';
|
||||
|
||||
const keypairFromSeed = {
|
||||
ecdsa: (seed: Uint8Array): Keypair => secp256k1FromSeed(seed),
|
||||
ed25519: (seed: Uint8Array): Keypair => naclFromSeed(seed),
|
||||
ethereum: (seed: Uint8Array): Keypair => secp256k1FromSeed(seed),
|
||||
sr25519: (seed: Uint8Array): Keypair => schnorrkelFromSeed(seed)
|
||||
};
|
||||
|
||||
/**
|
||||
* # @polkadot/keyring
|
||||
@@ -28,7 +35,7 @@ import Pairs from './pairs';
|
||||
* lookup of a pair for a given account address or public key using `getPair`. JSON metadata associated with
|
||||
* an account may be obtained using `toJson` accompanied by the account passphrase.
|
||||
*/
|
||||
export default class Keyring implements KeyringInstance {
|
||||
export class Keyring implements KeyringInstance {
|
||||
readonly #pairs: Pairs;
|
||||
|
||||
readonly #type: KeypairType;
|
||||
@@ -40,7 +47,7 @@ export default class Keyring implements KeyringInstance {
|
||||
constructor (options: KeyringOptions = {}) {
|
||||
options.type = options.type || 'ed25519';
|
||||
|
||||
assert(options && ['ecdsa', 'ed25519', 'sr25519'].includes(options.type || 'undefined'), `Expected a keyring type of either 'ed25519', 'sr25519' or 'ecdsa', found '${options.type}`);
|
||||
assert(['ecdsa', 'ethereum', 'ed25519', 'sr25519'].includes(options.type || 'undefined'), () => `Expected a keyring type of either 'ed25519', 'sr25519', 'ethereum' or 'ecdsa', found '${options.type || 'unknown'}`);
|
||||
|
||||
this.#pairs = new Pairs();
|
||||
this.#ss58 = options.ss58Format;
|
||||
@@ -79,15 +86,15 @@ export default class Keyring implements KeyringInstance {
|
||||
/**
|
||||
* @name addFromAddress
|
||||
* @summary Stores an account, given an account address, as a Key/Value (public key, pair) in Keyring Pair Dictionary
|
||||
* @description Allows user to explicitely provide separate inputs including account address or public key, and optionally
|
||||
* @description Allows user to explicitly provide separate inputs including account address or public key, and optionally
|
||||
* the associated account metadata, and the default encoded value as arguments (that may be obtained from the json file
|
||||
* of an account backup), and then generates a keyring pair from them that it passes to
|
||||
* `addPair` to stores in a keyring pair dictionary the public key of the generated pair as a key and the pair as the associated value.
|
||||
*/
|
||||
public addFromAddress (address: string | Uint8Array, meta: KeyringPair$Meta = {}, encoded: Uint8Array | null = null, type: KeypairType = this.type, ignoreChecksum?: boolean): KeyringPair {
|
||||
public addFromAddress (address: string | Uint8Array, meta: KeyringPair$Meta = {}, encoded: Uint8Array | null = null, type: KeypairType = this.type, ignoreChecksum?: boolean, encType?: EncryptedJsonEncoding[]): KeyringPair {
|
||||
const publicKey = this.decodeAddress(address, ignoreChecksum);
|
||||
|
||||
return this.addPair(createPair({ toSS58: this.encodeAddress, type }, { publicKey, secretKey: new Uint8Array() }, meta, encoded));
|
||||
return this.addPair(createPair({ toSS58: this.encodeAddress, type }, { publicKey, secretKey: new Uint8Array() }, meta, encoded, encType));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -97,12 +104,8 @@ export default class Keyring implements KeyringInstance {
|
||||
* of an account backup), and then generates a keyring pair from it that it passes to
|
||||
* `addPair` to stores in a keyring pair dictionary the public key of the generated pair as a key and the pair as the associated value.
|
||||
*/
|
||||
public addFromJson ({ address, encoded, encoding: { content, version }, meta }: KeyringPair$Json, ignoreChecksum?: boolean): KeyringPair {
|
||||
const type = version === '0' || !Array.isArray(content)
|
||||
? this.type
|
||||
: content[1];
|
||||
|
||||
return this.addFromAddress(address, meta, hexToU8a(encoded), type, ignoreChecksum);
|
||||
public addFromJson (json: KeyringPair$Json, ignoreChecksum?: boolean): KeyringPair {
|
||||
return this.addPair(this.createFromJson(json, ignoreChecksum));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -117,6 +120,16 @@ export default class Keyring implements KeyringInstance {
|
||||
return this.addFromUri(mnemonic, meta, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* @name addFromPair
|
||||
* @summary Stores an account created from an explicit publicKey/secreteKey combination
|
||||
*/
|
||||
public addFromPair (pair: Keypair, meta: KeyringPair$Meta = {}, type: KeypairType = this.type): KeyringPair {
|
||||
return this.addPair(
|
||||
this.createFromPair(pair, meta, type)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @name addFromSeed
|
||||
* @summary Stores an account, given seed data, as a Key/Value (public key, pair) in Keyring Pair Dictionary
|
||||
@@ -125,13 +138,9 @@ export default class Keyring implements KeyringInstance {
|
||||
* `addPair` to store in a keyring pair dictionary the public key of the generated pair as a key and the pair as the associated value.
|
||||
*/
|
||||
public addFromSeed (seed: Uint8Array, meta: KeyringPair$Meta = {}, type: KeypairType = this.type): KeyringPair {
|
||||
const keypair = {
|
||||
ecdsa: (): Keypair => secp256k1FromSeed(seed),
|
||||
ed25519: (): Keypair => naclFromSeed(seed),
|
||||
sr25519: (): Keypair => schnorrkelFromSeed(seed)
|
||||
}[type]();
|
||||
|
||||
return this.addPair(createPair({ toSS58: this.encodeAddress, type }, keypair, meta, null));
|
||||
return this.addPair(
|
||||
createPair({ toSS58: this.encodeAddress, type }, keypairFromSeed[type](seed), meta, null)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -145,6 +154,41 @@ export default class Keyring implements KeyringInstance {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @name createFromJson
|
||||
* @description Creates a pair from a JSON keyfile
|
||||
*/
|
||||
public createFromJson ({ address, encoded, encoding: { content, type, version }, meta }: KeyringPair$Json, ignoreChecksum?: boolean): KeyringPair {
|
||||
assert(version !== '3' || content[0] === 'pkcs8', () => `Unable to decode non-pkcs8 type, [${content.join(',')}] found}`);
|
||||
|
||||
const cryptoType = version === '0' || !Array.isArray(content)
|
||||
? this.type
|
||||
: content[1];
|
||||
const encType = !Array.isArray(type)
|
||||
? [type]
|
||||
: type;
|
||||
|
||||
assert(['ed25519', 'sr25519', 'ecdsa', 'ethereum'].includes(cryptoType), () => `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)
|
||||
? 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* @name createFromPair
|
||||
* @summary Creates a pair from an explicit publicKey/secreteKey combination
|
||||
*/
|
||||
public createFromPair (pair: Keypair, meta: KeyringPair$Meta = {}, type: KeypairType = this.type): KeyringPair {
|
||||
return createPair({ toSS58: this.encodeAddress, type }, pair, meta, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @name createFromUri
|
||||
* @summary Creates a Keypair from an suri
|
||||
@@ -155,21 +199,20 @@ export default class Keyring implements KeyringInstance {
|
||||
const suri = _suri.startsWith('//')
|
||||
? `${DEV_PHRASE}${_suri}`
|
||||
: _suri;
|
||||
const { password, path, phrase } = keyExtractSuri(suri);
|
||||
const { derivePath, password, path, phrase } = keyExtractSuri(suri);
|
||||
let seed: Uint8Array;
|
||||
const isPhraseHex = isHex(phrase, 256);
|
||||
|
||||
if (isHex(phrase, 256)) {
|
||||
if (isPhraseHex) {
|
||||
seed = hexToU8a(phrase);
|
||||
} else {
|
||||
const str = phrase as string;
|
||||
const str = phrase;
|
||||
const parts = str.split(' ');
|
||||
|
||||
if ([12, 15, 18, 21, 24].includes(parts.length)) {
|
||||
// FIXME This keeps compat with older versions, but breaks compat with subkey
|
||||
// seed = type === 'sr25519'
|
||||
// ? mnemonicToMiniSecret(phrase, password)
|
||||
// : mnemonicToSeed(phrase, password);
|
||||
seed = mnemonicToMiniSecret(phrase, password);
|
||||
seed = type === 'ethereum'
|
||||
? mnemonicToLegacySeed(phrase, '', false, 64)
|
||||
: mnemonicToMiniSecret(phrase, password);
|
||||
} else {
|
||||
assert(str.length <= 32, 'specified phrase is not a valid mnemonic and is invalid as a raw seed at > 32 bytes');
|
||||
|
||||
@@ -177,12 +220,11 @@ export default class Keyring implements KeyringInstance {
|
||||
}
|
||||
}
|
||||
|
||||
const keypair = {
|
||||
ecdsa: (): Keypair => secp256k1FromSeed(seed),
|
||||
ed25519: (): Keypair => naclFromSeed(seed),
|
||||
sr25519: (): Keypair => schnorrkelFromSeed(seed)
|
||||
};
|
||||
const derived = keyFromPath(keypair[type](), path, type);
|
||||
const derived = type === 'ethereum'
|
||||
? isPhraseHex
|
||||
? keypairFromSeed[type](seed) // for eth, if the private key is provided as suri, it must be derived only once
|
||||
: hdEthereum(seed, derivePath.substring(1))
|
||||
: keyFromPath(keypairFromSeed[type](seed), path, type);
|
||||
|
||||
return createPair({ toSS58: this.encodeAddress, type }, derived, meta, null);
|
||||
}
|
||||
@@ -192,7 +234,9 @@ export default class Keyring implements KeyringInstance {
|
||||
* @description Encodes the input into an ss58 representation
|
||||
*/
|
||||
public encodeAddress = (address: Uint8Array | string, ss58Format?: number): string => {
|
||||
return encodeAddress(address, ss58Format || this.#ss58);
|
||||
return this.type === 'ethereum'
|
||||
? ethereumEncode(address)
|
||||
: encodeAddress(address, isUndefined(ss58Format) ? this.#ss58 : ss58Format);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
// Copyright 2017-2021 @polkadot/keyring authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Auto-generated by @polkadot/dev, do not edit
|
||||
|
||||
export const packageInfo = { name: '@polkadot/keyring', version: '7.0.2' };
|
||||
@@ -1,10 +1,9 @@
|
||||
// Copyright 2017-2020 @polkadot/keyring authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
// Copyright 2017-2021 @polkadot/keyring authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import testingPairs from '../testingPairs';
|
||||
import { createTestPairs } from '../testingPairs';
|
||||
|
||||
const keyring = testingPairs({ type: 'ed25519' }, false);
|
||||
const keyring = createTestPairs({ type: 'ed25519' }, false);
|
||||
|
||||
describe('decode', (): void => {
|
||||
it('fails when no data provided', (): void => {
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
// Copyright 2017-2020 @polkadot/keyring authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
// Copyright 2017-2021 @polkadot/keyring authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { assert, stringToU8a, u8aFixLength } from '@polkadot/util';
|
||||
import { naclDecrypt } from '@polkadot/util-crypto';
|
||||
import { PairInfo } from './types';
|
||||
import type { EncryptedJsonEncoding } from '@polkadot/util-crypto/json/types';
|
||||
import type { PairInfo } from './types';
|
||||
|
||||
import { NONCE_LENGTH, PKCS8_DIVIDER, PKCS8_HEADER, PUB_LENGTH, SEC_LENGTH, SEED_LENGTH } from './defaults';
|
||||
import { assert, isUndefined, u8aEq } from '@polkadot/util';
|
||||
import { jsonDecryptData } from '@polkadot/util-crypto';
|
||||
|
||||
import { PKCS8_DIVIDER, PKCS8_HEADER, PUB_LENGTH, SEC_LENGTH, SEED_LENGTH } from './defaults';
|
||||
|
||||
const SEED_OFFSET = PKCS8_HEADER.length;
|
||||
|
||||
@@ -14,45 +15,33 @@ type DecodeResult = PairInfo & {
|
||||
secretKey: Uint8Array;
|
||||
};
|
||||
|
||||
function decodePkcs8 (encoded: Uint8Array): DecodeResult {
|
||||
const header = encoded.subarray(0, PKCS8_HEADER.length);
|
||||
export function decodePair (passphrase?: string, encrypted?: Uint8Array | null, _encType?: EncryptedJsonEncoding | EncryptedJsonEncoding[]): DecodeResult {
|
||||
const encType = Array.isArray(_encType) || isUndefined(_encType)
|
||||
? _encType
|
||||
: [_encType];
|
||||
const decrypted = jsonDecryptData(encrypted, passphrase, encType);
|
||||
const header = decrypted.subarray(0, PKCS8_HEADER.length);
|
||||
|
||||
assert(header.toString() === PKCS8_HEADER.toString(), 'Invalid Pkcs8 header found in body');
|
||||
assert(u8aEq(header, PKCS8_HEADER), 'Invalid Pkcs8 header found in body');
|
||||
|
||||
let secretKey = encoded.subarray(SEED_OFFSET, SEED_OFFSET + SEC_LENGTH);
|
||||
let secretKey = decrypted.subarray(SEED_OFFSET, SEED_OFFSET + SEC_LENGTH);
|
||||
let divOffset = SEED_OFFSET + SEC_LENGTH;
|
||||
let divider = encoded.subarray(divOffset, divOffset + PKCS8_DIVIDER.length);
|
||||
let divider = decrypted.subarray(divOffset, divOffset + PKCS8_DIVIDER.length);
|
||||
|
||||
// old-style, we have the seed here
|
||||
if (divider.toString() !== PKCS8_DIVIDER.toString()) {
|
||||
if (!u8aEq(divider, PKCS8_DIVIDER)) {
|
||||
divOffset = SEED_OFFSET + SEED_LENGTH;
|
||||
secretKey = encoded.subarray(SEED_OFFSET, divOffset);
|
||||
divider = encoded.subarray(divOffset, divOffset + PKCS8_DIVIDER.length);
|
||||
secretKey = decrypted.subarray(SEED_OFFSET, divOffset);
|
||||
divider = decrypted.subarray(divOffset, divOffset + PKCS8_DIVIDER.length);
|
||||
|
||||
assert(u8aEq(divider, PKCS8_DIVIDER), 'Invalid Pkcs8 divider found in body');
|
||||
}
|
||||
|
||||
assert(divider.toString() === PKCS8_DIVIDER.toString(), 'Invalid Pkcs8 divider found in body');
|
||||
|
||||
const pubOffset = divOffset + PKCS8_DIVIDER.length;
|
||||
const publicKey = encoded.subarray(pubOffset, pubOffset + PUB_LENGTH);
|
||||
const publicKey = decrypted.subarray(pubOffset, pubOffset + PUB_LENGTH);
|
||||
|
||||
return {
|
||||
publicKey,
|
||||
secretKey
|
||||
};
|
||||
}
|
||||
|
||||
export default function decode (passphrase?: string, encrypted?: Uint8Array | null): DecodeResult {
|
||||
assert(encrypted, 'No encrypted data available to decode');
|
||||
|
||||
const encoded = passphrase
|
||||
? naclDecrypt(
|
||||
encrypted.subarray(NONCE_LENGTH),
|
||||
encrypted.subarray(0, NONCE_LENGTH),
|
||||
u8aFixLength(stringToU8a(passphrase), 256, true)
|
||||
)
|
||||
: encrypted;
|
||||
|
||||
assert(encoded, 'Unable to unencrypt using the supplied passphrase');
|
||||
|
||||
return decodePkcs8(encoded);
|
||||
}
|
||||
|
||||
@@ -1,19 +1,9 @@
|
||||
// Copyright 2017-2020 @polkadot/keyring authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
// Copyright 2017-2021 @polkadot/keyring authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
const NONCE_LENGTH = 24;
|
||||
const PKCS8_DIVIDER = new Uint8Array([161, 35, 3, 33, 0]);
|
||||
const PKCS8_HEADER = new Uint8Array([48, 83, 2, 1, 1, 48, 5, 6, 3, 43, 101, 112, 4, 34, 4, 32]);
|
||||
const PUB_LENGTH = 32;
|
||||
const SEC_LENGTH = 64;
|
||||
const SEED_LENGTH = 32;
|
||||
|
||||
export {
|
||||
NONCE_LENGTH,
|
||||
PKCS8_DIVIDER,
|
||||
PKCS8_HEADER,
|
||||
PUB_LENGTH,
|
||||
SEC_LENGTH,
|
||||
SEED_LENGTH
|
||||
};
|
||||
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]);
|
||||
export const PUB_LENGTH = 32;
|
||||
export const SALT_LENGTH = 32;
|
||||
export const SEC_LENGTH = 64;
|
||||
export const SEED_LENGTH = 32;
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
// Copyright 2017-2020 @polkadot/keyring authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
// Copyright 2017-2021 @polkadot/keyring authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import testingPairs from '../testingPairs';
|
||||
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';
|
||||
|
||||
const PKCS8_LENGTH = PKCS8_DIVIDER.length + PKCS8_HEADER.length + PUB_LENGTH + SEC_LENGTH;
|
||||
const ENCODED_LENGTH = 157;
|
||||
const ENCODED_LENGTH = 16 + PKCS8_LENGTH + NONCE_LENGTH + SCRYPT_LENGTH;
|
||||
|
||||
const keyring = testingPairs({ type: 'ed25519' }, false);
|
||||
const keyring = createTestPairs({ type: 'ed25519' }, false);
|
||||
|
||||
describe('encode', (): void => {
|
||||
it('returns PKCS8 when no passphrase supplied', (): void => {
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
// Copyright 2017-2020 @polkadot/keyring authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
// Copyright 2017-2021 @polkadot/keyring authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { PairInfo } from './types';
|
||||
import type { PairInfo } from './types';
|
||||
|
||||
import { stringToU8a, u8aConcat, u8aFixLength, assert } from '@polkadot/util';
|
||||
import { naclEncrypt } from '@polkadot/util-crypto';
|
||||
import { assert, u8aConcat } from '@polkadot/util';
|
||||
import { naclEncrypt, scryptEncode, scryptToU8a } from '@polkadot/util-crypto';
|
||||
|
||||
import { PKCS8_DIVIDER, PKCS8_HEADER } from './defaults';
|
||||
|
||||
export default function encode ({ publicKey, secretKey }: PairInfo, passphrase?: string): Uint8Array {
|
||||
export function encodePair ({ publicKey, secretKey }: PairInfo, passphrase?: string): Uint8Array {
|
||||
assert(secretKey, 'Expected a valid secretKey to be passed to encode');
|
||||
|
||||
const encoded = u8aConcat(
|
||||
@@ -23,7 +22,8 @@ export default function encode ({ publicKey, secretKey }: PairInfo, passphrase?:
|
||||
return encoded;
|
||||
}
|
||||
|
||||
const { encrypted, nonce } = naclEncrypt(encoded, u8aFixLength(stringToU8a(passphrase), 256, true));
|
||||
const { params, password, salt } = scryptEncode(passphrase);
|
||||
const { encrypted, nonce } = naclEncrypt(encoded, password.subarray(0, 32));
|
||||
|
||||
return u8aConcat(nonce, encrypted);
|
||||
return u8aConcat(scryptToU8a(salt, params), nonce, encrypted);
|
||||
}
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
// Copyright 2017-2020 @polkadot/keyring authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
// Copyright 2017-2021 @polkadot/keyring authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { hexToU8a, u8aToHex } from '@polkadot/util';
|
||||
import { cryptoWaitReady, encodeAddress as toSS58, setSS58Format } from '@polkadot/util-crypto';
|
||||
|
||||
import { PAIRS } from '../testing';
|
||||
import testingPairs from '../testingPairs';
|
||||
import createPair from '.';
|
||||
import { PAIRSSR25519 } from '../testing';
|
||||
import { createTestPairs } from '../testingPairs';
|
||||
import { createPair } from '.';
|
||||
|
||||
const keyring = testingPairs({ type: 'ed25519' }, false);
|
||||
const keyring = createTestPairs({ type: 'ed25519' }, false);
|
||||
|
||||
const TEST_ADDRESS = '0x4119b2e6c3Cb618F4f0B93ac77f9BeeC7FF02887';
|
||||
|
||||
describe('pair', (): void => {
|
||||
beforeEach(async (): Promise<void> => {
|
||||
@@ -23,6 +25,11 @@ describe('pair', (): void => {
|
||||
).toEqual(
|
||||
new Uint8Array([209, 114, 167, 76, 218, 76, 134, 89, 18, 195, 43, 160, 168, 10, 87, 174, 105, 171, 174, 65, 14, 92, 203, 89, 222, 232, 78, 47, 68, 50, 219, 79])
|
||||
);
|
||||
expect(
|
||||
keyring.alice.addressRaw
|
||||
).toEqual(
|
||||
new Uint8Array([209, 114, 167, 76, 218, 76, 134, 89, 18, 195, 43, 160, 168, 10, 87, 174, 105, 171, 174, 65, 14, 92, 203, 89, 222, 232, 78, 47, 68, 50, 219, 79])
|
||||
);
|
||||
});
|
||||
|
||||
it('allows signing', (): void => {
|
||||
@@ -37,20 +44,56 @@ describe('pair', (): void => {
|
||||
expect(
|
||||
keyring.alice.verify(
|
||||
new Uint8Array([0x61, 0x62, 0x63, 0x64]),
|
||||
SIGNATURE
|
||||
SIGNATURE,
|
||||
keyring.alice.publicKey
|
||||
)
|
||||
).toEqual(true);
|
||||
});
|
||||
|
||||
it('fails a correctly signed message (signer changed)', (): void => {
|
||||
expect(
|
||||
keyring.alice.verify(
|
||||
new Uint8Array([0x61, 0x62, 0x63, 0x64, 0x65]),
|
||||
SIGNATURE,
|
||||
keyring.bob.publicKey
|
||||
)
|
||||
).toEqual(false);
|
||||
});
|
||||
|
||||
it('fails a correctly signed message (message changed)', (): void => {
|
||||
expect(
|
||||
keyring.alice.verify(
|
||||
new Uint8Array([0x61, 0x62, 0x63, 0x64, 0x65]),
|
||||
SIGNATURE
|
||||
SIGNATURE,
|
||||
keyring.alice.publicKey
|
||||
)
|
||||
).toEqual(false);
|
||||
});
|
||||
|
||||
it('allows vrf sign and verify', (): void => {
|
||||
const message = new Uint8Array([0x61, 0x62, 0x63, 0x64, 0x65]);
|
||||
|
||||
expect(
|
||||
keyring.alice.vrfVerify(
|
||||
message,
|
||||
keyring.alice.vrfSign(message),
|
||||
keyring.alice.publicKey
|
||||
)
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it('fails vrf sign and verify (publicKey changed)', (): void => {
|
||||
const message = new Uint8Array([0x61, 0x62, 0x63, 0x64, 0x65]);
|
||||
|
||||
expect(
|
||||
keyring.alice.vrfVerify(
|
||||
message,
|
||||
keyring.alice.vrfSign(message),
|
||||
keyring.bob.publicKey
|
||||
)
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
it('allows setting/getting of meta', (): void => {
|
||||
keyring.bob.setMeta({ foo: 'bar', something: 'else' });
|
||||
|
||||
@@ -62,15 +105,11 @@ describe('pair', (): void => {
|
||||
});
|
||||
|
||||
it('allows encoding of address with different prefixes', (): void => {
|
||||
expect(keyring.alice.address).toEqual(
|
||||
'5GoKvZWG5ZPYL1WUovuHW3zJBWBP5eT8CbqjdRY4Q6iMaQua'
|
||||
);
|
||||
expect(keyring.alice.address).toEqual('5GoKvZWG5ZPYL1WUovuHW3zJBWBP5eT8CbqjdRY4Q6iMaQua');
|
||||
|
||||
setSS58Format(68);
|
||||
setSS58Format(255);
|
||||
|
||||
expect(keyring.alice.address).toEqual(
|
||||
'7sGUeMak588SPY2YMmmuKUuLz7u2WQpf74F9dCFtSLB2td9d'
|
||||
);
|
||||
expect(keyring.alice.address).toEqual('yGHU8YKprxHbHdEv7oUK4rzMZXtsdhcXVG2CAMyC9WhzhjH2k');
|
||||
|
||||
setSS58Format(42);
|
||||
});
|
||||
@@ -87,11 +126,11 @@ describe('pair', (): void => {
|
||||
});
|
||||
|
||||
it('allows derivation on the pair', (): void => {
|
||||
const alice = createPair({ toSS58, type: 'sr25519' }, { publicKey: PAIRS[0].publicKey, secretKey: PAIRS[0].secretKey }, {});
|
||||
const alice = createPair({ toSS58, type: 'sr25519' }, { publicKey: PAIRSSR25519[0].publicKey, secretKey: PAIRSSR25519[0].secretKey }, {});
|
||||
const stash = alice.derive('//stash');
|
||||
const soft = alice.derive('//funding/0');
|
||||
|
||||
expect(stash.publicKey).toEqual(PAIRS[1].publicKey);
|
||||
expect(stash.publicKey).toEqual(PAIRSSR25519[1].publicKey);
|
||||
expect(soft.address).toEqual('5ECQNn7UueWHPFda5qUi4fTmTtyCnPvGnuoyVVSj5CboJh9J');
|
||||
});
|
||||
|
||||
@@ -103,4 +142,46 @@ describe('pair', (): void => {
|
||||
pair.sign(new Uint8Array([0]))
|
||||
).toThrow('Cannot sign with a locked key pair');
|
||||
});
|
||||
|
||||
describe('ethereum', (): void => {
|
||||
const PUBLICDERIVED = new Uint8Array([
|
||||
3, 129, 53, 27, 27, 70, 210, 96,
|
||||
43, 9, 146, 187, 93, 85, 49, 249,
|
||||
193, 105, 107, 8, 18, 254, 178, 83,
|
||||
75, 104, 132, 173, 196, 126, 46, 29,
|
||||
139
|
||||
]);
|
||||
const SECRETDERIVED = new Uint8Array([
|
||||
7, 13, 195, 17, 115, 0, 1, 25,
|
||||
24, 226, 107, 2, 23, 105, 69, 204,
|
||||
21, 195, 213, 72, 207, 73, 253, 132,
|
||||
24, 217, 127, 147, 175, 105, 158, 70
|
||||
]);
|
||||
|
||||
it('has a valid address from a known public', (): void => {
|
||||
const pair = createPair({ toSS58, type: 'ethereum' }, { publicKey: hexToU8a('0x03b9dc646dd71118e5f7fda681ad9eca36eb3ee96f344f582fbe7b5bcdebb13077') });
|
||||
|
||||
expect(pair.address).toEqual(TEST_ADDRESS);
|
||||
expect(pair.addressRaw).toEqual(hexToU8a(TEST_ADDRESS));
|
||||
});
|
||||
|
||||
it('has a valid address from a known ethereum address (20 length)', (): void => {
|
||||
const pair = createPair({ toSS58, type: 'ethereum' }, { publicKey: new Uint8Array([75, 32, 205, 127, 248, 119, 52, 31, 46, 171, 170, 23, 158, 23, 46, 108, 95, 180, 186, 168]), secretKey: new Uint8Array([]) });
|
||||
|
||||
expect(pair.address.toLowerCase()).toEqual('0x4b20cd7ff877341f2eabaa179e172e6c5fb4baa8');
|
||||
expect(pair.addressRaw).toEqual(hexToU8a('0x4b20cd7ff877341f2eabaa179e172e6c5fb4baa8'));
|
||||
});
|
||||
|
||||
it('converts to json', (): void => {
|
||||
const pair = createPair({ toSS58, type: 'ethereum' }, { publicKey: PUBLICDERIVED, secretKey: SECRETDERIVED });
|
||||
const json = pair.toJson('password');
|
||||
|
||||
expect(json.encoding).toEqual({
|
||||
content: ['pkcs8', 'ethereum'],
|
||||
type: ['scrypt', 'xsalsa20-poly1305'],
|
||||
version: '3'
|
||||
});
|
||||
expect(json.address).toEqual(u8aToHex(PUBLICDERIVED));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
// Copyright 2017-2020 @polkadot/keyring authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
// Copyright 2017-2021 @polkadot/keyring authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { Keypair, KeypairType } from '@polkadot/util-crypto/types';
|
||||
import { KeyringPair, KeyringPair$Json, KeyringPair$Meta, SignOptions } from '../types';
|
||||
import { PairInfo } from './types';
|
||||
import type { EncryptedJsonEncoding } from '@polkadot/util-crypto/json/types';
|
||||
import type { Keypair, KeypairType } from '@polkadot/util-crypto/types';
|
||||
import type { KeyringPair, KeyringPair$Json, KeyringPair$Meta, SignOptions } from '../types';
|
||||
import type { PairInfo } from './types';
|
||||
|
||||
import { assert, u8aConcat } from '@polkadot/util';
|
||||
import { keyExtractPath, keyFromPath, naclKeypairFromSeed as naclFromSeed, naclSign, naclVerify, schnorrkelKeypairFromSeed as schnorrkelFromSeed, schnorrkelSign, schnorrkelVerify, secp256k1KeypairFromSeed as secp256k1FromSeed, secp256k1Sign, secp256k1Verify, blake2AsU8a } from '@polkadot/util-crypto';
|
||||
import { assert, u8aConcat, u8aEq, u8aToHex, u8aToU8a } from '@polkadot/util';
|
||||
import { blake2AsU8a, ethereumEncode, keccakAsU8a, keyExtractPath, keyFromPath, naclKeypairFromSeed as naclFromSeed, naclSign, schnorrkelKeypairFromSeed as schnorrkelFromSeed, schnorrkelSign, schnorrkelVrfSign, schnorrkelVrfVerify, secp256k1Compress, secp256k1Expand, secp256k1KeypairFromSeed as secp256k1FromSeed, secp256k1Sign, signatureVerify } from '@polkadot/util-crypto';
|
||||
|
||||
import decode from './decode';
|
||||
import encode from './encode';
|
||||
import toJson from './toJson';
|
||||
import { decodePair } from './decode';
|
||||
import { encodePair } from './encode';
|
||||
import { pairToJson } from './toJson';
|
||||
|
||||
interface Setup {
|
||||
toSS58: (publicKey: Uint8Array) => string;
|
||||
@@ -19,70 +19,46 @@ interface Setup {
|
||||
}
|
||||
|
||||
const SIG_TYPE_NONE = new Uint8Array();
|
||||
const SIG_TYPE_ED25519 = new Uint8Array([0]);
|
||||
const SIG_TYPE_SR25519 = new Uint8Array([1]);
|
||||
const SIG_TYPE_ECDSA = new Uint8Array([2]);
|
||||
|
||||
function isEmpty (u8a: Uint8Array): boolean {
|
||||
return u8a.reduce((count, u8): number => count + u8, 0) === 0;
|
||||
}
|
||||
const TYPE_FROM_SEED = {
|
||||
ecdsa: secp256k1FromSeed,
|
||||
ed25519: naclFromSeed,
|
||||
ethereum: secp256k1FromSeed,
|
||||
sr25519: schnorrkelFromSeed
|
||||
};
|
||||
|
||||
function fromSeed (type: KeypairType, seed: Uint8Array): Keypair {
|
||||
return {
|
||||
ecdsa: (): Keypair => secp256k1FromSeed(seed),
|
||||
ed25519: (): Keypair => naclFromSeed(seed),
|
||||
sr25519: (): Keypair => schnorrkelFromSeed(seed)
|
||||
}[type]();
|
||||
}
|
||||
const TYPE_PREFIX = {
|
||||
ecdsa: new Uint8Array([2]),
|
||||
ed25519: new Uint8Array([0]),
|
||||
ethereum: new Uint8Array([2]),
|
||||
sr25519: new Uint8Array([1])
|
||||
};
|
||||
|
||||
function multiSignaturePrefix (type: KeypairType): Uint8Array {
|
||||
return {
|
||||
ecdsa: SIG_TYPE_ECDSA,
|
||||
ed25519: SIG_TYPE_ED25519,
|
||||
sr25519: SIG_TYPE_SR25519
|
||||
}[type];
|
||||
}
|
||||
const TYPE_SIGNATURE = {
|
||||
ecdsa: (m: Uint8Array, p: Partial<Keypair>) => secp256k1Sign(m, p, 'blake2'),
|
||||
ed25519: naclSign,
|
||||
ethereum: (m: Uint8Array, p: Partial<Keypair>) => secp256k1Sign(m, p, 'keccak'),
|
||||
sr25519: schnorrkelSign
|
||||
};
|
||||
|
||||
function sign (type: KeypairType, message: Uint8Array, pair: Partial<Keypair>, { withType = false }: SignOptions = {}): Uint8Array {
|
||||
const signature = {
|
||||
ecdsa: (): Uint8Array => secp256k1Sign(message, pair),
|
||||
ed25519: (): Uint8Array => naclSign(message, pair),
|
||||
sr25519: (): Uint8Array => schnorrkelSign(message, pair)
|
||||
}[type]();
|
||||
|
||||
return u8aConcat(
|
||||
// for multi-signatures, i.e. with indicator, append the signature type as per
|
||||
// the MultiSignature enum
|
||||
withType
|
||||
? multiSignaturePrefix(type)
|
||||
: SIG_TYPE_NONE,
|
||||
signature
|
||||
);
|
||||
}
|
||||
|
||||
function verify (type: KeypairType, message: Uint8Array, signature: Uint8Array, publicKey: Uint8Array): boolean {
|
||||
return {
|
||||
ecdsa: (): boolean => secp256k1Verify(message, signature, blake2AsU8a(publicKey, 256)),
|
||||
ed25519: (): boolean => naclVerify(message, signature, publicKey),
|
||||
sr25519: (): boolean => schnorrkelVerify(message, signature, publicKey)
|
||||
}[type]();
|
||||
}
|
||||
|
||||
function getAddress (type: KeypairType, publicKey: Uint8Array): Uint8Array {
|
||||
if (type === 'ecdsa' && publicKey.length > 32) {
|
||||
return blake2AsU8a(publicKey, 256);
|
||||
} else {
|
||||
return publicKey;
|
||||
}
|
||||
}
|
||||
const TYPE_ADDRESS = {
|
||||
ecdsa: (p: Uint8Array) => p.length > 32 ? blake2AsU8a(p) : p,
|
||||
ed25519: (p: Uint8Array) => p,
|
||||
ethereum: (p: Uint8Array) => p.length === 20 ? p : keccakAsU8a(secp256k1Expand(p)),
|
||||
sr25519: (p: Uint8Array) => p
|
||||
};
|
||||
|
||||
// Not 100% correct, since it can be a Uint8Array, but an invalid one - just say "undefined" is anything non-valid
|
||||
function isLocked (secretKey?: Uint8Array): secretKey is undefined {
|
||||
return !secretKey || secretKey.length === 0 || isEmpty(secretKey);
|
||||
return !secretKey || secretKey.length === 0 || secretKey.every((b) => b === 0);
|
||||
}
|
||||
|
||||
function vrfHash (proof: Uint8Array, context?: string | Uint8Array, extra?: string | Uint8Array): Uint8Array {
|
||||
return blake2AsU8a(u8aConcat(context || '', extra || '', proof));
|
||||
}
|
||||
|
||||
/**
|
||||
* @name pair
|
||||
* @name createPair
|
||||
* @summary Creates a keyring pair object
|
||||
* @description Creates a keyring pair object with provided account public key, metadata, and encoded arguments.
|
||||
* The keyring pair stores the account state including the encoded address and associated metadata.
|
||||
@@ -112,10 +88,48 @@ function isLocked (secretKey?: Uint8Array): secretKey is undefined {
|
||||
* an `encoded` property that is assigned with the encoded public key in hex format, and an `encoding`
|
||||
* property that indicates whether the public key value of the `encoded` property is encoded or not.
|
||||
*/
|
||||
export default function createPair ({ toSS58, type }: Setup, { publicKey, secretKey }: PairInfo, meta: KeyringPair$Meta = {}, encoded: Uint8Array | null = null): KeyringPair {
|
||||
export function createPair ({ toSS58, type }: Setup, { 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);
|
||||
|
||||
if (decoded.secretKey.length === 64) {
|
||||
publicKey = decoded.publicKey;
|
||||
secretKey = decoded.secretKey;
|
||||
} else {
|
||||
const pair = TYPE_FROM_SEED[type](decoded.secretKey);
|
||||
|
||||
publicKey = pair.publicKey;
|
||||
secretKey = pair.secretKey;
|
||||
}
|
||||
};
|
||||
|
||||
const recode = (passphrase?: string): Uint8Array => {
|
||||
isLocked(secretKey) && encoded && decodePkcs8(passphrase, encoded);
|
||||
|
||||
encoded = encodePair({ publicKey, secretKey }, passphrase); // re-encode, latest version
|
||||
encTypes = undefined; // swap to defaults, latest version follows
|
||||
|
||||
return encoded;
|
||||
};
|
||||
|
||||
const encodeAddress = (): string => {
|
||||
const raw = TYPE_ADDRESS[type](publicKey);
|
||||
|
||||
return type === 'ethereum'
|
||||
? ethereumEncode(raw)
|
||||
: toSS58(raw);
|
||||
};
|
||||
|
||||
return {
|
||||
get address (): string {
|
||||
return toSS58(getAddress(type, publicKey));
|
||||
return encodeAddress();
|
||||
},
|
||||
get addressRaw (): Uint8Array {
|
||||
const raw = TYPE_ADDRESS[type](publicKey);
|
||||
|
||||
return type === 'ethereum'
|
||||
? raw.slice(-20)
|
||||
: raw;
|
||||
},
|
||||
get isLocked (): boolean {
|
||||
return isLocked(secretKey);
|
||||
@@ -130,20 +144,9 @@ export default function createPair ({ toSS58, type }: Setup, { publicKey, secret
|
||||
return type;
|
||||
},
|
||||
// eslint-disable-next-line sort-keys
|
||||
decodePkcs8: (passphrase?: string, _encoded?: Uint8Array | null): void => {
|
||||
const decoded = decode(passphrase, _encoded || encoded);
|
||||
|
||||
if (decoded.secretKey.length === 64) {
|
||||
publicKey = decoded.publicKey;
|
||||
secretKey = decoded.secretKey;
|
||||
} else {
|
||||
const pair = fromSeed(type, decoded.secretKey);
|
||||
|
||||
publicKey = pair.publicKey;
|
||||
secretKey = pair.secretKey;
|
||||
}
|
||||
},
|
||||
decodePkcs8,
|
||||
derive: (suri: string, meta?: KeyringPair$Meta): KeyringPair => {
|
||||
assert(type !== 'ethereum', 'Unable to derive on this keypair');
|
||||
assert(!isLocked(secretKey), 'Cannot derive on a locked keypair');
|
||||
|
||||
const { path } = keyExtractPath(suri);
|
||||
@@ -151,22 +154,64 @@ export default function createPair ({ toSS58, type }: Setup, { publicKey, secret
|
||||
|
||||
return createPair({ toSS58, type }, derived, meta, null);
|
||||
},
|
||||
encodePkcs8: (passphrase?: string): Uint8Array =>
|
||||
encode({ publicKey, secretKey }, passphrase),
|
||||
encodePkcs8: (passphrase?: string): Uint8Array => {
|
||||
return recode(passphrase);
|
||||
},
|
||||
lock: (): void => {
|
||||
secretKey = new Uint8Array(0);
|
||||
secretKey = new Uint8Array();
|
||||
},
|
||||
setMeta: (additional: KeyringPair$Meta): void => {
|
||||
meta = { ...meta, ...additional };
|
||||
},
|
||||
sign: (message: Uint8Array, options?: SignOptions): Uint8Array => {
|
||||
sign: (message: string | Uint8Array, options: SignOptions = {}): Uint8Array => {
|
||||
assert(!isLocked(secretKey), 'Cannot sign with a locked key pair');
|
||||
|
||||
return sign(type, message, { publicKey, secretKey }, options);
|
||||
return u8aConcat(
|
||||
options.withType
|
||||
? TYPE_PREFIX[type]
|
||||
: SIG_TYPE_NONE,
|
||||
TYPE_SIGNATURE[type](u8aToU8a(message), { publicKey, secretKey })
|
||||
);
|
||||
},
|
||||
toJson: (passphrase?: string): KeyringPair$Json =>
|
||||
toJson(type, { address: toSS58(getAddress(type, publicKey)), meta }, encode({ publicKey, secretKey }, passphrase), !!passphrase),
|
||||
verify: (message: Uint8Array, signature: Uint8Array): boolean =>
|
||||
verify(type, message, signature, publicKey)
|
||||
toJson: (passphrase?: string): KeyringPair$Json => {
|
||||
// NOTE: For ecdsa and ethereum, the publicKey cannot be extracted from the address. For these
|
||||
// pass the hex-encoded publicKey through to the address portion of the JSON (before decoding)
|
||||
// unless the publicKey is already an address
|
||||
const address = ['ecdsa', 'ethereum'].includes(type)
|
||||
? publicKey.length === 20
|
||||
? u8aToHex(publicKey)
|
||||
: u8aToHex(secp256k1Compress(publicKey))
|
||||
: encodeAddress();
|
||||
|
||||
return pairToJson(type, { address, meta }, recode(passphrase), !!passphrase);
|
||||
},
|
||||
unlock: (passphrase?: string): void => {
|
||||
return decodePkcs8(passphrase);
|
||||
},
|
||||
verify: (message: string | Uint8Array, signature: Uint8Array, _signerPublic: string | Uint8Array): boolean => {
|
||||
return signatureVerify(message, signature, TYPE_ADDRESS[type](u8aToU8a(_signerPublic))).isValid;
|
||||
},
|
||||
vrfSign: (message: string | Uint8Array, context?: string | Uint8Array, extra?: string | Uint8Array): Uint8Array => {
|
||||
assert(!isLocked(secretKey), 'Cannot sign with a locked key pair');
|
||||
|
||||
if (type === 'sr25519') {
|
||||
return schnorrkelVrfSign(message, { secretKey }, context, extra);
|
||||
}
|
||||
|
||||
const proof = TYPE_SIGNATURE[type](u8aToU8a(message), { publicKey, secretKey });
|
||||
|
||||
return u8aConcat(vrfHash(proof, context, extra), proof);
|
||||
},
|
||||
vrfVerify: (message: string | Uint8Array, vrfResult: Uint8Array, _signerPublic: Uint8Array | string, context?: string | Uint8Array, extra?: string | Uint8Array): boolean => {
|
||||
const signerPublic = TYPE_ADDRESS[type](u8aToU8a(_signerPublic));
|
||||
|
||||
if (type === 'sr25519') {
|
||||
return schnorrkelVrfVerify(message, vrfResult, publicKey, context, extra);
|
||||
}
|
||||
|
||||
const result = signatureVerify(message, u8aConcat(TYPE_PREFIX[type], vrfResult.subarray(32)), signerPublic);
|
||||
|
||||
return result.isValid && u8aEq(vrfResult.subarray(0, 32), vrfHash(vrfResult.subarray(32), context, extra));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
// Copyright 2017-2020 @polkadot/keyring authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
// Copyright 2017-2021 @polkadot/keyring authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { KeyringPair, KeyringPair$Json, KeyringPair$Meta } from '../types';
|
||||
import type { KeyringPair, KeyringPair$Json, KeyringPair$Meta } from '../types';
|
||||
|
||||
import { encodeAddress } from '@polkadot/util-crypto';
|
||||
|
||||
@@ -23,9 +22,10 @@ const json: KeyringPair$Json = {
|
||||
meta
|
||||
};
|
||||
|
||||
export default function everybody (): KeyringPair {
|
||||
export function nobody (): KeyringPair {
|
||||
const pair: KeyringPair = {
|
||||
address,
|
||||
addressRaw: publicKey,
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
decodePkcs8: (passphrase?: string, encoded?: Uint8Array): void =>
|
||||
undefined,
|
||||
@@ -52,7 +52,16 @@ export default function everybody (): KeyringPair {
|
||||
json,
|
||||
type: 'ed25519',
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
unlock: (passphrase?: string): void =>
|
||||
undefined,
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
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 =>
|
||||
new Uint8Array(96),
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
vrfVerify: (message: Uint8Array, vrfResult: Uint8Array, context?: string | Uint8Array, extra?: string | Uint8Array): boolean =>
|
||||
false
|
||||
};
|
||||
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
// Copyright 2017-2020 @polkadot/keyring authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
// Copyright 2017-2021 @polkadot/keyring authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import testingPairs from '../testingPairs';
|
||||
import { createTestPairs } from '../testingPairs';
|
||||
|
||||
const keyring = testingPairs({ type: 'ed25519' }, false);
|
||||
const keyring = createTestPairs({ type: 'ed25519' }, false);
|
||||
|
||||
describe('toJson', (): void => {
|
||||
it('creates an unencoded output with no passphrase', (): void => {
|
||||
@@ -12,11 +11,11 @@ describe('toJson', (): void => {
|
||||
keyring.alice.toJson()
|
||||
).toMatchObject({
|
||||
address: '5GoKvZWG5ZPYL1WUovuHW3zJBWBP5eT8CbqjdRY4Q6iMaQua',
|
||||
encoded: '0x3053020101300506032b657004220420416c696365202020202020202020202020202020202020202020202020202020d172a74cda4c865912c32ba0a80a57ae69abae410e5ccb59dee84e2f4432db4fa123032100d172a74cda4c865912c32ba0a80a57ae69abae410e5ccb59dee84e2f4432db4f',
|
||||
encoded: 'MFMCAQEwBQYDK2VwBCIEIEFsaWNlICAgICAgICAgICAgICAgICAgICAgICAgICAg0XKnTNpMhlkSwyugqApXrmmrrkEOXMtZ3uhOL0Qy20+hIwMhANFyp0zaTIZZEsMroKgKV65pq65BDlzLWd7oTi9EMttP',
|
||||
encoding: {
|
||||
content: ['pkcs8', 'ed25519'],
|
||||
type: 'none',
|
||||
version: '2'
|
||||
type: ['none'],
|
||||
version: '3'
|
||||
},
|
||||
meta: {
|
||||
isTesting: true,
|
||||
@@ -28,13 +27,13 @@ describe('toJson', (): void => {
|
||||
it('creates an encoded output with passphrase', (): void => {
|
||||
const json = keyring.alice.toJson('testing');
|
||||
|
||||
expect(json.encoded).toHaveLength(316);
|
||||
expect(json.encoded).toHaveLength(268);
|
||||
expect(json).toMatchObject({
|
||||
address: '5GoKvZWG5ZPYL1WUovuHW3zJBWBP5eT8CbqjdRY4Q6iMaQua',
|
||||
encoding: {
|
||||
content: ['pkcs8', 'ed25519'],
|
||||
type: 'xsalsa20-poly1305',
|
||||
version: '2'
|
||||
type: ['scrypt', 'xsalsa20-poly1305'],
|
||||
version: '3'
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,28 +1,20 @@
|
||||
// Copyright 2017-2020 @polkadot/keyring authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
// Copyright 2017-2021 @polkadot/keyring authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { KeypairType } from '@polkadot/util-crypto/types';
|
||||
import { KeyringPair$Json, KeyringPair$Meta } from '../types';
|
||||
import type { KeypairType } from '@polkadot/util-crypto/types';
|
||||
import type { KeyringPair$Json, KeyringPair$Meta } from '../types';
|
||||
|
||||
import { u8aToHex } from '@polkadot/util';
|
||||
import { jsonEncryptFormat } from '@polkadot/util-crypto';
|
||||
|
||||
interface PairStateJson {
|
||||
address: string;
|
||||
meta: KeyringPair$Meta;
|
||||
}
|
||||
|
||||
export default function toJson (type: KeypairType, { address, meta }: PairStateJson, encoded: Uint8Array, isEncrypted: boolean): KeyringPair$Json {
|
||||
export function pairToJson (type: KeypairType, { address, meta }: PairStateJson, encoded: Uint8Array, isEncrypted: boolean): KeyringPair$Json {
|
||||
return {
|
||||
...jsonEncryptFormat(encoded, ['pkcs8', type], isEncrypted),
|
||||
address,
|
||||
encoded: u8aToHex(encoded),
|
||||
encoding: {
|
||||
content: ['pkcs8', type],
|
||||
type: isEncrypted
|
||||
? 'xsalsa20-poly1305'
|
||||
: 'none',
|
||||
version: '2'
|
||||
},
|
||||
meta
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
// Copyright 2017-2020 @polkadot/keyring authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
// Copyright 2017-2021 @polkadot/keyring authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
export interface PairInfo {
|
||||
publicKey: Uint8Array;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user