From e51243883f2f06c77a26ffa4ecc86149db4c44d6 Mon Sep 17 00:00:00 2001 From: Aayush Gautam Date: Thu, 30 Nov 2023 02:33:29 +0800 Subject: [PATCH 1/2] docs: add a draft readme with instructions to install cli --- README2.md | 97 ++++++++++++++++++++++++++++++++++++++ services_relationship.png | Bin 0 -> 40746 bytes 2 files changed, 97 insertions(+) create mode 100644 README2.md create mode 100644 services_relationship.png diff --git a/README2.md b/README2.md new file mode 100644 index 0000000..5b4def3 --- /dev/null +++ b/README2.md @@ -0,0 +1,97 @@ +# RockX DKG CLI + +- [RockX DKG CLI](#rockx-dkg-cli) + - [Overview](#overview) + - [DKG CLI](#dkg-cli) + - [Pre-built binary](#pre-built-binary) + - [Downloads](#downloads) + - [Installation](#installation) + - [Build from source](#build-from-source) + +## Overview + +This CLI utility helps user to perform DKG based on FROST (Flexible Round-Optimized Schnorr Threshold) signature scheme. Unlike single-party signatures, threshold signatures involve multiple participants, each possessing a private key share. FROST reduces network overhead and supports efficient signing with two-round or single-round options while retaining genuine threshold signing capabilities. It can identify and exclude misbehaving participants, making it well-suited for practical MPC deployments. FROST ensures security against chosen-message attacks, assuming the hardness of the discrete logarithm problem and control by adversaries over fewer participants than the threshold. + +This repository contains three primary services. SSV operators will execute the DKG Node service, while users creating validator keys on their local machines will utilize the CLI tool. Detailed instructions for building and running both the DKG Node and CLI services are provided in subsequent sections. Additionally, the repository includes a messenger service, serving as a communication layer connecting all DKG nodes for message exchange. RockX will host the messenger service for DKG usage in the SSV platform. If you prefer to run your own messenger service locally or as a Docker container, instructions for doing so are also available in a later section. Here's a brief overview of each service: + +| Service Name | Description | +| ------------ | ----------- | +| `rockx-dkg-cli`| A CLI utility for users to initiate DKG ceremony for keygen/resharing and generate files for DKG result, Deposit Data and SSV Keyshares | +| `rockx-dkg-node`| This is the core service run by each operator to participate in DKG ceremony | +| `rockx-dkg-messenger`| This is the communication layer enabling DKG Nodes to broadcase protocol messages to each other| + +The relationship between these services can be summarized in the following diagram + +![](/services_relationship.png) + +## DKG CLI + +### Pre-built binary + +#### Downloads +|Version|Link| os|arch| +|-------|----|---|----| +|0.2.7| https://github.com/RockX-SG/rockx-dkg-cli/releases/download/v0.2.7/rockx-dkg-cli.0.2.7.darwin.arm64.tar.gz | darwin| arm64| +|0.2.7| https://github.com/RockX-SG/rockx-dkg-cli/releases/download/v0.2.7/rockx-dkg-cli.0.2.7.linux.amd64.tar.gz | linux| amd64| + +#### Installation +1. Download the latest version of the cli tool from above links as per your system. The command for linux with amd64 architecture will be as follows: + +``` +wget https://github.com/RockX-SG/rockx-dkg-cli/releases/download/v0.2.7/rockx-dkg-cli.0.2.7.linux.amd64.tar.gz +``` +2. Extract the CLI tool + +``` +tar -xzvf rockx-dkg-cli.0.2.7.linux.amd64.tar.gz +``` +3. Move the downloaded binary to your PATH + +``` +cp ./rockx-dkg-cli /usr/local/bin +``` +> use sudo to run this command as root if you get permission denied error + +4. Configure Messenger Service Endpoint + +The default messenger address is preconfigured as https://dkg-messenger.rockx.com. If you're using this tool within the SSV platform, you can simply proceed without modifying the following environment variable. However, if you are hosting your own instance of the messenger service or running it locally on your machine (localhost), you have the option to set the following variable to specify the correct address for the messenger service configuration. +``` +export MESSENGER_SRV_ADDR=https://dkg-messenger.rockx.com +``` + +5. Configure logging directory + +The debug logs will be stored in the current directory. You can configure a custom path for logging by setting the following environment variable. Please note that you specify a location where this service has permission to create and write to a file. + +``` +export DKG_LOG_PATH=. +``` +6. + +### Build from source + +**Prerequisites** +1. Go 1.19 +2. Docker (version 20 or later) +3. Docker Comose (1.29 or later) + +To install the cli tool from source, clone this repository and run the following command + +``` +make build +``` + +The cli binary will be created at `./build/bin/rockx-dkg-cli`. You can add it to your PATH to access it directly by running + +``` +cd ./build/bin +export PATH=$PATH:`pwd` +``` +If you are running the example set of services (see [Examples](#example)) locally including the messenger service then make sure to set the following env variables + +``` +export MESSENGER_SRV_ADDR=http://0.0.0.0:3000 +export USE_HARDCODED_OPERATORS=true +``` + +We employ Docker Compose to establish seven DKG nodes running locally, spanning from localhost:8081 to localhost:8087. Simultaneously, we set up a messenger node locally at localhost:3000. It's important to note that this configuration does not establish a connection to SSV's Operator Registry and utilizes a predefined set of operator keys hardcoded into the setup. The key shares generated through this configuration are solely intended for demonstration purposes. his configuration is designed for your local exploration and debugging of the DKG solution. In a production environment, there is no need to set the `USE_HARDCODED_OPERATORS` environment variable as it is already set to `false`` by default. \ No newline at end of file diff --git a/services_relationship.png b/services_relationship.png new file mode 100644 index 0000000000000000000000000000000000000000..48ab8a2fb0ea29db099910a63dae78111e29234b GIT binary patch literal 40746 zcmeEu2|Sfs+rFfzgi2+|P$CJjg~B#uEaOJT3>$l!?J^G`DNZ73FoxKf=V6nCB1%Z+ zDKyF~u_>be{h)I??|Fywec$`O-+R9Q`Bm~v>silQ_gd?|uj{(kWi1Wmt(#dkQ&3QB zJ)xqYO+i5!0{?cM5&&-aW_Q1A!2DjK*tdg5&za1`7k@~gjb zql9b-F0R}n3fw3Z_RJYUD_g9!GuF{X&eroE#4+HooEMz7uY9@XVew90O#sQ~~vrx5#+9-*Nhzp8{!D(Jq6zi z(F5VQ#qI=1>X?l@-`TY}Tt$D;&=1w~gcxO$zzt)8{Qx!YR83sKx6 zirhkSP%!dWM1HL);lK$C6Y_=uU1+X+h{MN4l5-4h~z zS=#q99X*wuv1e@5305l&XXUwCtgzTo@zp}DyjIT~6FIti!rJ-!d)8iyoY1lLUaOEW zR2FFqYd2dfoXc8itEXHE1P52!GrvA*NpNz)S+4c(T8UU^XM)GCZ^IKD*1m4-o-^>_ zzbYL$p<{`4`0ZJJTPs&E5X2&nimp`;xmyKiYi;xW&B8)!R~)h5Z(cj$VuQ6Jc&t9Z za_YxkS#8Jft?5i4KzToO+K-pN-{j~ik8?n*^m{w5y$6ixzy9pct>OIhAo-sZC#Ios z!bn`@C{|rm1h4OUQU#@DEdbq#^r(xg*Z0Q7SwUN`9TJ>fZ3xx`C#-|wFK3TC6WpAv zR>nA3?(tvlQ6mt}KvN3CNjsdYtJj+0VBK5^aLUHj(P8Z>e2%l10URLDuN)X62QXUJ z4iykn{rRE-Vy4K^YF&{E!U;I|D-E=E%7x(O48v^YuD|--YxlWgovmT+`rG#%LEicI zd;OQbSH{6)0-pvA>Wp*1y4t$`x}w-MySM)NzTa2&FK^Hyz?2BZuMK69?S#iAn?+shwwdK?u>)^JwnQUbv9Di}mX8`U{g#!&-n-`YW#h>tJh*_|BHl zpEzf@2JW=0EqHx$YZn}Ct*j6)<+wA>#nu~ZvEs2He!&@JRa{wHMUQifD!`f5cOnJg zzI(l^r`BB3wTI!{+Jboo`-_wHS0~(6)BbOC-P-#FgapNotxa$LV&~xd;!nWiUA_lq zf0T7!c*WuRcRQr3w()OuEQMD*@BfB9{Y#8T&e<7@xUJt!XKh6N&P8g~)A+^T_zN#p z`1`W3=B0{$566D5QT}_%U-4#E8{+qM%m1#2EWCy-{4nP#BcokNK~))kYU5no9AHvJ zi8(-gbKJriezQh?Q^q;roUyJ545ENLLvUG{rWICB{GD4>ab6HB!^FEfRQ~X@`N}l& z`?~p84%jcV`O5f339Z@m+5-458Jv!u-v`w9;rWN0*;g&+2XmEIJMkN9`Zc!TVPorx z(>a4(3FSQi%mVxU0Y_LX@wcn|kE{7g&;0j$`Y$4Ek?(Vt$1lK>@OLM|<_FM8>@Onm zA7g&x{(p=ItxPZf#E^PzW&NQ8R%Z$gzz1P6ShMFJM)rSPUx<8f)bDV|k+nwt<8{Vw zC+}Z%#@cl9N9qh=kw0u_tVH7|p}#dURsi;2xupMrBV)~=)<(w9z~CQmWUO%$f2%Wo z8z20~cgB(L)7BraGZ1nB{{Fl90Z&_313&^0CIJV(8^Z5v>;N47LJlAYh{6BN6#V=U zLNKg6g_M9C{PNJs(f6lTzwVzB_^l1Vf5<5Oe-!wMeK&lhxuL0rzaRf&_vhCkAKd@P z3CvKxT`v#=)A<*3YJbErvo@LkIc8vrU5hOLa?Jcp>HXgxGrwKd{~R-ao%vgHR{tC` ze|yY`99;`V{%?<&HIL(mAo0&J^Vi4BT1@fhnEBgd=E$-CAI8k8^Zlz(UmfS-f^)J4 z#_=yBo&UJN^1Hfc&7Btge*8mRDf+z||Ff}3)SABMhbSLpWmqdqEa*#tHHJPxG=P8E zBf#b&6vht_@IR9@MuciWEF%Oq5_!6~Iuq=1@&pG0kkJZG1Sf=g21TsHUz}R4qWjF|Iqb618_ff{rCI6GY9_)7``y2AeHHpvMQ{U9fvy>YYMDbeGTwca4WBFoyMi$(zqUH^UJ`FsBo-9-MngGN=~+ zkWkb-Gbu7Sc5r?_scWqG5e{1zMX=~Nb@{%ZD&#P{-4W8XIvL*k@7CJXyp|vWss?aLUODX zPyGC1t%HX*zK)%^CATmpX@8~ zsxRsrybUJ=#f}`&Wu>SHmZgF(pyCgKBHkb1B>oh^oA-R!*wk^vkOiuJ23=(YB5KY%=d|NRdL5e;hhKuciU7GCb6Y~(Gu#6AySn8F3+#NXZFM&sL% zbGX9ZA3pJKyxPEAR6#jSP&Hl4J>Zv zNkHRvh@4-Rr=V;+dWx4?C}ijMxZIL0aJt<5?shOaek!5uI833R%!|^O3$5jINRRrb zw$rSmVT4kXAHE^&bDeeEus=lh&L*(Vkrf*oIb1vVwT^{_#avq(KH>Ui)za(G@jUXX zwa|*&pcO;Xjm9jM23L$#fr6;Qj{bn&E>?4a|Q>Qrwcg-FOm^G%k$6akbwcrzoSg|HWV=X$J5 zKEJur=h~+JA^Blm)w12f+YVD7*Ua>V66L{+^^`jD6vU&V?f0m`$OP6M=9>QUA+hi4 zOtZ|kC!(DOHCK zF<_!}(C_siDN8w=-Tlk^sJ_!KO`?}I>|8nxtx5W(UbXmG+tiOUU1t9M5^kebX1?TG zP11|wIh}Kb4T43~9Oqs*l~0uD4eA{7oUYy7$6wTFu{c>yn5}Rud!#y8^7v^5!_ytm zZwc+3yJ%!N4+d=GQtBp#OWXM_%-R;P9p*~vsoJp1;9<~KR{Wvt{0kK`&n3ldUU1&{ za(^h+-eIa@zT{CLbzl8~LNNnU=hnS`~{D*jP;cgOlpR4`|XsbFYPwX zzollBA)eJTO4tV){`fHynQvcRgj`7W3nOXbdDkS7J=4=;%D{q8{h+{Fr)> zo=8IM!LOeh4%b+dbJ;vzwnUzGJ^@RC5=XqiKCqH)r?~J?VRb6Iq7d~%8O(LrVQ;{! z30b-K?T$t#_taF(^)`UziW#4Iw88P}v7!6}iRTKZKR$KubKH&JF6xu6D&k728XH7; zjOCP?nh@_TjAr%iyTZR6zdp*?sjM!=n)$)&n&3ViP4v#mtO>K5dpoqr4`!aTs$~h1 z^0GXp22vLWeCPYmL@Uv^y(nBbziz$5;za2a-jajHWz3X4U>x{{#Lm51QL;0JoI+o= zfAq97P*rXAczISin$*@zn&l^co^8|YYZPhT6Y1J~^lfN9e|DC2bAo#_dj7~HwtYZ8 z-fwxbe5$&#ww}3mvcH_VrYp}(rhF{7ygKv_Uf4}YN%h%>M1MaUdAE@l_30R5wOV#$ zxkooP_+ybvGg_QUpRKZm7CU4A>S2KUs{rbu=e!H}9XWEG0s-w+c|sw!WTHEb+Rk-( zhB+CVbE(8TMBaGCU~ax{EzFI)5yydVL47=NAl~Y5UXcB-op@?xZA|F zMG2SS`DT-`{}MUPhOy%+Z3^DN?V*AaCfK5w;5_^yDXCJ}vhHF@<+tU<{QbE*I*dMb za?49Py}W0>5xRaRUlUW5c;D2Q+>sxS5xGVdj7(4!x;A`#h)SyRkWffWgBk@x^v&~6 zUghz5OysrgrJpEoyG3SK6j&O4JPid{!i0l6n*ZsgOY^1oABL1LbsFI>TFB!?%|YnP zD6g!X5~F*0^1*bk?-pseRec$X(>W57soc;gk)N!pgrPny_VSE;`TT%SO(6+?*zLLz z*%Zvgz2B|tQbmZw*__2r6OVp#0~}5Bu@AR}8os=cr|*e0cCtNO_0_q1>L*P0s10#2 zW0U7OeRD>gER`jO=*^Vuf&P5ee6<3kp2yjm=q{hD7Nt)8_8UNAMR!P%mBaXuDf{{}0$SKLjVprG4b{+HXOk}NvOA5>B`c<-yWLUr*)xV7FGnv*k=%q!QX}`wzmHfc zeI{K>_*4SYS5ohGQ9P`C852V&iY%eyYX)x%Uj(O$UdyYU5EoPwEh z_mNw-SDwDnpt7FfrvtBqKffhr*0JRuE(Q0<$v3N0GW=W}ubx2GFkvr^C++g_^G`Wd zx~(bt3r@_sT~ybp-{kpDL`k?T^aw?OCw!TVbf(?Qb&Jkpp?|*o&u0J6FgQk^T<0A& zHa5H-)FUQ1nw9C|&js6jy42M<%4YiXG-Us)DL%CP=tI8bz7m>nZe15XwK>#+Wg>kirQ<#rJ$;Ov;@|~?GxD1`G+1)w zHH>lRpLlFgD(F6Te3qLV9#IXs>Ldq`q|>ezhHJfib=PHNsBWjXSP6mx9P|=}Laf-S zoK+}@(efCYO~?zLuYQROkHl+PS*Wng-IW;XPWS5MUHg1n^5KK)!XKGwySi>c9{BUq z|LpZY4gUZ7Sa+O^>~^^oCo3;6UnZ$C#V5Zqc^SmGCKDBr8S2X88WFv2pVm3T7T=|q zHVX+#_Aj9rwKNV3?G@kazDIz zcZ=yb5;n*AFMl~OTEk+WjaA-r_TmJf=;z2T_^693o}M+_ItAixIuI-8u~?0Cp&d!9xW7mE2`ksu3^I zqi^PmD{7YZ$tp8-@4?MMT+-`U+TS_qQ~CML7Ri}Lk%`*fX2n~@x*xg^cv&06J;uKN z##_8c`Z|x6aZu*$T^VhiymHJmM|Z#nJU4l!=)$EGny<{^+rBV6(qFnRLl>Ed44pP{POO`1Rw)+)17L`lRW@9O$2lJ z<=@gXs@FSxRH&Ctz9W1N3^|GT0i?->^jbH z#KU4=oY>a3U6mhe`Q$38(s!{_G}Lt5{ujiiVC+DGXR?XU1PPm(pMe?g$kG>zm>=}7 z$|-s-k@U4g-^>xJe9!mu>);(tR9E*LL$$Y5`TNJ6tz$k=%_maUp=aE4O5X%Ws31oQ zklM9xFex%OzP&0b_?T1PyPi9$yL!vvJ&`duA;P`a8;uHYX=cmt23520$`>1{kZDpS;b-4* zV*B;bMkQ9q_HI3wn&H|?ZsO;sT;bh3aSq#QyP?_H@roZHNXrF|05W;1a z@AaRXX)1vTKRDX&>+}<$nv8Cz3bLLt;DV0Nk9|18Y}DkL0M1ib8-jYNp-QBjrbzDZkYkXSB4Do~aVnaKCJ_X*tX&9-RUXdl#a#aC4cK`l$6 zJw^AZwT!EzRkeBS>Ss5C3ADAkd z4+abs$sXHURE(`3zFTR83icD={=nB`U3rOsNtj@jw2Go7 zn26l(0pgM=PP&he!R=xdwbPBh+~GV=CppgG=RR5XVdLA(8ga?VdvEtY-AK2`hML{; zl|rI@r;bPxDq{4?9G`bWEZ!mIxx?r@&$Wg5ok}gnnBG9yLo}XW%`6U8^EyU&g;fKo~hwC+9*A8_eS+)tU!n9+1j1%57$v&eE$I;)M88?43O$hGykQ7EQ%y9 z`3z>g_}EBHyPw=d+#U&6n{+~Bv~W_+RMj_W{>x(uq|gLG=H9b!>o$no1287oHzanc zojjVA7vvin8{pt=yK5S3qy%ucT5_?Az{WZ~+h8|t$suHcKbg8K{<$QC6Nw%hGv2f< zOR#-K*e_*en41M{+BvxZZ;FkdxLMzJ!lJ(` zNj~^Yt6|!GK%SbQ!W~2$p3R^IK+5%ktWNim`oaFOJw`=Q5+`!J-Hv~`KbE`2XQ$g6 zqxqcj$@`D;pD`o=D2a`nNeX5!6exX(VmdzIk!^x1Hj3>`s7p<32FrHiczwfW;fO=%MKeh9YSX?wYSQNy>6Cp)@Cjm;GKpQ4qj`)hG}D+kD1O){-dkCdf%rJdD zHsL*lo%RuM*>s)y;S}lJPqq&Mc=1q-3){E;`9W5cO&!-dkzu{Pu@`;!TJ2LonBbW0 zA3x^;sla!(l679?;kg}81tq$zpCm*g;0xoWRcwd1=bGGY_D#`prJHl4*)6_n0b2Ht zZ`r#;4xzE10;&!ukg(3>nf`mqltXc{?k$g`CFhE15rUp~6~a-h52AfDtMZWc{;8jM zux2zdG}{pzCv^>-KY4qq4!vDykgD(s-CR#W8V;!+KvdHv0T}+1Vpa@k%9QvQImeG| zT0H(#;TnQvp}1GBHtN1PCq5Z*{tM4F6W9Fat7riPv*O*n3P52B_XZw?f&-m)CZFiu zeVpe4Fx{Nj082u!uGH-x%Fl*VHHrs}CkOhvkJ~aMb;7KIQCF^SWqv#oah};Vi$T4* zk^!|15fKEatzz^dw~h{m`Rq5Z++?+zZM?`*vjM47$nn((^`^s9P7Nsdj`1a%?Q@r| zUFJlZ)M^!#i_Uob#pxy2x*2uO@?rBtHXoxPsFM~WCHvq`rrKmH`Hg42_nU9*=To?m zfB2#r)h1|0PMy`OYTVB~-a>B>D0>vC7stEXP)MDU8CE)S7dI>Fr?&rbH~+_UZ8q1m z|MCpSB5*Jc5sJGC46Wlu+x9;#M7pfd-^+=0&Py-28$mDM1+E(F<<7jyh0KY9C+uS0 zv%__oK6B%?umI+&%Ph@`efv6tP>j~);EC;L-lyXQ#7AG^x33@0S!qftypA|O!GJ%Q zb>8@Fpk^?3~X_K9vP%x>gbS2S*x&==&J(6LtxG3qazD`xvOu@i|tOuz}6 zdoDS3v8Sfj?FpMlG@d0~a`I@XMcrGA9$Xa3KDVq6*zoxK5lHYNSF<=(HOPMMqnxpM zzy^nuTY9nS<2}}ijtINn57c32j&W&SBAe?AIk7XZWPRS>(nomb=6h*)pfhGPwy(-i zijj$7gVMDB_6gv3#2WaEsJL2NYeOyKK9x0zhck=RMH*OK-ZdZQ2M=QjBhC#1*5J>S z=8!s#5Y`W3r`VnBQl4i%_h`y2SwW;1t{yG4j@XUAm5$)W6jTp@{;g1n>p_VAcnP<{ zEr%a45I@UMvTtJIDrh`6HBd1DekVQ86nqbTQE;o%i#u}ItcNno)AR@dShMRqP)zWB{Uh&%Hj2H+aiRhHQ)9~ef?PD4go^nSYDMA)S3#L`|a78=av3J+Zk6Y2$cL8j$10O92q3lVP+Mu9~$~$=m zbsfW#k6e%Od2{(d^;RRisb!d`!=nwmX_YV{K{t%OBQd&OOZ4aQ`*2@P{l4Ik;PC>c zoj-*(W%+|_QG`)7yY#tx9?KxvWEf+_bde;MAUw8MM>vhxJO2P;6d?2IY)KUR$ zmU2%qZAOLTp}Yr$CIDWDfqQ(ZC;8iA)wd!Thk}jl^|H^@oFLW;i?C&O&Pa*eETVPW zTjP*{4$%{=wHE?GlS){hy4pRg=go}A)&yZg4i>M)HMwFP}SI_cS7q&Qnrl15Y_=({C;eCtKPdFSAiN+#}{ed*gg>5>KDIb`O zZXyhemH=3D+a7#|o`xd1lWQH3GK3$27cMD}s7X!~M|i~gE|I(DKpqk_LDQxtqV73< zH8K{V__ew)%4|FFyU1#FH=$d(O-5JNB?qKDrdo>+Dy_q?lG;-D7JLGHhWso=BM^=xWb;rKsa*A2z+U%uwL9x0J>wH8#>w^B}q zQ}J)f(p`GUo4QZ6g5msm>HvruJ7&|KQOoN%&wWm)<4x7gf8_?N^P_Ft^c=+KJ;GaM z@1Uq=KbIo0SwR)ppRuQ4ega#z{`J&*c8BHeO_cQYlDsQ&-C$1L+$`+m-I3tg@-_@l}}rH8&>NXJMLVL zPZPgN+IfGa4RZKyefEQ|6s~k1VNohD5z^j7#c7U5g?JBSn+6z(s3B@401e#TM>Eob zcGC|>m?MRO%*gchmjblU9PPIRK+0;~t{{46riNRHfsf9?d|7h{6Mk$c+FSxBdnyVq zNLI?a$|f1hekzr@7K8|>2P|Yz5!gOZJ}mutzUmvBsq-E8*{?=g@SQsmPEgFX~=5Y>Z`No) z+IQiiA53Px9ea25X6U4u@9)@st4l|~@7v;F@V&+PDZ&mOHJZboHX|;~kG!YH6zO8W zv>!T;yT3>t+Z|ms*J~djuR8H$e?DR`!b%Y#x5z3FL-vME3MvV+FpGnuaYH!7`*Byu zpO2~$DoSTt6nAeea_xO04lvgd7WrFU?8+67WvA{(9lP1mGXEHKQQI2h z=hi*j|LkQw?P#k*ieOVhhBR|am{>0_(snMk@y8}h=9L# zkwug%Eu{@kw{4_lV!&?|mCsl@KlNZnL+C8Z3}r$pHHi0_EJN1+p!YT%`aU?jHU@HM z76P7{dXJ>!-_9+x zIHUO|tDs`3oTY$oOH=+6rBzE43X5OeU!HxEZ>`CrRpcAEaVyG~r-tios)W^J*M|yq zno)QroESAd`yP!w4M%M2w0xLxVxl+7I*sfvEd{6Dc0PI3ff%Dap|2a?+m#-p6r;{8 zwzRY`mY0}}(UmkB?aWS?-UyAlId5obJL1K{h7vj*O#Clz#}oL@R_IMR=T>!HZ9T5yPJ4G8e%t*S^(zZAp(@-9p)V^E;i0aXP+@G!xo=DJHH99IN*G7`skexqLYqAr>opWpv%Sm$OoBD=ET}DmYd)3HCPhAq z^Up=!g1OMM|1-Hv?e3ch+m8BA0qd!Qq#MRN?ajzfPXC=L?aqJ;1&QoGs*!GiKd(R93*LKD`^I4s`kb@wlAN!h4Jb? zP}DKI?HDS1fw**@3l(Dd6-=m7-Bwu7 zCAYr-5V-uAO6MG3XXZB`kE*j1Bhyc5_*)GX@7A2RN!1$48%as@g;fi?$#77Zq)L4X zc!UE8w^hS_e1g7x(9Kp%^FX?&WY=sf+98sO^i0GrRppoY~6Wv+eD5RPdKKF(ehI@8i- zrxZ}x(OyAYF^61dMsZ^}!2Q7tr)2CRM$;c;{_npi<-^~4QNI{#E$VzKy}*uFjvIRL z)Jnp}%cM@UAM*!dT1P0QZ&rp6v-d%w2c43$2-S4H6{V-5vKg{2kn;~(UMbuo7ce1+|CvFDXx9pciRW!S%O zPl(=mNG;&lCo(saB%jIqLVTy;sJi+?E)aij^byR9zv&~IooK4d zG{MO`InP56JPlnsH++q6^Q=1f$T~YdA{}rsg#CiTMfsM^4A9T=R&{>Tt|~h>EFhjR zs7Jx3gpVuI%k8U9ve^JJ_{?6^AEr63NX#8ji#AX6or@6w23f4%wXN(SLN=@WKj^g& z*VuV#aBf)A4K!yft?m5y#~vFOo%@COp8cl~-&C3ZkodlIZ@jQ!{1G)rF$ipPI_A?4 zFD=fO!c^UbsDTl%DX@%u|G_MIlzu`tc(vZ2>VK*C?7na&;c9l@Sb|-ApOTND>BQ)d%&680UdP9Q z>x}CM=3LC_@-QZ2clm>1INZs(mF?Kl+u6v3_#EK6${Xu1*vHs)A*YcbR&= z&Tr%o^s3n^-feM30M91rPCKM65|Ze*kbxjSJR-TvHl0PPQGz>2XuEdaw(JaAVr160 zFU|hF2o&^fdA`aK_)Yf{6o-9HB;>hn?OT~6f4ceU=P}%(Y{eV{Zf|-)!B9|({dlPr zBZ5HnS=~^-u&#V*uCE3_DVk<*CxzChrS$f4Th0ymOkHxm?+1{M`H)=~Nbw1ynr)yC zZ)nXN1FwSw$fM6bB5zwpj|#IEiQDoh1ou9$z)cLr5lSF^L+0@;aAZNu8ny25>AkV` zxwZ&sRsX_nCF&?dVzhI5<&Z@*9%bgYNhAqLCvmeUyoZ#6_gs~Ruab`5$UhC+1jyXR4_4`ya61ZJ{RUzm?Y@9$VVGtjMe_a0+RYN5!Msi}$_fCml02 z7wJfYT1sjSqX3fSgI>UIJJ#N}ogP3d1_au8N%z=uWGt$wSa;`I&3V4p{3-9V>@zr^ z{OU5eiJpLuUNn?kI<4A_3RwaDq-GkiC+5LyXd0^Tdjr-BgstXVcBKh)J1ycd?Vc0R zc+TrSHGpQS^jli!0SW$2JeBB`j6h){ZE3)RJ1uk08%ACK3qSxIkTr324GhSpqlvv*TAh}XSP*-q0Ley9-$0y-*;`n zV+TyWyep}BkS>O2?Au_O#g}2d>l2E|Ta$t_5jY?&19JS{8yXVzrT~te`RP4GXZh>t zj&kzL9KJuC9Oml}5S;_SGb`>l>SipqBg2+iku9X9vK|QMpoO|n<{iBYfFIUezo(&V zUvC^mn?px@O6yelWeA&?jF)k%fTR;F2NBO{9~GHPQu9TS#PHdaG(&AtMvWxF3iO1{jJvzpF!@&?#RSARz+q> zwvGRVq=?yWmZmw|?>sn3;oNFIM6Y%F-_M6ID0eM14z{*pbi1R3cMV6+bi zr_1{TQI2;xS4Jz%d#RsS%h_#Zf1M9!Y6?r1ZrjViT+{p3(TWc&q**91O;yCZSA=(c z`i^##GsI}vT>|JXL3F0l@8rW#=TPD5^u0$+_7Qq3@q53`l~!E}NAigz7lw((rxP?H zwtaQdl)EK?22vbZlTUoNXmiH4D=%5<6!$C|RWGe3N;Gwoo=8h|q%B>|%o~Z*KXN7G zgM=U`bHW-LMc=!I7*QJ)KPecfskDD@b-ikN!QL2R(Y7lC*_ZZ>j?rD-=yGD!xoGuS zb1v?P@}yESp{Dj($^aR-@qFcpX>G6Lt3A%};^!X!)6e%BN4CJA|lD9TL2T3V;B64ymwQi-51m#{eT(w>+CB(*q(<0=>-Fd?dBm z9Uy$8<^*(2^Uh`?`y3pSL!AN;TXG3RL|4rB$C-lrdzU=gVSoKzD$icK`8_U;!YhhJ zV1x+zCT_Rfz}cC-lywfi;(gmqb|e|c<}mUVkn>ysd{jMny$R-z2fW7w`k=~=0CbaJ zbuU#c;VT8MQH-V1=us@@YqS5dCCIRBSO%I z8G+v?BIf+=srfxu6Oe|wLsZcNlz{^RKiAOS#eYfgoipqM@_8KSV#0$`JflB&*>&9G z;sc&Fkac+sak?FcVyx*P&GRg{NVM~aC{hf7v7o9kYhZQr`hoNgb3(pSQqIY^ z;oi_UAOY+=TErWe*(1%|Drj=QJ(&P`#ss+kr91Uc z3p2G5uSz_dtX!Nlcf~P^Zs~=L+qUeK&$KK@cpD!)ld{|B8qDVYR7ZM8gDx1Y#)czK z0SJ$`jq;XA2$CKuq}aP9z2Y*;6@jXWFXJ3bVh~iUv&>~h%D@t4F<9waV~tQ-hHvXy*)QVVN6kD!RFg8>b)~wS^qlJQL5?m*yVt(CpS$6~G}m z;yLid9P9!>{Wh)VSuEye(rJs!+~XYIJ}V1lAId4#j-J-_F_P{o^qxui7!n%a>biqy zz;bYe22roLAJ94mdEk$7P0C~OudRxgp}+fHB*{+zTUrQ`Q_gXY2jJD#Bs@YwB#J5^ z)(~#E5C|CeLe=J`us6N-d2IOMT>v_pGm7r$Ns^~#l|JWbpxqgo9C-&woL-?TT{*_$ ztRnbOIIvAJX%gb&iRpqQUmreEkxbvKnVKS(Q31Qn&YkV=?${mkNS^N4{`S&(p15w< zQ~;%jPzzqboRDylhIL3HZ@x9AfsCp-UCVPG!(Za3K#xdtxC5T8&}gk76rU85=PA-D z-$>8y0PL5(P{_iY_VL?|1{1BVS#u&9PT>|h#B@XPCMvrU?NnVQj7%3tM-p=_@a8Dp zs!z`jQNMKu(-SXATe^nA2{6~Dsx~7LPyNkNk%@xr-HXt&PlPPfdlUp@8gAPS6^?`^ z&z&5-qtV7(JLJRYcJj1HbgW|sdqe8kyK1_l8p<%Ft_p~*D5E5xnu?oJxlP%=UV9y3 zdu}8p$^k%^O+H_(7)7&6fw}HQGSuhx*okQ@?hp;+nMw7%f-)jyl_+Btzv!CcPcCw} zg~wZn%0i(iE0mqluCBsKgyqAF8Cx=vzMTnT#?$!F;x3NW z<~E;FN+ZJDtApgw*Pu#i?>=kbwDV65wL%klEqQCQd~bvp`y#0Vfn^yCZLssx+E)Zeq$|w}J~jt*>`XG_}>+EU7Jivbu?EbMTSr zHc*>EzClf4788S+It`7n{cX!NL*Y*_$0khLu`!VD&E1|hM<(=V1@a?-d9?4%%UPwf z*(mjS!Av&vq;gQH={PD;;&JkOJaa#KuDhmqN_%man}PB~Zb`2lwi(~V+sPizWtmeW zZczkAxzV!X>Aou$(FsPAk+$#nU}qYOvm`EOWChCDq}$5ddB-kD&A&KXs_96ZTD4KL zdb`?fI+u3AiG%I+BfXd3&oQcy?NW7oSa2u%oI9?VY@7x@cZ=#Us)nRmlz!i6R7YMu zFhhD`q#cALONYLiEDDr`fa<{D+}4qG$UxGi;&WuwkxMb9VZ2PCRG?zFZ6zDj40IW0 z1H~HyUc!bWLmJyDFTnJ2jTMm2mnw3c3{QgquVkGp-i)aAXsAwN8Qoqf90+r}cRcNC z8I=0tt~R=1vPofYV6|c}%}Hyk^tOL`anp|KB6@PjF?49}VrxKn9HH` z$=;OGQrLGwM#@;2obusdNC&b-1tgl>K`^e@7d_fk4B70L3uY3U!lvK}0qs+r@ ziRm&4P^AQB4`?}t^vwasS!)rxRJnWD@RCG*R5u(cxS*8?DPB7Sq1vF+^rhr#UL zyi)g-!y7UxO7EM73Uovj%Cw{1VC~d-5>}1~%X9-|v0=&V+(bipG=&j;X|9QP-_xfN zTs1XB(YNW;`h$R&y*?JOP(DzXOl>@-&hNbxk8hj3T@9e!rG?qka_DBQ@aruz8$^9l zpFA06zG&=7Iwf=xm5Pw`^l6>W^DW98Z0xsl^w*E>4Db$0W*;)i%N+`TjqGo+04yKJ z{X5DnHu$Oh8oDCDhAN%dKmqS3Kj z93Ztc+g4M4hs+|=pC^8Qc&n(lYG^`Ny7JIzSi6(*NUEU9ziy#lJ_qrzxm7Uifa2{@ z(%b36-DPOa23Z1Tp1UmD7Igj5Y?(q2LtZGu{usLZln`6)Vc^Zi+>~oER;#FwbuBZ*~LS!>FPV;w2fCgK&KYhO|; zIt$7sRZm`z3W-^Xhd}j9^Ot2+!d@yoQs)+L>Sz=IA@>AQ6_`w!d5bdi*FWRu^NTsz zpB5Yj`^`Lhq+$kB%cIko?93+2uTmGK#+Vf=sEyyx@~~9&C>ABzjU`_Z+!lo*~BQv-Kyi#q+YJn;1KJpIv*}Jsi*zD}3W1l9?c6gL01DaI?OJKc+EG zP+$any_nY%`@P980R-J99VOg$h&(Ig7{ggns2MfzGWq==fO-d*1S1NKPi+5tHKTqr;)NRp~=te>-2_BFLm-~ zMfT&4imGPK#dW3`zVw!`*%Wuk2PT7YQBF#vf4#W142bDVZYYA0#I0=^CPvx=_IVYc z2-8jvjZ-t9Xho$D@b9ZhO|djF;+beoxng@lf9NE&g&j9UIisHEt%S*IZR5W~YhEF7Brr4j2r*5yC@xm6BQ&A0kTy;*rYDe2 zf|p5g;&3}{rdmQ{+CpyI8y!nV(ZCF5UE%BsQ!Ujg)I==W!HLmLC@q05cH7WzduMYx zo|gPfa)SD1#EpX1@~g195L@UQ@S^R&<;Dxiqr_MV56*VSeFn6)Lo~!F_m=HBkkM3s z%EIq*dnjL5075LaRQ%|ya*?x9T`sd?6Qx}pMkI_p+IpSfLgaNxdv9Euy%ZtwGFjRt z=7A~OXfU1;$FQ?#PGuC`Xk^i~T!&~zzUnvBfX1;3QT=UwuN20z6K_T?!=LI1kHs*G z3sl%|DjVUhli3pnPdxgaTVt29hgmHFSAg!?e985_) z_Oeunw(`@-J1>+lX%|U@8mf;avXhw$2P%B}xT8*Q54{md5GC@=d_uNl0)ZF%9J&6b z3G9dxCPK)R7YUJIB*sWh6zG_EGpadOCBvRSuR#CFir;a{9g)|~;&^J?{h&*G1gWN1yyrHAL zp;5zVrYbCwXOtI(M7QwPq{g7h@*@7IPSTUNHdQI11$Y*cb&H-Zt3S zWf(_A!bV~5Bh8t1mebMM)@j#0&`ZQKj*VRFlEaYh35A@}xxI`8WHxAIF)$J*y~~g> z+UVq$X@Dy()$;jb#bfMJf6ms{cw<(I>X3$r1Dk{^jcO|@(nu+?tnIP`^8u5b4EvM9 zqIvQno+yW27v8pe5SD4^UQ#Q-AAqqoecAJ;8c0B6lFsv}H#p=J^Ez79N2J4}N!#wS zake!$6z1)5ox8K-)o5?Vd&6kSuznJc^u{xdJB&&No-e&bEf zGRTtr2{!H7rDfdIYfDe08#*I*CkJ}ck^AY=%CoAlc*DMJ%v44Y^K|p6F(NCo)(OfK zu@HbrmwbC~q+NAh@~0#P9y_xaHnDjJml4sE!kwG2FAmS_0vhdU9Hl`q)}E)KV10H( zw|IcF4J5#NqTgUz??F=bKHpYgQ~T1ExXj3o&(Ud=INI8&nnoh0bE3l|vU;I19i52- zhiC!iH(!$XEX^Rs*8(3HwkgwDV;GM^-Ry;gX^bmig`M3z`)f7W8=s+T--?-b0pT&_^}-TOCDQ!k#-t(!eVFdcX_%um@4Sa^IPC$ z)qb^;w?aC$kVi{`m@XdnG<`Ts;Qs8~_K8#NDLqGHIMDpYQK7flkLFO@j5!LRFeqJ= zx3_eXT68F}F{<(Iz`11c+~KDE-u5BvI$T_7hm9)a6v^pm^aF25ek(y%MrvO(w~kY< zeV?M7Vmq?+qY~B`mO~=t&}_B>`krxW&d8<@DUn8e(HhKJWI2La%h=*<=?VE5FEqnxdQ?}OjZyi#1hRR$-6B(MCZA>%qTf`Dk%b^+;N-prEzBf2sdbFa^=t5Uu0gh2qV&v{e z7KPe8{g1Xirqj>bL!t(lb9^Jbxf6lY(*UmFO?@5b+w2~Nm=TZ#O0_rKB0%?^8E8X&y}T|&Zr!GLwqC{VBmFhrIf;IPGbvpYqWx2)fFA_M$W=sYDrMmr5qGT*c%#5$ z#-O`q8Ec~*1R|8fG)ml|JOAUCgK4+7t7S$Si^}urbid@a%P0pkj;gl@2kA=4a{7bb za)<`yzk1IX4{S0iM>fPe0m`!* z_aXgZ+kiV!f2kuhnXbjg%hy?Wm^nPQ;^w2yLXR1JN_@>B+OygTX0&Kk#3-CkU^7F|r_j38O|HHF6|%u!!3Eje51GV;D1haJ?6SdL^oJIUh=X!keOsZ6O$e|pLlC>?9kJ|2VT zp_drGb0+WE7(+0f$1tNa1noTv6aMYKu?20GXOEO0tVv~-6VS1*%Y$Cqkz58cHLI^y z_jJ=jvm$Fm`_fgz8#9_z>;~^VLqyj}Q$~87dv`I5F`uYSe(zbEmU1?xFI6Pu%|3a) zn)F30Sy2&Q5x%Rincg`YodeItYPI?r(happY0UNDzDOMYqOr#f5p_iDl4?5wBA3wP zSz@Odcv%9pSrjkdS@#7(iA&Uu_K`UQ+<|wW3_oQg4Yk^iz}8-Zx6e6^v}zY=oUr#= z1T1cIT0F@rtJ$>)wupOO1uLVoaE8-FR{Nt}wYud;0@KkK5Lw?_Ym`GQ_f4#Q(j>#?Yvc@+T0-3}eT;Hg)sOMkstBR5=1&IePvO!ZOUI?iwg_tOeAq;w5kShb zNLt8g^JSm`Qe{jhNXls;nFOENc!`iTnb@&6KT6H!SQa7OqO1w@O*`DY!$dpt5ttd` z*r<`cckQ|!)^{{LK$zLgqMPz1BeocmN?SHlIQhDr2^_VJ`#*lsv&dTODxu^;#t{Vv|z%7xJq1fuPE_&(A&_w0z_ zM#AThujkrzG%qdME$+sth;BIwB+JIOOx208(f;z%j7lVw-;-)~uMv$r5#v#)2 z>$&(>R)wzQ@t!t>m#agE#^$t*ShF#Tl_m3NS>aOECrl9`-z1UB8ko zak3sgbB7Jk&agztjUvxQRej|iS8aCy4sy~K+~+(HY4dw)t_bnIO|QX2EYpoDVfWR zVadG_N$s>*8tM(aqgtVJ>dzWSSVZt@He*P}r|KJtjBIWKYOwMGKwx{ zj6tH>)7mjuB2m=xOn5aM8^_{@HAR@GudGy3U*Ddzq*sh;d`$r zA+cbr+Eg+AUZ*bvnNC94sEZ$NyJ$qeKZnquKqeN0Ht*QDhr>uKZAR$fw1mEcWf`d; z=0-FD`!1~xQbYm2Exm~c?>kxsYJVhU2qx=%$Aa4b*WR^8HFafSj8UE{YOtU}ISf;>|Adeyu#s}CMKoJyBe1RekFRNzo2~u9IK_Ws0K|v5Kl!pw6P=O{82nfFA zZ7W!d#hLHiB+|8J&CgjgvqpY$&b{a4-gC~rd++c2_PmS|f>?s`&_2$WH|k{do;%bx z6z(lUtjs3XJj&Y6%&>j*TYdkQ*1bq3<-3{V0l&opk-(^Ay$FL0PGA|>G_Od?HY+Wp zQ=0TpQmAYBhW%1HD*Wt6)}DCZRjj2F&(x@6ORLyiQ8ERMW+1krO3Pcx@w|O4KhgyX z%AwM=*>&AT{}P!LIEhRO7r5)HsLWYHY6Mis?5eFc@K#64x&n>a)8yD`kw7`f?mtvY z!)RagES{&$4o?lXkhj-ArtAjji|J~dS6|z17i*3C)4%bTxytQ|`9bPPfSYMVi;pyF z*0YSQ(2Ks@VWq%CyDHZ~L_=IBAiXcc+3pI-oK4#S4~h?Q!}`3LZ^Dv82J> zhh|Vg&(uB3S8hOggR!f8@^c#BPyYRr|G!!`MhSdU7J&FX*H-Vf|lBfZ%|f}-*;NeuZi8jGzh&tyA5Ed6Y-)A7n^4)H?YKznJGQDv=8o^ z{+{|pL&Mn39`zO}HCgS(S8{!c+Tc%*>b#+lI(9wLKsm%2z38VEBGCW9=D4Z7R)ZQ& zyk~^Ow*OYp_vf^2jiw#}y7Kv`L^t45#Mo*i+!+0W90ZnOBRQKROzblVJcl}Xbc}lY zFmT?Q;-`gze`;$!ynfjwd`uLZcchm6!iZ4u(wknZxDp>aEBM~G){W!PGD*n$)hToR zeeN>(VTNbXJWT(N!b)17R`uq_K@XZb=1};C93hVz*ln`(O+FKS*2=%ak#D$!!(QgYNi zNY+Q*iIm{+wL5AUq`WWlOe!+TmOlMNEkoXE8VmTL?A>uQ-VMGE{JpHju2g=A>Le86 z#?y386-*Ak1HVBWm-FGf`7sg^F%wqLwo={~U>P8OQaNLj^NS&wD9;tuMAJb&_;(*JNbf2I;P3zojy;`E> zhp={wv6H8Ls(*?YK`(cpw+FJN#0KY*Oq$?LZ8IhOK!Y)l`3XH0wS(`=89gG0eFCYAB4DE_!M}<17e*i28cdWbIDD|vH{Ke& z?y~XF7YZfJA`s#`Ac{H&F#?Jflw6)ya=#NwjWfZ?3gRRYM5*QS<>HCMa48B&l^cS+ zl)>fB-SYjBjBYU28yR)TKKPR3ib$VU3H$G%I0vJ#50zo&_ls=^;0z3|og`#*V`C5U zT_Hy4yX`rdkPe6sE^6UECwoTd0C>?kN~1$RGaR0rDp5e{Dfq1mGJ=E-F$7YW7B>{) zLD%8k*);w@*nL&>hQS%SoXR5;V;f{BJQI7ciyu2X?6EKNmBfCk}2`m z-?kj}Q&v)vgs3}Wb@=rQ{`~#=fOJxXs}v`_Is!b^vS`$H&5gej{}3pn9^XiUhDBKs zhm7ICtd!|PRE`QO>MWh0E1P3@3*li&6S7mPkveY$zkOGC*?vuKD6qhqS^2-R{1AqE z(*e}xf~4b?3rZ2YlR}Ol5Qs{@?t7Mnmm^O%<%94q#bWt|&%CiU*JXO>BMh|QxP(1Jld4VwB%2%ND7C!s&1MCz+a0C^?V&k_nGucT*DaF*|F1sPT*zyXR|MqhOb}()@@+<^^ z!g|!F^11*YsPUQCWIc=mIwvD-9>rV4_zbJF6`kY3qeo>LXp{2*hk(YQAGAMJb zSw#q6pL?|>-RUCfDxajM76QE1+!^}TV&Xg(i1MCD**t*o6(ys}8)Hwz=qm&3sgwqZ>Ul@1>K!F1% z1DvOmVYzBV2 zH%y<*`OKS1d*p=wxEPyulWd#Zv;<@LAQQXcNlW)XH=(y%ZtV}EbF^r7ySx6ZPCsZ62K)wHD=YPEU75p`{*E%}e*w77>YHHYR=ZA@Ff z36oJ0Q(;84(bX2}XbT)?4Q#@7qw=>5zj4@JRh!Zyt`p;@B`WxHa&TLH)t(>o E4;p;Xn*aa+ literal 0 HcmV?d00001 From 3c5bfc233dc636aade53839337465c5927607323 Mon Sep 17 00:00:00 2001 From: Aayush Gautam Date: Thu, 30 Nov 2023 13:56:17 +0800 Subject: [PATCH 2/2] version bumped to 0.2.8 and README file updated --- Makefile | 2 +- README.md | 359 ++++++++++++++------- README2.md | 97 ------ docs/cli_installation_instructions.md | 70 ---- docs/dkg_node_installation_instructions.md | 36 --- validator_onboarding.png | Bin 61718 -> 0 bytes 6 files changed, 248 insertions(+), 316 deletions(-) delete mode 100644 README2.md delete mode 100644 docs/cli_installation_instructions.md delete mode 100644 docs/dkg_node_installation_instructions.md delete mode 100644 validator_onboarding.png diff --git a/Makefile b/Makefile index 4f84fbc..96d8dd8 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -VERSION = 0.2.7 +VERSION = 0.2.8 GOBASE = $(shell pwd) GOBIN = $(GOBASE)/build/bin GOCMD = $(GOBASE)/cmd diff --git a/README.md b/README.md index d6c3f53..cd7c51f 100644 --- a/README.md +++ b/README.md @@ -1,189 +1,324 @@ -## RockX DKG CLI +# RockX DKG CLI + +- [RockX DKG CLI](#rockx-dkg-cli) + - [Overview](#overview) + - [DKG CLI](#dkg-cli) + - [Pre-built binary](#pre-built-binary) + - [Downloads](#downloads) + - [Installation](#installation) + - [Build from source](#build-from-source) + - [Environment Variables](#environment-variables) + - [Usage](#usage) + - [Keygen](#keygen) + - [Viewing results](#viewing-results) + - [Generate deposit data](#generate-deposit-data) + - [Get Keyshares](#get-keyshares) + - [DKG Node](#dkg-node) + - [Run using docker container](#run-using-docker-container) + - [Environment Variables](#environment-variables-1) + - [Running the container](#running-the-container) + - [DKG Messenger](#dkg-messenger) + - [Run using docker container](#run-using-docker-container-1) + - [Examples](#examples) + +## Overview + +This CLI utility helps user to perform DKG based on FROST (Flexible Round-Optimized Schnorr Threshold) signature scheme. Unlike single-party signatures, threshold signatures involve multiple participants, each possessing a private key share. FROST reduces network overhead and supports efficient signing with two-round or single-round options while retaining genuine threshold signing capabilities. It can identify and exclude misbehaving participants, making it well-suited for practical MPC deployments. FROST ensures security against chosen-message attacks, assuming the hardness of the discrete logarithm problem and control by adversaries over fewer participants than the threshold. + +This repository contains three primary services. SSV operators will execute the DKG Node service, while users creating validator keys on their local machines will utilize the CLI tool. Detailed instructions for building and running both the DKG Node and CLI services are provided in subsequent sections. Additionally, the repository includes a messenger service, serving as a communication layer connecting all DKG nodes for message exchange. RockX will host the messenger service for DKG usage in the SSV platform. If you prefer to run your own messenger service locally or as a Docker container, instructions for doing so are also available in a later section. Here's a brief overview of each service: + +| Service Name | Description | +| ------------ | ----------- | +| `rockx-dkg-cli`| A CLI utility for users to initiate DKG ceremony for keygen/resharing and generate files for DKG result, Deposit Data and SSV Keyshares | +| `rockx-dkg-node`| This is the core service run by each operator to participate in DKG ceremony | +| `rockx-dkg-messenger`| This is the communication layer enabling DKG Nodes to broadcase protocol messages to each other| + +The relationship between these services can be summarized in the following diagram + +![](/services_relationship.png) + +## DKG CLI + +### Pre-built binary + +#### Downloads +|Version|Link| os|arch| +|-------|----|---|----| +|0.2.8| https://github.com/RockX-SG/rockx-dkg-cli/releases/download/v0.2.8/rockx-dkg-cli.0.2.8.darwin.arm64.tar.gz | darwin| arm64| +|0.2.8| https://github.com/RockX-SG/rockx-dkg-cli/releases/download/v0.2.8/rockx-dkg-cli.0.2.8.linux.amd64.tar.gz | linux| amd64| + +#### Installation +1. Download the latest version of the cli tool from above links as per your system. The command for linux with amd64 architecture will be as follows: -### Overview - Validator Onboarding -![](/validator_onboarding.png) - -To become a validator on Ethereum 2.0 using SSV, you need to: +``` +wget https://github.com/RockX-SG/rockx-dkg-cli/releases/download/v0.2.8/rockx-dkg-cli.0.2.8.linux.amd64.tar.gz +``` +2. Extract the CLI tool -1. Create a signing key and withdrawal key using instructions on the Ethereum Launchpad -2. Make a deposit of 32 ETH along with deposit data via the Ethereum 2.0 deposit contract -3. Select operators in SSV app -4. Split the signing key to the selected operators -5. Selected operators will begin performing their duties for the new validators +``` +tar -xzvf rockx-dkg-cli.0.2.8.linux.amd64.tar.gz +``` +3. Move the downloaded binary to your PATH -> Note: This process is without the use of Distributed Key Generation (DKG) method to generate the keys and deposit data. +``` +cp ./rockx-dkg-cli /usr/local/bin +``` +> use sudo to run this command as root if you get permission denied error -With DKG, instead of creating signing key and deposit data manually, you can: +4. Configure Messenger Service Endpoint -1. Send a request through the SSV app to generate the keys and deposit data automatically. -2. The request can be bundled with operator selection, so no need for separate steps. -3. The operator will perform the DKG protocol to generate the keys and deposit data -4. User needs to supply the withdrawal credential (hash of the withdrawal key) -5. Retrieve deposit data from SSV app after DKG and use it to deposit 32 ETH via Ethereum 2.0 deposit contract -6. Pre-selected operators will begin performing their duties for the new validators after deposit is made. +The default messenger address is preconfigured as https://dkg-messenger.rockx.com. If you're using this tool within the SSV platform, you can simply proceed without modifying the following environment variable. However, if you are hosting your own instance of the messenger service or running it locally on your machine (localhost), you have the option to set the following variable to specify the correct address for the messenger service configuration. +``` +export MESSENGER_SRV_ADDR=https://dkg-messenger.rockx.com +``` -The process of creating keys and deposit data with DKG is different from without DKG, but they are compatible with each other. DKG gives users another option to generate keys and in some cases it may be required, but the existing way of generating keys will still work and no action is needed from the users. +5. Configure logging directory -## Getting Started (for local dev) +The debug logs will be stored in the current directory. You can configure a custom path for logging by setting the following environment variable. Please note that you specify a location where this service has permission to create and write to a file. -This repository has a set of services that demonstrate how to use frost DKG to generate a validator public key and shares that are split between operators using Shamir Secret Sharing. -It includes: +``` +export DKG_LOG_PATH=. +``` -1. An CLI utility that provides ways to start keygen/resharing and get results to retrieve validator public key, and generate deposit data in json format -2. A messenger service that allows operators to register and handles messages between operators -3. A Node service that receives messages from other nodes or CLI tool and runs the DKG algorithm to generate the validator public key +### Build from source -### Prerequisites +**Prerequisites** 1. Go 1.19 -2. Docker (20 or later) -3. Docker Compose (1.29 or later) -4. Keystore files for each dkg operator in `/keys` folder +2. Docker (version 20 or later) +3. Docker Comose (1.29 or later) -### Installation -This code repository contains a Docker Compose configuration file to set up and run all necessary services. To start these services, run the following command: +To install the cli tool from source, clone this repository and run the following command ``` -docker-compose up -d -``` - -To install the cli tool, run the following command: -```shell make build ``` -The cli binary can be found at `./build/bin` as `rockx-dkg-cli`. You can add it to you PATH to access it directly buy running +The cli binary will be created at `./build/bin/rockx-dkg-cli`. You can add it to your PATH to access it directly by running ``` cd ./build/bin export PATH=$PATH:`pwd` ``` -If you are running this cluster locally and if you are using hardcoded operators than set the following env vars +### Environment Variables + +| Variable | Description | Default Value | +| -------- | ----------- | ------------- | +| MESSENGER_SRV_ADDR | Address of messenger service | https://dkg-messenger.rockx.com +| USE_HARDCODED_OPERATORS | Use hardcoded private keys for operators for local testing. By default it's set to false and you need to set it to `true` to run DKG locally | false + +If you are running the example set of services (see [Examples](#example)) locally including the messenger service then make sure to set the following env variables + ``` export MESSENGER_SRV_ADDR=http://0.0.0.0:3000 export USE_HARDCODED_OPERATORS=true ``` -You can check all the available command by just typing `rockx-dkg-cli` -``` -NAME: - rockx-dkg-cli - A cli tool to run DKG for keygen and resharing and generate deposit data +### Usage -USAGE: - rockx-dkg-cli [global options] command [command options] [arguments...] +By now you must have installed the DKG CLI tool. You can run following commands: -COMMANDS: - keygen, k start keygen process - resharing, r start resharing process - get-dkg-results, gr get validator-pk and key shares data for all operators - get-keyshares, gks generates a keyshare for registering the validator on ssv UI - generate-deposit-data, gdd generate deposit data in json format - help, h Shows a list of commands or help for one command +#### Keygen -GLOBAL OPTIONS: - --help, -h show help (default: false) -``` +The `keygen` command initiates keygen protocol. It takes the following parameters: -### Key Generation -The `keygen` command is used to generate a new set of key shares using the distributed key generation protocol. The command takes the following parameters: +1. --operator: Key value pair of operatorID (int) and operator's DKG node endpoint +2. --threshold: the minimum number of operators required to sign a message. +3. --withdrawal-credentials: The withdrawal credential associated with the validator +4. --fork-version: ETH fork version (for eg: prater) -##### Command Options ---operator: The key value pair of operatorID (int) and server addr of the dkg operator node ---threshold: The minimum number of operators required to sign a message. ---withdrawal-credentials: The withdrawal credentials associated with the validator account. ---fork-version: The fork version value. +Example: -##### Example: ``` -rockx-dkg-cli keygen --operator 1="http://0.0.0.0:8081" --operator 2="http://0.0.0.0:8082" --operator 3="http://0.0.0.0:8083" --operator 4="http://0.0.0.0:8084" --threshold 3 --withdrawal-credentials "0100000000000000000000001d2f14d2dffee594b4093d42e4bc1b0ea55e8aa7" --fork-version "prater" +rockx-dkg-cli keygen \ + --operator 347="http://34.142.183.114:8081" \ + --operator 348="http://34.142.183.114:8080" \ + --operator 350="http://35.198.251.30:8080" \ + --operator 351="http://35.187.235.146:8080" \ + --threshold 3 \ + --withdrawal-credentials "0100000000000000000000001d2f14d2dffee594b4093d42e4bc1b0ea55e8aa7" \ + --fork-version "prater" ``` The CLI will return a request ID in the following format: ``` -keygen init request sent with ID: 9a45c1f30a9896c5263508c2a132ebf7fc7e3c37ab86c74b +keygen init request sent with ID: 33a5b7fe2b415673c4d971e6c0b002ce7d583b6621dffb31 ``` -### Resharing -The `resharing` command is used to reshare an existing validator public key from old committee members to new committee +#### Viewing results -##### Command Options ---operator: The key value pair of operatorID (int) and server addr of the dkg operator node in the new committee ---old-operator: The key value pair of operatorID (int) and server addr of the dkg operator node from the old committee. Atleast previous threshold number of operators are required to successfully perform resharing ---threshold: The minimum number of operators required to sign a message. ---validator-pk: The public key of the validator account. +This command generates results of keygen/reshare by using the request ID generated in keygen/reshare command. It takes the following parameter: -##### Example: +1. --request-id: ID generated from calling keygen or reshare + +Example: ``` -rockx-dkg-cli resharing --operator 5="http://0.0.0.0:8085" --operator 6="http://0.0.0.0:8086" --operator 7="http://0.0.0.0:8087" --operator 8="http://0.0.0.0:8088" --old-operator 1="http://0.0.0.0:8081" --old-operator 2="http://0.0.0.0:8082" --old-operator 3="http://0.0.0.0:8083" --threshold 3 --validator-pk adf8b634f1c2bb64fe61af95b208a2a7bdac0d2d15963f83463bdb85c7e726250bfa3a390bf01edfc0700d61f4bee579 +rockx-dkg-cli get-dkg-results --request-id 33a5b7fe2b415673c4d971e6c0b002ce7d583b6621dffb31 ``` -The CLI will return a request ID in the following format: +This will write the results of the key generation/resharing process with the given request ID to a file of format `dkg_results__.json` ``` -resharing init request sent with ID: c9e8c174060ee45bf86aaea3e409d8ee48a8fcb3d008fd18 +writing results to file: dkg_results_33a5b7fe2b415673c4d971e6c0b002ce7d583b6621dffb31_1701317995.json ``` -### Viewing Results -To view the results of a key generation process (or resharing), use the request ID returned from the previous step and use `get-dkg-results` command +#### Generate deposit data + +Once the keygen is finished, you can also generate a Deposit Data file for depositing 32 ETH into your validator. It takes the following parameters: + +1. --request-id: ID generated from calling keygen or reshare +2. --withdrawal-credentials: The withdrawal credential associated with the validator +4. --fork-version: ETH fork version (for eg: prater) -##### Command Options ---request-id: request id generated from calling keygen or resharing command +Example: -##### Example: ``` -rockx-dkg-cli get-dkg-results --request-id 9a45c1f30a9896c5263508c2a132ebf7fc7e3c37ab86c74b +rockx-dkg-cli generate-deposit-data --request-id 33a5b7fe2b415673c4d971e6c0b002ce7d583b6621dffb31 -withdrawal-credentials "0100000000000000000000001d2f14d2dffee594b4093d42e4bc1b0ea55e8aa7" --fork-version "prater" ``` -This will write the results of the key generation/resharing process with the given request ID to a file of format `dkg_results__.json` +This will right the results to a json file in the following way + +``` +writing deposit data json to file deposit-data_1701318343.json +``` + +#### Get Keyshares + +To distribute validator on SSV platform, you will need to select split key offine and then upload a keyshares file. To generate that keyshares file you can run the `get-keyshares` command. It takes the following parameters: + +1. --request-id: ID generated from calling keygen or reshare +2. --operator: Key value pair of operatorID (int) and operator's DKG node endpoint +3. --owner-address: The cluster owner address (in the SSV contract) +4. --owner-nonce: The validator registration nonce of the account (owner address) within the SSV contract (increments after each validator registration), obtained using the ssv-scanner tool. (default: 0) + +Example: +``` +rockx-dkg-cli get-keyshares \ + --request-id 33a5b7fe2b415673c4d971e6c0b002ce7d583b6621dffb31 \ + --operator 347="http://34.142.183.114:8081" \ + --operator 348="http://34.142.183.114:8080" \ + --operator 350="http://35.198.251.30:8080" \ + --operator 351="http://35.187.235.146:8080" --owner-address "0x1d2f14d2dffee594b4093d42e4bc1b0ea55e8aa7" \ + --owner-nonce 0 +``` + +It will generate a keyshares file in the following format that can be used to registor validator on SSV platform. + +``` +writing keyshares to file: keyshares-1701319254.json +``` + +## DKG Node + +### Run using docker container + +To run DKG node from a docker image, first you need to prepare application environment variable file and operator keys. + +#### Environment Variables + +| Variable | Description | requried/default value | +| -------- | ----------- | ---------------------- | +| NODE_OPERATOR_ID | SSV operator ID for this node | required | +| NODE_ADDR | Http address of the service | 0.0.0.0:8080 | +| NODE_BROADCAST_ADDR | The public ip or address of this DKG node | required | +| MESSENGER_SRV_ADDR | address of the messenger service | https://dkg-messenger.rockx.com | +| USE_HARDCODED_OPERATORS | use `true` for running local example | false | +| OPERATOR_PRIVATE_KEY | The raw base64 encoded RSA private key | Use either raw RSA private or JSON encode private key | +| OPERATOR_PRIVATE_KEY_PASSWORD_PATH | password file path for json encoded RSA private key | required | +| OPERATOR_PRIVATE_KEY_PATH | file path for json encoded RSA private key | required | + +> Note: if your operator is configured using raw private key then use OPERATOR_PRIVATE_KEY. If it is configured using JSON encoded key then use OPERATOR_PRIVATE_KEY_PASSWORD_PATH and OPERATOR_PRIVATE_KEY_PATH + +#### Running the container + +By now you must have prepared env file and operator keys if you are using JSON encoded. + +This might look something like this if you're using JSON encoded private key: ``` -writing results to file: dkg_results_c9e8c174060ee45bf86aaea3e409d8ee48a8fcb3d008fd18_1678083260.json +$ ls -Rw 1 +.: +351.env +keys + +./keys: +encryption_private_key.json +password ``` -### Generating Keyshares file -To generate keyshares file to be uploaded to SSV V3 UI for registering validater, `get-keyshares` command is used +In case of raw private key you will just have the environment file -##### Command Options ---request-id value, --req value request id for keygen/resharing ---operator value, -o value operator key-value pair ---owner-address value, --oa value The cluster owner address (in the SSV contract) ---owner-nonce value, --on value The validator registration nonce of the account (owner address) within the SSV contract (increments after each validator registration), obtained using the ssv-scanner tool. (default: 0) +The environment file should look like these: -##### Example: +with raw private key: ``` -rockx-dkg-cli get-keyshares --operator 1="http://0.0.0.0:8081" --operator 2="http://0.0.0.0:8082" --operator 3="http://0.0.0.0:8083" --operator 4="http://0.0.0.0:8084" --owner-address 0x1d2f14d2dffee594b4093d42e4bc1b0ea55e8aa7 --owner-nonce 999 --request-id 9a45c1f30a9896c5263508c2a132ebf7fc7e3c37ab86c74b +NODE_OPERATOR_ID=351 +NODE_ADDR=0.0.0.0:8080 +NODE_BROADCAST_ADDR=http://35.187.235.146:8080 +MESSENGER_SRV_ADDR=https://dkg-messenger.rockx.com +OPERATOR_PRIVATE_KEY=LS0tLS1CRUd...FURSBLRVktLS0tLQo= ``` -This will write the results of the key generation/resharing process with the given request ID to a file of format `keyshares-.json` +with JSON encoded private key: ``` -writing keyshares to file: keyshares-1680588773.json +NODE_OPERATOR_ID=351 +NODE_ADDR=0.0.0.0:8080 +NODE_BROADCAST_ADDR=http://35.187.235.146:8080 +MESSENGER_SRV_ADDR=https://dkg-messenger.rockx.com +OPERATOR_PRIVATE_KEY_PATH=/keys/encryption_private_key.json +OPERATOR_PRIVATE_KEY_PASSWORD_PATH=/keys/password ``` -### Generate Deposit data -To generate deposit data run the command `generate-deposit-data` from the cli. It will generate a json file with name format as `deposit-data_*.json` +**Pull the latest docker image** -##### Command Options ---request-id: request id of previously ran keygen process. ---withdrawal-credentials: The withdrawal credentials associated with the validator account. ---fork-version: The fork version value. +You can now pull the latest docker image for DKG node -#### Example: ``` -rockx-dkg-cli generate-deposit-data --withdrawal-credentials "0100000000000000000000001d2f14d2dffee594b4093d42e4bc1b0ea55e8aa7" --fork-version "prater" --request-id 9a45c1f30a9896c5263508c2a132ebf7fc7e3c37ab86c74b +docker pull asia-southeast1-docker.pkg.dev/rockx-mpc-lab/rockx-dkg/rockx-dkg-node:latest ``` -The generated file can be verified at https://goerli.launchpad.ethereum.org/en/overview +**Run the container** -### Verifying Results -To verify results, use Verify tool with Validator Public Key and Deposit Data signature ``` -# Build verify tool -make build_verify +docker run -d --restart unless-stopped --name operator-351 -v /home/ubuntu/dkg/operator-351/keys:/keys --env-file /home/ubuntu/dkg/operator-351/351.env -p 8080:8080 asia-southeast1-docker.pkg.dev/rockx-mpc-lab/rockx-dkg/rockx-dkg-node:latest +``` + +You can check if your DKG node is correctly registered with the messenger service by running the following command and looking for your operatorID and your DKG node's public endpoint + +``` +curl -X GET https://dkg-messenger.rockx.com/topics/default +``` + +## DKG Messenger + -# Run verify tool -# ./build/bin/verify +At present, RockX provides a hosted messenger service at https://dkg-messenger.rockx.com. If you prefer to operate your own messenger service, you can do so by utilizing the Docker image and configuring it to map to your SSL-enabled public address or IP -./build/bin/verify prater 91d5dfe9e2357e291bf8286d16ab501dab48e75f2a82b5f81c4acc88f8e84f228719d4a132e414f3746d071537e04d84 887caab77686fce13407f9e02de9db029344d31ffbcc4bd68d0d4248c969c6e19b0ea297e42ee82b02db8f95e14dd743179400eef4b58af7b1bb97cc78d1a7984000a233657cfe65e665a9d4762243229c83a8164767e7fd224cfa4e2bbdd821 0100000000000000000000001d2f14d2dffee594b4093d42e4bc1b0ea55e8aa7 +#### Run using docker container -# Output -# signature verification succeeded +**Pull your docker image from GCP container registry** ``` +docker pull asia-southeast1-docker.pkg.dev/rockx-mpc-lab/rockx-dkg/rockx-dkg-messenger:latest +``` + +**Run the container** +``` +sudo docker run -d --name messenger -p 3000:3000 asia-southeast1-docker.pkg.dev/rockx-mpc-lab/rockx-dkg/rockx-dkg-messenger:latest +``` + +This will run the messenger service on port 3000 + +## Examples + +The /env directory contains sample env files for 7 operator nodes with IDs from 1 to 7. You can run the following command to spin up 7 DKG nodes and a messenger node using following command + +``` +docker-compose up --build -d +``` + +You can then build the cli tool using `make build` command and test keygen and other commands locally. Make sure you set the following env vars to run locally + +``` +export MESSENGER_SRV_ADDR=http://0.0.0.0:3000 +export USE_HARDCODED_OPERATORS=true +``` + diff --git a/README2.md b/README2.md deleted file mode 100644 index 5b4def3..0000000 --- a/README2.md +++ /dev/null @@ -1,97 +0,0 @@ -# RockX DKG CLI - -- [RockX DKG CLI](#rockx-dkg-cli) - - [Overview](#overview) - - [DKG CLI](#dkg-cli) - - [Pre-built binary](#pre-built-binary) - - [Downloads](#downloads) - - [Installation](#installation) - - [Build from source](#build-from-source) - -## Overview - -This CLI utility helps user to perform DKG based on FROST (Flexible Round-Optimized Schnorr Threshold) signature scheme. Unlike single-party signatures, threshold signatures involve multiple participants, each possessing a private key share. FROST reduces network overhead and supports efficient signing with two-round or single-round options while retaining genuine threshold signing capabilities. It can identify and exclude misbehaving participants, making it well-suited for practical MPC deployments. FROST ensures security against chosen-message attacks, assuming the hardness of the discrete logarithm problem and control by adversaries over fewer participants than the threshold. - -This repository contains three primary services. SSV operators will execute the DKG Node service, while users creating validator keys on their local machines will utilize the CLI tool. Detailed instructions for building and running both the DKG Node and CLI services are provided in subsequent sections. Additionally, the repository includes a messenger service, serving as a communication layer connecting all DKG nodes for message exchange. RockX will host the messenger service for DKG usage in the SSV platform. If you prefer to run your own messenger service locally or as a Docker container, instructions for doing so are also available in a later section. Here's a brief overview of each service: - -| Service Name | Description | -| ------------ | ----------- | -| `rockx-dkg-cli`| A CLI utility for users to initiate DKG ceremony for keygen/resharing and generate files for DKG result, Deposit Data and SSV Keyshares | -| `rockx-dkg-node`| This is the core service run by each operator to participate in DKG ceremony | -| `rockx-dkg-messenger`| This is the communication layer enabling DKG Nodes to broadcase protocol messages to each other| - -The relationship between these services can be summarized in the following diagram - -![](/services_relationship.png) - -## DKG CLI - -### Pre-built binary - -#### Downloads -|Version|Link| os|arch| -|-------|----|---|----| -|0.2.7| https://github.com/RockX-SG/rockx-dkg-cli/releases/download/v0.2.7/rockx-dkg-cli.0.2.7.darwin.arm64.tar.gz | darwin| arm64| -|0.2.7| https://github.com/RockX-SG/rockx-dkg-cli/releases/download/v0.2.7/rockx-dkg-cli.0.2.7.linux.amd64.tar.gz | linux| amd64| - -#### Installation -1. Download the latest version of the cli tool from above links as per your system. The command for linux with amd64 architecture will be as follows: - -``` -wget https://github.com/RockX-SG/rockx-dkg-cli/releases/download/v0.2.7/rockx-dkg-cli.0.2.7.linux.amd64.tar.gz -``` -2. Extract the CLI tool - -``` -tar -xzvf rockx-dkg-cli.0.2.7.linux.amd64.tar.gz -``` -3. Move the downloaded binary to your PATH - -``` -cp ./rockx-dkg-cli /usr/local/bin -``` -> use sudo to run this command as root if you get permission denied error - -4. Configure Messenger Service Endpoint - -The default messenger address is preconfigured as https://dkg-messenger.rockx.com. If you're using this tool within the SSV platform, you can simply proceed without modifying the following environment variable. However, if you are hosting your own instance of the messenger service or running it locally on your machine (localhost), you have the option to set the following variable to specify the correct address for the messenger service configuration. -``` -export MESSENGER_SRV_ADDR=https://dkg-messenger.rockx.com -``` - -5. Configure logging directory - -The debug logs will be stored in the current directory. You can configure a custom path for logging by setting the following environment variable. Please note that you specify a location where this service has permission to create and write to a file. - -``` -export DKG_LOG_PATH=. -``` -6. - -### Build from source - -**Prerequisites** -1. Go 1.19 -2. Docker (version 20 or later) -3. Docker Comose (1.29 or later) - -To install the cli tool from source, clone this repository and run the following command - -``` -make build -``` - -The cli binary will be created at `./build/bin/rockx-dkg-cli`. You can add it to your PATH to access it directly by running - -``` -cd ./build/bin -export PATH=$PATH:`pwd` -``` -If you are running the example set of services (see [Examples](#example)) locally including the messenger service then make sure to set the following env variables - -``` -export MESSENGER_SRV_ADDR=http://0.0.0.0:3000 -export USE_HARDCODED_OPERATORS=true -``` - -We employ Docker Compose to establish seven DKG nodes running locally, spanning from localhost:8081 to localhost:8087. Simultaneously, we set up a messenger node locally at localhost:3000. It's important to note that this configuration does not establish a connection to SSV's Operator Registry and utilizes a predefined set of operator keys hardcoded into the setup. The key shares generated through this configuration are solely intended for demonstration purposes. his configuration is designed for your local exploration and debugging of the DKG solution. In a production environment, there is no need to set the `USE_HARDCODED_OPERATORS` environment variable as it is already set to `false`` by default. \ No newline at end of file diff --git a/docs/cli_installation_instructions.md b/docs/cli_installation_instructions.md deleted file mode 100644 index b3c19ee..0000000 --- a/docs/cli_installation_instructions.md +++ /dev/null @@ -1,70 +0,0 @@ -## RockX DKG CLI - Installation instructions ---- - -Downloads -|Version|Link| os|arch| -|-------|----|---|----| -|0.2.7| https://github.com/RockX-SG/rockx-dkg-cli/releases/download/v0.2.7/rockx-dkg-cli.0.2.7.darwin.arm64.tar.gz | darwin| arm64| -|0.2.7| https://github.com/RockX-SG/rockx-dkg-cli/releases/download/v0.2.7/rockx-dkg-cli.0.2.7.linux.amd64.tar.gz | linux| amd64| - - -### Installation (for os: darwin and arch: arm64) - -1. Download the latest version of the cli tool from above page - -``` -wget https://github.com/RockX-SG/rockx-dkg-cli/releases/download/v0.2.7/rockx-dkg-cli.0.2.7.linux.amd64.tar.gz -``` - -2. Extract the cli - -``` -tar -xzvf rockx-dkg-cli.0.2.7.linux.amd64.tar.gz -``` - -3. Move the file to your PATH and Set messenger service address for the cli - -``` -cp ./rockx-dkg-cli /usr/local/bin -export MESSENGER_SRV_ADDR=https://dkg-messenger.rockx.com -export DKG_LOG_PATH=. -``` -> `DKG_LOG_PATH` instructs the cli to store logs at this location under the filename `dkg_cli.log`. Make sure it is a location with permission to create files - -4. Perform DKG -``` -rockx-dkg-cli keygen \ - --operator 291="http://34.143.199.161:8080" \ - --operator 513="http://35.240.226.66:8080" \ - --operator 514="http://34.87.9.120:8080" \ - --operator 515="http://34.124.174.255:8080" \ - --threshold 3 \ - --withdrawal-credentials "0100000000000000000000001d2f14d2dffee594b4093d42e4bc1b0ea55e8aa7" \ - --fork-version "prater" -``` - -5. View Results -``` -rockx-dkg-cli get-dkg-results \ - --request-id f99672b06987b3ae88a2f884488d684373bb18be8eb72e5d -``` - -6. Generate Deposit Data -``` -rockx-dkg-cli generate-deposit-data \ - --withdrawal-credentials "0100000000000000000000001d2f14d2dffee594b4093d42e4bc1b0ea55e8aa7" \ - --fork-version "prater" \ - --request-id f99672b06987b3ae88a2f884488d684373bb18be8eb72e5d -``` - -7. Generate Keyshares -``` -rockx-dkg-cli get-keyshares \ - --operator 291="http://34.143.199.161:8080" \ - --operator 513="http://35.240.226.66:8080" \ - --operator 514="http://34.87.9.120:8080" \ - --operator 515="http://34.124.174.255:8080" \ - --owner-address "0x1d2f14d2dffee594b4093d42e4bc1b0ea55e8aa7" \ - --owner-nonce 999 \ - --request-id f99672b06987b3ae88a2f884488d684373bb18be8eb72e5d -``` diff --git a/docs/dkg_node_installation_instructions.md b/docs/dkg_node_installation_instructions.md deleted file mode 100644 index 9f7e56f..0000000 --- a/docs/dkg_node_installation_instructions.md +++ /dev/null @@ -1,36 +0,0 @@ -# DKG Operator Node - installation - -### Environment variables for .env file -``` -NODE_OPERATOR_ID=1 -NODE_ADDR=0.0.0.0:8080 -NODE_BROADCAST_ADDR= -MESSENGER_SRV_ADDR=https://dkg-messenger.rockx.com -OPERATOR_PRIVATE_KEY= -USE_HARDCODED_OPERATORS=false -``` - -> Note: keep USE_HARDCODED_OPERATORS=false to use SSV operator registry instead of hardcoded values -> Note: NODE_BROADCAST_ADDR is the public ip and port of the instance running this DKG node eg: http://34.143.199.161:8080 - - -### Docker command to run the containers - -#### Environment Variables file - -Create a folder `env` and store your env file here - -``` -ls env/ -operator.1.env -``` - -#### Pull your docker image from GCP container registry -``` -docker pull asia-southeast1-docker.pkg.dev/rockx-mpc-lab/rockx-dkg/rockx-dkg-node:latest -``` - -#### Run the container with the env file -``` -docker run -d --name operator-node --env-file ./env/operator.1.env -p 8080:8080 asia-southeast1-docker.pkg.dev/rockx-mpc-lab/rockx-dkg/rockx-dkg-node -``` \ No newline at end of file diff --git a/validator_onboarding.png b/validator_onboarding.png deleted file mode 100644 index 1601144ba8e68475ce9269fe4fcae9084d21efc4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 61718 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
F(XGyLJU_I^as7Phvh%H4)pA5F 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