Compare commits
1448 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1c35746d0b | |||
| b7a0cd81ec | |||
| ded45f15af | |||
| d2298757d7 | |||
| b17b3dcd44 | |||
| 9b97d22a4b | |||
| 04b311b75f | |||
| 6f2aeb3f48 | |||
| 02b812d0a3 | |||
| 8d9d790685 | |||
| a2d1aa626a | |||
| 5e1b5dce61 | |||
| ee8d4ab9e7 | |||
| d5272057b8 | |||
| 593a6efbe7 | |||
| 784501f357 | |||
| 07b75d48d5 | |||
| 786dcbd55f | |||
| 26efbc975e | |||
| 7beaf57376 | |||
| 8c00f7d26d | |||
| d1bd782fb2 | |||
| 9ca55bd046 | |||
| a4d6a8cef0 | |||
| 98ec346d74 | |||
| 80a2c52ac6 | |||
| 27d7f043e7 | |||
| 806476d4b4 | |||
| 5a0db2aea4 | |||
| f8733f59c5 | |||
| 56f351538b | |||
| 36bcfc132d | |||
| 6e245208ac | |||
| a3eb274a3b | |||
| 0ddc6c4bc8 | |||
| eccd6e16e2 | |||
| 3ccec3857e | |||
| 5fd68ae909 | |||
| fb04a85b5a | |||
| 825e190c37 | |||
| 7e60dea257 | |||
| 014e5486a8 | |||
| 33c8b2e963 | |||
| a727d96fe7 | |||
| d3325c176f | |||
| de47061558 | |||
| f1947d1370 | |||
| fba694f61a | |||
| 1c1d02f15a | |||
| cb910f41bd | |||
| e6d3083eea | |||
| b97f8c1145 | |||
| 0c678553af | |||
| 96e740ec22 | |||
| 8affba8be4 | |||
| 81a0729f52 | |||
| e85c7b6f5f | |||
| 33838eae8c | |||
| 1c2e3c754e | |||
| a9a1eecfff | |||
| 95e3971b9c | |||
| 21cf6c974f | |||
| f536a204ba | |||
| 114d92f93f | |||
| 6dc8148372 | |||
| cd3d4ffc9f | |||
| d6c27c0985 | |||
| 9d8280986d | |||
| 8aa8f07cb8 | |||
| 98c03ffa56 | |||
| 0a3a31dedc | |||
| 79ae9b69ef | |||
| 549b58311d | |||
| 279b494a60 | |||
| 3be0a6cf65 | |||
| 9b8add1daa | |||
| 2193378d42 | |||
| c57263e91b | |||
| 74d8d82b74 | |||
| 397e8223bc | |||
| 685f26792f | |||
| 109659152d | |||
| 73a75f7aef | |||
| 06956efa3f | |||
| 604657c1dc | |||
| f130ff73ad | |||
| ddaabdc856 | |||
| 65de9d146d | |||
| ec3aa7d8eb | |||
| 805e1b8759 | |||
| 53db649e84 | |||
| f76092e8e7 | |||
| c75fda0eb1 | |||
| 9dfbc8c9c8 | |||
| 0171791188 | |||
| f6a9d0b843 | |||
| 9654cbf87e | |||
| fc8ac8956d | |||
| 359a4e5bbd | |||
| 42d2ecca3c | |||
| 3c750f61e5 | |||
| a8e7c3ca49 | |||
| 4f39630861 | |||
| 63714092df | |||
| cd89f4866a | |||
| a94c4c0895 | |||
| 56ef23b7d1 | |||
| 63b0658c65 | |||
| 6b161700f6 | |||
| 339244a1fb | |||
| 6aa984621e | |||
| ba0b5e2120 | |||
| b48e2af2c4 | |||
| 03736cc209 | |||
| dcfe5f7c5b | |||
| cd89e26b74 | |||
| 4f9df2a8b1 | |||
| f6a4fc3b6f | |||
| 899db660ce | |||
| ec0ac56b8a | |||
| 8981ffdcf9 | |||
| df25c01771 | |||
| a11dead84a | |||
| 5aa999643f | |||
| 96b54db060 | |||
| 5bd4295164 | |||
| b07627d57e | |||
| c4667a6792 | |||
| 2e2d258e53 | |||
| 843c74db63 | |||
| 142443b87e | |||
| ec4765c9c6 | |||
| 77a56600f0 | |||
| 90027dc525 | |||
| 6a39e19f2e | |||
| 48140647b7 | |||
| 7d1cb6ca19 | |||
| d1f7066eb5 | |||
| 2789951d9a | |||
| faab815c79 | |||
| a205fecece | |||
| f3116993d8 | |||
| 4fae075dae | |||
| da46955817 | |||
| f2fc837811 | |||
| e7929d6f6b | |||
| e8f99cfdbe | |||
| b4ccd16d8b | |||
| f7974c5db8 | |||
| 90a925ee62 | |||
| 4890c528bc | |||
| d96de448d0 | |||
| 74cd6f0198 | |||
| e71ae7198f | |||
| 273f612d46 | |||
| 2e8d318587 | |||
| 17bd44f840 | |||
| c1076f81a6 | |||
| 26507ee7d3 | |||
| 4677312cad | |||
| 07eddc8187 | |||
| b9a9a407e9 | |||
| 3c482eff6e | |||
| 2880049196 | |||
| 8d2e8b3d26 | |||
| 33bf344d63 | |||
| 0efa78c4a8 | |||
| 32ee16bf0b | |||
| a8f70fe4a2 | |||
| f6fe5d41ea | |||
| 2a87533b12 | |||
| 499fd8a91d | |||
| e336b9948e | |||
| 1cf2b10e31 | |||
| b3cd42de58 | |||
| f16498915a | |||
| d364510400 | |||
| 96f9e39e1d | |||
| e083bfcfe4 | |||
| 22c59be82c | |||
| f17e7378f7 | |||
| 1bb455675e | |||
| 73076a2b26 | |||
| 1e1bf25514 | |||
| 4df29535dc | |||
| 6f08b60789 | |||
| 9ec0f4a88e | |||
| 6b4b7f5cdd | |||
| 581cba9365 | |||
| c7d99bb951 | |||
| ee938e6a0c | |||
| 00501f7073 | |||
| db80666271 | |||
| 3f9fdac9ec | |||
| 3257315676 | |||
| 2f874a66de | |||
| defbcea227 | |||
| 58f79a972c | |||
| de531d41ed | |||
| 15df2cfbe5 | |||
| 987401c320 | |||
| 81cbc48521 | |||
| 8935eb125b | |||
| ca2aad778b | |||
| 584c902f93 | |||
| 2b15d53f45 | |||
| ce98ce72d8 | |||
| 5a8bad4503 | |||
| 0e37084f34 | |||
| 8af83ceac6 | |||
| ee6b6ecc7e | |||
| 27a9557c7b | |||
| c143fef912 | |||
| e7e48f0e53 | |||
| c62b344349 | |||
| 441fbf8255 | |||
| b5cde68e62 | |||
| c3d38fb904 | |||
| 2922306e25 | |||
| 204b2e1101 | |||
| c022486e63 | |||
| 2a7a681b7d | |||
| a50b4ad211 | |||
| ca613ad3aa | |||
| f518c8377b | |||
| e1a30ea01a | |||
| 9f5a0a7ca6 | |||
| c7de97d6dd | |||
| 85a7ec9f02 | |||
| 8d105cf4dd | |||
| 6131d000e6 | |||
| 972a220209 | |||
| b7cf7e06d2 | |||
| 2df42e222c | |||
| 83a0a6455f | |||
| f53e5c42c3 | |||
| b537a7c2c7 | |||
| 9fb8b1d7c0 | |||
| a1482a2887 | |||
| b57df35f8c | |||
| 7f0a02f6ec | |||
| cfc86ba9f5 | |||
| 9c68de64a0 | |||
| 2fdd09deee | |||
| 5f9a514bc7 | |||
| 0812a0f599 | |||
| 769a26fdeb | |||
| 2e7ddcb195 | |||
| 84d893198b | |||
| 7741a3fea1 | |||
| 2f6617daac | |||
| 9e483da802 | |||
| 017d536d35 | |||
| d530e492ec | |||
| 6c67cff235 | |||
| 66f04d17b7 | |||
| 492155d04a | |||
| 069226125b | |||
| 1ce536c2fa | |||
| 2fbb901deb | |||
| 3c3ec9c831 | |||
| 6a34a99fee | |||
| ec75a06c9d | |||
| 2fbe7bb350 | |||
| ee67f3d0f0 | |||
| 188650ea05 | |||
| decae2b54d | |||
| 8104761914 | |||
| 8503def37f | |||
| 48023eab41 | |||
| b050ae72de | |||
| 377c9be790 | |||
| 5d7fd66cfc | |||
| 5128aef193 | |||
| eb444f73ce | |||
| 6a327b0bd6 | |||
| 8a38c61065 | |||
| f0a888d59c | |||
| d108919cf6 | |||
| f1b9cf4d68 | |||
| 392e7b5268 | |||
| 776a9d508a | |||
| 2f624d4f10 | |||
| 3c9faff4ec | |||
| 026d52a218 | |||
| f8b70097d3 | |||
| 0d3df4b58d | |||
| 5241047f45 | |||
| 2651784e8b | |||
| 2cd2b1ccd4 | |||
| af4e8241e7 | |||
| 92350daca8 | |||
| b429c64168 | |||
| f88622ac08 | |||
| 0a5a2c6747 | |||
| 824bd636f9 | |||
| cf6411ac08 | |||
| 6428133122 | |||
| 3c69f9c2f9 | |||
| c1e4b87744 | |||
| 5d454f2efc | |||
| 22246d0d5d | |||
| 29593ef3c9 | |||
| ffac0a1f92 | |||
| 12f21185e3 | |||
| 8004d54d5e | |||
| b6febc51a3 | |||
| 5a0255fd01 | |||
| 5b86646bd8 | |||
| 85ab3d5c80 | |||
| dffe171b7f | |||
| 067a501d98 | |||
| fa9908413b | |||
| 6d3b198f00 | |||
| d4920b82f0 | |||
| 24099d159b | |||
| 463033aa64 | |||
| c1ba56ab1c | |||
| 8dfe8f4678 | |||
| c2a38c9b53 | |||
| 33e7ce53fb | |||
| bdf18e30fb | |||
| e0b32e1cc9 | |||
| 4ff69b77a9 | |||
| 5f095d703d | |||
| ff4dbd09d0 | |||
| 404d2d9857 | |||
| b5f2ecd79e | |||
| 38b9e14851 | |||
| 6ead19bd97 | |||
| c169971287 | |||
| 7b3cbdcd44 | |||
| d6369ea784 | |||
| 43dfb31eb2 | |||
| ff4350ec90 | |||
| c8516071fc | |||
| e49c8588c6 | |||
| ee5b55fab6 | |||
| 11f3ce9224 | |||
| 0f43521497 | |||
| a1a1970dc1 | |||
| 89ea3039d5 | |||
| efa1e0353e | |||
| 96e2712039 | |||
| 84ad777c42 | |||
| f569ba1c17 | |||
| 54ff3ee987 | |||
| 1f2a2c37ab | |||
| b0d5bacafd | |||
| 8b65e44767 | |||
| a2445183bf | |||
| 230d8aa170 | |||
| 035535058e | |||
| df9aec1554 | |||
| 740846befc | |||
| 074e27291b | |||
| b1c3264f69 | |||
| 905318ad27 | |||
| 7065f870eb | |||
| ee14dfc75e | |||
| a93de8b4c5 | |||
| 534c8f49d1 | |||
| 3da3f66ea3 | |||
| 32bfceacb5 | |||
| 7a606e11f4 | |||
| d3d5346cfe | |||
| 8fe549daa5 | |||
| f15be9456a | |||
| 567d3c8173 | |||
| ce81f0c841 | |||
| 9652060c57 | |||
| 9c0317ab28 | |||
| d13116bda0 | |||
| 77f8eadd0e | |||
| 1e2de5067a | |||
| c43344d489 | |||
| 2711e6f679 | |||
| c85f7d2565 | |||
| e8506f6d53 | |||
| 6d5ff1146b | |||
| 1f226682f4 | |||
| f17d2cec0d | |||
| 089d5e6dbb | |||
| fca384fba2 | |||
| 3ae803a343 | |||
| 99224310e9 | |||
| d2e59f12f6 | |||
| 99a321c54d | |||
| 8fd832e217 | |||
| 09c4df8448 | |||
| 09b15ae020 | |||
| 585cf55026 | |||
| a0418daaea | |||
| f0c0ddb1c2 | |||
| b006e1820f | |||
| 50b755cfde | |||
| a002ddda8d | |||
| 49d909815d | |||
| 990f7d64dd | |||
| d422741be4 | |||
| 389ccffb63 | |||
| 9a76db479b | |||
| 55cd1a8b91 | |||
| cbee6153bd | |||
| 232032baf4 | |||
| 17e1c5f970 | |||
| 85ab634d9c | |||
| 3d245f745f | |||
| c8cee9b56e | |||
| aa64256ecd | |||
| 853d537e51 | |||
| 2993e85c7a | |||
| a8041eec7b | |||
| e849dc13fd | |||
| d13c8bde57 | |||
| aae4725005 | |||
| 42d08195f7 | |||
| 3409e86a63 | |||
| a255c6733b | |||
| c3a09a0860 | |||
| 4652ac882f | |||
| 1740cead37 | |||
| cc6fdfa110 | |||
| 9e40763f7f | |||
| 6bcc781a67 | |||
| 15bc4ae272 | |||
| 3c8dd7a72b | |||
| 8ef9560843 | |||
| c41e377c69 | |||
| dbe2790ba0 | |||
| 93214cabbb | |||
| ce47e91186 | |||
| a4f415cb45 | |||
| e911e9e7ee | |||
| dd887bd89b | |||
| e2bf9daf52 | |||
| aa7a6114be | |||
| a2a887627d | |||
| 2b283090fa | |||
| c097567f78 | |||
| 93ec0f1984 | |||
| edf5050ba6 | |||
| 3317804a80 | |||
| 0951c83ace | |||
| 9754cd8a06 | |||
| 6d3570913b | |||
| 8ef84df168 | |||
| 28f4ddb698 | |||
| c52cb4f963 | |||
| 59a7034121 | |||
| 9ec1d2dc36 | |||
| 022951ed0c | |||
| 1538eb0f6f | |||
| 82ea3add6a | |||
| 53b653d9cf | |||
| e504def9e4 | |||
| a97004b6e0 | |||
| 61aacd16cd | |||
| 55bf5ce5b0 | |||
| e9789681cc | |||
| d33d9d4409 | |||
| 852e1ace7e | |||
| cc3cfbfdc1 | |||
| 55f3fc278f | |||
| 3ea4e0bf7c | |||
| 4681c0b275 | |||
| 9478472070 | |||
| 950919b36c | |||
| 5ee9c24b92 | |||
| de67055e4f | |||
| 52e27152f6 | |||
| 0c24f39300 | |||
| 204dba1a66 | |||
| 461a7a2df9 | |||
| f12f6b29cd | |||
| 5385685b3f | |||
| 691ac6d5ea | |||
| ed3535d510 | |||
| c6519ffdff | |||
| 69e4b1ae1c | |||
| d0ba4056d6 | |||
| c81a5ac002 | |||
| 93a8e2a9bf | |||
| 6c83b88247 | |||
| 83d5cc9bf4 | |||
| 6a54a6653c | |||
| d11cf4c9a3 | |||
| f9108ea400 | |||
| 9a5ce73dfd | |||
| af51ab3f71 | |||
| 3714ee76ff | |||
| 0e37c572f0 | |||
| b1b276e8ba | |||
| 9966d0fa5f | |||
| c5c6d3cc27 | |||
| 0f777204b8 | |||
| cbda950259 | |||
| d57e8efff2 | |||
| c4c4355a54 | |||
| aaef36a5d7 | |||
| 062f4911e1 | |||
| 59e4567342 | |||
| de2b106568 | |||
| ae79dc4ec6 | |||
| d49ba6e025 | |||
| 60ab58998d | |||
| 75bb9140b0 | |||
| b63f5409db | |||
| de6c1ba1f0 | |||
| e705b76b36 | |||
| 05259410b2 | |||
| 6be7c094be | |||
| 2db3297d1e | |||
| a1295a316b | |||
| fc7e4be175 | |||
| 3dd3692e8d | |||
| 4bb6f21faa | |||
| 62c03b3136 | |||
| e9d10caaf8 | |||
| 432f6a006f | |||
| 4f05169361 | |||
| be88a9b277 | |||
| fce2c704af | |||
| d8a95d3810 | |||
| 191aa149df | |||
| f4df1a9168 | |||
| 62316244d9 | |||
| a26c6d7a29 | |||
| 8fda246a3c | |||
| 5620fd7009 | |||
| 122612fa03 | |||
| 53db18df2c | |||
| e00910bcb8 | |||
| 23a669c4de | |||
| 0af9b3c6c8 | |||
| 88d2592a4e | |||
| 85c22525cf | |||
| 7e27413a12 | |||
| 50acec575f | |||
| 2d60a9da3f | |||
| 795efb9f0b | |||
| ffb9ab9019 | |||
| 1a195d151d | |||
| 2eeb8bb590 | |||
| 2565716816 | |||
| f954ce5c97 | |||
| baebbe4e4d | |||
| 695d34735c | |||
| 314d7a7526 | |||
| 2dd3e031bd | |||
| 860ec74b59 | |||
| bff806e5f5 | |||
| f8b9bb7e78 | |||
| 913095ee60 | |||
| d44b88842e | |||
| a67092ad17 | |||
| a86c1a6a60 | |||
| 7ad2865250 | |||
| 49440bf60e | |||
| b3b43b56be | |||
| 4a23729a6a | |||
| 5711bbd0c1 | |||
| 1b1f0293ec | |||
| 0b29e28e3f | |||
| f26f159bb0 | |||
| a8ddaddaf4 | |||
| 84741f2020 | |||
| cc65236085 | |||
| e18c541400 | |||
| c1e8ebd46a | |||
| 0b6eb17793 | |||
| 10696ae4dc | |||
| 9285aaf487 | |||
| 55bd7f8a61 | |||
| b66c4cf0bb | |||
| dd4f4c44c3 | |||
| c04993e49c | |||
| 464984a83c | |||
| 4696470b19 | |||
| 5dacf0c8f8 | |||
| cbafd37102 | |||
| e537359c73 | |||
| 2ed3e646be | |||
| c725ae4e2b | |||
| 5ab2c738df | |||
| cd70b0de75 | |||
| 6395303466 | |||
| 60264486fd | |||
| 6359b38a5d | |||
| 40ffb6b65d | |||
| 502a2d6a23 | |||
| 974cee1f22 | |||
| 00b5a46cbc | |||
| e97a068bf0 | |||
| 7ac3bb10cb | |||
| 20d51437b5 | |||
| 1965df05e7 | |||
| 615c65cb22 | |||
| c7147ebfb2 | |||
| a344cda916 | |||
| 15a6af49f0 | |||
| 97956afdf6 | |||
| bb263f8c5e | |||
| 82872ae02a | |||
| 432af5a204 | |||
| ce87df3026 | |||
| db407847e3 | |||
| 6db396e877 | |||
| 7b71775e08 | |||
| d8925fe234 | |||
| 02f5fa6816 | |||
| 5fbccc3406 | |||
| 5964f104c5 | |||
| ac8afe133f | |||
| 3aa9ad0197 | |||
| 7ccadffdba | |||
| 19736b1204 | |||
| 6e5f6bf0df | |||
| 0bfc1be1d5 | |||
| 67435e9cdf | |||
| a47899aa77 | |||
| aedacf6c65 | |||
| 44fa52a7a7 | |||
| f6e20c8201 | |||
| 1da6ee2058 | |||
| 109fb96fca | |||
| 557bfa7b34 | |||
| 4c9727b1ef | |||
| a0408b74dc | |||
| 8a1ed12f58 | |||
| c38c5c2f0d | |||
| 03300a859e | |||
| 2fe5401a38 | |||
| d8a44cd9c1 | |||
| a0b41db22d | |||
| 7d6d8669b0 | |||
| a1a2f37fce | |||
| 91341733c1 | |||
| 93cd8821c3 | |||
| b79ec60381 | |||
| 2c2dd54028 | |||
| 4306cec49c | |||
| 5781d3043f | |||
| d843407ba7 | |||
| 053e047cca | |||
| 516561dcf9 | |||
| 290dbc1a03 | |||
| c120196be0 | |||
| f2a395fe42 | |||
| 524863aae7 | |||
| 61ad336b18 | |||
| 867b745a38 | |||
| 78e54287da | |||
| 96c29b974b | |||
| eadd116ae4 | |||
| f1175280cf | |||
| cf79bdc098 | |||
| 34e2affef8 | |||
| 34a47a9449 | |||
| dff11df2bd | |||
| feb888a154 | |||
| 415fe4605c | |||
| 70e6539298 | |||
| fe76ba68a0 | |||
| 863580a6f2 | |||
| 4c558db08e | |||
| 9d5b582908 | |||
| c12b20f1d6 | |||
| edeb8369df | |||
| 22b2405aa2 | |||
| 63254ecffe | |||
| 407d280019 | |||
| 41e1009095 | |||
| 1fafc126fb | |||
| 9a51135d22 | |||
| 1b2790da80 | |||
| f8943eebce | |||
| d7b53cba40 | |||
| 89d2f0ac12 | |||
| 110b4d384e | |||
| cf71d655e2 | |||
| 141b9d396c | |||
| ff65d052b8 | |||
| 153e899e0e | |||
| 7e5c79848f | |||
| 92b4dbb250 | |||
| 6d79b6f600 | |||
| 4631c72c6b | |||
| 12aa5f1f4f | |||
| 825f25800a | |||
| d9b4d8fde6 | |||
| a98613d83c | |||
| 34de42fe7a | |||
| 766261f774 | |||
| 6e2eaf29e7 | |||
| c99309dd79 | |||
| 37c875d8ee | |||
| b2b0a1478b | |||
| c6b193eb4f | |||
| aa67e183a6 | |||
| b27fa51092 | |||
| d01b6a12d6 | |||
| a133457722 | |||
| ad995b1934 | |||
| a881740c20 | |||
| 90cc68435c | |||
| c3ce9e24e2 | |||
| bdda08c0b4 | |||
| 0e48ff5e9e | |||
| 68d6ece6c2 | |||
| e17ae9dce0 | |||
| 493f036687 | |||
| 1f4f312e8e | |||
| d829837275 | |||
| 36253e3f36 | |||
| 7743554bb8 | |||
| de05e32845 | |||
| 136f4a8473 | |||
| 57e2628928 | |||
| 879e324696 | |||
| 351552b863 | |||
| 847f3a0ecc | |||
| 58958a2449 | |||
| 3051d84e8d | |||
| 2d7003dfae | |||
| 92b9edf0da | |||
| a91c997aed | |||
| 5787653210 | |||
| adbeeb3e5f | |||
| 4899ccf4ef | |||
| 9e0bcc025f | |||
| 16d6444169 | |||
| 997faeb1e6 | |||
| 565e7768e3 | |||
| 730f03de30 | |||
| 2e366a094d | |||
| b134334ec7 | |||
| f95b9b7f4a | |||
| 11ed3b3e45 | |||
| 271a5fbab6 | |||
| 90a97b398e | |||
| fc2236c3c8 | |||
| a71e228a25 | |||
| da9c2e5a7c | |||
| e025564678 | |||
| cf6188d794 | |||
| dd7308d92f | |||
| 73ca14aae2 | |||
| 0fee189a89 | |||
| a0c6efafd2 | |||
| c3d3164533 | |||
| fa2e0a9010 | |||
| fcc5398aab | |||
| 9f1f765f73 | |||
| 6403d0055b | |||
| 7bbb10e52c | |||
| 1aad69a527 | |||
| 4ad02d5328 | |||
| 45b74008f1 | |||
| 2ddf9646ec | |||
| b258cd8733 | |||
| ed48a2ddd4 | |||
| 7a1a7c003e | |||
| ef36c29b91 | |||
| 4025fed882 | |||
| 9aaa74204b | |||
| 9d7a6b2aec | |||
| 4b13a5cf61 | |||
| c9489fb48e | |||
| 6c3653c128 | |||
| 02a4452eca | |||
| d47633faa8 | |||
| a3da077ce9 | |||
| 131952c036 | |||
| 8d2ef605ed | |||
| fbcc2907bb | |||
| c0bb5503cf | |||
| ef7beaa12f | |||
| 31568b544c | |||
| 2953837f25 | |||
| ee98820bb4 | |||
| ed76000dd0 | |||
| 0dfe1460e4 | |||
| e06087ad3f | |||
| 0f41dda013 | |||
| 51d66c3e0c | |||
| 0a6a015987 | |||
| efd8ba5978 | |||
| 0c7181a211 | |||
| f14b40a769 | |||
| d8f80434b4 | |||
| f47a111640 | |||
| ae5a9ccc50 | |||
| 40465665f0 | |||
| 8c437ac964 | |||
| f3b17ad2f8 | |||
| 9121078576 | |||
| c505a00fac | |||
| 09bad9c6b4 | |||
| 597f5e9545 | |||
| 54cb7be1e1 | |||
| 431c98e591 | |||
| 35f2e71202 | |||
| 0134030341 | |||
| 97c775bc68 | |||
| 62ba6b30ae | |||
| 24354275d3 | |||
| 76335e9adc | |||
| bab8eb746e | |||
| f298f5d4fa | |||
| 85b078a3e8 | |||
| 0115b02be3 | |||
| a4ffd135e7 | |||
| bbce67902b | |||
| e6930046c4 | |||
| 0c9402503a | |||
| 81e133b789 | |||
| 7be07c29c1 | |||
| 31bc439f65 | |||
| 6479480cf7 | |||
| 4af70ef255 | |||
| eba58f6451 | |||
| 35206655e0 | |||
| e14db00fc2 | |||
| 2f98912778 | |||
| 72b92784cc | |||
| 38b95c2673 | |||
| f0f9899f82 | |||
| 09c46e3403 | |||
| 9fbab5aaad | |||
| 2032b3bdae | |||
| 8f57919571 | |||
| 3748ab77a1 | |||
| 3cdca0ad8d | |||
| 9cbb3dfa0e | |||
| 4071d30f3c | |||
| 4c13d91bfb | |||
| 8355e6ce5e | |||
| dd33052f0e | |||
| a76a51e823 | |||
| 4caa9390cf | |||
| b31d3c003f | |||
| 21e11c9221 | |||
| c9dcde0ee0 | |||
| 3fcc16090a | |||
| bbb1e5e15a | |||
| 6d30e7ea8e | |||
| 9288f71c5f | |||
| 79f5983c76 | |||
| 335453b63c | |||
| 4292a55614 | |||
| 92e902c81e | |||
| c47bc174bc | |||
| f97f0475e9 | |||
| 67a945a15f | |||
| d1a28826d5 | |||
| 8f026ab6c6 | |||
| bdcdcf7f8b | |||
| 182e147a86 | |||
| 687b437ea0 | |||
| f2c5dbb696 | |||
| a8bf690c17 | |||
| 1328ba35be | |||
| 8b046d4139 | |||
| f4cd372808 | |||
| 7228331db6 | |||
| 45f3f3ec01 | |||
| 5f9e54c83c | |||
| f8c2f90502 | |||
| 96e8bdfea4 | |||
| 0fa1961a04 | |||
| 88002969b7 | |||
| b90dedf3ae | |||
| 582cb32223 | |||
| 31b7921c68 | |||
| 42a43a3709 | |||
| c5ad4006ae | |||
| 71fb6a1ba1 | |||
| 68a37bc692 | |||
| 542fd92a46 | |||
| 527c71d3df | |||
| 7ee47bdb4c | |||
| 9fa36b6393 | |||
| 2b40b96aa1 | |||
| 9a68702d4d | |||
| bc5198768e | |||
| 892653cd96 | |||
| a7471ef324 | |||
| 403141c1f5 | |||
| d8c82bf6d0 | |||
| dd86ba36dd | |||
| 42acbfe806 | |||
| 7c55483585 | |||
| 0320220219 | |||
| e32ee2ccf3 | |||
| b8ca1762c2 | |||
| d1e9fcf03a | |||
| 303a774378 | |||
| c9ca71f47b | |||
| 92faf1e3d5 | |||
| e509989ac3 | |||
| c04cc9a4cf | |||
| 17258d1445 | |||
| 8f3d7606f5 | |||
| fd97f0e8ca | |||
| d4ce1635a8 | |||
| 2bc564ad01 | |||
| 5910bcbc02 | |||
| 8c63fe9d0d | |||
| 6e5a1973da | |||
| 1aa11887aa | |||
| 07740cbf08 | |||
| 87cb8a6b20 | |||
| 2977b8f25f | |||
| 9ae4fd04ac | |||
| 4470969bec | |||
| 1a4c3a7709 | |||
| 99b31920d5 | |||
| 019b3299f2 | |||
| d684957423 | |||
| cb4eda4c62 | |||
| ac5f380ee2 | |||
| 4e278ca07d | |||
| cd6a725875 | |||
| 62ccb6b4cd | |||
| 365e0134b4 | |||
| d5514a060c | |||
| 8432c30f6c | |||
| c2764f90b3 | |||
| 958b6d37ee | |||
| 5e36bb014c | |||
| 8d821881ae | |||
| fca9761145 | |||
| 11481e4d13 | |||
| a6a39d1234 | |||
| 5f35d54fcb | |||
| 096a599673 | |||
| 41da67ad6f | |||
| 273a741cdf | |||
| b5c8b69547 | |||
| 5bd87bdaa8 | |||
| 7d64618701 | |||
| 4151c65251 | |||
| ccb48f92cd | |||
| 8fce478a1f | |||
| 4f712ad4ba | |||
| 562fd44a30 | |||
| 603e897e2d | |||
| 6c122aad10 | |||
| b4ac601a82 | |||
| ce380a6b0d | |||
| 5b02801c04 | |||
| 525372d7ac | |||
| e473a05250 | |||
| a55d604bf5 | |||
| 5075894ff5 | |||
| c8b82a9553 | |||
| c392266a4c | |||
| 9b540936db | |||
| 7bf1036b68 | |||
| 1d82ec56d8 | |||
| 3ae5b59141 | |||
| 929b401f95 | |||
| d158deba77 | |||
| 00c2f5359c | |||
| 5c77b48708 | |||
| 1a4e0f4e08 | |||
| 73d53653db | |||
| 74bedead20 | |||
| 1bec95d2a1 | |||
| 30137e285d | |||
| 5253d5ec51 | |||
| 7ed7329917 | |||
| 4abc0ae0ba | |||
| 47d8fcb21a | |||
| acef5a5652 | |||
| cb919a3af9 | |||
| 8e021a4419 | |||
| e5db7cb915 | |||
| 9bd03af3e9 | |||
| e8a026ef0b | |||
| 86755aa6ba | |||
| 77e0c6425e | |||
| 69230a10cb | |||
| 0373e2b02a | |||
| e8dd347186 | |||
| 5681920092 | |||
| edbf35cb34 | |||
| c46d04d3c4 | |||
| 4ebd1dd7f5 | |||
| 62ab760656 | |||
| 32de7efc32 | |||
| deae210b82 | |||
| 5b2b45a6eb | |||
| bc0f0cfc55 | |||
| 2661e4539e | |||
| 2fe5a5249c | |||
| c5b678d4e9 | |||
| 487f07ef35 | |||
| 6a63be63e9 | |||
| 552c99389e | |||
| 55502d210c | |||
| 66967ca88e | |||
| ba6d02b1db | |||
| ebc957c04d | |||
| 81c3ad74ca | |||
| 88f57e6d87 | |||
| 28a965e698 | |||
| 029c445805 | |||
| 358c95d541 | |||
| 0f7793a881 | |||
| 5478c23563 | |||
| 9f39e93e7b | |||
| 896a3e1be6 | |||
| 800390db85 | |||
| 1eaa13155c | |||
| fad3346096 | |||
| 150f832f8e | |||
| 202336b8a1 | |||
| f0e94f8e5e | |||
| 6cd00b8d10 | |||
| 534187cc8f | |||
| 25b4934f69 | |||
| 5ef7e24893 | |||
| 87ef46bc05 | |||
| f7bc5be8e4 | |||
| b309583886 | |||
| 245185710a | |||
| b7cfe31d72 | |||
| 68ca41a6be | |||
| 5621e7d22e | |||
| a1a5c7772d | |||
| b47deafc14 | |||
| cc6a6d8db2 | |||
| 5b28e24c17 | |||
| f8d68d8ef0 | |||
| a9d86508b5 | |||
| bb7fa587de | |||
| 6585732dfc | |||
| 2065e0fc17 | |||
| 3f7bdad59c | |||
| 6209e78c1e | |||
| 8e5062af96 | |||
| 496e642d7f | |||
| 07e18ec198 | |||
| d5953c28c1 | |||
| 3aa4b66588 | |||
| 005f0ce340 | |||
| 8d1d025fa2 | |||
| 1d53a2f954 | |||
| 966d123608 | |||
| 963d55273f | |||
| 6872d7bf77 | |||
| 6fe93bcda0 | |||
| 78d568e04e | |||
| 8880bdd857 | |||
| cc83ecf7e4 | |||
| 796f5a678a | |||
| 00b60f5493 | |||
| 0dfd1cca44 | |||
| eacefd3697 | |||
| 424c25768c | |||
| e460c1700e | |||
| 9935c99d41 | |||
| 2c4aee63bf | |||
| 0ebc395df9 | |||
| 1de3317e75 | |||
| 91c20af893 | |||
| 1365e2f246 | |||
| cfa1ce46f2 | |||
| 3f4f76859b | |||
| 3f7f4b82de | |||
| 934ba2b027 | |||
| 221e1870e5 | |||
| 9b36bccf0c | |||
| 80d7285497 | |||
| b94f2a483d | |||
| f64cfb4cd1 | |||
| eda223ed3d | |||
| c98d4305fa | |||
| 2eecbca6eb | |||
| a58c80ef08 | |||
| ac9d0db8be | |||
| 7521d98963 | |||
| 1e98131090 | |||
| 46bf65462c | |||
| e3df4c2d68 | |||
| 45c013350f | |||
| 30e2f27c64 | |||
| 6fecc53975 | |||
| e4dbfb1904 | |||
| 3113c1e9a7 | |||
| f822d3db7b | |||
| 9d23766288 | |||
| fd4930b198 | |||
| 5d7be89edb | |||
| 47f5b4ceac | |||
| 790220039b | |||
| 16fdfa4583 | |||
| 1d8a931e0c | |||
| 48d0883b31 | |||
| e271370326 | |||
| cbbeb66b5b | |||
| 3f0d4846df | |||
| de020f46a6 | |||
| 9bfcdbe8e2 | |||
| 8c4885ce2c | |||
| f24bb5c038 | |||
| 79dfe7eeda | |||
| 0108c6ed19 | |||
| 926389df89 | |||
| b55db00408 | |||
| cfcb64f7e5 | |||
| 0e8f60d501 | |||
| 9c6c5f5170 | |||
| f28888e3e7 | |||
| 6e30e6178b | |||
| 9549bed8bb | |||
| 7c65d61d91 | |||
| ad2efb7e62 | |||
| a50c9bfa1a | |||
| 30cdbf535a | |||
| f5365cbca9 | |||
| 22e7cb887b | |||
| b571f1a881 | |||
| b1c4e3ded7 | |||
| 4694ded8bd | |||
| 7971573026 | |||
| c4780c8af2 | |||
| 246f0b3f52 | |||
| 7879d76592 | |||
| 0f62ea25d8 | |||
| 6dbe8205d6 | |||
| 1b94ad5c4c | |||
| 37be99ab8f | |||
| 6f5cee8c36 | |||
| 58d805ab72 | |||
| 68ad75f737 | |||
| 73ea2b5fec | |||
| a0b37daeb0 | |||
| c9972047f6 | |||
| ccdf698380 | |||
| c10ed5a2f3 | |||
| 600b6d2b03 | |||
| b1391bbb17 | |||
| a171103a80 | |||
| 3e2009aa9d | |||
| 4b6e942667 | |||
| a6723044b9 | |||
| f60a25ee2d | |||
| 770baefe35 | |||
| 1c3403d7e6 | |||
| 342fd869a2 | |||
| 6f7db4172f | |||
| 55fd7b8890 | |||
| a14b4dc80c | |||
| c81f6962d7 | |||
| 9f4ef6842b | |||
| 7ca0c06c87 | |||
| 57aa763a84 | |||
| ba5fecf6b3 | |||
| 35343509f9 | |||
| 42d8b06346 | |||
| f30f0e8316 | |||
| e1aaf509d1 | |||
| 8db5eadea6 | |||
| 4dda824d37 | |||
| 0579b3afb0 | |||
| d328c458e6 | |||
| c8651cddbb | |||
| cde2a1ab26 | |||
| 8d78c92c03 | |||
| af311c3d33 | |||
| 906bcf1634 | |||
| 843bd4f4fa | |||
| 9bbe4a96d0 | |||
| 974ac0691c | |||
| 1188e48313 | |||
| e7ed5f3de3 | |||
| d45b2de241 | |||
| 3d9cbf351f | |||
| 844e22d94d | |||
| 09c905910e | |||
| 8fd8bf8792 | |||
| 243658637c | |||
| 5603a79d49 | |||
| 0007a4cc74 | |||
| 3dafe02f0e | |||
| e62e9cde02 | |||
| cde53c02e7 | |||
| de64da8e20 | |||
| 683790b068 | |||
| f9c24c8a23 | |||
| 886bb95e18 | |||
| 214fd0caf5 | |||
| 4aeac1acd2 | |||
| 679be24074 | |||
| 36e07f546d | |||
| d264feaf22 | |||
| 32b7b7afdc | |||
| 7a50f0c3b2 | |||
| 091382ef30 | |||
| 2da6a2fbfa | |||
| d910a4e0ee | |||
| 672ab79421 | |||
| 1ad97adc7c | |||
| 2bd585a0ff | |||
| df0b0367a4 | |||
| bb9e26d745 | |||
| dc5c765ecb | |||
| 95e2e3d0d2 | |||
| 690c4164a7 | |||
| ee656aa3ef | |||
| 3d4123aca5 | |||
| 29a8e23f72 | |||
| a4c5407b04 | |||
| 75bc36a9e6 | |||
| b8e2fb46fb | |||
| eff931f9ca | |||
| e4d8d721c0 | |||
| 21335b5ff1 | |||
| dadfdacf14 | |||
| e3eeef4301 | |||
| 6a519f4a1a | |||
| fde8bd89b6 | |||
| 099013bc6d | |||
| 11eef024ea | |||
| cc6017db3b | |||
| 84c1679973 | |||
| b1d18a5974 | |||
| 5019b4b266 | |||
| 790e7a0e1e | |||
| 0b1b6947e8 | |||
| c79b2cfb78 | |||
| dd699bce9a | |||
| 5ce017ef3d | |||
| 59c1ce2639 | |||
| 4fb63d8892 | |||
| a3b4d04d02 | |||
| aa3af8faea | |||
| 20c7f0e96f | |||
| e21142f1bd | |||
| ba3a6eaeb5 | |||
| 9d0bc8ab9e | |||
| 0d65ca78c4 | |||
| 0505a4807d | |||
| 01aa06e488 | |||
| 3b8dd1f4a5 | |||
| 4a837ce28c | |||
| 696f6c399c | |||
| ac9290de27 | |||
| b026e9107f | |||
| 1347535e8f | |||
| 479327849a | |||
| 21611a9434 | |||
| 78d9030567 | |||
| 4feb168cf7 | |||
| f3c16476f9 | |||
| 4678059eaf | |||
| a69d4bb457 | |||
| 50e3f2be38 | |||
| 276edfd562 | |||
| 605f8fcde3 | |||
| 645c9b5e67 | |||
| f0e4d1a7cf | |||
| 055ec4bdd5 | |||
| 5761f9ac7f | |||
| 32620fd55f | |||
| abb5cdbe06 | |||
| 8cad2b0076 | |||
| bcd6c19a97 | |||
| 764a3a6228 | |||
| d17aa72829 | |||
| d62658f515 | |||
| e6d4095bf9 | |||
| 9ace9d6960 | |||
| 6c32ff9708 | |||
| 5eae62ae33 | |||
| 331483f86a | |||
| 4ee0aeb2b1 | |||
| 08354f7651 | |||
| f1f599dd09 | |||
| 51251668e3 | |||
| 6e72433f99 | |||
| e6957e7a99 | |||
| de2406a2c7 | |||
| 956a264106 | |||
| 9b62d18101 | |||
| 390730f304 | |||
| e134ef8e15 | |||
| 7bd1550195 | |||
| 134ab2f0d6 | |||
| 1a4e7433b2 | |||
| f211b1e366 | |||
| b2db208e6e | |||
| c9c0de1fba | |||
| 9d91a018b2 | |||
| 0f7e3fe53e | |||
| ae9c1b4070 | |||
| e0d98af04f | |||
| 81e31c0550 | |||
| 1c771df941 | |||
| adcd8703d3 | |||
| aee4c2d80d | |||
| 5e04f48500 | |||
| a7610a7a88 | |||
| 28e6e9140c | |||
| 17c2aecd99 | |||
| 85074f3ac8 | |||
| c7020da81c | |||
| 271a126556 | |||
| 7da444c7a4 | |||
| 2a7fd71416 | |||
| 6ffd211e51 | |||
| f61ed48240 | |||
| 8d3dc405a5 | |||
| 21bf0fb27b | |||
| 7313f56c01 | |||
| cfef9e96e6 | |||
| 8b9a5cf500 | |||
| ce94ce058f | |||
| 018e4d6079 | |||
| ebadd9799f | |||
| 268fa02b83 | |||
| cb525477e5 | |||
| 4d6d2f0d33 | |||
| c7f8b05604 | |||
| 2878e9be9d | |||
| 7b419c2b12 | |||
| 0049126a91 | |||
| 80c5194d8b | |||
| 27a6b99453 | |||
| 61982de511 | |||
| efd9883197 | |||
| ce4ae8d90c | |||
| 1d2722f994 | |||
| 7e109e7f2d | |||
| f7a0b305df | |||
| 746ec71a0d | |||
| 41a63a0985 | |||
| 5a149c5492 | |||
| 7ff0becf72 | |||
| 4c2967a733 | |||
| 2b80e5d1c9 | |||
| 4e7ff53214 | |||
| 9ec36e49b7 | |||
| cdfa5ee540 | |||
| 71853f69f3 | |||
| dd13073037 | |||
| 1010df1077 | |||
| 9eaf9cf491 | |||
| 8e96318478 | |||
| bedff1f258 | |||
| 71a10a9a8b | |||
| 54287666e8 | |||
| 6de829163d | |||
| 605aed6f20 | |||
| adb5ed7c30 | |||
| 2b019e57df | |||
| 30c07712e3 | |||
| 82c92501d9 | |||
| c2a871a1a7 | |||
| dfd7bd5889 | |||
| 5aee4b1660 | |||
| 68a7bb67de | |||
| 7ff043d8df | |||
| 31e93428cf | |||
| 5f56b3eeea | |||
| e69b05693a | |||
| 8ae2451340 | |||
| b3b3279345 | |||
| 94a451c79b | |||
| ec7b959028 | |||
| 7061beea6e | |||
| e408162e26 | |||
| 25ae3895cb | |||
| 60296f2a41 | |||
| 3b97844310 | |||
| c904d245d2 | |||
| d315a2a91b | |||
| 0741d05ab3 | |||
| 61aa920362 | |||
| 24b9b17e64 | |||
| 5e3e633c4b | |||
| 8e6d3c34e2 | |||
| f3cff902ba | |||
| 4fe1b4c26f | |||
| cb24a08b06 | |||
| 597a53d11a | |||
| 639deeb502 | |||
| 03e082725e | |||
| 3e3307887e | |||
| d85683aaa8 | |||
| e89ed985fc | |||
| b1fb8bb18c | |||
| 45ebd7c37a | |||
| 3506020e55 | |||
| eca77d684b | |||
| e263a4a21f | |||
| dc4353c682 | |||
| e1d8069967 | |||
| 060726b7a3 | |||
| f72ccb0f0d | |||
| 2ff6bfbdd8 | |||
| d4f0b4772b | |||
| 17d258d094 | |||
| 8288d38257 | |||
| 3a0c8f3f4e | |||
| 1cd560c85e | |||
| 9018642992 | |||
| 04e652441e | |||
| ccf5990bc7 | |||
| 3d7c9ee2b8 | |||
| ad35c4006e | |||
| 2ec790e851 | |||
| 8f8cec0785 | |||
| 4a80cd301b | |||
| 63524eceff | |||
| a477b007e1 | |||
| 5b81510325 | |||
| 3bef973326 | |||
| bc5bb271d8 | |||
| 158e3cb073 | |||
| 36fb0eba29 | |||
| 1b37e85418 | |||
| 6a93497c8f | |||
| b8ee3465f8 | |||
| a7dfb36a84 | |||
| 14a7b5bdc8 | |||
| ffbd76539a | |||
| bdcc19e86a | |||
| 7929bac685 | |||
| f590aad42c | |||
| ec23f3dcb7 | |||
| 9644eb4329 | |||
| 7a4c6e4ed4 | |||
| d5ad504104 | |||
| d684f6d7ae | |||
| f0d9703587 | |||
| c08efef8ed | |||
| 6d29774744 | |||
| af6bab7703 | |||
| 7033f92d82 | |||
| 128dfa6d81 | |||
| 0b0ec075bb | |||
| cca4d21e7c | |||
| 4f59678ded | |||
| 8a1d2af3cf |
+17
-22
@@ -11,30 +11,25 @@
|
|||||||
# In each subsection folders are ordered first by depth, then alphabetically.
|
# In each subsection folders are ordered first by depth, then alphabetically.
|
||||||
# This should make it easy to add new rules without breaking existing ones.
|
# This should make it easy to add new rules without breaking existing ones.
|
||||||
|
|
||||||
# Something weird not covered by anything else
|
# contracts
|
||||||
* @futurechimp @mmsinclair
|
/contracts/mixnet @durch @jstuczyn
|
||||||
|
/contracts/vesting @durch @jstuczyn
|
||||||
|
/contracts/service-provider-directory @octol
|
||||||
|
|
||||||
# Rust rules:
|
# crypto code
|
||||||
*.rs @durch @futurechimp @jstuczyn @neacsu @octol
|
/common/crypto/ @jstuczyn
|
||||||
Cargo.* @durch @futurechimp @jstuczyn @neacsu @octol
|
/common/nymcoconut/ @jstuczyn
|
||||||
|
/common/dkg/ @jstuczyn
|
||||||
|
/common/nymsphinx/ @jstuczyn
|
||||||
|
|
||||||
# JS rules:
|
# rust sdk
|
||||||
*.js @mmsinclair @fmtabbara
|
/sdk/rust/ @octol
|
||||||
*.ts @mmsinclair @fmtabbara
|
|
||||||
*.tsx @mmsinclair @fmtabbara
|
|
||||||
*.jsx @mmsinclair @fmtabbara
|
|
||||||
|
|
||||||
# Something looking like possible documentation rules:
|
# nym-connect (rust)
|
||||||
*.md @mfahampshire
|
/nym-connect/desktop/src-tauri/ @octol
|
||||||
|
|
||||||
# our docker scripts
|
# nym-wallet (rust)
|
||||||
/docker/ @neacsu
|
/nym-wallet/src-tauri/ @octol
|
||||||
|
|
||||||
# if there are any changes in the core crypto, I feel like Ania should take a look:
|
# documentation
|
||||||
/common/crypto/ @aniampio
|
/documentation @mfahampshire
|
||||||
/common/nymsphinx/ @aniampio
|
|
||||||
|
|
||||||
# Explorer and wallet should probably get looked by the product team
|
|
||||||
/explorer/ @nymtech/product
|
|
||||||
/nym-wallet/ @nymtech/product
|
|
||||||
/wallet-web/ @nymtech/product
|
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
---
|
||||||
|
name: 'Documentation'
|
||||||
|
about: Suggest a fix or enhancement to the documentation or developer portal content
|
||||||
|
title: "[DOCS]"
|
||||||
|
labels: documentation, needs-triage
|
||||||
|
assignees: mfahampshire
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Is your issue either:
|
||||||
|
- [ ] a fix to existing documentation (e.g. fixing a broken link or incorrect command)
|
||||||
|
- [ ] an enhancement (e.g. adding a description for an undocumented feature)
|
||||||
|
|
||||||
|
Please briefly describe your issue:
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
name: Feature request
|
name: Feature request
|
||||||
about: Suggest an enhancement to the product
|
about: Suggest an enhancement to the product
|
||||||
title: "[Feature Request]"
|
title: "[Feature Request]"
|
||||||
labels: enhancement
|
labels: enhancement, needs-triage
|
||||||
assignees: ''
|
assignees: ''
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
name: Report
|
name: Report
|
||||||
about: To help identify and reproduce issues
|
about: To help identify and reproduce issues
|
||||||
title: "[Issue]"
|
title: "[Issue]"
|
||||||
labels: bug, bug-needs-triage, qa
|
labels: bug, bug-needs-triage, qa, needs-triage
|
||||||
assignees: tommyv1987
|
assignees: tommyv1987
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
.tmp
|
||||||
|
hashes.json
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
name: 'Nym Hash Release'
|
||||||
|
author: 'Nym Technologies SA'
|
||||||
|
description: 'Generate hashes and signatures for assets in Nym releases'
|
||||||
|
inputs:
|
||||||
|
hash-type:
|
||||||
|
description: 'Type of hash to generate (md5, sha1, sha256, sha512)'
|
||||||
|
required: false
|
||||||
|
default: 'sha256'
|
||||||
|
file-name:
|
||||||
|
description: 'File name to save as if desired'
|
||||||
|
required: false
|
||||||
|
default: 'hashes.json'
|
||||||
|
release-tag-or-name-or-id:
|
||||||
|
description: 'The tag/release to process. Uses the release id when trigger from a release.'
|
||||||
|
required: false
|
||||||
|
default: ''
|
||||||
|
outputs:
|
||||||
|
hashes:
|
||||||
|
description: 'A string containing JSON with the release asset hashes and signatures'
|
||||||
|
runs:
|
||||||
|
using: 'node16'
|
||||||
|
main: 'index.js'
|
||||||
|
branding:
|
||||||
|
icon: 'hash'
|
||||||
|
color: 'green'
|
||||||
@@ -0,0 +1,259 @@
|
|||||||
|
import hasha from "hasha";
|
||||||
|
import fetch from "node-fetch";
|
||||||
|
import { Octokit } from "@octokit/rest";
|
||||||
|
import fs from "fs";
|
||||||
|
import path from "path";
|
||||||
|
|
||||||
|
async function run(assets, algorithm, filename, cache) {
|
||||||
|
try {
|
||||||
|
fs.mkdirSync('.tmp');
|
||||||
|
} catch(e) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
|
||||||
|
const hashes = {};
|
||||||
|
let numAwaiting = 0;
|
||||||
|
for (const asset of assets) {
|
||||||
|
if (filename === "" || asset.name !== filename) { // don't hash the hash file (if the file has the same name)
|
||||||
|
numAwaiting++;
|
||||||
|
|
||||||
|
let buffer = null;
|
||||||
|
let sig = null;
|
||||||
|
if(cache) {
|
||||||
|
// cache in `${WORKING_DIR}/.tmp/`
|
||||||
|
const cacheFilename = path.resolve(`.tmp/${asset.name}`);
|
||||||
|
if(!fs.existsSync(cacheFilename)) {
|
||||||
|
console.log(`Downloading ${asset.browser_download_url}... to ${cacheFilename}`);
|
||||||
|
buffer = Buffer.from(await fetch(asset.browser_download_url).then(res => res.arrayBuffer()));
|
||||||
|
fs.writeFileSync(cacheFilename, buffer);
|
||||||
|
} else {
|
||||||
|
console.log(`Loading from ${cacheFilename}`);
|
||||||
|
buffer = Buffer.from(fs.readFileSync(cacheFilename));
|
||||||
|
|
||||||
|
// console.log('Reading signature from content');
|
||||||
|
// if(asset.name.endsWith('.sig')) {
|
||||||
|
// sig = fs.readFileSync(cacheFilename).toString();
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// fetch always
|
||||||
|
buffer = Buffer.from(await fetch(asset.browser_download_url).then(res => res.arrayBuffer()));
|
||||||
|
}
|
||||||
|
if(!hashes[asset.name]) {
|
||||||
|
hashes[asset.name] = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
if(asset.name.endsWith('.sig')) {
|
||||||
|
sig = buffer.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
hashes[asset.name][algorithm] = hasha(new Uint8Array(buffer), {algorithm: algorithm});
|
||||||
|
|
||||||
|
let platform;
|
||||||
|
let kind;
|
||||||
|
if(asset.name.endsWith('.sig')) {
|
||||||
|
kind = 'signature';
|
||||||
|
}
|
||||||
|
if(asset.name.endsWith('.app.tar.gz')) {
|
||||||
|
platform = 'MacOS';
|
||||||
|
kind = 'auto-updater';
|
||||||
|
}
|
||||||
|
if(asset.name.endsWith('.app.tar.gz.sig')) {
|
||||||
|
platform = 'MacOS';
|
||||||
|
kind = 'auto-updater-signature';
|
||||||
|
}
|
||||||
|
if(asset.name.endsWith('.dmg')) {
|
||||||
|
platform = 'MacOS';
|
||||||
|
kind = 'installer';
|
||||||
|
}
|
||||||
|
if(asset.name.endsWith('.msi.zip')) {
|
||||||
|
platform = 'Windows';
|
||||||
|
kind = 'auto-updater';
|
||||||
|
}
|
||||||
|
if(asset.name.endsWith('.msi.zip.sig')) {
|
||||||
|
platform = 'Windows';
|
||||||
|
kind = 'auto-updater-signature';
|
||||||
|
}
|
||||||
|
if(asset.name.endsWith('.msi')) {
|
||||||
|
platform = 'Windows';
|
||||||
|
kind = 'installer';
|
||||||
|
}
|
||||||
|
if(asset.name.endsWith('.AppImage.tar.gz')) {
|
||||||
|
platform = 'Linux';
|
||||||
|
kind = 'auto-updater';
|
||||||
|
}
|
||||||
|
if(asset.name.endsWith('.AppImage.tar.gz.sig')) {
|
||||||
|
platform = 'Linux';
|
||||||
|
kind = 'auto-updater-signature';
|
||||||
|
}
|
||||||
|
if(asset.name.endsWith('.AppImage')) {
|
||||||
|
platform = 'Linux';
|
||||||
|
kind = 'installer';
|
||||||
|
}
|
||||||
|
|
||||||
|
hashes[asset.name].downloadUrl = asset.browser_download_url;
|
||||||
|
|
||||||
|
if(platform) {
|
||||||
|
hashes[asset.name].platform = platform;
|
||||||
|
}
|
||||||
|
if(kind) {
|
||||||
|
hashes[asset.name].kind = kind;
|
||||||
|
}
|
||||||
|
|
||||||
|
// process Tauri signature files
|
||||||
|
if(asset.name.endsWith('.sig')) {
|
||||||
|
const otherFilename = asset.name.replace('.sig', '');
|
||||||
|
if(!hashes[otherFilename]) {
|
||||||
|
hashes[otherFilename] = {};
|
||||||
|
}
|
||||||
|
hashes[otherFilename].signature = sig;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return hashes;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function createHashes({ assets, algorithm, filename, cache }) {
|
||||||
|
const output = await run(assets, algorithm, filename, cache);
|
||||||
|
if(filename?.length) {
|
||||||
|
fs.writeFileSync(filename, JSON.stringify(output, null, 2));
|
||||||
|
}
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function createHashesFromReleaseTagOrNameOrId({ releaseTagOrNameOrId, algorithm = 'sha256', filename = 'hashes.json', cache = false, upload = true }) {
|
||||||
|
console.log("🚀🚀🚀 Getting releases");
|
||||||
|
|
||||||
|
let auth;
|
||||||
|
let authStrategy;
|
||||||
|
if(process.env.GITHUB_TOKEN) {
|
||||||
|
console.log('Using GITHUB_TOKEN for auth');
|
||||||
|
// authStrategy = createActionAuth();
|
||||||
|
// auth = await authStrategy();
|
||||||
|
}
|
||||||
|
|
||||||
|
const octokit = new Octokit({
|
||||||
|
auth: process.env.GITHUB_TOKEN,
|
||||||
|
request: { fetch }
|
||||||
|
});
|
||||||
|
const owner = "nymtech";
|
||||||
|
const repo = "nym";
|
||||||
|
|
||||||
|
let releases;
|
||||||
|
if(cache) {
|
||||||
|
const cacheFilename = path.resolve(`.tmp/releases.json`);
|
||||||
|
if(!fs.existsSync(cacheFilename)) {
|
||||||
|
releases = await octokit.paginate(
|
||||||
|
octokit.rest.repos.listReleases,
|
||||||
|
{
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
per_page: 100,
|
||||||
|
},
|
||||||
|
(response) => response.data
|
||||||
|
);
|
||||||
|
fs.writeFileSync(cacheFilename, JSON.stringify(releases, null, 2));
|
||||||
|
} else {
|
||||||
|
console.log('Loading releases from cache...');
|
||||||
|
releases = JSON.parse(fs.readFileSync(cacheFilename));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
releases = await octokit.paginate(
|
||||||
|
octokit.rest.repos.listReleases,
|
||||||
|
{
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
per_page: 100,
|
||||||
|
},
|
||||||
|
(response) => response.data
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// process all releases by default
|
||||||
|
let releasesToProcess = releases;
|
||||||
|
|
||||||
|
// process a single release
|
||||||
|
if(releaseTagOrNameOrId) {
|
||||||
|
releasesToProcess = releases.filter(r => {
|
||||||
|
if (r.tag_name === releaseTagOrNameOrId) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (`${r.id}` === `${releaseTagOrNameOrId}`) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (r.name === releaseTagOrNameOrId) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
releasesToProcess.forEach(release => {
|
||||||
|
const {tag_name, name} = release;
|
||||||
|
const tagComponents = tag_name.split('-v');
|
||||||
|
const componentName = tagComponents[0];
|
||||||
|
const componentVersion = 'v' + tagComponents[1];
|
||||||
|
|
||||||
|
if(!tagComponents[1] || !name) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
release.componentName = componentName;
|
||||||
|
release.componentVersion = componentVersion;
|
||||||
|
})
|
||||||
|
|
||||||
|
releasesToProcess = releasesToProcess.filter(release =>
|
||||||
|
!!release.name && !!release.componentVersion
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log('Releases to process:');
|
||||||
|
console.table(releasesToProcess.map(r => {
|
||||||
|
const { id, name, tag_name, componentName, componentVersion, assets } = r;
|
||||||
|
return { id, name, tag_name, componentName, componentVersion, assetCount: assets.length };
|
||||||
|
}));
|
||||||
|
|
||||||
|
for(const release of releasesToProcess) {
|
||||||
|
const {id, name, tag_name, html_url, componentName, componentVersion} = release;
|
||||||
|
|
||||||
|
const hashes = await createHashes({ assets: release.assets, algorithm, filename, cache });
|
||||||
|
|
||||||
|
const output = {
|
||||||
|
id, name, tag_name, html_url,
|
||||||
|
componentName,
|
||||||
|
componentVersion,
|
||||||
|
assets: hashes,
|
||||||
|
};
|
||||||
|
|
||||||
|
if(upload) {
|
||||||
|
console.log(`🚚 Uploading ${filename} to release name="${release.name}" id=${release.id} (${release.upload_url})...`);
|
||||||
|
|
||||||
|
const exists = (await octokit.repos.listReleaseAssets({ owner, repo, release_id: release.id })).data.find(a => a.name === filename)
|
||||||
|
if (exists) {
|
||||||
|
console.log(`Deleting existing asset ${filename}...`);
|
||||||
|
await octokit.repos.deleteReleaseAsset({ owner, repo, asset_id: exists.id })
|
||||||
|
console.log('Deleted existing asset');
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const data = JSON.stringify(output, null, 2);
|
||||||
|
await octokit.rest.repos.uploadReleaseAsset({
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
release_id: release.id,
|
||||||
|
headers: {
|
||||||
|
'X-GitHub-Api-Version': '2022-11-28'
|
||||||
|
},
|
||||||
|
name: filename,
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
console.log('✅ Upload to release is complete.');
|
||||||
|
} catch(e) {
|
||||||
|
console.log('❌ failed to upload:', e.message, e.status, e.response.data);
|
||||||
|
console.log(e);
|
||||||
|
process.exit(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
import core from "@actions/core";
|
||||||
|
import github from "@actions/github";
|
||||||
|
import { createHashesFromReleaseTagOrNameOrId } from './create-hashes.mjs';
|
||||||
|
|
||||||
|
const algorithm = core.getInput('hash-type');
|
||||||
|
const filename = core.getInput("file-name");
|
||||||
|
|
||||||
|
// use the release id from the payload if it is set
|
||||||
|
const releaseTagOrNameOrId = core.getInput("release-tag-or-name-or-id") || github.context.payload.release?.id;
|
||||||
|
|
||||||
|
try {
|
||||||
|
await createHashesFromReleaseTagOrNameOrId({ releaseTagOrNameOrId, algorithm, filename })
|
||||||
|
} catch (error) {
|
||||||
|
core.setFailed(error.message);
|
||||||
|
}
|
||||||
+536
@@ -0,0 +1,536 @@
|
|||||||
|
{
|
||||||
|
"name": "ghaction-generate-release-hashes",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"lockfileVersion": 3,
|
||||||
|
"requires": true,
|
||||||
|
"packages": {
|
||||||
|
"": {
|
||||||
|
"name": "ghaction-generate-release-hashes",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@actions/core": "^1.10.0",
|
||||||
|
"@actions/github": "^5.1.1",
|
||||||
|
"@octokit/auth-action": "^4.0.0",
|
||||||
|
"@octokit/rest": "^20.0.1",
|
||||||
|
"hasha": "^5.2.0",
|
||||||
|
"node-fetch": "^3.2.10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@actions/core": {
|
||||||
|
"version": "1.10.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.10.0.tgz",
|
||||||
|
"integrity": "sha512-2aZDDa3zrrZbP5ZYg159sNoLRb61nQ7awl5pSvIq5Qpj81vwDzdMRKzkWJGJuwVvWpvZKx7vspJALyvaaIQyug==",
|
||||||
|
"dependencies": {
|
||||||
|
"@actions/http-client": "^2.0.1",
|
||||||
|
"uuid": "^8.3.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@actions/github": {
|
||||||
|
"version": "5.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@actions/github/-/github-5.1.1.tgz",
|
||||||
|
"integrity": "sha512-Nk59rMDoJaV+mHCOJPXuvB1zIbomlKS0dmSIqPGxd0enAXBnOfn4VWF+CGtRCwXZG9Epa54tZA7VIRlJDS8A6g==",
|
||||||
|
"dependencies": {
|
||||||
|
"@actions/http-client": "^2.0.1",
|
||||||
|
"@octokit/core": "^3.6.0",
|
||||||
|
"@octokit/plugin-paginate-rest": "^2.17.0",
|
||||||
|
"@octokit/plugin-rest-endpoint-methods": "^5.13.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@actions/http-client": {
|
||||||
|
"version": "2.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.1.1.tgz",
|
||||||
|
"integrity": "sha512-qhrkRMB40bbbLo7gF+0vu+X+UawOvQQqNAA/5Unx774RS8poaOhThDOG6BGmxvAnxhQnDp2BG/ZUm65xZILTpw==",
|
||||||
|
"dependencies": {
|
||||||
|
"tunnel": "^0.0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/auth-action": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/auth-action/-/auth-action-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-sMm9lWZdiX6e89YFaLrgE9EFs94k58BwIkvjOtozNWUqyTmsrnWFr/M5LolaRzZ7Kmb5FbhF9hi7FEeE274SoQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"@octokit/auth-token": "^4.0.0",
|
||||||
|
"@octokit/types": "^11.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/auth-action/node_modules/@octokit/auth-token": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/auth-action/node_modules/@octokit/openapi-types": {
|
||||||
|
"version": "18.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-18.0.0.tgz",
|
||||||
|
"integrity": "sha512-V8GImKs3TeQRxRtXFpG2wl19V7444NIOTDF24AWuIbmNaNYOQMWRbjcGDXV5B+0n887fgDcuMNOmlul+k+oJtw=="
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/auth-action/node_modules/@octokit/types": {
|
||||||
|
"version": "11.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-11.1.0.tgz",
|
||||||
|
"integrity": "sha512-Fz0+7GyLm/bHt8fwEqgvRBWwIV1S6wRRyq+V6exRKLVWaKGsuy6H9QFYeBVDV7rK6fO3XwHgQOPxv+cLj2zpXQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"@octokit/openapi-types": "^18.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/auth-token": {
|
||||||
|
"version": "2.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz",
|
||||||
|
"integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==",
|
||||||
|
"dependencies": {
|
||||||
|
"@octokit/types": "^6.0.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/core": {
|
||||||
|
"version": "3.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.6.0.tgz",
|
||||||
|
"integrity": "sha512-7RKRKuA4xTjMhY+eG3jthb3hlZCsOwg3rztWh75Xc+ShDWOfDDATWbeZpAHBNRpm4Tv9WgBMOy1zEJYXG6NJ7Q==",
|
||||||
|
"dependencies": {
|
||||||
|
"@octokit/auth-token": "^2.4.4",
|
||||||
|
"@octokit/graphql": "^4.5.8",
|
||||||
|
"@octokit/request": "^5.6.3",
|
||||||
|
"@octokit/request-error": "^2.0.5",
|
||||||
|
"@octokit/types": "^6.0.3",
|
||||||
|
"before-after-hook": "^2.2.0",
|
||||||
|
"universal-user-agent": "^6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/endpoint": {
|
||||||
|
"version": "6.0.12",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz",
|
||||||
|
"integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==",
|
||||||
|
"dependencies": {
|
||||||
|
"@octokit/types": "^6.0.3",
|
||||||
|
"is-plain-object": "^5.0.0",
|
||||||
|
"universal-user-agent": "^6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/graphql": {
|
||||||
|
"version": "4.8.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz",
|
||||||
|
"integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==",
|
||||||
|
"dependencies": {
|
||||||
|
"@octokit/request": "^5.6.0",
|
||||||
|
"@octokit/types": "^6.0.3",
|
||||||
|
"universal-user-agent": "^6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/openapi-types": {
|
||||||
|
"version": "12.11.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-12.11.0.tgz",
|
||||||
|
"integrity": "sha512-VsXyi8peyRq9PqIz/tpqiL2w3w80OgVMwBHltTml3LmVvXiphgeqmY9mvBw9Wu7e0QWk/fqD37ux8yP5uVekyQ=="
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/plugin-paginate-rest": {
|
||||||
|
"version": "2.21.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.21.3.tgz",
|
||||||
|
"integrity": "sha512-aCZTEf0y2h3OLbrgKkrfFdjRL6eSOo8komneVQJnYecAxIej7Bafor2xhuDJOIFau4pk0i/P28/XgtbyPF0ZHw==",
|
||||||
|
"dependencies": {
|
||||||
|
"@octokit/types": "^6.40.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@octokit/core": ">=2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/plugin-rest-endpoint-methods": {
|
||||||
|
"version": "5.16.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.16.2.tgz",
|
||||||
|
"integrity": "sha512-8QFz29Fg5jDuTPXVtey05BLm7OB+M8fnvE64RNegzX7U+5NUXcOcnpTIK0YfSHBg8gYd0oxIq3IZTe9SfPZiRw==",
|
||||||
|
"dependencies": {
|
||||||
|
"@octokit/types": "^6.39.0",
|
||||||
|
"deprecation": "^2.3.1"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@octokit/core": ">=3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/request": {
|
||||||
|
"version": "5.6.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.3.tgz",
|
||||||
|
"integrity": "sha512-bFJl0I1KVc9jYTe9tdGGpAMPy32dLBXXo1dS/YwSCTL/2nd9XeHsY616RE3HPXDVk+a+dBuzyz5YdlXwcDTr2A==",
|
||||||
|
"dependencies": {
|
||||||
|
"@octokit/endpoint": "^6.0.1",
|
||||||
|
"@octokit/request-error": "^2.1.0",
|
||||||
|
"@octokit/types": "^6.16.1",
|
||||||
|
"is-plain-object": "^5.0.0",
|
||||||
|
"node-fetch": "^2.6.7",
|
||||||
|
"universal-user-agent": "^6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/request-error": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==",
|
||||||
|
"dependencies": {
|
||||||
|
"@octokit/types": "^6.0.3",
|
||||||
|
"deprecation": "^2.0.0",
|
||||||
|
"once": "^1.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/request/node_modules/node-fetch": {
|
||||||
|
"version": "2.7.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
|
||||||
|
"integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
|
||||||
|
"dependencies": {
|
||||||
|
"whatwg-url": "^5.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "4.x || >=6.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"encoding": "^0.1.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"encoding": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/rest": {
|
||||||
|
"version": "20.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-20.0.1.tgz",
|
||||||
|
"integrity": "sha512-wROV21RwHQIMNb2Dgd4+pY+dVy1Dwmp85pBrgr6YRRDYRBu9Gb+D73f4Bl2EukZSj5hInq2Tui9o7gAQpc2k2Q==",
|
||||||
|
"dependencies": {
|
||||||
|
"@octokit/core": "^5.0.0",
|
||||||
|
"@octokit/plugin-paginate-rest": "^8.0.0",
|
||||||
|
"@octokit/plugin-request-log": "^4.0.0",
|
||||||
|
"@octokit/plugin-rest-endpoint-methods": "^9.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/rest/node_modules/@octokit/auth-token": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/rest/node_modules/@octokit/core": {
|
||||||
|
"version": "5.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.0.0.tgz",
|
||||||
|
"integrity": "sha512-YbAtMWIrbZ9FCXbLwT9wWB8TyLjq9mxpKdgB3dUNxQcIVTf9hJ70gRPwAcqGZdY6WdJPZ0I7jLaaNDCiloGN2A==",
|
||||||
|
"dependencies": {
|
||||||
|
"@octokit/auth-token": "^4.0.0",
|
||||||
|
"@octokit/graphql": "^7.0.0",
|
||||||
|
"@octokit/request": "^8.0.2",
|
||||||
|
"@octokit/request-error": "^5.0.0",
|
||||||
|
"@octokit/types": "^11.0.0",
|
||||||
|
"before-after-hook": "^2.2.0",
|
||||||
|
"universal-user-agent": "^6.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/rest/node_modules/@octokit/endpoint": {
|
||||||
|
"version": "9.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.0.tgz",
|
||||||
|
"integrity": "sha512-szrQhiqJ88gghWY2Htt8MqUDO6++E/EIXqJ2ZEp5ma3uGS46o7LZAzSLt49myB7rT+Hfw5Y6gO3LmOxGzHijAQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"@octokit/types": "^11.0.0",
|
||||||
|
"is-plain-object": "^5.0.0",
|
||||||
|
"universal-user-agent": "^6.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/rest/node_modules/@octokit/graphql": {
|
||||||
|
"version": "7.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-7.0.1.tgz",
|
||||||
|
"integrity": "sha512-T5S3oZ1JOE58gom6MIcrgwZXzTaxRnxBso58xhozxHpOqSTgDS6YNeEUvZ/kRvXgPrRz/KHnZhtb7jUMRi9E6w==",
|
||||||
|
"dependencies": {
|
||||||
|
"@octokit/request": "^8.0.1",
|
||||||
|
"@octokit/types": "^11.0.0",
|
||||||
|
"universal-user-agent": "^6.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/rest/node_modules/@octokit/openapi-types": {
|
||||||
|
"version": "18.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-18.0.0.tgz",
|
||||||
|
"integrity": "sha512-V8GImKs3TeQRxRtXFpG2wl19V7444NIOTDF24AWuIbmNaNYOQMWRbjcGDXV5B+0n887fgDcuMNOmlul+k+oJtw=="
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/rest/node_modules/@octokit/plugin-paginate-rest": {
|
||||||
|
"version": "8.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-8.0.0.tgz",
|
||||||
|
"integrity": "sha512-2xZ+baZWUg+qudVXnnvXz7qfrTmDeYPCzangBVq/1gXxii/OiS//4shJp9dnCCvj1x+JAm9ji1Egwm1BA47lPQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"@octokit/types": "^11.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@octokit/core": ">=5"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/rest/node_modules/@octokit/plugin-request-log": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-2uJI1COtYCq8Z4yNSnM231TgH50bRkheQ9+aH8TnZanB6QilOnx8RMD2qsnamSOXtDj0ilxvevf5fGsBhBBzKA==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@octokit/core": ">=5"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/rest/node_modules/@octokit/plugin-rest-endpoint-methods": {
|
||||||
|
"version": "9.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-9.0.0.tgz",
|
||||||
|
"integrity": "sha512-KquMF/VB1IkKNiVnzJKspY5mFgGyLd7HzdJfVEGTJFzqu9BRFNWt+nwTCMuUiWc72gLQhRWYubTwOkQj+w/1PA==",
|
||||||
|
"dependencies": {
|
||||||
|
"@octokit/types": "^11.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@octokit/core": ">=5"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/rest/node_modules/@octokit/request": {
|
||||||
|
"version": "8.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.1.1.tgz",
|
||||||
|
"integrity": "sha512-8N+tdUz4aCqQmXl8FpHYfKG9GelDFd7XGVzyN8rc6WxVlYcfpHECnuRkgquzz+WzvHTK62co5di8gSXnzASZPQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"@octokit/endpoint": "^9.0.0",
|
||||||
|
"@octokit/request-error": "^5.0.0",
|
||||||
|
"@octokit/types": "^11.1.0",
|
||||||
|
"is-plain-object": "^5.0.0",
|
||||||
|
"universal-user-agent": "^6.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/rest/node_modules/@octokit/request-error": {
|
||||||
|
"version": "5.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-5.0.0.tgz",
|
||||||
|
"integrity": "sha512-1ue0DH0Lif5iEqT52+Rf/hf0RmGO9NWFjrzmrkArpG9trFfDM/efx00BJHdLGuro4BR/gECxCU2Twf5OKrRFsQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"@octokit/types": "^11.0.0",
|
||||||
|
"deprecation": "^2.0.0",
|
||||||
|
"once": "^1.4.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/rest/node_modules/@octokit/types": {
|
||||||
|
"version": "11.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-11.1.0.tgz",
|
||||||
|
"integrity": "sha512-Fz0+7GyLm/bHt8fwEqgvRBWwIV1S6wRRyq+V6exRKLVWaKGsuy6H9QFYeBVDV7rK6fO3XwHgQOPxv+cLj2zpXQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"@octokit/openapi-types": "^18.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@octokit/types": {
|
||||||
|
"version": "6.41.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.41.0.tgz",
|
||||||
|
"integrity": "sha512-eJ2jbzjdijiL3B4PrSQaSjuF2sPEQPVCPzBvTHJD9Nz+9dw2SGH4K4xeQJ77YfTq5bRQ+bD8wT11JbeDPmxmGg==",
|
||||||
|
"dependencies": {
|
||||||
|
"@octokit/openapi-types": "^12.11.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/before-after-hook": {
|
||||||
|
"version": "2.2.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz",
|
||||||
|
"integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ=="
|
||||||
|
},
|
||||||
|
"node_modules/data-uri-to-buffer": {
|
||||||
|
"version": "4.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz",
|
||||||
|
"integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 12"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/deprecation": {
|
||||||
|
"version": "2.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz",
|
||||||
|
"integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ=="
|
||||||
|
},
|
||||||
|
"node_modules/fetch-blob": {
|
||||||
|
"version": "3.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz",
|
||||||
|
"integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/jimmywarting"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "paypal",
|
||||||
|
"url": "https://paypal.me/jimmywarting"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"dependencies": {
|
||||||
|
"node-domexception": "^1.0.0",
|
||||||
|
"web-streams-polyfill": "^3.0.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^12.20 || >= 14.13"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/formdata-polyfill": {
|
||||||
|
"version": "4.0.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz",
|
||||||
|
"integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==",
|
||||||
|
"dependencies": {
|
||||||
|
"fetch-blob": "^3.1.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12.20.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/hasha": {
|
||||||
|
"version": "5.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz",
|
||||||
|
"integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"is-stream": "^2.0.0",
|
||||||
|
"type-fest": "^0.8.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/is-plain-object": {
|
||||||
|
"version": "5.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
|
||||||
|
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/is-stream": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/node-domexception": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/jimmywarting"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://paypal.me/jimmywarting"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.5.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/node-fetch": {
|
||||||
|
"version": "3.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz",
|
||||||
|
"integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==",
|
||||||
|
"dependencies": {
|
||||||
|
"data-uri-to-buffer": "^4.0.0",
|
||||||
|
"fetch-blob": "^3.1.4",
|
||||||
|
"formdata-polyfill": "^4.0.10"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/node-fetch"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/once": {
|
||||||
|
"version": "1.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||||
|
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
|
||||||
|
"dependencies": {
|
||||||
|
"wrappy": "1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/tr46": {
|
||||||
|
"version": "0.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
|
||||||
|
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
|
||||||
|
},
|
||||||
|
"node_modules/tunnel": {
|
||||||
|
"version": "0.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
|
||||||
|
"integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.6.11 <=0.7.0 || >=0.7.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/type-fest": {
|
||||||
|
"version": "0.8.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
|
||||||
|
"integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/universal-user-agent": {
|
||||||
|
"version": "6.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz",
|
||||||
|
"integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w=="
|
||||||
|
},
|
||||||
|
"node_modules/uuid": {
|
||||||
|
"version": "8.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
|
||||||
|
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
|
||||||
|
"bin": {
|
||||||
|
"uuid": "dist/bin/uuid"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/web-streams-polyfill": {
|
||||||
|
"version": "3.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz",
|
||||||
|
"integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/webidl-conversions": {
|
||||||
|
"version": "3.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
||||||
|
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
|
||||||
|
},
|
||||||
|
"node_modules/whatwg-url": {
|
||||||
|
"version": "5.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
||||||
|
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
|
||||||
|
"dependencies": {
|
||||||
|
"tr46": "~0.0.3",
|
||||||
|
"webidl-conversions": "^3.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/wrappy": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"name": "nym-hash-release",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "Generate hashes and signatures for assets in Nym releases",
|
||||||
|
"main": "index.js",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"local": "node run-local.mjs"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@actions/core": "^1.10.0",
|
||||||
|
"@actions/github": "^5.1.1",
|
||||||
|
"@octokit/auth-action": "^4.0.0",
|
||||||
|
"@octokit/rest": "^20.0.1",
|
||||||
|
"hasha": "^5.2.0",
|
||||||
|
"node-fetch": "^3.2.10"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
import {createHashesFromReleaseTagOrNameOrId} from './create-hashes.mjs';
|
||||||
|
|
||||||
|
await createHashesFromReleaseTagOrNameOrId({releaseTagOrNameOrId: 119065724, cache: true, upload: false});
|
||||||
|
await createHashesFromReleaseTagOrNameOrId({releaseTagOrNameOrId: '119065724', cache: true, upload: false});
|
||||||
|
await createHashesFromReleaseTagOrNameOrId({releaseTagOrNameOrId: 'nym-connect-v1.1.19-snickers', cache: true, upload: false});
|
||||||
|
await createHashesFromReleaseTagOrNameOrId({releaseTagOrNameOrId: 'Nym Connect v1.1.19-snickers', cache: true, upload: false});
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
# To get started with Dependabot version updates, you'll need to specify which
|
||||||
|
# package ecosystems to update and where the package manifests are located.
|
||||||
|
# Please see the documentation for all configuration options:
|
||||||
|
# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
|
||||||
|
|
||||||
|
version: 2
|
||||||
|
updates:
|
||||||
|
# Maintain dependencies for GitHub Actions
|
||||||
|
- package-ecosystem: "github-actions"
|
||||||
|
directory: "/"
|
||||||
|
schedule:
|
||||||
|
interval: "daily"
|
||||||
|
commit-message:
|
||||||
|
prefix: build
|
||||||
|
prefix-development: chore
|
||||||
|
include: scope
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
[
|
|
||||||
{
|
|
||||||
"os":"ubuntu-20.04",
|
|
||||||
"rust":"stable",
|
|
||||||
"runOnEvent":"always"
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"os":"windows-latest",
|
|
||||||
"rust":"stable",
|
|
||||||
"runOnEvent":"pull_request"
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"os":"macos-latest",
|
|
||||||
"rust":"stable",
|
|
||||||
"runOnEvent":"pull_request"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
@@ -0,0 +1,127 @@
|
|||||||
|
name: CD docs
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
push:
|
||||||
|
branches: master
|
||||||
|
paths:
|
||||||
|
- 'documentation/docs/**'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: custom-runner-linux
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- name: Install rsync
|
||||||
|
run: sudo apt-get install rsync
|
||||||
|
- uses: rlespinasse/github-slug-action@v3.x
|
||||||
|
- uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: 18
|
||||||
|
- name: Install Rust stable
|
||||||
|
uses: actions-rs/toolchain@v1
|
||||||
|
with:
|
||||||
|
toolchain: stable
|
||||||
|
- name: Build all binaries
|
||||||
|
uses: actions-rs/cargo@v1
|
||||||
|
with:
|
||||||
|
command: build
|
||||||
|
args: --workspace --release --all
|
||||||
|
- name: Install mdbook
|
||||||
|
run: (test -x $HOME/.cargo/bin/mdbook || cargo install --vers "^0.4.33" mdbook)
|
||||||
|
- name: Install mdbook plugins
|
||||||
|
run: |
|
||||||
|
cargo install --vers "=0.2.2" mdbook-variables && cargo install \
|
||||||
|
--vers "^1.8.0" mdbook-admonish && cargo install --vers \
|
||||||
|
"^0.1.2" mdbook-last-changed && cargo install --vers "^0.1.2" mdbook-theme \
|
||||||
|
&& cargo install --vers "^0.7.7" mdbook-linkcheck
|
||||||
|
- name: Build all projects in documentation/ & move to ~/dist/docs/
|
||||||
|
run: cd documentation && ./build_all_to_dist.sh
|
||||||
|
continue-on-error: false
|
||||||
|
|
||||||
|
- name: Deploy branch master to dev
|
||||||
|
continue-on-error: true
|
||||||
|
uses: easingthemes/ssh-deploy@main
|
||||||
|
env:
|
||||||
|
SSH_PRIVATE_KEY: ${{ secrets.CD_WWW_SSH_PRIVATE_KEY }}
|
||||||
|
ARGS: "-rltgoDzvO --delete"
|
||||||
|
SOURCE: "dist/docs/"
|
||||||
|
REMOTE_HOST: ${{ secrets.CD_WWW_REMOTE_HOST_DEV }}
|
||||||
|
REMOTE_USER: ${{ secrets.CD_WWW_REMOTE_USER }}
|
||||||
|
TARGET: ${{ secrets.CD_WWW_REMOTE_TARGET }}/
|
||||||
|
EXCLUDE: "/node_modules/"
|
||||||
|
|
||||||
|
- name: Deploy branch master to prod
|
||||||
|
if: github.ref == 'refs/heads/master'
|
||||||
|
uses: easingthemes/ssh-deploy@main
|
||||||
|
env:
|
||||||
|
SSH_PRIVATE_KEY: ${{ secrets.CD_WWW_SSH_PRIVATE_KEY }}
|
||||||
|
ARGS: "-rltgoDzvO --delete"
|
||||||
|
SOURCE: "dist/docs/"
|
||||||
|
REMOTE_HOST: ${{ secrets.CD_WWW_REMOTE_HOST_PROD }}
|
||||||
|
REMOTE_USER: ${{ secrets.CD_WWW_REMOTE_USER }}
|
||||||
|
TARGET: ${{ secrets.CD_WWW_REMOTE_TARGET }}/
|
||||||
|
EXCLUDE: "/node_modules/"
|
||||||
|
|
||||||
|
- name: Post process
|
||||||
|
run: cd documentation && ./post_process.sh
|
||||||
|
continue-on-error: false
|
||||||
|
|
||||||
|
- name: Create Vercel project file
|
||||||
|
uses: mobiledevops/secret-to-file-action@v1
|
||||||
|
with:
|
||||||
|
base64-encoded-secret: ${{ secrets.VERCEL_PROJECT_JSON_BASE64 }}
|
||||||
|
filename: "project.json"
|
||||||
|
is-executable: true
|
||||||
|
working-directory: "./dist/docs/.vercel"
|
||||||
|
|
||||||
|
- name: Install Vercel CLI
|
||||||
|
run: npm install --global vercel@latest
|
||||||
|
|
||||||
|
- name: Pull Vercel Environment Information (preview)
|
||||||
|
if: github.ref != 'refs/heads/master'
|
||||||
|
run: vercel pull --yes --environment=preview --token=${{ secrets.VERCEL_TOKEN }}
|
||||||
|
working-directory: dist/docs
|
||||||
|
- name: Pull Vercel Environment Information (production)
|
||||||
|
if: github.ref == 'refs/heads/master'
|
||||||
|
run: vercel pull --yes --environment=production --token=${{ secrets.VERCEL_TOKEN }}
|
||||||
|
working-directory: dist/docs
|
||||||
|
|
||||||
|
- name: Build Project Artifacts (preview)
|
||||||
|
if: github.ref != 'refs/heads/master'
|
||||||
|
run: vercel build --token=${{ secrets.VERCEL_TOKEN }}
|
||||||
|
working-directory: dist/docs
|
||||||
|
- name: Build Project Artifacts (production)
|
||||||
|
if: github.ref == 'refs/heads/master'
|
||||||
|
run: vercel build --prod --token=${{ secrets.VERCEL_TOKEN }}
|
||||||
|
working-directory: dist/docs
|
||||||
|
|
||||||
|
- name: Deploy Project Artifacts to Vercel (preview)
|
||||||
|
if: github.ref != 'refs/heads/master'
|
||||||
|
run: vercel deploy --prebuilt --token=${{ secrets.VERCEL_TOKEN }}
|
||||||
|
working-directory: dist/docs
|
||||||
|
- name: Deploy Project Artifacts to Vercel (master)
|
||||||
|
if: github.ref == 'refs/heads/master'
|
||||||
|
run: vercel deploy --prebuilt --prod --token=${{ secrets.VERCEL_TOKEN }}
|
||||||
|
working-directory: dist/docs
|
||||||
|
|
||||||
|
- name: Matrix - Node Install
|
||||||
|
run: npm install
|
||||||
|
working-directory: .github/workflows/support-files
|
||||||
|
- name: Matrix - Send Notification
|
||||||
|
env:
|
||||||
|
NYM_NOTIFICATION_KIND: cd-docs
|
||||||
|
NYM_PROJECT_NAME: "Docs CD"
|
||||||
|
NYM_CI_WWW_BASE: "${{ secrets.NYM_CD_WWW_BASE }}"
|
||||||
|
NYM_CI_WWW_LOCATION: "${{ env.GITHUB_REF_SLUG }}"
|
||||||
|
GIT_COMMIT_MESSAGE: "${{ github.event.head_commit.message }}"
|
||||||
|
GIT_BRANCH: "${GITHUB_REF##*/}"
|
||||||
|
MATRIX_SERVER: "${{ secrets.MATRIX_SERVER }}"
|
||||||
|
MATRIX_ROOM: "${{ secrets.MATRIX_ROOM_DOCS }}"
|
||||||
|
MATRIX_USER_ID: "${{ secrets.MATRIX_USER_ID }}"
|
||||||
|
MATRIX_TOKEN: "${{ secrets.MATRIX_TOKEN }}"
|
||||||
|
MATRIX_DEVICE_ID: "${{ secrets.MATRIX_DEVICE_ID }}"
|
||||||
|
IS_SUCCESS: "${{ job.status == 'success' }}"
|
||||||
|
uses: docker://keybaseio/client:stable-node
|
||||||
|
with:
|
||||||
|
args: .github/workflows/support-files/notifications/entry_point.sh
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
name: CI for ts-packages
|
name: ci-build-ts
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
@@ -16,7 +16,7 @@ jobs:
|
|||||||
- uses: rlespinasse/github-slug-action@v3.x
|
- uses: rlespinasse/github-slug-action@v3.x
|
||||||
- uses: actions/setup-node@v3
|
- uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: 16
|
node-version: 18
|
||||||
- name: Setup yarn
|
- name: Setup yarn
|
||||||
run: npm install -g yarn
|
run: npm install -g yarn
|
||||||
- name: Build
|
- name: Build
|
||||||
+4
-20
@@ -1,4 +1,4 @@
|
|||||||
name: Build and upload binaries to CI
|
name: ci-build-upload-binaries
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
@@ -6,7 +6,6 @@ on:
|
|||||||
paths:
|
paths:
|
||||||
- 'clients/**'
|
- 'clients/**'
|
||||||
- 'common/**'
|
- 'common/**'
|
||||||
- 'contracts/**'
|
|
||||||
- 'explorer-api/**'
|
- 'explorer-api/**'
|
||||||
- 'gateway/**'
|
- 'gateway/**'
|
||||||
- 'integrations/**'
|
- 'integrations/**'
|
||||||
@@ -21,7 +20,6 @@ on:
|
|||||||
paths:
|
paths:
|
||||||
- 'clients/**'
|
- 'clients/**'
|
||||||
- 'common/**'
|
- 'common/**'
|
||||||
- 'contracts/**'
|
|
||||||
- 'explorer-api/**'
|
- 'explorer-api/**'
|
||||||
- 'gateway/**'
|
- 'gateway/**'
|
||||||
- 'integrations/**'
|
- 'integrations/**'
|
||||||
@@ -57,7 +55,7 @@ jobs:
|
|||||||
echo $OUTPUT_DIR
|
echo $OUTPUT_DIR
|
||||||
|
|
||||||
- name: Install Dependencies (Linux)
|
- name: Install Dependencies (Linux)
|
||||||
run: sudo apt-get update && sudo apt-get -y install libwebkit2gtk-4.0-dev build-essential curl wget libssl-dev libgtk-3-dev libudev-dev squashfs-tools
|
run: sudo apt-get update && sudo apt-get -y install libwebkit2gtk-4.0-dev build-essential curl wget libssl-dev libgtk-3-dev libudev-dev squashfs-tools protobuf-compiler
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
|
|
||||||
- name: Install Rust stable
|
- name: Install Rust stable
|
||||||
@@ -69,18 +67,7 @@ jobs:
|
|||||||
uses: actions-rs/cargo@v1
|
uses: actions-rs/cargo@v1
|
||||||
with:
|
with:
|
||||||
command: build
|
command: build
|
||||||
args: --workspace --release --all
|
args: --workspace --release
|
||||||
|
|
||||||
- name: Install Rust stable
|
|
||||||
uses: actions-rs/toolchain@v1
|
|
||||||
with:
|
|
||||||
toolchain: stable
|
|
||||||
target: wasm32-unknown-unknown
|
|
||||||
override: true
|
|
||||||
components: rustfmt, clippy
|
|
||||||
|
|
||||||
- name: Build release contracts
|
|
||||||
run: make wasm
|
|
||||||
|
|
||||||
- name: Prepare build output
|
- name: Prepare build output
|
||||||
shell: bash
|
shell: bash
|
||||||
@@ -95,10 +82,7 @@ jobs:
|
|||||||
cp target/release/nym-network-requester $OUTPUT_DIR
|
cp target/release/nym-network-requester $OUTPUT_DIR
|
||||||
cp target/release/nym-network-statistics $OUTPUT_DIR
|
cp target/release/nym-network-statistics $OUTPUT_DIR
|
||||||
cp target/release/nym-cli $OUTPUT_DIR
|
cp target/release/nym-cli $OUTPUT_DIR
|
||||||
cp target/release/credential $OUTPUT_DIR
|
cp target/release/explorer-api $OUTPUT_DIR
|
||||||
|
|
||||||
cp contracts/target/wasm32-unknown-unknown/release/mixnet_contract.wasm $OUTPUT_DIR
|
|
||||||
cp contracts/target/wasm32-unknown-unknown/release/vesting_contract.wasm $OUTPUT_DIR
|
|
||||||
|
|
||||||
- name: Deploy branch to CI www
|
- name: Deploy branch to CI www
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
name: Continuous integration
|
name: ci-build
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
@@ -6,29 +6,37 @@ on:
|
|||||||
- 'clients/**'
|
- 'clients/**'
|
||||||
- 'common/**'
|
- 'common/**'
|
||||||
- 'explorer-api/**'
|
- 'explorer-api/**'
|
||||||
|
- 'ephemera/**'
|
||||||
- 'gateway/**'
|
- 'gateway/**'
|
||||||
- 'integrations/**'
|
- 'integrations/**'
|
||||||
- 'mixnode/**'
|
- 'mixnode/**'
|
||||||
|
- 'sdk/lib/socks5-listener/**'
|
||||||
- 'sdk/rust/nym-sdk/**'
|
- 'sdk/rust/nym-sdk/**'
|
||||||
- 'service-providers/**'
|
- 'service-providers/**'
|
||||||
- 'nym-api/**'
|
- 'nym-api/**'
|
||||||
- 'nym-outfox/**'
|
- 'nym-outfox/**'
|
||||||
- 'tools/nym-cli/**'
|
- 'tools/nym-cli/**'
|
||||||
|
- 'tools/nym-nr-query/**'
|
||||||
- 'tools/ts-rs-cli/**'
|
- 'tools/ts-rs-cli/**'
|
||||||
|
- 'Cargo.toml'
|
||||||
pull_request:
|
pull_request:
|
||||||
paths:
|
paths:
|
||||||
- 'clients/**'
|
- 'clients/**'
|
||||||
- 'common/**'
|
- 'common/**'
|
||||||
- 'explorer-api/**'
|
- 'explorer-api/**'
|
||||||
|
- 'ephemera/**'
|
||||||
- 'gateway/**'
|
- 'gateway/**'
|
||||||
- 'integrations/**'
|
- 'integrations/**'
|
||||||
- 'mixnode/**'
|
- 'mixnode/**'
|
||||||
|
- 'sdk/lib/socks5-listener/**'
|
||||||
- 'sdk/rust/nym-sdk/**'
|
- 'sdk/rust/nym-sdk/**'
|
||||||
- 'service-providers/**'
|
- 'service-providers/**'
|
||||||
- 'nym-api/**'
|
- 'nym-api/**'
|
||||||
- 'nym-outfox/**'
|
- 'nym-outfox/**'
|
||||||
- 'tools/nym-cli/**'
|
- 'tools/nym-cli/**'
|
||||||
|
- 'tools/nym-nr-query/**'
|
||||||
- 'tools/ts-rs-cli/**'
|
- 'tools/ts-rs-cli/**'
|
||||||
|
- 'Cargo.toml'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
@@ -38,7 +46,7 @@ jobs:
|
|||||||
RUSTC_WRAPPER: /home/ubuntu/.cargo/bin/sccache
|
RUSTC_WRAPPER: /home/ubuntu/.cargo/bin/sccache
|
||||||
steps:
|
steps:
|
||||||
- name: Install Dependencies (Linux)
|
- name: Install Dependencies (Linux)
|
||||||
run: sudo apt-get update && sudo apt-get -y install libwebkit2gtk-4.0-dev build-essential curl wget libssl-dev libgtk-3-dev libudev-dev squashfs-tools
|
run: sudo apt-get update && sudo apt-get -y install libwebkit2gtk-4.0-dev build-essential curl wget libssl-dev libgtk-3-dev libudev-dev squashfs-tools protobuf-compiler
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
|
|
||||||
- name: Check out repository code
|
- name: Check out repository code
|
||||||
@@ -83,14 +91,14 @@ jobs:
|
|||||||
command: test
|
command: test
|
||||||
args: --workspace -- --ignored
|
args: --workspace -- --ignored
|
||||||
|
|
||||||
- uses: actions-rs/clippy-check@v1
|
- name: Annotate with clippy checks
|
||||||
name: Clippy checks
|
uses: actions-rs/clippy-check@v1
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
args: --workspace
|
args: --workspace
|
||||||
|
|
||||||
- name: Run clippy
|
- name: Clippy
|
||||||
uses: actions-rs/cargo@v1
|
uses: actions-rs/cargo@v1
|
||||||
with:
|
with:
|
||||||
command: clippy
|
command: clippy
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
name: ci-contracts-schema
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
paths:
|
||||||
|
- 'contracts/**'
|
||||||
|
- 'common/**'
|
||||||
|
pull_request:
|
||||||
|
paths:
|
||||||
|
- 'contracts/**'
|
||||||
|
- 'common/**'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
check-schema:
|
||||||
|
name: Generate and check schema
|
||||||
|
runs-on: custom-runner-linux
|
||||||
|
steps:
|
||||||
|
- name: Check out repository code
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Install Rust toolchain
|
||||||
|
uses: actions-rs/toolchain@v1
|
||||||
|
with:
|
||||||
|
toolchain: stable
|
||||||
|
|
||||||
|
|
||||||
|
- name: Generate the schema
|
||||||
|
run: make contract-schema
|
||||||
|
|
||||||
|
- name: Check for diff
|
||||||
|
run: git diff --exit-code -- contracts/*/schema
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
name: ci-contracts-upload-binaries
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
push:
|
||||||
|
paths:
|
||||||
|
- 'common/**'
|
||||||
|
- 'contracts/**'
|
||||||
|
pull_request:
|
||||||
|
paths:
|
||||||
|
- 'common/**'
|
||||||
|
- 'contracts/**'
|
||||||
|
|
||||||
|
env:
|
||||||
|
NETWORK: mainnet
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
publish-nym-contracts:
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
platform: [ubuntu-20.04]
|
||||||
|
|
||||||
|
runs-on: ${{ matrix.platform }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Prepare build output directory
|
||||||
|
shell: bash
|
||||||
|
env:
|
||||||
|
OUTPUT_DIR: ci-contract-builds/${{ github.ref_name }}
|
||||||
|
run: |
|
||||||
|
rm -rf ci-contract-builds || true
|
||||||
|
mkdir -p $OUTPUT_DIR
|
||||||
|
echo $OUTPUT_DIR
|
||||||
|
|
||||||
|
- name: Install Dependencies (Linux)
|
||||||
|
run: sudo apt-get update && sudo apt-get -y install libwebkit2gtk-4.0-dev build-essential curl wget libssl-dev libgtk-3-dev libudev-dev squashfs-tools protobuf-compiler
|
||||||
|
continue-on-error: true
|
||||||
|
|
||||||
|
- name: Install Rust stable
|
||||||
|
uses: actions-rs/toolchain@v1
|
||||||
|
with:
|
||||||
|
toolchain: 1.69.0
|
||||||
|
target: wasm32-unknown-unknown
|
||||||
|
override: true
|
||||||
|
|
||||||
|
- name: Install wasm-opt
|
||||||
|
run: cargo install --version 0.112.0 wasm-opt
|
||||||
|
|
||||||
|
- name: Build release contracts
|
||||||
|
run: make contracts-wasm
|
||||||
|
|
||||||
|
- name: Prepare build output
|
||||||
|
shell: bash
|
||||||
|
env:
|
||||||
|
OUTPUT_DIR: ci-contract-builds/${{ github.ref_name }}
|
||||||
|
run: |
|
||||||
|
cp contracts/target/wasm32-unknown-unknown/release/mixnet_contract.wasm $OUTPUT_DIR
|
||||||
|
cp contracts/target/wasm32-unknown-unknown/release/vesting_contract.wasm $OUTPUT_DIR
|
||||||
|
cp contracts/target/wasm32-unknown-unknown/release/nym_coconut_bandwidth.wasm $OUTPUT_DIR
|
||||||
|
cp contracts/target/wasm32-unknown-unknown/release/nym_coconut_dkg.wasm $OUTPUT_DIR
|
||||||
|
cp contracts/target/wasm32-unknown-unknown/release/cw3_flex_multisig.wasm $OUTPUT_DIR
|
||||||
|
cp contracts/target/wasm32-unknown-unknown/release/cw4_group.wasm $OUTPUT_DIR
|
||||||
|
cp contracts/target/wasm32-unknown-unknown/release/nym_service_provider_directory.wasm $OUTPUT_DIR
|
||||||
|
cp contracts/target/wasm32-unknown-unknown/release/nym_name_service.wasm $OUTPUT_DIR
|
||||||
|
cp contracts/target/wasm32-unknown-unknown/release/nym_ephemera.wasm $OUTPUT_DIR
|
||||||
|
|
||||||
|
- name: Deploy branch to CI www
|
||||||
|
continue-on-error: true
|
||||||
|
uses: easingthemes/ssh-deploy@main
|
||||||
|
env:
|
||||||
|
SSH_PRIVATE_KEY: ${{ secrets.CI_WWW_SSH_PRIVATE_KEY }}
|
||||||
|
ARGS: "-avzr"
|
||||||
|
SOURCE: "ci-contract-builds/"
|
||||||
|
REMOTE_HOST: ${{ secrets.CI_WWW_REMOTE_HOST }}
|
||||||
|
REMOTE_USER: ${{ secrets.CI_WWW_REMOTE_USER }}
|
||||||
|
TARGET: ${{ secrets.CI_WWW_REMOTE_TARGET }}/builds/
|
||||||
|
EXCLUDE: "/dist/, /node_modules/"
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
name: Contracts
|
name: ci-contracts
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
@@ -16,20 +16,21 @@ jobs:
|
|||||||
outputs:
|
outputs:
|
||||||
matrix: ${{ steps.set-matrix.outputs.matrix }}
|
matrix: ${{ steps.set-matrix.outputs.matrix }}
|
||||||
steps:
|
steps:
|
||||||
# creates the matrix strategy from build_matrix_includes.json
|
# creates the matrix strategy from ci-contracts-matrix-includes.json
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- id: set-matrix
|
- id: set-matrix
|
||||||
uses: JoshuaTheMiller/conditional-build-matrix@main
|
uses: JoshuaTheMiller/conditional-build-matrix@main
|
||||||
with:
|
with:
|
||||||
inputFile: '.github/workflows/contract_matrix_includes.json'
|
inputFile: '.github/workflows/ci-contracts-matrix-includes.json'
|
||||||
filter: '[?runOnEvent==`${{ github.event_name }}` || runOnEvent==`always`]'
|
filter: '[?runOnEvent==`${{ github.event_name }}` || runOnEvent==`always`]'
|
||||||
contracts:
|
build:
|
||||||
# since it's going to be compiled into wasm, there's absolutely
|
# since it's going to be compiled into wasm, there's absolutely
|
||||||
# no point in running CI on different OS-es
|
# no point in running CI on different OS-es
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
continue-on-error: ${{ matrix.rust == 'nightly' }}
|
continue-on-error: ${{ matrix.rust == 'nightly' }}
|
||||||
needs: matrix_prep
|
needs: matrix_prep
|
||||||
strategy:
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
matrix: ${{fromJson(needs.matrix_prep.outputs.matrix)}}
|
matrix: ${{fromJson(needs.matrix_prep.outputs.matrix)}}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
@@ -47,12 +48,12 @@ jobs:
|
|||||||
RUSTFLAGS: '-C link-arg=-s'
|
RUSTFLAGS: '-C link-arg=-s'
|
||||||
with:
|
with:
|
||||||
command: build
|
command: build
|
||||||
args: --manifest-path contracts/Cargo.toml --workspace --target wasm32-unknown-unknown
|
args: --manifest-path contracts/Cargo.toml --workspace --lib --target wasm32-unknown-unknown
|
||||||
|
|
||||||
- uses: actions-rs/cargo@v1
|
- uses: actions-rs/cargo@v1
|
||||||
with:
|
with:
|
||||||
command: test
|
command: test
|
||||||
args: --manifest-path contracts/Cargo.toml
|
args: --lib --manifest-path contracts/Cargo.toml
|
||||||
|
|
||||||
- uses: actions-rs/cargo@v1
|
- uses: actions-rs/cargo@v1
|
||||||
with:
|
with:
|
||||||
@@ -63,4 +64,4 @@ jobs:
|
|||||||
if: ${{ matrix.rust != 'nightly' }}
|
if: ${{ matrix.rust != 'nightly' }}
|
||||||
with:
|
with:
|
||||||
command: clippy
|
command: clippy
|
||||||
args: --manifest-path contracts/Cargo.toml --workspace -- -D warnings
|
args: --lib --manifest-path contracts/Cargo.toml --workspace --all-targets -- -D warnings
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
name: ci-docs
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
push:
|
||||||
|
branches-ignore: master
|
||||||
|
paths:
|
||||||
|
- 'documentation/docs/**'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: custom-runner-linux
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- name: Install rsync
|
||||||
|
run: sudo apt-get install rsync
|
||||||
|
- uses: rlespinasse/github-slug-action@v3.x
|
||||||
|
- uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: 18
|
||||||
|
- name: Install Rust stable
|
||||||
|
uses: actions-rs/toolchain@v1
|
||||||
|
with:
|
||||||
|
toolchain: stable
|
||||||
|
- name: Build all binaries
|
||||||
|
uses: actions-rs/cargo@v1
|
||||||
|
with:
|
||||||
|
command: build
|
||||||
|
args: --workspace --release --all
|
||||||
|
- name: Install mdbook
|
||||||
|
run: (test -x $HOME/.cargo/bin/mdbook || cargo install --vers "^0.4.33" mdbook)
|
||||||
|
- name: Install mdbook plugins
|
||||||
|
run: |
|
||||||
|
cargo install --vers "=0.2.2" mdbook-variables && cargo install \
|
||||||
|
--vers "^1.8.0" mdbook-admonish && cargo install --vers \
|
||||||
|
"^0.1.2" mdbook-last-changed && cargo install --vers "^0.1.2" mdbook-theme \
|
||||||
|
&& cargo install --vers "^0.7.7" mdbook-linkcheck
|
||||||
|
- name: Build all projects in documentation/ & move to ~/dist/docs/
|
||||||
|
run: cd documentation && ./build_all_to_dist.sh
|
||||||
|
continue-on-error: false
|
||||||
|
- name: Deploy branch to CI www
|
||||||
|
continue-on-error: true
|
||||||
|
uses: easingthemes/ssh-deploy@main
|
||||||
|
env:
|
||||||
|
SSH_PRIVATE_KEY: ${{ secrets.CI_WWW_SSH_PRIVATE_KEY }}
|
||||||
|
ARGS: "-rltgoDzvO --delete"
|
||||||
|
SOURCE: "dist/docs/"
|
||||||
|
REMOTE_HOST: ${{ secrets.CI_WWW_REMOTE_HOST }}
|
||||||
|
REMOTE_USER: ${{ secrets.CI_WWW_REMOTE_USER }}
|
||||||
|
TARGET: ${{ secrets.CI_WWW_REMOTE_TARGET }}/docs-${{ env.GITHUB_REF_SLUG }}
|
||||||
|
EXCLUDE: "/node_modules/"
|
||||||
|
- name: Matrix - Node Install
|
||||||
|
run: npm install
|
||||||
|
working-directory: .github/workflows/support-files
|
||||||
|
- name: Matrix - Send Notification
|
||||||
|
env:
|
||||||
|
NYM_NOTIFICATION_KIND: ci-docs
|
||||||
|
NYM_PROJECT_NAME: "Docs CI"
|
||||||
|
NYM_CI_WWW_BASE: "${{ secrets.NYM_CI_WWW_BASE }}"
|
||||||
|
NYM_CI_WWW_LOCATION: "docs-${{ env.GITHUB_REF_SLUG }}"
|
||||||
|
GIT_COMMIT_MESSAGE: "${{ github.event.head_commit.message }}"
|
||||||
|
GIT_BRANCH: "${GITHUB_REF##*/}"
|
||||||
|
MATRIX_SERVER: "${{ secrets.MATRIX_SERVER }}"
|
||||||
|
MATRIX_ROOM: "${{ secrets.MATRIX_ROOM_DOCS }}"
|
||||||
|
MATRIX_USER_ID: "${{ secrets.MATRIX_USER_ID }}"
|
||||||
|
MATRIX_TOKEN: "${{ secrets.MATRIX_TOKEN }}"
|
||||||
|
MATRIX_DEVICE_ID: "${{ secrets.MATRIX_DEVICE_ID }}"
|
||||||
|
IS_SUCCESS: "${{ job.status == 'success' }}"
|
||||||
|
uses: docker://keybaseio/client:stable-node
|
||||||
|
with:
|
||||||
|
args: .github/workflows/support-files/notifications/entry_point.sh
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
name: ci-lint-typescript
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
paths:
|
||||||
|
- "ts-packages/**"
|
||||||
|
- "sdk/typescript/**"
|
||||||
|
- "nym-connect/desktop/src/**"
|
||||||
|
- "nym-connect/desktop/package.json"
|
||||||
|
- "nym-wallet/src/**"
|
||||||
|
- "nym-wallet/package.json"
|
||||||
|
- "explorer/**"
|
||||||
|
pull_request:
|
||||||
|
paths:
|
||||||
|
- "ts-packages/**"
|
||||||
|
- "sdk/typescript/**"
|
||||||
|
- "nym-connect/desktop/src/**"
|
||||||
|
- "nym-connect/desktop/package.json"
|
||||||
|
- "nym-wallet/src/**"
|
||||||
|
- "nym-wallet/package.json"
|
||||||
|
- "explorer/**"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: custom-runner-linux
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: rlespinasse/github-slug-action@v3.x
|
||||||
|
|
||||||
|
- uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: 18
|
||||||
|
- name: Setup yarn
|
||||||
|
run: npm install -g yarn
|
||||||
|
|
||||||
|
- name: Install Rust stable
|
||||||
|
uses: actions-rs/toolchain@v1
|
||||||
|
with:
|
||||||
|
toolchain: stable
|
||||||
|
- name: Install wasm-pack
|
||||||
|
run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
|
||||||
|
|
||||||
|
- name: Set up Go
|
||||||
|
uses: actions/setup-go@v4
|
||||||
|
with:
|
||||||
|
go-version: '1.20'
|
||||||
|
|
||||||
|
- name: Install
|
||||||
|
run: yarn
|
||||||
|
|
||||||
|
- name: Build packages
|
||||||
|
run: yarn build:ci:sdk
|
||||||
|
|
||||||
|
- name: Lint
|
||||||
|
run: yarn lint
|
||||||
|
- name: Typecheck with tsc
|
||||||
|
run: yarn tsc
|
||||||
|
|
||||||
|
- name: Matrix - Node Install
|
||||||
|
run: npm install
|
||||||
|
working-directory: .github/workflows/support-files
|
||||||
|
- name: Matrix - Send Notification
|
||||||
|
env:
|
||||||
|
NYM_NOTIFICATION_KIND: ts-packages
|
||||||
|
NYM_PROJECT_NAME: "ts-packages"
|
||||||
|
NYM_CI_WWW_BASE: "${{ secrets.NYM_CI_WWW_BASE }}"
|
||||||
|
NYM_CI_WWW_LOCATION: "ts-${{ env.GITHUB_REF_SLUG }}"
|
||||||
|
GIT_COMMIT_MESSAGE: "${{ github.event.head_commit.message }}"
|
||||||
|
GIT_BRANCH: "${GITHUB_REF##*/}"
|
||||||
|
IS_SUCCESS: "${{ job.status == 'success' }}"
|
||||||
|
MATRIX_SERVER: "${{ secrets.MATRIX_SERVER }}"
|
||||||
|
MATRIX_ROOM: "${{ secrets.MATRIX_ROOM }}"
|
||||||
|
MATRIX_USER_ID: "${{ secrets.MATRIX_USER_ID }}"
|
||||||
|
MATRIX_TOKEN: "${{ secrets.MATRIX_TOKEN }}"
|
||||||
|
MATRIX_DEVICE_ID: "${{ secrets.MATRIX_DEVICE_ID }}"
|
||||||
|
uses: docker://keybaseio/client:stable-node
|
||||||
|
with:
|
||||||
|
args: .github/workflows/support-files/notifications/entry_point.sh
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
name: Nym Connect - desktop (Rust)
|
name: ci-nym-connect-desktop-rust
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
+14
-3
@@ -1,4 +1,4 @@
|
|||||||
name: CI for nym-connect - Desktop
|
name: ci-nym-connect-desktop
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
@@ -20,11 +20,22 @@ jobs:
|
|||||||
- uses: rlespinasse/github-slug-action@v3.x
|
- uses: rlespinasse/github-slug-action@v3.x
|
||||||
- uses: actions/setup-node@v3
|
- uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: 16
|
node-version: 18
|
||||||
- name: Install Yarn
|
- name: Install Yarn
|
||||||
run: npm install -g yarn
|
run: npm install -g yarn
|
||||||
- run: yarn
|
- name: Install Rust stable
|
||||||
|
uses: actions-rs/toolchain@v1
|
||||||
|
with:
|
||||||
|
toolchain: stable
|
||||||
|
- name: Install wasm-pack
|
||||||
|
run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
|
||||||
|
- name: Install project dependencies
|
||||||
|
run: cd ../.. && yarn --network-timeout 100000
|
||||||
|
|
||||||
|
- name: Install app dependencies
|
||||||
|
run: yarn
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
|
|
||||||
- name: Set environment from the example
|
- name: Set environment from the example
|
||||||
run: cp .env.sample .env
|
run: cp .env.sample .env
|
||||||
- run: yarn storybook:build
|
- run: yarn storybook:build
|
||||||
+2
-2
@@ -1,4 +1,4 @@
|
|||||||
name: CI for Network Explorer
|
name: ci-nym-network-explorer
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
@@ -21,7 +21,7 @@ jobs:
|
|||||||
- uses: rlespinasse/github-slug-action@v3.x
|
- uses: rlespinasse/github-slug-action@v3.x
|
||||||
- uses: actions/setup-node@v3
|
- uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: 16
|
node-version: 18
|
||||||
- name: Setup yarn
|
- name: Setup yarn
|
||||||
run: npm install -g yarn
|
run: npm install -g yarn
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
name: Nym Wallet (rust)
|
name: ci-nym-wallet-rust
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
@@ -31,7 +31,7 @@ jobs:
|
|||||||
uses: actions-rs/toolchain@v1
|
uses: actions-rs/toolchain@v1
|
||||||
with:
|
with:
|
||||||
profile: minimal
|
profile: minimal
|
||||||
toolchain: stable
|
toolchain: 1.71.0
|
||||||
override: true
|
override: true
|
||||||
components: rustfmt, clippy
|
components: rustfmt, clippy
|
||||||
|
|
||||||
@@ -64,4 +64,4 @@ jobs:
|
|||||||
uses: actions-rs/cargo@v1
|
uses: actions-rs/cargo@v1
|
||||||
with:
|
with:
|
||||||
command: clippy
|
command: clippy
|
||||||
args: --manifest-path nym-wallet/Cargo.toml --workspace --all-features -- -D warnings
|
args: --manifest-path nym-wallet/Cargo.toml --workspace --all-features --all-targets -- -D warnings
|
||||||
+7
-1
@@ -16,9 +16,15 @@ jobs:
|
|||||||
- uses: rlespinasse/github-slug-action@v3.x
|
- uses: rlespinasse/github-slug-action@v3.x
|
||||||
- uses: actions/setup-node@v3
|
- uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: 16
|
node-version: 18
|
||||||
- name: Setup yarn
|
- name: Setup yarn
|
||||||
run: npm install -g yarn
|
run: npm install -g yarn
|
||||||
|
- name: Install Rust stable
|
||||||
|
uses: actions-rs/toolchain@v1
|
||||||
|
with:
|
||||||
|
toolchain: stable
|
||||||
|
- name: Install wasm-pack
|
||||||
|
run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
|
||||||
- name: Build dependencies
|
- name: Build dependencies
|
||||||
run: yarn && yarn build
|
run: yarn && yarn build
|
||||||
- name: Build storybook
|
- name: Build storybook
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
name: ci-sdk-docs-typescript
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
paths:
|
||||||
|
- "sdk/typescript/**"
|
||||||
|
- "wasm/**"
|
||||||
|
pull_request:
|
||||||
|
paths:
|
||||||
|
- "sdk/typescript/**"
|
||||||
|
- "wasm/**"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: custom-runner-linux
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Install rsync
|
||||||
|
run: sudo apt-get install rsync
|
||||||
|
continue-on-error: true
|
||||||
|
- uses: rlespinasse/github-slug-action@v3.x
|
||||||
|
- uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: 18
|
||||||
|
- name: Install Rust stable
|
||||||
|
uses: actions-rs/toolchain@v1
|
||||||
|
with:
|
||||||
|
toolchain: stable
|
||||||
|
- name: Setup yarn
|
||||||
|
run: npm install -g yarn
|
||||||
|
|
||||||
|
- name: Set up Go
|
||||||
|
uses: actions/setup-go@v4
|
||||||
|
with:
|
||||||
|
go-version: '1.20'
|
||||||
|
|
||||||
|
- name: Build branch WASM packages
|
||||||
|
run: make sdk-wasm-build
|
||||||
|
|
||||||
|
- name: Install
|
||||||
|
run: yarn
|
||||||
|
- name: Build
|
||||||
|
run: yarn docs:prod:build
|
||||||
|
- name: Deploy branch to CI www (docs)
|
||||||
|
continue-on-error: true
|
||||||
|
uses: easingthemes/ssh-deploy@main
|
||||||
|
env:
|
||||||
|
SSH_PRIVATE_KEY: ${{ secrets.CI_WWW_SSH_PRIVATE_KEY }}
|
||||||
|
ARGS: "-rltgoDzvO --delete"
|
||||||
|
SOURCE: "dist/ts/"
|
||||||
|
REMOTE_HOST: ${{ secrets.CI_WWW_REMOTE_HOST }}
|
||||||
|
REMOTE_USER: ${{ secrets.CI_WWW_REMOTE_USER }}
|
||||||
|
TARGET: ${{ secrets.CI_WWW_REMOTE_TARGET }}/sdk-ts-docs-${{ env.GITHUB_REF_SLUG }}
|
||||||
|
EXCLUDE: "/dist/, /node_modules/"
|
||||||
|
- name: Matrix - Node Install
|
||||||
|
run: npm install
|
||||||
|
working-directory: .github/workflows/support-files
|
||||||
|
- name: Matrix - Send Notification
|
||||||
|
env:
|
||||||
|
NYM_NOTIFICATION_KIND: ts-packages
|
||||||
|
NYM_PROJECT_NAME: "sdk-ts-docs"
|
||||||
|
NYM_CI_WWW_BASE: "${{ secrets.NYM_CI_WWW_BASE }}/docs/sdk/typescript"
|
||||||
|
NYM_CI_WWW_LOCATION: "sdk-ts-docs-${{ env.GITHUB_REF_SLUG }}"
|
||||||
|
GIT_COMMIT_MESSAGE: "${{ github.event.head_commit.message }}"
|
||||||
|
GIT_BRANCH: "${GITHUB_REF##*/}"
|
||||||
|
IS_SUCCESS: "${{ job.status == 'success' }}"
|
||||||
|
MATRIX_SERVER: "${{ secrets.MATRIX_SERVER }}"
|
||||||
|
MATRIX_ROOM: "${{ secrets.MATRIX_ROOM }}"
|
||||||
|
MATRIX_USER_ID: "${{ secrets.MATRIX_USER_ID }}"
|
||||||
|
MATRIX_TOKEN: "${{ secrets.MATRIX_TOKEN }}"
|
||||||
|
MATRIX_DEVICE_ID: "${{ secrets.MATRIX_DEVICE_ID }}"
|
||||||
|
uses: docker://keybaseio/client:stable-node
|
||||||
|
with:
|
||||||
|
args: .github/workflows/support-files/notifications/entry_point.sh
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
name: ci-sdk-wasm
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
paths:
|
||||||
|
- 'wasm/**'
|
||||||
|
- 'clients/client-core/**'
|
||||||
|
- 'common/**'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
wasm:
|
||||||
|
runs-on: [custom-runner-linux]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: 18
|
||||||
|
|
||||||
|
- uses: actions-rs/toolchain@v1
|
||||||
|
with:
|
||||||
|
profile: minimal
|
||||||
|
toolchain: stable
|
||||||
|
target: wasm32-unknown-unknown
|
||||||
|
override: true
|
||||||
|
components: rustfmt, clippy
|
||||||
|
|
||||||
|
- name: Set up Go
|
||||||
|
uses: actions/setup-go@v4
|
||||||
|
with:
|
||||||
|
go-version: '1.20'
|
||||||
|
|
||||||
|
|
||||||
|
- name: Install wasm-pack
|
||||||
|
run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
|
||||||
|
|
||||||
|
- name: Install wasm-opt
|
||||||
|
run: cargo install wasm-opt
|
||||||
|
|
||||||
|
- name: Install wasm-bindgen-cli
|
||||||
|
run: cargo install wasm-bindgen-cli
|
||||||
|
|
||||||
|
- name: "Build"
|
||||||
|
run: make sdk-wasm-build
|
||||||
|
|
||||||
|
- name: "Test"
|
||||||
|
run: make sdk-wasm-test
|
||||||
|
|
||||||
|
- name: "Lint"
|
||||||
|
run: make sdk-wasm-lint
|
||||||
@@ -1,138 +0,0 @@
|
|||||||
name: Nym Connect - Android APK Build
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_dispatch:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- "release/nc-android-v[0-9].[0-9].[0-9]*"
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
name: Build APK
|
|
||||||
runs-on: custom-runner-linux
|
|
||||||
env:
|
|
||||||
ANDROID_HOME: ${{ github.workspace }}/android-sdk
|
|
||||||
NDK_VERSION: 25.1.8937393
|
|
||||||
NDK_HOME: ${{ github.workspace }}/android-sdk/ndk/25.1.8937393
|
|
||||||
SDK_PLATFORM_VERSION: android-33
|
|
||||||
SDK_BUILDTOOLS_VERSION: 33.0.1
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Install Dependencies (Linux)
|
|
||||||
# https://next--tauri.netlify.app/next/guides/getting-started/prerequisites/linux/#1-system-dependencies
|
|
||||||
run: |
|
|
||||||
sudo apt-get update
|
|
||||||
sudo apt-get -y install \
|
|
||||||
build-essential \
|
|
||||||
unzip \
|
|
||||||
curl \
|
|
||||||
wget \
|
|
||||||
libssl-dev \
|
|
||||||
squashfs-tools \
|
|
||||||
librsvg2-dev
|
|
||||||
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
|
|
||||||
- name: Install Java
|
|
||||||
uses: actions/setup-java@v3
|
|
||||||
with:
|
|
||||||
distribution: "temurin"
|
|
||||||
java-version: "17"
|
|
||||||
|
|
||||||
- name: Install Android SDK manager
|
|
||||||
# https://developer.android.com/studio/command-line/sdkmanager
|
|
||||||
run: |
|
|
||||||
curl -sS https://dl.google.com/android/repository/commandlinetools-linux-9477386_latest.zip -o cmdline-tools.zip
|
|
||||||
unzip cmdline-tools.zip
|
|
||||||
mkdir -p $ANDROID_HOME/cmdline-tools/latest
|
|
||||||
mv cmdline-tools/* $ANDROID_HOME/cmdline-tools/latest
|
|
||||||
rm -rf cmdline-tools
|
|
||||||
|
|
||||||
- name: Install Android S/NDK
|
|
||||||
run: |
|
|
||||||
echo y | $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager --licenses
|
|
||||||
echo y | $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager \
|
|
||||||
"platforms;$SDK_PLATFORM_VERSION" \
|
|
||||||
"platform-tools" \
|
|
||||||
"ndk;$NDK_VERSION" \
|
|
||||||
"build-tools;$SDK_BUILDTOOLS_VERSION"
|
|
||||||
|
|
||||||
- name: Install Rust toolchain
|
|
||||||
uses: dtolnay/rust-toolchain@stable
|
|
||||||
|
|
||||||
# TODO this step takes a considerable amount of time
|
|
||||||
# We could avoid to compile from source tauri-cli and use instead
|
|
||||||
# pre-compiled binary provided by the node package `@tauri-apps/cli`
|
|
||||||
# But when using the later the build fails for some reason
|
|
||||||
# so keep installing and using tauri-cli
|
|
||||||
- name: Install tauri cli
|
|
||||||
run: cargo install tauri-cli --version "^2.0.0-alpha.2"
|
|
||||||
|
|
||||||
- name: Install rust android targets
|
|
||||||
run: |
|
|
||||||
rustup target add aarch64-linux-android \
|
|
||||||
armv7-linux-androideabi \
|
|
||||||
i686-linux-android \
|
|
||||||
x86_64-linux-android
|
|
||||||
|
|
||||||
- name: Setup Nodejs
|
|
||||||
uses: actions/setup-node@v3
|
|
||||||
with:
|
|
||||||
node-version: 18
|
|
||||||
|
|
||||||
- name: Install yarn
|
|
||||||
run: |
|
|
||||||
npm i -g yarn
|
|
||||||
yarn --version
|
|
||||||
|
|
||||||
- name: Build frontend code
|
|
||||||
run: |
|
|
||||||
yarn install --frozen-lockfile
|
|
||||||
yarn build
|
|
||||||
yarn workspace @nym/nym-connect-mobile webpack:prod
|
|
||||||
|
|
||||||
- name: Build APK
|
|
||||||
working-directory: nym-connect/mobile
|
|
||||||
env:
|
|
||||||
# NODE_TAURI_CLI=${{ github.workspace }}/nym-connect/mobile/node_modules/.bin/tauri
|
|
||||||
ANDROID_SDK_ROOT: ${{ env.ANDROID_HOME }}
|
|
||||||
WRY_ANDROID_PACKAGE: net.nymtech.nym_connect
|
|
||||||
WRY_ANDROID_LIBRARY: nym_connect
|
|
||||||
# TODO build with release profile (--release), it will requires
|
|
||||||
# to sign the APK. For now build with debug profile to avoid that
|
|
||||||
# TODO build using `yarn tauri`, provide NODE_TAURI_CLI, see TODO notes above
|
|
||||||
run: cargo tauri android build --debug --apk --split-per-abi -t aarch64
|
|
||||||
|
|
||||||
# TODO add the version number to APK name
|
|
||||||
- name: Rename APK artifact
|
|
||||||
run: |
|
|
||||||
mkdir apk/
|
|
||||||
mv nym-connect/mobile/src-tauri/gen/android/nym_connect/app/build/outputs/apk/arm64/debug/app-arm64-debug.apk \
|
|
||||||
apk/nym-connect-arm64-debug.apk
|
|
||||||
mv nym-connect/mobile/src-tauri/gen/android/nym_connect/app/build/outputs/apk/x86_64/debug/app-x86_64-debug.apk \
|
|
||||||
apk/nym-connect-x86_64-debug.apk
|
|
||||||
|
|
||||||
- name: Upload APK artifact
|
|
||||||
uses: actions/upload-artifact@v3
|
|
||||||
with:
|
|
||||||
name: nc-apk-debug
|
|
||||||
path: |
|
|
||||||
apk/nym-connect-arm64-debug.apk
|
|
||||||
apk/nym-connect-x86_64-debug.apk
|
|
||||||
|
|
||||||
# publish:
|
|
||||||
# name: Publish APK
|
|
||||||
# needs: build
|
|
||||||
# runs-on: ubuntu-latest
|
|
||||||
# steps:
|
|
||||||
# - name: Checkout
|
|
||||||
# uses: actions/checkout@v3
|
|
||||||
# - name: Download binary artifact
|
|
||||||
# uses: actions/download-artifact@v3
|
|
||||||
# with:
|
|
||||||
# name: nc-apk-debug
|
|
||||||
# path: apk
|
|
||||||
# # TODO add a step to upload the APK somewhere
|
|
||||||
# - name: Publish
|
|
||||||
# uses: ???
|
|
||||||
@@ -1,72 +0,0 @@
|
|||||||
name: Nym Connect - mobile (Rust)
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
paths:
|
|
||||||
- "nym-connect/mobile/src-tauri/**"
|
|
||||||
- "nym-connect/mobile/src-tauri/Cargo.toml"
|
|
||||||
- "!nym-connect/mobile/src-tauri/gen/**"
|
|
||||||
- "clients/client-core/**"
|
|
||||||
- "clients/socks5/**"
|
|
||||||
- "common/**"
|
|
||||||
- "gateway/gateway-requests/**"
|
|
||||||
- "contracts/vesting/**"
|
|
||||||
- "nym-api/nym-api-requests/**"
|
|
||||||
pull_request:
|
|
||||||
paths:
|
|
||||||
- "nym-connect/mobile/src-tauri/**"
|
|
||||||
- "nym-connect/mobile/src-tauri/Cargo.toml"
|
|
||||||
- "!nym-connect/mobile/src-tauri/gen/**"
|
|
||||||
- "clients/client-core/**"
|
|
||||||
- "clients/socks5/**"
|
|
||||||
- "common/**"
|
|
||||||
- "gateway/gateway-requests/**"
|
|
||||||
- "contracts/vesting/**"
|
|
||||||
- "nym-api/nym-api-requests/**"
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
#runs-on: [self-hosted, custom-linux]
|
|
||||||
runs-on: ubuntu-22.04
|
|
||||||
#env:
|
|
||||||
#RUSTC_WRAPPER: /home/ubuntu/.cargo/bin/sccache
|
|
||||||
#defaults:
|
|
||||||
#run:
|
|
||||||
#working-directory: nym-connect/mobile/src-tauri/
|
|
||||||
steps:
|
|
||||||
- name: Install Dependencies (Linux)
|
|
||||||
run: |
|
|
||||||
sudo apt-get update
|
|
||||||
sudo apt-get -y install \
|
|
||||||
libwebkit2gtk-4.1-dev \
|
|
||||||
build-essential \
|
|
||||||
curl \
|
|
||||||
wget \
|
|
||||||
libssl-dev \
|
|
||||||
libgtk-3-dev \
|
|
||||||
squashfs-tools \
|
|
||||||
libayatana-appindicator3-dev \
|
|
||||||
librsvg2-dev \
|
|
||||||
libsoup-3.0-dev \
|
|
||||||
libjavascriptcoregtk-4.1-dev
|
|
||||||
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
|
|
||||||
- name: Install Rust toolchain
|
|
||||||
uses: dtolnay/rust-toolchain@master
|
|
||||||
with:
|
|
||||||
toolchain: stable
|
|
||||||
components: clippy, rustfmt
|
|
||||||
|
|
||||||
- name: Check formatting
|
|
||||||
run: cargo fmt --manifest-path nym-connect/mobile/src-tauri/Cargo.toml -- --check
|
|
||||||
|
|
||||||
- name: Build all binaries
|
|
||||||
run: cargo build --manifest-path nym-connect/mobile/src-tauri/Cargo.toml
|
|
||||||
|
|
||||||
- name: Run all tests
|
|
||||||
run: cargo test --manifest-path nym-connect/mobile/src-tauri/Cargo.toml
|
|
||||||
|
|
||||||
- name: Clippy
|
|
||||||
run: cargo clippy --manifest-path nym-connect/mobile/src-tauri/Cargo.toml --all-targets -- -D warnings
|
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
name: Greetings
|
||||||
|
|
||||||
|
on: [pull_request_target, issues]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
greeting:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/first-interaction@v1
|
||||||
|
with:
|
||||||
|
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
issue-message: 'Thank you for raising this issue'
|
||||||
|
pr-message: 'Thank you for making this first PR'
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
name: CI for Network Explorer API
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_dispatch:
|
|
||||||
release:
|
|
||||||
types: [created]
|
|
||||||
|
|
||||||
env:
|
|
||||||
NETWORK: mainnet
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
publish-nym:
|
|
||||||
if: ${{ startsWith(github.ref, 'refs/tags/nym-explorer-api-') && (github.event_name == 'release' || github.event_name == 'workflow_dispatch') }}
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
platform: [ubuntu-20.04]
|
|
||||||
|
|
||||||
runs-on: ${{ matrix.platform }}
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
|
|
||||||
- name: Install Dependencies (Linux)
|
|
||||||
run: sudo apt-get update && sudo apt-get -y install libwebkit2gtk-4.0-dev build-essential curl wget libssl-dev libgtk-3-dev libudev-dev squashfs-tools
|
|
||||||
continue-on-error: true
|
|
||||||
|
|
||||||
- name: Check the release tag starts with `nym-explorer-api-`
|
|
||||||
uses: actions/github-script@v3
|
|
||||||
with:
|
|
||||||
script: |
|
|
||||||
core.setFailed('Release tag did not start with nym-explorer-api-...')
|
|
||||||
|
|
||||||
- name: Install Rust stable
|
|
||||||
uses: actions-rs/toolchain@v1
|
|
||||||
with:
|
|
||||||
toolchain: stable
|
|
||||||
|
|
||||||
- name: Build all explorer-api
|
|
||||||
uses: actions-rs/cargo@v1
|
|
||||||
with:
|
|
||||||
command: build
|
|
||||||
args: --manifest-path explorer-api/Cargo.toml --workspace --release
|
|
||||||
|
|
||||||
- name: Upload Artifact
|
|
||||||
uses: actions/upload-artifact@v3
|
|
||||||
with:
|
|
||||||
name: my-artifact
|
|
||||||
path: |
|
|
||||||
target/release/explorer-api
|
|
||||||
retention-days: 30
|
|
||||||
|
|
||||||
- name: Upload to release based on tag name
|
|
||||||
uses: softprops/action-gh-release@v1
|
|
||||||
if: github.event_name == 'release'
|
|
||||||
with:
|
|
||||||
files: |
|
|
||||||
target/release/explorer-api
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
name: Linting for Network Explorer (eslint/prettier)
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
paths:
|
|
||||||
- 'explorer/**'
|
|
||||||
|
|
||||||
defaults:
|
|
||||||
run:
|
|
||||||
working-directory: explorer
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: custom-runner-linux
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- uses: actions/setup-node@v3
|
|
||||||
with:
|
|
||||||
node-version: 16
|
|
||||||
- name: Setup yarn
|
|
||||||
run: npm install -g yarn
|
|
||||||
- name: Run ESLint
|
|
||||||
# GitHub should automatically annotate the PR
|
|
||||||
run: yarn && yarn lint
|
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
name: check-merge-conflicts
|
name: nightly-check-merge-conflicts
|
||||||
|
|
||||||
# Check that the latest release branch merges into master and develop without
|
# Check that the latest release branch merges into master and develop without
|
||||||
# any conflicts that git is not able to resolve
|
# any conflicts that git is not able to resolve
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
name: nightly-nym-wallet-build
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
schedule:
|
||||||
|
- cron: '14 1 * * *'
|
||||||
|
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
working-directory: nym-wallet
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
os: [ubuntu-20.04, macos-latest, windows10]
|
||||||
|
fail-fast: false
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
steps:
|
||||||
|
- name: Install Dependencies (Linux)
|
||||||
|
run: sudo apt-get update && sudo apt-get install libwebkit2gtk-4.0-dev build-essential curl wget libssl-dev libgtk-3-dev libudev-dev squashfs-tools protobuf-compiler
|
||||||
|
continue-on-error: true
|
||||||
|
if: matrix.os == 'ubuntu-20.04'
|
||||||
|
|
||||||
|
- name: Check out repository code
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Install rust toolchain
|
||||||
|
uses: actions-rs/toolchain@v1
|
||||||
|
with:
|
||||||
|
profile: minimal
|
||||||
|
# There is an issue with 1.72.0 where clippy crashes on nym-wallet-types. Pin to 1.71.0 for now
|
||||||
|
toolchain: 1.71.0
|
||||||
|
override: true
|
||||||
|
components: rustfmt, clippy
|
||||||
|
|
||||||
|
- name: Check formatting
|
||||||
|
uses: actions-rs/cargo@v1
|
||||||
|
with:
|
||||||
|
command: fmt
|
||||||
|
args: --all -- --check
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
uses: actions-rs/cargo@v1
|
||||||
|
with:
|
||||||
|
command: build
|
||||||
|
args: --workspace
|
||||||
|
|
||||||
|
- name: Unit tests
|
||||||
|
uses: actions-rs/cargo@v1
|
||||||
|
with:
|
||||||
|
command: test
|
||||||
|
args: --workspace
|
||||||
|
|
||||||
|
- name: Annotate with clippy warnings
|
||||||
|
uses: actions-rs/clippy-check@v1
|
||||||
|
continue-on-error: true
|
||||||
|
with:
|
||||||
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
args: --workspace
|
||||||
|
|
||||||
|
- name: Clippy
|
||||||
|
uses: actions-rs/cargo@v1
|
||||||
|
with:
|
||||||
|
command: clippy
|
||||||
|
args: --workspace --all-targets -- -D warnings
|
||||||
|
|
||||||
|
notification:
|
||||||
|
needs: build
|
||||||
|
runs-on: custom-runner-linux
|
||||||
|
steps:
|
||||||
|
- name: Collect jobs status
|
||||||
|
uses: technote-space/workflow-conclusion-action@v2
|
||||||
|
- name: Check out repository code
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
- name: install npm
|
||||||
|
uses: actions/setup-node@v3
|
||||||
|
if: env.WORKFLOW_CONCLUSION == 'failure'
|
||||||
|
with:
|
||||||
|
node-version: 18
|
||||||
|
- name: Matrix - Node Install
|
||||||
|
if: env.WORKFLOW_CONCLUSION == 'failure'
|
||||||
|
run: npm install
|
||||||
|
working-directory: .github/workflows/support-files
|
||||||
|
- name: Matrix - Send Notification
|
||||||
|
if: env.WORKFLOW_CONCLUSION == 'failure'
|
||||||
|
env:
|
||||||
|
NYM_NOTIFICATION_KIND: nightly
|
||||||
|
NYM_PROJECT_NAME: "nym-wallet-nightly-build"
|
||||||
|
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
|
||||||
|
GIT_COMMIT_MESSAGE: "${{ github.event.head_commit.message }}"
|
||||||
|
GIT_BRANCH: "${GITHUB_REF##*/}"
|
||||||
|
IS_SUCCESS: "${{ env.WORKFLOW_CONCLUSION == 'success' }}"
|
||||||
|
MATRIX_SERVER: "${{ secrets.MATRIX_SERVER }}"
|
||||||
|
MATRIX_ROOM: "${{ secrets.MATRIX_ROOM_NIGHTLY }}"
|
||||||
|
MATRIX_USER_ID: "${{ secrets.MATRIX_USER_ID }}"
|
||||||
|
MATRIX_TOKEN: "${{ secrets.MATRIX_TOKEN }}"
|
||||||
|
MATRIX_DEVICE_ID: "${{ secrets.MATRIX_DEVICE_ID }}"
|
||||||
|
uses: docker://keybaseio/client:stable-node
|
||||||
|
with:
|
||||||
|
args: .github/workflows/support-files/notifications/entry_point.sh
|
||||||
@@ -38,7 +38,7 @@ jobs:
|
|||||||
- name: install npm
|
- name: install npm
|
||||||
uses: actions/setup-node@v3
|
uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: 16
|
node-version: 18
|
||||||
- name: Matrix - Node Install
|
- name: Matrix - Node Install
|
||||||
run: npm install
|
run: npm install
|
||||||
working-directory: .github/workflows/support-files
|
working-directory: .github/workflows/support-files
|
||||||
@@ -24,9 +24,9 @@ jobs:
|
|||||||
continue-on-error: ${{ matrix.rust == 'nightly' || matrix.rust == 'beta' || matrix.rust == 'stable' }}
|
continue-on-error: ${{ matrix.rust == 'nightly' || matrix.rust == 'beta' || matrix.rust == 'stable' }}
|
||||||
steps:
|
steps:
|
||||||
- name: Install Dependencies (Linux)
|
- name: Install Dependencies (Linux)
|
||||||
run: sudo apt-get update && sudo apt-get install libwebkit2gtk-4.0-dev build-essential curl wget libssl-dev libgtk-3-dev libudev-dev squashfs-tools
|
run: sudo apt-get update && sudo apt-get install libwebkit2gtk-4.0-dev build-essential curl wget libssl-dev libgtk-3-dev libudev-dev squashfs-tools protobuf-compiler
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
if: matrix.os == 'ubuntu-20.04'
|
if: matrix.os == 'custom-linux'
|
||||||
|
|
||||||
- name: Check out repository code
|
- name: Check out repository code
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
@@ -53,7 +53,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Reclaim some disk space
|
- name: Reclaim some disk space
|
||||||
uses: actions-rs/cargo@v1
|
uses: actions-rs/cargo@v1
|
||||||
if: ${{ matrix.os == 'windows-latest' || matrix.os == 'ubuntu-20.04' }}
|
if: ${{ matrix.os == 'windows-latest' || matrix.os == 'custom-linux' }}
|
||||||
with:
|
with:
|
||||||
command: clean
|
command: clean
|
||||||
|
|
||||||
@@ -65,7 +65,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Reclaim some disk space
|
- name: Reclaim some disk space
|
||||||
uses: actions-rs/cargo@v1
|
uses: actions-rs/cargo@v1
|
||||||
if: ${{ matrix.os == 'windows-latest' || matrix.os == 'ubuntu-20.04' }}
|
if: ${{ matrix.os == 'windows-latest' || matrix.os == 'custom-linux' }}
|
||||||
with:
|
with:
|
||||||
command: clean
|
command: clean
|
||||||
|
|
||||||
@@ -77,7 +77,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Reclaim some disk space
|
- name: Reclaim some disk space
|
||||||
uses: actions-rs/cargo@v1
|
uses: actions-rs/cargo@v1
|
||||||
if: ${{ matrix.os == 'windows-latest' || matrix.os == 'ubuntu-20.04' }}
|
if: ${{ matrix.os == 'windows-latest' || matrix.os == 'custom-linux' }}
|
||||||
with:
|
with:
|
||||||
command: clean
|
command: clean
|
||||||
|
|
||||||
@@ -90,7 +90,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Reclaim some disk space
|
- name: Reclaim some disk space
|
||||||
uses: actions-rs/cargo@v1
|
uses: actions-rs/cargo@v1
|
||||||
if: ${{ matrix.os == 'windows-latest' || matrix.os == 'ubuntu-20.04' }}
|
if: ${{ matrix.os == 'windows-latest' || matrix.os == 'custom-linux' }}
|
||||||
with:
|
with:
|
||||||
command: clean
|
command: clean
|
||||||
|
|
||||||
@@ -110,36 +110,10 @@ jobs:
|
|||||||
|
|
||||||
- name: Reclaim some disk space
|
- name: Reclaim some disk space
|
||||||
uses: actions-rs/cargo@v1
|
uses: actions-rs/cargo@v1
|
||||||
if: ${{ matrix.os == 'windows-latest' || matrix.os == 'ubuntu-20.04' }}
|
if: ${{ matrix.os == 'windows-latest' || matrix.os == 'custom-linux' }}
|
||||||
with:
|
with:
|
||||||
command: clean
|
command: clean
|
||||||
|
|
||||||
# nym-wallet (the rust part)
|
|
||||||
- name: Build nym-wallet rust code
|
|
||||||
uses: actions-rs/cargo@v1
|
|
||||||
with:
|
|
||||||
command: build
|
|
||||||
args: --manifest-path nym-wallet/Cargo.toml --workspace
|
|
||||||
|
|
||||||
- name: Run nym-wallet tests
|
|
||||||
uses: actions-rs/cargo@v1
|
|
||||||
with:
|
|
||||||
command: test
|
|
||||||
args: --manifest-path nym-wallet/Cargo.toml --workspace
|
|
||||||
|
|
||||||
- name: Check nym-wallet formatting
|
|
||||||
uses: actions-rs/cargo@v1
|
|
||||||
with:
|
|
||||||
command: fmt
|
|
||||||
args: --manifest-path nym-wallet/Cargo.toml --all -- --check
|
|
||||||
|
|
||||||
- name: Run clippy for nym-wallet
|
|
||||||
uses: actions-rs/cargo@v1
|
|
||||||
if: ${{ matrix.rust != 'nightly' }}
|
|
||||||
with:
|
|
||||||
command: clippy
|
|
||||||
args: --manifest-path nym-wallet/Cargo.toml --workspace --all-targets -- -D warnings
|
|
||||||
|
|
||||||
notification:
|
notification:
|
||||||
needs: build
|
needs: build
|
||||||
runs-on: custom-runner-linux
|
runs-on: custom-runner-linux
|
||||||
@@ -152,7 +126,7 @@ jobs:
|
|||||||
uses: actions/setup-node@v3
|
uses: actions/setup-node@v3
|
||||||
if: env.WORKFLOW_CONCLUSION == 'failure'
|
if: env.WORKFLOW_CONCLUSION == 'failure'
|
||||||
with:
|
with:
|
||||||
node-version: 16
|
node-version: 18
|
||||||
- name: Matrix - Node Install
|
- name: Matrix - Node Install
|
||||||
if: env.WORKFLOW_CONCLUSION == 'failure'
|
if: env.WORKFLOW_CONCLUSION == 'failure'
|
||||||
run: npm install
|
run: npm install
|
||||||
|
|||||||
@@ -1,49 +1,49 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"os":"ubuntu-20.04",
|
"os":"custom-linux",
|
||||||
"rust":"stable",
|
"rust":"stable",
|
||||||
"runOnEvent":"schedule"
|
"runOnEvent":"schedule"
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"os":"windows-latest",
|
"os":"windows10",
|
||||||
"rust":"stable",
|
"rust":"stable",
|
||||||
"runOnEvent":"schedule"
|
"runOnEvent":"schedule"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"os":"macos-latest",
|
"os":"custom-runner-mac-m1",
|
||||||
"rust":"stable",
|
"rust":"stable",
|
||||||
"runOnEvent":"schedule"
|
"runOnEvent":"schedule"
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"os":"ubuntu-20.04",
|
"os":"custom-linux",
|
||||||
"rust":"beta",
|
"rust":"beta",
|
||||||
"runOnEvent":"schedule"
|
"runOnEvent":"schedule"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"os":"windows-latest",
|
"os":"windows10",
|
||||||
"rust":"beta",
|
"rust":"beta",
|
||||||
"runOnEvent":"schedule"
|
"runOnEvent":"schedule"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"os":"macos-latest",
|
"os":"custom-runner-mac-m1",
|
||||||
"rust":"beta",
|
"rust":"beta",
|
||||||
"runOnEvent":"schedule"
|
"runOnEvent":"schedule"
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"os":"ubuntu-20.04",
|
"os":"custom-linux",
|
||||||
"rust":"nightly",
|
"rust":"nightly",
|
||||||
"runOnEvent":"schedule"
|
"runOnEvent":"schedule"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"os":"windows-latest",
|
"os":"windows10",
|
||||||
"rust":"nightly",
|
"rust":"nightly",
|
||||||
"runOnEvent":"schedule"
|
"runOnEvent":"schedule"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"os":"macos-latest",
|
"os":"custom-runner-mac-m1",
|
||||||
"rust":"nightly",
|
"rust":"nightly",
|
||||||
"runOnEvent":"schedule"
|
"runOnEvent":"schedule"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"os":"ubuntu-20.04",
|
||||||
|
"rust":"stable",
|
||||||
|
"runOnEvent":"workflow_dispatch"
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"os":"windows10",
|
||||||
|
"rust":"stable",
|
||||||
|
"runOnEvent":"workflow_dispatch"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"os":"custom-runner-mac-m1",
|
||||||
|
"rust":"stable",
|
||||||
|
"runOnEvent":"workflow_dispatch"
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"os":"ubuntu-20.04",
|
||||||
|
"rust":"beta",
|
||||||
|
"runOnEvent":"workflow_dispatch"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"os":"windows10",
|
||||||
|
"rust":"beta",
|
||||||
|
"runOnEvent":"workflow_dispatch"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"os":"custom-runner-mac-m1",
|
||||||
|
"rust":"beta",
|
||||||
|
"runOnEvent":"workflow_dispatch"
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"os":"ubuntu-20.04",
|
||||||
|
"rust":"nightly",
|
||||||
|
"runOnEvent":"workflow_dispatch"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"os":"windows10",
|
||||||
|
"rust":"nightly",
|
||||||
|
"runOnEvent":"workflow_dispatch"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"os":"custom-runner-mac-m1",
|
||||||
|
"rust":"nightly",
|
||||||
|
"runOnEvent":"workflow_dispatch"
|
||||||
|
}
|
||||||
|
]
|
||||||
+10
-27
@@ -1,8 +1,6 @@
|
|||||||
name: Nightly builds on latest release
|
name: Nightly builds on dispatch
|
||||||
|
|
||||||
on:
|
on: workflow_dispatch
|
||||||
schedule:
|
|
||||||
- cron: '14 2 * * *'
|
|
||||||
jobs:
|
jobs:
|
||||||
matrix_prep:
|
matrix_prep:
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
@@ -14,37 +12,22 @@ jobs:
|
|||||||
- id: set-matrix
|
- id: set-matrix
|
||||||
uses: JoshuaTheMiller/conditional-build-matrix@main
|
uses: JoshuaTheMiller/conditional-build-matrix@main
|
||||||
with:
|
with:
|
||||||
inputFile: '.github/workflows/nightly_build_matrix_includes.json'
|
inputFile: '.github/workflows/nightly_build_matrix_on_dispatch.json'
|
||||||
filter: '[?runOnEvent==`${{ github.event_name }}` || runOnEvent==`always`]'
|
filter: '[?runOnEvent==`${{ github.event_name }}` || runOnEvent==`always`]'
|
||||||
get_release:
|
|
||||||
runs-on: ubuntu-20.04
|
|
||||||
needs: matrix_prep
|
|
||||||
outputs:
|
|
||||||
output1: ${{ steps.step2.outputs.latest_release }}
|
|
||||||
steps:
|
|
||||||
- name: Check out repository code
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
- name: Fetch all branches
|
|
||||||
run: git fetch --all
|
|
||||||
- name: Set output variable to latest release branch
|
|
||||||
id: step2
|
|
||||||
run: echo "latest_release=$(git branch -r | grep -E 'release/v[0-9]+\.[0-9]+\.[0-9]+$' | sort -V | tail -n 1 | sed 's/ origin\///')" >> $GITHUB_OUTPUT
|
|
||||||
build:
|
build:
|
||||||
needs: [get_release,matrix_prep]
|
needs: matrix_prep
|
||||||
strategy:
|
strategy:
|
||||||
matrix: ${{fromJson(needs.matrix_prep.outputs.matrix)}}
|
matrix: ${{fromJson(needs.matrix_prep.outputs.matrix)}}
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
continue-on-error: ${{ matrix.rust == 'nightly' || matrix.rust == 'beta' || matrix.rust == 'stable' }}
|
continue-on-error: ${{ matrix.rust == 'nightly' || matrix.rust == 'beta' || matrix.rust == 'stable' }}
|
||||||
steps:
|
steps:
|
||||||
- name: Install Dependencies (Linux)
|
- name: Install Dependencies (Linux)
|
||||||
run: sudo apt-get update && sudo apt-get install libwebkit2gtk-4.0-dev build-essential curl wget libssl-dev libgtk-3-dev libudev-dev squashfs-tools
|
run: sudo apt-get update && sudo apt-get install libwebkit2gtk-4.0-dev build-essential curl wget libssl-dev libgtk-3-dev libudev-dev squashfs-tools protobuf-compiler
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
if: matrix.os == 'ubuntu-20.04'
|
if: matrix.os == 'ubuntu-20.04'
|
||||||
|
|
||||||
- name: Check out latest release branch
|
- name: Check out repository code
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
with:
|
|
||||||
ref: ${{needs.get_release.outputs.output1}}
|
|
||||||
|
|
||||||
- name: Install rust toolchain
|
- name: Install rust toolchain
|
||||||
uses: actions-rs/toolchain@v1
|
uses: actions-rs/toolchain@v1
|
||||||
@@ -156,7 +139,7 @@ jobs:
|
|||||||
args: --manifest-path nym-wallet/Cargo.toml --workspace --all-targets -- -D warnings
|
args: --manifest-path nym-wallet/Cargo.toml --workspace --all-targets -- -D warnings
|
||||||
|
|
||||||
notification:
|
notification:
|
||||||
needs: [build,get_release]
|
needs: build
|
||||||
runs-on: custom-runner-linux
|
runs-on: custom-runner-linux
|
||||||
steps:
|
steps:
|
||||||
- name: Collect jobs status
|
- name: Collect jobs status
|
||||||
@@ -167,7 +150,7 @@ jobs:
|
|||||||
uses: actions/setup-node@v3
|
uses: actions/setup-node@v3
|
||||||
if: env.WORKFLOW_CONCLUSION == 'failure'
|
if: env.WORKFLOW_CONCLUSION == 'failure'
|
||||||
with:
|
with:
|
||||||
node-version: 16
|
node-version: 18
|
||||||
- name: Matrix - Node Install
|
- name: Matrix - Node Install
|
||||||
if: env.WORKFLOW_CONCLUSION == 'failure'
|
if: env.WORKFLOW_CONCLUSION == 'failure'
|
||||||
run: npm install
|
run: npm install
|
||||||
@@ -176,10 +159,10 @@ jobs:
|
|||||||
if: env.WORKFLOW_CONCLUSION == 'failure'
|
if: env.WORKFLOW_CONCLUSION == 'failure'
|
||||||
env:
|
env:
|
||||||
NYM_NOTIFICATION_KIND: nightly
|
NYM_NOTIFICATION_KIND: nightly
|
||||||
NYM_PROJECT_NAME: "Nym nightly build on latest release"
|
NYM_PROJECT_NAME: "Nym nightly build"
|
||||||
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
|
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
|
||||||
GIT_COMMIT_MESSAGE: "${{ github.event.head_commit.message }}"
|
GIT_COMMIT_MESSAGE: "${{ github.event.head_commit.message }}"
|
||||||
GIT_BRANCH_NAME: "${{needs.get_release.outputs.output1}}"
|
GIT_BRANCH: "${GITHUB_REF##*/}"
|
||||||
IS_SUCCESS: "${{ env.WORKFLOW_CONCLUSION == 'success' }}"
|
IS_SUCCESS: "${{ env.WORKFLOW_CONCLUSION == 'success' }}"
|
||||||
MATRIX_SERVER: "${{ secrets.MATRIX_SERVER }}"
|
MATRIX_SERVER: "${{ secrets.MATRIX_SERVER }}"
|
||||||
MATRIX_ROOM: "${{ secrets.MATRIX_ROOM_NIGHTLY }}"
|
MATRIX_ROOM: "${{ secrets.MATRIX_ROOM_NIGHTLY }}"
|
||||||
@@ -1,191 +0,0 @@
|
|||||||
name: Nightly builds on second latest release
|
|
||||||
|
|
||||||
on:
|
|
||||||
schedule:
|
|
||||||
- cron: '24 2 * * *'
|
|
||||||
jobs:
|
|
||||||
matrix_prep:
|
|
||||||
runs-on: ubuntu-20.04
|
|
||||||
outputs:
|
|
||||||
matrix: ${{ steps.set-matrix.outputs.matrix }}
|
|
||||||
steps:
|
|
||||||
# creates the matrix strategy from nightly_build_matrix_includes.json
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
- id: set-matrix
|
|
||||||
uses: JoshuaTheMiller/conditional-build-matrix@main
|
|
||||||
with:
|
|
||||||
inputFile: '.github/workflows/nightly_build_matrix_includes.json'
|
|
||||||
filter: '[?runOnEvent==`${{ github.event_name }}` || runOnEvent==`always`]'
|
|
||||||
get_release:
|
|
||||||
runs-on: ubuntu-20.04
|
|
||||||
needs: matrix_prep
|
|
||||||
outputs:
|
|
||||||
output1: ${{ steps.step2.outputs.latest_release }}
|
|
||||||
steps:
|
|
||||||
- name: Check out repository code
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
- name: Fetch all branches
|
|
||||||
run: git fetch --all
|
|
||||||
- name: Set output variable to latest release branch
|
|
||||||
id: step2
|
|
||||||
run: echo "latest_release=$(git branch -r | grep -E 'release/v[0-9]+\.[0-9]+\.[0-9]+$' | sort -V | tail -n 2 | head -n 1 | sed 's/ origin\///')" >> $GITHUB_OUTPUT
|
|
||||||
build:
|
|
||||||
needs: [get_release,matrix_prep]
|
|
||||||
strategy:
|
|
||||||
matrix: ${{fromJson(needs.matrix_prep.outputs.matrix)}}
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
continue-on-error: ${{ matrix.rust == 'nightly' || matrix.rust == 'beta' || matrix.rust == 'stable' }}
|
|
||||||
steps:
|
|
||||||
- name: Install Dependencies (Linux)
|
|
||||||
run: sudo apt-get update && sudo apt-get install libwebkit2gtk-4.0-dev build-essential curl wget libssl-dev libgtk-3-dev libudev-dev squashfs-tools
|
|
||||||
continue-on-error: true
|
|
||||||
if: matrix.os == 'ubuntu-20.04'
|
|
||||||
|
|
||||||
- name: Check out latest release branch
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
with:
|
|
||||||
ref: ${{needs.get_release.outputs.output1}}
|
|
||||||
|
|
||||||
- name: Install rust toolchain
|
|
||||||
uses: actions-rs/toolchain@v1
|
|
||||||
with:
|
|
||||||
profile: minimal
|
|
||||||
toolchain: ${{ matrix.rust }}
|
|
||||||
override: true
|
|
||||||
components: rustfmt, clippy
|
|
||||||
|
|
||||||
- name: Check formatting
|
|
||||||
uses: actions-rs/cargo@v1
|
|
||||||
with:
|
|
||||||
command: fmt
|
|
||||||
args: --all -- --check
|
|
||||||
|
|
||||||
- name: Build all binaries
|
|
||||||
uses: actions-rs/cargo@v1
|
|
||||||
with:
|
|
||||||
command: build
|
|
||||||
args: --workspace
|
|
||||||
|
|
||||||
- name: Reclaim some disk space (because Windows is being annoying)
|
|
||||||
uses: actions-rs/cargo@v1
|
|
||||||
if: ${{ matrix.os == 'windows-latest' }}
|
|
||||||
with:
|
|
||||||
command: clean
|
|
||||||
|
|
||||||
- name: Build all examples
|
|
||||||
uses: actions-rs/cargo@v1
|
|
||||||
with:
|
|
||||||
command: build
|
|
||||||
args: --workspace --examples
|
|
||||||
|
|
||||||
- name: Reclaim some disk space (because Windows is being annoying)
|
|
||||||
uses: actions-rs/cargo@v1
|
|
||||||
if: ${{ matrix.os == 'windows-latest' }}
|
|
||||||
with:
|
|
||||||
command: clean
|
|
||||||
|
|
||||||
- name: Run all tests
|
|
||||||
uses: actions-rs/cargo@v1
|
|
||||||
with:
|
|
||||||
command: test
|
|
||||||
args: --workspace
|
|
||||||
|
|
||||||
- name: Reclaim some disk space (because Windows is being annoying)
|
|
||||||
uses: actions-rs/cargo@v1
|
|
||||||
if: ${{ matrix.os == 'windows-latest' || matrix.os == 'ubuntu-20.04' }}
|
|
||||||
with:
|
|
||||||
command: clean
|
|
||||||
|
|
||||||
- name: Run expensive tests
|
|
||||||
if: github.ref == 'refs/heads/develop' || github.event.pull_request.base.ref == 'develop' || github.event.pull_request.base.ref == 'master'
|
|
||||||
uses: actions-rs/cargo@v1
|
|
||||||
with:
|
|
||||||
command: test
|
|
||||||
args: --workspace -- --ignored
|
|
||||||
|
|
||||||
- name: Reclaim some disk space (because Windows is being annoying)
|
|
||||||
uses: actions-rs/cargo@v1
|
|
||||||
if: ${{ matrix.os == 'windows-latest' }}
|
|
||||||
with:
|
|
||||||
command: clean
|
|
||||||
|
|
||||||
- uses: actions-rs/clippy-check@v1
|
|
||||||
name: Clippy checks
|
|
||||||
continue-on-error: true
|
|
||||||
with:
|
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
args: --workspace
|
|
||||||
|
|
||||||
- name: Run clippy
|
|
||||||
uses: actions-rs/cargo@v1
|
|
||||||
if: ${{ matrix.rust != 'nightly' }}
|
|
||||||
with:
|
|
||||||
command: clippy
|
|
||||||
args: --workspace --all-targets -- -D warnings
|
|
||||||
|
|
||||||
- name: Reclaim some disk space
|
|
||||||
uses: actions-rs/cargo@v1
|
|
||||||
if: ${{ matrix.os == 'windows-latest' || matrix.os == 'ubuntu-20.04' }}
|
|
||||||
with:
|
|
||||||
command: clean
|
|
||||||
|
|
||||||
# nym-wallet (the rust part)
|
|
||||||
- name: Build nym-wallet rust code
|
|
||||||
uses: actions-rs/cargo@v1
|
|
||||||
with:
|
|
||||||
command: build
|
|
||||||
args: --manifest-path nym-wallet/Cargo.toml --workspace
|
|
||||||
|
|
||||||
- name: Run nym-wallet tests
|
|
||||||
uses: actions-rs/cargo@v1
|
|
||||||
with:
|
|
||||||
command: test
|
|
||||||
args: --manifest-path nym-wallet/Cargo.toml --workspace
|
|
||||||
|
|
||||||
- name: Check nym-wallet formatting
|
|
||||||
uses: actions-rs/cargo@v1
|
|
||||||
with:
|
|
||||||
command: fmt
|
|
||||||
args: --manifest-path nym-wallet/Cargo.toml --all -- --check
|
|
||||||
|
|
||||||
- name: Run clippy for nym-wallet
|
|
||||||
uses: actions-rs/cargo@v1
|
|
||||||
if: ${{ matrix.rust != 'nightly' }}
|
|
||||||
with:
|
|
||||||
command: clippy
|
|
||||||
args: --manifest-path nym-wallet/Cargo.toml --workspace --all-targets -- -D warnings
|
|
||||||
|
|
||||||
notification:
|
|
||||||
needs: [build,get_release]
|
|
||||||
runs-on: custom-runner-linux
|
|
||||||
steps:
|
|
||||||
- name: Collect jobs status
|
|
||||||
uses: technote-space/workflow-conclusion-action@v2
|
|
||||||
- name: Check out repository code
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
- name: install npm
|
|
||||||
uses: actions/setup-node@v3
|
|
||||||
if: env.WORKFLOW_CONCLUSION == 'failure'
|
|
||||||
with:
|
|
||||||
node-version: 16
|
|
||||||
- name: Matrix - Node Install
|
|
||||||
if: env.WORKFLOW_CONCLUSION == 'failure'
|
|
||||||
run: npm install
|
|
||||||
working-directory: .github/workflows/support-files
|
|
||||||
- name: Matrix - Send Notification
|
|
||||||
if: env.WORKFLOW_CONCLUSION == 'failure'
|
|
||||||
env:
|
|
||||||
NYM_NOTIFICATION_KIND: nightly
|
|
||||||
NYM_PROJECT_NAME: "Nym nightly build on latest release"
|
|
||||||
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
|
|
||||||
GIT_COMMIT_MESSAGE: "${{ github.event.head_commit.message }}"
|
|
||||||
GIT_BRANCH_NAME: "${{needs.get_release.outputs.output1}}"
|
|
||||||
IS_SUCCESS: "${{ env.WORKFLOW_CONCLUSION == 'success' }}"
|
|
||||||
MATRIX_SERVER: "${{ secrets.MATRIX_SERVER }}"
|
|
||||||
MATRIX_ROOM: "${{ secrets.MATRIX_ROOM_NIGHTLY }}"
|
|
||||||
MATRIX_USER_ID: "${{ secrets.MATRIX_USER_ID }}"
|
|
||||||
MATRIX_TOKEN: "${{ secrets.MATRIX_TOKEN }}"
|
|
||||||
MATRIX_DEVICE_ID: "${{ secrets.MATRIX_DEVICE_ID }}"
|
|
||||||
uses: docker://keybaseio/client:stable-node
|
|
||||||
with:
|
|
||||||
args: .github/workflows/support-files/notifications/entry_point.sh
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
name: Publish Nym CLI binaries
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_dispatch:
|
|
||||||
release:
|
|
||||||
types: [created]
|
|
||||||
|
|
||||||
env:
|
|
||||||
NETWORK: mainnet
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
publish-nym-cli:
|
|
||||||
if: ${{ startsWith(github.ref, 'refs/tags/nym-cli-') && (github.event_name == 'release' || github.event_name == 'workflow_dispatch') }}
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
platform: [ubuntu-20.04, windows-latest, macos-latest]
|
|
||||||
|
|
||||||
runs-on: ${{ matrix.platform }}
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
|
|
||||||
- name: Check the release tag starts with `nym-cli-`
|
|
||||||
uses: actions/github-script@v3
|
|
||||||
with:
|
|
||||||
script: |
|
|
||||||
core.setFailed('Release tag did not start with nym-cli-...')
|
|
||||||
|
|
||||||
- name: Install Rust stable
|
|
||||||
uses: actions-rs/toolchain@v1
|
|
||||||
with:
|
|
||||||
toolchain: stable
|
|
||||||
|
|
||||||
- name: Build binary
|
|
||||||
run: make build-nym-cli
|
|
||||||
|
|
||||||
- name: Upload Artifact
|
|
||||||
uses: actions/upload-artifact@v3
|
|
||||||
with:
|
|
||||||
name: nym-cli-${{ matrix.platform }}
|
|
||||||
path: |
|
|
||||||
target/release/nym-cli*
|
|
||||||
retention-days: 30
|
|
||||||
|
|
||||||
- name: Upload to release based on tag name
|
|
||||||
uses: softprops/action-gh-release@v1
|
|
||||||
if: github.event_name == 'release'
|
|
||||||
with:
|
|
||||||
files: |
|
|
||||||
target/release/nym-cli
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
name: Publish Nym Wallet (Ubuntu)
|
|
||||||
on:
|
|
||||||
release:
|
|
||||||
types: [created]
|
|
||||||
|
|
||||||
defaults:
|
|
||||||
run:
|
|
||||||
working-directory: nym-wallet
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
publish-tauri:
|
|
||||||
if: ${{ startsWith(github.ref, 'refs/tags/nym-wallet-') && github.event_name == 'release' }}
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
platform: [custom-runner-linux]
|
|
||||||
|
|
||||||
runs-on: ${{ matrix.platform }}
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
|
|
||||||
- name: Tauri dependencies
|
|
||||||
run: >
|
|
||||||
sudo apt-get update &&
|
|
||||||
sudo apt-get install -y webkit2gtk-4.0
|
|
||||||
continue-on-error: true
|
|
||||||
|
|
||||||
- name: Node v16
|
|
||||||
uses: actions/setup-node@v3
|
|
||||||
with:
|
|
||||||
node-version: 16
|
|
||||||
|
|
||||||
- name: Install Rust stable
|
|
||||||
uses: actions-rs/toolchain@v1
|
|
||||||
with:
|
|
||||||
toolchain: stable
|
|
||||||
- name: Install app dependencies
|
|
||||||
run: yarn
|
|
||||||
- name: Create env file
|
|
||||||
uses: timheuer/base64-to-file@v1.1
|
|
||||||
with:
|
|
||||||
fileName: '.env'
|
|
||||||
encodedString: ${{ secrets.WALLET_ADMIN_ADDRESS }}
|
|
||||||
|
|
||||||
- name: Build app
|
|
||||||
run: yarn build
|
|
||||||
env:
|
|
||||||
TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
|
|
||||||
TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
|
|
||||||
- name: Upload to release based on tag name
|
|
||||||
uses: softprops/action-gh-release@v1
|
|
||||||
with:
|
|
||||||
files: |
|
|
||||||
nym-wallet/target/release/bundle/appimage/*.AppImage
|
|
||||||
nym-wallet/target/release/bundle/appimage/*.AppImage.tar.gz*
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
name: Release Nym Wallet
|
|
||||||
on:
|
|
||||||
workflow_dispatch:
|
|
||||||
inputs:
|
|
||||||
nym_wallet_version:
|
|
||||||
description: 'The version of the Nym Wallet to release'
|
|
||||||
default: '1.0.x'
|
|
||||||
required: true
|
|
||||||
type: string
|
|
||||||
jobs:
|
|
||||||
create-release:
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
platform: [ubuntu-20.04]
|
|
||||||
runs-on: ${{ matrix.platform }}
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- name: Create release
|
|
||||||
uses: softprops/action-gh-release@v1
|
|
||||||
with:
|
|
||||||
body: >-
|
|
||||||
This is a pre-release
|
|
||||||
|
|
||||||
Download the wallet for your platform:
|
|
||||||
|
|
||||||
- [Linux](https://github.com/nymtech/nym/releases/download/nym-wallet-v${{ inputs.nym_wallet_version}}/nym-wallet_v${{ inputs.nym_wallet_version}}_amd64_ubuntu20.04.AppImage)
|
|
||||||
- [MacOS](https://github.com/nymtech/nym/releases/download/nym-wallet-v${{ inputs.nym_wallet_version}}/nym-wallet_v${{ inputs.nym_wallet_version}}_x64_macos_11.dmg)
|
|
||||||
- [Windows](https://github.com/nymtech/nym/releases/download/nym-wallet-v${{ inputs.nym_wallet_version}}/nym-wallet_v${{ inputs.nym_wallet_version}}_x64_windows.msi)
|
|
||||||
prerelease: true
|
|
||||||
name: Nym Wallet v${{ inputs.nym_wallet_version}}
|
|
||||||
tag_name: nym-wallet-v${{ inputs.nym_wallet_version}}
|
|
||||||
@@ -1,78 +0,0 @@
|
|||||||
name: Webdriverio tests for nym wallet
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
paths:
|
|
||||||
- "nym-wallet/**"
|
|
||||||
|
|
||||||
defaults:
|
|
||||||
run:
|
|
||||||
working-directory: nym-wallet
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
test:
|
|
||||||
name: wallet tests
|
|
||||||
runs-on: ubuntu-20.04
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
|
|
||||||
- name: Tauri dependencies
|
|
||||||
run: >
|
|
||||||
sudo apt-get update &&
|
|
||||||
sudo apt-get install -y
|
|
||||||
libgtk-3-dev
|
|
||||||
libgtksourceview-3.0-dev
|
|
||||||
webkit2gtk-4.0
|
|
||||||
libappindicator3-dev
|
|
||||||
webkit2gtk-driver
|
|
||||||
xvfb
|
|
||||||
continue-on-error: true
|
|
||||||
|
|
||||||
- name: Install minimal stable
|
|
||||||
uses: actions-rs/toolchain@v1
|
|
||||||
with:
|
|
||||||
profile: minimal
|
|
||||||
toolchain: stable
|
|
||||||
|
|
||||||
- name: Node v16
|
|
||||||
uses: actions/setup-node@v3
|
|
||||||
with:
|
|
||||||
node-version: 16
|
|
||||||
|
|
||||||
- name: Install yarn for building application
|
|
||||||
run: yarn install
|
|
||||||
|
|
||||||
- name: Build application
|
|
||||||
run: yarn run webpack:build & yarn run tauri:build
|
|
||||||
|
|
||||||
- name: Check binary exists
|
|
||||||
run: |
|
|
||||||
cd target/release/
|
|
||||||
(test -f nym-wallet && echo nym binary exists) || echo wallet does not exist
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
run: yarn install
|
|
||||||
working-directory: nym-wallet/webdriver
|
|
||||||
|
|
||||||
- name: Remove existing user datafile
|
|
||||||
uses: JesseTG/rm@v1.0.2
|
|
||||||
with:
|
|
||||||
path: nym-wallet/webdriver/common/data/user-data.json
|
|
||||||
|
|
||||||
- name: Create user data json file
|
|
||||||
id: create-json
|
|
||||||
uses: jsdaniell/create-json@1.1.2
|
|
||||||
with:
|
|
||||||
name: "user-data.json"
|
|
||||||
json: ${{ secrets.WALLET_USERDATA }}
|
|
||||||
dir: "nym-wallet/webdriver/common/data/"
|
|
||||||
|
|
||||||
- name: Install tauri-driver
|
|
||||||
uses: actions-rs/cargo@v1
|
|
||||||
with:
|
|
||||||
command: install
|
|
||||||
args: tauri-driver
|
|
||||||
|
|
||||||
- name: Launch tests
|
|
||||||
run: xvfb-run yarn test:runall
|
|
||||||
working-directory: nym-wallet/webdriver
|
|
||||||
+36
-9
@@ -2,34 +2,52 @@ name: Publish Nym binaries
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
inputs:
|
inputs:
|
||||||
add_tokio_unstable:
|
add_tokio_unstable:
|
||||||
description: 'True to add RUSTFLAGS="--cfg tokio_unstable"'
|
description: 'True to add RUSTFLAGS="--cfg tokio_unstable"'
|
||||||
required: true
|
required: true
|
||||||
default: false
|
default: false
|
||||||
type: boolean
|
type: boolean
|
||||||
release:
|
release:
|
||||||
types: [created]
|
types: [created]
|
||||||
|
|
||||||
env:
|
env:
|
||||||
NETWORK: mainnet
|
NETWORK: mainnet
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
publish-nym:
|
publish-nym:
|
||||||
if: ${{ startsWith(github.ref, 'refs/tags/nym-binaries-') && github.event_name == 'release' }}
|
if: ${{ (startsWith(github.ref, 'refs/tags/nym-binaries-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }}
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
platform: [custom-runner-linux]
|
platform: [custom-runner-linux]
|
||||||
|
|
||||||
runs-on: ${{ matrix.platform }}
|
runs-on: ${{ matrix.platform }}
|
||||||
|
|
||||||
|
outputs:
|
||||||
|
release_id: ${{ steps.create-release.outputs.id }}
|
||||||
|
release_date: ${{ fromJSON(steps.create-release.outputs.assets)[0].published_at }}
|
||||||
|
client_hash: ${{ steps.binary-hashes.outputs.client_hash }}
|
||||||
|
mixnode_hash: ${{ steps.binary-hashes.outputs.mixnode_hash }}
|
||||||
|
gateway_hash: ${{ steps.binary-hashes.outputs.gateway_hash }}
|
||||||
|
socks5_hash: ${{ steps.binary-hashes.outputs.socks5_hash }}
|
||||||
|
netreq_hash: ${{ steps.binary-hashes.outputs.netreq_hash }}
|
||||||
|
cli_hash: ${{ steps.binary-hashes.outputs.cli_hash }}
|
||||||
|
netstat_hash: ${{ steps.binary-hashes.outputs.netstat_hash }}
|
||||||
|
client_version: ${{ steps.binary-versions.outputs.client_version }}
|
||||||
|
mixnode_version: ${{ steps.binary-versions.outputs.mixnode_version }}
|
||||||
|
gateway_version: ${{ steps.binary-versions.outputs.gateway_version }}
|
||||||
|
socks5_version: ${{ steps.binary-versions.outputs.socks5_version }}
|
||||||
|
netreq_version: ${{ steps.binary-versions.outputs.netreq_version }}
|
||||||
|
cli_version: ${{ steps.binary-versions.outputs.cli_version }}
|
||||||
|
netstat_version: ${{ steps.binary-versions.outputs.netstat_version }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Install Dependencies (Linux)
|
- name: Install Dependencies (Linux)
|
||||||
run: sudo apt-get update && sudo apt-get -y install libwebkit2gtk-4.0-dev build-essential curl wget libssl-dev libgtk-3-dev libudev-dev squashfs-tools
|
run: sudo apt-get update && sudo apt-get -y install ripgrep libwebkit2gtk-4.0-dev build-essential curl wget libssl-dev libgtk-3-dev libudev-dev squashfs-tools
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
|
|
||||||
- name: Sets env vars for tokio if set in manual dispatch inputs
|
- name: Sets env vars for tokio if set in manual dispatch inputs
|
||||||
run: |
|
run: |
|
||||||
echo 'RUSTFLAGS="--cfg tokio_unstable"' >> $GITHUB_ENV
|
echo 'RUSTFLAGS="--cfg tokio_unstable"' >> $GITHUB_ENV
|
||||||
@@ -62,7 +80,8 @@ jobs:
|
|||||||
target/release/nym-cli
|
target/release/nym-cli
|
||||||
retention-days: 30
|
retention-days: 30
|
||||||
|
|
||||||
- name: Upload to release based on tag name
|
- id: create-release
|
||||||
|
name: Upload to release based on tag name
|
||||||
uses: softprops/action-gh-release@v1
|
uses: softprops/action-gh-release@v1
|
||||||
if: github.event_name == 'release'
|
if: github.event_name == 'release'
|
||||||
with:
|
with:
|
||||||
@@ -76,3 +95,11 @@ jobs:
|
|||||||
target/release/nym-network-requester
|
target/release/nym-network-requester
|
||||||
target/release/nym-network-statistics
|
target/release/nym-network-statistics
|
||||||
target/release/nym-cli
|
target/release/nym-cli
|
||||||
|
|
||||||
|
push-release-data-client:
|
||||||
|
if: ${{ (startsWith(github.ref, 'refs/tags/nym-binaries-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }}
|
||||||
|
uses: ./.github/workflows/release-calculate-hash.yml
|
||||||
|
needs: publish-nym
|
||||||
|
with:
|
||||||
|
release_tag: ${{ github.ref_name }}
|
||||||
|
secrets: inherit
|
||||||
+38
-11
@@ -14,24 +14,36 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
platform: [custom-runner-mac-m1]
|
platform: [macos-latest]
|
||||||
|
|
||||||
runs-on: ${{ matrix.platform }}
|
runs-on: ${{ matrix.platform }}
|
||||||
|
|
||||||
|
outputs:
|
||||||
|
release_id: ${{ steps.create-release.outputs.id }}
|
||||||
|
release_date: ${{ fromJSON(steps.create-release.outputs.assets)[0].created_at }}
|
||||||
|
version: ${{ steps.release-info.outputs.version }}
|
||||||
|
filename: ${{ steps.release-info.outputs.filename }}
|
||||||
|
file_hash: ${{ steps.release-info.outputs.file_hash }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
- name: Node v16
|
- name: Node
|
||||||
uses: actions/setup-node@v3
|
uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: 16
|
node-version: 18
|
||||||
|
|
||||||
- name: Setup yarn
|
|
||||||
run: npm install -g yarn
|
|
||||||
|
|
||||||
- name: Install Rust stable
|
- name: Install Rust stable
|
||||||
uses: actions-rs/toolchain@v1
|
uses: actions-rs/toolchain@v1
|
||||||
with:
|
with:
|
||||||
toolchain: stable
|
toolchain: stable
|
||||||
|
target: wasm32-unknown-unknown
|
||||||
|
|
||||||
|
- name: Install wasm-pack
|
||||||
|
run: |
|
||||||
|
export WASM_PACK_VERSION="v0.12.1"
|
||||||
|
curl -LO https://github.com/rustwasm/wasm-pack/releases/download/${WASM_PACK_VERSION}/wasm-pack-${WASM_PACK_VERSION}-x86_64-apple-darwin.tar.gz
|
||||||
|
tar xvzf wasm-pack-${WASM_PACK_VERSION}-x86_64-apple-darwin.tar.gz -C $HOME/.cargo/bin --strip-components=1
|
||||||
|
rm wasm-pack-${WASM_PACK_VERSION}-x86_64-apple-darwin.tar.gz
|
||||||
|
|
||||||
- name: Install the Apple developer certificate for code signing
|
- name: Install the Apple developer certificate for code signing
|
||||||
env:
|
env:
|
||||||
@@ -44,7 +56,7 @@ jobs:
|
|||||||
KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db
|
KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db
|
||||||
|
|
||||||
# import certificate and provisioning profile from secrets
|
# import certificate and provisioning profile from secrets
|
||||||
echo -n "$APPLE_CERTIFICATE" | base64 --decode --output=$CERTIFICATE_PATH
|
echo -n "$APPLE_CERTIFICATE" | base64 --decode --output $CERTIFICATE_PATH
|
||||||
|
|
||||||
# create temporary keychain
|
# create temporary keychain
|
||||||
security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
|
security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
|
||||||
@@ -56,11 +68,15 @@ jobs:
|
|||||||
security list-keychain -d user -s $KEYCHAIN_PATH
|
security list-keychain -d user -s $KEYCHAIN_PATH
|
||||||
|
|
||||||
- name: Create env file
|
- name: Create env file
|
||||||
uses: timheuer/base64-to-file@v1.1
|
uses: timheuer/base64-to-file@v1.2
|
||||||
with:
|
with:
|
||||||
fileName: '.env'
|
fileName: '.env'
|
||||||
encodedString: ${{ secrets.WALLET_ADMIN_ADDRESS }}
|
encodedString: ${{ secrets.WALLET_ADMIN_ADDRESS }}
|
||||||
|
|
||||||
|
- name: Install project dependencies
|
||||||
|
shell: bash
|
||||||
|
run: cd .. && yarn --network-timeout 100000
|
||||||
|
|
||||||
- name: Install app dependencies and build it
|
- name: Install app dependencies and build it
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
@@ -72,13 +88,15 @@ jobs:
|
|||||||
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
|
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
|
||||||
TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
|
TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
|
||||||
TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
|
TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
|
||||||
|
SENTRY_DSN_RUST: ${{ secrets.SENTRY_DSN_RUST }}
|
||||||
|
SENTRY_DSN_JS: ${{ secrets.SENTRY_DSN_JS }}
|
||||||
run: yarn && yarn build
|
run: yarn && yarn build
|
||||||
|
|
||||||
- name: Upload Artifact
|
- name: Upload Artifact
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: nym-connect_1.0.0_x64.dmg
|
name: nym-connect_1.0.0_x64.dmg
|
||||||
path: nym-connect/desktop/target/release/bundle/dmg/nym-connect_1.0.0_x64.dmg
|
path: nym-connect/desktop/target/release/bundle/dmg/nym-connect_1*_x64.dmg
|
||||||
retention-days: 30
|
retention-days: 30
|
||||||
|
|
||||||
- name: Clean up keychain
|
- name: Clean up keychain
|
||||||
@@ -86,10 +104,19 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
security delete-keychain $RUNNER_TEMP/app-signing.keychain-db
|
security delete-keychain $RUNNER_TEMP/app-signing.keychain-db
|
||||||
|
|
||||||
- name: Upload to release based on tag name
|
- id: create-release
|
||||||
|
name: Upload to release based on tag name
|
||||||
uses: softprops/action-gh-release@v1
|
uses: softprops/action-gh-release@v1
|
||||||
if: github.event_name == 'release'
|
if: github.event_name == 'release'
|
||||||
with:
|
with:
|
||||||
files: |
|
files: |
|
||||||
nym-connect/desktop/target/release/bundle/dmg/*.dmg
|
nym-connect/desktop/target/release/bundle/dmg/*.dmg
|
||||||
nym-connect/desktop/target/release/bundle/macos/*.app.tar.gz*
|
nym-connect/desktop/target/release/bundle/macos/*.app.tar.gz*
|
||||||
|
|
||||||
|
push-release-data:
|
||||||
|
if: ${{ (startsWith(github.ref, 'refs/tags/nym-connect-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }}
|
||||||
|
uses: ./.github/workflows/release-calculate-hash.yml
|
||||||
|
needs: publish-tauri
|
||||||
|
with:
|
||||||
|
release_tag: ${{ github.ref_name }}
|
||||||
|
secrets: inherit
|
||||||
+31
-7
@@ -10,13 +10,20 @@ defaults:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
publish-tauri:
|
publish-tauri:
|
||||||
if: ${{ startsWith(github.ref, 'refs/tags/nym-connect-') && github.event_name == 'release' }}
|
if: ${{ (startsWith(github.ref, 'refs/tags/nym-connect-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }}
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
platform: [custom-runner-linux]
|
platform: [custom-runner-linux]
|
||||||
|
|
||||||
runs-on: ${{ matrix.platform }}
|
runs-on: ${{ matrix.platform }}
|
||||||
|
|
||||||
|
outputs:
|
||||||
|
release_id: ${{ steps.create-release.outputs.id }}
|
||||||
|
release_date: ${{ fromJSON(steps.create-release.outputs.assets)[0].created_at }}
|
||||||
|
version: ${{ steps.release-info.outputs.version }}
|
||||||
|
filename: ${{ steps.release-info.outputs.filename }}
|
||||||
|
file_hash: ${{ steps.release-info.outputs.file_hash }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
@@ -26,19 +33,25 @@ jobs:
|
|||||||
sudo apt-get install -y webkit2gtk-4.0 libayatana-appindicator3-dev
|
sudo apt-get install -y webkit2gtk-4.0 libayatana-appindicator3-dev
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
|
|
||||||
- name: Node v16
|
- name: Node
|
||||||
uses: actions/setup-node@v3
|
uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: 16
|
node-version: 18
|
||||||
|
|
||||||
- name: Install Rust stable
|
- name: Install Rust stable
|
||||||
uses: actions-rs/toolchain@v1
|
uses: actions-rs/toolchain@v1
|
||||||
with:
|
with:
|
||||||
toolchain: stable
|
toolchain: stable
|
||||||
|
|
||||||
|
- name: Install project dependencies
|
||||||
|
shell: bash
|
||||||
|
run: cd .. && yarn --network-timeout 100000
|
||||||
|
|
||||||
- name: Install app dependencies
|
- name: Install app dependencies
|
||||||
run: yarn
|
run: yarn
|
||||||
|
|
||||||
- name: Create env file
|
- name: Create env file
|
||||||
uses: timheuer/base64-to-file@v1.1
|
uses: timheuer/base64-to-file@v1.2
|
||||||
with:
|
with:
|
||||||
fileName: '.env'
|
fileName: '.env'
|
||||||
encodedString: ${{ secrets.WALLET_ADMIN_ADDRESS }}
|
encodedString: ${{ secrets.WALLET_ADMIN_ADDRESS }}
|
||||||
@@ -48,18 +61,29 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
|
TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
|
||||||
TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
|
TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
|
||||||
|
SENTRY_DSN_RUST: ${{ secrets.SENTRY_DSN_RUST }}
|
||||||
|
SENTRY_DSN_JS: ${{ secrets.SENTRY_DSN_JS }}
|
||||||
|
|
||||||
- name: Upload Artifact
|
- name: Upload Artifact
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: nym-connect.AppImage.tar.gz
|
name: nym-connect.AppImage.tar.gz
|
||||||
path: nym-connect/desktop/target/release/bundle/appimage/nym-connect_1.0.0_amd64.AppImage
|
path: nym-connect/desktop/target/release/bundle/appimage/nym-connect_1*_amd64.AppImage
|
||||||
retention-days: 30
|
retention-days: 30
|
||||||
|
|
||||||
- name: Upload to release based on tag name
|
- id: create-release
|
||||||
|
name: Upload to release based on tag name
|
||||||
uses: softprops/action-gh-release@v1
|
uses: softprops/action-gh-release@v1
|
||||||
if: github.event_name == 'release'
|
if: github.event_name == 'release'
|
||||||
with:
|
with:
|
||||||
files: |
|
files: |
|
||||||
nym-connect/desktop/target/release/bundle/appimage/*.AppImage
|
nym-connect/desktop/target/release/bundle/appimage/*.AppImage
|
||||||
nym-connect/desktop/target/release/bundle/appimage/*.AppImage.tar.gz*
|
nym-connect/desktop/target/release/bundle/appimage/*.AppImage.tar.gz*
|
||||||
|
|
||||||
|
push-release-data:
|
||||||
|
if: ${{ (startsWith(github.ref, 'refs/tags/nym-connect-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }}
|
||||||
|
uses: ./.github/workflows/release-calculate-hash.yml
|
||||||
|
needs: publish-tauri
|
||||||
|
with:
|
||||||
|
release_tag: ${{ github.ref_name }}
|
||||||
|
secrets: inherit
|
||||||
+30
-6
@@ -15,8 +15,15 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
platform: [windows10]
|
platform: [windows10]
|
||||||
|
|
||||||
runs-on: ${{ matrix.platform }}
|
runs-on: ${{ matrix.platform }}
|
||||||
|
|
||||||
|
outputs:
|
||||||
|
release_id: ${{ steps.create-release.outputs.id }}
|
||||||
|
release_date: ${{ fromJSON(steps.create-release.outputs.assets)[0].created_at }}
|
||||||
|
version: ${{ steps.release-info.outputs.version }}
|
||||||
|
filename: ${{ steps.release-info.outputs.filename }}
|
||||||
|
file_hash: ${{ steps.release-info.outputs.file_hash }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Clean up first
|
- name: Clean up first
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
@@ -39,10 +46,10 @@ jobs:
|
|||||||
Remove-Item -path certificate -include tempCert.txt
|
Remove-Item -path certificate -include tempCert.txt
|
||||||
Import-PfxCertificate -FilePath certificate/certificate.pfx -CertStoreLocation Cert:\CurrentUser\My -Password (ConvertTo-SecureString -String $env:WINDOWS_CERTIFICATE_PASSWORD -Force -AsPlainText)
|
Import-PfxCertificate -FilePath certificate/certificate.pfx -CertStoreLocation Cert:\CurrentUser\My -Password (ConvertTo-SecureString -String $env:WINDOWS_CERTIFICATE_PASSWORD -Force -AsPlainText)
|
||||||
|
|
||||||
- name: Node v16
|
- name: Node
|
||||||
uses: actions/setup-node@v3
|
uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: 16
|
node-version: 18
|
||||||
|
|
||||||
- name: Install Rust stable
|
- name: Install Rust stable
|
||||||
uses: actions-rs/toolchain@v1
|
uses: actions-rs/toolchain@v1
|
||||||
@@ -50,15 +57,21 @@ jobs:
|
|||||||
toolchain: stable
|
toolchain: stable
|
||||||
|
|
||||||
- name: Create env file
|
- name: Create env file
|
||||||
uses: timheuer/base64-to-file@v1.1
|
uses: timheuer/base64-to-file@v1.2
|
||||||
with:
|
with:
|
||||||
fileName: '.env'
|
fileName: '.env'
|
||||||
encodedString: ${{ secrets.WALLET_ADMIN_ADDRESS }}
|
encodedString: ${{ secrets.WALLET_ADMIN_ADDRESS }}
|
||||||
|
|
||||||
|
- name: Install project dependencies
|
||||||
|
shell: bash
|
||||||
|
run: cd .. && yarn --network-timeout 100000
|
||||||
|
|
||||||
- name: Install app dependencies
|
- name: Install app dependencies
|
||||||
|
shell: bash
|
||||||
run: yarn --network-timeout 100000
|
run: yarn --network-timeout 100000
|
||||||
|
|
||||||
- name: Build and sign it
|
- name: Build and sign it
|
||||||
|
shell: bash
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
ENABLE_CODE_SIGNING: ${{ secrets.WINDOWS_CERTIFICATE }}
|
ENABLE_CODE_SIGNING: ${{ secrets.WINDOWS_CERTIFICATE }}
|
||||||
@@ -66,19 +79,30 @@ jobs:
|
|||||||
WINDOWS_CERTIFICATE_PASSWORD: ${{ secrets.WINDOWS_CERTIFICATE_PASSWORD }}
|
WINDOWS_CERTIFICATE_PASSWORD: ${{ secrets.WINDOWS_CERTIFICATE_PASSWORD }}
|
||||||
TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
|
TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
|
||||||
TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
|
TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
|
||||||
|
SENTRY_DSN_RUST: ${{ secrets.SENTRY_DSN_RUST }}
|
||||||
|
SENTRY_DSN_JS: ${{ secrets.SENTRY_DSN_JS }}
|
||||||
run: yarn build
|
run: yarn build
|
||||||
|
|
||||||
- name: Upload Artifact
|
- name: Upload Artifact
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: nym-connect_1.0.0_x64_en-US.msi
|
name: nym-connect_1.0.0_x64_en-US.msi
|
||||||
path: nym-connect/desktop/target/release/bundle/msi/nym-connect_1.0.0_x64_en-US.msi
|
path: nym-connect/desktop/target/release/bundle/msi/nym-connect_1*_x64_en-US.msi
|
||||||
retention-days: 30
|
retention-days: 30
|
||||||
|
|
||||||
- name: Upload to release based on tag name
|
- id: create-release
|
||||||
|
name: Upload to release based on tag name
|
||||||
uses: softprops/action-gh-release@v1
|
uses: softprops/action-gh-release@v1
|
||||||
if: github.event_name == 'release'
|
if: github.event_name == 'release'
|
||||||
with:
|
with:
|
||||||
files: |
|
files: |
|
||||||
nym-connect/desktop/target/release/bundle/msi/*.msi
|
nym-connect/desktop/target/release/bundle/msi/*.msi
|
||||||
nym-connect/desktop/target/release/bundle/msi/*.msi.zip*
|
nym-connect/desktop/target/release/bundle/msi/*.msi.zip*
|
||||||
|
|
||||||
|
push-release-data:
|
||||||
|
if: ${{ (startsWith(github.ref, 'refs/tags/nym-connect-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }}
|
||||||
|
uses: ./.github/workflows/release-calculate-hash.yml
|
||||||
|
needs: publish-tauri
|
||||||
|
with:
|
||||||
|
release_tag: ${{ github.ref_name }}
|
||||||
|
secrets: inherit
|
||||||
@@ -6,7 +6,7 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
if: ${{ startsWith(github.ref, 'refs/tags/nym-contracts-') && github.event_name == 'release' }}
|
if: ${{ (startsWith(github.ref, 'refs/tags/nym-contracts-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }}
|
||||||
runs-on: [self-hosted, custom-runner-linux]
|
runs-on: [self-hosted, custom-runner-linux]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
@@ -14,13 +14,16 @@ jobs:
|
|||||||
- name: Install Rust stable
|
- name: Install Rust stable
|
||||||
uses: actions-rs/toolchain@v1
|
uses: actions-rs/toolchain@v1
|
||||||
with:
|
with:
|
||||||
toolchain: stable
|
toolchain: 1.69.0
|
||||||
target: wasm32-unknown-unknown
|
target: wasm32-unknown-unknown
|
||||||
override: true
|
override: true
|
||||||
components: rustfmt, clippy
|
components: rustfmt, clippy
|
||||||
|
|
||||||
|
- name: Install wasm-opt
|
||||||
|
run: cargo install --version 0.112.0 wasm-opt
|
||||||
|
|
||||||
- name: Build release contracts
|
- name: Build release contracts
|
||||||
run: make wasm
|
run: make contracts-wasm
|
||||||
|
|
||||||
- name: Upload Mixnet Contract Artifact
|
- name: Upload Mixnet Contract Artifact
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v3
|
||||||
+26
-7
@@ -10,20 +10,27 @@ defaults:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
publish-tauri:
|
publish-tauri:
|
||||||
if: ${{ startsWith(github.ref, 'refs/tags/nym-wallet-') && github.event_name == 'release' }}
|
if: ${{ (startsWith(github.ref, 'refs/tags/nym-wallet-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }}
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
platform: [macos-latest]
|
platform: [macos-latest]
|
||||||
|
|
||||||
runs-on: ${{ matrix.platform }}
|
runs-on: ${{ matrix.platform }}
|
||||||
|
|
||||||
|
outputs:
|
||||||
|
release_id: ${{ steps.create-release.outputs.id }}
|
||||||
|
release_date: ${{ fromJSON(steps.create-release.outputs.assets)[0].created_at }}
|
||||||
|
version: ${{ steps.release-info.outputs.version }}
|
||||||
|
filename: ${{ steps.release-info.outputs.filename }}
|
||||||
|
file_hash: ${{ steps.release-info.outputs.file_hash }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
- name: Node v16
|
- name: Node
|
||||||
uses: actions/setup-node@v3
|
uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: 16
|
node-version: 18
|
||||||
- name: Install Rust stable
|
- name: Install Rust stable
|
||||||
uses: actions-rs/toolchain@v1
|
uses: actions-rs/toolchain@v1
|
||||||
with:
|
with:
|
||||||
@@ -51,11 +58,15 @@ jobs:
|
|||||||
security list-keychain -d user -s $KEYCHAIN_PATH
|
security list-keychain -d user -s $KEYCHAIN_PATH
|
||||||
|
|
||||||
- name: Create env file
|
- name: Create env file
|
||||||
uses: timheuer/base64-to-file@v1.1
|
uses: timheuer/base64-to-file@v1.2
|
||||||
with:
|
with:
|
||||||
fileName: '.env'
|
fileName: '.env'
|
||||||
encodedString: ${{ secrets.WALLET_ADMIN_ADDRESS }}
|
encodedString: ${{ secrets.WALLET_ADMIN_ADDRESS }}
|
||||||
|
|
||||||
|
- name: Install project dependencies
|
||||||
|
shell: bash
|
||||||
|
run: cd .. && yarn --network-timeout 100000
|
||||||
|
|
||||||
- name: Install app dependencies and build it
|
- name: Install app dependencies and build it
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
@@ -80,11 +91,19 @@ jobs:
|
|||||||
if: ${{ always() }}
|
if: ${{ always() }}
|
||||||
run: |
|
run: |
|
||||||
security delete-keychain $RUNNER_TEMP/app-signing.keychain-db
|
security delete-keychain $RUNNER_TEMP/app-signing.keychain-db
|
||||||
|
- id: create-release
|
||||||
- name: Upload to release based on tag name
|
name: Upload to release based on tag name
|
||||||
uses: softprops/action-gh-release@v1
|
uses: softprops/action-gh-release@v1
|
||||||
if: github.event_name == 'release'
|
if: github.event_name == 'release'
|
||||||
with:
|
with:
|
||||||
files: |
|
files: |
|
||||||
nym-wallet/target/release/bundle/dmg/*.dmg
|
nym-wallet/target/release/bundle/dmg/*.dmg
|
||||||
nym-wallet/target/release/bundle/macos/*.app.tar.gz*
|
nym-wallet/target/release/bundle/macos/*.app.tar.gz*
|
||||||
|
|
||||||
|
push-release-data:
|
||||||
|
if: ${{ (startsWith(github.ref, 'refs/tags/nym-wallet-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }}
|
||||||
|
uses: ./.github/workflows/release-calculate-hash.yml
|
||||||
|
needs: publish-tauri
|
||||||
|
with:
|
||||||
|
release_tag: ${{ github.ref_name }}
|
||||||
|
secrets: inherit
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
name: Publish Nym Wallet (Ubuntu)
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
release:
|
||||||
|
types: [created]
|
||||||
|
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
working-directory: nym-wallet
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
publish-tauri:
|
||||||
|
if: ${{ (startsWith(github.ref, 'refs/tags/nym-wallet-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }}
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
platform: [custom-runner-linux]
|
||||||
|
runs-on: ${{ matrix.platform }}
|
||||||
|
|
||||||
|
outputs:
|
||||||
|
release_id: ${{ steps.create-release.outputs.id }}
|
||||||
|
release_date: ${{ fromJSON(steps.create-release.outputs.assets)[0].created_at }}
|
||||||
|
version: ${{ steps.release-info.outputs.version }}
|
||||||
|
filename: ${{ steps.release-info.outputs.filename }}
|
||||||
|
file_hash: ${{ steps.release-info.outputs.file_hash }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Tauri dependencies
|
||||||
|
run: >
|
||||||
|
sudo apt-get update &&
|
||||||
|
sudo apt-get install -y webkit2gtk-4.0
|
||||||
|
continue-on-error: true
|
||||||
|
|
||||||
|
- name: Node
|
||||||
|
uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: 18
|
||||||
|
|
||||||
|
- name: Install Rust stable
|
||||||
|
uses: actions-rs/toolchain@v1
|
||||||
|
with:
|
||||||
|
toolchain: stable
|
||||||
|
|
||||||
|
- name: Install project dependencies
|
||||||
|
shell: bash
|
||||||
|
run: cd .. && yarn --network-timeout 100000
|
||||||
|
|
||||||
|
- name: Install app dependencies
|
||||||
|
run: yarn
|
||||||
|
- name: Create env file
|
||||||
|
uses: timheuer/base64-to-file@v1.2
|
||||||
|
with:
|
||||||
|
fileName: '.env'
|
||||||
|
encodedString: ${{ secrets.WALLET_ADMIN_ADDRESS }}
|
||||||
|
|
||||||
|
- name: Build app
|
||||||
|
run: yarn build
|
||||||
|
env:
|
||||||
|
TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
|
||||||
|
TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
|
||||||
|
|
||||||
|
- name: Upload Artifact
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: nym-wallet_1.0.0_amd64.AppImage.tar.gz
|
||||||
|
path: nym-wallet/target/release/bundle/appimage/nym-wallet*.AppImage.tar.gz
|
||||||
|
retention-days: 30
|
||||||
|
|
||||||
|
- id: create-release
|
||||||
|
name: Upload to release based on tag name
|
||||||
|
uses: softprops/action-gh-release@v1
|
||||||
|
if: github.event_name == 'release'
|
||||||
|
with:
|
||||||
|
files: |
|
||||||
|
nym-wallet/target/release/bundle/appimage/*.AppImage
|
||||||
|
nym-wallet/target/release/bundle/appimage/*.AppImage.tar.gz*
|
||||||
|
|
||||||
|
push-release-data:
|
||||||
|
if: ${{ (startsWith(github.ref, 'refs/tags/nym-wallet-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }}
|
||||||
|
uses: ./.github/workflows/release-calculate-hash.yml
|
||||||
|
needs: publish-tauri
|
||||||
|
with:
|
||||||
|
release_tag: ${{ github.ref_name }}
|
||||||
|
secrets: inherit
|
||||||
+27
-5
@@ -15,8 +15,15 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
platform: [windows10]
|
platform: [windows10]
|
||||||
|
|
||||||
runs-on: ${{ matrix.platform }}
|
runs-on: ${{ matrix.platform }}
|
||||||
|
|
||||||
|
outputs:
|
||||||
|
release_id: ${{ steps.create-release.outputs.id }}
|
||||||
|
release_date: ${{ fromJSON(steps.create-release.outputs.assets)[0].created_at }}
|
||||||
|
version: ${{ steps.release-info.outputs.version }}
|
||||||
|
filename: ${{ steps.release-info.outputs.filename }}
|
||||||
|
file_hash: ${{ steps.release-info.outputs.file_hash }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Clean up first
|
- name: Clean up first
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
@@ -39,10 +46,10 @@ jobs:
|
|||||||
Remove-Item -path certificate -include tempCert.txt
|
Remove-Item -path certificate -include tempCert.txt
|
||||||
Import-PfxCertificate -FilePath certificate/certificate.pfx -CertStoreLocation Cert:\CurrentUser\My -Password (ConvertTo-SecureString -String $env:WINDOWS_CERTIFICATE_PASSWORD -Force -AsPlainText)
|
Import-PfxCertificate -FilePath certificate/certificate.pfx -CertStoreLocation Cert:\CurrentUser\My -Password (ConvertTo-SecureString -String $env:WINDOWS_CERTIFICATE_PASSWORD -Force -AsPlainText)
|
||||||
|
|
||||||
- name: Node v16
|
- name: Node
|
||||||
uses: actions/setup-node@v3
|
uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: 16
|
node-version: 18
|
||||||
|
|
||||||
- name: Install Rust stable
|
- name: Install Rust stable
|
||||||
uses: actions-rs/toolchain@v1
|
uses: actions-rs/toolchain@v1
|
||||||
@@ -50,15 +57,21 @@ jobs:
|
|||||||
toolchain: stable
|
toolchain: stable
|
||||||
|
|
||||||
- name: Create env file
|
- name: Create env file
|
||||||
uses: timheuer/base64-to-file@v1.1
|
uses: timheuer/base64-to-file@v1.2
|
||||||
with:
|
with:
|
||||||
fileName: '.env'
|
fileName: '.env'
|
||||||
encodedString: ${{ secrets.WALLET_ADMIN_ADDRESS }}
|
encodedString: ${{ secrets.WALLET_ADMIN_ADDRESS }}
|
||||||
|
|
||||||
|
- name: Install project dependencies
|
||||||
|
shell: bash
|
||||||
|
run: cd .. && yarn --network-timeout 100000
|
||||||
|
|
||||||
- name: Install app dependencies
|
- name: Install app dependencies
|
||||||
|
shell: bash
|
||||||
run: yarn --network-timeout 100000
|
run: yarn --network-timeout 100000
|
||||||
|
|
||||||
- name: Build and sign it
|
- name: Build and sign it
|
||||||
|
shell: bash
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
ENABLE_CODE_SIGNING: ${{ secrets.WINDOWS_CERTIFICATE }}
|
ENABLE_CODE_SIGNING: ${{ secrets.WINDOWS_CERTIFICATE }}
|
||||||
@@ -75,10 +88,19 @@ jobs:
|
|||||||
path: nym-wallet/target/release/bundle/msi/nym-wallet_1.*.msi
|
path: nym-wallet/target/release/bundle/msi/nym-wallet_1.*.msi
|
||||||
retention-days: 30
|
retention-days: 30
|
||||||
|
|
||||||
- name: Upload to release based on tag name
|
- id: create-release
|
||||||
|
name: Upload to release based on tag name
|
||||||
uses: softprops/action-gh-release@v1
|
uses: softprops/action-gh-release@v1
|
||||||
if: github.event_name == 'release'
|
if: github.event_name == 'release'
|
||||||
with:
|
with:
|
||||||
files: |
|
files: |
|
||||||
nym-wallet/target/release/bundle/msi/*.msi
|
nym-wallet/target/release/bundle/msi/*.msi
|
||||||
nym-wallet/target/release/bundle/msi/*.msi.zip*
|
nym-wallet/target/release/bundle/msi/*.msi.zip*
|
||||||
|
|
||||||
|
push-release-data:
|
||||||
|
if: ${{ (startsWith(github.ref, 'refs/tags/nym-wallet-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }}
|
||||||
|
uses: ./.github/workflows/release-calculate-hash.yml
|
||||||
|
needs: publish-tauri
|
||||||
|
with:
|
||||||
|
release_tag: ${{ github.ref_name }}
|
||||||
|
secrets: inherit
|
||||||
@@ -0,0 +1,111 @@
|
|||||||
|
name: Nyms5 Android
|
||||||
|
# unsigned APKs only, supported archs:
|
||||||
|
# - arm64-v8a (arm64)
|
||||||
|
# - x86_64
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- nyms5-android-v*
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
name: Build APK
|
||||||
|
runs-on: custom-runner-linux
|
||||||
|
env:
|
||||||
|
ANDROID_HOME: ${{ github.workspace }}/android-sdk
|
||||||
|
NDK_VERSION: 25.2.9519653
|
||||||
|
NDK_HOME: ${{ github.workspace }}/android-sdk/ndk/25.2.9519653
|
||||||
|
SDK_PLATFORM_VERSION: android-33
|
||||||
|
SDK_BUILDTOOLS_VERSION: 33.0.2
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Install Java
|
||||||
|
uses: actions/setup-java@v3
|
||||||
|
with:
|
||||||
|
distribution: "temurin"
|
||||||
|
java-version: "17"
|
||||||
|
|
||||||
|
- name: Install Android SDK manager
|
||||||
|
# https://developer.android.com/studio/command-line/sdkmanager
|
||||||
|
run: |
|
||||||
|
curl -sS https://dl.google.com/android/repository/commandlinetools-linux-9477386_latest.zip -o cmdline-tools.zip
|
||||||
|
unzip cmdline-tools.zip
|
||||||
|
mkdir -p $ANDROID_HOME/cmdline-tools/latest
|
||||||
|
mv cmdline-tools/* $ANDROID_HOME/cmdline-tools/latest
|
||||||
|
rm -rf cmdline-tools
|
||||||
|
|
||||||
|
- name: Install Android S/NDK
|
||||||
|
run: |
|
||||||
|
echo y | $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager --licenses
|
||||||
|
echo y | $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager \
|
||||||
|
"platforms;$SDK_PLATFORM_VERSION" \
|
||||||
|
"platform-tools" \
|
||||||
|
"ndk;$NDK_VERSION" \
|
||||||
|
"build-tools;$SDK_BUILDTOOLS_VERSION"
|
||||||
|
|
||||||
|
- name: Install Rust toolchain
|
||||||
|
uses: dtolnay/rust-toolchain@1.70.0
|
||||||
|
|
||||||
|
- name: Install rust android targets
|
||||||
|
run: |
|
||||||
|
rustup target add aarch64-linux-android \
|
||||||
|
x86_64-linux-android
|
||||||
|
|
||||||
|
- name: Build lib nym-socks5-listener
|
||||||
|
working-directory: sdk/lib/socks5-listener/
|
||||||
|
env:
|
||||||
|
RELEASE: true
|
||||||
|
RUSTFLAGS: "-C link-args=-Wl,--hash-style=gnu"
|
||||||
|
# build for arm64 and x86_64
|
||||||
|
run: ./build-android.sh aarch64 x86_64
|
||||||
|
|
||||||
|
- name: Build APKs (unsigned)
|
||||||
|
working-directory: nym-connect/native/android
|
||||||
|
env:
|
||||||
|
ANDROID_SDK_ROOT: ${{ env.ANDROID_HOME }}
|
||||||
|
SENTRY_AUTH_TOKEN: ${{ secrets.NYMS5_ANDROID_SENTRY_AUTH_TOKEN }}
|
||||||
|
# build for arm64 and x86_64
|
||||||
|
run: |
|
||||||
|
echo "auth.token=$SENTRY_AUTH_TOKEN" | tee -a sentry.properties
|
||||||
|
./gradlew :app:assembleArch64Debug
|
||||||
|
./gradlew :app:assembleArch64Release
|
||||||
|
|
||||||
|
- name: Prepare APKs
|
||||||
|
run: |
|
||||||
|
mkdir apk
|
||||||
|
mv nym-connect/native/android/app/build/outputs/apk/arch64/debug/app-arch64-debug.apk \
|
||||||
|
apk/nyms5-arch64-debug.apk
|
||||||
|
mv nym-connect/native/android/app/build/outputs/apk/arch64/release/app-arch64-release-unsigned.apk \
|
||||||
|
apk/nyms5-arch64-release.apk
|
||||||
|
|
||||||
|
- name: Upload APKs
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: nyms5-apk-arch64
|
||||||
|
path: |
|
||||||
|
apk/nyms5-arch64-debug.apk
|
||||||
|
apk/nyms5-arch64-release.apk
|
||||||
|
|
||||||
|
gh-release:
|
||||||
|
name: Publish APK (GH release)
|
||||||
|
needs: build
|
||||||
|
runs-on: custom-runner-linux
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
- name: Download binary artifact
|
||||||
|
uses: actions/download-artifact@v3
|
||||||
|
with:
|
||||||
|
name: nyms5-apk-arch64
|
||||||
|
path: apk
|
||||||
|
- name: Release
|
||||||
|
uses: softprops/action-gh-release@v1
|
||||||
|
with:
|
||||||
|
files: |
|
||||||
|
apk/nyms5-arch64-debug.apk
|
||||||
|
apk/nyms5-arch64-release.apk
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
name: publish-sdk-npm
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
publish:
|
||||||
|
runs-on: [custom-runner-linux]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Install Node
|
||||||
|
uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: 18
|
||||||
|
registry-url: 'https://registry.npmjs.org'
|
||||||
|
|
||||||
|
- name: Setup yarn
|
||||||
|
run: npm install -g yarn
|
||||||
|
|
||||||
|
- name: Install Rust stable
|
||||||
|
uses: actions-rs/toolchain@v1
|
||||||
|
with:
|
||||||
|
toolchain: stable
|
||||||
|
|
||||||
|
- name: Install wasm-pack
|
||||||
|
run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: yarn
|
||||||
|
|
||||||
|
- name: Build and publish
|
||||||
|
env:
|
||||||
|
NODE_AUTH_TOKEN: ${{ secrets.NODE_AUTH_TOKEN }}
|
||||||
|
working-directory: ./sdk/typescript/packages/sdk
|
||||||
|
run: scripts/publish.sh
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
name: Releases - calculate file hashes
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_call:
|
||||||
|
inputs:
|
||||||
|
release_tag:
|
||||||
|
description: 'Release tag'
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
workflow_dispatch:
|
||||||
|
release_tag:
|
||||||
|
tag:
|
||||||
|
description: 'Release tag'
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
name: Calculate hash for assets in release
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Check out repository code
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
- uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: 18
|
||||||
|
- name: Install packages
|
||||||
|
run: cd ./.github/actions/nym-hash-releases && npm i
|
||||||
|
|
||||||
|
- uses: ./.github/actions/nym-hash-releases
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
with:
|
||||||
|
release-tag-or-name-or-id: ${{ inputs.release_tag }}
|
||||||
|
|
||||||
|
- uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
name: Asset Hashes
|
||||||
|
path: hashes.json
|
||||||
@@ -32,5 +32,5 @@ jobs:
|
|||||||
run: yarn
|
run: yarn
|
||||||
|
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
run: yarn test:qa
|
run: yarn test:sandbox
|
||||||
working-directory: nym-api/tests
|
working-directory: nym-api/tests
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
16
|
18
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
const Handlebars = require('handlebars');
|
||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
async function addToContextAndValidate(context) {
|
||||||
|
if (!context.env.NYM_CI_WWW_LOCATION) {
|
||||||
|
throw new Error('Please ensure the env var NYM_CI_WWW_LOCATION is set');
|
||||||
|
}
|
||||||
|
if (!context.env.NYM_CI_WWW_BASE) {
|
||||||
|
throw new Error('Please ensure the env var NYM_CI_WWW_BASE is set');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getMessageBody(context) {
|
||||||
|
const source = fs
|
||||||
|
.readFileSync(
|
||||||
|
context.env.IS_SUCCESS === 'true'
|
||||||
|
? path.resolve(__dirname, 'templates', 'success')
|
||||||
|
: path.resolve(__dirname, 'templates', 'failure'),
|
||||||
|
)
|
||||||
|
.toString();
|
||||||
|
const template = Handlebars.compile(source);
|
||||||
|
return template(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
addToContextAndValidate,
|
||||||
|
getMessageBody,
|
||||||
|
};
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥
|
||||||
|
> :rocket: {{ env.NYM_PROJECT_NAME }}
|
||||||
|
>
|
||||||
|
> 🔴 **FAILURE** :cry:
|
||||||
|
>
|
||||||
|
> `branch` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/tree/{{ env.GIT_BRANCH_NAME }}
|
||||||
|
>
|
||||||
|
> `commit` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/commit/{{ env.GITHUB_SHA }}
|
||||||
|
>
|
||||||
|
> `build ` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/actions/runs/{{ env.GITHUB_RUN_ID }}
|
||||||
|
>
|
||||||
|
|
||||||
|
Commit message:
|
||||||
|
|
||||||
|
```
|
||||||
|
{{ env.GIT_COMMIT_MESSAGE }}
|
||||||
|
```
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩
|
||||||
|
> :rocket: {{ env.NYM_PROJECT_NAME }} ➡️➡️➡️➡️➡️ **View output:** https://{{ env.NYM_CI_WWW_BASE }}/developers/
|
||||||
|
>
|
||||||
|
> ✅ **SUCCESS**
|
||||||
|
>
|
||||||
|
> `branch` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/tree/{{ env.GIT_BRANCH_NAME }}
|
||||||
|
>
|
||||||
|
> `commit` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/commit/{{ env.GITHUB_SHA }}
|
||||||
|
>
|
||||||
|
> `build ` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/actions/runs/{{ env.GITHUB_RUN_ID }}
|
||||||
|
>
|
||||||
|
|
||||||
|
Commit message by `{{ env.GITHUB_ACTOR }}` at {{ timestamp }}:
|
||||||
|
|
||||||
|
```
|
||||||
|
{{ env.GIT_COMMIT_MESSAGE }}
|
||||||
|
```
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
const Handlebars = require('handlebars');
|
||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
async function addToContextAndValidate(context) {
|
||||||
|
if (!context.env.NYM_CI_WWW_LOCATION) {
|
||||||
|
throw new Error('Please ensure the env var NYM_CI_WWW_LOCATION is set');
|
||||||
|
}
|
||||||
|
if (!context.env.NYM_CI_WWW_BASE) {
|
||||||
|
throw new Error('Please ensure the env var NYM_CI_WWW_BASE is set');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getMessageBody(context) {
|
||||||
|
const source = fs
|
||||||
|
.readFileSync(
|
||||||
|
context.env.IS_SUCCESS === 'true'
|
||||||
|
? path.resolve(__dirname, 'templates', 'success')
|
||||||
|
: path.resolve(__dirname, 'templates', 'failure'),
|
||||||
|
)
|
||||||
|
.toString();
|
||||||
|
const template = Handlebars.compile(source);
|
||||||
|
return template(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
addToContextAndValidate,
|
||||||
|
getMessageBody,
|
||||||
|
};
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥
|
||||||
|
> :rocket: {{ env.NYM_PROJECT_NAME }}
|
||||||
|
> 🔴 **FAILURE** :cry:
|
||||||
|
> `branch` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/tree/{{ env.GIT_BRANCH_NAME }}
|
||||||
|
> `commit` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/commit/{{ env.GITHUB_SHA }}
|
||||||
|
> `build ` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/actions/runs/{{ env.GITHUB_RUN_ID }}
|
||||||
|
|
||||||
|
Commit message:
|
||||||
|
```
|
||||||
|
{{ env.GIT_COMMIT_MESSAGE }}
|
||||||
|
```
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩
|
||||||
|
> :rocket: {{ env.NYM_PROJECT_NAME }} ➡️➡️➡️➡️➡️ **View output:** https://{{ env.NYM_CI_WWW_BASE }}/docs/
|
||||||
|
>
|
||||||
|
> ✅ **SUCCESS**
|
||||||
|
>
|
||||||
|
> `branch` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/tree/{{ env.GIT_BRANCH_NAME }}
|
||||||
|
>
|
||||||
|
> `commit` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/commit/{{ env.GITHUB_SHA }}
|
||||||
|
>
|
||||||
|
> `build ` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/actions/runs/{{ env.GITHUB_RUN_ID }}
|
||||||
|
>
|
||||||
|
|
||||||
|
Commit message by `{{ env.GITHUB_ACTOR }}` at {{ timestamp }}:
|
||||||
|
|
||||||
|
```
|
||||||
|
{{ env.GIT_COMMIT_MESSAGE }}
|
||||||
|
```
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
const Handlebars = require('handlebars');
|
||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
async function addToContextAndValidate(context) {
|
||||||
|
if (!context.env.NYM_CI_WWW_LOCATION) {
|
||||||
|
throw new Error('Please ensure the env var NYM_CI_WWW_LOCATION is set');
|
||||||
|
}
|
||||||
|
if (!context.env.NYM_CI_WWW_BASE) {
|
||||||
|
throw new Error('Please ensure the env var NYM_CI_WWW_BASE is set');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getMessageBody(context) {
|
||||||
|
const source = fs
|
||||||
|
.readFileSync(
|
||||||
|
context.env.IS_SUCCESS === 'true'
|
||||||
|
? path.resolve(__dirname, 'templates', 'success')
|
||||||
|
: path.resolve(__dirname, 'templates', 'failure'),
|
||||||
|
)
|
||||||
|
.toString();
|
||||||
|
const template = Handlebars.compile(source);
|
||||||
|
return template(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
addToContextAndValidate,
|
||||||
|
getMessageBody,
|
||||||
|
};
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥
|
||||||
|
> :rocket: {{ env.NYM_PROJECT_NAME }}
|
||||||
|
>
|
||||||
|
> 🔴 **FAILURE** :cry:
|
||||||
|
>
|
||||||
|
> `branch` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/tree/{{ env.GIT_BRANCH_NAME }}
|
||||||
|
>
|
||||||
|
> `commit` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/commit/{{ env.GITHUB_SHA }}
|
||||||
|
>
|
||||||
|
> `build ` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/actions/runs/{{ env.GITHUB_RUN_ID }}
|
||||||
|
>
|
||||||
|
|
||||||
|
Commit message:
|
||||||
|
|
||||||
|
```
|
||||||
|
{{ env.GIT_COMMIT_MESSAGE }}
|
||||||
|
```
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩
|
||||||
|
> :rocket: {{ env.NYM_PROJECT_NAME }} ➡️➡️➡️➡️➡️ **View output:** https://{{ env.NYM_CI_WWW_LOCATION }}.{{ env.NYM_CI_WWW_BASE }}/
|
||||||
|
>
|
||||||
|
> ✅ **SUCCESS**
|
||||||
|
>
|
||||||
|
> `branch` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/tree/{{ env.GIT_BRANCH_NAME }}
|
||||||
|
>
|
||||||
|
> `commit` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/commit/{{ env.GITHUB_SHA }}
|
||||||
|
>
|
||||||
|
> `build ` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/actions/runs/{{ env.GITHUB_RUN_ID }}
|
||||||
|
>
|
||||||
|
|
||||||
|
Commit message by `{{ env.GITHUB_ACTOR }}` at {{ timestamp }}:
|
||||||
|
|
||||||
|
```
|
||||||
|
{{ env.GIT_COMMIT_MESSAGE }}
|
||||||
|
```
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
const Handlebars = require('handlebars');
|
||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
async function addToContextAndValidate(context) {
|
||||||
|
if (!context.env.NYM_CI_WWW_LOCATION) {
|
||||||
|
throw new Error('Please ensure the env var NYM_CI_WWW_LOCATION is set');
|
||||||
|
}
|
||||||
|
if (!context.env.NYM_CI_WWW_BASE) {
|
||||||
|
throw new Error('Please ensure the env var NYM_CI_WWW_BASE is set');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getMessageBody(context) {
|
||||||
|
const source = fs
|
||||||
|
.readFileSync(
|
||||||
|
context.env.IS_SUCCESS === 'true'
|
||||||
|
? path.resolve(__dirname, 'templates', 'success')
|
||||||
|
: path.resolve(__dirname, 'templates', 'failure'),
|
||||||
|
)
|
||||||
|
.toString();
|
||||||
|
const template = Handlebars.compile(source);
|
||||||
|
return template(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
addToContextAndValidate,
|
||||||
|
getMessageBody,
|
||||||
|
};
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥
|
||||||
|
> :rocket: {{ env.NYM_PROJECT_NAME }}
|
||||||
|
>
|
||||||
|
> 🔴 **FAILURE** :cry:
|
||||||
|
>
|
||||||
|
> `branch` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/tree/{{ env.GIT_BRANCH_NAME }}
|
||||||
|
>
|
||||||
|
> `commit` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/commit/{{ env.GITHUB_SHA }}
|
||||||
|
>
|
||||||
|
> `build ` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/actions/runs/{{ env.GITHUB_RUN_ID }}
|
||||||
|
>
|
||||||
|
|
||||||
|
Commit message:
|
||||||
|
|
||||||
|
```
|
||||||
|
{{ env.GIT_COMMIT_MESSAGE }}
|
||||||
|
```
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩
|
||||||
|
> :rocket: {{ env.NYM_PROJECT_NAME }} ➡️➡️➡️➡️➡️ **View output:** https://{{ env.NYM_CI_WWW_LOCATION }}.{{ env.NYM_CI_WWW_BASE }}/
|
||||||
|
>
|
||||||
|
> ✅ **SUCCESS**
|
||||||
|
>
|
||||||
|
> `branch` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/tree/{{ env.GIT_BRANCH_NAME }}
|
||||||
|
>
|
||||||
|
> `commit` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/commit/{{ env.GITHUB_SHA }}
|
||||||
|
>
|
||||||
|
> `build ` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/actions/runs/{{ env.GITHUB_RUN_ID }}
|
||||||
|
>
|
||||||
|
|
||||||
|
Commit message by `{{ env.GITHUB_ACTOR }}` at {{ timestamp }}:
|
||||||
|
|
||||||
|
```
|
||||||
|
{{ env.GIT_COMMIT_MESSAGE }}
|
||||||
|
```
|
||||||
@@ -3,7 +3,7 @@ require('dotenv').config();
|
|||||||
const { sendMatrixMessage } = require('./send_message_to_matrix');
|
const { sendMatrixMessage } = require('./send_message_to_matrix');
|
||||||
|
|
||||||
let context = {
|
let context = {
|
||||||
kinds: ['nym-wallet', 'ts-packages', 'network-explorer', 'nightly', 'nym-connect','security'],
|
kinds: ['nym-wallet', 'ts-packages', 'network-explorer', 'nightly', 'nym-connect','security','ci-docs','cd-docs','ci-dev','cd-dev'],
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -22,6 +22,6 @@
|
|||||||
"unified": "^9.2.2"
|
"unified": "^9.2.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"prettier": "2.3.2"
|
"prettier": "^2.8.7"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ async function addToContextAndValidate(context) {
|
|||||||
async function getMessageBody(context) {
|
async function getMessageBody(context) {
|
||||||
try {
|
try {
|
||||||
const source = fs
|
const source = fs
|
||||||
.readFileSync("deny.message").toString();
|
.readFileSync("./notifications/deny.message").toString();
|
||||||
return source;
|
return source;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
|
|||||||
@@ -1,64 +0,0 @@
|
|||||||
name: CI for linting Typescript
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
paths:
|
|
||||||
- 'ts-packages/**'
|
|
||||||
- 'sdk/typescript/**'
|
|
||||||
- 'nym-connect/desktop/src/**'
|
|
||||||
- 'nym-connect/desktop/package.json'
|
|
||||||
- 'nym-connect/mobile/src/**'
|
|
||||||
- 'nym-connect/mobile/package.json'
|
|
||||||
- 'nym-wallet/src/**'
|
|
||||||
- 'nym-wallet/package.json'
|
|
||||||
pull_request:
|
|
||||||
paths:
|
|
||||||
- 'ts-packages/**'
|
|
||||||
- 'sdk/typescript/**'
|
|
||||||
- 'nym-connect/desktop/src/**'
|
|
||||||
- 'nym-connect/desktop/package.json'
|
|
||||||
- 'nym-connect/mobile/src/**'
|
|
||||||
- 'nym-connect/mobile/package.json'
|
|
||||||
- 'nym-wallet/src/**'
|
|
||||||
- 'nym-wallet/package.json'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: custom-runner-linux
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- name: Install rsync
|
|
||||||
run: sudo apt-get install rsync
|
|
||||||
continue-on-error: true
|
|
||||||
- uses: rlespinasse/github-slug-action@v3.x
|
|
||||||
- uses: actions/setup-node@v3
|
|
||||||
with:
|
|
||||||
node-version: 16
|
|
||||||
- name: Setup yarn
|
|
||||||
run: npm install -g yarn
|
|
||||||
- name: Install
|
|
||||||
run: yarn
|
|
||||||
- name: Build packages
|
|
||||||
run: yarn build
|
|
||||||
- name: Lint
|
|
||||||
run: yarn lint && yarn tsc
|
|
||||||
- name: Matrix - Node Install
|
|
||||||
run: npm install
|
|
||||||
working-directory: .github/workflows/support-files
|
|
||||||
- name: Matrix - Send Notification
|
|
||||||
env:
|
|
||||||
NYM_NOTIFICATION_KIND: ts-packages
|
|
||||||
NYM_PROJECT_NAME: "ts-packages"
|
|
||||||
NYM_CI_WWW_BASE: "${{ secrets.NYM_CI_WWW_BASE }}"
|
|
||||||
NYM_CI_WWW_LOCATION: "ts-${{ env.GITHUB_REF_SLUG }}"
|
|
||||||
GIT_COMMIT_MESSAGE: "${{ github.event.head_commit.message }}"
|
|
||||||
GIT_BRANCH: "${GITHUB_REF##*/}"
|
|
||||||
IS_SUCCESS: "${{ job.status == 'success' }}"
|
|
||||||
MATRIX_SERVER: "${{ secrets.MATRIX_SERVER }}"
|
|
||||||
MATRIX_ROOM: "${{ secrets.MATRIX_ROOM }}"
|
|
||||||
MATRIX_USER_ID: "${{ secrets.MATRIX_USER_ID }}"
|
|
||||||
MATRIX_TOKEN: "${{ secrets.MATRIX_TOKEN }}"
|
|
||||||
MATRIX_DEVICE_ID: "${{ secrets.MATRIX_DEVICE_ID }}"
|
|
||||||
uses: docker://keybaseio/client:stable-node
|
|
||||||
with:
|
|
||||||
args: .github/workflows/support-files/notifications/entry_point.sh
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
name: Wasm Client
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
paths:
|
|
||||||
- 'clients/webassembly/**'
|
|
||||||
- 'clients/client-core/**'
|
|
||||||
- 'common/**'
|
|
||||||
- 'contracts/**'
|
|
||||||
- 'gateway/gateway-requests/**'
|
|
||||||
- 'nym-api/nym-api-requests/**'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
wasm:
|
|
||||||
runs-on: ubuntu-20.04
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
|
|
||||||
- uses: actions-rs/toolchain@v1
|
|
||||||
with:
|
|
||||||
profile: minimal
|
|
||||||
toolchain: stable
|
|
||||||
target: wasm32-unknown-unknown
|
|
||||||
override: true
|
|
||||||
components: rustfmt, clippy
|
|
||||||
|
|
||||||
- uses: actions-rs/cargo@v1
|
|
||||||
with:
|
|
||||||
command: build
|
|
||||||
args: --manifest-path clients/webassembly/Cargo.toml --target wasm32-unknown-unknown
|
|
||||||
|
|
||||||
- uses: actions-rs/cargo@v1
|
|
||||||
with:
|
|
||||||
command: fmt
|
|
||||||
args: --manifest-path clients/webassembly/Cargo.toml -- --check
|
|
||||||
|
|
||||||
- uses: actions-rs/cargo@v1
|
|
||||||
with:
|
|
||||||
command: clippy
|
|
||||||
args: --manifest-path clients/webassembly/Cargo.toml --target wasm32-unknown-unknown -- -D warnings
|
|
||||||
+5
-2
@@ -8,6 +8,7 @@
|
|||||||
.idea
|
.idea
|
||||||
target
|
target
|
||||||
.env
|
.env
|
||||||
|
.env.dev
|
||||||
/.vscode/settings.json
|
/.vscode/settings.json
|
||||||
validator/.vscode
|
validator/.vscode
|
||||||
sample-configs/validator-config.toml
|
sample-configs/validator-config.toml
|
||||||
@@ -39,7 +40,9 @@ validator-api-config.toml
|
|||||||
dist
|
dist
|
||||||
storybook-static
|
storybook-static
|
||||||
envs/qwerty.env
|
envs/qwerty.env
|
||||||
Cargo.lock
|
|
||||||
nym-connect/Cargo.lock
|
|
||||||
.parcel-cache
|
.parcel-cache
|
||||||
**/.DS_Store
|
**/.DS_Store
|
||||||
|
cpu-cycles/libcpucycles/build
|
||||||
|
foxyfox.env
|
||||||
|
|
||||||
|
.next
|
||||||
+329
@@ -4,6 +4,335 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
## [v1.1.31-kitkat] (2023-09-12)
|
||||||
|
|
||||||
|
- feat: add name to `TaskClient` ([#3844])
|
||||||
|
- added 'open_proxy', 'enabled_statistics' and 'statistics_recipient' to NR config ([#3839])
|
||||||
|
- MixFetch: initial prototype for insecure HTTP ([#3645])
|
||||||
|
- MixFetch: prototype implementing TLS in WASM for HTTPS ([#3644])
|
||||||
|
- SDK: build package for NodeJS ([#3558])
|
||||||
|
- [Issue] There is already an open connection to this client ([#2845])
|
||||||
|
|
||||||
|
[#3844]: https://github.com/nymtech/nym/pull/3844
|
||||||
|
[#3839]: https://github.com/nymtech/nym/pull/3839
|
||||||
|
[#3645]: https://github.com/nymtech/nym/issues/3645
|
||||||
|
[#3644]: https://github.com/nymtech/nym/issues/3644
|
||||||
|
[#3558]: https://github.com/nymtech/nym/issues/3558
|
||||||
|
[#2845]: https://github.com/nymtech/nym/issues/2845
|
||||||
|
|
||||||
|
## [v1.1.30-twix] (2023-09-05)
|
||||||
|
|
||||||
|
- geo_aware_provider: fix too much filtering of gateways ([#3826])
|
||||||
|
- network-requester: add description to config ([#3799])
|
||||||
|
- Speedy mode - selects gateway based on latency in medium / speedy mode ([#3770])
|
||||||
|
- Chore/enable versioning ([#3768])
|
||||||
|
- Create explorer-client and use in geo aware provider ([#3824])
|
||||||
|
|
||||||
|
[#3826]: https://github.com/nymtech/nym/pull/3826
|
||||||
|
[#3799]: https://github.com/nymtech/nym/pull/3799
|
||||||
|
[#3770]: https://github.com/nymtech/nym/issues/3770
|
||||||
|
[#3768]: https://github.com/nymtech/nym/pull/3768
|
||||||
|
[#3824]: https://github.com/nymtech/nym/pull/3824
|
||||||
|
|
||||||
|
## [v1.1.29-snickers] (2023-08-29)
|
||||||
|
|
||||||
|
- Add EXPLORER_API configurable url ([#3810])
|
||||||
|
- Bugfix/use correct tendermint dialect ([#3802])
|
||||||
|
- Explorer - look up gateways based on geo-location ([#3776])
|
||||||
|
- Speedy mode - select the mixnodes based on the location of the NR ([#3775])
|
||||||
|
- NR - reduce response time by removing poisson delay ([#3774])
|
||||||
|
- [demo] libp2p example with nym-sdk ([#3763])
|
||||||
|
- introduced /network/details endpoint to nym-api to return used network information ([#3758])
|
||||||
|
- Feature/issue credentials ([#3691])
|
||||||
|
|
||||||
|
[#3810]: https://github.com/nymtech/nym/pull/3810
|
||||||
|
[#3802]: https://github.com/nymtech/nym/pull/3802
|
||||||
|
[#3776]: https://github.com/nymtech/nym/issues/3776
|
||||||
|
[#3775]: https://github.com/nymtech/nym/issues/3775
|
||||||
|
[#3774]: https://github.com/nymtech/nym/issues/3774
|
||||||
|
[#3763]: https://github.com/nymtech/nym/pull/3763
|
||||||
|
[#3758]: https://github.com/nymtech/nym/pull/3758
|
||||||
|
[#3691]: https://github.com/nymtech/nym/pull/3691
|
||||||
|
|
||||||
|
## [v1.1.28] (2023-08-22)
|
||||||
|
|
||||||
|
- [final step3]: add [rust] support to nyxd client in wasm ([#3743])
|
||||||
|
- Feature/ephemera upgrade ([#3791])
|
||||||
|
- [rust-sdk] feat: make it more convenient to send and receive messages in different tasks ([#3756])
|
||||||
|
- feat: validator client refactoring + wasm compatible nyxd client ([#3726])
|
||||||
|
- feat: retain connection between client init and run ([#3767])
|
||||||
|
|
||||||
|
[#3743]: https://github.com/nymtech/nym/issues/3743
|
||||||
|
[#3791]: https://github.com/nymtech/nym/pull/3791
|
||||||
|
[#3756]: https://github.com/nymtech/nym/pull/3756
|
||||||
|
[#3726]: https://github.com/nymtech/nym/pull/3726
|
||||||
|
[#3767]: https://github.com/nymtech/nym/pull/3767
|
||||||
|
|
||||||
|
|
||||||
|
## [v1.1.27] (2023-08-16)
|
||||||
|
|
||||||
|
- fix serialisation of contract types ([#3752])
|
||||||
|
- Investigate spending credentials from the main API (coconut enabled to a gateway) from feature/ephemera branch ([#3741])
|
||||||
|
- NymConnect UI stuck in showing "Gateway has issues" ([#3594])
|
||||||
|
- [UPDATE] Update MiniBolt community-applications-and-guides dev docs ([#3754])
|
||||||
|
|
||||||
|
[#3752]: https://github.com/nymtech/nym/issues/3752
|
||||||
|
[#3741]: https://github.com/nymtech/nym/issues/3741
|
||||||
|
[#3594]: https://github.com/nymtech/nym/issues/3594
|
||||||
|
[#3754]: https://github.com/nymtech/nym/pull/3754
|
||||||
|
|
||||||
|
## [v1.1.24] (2023-08-08)
|
||||||
|
|
||||||
|
- Latency based gateway selection is serial and slow ([#3710])
|
||||||
|
- Network-requester: strip comments from allow lists ([#3625])
|
||||||
|
- Remove (or start maintaining) `upgrade` commands from all binaries ([#3600])
|
||||||
|
- Set sphinx as default packet type ([#3748])
|
||||||
|
- Apply fix from feature/ephemera to develop too (#3698) ([#3742])
|
||||||
|
- Feature/coco demos ([#3732])
|
||||||
|
- Add updates to community list projects ([#3722])
|
||||||
|
- Add geo-aware mixnet topology provider ([#3713])
|
||||||
|
- Add updates to community list projects ([#3711])
|
||||||
|
|
||||||
|
[#3710]: https://github.com/nymtech/nym/issues/3710
|
||||||
|
[#3625]: https://github.com/nymtech/nym/issues/3625
|
||||||
|
[#3600]: https://github.com/nymtech/nym/issues/3600
|
||||||
|
[#3748]: https://github.com/nymtech/nym/pull/3748
|
||||||
|
[#3742]: https://github.com/nymtech/nym/pull/3742
|
||||||
|
[#3732]: https://github.com/nymtech/nym/pull/3732
|
||||||
|
[#3722]: https://github.com/nymtech/nym/pull/3722
|
||||||
|
[#3713]: https://github.com/nymtech/nym/pull/3713
|
||||||
|
[#3711]: https://github.com/nymtech/nym/pull/3711
|
||||||
|
|
||||||
|
## [v1.1.23] (2023-07-04)
|
||||||
|
|
||||||
|
- nym-cli: add client identity key signing support ([#3576])
|
||||||
|
- Feature/node tester package ([#3634])
|
||||||
|
- Add medium toggle to socks5 client ([#3615])
|
||||||
|
- Don't fully turn off background task when cover traffic is disabled ([#3596])
|
||||||
|
|
||||||
|
[#3576]: https://github.com/nymtech/nym/issues/3576
|
||||||
|
[#3634]: https://github.com/nymtech/nym/pull/3634
|
||||||
|
[#3615]: https://github.com/nymtech/nym/pull/3615
|
||||||
|
[#3596]: https://github.com/nymtech/nym/pull/3596
|
||||||
|
|
||||||
|
## [v1.1.22] (2023-06-20)
|
||||||
|
|
||||||
|
- CLI tool for querying network-requesters ([#3539])
|
||||||
|
- Statically link OpenSSL ([#3510])
|
||||||
|
- NymConnect - add sentry.io reporting ([#3421])
|
||||||
|
- init command does not change version number in config.toml ([#3336])
|
||||||
|
- [Bug] Config version does not correspond to binary version ([#3434])
|
||||||
|
|
||||||
|
[#3539]: https://github.com/nymtech/nym/issues/3539
|
||||||
|
[#3510]: https://github.com/nymtech/nym/issues/3510
|
||||||
|
[#3421]: https://github.com/nymtech/nym/issues/3421
|
||||||
|
[#3336]: https://github.com/nymtech/nym/issues/3336
|
||||||
|
[#3434]: https://github.com/nymtech/nym/issues/3434
|
||||||
|
|
||||||
|
## [v1.1.21] (2023-06-13)
|
||||||
|
|
||||||
|
- mixFetch: Change socks5 `SendRequest` to include OrderedMessage index as a field rather than making it serialized inside the `data` field
|
||||||
|
([#3534])
|
||||||
|
- Explorer - add more data columns to the Service Provider section: ([#3474])
|
||||||
|
- network-requester: support report if they run an open proxy using `ControlRequest` API ([#3461])
|
||||||
|
- Refactor client configs (London discussion) ([#3444])
|
||||||
|
- Increase `DEFAULT_MAXIMUM_CONNECTION_BUFFER_SIZE` to 2000 to improve reliability ([#3433])
|
||||||
|
- socks5: sender waits for lanes to clear even though the connection is closed ([#3366])
|
||||||
|
- version bump for variables ([#3545])
|
||||||
|
|
||||||
|
[#3534]: https://github.com/nymtech/nym/issues/3534
|
||||||
|
[#3474]: https://github.com/nymtech/nym/issues/3474
|
||||||
|
[#3461]: https://github.com/nymtech/nym/issues/3461
|
||||||
|
[#3444]: https://github.com/nymtech/nym/issues/3444
|
||||||
|
[#3433]: https://github.com/nymtech/nym/issues/3433
|
||||||
|
[#3366]: https://github.com/nymtech/nym/issues/3366
|
||||||
|
[#3545]: https://github.com/nymtech/nym/pull/3545
|
||||||
|
|
||||||
|
## [v1.1.20] (2023-06-06)
|
||||||
|
|
||||||
|
- Explorer - Fix SP supported apps list ([#3458])
|
||||||
|
- Investigate if we need to lower `SHUTDOWN_TIMEOUT` in socks5 to zero (or almost zero) ([#3438])
|
||||||
|
- Explorer - show all gateways in the default view regardless of the version number ([#3427])
|
||||||
|
- service-provider-directory: add signature check when announcing ([#3360])
|
||||||
|
- Support functionality for nym-name-service (nym-api, nym-cli, etc) ([#3355])
|
||||||
|
- Edit the nym-network-requester to support the enabled-credentials-mode flag ([#3101])
|
||||||
|
- [BUG] network requester documentation update ([#3493])
|
||||||
|
- removing hardcoded version numbers ([#3485])
|
||||||
|
- [BUG] network requester documentation update ([#3481])
|
||||||
|
- [BUG] network requester documentation update ([#3469])
|
||||||
|
- Sign when announcing service providers to the directory contract ([#3459])
|
||||||
|
- mixnode documentation update ([#3435])
|
||||||
|
- updated readme with new developer chat links + new docs links ([#3141])
|
||||||
|
|
||||||
|
[#3458]: https://github.com/nymtech/nym/issues/3458
|
||||||
|
[#3438]: https://github.com/nymtech/nym/issues/3438
|
||||||
|
[#3427]: https://github.com/nymtech/nym/issues/3427
|
||||||
|
[#3360]: https://github.com/nymtech/nym/issues/3360
|
||||||
|
[#3355]: https://github.com/nymtech/nym/issues/3355
|
||||||
|
[#3101]: https://github.com/nymtech/nym/issues/3101
|
||||||
|
[#3493]: https://github.com/nymtech/nym/pull/3493
|
||||||
|
[#3485]: https://github.com/nymtech/nym/pull/3485
|
||||||
|
[#3481]: https://github.com/nymtech/nym/pull/3481
|
||||||
|
[#3469]: https://github.com/nymtech/nym/pull/3469
|
||||||
|
[#3459]: https://github.com/nymtech/nym/pull/3459
|
||||||
|
[#3435]: https://github.com/nymtech/nym/pull/3435
|
||||||
|
[#3141]: https://github.com/nymtech/nym/pull/3141
|
||||||
|
|
||||||
|
## [v1.1.19] (2023-05-16)
|
||||||
|
|
||||||
|
- nym-name-service endpoint in nym-api ([#3403])
|
||||||
|
- Implement key storage for WASM client using IndexedDB (for browser) ([#3329])
|
||||||
|
- Initial version of nym-name-service contract providing name aliases for nym-addresses ([#3274])
|
||||||
|
- Update Cargo.lock ([#3410])
|
||||||
|
|
||||||
|
[#3403]: https://github.com/nymtech/nym/issues/3403
|
||||||
|
[#3329]: https://github.com/nymtech/nym/issues/3329
|
||||||
|
[#3274]: https://github.com/nymtech/nym/issues/3274
|
||||||
|
[#3410]: https://github.com/nymtech/nym/pull/3410
|
||||||
|
|
||||||
|
## [v1.1.18] (2023-05-09)
|
||||||
|
|
||||||
|
- Implement heartbeat messages between socks5 proxy and network requester ([#3215])
|
||||||
|
|
||||||
|
[#3215]: https://github.com/nymtech/nym/issues/3215
|
||||||
|
|
||||||
|
## [v1.1.17] (2023-05-02)
|
||||||
|
|
||||||
|
- Add service-provider-directory-contract support to nym-cli ([#3334])
|
||||||
|
- Start using the node-testing-utils (implemented in #3270) in nym-api Network monitor to simplify the logic there ([#3312])
|
||||||
|
- Add service-provider-directory support to validator-client ([#3296])
|
||||||
|
- Allow topology injection in our WASM client ('test my node' feature) ([#3270])
|
||||||
|
- Expose service-provider-directory contract data in nym-api endpoints ([#3242])
|
||||||
|
- Cache service provider contract in nym-api ([#3241])
|
||||||
|
- Feature/1 1 17 docs ([#3370])
|
||||||
|
- adding a test for SP endpoint ([#3367])
|
||||||
|
- Feature/store cipher ([#3350])
|
||||||
|
|
||||||
|
[#3334]: https://github.com/nymtech/nym/issues/3334
|
||||||
|
[#3312]: https://github.com/nymtech/nym/issues/3312
|
||||||
|
[#3296]: https://github.com/nymtech/nym/issues/3296
|
||||||
|
[#3270]: https://github.com/nymtech/nym/issues/3270
|
||||||
|
[#3242]: https://github.com/nymtech/nym/issues/3242
|
||||||
|
[#3241]: https://github.com/nymtech/nym/issues/3241
|
||||||
|
[#3370]: https://github.com/nymtech/nym/pull/3370
|
||||||
|
[#3367]: https://github.com/nymtech/nym/pull/3367
|
||||||
|
[#3350]: https://github.com/nymtech/nym/pull/3350
|
||||||
|
|
||||||
|
## [v1.1.16] (2023-04-25)
|
||||||
|
|
||||||
|
- Explorer - Fix sorting function on Stake Saturation. It is currently working per page and not globally ([#3320])
|
||||||
|
- Poisson process gets stuck at too slow rate. Rework to more aggressively up-regulate ([#3309])
|
||||||
|
- decrease the logging level of warnings associated with clients dropping packets due to gateway being overloaded (I'd say reduce it to debug/trace) - there are few sources of those, e.g. in real and cover traffic streams ([#3299])
|
||||||
|
- Make the buffer size in `AvailableReader` depend on packet sizes the client is using + introduce read timeouts ([#3213])
|
||||||
|
- Rust SDK - Support coconut, credential storage etc ([#2755])
|
||||||
|
- version bump for next release ([#3349])
|
||||||
|
- added coconut credential generation example ([#3339])
|
||||||
|
- update mix-node setup docs with node description ([#3325])
|
||||||
|
- exposed missing gateway commands in nym-cli ([#3324])
|
||||||
|
- make sure to clear inner 'ack_map' in 'GatewaysReader' ([#3300])
|
||||||
|
|
||||||
|
[#3320]: https://github.com/nymtech/nym/issues/3320
|
||||||
|
[#3309]: https://github.com/nymtech/nym/issues/3309
|
||||||
|
[#3299]: https://github.com/nymtech/nym/issues/3299
|
||||||
|
[#3213]: https://github.com/nymtech/nym/issues/3213
|
||||||
|
[#2755]: https://github.com/nymtech/nym/issues/2755
|
||||||
|
[#3349]: https://github.com/nymtech/nym/pull/3349
|
||||||
|
[#3339]: https://github.com/nymtech/nym/pull/3339
|
||||||
|
[#3325]: https://github.com/nymtech/nym/pull/3325
|
||||||
|
[#3324]: https://github.com/nymtech/nym/pull/3324
|
||||||
|
[#3300]: https://github.com/nymtech/nym/pull/3300
|
||||||
|
|
||||||
|
## [v1.1.15] (2023-04-18)
|
||||||
|
|
||||||
|
- Fix verloc being stuck waiting for shutdown signal ([#3250])
|
||||||
|
- Introduce `--output json` flag to `sign` command to allow to more easily capture the output ([#3249])
|
||||||
|
- Explorer - Dont fetch Service Provider list on Testnet ([#3245])
|
||||||
|
- When determining active set, rather than weighting the nodes by just the `stake`, use `stake * performance` ([#3234])
|
||||||
|
- Introduce dual packet sizes to our clients (as in use two packet sizes at the same time depending on message size) ([#3189])
|
||||||
|
- Experiment with offline signing in our validator client ([#3174])
|
||||||
|
- Modify network requester binary to reload `allowed.list` periodically to pull in any changes made upstream without having to restart the service ([#3149])
|
||||||
|
- Standardise all `--output json` on binary inits, we pass the output json at different points for different binaries. ([#3080])
|
||||||
|
- Service provider directory contract: initial version ([#2759])
|
||||||
|
- Fix issue where network-requester run failed on fresh init due to missing allow file ([#3316])
|
||||||
|
|
||||||
|
[#3250]: https://github.com/nymtech/nym/issues/3250
|
||||||
|
[#3249]: https://github.com/nymtech/nym/issues/3249
|
||||||
|
[#3245]: https://github.com/nymtech/nym/issues/3245
|
||||||
|
[#3234]: https://github.com/nymtech/nym/issues/3234
|
||||||
|
[#3189]: https://github.com/nymtech/nym/issues/3189
|
||||||
|
[#3174]: https://github.com/nymtech/nym/issues/3174
|
||||||
|
[#3149]: https://github.com/nymtech/nym/issues/3149
|
||||||
|
[#3080]: https://github.com/nymtech/nym/issues/3080
|
||||||
|
[#2759]: https://github.com/nymtech/nym/issues/2759
|
||||||
|
[#3316]: https://github.com/nymtech/nym/pull/3316
|
||||||
|
|
||||||
|
## [v1.1.14] (2023-04-04)
|
||||||
|
|
||||||
|
- Investigate cause of qwerty validator being in invalid rewarding state ([#3224])
|
||||||
|
- Fix NR config due to changes in #3199 ([#3223])
|
||||||
|
- [Issue] Mixnodes and gateway do not close connections properly ([#3187])
|
||||||
|
- disable sign-ext when using wasm-opt + update wasm-opt ([#3203])
|
||||||
|
- chore: tidy up client `Debug` config section ([#3199])
|
||||||
|
|
||||||
|
[#3224]: https://github.com/nymtech/nym/issues/3224
|
||||||
|
[#3223]: https://github.com/nymtech/nym/issues/3223
|
||||||
|
[#3187]: https://github.com/nymtech/nym/issues/3187
|
||||||
|
[#3203]: https://github.com/nymtech/nym/pull/3203
|
||||||
|
[#3199]: https://github.com/nymtech/nym/pull/3199
|
||||||
|
>>>>>>> master
|
||||||
|
|
||||||
|
## [v1.1.13] (2023-03-15)
|
||||||
|
|
||||||
|
- NE - instead of throwing a "Mixnode/Gateway not found" error for blacklisted nodes due to bad performance, show their history but tag them as "Having poor performance" ([#2979])
|
||||||
|
- NE - Upgrade Sandbox and make below changes: ([#2332])
|
||||||
|
- Explorer - Updates ([#3168])
|
||||||
|
- Website v2 - deploy infrastructure for strapi and CI ([#2213])
|
||||||
|
- add blockstream green to sp list ([#3180])
|
||||||
|
- mock-nym-api: fix .storybook lint error ([#3178])
|
||||||
|
- Validating new interval config parameters to prevent division by zero ([#3153])
|
||||||
|
|
||||||
|
[#2979]: https://github.com/nymtech/nym/issues/2979
|
||||||
|
[#2332]: https://github.com/nymtech/nym/issues/2332
|
||||||
|
[#3168]: https://github.com/nymtech/nym/issues/3168
|
||||||
|
[#2213]: https://github.com/nymtech/nym/issues/2213
|
||||||
|
[#3180]: https://github.com/nymtech/nym/pull/3180
|
||||||
|
[#3178]: https://github.com/nymtech/nym/pull/3178
|
||||||
|
[#3153]: https://github.com/nymtech/nym/pull/3153
|
||||||
|
|
||||||
|
## [v1.1.12] (2023-03-07)
|
||||||
|
|
||||||
|
- Fix generated docs for mixnet and vesting contract on docs.rs ([#3093])
|
||||||
|
- Introduce a way of injecting topology into the client ([#3044])
|
||||||
|
- Update mixnet TypeScript client methods #1 ([#2783])
|
||||||
|
- Update tooltips for routing and average score ([#3133])
|
||||||
|
- update selected service provider description style ([#3128])
|
||||||
|
|
||||||
|
[#3093]: https://github.com/nymtech/nym/issues/3093
|
||||||
|
[#3044]: https://github.com/nymtech/nym/issues/3044
|
||||||
|
[#2783]: https://github.com/nymtech/nym/issues/2783
|
||||||
|
[#3133]: https://github.com/nymtech/nym/pull/3133
|
||||||
|
[#3128]: https://github.com/nymtech/nym/pull/3128
|
||||||
|
|
||||||
|
## [v1.1.11] (2023-02-28)
|
||||||
|
|
||||||
|
- Fix empty dealer set loop ([#3105])
|
||||||
|
- The nym-api db.sqlite is broken when trying to run against it it in `enabled-credentials-mode true` there is an ordering issue with migrations when using the credential binary to purchase bandwidth ([#3100])
|
||||||
|
- Feature/latency based gateway selection ([#3081])
|
||||||
|
- Fix the credential binary to handle transactions to sleep when in non-inProgress epochs ([#3057])
|
||||||
|
- Publish mixnet contract to crates.io ([#1919])
|
||||||
|
- Publish vesting contract to crates.io ([#1920])
|
||||||
|
- Feature/update checker to use master ([#3097])
|
||||||
|
- Feature/improve binary checks ([#3094])
|
||||||
|
|
||||||
|
[#3105]: https://github.com/nymtech/nym/issues/3105
|
||||||
|
[#3100]: https://github.com/nymtech/nym/issues/3100
|
||||||
|
[#3081]: https://github.com/nymtech/nym/pull/3081
|
||||||
|
[#3057]: https://github.com/nymtech/nym/issues/3057
|
||||||
|
[#1919]: https://github.com/nymtech/nym/issues/1919
|
||||||
|
[#1920]: https://github.com/nymtech/nym/issues/1920
|
||||||
|
[#3097]: https://github.com/nymtech/nym/pull/3097
|
||||||
|
[#3094]: https://github.com/nymtech/nym/pull/3094
|
||||||
|
|
||||||
## [v1.1.10] (2023-02-21)
|
## [v1.1.10] (2023-02-21)
|
||||||
|
|
||||||
- Verloc listener causing mixnode unexpected shutdown ([#3038])
|
- Verloc listener causing mixnode unexpected shutdown ([#3038])
|
||||||
|
|||||||
Generated
+6973
-1746
File diff suppressed because it is too large
Load Diff
+91
-10
@@ -17,13 +17,13 @@ opt-level = 3
|
|||||||
|
|
||||||
resolver = "2"
|
resolver = "2"
|
||||||
members = [
|
members = [
|
||||||
"clients/client-core",
|
|
||||||
"clients/credential",
|
|
||||||
"clients/native",
|
"clients/native",
|
||||||
"clients/native/websocket-requests",
|
"clients/native/websocket-requests",
|
||||||
"clients/socks5",
|
"clients/socks5",
|
||||||
"common/bandwidth-claim-contract",
|
"common/async-file-watcher",
|
||||||
|
"common/bandwidth-controller",
|
||||||
"common/bin-common",
|
"common/bin-common",
|
||||||
|
"common/client-core",
|
||||||
"common/client-libs/gateway-client",
|
"common/client-libs/gateway-client",
|
||||||
"common/client-libs/mixnet-client",
|
"common/client-libs/mixnet-client",
|
||||||
"common/client-libs/validator-client",
|
"common/client-libs/validator-client",
|
||||||
@@ -33,20 +33,25 @@ members = [
|
|||||||
"common/cosmwasm-smart-contracts/coconut-bandwidth-contract",
|
"common/cosmwasm-smart-contracts/coconut-bandwidth-contract",
|
||||||
"common/cosmwasm-smart-contracts/coconut-dkg",
|
"common/cosmwasm-smart-contracts/coconut-dkg",
|
||||||
"common/cosmwasm-smart-contracts/contracts-common",
|
"common/cosmwasm-smart-contracts/contracts-common",
|
||||||
|
"common/cosmwasm-smart-contracts/ephemera",
|
||||||
"common/cosmwasm-smart-contracts/group-contract",
|
"common/cosmwasm-smart-contracts/group-contract",
|
||||||
"common/cosmwasm-smart-contracts/mixnet-contract",
|
"common/cosmwasm-smart-contracts/mixnet-contract",
|
||||||
"common/cosmwasm-smart-contracts/multisig-contract",
|
"common/cosmwasm-smart-contracts/multisig-contract",
|
||||||
|
"common/cosmwasm-smart-contracts/name-service",
|
||||||
|
"common/cosmwasm-smart-contracts/service-provider-directory",
|
||||||
"common/cosmwasm-smart-contracts/vesting-contract",
|
"common/cosmwasm-smart-contracts/vesting-contract",
|
||||||
"common/mobile-storage",
|
|
||||||
"common/credential-storage",
|
"common/credential-storage",
|
||||||
"common/credentials",
|
"common/credentials",
|
||||||
|
"common/credential-utils",
|
||||||
"common/crypto",
|
"common/crypto",
|
||||||
"common/dkg",
|
"common/dkg",
|
||||||
"common/execute",
|
"common/execute",
|
||||||
|
"common/http-requests",
|
||||||
"common/inclusion-probability",
|
"common/inclusion-probability",
|
||||||
"common/ledger",
|
"common/ledger",
|
||||||
"common/mixnode-common",
|
"common/mixnode-common",
|
||||||
"common/network-defaults",
|
"common/network-defaults",
|
||||||
|
"common/node-tester-utils",
|
||||||
"common/nonexhaustive-delayqueue",
|
"common/nonexhaustive-delayqueue",
|
||||||
"common/nymcoconut",
|
"common/nymcoconut",
|
||||||
"common/nymsphinx",
|
"common/nymsphinx",
|
||||||
@@ -58,29 +63,46 @@ members = [
|
|||||||
"common/nymsphinx/forwarding",
|
"common/nymsphinx/forwarding",
|
||||||
"common/nymsphinx/framing",
|
"common/nymsphinx/framing",
|
||||||
"common/nymsphinx/params",
|
"common/nymsphinx/params",
|
||||||
|
"common/nymsphinx/routing",
|
||||||
"common/nymsphinx/types",
|
"common/nymsphinx/types",
|
||||||
"common/pemstore",
|
"common/pemstore",
|
||||||
|
"common/socks5-client-core",
|
||||||
"common/socks5/proxy-helpers",
|
"common/socks5/proxy-helpers",
|
||||||
"common/socks5/requests",
|
"common/socks5/requests",
|
||||||
"common/statistics",
|
"common/statistics",
|
||||||
|
"common/store-cipher",
|
||||||
"common/task",
|
"common/task",
|
||||||
"common/topology",
|
"common/topology",
|
||||||
"common/types",
|
"common/types",
|
||||||
"common/wasm-utils",
|
"common/wasm/client-core",
|
||||||
|
"common/wasm/storage",
|
||||||
|
"common/wasm/utils",
|
||||||
|
"common/wireguard",
|
||||||
"explorer-api",
|
"explorer-api",
|
||||||
|
"explorer-api/explorer-api-requests",
|
||||||
|
"explorer-api/explorer-client",
|
||||||
"gateway",
|
"gateway",
|
||||||
"gateway/gateway-requests",
|
"gateway/gateway-requests",
|
||||||
"integrations/bity",
|
"integrations/bity",
|
||||||
"mixnode",
|
"mixnode",
|
||||||
|
"sdk/lib/socks5-listener",
|
||||||
"sdk/rust/nym-sdk",
|
"sdk/rust/nym-sdk",
|
||||||
"service-providers/common",
|
"service-providers/common",
|
||||||
"service-providers/network-requester",
|
"service-providers/network-requester",
|
||||||
"service-providers/network-statistics",
|
"service-providers/network-statistics",
|
||||||
"nym-api",
|
"nym-api",
|
||||||
|
"nym-browser-extension/storage",
|
||||||
"nym-api/nym-api-requests",
|
"nym-api/nym-api-requests",
|
||||||
"nym-outfox",
|
"nym-outfox",
|
||||||
|
"tools/internal/ssl-inject",
|
||||||
|
"tools/internal/sdk-version-bump",
|
||||||
"tools/nym-cli",
|
"tools/nym-cli",
|
||||||
"tools/ts-rs-cli"
|
"tools/nym-nr-query",
|
||||||
|
"tools/ts-rs-cli",
|
||||||
|
"wasm/client",
|
||||||
|
"wasm/full-nym-wasm",
|
||||||
|
"wasm/mix-fetch",
|
||||||
|
"wasm/node-tester",
|
||||||
]
|
]
|
||||||
|
|
||||||
default-members = [
|
default-members = [
|
||||||
@@ -94,7 +116,7 @@ default-members = [
|
|||||||
"explorer-api",
|
"explorer-api",
|
||||||
]
|
]
|
||||||
|
|
||||||
exclude = ["explorer", "contracts", "clients/webassembly", "nym-wallet", "nym-connect/mobile/src-tauri", "nym-connect/desktop"]
|
exclude = ["explorer", "contracts", "nym-wallet", "nym-connect/mobile/src-tauri", "nym-connect/desktop", "cpu-cycles"]
|
||||||
|
|
||||||
[workspace.package]
|
[workspace.package]
|
||||||
authors = ["Nym Technologies SA"]
|
authors = ["Nym Technologies SA"]
|
||||||
@@ -105,16 +127,75 @@ edition = "2021"
|
|||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
|
|
||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
async-trait = "0.1.63"
|
anyhow = "1.0.71"
|
||||||
|
async-trait = "0.1.68"
|
||||||
|
bip39 = { version = "2.0.0", features = ["zeroize"] }
|
||||||
cfg-if = "1.0.0"
|
cfg-if = "1.0.0"
|
||||||
dotenv = "0.15.0"
|
cosmwasm-derive = "=1.3.0"
|
||||||
|
cosmwasm-schema = "=1.3.0"
|
||||||
|
cosmwasm-std = "=1.3.0"
|
||||||
|
# use 0.5.0 as that's the version used by cosmwasm-std 1.3.0
|
||||||
|
# (and ideally we don't want to pull the same dependency twice)
|
||||||
|
serde-json-wasm = "=0.5.0"
|
||||||
|
cosmwasm-storage = "=1.3.0"
|
||||||
|
cosmrs = "=0.14.0"
|
||||||
|
# same version as used by cosmrs
|
||||||
|
cw-utils = "=1.0.1"
|
||||||
|
cw-storage-plus = "=1.1.0"
|
||||||
|
cw2 = { version = "=1.1.0" }
|
||||||
|
cw3 = { version = "=1.1.0" }
|
||||||
|
cw4 = { version = "=1.1.0" }
|
||||||
|
cw-controllers = { version = "=1.1.0" }
|
||||||
|
dashmap = "5.5.3"
|
||||||
|
dotenvy = "0.15.6"
|
||||||
|
futures = "0.3.28"
|
||||||
|
generic-array = "0.14.7"
|
||||||
|
getrandom = "0.2.10"
|
||||||
|
k256 = "0.13"
|
||||||
lazy_static = "1.4.0"
|
lazy_static = "1.4.0"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
once_cell = "1.7.2"
|
once_cell = "1.7.2"
|
||||||
|
parking_lot = "0.12.1"
|
||||||
rand = "0.8.5"
|
rand = "0.8.5"
|
||||||
|
reqwest = "0.11.18"
|
||||||
serde = "1.0.152"
|
serde = "1.0.152"
|
||||||
serde_json = "1.0.91"
|
serde_json = "1.0.91"
|
||||||
tap = "1.0.1"
|
tap = "1.0.1"
|
||||||
|
tendermint-rpc = "0.32" # same version as used by cosmrs
|
||||||
thiserror = "1.0.38"
|
thiserror = "1.0.38"
|
||||||
tokio = "1.24.1"
|
tokio = "1.24.1"
|
||||||
url = "2.2"
|
ts-rs = "7.0.0"
|
||||||
|
url = "2.4"
|
||||||
|
zeroize = "1.6.0"
|
||||||
|
|
||||||
|
# wasm-related dependencies
|
||||||
|
gloo-utils = "0.1.7"
|
||||||
|
js-sys = "0.3.63"
|
||||||
|
serde-wasm-bindgen = "0.5.0"
|
||||||
|
tsify = "0.4.5"
|
||||||
|
wasm-bindgen = "0.2.86"
|
||||||
|
wasm-bindgen-futures = "0.4.37"
|
||||||
|
wasmtimer = "0.2.0"
|
||||||
|
web-sys = "0.3.63"
|
||||||
|
|
||||||
|
# Profile settings for individual crates
|
||||||
|
|
||||||
|
[profile.release.package.nym-socks5-listener]
|
||||||
|
strip = true
|
||||||
|
codegen-units = 1
|
||||||
|
|
||||||
|
[profile.release.package.nym-client-wasm]
|
||||||
|
# lto = true
|
||||||
|
opt-level = 'z'
|
||||||
|
|
||||||
|
[profile.release.package.nym-node-tester-wasm]
|
||||||
|
# lto = true
|
||||||
|
opt-level = 'z'
|
||||||
|
|
||||||
|
[profile.release.package.nym-wasm-sdk]
|
||||||
|
# lto = true
|
||||||
|
opt-level = 'z'
|
||||||
|
|
||||||
|
[profile.release.package.mix-fetch-wasm]
|
||||||
|
# lto = true
|
||||||
|
opt-level = 'z'
|
||||||
|
|||||||
@@ -1,134 +1,191 @@
|
|||||||
test: clippy-all cargo-test wasm fmt
|
# Default target
|
||||||
|
all: test
|
||||||
|
|
||||||
|
test: clippy cargo-test contracts-wasm sdk-wasm-test fmt
|
||||||
|
|
||||||
test-all: test cargo-test-expensive
|
test-all: test cargo-test-expensive
|
||||||
no-clippy: build cargo-test wasm fmt
|
|
||||||
|
no-clippy: build cargo-test contracts-wasm fmt fmt-browser-extension-storage
|
||||||
|
|
||||||
happy: fmt clippy-happy test
|
happy: fmt clippy-happy test
|
||||||
clippy-all: clippy-main clippy-main-examples clippy-all-contracts clippy-all-wallet clippy-all-connect clippy-all-connect-mobile clippy-all-wasm-client
|
|
||||||
clippy-happy: clippy-happy-main clippy-happy-contracts clippy-happy-wallet clippy-happy-connect clippy-happy-connect-mobile
|
|
||||||
cargo-test: test-main test-contracts test-wallet test-connect test-connect-mobile
|
|
||||||
cargo-test-expensive: test-main-expensive test-contracts-expensive test-wallet-expensive test-connect-expensive
|
|
||||||
build: build-contracts build-wallet build-main build-main-examples build-connect build-connect-mobile build-wasm-client
|
|
||||||
fmt: fmt-main fmt-contracts fmt-wallet fmt-connect fmt-connect-mobile fmt-wasm-client
|
|
||||||
|
|
||||||
clippy-happy-main:
|
build: sdk-wasm-build build-browser-extension-storage
|
||||||
cargo clippy
|
|
||||||
|
|
||||||
clippy-happy-contracts:
|
# Building release binaries is a little manual as we can't just build --release
|
||||||
cargo clippy --manifest-path contracts/Cargo.toml --target wasm32-unknown-unknown
|
# on all workspaces.
|
||||||
|
build-release: build-release-main contracts-wasm
|
||||||
|
|
||||||
clippy-happy-wallet:
|
clippy: sdk-wasm-lint clippy-browser-extension-storage
|
||||||
cargo clippy --manifest-path nym-wallet/Cargo.toml
|
|
||||||
|
|
||||||
clippy-happy-connect:
|
# -----------------------------------------------------------------------------
|
||||||
cargo clippy --manifest-path nym-connect/desktop/Cargo.toml
|
# Define targets for a given workspace
|
||||||
|
# $(1): name
|
||||||
|
# $(2): path to workspace
|
||||||
|
# $(3): extra arguments to cargo
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
define add_cargo_workspace
|
||||||
|
|
||||||
clippy-happy-connect-mobile:
|
clippy-happy-$(1):
|
||||||
cargo clippy --manifest-path nym-connect/mobile/src-tauri/Cargo.toml
|
cargo clippy --manifest-path $(2)/Cargo.toml $(3)
|
||||||
|
|
||||||
clippy-main:
|
clippy-$(1):
|
||||||
cargo clippy --workspace -- -D warnings
|
cargo clippy --manifest-path $(2)/Cargo.toml --workspace $(3) -- -D warnings
|
||||||
|
|
||||||
clippy-main-examples:
|
clippy-examples-$(1):
|
||||||
cargo clippy --workspace --examples -- -D warnings
|
cargo clippy --manifest-path $(2)/Cargo.toml --workspace --examples -- -D warnings
|
||||||
|
|
||||||
clippy-wasm:
|
check-$(1):
|
||||||
cargo clippy --manifest-path clients/webassembly/Cargo.toml --target wasm32-unknown-unknown --workspace -- -D warnings
|
cargo check --manifest-path $(2)/Cargo.toml --workspace $(3)
|
||||||
|
|
||||||
|
test-$(1):
|
||||||
|
cargo test --manifest-path $(2)/Cargo.toml --workspace
|
||||||
|
|
||||||
clippy-all-contracts:
|
test-expensive-$(1):
|
||||||
cargo clippy --workspace --manifest-path contracts/Cargo.toml --all-features --target wasm32-unknown-unknown -- -D warnings
|
cargo test --manifest-path $(2)/Cargo.toml --workspace -- --ignored
|
||||||
|
|
||||||
clippy-all-wallet:
|
build-standalone-$(1):
|
||||||
cargo clippy --workspace --manifest-path nym-wallet/Cargo.toml --all-features -- -D warnings
|
cargo build --manifest-path $(2)/Cargo.toml $(3)
|
||||||
|
|
||||||
clippy-all-connect:
|
build-$(1):
|
||||||
cargo clippy --workspace --manifest-path nym-connect/desktop/Cargo.toml --all-features -- -D warnings
|
cargo build --manifest-path $(2)/Cargo.toml --workspace $(3)
|
||||||
|
|
||||||
clippy-all-connect-mobile:
|
build-examples-$(1):
|
||||||
cargo clippy --workspace --manifest-path nym-connect/mobile/src-tauri/Cargo.toml --all-features -- -D warnings
|
cargo build --manifest-path $(2)/Cargo.toml --workspace --examples
|
||||||
|
|
||||||
clippy-all-wasm-client:
|
build-release-$(1):
|
||||||
cargo clippy --workspace --manifest-path clients/webassembly/Cargo.toml --all-features --target wasm32-unknown-unknown -- -D warnings
|
cargo build --manifest-path $(2)/Cargo.toml --workspace --release $(3)
|
||||||
|
|
||||||
test-main:
|
fmt-$(1):
|
||||||
cargo test --workspace
|
cargo fmt --manifest-path $(2)/Cargo.toml --all
|
||||||
|
|
||||||
test-main-expensive:
|
clippy-happy: clippy-happy-$(1)
|
||||||
cargo test --workspace -- --ignored
|
clippy: clippy-$(1) clippy-examples-$(1)
|
||||||
|
check: check-$(1)
|
||||||
|
cargo-test: test-$(1)
|
||||||
|
cargo-test-expensive: test-expensive-$(1)
|
||||||
|
build: build-$(1) build-examples-$(1)
|
||||||
|
build-release-all: build-release-$(1)
|
||||||
|
fmt: fmt-$(1)
|
||||||
|
|
||||||
test-contracts:
|
endef
|
||||||
cargo test --manifest-path contracts/Cargo.toml --all-features
|
|
||||||
|
|
||||||
test-contracts-expensive:
|
# -----------------------------------------------------------------------------
|
||||||
cargo test --manifest-path contracts/Cargo.toml --all-features -- --ignored
|
# Rust workspaces
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
test-wallet:
|
# Generate targets for the various cargo workspaces
|
||||||
cargo test --manifest-path nym-wallet/Cargo.toml --all-features
|
|
||||||
|
|
||||||
test-wallet-expensive:
|
$(eval $(call add_cargo_workspace,main,.))
|
||||||
cargo test --manifest-path nym-wallet/Cargo.toml --all-features -- --ignored
|
$(eval $(call add_cargo_workspace,contracts,contracts,--lib --target wasm32-unknown-unknown))
|
||||||
|
#$(eval $(call add_cargo_workspace,wasm-client,clients/webassembly,--target wasm32-unknown-unknown))
|
||||||
|
$(eval $(call add_cargo_workspace,wallet,nym-wallet,))
|
||||||
|
$(eval $(call add_cargo_workspace,connect,nym-connect/desktop))
|
||||||
|
|
||||||
test-connect:
|
# -----------------------------------------------------------------------------
|
||||||
cargo test --manifest-path nym-connect/desktop/Cargo.toml --all-features
|
# Convenience targets for crates that are already part of the main workspace
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
test-connect-expensive:
|
|
||||||
cargo test --manifest-path nym-connect/desktop/Cargo.toml --all-features -- --ignored
|
|
||||||
|
|
||||||
test-connect-mobile:
|
|
||||||
cargo test --manifest-path nym-connect/mobile/src-tauri/Cargo.toml --all-features
|
|
||||||
|
|
||||||
test-connect-mobile-expensive:
|
|
||||||
cargo test --manifest-path nym-connect/mobile/src-tauri/Cargo.toml --all-features -- --ignored
|
|
||||||
|
|
||||||
build-main:
|
|
||||||
cargo build --workspace
|
|
||||||
|
|
||||||
build-main-examples:
|
|
||||||
cargo build --workspace --examples
|
|
||||||
|
|
||||||
build-contracts:
|
|
||||||
cargo build --manifest-path contracts/Cargo.toml --workspace
|
|
||||||
|
|
||||||
build-wallet:
|
|
||||||
cargo build --manifest-path nym-wallet/Cargo.toml --workspace
|
|
||||||
|
|
||||||
build-connect:
|
|
||||||
cargo build --manifest-path nym-connect/desktop/Cargo.toml --workspace
|
|
||||||
|
|
||||||
build-connect-mobile:
|
|
||||||
cargo build --manifest-path nym-connect/mobile/src-tauri/Cargo.toml --workspace
|
|
||||||
|
|
||||||
build-explorer-api:
|
build-explorer-api:
|
||||||
cargo build --manifest-path explorer-api/Cargo.toml --workspace
|
cargo build -p explorer-api
|
||||||
|
|
||||||
build-wasm-client:
|
|
||||||
cargo build --manifest-path clients/webassembly/Cargo.toml --workspace --target wasm32-unknown-unknown
|
|
||||||
|
|
||||||
build-nym-cli:
|
build-nym-cli:
|
||||||
cargo build --release --manifest-path tools/nym-cli/Cargo.toml
|
cargo build -p nym-cli --release
|
||||||
|
|
||||||
fmt-main:
|
build-browser-extension-storage:
|
||||||
cargo fmt --all
|
cargo build -p extension-storage --target wasm32-unknown-unknown
|
||||||
|
|
||||||
fmt-contracts:
|
fmt-browser-extension-storage:
|
||||||
cargo fmt --manifest-path contracts/Cargo.toml --all
|
cargo fmt -p extension-storage -- --check
|
||||||
|
|
||||||
fmt-wallet:
|
clippy-browser-extension-storage:
|
||||||
cargo fmt --manifest-path nym-wallet/Cargo.toml --all
|
cargo clippy -p extension-storage --target wasm32-unknown-unknown -- -Dwarnings
|
||||||
|
|
||||||
fmt-connect:
|
sdk-wasm: sdk-wasm-build sdk-wasm-test sdk-wasm-lint
|
||||||
cargo fmt --manifest-path nym-connect/desktop/Cargo.toml --all
|
|
||||||
|
|
||||||
fmt-connect-mobile:
|
sdk-wasm-build:
|
||||||
cargo fmt --manifest-path nym-connect/mobile/src-tauri/Cargo.toml --all
|
# browser storage
|
||||||
|
$(MAKE) -C nym-browser-extension/storage wasm-pack
|
||||||
|
|
||||||
fmt-wasm-client:
|
# client
|
||||||
cargo fmt --manifest-path clients/webassembly/Cargo.toml --all
|
$(MAKE) -C wasm/client build
|
||||||
|
|
||||||
wasm:
|
# client (node)
|
||||||
RUSTFLAGS='-C link-arg=-s' cargo build --manifest-path contracts/Cargo.toml --release --target wasm32-unknown-unknown
|
$(MAKE) -C wasm/client build-node
|
||||||
|
|
||||||
mixnet-opt: wasm
|
# node-tester
|
||||||
cd contracts/mixnet && make opt
|
$(MAKE) -C wasm/node-tester build
|
||||||
|
|
||||||
|
# mix-fetch
|
||||||
|
$(MAKE) -C wasm/mix-fetch build
|
||||||
|
|
||||||
|
# mix-fetch (node)
|
||||||
|
$(MAKE) -C wasm/mix-fetch build-node
|
||||||
|
|
||||||
|
# full
|
||||||
|
$(MAKE) -C wasm/full-nym-wasm build-full
|
||||||
|
|
||||||
|
# run this from npm/yarn to ensure tools are in the path, e.g. yarn build:sdk from root of repo
|
||||||
|
sdk-typescript-build:
|
||||||
|
npx lerna run --scope @nymproject/sdk build --stream
|
||||||
|
npx lerna run --scope @nymproject/mix-fetch build --stream
|
||||||
|
npx lerna run --scope @nymproject/node-tester build --stream
|
||||||
|
yarn --cwd sdk/typescript/codegen/contract-clients build
|
||||||
|
|
||||||
|
sdk-wasm-test:
|
||||||
|
# # client
|
||||||
|
# cargo test -p nym-client-wasm --target wasm32-unknown-unknown
|
||||||
|
#
|
||||||
|
# # node-tester
|
||||||
|
# cargo test -p nym-node-tester-wasm --target wasm32-unknown-unknown
|
||||||
|
#
|
||||||
|
# # mix-fetch
|
||||||
|
# #cargo test -p nym-wasm-sdk --target wasm32-unknown-unknown
|
||||||
|
#
|
||||||
|
# # full
|
||||||
|
# cargo test -p nym-wasm-sdk --target wasm32-unknown-unknown
|
||||||
|
|
||||||
|
|
||||||
|
sdk-wasm-lint:
|
||||||
|
# client
|
||||||
|
cargo clippy -p nym-client-wasm --target wasm32-unknown-unknown -- -Dwarnings
|
||||||
|
|
||||||
|
# node-tester
|
||||||
|
cargo clippy -p nym-node-tester-wasm --target wasm32-unknown-unknown -- -Dwarnings
|
||||||
|
|
||||||
|
# mix-fetch
|
||||||
|
$(MAKE) -C wasm/mix-fetch check-fmt
|
||||||
|
|
||||||
|
# full
|
||||||
|
cargo clippy -p nym-wasm-sdk --target wasm32-unknown-unknown -- -Dwarnings
|
||||||
|
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# Build contracts ready for deploy
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
CONTRACTS_OUT_DIR=contracts/target/wasm32-unknown-unknown/release
|
||||||
|
VESTING_CONTRACT=$(CONTRACTS_OUT_DIR)/vesting_contract.wasm
|
||||||
|
MIXNET_CONTRACT=$(CONTRACTS_OUT_DIR)/mixnet_contract.wasm
|
||||||
|
SERVICE_PROVIDER_DIRECTORY_CONTRACT=$(CONTRACTS_OUT_DIR)/nym_service_provider_directory.wasm
|
||||||
|
NAME_SERVICE_CONTRACT=$(CONTRACTS_OUT_DIR)/nym_name_service.wasm
|
||||||
|
|
||||||
|
contracts-wasm: contracts-wasm-build contracts-wasm-opt
|
||||||
|
|
||||||
|
contracts-wasm-build:
|
||||||
|
RUSTFLAGS='-C link-arg=-s' cargo build --lib --manifest-path contracts/Cargo.toml --release --target wasm32-unknown-unknown
|
||||||
|
|
||||||
|
contracts-wasm-opt:
|
||||||
|
wasm-opt --disable-sign-ext -Os $(VESTING_CONTRACT) -o $(VESTING_CONTRACT)
|
||||||
|
wasm-opt --disable-sign-ext -Os $(MIXNET_CONTRACT) -o $(MIXNET_CONTRACT)
|
||||||
|
wasm-opt --disable-sign-ext -Os $(SERVICE_PROVIDER_DIRECTORY_CONTRACT) -o $(SERVICE_PROVIDER_DIRECTORY_CONTRACT)
|
||||||
|
wasm-opt --disable-sign-ext -Os $(NAME_SERVICE_CONTRACT) -o $(NAME_SERVICE_CONTRACT)
|
||||||
|
|
||||||
|
contract-schema:
|
||||||
|
$(MAKE) -C contracts schema
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# Misc
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
generate-typescript:
|
generate-typescript:
|
||||||
cd tools/ts-rs-cli && cargo run && cd ../..
|
cd tools/ts-rs-cli && cargo run && cd ../..
|
||||||
|
|||||||
@@ -13,16 +13,16 @@ The platform is composed of multiple Rust crates. Top-level executable binary cr
|
|||||||
* nym-gateway - acts sort of like a mailbox for mixnet messages, which removes the need for direct delivery to potentially offline or firewalled devices.
|
* nym-gateway - acts sort of like a mailbox for mixnet messages, which removes the need for direct delivery to potentially offline or firewalled devices.
|
||||||
* nym-network-monitor - sends packets through the full system to check that they are working as expected, and stores node uptime histories as the basis of a rewards system ("mixmining" or "proof-of-mixing").
|
* nym-network-monitor - sends packets through the full system to check that they are working as expected, and stores node uptime histories as the basis of a rewards system ("mixmining" or "proof-of-mixing").
|
||||||
* nym-explorer - a (projected) block explorer and (existing) mixnet viewer.
|
* nym-explorer - a (projected) block explorer and (existing) mixnet viewer.
|
||||||
* nym-wallet - a desktop wallet implemented using the [Tauri](https://tauri.studio/en/docs/about/intro) framework.
|
* nym-wallet - a desktop wallet implemented using the [Tauri](https://tauri.studio/en/docs/about/intro) framework.
|
||||||
|
|
||||||
[](https://opensource.org/licenses/Apache-2.0)
|
[](https://opensource.org/licenses/Apache-2.0)
|
||||||
[](https://github.com/nymtech/nym/actions?query=branch%3Adevelop)
|
[](https://github.com/nymtech/nym/actions?query=branch%3Adevelop)
|
||||||
|
|
||||||
|
|
||||||
### Building
|
### Building
|
||||||
|
|
||||||
Platform build instructions are available on [our docs site](https://nymtech.net/docs/stable/run-nym-nodes/build-nym).
|
Platform build instructions are available on [our docs site](https://nymtech.net/docs/binaries/pre-built-binaries.html).
|
||||||
Wallet build instructions are also available on [our docs site](https://nymtech.net/docs/stable/nym-apps/wallet#for-developers).
|
Wallet build instructions are also available on [our docs site](https://nymtech.net/docs/wallet/desktop-wallet.html).
|
||||||
|
|
||||||
### Developing
|
### Developing
|
||||||
|
|
||||||
@@ -32,7 +32,11 @@ For Typescript components, please see [ts-packages](./ts-packages).
|
|||||||
|
|
||||||
### Developer chat
|
### Developer chat
|
||||||
|
|
||||||
You can chat to us in [Keybase](https://keybase.io). Download their chat app, then click **Teams -> Join a team**. Type **nymtech.friends** into the team name and hit **continue**. For general chat, hang out in the **#general** channel. Our development takes places in the **#dev** channel. Node operators should be in the **#node-operators** channel.
|
> We used to use Keybase for developer chats, but we have since migrated to Matrix and Discord. We no longer check the old **nymtech.friends** Keybase team.
|
||||||
|
|
||||||
|
You can chat to us in two places:
|
||||||
|
* The #dev channel on [Matrix](https://matrix.to/#/#dev:nymtech.chat)
|
||||||
|
* The various developer channels on [Discord](https://discord.gg/nym)
|
||||||
|
|
||||||
### Rewards
|
### Rewards
|
||||||
|
|
||||||
@@ -46,7 +50,7 @@ Node, node operator and delegator rewards are determined according to the princi
|
|||||||
|<img src="https://render.githubusercontent.com/render/math?math=\lambda_{i}#gh-light-mode-only"><img src="https://render.githubusercontent.com/render/math?math=\color{white}\lambda_{i}#gh-dark-mode-only">|ratio of stake operator has pledged to their node to the token circulating supply.
|
|<img src="https://render.githubusercontent.com/render/math?math=\lambda_{i}#gh-light-mode-only"><img src="https://render.githubusercontent.com/render/math?math=\color{white}\lambda_{i}#gh-dark-mode-only">|ratio of stake operator has pledged to their node to the token circulating supply.
|
||||||
|<img src="https://render.githubusercontent.com/render/math?math=\omega_{i}#gh-light-mode-only"><img src="https://render.githubusercontent.com/render/math?math=\color{white}\omega_{i}#gh-dark-mode-only">|fraction of total effort undertaken by node `i`, set to `1/k`.
|
|<img src="https://render.githubusercontent.com/render/math?math=\omega_{i}#gh-light-mode-only"><img src="https://render.githubusercontent.com/render/math?math=\color{white}\omega_{i}#gh-dark-mode-only">|fraction of total effort undertaken by node `i`, set to `1/k`.
|
||||||
|<img src="https://render.githubusercontent.com/render/math?math=k#gh-light-mode-only"><img src="https://render.githubusercontent.com/render/math?math=\color{white}k#gh-dark-mode-only">|number of nodes stakeholders are incentivised to create, set by the validators, a matter of governance. Currently determined by the `reward set` size, and set to 720 in testnet Sandbox.
|
|<img src="https://render.githubusercontent.com/render/math?math=k#gh-light-mode-only"><img src="https://render.githubusercontent.com/render/math?math=\color{white}k#gh-dark-mode-only">|number of nodes stakeholders are incentivised to create, set by the validators, a matter of governance. Currently determined by the `reward set` size, and set to 720 in testnet Sandbox.
|
||||||
|<img src="https://render.githubusercontent.com/render/math?math=\alpha#gh-light-mode-only"><img src="https://render.githubusercontent.com/render/math?math=\color{white}\alpha#gh-dark-mode-only">|Sybil attack resistance parameter - the higher this parameter is set the stronger the reduction in competitivness gets for a Sybil attacker.
|
|<img src="https://render.githubusercontent.com/render/math?math=\alpha#gh-light-mode-only"><img src="https://render.githubusercontent.com/render/math?math=\color{white}\alpha#gh-dark-mode-only">|Sybil attack resistance parameter - the higher this parameter is set the stronger the reduction in competitiveness gets for a Sybil attacker.
|
||||||
|<img src="https://render.githubusercontent.com/render/math?math=PM_{i}#gh-light-mode-only"><img src="https://render.githubusercontent.com/render/math?math=\color{white}PM_{i}#gh-dark-mode-only">|declared profit margin of operator `i`, defaults to 10% in.
|
|<img src="https://render.githubusercontent.com/render/math?math=PM_{i}#gh-light-mode-only"><img src="https://render.githubusercontent.com/render/math?math=\color{white}PM_{i}#gh-dark-mode-only">|declared profit margin of operator `i`, defaults to 10% in.
|
||||||
|<img src="https://render.githubusercontent.com/render/math?math=PF_{i}#gh-light-mode-only"><img src="https://render.githubusercontent.com/render/math?math=\color{white}PF_{i}#gh-dark-mode-only">|uptime of node `i`, scaled to 0 - 1, for the rewarding epoch
|
|<img src="https://render.githubusercontent.com/render/math?math=PF_{i}#gh-light-mode-only"><img src="https://render.githubusercontent.com/render/math?math=\color{white}PF_{i}#gh-dark-mode-only">|uptime of node `i`, scaled to 0 - 1, for the rewarding epoch
|
||||||
|<img src="https://render.githubusercontent.com/render/math?math=PP_{i}#gh-light-mode-only"><img src="https://render.githubusercontent.com/render/math?math=\color{white}PP_{i}#gh-dark-mode-only">|cost of operating node `i` for the duration of the rewarding epoch, set to 40 NYMT.
|
|<img src="https://render.githubusercontent.com/render/math?math=PP_{i}#gh-light-mode-only"><img src="https://render.githubusercontent.com/render/math?math=\color{white}PP_{i}#gh-dark-mode-only">|cost of operating node `i` for the duration of the rewarding epoch, set to 40 NYMT.
|
||||||
@@ -70,7 +74,7 @@ Operator of node `i` is credited with the following amount:
|
|||||||
<img src="https://render.githubusercontent.com/render/math?math=min\{PP_{i},R_{i})\} %2b max\{0, (PM_{i} %2b (1 - PM_{i}) \cdot \lambda_{i}/\delta_{i}) \cdot (R_{i} - PP_{i})\}#gh-light-mode-only">
|
<img src="https://render.githubusercontent.com/render/math?math=min\{PP_{i},R_{i})\} %2b max\{0, (PM_{i} %2b (1 - PM_{i}) \cdot \lambda_{i}/\delta_{i}) \cdot (R_{i} - PP_{i})\}#gh-light-mode-only">
|
||||||
<img src="https://render.githubusercontent.com/render/math?math=\color{white}min\{PP_{i},R_{i})\} %2b max\{0, (PM_{i} %2b (1 - PM_{i}) \cdot \lambda_{i}/\delta_{i}) \cdot (R_{i} - PP_{i})\}#gh-dark-mode-only">
|
<img src="https://render.githubusercontent.com/render/math?math=\color{white}min\{PP_{i},R_{i})\} %2b max\{0, (PM_{i} %2b (1 - PM_{i}) \cdot \lambda_{i}/\delta_{i}) \cdot (R_{i} - PP_{i})\}#gh-dark-mode-only">
|
||||||
|
|
||||||
Delegate with stake `s` recieves:
|
Delegate with stake `s` receives:
|
||||||
|
|
||||||
<img src="https://render.githubusercontent.com/render/math?math=max\{0, (1-PM_{i}) \cdot (s^'/\sigma_{i}) \cdot (R_{i} - PP_{i})\}#gh-light-mode-only">
|
<img src="https://render.githubusercontent.com/render/math?math=max\{0, (1-PM_{i}) \cdot (s^'/\sigma_{i}) \cdot (R_{i} - PP_{i})\}#gh-light-mode-only">
|
||||||
<img src="https://render.githubusercontent.com/render/math?math=\color{white}max\{0, (1-PM_{i}) \cdot (s^'/\sigma_{i}) \cdot (R_{i} - PP_{i})\}#gh-dark-mode-only">
|
<img src="https://render.githubusercontent.com/render/math?math=\color{white}max\{0, (1-PM_{i}) \cdot (s^'/\sigma_{i}) \cdot (R_{i} - PP_{i})\}#gh-dark-mode-only">
|
||||||
@@ -80,4 +84,3 @@ where `s'` is stake `s` scaled over total token circulating supply.
|
|||||||
### Licensing and copyright information
|
### Licensing and copyright information
|
||||||
|
|
||||||
This program is available as open source under the terms of the Apache 2.0 license. However, some elements are being licensed under CC0-1.0 and MIT. For accurate information, please check individual files.
|
This program is available as open source under the terms of the Apache 2.0 license. However, some elements are being licensed under CC0-1.0 and MIT. For accurate information, please check individual files.
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -3,8 +3,8 @@ Critical bug or security issue 💥
|
|||||||
If you're here because you're trying to figure out how to notify us of a security issue, go to Discord, and alert the core engineers:
|
If you're here because you're trying to figure out how to notify us of a security issue, go to Discord, and alert the core engineers:
|
||||||
|
|
||||||
Dave Hrycyszyn futurechimp#5430
|
Dave Hrycyszyn futurechimp#5430
|
||||||
Drazen Urch drazen#4873
|
|
||||||
Jedrzej Stuczynski "Jedrzej | Nym#5666"
|
Jedrzej Stuczynski "Jedrzej | Nym#5666"
|
||||||
|
Fran Arbanas | franarbanas#0995
|
||||||
|
Mark Sinclair | marknym#8088
|
||||||
|
|
||||||
|
Please avoid opening public issues on GitHub that contain information about a potential security vulnerability as this makes it difficult to reduce the impact and harm of valid security issues.
|
||||||
Please avoid opening public issues on GitHub that contain information about a potential security vulnerability as this makes it difficult to reduce the impact and harm of valid security issues.
|
|
||||||
|
|||||||
@@ -0,0 +1,53 @@
|
|||||||
|
<svg
|
||||||
|
width="100%"
|
||||||
|
height="100%"
|
||||||
|
viewBox="0 0 80 80"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<g clip-path="url(#clip0_421_13045)">
|
||||||
|
<path
|
||||||
|
d="M40 80C62.0914 80 80 62.0914 80 40C80 17.9086 62.0914 0 40 0C17.9086 0 0 17.9086 0 40C0 62.0914 17.9086 80 40 80Z"
|
||||||
|
fill="black"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M40 77.2636C60.5801 77.2636 77.2636 60.5801 77.2636 40C77.2636 19.4199 60.5801 2.73645 40 2.73645C19.4199 2.73645 2.73645 19.4199 2.73645 40C2.73645 60.5801 19.4199 77.2636 40 77.2636Z"
|
||||||
|
fill="white"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M24.0224 32.471H23.9776V32.5084V45.5775L18.4673 32.4934L18.4598 32.471H18.4299H15.3047H11.7981H11.7607V32.5084V47.4916V47.529H11.7981H15.3047H15.3421V47.4916V34.4L20.8748 47.5065L20.8822 47.529H20.9121H24.0224H27.5215H27.5589V47.4916V32.5084V32.471H27.5215H24.0224Z"
|
||||||
|
fill="black"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
fill-rule="evenodd"
|
||||||
|
clip-rule="evenodd"
|
||||||
|
d="M23.8965 32.39H27.64V47.6101H20.8238L20.7989 47.5352L15.4232 34.8006V47.6101H11.6797V32.39H18.5183L18.5432 32.4649L23.8965 45.1761V32.39ZM23.9776 45.5776L18.4673 32.4935L18.4598 32.471H11.7608V47.529H15.3421V34.4L20.8748 47.5065L20.8823 47.529H27.5589V32.471H23.9776V45.5776Z"
|
||||||
|
fill="black"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M68.2019 32.471H61.5178H61.4804L61.4729 32.5009L58.0486 45.6374L54.6169 32.5009L54.6094 32.471H54.5795H47.8804H47.8355V32.5084V47.4916V47.529H47.8804H51.3795H51.4169V47.4916V34.5047L54.8038 47.499L54.8112 47.529H54.8486H61.2337H61.2636L61.2711 47.499L64.658 34.5047V47.4916V47.529H64.6954H68.2019H68.2393V47.4916V32.5084V32.471H68.2019Z"
|
||||||
|
fill="black"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
fill-rule="evenodd"
|
||||||
|
clip-rule="evenodd"
|
||||||
|
d="M61.4171 32.39H68.3204V47.6101H64.5769V35.1372L61.3497 47.5187L61.3495 47.5195L61.3269 47.6101H54.7479L54.7253 47.5195L54.7251 47.5187L51.4979 35.1372V47.6101H47.7545V32.39H54.6727L54.6953 32.4804L54.6955 32.4813L58.0485 45.3163L61.3943 32.4813L61.3945 32.4805L61.4171 32.39ZM58.0486 45.6374L54.6168 32.5009L54.6094 32.471H47.8355V47.529H51.4168V34.5047L54.8038 47.4991L54.8112 47.529H61.2636L61.2711 47.4991L64.658 34.5047V47.529H68.2393V32.471H61.4804L61.4729 32.5009L58.0486 45.6374Z"
|
||||||
|
fill="black"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M42.0711 32.471H42.0486L42.0412 32.486L37.7869 39.8804L33.5103 32.486L33.5028 32.471H33.4804H29.4355H29.3608L29.3982 32.5308L35.9851 43.9402V47.4916V47.529H36.0225H39.529H39.5664V47.4916V43.9402L46.1533 32.5308L46.1907 32.471H46.1159H42.0711Z"
|
||||||
|
fill="black"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
fill-rule="evenodd"
|
||||||
|
clip-rule="evenodd"
|
||||||
|
d="M41.9985 32.39H46.337L46.2228 32.5726L39.6475 43.9619V47.6101H35.904V43.9619L29.3286 32.5726L29.2145 32.39H33.5529L33.5817 32.4475L37.7868 39.7181L41.9697 32.4476L41.9985 32.39ZM42.0411 32.486L37.7869 39.8804L33.5103 32.486L33.5028 32.471H29.3608L29.3981 32.5308L35.9851 43.9402V47.529H39.5664V43.9402L46.1533 32.5308L46.1907 32.471H42.0486L42.0411 32.486Z"
|
||||||
|
fill="black"
|
||||||
|
/>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<clipPath id="clip0_421_13045">
|
||||||
|
<rect width="80" height="80" fill="white" />
|
||||||
|
</clipPath>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 3.0 KiB |
@@ -1,84 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "client-core"
|
|
||||||
version = "1.1.10"
|
|
||||||
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>"]
|
|
||||||
edition = "2021"
|
|
||||||
rust-version = "1.66"
|
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
async-trait = { version = "0.1.58" }
|
|
||||||
dirs = "4.0"
|
|
||||||
dashmap = "5.4.0"
|
|
||||||
futures = "0.3"
|
|
||||||
humantime-serde = "1.0"
|
|
||||||
log = { workspace = true }
|
|
||||||
rand = { version = "0.7.3", features = ["wasm-bindgen"] }
|
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
|
||||||
serde_json = "1.0.89"
|
|
||||||
tap = "1.0.1"
|
|
||||||
thiserror = "1.0.34"
|
|
||||||
url = { version ="2.2", features = ["serde"] }
|
|
||||||
tokio = { version = "1.24.1", features = ["macros"]}
|
|
||||||
time = "0.3.17"
|
|
||||||
|
|
||||||
# internal
|
|
||||||
nym-config = { path = "../../common/config" }
|
|
||||||
nym-crypto = { path = "../../common/crypto" }
|
|
||||||
gateway-client = { path = "../../common/client-libs/gateway-client" }
|
|
||||||
#gateway-client = { path = "../../common/client-libs/gateway-client", default-features = false, features = ["wasm", "coconut"] }
|
|
||||||
gateway-requests = { path = "../../gateway/gateway-requests" }
|
|
||||||
nym-nonexhaustive-delayqueue = { path = "../../common/nonexhaustive-delayqueue" }
|
|
||||||
nym-sphinx = { path = "../../common/nymsphinx" }
|
|
||||||
nym-pemstore = { path = "../../common/pemstore" }
|
|
||||||
nym-topology = { path = "../../common/topology" }
|
|
||||||
validator-client = { path = "../../common/client-libs/validator-client", default-features = false }
|
|
||||||
nym-task = { path = "../../common/task" }
|
|
||||||
|
|
||||||
[target."cfg(not(target_arch = \"wasm32\"))".dependencies.tokio-stream]
|
|
||||||
version = "0.1.11"
|
|
||||||
features = ["time"]
|
|
||||||
|
|
||||||
[target."cfg(not(target_arch = \"wasm32\"))".dependencies.tokio]
|
|
||||||
version = "1.24.1"
|
|
||||||
features = ["time"]
|
|
||||||
|
|
||||||
[target."cfg(not(target_arch = \"wasm32\"))".dependencies.sqlx]
|
|
||||||
version = "0.6.2"
|
|
||||||
features = ["runtime-tokio-rustls", "sqlite", "macros", "migrate"]
|
|
||||||
optional = true
|
|
||||||
|
|
||||||
[target."cfg(target_arch = \"wasm32\")".dependencies.wasm-bindgen-futures]
|
|
||||||
version = "0.4"
|
|
||||||
|
|
||||||
[target."cfg(target_arch = \"wasm32\")".dependencies.wasm-bindgen]
|
|
||||||
version = "0.2.83"
|
|
||||||
|
|
||||||
[target."cfg(target_arch = \"wasm32\")".dependencies.wasm-timer]
|
|
||||||
git = "https://github.com/mmsinclair/wasm-timer"
|
|
||||||
rev = "b9d1a54ad514c2f230a026afe0dde341e98cd7b6"
|
|
||||||
|
|
||||||
[target."cfg(target_arch = \"wasm32\")".dependencies.gloo-timers]
|
|
||||||
version = "0.2.4"
|
|
||||||
features = ["futures"]
|
|
||||||
|
|
||||||
[target."cfg(target_arch = \"wasm32\")".dependencies.wasm-utils]
|
|
||||||
path = "../../common/wasm-utils"
|
|
||||||
|
|
||||||
[target."cfg(target_arch = \"wasm32\")".dependencies.time]
|
|
||||||
version = "0.3.17"
|
|
||||||
features = ["wasm-bindgen"]
|
|
||||||
|
|
||||||
[dev-dependencies]
|
|
||||||
tempfile = "3.1.0"
|
|
||||||
|
|
||||||
[build-dependencies]
|
|
||||||
tokio = { version = "1.24.1", features = ["rt-multi-thread", "macros"] }
|
|
||||||
sqlx = { version = "0.6.2", features = ["runtime-tokio-rustls", "sqlite", "macros", "migrate"] }
|
|
||||||
|
|
||||||
[features]
|
|
||||||
default = []
|
|
||||||
fs-surb-storage = ["sqlx"]
|
|
||||||
wasm = ["gateway-client/wasm"]
|
|
||||||
|
|
||||||
@@ -1,569 +0,0 @@
|
|||||||
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
use crate::client::cover_traffic_stream::LoopCoverTrafficStream;
|
|
||||||
use crate::client::inbound_messages::{InputMessage, InputMessageReceiver, InputMessageSender};
|
|
||||||
use crate::client::key_manager::KeyManager;
|
|
||||||
use crate::client::mix_traffic::{BatchMixMessageSender, MixTrafficController};
|
|
||||||
use crate::client::real_messages_control;
|
|
||||||
use crate::client::real_messages_control::RealMessagesController;
|
|
||||||
use crate::client::received_buffer::{
|
|
||||||
ReceivedBufferRequestReceiver, ReceivedBufferRequestSender, ReceivedMessagesBufferController,
|
|
||||||
};
|
|
||||||
use crate::client::replies::reply_controller;
|
|
||||||
use crate::client::replies::reply_controller::{ReplyControllerReceiver, ReplyControllerSender};
|
|
||||||
use crate::client::replies::reply_storage::{
|
|
||||||
CombinedReplyStorage, PersistentReplyStorage, ReplyStorageBackend, SentReplyKeys,
|
|
||||||
};
|
|
||||||
use crate::client::topology_control::{
|
|
||||||
TopologyAccessor, TopologyRefresher, TopologyRefresherConfig,
|
|
||||||
};
|
|
||||||
use crate::config::{Config, DebugConfig, GatewayEndpointConfig};
|
|
||||||
use crate::error::ClientCoreError;
|
|
||||||
use crate::spawn_future;
|
|
||||||
use futures::channel::mpsc;
|
|
||||||
use gateway_client::bandwidth::BandwidthController;
|
|
||||||
#[cfg(target_arch = "wasm32")]
|
|
||||||
use gateway_client::wasm_mockups::CosmWasmClient;
|
|
||||||
use gateway_client::{
|
|
||||||
AcknowledgementReceiver, AcknowledgementSender, GatewayClient, MixnetMessageReceiver,
|
|
||||||
MixnetMessageSender,
|
|
||||||
};
|
|
||||||
use log::{debug, info};
|
|
||||||
use nym_crypto::asymmetric::{encryption, identity};
|
|
||||||
use nym_sphinx::acknowledgements::AckKey;
|
|
||||||
use nym_sphinx::addressing::clients::Recipient;
|
|
||||||
use nym_sphinx::addressing::nodes::NodeIdentity;
|
|
||||||
use nym_sphinx::receiver::ReconstructedMessage;
|
|
||||||
use nym_task::connections::{ConnectionCommandReceiver, ConnectionCommandSender, LaneQueueLengths};
|
|
||||||
use nym_task::{TaskClient, TaskManager};
|
|
||||||
use std::sync::Arc;
|
|
||||||
use std::time::Duration;
|
|
||||||
use tap::TapFallible;
|
|
||||||
use url::Url;
|
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
|
||||||
use validator_client::nyxd::CosmWasmClient;
|
|
||||||
|
|
||||||
use super::received_buffer::ReceivedBufferMessage;
|
|
||||||
|
|
||||||
#[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))]
|
|
||||||
pub mod non_wasm_helpers;
|
|
||||||
|
|
||||||
pub mod helpers;
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct ClientInput {
|
|
||||||
pub connection_command_sender: ConnectionCommandSender,
|
|
||||||
pub input_sender: InputMessageSender,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ClientInput {
|
|
||||||
pub async fn send(
|
|
||||||
&self,
|
|
||||||
message: InputMessage,
|
|
||||||
) -> Result<(), tokio::sync::mpsc::error::SendError<InputMessage>> {
|
|
||||||
self.input_sender.send(message).await
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct ClientOutput {
|
|
||||||
pub received_buffer_request_sender: ReceivedBufferRequestSender,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ClientOutput {
|
|
||||||
pub fn register_receiver(
|
|
||||||
&mut self,
|
|
||||||
) -> Result<mpsc::UnboundedReceiver<Vec<ReconstructedMessage>>, ClientCoreError> {
|
|
||||||
let (reconstructed_sender, reconstructed_receiver) = mpsc::unbounded();
|
|
||||||
|
|
||||||
self.received_buffer_request_sender
|
|
||||||
.unbounded_send(ReceivedBufferMessage::ReceiverAnnounce(
|
|
||||||
reconstructed_sender,
|
|
||||||
))
|
|
||||||
.map_err(|_| ClientCoreError::FailedToRegisterReceiver)?;
|
|
||||||
|
|
||||||
Ok(reconstructed_receiver)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct ClientState {
|
|
||||||
pub shared_lane_queue_lengths: LaneQueueLengths,
|
|
||||||
pub reply_controller_sender: ReplyControllerSender,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub enum ClientInputStatus {
|
|
||||||
AwaitingProducer { client_input: ClientInput },
|
|
||||||
Connected,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ClientInputStatus {
|
|
||||||
pub fn register_producer(&mut self) -> ClientInput {
|
|
||||||
match std::mem::replace(self, ClientInputStatus::Connected) {
|
|
||||||
ClientInputStatus::AwaitingProducer { client_input } => client_input,
|
|
||||||
ClientInputStatus::Connected => panic!("producer was already registered before"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub enum ClientOutputStatus {
|
|
||||||
AwaitingConsumer { client_output: ClientOutput },
|
|
||||||
Connected,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ClientOutputStatus {
|
|
||||||
pub fn register_consumer(&mut self) -> ClientOutput {
|
|
||||||
match std::mem::replace(self, ClientOutputStatus::Connected) {
|
|
||||||
ClientOutputStatus::AwaitingConsumer { client_output } => client_output,
|
|
||||||
ClientOutputStatus::Connected => panic!("consumer was already registered before"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
|
||||||
pub enum CredentialsToggle {
|
|
||||||
Enabled,
|
|
||||||
Disabled,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CredentialsToggle {
|
|
||||||
pub fn is_enabled(&self) -> bool {
|
|
||||||
self == &CredentialsToggle::Enabled
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is_disabled(&self) -> bool {
|
|
||||||
self == &CredentialsToggle::Disabled
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<bool> for CredentialsToggle {
|
|
||||||
fn from(value: bool) -> Self {
|
|
||||||
if value {
|
|
||||||
CredentialsToggle::Enabled
|
|
||||||
} else {
|
|
||||||
CredentialsToggle::Disabled
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct BaseClientBuilder<'a, B, C: Clone> {
|
|
||||||
// due to wasm limitations I had to split it like this : (
|
|
||||||
gateway_config: &'a GatewayEndpointConfig,
|
|
||||||
debug_config: &'a DebugConfig,
|
|
||||||
disabled_credentials: bool,
|
|
||||||
nym_api_endpoints: Vec<Url>,
|
|
||||||
reply_storage_backend: B,
|
|
||||||
|
|
||||||
bandwidth_controller: Option<BandwidthController<C>>,
|
|
||||||
key_manager: KeyManager,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, B, C> BaseClientBuilder<'a, B, C>
|
|
||||||
where
|
|
||||||
B: ReplyStorageBackend + Send + Sync + 'static,
|
|
||||||
C: CosmWasmClient + Sync + Send + Clone + 'static,
|
|
||||||
{
|
|
||||||
pub fn new_from_base_config<T>(
|
|
||||||
base_config: &'a Config<T>,
|
|
||||||
key_manager: KeyManager,
|
|
||||||
bandwidth_controller: Option<BandwidthController<C>>,
|
|
||||||
reply_storage_backend: B,
|
|
||||||
) -> BaseClientBuilder<'a, B, C> {
|
|
||||||
BaseClientBuilder {
|
|
||||||
gateway_config: base_config.get_gateway_endpoint_config(),
|
|
||||||
debug_config: base_config.get_debug_config(),
|
|
||||||
disabled_credentials: base_config.get_disabled_credentials_mode(),
|
|
||||||
nym_api_endpoints: base_config.get_nym_api_endpoints(),
|
|
||||||
bandwidth_controller,
|
|
||||||
reply_storage_backend,
|
|
||||||
key_manager,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new(
|
|
||||||
gateway_config: &'a GatewayEndpointConfig,
|
|
||||||
debug_config: &'a DebugConfig,
|
|
||||||
key_manager: KeyManager,
|
|
||||||
bandwidth_controller: Option<BandwidthController<C>>,
|
|
||||||
reply_storage_backend: B,
|
|
||||||
credentials_toggle: CredentialsToggle,
|
|
||||||
nym_api_endpoints: Vec<Url>,
|
|
||||||
) -> BaseClientBuilder<'a, B, C> {
|
|
||||||
BaseClientBuilder {
|
|
||||||
gateway_config,
|
|
||||||
debug_config,
|
|
||||||
disabled_credentials: credentials_toggle.is_disabled(),
|
|
||||||
nym_api_endpoints,
|
|
||||||
reply_storage_backend,
|
|
||||||
bandwidth_controller,
|
|
||||||
key_manager,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn as_mix_recipient(&self) -> Recipient {
|
|
||||||
Recipient::new(
|
|
||||||
*self.key_manager.identity_keypair().public_key(),
|
|
||||||
*self.key_manager.encryption_keypair().public_key(),
|
|
||||||
// TODO: below only works under assumption that gateway address == gateway id
|
|
||||||
// (which currently is true)
|
|
||||||
NodeIdentity::from_base58_string(&self.gateway_config.gateway_id).unwrap(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// future constantly pumping loop cover traffic at some specified average rate
|
|
||||||
// the pumped traffic goes to the MixTrafficController
|
|
||||||
fn start_cover_traffic_stream(
|
|
||||||
debug_config: &DebugConfig,
|
|
||||||
ack_key: Arc<AckKey>,
|
|
||||||
self_address: Recipient,
|
|
||||||
topology_accessor: TopologyAccessor,
|
|
||||||
mix_tx: BatchMixMessageSender,
|
|
||||||
shutdown: TaskClient,
|
|
||||||
) {
|
|
||||||
info!("Starting loop cover traffic stream...");
|
|
||||||
|
|
||||||
let mut stream = LoopCoverTrafficStream::new(
|
|
||||||
ack_key,
|
|
||||||
debug_config.average_ack_delay,
|
|
||||||
debug_config.average_packet_delay,
|
|
||||||
debug_config.loop_cover_traffic_average_delay,
|
|
||||||
mix_tx,
|
|
||||||
self_address,
|
|
||||||
topology_accessor,
|
|
||||||
);
|
|
||||||
|
|
||||||
if let Some(size) = debug_config.use_extended_packet_size {
|
|
||||||
log::debug!("Setting extended packet size: {:?}", size);
|
|
||||||
stream.set_custom_packet_size(size.into());
|
|
||||||
}
|
|
||||||
|
|
||||||
stream.start_with_shutdown(shutdown);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(clippy::too_many_arguments)]
|
|
||||||
fn start_real_traffic_controller(
|
|
||||||
controller_config: real_messages_control::Config,
|
|
||||||
topology_accessor: TopologyAccessor,
|
|
||||||
ack_receiver: AcknowledgementReceiver,
|
|
||||||
input_receiver: InputMessageReceiver,
|
|
||||||
mix_sender: BatchMixMessageSender,
|
|
||||||
reply_storage: CombinedReplyStorage,
|
|
||||||
reply_controller_sender: ReplyControllerSender,
|
|
||||||
reply_controller_receiver: ReplyControllerReceiver,
|
|
||||||
lane_queue_lengths: LaneQueueLengths,
|
|
||||||
client_connection_rx: ConnectionCommandReceiver,
|
|
||||||
shutdown: TaskClient,
|
|
||||||
) {
|
|
||||||
info!("Starting real traffic stream...");
|
|
||||||
|
|
||||||
RealMessagesController::new(
|
|
||||||
controller_config,
|
|
||||||
ack_receiver,
|
|
||||||
input_receiver,
|
|
||||||
mix_sender,
|
|
||||||
topology_accessor,
|
|
||||||
reply_storage,
|
|
||||||
reply_controller_sender,
|
|
||||||
reply_controller_receiver,
|
|
||||||
lane_queue_lengths,
|
|
||||||
client_connection_rx,
|
|
||||||
)
|
|
||||||
.start_with_shutdown(shutdown);
|
|
||||||
}
|
|
||||||
|
|
||||||
// buffer controlling all messages fetched from provider
|
|
||||||
// required so that other components would be able to use them (say the websocket)
|
|
||||||
fn start_received_messages_buffer_controller(
|
|
||||||
local_encryption_keypair: Arc<encryption::KeyPair>,
|
|
||||||
query_receiver: ReceivedBufferRequestReceiver,
|
|
||||||
mixnet_receiver: MixnetMessageReceiver,
|
|
||||||
reply_key_storage: SentReplyKeys,
|
|
||||||
reply_controller_sender: ReplyControllerSender,
|
|
||||||
shutdown: TaskClient,
|
|
||||||
) {
|
|
||||||
info!("Starting received messages buffer controller...");
|
|
||||||
ReceivedMessagesBufferController::new(
|
|
||||||
local_encryption_keypair,
|
|
||||||
query_receiver,
|
|
||||||
mixnet_receiver,
|
|
||||||
reply_key_storage,
|
|
||||||
reply_controller_sender,
|
|
||||||
)
|
|
||||||
.start_with_shutdown(shutdown)
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn start_gateway_client(
|
|
||||||
&mut self,
|
|
||||||
mixnet_message_sender: MixnetMessageSender,
|
|
||||||
ack_sender: AcknowledgementSender,
|
|
||||||
shutdown: TaskClient,
|
|
||||||
) -> Result<GatewayClient<C>, ClientCoreError> {
|
|
||||||
let gateway_id = self.gateway_config.gateway_id.clone();
|
|
||||||
if gateway_id.is_empty() {
|
|
||||||
return Err(ClientCoreError::GatewayIdUnknown);
|
|
||||||
}
|
|
||||||
let gateway_address = self.gateway_config.gateway_listener.clone();
|
|
||||||
if gateway_address.is_empty() {
|
|
||||||
return Err(ClientCoreError::GatwayAddressUnknown);
|
|
||||||
}
|
|
||||||
|
|
||||||
let gateway_identity = identity::PublicKey::from_base58_string(gateway_id)
|
|
||||||
.map_err(ClientCoreError::UnableToCreatePublicKeyFromGatewayId)?;
|
|
||||||
|
|
||||||
// disgusting wasm workaround since there's no key persistence there (nor `client init`)
|
|
||||||
let shared_key = if self.key_manager.is_gateway_key_set() {
|
|
||||||
Some(self.key_manager.gateway_shared_key())
|
|
||||||
} else {
|
|
||||||
log::info!("Gateway key not set! Will proceed anyway.");
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut gateway_client = GatewayClient::new(
|
|
||||||
gateway_address,
|
|
||||||
self.key_manager.identity_keypair(),
|
|
||||||
gateway_identity,
|
|
||||||
shared_key,
|
|
||||||
mixnet_message_sender,
|
|
||||||
ack_sender,
|
|
||||||
self.debug_config.gateway_response_timeout,
|
|
||||||
self.bandwidth_controller.take(),
|
|
||||||
shutdown,
|
|
||||||
);
|
|
||||||
|
|
||||||
gateway_client.set_disabled_credentials_mode(self.disabled_credentials);
|
|
||||||
|
|
||||||
gateway_client
|
|
||||||
.authenticate_and_start()
|
|
||||||
.await
|
|
||||||
.tap_err(|err| {
|
|
||||||
log::error!("Could not authenticate and start up the gateway connection - {err}")
|
|
||||||
})?;
|
|
||||||
Ok(gateway_client)
|
|
||||||
}
|
|
||||||
|
|
||||||
// future responsible for periodically polling directory server and updating
|
|
||||||
// the current global view of topology
|
|
||||||
async fn start_topology_refresher(
|
|
||||||
nym_api_urls: Vec<Url>,
|
|
||||||
refresh_rate: Duration,
|
|
||||||
topology_accessor: TopologyAccessor,
|
|
||||||
shutdown: TaskClient,
|
|
||||||
) -> Result<(), ClientCoreError> {
|
|
||||||
let topology_refresher_config = TopologyRefresherConfig::new(
|
|
||||||
nym_api_urls,
|
|
||||||
refresh_rate,
|
|
||||||
env!("CARGO_PKG_VERSION").to_string(),
|
|
||||||
);
|
|
||||||
let mut topology_refresher =
|
|
||||||
TopologyRefresher::new(topology_refresher_config, topology_accessor);
|
|
||||||
// before returning, block entire runtime to refresh the current network view so that any
|
|
||||||
// components depending on topology would see a non-empty view
|
|
||||||
info!("Obtaining initial network topology");
|
|
||||||
topology_refresher.refresh().await;
|
|
||||||
|
|
||||||
if let Err(err) = topology_refresher.ensure_topology_is_routable().await {
|
|
||||||
log::error!(
|
|
||||||
"The current network topology seem to be insufficient to route any packets through \
|
|
||||||
- check if enough nodes and a gateway are online - source: {err}"
|
|
||||||
);
|
|
||||||
return Err(ClientCoreError::InsufficientNetworkTopology(err));
|
|
||||||
}
|
|
||||||
|
|
||||||
info!("Starting topology refresher...");
|
|
||||||
topology_refresher.start_with_shutdown(shutdown);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
// controller for sending sphinx packets to mixnet (either real traffic or cover traffic)
|
|
||||||
// TODO: if we want to send control messages to gateway_client, this CAN'T take the ownership
|
|
||||||
// over it. Perhaps GatewayClient needs to be thread-shareable or have some channel for
|
|
||||||
// requests?
|
|
||||||
fn start_mix_traffic_controller(
|
|
||||||
gateway_client: GatewayClient<C>,
|
|
||||||
shutdown: TaskClient,
|
|
||||||
) -> BatchMixMessageSender {
|
|
||||||
info!("Starting mix traffic controller...");
|
|
||||||
let (mix_traffic_controller, mix_tx) = MixTrafficController::new(gateway_client);
|
|
||||||
mix_traffic_controller.start_with_shutdown(shutdown);
|
|
||||||
mix_tx
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn setup_persistent_reply_storage(
|
|
||||||
backend: B,
|
|
||||||
shutdown: TaskClient,
|
|
||||||
) -> Result<CombinedReplyStorage, ClientCoreError>
|
|
||||||
where
|
|
||||||
<B as ReplyStorageBackend>::StorageError: Sync + Send,
|
|
||||||
{
|
|
||||||
if backend.is_active() {
|
|
||||||
log::trace!("Setup persistent reply storage");
|
|
||||||
let persistent_storage = PersistentReplyStorage::new(backend);
|
|
||||||
let mem_store = persistent_storage
|
|
||||||
.load_state_from_backend()
|
|
||||||
.await
|
|
||||||
.map_err(|err| ClientCoreError::SurbStorageError {
|
|
||||||
source: Box::new(err),
|
|
||||||
})?;
|
|
||||||
|
|
||||||
let store_clone = mem_store.clone();
|
|
||||||
spawn_future(async move {
|
|
||||||
persistent_storage
|
|
||||||
.flush_on_shutdown(store_clone, shutdown)
|
|
||||||
.await
|
|
||||||
});
|
|
||||||
|
|
||||||
Ok(mem_store)
|
|
||||||
} else {
|
|
||||||
log::trace!("Setup inactive reply storage");
|
|
||||||
Ok(backend
|
|
||||||
.get_inactive_storage()
|
|
||||||
.map_err(|err| ClientCoreError::SurbStorageError {
|
|
||||||
source: Box::new(err),
|
|
||||||
})?)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn start_base(mut self) -> Result<BaseClient, ClientCoreError>
|
|
||||||
where
|
|
||||||
<B as ReplyStorageBackend>::StorageError: Sync + Send,
|
|
||||||
{
|
|
||||||
info!("Starting nym client");
|
|
||||||
// channels for inter-component communication
|
|
||||||
// TODO: make the channels be internally created by the relevant components
|
|
||||||
// rather than creating them here, so say for example the buffer controller would create the request channels
|
|
||||||
// and would allow anyone to clone the sender channel
|
|
||||||
|
|
||||||
// unwrapped_sphinx_sender is the transmitter of mixnet messages received from the gateway
|
|
||||||
// unwrapped_sphinx_receiver is the receiver for said messages - used by ReceivedMessagesBuffer
|
|
||||||
let (mixnet_messages_sender, mixnet_messages_receiver) = mpsc::unbounded();
|
|
||||||
|
|
||||||
// used for announcing connection or disconnection of a channel for pushing re-assembled messages to
|
|
||||||
let (received_buffer_request_sender, received_buffer_request_receiver) = mpsc::unbounded();
|
|
||||||
|
|
||||||
// channels responsible for controlling real messages
|
|
||||||
let (input_sender, input_receiver) = tokio::sync::mpsc::channel::<InputMessage>(1);
|
|
||||||
|
|
||||||
// channels responsible for controlling ack messages
|
|
||||||
let (ack_sender, ack_receiver) = mpsc::unbounded();
|
|
||||||
let shared_topology_accessor = TopologyAccessor::new();
|
|
||||||
|
|
||||||
// Shutdown notifier for signalling tasks to stop
|
|
||||||
let task_manager = TaskManager::default();
|
|
||||||
|
|
||||||
// channels responsible for dealing with reply-related fun
|
|
||||||
let (reply_controller_sender, reply_controller_receiver) =
|
|
||||||
reply_controller::requests::new_control_channels();
|
|
||||||
|
|
||||||
let self_address = self.as_mix_recipient();
|
|
||||||
|
|
||||||
// the components are started in very specific order. Unless you know what you are doing,
|
|
||||||
// do not change that.
|
|
||||||
let gateway_client = self
|
|
||||||
.start_gateway_client(mixnet_messages_sender, ack_sender, task_manager.subscribe())
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
let reply_storage = Self::setup_persistent_reply_storage(
|
|
||||||
self.reply_storage_backend,
|
|
||||||
task_manager.subscribe(),
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
Self::start_topology_refresher(
|
|
||||||
self.nym_api_endpoints.clone(),
|
|
||||||
self.debug_config.topology_refresh_rate,
|
|
||||||
shared_topology_accessor.clone(),
|
|
||||||
task_manager.subscribe(),
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
Self::start_received_messages_buffer_controller(
|
|
||||||
self.key_manager.encryption_keypair(),
|
|
||||||
received_buffer_request_receiver,
|
|
||||||
mixnet_messages_receiver,
|
|
||||||
reply_storage.key_storage(),
|
|
||||||
reply_controller_sender.clone(),
|
|
||||||
task_manager.subscribe(),
|
|
||||||
);
|
|
||||||
|
|
||||||
// The sphinx_message_sender is the transmitter for any component generating sphinx packets
|
|
||||||
// that are to be sent to the mixnet. They are used by cover traffic stream and real
|
|
||||||
// traffic stream.
|
|
||||||
// The MixTrafficController then sends the actual traffic
|
|
||||||
let sphinx_message_sender =
|
|
||||||
Self::start_mix_traffic_controller(gateway_client, task_manager.subscribe());
|
|
||||||
|
|
||||||
// Channels that the websocket listener can use to signal downstream to the real traffic
|
|
||||||
// controller that connections are closed.
|
|
||||||
let (client_connection_tx, client_connection_rx) = mpsc::unbounded();
|
|
||||||
|
|
||||||
// Shared queue length data. Published by the `OutQueueController` in the client, and used
|
|
||||||
// primarily to throttle incoming connections (e.g socks5 for attached network-requesters)
|
|
||||||
let shared_lane_queue_lengths = LaneQueueLengths::new();
|
|
||||||
|
|
||||||
let mut controller_config = real_messages_control::Config::new(
|
|
||||||
self.debug_config,
|
|
||||||
self.key_manager.ack_key(),
|
|
||||||
self_address,
|
|
||||||
);
|
|
||||||
|
|
||||||
if let Some(size) = self.debug_config.use_extended_packet_size {
|
|
||||||
log::debug!("Setting extended packet size: {:?}", size);
|
|
||||||
controller_config.set_custom_packet_size(size.into());
|
|
||||||
}
|
|
||||||
|
|
||||||
Self::start_real_traffic_controller(
|
|
||||||
controller_config,
|
|
||||||
shared_topology_accessor.clone(),
|
|
||||||
ack_receiver,
|
|
||||||
input_receiver,
|
|
||||||
sphinx_message_sender.clone(),
|
|
||||||
reply_storage,
|
|
||||||
reply_controller_sender.clone(),
|
|
||||||
reply_controller_receiver,
|
|
||||||
shared_lane_queue_lengths.clone(),
|
|
||||||
client_connection_rx,
|
|
||||||
task_manager.subscribe(),
|
|
||||||
);
|
|
||||||
|
|
||||||
if !self.debug_config.disable_loop_cover_traffic_stream {
|
|
||||||
Self::start_cover_traffic_stream(
|
|
||||||
self.debug_config,
|
|
||||||
self.key_manager.ack_key(),
|
|
||||||
self_address,
|
|
||||||
shared_topology_accessor,
|
|
||||||
sphinx_message_sender,
|
|
||||||
task_manager.subscribe(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
debug!("Core client startup finished!");
|
|
||||||
debug!("The address of this client is: {self_address}");
|
|
||||||
|
|
||||||
Ok(BaseClient {
|
|
||||||
client_input: ClientInputStatus::AwaitingProducer {
|
|
||||||
client_input: ClientInput {
|
|
||||||
connection_command_sender: client_connection_tx,
|
|
||||||
input_sender,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
client_output: ClientOutputStatus::AwaitingConsumer {
|
|
||||||
client_output: ClientOutput {
|
|
||||||
received_buffer_request_sender,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
client_state: ClientState {
|
|
||||||
shared_lane_queue_lengths,
|
|
||||||
reply_controller_sender,
|
|
||||||
},
|
|
||||||
task_manager,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct BaseClient {
|
|
||||||
pub client_input: ClientInputStatus,
|
|
||||||
pub client_output: ClientOutputStatus,
|
|
||||||
pub client_state: ClientState,
|
|
||||||
|
|
||||||
pub task_manager: TaskManager,
|
|
||||||
}
|
|
||||||
@@ -1,100 +0,0 @@
|
|||||||
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
use crate::client::replies::reply_storage::{
|
|
||||||
fs_backend, CombinedReplyStorage, ReplyStorageBackend,
|
|
||||||
};
|
|
||||||
use crate::config::DebugConfig;
|
|
||||||
use crate::error::ClientCoreError;
|
|
||||||
use log::{error, info};
|
|
||||||
use std::path::Path;
|
|
||||||
use std::{fs, io};
|
|
||||||
use time::OffsetDateTime;
|
|
||||||
|
|
||||||
async fn setup_fresh_backend<P: AsRef<Path>>(
|
|
||||||
db_path: P,
|
|
||||||
debug_config: &DebugConfig,
|
|
||||||
) -> Result<fs_backend::Backend, ClientCoreError> {
|
|
||||||
info!("creating fresh surb database");
|
|
||||||
let mut storage_backend = match fs_backend::Backend::init(db_path).await {
|
|
||||||
Ok(backend) => backend,
|
|
||||||
Err(err) => {
|
|
||||||
error!("failed to setup persistent storage backend for our reply needs: {err}");
|
|
||||||
return Err(ClientCoreError::SurbStorageError {
|
|
||||||
source: Box::new(err),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// while I kinda hate that we're going to be creating `CombinedReplyStorage` twice,
|
|
||||||
// it will only be happening on the very first run and in practice won't incur huge
|
|
||||||
// costs since the storage is going to be empty
|
|
||||||
let mem_store = CombinedReplyStorage::new(
|
|
||||||
debug_config.minimum_reply_surb_storage_threshold,
|
|
||||||
debug_config.maximum_reply_surb_storage_threshold,
|
|
||||||
);
|
|
||||||
storage_backend
|
|
||||||
.init_fresh(&mem_store)
|
|
||||||
.await
|
|
||||||
.map_err(|err| ClientCoreError::SurbStorageError {
|
|
||||||
source: Box::new(err),
|
|
||||||
})?;
|
|
||||||
|
|
||||||
Ok(storage_backend)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn setup_inactive_backend(debug_config: &DebugConfig) -> fs_backend::Backend {
|
|
||||||
info!("creating inactive surb database");
|
|
||||||
fs_backend::Backend::new_inactive(
|
|
||||||
debug_config.minimum_reply_surb_storage_threshold,
|
|
||||||
debug_config.maximum_reply_surb_storage_threshold,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn archive_corrupted_database<P: AsRef<Path>>(db_path: P) -> io::Result<()> {
|
|
||||||
let db_path = db_path.as_ref();
|
|
||||||
debug_assert!(db_path.exists());
|
|
||||||
|
|
||||||
let now = OffsetDateTime::now_utc().unix_timestamp();
|
|
||||||
|
|
||||||
let suffix = format!("_{now}.corrupted");
|
|
||||||
|
|
||||||
let new_extension =
|
|
||||||
if let Some(existing_extension) = db_path.extension().and_then(|ext| ext.to_str()) {
|
|
||||||
format!("{existing_extension}.{suffix}")
|
|
||||||
} else {
|
|
||||||
suffix
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut renamed = db_path.to_owned();
|
|
||||||
renamed.set_extension(new_extension);
|
|
||||||
|
|
||||||
fs::rename(db_path, renamed)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn setup_fs_reply_surb_backend<P: AsRef<Path>>(
|
|
||||||
db_path: Option<P>,
|
|
||||||
debug_config: &DebugConfig,
|
|
||||||
) -> Result<fs_backend::Backend, ClientCoreError> {
|
|
||||||
if let Some(db_path) = db_path {
|
|
||||||
// if the database file doesnt exist, initialise fresh storage, otherwise attempt to load
|
|
||||||
// the existing one
|
|
||||||
let db_path = db_path.as_ref();
|
|
||||||
if db_path.exists() {
|
|
||||||
info!("loading existing surb database");
|
|
||||||
match fs_backend::Backend::try_load(db_path).await {
|
|
||||||
Ok(backend) => Ok(backend),
|
|
||||||
Err(err) => {
|
|
||||||
error!("failed to setup persistent storage backend for our reply needs: {err}. We're going to create a fresh database instead. This behaviour might change in the future");
|
|
||||||
|
|
||||||
archive_corrupted_database(db_path)?;
|
|
||||||
setup_fresh_backend(db_path, debug_config).await
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
setup_fresh_backend(db_path, debug_config).await
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Ok(setup_inactive_backend(debug_config))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,227 +0,0 @@
|
|||||||
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
use crate::config::persistence::key_pathfinder::ClientKeyPathfinder;
|
|
||||||
use gateway_requests::registration::handshake::SharedKeys;
|
|
||||||
use log::*;
|
|
||||||
use nym_crypto::asymmetric::{encryption, identity};
|
|
||||||
use nym_sphinx::acknowledgements::AckKey;
|
|
||||||
use rand::{CryptoRng, RngCore};
|
|
||||||
use std::io;
|
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
// Note: to support key rotation in the future, all keys will require adding an extra smart pointer,
|
|
||||||
// most likely an AtomicCell, or if it doesn't work as I think it does, a Mutex. Although I think
|
|
||||||
// AtomicCell includes a Mutex implicitly if the underlying type does not work atomically.
|
|
||||||
// And I guess there will need to be some mechanism for a grace period when you can still
|
|
||||||
// use the old key after new one was issued.
|
|
||||||
|
|
||||||
// Remember that Arc<T> has Deref implementation for T
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct KeyManager {
|
|
||||||
/// identity key associated with the client instance.
|
|
||||||
identity_keypair: Arc<identity::KeyPair>,
|
|
||||||
|
|
||||||
/// encryption key associated with the client instance.
|
|
||||||
encryption_keypair: Arc<encryption::KeyPair>,
|
|
||||||
|
|
||||||
/// shared key derived with the gateway during "registration handshake"
|
|
||||||
gateway_shared_key: Option<Arc<SharedKeys>>,
|
|
||||||
|
|
||||||
/// key used for producing and processing acknowledgement packets.
|
|
||||||
ack_key: Arc<AckKey>,
|
|
||||||
}
|
|
||||||
|
|
||||||
// The expected flow of a KeyManager "lifetime" is as follows:
|
|
||||||
/*
|
|
||||||
1. ::new() is called during client-init
|
|
||||||
2. after gateway registration is completed [in init] ::insert_gateway_shared_key() is called
|
|
||||||
3. ::store_keys() is called before init finishes execution.
|
|
||||||
4. ::load_keys() is called at the beginning of each subsequent client-run
|
|
||||||
5. [not implemented] ::rotate_keys() is called periodically during client-run I presume?
|
|
||||||
*/
|
|
||||||
|
|
||||||
impl KeyManager {
|
|
||||||
/// Creates new instance of a [`KeyManager`]
|
|
||||||
pub fn new<R>(rng: &mut R) -> Self
|
|
||||||
where
|
|
||||||
R: RngCore + CryptoRng,
|
|
||||||
{
|
|
||||||
KeyManager {
|
|
||||||
identity_keypair: Arc::new(identity::KeyPair::new(rng)),
|
|
||||||
encryption_keypair: Arc::new(encryption::KeyPair::new(rng)),
|
|
||||||
gateway_shared_key: None,
|
|
||||||
ack_key: Arc::new(AckKey::new(rng)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn from_keys(
|
|
||||||
id_keypair: identity::KeyPair,
|
|
||||||
enc_keypair: encryption::KeyPair,
|
|
||||||
gateway_shared_key: SharedKeys,
|
|
||||||
ack_key: AckKey,
|
|
||||||
) -> Self {
|
|
||||||
Self {
|
|
||||||
identity_keypair: Arc::new(id_keypair),
|
|
||||||
encryption_keypair: Arc::new(enc_keypair),
|
|
||||||
gateway_shared_key: Some(Arc::new(gateway_shared_key)),
|
|
||||||
ack_key: Arc::new(ack_key),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Loads previously stored client keys from the disk.
|
|
||||||
fn load_client_keys(client_pathfinder: &ClientKeyPathfinder) -> io::Result<Self> {
|
|
||||||
let identity_keypair: identity::KeyPair =
|
|
||||||
nym_pemstore::load_keypair(&nym_pemstore::KeyPairPath::new(
|
|
||||||
client_pathfinder.private_identity_key().to_owned(),
|
|
||||||
client_pathfinder.public_identity_key().to_owned(),
|
|
||||||
))?;
|
|
||||||
let encryption_keypair: encryption::KeyPair =
|
|
||||||
nym_pemstore::load_keypair(&nym_pemstore::KeyPairPath::new(
|
|
||||||
client_pathfinder.private_encryption_key().to_owned(),
|
|
||||||
client_pathfinder.public_encryption_key().to_owned(),
|
|
||||||
))?;
|
|
||||||
|
|
||||||
let ack_key: AckKey = nym_pemstore::load_key(client_pathfinder.ack_key())?;
|
|
||||||
|
|
||||||
Ok(KeyManager {
|
|
||||||
identity_keypair: Arc::new(identity_keypair),
|
|
||||||
encryption_keypair: Arc::new(encryption_keypair),
|
|
||||||
gateway_shared_key: None,
|
|
||||||
ack_key: Arc::new(ack_key),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Loads previously stored keys from the disk. Fails if not all, including the shared gateway
|
|
||||||
/// key, is available.
|
|
||||||
pub fn load_keys(client_pathfinder: &ClientKeyPathfinder) -> io::Result<Self> {
|
|
||||||
let mut key_manager = Self::load_client_keys(client_pathfinder)?;
|
|
||||||
|
|
||||||
let gateway_shared_key: SharedKeys =
|
|
||||||
nym_pemstore::load_key(client_pathfinder.gateway_shared_key())?;
|
|
||||||
|
|
||||||
key_manager.gateway_shared_key = Some(Arc::new(gateway_shared_key));
|
|
||||||
|
|
||||||
Ok(key_manager)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Loads previously stored keys from the disk. Fails if client keys are not availabe, but the
|
|
||||||
/// shared gateway key is optional.
|
|
||||||
pub fn load_keys_but_gateway_is_optional(
|
|
||||||
client_pathfinder: &ClientKeyPathfinder,
|
|
||||||
) -> io::Result<Self> {
|
|
||||||
let mut key_manager = Self::load_client_keys(client_pathfinder)?;
|
|
||||||
|
|
||||||
let gateway_shared_key: Result<SharedKeys, io::Error> =
|
|
||||||
nym_pemstore::load_key(client_pathfinder.gateway_shared_key());
|
|
||||||
|
|
||||||
// It's ok if the gateway key was not found
|
|
||||||
let gateway_shared_key = match gateway_shared_key {
|
|
||||||
Err(err) if err.kind() == io::ErrorKind::NotFound => Ok(None),
|
|
||||||
Err(err) => Err(err),
|
|
||||||
Ok(key) => Ok(Some(key)),
|
|
||||||
}?;
|
|
||||||
|
|
||||||
key_manager.gateway_shared_key = gateway_shared_key.map(Arc::new);
|
|
||||||
|
|
||||||
Ok(key_manager)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Stores all available keys on the disk.
|
|
||||||
// While perhaps there is no much point in storing the `AckKey` on the disk,
|
|
||||||
// it is done so for the consistency sake so that you wouldn't require an rng instance
|
|
||||||
// during `load_keys` to generate the said key.
|
|
||||||
pub fn store_keys(&self, client_pathfinder: &ClientKeyPathfinder) -> io::Result<()> {
|
|
||||||
nym_pemstore::store_keypair(
|
|
||||||
self.identity_keypair.as_ref(),
|
|
||||||
&nym_pemstore::KeyPairPath::new(
|
|
||||||
client_pathfinder.private_identity_key().to_owned(),
|
|
||||||
client_pathfinder.public_identity_key().to_owned(),
|
|
||||||
),
|
|
||||||
)?;
|
|
||||||
nym_pemstore::store_keypair(
|
|
||||||
self.encryption_keypair.as_ref(),
|
|
||||||
&nym_pemstore::KeyPairPath::new(
|
|
||||||
client_pathfinder.private_encryption_key().to_owned(),
|
|
||||||
client_pathfinder.public_encryption_key().to_owned(),
|
|
||||||
),
|
|
||||||
)?;
|
|
||||||
|
|
||||||
nym_pemstore::store_key(self.ack_key.as_ref(), client_pathfinder.ack_key())?;
|
|
||||||
|
|
||||||
match self.gateway_shared_key.as_ref() {
|
|
||||||
None => debug!("No gateway shared key available to store!"),
|
|
||||||
Some(gate_key) => {
|
|
||||||
nym_pemstore::store_key(gate_key.as_ref(), client_pathfinder.gateway_shared_key())?
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn store_gateway_key(&self, client_pathfinder: &ClientKeyPathfinder) -> io::Result<()> {
|
|
||||||
match self.gateway_shared_key.as_ref() {
|
|
||||||
None => {
|
|
||||||
return Err(io::Error::new(
|
|
||||||
io::ErrorKind::Other,
|
|
||||||
"trying to store a non-existing key",
|
|
||||||
))
|
|
||||||
}
|
|
||||||
Some(gate_key) => {
|
|
||||||
nym_pemstore::store_key(gate_key.as_ref(), client_pathfinder.gateway_shared_key())?
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Overwrite the existing identity keypair
|
|
||||||
pub fn set_identity_keypair(&mut self, id_keypair: identity::KeyPair) {
|
|
||||||
self.identity_keypair = Arc::new(id_keypair);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Gets an atomically reference counted pointer to [`identity::KeyPair`].
|
|
||||||
pub fn identity_keypair(&self) -> Arc<identity::KeyPair> {
|
|
||||||
Arc::clone(&self.identity_keypair)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Overwrite the existing encryption keypair
|
|
||||||
pub fn set_encryption_keypair(&mut self, enc_keypair: encryption::KeyPair) {
|
|
||||||
self.encryption_keypair = Arc::new(enc_keypair);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Gets an atomically reference counted pointer to [`encryption::KeyPair`].
|
|
||||||
pub fn encryption_keypair(&self) -> Arc<encryption::KeyPair> {
|
|
||||||
Arc::clone(&self.encryption_keypair)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Overwrite the existing ack key
|
|
||||||
pub fn set_ack_key(&mut self, ack_key: AckKey) {
|
|
||||||
self.ack_key = Arc::new(ack_key);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Gets an atomically reference counted pointer to [`AckKey`].
|
|
||||||
pub fn ack_key(&self) -> Arc<AckKey> {
|
|
||||||
Arc::clone(&self.ack_key)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// After shared key with the gateway is derived, puts its ownership to this instance of a [`KeyManager`].
|
|
||||||
pub fn insert_gateway_shared_key(&mut self, gateway_shared_key: Arc<SharedKeys>) {
|
|
||||||
self.gateway_shared_key = Some(gateway_shared_key)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Gets an atomically reference counted pointer to [`SharedKey`].
|
|
||||||
// since this function is not fully public, it is not expected to be used externally and
|
|
||||||
// hence it's up to us to ensure it's called in correct context
|
|
||||||
pub fn gateway_shared_key(&self) -> Arc<SharedKeys> {
|
|
||||||
Arc::clone(
|
|
||||||
self.gateway_shared_key
|
|
||||||
.as_ref()
|
|
||||||
.expect("tried to unwrap empty gateway key!"),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is_gateway_key_set(&self) -> bool {
|
|
||||||
self.gateway_shared_key.is_some()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,336 +0,0 @@
|
|||||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
use crate::spawn_future;
|
|
||||||
use futures::StreamExt;
|
|
||||||
use log::*;
|
|
||||||
use nym_sphinx::addressing::clients::Recipient;
|
|
||||||
use nym_sphinx::params::DEFAULT_NUM_MIX_HOPS;
|
|
||||||
use nym_topology::{nym_topology_from_detailed, NymTopology, NymTopologyError};
|
|
||||||
use rand::seq::SliceRandom;
|
|
||||||
use rand::thread_rng;
|
|
||||||
use std::ops::Deref;
|
|
||||||
use std::sync::Arc;
|
|
||||||
use std::time::Duration;
|
|
||||||
use tokio::sync::{RwLock, RwLockReadGuard};
|
|
||||||
use url::Url;
|
|
||||||
|
|
||||||
// I'm extremely curious why compiler NEVER complained about lack of Debug here before
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct TopologyAccessorInner(Option<NymTopology>);
|
|
||||||
|
|
||||||
impl AsRef<Option<NymTopology>> for TopologyAccessorInner {
|
|
||||||
fn as_ref(&self) -> &Option<NymTopology> {
|
|
||||||
&self.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TopologyAccessorInner {
|
|
||||||
fn new() -> Self {
|
|
||||||
TopologyAccessorInner(None)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn update(&mut self, new: Option<NymTopology>) {
|
|
||||||
self.0 = new;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct TopologyReadPermit<'a> {
|
|
||||||
permit: RwLockReadGuard<'a, TopologyAccessorInner>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> Deref for TopologyReadPermit<'a> {
|
|
||||||
type Target = TopologyAccessorInner;
|
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
|
||||||
&self.permit
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> TopologyReadPermit<'a> {
|
|
||||||
/// Using provided topology read permit, tries to get an immutable reference to the underlying
|
|
||||||
/// topology. For obvious reasons the lifetime of the topology reference is bound to the permit.
|
|
||||||
pub(super) fn try_get_valid_topology_ref(
|
|
||||||
&'a self,
|
|
||||||
ack_recipient: &Recipient,
|
|
||||||
packet_recipient: Option<&Recipient>,
|
|
||||||
) -> Result<&'a NymTopology, NymTopologyError> {
|
|
||||||
// 1. Have we managed to get anything from the refresher, i.e. have the nym-api queries gone through?
|
|
||||||
let topology = self
|
|
||||||
.permit
|
|
||||||
.as_ref()
|
|
||||||
.as_ref()
|
|
||||||
.ok_or(NymTopologyError::EmptyNetworkTopology)?;
|
|
||||||
|
|
||||||
// 2. does it have any mixnode at all?
|
|
||||||
// 3. does it have any gateways at all?
|
|
||||||
// 4. does it have a mixnode on each layer?
|
|
||||||
topology.ensure_can_construct_path_through(DEFAULT_NUM_MIX_HOPS)?;
|
|
||||||
|
|
||||||
// 5. does it contain OUR gateway (so that we could create an ack packet)?
|
|
||||||
if !topology.gateway_exists(ack_recipient.gateway()) {
|
|
||||||
return Err(NymTopologyError::NonExistentGatewayError {
|
|
||||||
identity_key: ack_recipient.gateway().to_base58_string(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// 6. for our target recipient, does it contain THEIR gateway (so that we could create
|
|
||||||
if let Some(recipient) = packet_recipient {
|
|
||||||
if !topology.gateway_exists(recipient.gateway()) {
|
|
||||||
return Err(NymTopologyError::NonExistentGatewayError {
|
|
||||||
identity_key: recipient.gateway().to_base58_string(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(topology)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> From<RwLockReadGuard<'a, TopologyAccessorInner>> for TopologyReadPermit<'a> {
|
|
||||||
fn from(read_permit: RwLockReadGuard<'a, TopologyAccessorInner>) -> Self {
|
|
||||||
TopologyReadPermit {
|
|
||||||
permit: read_permit,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub struct TopologyAccessor {
|
|
||||||
// `RwLock` *seems to* be the better approach for this as write access is only requested every
|
|
||||||
// few seconds, while reads are needed every single packet generated.
|
|
||||||
// However, proper benchmarks will be needed to determine if `RwLock` is indeed a better
|
|
||||||
// approach than a `Mutex`
|
|
||||||
inner: Arc<RwLock<TopologyAccessorInner>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TopologyAccessor {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
TopologyAccessor {
|
|
||||||
inner: Arc::new(RwLock::new(TopologyAccessorInner::new())),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn get_read_permit(&self) -> TopologyReadPermit<'_> {
|
|
||||||
self.inner.read().await.into()
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn update_global_topology(&self, new_topology: Option<NymTopology>) {
|
|
||||||
self.inner.write().await.update(new_topology);
|
|
||||||
}
|
|
||||||
|
|
||||||
// only used by the client at startup to get a slightly more reasonable error message
|
|
||||||
// (currently displays as unused because health checker is disabled due to required changes)
|
|
||||||
pub async fn ensure_is_routable(&self) -> Result<(), NymTopologyError> {
|
|
||||||
match &self.inner.read().await.0 {
|
|
||||||
None => Err(NymTopologyError::EmptyNetworkTopology),
|
|
||||||
Some(ref topology) => topology.ensure_can_construct_path_through(DEFAULT_NUM_MIX_HOPS),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for TopologyAccessor {
|
|
||||||
fn default() -> Self {
|
|
||||||
TopologyAccessor::new()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct TopologyRefresherConfig {
|
|
||||||
nym_api_urls: Vec<Url>,
|
|
||||||
refresh_rate: Duration,
|
|
||||||
client_version: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TopologyRefresherConfig {
|
|
||||||
pub fn new(nym_api_urls: Vec<Url>, refresh_rate: Duration, client_version: String) -> Self {
|
|
||||||
TopologyRefresherConfig {
|
|
||||||
nym_api_urls,
|
|
||||||
refresh_rate,
|
|
||||||
client_version,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct TopologyRefresher {
|
|
||||||
validator_client: validator_client::client::NymApiClient,
|
|
||||||
client_version: String,
|
|
||||||
|
|
||||||
nym_api_urls: Vec<Url>,
|
|
||||||
topology_accessor: TopologyAccessor,
|
|
||||||
refresh_rate: Duration,
|
|
||||||
|
|
||||||
currently_used_api: usize,
|
|
||||||
was_latest_valid: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TopologyRefresher {
|
|
||||||
pub fn new(mut cfg: TopologyRefresherConfig, topology_accessor: TopologyAccessor) -> Self {
|
|
||||||
cfg.nym_api_urls.shuffle(&mut thread_rng());
|
|
||||||
|
|
||||||
TopologyRefresher {
|
|
||||||
validator_client: validator_client::client::NymApiClient::new(
|
|
||||||
cfg.nym_api_urls[0].clone(),
|
|
||||||
),
|
|
||||||
client_version: cfg.client_version,
|
|
||||||
nym_api_urls: cfg.nym_api_urls,
|
|
||||||
topology_accessor,
|
|
||||||
refresh_rate: cfg.refresh_rate,
|
|
||||||
currently_used_api: 0,
|
|
||||||
was_latest_valid: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn use_next_nym_api(&mut self) {
|
|
||||||
if self.nym_api_urls.len() == 1 {
|
|
||||||
warn!("There's only a single nym API available - it won't be possible to use a different one");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.currently_used_api = (self.currently_used_api + 1) % self.nym_api_urls.len();
|
|
||||||
self.validator_client
|
|
||||||
.change_nym_api(self.nym_api_urls[self.currently_used_api].clone())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Verifies whether nodes a reasonably distributed among all mix layers.
|
|
||||||
///
|
|
||||||
/// In ideal world we would have 33% nodes on layer 1, 33% on layer 2 and 33% on layer 3.
|
|
||||||
/// However, this is a rather unrealistic expectation, instead we check whether there exists
|
|
||||||
/// a layer with more than 66% of nodes or with fewer than 15% and if so, we trigger a failure.
|
|
||||||
///
|
|
||||||
/// # Arguments
|
|
||||||
///
|
|
||||||
/// * `topology`: active topology constructed from validator api data
|
|
||||||
fn check_layer_distribution(&self, active_topology: &NymTopology) -> bool {
|
|
||||||
let mixes = active_topology.mixes();
|
|
||||||
let mixnodes_count = active_topology.num_mixnodes();
|
|
||||||
|
|
||||||
if active_topology.gateways().is_empty() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// trivial check to see if have at least a single node on each layer (regardless of active set size)
|
|
||||||
if mixes.get(&1).is_none() || mixes.get(&2).is_none() || mixes.get(&3).is_none() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
let upper_bound = (mixnodes_count as f32 * 0.66) as usize;
|
|
||||||
let lower_bound = (mixnodes_count as f32 * 0.15) as usize;
|
|
||||||
|
|
||||||
let layer1 = mixes.get(&1).unwrap().len();
|
|
||||||
let layer2 = mixes.get(&2).unwrap().len();
|
|
||||||
let layer3 = mixes.get(&3).unwrap().len();
|
|
||||||
|
|
||||||
if layer1 < lower_bound || layer1 > upper_bound {
|
|
||||||
warn!(
|
|
||||||
"nodes: {}, layer1: {}, layer2: {}, layer3: {}",
|
|
||||||
mixnodes_count, layer1, layer2, layer3
|
|
||||||
);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if layer2 < lower_bound || layer2 > upper_bound {
|
|
||||||
warn!(
|
|
||||||
"nodes: {}, layer1: {}, layer2: {}, layer3: {}",
|
|
||||||
mixnodes_count, layer1, layer2, layer3
|
|
||||||
);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if layer3 < lower_bound || layer3 > upper_bound {
|
|
||||||
warn!(
|
|
||||||
"nodes: {}, layer1: {}, layer2: {}, layer3: {}",
|
|
||||||
mixnodes_count, layer1, layer2, layer3
|
|
||||||
);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn get_current_compatible_topology(&self) -> Option<NymTopology> {
|
|
||||||
// TODO: optimization for the future:
|
|
||||||
// only refresh mixnodes on timer and refresh gateways only when
|
|
||||||
// we have to send to a new, unknown, gateway
|
|
||||||
|
|
||||||
let mixnodes = match self.validator_client.get_cached_active_mixnodes().await {
|
|
||||||
Err(err) => {
|
|
||||||
error!("failed to get network mixnodes - {err}");
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
Ok(mixes) => mixes,
|
|
||||||
};
|
|
||||||
|
|
||||||
let gateways = match self.validator_client.get_cached_gateways().await {
|
|
||||||
Err(err) => {
|
|
||||||
error!("failed to get network gateways - {err}");
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
Ok(gateways) => gateways,
|
|
||||||
};
|
|
||||||
|
|
||||||
let topology = nym_topology_from_detailed(mixnodes, gateways)
|
|
||||||
.filter_system_version(&self.client_version);
|
|
||||||
|
|
||||||
if !self.check_layer_distribution(&topology) {
|
|
||||||
warn!("The current filtered active topology has extremely skewed layer distribution. It cannot be used.");
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(topology)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn refresh(&mut self) {
|
|
||||||
trace!("Refreshing the topology");
|
|
||||||
let new_topology = self.get_current_compatible_topology().await;
|
|
||||||
|
|
||||||
if new_topology.is_none() {
|
|
||||||
self.use_next_nym_api();
|
|
||||||
}
|
|
||||||
|
|
||||||
if new_topology.is_none() && self.was_latest_valid {
|
|
||||||
// if we failed to grab this topology, but the one before it was alright, let's assume
|
|
||||||
// validator had a tiny hiccup and use the old data
|
|
||||||
warn!("we're going to keep on using the old topology for this iteration");
|
|
||||||
self.was_latest_valid = false;
|
|
||||||
return;
|
|
||||||
} else if new_topology.is_some() {
|
|
||||||
self.was_latest_valid = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.topology_accessor
|
|
||||||
.update_global_topology(new_topology)
|
|
||||||
.await;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn ensure_topology_is_routable(&self) -> Result<(), NymTopologyError> {
|
|
||||||
self.topology_accessor.ensure_is_routable().await
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn start_with_shutdown(mut self, mut shutdown: nym_task::TaskClient) {
|
|
||||||
spawn_future(async move {
|
|
||||||
debug!("Started TopologyRefresher with graceful shutdown support");
|
|
||||||
|
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
|
||||||
let mut interval = tokio_stream::wrappers::IntervalStream::new(tokio::time::interval(
|
|
||||||
self.refresh_rate,
|
|
||||||
));
|
|
||||||
|
|
||||||
#[cfg(target_arch = "wasm32")]
|
|
||||||
let mut interval =
|
|
||||||
gloo_timers::future::IntervalStream::new(self.refresh_rate.as_millis() as u32);
|
|
||||||
|
|
||||||
while !shutdown.is_shutdown() {
|
|
||||||
tokio::select! {
|
|
||||||
_ = interval.next() => {
|
|
||||||
self.refresh().await;
|
|
||||||
},
|
|
||||||
_ = shutdown.recv() => {
|
|
||||||
log::trace!("TopologyRefresher: Received shutdown");
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
shutdown.recv_timeout().await;
|
|
||||||
log::debug!("TopologyRefresher: Exiting");
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,95 +0,0 @@
|
|||||||
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
use crate::config::Config;
|
|
||||||
use nym_config::NymConfig;
|
|
||||||
use std::path::{Path, PathBuf};
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct ClientKeyPathfinder {
|
|
||||||
pub identity_private_key: PathBuf,
|
|
||||||
pub identity_public_key: PathBuf,
|
|
||||||
pub encryption_private_key: PathBuf,
|
|
||||||
pub encryption_public_key: PathBuf,
|
|
||||||
pub gateway_shared_key: PathBuf,
|
|
||||||
pub ack_key: PathBuf,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ClientKeyPathfinder {
|
|
||||||
pub fn new(id: String) -> Self {
|
|
||||||
let os_config_dir = dirs::config_dir().expect("no config directory known for this OS"); // grabs the OS default config dir
|
|
||||||
let config_dir = os_config_dir.join("nym").join("clients").join(id);
|
|
||||||
ClientKeyPathfinder {
|
|
||||||
identity_private_key: config_dir.join("private_identity.pem"),
|
|
||||||
identity_public_key: config_dir.join("public_identity.pem"),
|
|
||||||
encryption_private_key: config_dir.join("private_encryption.pem"),
|
|
||||||
encryption_public_key: config_dir.join("public_encryption.pem"),
|
|
||||||
gateway_shared_key: config_dir.join("gateway_shared.pem"),
|
|
||||||
ack_key: config_dir.join("ack_key.pem"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new_from_config<T: NymConfig>(config: &Config<T>) -> Self {
|
|
||||||
ClientKeyPathfinder {
|
|
||||||
identity_private_key: config.get_private_identity_key_file(),
|
|
||||||
identity_public_key: config.get_public_identity_key_file(),
|
|
||||||
encryption_private_key: config.get_private_encryption_key_file(),
|
|
||||||
encryption_public_key: config.get_public_encryption_key_file(),
|
|
||||||
gateway_shared_key: config.get_gateway_shared_key_file(),
|
|
||||||
ack_key: config.get_ack_key_file(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn any_file_exists(&self) -> bool {
|
|
||||||
matches!(self.identity_public_key.try_exists(), Ok(true))
|
|
||||||
|| matches!(self.identity_private_key.try_exists(), Ok(true))
|
|
||||||
|| matches!(self.encryption_public_key.try_exists(), Ok(true))
|
|
||||||
|| matches!(self.encryption_private_key.try_exists(), Ok(true))
|
|
||||||
|| matches!(self.gateway_shared_key.try_exists(), Ok(true))
|
|
||||||
|| matches!(self.ack_key.try_exists(), Ok(true))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn any_file_exists_and_return(&self) -> Option<PathBuf> {
|
|
||||||
file_exists(&self.identity_public_key)
|
|
||||||
.or_else(|| file_exists(&self.identity_private_key))
|
|
||||||
.or_else(|| file_exists(&self.encryption_public_key))
|
|
||||||
.or_else(|| file_exists(&self.encryption_private_key))
|
|
||||||
.or_else(|| file_exists(&self.gateway_shared_key))
|
|
||||||
.or_else(|| file_exists(&self.ack_key))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn gateway_key_file_exists(&self) -> bool {
|
|
||||||
matches!(self.gateway_shared_key.try_exists(), Ok(true))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn private_identity_key(&self) -> &Path {
|
|
||||||
&self.identity_private_key
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn public_identity_key(&self) -> &Path {
|
|
||||||
&self.identity_public_key
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn private_encryption_key(&self) -> &Path {
|
|
||||||
&self.encryption_private_key
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn public_encryption_key(&self) -> &Path {
|
|
||||||
&self.encryption_public_key
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn gateway_shared_key(&self) -> &Path {
|
|
||||||
&self.gateway_shared_key
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn ack_key(&self) -> &Path {
|
|
||||||
&self.ack_key
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn file_exists(path: &Path) -> Option<PathBuf> {
|
|
||||||
if matches!(path.try_exists(), Ok(true)) {
|
|
||||||
return Some(path.to_path_buf());
|
|
||||||
}
|
|
||||||
None
|
|
||||||
}
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
pub mod key_pathfinder;
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
use gateway_client::error::GatewayClientError;
|
|
||||||
use nym_crypto::asymmetric::identity::Ed25519RecoveryError;
|
|
||||||
use nym_topology::NymTopologyError;
|
|
||||||
use validator_client::ValidatorClientError;
|
|
||||||
|
|
||||||
#[derive(thiserror::Error, Debug)]
|
|
||||||
pub enum ClientCoreError {
|
|
||||||
#[error("I/O error: {0}")]
|
|
||||||
IoError(#[from] std::io::Error),
|
|
||||||
|
|
||||||
#[error("Gateway client error: {0}")]
|
|
||||||
GatewayClientError(#[from] GatewayClientError),
|
|
||||||
|
|
||||||
#[error("Ed25519 error: {0}")]
|
|
||||||
Ed25519RecoveryError(#[from] Ed25519RecoveryError),
|
|
||||||
|
|
||||||
#[error("Validator client error: {0}")]
|
|
||||||
ValidatorClientError(#[from] ValidatorClientError),
|
|
||||||
|
|
||||||
#[error("No gateway with id: {0}")]
|
|
||||||
NoGatewayWithId(String),
|
|
||||||
|
|
||||||
#[error("No gateways on network")]
|
|
||||||
NoGatewaysOnNetwork,
|
|
||||||
|
|
||||||
#[error("Failed to setup gateway")]
|
|
||||||
FailedToSetupGateway,
|
|
||||||
|
|
||||||
#[error("List of nym apis is empty")]
|
|
||||||
ListOfNymApisIsEmpty,
|
|
||||||
|
|
||||||
#[error("Could not load existing gateway configuration: {0}")]
|
|
||||||
CouldNotLoadExistingGatewayConfiguration(std::io::Error),
|
|
||||||
|
|
||||||
#[error("The current network topology seem to be insufficient to route any packets through")]
|
|
||||||
InsufficientNetworkTopology(#[from] NymTopologyError),
|
|
||||||
|
|
||||||
#[error("experienced a failure with our reply surb persistent storage: {source}")]
|
|
||||||
SurbStorageError {
|
|
||||||
source: Box<dyn std::error::Error + Send + Sync>,
|
|
||||||
},
|
|
||||||
|
|
||||||
#[error("The gateway id is invalid - {0}")]
|
|
||||||
UnableToCreatePublicKeyFromGatewayId(Ed25519RecoveryError),
|
|
||||||
|
|
||||||
#[error("The identity of the gateway is unknwown - did you run init?")]
|
|
||||||
GatewayIdUnknown,
|
|
||||||
|
|
||||||
#[error("The owner of the gateway is unknown - did you run init?")]
|
|
||||||
GatewayOwnerUnknown,
|
|
||||||
|
|
||||||
#[error("The address of the gateway is unknown - did you run init?")]
|
|
||||||
GatwayAddressUnknown,
|
|
||||||
|
|
||||||
#[error("failed to register receiver for reconstructed mixnet messages")]
|
|
||||||
FailedToRegisterReceiver,
|
|
||||||
|
|
||||||
#[error("Unexpected exit")]
|
|
||||||
UnexpectedExit,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set of messages that the client can send to listeners via the task manager
|
|
||||||
#[derive(thiserror::Error, Debug)]
|
|
||||||
pub enum ClientCoreStatusMessage {
|
|
||||||
// NOTE: The nym-connect frontend listens for these strings, so don't change them until we have a more robust mechanism in place
|
|
||||||
#[error("The connected gateway is slow, or the connection to it is slow")]
|
|
||||||
GatewayIsSlow,
|
|
||||||
// NOTE: The nym-connect frontend listens for these strings, so don't change them until we have a more robust mechanism in place
|
|
||||||
#[error("The connected gateway is very slow, or the connection to it is very slow")]
|
|
||||||
GatewayIsVerySlow,
|
|
||||||
}
|
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
use crate::{
|
|
||||||
client::key_manager::KeyManager,
|
|
||||||
config::{persistence::key_pathfinder::ClientKeyPathfinder, Config},
|
|
||||||
error::ClientCoreError,
|
|
||||||
};
|
|
||||||
#[cfg(target_arch = "wasm32")]
|
|
||||||
use gateway_client::wasm_mockups::SigningNyxdClient;
|
|
||||||
use gateway_client::GatewayClient;
|
|
||||||
use gateway_requests::registration::handshake::SharedKeys;
|
|
||||||
use nym_config::NymConfig;
|
|
||||||
use nym_crypto::asymmetric::identity;
|
|
||||||
use nym_topology::{filter::VersionFilterable, gateway};
|
|
||||||
use rand::{seq::SliceRandom, thread_rng};
|
|
||||||
use std::{sync::Arc, time::Duration};
|
|
||||||
use tap::TapFallible;
|
|
||||||
use url::Url;
|
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
|
||||||
use validator_client::nyxd::SigningNyxdClient;
|
|
||||||
|
|
||||||
pub(super) async fn query_gateway_details(
|
|
||||||
validator_servers: Vec<Url>,
|
|
||||||
chosen_gateway_id: Option<identity::PublicKey>,
|
|
||||||
) -> Result<gateway::Node, ClientCoreError> {
|
|
||||||
let nym_api = validator_servers
|
|
||||||
.choose(&mut thread_rng())
|
|
||||||
.ok_or(ClientCoreError::ListOfNymApisIsEmpty)?;
|
|
||||||
let validator_client = validator_client::client::NymApiClient::new(nym_api.clone());
|
|
||||||
|
|
||||||
log::trace!("Fetching list of gateways from: {}", nym_api);
|
|
||||||
let gateways = validator_client.get_cached_gateways().await?;
|
|
||||||
let valid_gateways = gateways
|
|
||||||
.into_iter()
|
|
||||||
.filter_map(|gateway| gateway.try_into().ok())
|
|
||||||
.collect::<Vec<gateway::Node>>();
|
|
||||||
|
|
||||||
let filtered_gateways = valid_gateways.filter_by_version(env!("CARGO_PKG_VERSION"));
|
|
||||||
|
|
||||||
// if we have chosen particular gateway - use it, otherwise choose a random one.
|
|
||||||
// (remember that in active topology all gateways have at least 100 reputation so should
|
|
||||||
// be working correctly)
|
|
||||||
if let Some(gateway_id) = chosen_gateway_id {
|
|
||||||
filtered_gateways
|
|
||||||
.iter()
|
|
||||||
.find(|gateway| gateway.identity_key == gateway_id)
|
|
||||||
.ok_or_else(|| ClientCoreError::NoGatewayWithId(gateway_id.to_string()))
|
|
||||||
.cloned()
|
|
||||||
} else {
|
|
||||||
filtered_gateways
|
|
||||||
.choose(&mut rand::thread_rng())
|
|
||||||
.ok_or(ClientCoreError::NoGatewaysOnNetwork)
|
|
||||||
.cloned()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(super) async fn register_with_gateway(
|
|
||||||
gateway: &gateway::Node,
|
|
||||||
our_identity: Arc<identity::KeyPair>,
|
|
||||||
) -> Result<Arc<SharedKeys>, ClientCoreError> {
|
|
||||||
let timeout = Duration::from_millis(1500);
|
|
||||||
let mut gateway_client: GatewayClient<SigningNyxdClient> = GatewayClient::new_init(
|
|
||||||
gateway.clients_address(),
|
|
||||||
gateway.identity_key,
|
|
||||||
our_identity.clone(),
|
|
||||||
timeout,
|
|
||||||
);
|
|
||||||
gateway_client
|
|
||||||
.establish_connection()
|
|
||||||
.await
|
|
||||||
.tap_err(|_| log::warn!("Failed to establish connection with gateway!"))?;
|
|
||||||
let shared_keys = gateway_client
|
|
||||||
.perform_initial_authentication()
|
|
||||||
.await
|
|
||||||
.tap_err(|_| log::warn!("Failed to register with the gateway!"))?;
|
|
||||||
Ok(shared_keys)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(super) fn store_keys<T>(
|
|
||||||
key_manager: &KeyManager,
|
|
||||||
config: &Config<T>,
|
|
||||||
) -> Result<(), ClientCoreError>
|
|
||||||
where
|
|
||||||
T: NymConfig,
|
|
||||||
{
|
|
||||||
let pathfinder = ClientKeyPathfinder::new_from_config(config);
|
|
||||||
Ok(key_manager
|
|
||||||
.store_keys(&pathfinder)
|
|
||||||
.tap_err(|err| log::error!("Failed to generate keys: {err}"))?)
|
|
||||||
}
|
|
||||||
@@ -1,234 +0,0 @@
|
|||||||
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
//! Collection of initialization steps used by client implementations
|
|
||||||
|
|
||||||
use std::fmt::Display;
|
|
||||||
|
|
||||||
use nym_sphinx::addressing::{clients::Recipient, nodes::NodeIdentity};
|
|
||||||
use rand::rngs::OsRng;
|
|
||||||
use serde::Serialize;
|
|
||||||
use tap::TapFallible;
|
|
||||||
|
|
||||||
use nym_config::NymConfig;
|
|
||||||
use nym_crypto::asymmetric::{encryption, identity};
|
|
||||||
use url::Url;
|
|
||||||
|
|
||||||
use crate::client::key_manager::KeyManager;
|
|
||||||
use crate::{
|
|
||||||
config::{
|
|
||||||
persistence::key_pathfinder::ClientKeyPathfinder, ClientCoreConfigTrait, Config,
|
|
||||||
GatewayEndpointConfig,
|
|
||||||
},
|
|
||||||
error::ClientCoreError,
|
|
||||||
};
|
|
||||||
|
|
||||||
mod helpers;
|
|
||||||
|
|
||||||
/// Struct describing the results of the client initialization procedure.
|
|
||||||
#[derive(Debug, Serialize)]
|
|
||||||
pub struct InitResults {
|
|
||||||
version: String,
|
|
||||||
id: String,
|
|
||||||
identity_key: String,
|
|
||||||
encryption_key: String,
|
|
||||||
gateway_id: String,
|
|
||||||
gateway_listener: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl InitResults {
|
|
||||||
pub fn new<T>(config: &Config<T>, address: &Recipient) -> Self
|
|
||||||
where
|
|
||||||
T: NymConfig,
|
|
||||||
{
|
|
||||||
Self {
|
|
||||||
version: config.get_version().to_string(),
|
|
||||||
id: config.get_id(),
|
|
||||||
identity_key: address.identity().to_base58_string(),
|
|
||||||
encryption_key: address.encryption_key().to_base58_string(),
|
|
||||||
gateway_id: config.get_gateway_id(),
|
|
||||||
gateway_listener: config.get_gateway_listener(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Display for InitResults {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
||||||
writeln!(f, "Version: {}", self.version)?;
|
|
||||||
writeln!(f, "ID: {}", self.id)?;
|
|
||||||
writeln!(f, "Identity key: {}", self.identity_key)?;
|
|
||||||
writeln!(f, "Encryption: {}", self.encryption_key)?;
|
|
||||||
writeln!(f, "Gateway ID: {}", self.gateway_id)?;
|
|
||||||
write!(f, "Gateway: {}", self.gateway_listener)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Create a new set of client keys.
|
|
||||||
pub fn new_client_keys() -> KeyManager {
|
|
||||||
let mut rng = OsRng;
|
|
||||||
KeyManager::new(&mut rng)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Authenticate and register with a gateway.
|
|
||||||
/// Either pick one at random by querying the available gateways from the nym-api, or use the
|
|
||||||
/// chosen one if it's among the available ones.
|
|
||||||
/// The shared key is added to the supplied `KeyManager` and the endpoint details are returned.
|
|
||||||
pub async fn register_with_gateway(
|
|
||||||
key_manager: &mut KeyManager,
|
|
||||||
nym_api_endpoints: Vec<Url>,
|
|
||||||
chosen_gateway_id: Option<identity::PublicKey>,
|
|
||||||
) -> Result<GatewayEndpointConfig, ClientCoreError> {
|
|
||||||
// Get the gateway details of the gateway we will use
|
|
||||||
let gateway = helpers::query_gateway_details(nym_api_endpoints, chosen_gateway_id).await?;
|
|
||||||
log::debug!("Querying gateway gives: {}", gateway);
|
|
||||||
|
|
||||||
let our_identity = key_manager.identity_keypair();
|
|
||||||
|
|
||||||
// Establish connection, authenticate and generate keys for talking with the gateway
|
|
||||||
let shared_keys = helpers::register_with_gateway(&gateway, our_identity).await?;
|
|
||||||
key_manager.insert_gateway_shared_key(shared_keys);
|
|
||||||
|
|
||||||
Ok(gateway.into())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Convenience function for setting up the gateway for a client given a `Config`. Depending on the
|
|
||||||
/// arguments given it will do the sensible thing. Either it will
|
|
||||||
///
|
|
||||||
/// a. Reuse existing gateway configuration from storage.
|
|
||||||
/// b. Create a new gateway configuration but keep existing keys. This assumes that the caller
|
|
||||||
/// knows what they are doing and that the keys match the requested gateway.
|
|
||||||
/// c. Create a new gateway configuration with a newly registered gateway and keys.
|
|
||||||
pub async fn setup_gateway_from_config<C, T>(
|
|
||||||
register_gateway: bool,
|
|
||||||
user_chosen_gateway_id: Option<identity::PublicKey>,
|
|
||||||
config: &Config<T>,
|
|
||||||
) -> Result<GatewayEndpointConfig, ClientCoreError>
|
|
||||||
where
|
|
||||||
C: NymConfig + ClientCoreConfigTrait,
|
|
||||||
T: NymConfig,
|
|
||||||
{
|
|
||||||
let id = config.get_id();
|
|
||||||
|
|
||||||
// If we are not going to register gateway, and an explicitly chosed gateway is not passed in,
|
|
||||||
// load the existing configuration file
|
|
||||||
if !register_gateway && user_chosen_gateway_id.is_none() {
|
|
||||||
println!("Not registering gateway, will reuse existing config and keys");
|
|
||||||
return load_existing_gateway_config::<C>(&id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Else, we preceed by querying the nym-api
|
|
||||||
let gateway =
|
|
||||||
helpers::query_gateway_details(config.get_nym_api_endpoints(), user_chosen_gateway_id)
|
|
||||||
.await?;
|
|
||||||
log::debug!("Querying gateway gives: {}", gateway);
|
|
||||||
|
|
||||||
// If we are not registering, just return this and assume the caller has the keys already and
|
|
||||||
// wants to keep the,
|
|
||||||
if !register_gateway && user_chosen_gateway_id.is_some() {
|
|
||||||
println!("Using gateway provided by user, keeping existing keys");
|
|
||||||
return Ok(gateway.into());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create new keys and derive our identity
|
|
||||||
let mut key_manager = new_client_keys();
|
|
||||||
let our_identity = key_manager.identity_keypair();
|
|
||||||
|
|
||||||
// Establish connection, authenticate and generate keys for talking with the gateway
|
|
||||||
println!("Registering with new gateway");
|
|
||||||
let shared_keys = helpers::register_with_gateway(&gateway, our_identity).await?;
|
|
||||||
key_manager.insert_gateway_shared_key(shared_keys);
|
|
||||||
|
|
||||||
// Write all keys to storage and just return the gateway endpoint config. It is assumed that we
|
|
||||||
// will load keys from storage when actually connecting.
|
|
||||||
helpers::store_keys(&key_manager, config)?;
|
|
||||||
Ok(gateway.into())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Read and reuse the existing gateway configuration from a file that was generate earlier.
|
|
||||||
pub fn load_existing_gateway_config<T>(id: &str) -> Result<GatewayEndpointConfig, ClientCoreError>
|
|
||||||
where
|
|
||||||
T: NymConfig + ClientCoreConfigTrait,
|
|
||||||
{
|
|
||||||
T::load_from_file(id)
|
|
||||||
.map(|existing_config| existing_config.get_gateway_endpoint().clone())
|
|
||||||
.map_err(|err| {
|
|
||||||
log::error!(
|
|
||||||
"Unable to configure gateway: {err}. \n
|
|
||||||
Seems like the client was already initialized but it was not possible to read \
|
|
||||||
the existing configuration file. \n
|
|
||||||
CAUTION: Consider backing up your gateway keys and try force gateway registration, or \
|
|
||||||
removing the existing configuration and starting over."
|
|
||||||
);
|
|
||||||
ClientCoreError::CouldNotLoadExistingGatewayConfiguration(err)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get the full client address from the client keys and the gateway identity
|
|
||||||
pub fn get_client_address(
|
|
||||||
key_manager: &KeyManager,
|
|
||||||
gateway_config: &GatewayEndpointConfig,
|
|
||||||
) -> Recipient {
|
|
||||||
Recipient::new(
|
|
||||||
*key_manager.identity_keypair().public_key(),
|
|
||||||
*key_manager.encryption_keypair().public_key(),
|
|
||||||
// TODO: below only works under assumption that gateway address == gateway id
|
|
||||||
// (which currently is true)
|
|
||||||
NodeIdentity::from_base58_string(&gateway_config.gateway_id).unwrap(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get the client address by loading the keys from stored files.
|
|
||||||
pub fn get_client_address_from_stored_keys<T>(
|
|
||||||
config: &Config<T>,
|
|
||||||
) -> Result<Recipient, ClientCoreError>
|
|
||||||
where
|
|
||||||
T: nym_config::NymConfig,
|
|
||||||
{
|
|
||||||
fn load_identity_keys(
|
|
||||||
pathfinder: &ClientKeyPathfinder,
|
|
||||||
) -> Result<identity::KeyPair, ClientCoreError> {
|
|
||||||
let identity_keypair: identity::KeyPair =
|
|
||||||
nym_pemstore::load_keypair(&nym_pemstore::KeyPairPath::new(
|
|
||||||
pathfinder.private_identity_key().to_owned(),
|
|
||||||
pathfinder.public_identity_key().to_owned(),
|
|
||||||
))
|
|
||||||
.tap_err(|_| log::error!("Failed to read stored identity key files"))?;
|
|
||||||
Ok(identity_keypair)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn load_sphinx_keys(
|
|
||||||
pathfinder: &ClientKeyPathfinder,
|
|
||||||
) -> Result<encryption::KeyPair, ClientCoreError> {
|
|
||||||
let sphinx_keypair: encryption::KeyPair =
|
|
||||||
nym_pemstore::load_keypair(&nym_pemstore::KeyPairPath::new(
|
|
||||||
pathfinder.private_encryption_key().to_owned(),
|
|
||||||
pathfinder.public_encryption_key().to_owned(),
|
|
||||||
))
|
|
||||||
.tap_err(|_| log::error!("Failed to read stored sphinx key files"))?;
|
|
||||||
Ok(sphinx_keypair)
|
|
||||||
}
|
|
||||||
|
|
||||||
let pathfinder = ClientKeyPathfinder::new_from_config(config);
|
|
||||||
let identity_keypair = load_identity_keys(&pathfinder)?;
|
|
||||||
let sphinx_keypair = load_sphinx_keys(&pathfinder)?;
|
|
||||||
|
|
||||||
let client_recipient = Recipient::new(
|
|
||||||
*identity_keypair.public_key(),
|
|
||||||
*sphinx_keypair.public_key(),
|
|
||||||
// TODO: below only works under assumption that gateway address == gateway id
|
|
||||||
// (which currently is true)
|
|
||||||
NodeIdentity::from_base58_string(config.get_gateway_id())?,
|
|
||||||
);
|
|
||||||
|
|
||||||
Ok(client_recipient)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn output_to_json<T: Serialize>(init_results: &T, output_file: &str) {
|
|
||||||
match std::fs::File::create(output_file) {
|
|
||||||
Ok(file) => match serde_json::to_writer_pretty(file, init_results) {
|
|
||||||
Ok(_) => println!("Saved: {output_file}"),
|
|
||||||
Err(err) => eprintln!("Could not save {output_file}: {err}"),
|
|
||||||
},
|
|
||||||
Err(err) => eprintln!("Could not save {output_file}: {err}"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "credential"
|
|
||||||
version = "0.1.0"
|
|
||||||
edition = "2021"
|
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
bip39 = "1.0.1"
|
|
||||||
clap = { version = "4.0", features = ["cargo", "derive"] }
|
|
||||||
log = "0.4"
|
|
||||||
rand = "0.7.3"
|
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
|
||||||
thiserror = "1.0"
|
|
||||||
url = "2.2"
|
|
||||||
tokio = { version = "1.24.1", features = ["rt-multi-thread", "net", "signal", "macros"] } # async runtime
|
|
||||||
|
|
||||||
coconut-interface = { path = "../../common/coconut-interface" }
|
|
||||||
nym-config = { path = "../../common/config" }
|
|
||||||
credentials = { path = "../../common/credentials" }
|
|
||||||
credential-storage = { path = "../../common/credential-storage" }
|
|
||||||
nym-crypto = { path = "../../common/crypto", features = ["rand", "asymmetric", "symmetric", "aes", "hashing"] }
|
|
||||||
nym-bin-common = { path = "../../common/bin-common"}
|
|
||||||
nym-network-defaults = { path = "../../common/network-defaults" }
|
|
||||||
nym-pemstore = { path = "../../common/pemstore" }
|
|
||||||
validator-client = { path = "../../common/client-libs/validator-client", features = ["nyxd-client"] }
|
|
||||||
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
use crate::error::Result;
|
|
||||||
use bip39::Mnemonic;
|
|
||||||
use nym_network_defaults::{NymNetworkDetails, VOUCHER_INFO};
|
|
||||||
use std::str::FromStr;
|
|
||||||
use url::Url;
|
|
||||||
use validator_client::nyxd;
|
|
||||||
use validator_client::nyxd::traits::CoconutBandwidthSigningClient;
|
|
||||||
use validator_client::nyxd::{Coin, Fee, NyxdClient, SigningNyxdClient};
|
|
||||||
|
|
||||||
pub(crate) struct Client {
|
|
||||||
nyxd_client: NyxdClient<SigningNyxdClient>,
|
|
||||||
mix_denom_base: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Client {
|
|
||||||
pub fn new(nyxd_url: &str, mnemonic: &str) -> Self {
|
|
||||||
let nyxd_url = Url::from_str(nyxd_url).unwrap();
|
|
||||||
let mnemonic = Mnemonic::from_str(mnemonic).unwrap();
|
|
||||||
let network_details = NymNetworkDetails::new_from_env();
|
|
||||||
let config = nyxd::Config::try_from_nym_network_details(&network_details)
|
|
||||||
.expect("failed to construct valid validator client config with the provided network");
|
|
||||||
let nyxd_client =
|
|
||||||
NyxdClient::connect_with_mnemonic(config, nyxd_url.as_ref(), mnemonic, None).unwrap();
|
|
||||||
|
|
||||||
Client {
|
|
||||||
nyxd_client,
|
|
||||||
mix_denom_base: network_details.chain_details.mix_denom.base,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn deposit(
|
|
||||||
&self,
|
|
||||||
amount: u64,
|
|
||||||
verification_key: String,
|
|
||||||
encryption_key: String,
|
|
||||||
fee: Option<Fee>,
|
|
||||||
) -> Result<String> {
|
|
||||||
let amount = Coin::new(amount as u128, self.mix_denom_base.clone());
|
|
||||||
Ok(self
|
|
||||||
.nyxd_client
|
|
||||||
.deposit(
|
|
||||||
amount,
|
|
||||||
String::from(VOUCHER_INFO),
|
|
||||||
verification_key,
|
|
||||||
encryption_key,
|
|
||||||
fee,
|
|
||||||
)
|
|
||||||
.await?
|
|
||||||
.transaction_hash
|
|
||||||
.to_string())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,165 +0,0 @@
|
|||||||
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
use clap::{ArgGroup, Args, Subcommand};
|
|
||||||
use log::*;
|
|
||||||
use nym_bin_common::completions::ArgShell;
|
|
||||||
use rand::rngs::OsRng;
|
|
||||||
use std::str::FromStr;
|
|
||||||
|
|
||||||
use coconut_interface::{Base58, Parameters};
|
|
||||||
use credential_storage::storage::Storage;
|
|
||||||
use credential_storage::PersistentStorage;
|
|
||||||
use credentials::coconut::bandwidth::{BandwidthVoucher, TOTAL_ATTRIBUTES};
|
|
||||||
use credentials::coconut::utils::obtain_aggregate_signature;
|
|
||||||
use nym_crypto::asymmetric::{encryption, identity};
|
|
||||||
use nym_network_defaults::VOUCHER_INFO;
|
|
||||||
use validator_client::nyxd::traits::DkgQueryClient;
|
|
||||||
use validator_client::nyxd::tx::Hash;
|
|
||||||
use validator_client::nyxd::CosmWasmClient;
|
|
||||||
use validator_client::CoconutApiClient;
|
|
||||||
|
|
||||||
use crate::client::Client;
|
|
||||||
use crate::error::{CredentialClientError, Result};
|
|
||||||
use crate::recovery_storage::RecoveryStorage;
|
|
||||||
use crate::state::{KeyPair, State};
|
|
||||||
|
|
||||||
#[derive(Subcommand)]
|
|
||||||
pub(crate) enum Command {
|
|
||||||
/// Run the binary to obtain a credential
|
|
||||||
Run(Run),
|
|
||||||
|
|
||||||
/// Generate shell completions
|
|
||||||
Completions(ArgShell),
|
|
||||||
|
|
||||||
/// Generate Fig specification
|
|
||||||
GenerateFigSpec,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Args)]
|
|
||||||
#[clap(group(
|
|
||||||
ArgGroup::new("recov")
|
|
||||||
.required(true)
|
|
||||||
.args(&["amount", "recovery_mode"]),
|
|
||||||
))]
|
|
||||||
pub(crate) struct Run {
|
|
||||||
/// Home directory of the client that is supposed to use the credential.
|
|
||||||
#[clap(long)]
|
|
||||||
pub(crate) client_home_directory: std::path::PathBuf,
|
|
||||||
|
|
||||||
/// The nyxd URL that should be used
|
|
||||||
#[clap(long)]
|
|
||||||
pub(crate) nyxd_url: String,
|
|
||||||
|
|
||||||
/// A mnemonic for the account that buys the credential
|
|
||||||
#[clap(long)]
|
|
||||||
pub(crate) mnemonic: String,
|
|
||||||
|
|
||||||
/// The amount of utokens the credential will hold. If recovery mode is enabled, this value
|
|
||||||
/// is not needed
|
|
||||||
#[clap(long, default_value = "0")]
|
|
||||||
pub(crate) amount: u64,
|
|
||||||
|
|
||||||
/// Path to a directory used to store recovery files for unconsumed deposits
|
|
||||||
#[clap(long)]
|
|
||||||
pub(crate) recovery_dir: std::path::PathBuf,
|
|
||||||
|
|
||||||
/// Recovery mode, when enabled, tries to recover any deposit data dumped in recovery_dir
|
|
||||||
#[clap(long)]
|
|
||||||
pub(crate) recovery_mode: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) async fn deposit(nyxd_url: &str, mnemonic: &str, amount: u64) -> Result<State> {
|
|
||||||
let mut rng = OsRng;
|
|
||||||
let signing_keypair = KeyPair::from(identity::KeyPair::new(&mut rng));
|
|
||||||
let encryption_keypair = KeyPair::from(encryption::KeyPair::new(&mut rng));
|
|
||||||
let params = Parameters::new(TOTAL_ATTRIBUTES).unwrap();
|
|
||||||
|
|
||||||
let client = Client::new(nyxd_url, mnemonic);
|
|
||||||
let tx_hash = client
|
|
||||||
.deposit(
|
|
||||||
amount,
|
|
||||||
signing_keypair.public_key.clone(),
|
|
||||||
encryption_keypair.public_key.clone(),
|
|
||||||
None,
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
let voucher = BandwidthVoucher::new(
|
|
||||||
¶ms,
|
|
||||||
amount.to_string(),
|
|
||||||
VOUCHER_INFO.to_string(),
|
|
||||||
Hash::from_str(&tx_hash).map_err(|_| CredentialClientError::InvalidTxHash)?,
|
|
||||||
identity::PrivateKey::from_base58_string(&signing_keypair.private_key)?,
|
|
||||||
encryption::PrivateKey::from_base58_string(&encryption_keypair.private_key)?,
|
|
||||||
);
|
|
||||||
|
|
||||||
let state = State { voucher, params };
|
|
||||||
|
|
||||||
Ok(state)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) async fn get_credential<C: Clone + CosmWasmClient + Send + Sync>(
|
|
||||||
state: &State,
|
|
||||||
client: validator_client::Client<C>,
|
|
||||||
shared_storage: PersistentStorage,
|
|
||||||
) -> Result<()> {
|
|
||||||
let epoch_id = client.nyxd.get_current_epoch().await?.epoch_id;
|
|
||||||
let threshold = client
|
|
||||||
.nyxd
|
|
||||||
.get_current_epoch_threshold()
|
|
||||||
.await?
|
|
||||||
.ok_or(CredentialClientError::NoThreshold)?;
|
|
||||||
let coconut_api_clients = CoconutApiClient::all_coconut_api_clients(&client, epoch_id).await?;
|
|
||||||
|
|
||||||
let signature = obtain_aggregate_signature(
|
|
||||||
&state.params,
|
|
||||||
&state.voucher,
|
|
||||||
&coconut_api_clients,
|
|
||||||
threshold,
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
info!("Signature: {:?}", signature.to_bs58());
|
|
||||||
shared_storage
|
|
||||||
.insert_coconut_credential(
|
|
||||||
state.voucher.get_voucher_value(),
|
|
||||||
VOUCHER_INFO.to_string(),
|
|
||||||
state.voucher.get_private_attributes()[0].to_bs58(),
|
|
||||||
state.voucher.get_private_attributes()[1].to_bs58(),
|
|
||||||
signature.to_bs58(),
|
|
||||||
epoch_id.to_string(),
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) async fn recover_credentials<C: Clone + CosmWasmClient + Send + Sync>(
|
|
||||||
client: validator_client::Client<C>,
|
|
||||||
recovery_storage: &RecoveryStorage,
|
|
||||||
shared_storage: PersistentStorage,
|
|
||||||
) -> Result<()> {
|
|
||||||
for voucher in recovery_storage.unconsumed_vouchers()? {
|
|
||||||
let state = State {
|
|
||||||
voucher,
|
|
||||||
params: Parameters::new(TOTAL_ATTRIBUTES).unwrap(),
|
|
||||||
};
|
|
||||||
if let Err(e) = get_credential(&state, client.clone(), shared_storage.clone()).await {
|
|
||||||
error!(
|
|
||||||
"Could not recover deposit {} due to {:?}, try again later",
|
|
||||||
state.voucher.tx_hash(),
|
|
||||||
e
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
info!(
|
|
||||||
"Converted deposit {} to a credential, removing recovery data for it",
|
|
||||||
state.voucher.tx_hash()
|
|
||||||
);
|
|
||||||
if let Err(e) = recovery_storage.remove_voucher(state.voucher.tx_hash().to_string()) {
|
|
||||||
warn!("Could not remove recovery data - {:?}", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
use std::time::SystemTimeError;
|
|
||||||
use thiserror::Error;
|
|
||||||
|
|
||||||
use credential_storage::error::StorageError;
|
|
||||||
use credentials::error::Error as CredentialError;
|
|
||||||
use nym_crypto::asymmetric::encryption::KeyRecoveryError;
|
|
||||||
use nym_crypto::asymmetric::identity::Ed25519RecoveryError;
|
|
||||||
use validator_client::nyxd::error::NyxdError;
|
|
||||||
use validator_client::ValidatorClientError;
|
|
||||||
|
|
||||||
pub type Result<T> = std::result::Result<T, CredentialClientError>;
|
|
||||||
|
|
||||||
#[derive(Error, Debug)]
|
|
||||||
pub enum CredentialClientError {
|
|
||||||
#[error("IO error: {0}")]
|
|
||||||
IOError(#[from] std::io::Error),
|
|
||||||
|
|
||||||
#[error("Nyxd error: {0}")]
|
|
||||||
Nyxd(#[from] NyxdError),
|
|
||||||
|
|
||||||
#[error("Validator client error: {0}")]
|
|
||||||
ValidatorClientError(#[from] ValidatorClientError),
|
|
||||||
|
|
||||||
#[error("Credential error: {0}")]
|
|
||||||
Credential(#[from] CredentialError),
|
|
||||||
|
|
||||||
#[error("The tx hash provided is not valid")]
|
|
||||||
InvalidTxHash,
|
|
||||||
|
|
||||||
#[error("Could not parse Ed25519 data")]
|
|
||||||
Ed25519ParseError(#[from] Ed25519RecoveryError),
|
|
||||||
|
|
||||||
#[error("Could not parse X25519 data")]
|
|
||||||
X25519ParseError(#[from] KeyRecoveryError),
|
|
||||||
|
|
||||||
#[error("Could not use shared storage")]
|
|
||||||
SharedStorageError(#[from] StorageError),
|
|
||||||
|
|
||||||
#[error("Could not get system time")]
|
|
||||||
SysTimeError(#[from] SystemTimeError),
|
|
||||||
|
|
||||||
#[error("Threshold not set yet")]
|
|
||||||
NoThreshold,
|
|
||||||
}
|
|
||||||
@@ -1,109 +0,0 @@
|
|||||||
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
mod client;
|
|
||||||
mod commands;
|
|
||||||
mod error;
|
|
||||||
mod recovery_storage;
|
|
||||||
mod state;
|
|
||||||
|
|
||||||
use commands::*;
|
|
||||||
use error::Result;
|
|
||||||
use log::*;
|
|
||||||
use nym_bin_common::completions::fig_generate;
|
|
||||||
use nym_config::{DATA_DIR, DB_FILE_NAME};
|
|
||||||
use nym_network_defaults::{setup_env, NymNetworkDetails};
|
|
||||||
use std::process::exit;
|
|
||||||
use std::time::{Duration, SystemTime};
|
|
||||||
|
|
||||||
use clap::{CommandFactory, Parser};
|
|
||||||
use nym_bin_common::logging::setup_logging;
|
|
||||||
use validator_client::nyxd::traits::DkgQueryClient;
|
|
||||||
use validator_client::nyxd::CosmWasmClient;
|
|
||||||
use validator_client::Config;
|
|
||||||
|
|
||||||
const SAFETY_BUFFER_SECS: u64 = 60; // 1 minute
|
|
||||||
|
|
||||||
#[derive(Parser)]
|
|
||||||
#[clap(author = "Nymtech", version, about)]
|
|
||||||
struct Cli {
|
|
||||||
/// Path pointing to an env file that configures the client.
|
|
||||||
#[clap(short, long)]
|
|
||||||
pub(crate) config_env_file: Option<std::path::PathBuf>,
|
|
||||||
|
|
||||||
#[clap(subcommand)]
|
|
||||||
pub(crate) command: Command,
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn block_until_coconut_is_available<C: Clone + CosmWasmClient + Send + Sync>(
|
|
||||||
client: &validator_client::Client<C>,
|
|
||||||
) -> Result<()> {
|
|
||||||
loop {
|
|
||||||
let epoch = client.nyxd.get_current_epoch().await?;
|
|
||||||
let current_timestamp_secs = SystemTime::now()
|
|
||||||
.duration_since(SystemTime::UNIX_EPOCH)?
|
|
||||||
.as_secs();
|
|
||||||
if epoch.state.is_final() {
|
|
||||||
if current_timestamp_secs + SAFETY_BUFFER_SECS >= epoch.finish_timestamp.seconds() {
|
|
||||||
info!("In the next {} minute(s), a transition will take place in the coconut system. Deposits should be halted in this time for safety reasons.", SAFETY_BUFFER_SECS / 60);
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
// Use 20 additional seconds to avoid the exact moment of going into the final epoch state
|
|
||||||
let secs_until_final = epoch.final_timestamp_secs() + 20 - current_timestamp_secs;
|
|
||||||
info!("Approximately {} seconds until coconut is available. Sleeping until then. You can safely kill the process at any moment.", secs_until_final);
|
|
||||||
std::thread::sleep(Duration::from_secs(secs_until_final));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tokio::main]
|
|
||||||
async fn main() -> Result<()> {
|
|
||||||
let args = Cli::parse();
|
|
||||||
setup_logging();
|
|
||||||
setup_env(args.config_env_file.as_ref());
|
|
||||||
let bin_name = "nym-credential-client";
|
|
||||||
|
|
||||||
match args.command {
|
|
||||||
Command::Run(r) => {
|
|
||||||
let db_path = r.client_home_directory.join(DATA_DIR).join(DB_FILE_NAME);
|
|
||||||
let shared_storage = credential_storage::initialise_storage(db_path).await;
|
|
||||||
let recovery_storage = recovery_storage::RecoveryStorage::new(r.recovery_dir)?;
|
|
||||||
|
|
||||||
let network_details = NymNetworkDetails::new_from_env();
|
|
||||||
let config = Config::try_from_nym_network_details(&network_details)?;
|
|
||||||
let client = validator_client::Client::new_query(config)?;
|
|
||||||
|
|
||||||
block_until_coconut_is_available(&client).await?;
|
|
||||||
info!("Starting depositing funds, don't kill the process");
|
|
||||||
|
|
||||||
if !r.recovery_mode {
|
|
||||||
let state = deposit(&r.nyxd_url, &r.mnemonic, r.amount).await?;
|
|
||||||
if get_credential(&state, client, shared_storage)
|
|
||||||
.await
|
|
||||||
.is_err()
|
|
||||||
{
|
|
||||||
warn!("Failed to obtain credential. Dumping recovery data.",);
|
|
||||||
match recovery_storage.insert_voucher(&state.voucher) {
|
|
||||||
Ok(file_path) => {
|
|
||||||
warn!("Dumped recovery data to {:?}. Try using recovery mode to convert it to a credential", file_path);
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
error!("Could not dump recovery data to file system due to {:?}, the deposit will be lost!", e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
recover_credentials(client, &recovery_storage, shared_storage).await?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Command::Completions(c) => c.generate(&mut crate::Cli::command(), bin_name),
|
|
||||||
Command::GenerateFigSpec => fig_generate(&mut crate::Cli::command(), bin_name),
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user