From 1befe7b29322bd00b341fca96dc67139c0fe7623 Mon Sep 17 00:00:00 2001 From: kostyamospan <37243242+kostyamospan@users.noreply.github.com> Date: Fri, 13 Feb 2026 18:48:54 +0000 Subject: [PATCH 01/15] chore: basic timelock tests --- Anchor.toml | 1 + external/squads.so | Bin 0 -> 1470416 bytes package.json | 1 + test/constants/squads.constant.ts | 3 + test/data-feed.test.ts | 8 +- test/fixture/ac.fixture.ts | 6 +- test/fixture/dafa-feed.fixture.ts | 6 +- test/fixture/squads.fixture.ts | 125 +++++++ test/fixture/vaults.fixture.ts | 5 +- test/helpers/common.helpers.ts | 38 +- test/squads.test.ts | 196 +++++++++++ test/testers/squads.testers.ts | 120 +++++++ yarn.lock | 560 +++++++++++++++++++++++++++++- 13 files changed, 1047 insertions(+), 22 deletions(-) create mode 100644 external/squads.so create mode 100644 test/constants/squads.constant.ts create mode 100644 test/fixture/squads.fixture.ts create mode 100644 test/squads.test.ts create mode 100644 test/testers/squads.testers.ts diff --git a/Anchor.toml b/Anchor.toml index 7cfe463..4cff8e3 100644 --- a/Anchor.toml +++ b/Anchor.toml @@ -40,3 +40,4 @@ test-feed = "yarn vitest run test/data-feed.test.ts" test-minter = "yarn vitest run test/minter-vault.test.ts" test-redeemer = "yarn vitest run test/redeemer-vault.test.ts" test-tokens = "yarn vitest run test/mtokens.test.ts" +test-squads= "yarn vitest run test/squads.test.ts" diff --git a/external/squads.so b/external/squads.so new file mode 100644 index 0000000000000000000000000000000000000000..017fdadcb15c3412fba3e6ce034ac0ce27d77cdb GIT binary patch literal 1470416 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�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�zAZK{oSv=oG<4EHV zlwsW`kY)p(M<*=gYq*H;JjIVCJW;~*x&czrHHhIx>(5d6hh?%sucxE;BN9k)%r7GE zbMgG)`|XMBUbdUqo(sCR;l?n&w}-}wLVmx3vprvfq~B|7BND9dm}mM0Xmlw5ILmt@ zvX>(1ITg2NNqsH&gu`&X)YSi3=Fx86%Qr#K^S z`9%C^&64f$dAF}Y+QIz%KH(wKhA$xRL$Ey@%m0SZ8(w3*XqWU(+2fK1LO91G8-6L$ zf7!T)4wYf~FL*qvUF}kjkTHeO*C=BiA7A(>)t-F5h}UhBL;P=0JrsP$5JdWawTS!j zL}c*uMjaa@>>Q`;6jSK^?35FXkCBDirJZ~YVrtkaKNC~VlJp||Nyt&_$jPE&ueiw+ zqsK{SjK1X}|B=&ojIkFbvQx^8za#EjCyI-6;~e~~!8{Rkf)BI~`7UQZ_(Vo0{bXlK zy5&CIYm|$8#Lss8BKeHhZz@-Sbl*tHaIbn_7v-mQ!r4x?YcftW>Arw8e4Ob)yno?Z zr0aYV>xmlAIfasbzL&!L7pjNyb*TB^98Z=j@+!|MJ-PXic&@GzRCmic*YzBk@eNZJB&sqEUG z@v;1b?@@Tmu2Fi8<{ADMd?WqO@9)S_>xFN^6;#~lQ|khMFP7{MYQeYSQjy-Ho@?xr z(@K0di0b8agz{4uHp{mu8K zYk(I0Q1oZYVYcYtbK#DNEI;7>Fgiv2wd5;Fjt{{USpQ}x$L^&O-fPJHPG%iJ$cJ{R z9`eV4t=4la-B@Rd6?|Wpo*Sp{y-*p7y~YyyX>=?Sk@&8sSkJ&ViuoKOn4+FzL3s-N z97{A$!hM&?xEtjt%XajO=;%falu@bl7r#e2bFs`Hoq!Aod|$vSkN$}Ah(&qDzuJH- zmwB;_qj^dWzjXVfL`7e=ed4!?8qOUi*GKka@OzJ=JLLT0^KJ64(s=aE63rSpm&lmg z=liPs{dMx2^$X1`?VEwMe8UR=tsXP(0mp1 z2fu~jL?mLLY^G; z3wm{VQt6bx0RJ+}@dttRe2048G}|*$;5&|y@)a(tl;fcI$?qK{`Cg~(S9;3Yt$fs# zp0afU?kU?SV*P$-6&Tc0)+_K-k8K}Z)+EcR_bgFA+E-)<^_LZh zSnS)7(Kk_!55ZKhBTEi)BS4}5RUCv>+=q54A63wiC8`l$(X;1ExAKua)R9GhA@}%a z&qq&g%K8o>ts{&6#>o>+fA4JB+&O zTTWbpUZF{a&~w&e$)7RhGCp68N4gvj-}qdS&o{x8@jO}HYn&=zU4Dc-YTq5Qe;4IF z)y^If>*dPPPkxVtjxQDXCq;geUz>cZbJD|ozeV@+^rAl9&m;Uk%AO`a&kjw#N&ZRi z(zsL1=c&H&vj6N)=lQDBE%~t9qT9{~*?&Ig)yqjfBgO$Jko(K`BQk4Lx#2Qq zJ0(ZiFYIUMb(qGD`b*!Xpg{cq*x#Y%HAMtB;)mdqid)0--i-B~it(a2{PJKVf^V+c ze=2;=JefXjuH=W;C=`fn&+#JWeL;sBC*F@Z&$oi^d`aIhSr6HPr=W&DWiQpBKRE;| zzBb}F^{mpwAB2hUtG$Vs-~o-ykLtm`+a7xxJ~@yV_i_X~WyduHY62fsIn z%I$oJMpOoVPDpP@>cyD;tr{L1k9c~wMbv-fdbdvG-zodIUD84O=3d|rwZ6RPSYK$y zk=~)$YgEbl)V?8ldKQT%>@>-*=ozU3&h|_pv_bMnEVTR}a#|w4;=ZmY>I;&)G>Y zo1nK_#l&}led8zNuasjViSWcX-*_nxhbm8;@r@r!#nm{v0n3hgjpGEK?7@HbX?kO- zoPVVMoT?Ell+}#mlJ){kVNmZovGE!&y!Poc|VKaUcRHf z903n(@5eulm8bUdRC{Sp#qcyPVazM1Jn(rH*%8k!KG;w4XQDj$O(^DZp?cB0&|9?r zQvV6|Eug;=rkK|;niuC4qCUhX@ZBmVzZ#urk)K19KSPxVOo9ECB=2u~Q68}ge7A~e z{eByDk^U6r$>EE@cAQ>5XL$VbIao$~Tn_!BKzbEjGKgM6RVura_(3i3{l`kVEik`W+<*#}@e*UW8rz8I_Z1vY5|6Yurv;J)NGyQw- zc3X5%K6?M_z6za=9g{zj7qYlW4`h85!;@SV>UyS06gS9!N_>lkw+KYG zN8Srz`U_T)H7ik;?zDpE0^z&S>r=R4L?j?}iQ%wDvf`8GE(8YYPB!Y&u}b34dR?b7``ius(8-`_*)OAd+>A5Fx}M}CfU zBJSr?i#!imUU|Pp{G~wrJOO=*c5V@H=7l1{_YtL__e_>}=X zP}M!^{ve-A`FVfRDC@sW4!bztpnmXvX+85lSLVz1Vqg&_x~GWx`8huBPjrj4V|c&Q zAlYl#J47G;x9p=D=mpWId5cncx!zB3q2V8h4!!G>?3v zsWy@WY5#-*0yO*{d7p>nYJG>q^S$Z@NBuP4Y1~Er>}TU&Zfe9YIpQX`cC97&rvJPj)CeZr0uh+Vgd3FZ)s#i}K9BJ|$=TeS~b| zDqHs*mHZ+4 zNe=is19&f$Xuw}0+sRk+)?XoEejb?Z`G%DePx_JQA-ajq6pSUoyq@#?$rh<`KI%J()hotdbQ!azDh0#EA~WzqfKg3secveBUY2mJnOz8@dmx=OUq{qC76 z;pleBx9DAxk34T!FRq*ZQvR^!IJy)2L|8*j}=nws}1U3&}6>y>E%kPv;&q9)2aqG!B%WjpynqN6%C#=luLM*+BcDf*WGOR zbtqW!vQ5cLu0Z1+x_!K|lcoGb)%%+Hd!Vd0_&qybv5LpmtpW0LjI5vOjc%3W7u_c3 z5!V~trsPQRgU6HQ&1*a@`0UgZL=S~=HQYZX_uC|%<`Kzp^lmv%`96rQFP}#qmgAlg zTSURWI$8ck8KHi8?#A=dAC?Ks?`)5JZh_ZV8W%K+=kry+3gvqXd&(rt`}8AOM>6zv zVWMo8zf0s_AqAuc?GXpy&kz~1)%$3oE9ry+a(udo#QN|){9^pP599e9l-7?oaetiq zO?;xjen;Xz-5;m?)Dl0>mstk@L4Th|FX`!Gi4P~Q7eAOU`n?7kSoUv_o+J77DSs>P z-^uQvdsAdL7ErohKA%Ex4gT?aHT3!03;aY^mO(M&FOy;deIfUmx_%J!D*Zt7iOTix zd(H0xfS`{TRYmLmH}&s7fp`*0;$t4}rCNLhvRCEb;&`s$n$I*l;eP?YX-WG}OUWFi^g+c||x{`KI;DL^+o8Zu}N7@Dz?*&gJ?ZlXLkz9m_Mz>Hnmh z|MCd=UiiP1?^53X^Z0)I5%S#~hwo8R-UtKbT^eFXEAP6TLj@YXm1H5s^m<}FF85_I z`IhqjpCsR*Bjoc-xbIGSpVoa|H~$m)Eamw>kI!?Dkk30bKC`{$pCRoa-Urq|2uZ}N zl^s!o_16T<-wm?9&jLKH<1}tJBlfEA8?s$Vc8;)jptq?$et#+7(;r~(DEmA-LfJd0 zpX7n}z1?U`%nz@cA5~AYv-tZ zTz-I^qwFB!1DZahoioTWZq)vN65nj{?&$YK>-pV1a({vT_Nx9m?X)wGO77(N4wSoT z#Gcsu(KPv61U#R+v;2K&{lRj`b~npmm1thv!xM7&RrT}$eopxxlfy^#eGB?a;Xjdo zM<$Q299AAvG8&^gU=Nvdf)Ev-}{M|;K@j#`Q3ondTvwkp$2>s z{X#7IrTR~02&S_?3XO;bJ@_N&0nSEGmdGZ~AIN{L?Y^PdOZ>&-KeLnZ5a$+62OQw@wNYJ-H!Jw-EKf|h>ME&4( zg6u}(RgUVPwVzh?v;9WqKo;qUFqd+#FUTPzcgOGaoXRY<%=pm8$Zuyy`My_<5#0@Vm7tND7b-1f@jNYkkDSjLSbmw$*`5(1V~)~4q{lYtd{%VOdPRZsor#$2Vv326 z6uAD(xe}g;@7lf$8u>m9kZ*8`Og(-aqoioOL}aVv9#GZ3 zmC{drf%bepIJWm{EF{QhF8Ywqk3A8*)Qiooy1#w^-Gxa2g#e)P=0gfhtgLh z4}u@6-O1pO;75@xKQZZe!H+rh69j_Kd25i5o=>@;NX~7hm-mw#0 zWUiBO-(%b4sOs;_mC>?g^y7!Ph&(M@`f`ayC>bg|s>J=M&4sy_6W z_{Q(^=wUqMiOP}w5HT`QyFu4y{gj{kb2$F;d^@b%luLRnxmhIP0dk}IYst;&N^Xke zbKQK-!uM2p95NTk`YgFodV=R=>paO%)|+gn^7tNpo{UT|PwetgL-GJp=-!O}oK!w3 zMFg^ML@XoA?&W#ZQzH|s`2&!O_>$y%axN&8el+L&2~UWXqx`MMNcrdUm>P^X(Z&4Z zc`{&}XUTfH(GQX@zVAP9o{Y85O{fIvSCUhf2Ve1ELR;tLm=^o)@6nfujg~{+7&Vf*+;PedK;vIX1lO5azOrJ7+3^qPv)20WjmkgNI0HK-}}a2 zCF;@j3)RH$$EjQ>k`126q<=^R;^B#+cz9|m9-cT94{vJt?HC8^;6fO4YWsywArm5e8O$V8w#6xXW!;yGX_P{NZQ z<>!FuUSBzI#II7s+3xZ9i~6UC$mmA8;B%gYD>uuy@A6o>;By>2(G@Sh;B%b(g3odA zrdH2(6ed3F?F+twP6|1W^0mr7pnH>okE>)pexGTdns}t21s_%Z+Gd$AU)dGJhf=El zTN2Or_-K8idCdEkP?b!ldsIZ%!$_ytXVPB@Q%w5SL`;0AI7iLXzH$HvHTXyMhKN}R zypIZ@J_bEoKXEdFGF>*9PxoDY?>XhdF=cr4rBY5$tP{urEAZ{2*;X<+GENUZp`n;O7Tf-}C*0Y>(70 zjfezY>ty~MHI97WsP#hm92dWLfS-S;LBGZLsQWtW=gRW6vRb3EQNsK_m7ZM5@SY74 z&w9D1OrFE=^CY~FXarFvvhu!&pW7#T1zyFxf28?Jc>eBRzS6gR?~KR48+k-NCD-|* zfk5ErKluGREN6Tl)4IQ>^7Hc${QOtu&9WYv_b&Y8_lOWof#3hp6P7Uds}XE5fvOxO z@%$V}z8qE~f1 z(=Mo$>J`t2zt>Oo+1GbGTU}3B=zBH4*+0YU0sD2kAy-AnSA)18|MOIvg;_&I&c8~_)N86@cPQ%-?a8s4KhEkGyL6Ge%_7f6LO)+A<0>#>Ic~w zlurA57dFb#Epq)Jd+ZC~to@g*fBV)~s&$LctEs%(R{mf8RG#`pMO(wtu%mga%XKZ& zfxIO8m6P!YfxiQn6PEBqJdZ?lQ#%w7u!APZe3ipx9E!-e5$&1yN%Mo^^=dwIzV)ho z)^BWYvYpA#xf9)5=;ikcS$3u3Ge6hM&%vBqC=1ehN_^n&6mz;-?(n@~$#*Z_l0fZ9 zZ4P~m=YlBc`j+b9=h}E2SstjLVxDuq#*5;j|3V+f!3%vH2QTz-9K4Atxn1`E575VI zJZK+6^wui9mNQqsiA ze|EUv>ZbISO+mAMt=E(=8#5?6@cKxJ2C)WZ6{vQ0hT*&B&II)7{B-*|k^OHCTz zapjfm?P|Otok4%Nt24@7Ufm3a`dfo$UVStY44dgcKX%J&KYL>{%^3<$|Myw%Zo2WR zQ&=|U2mOH-@F$>R9`7;dJ^qu(##y;LKHC;JeaN;KZhvawv=OT=pJw`7h4effojzgk zF$Yr4nlS!%=f2fe7w&Ax4+QgDLxJg?;njXn5g=LY?re?(&F-d9OVF(ETD>~hncoy@ z4d!=twSk%W-J#Ak`R!mZNr^8K3blltAVdba!;$=!=K4;5XEZ+?3FK32&7lFUq4O=a z#`324&H2q?v=B9$TiaWLt--d4pM==#3`V*-+d!qi%?yfB>uL+GYY#SHuv?;EnM!{P zxGLy`G&Q$13a+$-gS5?}ogMAcNF|c_gr(M)ihp_dM}f9vWL7kU0>NJ>`+F>4a%LWf ze_z97THP6HU4yu-tEGiZ2r`$vSOAA1uJ?z7E5Kze3F54U)kgS><{CfuV zlBS)4f5En{)`^Je`D=2Qkfl!h$Cl~Rz=tSyK{2v{3yVKvEH>J+RIQq>xqOs0g>u>48 zTnGm{#rR4YEHi^`0rTWJW;o*SjF^)q2^hSfSu!ARX!YuFFkC7i36ba`;U3ayD317MPm_#;&z)zvI!};}4Ai?}L z|Jvq8sJVY{J8OdtYKm60H8h1f1($S1xgyln*$@=7ua=aS{6%743z3Armx$JIqx=!- zY;J_=54E=YJA;8*G2-D0xt=XU`IVi~g_svh+9C^RMxQ|v5w7a0UlWXmtF74$N$G6% z(+WsBxy(Gxzive^7+4x?Ym784SOgP^=30 z9d23@5(5+~xg5kTSVtC2HOOsm$HWI6(J+Pz!=v(rMGr}_3Kbr9jMeg>5OL(!*o1Yz zA!r}kxn0e$Y1&lp!>57Y^RVcH&+{NzU6CMq7Xg>#07%}7v9G{l*3=q|G&fW#%SsJg zI6vIcmAt%O%+p*kW zCe^kyw>Hz#b@Z&W>XUSS#X7$H5L$F}23uh){yVy+m{I!`dWI^*Hl>z!9c#a=cv`i5 z1u?Sfp#8^}8YR21)MCrFohr^_9XxlCB? zWhU*<>&eh7s4Xl2y}|Y-Y`r`EEw$3iQWflMC7UzUHb2)?`OL!P;At28 z8up9%J3Gn85jM$&j>7hb?+wl|RdgC$QgCzy&8~Lx$`sFVuK)AmpbI&XIsAw_@bCvk`Iz);+V`8psOifRt_@pvj{{zLl;vC1uz)z#T?=^Qz9! z+GgyrR2SGE=U4TMmXrq%SuM9DCU8rTsm2J)1e(@eY^}q^VOhRXG$nsbzudx@esY|x zB_hE_EwdwAXYlL75p>7|kYlQ>kzDBw3xo7Wis{fqBBT*GEE9(&S$Y?`{Nc8gkOY zzoSG)?Nr&X%4{U>6aNkb!%z)khqywS#iSR>6K~F|T4JIma)XkNAn&f^hNLAd zoAs}2ZtcQs!Pd4LW%Fhim;rw@JVot$d4iAwT6mRDQ?rAJAjbjip25SP>ykw%3MSqJpAYihE zM&d?!NS4wDNjZ}_O_wrue1sQbEL)%%=>?IIcq`E4Trx7@eI6qisitS0LQ&<4nq~xr2t3=6yvWn!+ zrWT&Bd9(*4p;#S6m4Xs$&@BT%6+Vi+fW0~B39;XexrI7e7HVmOq>Px*nqV7mQnYzm z8%dBL@v12sV45^pP5AP_dehV@BS6h>jc3YeS9HWy2{mFuV9%hs#4k<4rH0ZFRdUWr zyiJ_7OmoFq#~c~vE?Bf=nYm)Yyz1pkR-QS1<*JqD8HFm%Ait-vLb#7iYhJ514D_59 zqS~&`7NaQ=X%Cm>D_7I>a0urEILv5>gpFV;?4+_Vye(wRm4`b5;pxqxX%ek+m19HL z0Ibm-f>ju`s%wN#tE+xGoT~Yf3LhGegdigMYm4&hTSE2usJ$)UBEK~NvVu6tAs1{5 z48bm#ZJ?pe2n%;E1TYYcSH1L+`Oqh>-tcz?nql{ajY?P#ohyP3)68YTP#_AHDE=&1 zHa`*Pk~cj4{GzwVH$C!D^?AE4doXSKfp32Pqn7V}lHb?#;{CTjyaNr9ay+z5<5UR- zm!^4eR2OIwbB5iYSma?Pmo*2-l^Qz)MK)}kFi(}14#4MHi(>^7##C1eY@L>F=x{Q+ zaQr~(38N!aF0c8*(sfojk2dbA#sO)RI?&l7_<}W%)b)dq$5pR)3!?Nd|Zdf zFt3SrJS*8$j#~*BBKa1d=S(KDEyr>&PaeXAI^)&_a&4+5ZYD`};(U@CO)E*Uw$(Kt z&jRVRwPg~D@zC{XsZy-sv^6jf3A?SO0a+FZkB}`-d}`?6CyqcnGso+mQ2BA_6?j!Z zBg{q&gjeiC;uPnk3gxPdTdqQGNaCg~7rT(SN!TY~=W&Q6$271B2`m;{$pJE;^iNnQ zBU@G{I}el7xtOZ#1M3wTZI$_zD>Kwmt1a&JVqJwQZkLKG5`r35<%F*(`S+i`^-6H- z4X^(4t%cA3HG2QpA6)YH+OtcpE4%8GOTO7}+(YT_cU}9&sJZ7p_D;*MU;ELR1E*c| zuj+M{tvZ%EBmY4Yi@1TB3z8nIYUrAmfjne)C}Om02!8 zb^8klTOoLvXe*8DR%P~bOX069GnbQpugnyH{HbQ@kf!2djxPUt_+a@R7JbC3g&=PHKp=wzd5D^On7zRWL@2iD`eyefPNB= zo`u-d*ZblASl!houUwe8yI^;stb}oh{A74xKTftI)c~y*#61N%Zx`mHyuGJ28Nb+3 z6r%fWbeTe2)*|O3UC)DV6?<28+0XKYtMEq4OID;a zoa=`oB9_6vQdl&CIpP|Z)khj8b$48;ea9j+;9j}qsP@ARO_zR2kFp>~u$8vRty0V0 zlKG++)G@6yoXXtBM4=opbxK2FZ=Kmg=ZphWRRtD(G!f;g8}c zbQmz;egoOlxabdCS+m38Kt$$4-n)=K4Zh6TtPbME)z>m}nl+KkC9qb-jm7H7>e2<& z5IU+*b8%yZbQV>aE3yo{f@(BWh)X3pzVRZ;Rlg}?4#b3ka z_9S_eQ&Lr#wDduPGlpbl^$#6(%<$~~5hF*99&_y2amVGDGDGh1<0njxx0e+GD}>N=C@|WsS5sbC7JDtqD9`yt9&r@{`e!vxWg+5gn+1aB z3L9qiU9Ih=FiBCGR4>Zft~}!|GLCth&6CU-a@6R=J%R~Bh3M1{4`PTJAW#34z1J9o zDJD*mpqAzNy|jA+Au)$x571EzEPYTWuF5Nd$oOP4kSDx2-&N}jPA%!aFEvXOjwtp? zqni%~xwxH4|N7GXES;R_HQmp{$sI@{lnQ+`nirLbOw4Ta) z;DRr$jssd;Z_tmd)rDeKT6EHiLu)eFaHkltxKxbOWZWt?3dhGgW zArN+xU;$rF*P9b%=s69d$sdzLtWpuNH{@kpoa)9F6?)uD)94`#IF>mw&*D@<$KTHK z)K9J3v94iGfY1<~X)_&~VV@PG)w2$l$>?G` z{gh8ZiAf-z)KSk*K!ox9Td+G4ZHN95r)#bLcA6{vm`7C+xm<4OZi zGxeQff7{;Nj;k)>;vElIa9wja5|-j5_D;gvgG1H^+%!RLFqi4Uj1c@!WW!jH^+U+K zaH)XyfG^aBYm{^;PZ_b;gYZ2%JVw~u)vBenghK7~3<}l`(FnCK@5ST=r#DWA9o&is zzScnThuWuzdqO66ifX}hX$!Q#dXl=mxeZTB;Ia#RR+#3Uj3(VfSAGKYsHc4RkNf~w zDAv&I>1v~2V%4HLHR?LLLeN^Qbwz_>6@pfTu9GLrc!Dq-jT!%<;{w-!7Q((ja4jAh zL!ZzI^b_j{(Z)C72pwh}i%ihayv)VMgCw`Jv#T8f08-iJi9Hx7t~_F~B>Ko%Chx>y zxa7mK!jOTV54xfe_bTben?O~D)%_K*sLLflB$#<2EHz{qnN#Ljg1S5?2{dj&AtN4<(>Tpn%n-4jiE9A5aVp<^;$^s#tH6)aC zNhVQ2#e9~?CE?g_3yB;H=)&Q0NMj|0aiJxPv0qCeP%G%}o@$y>77JloB86!Q$&&g# z9|9!Kvd@CptdMs?7vdR5G_*pAPORqBNoW?Rm735iL!qT4F|ez}U4*$1m<5*ejdBoX z9*IjZJYUF57-dewRmr6!ABqUdNWxR0mgJ?77OEPXf+aBt(QJ*_!(|IXt1G)Am8)@< z46&%hvesFx3xtq>GP>!AWX!iCb|xNjo8Ca{7hMYR6|XKV3Cx&LU+*uRRZvj4I-l-RL1T5d`3j~N z7EPZaO2I9vEOA={U*>sT>zU5gtr1lxYYR}zH^c>B_z_=Wh%p_tc#IGh?129J$vTA> zMBD?$GKLl7aF6&7tRFO??kQNR)nlXLzN483^*ec+&1HsBp5ZZiFUAwT^sdSBr0rEPz|dHZW0|Lc@Ld-%m8GFn z>I)i{Up#y3b0fcKzwhyJHg;GypRPd|TMz=L02Q}MxdXFM_Vz&ipy>A?C; z59I8=dfI`%3HYL0s|)kaIsLZ_4}2`(AO8IA2d=%pPLFzytw5S9amVUtSV<#W*-kz#re-ck{1bxOB_02a5#!$NQ&_+?-zY!K{NP3HX}t z&zkyqW9j#+4$c?wiKjgK-*3LS>*6&BmkRjNU;lQ@C3nsMO|GP&I1_b=+Yqc4xR^RvCmkzcFc+x+9_QnnS-~Q->gAoBg(%XOU zjt74D!}Kq{A>b=d{YHzow*In-UtBEU6$L*ns_TF3=cjyem4K@!J$l_$mn^&KtS`PL z;K#o?rF}y8zut^|al3%8edLdi-0}FEcVGL(odW*W1(A&})ZVlIo-ghf@C&!?xb}wj z`9FU8iysJhO?GDA{(Y%ey!pjr0{&59VX%7Q&R_rQi>C#A|N5TY&%S-iEyMeNCE(-} zPni02);aG??|)Iizr8-(e9MFh_b%ywUBE+rVO;d#4=+2|(EpBr|2k&q^?}qsKK9N2 zzX|wP8>>QTzk2MdTlzm1@U-CQw^xmP_&5L6e?Y);>X+aCe1A;2WZm`Rd++tj_fx{s zzyF!Pu6w|vzE^N@+PC(vn|;cL;|zK;fnoetcFNCtp1=9YQe%RE+t2w+&+{|BdF={g znt+>n|9sz_rT_g>t9WY-?j;<5>&QuyEAQB7$oBBSSsM(1@9YkP3m(O?J-sg_||b9bN@B&+^0V@&JpmccaOb$TJvewXSf0a{>#BHUYqP{5%8(qAKZG&cU!m3bwvbx$(jp((6cV>!*g8U5ODXX-$%E;v+@Vsu8Rfy z)HAo8ef_0pUwXakDgn)Ic+BnPKlss(91!rdi)-%A`XFbw>A?p^5T+Df_vb&}nRVNVp1}hC_TbyMetuilyVaiIGX3Kd z>t8kV?r-;u74Ri5Y(M|Jug&kh(lbH8zTe;PDSs!o?=H_Y0bkoc|GfO$8?SlNQzYPu zN3Od4+aqVb_?qV=0pD}%AAWHC??!*;6VH4BzuNugqiuaR{WUXbseq4cy=d%g4tHUF zO{8_r6HKXV;rq%fG*3FoEH0!sVA%Y(foAf);DlcsVGgV+msSZVc(D!3n{pI)DhAf2 zRxvv@)M0wZMgafb^T_WVZMoECl+VpHdT-in7;k;zHGXmHiHGEg^rH@J5yYQea4wd{ z`pE^82PR`j7YWDKz@q5|(|so_^Dl!FHqJt8TQA`y!`ca3N_qca+zp^GW&=*2K38}; zgyAQDp4KJb+rYbJ>|$V-1_Nc5!$ZETD2kVGa7x+P?f$lAT7crG>L+6wD}`F=NKe z8AUT@%_yExGNW|H?3o2K3un&2%f*Uj&YD>~vt(xJ%-KZ+MTJE(ie?rS70oItE-EQ1 zEt);6U{>L*8F+N7Xx6M*#j{FgmCl-7Tu@wCJfnDKaZ&NC;^N|x;?m;TB?TpgB{NE9 zmK2rDDk&~0DJdNRv9fPy>0D(GGLN_#o#_<@Hj#e1+B%ir%#`L zZaub)ZM4myXFBuh1hdr0vB%sbZ=QU07hc13B0cqlBSx%u*s3U}Oi^x}e3G9G* z1M^;O1P3I+@kd8w`R(v1iG43^mXcjAk1NUTO-XU5rlz^my@T9ClCoSw-NU@c3?1&u zc8_$A&KT<*mzv|6;QD&f8ux>qhun|3UvU4%{o>%4(q4AI;(pDw*ZY?H-K6*2@0<9ocGB%f!s$CW?5_rh_W!pyNr6Vi_Jp5UFI zG-PV;y~z`jCM4yh77bc9Z$nAii1gG^CoY)nX-G{g7~#$J9P4$JmnMD9o1c`Pl9p0# zPEHz}R_rPBj!8)xoKm%6Jbectg42Bjxw98;E@UOX*nWbcnp3al8s zI4ynQf@2q_uEN$CsI^SsAgxby7b*OF$Z3@s;-xOso-#V=1y z+xG5;nVGI}$wQJ-H(Ygj(i(4uCoLuG`npAFk&}8qO%JEGXD>W|_~7A#YtlydUbbP8 z=aRXZ*%w#kBq#U2bb|NfTvxl#GbYKsp*&}3nb);p_tXpj)cemVOOw)*+!qae z=v-dv@yj->96S!R6sHbB*0hw~UrtQFIN5M{yx!zwcS>?Cu zmS@SylHy$9W2 zc>2>GSQowW>TLxztFF9i)7ak+$^6>V&ksz`KjoZrYu~>3>T9mM{+@>({mC=W{`?nj zyz|F?BS{E!N!f{WmYjO-#n&M52ao>b*W!aIL7EO9@P+?O$Q!ID6*_u}tA_C()Huk8EBMVDN8=iN{A zJ@ecPul;WE=Er~i?DH=ySyowd=6SW3Uvuq4KYF-+xkNoV-lNY_o1rsr>e z@ZrAaUU=orTgz|WTySm9f4}&A|FX)n&Q3|q%$l74{s(QLk~yc$U9jo86^&iHe!lxR zdtQAPUqm!(kH7HEqzmV#9-EXrbi@5adhhe*q-{9XGdk6kl%G_Tl;UxvB&Q5bugV;j zQk~*S8k?TxN%f?7+)$%~lf0fm$*v*U-eoDrrqraklSdA&N}A{KK|Kvk&Kz8pG;U(8 z*_!nAiM_kL7w+_oNxtx)=ggE5X`|9e;J%)mo;)V`%#;(n3)811K{h;vgQg{oNgm|s zy&p;Wg{OIX?@T?(lj%7rr8M;f?}hzCN2TTu^?7nLb2EFdO1kjo(Sx!#e#@KhJrR;N zDy{d4<0FH6Umi2q+uQH$eRJ@K-}aQGZ8&Fm?<1+bzx1Y$I?4WFdA%&Eypy*jD)3D2>f z%#4HzS}E#Ua`;0>56BlJhaFvY7?47~uzK9i5r)%11GFt9jk|#<0lfSR2bw40(anL0 z(g6=|5Up&mnJ-E*jqAL1#<|CAF@}vaa|WArIUh{ha>CRCb6V)`z0=$~>U_t2UN_zN z!Yuwye_ioG*IUJ|^xTpO8E=)`H^e_Xf7I651!Mh-KRRyf(()pI)xNK9J-srNyZqaa zZC!4>;9n8^&DIshYq=|py>C^2?`?n0-`>eRbN72&&oqtq&)nx)f0ogX*ZTQjSGe(? zYw@6h>?~Ih0^@eOlE%A^JNE2BWoc=yQAw^etZm*CJSU}29py4hP#`H4f{~K$9_K2f z;z_BR}Q7e&zM%@IDbE_d3XlqK$CQJ>3I zGQ@=zy@Om6(p;;PT*)BHJ=&e*$x6z=&tzAo3%vJ?b03HQ%H6J%RF`{DnhVpz)#X0k zwbqm5PID!Deg`Ii+7znMotm8Pb`|6lCKUkoy7JNnyG?Y`zBQfEdIS20$U&*lCrXiG+Xth+juFkdHrAT{X0pyC4oF83!Gc}Rq76WU91ndy1S zVx*GYp6Ot?kphOemX81_sO9`*GytAM+Ndd)fzd7Udg+%dIn#j7FkGi3;WhehW4e1J zUNVf!F{!EUl;e`Vm6Z9$niN#H0VyHA>pTf!OQ zeUofNni2V}GKQV;s=e}kl7y#sNpdjD28*AG(if|A&bN7&Y-jV|Wetz0c*k=RX8cZt zzZ!InRgH~QF-7+Pzg)q!cp>Hl_4{++>AjW|=zW+R*6oc?f2nkJ7)`mtMPU>mABFb4 zA`*XOiiGzZC!xx&4CTebw~nyUmtT6oJJi=^i0|D{?h|36$HOlMp8KTdUjjV6zmtNF zKNWcHi;lkr_;Qikp8p5H<0wJ|J^xd{pAiS|^U8OaQj(tkWZIbD~sd{xjY<$L!WI(_e} zhfd!uU5Q2_`7T#-UAI@htCnhm7+7J~oAPJfTR6W`Se^d;(v@c3h+o|!7 z+vS+ZDfq1VIxD!x*FJr>Gfljs|aZz^fAUck_c%g4XtA80t0X2Ayy6*gEl< zs*Q8LkzvibGl65d+7EoC%CkblZ&;sUEK>MR#4Pu_fam-)hbOB%I{sAPm^K~%;{^GC zm>~am(bahM-vK<=zo9qQuX(74^;y@37@qpU{rws6GXYbe{5-cm1-_h+2*=@Hn)qcH zy?f*9kIiG{x}ujOy?&x9=f5z+;#nzhT%V5jCBO%OXS($KYk+4xq2td6eg^(g(D4u< ziyu1v4;ucUM(3micoTT0U(bJQg8Wwl&-Bc^C_|mT$Zu3|JvzQft6#@gX!r+F&nbW@ zOv69skB;{P&-Lqg(!Vq|6m6LF@bd?ga|_}iP2>O9!5xn zMCmXMDPZ{dinbuaBpXZ)fVM{1?fZShYIfj*6q4}!1Vrd4x=v1uyhpR zPI17i0q1dM#Mc1M)!+vKkJ8}h0PFSdbEpHho{e^R5@6Cd9L@vGx{`3$0@mqy z7%=M;N`Dt{CjC(1Q@~QwNrd}yyIr0QSm)0)z-%K@i6strHQ;htmH2x%;Cu~!39wGz zLBP|s^b@Yg5c-)>@gwlBet0oMETDqx+z zL$Ayb@71Tg6ix)Juk+P_=gTDV_cvI#X?>({68>>tbv)@$9+SsVp65E1`8i;HJdVZs zT|o&5v~DqNI{s_Gv+mUG09w;e#y<)={(iti1lEoxx>hOty_!9tx2xm*$V+Wgcnfrs zp5vg~9c03CzQwS&Q#li2_f;7dErcH9fOR|NW~84%nGkgRR=`}pj^746>yke>>iq{` zY}>5xPrxY_WEfun*2ksELHD4mGsO8S7t!q?;`<3ILC4>b0DrbCCJ%c4D}d*EUg*s* zPE&Q#n#OXV<4NB#AI8GoAv=%)*?lZ;y4@57p2u6ao9NsaO^cx8r)qfJE}}J=^XqoV zAPxUh*da6@C=lN{ziw}k+%sOc6KJo;_z>)ba=;XHI`ws5$KQx?I*$vZ%rV!-){7~C zImv{c(L>9PF}+a)f_WUi2|UkFAJwM{>G;bv{HkGtEd8&`J^LdPr91r=Rj*3=c4re; z@pVWQ@6D7j*NbmnoMG*y zD1C$0KEc-m*86`0V150&*O7i7VAiEn{%Gs(b*xukwZ0#N9$l~X0oL`}ZvgA-<gnJBd2`3`{2=FWo&b!raU!4hfnwEYE zU|xF({WM^3LMK3O#^%FGHwX0rOsi;6A`* z^h1SzIns~2-OiuIfc5$s0qgQ|xdXlru+GmH0PF3444CvJhum-5?ZGO*lQ|J_H( z{A&Qu=E@M?37FSjLca)DmygsfcKW6O*89I0uwI_lDU&KvVI9&>VF2;NfXQCt@DgCX z|DQV2hi|phvluY@IH-<`0PFVq_W|qte;2Sme~#OhVJzgv5eES4{P;FtwgV{JtAH12 z`OWWUSh}9jTLJSr&;rHG`+ObW3VfETL&rA(&+CbfuLjs0x7!4KR14RDN7!$?&BlixUW{TmO{ zewN}#qWVXv`ZprqD8&oC|9h^I?eD&1kfp!$^!-=Lbe*r{YdAsG_0v0J>+FZX@wmPK zJlkL-ccWE)9Z&u<&ZFZSH2jY3Jo2)F+wY3mCCv~3uc}walRU=5j|ZOV)AQ@{rQ`j` z&o+vVpA0-xrQ=UXfX`2WpOpY#ngD-d0{kfn@bePj>DDdVPCEUBkJqo$65#2x-JIXR z{A0P{n1-hJYAHVtVBC1W{{+ghuI~e$X`%ct1LitOzjB#B0I&N~^n7okK9dR~48J=z z@4g0DwmuL~wkrjiH>{&{y7y+w-9!%R<9S2*uhHyOsvAv*w15>+AhX zfU{Luiv9vvw=Ys4_uO|%9}QSfF9xjZ^KSq?fikK<^G3G^p8%}u_s;<9>*s_W8RFZ7 zT>ezR`g+$4n0*$MXFFhh{d>hx{vhDxTp8lZdt&=TLSGA5FW(1Pum2!m9wW-1a<6?o zp9XjVC8)47W3V+&`Z)4_E>XI3KWDxxrEf3l6Jdyq+f!uB`28yVLeRlFh4Nnsm}P?C zs}7U?z9vuc%HN3cEW`2Aw;)~LN2~*^^KH8Weh9GY8C7RI4p`qOJp#K{=ie`p?h!fV zpObKoout9fJL-E4u)Yrd88FXhD)uR0y}i`?^i<5_k%O)J^>%iSkW}X(o%zc#)w}lu znO=Z&p09d8>VT&(3UR#oUZCoybS}p+m0P9Ko%H_b0sHv;6tGU$%MaT9n)?C!sX_$u z@#KkLhVj5o`?#D5nD_O%{@qy=zki#{W&g@6WV~gjjNd{%x?lYnz_g#Ikn4`ElRHo^ z2c7=C3P16om>vwEoT)OO4E%5|hGI)0gk-}(KR9_<32 z*L5AgHUYjn0sj01_@4sL^yu|}20Tltj(4GB&)kIr=o@ad>0Uj9J|@PiZJ zJAmhPRi|ey@HIpvf{wok_;~aOfsfbUuK~|{PQ9KXz{jIML&NWVBzB%~0qEehPsiT_ zJlCV+?@fTeF9H603Gfdlz!U#@j_BNuT`B4M;v&2Mb0W&?dh{f~JeE|>ng0!k9kIZX-&x+-|7FOp^ONX}w~j8} zCHq_YYZ>o*SH=w}&pv==(8sjj1ims}U&nO(hY%LFHFf+fbeP9b$4>|Tcwz#=)sNZv zd85N`6% zm{n|5DqjyMKs+Cb7f;DgECy;jL7+f4;8juh3bT5tnys!zw1`)5H>|0ZFUu482}v*E z({Z3$d-*zK|7q+VTV_(v%^M@9WHmk zO*HWln4W^m?C|Dm>~QZcJG|rPb~x(=JDlf$n|@8_yvYGS;($wkXRoi$0k3nw zTO9Bs4mkC7dwr$@9`$>B`Ys2&*8%Tyz)f%1%a3}~4i`A!atBheKDOs?cfk8Tv8ShgYKM0?U~|7cz0?7hAGD{pJK)U@c&`J_`odnm z)B!h-symMIpEEU?ETq74n9qO-gCfB7ueG`JK(Hu+SBtK@Z$CM z^g0LJ>wp(uWzYY})pmHd1K#I=%Wt*k-*KBA-gCPh-sgb#e#f5PbcY?@?0|PV;PVWGU@J0u`!vXJh!22Dr`Cs<-7CYc32fWb%?{vVs z9q@h!Z2rLB-mX8|;k^!c-=FO1Rqxv2Ee?3M1Afl|?{~nv-m};D-e2tS;=kJA%?@~% z1K#U^_c`Dv|7Nex_=g>?bHFT)N+0zR3aiI^azXxawby@}Jq^y3ZZ(0Xw|zpdH@ifOn_M4LR$FfH$23 zXYc|Z-AnH`-A|n!pspUM?!ZHM0;h04)cXw%Qjg&3!MZ2#0j30%Oz1N40OAa(Fyb>~QRA5P#5Uci&1^nMwf!%MjRP`y5dD-YAX3CC~; zu0I^tKT6$&r|{s>dcN9LH{cfBfd}viPT|IJ`g#!@!(%u&Uaybg0X%{y@c6NMzu*LQ z4A&l~`y37*uloRQJpudr52!ak{}pg>qMmQVDO`D?p07MfUBdB`bsxjMr|3R{b2xpf zp3mXNNxDZ}bqeQjW6LMl+5X3?8C=56ll6QKSDvnW4CkxAc(CQm=0Be$JUdnQ9PXZ` z`v9Jvq5BN(o~e8BEOqc~b@MEB7aqa|Tzj5gAHlPM?n}7-BHd%Sezxudcn$|I*7G&E z0Y~TP`O!<&OSqNjK8Ayr=^n!acmz-2?s(pa- z4j1qePG7J0TfSL6yHMS@NZp4ga0bue;l+Bt!Q0gFJJeG+xJ365ZozH1_D;RNF;OS* z0y4!*AY3~qiy_Yqvc({Jke>9^F2g}Q{J@9Ex#E8o|>4o~395A=K+PT(;-g_m&q zhkE}B-20L4;g8irIEN>>o}d3j9sX23fOEL=Gd&-}-Jk2;y+&R9LLK~4JuKA|xN^Pj zbvT53Z~~9u#-H{6eYk*IOFchUMjI)y9$(7g%Aa0ib6sn<{8;0E2Jn{EAH zu55n45$&v=SJVYOxw-BcT)TztA-ue`?)6>OUATnfs-7Ri-Q9F=-bOuw3wU~4J)btz zwSClGINVqFF+78-_tNwI{nQhnu8?o*Y9K+e8^nCqTbq{X-7xu@f6L4ePTht3kJY_%g1Qg49;f^A z@#@+W)Nx1Mg%fxT*Pp1@H{mwigXd4u>kGK@WZmmKRg+@6?uXUORNefDdH~NprhDb%>J~itr0xaW_>}I!Rq6;H zz^%{g`QQuc_>1b`OX|i~)XlG|`|tuzuGaHocrn*~^mX+DUVc;e^1JHp_tbN^_I=&Q zKUBv*QCF`~_uvf9f2rrgU#W+14o`lq=fmHqhj0$puGRB>cm^-w>UDa39nRs|@AQ05 zm%4|)SJ(fbj^P4s{87)3|D+DCSJ&VPJX-4c-e1(&U)8n0spG$^qZ`zV9k%{2r8d7m zs_m#A@1zcPR!4AhbKPg~^j5lecUAYR>J%>F{_c9dej9akJ9TgebswI>GkAF?y*}PU zJ%+=(=stvVxO!JT-+-I&63*|Y*Dv92UH23o?y36%uHIeu>OIuaJ=F_%xUcT5d#R^z zWk21c1JwC}>UyXiz>|Y@uNS0AqKz$17GxBf$~@54iQ z40j%(*DsGzN3nW*tU84okI_AW$8ZiW;YwTY7aXrH9;?nyP}d%>?!l8M=w3NdU5C3* z*1hr+b#jt=1`nU6`y8&Etb6wq^#m?X)4g%JIy^&NoT;uoTb;pqU-$I6>hLV}2+rZ| z3-o;L9QE>Cb^APZd4W1!J*Z{7?@wd6`%2xTp?VCLaQ#(!z6rPB%B%H!_!@N!PG75g z@H+JpZogjl2|OR^-hZQd0XN>Hd+W{W6wcwsTl9Q*k-7yZaD1_zAH$uu>E3+1x^;;< zc&B=Kse14(bp{9jqkH*o_53~R=4I+WoJ@7^T%n$RKwU}I9e4`QKdR@OA6F0I9G-ka z&rd$7u6#<}h9~eGu4Q_C^Gfv?PT>M>U8UEL;2E65B|QDK-Y@-}dI=}r#SXW=r+fYT z>e0{D^=s5Uxb+L&qifa8zp7(6{Deu6 zN8L-fa}(W%H&q8asb{xRmvHmex>u{}2Hb)>@BkjcOSr7*>oxDF?!n{zbf2#tAhzAl zZ&K{j@EA_v8Jxs=zvZ#&)}z(wW7Nar)a~QdmB*^n6V$;I)O~pLRNa?w z>m=R#@DLuuovvQre42U$7jW%lJs-jm96Vjm51*-SoT+ZZ*>iPoo~7K?33z$3VQkzU^zt0TC7sqRC#I?=rW$M4m>3s)}FJ-J*xhVu{TUj3lD2`6w0=WzH* zz26jG!sAcr`8m9V8=0O@;o?f&2Un>(pHJ#N{_v@+ZAJpNW)W!Ac>s)( z|5O)n^9J2}@EqRqh-Y~}Z8(K1JLvf)9K#*BzN21WyD7YrI=q>>4=>?aMbFP}p&sp` zPHw55!IfL-p4?hJ-c>!kjd~7OZ>xL%4(hz7uHRAJf%|*tp2ADGe-}NU!NFa1Z^83D zbx-cD4(_S0H`M)o)$zU5Q#ja9_YiKuZFmGP;nx0o|LOti)B~XI6Yp^2ai=3k5>;?4>;fM=Y#Hv>e>_4ohPYhPfy3t2Sau5)#@p{c%AO;*Q-;w z@&?_Ta13|g`be+uy-_`ab2xglo=@NzyoAHI==IYJ)g|1&Soa}3g=cVktk;L{P){#W zH{PkPUaHRE-bDBOUFzn0)O~mXH!sukz01}0E7bA()H8VaLES4KQs=39{tl5nyN_FSc>IIyAM)%%l)%DM*ho4s$Ur;x`s7~PGOS;#;qMmH_ZkRQKd(>gea{5#0NQ?#n_w|CKuZjk>&6UHPp#foG-e z(eKrxKdJNU)%8ECXMa&w{-$ohW4QRcp6~oa-G>u+aD$%D;c)#Vo6WDMmTpB0NcZ#zb@E_!cBDEuNi9p^LwE+aj@9#h zxceC0M{wf=-Sfw(t4~m;@Zv<>M^92OpQ>)3q@KXDr|I55S-pT8PuINzXK?itJs-hs zxC=K<)$5DX)w5@)hi9lOXR0%}|18}r|E;b)N8N@SXJLQ7dJY#a(!F)IdIYC0(YQa#^?CvXPO;bEfp8=t4HoUd+Npw3^R&R(gmy-MAK$FJ6X_BwTQ zr0&DZH|ri>s2;+zi*>Jz)#*Fby?3eym#Q;(3HRTn=j;EYj^3l5T&AvHu5QCUID;!w zy?*#Ub@#*SKfeqwC*w7gD2n7^TTV@lV7Vd zIQWh3oom%8T>Y)?@$b~jQa$^1-y8q?(s3|F+7J0cnMEqyC#R_Er>cAK7*63C+&fM0SHQKib&p@B zj?Po3aOLH?H{lrWz_s)B`T<;hgYFSrzE$_^ZR+OR)d`%!b2x`b@6h`Nm#CNTRY#Y> zm#fDgR1ZI-u6$VCh7))UPvLH=_nX7BPwGCqT3wy1qaUfmAFDICgh#oaPk*8gf2tn9 zQ+Nh1;Nj2oeoJ_~ej?=7Q(K;Kxx>~6Xl>ltQN4g0H_^Qf_uv8Cys2J4h8w%<-rPgo z+f&`xTU|X=9m8F?@hCmNgrj41Z$4T*fG5Z4Uc%MK>fVNDC+J>%oVp87>8I-XB^;iN z9UeYi_vlphqOUID@Hx7-;5IyjThG<&J8fHuf9@UhgA2gR7aI z@4!8Pa2u|#pAWtH z@uUlPo~rkoz{yFv*Po`2PgbX=s{5y@OL+VY-6vdN!f#q-s{i`0F1^kUuPm#B+#)XQ_#t(U6jaFOWVJWpN1^$T?G!X?~!rJi35)#KNy zN3T;iUa!vHpq`B2H>wwJQjgvYzeQcXRUN%eoxM}tyi}dQDLjXBcr?-b1@BTP?^Czm zukNSn@julmT*A{Gw?2V>^ZmWHo4UEXI=sC)xSP5Q58xDD!eL$S*MWy{1_%G9*Vo_( z?!rSjg%@zJr@meTj^RE$f>St$gT3&2a18hN*7HNS-q5`XSNGAqvY)yE&kxeQfNKZq z-hsnIbnn7TxO%9bkKismf(y93x8AREn7Rpf;3=HkN3Wm5NmKX9ebvGJ)FHft!~5&` zAsig8dlT-#%?IfDA)LWWIQw_KzVbkI2DhG|`}FDR{weAbuAHiS4bD!}y?VO34Ugd* zuJ`o%4m^ezaP=8_eG4AIDO|#hXX^br@DR@660V=2_lw~HJcV<(dZyklf_v~7p1~zt zdlv2wci|zN!Z}=dw%$L4+wcIMz;k#B*Z*5zuLbwu5uCvVTR-gXie| z8*mKw;W0div*+sl7jOwjXX*Ji+5Gq^Zg&j&A7SK$`igGcZTF5%X> z`g)7=)FoVdx$Yf!2sh5x^AX&J$8ZXV7wG-wZ~@m|q33&W0#D&3Tz#e9FNE9h1kT`K zsQ0VEJve!_o*%=(8+C8P%{S?ud{8}xGk5_9AJXgVa1(CBJ$MLD;2E65!H4zZsliP+ zhI?=VPv8vB;U!#4_2UcS81BLeJccuP0Waa|NA%z{wX5{{5Uwq-!x8;UJ)gkK zU+Z4~jk*QbuhTt-`*7uVdcF=va2sBhdVTfx>JVfdIJk-K4LFAT@ED%KC0x6yzFq`(;US#D zIb7LE@85)nx6-{*Rkz>-&f&&xdVL2T!HwPZd>0$%iH@$xZ_uw%+hfBCx*ZYTX z4ENv!p1?D>fGhu|uV05FxC0O15uCyccnR0`)Q_hLx8XiKf>U_5m)^gGD|gpDhP&__ zuG~YfZ^J`)0?*(AZr@YyKZGZ60S9~Q^$WP98+tz6M?KqDUAdRK3D@@1J%oGk1YW?^ z{q=qk+=IvP91af9`-N}^9>N)1!u137{t?`P`|t=(;RU>eYoWe=6K=zOcnDA7Ib6ck zgY@-7IEH)h5T3$wxP+?*>+AR70Gch`4^QFB=k@wNJb{Cmo=?84UVKG8`l@;gcdpib38!=2n_p8; z;pFSOXK?2my7%GwH+5gY{cq{s`L;TPN8i!CwNO{Ss~*FR@9CcYKs|?Zc=97XU&8et z>pq3ET=xQwexiE@FW}zK_52Xd;L0_6z79ul^%r_RfqTEyeF+Z=-KX#Zu3f9=Q#kvp z?&BNO!{Ao(=j)vv)WuEJ^_|qSo2i4H)s>s8BRJee_aVH5+qcy7132DI_Y@9ptNY}3 z>gpZUJ-C2dchd72T;D_Yl^R{Uc&8r>Ge~%fTR6zet-4& zK=mwC2M4J`xC5tf>rlPE0}tU0?%rFkpTHTsfNO{8^&vcM>OO8SE&o_=# zx8c!Iy3gS1Lv)Yeq@{Zbmk-sw{xEg>;pzmgK0^24k?PSg>S3&o|5Kg7wg0300B$`> z_x!)q{YR@4xb+y_t8H}zcW1iy;SoHAQ+N(9;2bXC5?;c=7xd$;z*V>bM{pbN!F_lD zC-4}az!|)NOStkyeZO_M3CD039>61b3eVsUID}hp2kyf|cmz-36rRHi zxP+H*^~?JHYH$cQ;TUeiJ-81K;SoHAQ+N(9;1XWK)vw_F!y(*+TW}lh!UH&g$8ZYI z;Q|i6iuVJDa0~9heRv2@;0#{CC0w~$Ki(?bfFrmK_uvE`!znz63pkkT$6JF#xCM9M zK0Jgca0V~n60UqrKi(?bfFrmCci=uegePzYFW?eh!qux;2u1HhwvDl z!Wle=bGU?qZ{hvJbvT40xDEH<0X&2!a0V~n60Uq(-%lNG!Y#N1_uv6MgePzYFW>@R z!jDYVxCzH_7aqVPcnZ(p9A3iJg?{`EID*@74^H4QoWgTBhnH~WyZZ6g;U*lz zUAPA)@DLusV|W5j;S|o`8JxofT*6DZ`aSJcgG0Cl$8Zu?B1a13|g9z1}D@ED%L89aw`xP*fr;QhmOID{iOhC6T%9>7C*3{T+S%;2}JQr*H<(;T$gE;754>a2*ce2#(S%;2}JLGk5`)aOEfZ z{_1c8j^H-jf&1_P9>HUH3TN;F&fz5-{8Zm>4X(pYID*@72kyfIcmz-38JxpQxbic7 ze|5MC$8Z-Oz$17H&)^(h!quPa$J>A-xDEH<1RldFoWTpYfP-uFhk z;66Nn6L<)Z;0c_R+OGyT;3nLH+i(}|!wEcsCvXbS;00X3!LRiFR^U3^ zfFrmCci=8OfD?EGPv8`u!8u&Qm0#=oufq*Egqv^+?!bL`0FU4aoWe6WhnH~mH~M}X za0IvE9-P2qIECkM0SDLW$5(?xxCM9MK0Jgca0V~n60TgQA8#FQ!ZF;12k;1gh%igPT@IRz`^hJ{np?H+=N?j8}7n=IDtp-1Ww@@ynqXM30M9X z?;mc!O}GWO;VwLYNAMJ$!8yEytAEh<6Cb?w@3XEx%j6DQ{;#|B@vAp}7V4XB@qFv2 ztNxd}TR$D;HgCP%zg)k~jei~XUoLK^9`B`|z`^mlSK#TBbWh>M>AL4|<-c{W!u5gf z4LCnX_X3VD(7g?3U(h|eTAjhoujxMey1MZVb>&Cu_K(%QU#c5_P#19WN8Rh!t1~!W z>OTF4I{v46u*>ROUGT4OFH<;&tGCqit*Sb>Eqo{Swr*QK=y2tRMse1|c@2C3^t{tv>2u~lN`wWgB zsCyTlN4ghq{|McOaP3IlLwNWQ-J=(%`!7^?2I}Gh_3Rbu%7y9#&fc#3{4(_dUS6Yn zwNO{CRZo`c>Oa&IxcN`r;~Ug%czBB)<@@^xE_czrwX3=d$Ghp?hNrvhUb(%x0oU%R zd#$dn!-Ko)K8DMEb)O%oo*ty0!>vPfA0Mu+JwQD^QeDD}qjawxt!_S49l`yFVQ;JZ z@D!fI-Q)E7?09wUM0NF4^%5SPrh9&ddT^$?_H6a!EOq;N>U^NCzDV7KyKwYkJ)gZy zJ-a|1y+Yl5jk@}J_$}(fR;l*1OcxcdM80Q3vl;FH?2xBkCzU`KazWT>F^r z-H)s1Gj;G~b?>X{>etkj@2Y#>Q#Ze_p8Y^w`=vVnjXJnaUHnd+mFgut_+Q=Ue^Qrl z>w4X%aQ`2=2RFZo{CK>8Ter}?eUN$x&*0!-Jzs~X@Zi3BetfvPh}5Ga)MGe1TKCpN z)ZJJ;eT;f=oVs$ndU%4m`UG_d4?4Q1aQsBw6F7LX?oBv7MfXu(T|7q}Jzt%{(F?G{ zlNajV7^tf+QZM2D+1TO!i*@h3M4iLoxw=o`ZlZhqGWGa8b^Yb)FX{ z+`LZriC1|C7gar_X4hFx<_#JGrHH{;A-6~aQj=j_jlO(2Xw1HhFg70?d_+oAEQp- zFxEXjPMyN@6Lep|@ddi)aQ_XuPcByH^jmc=;NYXWx8V*v|D>K@z`cd;Gk6XUay_5G z<3H;@fye*Qy|UBJ^5aXiv$_Q@?xuTKS2y9=LAuZ3!6~|r&QTXHRVSCLTUV%KIQf|F zm5-~#E7jdktE11TCtp+deyv`>wZG_Ihg*NwJ%$Ij*!m=;&G)z3F6su{f+x4s^V8kc z&HdEv!_*l(UqA1D^YH}h=hbgqT|Zxb<9z-6_>If;^WHbkpRTW$ub;QR*}LoKr*GVU zxt_1QO}$({Uwm^uT|W<7EB3>WxS1=Sy!K@3Hm2pxC&( zeqQv(gF|&+oT|>@%KG`lo9laUfBk&o&7Pj6_sig5{k-AL`OZu9e6)U^@MiDB(fawn zn>|=RpLgRCJYPSbceD4_&*R;=c7eWrbN&3=&EA1~>*on>_Hg}tz>S-5|Mblb3TSsxb{Z9z6Zza=ZS3YH@isB_us8v!i~#x z58?I|x)0u`PS?*P*}Q%U*VfMm+3Yc#z!|)R!}aq#HuvkoV|W2qQ~mf`@BmKX5^k)Y z$Fcc%TI=U;Y}{Vx>-FITUj9JO_kO5u=IY_k)t&Y8H#V<7yiWJ#`gs|fy$3he&%@a4 z9e4(h*U!t?oKLUU*IU5NKkGhRsw?Z~XKd~luAhgoack#of8SyC<8gLNb^BK8=3eT~ z-s;xA>e;>23%I@A-?v!3eh2QtJ$MXH;r1c=`XhLJsP4VP)CpYNNB5wqF4v#$dDFLc zKi!l2tLJcWxbBrm9m9jok>iY8=Z(gqrkKyn%yS%3cD&HWm12Tm{2`&BMhx8UJhbuTYf=j+ec zyLtV}yLE5AN1ec(%XDAB^~-hd!o~Y_AAUeRUVr}B&Br%if4dqeO`abHx ze(D80+h6zDf$A_+_YYN1;02sF^?d7absr8Mp!@I$b?-=Zew4cX5cRyJZaz#sez>~! zNcALEH`?kpy!gYm|2}2)C#{1&s-wMDKTB`@{p@P*zE0iS?$3i)d-j%Xf4+C){jzO; zzO-`dnEwKfiMI5`F#X3iadz z>RG04U8Nq+)b;PEC)cP)zfvdHsYicEda|o}y1ROQ2X%aBb#Pa8 zb5C_=Z}n^+b#Nejh`M%|I=G*@d$>A`)X9U@`O)g(!_--g^)6N)@8E&DcO!MQ z-LJ1#=jV^x_T$OwdwO-dKQCE*PwyPJZC|;2;kNs&{-iWHVcWj)V*NbC)yH$=xBQQ7 zJHPsO`LEQY?S4PDTKYfUwy%C>>s`Cet5?c)+V=C^t+#l1vu)mWwI9FjQ z>7N-K@Z{&5cE*{{-17B_XP$V#GoNzG0na==xbf>P!`AgVr{4JWiKjm8Nx=bUbhn&7 z^Ta1^Idl5zlGUC5zrL*g7UAmuw*F|k<;TUXf35IeUoU!FKkm(oZ2eQ{jkf$axaA*L zm+ZdzSI=CZUw?hlqc_9WuWx+s+x@Fmo7MGOe>T|ipW|%n^_#D=eYZQj`|3Z*t$$l*%eRyD^_#Cp>mIA?SO2)VzP9C` zS6^1&_ExXGxxV+Otsnp9>-AsLULC#h%ldX326x`_PpfZ_o9nyRuiyXr>-=w9kFLH? ztiEhsfAjGlw&mY#-usOQ*8i{dzpHPBTYj8ad-D}vfAjDCwF|g_3%Gy_xPS||fD5>Q z3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_ zxPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS|| zfD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q z3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_ zxPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS|| zfD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q z3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_ zxPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS|| zfD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q z3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_ zxPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS|| zfD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q z3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_ zxPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS|| zfD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q z3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_ zxPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS|| zfD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q z3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_ zxPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS|| zfD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q z3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_ zxPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS|| zfD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q z3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_ zxPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS|| zfD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q z3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_ zxPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS|| zfD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q z3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_ zxPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS|| zfD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q z3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_ zxPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS|| zfD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q z3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_ zxPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS|| zfD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q z3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_ zxPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS|| zfD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q z3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_ zxPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS|| zfD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q z3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_ zxPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS|| zfD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q z3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_ zxPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS|| zfD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q z3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_ zxPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS|| zfD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q h3%Gy_xPS||fD5>Q3%Gy_xPS||fD5>Q3;e$d{9m5z6u$rf literal 0 HcmV?d00001 diff --git a/package.json b/package.json index c150396..4883004 100644 --- a/package.json +++ b/package.json @@ -38,6 +38,7 @@ "@solana/spl-token": "0.4.9", "@solana/spl-token-metadata": "0.1.6", "@solana/web3.js": "1.95.4", + "@sqds/multisig": "2.1.4", "@switchboard-xyz/on-demand": "1.2.54", "@types/bn.js": "5.1.6", "anchor-bankrun": "0.5.0", diff --git a/test/constants/squads.constant.ts b/test/constants/squads.constant.ts new file mode 100644 index 0000000..21a283e --- /dev/null +++ b/test/constants/squads.constant.ts @@ -0,0 +1,3 @@ +import { PublicKey } from "@solana/web3.js"; + +export const SQUADS_PROGRAM_ID = new PublicKey('SQDS4ep65T869zMMBKyuUq6aD6EgTu8psMjkvj52pCf'); \ No newline at end of file diff --git a/test/data-feed.test.ts b/test/data-feed.test.ts index a68d524..ff50f03 100644 --- a/test/data-feed.test.ts +++ b/test/data-feed.test.ts @@ -478,7 +478,7 @@ describe('data-feed', () => { const feedUpdatedAtSlot = 348058928n; it('when underlying Switchboard feed is valid', async () => { - const fixture = await vaultsFixture(feedUpdatedAtSlot); + const fixture = await vaultsFixture(undefined, feedUpdatedAtSlot); const feed = await createNewFeed(fixture, { mode: 'switchboard', @@ -512,7 +512,7 @@ describe('data-feed', () => { }); it('should fail: when underlying Switchboard feed is stale', async () => { - const fixture = await vaultsFixture(feedUpdatedAtSlot + 150n); + const fixture = await vaultsFixture(undefined, feedUpdatedAtSlot + 150n); const feed = await createNewFeed(fixture, { mode: 'switchboard', @@ -547,7 +547,7 @@ describe('data-feed', () => { }); it('should fail: when price is > max price', async () => { - const fixture = await vaultsFixture(feedUpdatedAtSlot); + const fixture = await vaultsFixture(undefined, feedUpdatedAtSlot); const feed = await createNewFeed(fixture, { mode: 'switchboard', @@ -582,7 +582,7 @@ describe('data-feed', () => { }); it('should fail: when price is < min price', async () => { - const fixture = await vaultsFixture(feedUpdatedAtSlot); + const fixture = await vaultsFixture(undefined, feedUpdatedAtSlot); const feed = await createNewFeed(fixture, { mode: 'switchboard', diff --git a/test/fixture/ac.fixture.ts b/test/fixture/ac.fixture.ts index caeccdf..e6a1ae0 100644 --- a/test/fixture/ac.fixture.ts +++ b/test/fixture/ac.fixture.ts @@ -6,11 +6,11 @@ import { AccessControl } from 'target/types/access_control'; import ACCESS_CONTROL_IDL from '../../target/idl/access_control.json' with { type: 'json' }; import { AC_ROLES } from '../constants/ac.constants'; import { acRoleToBuffer, generateAcRoleAccount } from '../helpers/ac.helpers'; -import { initBankrun, processTransaction } from '../helpers/common.helpers'; +import { initBankrun, InitBankrunReturnType, processTransaction } from '../helpers/common.helpers'; import { generateAcAccount } from '../helpers/vaults.helpers'; -export const acFixture = async (initSlot?: bigint) => { - const { provider, context, accounts } = await initBankrun(10, initSlot); +export const acFixture = async (fixture?: InitBankrunReturnType, initSlot?: bigint) => { + const { provider, context, accounts } = fixture ?? await initBankrun(10, initSlot); const [authority, ...regularAccounts] = accounts; // eslint-disable-next-line @typescript-eslint/no-explicit-any diff --git a/test/fixture/dafa-feed.fixture.ts b/test/fixture/dafa-feed.fixture.ts index 95dcec4..b25bbaf 100644 --- a/test/fixture/dafa-feed.fixture.ts +++ b/test/fixture/dafa-feed.fixture.ts @@ -8,7 +8,7 @@ import DATA_FEED_IDL from '../../target/idl/data_feed.json' with { type: 'json' import { AC_ROLES } from '../constants/ac.constants'; import { DATA_FEED_AC_ROLES } from '../constants/data-feed.constants'; import { acRoleToBuffer, getAccountAcRoleStatePda } from '../helpers/ac.helpers'; -import { formatUnits, parseUnits, processTransaction, toBN } from '../helpers/common.helpers'; +import { formatUnits, InitBankrunReturnType, parseUnits, processTransaction, toBN } from '../helpers/common.helpers'; import { DataFeedMode, generateFeedAcccount, @@ -65,8 +65,8 @@ const initMockedFeeds = async (context: ProgramTestContext) => { }; }; -export const dataFeedFixture = async (initSlot?: bigint) => { - const acF = await acFixture(initSlot); +export const dataFeedFixture = async (fixture?: InitBankrunReturnType, initSlot?: bigint) => { + const acF = await acFixture(fixture, initSlot); const { provider, diff --git a/test/fixture/squads.fixture.ts b/test/fixture/squads.fixture.ts new file mode 100644 index 0000000..4b01094 --- /dev/null +++ b/test/fixture/squads.fixture.ts @@ -0,0 +1,125 @@ +import { Program } from '@coral-xyz/anchor'; +import { Keypair, PublicKey, Transaction } from '@solana/web3.js'; + +import { AccessControl } from 'target/types/access_control'; + +import ACCESS_CONTROL_IDL from '../../target/idl/access_control.json' with { type: 'json' }; +import { AC_ROLES } from '../constants/ac.constants'; +import { acRoleToBuffer, generateAcRoleAccount } from '../helpers/ac.helpers'; +import { initBankrun, processTransaction } from '../helpers/common.helpers'; +import { generateAcAccount } from '../helpers/vaults.helpers'; +import { ProgramTestContext } from 'solana-bankrun'; +import { DAY } from '../constants/common.constants'; +import * as multisig from "@sqds/multisig"; +import { SQUADS_PROGRAM_ID } from '../constants/squads.constant'; + +const createMultisig = async (context: ProgramTestContext, { + authority, + timelock = 2n * DAY, + connection, + member +}: { + authority: Keypair, + member?: PublicKey + timelock?: bigint; + connection: any; +}) => { + const createKey = Keypair.generate(); + const [multisigPda] = multisig.getMultisigPda({ + createKey: createKey.publicKey, + }); + + const programConfigPda = multisig.getProgramConfigPda({})[0]; + + const programConfig = + await multisig.accounts.ProgramConfig.fromAccountAddress( + connection, + programConfigPda + ); + + const configTreasury = programConfig.treasury; + + await processTransaction(context, new Transaction().add(multisig.instructions.multisigCreateV2({ + // Must sign the transaction, unless the .rpc method is used. + createKey: createKey.publicKey, + // The creator & fee payer + creator: authority.publicKey, + // The PDA of the multisig you are creating, derived by a random PublicKey + multisigPda, + // Here the config authority will be the system program + configAuthority: null, + // Create without any time-lock + timeLock: Number(timelock), + // List of the members to add to the multisig + members: [{ + // Members Public Key + key: member ?? authority.publicKey, + // Granted Proposer, Voter, and Executor permissions + permissions: multisig.types.Permissions.all(), + }, + + ], + // This means that there needs to be 2 votes for a transaction proposal to be approved + threshold: 1, + // This is for the program config treasury account + treasury: configTreasury, + // Rent reclaim account + rentCollector: null + })), [authority, createKey]); + + return multisigPda as PublicKey; + +} + +export const squadsFixture = async (initSlot?: bigint) => { + const { provider, context, accounts } = await initBankrun(10, initSlot, [{ + name: 'external/squads', + programId: SQUADS_PROGRAM_ID, + }]); + + const [authority, ...regularAccounts] = accounts; + + + const mockAccounts = [{ + data: Buffer.from('xNJa55CVjD92Raz2HiWPdZHPcd7iP2i7V0ot8H6/wFdsT5Tc2zbKegAAAAAAAAAAPpPXMsRIJCeQ0tu1MaQKvRnxbFXjEyz/UnetydaTq1oAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA', + 'base64'), + publicKey: new PublicKey('BSTq9w3kZwNwpBXJEvTZz2G9ZTNyKBvoSeXMvwb4cNZr'), + owner: SQUADS_PROGRAM_ID, + }] + + for (const account of mockAccounts) { + context.setAccount(account.publicKey, { + data: account.data, + owner: account.owner, + lamports: 10000, + executable: false + }); + } + + + const mutlisigPda = await createMultisig(context, { + authority, + connection: provider.connection, + }); + + + const squadsConnection = provider.connection as any; + + return { + provider, + context, + authority, + mutlisigPda, + regularAccounts, + squadsConnection, + accounts, + getMutlisigData: async (pda?: PublicKey) => { + return await multisig.accounts.Multisig.fromAccountAddress( + squadsConnection, + pda ?? mutlisigPda + ); + } + }; +}; + +export type SquadsFixtureReturnType = Awaited>; diff --git a/test/fixture/vaults.fixture.ts b/test/fixture/vaults.fixture.ts index 3c1ecd5..b241233 100644 --- a/test/fixture/vaults.fixture.ts +++ b/test/fixture/vaults.fixture.ts @@ -20,6 +20,7 @@ import { acRoleToBuffer, getAccountAcRoleStatePda } from '../helpers/ac.helpers' import { createMint, getOrCreateAta, + InitBankrunReturnType, parseUnits, processTransaction, toBN, @@ -34,8 +35,8 @@ import { import { dataFeedFixture } from './dafa-feed.fixture'; import { tokenAuthorityFixture } from './token-authority.fixture'; -export const vaultsFixture = async (initSlot?: bigint) => { - const dfFixture = await dataFeedFixture(initSlot); +export const vaultsFixture = async (fixture?: InitBankrunReturnType, initSlot?: bigint) => { + const dfFixture = await dataFeedFixture(fixture, initSlot); const taFixture = await tokenAuthorityFixture(dfFixture); const { diff --git a/test/helpers/common.helpers.ts b/test/helpers/common.helpers.ts index 482df0c..4664ea2 100644 --- a/test/helpers/common.helpers.ts +++ b/test/helpers/common.helpers.ts @@ -21,11 +21,13 @@ import { Signer, SystemProgram, Transaction, + VersionedTransaction, } from '@solana/web3.js'; import { BankrunProvider } from 'anchor-bankrun'; import BN from 'bn.js'; import { AddedAccount, + AddedProgram, BanksTransactionMeta, Clock, ProgramTestContext, @@ -39,6 +41,7 @@ import { MidasVaults } from '@/target/types/midas_vaults'; import { TokenAuthority } from '@/target/types/token_authority'; import { DEFAULT_PUBKEY } from '../constants/common.constants'; +import { SQUADS_PROGRAM_ID } from '../constants/squads.constant'; // import { ZERO_ADDRESS } from "test/constants/common.constants"; export interface OptionalCommonParams { @@ -57,7 +60,19 @@ export function numToHex(decimalCode: number): string { return hexCode; } -export const initBankrun = async (numAccounts = 10, initSlot?: bigint) => { +export type InitBankrunReturnType = { + context: ProgramTestContext; + provider: BankrunProvider; + accounts: Keypair[]; +}; + +let bunrunReturnCache: InitBankrunReturnType | null = null; + +export const initBankrun = async (numAccounts = 10, initSlot?: bigint, extraPrograms: AddedProgram[] = []) => { + if (bunrunReturnCache) { + return bunrunReturnCache; + } + const accounts: Keypair[] = []; const accountsToInject: AddedAccount[] = []; @@ -77,7 +92,8 @@ export const initBankrun = async (numAccounts = 10, initSlot?: bigint) => { }); } - const context = await startAnchor('.', [], [...accountsToInject]); + const context = await startAnchor('.', extraPrograms, [...accountsToInject]); + if (initSlot) { await warpToSlot(context, initSlot); } @@ -85,11 +101,13 @@ export const initBankrun = async (numAccounts = 10, initSlot?: bigint) => { anchor.setProvider(provider); - return { + bunrunReturnCache = { context, provider, accounts, }; + + return bunrunReturnCache; }; export const fromBN = (bn?: BN) => { @@ -118,7 +136,7 @@ export const findPDA = ( export const expectTxReverted = async ( ctx: ProgramTestContext, - transaction: web3.Transaction, + transaction: Transaction | VersionedTransaction, signers: (Keypair | Signer)[], opt?: OptionalCommonParams, ) => { @@ -206,7 +224,7 @@ export const expectEvents = async ( export const expectTxNotReverted = async ( ctx: ProgramTestContext, - transaction: Transaction, + transaction: Transaction | VersionedTransaction, signers: (Keypair | Signer)[], ) => { try { @@ -228,7 +246,7 @@ export const warpToSlot = async (ctx: ProgramTestContext, slot: bigint) => { export const processTransaction = async ( ctx: ProgramTestContext, - transaction: Transaction, + transaction: Transaction | VersionedTransaction, signers: (Keypair | Signer)[], ) => { // Need to generate new blockhash @@ -238,8 +256,12 @@ export const processTransaction = async ( const blockHash = ctx.lastBlockhash; const client = ctx.banksClient; - transaction.recentBlockhash = blockHash; - transaction.sign(...signers); + if(transaction instanceof Transaction) { + transaction.recentBlockhash = blockHash; + transaction.sign(...signers); + } else { + transaction.sign([...signers]); + } return await client.processTransaction(transaction); }; diff --git a/test/squads.test.ts b/test/squads.test.ts new file mode 100644 index 0000000..4b7055d --- /dev/null +++ b/test/squads.test.ts @@ -0,0 +1,196 @@ +import { LAMPORTS_PER_SOL, SystemProgram, Transaction } from "@solana/web3.js"; +import { DAY } from "./constants/common.constants"; +import { squadsFixture } from "./fixture/squads.fixture"; +import { sendSquadsTxWithTimelock } from "./testers/squads.testers"; +import * as multisig from "@sqds/multisig"; +import { processTransaction } from "./helpers/common.helpers"; +import { acFixture } from "./fixture/ac.fixture"; +import { grantRole } from "./testers/ac.testers"; +import { AC_ROLES } from "./constants/ac.constants"; +import { acRoleToBuffer } from "./helpers/ac.helpers"; + +describe('Squads multisig', () => { + describe('initializing', () => { + it('should create multisig', async () => { + const { getMutlisigData, authority } = await squadsFixture(); + const data = await getMutlisigData(); + expect(data.members.length).toBe(1); + expect(data.members[0].key.equals(authority.publicKey)).toBe(true); + expect(data.threshold).toBe(1); + expect(data.timeLock).toBe(Number(2n * DAY)); + }); + }); + + + describe('timelock', () => { + it('regular sol transfer with timelock', async () => { + const fixture = await squadsFixture(); + const { mutlisigPda, getMutlisigData, authority, regularAccounts, context } = fixture; + + const [vaultPda] = multisig.getVaultPda({ + multisigPda: mutlisigPda as any, + index: 0, + }); + + await processTransaction(context, + new Transaction().add(SystemProgram.transfer({ + fromPubkey: authority.publicKey, + toPubkey: vaultPda, + lamports: LAMPORTS_PER_SOL, + })), [authority]); + + + const instructions = [ + SystemProgram.transfer({ + fromPubkey: vaultPda, + toPubkey: regularAccounts[0].publicKey, + lamports: LAMPORTS_PER_SOL, + }), + ]; + + await sendSquadsTxWithTimelock(fixture, { + instructions, + }); + }); + + it('custom instruction with timelock', async () => { + const fixture = await squadsFixture(); + const fixtureAc = await acFixture(fixture); + + const { mutlisigPda, getMutlisigData, authority, regularAccounts, context } = fixture; + + const [vaultPda] = multisig.getVaultPda({ + multisigPda: mutlisigPda as any, + index: 0, + }); + + + await processTransaction(context, + new Transaction().add(SystemProgram.transfer({ + fromPubkey: authority.publicKey, + toPubkey: vaultPda, + lamports: LAMPORTS_PER_SOL, + })), [authority]); + + await grantRole(fixtureAc, { + account: vaultPda, + acRole: fixtureAc.acRoleGlobal.publicKey, + role: AC_ROLES.ADMIN, + }); + + + const instructions = [ + await fixtureAc.acProgram.methods.grantRole(acRoleToBuffer(AC_ROLES.UPDATE_ACCOUNT_AC)) + .accounts({ + acRole: fixtureAc.acRoleGlobal.publicKey, + authority: vaultPda, + account: regularAccounts[0].publicKey, + }) + .instruction(), + ]; + + await sendSquadsTxWithTimelock(fixture, { + instructions, + }); + }); + + it('should fail: sol transfer but timelock is not passed', async () => { + const fixture = await squadsFixture(); + const { mutlisigPda, getMutlisigData, authority, regularAccounts, context } = fixture; + + const [vaultPda] = multisig.getVaultPda({ + multisigPda: mutlisigPda as any, + index: 0, + }); + + await processTransaction(context, + new Transaction().add(SystemProgram.transfer({ + fromPubkey: authority.publicKey, + toPubkey: vaultPda, + lamports: LAMPORTS_PER_SOL, + })), [authority]); + + + const instructions = [ + SystemProgram.transfer({ + fromPubkey: vaultPda, + toPubkey: regularAccounts[0].publicKey, + lamports: LAMPORTS_PER_SOL, + }), + ]; + + await sendSquadsTxWithTimelock(fixture, { + instructions, + waitForTimelock: false, + }, { + revertedWithExecute: '0x1785', + }); + }); + + it('should fail: sol transfer create from non-member', async () => { + const fixture = await squadsFixture(); + const { mutlisigPda, getMutlisigData, authority, regularAccounts, context } = fixture; + + const [vaultPda] = multisig.getVaultPda({ + multisigPda: mutlisigPda as any, + index: 0, + }); + + await processTransaction(context, + new Transaction().add(SystemProgram.transfer({ + fromPubkey: authority.publicKey, + toPubkey: vaultPda, + lamports: LAMPORTS_PER_SOL, + })), [authority]); + + + const instructions = [ + SystemProgram.transfer({ + fromPubkey: vaultPda, + toPubkey: regularAccounts[0].publicKey, + lamports: LAMPORTS_PER_SOL, + }), + ]; + + await sendSquadsTxWithTimelock(fixture, { + instructions, + }, { + revertedWithCreate: '0x1775', + fromCreate: regularAccounts[1], + }); + }); + + it('should fail: sol transfer execite from non-member', async () => { + const fixture = await squadsFixture(); + const { mutlisigPda, getMutlisigData, authority, regularAccounts, context } = fixture; + + const [vaultPda] = multisig.getVaultPda({ + multisigPda: mutlisigPda as any, + index: 0, + }); + + await processTransaction(context, + new Transaction().add(SystemProgram.transfer({ + fromPubkey: authority.publicKey, + toPubkey: vaultPda, + lamports: LAMPORTS_PER_SOL, + })), [authority]); + + + const instructions = [ + SystemProgram.transfer({ + fromPubkey: vaultPda, + toPubkey: regularAccounts[0].publicKey, + lamports: LAMPORTS_PER_SOL, + }), + ]; + + await sendSquadsTxWithTimelock(fixture, { + instructions, + }, { + revertedWithExecute: '0x1775', + fromExecute: regularAccounts[1], + }); + }); + }); +}) \ No newline at end of file diff --git a/test/testers/squads.testers.ts b/test/testers/squads.testers.ts new file mode 100644 index 0000000..07668b9 --- /dev/null +++ b/test/testers/squads.testers.ts @@ -0,0 +1,120 @@ +import { instructions } from "@sqds/multisig"; +import { SquadsFixtureReturnType } from "../fixture/squads.fixture"; +import { Keypair, LAMPORTS_PER_SOL, SystemProgram, Transaction, TransactionInstruction, TransactionMessage, VersionedTransaction } from "@solana/web3.js"; +import { expectTxNotReverted, expectTxReverted, OptionalCommonParams, timeTravel } from "../helpers/common.helpers"; +import * as multisig from "@sqds/multisig"; +import { DAY } from "../constants/common.constants"; + + + +export const sendSquadsTxWithTimelock = async (fixture: SquadsFixtureReturnType, { + waitForTimelock = true, + instructions, +}: { + instructions: TransactionInstruction[]; + waitForTimelock?: boolean; +}, opt?: { + revertedWithCreate?: string; + revertedWithExecute?: string; + fromCreate?: Keypair; + fromExecute?: Keypair; +}) => { + const { mutlisigPda, getMutlisigData, authority, squadsConnection } = fixture; + + const fromCreate = opt?.fromCreate ?? authority; + const fromExecute = opt?.fromExecute ?? authority; + + // Derive the PDA of the Squads Vault + const [vaultPda] = multisig.getVaultPda({ + multisigPda: mutlisigPda as any, + index: 0, + }); + + // Get deserialized multisig account info + const multisigInfo = await multisig.accounts.Multisig.fromAccountAddress( + squadsConnection, + mutlisigPda as any + ); + // Get the updated transaction index + const newTransactionIndex = BigInt(multisigInfo.transactionIndex.toString()) + 1n; + + // Build a message with instructions we want to execute + const txMessage = new TransactionMessage({ + payerKey: vaultPda, + recentBlockhash: fixture.context.lastBlockhash, + instructions: instructions, + }); + + const txCreate = new Transaction().add( + multisig.instructions.vaultTransactionCreate({ + multisigPda: mutlisigPda as any, + transactionIndex: newTransactionIndex, + creator: fromCreate.publicKey, + vaultIndex: 0, + ephemeralSigners: 0, + transactionMessage: txMessage as any, + }), + multisig.instructions.proposalCreate({ + multisigPda: mutlisigPda as any, + transactionIndex: newTransactionIndex, + creator: fromCreate.publicKey, + }), + multisig.instructions.proposalApprove({ + multisigPda: mutlisigPda as any, + transactionIndex: newTransactionIndex, + member: fromCreate.publicKey, + + }), + ); + + if (opt?.revertedWithCreate !== undefined) { + await expectTxReverted(fixture.context, txCreate, [fromCreate], { + revertedWith: opt.revertedWithCreate, + }); + return; + } + + await expectTxNotReverted(fixture.context, txCreate, [fromCreate]); + + const [proposalPda] = multisig.getProposalPda({ + multisigPda: mutlisigPda as any, + transactionIndex: newTransactionIndex, + }); + const createdProposal = await multisig.accounts.Proposal.fromAccountAddress(squadsConnection, proposalPda); + + expect(createdProposal.status.__kind).toBe('Approved'); + + const inxExecute = await multisig.instructions.vaultTransactionExecute({ + connection: squadsConnection, + multisigPda: mutlisigPda as any, + member: fromExecute.publicKey, + transactionIndex: newTransactionIndex, + }) + + const txExecute = new VersionedTransaction(new TransactionMessage({ + payerKey: fromExecute.publicKey, + recentBlockhash: fixture.context.lastBlockhash, + instructions: [inxExecute.instruction], + }).compileToV0Message(inxExecute.lookupTableAccounts)); + + + if (waitForTimelock) { + const currentTime = await fixture.context.banksClient.getClock().then(clock => clock.unixTimestamp); + const txApprovedAt = BigInt(createdProposal.status.__kind === 'Approved' ? createdProposal.status.timestamp.toString() : 0); + const timelockDuration = 2n * DAY; + const timelockEndsAt = txApprovedAt + timelockDuration; + const deltaTime = timelockEndsAt - BigInt(currentTime); + await timeTravel(fixture.context, deltaTime); + } + + + if (opt?.revertedWithExecute !== undefined) { + await expectTxReverted(fixture.context, txExecute, [fromExecute], { + revertedWith: opt.revertedWithExecute, + }); + return; + } + + await expectTxNotReverted(fixture.context, txExecute, [fromExecute]); + +} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 4621cb4..cf3d274 100644 --- a/yarn.lock +++ b/yarn.lock @@ -447,6 +447,48 @@ __metadata: languageName: node linkType: hard +"@metaplex-foundation/beet-solana@npm:0.4.0": + version: 0.4.0 + resolution: "@metaplex-foundation/beet-solana@npm:0.4.0" + dependencies: + "@metaplex-foundation/beet": "npm:>=0.1.0" + "@solana/web3.js": "npm:^1.56.2" + bs58: "npm:^5.0.0" + debug: "npm:^4.3.4" + checksum: 10c0/52a3b66e51e7c326c3a106cc01129e11ab12e44bfc503725ffbff8f7adfbafd226f4b6e4095a8ae5dc350b88c7156d599ffc44733b5e34ca18d3278b5fb9b3b2 + languageName: node + linkType: hard + +"@metaplex-foundation/beet@npm:0.7.1": + version: 0.7.1 + resolution: "@metaplex-foundation/beet@npm:0.7.1" + dependencies: + ansicolors: "npm:^0.3.2" + bn.js: "npm:^5.2.0" + debug: "npm:^4.3.3" + checksum: 10c0/9b643f519261eac9dab49291a0b66a1ec21189dd90c40a0a3d28197f4b0c7af465848164ab7ed995c72c81c656665bd21f7e71a66d9cb72257ea997f17c1ed19 + languageName: node + linkType: hard + +"@metaplex-foundation/beet@npm:>=0.1.0": + version: 0.7.2 + resolution: "@metaplex-foundation/beet@npm:0.7.2" + dependencies: + ansicolors: "npm:^0.3.2" + assert: "npm:^2.1.0" + bn.js: "npm:^5.2.0" + debug: "npm:^4.3.3" + checksum: 10c0/38c2eb1664b0becf7d1afaa331b8406df5632a7593b8be953bc44f397dadc96c4a1b9b3e0e22aebfd5f8a0c8756cf6172cd76cf29dff5fc723408786da84ebc1 + languageName: node + linkType: hard + +"@metaplex-foundation/cusper@npm:^0.0.2": + version: 0.0.2 + resolution: "@metaplex-foundation/cusper@npm:0.0.2" + checksum: 10c0/0bd4cc82526df04f9db7505c473ea502b816791d8f392fef9f779ed17ee5e8b6375947578039873dcd1c973596b01423acf2cef0a8c240cb2a7ead5c2373e009 + languageName: node + linkType: hard + "@napi-rs/wasm-runtime@npm:^0.2.11": version: 0.2.12 resolution: "@napi-rs/wasm-runtime@npm:0.2.12" @@ -831,6 +873,17 @@ __metadata: languageName: node linkType: hard +"@solana/codecs-core@npm:2.3.0": + version: 2.3.0 + resolution: "@solana/codecs-core@npm:2.3.0" + dependencies: + "@solana/errors": "npm:2.3.0" + peerDependencies: + typescript: ">=5.3.3" + checksum: 10c0/efef080b94fe572bcfeac9f1c0b222700203bd2b45c9590e77445b35335d0ed2582d1cc4e533003d2090c385c06eb93dfa05388f9766182aa60ce85eacfd8042 + languageName: node + linkType: hard + "@solana/codecs-data-structures@npm:2.0.0-rc.1": version: 2.0.0-rc.1 resolution: "@solana/codecs-data-structures@npm:2.0.0-rc.1" @@ -856,6 +909,18 @@ __metadata: languageName: node linkType: hard +"@solana/codecs-numbers@npm:^2.1.0": + version: 2.3.0 + resolution: "@solana/codecs-numbers@npm:2.3.0" + dependencies: + "@solana/codecs-core": "npm:2.3.0" + "@solana/errors": "npm:2.3.0" + peerDependencies: + typescript: ">=5.3.3" + checksum: 10c0/0780d60771e451cfe22ea614315fed2f37507aa62f83cddb900186f88d4d4532eea298d74796d1dbc8c34321a570b5d9ada25e8f4a5aeadd57aa4e688b4465f5 + languageName: node + linkType: hard + "@solana/codecs-strings@npm:2.0.0-rc.1": version: 2.0.0-rc.1 resolution: "@solana/codecs-strings@npm:2.0.0-rc.1" @@ -899,6 +964,20 @@ __metadata: languageName: node linkType: hard +"@solana/errors@npm:2.3.0": + version: 2.3.0 + resolution: "@solana/errors@npm:2.3.0" + dependencies: + chalk: "npm:^5.4.1" + commander: "npm:^14.0.0" + peerDependencies: + typescript: ">=5.3.3" + bin: + errors: bin/cli.mjs + checksum: 10c0/55bef8828b4a6bb5222d3dbfe27162684906ba90753126b9cfd1e8e39c6c29209c0f4f331cfb1d3d1cf43fd456022af92337b4234a145d8de292588197c12c71 + languageName: node + linkType: hard + "@solana/options@npm:2.0.0-rc.1": version: 2.0.0-rc.1 resolution: "@solana/options@npm:2.0.0-rc.1" @@ -951,7 +1030,7 @@ __metadata: languageName: node linkType: hard -"@solana/spl-token@npm:^0.3.4": +"@solana/spl-token@npm:^0.3.4, @solana/spl-token@npm:^0.3.6": version: 0.3.11 resolution: "@solana/spl-token@npm:0.3.11" dependencies: @@ -988,6 +1067,29 @@ __metadata: languageName: node linkType: hard +"@solana/web3.js@npm:^1.56.2, @solana/web3.js@npm:^1.70.3": + version: 1.98.4 + resolution: "@solana/web3.js@npm:1.98.4" + dependencies: + "@babel/runtime": "npm:^7.25.0" + "@noble/curves": "npm:^1.4.2" + "@noble/hashes": "npm:^1.4.0" + "@solana/buffer-layout": "npm:^4.0.1" + "@solana/codecs-numbers": "npm:^2.1.0" + agentkeepalive: "npm:^4.5.0" + bn.js: "npm:^5.2.1" + borsh: "npm:^0.7.0" + bs58: "npm:^4.0.1" + buffer: "npm:6.0.3" + fast-stable-stringify: "npm:^1.0.0" + jayson: "npm:^4.1.1" + node-fetch: "npm:^2.7.0" + rpc-websockets: "npm:^9.0.2" + superstruct: "npm:^2.0.2" + checksum: 10c0/73bf7b6b5b65c7f264587182bbfd65327775b4f3e4831750de6356f58858e57d49213098eec671650940bb7a9bbaa1f352e0710c4075f126d903d72ddddcbdbc + languageName: node + linkType: hard + "@solana/web3.js@npm:^1.95.3, @solana/web3.js@npm:^1.95.8": version: 1.95.8 resolution: "@solana/web3.js@npm:1.95.8" @@ -1036,6 +1138,24 @@ __metadata: languageName: node linkType: hard +"@sqds/multisig@npm:2.1.4": + version: 2.1.4 + resolution: "@sqds/multisig@npm:2.1.4" + dependencies: + "@metaplex-foundation/beet": "npm:0.7.1" + "@metaplex-foundation/beet-solana": "npm:0.4.0" + "@metaplex-foundation/cusper": "npm:^0.0.2" + "@solana/spl-token": "npm:^0.3.6" + "@solana/web3.js": "npm:^1.70.3" + "@types/bn.js": "npm:^5.1.1" + assert: "npm:^2.0.0" + bn.js: "npm:^5.2.1" + buffer: "npm:6.0.3" + invariant: "npm:2.2.4" + checksum: 10c0/a70e608a4b8db84b44778bb8da8671be6f7d7e4c02e0ea8a713fb61a80cdf36957eeb448ea522000ecce99edb3ca1c768c2b73b24d7ec6ef37d64fd843f00233 + languageName: node + linkType: hard + "@standard-schema/spec@npm:^1.0.0": version: 1.0.0 resolution: "@standard-schema/spec@npm:1.0.0" @@ -1107,6 +1227,15 @@ __metadata: languageName: node linkType: hard +"@types/bn.js@npm:^5.1.1": + version: 5.2.0 + resolution: "@types/bn.js@npm:5.2.0" + dependencies: + "@types/node": "npm:*" + checksum: 10c0/7a36114b8e61faba5c28b433c3e5aabded261745dabb8f3fe41b2d84e8c4c2b8282e52a88a842bd31a565ff5dbf685145ccd91171f1a8d657fb249025c17aa85 + languageName: node + linkType: hard + "@types/chai@npm:5.0.1": version: 5.0.1 resolution: "@types/chai@npm:5.0.1" @@ -1731,6 +1860,13 @@ __metadata: languageName: node linkType: hard +"ansicolors@npm:^0.3.2": + version: 0.3.2 + resolution: "ansicolors@npm:0.3.2" + checksum: 10c0/e202182895e959c5357db6c60791b2abaade99fcc02221da11a581b26a7f83dc084392bc74e4d3875c22f37b3c9ef48842e896e3bfed394ec278194b8003e0ac + languageName: node + linkType: hard + "argparse@npm:^2.0.1": version: 2.0.1 resolution: "argparse@npm:2.0.1" @@ -1738,6 +1874,19 @@ __metadata: languageName: node linkType: hard +"assert@npm:^2.0.0, assert@npm:^2.1.0": + version: 2.1.0 + resolution: "assert@npm:2.1.0" + dependencies: + call-bind: "npm:^1.0.2" + is-nan: "npm:^1.3.2" + object-is: "npm:^1.1.5" + object.assign: "npm:^4.1.4" + util: "npm:^0.12.5" + checksum: 10c0/7271a5da883c256a1fa690677bf1dd9d6aa882139f2bed1cd15da4f9e7459683e1da8e32a203d6cc6767e5e0f730c77a9532a87b896b4b0af0dd535f668775f0 + languageName: node + linkType: hard + "assertion-error@npm:^2.0.1": version: 2.0.1 resolution: "assertion-error@npm:2.0.1" @@ -1745,6 +1894,20 @@ __metadata: languageName: node linkType: hard +"async-function@npm:^1.0.0": + version: 1.0.0 + resolution: "async-function@npm:1.0.0" + checksum: 10c0/669a32c2cb7e45091330c680e92eaeb791bc1d4132d827591e499cd1f776ff5a873e77e5f92d0ce795a8d60f10761dec9ddfe7225a5de680f5d357f67b1aac73 + languageName: node + linkType: hard + +"async-generator-function@npm:^1.0.0": + version: 1.0.0 + resolution: "async-generator-function@npm:1.0.0" + checksum: 10c0/2c50ef856c543ad500d8d8777d347e3c1ba623b93e99c9263ecc5f965c1b12d2a140e2ab6e43c3d0b85366110696f28114649411cbcd10b452a92a2318394186 + languageName: node + linkType: hard + "asynckit@npm:^0.4.0": version: 0.4.0 resolution: "asynckit@npm:0.4.0" @@ -1752,6 +1915,15 @@ __metadata: languageName: node linkType: hard +"available-typed-arrays@npm:^1.0.7": + version: 1.0.7 + resolution: "available-typed-arrays@npm:1.0.7" + dependencies: + possible-typed-array-names: "npm:^1.0.0" + checksum: 10c0/d07226ef4f87daa01bd0fe80f8f310982e345f372926da2e5296aecc25c41cab440916bbaa4c5e1034b453af3392f67df5961124e4b586df1e99793a1374bdb2 + languageName: node + linkType: hard + "axios@npm:^1.7.8": version: 1.7.9 resolution: "axios@npm:1.7.9" @@ -1953,6 +2125,38 @@ __metadata: languageName: node linkType: hard +"call-bind-apply-helpers@npm:^1.0.0, call-bind-apply-helpers@npm:^1.0.1, call-bind-apply-helpers@npm:^1.0.2": + version: 1.0.2 + resolution: "call-bind-apply-helpers@npm:1.0.2" + dependencies: + es-errors: "npm:^1.3.0" + function-bind: "npm:^1.1.2" + checksum: 10c0/47bd9901d57b857590431243fea704ff18078b16890a6b3e021e12d279bbf211d039155e27d7566b374d49ee1f8189344bac9833dec7a20cdec370506361c938 + languageName: node + linkType: hard + +"call-bind@npm:^1.0.0, call-bind@npm:^1.0.2, call-bind@npm:^1.0.7, call-bind@npm:^1.0.8": + version: 1.0.8 + resolution: "call-bind@npm:1.0.8" + dependencies: + call-bind-apply-helpers: "npm:^1.0.0" + es-define-property: "npm:^1.0.0" + get-intrinsic: "npm:^1.2.4" + set-function-length: "npm:^1.2.2" + checksum: 10c0/a13819be0681d915144467741b69875ae5f4eba8961eb0bf322aab63ec87f8250eb6d6b0dcbb2e1349876412a56129ca338592b3829ef4343527f5f18a0752d4 + languageName: node + linkType: hard + +"call-bound@npm:^1.0.2, call-bound@npm:^1.0.3, call-bound@npm:^1.0.4": + version: 1.0.4 + resolution: "call-bound@npm:1.0.4" + dependencies: + call-bind-apply-helpers: "npm:^1.0.2" + get-intrinsic: "npm:^1.3.0" + checksum: 10c0/f4796a6a0941e71c766aea672f63b72bc61234c4f4964dc6d7606e3664c307e7d77845328a8f3359ce39ddb377fed67318f9ee203dea1d47e46165dcf2917644 + languageName: node + linkType: hard + "callsites@npm:^3.0.0": version: 3.1.0 resolution: "callsites@npm:3.1.0" @@ -2004,6 +2208,13 @@ __metadata: languageName: node linkType: hard +"chalk@npm:^5.4.1": + version: 5.6.2 + resolution: "chalk@npm:5.6.2" + checksum: 10c0/99a4b0f0e7991796b1e7e3f52dceb9137cae2a9dfc8fc0784a550dc4c558e15ab32ed70b14b21b52beb2679b4892b41a0aa44249bcb996f01e125d58477c6976 + languageName: node + linkType: hard + "check-error@npm:^2.1.1": version: 2.1.1 resolution: "check-error@npm:2.1.1" @@ -2061,6 +2272,13 @@ __metadata: languageName: node linkType: hard +"commander@npm:^14.0.0": + version: 14.0.3 + resolution: "commander@npm:14.0.3" + checksum: 10c0/755652564bbf56ff2ff083313912b326450d3f8d8c85f4b71416539c9a05c3c67dbd206821ca72635bf6b160e2afdefcb458e86b317827d5cb333b69ce7f1a24 + languageName: node + linkType: hard + "commander@npm:^2.20.3": version: 2.20.3 resolution: "commander@npm:2.20.3" @@ -2116,7 +2334,7 @@ __metadata: languageName: node linkType: hard -"debug@npm:4, debug@npm:^4.3.2, debug@npm:^4.3.4, debug@npm:^4.4.1, debug@npm:^4.4.3": +"debug@npm:4, debug@npm:^4.3.2, debug@npm:^4.3.3, debug@npm:^4.3.4, debug@npm:^4.4.1, debug@npm:^4.4.3": version: 4.4.3 resolution: "debug@npm:4.4.3" dependencies: @@ -2161,6 +2379,28 @@ __metadata: languageName: node linkType: hard +"define-data-property@npm:^1.0.1, define-data-property@npm:^1.1.4": + version: 1.1.4 + resolution: "define-data-property@npm:1.1.4" + dependencies: + es-define-property: "npm:^1.0.0" + es-errors: "npm:^1.3.0" + gopd: "npm:^1.0.1" + checksum: 10c0/dea0606d1483eb9db8d930d4eac62ca0fa16738b0b3e07046cddfacf7d8c868bbe13fa0cb263eb91c7d0d527960dc3f2f2471a69ed7816210307f6744fe62e37 + languageName: node + linkType: hard + +"define-properties@npm:^1.1.3, define-properties@npm:^1.2.1": + version: 1.2.1 + resolution: "define-properties@npm:1.2.1" + dependencies: + define-data-property: "npm:^1.0.1" + has-property-descriptors: "npm:^1.0.0" + object-keys: "npm:^1.1.1" + checksum: 10c0/88a152319ffe1396ccc6ded510a3896e77efac7a1bfbaa174a7b00414a1747377e0bb525d303794a47cf30e805c2ec84e575758512c6e44a993076d29fd4e6c3 + languageName: node + linkType: hard + "delay@npm:^5.0.0": version: 5.0.0 resolution: "delay@npm:5.0.0" @@ -2192,6 +2432,17 @@ __metadata: languageName: node linkType: hard +"dunder-proto@npm:^1.0.1": + version: 1.0.1 + resolution: "dunder-proto@npm:1.0.1" + dependencies: + call-bind-apply-helpers: "npm:^1.0.1" + es-errors: "npm:^1.3.0" + gopd: "npm:^1.2.0" + checksum: 10c0/199f2a0c1c16593ca0a145dbf76a962f8033ce3129f01284d48c45ed4e14fea9bbacd7b3610b6cdc33486cef20385ac054948fefc6272fcce645c09468f93031 + languageName: node + linkType: hard + "eastasianwidth@npm:^0.2.0": version: 0.2.0 resolution: "eastasianwidth@npm:0.2.0" @@ -2243,6 +2494,20 @@ __metadata: languageName: node linkType: hard +"es-define-property@npm:^1.0.0, es-define-property@npm:^1.0.1": + version: 1.0.1 + resolution: "es-define-property@npm:1.0.1" + checksum: 10c0/3f54eb49c16c18707949ff25a1456728c883e81259f045003499efba399c08bad00deebf65cccde8c0e07908c1a225c9d472b7107e558f2a48e28d530e34527c + languageName: node + linkType: hard + +"es-errors@npm:^1.3.0": + version: 1.3.0 + resolution: "es-errors@npm:1.3.0" + checksum: 10c0/0a61325670072f98d8ae3b914edab3559b6caa980f08054a3b872052640d91da01d38df55df797fcc916389d77fc92b8d5906cf028f4db46d7e3003abecbca85 + languageName: node + linkType: hard + "es-module-lexer@npm:^1.7.0": version: 1.7.0 resolution: "es-module-lexer@npm:1.7.0" @@ -2250,6 +2515,15 @@ __metadata: languageName: node linkType: hard +"es-object-atoms@npm:^1.0.0, es-object-atoms@npm:^1.1.1": + version: 1.1.1 + resolution: "es-object-atoms@npm:1.1.1" + dependencies: + es-errors: "npm:^1.3.0" + checksum: 10c0/65364812ca4daf48eb76e2a3b7a89b3f6a2e62a1c420766ce9f692665a29d94fe41fe88b65f24106f449859549711e4b40d9fb8002d862dfd7eb1c512d10be0c + languageName: node + linkType: hard + "es6-promise@npm:^4.0.3": version: 4.2.8 resolution: "es6-promise@npm:4.2.8" @@ -2763,6 +3037,15 @@ __metadata: languageName: node linkType: hard +"for-each@npm:^0.3.5": + version: 0.3.5 + resolution: "for-each@npm:0.3.5" + dependencies: + is-callable: "npm:^1.2.7" + checksum: 10c0/0e0b50f6a843a282637d43674d1fb278dda1dd85f4f99b640024cfb10b85058aac0cc781bf689d5fe50b4b7f638e91e548560723a4e76e04fe96ae35ef039cee + languageName: node + linkType: hard + "foreground-child@npm:^3.1.0": version: 3.3.1 resolution: "foreground-child@npm:3.3.1" @@ -2812,6 +3095,20 @@ __metadata: languageName: node linkType: hard +"function-bind@npm:^1.1.2": + version: 1.1.2 + resolution: "function-bind@npm:1.1.2" + checksum: 10c0/d8680ee1e5fcd4c197e4ac33b2b4dce03c71f4d91717292785703db200f5c21f977c568d28061226f9b5900cbcd2c84463646134fd5337e7925e0942bc3f46d5 + languageName: node + linkType: hard + +"generator-function@npm:^2.0.0": + version: 2.0.1 + resolution: "generator-function@npm:2.0.1" + checksum: 10c0/8a9f59df0f01cfefafdb3b451b80555e5cf6d76487095db91ac461a0e682e4ff7a9dbce15f4ecec191e53586d59eece01949e05a4b4492879600bbbe8e28d6b8 + languageName: node + linkType: hard + "get-caller-file@npm:^2.0.5": version: 2.0.5 resolution: "get-caller-file@npm:2.0.5" @@ -2826,6 +3123,37 @@ __metadata: languageName: node linkType: hard +"get-intrinsic@npm:^1.2.4, get-intrinsic@npm:^1.3.0": + version: 1.3.1 + resolution: "get-intrinsic@npm:1.3.1" + dependencies: + async-function: "npm:^1.0.0" + async-generator-function: "npm:^1.0.0" + call-bind-apply-helpers: "npm:^1.0.2" + es-define-property: "npm:^1.0.1" + es-errors: "npm:^1.3.0" + es-object-atoms: "npm:^1.1.1" + function-bind: "npm:^1.1.2" + generator-function: "npm:^2.0.0" + get-proto: "npm:^1.0.1" + gopd: "npm:^1.2.0" + has-symbols: "npm:^1.1.0" + hasown: "npm:^2.0.2" + math-intrinsics: "npm:^1.1.0" + checksum: 10c0/9f4ab0cf7efe0fd2c8185f52e6f637e708f3a112610c88869f8f041bb9ecc2ce44bf285dfdbdc6f4f7c277a5b88d8e94a432374d97cca22f3de7fc63795deb5d + languageName: node + linkType: hard + +"get-proto@npm:^1.0.1": + version: 1.0.1 + resolution: "get-proto@npm:1.0.1" + dependencies: + dunder-proto: "npm:^1.0.1" + es-object-atoms: "npm:^1.0.0" + checksum: 10c0/9224acb44603c5526955e83510b9da41baf6ae73f7398875fba50edc5e944223a89c4a72b070fcd78beb5f7bdda58ecb6294adc28f7acfc0da05f76a2399643c + languageName: node + linkType: hard + "get-tsconfig@npm:^4.10.1, get-tsconfig@npm:^4.7.5": version: 4.13.0 resolution: "get-tsconfig@npm:4.13.0" @@ -2883,6 +3211,13 @@ __metadata: languageName: node linkType: hard +"gopd@npm:^1.0.1, gopd@npm:^1.2.0": + version: 1.2.0 + resolution: "gopd@npm:1.2.0" + checksum: 10c0/50fff1e04ba2b7737c097358534eacadad1e68d24cccee3272e04e007bed008e68d2614f3987788428fd192a5ae3889d08fb2331417e4fc4a9ab366b2043cead + languageName: node + linkType: hard + "graceful-fs@npm:^4.2.6": version: 4.2.11 resolution: "graceful-fs@npm:4.2.11" @@ -2904,6 +3239,40 @@ __metadata: languageName: node linkType: hard +"has-property-descriptors@npm:^1.0.0, has-property-descriptors@npm:^1.0.2": + version: 1.0.2 + resolution: "has-property-descriptors@npm:1.0.2" + dependencies: + es-define-property: "npm:^1.0.0" + checksum: 10c0/253c1f59e80bb476cf0dde8ff5284505d90c3bdb762983c3514d36414290475fe3fd6f574929d84de2a8eec00d35cf07cb6776205ff32efd7c50719125f00236 + languageName: node + linkType: hard + +"has-symbols@npm:^1.0.3, has-symbols@npm:^1.1.0": + version: 1.1.0 + resolution: "has-symbols@npm:1.1.0" + checksum: 10c0/dde0a734b17ae51e84b10986e651c664379018d10b91b6b0e9b293eddb32f0f069688c841fb40f19e9611546130153e0a2a48fd7f512891fb000ddfa36f5a20e + languageName: node + linkType: hard + +"has-tostringtag@npm:^1.0.2": + version: 1.0.2 + resolution: "has-tostringtag@npm:1.0.2" + dependencies: + has-symbols: "npm:^1.0.3" + checksum: 10c0/a8b166462192bafe3d9b6e420a1d581d93dd867adb61be223a17a8d6dad147aa77a8be32c961bb2f27b3ef893cae8d36f564ab651f5e9b7938ae86f74027c48c + languageName: node + linkType: hard + +"hasown@npm:^2.0.2": + version: 2.0.2 + resolution: "hasown@npm:2.0.2" + dependencies: + function-bind: "npm:^1.1.2" + checksum: 10c0/3769d434703b8ac66b209a4cca0737519925bbdb61dd887f93a16372b14694c63ff4e797686d87c90f08168e81082248b9b028bad60d4da9e0d1148766f56eb9 + languageName: node + linkType: hard + "http-cache-semantics@npm:^4.1.1": version: 4.2.0 resolution: "http-cache-semantics@npm:4.2.0" @@ -2994,6 +3363,15 @@ __metadata: languageName: node linkType: hard +"invariant@npm:2.2.4": + version: 2.2.4 + resolution: "invariant@npm:2.2.4" + dependencies: + loose-envify: "npm:^1.0.0" + checksum: 10c0/5af133a917c0bcf65e84e7f23e779e7abc1cd49cb7fdc62d00d1de74b0d8c1b5ee74ac7766099fb3be1b05b26dfc67bab76a17030d2fe7ea2eef867434362dfc + languageName: node + linkType: hard + "ip-address@npm:^10.0.1": version: 10.0.1 resolution: "ip-address@npm:10.0.1" @@ -3001,6 +3379,16 @@ __metadata: languageName: node linkType: hard +"is-arguments@npm:^1.0.4": + version: 1.2.0 + resolution: "is-arguments@npm:1.2.0" + dependencies: + call-bound: "npm:^1.0.2" + has-tostringtag: "npm:^1.0.2" + checksum: 10c0/6377344b31e9fcb707c6751ee89b11f132f32338e6a782ec2eac9393b0cbd32235dad93052998cda778ee058754860738341d8114910d50ada5615912bb929fc + languageName: node + linkType: hard + "is-bun-module@npm:^2.0.0": version: 2.0.0 resolution: "is-bun-module@npm:2.0.0" @@ -3010,6 +3398,13 @@ __metadata: languageName: node linkType: hard +"is-callable@npm:^1.2.7": + version: 1.2.7 + resolution: "is-callable@npm:1.2.7" + checksum: 10c0/ceebaeb9d92e8adee604076971dd6000d38d6afc40bb843ea8e45c5579b57671c3f3b50d7f04869618242c6cee08d1b67806a8cb8edaaaf7c0748b3720d6066f + languageName: node + linkType: hard + "is-extglob@npm:^2.1.1": version: 2.1.1 resolution: "is-extglob@npm:2.1.1" @@ -3024,6 +3419,19 @@ __metadata: languageName: node linkType: hard +"is-generator-function@npm:^1.0.7": + version: 1.1.2 + resolution: "is-generator-function@npm:1.1.2" + dependencies: + call-bound: "npm:^1.0.4" + generator-function: "npm:^2.0.0" + get-proto: "npm:^1.0.1" + has-tostringtag: "npm:^1.0.2" + safe-regex-test: "npm:^1.1.0" + checksum: 10c0/83da102e89c3e3b71d67b51d47c9f9bc862bceb58f87201727e27f7fa19d1d90b0ab223644ecaee6fc6e3d2d622bb25c966fbdaf87c59158b01ce7c0fe2fa372 + languageName: node + linkType: hard + "is-glob@npm:^4.0.0, is-glob@npm:^4.0.1, is-glob@npm:^4.0.3": version: 4.0.3 resolution: "is-glob@npm:4.0.3" @@ -3033,6 +3441,16 @@ __metadata: languageName: node linkType: hard +"is-nan@npm:^1.3.2": + version: 1.3.2 + resolution: "is-nan@npm:1.3.2" + dependencies: + call-bind: "npm:^1.0.0" + define-properties: "npm:^1.1.3" + checksum: 10c0/8bfb286f85763f9c2e28ea32e9127702fe980ffd15fa5d63ade3be7786559e6e21355d3625dd364c769c033c5aedf0a2ed3d4025d336abf1b9241e3d9eddc5b0 + languageName: node + linkType: hard + "is-number@npm:^7.0.0": version: 7.0.0 resolution: "is-number@npm:7.0.0" @@ -3040,6 +3458,27 @@ __metadata: languageName: node linkType: hard +"is-regex@npm:^1.2.1": + version: 1.2.1 + resolution: "is-regex@npm:1.2.1" + dependencies: + call-bound: "npm:^1.0.2" + gopd: "npm:^1.2.0" + has-tostringtag: "npm:^1.0.2" + hasown: "npm:^2.0.2" + checksum: 10c0/1d3715d2b7889932349241680032e85d0b492cfcb045acb75ffc2c3085e8d561184f1f7e84b6f8321935b4aea39bc9c6ba74ed595b57ce4881a51dfdbc214e04 + languageName: node + linkType: hard + +"is-typed-array@npm:^1.1.3": + version: 1.1.15 + resolution: "is-typed-array@npm:1.1.15" + dependencies: + which-typed-array: "npm:^1.1.16" + checksum: 10c0/415511da3669e36e002820584e264997ffe277ff136643a3126cc949197e6ca3334d0f12d084e83b1994af2e9c8141275c741cf2b7da5a2ff62dd0cac26f76c4 + languageName: node + linkType: hard + "isexe@npm:^2.0.0": version: 2.0.0 resolution: "isexe@npm:2.0.0" @@ -3114,6 +3553,13 @@ __metadata: languageName: node linkType: hard +"js-tokens@npm:^3.0.0 || ^4.0.0": + version: 4.0.0 + resolution: "js-tokens@npm:4.0.0" + checksum: 10c0/e248708d377aa058eacf2037b07ded847790e6de892bbad3dac0abba2e759cb9f121b00099a65195616badcb6eca8d14d975cb3e89eb1cfda644756402c8aeed + languageName: node + linkType: hard + "js-yaml@npm:^4.1.0": version: 4.1.0 resolution: "js-yaml@npm:4.1.0" @@ -3232,6 +3678,17 @@ __metadata: languageName: node linkType: hard +"loose-envify@npm:^1.0.0": + version: 1.4.0 + resolution: "loose-envify@npm:1.4.0" + dependencies: + js-tokens: "npm:^3.0.0 || ^4.0.0" + bin: + loose-envify: cli.js + checksum: 10c0/655d110220983c1a4b9c0c679a2e8016d4b67f6e9c7b5435ff5979ecdb20d0813f4dec0a08674fcbdd4846a3f07edbb50a36811fd37930b94aaa0d9daceb017e + languageName: node + linkType: hard + "loupe@npm:^3.1.0": version: 3.1.2 resolution: "loupe@npm:3.1.2" @@ -3283,6 +3740,13 @@ __metadata: languageName: node linkType: hard +"math-intrinsics@npm:^1.1.0": + version: 1.1.0 + resolution: "math-intrinsics@npm:1.1.0" + checksum: 10c0/7579ff94e899e2f76ab64491d76cf606274c874d8f2af4a442c016bd85688927fcfca157ba6bf74b08e9439dc010b248ce05b96cc7c126a354c3bae7fcb48b7f + languageName: node + linkType: hard + "merge2@npm:^1.3.0": version: 1.4.1 resolution: "merge2@npm:1.4.1" @@ -3551,6 +4015,37 @@ __metadata: languageName: node linkType: hard +"object-is@npm:^1.1.5": + version: 1.1.6 + resolution: "object-is@npm:1.1.6" + dependencies: + call-bind: "npm:^1.0.7" + define-properties: "npm:^1.2.1" + checksum: 10c0/506af444c4dce7f8e31f34fc549e2fb8152d6b9c4a30c6e62852badd7f520b579c679af433e7a072f9d78eb7808d230dc12e1cf58da9154dfbf8813099ea0fe0 + languageName: node + linkType: hard + +"object-keys@npm:^1.1.1": + version: 1.1.1 + resolution: "object-keys@npm:1.1.1" + checksum: 10c0/b11f7ccdbc6d406d1f186cdadb9d54738e347b2692a14439ca5ac70c225fa6db46db809711b78589866d47b25fc3e8dee0b4c722ac751e11180f9380e3d8601d + languageName: node + linkType: hard + +"object.assign@npm:^4.1.4": + version: 4.1.7 + resolution: "object.assign@npm:4.1.7" + dependencies: + call-bind: "npm:^1.0.8" + call-bound: "npm:^1.0.3" + define-properties: "npm:^1.2.1" + es-object-atoms: "npm:^1.0.0" + has-symbols: "npm:^1.1.0" + object-keys: "npm:^1.1.1" + checksum: 10c0/3b2732bd860567ea2579d1567525168de925a8d852638612846bd8082b3a1602b7b89b67b09913cbb5b9bd6e95923b2ae73580baa9d99cb4e990564e8cbf5ddc + languageName: node + linkType: hard + "optionator@npm:^0.9.3": version: 0.9.4 resolution: "optionator@npm:0.9.4" @@ -3692,6 +4187,13 @@ __metadata: languageName: node linkType: hard +"possible-typed-array-names@npm:^1.0.0": + version: 1.1.0 + resolution: "possible-typed-array-names@npm:1.1.0" + checksum: 10c0/c810983414142071da1d644662ce4caebce890203eb2bc7bf119f37f3fe5796226e117e6cca146b521921fa6531072674174a3325066ac66fce089a53e1e5196 + languageName: node + linkType: hard + "postcss@npm:^8.5.6": version: 8.5.6 resolution: "postcss@npm:8.5.6" @@ -3922,6 +4424,7 @@ __metadata: "@solana/spl-token": "npm:0.4.9" "@solana/spl-token-metadata": "npm:0.1.6" "@solana/web3.js": "npm:1.95.4" + "@sqds/multisig": "npm:2.1.4" "@switchboard-xyz/on-demand": "npm:1.2.54" "@types/bn.js": "npm:5.1.6" "@types/chai": "npm:5.0.1" @@ -3989,6 +4492,17 @@ __metadata: languageName: node linkType: hard +"safe-regex-test@npm:^1.1.0": + version: 1.1.0 + resolution: "safe-regex-test@npm:1.1.0" + dependencies: + call-bound: "npm:^1.0.2" + es-errors: "npm:^1.3.0" + is-regex: "npm:^1.2.1" + checksum: 10c0/f2c25281bbe5d39cddbbce7f86fca5ea9b3ce3354ea6cd7c81c31b006a5a9fff4286acc5450a3b9122c56c33eba69c56b9131ad751457b2b4a585825e6a10665 + languageName: node + linkType: hard + "safer-buffer@npm:>= 2.1.2 < 3.0.0": version: 2.1.2 resolution: "safer-buffer@npm:2.1.2" @@ -4005,6 +4519,20 @@ __metadata: languageName: node linkType: hard +"set-function-length@npm:^1.2.2": + version: 1.2.2 + resolution: "set-function-length@npm:1.2.2" + dependencies: + define-data-property: "npm:^1.1.4" + es-errors: "npm:^1.3.0" + function-bind: "npm:^1.1.2" + get-intrinsic: "npm:^1.2.4" + gopd: "npm:^1.0.1" + has-property-descriptors: "npm:^1.0.2" + checksum: 10c0/82850e62f412a258b71e123d4ed3873fa9377c216809551192bb6769329340176f109c2eeae8c22a8d386c76739855f78e8716515c818bcaef384b51110f0f3c + languageName: node + linkType: hard + "shebang-command@npm:^2.0.0": version: 2.0.0 resolution: "shebang-command@npm:2.0.0" @@ -4597,6 +5125,19 @@ __metadata: languageName: node linkType: hard +"util@npm:^0.12.5": + version: 0.12.5 + resolution: "util@npm:0.12.5" + dependencies: + inherits: "npm:^2.0.3" + is-arguments: "npm:^1.0.4" + is-generator-function: "npm:^1.0.7" + is-typed-array: "npm:^1.1.3" + which-typed-array: "npm:^1.1.2" + checksum: 10c0/c27054de2cea2229a66c09522d0fa1415fb12d861d08523a8846bf2e4cbf0079d4c3f725f09dcb87493549bcbf05f5798dce1688b53c6c17201a45759e7253f3 + languageName: node + linkType: hard + "uuid@npm:^8.3.2": version: 8.3.2 resolution: "uuid@npm:8.3.2" @@ -4769,6 +5310,21 @@ __metadata: languageName: node linkType: hard +"which-typed-array@npm:^1.1.16, which-typed-array@npm:^1.1.2": + version: 1.1.20 + resolution: "which-typed-array@npm:1.1.20" + dependencies: + available-typed-arrays: "npm:^1.0.7" + call-bind: "npm:^1.0.8" + call-bound: "npm:^1.0.4" + for-each: "npm:^0.3.5" + get-proto: "npm:^1.0.1" + gopd: "npm:^1.2.0" + has-tostringtag: "npm:^1.0.2" + checksum: 10c0/16fcdada95c8afb821cd1117f0ab50b4d8551677ac08187f21d4e444530913c9ffd2dac634f0c1183345f96344b69280f40f9a8bc52164ef409e555567c2604b + languageName: node + linkType: hard + "which@npm:^2.0.1": version: 2.0.2 resolution: "which@npm:2.0.2" From dc7314bfdf0d060723285eb66b6d22956dbfa957 Mon Sep 17 00:00:00 2001 From: kostyamospan <37243242+kostyamospan@users.noreply.github.com> Date: Sat, 14 Feb 2026 13:03:57 +0000 Subject: [PATCH 02/15] chore: more squads scripts --- test/fixture/squads.fixture.ts | 19 +- test/squads.test.ts | 391 +++++++++++++++++++++++---------- test/testers/squads.testers.ts | 308 ++++++++++++++++++++++++-- 3 files changed, 582 insertions(+), 136 deletions(-) diff --git a/test/fixture/squads.fixture.ts b/test/fixture/squads.fixture.ts index 4b01094..a9de367 100644 --- a/test/fixture/squads.fixture.ts +++ b/test/fixture/squads.fixture.ts @@ -97,11 +97,22 @@ export const squadsFixture = async (initSlot?: bigint) => { } - const mutlisigPda = await createMultisig(context, { + const multisigPda = await createMultisig(context, { authority, connection: provider.connection, }); + const multisigSignerPda = await createMultisig(context, { + authority, + connection: provider.connection, + timelock: 0n + }); + + const multisigWithSquadsSignerPda = await createMultisig(context, { + authority, + connection: provider.connection, + member: multisigSignerPda + }); const squadsConnection = provider.connection as any; @@ -109,14 +120,16 @@ export const squadsFixture = async (initSlot?: bigint) => { provider, context, authority, - mutlisigPda, + multisigPda, regularAccounts, squadsConnection, accounts, + multisigSignerPda, + multisigWithSquadsSignerPda, getMutlisigData: async (pda?: PublicKey) => { return await multisig.accounts.Multisig.fromAccountAddress( squadsConnection, - pda ?? mutlisigPda + pda ?? multisigPda ); } }; diff --git a/test/squads.test.ts b/test/squads.test.ts index 4b7055d..ce92fad 100644 --- a/test/squads.test.ts +++ b/test/squads.test.ts @@ -1,7 +1,7 @@ import { LAMPORTS_PER_SOL, SystemProgram, Transaction } from "@solana/web3.js"; import { DAY } from "./constants/common.constants"; import { squadsFixture } from "./fixture/squads.fixture"; -import { sendSquadsTxWithTimelock } from "./testers/squads.testers"; +import { sendSquadsConfigurationTxWithTimelock, sendSquadsTxWithTimelock } from "./testers/squads.testers"; import * as multisig from "@sqds/multisig"; import { processTransaction } from "./helpers/common.helpers"; import { acFixture } from "./fixture/ac.fixture"; @@ -21,118 +21,307 @@ describe('Squads multisig', () => { }); }); - describe('timelock', () => { - it('regular sol transfer with timelock', async () => { - const fixture = await squadsFixture(); - const { mutlisigPda, getMutlisigData, authority, regularAccounts, context } = fixture; - - const [vaultPda] = multisig.getVaultPda({ - multisigPda: mutlisigPda as any, - index: 0, + describe('config transactions', () => { + it('change the timelock configuration when timelock is passed', async () => { + const fixture = await squadsFixture(); + + const { multisigPda, getMutlisigData, authority, regularAccounts, context } = fixture; + + const [vaultPda] = multisig.getVaultPda({ + multisigPda: multisigPda as any, + index: 0, + }); + + await processTransaction(context, + new Transaction().add(SystemProgram.transfer({ + fromPubkey: authority.publicKey, + toPubkey: vaultPda, + lamports: LAMPORTS_PER_SOL, + })), [authority]); + + await sendSquadsConfigurationTxWithTimelock(fixture, { + actions: [{ + __kind: 'SetTimeLock', + newTimeLock: 0 + }], + }); + + const data = await getMutlisigData(); + expect(data.timeLock).toBe(0); }); - await processTransaction(context, - new Transaction().add(SystemProgram.transfer({ - fromPubkey: authority.publicKey, - toPubkey: vaultPda, - lamports: LAMPORTS_PER_SOL, - })), [authority]); + it('change the members configuration when timelock is passed', async () => { + const fixture = await squadsFixture(); + const { multisigPda, getMutlisigData, authority, regularAccounts, context } = fixture; - const instructions = [ - SystemProgram.transfer({ - fromPubkey: vaultPda, - toPubkey: regularAccounts[0].publicKey, - lamports: LAMPORTS_PER_SOL, - }), - ]; - - await sendSquadsTxWithTimelock(fixture, { - instructions, - }); - }); + const [vaultPda] = multisig.getVaultPda({ + multisigPda: multisigPda as any, + index: 0, + }); - it('custom instruction with timelock', async () => { - const fixture = await squadsFixture(); - const fixtureAc = await acFixture(fixture); + await processTransaction(context, + new Transaction().add(SystemProgram.transfer({ + fromPubkey: authority.publicKey, + toPubkey: vaultPda, + lamports: LAMPORTS_PER_SOL, + })), [authority]); - const { mutlisigPda, getMutlisigData, authority, regularAccounts, context } = fixture; + await sendSquadsConfigurationTxWithTimelock(fixture, { + actions: [{ + __kind: 'SetRentCollector', + newRentCollector: regularAccounts[1].publicKey, + }], + }); - const [vaultPda] = multisig.getVaultPda({ - multisigPda: mutlisigPda as any, - index: 0, + const data = await getMutlisigData(); + expect(data.rentCollector.equals(regularAccounts[1].publicKey)).toBe(true); }); - await processTransaction(context, - new Transaction().add(SystemProgram.transfer({ - fromPubkey: authority.publicKey, - toPubkey: vaultPda, - lamports: LAMPORTS_PER_SOL, - })), [authority]); - - await grantRole(fixtureAc, { - account: vaultPda, - acRole: fixtureAc.acRoleGlobal.publicKey, - role: AC_ROLES.ADMIN, + it('should fail: change the timelock configuration when timelock is not passed', async () => { + const fixture = await squadsFixture(); + + const { multisigPda, getMutlisigData, authority, regularAccounts, context } = fixture; + + const [vaultPda] = multisig.getVaultPda({ + multisigPda: multisigPda as any, + index: 0, + }); + + await processTransaction(context, + new Transaction().add(SystemProgram.transfer({ + fromPubkey: authority.publicKey, + toPubkey: vaultPda, + lamports: LAMPORTS_PER_SOL, + })), [authority]); + + await sendSquadsConfigurationTxWithTimelock(fixture, { + actions: [{ + __kind: 'SetTimeLock', + newTimeLock: 0 + }], + waitForTimelock: false + }, { + revertedWithExecute: '0x1785', + }); }); - - const instructions = [ - await fixtureAc.acProgram.methods.grantRole(acRoleToBuffer(AC_ROLES.UPDATE_ACCOUNT_AC)) - .accounts({ - acRole: fixtureAc.acRoleGlobal.publicKey, - authority: vaultPda, - account: regularAccounts[0].publicKey, - }) - .instruction(), - ]; - - await sendSquadsTxWithTimelock(fixture, { - instructions, + it('should fail: change the members configuration when timelock is not passed', async () => { + const fixture = await squadsFixture(); + + const { multisigPda, getMutlisigData, authority, regularAccounts, context } = fixture; + + const [vaultPda] = multisig.getVaultPda({ + multisigPda: multisigPda as any, + index: 0, + }); + + await processTransaction(context, + new Transaction().add(SystemProgram.transfer({ + fromPubkey: authority.publicKey, + toPubkey: vaultPda, + lamports: LAMPORTS_PER_SOL, + })), [authority]); + + await sendSquadsConfigurationTxWithTimelock(fixture, { + actions: [{ + __kind: 'AddMember', + newMember: { + key: regularAccounts[1].publicKey, + permissions: multisig.types.Permissions.all(), + } + }], + waitForTimelock: false + }, { + revertedWithExecute: '0x1785', + }); }); }); - it('should fail: sol transfer but timelock is not passed', async () => { - const fixture = await squadsFixture(); - const { mutlisigPda, getMutlisigData, authority, regularAccounts, context } = fixture; + describe('vault transactions', () => { + it('regular sol transfer with timelock', async () => { + const fixture = await squadsFixture(); + const { multisigPda, getMutlisigData, authority, regularAccounts, context } = fixture; + + const [vaultPda] = multisig.getVaultPda({ + multisigPda: multisigPda as any, + index: 0, + }); + + await processTransaction(context, + new Transaction().add(SystemProgram.transfer({ + fromPubkey: authority.publicKey, + toPubkey: vaultPda, + lamports: LAMPORTS_PER_SOL, + })), [authority]); + + + const instructions = [ + SystemProgram.transfer({ + fromPubkey: vaultPda, + toPubkey: regularAccounts[0].publicKey, + lamports: LAMPORTS_PER_SOL, + }), + ]; + + await sendSquadsTxWithTimelock(fixture, { + instructions, + }); + }); - const [vaultPda] = multisig.getVaultPda({ - multisigPda: mutlisigPda as any, - index: 0, + it('custom instruction with timelock', async () => { + const fixture = await squadsFixture(); + const fixtureAc = await acFixture(fixture); + + const { multisigPda, getMutlisigData, authority, regularAccounts, context } = fixture; + + const [vaultPda] = multisig.getVaultPda({ + multisigPda: multisigPda as any, + index: 0, + }); + + + await processTransaction(context, + new Transaction().add(SystemProgram.transfer({ + fromPubkey: authority.publicKey, + toPubkey: vaultPda, + lamports: LAMPORTS_PER_SOL, + })), [authority]); + + await grantRole(fixtureAc, { + account: vaultPda, + acRole: fixtureAc.acRoleGlobal.publicKey, + role: AC_ROLES.ADMIN, + }); + + + const instructions = [ + await fixtureAc.acProgram.methods.grantRole(acRoleToBuffer(AC_ROLES.UPDATE_ACCOUNT_AC)) + .accounts({ + acRole: fixtureAc.acRoleGlobal.publicKey, + authority: vaultPda, + account: regularAccounts[0].publicKey, + }) + .instruction(), + ]; + + await sendSquadsTxWithTimelock(fixture, { + instructions, + }); }); - await processTransaction(context, - new Transaction().add(SystemProgram.transfer({ - fromPubkey: authority.publicKey, - toPubkey: vaultPda, - lamports: LAMPORTS_PER_SOL, - })), [authority]); + it('should fail: sol transfer but timelock is not passed', async () => { + const fixture = await squadsFixture(); + const { multisigPda, getMutlisigData, authority, regularAccounts, context } = fixture; + + const [vaultPda] = multisig.getVaultPda({ + multisigPda: multisigPda as any, + index: 0, + }); + + await processTransaction(context, + new Transaction().add(SystemProgram.transfer({ + fromPubkey: authority.publicKey, + toPubkey: vaultPda, + lamports: LAMPORTS_PER_SOL, + })), [authority]); + + + const instructions = [ + SystemProgram.transfer({ + fromPubkey: vaultPda, + toPubkey: regularAccounts[0].publicKey, + lamports: LAMPORTS_PER_SOL, + }), + ]; + + await sendSquadsTxWithTimelock(fixture, { + instructions, + waitForTimelock: false, + }, { + revertedWithExecute: '0x1785', + }); + }); - const instructions = [ - SystemProgram.transfer({ - fromPubkey: vaultPda, - toPubkey: regularAccounts[0].publicKey, - lamports: LAMPORTS_PER_SOL, - }), - ]; + it('should fail: sol transfer create from non-member', async () => { + const fixture = await squadsFixture(); + const { multisigPda, getMutlisigData, authority, regularAccounts, context } = fixture; + + const [vaultPda] = multisig.getVaultPda({ + multisigPda: multisigPda as any, + index: 0, + }); + + await processTransaction(context, + new Transaction().add(SystemProgram.transfer({ + fromPubkey: authority.publicKey, + toPubkey: vaultPda, + lamports: LAMPORTS_PER_SOL, + })), [authority]); + + + const instructions = [ + SystemProgram.transfer({ + fromPubkey: vaultPda, + toPubkey: regularAccounts[0].publicKey, + lamports: LAMPORTS_PER_SOL, + }), + ]; + + await sendSquadsTxWithTimelock(fixture, { + instructions, + }, { + revertedWithCreate: '0x1775', + fromCreate: regularAccounts[1], + }); + }); - await sendSquadsTxWithTimelock(fixture, { - instructions, - waitForTimelock: false, - }, { - revertedWithExecute: '0x1785', + it('should fail: sol transfer execute from non-member', async () => { + const fixture = await squadsFixture(); + const { multisigPda, getMutlisigData, authority, regularAccounts, context } = fixture; + + const [vaultPda] = multisig.getVaultPda({ + multisigPda: multisigPda as any, + index: 0, + }); + + await processTransaction(context, + new Transaction().add(SystemProgram.transfer({ + fromPubkey: authority.publicKey, + toPubkey: vaultPda, + lamports: LAMPORTS_PER_SOL, + })), [authority]); + + + const instructions = [ + SystemProgram.transfer({ + fromPubkey: vaultPda, + toPubkey: regularAccounts[0].publicKey, + lamports: LAMPORTS_PER_SOL, + }), + ]; + + await sendSquadsTxWithTimelock(fixture, { + instructions, + }, { + revertedWithExecute: '0x1775', + fromExecute: regularAccounts[1], + }); }); }); - it('should fail: sol transfer create from non-member', async () => { + }); + + describe('squads member', () => { + it('should create and execute tx with squads member', async () => { const fixture = await squadsFixture(); - const { mutlisigPda, getMutlisigData, authority, regularAccounts, context } = fixture; + const { multisigWithSquadsSignerPda, multisigSignerPda, getMutlisigData, authority, regularAccounts, context } = fixture; const [vaultPda] = multisig.getVaultPda({ - multisigPda: mutlisigPda as any, + multisigPda: multisigWithSquadsSignerPda as any, index: 0, }); @@ -143,36 +332,10 @@ describe('Squads multisig', () => { lamports: LAMPORTS_PER_SOL, })), [authority]); - - const instructions = [ - SystemProgram.transfer({ - fromPubkey: vaultPda, - toPubkey: regularAccounts[0].publicKey, - lamports: LAMPORTS_PER_SOL, - }), - ]; - - await sendSquadsTxWithTimelock(fixture, { - instructions, - }, { - revertedWithCreate: '0x1775', - fromCreate: regularAccounts[1], - }); - }); - - it('should fail: sol transfer execite from non-member', async () => { - const fixture = await squadsFixture(); - const { mutlisigPda, getMutlisigData, authority, regularAccounts, context } = fixture; - - const [vaultPda] = multisig.getVaultPda({ - multisigPda: mutlisigPda as any, - index: 0, - }); - await processTransaction(context, new Transaction().add(SystemProgram.transfer({ fromPubkey: authority.publicKey, - toPubkey: vaultPda, + toPubkey: multisigSignerPda, lamports: LAMPORTS_PER_SOL, })), [authority]); @@ -187,9 +350,7 @@ describe('Squads multisig', () => { await sendSquadsTxWithTimelock(fixture, { instructions, - }, { - revertedWithExecute: '0x1775', - fromExecute: regularAccounts[1], + multisigPda: multisigWithSquadsSignerPda, }); }); }); diff --git a/test/testers/squads.testers.ts b/test/testers/squads.testers.ts index 07668b9..d463318 100644 --- a/test/testers/squads.testers.ts +++ b/test/testers/squads.testers.ts @@ -1,39 +1,122 @@ import { instructions } from "@sqds/multisig"; import { SquadsFixtureReturnType } from "../fixture/squads.fixture"; -import { Keypair, LAMPORTS_PER_SOL, SystemProgram, Transaction, TransactionInstruction, TransactionMessage, VersionedTransaction } from "@solana/web3.js"; +import { AddressLookupTableAccount, Keypair, LAMPORTS_PER_SOL, PublicKey, SystemProgram, Transaction, TransactionInstruction, TransactionMessage, VersionedTransaction } from "@solana/web3.js"; import { expectTxNotReverted, expectTxReverted, OptionalCommonParams, timeTravel } from "../helpers/common.helpers"; import * as multisig from "@sqds/multisig"; import { DAY } from "../constants/common.constants"; +const wrapTxWithSqudsSigner = async (fixture: SquadsFixtureReturnType, { + instructions, + member, + addressLookupTableAccounts, + payer +}: { + instructions: TransactionInstruction[], + addressLookupTableAccounts?: AddressLookupTableAccount[], + member: PublicKey, + payer: PublicKey +}) => { + // Derive the PDA of the Squads Vault + const [vaultPda] = multisig.getVaultPda({ + multisigPda: fixture.multisigSignerPda as any, + index: 0, + }); + + // Get deserialized multisig account info + const multisigInfo = await multisig.accounts.Multisig.fromAccountAddress( + fixture.squadsConnection, + fixture.multisigSignerPda as any + ); + // Get the updated transaction index + const newTransactionIndex = BigInt(multisigInfo.transactionIndex.toString()) + 1n; + + const txMessage = new TransactionMessage({ + payerKey: vaultPda, + recentBlockhash: fixture.context.lastBlockhash, + instructions: instructions, + }); + + const tx = new Transaction().add( + multisig.instructions.vaultTransactionCreate({ + multisigPda: fixture.multisigSignerPda as any, + transactionIndex: newTransactionIndex, + creator: member, + vaultIndex: 0, + ephemeralSigners: 0, + transactionMessage: txMessage as any, + addressLookupTableAccounts, + }), + multisig.instructions.proposalCreate({ + multisigPda: fixture.multisigSignerPda as any, + transactionIndex: newTransactionIndex, + creator: member, + }), + multisig.instructions.proposalApprove({ + multisigPda: fixture.multisigSignerPda as any, + transactionIndex: newTransactionIndex, + member, + }), + ); + + const getTxExecute = async () => { + const { instruction, lookupTableAccounts } = await multisig.instructions.vaultTransactionExecute({ + multisigPda: fixture.multisigSignerPda as any, + member, + transactionIndex: newTransactionIndex, + connection: fixture.squadsConnection, + }); + + const txExecute = new VersionedTransaction(new TransactionMessage({ + payerKey: payer, + recentBlockhash: fixture.context.lastBlockhash, + instructions: [instruction], + }).compileToV0Message(lookupTableAccounts)); + + return txExecute; + } + + + return { txCreate: tx, getTxExecute }; +} export const sendSquadsTxWithTimelock = async (fixture: SquadsFixtureReturnType, { waitForTimelock = true, instructions, + multisigPda, }: { instructions: TransactionInstruction[]; waitForTimelock?: boolean; + multisigPda?: PublicKey; }, opt?: { revertedWithCreate?: string; revertedWithExecute?: string; fromCreate?: Keypair; fromExecute?: Keypair; }) => { - const { mutlisigPda, getMutlisigData, authority, squadsConnection } = fixture; + const { multisigPda: defaultMultisigPda, multisigWithSquadsSignerPda, multisigSignerPda, getMutlisigData, authority, squadsConnection } = fixture; const fromCreate = opt?.fromCreate ?? authority; const fromExecute = opt?.fromExecute ?? authority; + + multisigPda ??= defaultMultisigPda; + + const squadsSigner = multisigPda.equals(defaultMultisigPda) ? false : true; + + const memberCreate = squadsSigner ? multisigSignerPda : fromCreate.publicKey; + const memberExecute = squadsSigner ? multisigSignerPda : fromExecute.publicKey; + // Derive the PDA of the Squads Vault const [vaultPda] = multisig.getVaultPda({ - multisigPda: mutlisigPda as any, + multisigPda: multisigPda as any, index: 0, }); // Get deserialized multisig account info const multisigInfo = await multisig.accounts.Multisig.fromAccountAddress( squadsConnection, - mutlisigPda as any + multisigPda as any ); // Get the updated transaction index const newTransactionIndex = BigInt(multisigInfo.transactionIndex.toString()) + 1n; @@ -45,39 +128,60 @@ export const sendSquadsTxWithTimelock = async (fixture: SquadsFixtureReturnType, instructions: instructions, }); - const txCreate = new Transaction().add( + + let txCreate = new Transaction().add( multisig.instructions.vaultTransactionCreate({ - multisigPda: mutlisigPda as any, + multisigPda: multisigPda as any, transactionIndex: newTransactionIndex, - creator: fromCreate.publicKey, + creator: memberCreate, + rentPayer: fromCreate.publicKey, vaultIndex: 0, ephemeralSigners: 0, transactionMessage: txMessage as any, }), multisig.instructions.proposalCreate({ - multisigPda: mutlisigPda as any, + multisigPda: multisigPda as any, transactionIndex: newTransactionIndex, - creator: fromCreate.publicKey, + creator: memberCreate, + rentPayer: fromCreate.publicKey, }), multisig.instructions.proposalApprove({ - multisigPda: mutlisigPda as any, + multisigPda: multisigPda as any, transactionIndex: newTransactionIndex, - member: fromCreate.publicKey, - + member: memberCreate, }), ); + let getTxCreateExecute: () => Promise; + + if (squadsSigner) { + const res = await wrapTxWithSqudsSigner(fixture, { + instructions: txCreate.instructions, + member: fromCreate.publicKey, + payer: fromCreate.publicKey, + }); + + txCreate = res.txCreate; + getTxCreateExecute = res.getTxExecute; + } + if (opt?.revertedWithCreate !== undefined) { - await expectTxReverted(fixture.context, txCreate, [fromCreate], { + await expectTxReverted(fixture.context, txCreate, [authority, fromCreate], { revertedWith: opt.revertedWithCreate, }); return; } - await expectTxNotReverted(fixture.context, txCreate, [fromCreate]); + await expectTxNotReverted(fixture.context, txCreate, [authority, fromCreate]); + + if (getTxCreateExecute) { + const txCreateExecute = await getTxCreateExecute(); + await expectTxNotReverted(fixture.context, txCreateExecute, [authority, fromCreate]); + + } const [proposalPda] = multisig.getProposalPda({ - multisigPda: mutlisigPda as any, + multisigPda: multisigPda as any, transactionIndex: newTransactionIndex, }); const createdProposal = await multisig.accounts.Proposal.fromAccountAddress(squadsConnection, proposalPda); @@ -86,17 +190,30 @@ export const sendSquadsTxWithTimelock = async (fixture: SquadsFixtureReturnType, const inxExecute = await multisig.instructions.vaultTransactionExecute({ connection: squadsConnection, - multisigPda: mutlisigPda as any, - member: fromExecute.publicKey, + multisigPda: multisigPda as any, + member: memberExecute, transactionIndex: newTransactionIndex, }) - const txExecute = new VersionedTransaction(new TransactionMessage({ + let txExecute: Transaction | VersionedTransaction = new VersionedTransaction(new TransactionMessage({ payerKey: fromExecute.publicKey, recentBlockhash: fixture.context.lastBlockhash, instructions: [inxExecute.instruction], }).compileToV0Message(inxExecute.lookupTableAccounts)); + let getTxExecuteExecute: () => Promise; + + if (squadsSigner) { + const res = await wrapTxWithSqudsSigner(fixture, { + instructions: [inxExecute.instruction], + addressLookupTableAccounts: inxExecute.lookupTableAccounts, + member: fromExecute.publicKey, + payer: fromExecute.publicKey, + }); + + txExecute = res.txCreate; + getTxExecuteExecute = res.getTxExecute; + } if (waitForTimelock) { const currentTime = await fixture.context.banksClient.getClock().then(clock => clock.unixTimestamp); @@ -117,4 +234,159 @@ export const sendSquadsTxWithTimelock = async (fixture: SquadsFixtureReturnType, await expectTxNotReverted(fixture.context, txExecute, [fromExecute]); + if (getTxExecuteExecute) { + const txExecuteExecute = await getTxExecuteExecute(); + await expectTxNotReverted(fixture.context, txExecuteExecute, [fromExecute]); + } + + const proposalStatusAfter = await multisig.accounts.Proposal.fromAccountAddress(squadsConnection, proposalPda); + expect(proposalStatusAfter.status.__kind).toBe('Executed'); +} + +export const sendSquadsConfigurationTxWithTimelock = async (fixture: SquadsFixtureReturnType, { + waitForTimelock = true, + actions, + multisigPda, +}: { + actions: multisig.types.ConfigAction[]; + waitForTimelock?: boolean; + multisigPda?: PublicKey; +}, opt?: { + revertedWithCreate?: string; + revertedWithExecute?: string; + fromCreate?: Keypair; + fromExecute?: Keypair; +}) => { + const { multisigPda: defaultMultisigPda, multisigSignerPda, getMutlisigData, authority, squadsConnection } = fixture; + + const fromCreate = opt?.fromCreate ?? authority; + const fromExecute = opt?.fromExecute ?? authority; + + + multisigPda ??= defaultMultisigPda; + + const squadsSigner = multisigPda.equals(defaultMultisigPda) ? false : true; + + const member = squadsSigner ? multisigSignerPda : authority.publicKey; + + // Derive the PDA of the Squads Vault + const [vaultPda] = multisig.getVaultPda({ + multisigPda: multisigPda as any, + index: 0, + }); + + // Get deserialized multisig account info + const multisigInfo = await multisig.accounts.Multisig.fromAccountAddress( + squadsConnection, + multisigPda as any + ); + // Get the updated transaction index + const newTransactionIndex = BigInt(multisigInfo.transactionIndex.toString()) + 1n; + + let txCreate = new Transaction().add( + multisig.instructions.configTransactionCreate({ + multisigPda: multisigPda as any, + transactionIndex: newTransactionIndex, + creator: member, + rentPayer: fromCreate.publicKey, + actions, + }), + multisig.instructions.proposalCreate({ + multisigPda: multisigPda as any, + transactionIndex: newTransactionIndex, + creator: member, + rentPayer: fromCreate.publicKey, + }), + multisig.instructions.proposalApprove({ + multisigPda: multisigPda as any, + transactionIndex: newTransactionIndex, + member, + }), + ); + + let getTxCreateExecute: () => Promise; + + if (squadsSigner) { + const res = await wrapTxWithSqudsSigner(fixture, { + instructions: txCreate.instructions, + member: fromCreate.publicKey, + payer: fromCreate.publicKey, + }); + + txCreate = res.txCreate; + getTxCreateExecute = res.getTxExecute; + } + + if (opt?.revertedWithCreate !== undefined) { + await expectTxReverted(fixture.context, txCreate, [authority, fromCreate], { + revertedWith: opt.revertedWithCreate, + }); + return; + } + + await expectTxNotReverted(fixture.context, txCreate, [authority, fromCreate]); + + if (getTxCreateExecute) { + const txCreateExecute = await getTxCreateExecute(); + await expectTxNotReverted(fixture.context, txCreateExecute, [authority, fromCreate]); + + } + + const [proposalPda] = multisig.getProposalPda({ + multisigPda: multisigPda as any, + transactionIndex: newTransactionIndex, + }); + const createdProposal = await multisig.accounts.Proposal.fromAccountAddress(squadsConnection, proposalPda); + + expect(createdProposal.status.__kind).toBe('Approved'); + + + if (waitForTimelock) { + const currentTime = await fixture.context.banksClient.getClock().then(clock => clock.unixTimestamp); + const txApprovedAt = BigInt(createdProposal.status.__kind === 'Approved' ? createdProposal.status.timestamp.toString() : 0); + const timelockDuration = 2n * DAY; + const timelockEndsAt = txApprovedAt + timelockDuration; + const deltaTime = timelockEndsAt - BigInt(currentTime); + await timeTravel(fixture.context, deltaTime + 1n); + } + + + const inxExecute = multisig.instructions.configTransactionExecute({ + multisigPda: multisigPda as any, + member, + transactionIndex: newTransactionIndex, + }) + + let txExecute = new Transaction().add(inxExecute); + + let getTxExecuteExecute: () => Promise; + + if (squadsSigner) { + const res = await wrapTxWithSqudsSigner(fixture, { + instructions: txExecute.instructions, + member: fromExecute.publicKey, + payer: fromExecute.publicKey, + }); + + txExecute = res.txCreate; + getTxExecuteExecute = res.getTxExecute; + } + + + if (opt?.revertedWithExecute !== undefined) { + await expectTxReverted(fixture.context, txExecute, [authority, fromExecute], { + revertedWith: opt.revertedWithExecute, + }); + return; + } + + await expectTxNotReverted(fixture.context, txExecute, [authority, fromExecute]); + + if (getTxExecuteExecute) { + const txExecuteExecute = await getTxExecuteExecute(); + await expectTxNotReverted(fixture.context, txExecuteExecute, [authority, fromExecute]); + } + + const proposalStatusAfter = await multisig.accounts.Proposal.fromAccountAddress(squadsConnection, proposalPda); + expect(proposalStatusAfter.status.__kind).toBe('Executed'); } \ No newline at end of file From 4644d35eca675a9dcce3066e31d3ce3b42079daf Mon Sep 17 00:00:00 2001 From: kostyamospan <37243242+kostyamospan@users.noreply.github.com> Date: Sat, 14 Feb 2026 13:49:18 +0000 Subject: [PATCH 03/15] chore: timelock deployment scripts --- common/addresses.ts | 1 + package.json | 1 + scripts/configs/loadNetworkConfig.ts | 14 ++++ scripts/configs/network-config.ts | 11 +++ scripts/configs/types.ts | 12 ++++ scripts/deploy/timelock.ts | 70 +++++++++++++++++++ .../tasks/deploy/network/deploy-timelock.ts | 48 +++++++++++++ scripts/utils/addressQueries.ts | 4 ++ scripts/utils/addressRegistry.ts | 6 ++ 9 files changed, 167 insertions(+) create mode 100644 scripts/configs/loadNetworkConfig.ts create mode 100644 scripts/configs/network-config.ts create mode 100644 scripts/deploy/timelock.ts create mode 100644 scripts/tasks/deploy/network/deploy-timelock.ts diff --git a/common/addresses.ts b/common/addresses.ts index 05f68b5..44d7b7e 100644 --- a/common/addresses.ts +++ b/common/addresses.ts @@ -6,6 +6,7 @@ import { MProduct, PaymentToken } from './tokenTypes'; export interface NetworkAddresses { acRoleGlobal?: PublicKey; ac?: PublicKey; + timelock?: PublicKey; tokens?: Partial>; feeds?: Partial>; } diff --git a/package.json b/package.json index 4883004..708196a 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "format": "prettier --write .", "format:check": "prettier --check .", "docgen": "cargo doc", + "deploy:timelock": "tsx scripts/tasks/deploy/network/deploy-timelock.ts", "deploy:global-ac-role": "tsx scripts/tasks/deploy/network/deploy-global-ac-role.ts", "deploy:global-ac": "tsx scripts/tasks/deploy/network/deploy-global-ac.ts", "deploy:token-ac-role": "tsx scripts/tasks/deploy/deploy-token-ac-role.ts", diff --git a/scripts/configs/loadNetworkConfig.ts b/scripts/configs/loadNetworkConfig.ts new file mode 100644 index 0000000..a4be48b --- /dev/null +++ b/scripts/configs/loadNetworkConfig.ts @@ -0,0 +1,14 @@ +import { createUserError } from '@/common/errorHandler'; + +import { NetworkConfig, networkConfigSchema} from './types'; +import { networkConfigs } from './network-config'; + +export function loadNetworkConfig(network: string): NetworkConfig[string] { + const config = networkConfigs[network]; + if (!config) { + throw createUserError(`Network config not found: ${network}`); + } + + const networkConfig = networkConfigSchema.parse(config); + return networkConfig[network]; +} diff --git a/scripts/configs/network-config.ts b/scripts/configs/network-config.ts new file mode 100644 index 0000000..f31a300 --- /dev/null +++ b/scripts/configs/network-config.ts @@ -0,0 +1,11 @@ +import { NetworkConfig } from "./types"; + +export const networkConfigs: NetworkConfig = { + devnet: { + timelock: { + // 2 days + delay: 2 * 86400, + member: '33vVYcpTkv7HyEnkFHQVY1ndUSfHNFHxyG9PBqy2MCwm', + }, + }, +}; \ No newline at end of file diff --git a/scripts/configs/types.ts b/scripts/configs/types.ts index c1dc056..0012e68 100644 --- a/scripts/configs/types.ts +++ b/scripts/configs/types.ts @@ -169,6 +169,11 @@ export const redeemerVaultConfigSchema = z.object({ paymentTokens: z.array(paymentTokenConfigSchema), }); +export const timelockConfigSchema = z.object({ + delay: z.number().int().positive(), + member: publicKeySchema, +}); + export const tokenConfigSchema = z.object({ metadata: tokenMetadataSchema, tokenAuthority: tokenAuthorityConfigSchema, @@ -213,6 +218,13 @@ export const paymentTokenConfigWithNetworksSchema = z.object({ networks: z.record(z.string(), paymentTokenNetworkConfigSchema), }); +export const networkConfigSchema = z.record(z.string(), + z.object({ + timelock: timelockConfigSchema.optional(), + }) +); + +export type NetworkConfig = z.infer; export type DataFeedConfig = z.infer; export type TokenConfig = z.infer; export type TokenConfigWithNetworks = z.infer; diff --git a/scripts/deploy/timelock.ts b/scripts/deploy/timelock.ts new file mode 100644 index 0000000..a267d0d --- /dev/null +++ b/scripts/deploy/timelock.ts @@ -0,0 +1,70 @@ +import { Keypair, PublicKey, Transaction } from '@solana/web3.js'; + +import { sendAndWaitForCustomSolanaTxSign } from '@/common/solanaTxHelper'; + +import { CommonParams } from './dataFeed'; +import * as multisig from "@sqds/multisig"; + +export interface DeployTimelockConfig { + delay: number; + member: PublicKey; + createKey?: Keypair; +} + +export const deployTimelock = async (common: CommonParams, { delay, member, createKey }: DeployTimelockConfig) => { + createKey ??= Keypair.generate(); + const [multisigPda] = multisig.getMultisigPda({ + createKey: createKey.publicKey, + }); + + const programConfigPda = multisig.getProgramConfigPda({})[0]; + + const programConfig = + await multisig.accounts.ProgramConfig.fromAccountAddress( + common.provider.connection as any, + programConfigPda + ); + + const configTreasury = programConfig.treasury; + + const tx = new Transaction().add(multisig.instructions.multisigCreateV2({ + // Must sign the transaction, unless the .rpc method is used. + createKey: createKey.publicKey, + // The creator & fee payer + creator: common.payer.publicKey, + // The PDA of the multisig you are creating, derived by a random PublicKey + multisigPda, + // Here the config authority will be the system program + configAuthority: null, + // Create without any time-lock + timeLock: Number(delay), + // List of the members to add to the multisig + members: [{ + // Members Public Key + key: member, + // Granted Proposer, Voter, and Executor permissions + permissions: multisig.types.Permissions.all(), + }], + // This means that there needs to be 2 votes for a transaction proposal to be approved + threshold: 1, + // This is for the program config treasury account + treasury: configTreasury, + // Rent reclaim account + rentCollector: member + })); + + const result = await sendAndWaitForCustomSolanaTxSign(common.provider, tx, [createKey], { + action: 'deployer', + comment: 'Deploy Timelock', + waitForTx: true, + pollingIntervalMs: 1000, + timeoutDurationMs: 120 * 1000, + }); + + if (result.signature) { + console.log(`Transaction signature: ${result.signature}`); + } + + return multisigPda as PublicKey; +}; + diff --git a/scripts/tasks/deploy/network/deploy-timelock.ts b/scripts/tasks/deploy/network/deploy-timelock.ts new file mode 100644 index 0000000..9c3b12a --- /dev/null +++ b/scripts/tasks/deploy/network/deploy-timelock.ts @@ -0,0 +1,48 @@ +import { AnchorProvider, Wallet } from '@coral-xyz/anchor'; + +import { createUserError } from '@/common/errorHandler'; +import { executeNetworkScript } from '@/common/scriptRunner'; + +import { getTimelockAddress } from '../../../utils/addressQueries'; +import { registerGlobalTimelock } from '../../../utils/addressRegistry'; +import { saveAddressesToFile } from '../../../utils/addressStorage'; +import { getNetwork } from '../../../utils/argumentParser'; +import { loadNetworkConfig } from '@/scripts/configs/loadNetworkConfig'; +import { deployTimelock, DeployTimelockConfig } from '@/scripts/deploy/timelock'; +import { PublicKey } from '@solana/web3.js'; + +async function main(provider: AnchorProvider, payer: Wallet, network: string) { + console.log(`Deploying Timelock for: ${network}`); + + const networkConfig = loadNetworkConfig(network); + + if (!networkConfig?.timelock) { + throw createUserError(`Timelock config not found for network ${network}`,); + } + + const existingTimelock = getTimelockAddress(network); + if (existingTimelock) { + console.log('āœ“ Timelock already deployed'); + console.log(`Timelock: ${existingTimelock.toString()}`); + return; + } + + const common = { provider, payer, network }; + + const timelockConfig: DeployTimelockConfig = { + delay: networkConfig.timelock.delay, + member: new PublicKey(networkConfig.timelock.member), + }; + + const timelock = await deployTimelock(common, timelockConfig); + + registerGlobalTimelock(network, timelock); + await saveAddressesToFile(); + + console.log('\nāœ… Timelock deployment submitted'); + console.log(`Timelock: ${timelock.toString()}`); + return; +} + +const network = getNetwork(); +executeNetworkScript(network, main, 'deployer'); diff --git a/scripts/utils/addressQueries.ts b/scripts/utils/addressQueries.ts index 4efd3e6..91110ab 100644 --- a/scripts/utils/addressQueries.ts +++ b/scripts/utils/addressQueries.ts @@ -25,6 +25,10 @@ export function getAcAddress(network: string): PublicKey | undefined { return addresses[network]?.ac; } +export function getTimelockAddress(network: string): PublicKey | undefined { + return addresses[network]?.timelock; +} + export function getAcRoleGlobalAddress(network: string): PublicKey | undefined { return addresses[network]?.acRoleGlobal; } diff --git a/scripts/utils/addressRegistry.ts b/scripts/utils/addressRegistry.ts index 321180c..3d042f0 100644 --- a/scripts/utils/addressRegistry.ts +++ b/scripts/utils/addressRegistry.ts @@ -50,6 +50,12 @@ export function registerGlobalAc(network: string, ac: PublicKey): void { networkAddrs.ac = ac; } +export function registerGlobalTimelock(network: string, timelock: PublicKey): void { + ensureNetworkExists(network); + const networkAddrs = addresses[network]; + networkAddrs.timelock = timelock; +} + // Validation helpers function validateValueNotNull(component: string, value: T | null | undefined): void { if (value === null || value === undefined) { From 4cf5cbead1faa8abbeb88880c98ea586a4235ac1 Mon Sep 17 00:00:00 2001 From: kostyamospan <37243242+kostyamospan@users.noreply.github.com> Date: Mon, 16 Feb 2026 16:15:34 +0000 Subject: [PATCH 04/15] chore: upgrade scripts --- common/addresses.ts | 13 + package.json | 6 +- scripts/README.md | 5 +- scripts/configs/network-config.ts | 2 +- scripts/deploy/timelock.ts | 325 +++++++- scripts/tasks/deploy/deploy-nonce-account.ts | 3 +- .../tasks/deploy/network/deploy-timelock.ts | 8 +- .../manage/transfer-upgrade-authority.ts | 82 ++ .../tasks/upgrade/execute-upgrade-program.ts | 86 ++ .../tasks/upgrade/propose-upgrade-program.ts | 87 ++ scripts/utils/argumentParser.ts | 104 ++- scripts/utils/loaderProgramHelpers.ts | 62 ++ yarn.lock | 753 +++++++++++++++++- 13 files changed, 1500 insertions(+), 36 deletions(-) create mode 100644 scripts/tasks/manage/transfer-upgrade-authority.ts create mode 100644 scripts/tasks/upgrade/execute-upgrade-program.ts create mode 100644 scripts/tasks/upgrade/propose-upgrade-program.ts create mode 100644 scripts/utils/loaderProgramHelpers.ts diff --git a/common/addresses.ts b/common/addresses.ts index 44d7b7e..f0a3bd5 100644 --- a/common/addresses.ts +++ b/common/addresses.ts @@ -3,6 +3,11 @@ import { PublicKey } from '@solana/web3.js'; import { MProduct, PaymentToken } from './tokenTypes'; +import ACCESS_CONTROL_IDL from '../target/idl/access_control.json' with { type: 'json' }; +import VAULTS_IDL from '../target/idl/midas_vaults.json' with { type: 'json' }; +import TOKEN_AUTHORITY_IDL from '../target/idl/token_authority.json' with { type: 'json' }; +import DATA_FEED_IDL from '../target/idl/data_feed.json' with { type: 'json' }; + export interface NetworkAddresses { acRoleGlobal?: PublicKey; ac?: PublicKey; @@ -111,3 +116,11 @@ export const addresses: Record = { }, }, }; + + +export const programAddresses = { + access_control: new PublicKey(ACCESS_CONTROL_IDL.address), + midas_vaults: new PublicKey(VAULTS_IDL.address), + token_authority: new PublicKey(TOKEN_AUTHORITY_IDL.address), + data_feed: new PublicKey(DATA_FEED_IDL.address), +}; \ No newline at end of file diff --git a/package.json b/package.json index 708196a..bc7e113 100644 --- a/package.json +++ b/package.json @@ -32,10 +32,14 @@ "transfer:authority": "tsx scripts/tasks/manage/transfer-authority.ts", "update:data-feed": "tsx scripts/tasks/manage/update-data-feed.ts", "update:manual-feed-price": "tsx scripts/tasks/manage/update-manual-feed-price.ts", - "delegate": "tsx scripts/tasks/manage/delegate.ts" + "delegate": "tsx scripts/tasks/manage/delegate.ts", + "upgrade:program:propose": "tsx scripts/tasks/upgrade/propose-upgrade-program.ts", + "upgrade:program:execute": "tsx scripts/tasks/upgrade/execute-upgrade-program.ts" }, "dependencies": { "@coral-xyz/anchor": "0.30.1", + "@solana-program/loader-v3": "0.3.0", + "@solana/kit": "6.0.1", "@solana/spl-token": "0.4.9", "@solana/spl-token-metadata": "0.1.6", "@solana/web3.js": "1.95.4", diff --git a/scripts/README.md b/scripts/README.md index 5ec0ae9..f281f80 100644 --- a/scripts/README.md +++ b/scripts/README.md @@ -15,8 +15,9 @@ anchor deploy --provider.cluster Run once per network before deploying any tokens: -1. `yarn deploy:global-ac-role --network ` - Deploy Global AC Role -2. `yarn deploy:global-ac --network ` - Deploy Global AC +1. `yarn deploy:timelock --network ` - Deploy Timelock for upgrade authority +2. `yarn deploy:global-ac-role --network ` - Deploy Global AC Role +3. `yarn deploy:global-ac --network ` - Deploy Global AC ### Token Deployment diff --git a/scripts/configs/network-config.ts b/scripts/configs/network-config.ts index f31a300..427b184 100644 --- a/scripts/configs/network-config.ts +++ b/scripts/configs/network-config.ts @@ -5,7 +5,7 @@ export const networkConfigs: NetworkConfig = { timelock: { // 2 days delay: 2 * 86400, - member: '33vVYcpTkv7HyEnkFHQVY1ndUSfHNFHxyG9PBqy2MCwm', + member: '77F5WP7E9PE3cRbUXGZ8W8S2zvSGvb2WS7QuVGYpavug', }, }, }; \ No newline at end of file diff --git a/scripts/deploy/timelock.ts b/scripts/deploy/timelock.ts index a267d0d..0b2639b 100644 --- a/scripts/deploy/timelock.ts +++ b/scripts/deploy/timelock.ts @@ -1,9 +1,10 @@ -import { Keypair, PublicKey, Transaction } from '@solana/web3.js'; +import { AddressLookupTableAccount, Connection, Keypair, PublicKey, Transaction, TransactionInstruction, TransactionMessage, VersionedTransaction } from '@solana/web3.js'; import { sendAndWaitForCustomSolanaTxSign } from '@/common/solanaTxHelper'; import { CommonParams } from './dataFeed'; import * as multisig from "@sqds/multisig"; +import { Wallet } from '@coral-xyz/anchor'; export interface DeployTimelockConfig { delay: number; @@ -11,6 +12,328 @@ export interface DeployTimelockConfig { createKey?: Keypair; } + + +const wrapTxWithSqudsSigner = async (connection: Connection, { + instructions, + multisigSignerPda, + addressLookupTableAccounts, + member, +}: { + instructions: TransactionInstruction[], + addressLookupTableAccounts?: AddressLookupTableAccount[], + multisigSignerPda: PublicKey, + member: PublicKey +}) => { + // Derive the PDA of the Squads Vault + const [vaultPda] = multisig.getVaultPda({ + multisigPda: multisigSignerPda, + index: 0, + }); + + // Get deserialized multisig account info + const multisigInfo = await multisig.accounts.Multisig.fromAccountAddress( + connection as any, + multisigSignerPda + ); + // Get the updated transaction index + const newTransactionIndex = BigInt(multisigInfo.transactionIndex.toString()) + 1n; + + const [proposalPda] = multisig.getProposalPda({ + multisigPda: multisigSignerPda, + transactionIndex: newTransactionIndex, + programId: multisig.PROGRAM_ID, + }); + + const [transactionPda] = multisig.getTransactionPda({ + multisigPda: multisigSignerPda, + index: newTransactionIndex, + programId: multisig.PROGRAM_ID, + }); + + const txMessage = new TransactionMessage({ + payerKey: vaultPda, + recentBlockhash: await connection.getLatestBlockhash().then(v => v.blockhash), + instructions: instructions, + }); + + const tx = new Transaction().add( + multisig.instructions.vaultTransactionCreate({ + multisigPda: multisigSignerPda, + transactionIndex: newTransactionIndex, + rentPayer: member, + creator: member, + vaultIndex: 0, + ephemeralSigners: 0, + transactionMessage: txMessage as any, + addressLookupTableAccounts, + }), + multisig.instructions.proposalCreate({ + multisigPda: multisigSignerPda, + transactionIndex: newTransactionIndex, + creator: member, + rentPayer: member, + }), + multisig.instructions.proposalApprove({ + multisigPda: multisigSignerPda, + transactionIndex: newTransactionIndex, + member: member, + }), + ); + + const messageBytes = multisig.utils.transactionMessageToMultisigTransactionMessageBytes({ + message: txMessage as any, + addressLookupTableAccounts, + vaultPda, + }); + + const [messageDecoded] = multisig.types.transactionMessageBeet.deserialize(Buffer.from(messageBytes)); + + const { accountMetas, lookupTableAccounts } = + await multisig.utils.accountsForTransactionExecute({ + connection: connection as any, + message: { + numSigners: messageDecoded.numSigners, + numWritableSigners: messageDecoded.numWritableSigners, + numWritableNonSigners: messageDecoded.numWritableNonSigners, + accountKeys: messageDecoded.accountKeys, + instructions: messageDecoded.instructions.map((instruction) => { + return { + programIdIndex: instruction.programIdIndex, + accountIndexes: new Uint8Array(instruction.accountIndexes), + data: new Uint8Array(instruction.data), + }; + }), + addressTableLookups: messageDecoded.addressTableLookups.map((lookup) => { + return { + accountKey: lookup.accountKey, + writableIndexes: new Uint8Array(lookup.writableIndexes), + readonlyIndexes: new Uint8Array(lookup.readonlyIndexes), + }; + }), + }, + ephemeralSignerBumps: [], + vaultPda, + transactionPda, + programId: multisig.PROGRAM_ID, + }); + + const res = { + instruction: multisig.generated.createVaultTransactionExecuteInstruction( + { + multisig: multisigSignerPda, + member: member, + proposal: proposalPda, + transaction: transactionPda, + anchorRemainingAccounts: accountMetas, + }, + multisig.PROGRAM_ID + ), + lookupTableAccounts, + }; + + const latestBlockhash = await connection.getLatestBlockhash().then(v => v.blockhash); + + const closeTxInstruction = multisig.instructions.vaultTransactionAccountsClose({ + multisigPda: multisigSignerPda, + transactionIndex: newTransactionIndex, + rentCollector: multisigInfo.rentCollector + }); + + const mergeTxs = async () => { + const instructions = [...tx.instructions, res.instruction, closeTxInstruction]; + const txMessage = new TransactionMessage({ + payerKey: member, + recentBlockhash: latestBlockhash, + instructions: instructions, + }); + + return new VersionedTransaction(txMessage.compileToV0Message(res.lookupTableAccounts)); + } + + return mergeTxs(); +} + +export const sendTxWithTimelock = async (connection: Connection, { + instructions, + timelock, + signer, + action +}: { + instructions: TransactionInstruction[]; + timelock: PublicKey; + signer: PublicKey; + action: { type: 'create' } | { type: 'execute', transactionIndex: bigint }; +}) => { + + const payer = signer; + + // Derive the PDA of the Squads Vault + const [vaultPda] = multisig.getVaultPda({ + multisigPda: timelock, + index: 0, + }); + + // Get deserialized multisig account info + const multisigInfo = await multisig.accounts.Multisig.fromAccountAddress( + connection as any, + timelock + ); + + if (multisigInfo.members.length !== 1) { + throw new Error('Expected timelock to have only one member, got ' + multisigInfo.members.length); + } + + const multisigSignerPda = multisigInfo.members[0].key; + + const multisigSignerPdaAccount: multisig.accounts.Multisig | null = await multisig.accounts.Multisig.fromAccountAddress(connection as any, multisigSignerPda).catch(err => { + if (err instanceof Error && err.message.includes('Unable to find Multisig account at')) { + return null; + } + throw err; + }); + + const squadsSigner = multisigSignerPdaAccount !== null; + + if (squadsSigner) { + console.log('Timelock member is a squads signer, timelock txs will be wrapped with squads signer'); + } + + const member = squadsSigner ? multisigSignerPda : payer; + + let tx: Transaction | VersionedTransaction; + + if (action.type === 'create') { + // Get the updated transaction index + // TODO: get the index from the custom signer + const newTransactionIndex = BigInt(multisigInfo.transactionIndex.toString()) + 1n; + + // Build a message with instructions we want to execute + const txMessage = new TransactionMessage({ + payerKey: vaultPda, + recentBlockhash: await connection.getLatestBlockhash().then(v => v.blockhash), + instructions: instructions, + }); + + + const txCreate = new Transaction().add( + multisig.instructions.vaultTransactionCreate({ + multisigPda: timelock, + transactionIndex: newTransactionIndex, + creator: member, + rentPayer: payer, + vaultIndex: 0, + ephemeralSigners: 0, + transactionMessage: txMessage as any, + }), + multisig.instructions.proposalCreate({ + multisigPda: timelock, + transactionIndex: newTransactionIndex, + creator: member, + rentPayer: payer, + }), + multisig.instructions.proposalApprove({ + multisigPda: timelock, + transactionIndex: newTransactionIndex, + member: member, + }), + ); + + tx = txCreate; + + if (squadsSigner !== undefined) { + tx = await wrapTxWithSqudsSigner(connection, { + instructions: txCreate.instructions, + member: payer, + multisigSignerPda: multisigSignerPda, + }); + } + + } else { + const transactionIndex = action.transactionIndex; + + const [proposalPda] = multisig.getProposalPda({ + multisigPda: timelock, + transactionIndex, + }); + const createdProposal: multisig.accounts.Proposal | null = await multisig.accounts.Proposal.fromAccountAddress(connection as any, proposalPda).catch(err => { + if (err instanceof Error && err.message.includes('Unable to find Proposal account at')) { + return null; + } + throw err; + }); + + if (createdProposal === null) { + throw new Error('Expected proposal to be created, but it was not found'); + } + + if (createdProposal.status.__kind !== 'Approved') { + throw new Error('Expected proposal to be approved, but the status is ' + createdProposal.status.__kind); + } else { + console.log('Proposal is approved, executing transaction'); + } + + const inxExecute = await multisig.instructions.vaultTransactionExecute({ + connection: connection as any, + multisigPda: timelock, + member: member, + transactionIndex, + }) + + tx = new VersionedTransaction(new TransactionMessage({ + payerKey: payer, + recentBlockhash: await connection.getLatestBlockhash().then(v => v.blockhash), + instructions: [inxExecute.instruction], + }).compileToV0Message(inxExecute.lookupTableAccounts)); + + if (squadsSigner !== undefined) { + tx = await wrapTxWithSqudsSigner(connection, { + instructions: [inxExecute.instruction], + member: payer, + multisigSignerPda: multisigSignerPda, + addressLookupTableAccounts: inxExecute.lookupTableAccounts, + }); + } + } + + return tx; +} + +export const getTimelockTransaction = async (connection: Connection, { + timelock, + transactionIndex +}: { + timelock: PublicKey; + transactionIndex: bigint; +}) => { + + const [transactionPda] = multisig.getTransactionPda({ + multisigPda: timelock, + index: transactionIndex, + }); + + const transaction: multisig.accounts.VaultTransaction | null = await multisig.accounts.VaultTransaction.fromAccountAddress(connection as any, transactionPda).catch(err => { + if (err instanceof Error && err.message.includes('Unable to find VaultTransaction account at')) { + return null; + } + throw err; + }); + + const [proposalPda] = multisig.getProposalPda({ + multisigPda: timelock, + transactionIndex: transactionIndex, + }); + + const proposal: multisig.accounts.Proposal | null = await multisig.accounts.Proposal.fromAccountAddress(connection as any, proposalPda).catch(err => { + if (err instanceof Error && err.message.includes('Unable to find Proposal account at')) { + return null; + } + throw err; + }); + + return { proposal, transaction }; +}; + export const deployTimelock = async (common: CommonParams, { delay, member, createKey }: DeployTimelockConfig) => { createKey ??= Keypair.generate(); const [multisigPda] = multisig.getMultisigPda({ diff --git a/scripts/tasks/deploy/deploy-nonce-account.ts b/scripts/tasks/deploy/deploy-nonce-account.ts index 8cd4b09..d2b3d26 100644 --- a/scripts/tasks/deploy/deploy-nonce-account.ts +++ b/scripts/tasks/deploy/deploy-nonce-account.ts @@ -7,8 +7,7 @@ import { deployNonceAccount } from '../../deploy/nonce-account'; import { getAuthority, getNetwork } from '../../utils/argumentParser'; async function main(provider: AnchorProvider, payer: Wallet, network: string) { - const authorityStr = getAuthority(); - const authority = new PublicKey(authorityStr); + const authority = getAuthority(); console.log(`Deploying nonce account for authority: ${authority.toBase58()}`); console.log(`Network: ${network}`); diff --git a/scripts/tasks/deploy/network/deploy-timelock.ts b/scripts/tasks/deploy/network/deploy-timelock.ts index 9c3b12a..5e6cf9b 100644 --- a/scripts/tasks/deploy/network/deploy-timelock.ts +++ b/scripts/tasks/deploy/network/deploy-timelock.ts @@ -3,10 +3,10 @@ import { AnchorProvider, Wallet } from '@coral-xyz/anchor'; import { createUserError } from '@/common/errorHandler'; import { executeNetworkScript } from '@/common/scriptRunner'; -import { getTimelockAddress } from '../../../utils/addressQueries'; -import { registerGlobalTimelock } from '../../../utils/addressRegistry'; -import { saveAddressesToFile } from '../../../utils/addressStorage'; -import { getNetwork } from '../../../utils/argumentParser'; +import { getTimelockAddress } from '@/scripts/utils/addressQueries'; +import { registerGlobalTimelock } from '@/scripts/utils/addressRegistry'; +import { saveAddressesToFile } from '@/scripts/utils/addressStorage'; +import { getNetwork } from '@/scripts/utils/argumentParser'; import { loadNetworkConfig } from '@/scripts/configs/loadNetworkConfig'; import { deployTimelock, DeployTimelockConfig } from '@/scripts/deploy/timelock'; import { PublicKey } from '@solana/web3.js'; diff --git a/scripts/tasks/manage/transfer-upgrade-authority.ts b/scripts/tasks/manage/transfer-upgrade-authority.ts new file mode 100644 index 0000000..feb1f51 --- /dev/null +++ b/scripts/tasks/manage/transfer-upgrade-authority.ts @@ -0,0 +1,82 @@ + +import { AnchorProvider, Wallet } from '@coral-xyz/anchor'; + +import { createUserError } from '@/common/errorHandler'; +import { executeNetworkScript } from '@/common/scriptRunner'; + +import { getTimelockAddress } from '@/scripts/utils/addressQueries'; +import { getAuthority, getNetwork, getProgram } from '@/scripts/utils/argumentParser'; +import { PublicKey, Transaction } from '@solana/web3.js'; +import { programAddresses } from '@/common/addresses'; +import { LOADER_V3_PROGRAM_ADDRESS } from '@solana-program/loader-v3'; +import { sendAndWaitForCustomSolanaTxSign } from '@/common/solanaTxHelper'; +import { getSetAuthorityInstructionIx } from '@/scripts/utils/loaderProgramHelpers'; + +async function main( + provider: AnchorProvider, + payer: Wallet, + network: string, +) { + let authority = getAuthority(false); + const program = getProgram(); + + + if (!authority) { + console.log('Authority not provided, will use timelock as new authority'); + + const existingTimelock = getTimelockAddress(network); + if (!existingTimelock) { + throw createUserError(`Timelock not found for network ${network}`,); + } + + authority = existingTimelock; + } + + console.log(`Transferring upgrade authority for program ${program} to ${authority.toBase58()} on network ${network}`); + + const common = { provider, payer, network }; + + const programId = programAddresses[program]; + + if (!programId) { + throw createUserError(`Program id for ${program} not found`,); + } + + const [programDataPda] = PublicKey.findProgramAddressSync( + [programId.toBuffer()], + new PublicKey(LOADER_V3_PROGRAM_ADDRESS) + ); + + const data = await provider.connection.getAccountInfo(programDataPda); + + if (!data) { + throw createUserError(`No program data found for ${program} at address ${programDataPda.toBase58()}`); + } + + const tx = new Transaction().add(getSetAuthorityInstructionIx({ + bufferOrProgramDataAccount: programDataPda, + currentAuthority: payer.publicKey, + newAuthority: authority, + })); + + const result = await sendAndWaitForCustomSolanaTxSign(common.provider, tx, [], { + action: 'update-timelock', + comment: `Transfer upgrade authority for ${program} to ${authority.toBase58()} on network ${network}`, + waitForTx: true, + pollingIntervalMs: 1000, + timeoutDurationMs: 120 * 1000, + }); + + if (result.signature) { + console.log(`Transaction signature: ${result.signature}`); + } +} + +const network = getNetwork(); + +executeNetworkScript( + network, + (provider, payer, network) => + main(provider, payer as Wallet, network), + 'update-timelock' +); diff --git a/scripts/tasks/upgrade/execute-upgrade-program.ts b/scripts/tasks/upgrade/execute-upgrade-program.ts new file mode 100644 index 0000000..12f58be --- /dev/null +++ b/scripts/tasks/upgrade/execute-upgrade-program.ts @@ -0,0 +1,86 @@ + +import { AnchorProvider, Wallet } from '@coral-xyz/anchor'; + +import { createUserError } from '@/common/errorHandler'; +import { executeNetworkScript } from '@/common/scriptRunner'; + +import { getTimelockAddress } from '@/scripts/utils/addressQueries'; +import { getMultisigTxIndex, getNetwork } from '@/scripts/utils/argumentParser'; +import { programAddresses } from '@/common/addresses'; +import { sendAndWaitForCustomSolanaTxSign } from '@/common/solanaTxHelper'; +import { getTimelockTransaction, sendTxWithTimelock } from '@/scripts/deploy/timelock'; + +async function main( + provider: AnchorProvider, + payer: Wallet, + network: string +) { + const multisigTxIndex = getMultisigTxIndex(); + + console.log(`Executing program upgrade trough the timelock for: ${network}`); + + const existingTimelock = getTimelockAddress(network); + if (!existingTimelock) { + throw createUserError(`Timelock not found for network ${network}`,); + } + + const common = { provider, payer, network }; + + const { transaction, proposal } = await getTimelockTransaction(common.provider.connection, { + timelock: existingTimelock, + transactionIndex: BigInt(multisigTxIndex), + }); + + if (!transaction || !proposal) { + throw createUserError(`Transaction or proposal not found for multisig tx index ${multisigTxIndex}. Its either not created or already executed`,); + } + + if (proposal.status.__kind !== 'Approved') { + throw createUserError(`Proposal is not approved for multisig tx index ${multisigTxIndex}`,); + } + + const programIdIndex = transaction.message.instructions[0].accountIndexes[1]; + const bufferIndex = transaction.message.instructions[0].accountIndexes[2]; + + const programId = transaction.message.accountKeys[programIdIndex]; + const buffer = transaction.message.accountKeys[bufferIndex]; + + console.log(`Program id: ${programId.toBase58()}`); + console.log(`Buffer: ${buffer.toBase58()}`); + + const program = Object.keys(programAddresses).find(key => programAddresses[key as keyof typeof programAddresses].equals(programId)); + + if (!program) { + throw createUserError(`Program id ${programId.toBase58()} not found in program addresses`,); + } + + console.log(`Program: ${program}`); + + const tx = await sendTxWithTimelock(common.provider.connection, { + instructions: [], + timelock: existingTimelock, + signer: payer.publicKey, + action: { type: 'execute', transactionIndex: BigInt(multisigTxIndex) }, + }); + + const result = await sendAndWaitForCustomSolanaTxSign(common.provider, tx, [], { + action: 'update-timelock', + comment: `Execute upgrade of ${program} program trough the timelock`, + waitForTx: true, + pollingIntervalMs: 1000, + timeoutDurationMs: 120 * 1000, + }); + + if (result.signature) { + console.log(`Transaction signature: ${result.signature}`); + } +} + +const network = getNetwork(); + +executeNetworkScript( + network, + (provider, payer, network) => + main(provider, payer as Wallet, network), + 'update-timelock' +); diff --git a/scripts/tasks/upgrade/propose-upgrade-program.ts b/scripts/tasks/upgrade/propose-upgrade-program.ts new file mode 100644 index 0000000..8d8b75a --- /dev/null +++ b/scripts/tasks/upgrade/propose-upgrade-program.ts @@ -0,0 +1,87 @@ + +import { AnchorProvider, Wallet } from '@coral-xyz/anchor'; + +import { createUserError } from '@/common/errorHandler'; +import { executeNetworkScript } from '@/common/scriptRunner'; + +import { getTimelockAddress } from '@/scripts/utils/addressQueries'; +import { getBufferAccount, getMultisigTxIndex, getNetwork, getProgram } from '@/scripts/utils/argumentParser'; +import { PublicKey, TransactionInstruction } from '@solana/web3.js'; +import { programAddresses } from '@/common/addresses'; +import { getUpgradeInstruction, LOADER_V3_PROGRAM_ADDRESS } from '@solana-program/loader-v3'; +import { sendAndWaitForCustomSolanaTxSign } from '@/common/solanaTxHelper'; +import { AccountRole, Address, TransactionSigner } from '@solana/kit'; +import { sendTxWithTimelock } from '@/scripts/deploy/timelock'; +import { getUpgradeInstructionIx } from '@/scripts/utils/loaderProgramHelpers'; + +async function main( + provider: AnchorProvider, + payer: Wallet, + network: string +) { + const bufferAccount = getBufferAccount(); + const program = getProgram(); + + console.log(`Proposing upgrade of ${program} program trough the timelock for: ${network}`); + + const existingTimelock = getTimelockAddress(network); + if (!existingTimelock) { + throw createUserError(`Timelock not found for network ${network}`,); + } + + const common = { provider, payer, network }; + + const programId = programAddresses[program]; + + if (!programId) { + throw createUserError(`Program id for ${program} not found`,); + } + + const [programDataPda] = PublicKey.findProgramAddressSync( + [programId.toBuffer()], + new PublicKey(LOADER_V3_PROGRAM_ADDRESS) + ); + + const data = await provider.connection.getAccountInfo(programDataPda); + + if (!data) { + throw createUserError(`No program data found for ${program} at address ${programDataPda.toBase58()}`); + } + + const inx = getUpgradeInstructionIx({ + programId, + programDataPda, + bufferAccount, + spillAccount: payer.publicKey, + authority: payer.publicKey, + }); + + const tx = await sendTxWithTimelock(common.provider.connection, { + instructions: [inx], + timelock: existingTimelock, + signer: payer.publicKey, + action: { type: 'create' }, + }); + + const result = await sendAndWaitForCustomSolanaTxSign(common.provider, tx, [], { + action: 'update-timelock', + comment: `Propose upgrade of ${program} program trough the timelock`, + waitForTx: true, + pollingIntervalMs: 1000, + timeoutDurationMs: 120 * 1000, + }); + + if (result.signature) { + console.log(`Transaction signature: ${result.signature}`); + } +} + +const network = getNetwork(); + + +executeNetworkScript( + network, + (provider, payer, network) => + main(provider, payer as Wallet, network), + 'update-timelock' +); diff --git a/scripts/utils/argumentParser.ts b/scripts/utils/argumentParser.ts index 20f1cba..968cd6e 100644 --- a/scripts/utils/argumentParser.ts +++ b/scripts/utils/argumentParser.ts @@ -5,6 +5,8 @@ import { createUserError } from '@/common/errorHandler'; import { MProduct, isMProduct, PaymentToken, isPaymentToken } from '@/common/tokenTypes'; import { getAvailableNetworks } from './getAvailableNetworks'; +import { PublicKey } from '@solana/web3.js'; +import { programAddresses } from '@/common/addresses'; /** Simple cached parser - parses all args once */ let parsedArgs: Record | null = null; @@ -52,6 +54,97 @@ export function getNetwork(): string { return network; } +/** Get network from arguments */ +export function getBufferAccount(): PublicKey { + const argv = getParsedArgs(); + const bufferAccount = (argv.buffer || argv.ba) as string | undefined; + + if (!bufferAccount) { + throw createUserError('Buffer account is required', [ + 'Use --buffer or -b to specify the buffer account', + 'Example: --buffer 33vVYcpTkv7HyEnkFHQVY1ndUSfHNFHxyG9PBqy2MCwmc', + ]); + } + + try { + return new PublicKey(bufferAccount); + } catch { + throw createUserError(`Invalid buffer account '${bufferAccount}'`, [ + 'Must be a valid PublicKey', + ]); + } +} + +/** Get network from arguments */ +export function getProgram(): keyof (typeof programAddresses) { + const argv = getParsedArgs(); + const program = (argv.program || argv.p) as string | undefined; + + if (!program) { + throw createUserError('Program is required', [ + 'Use --program or -p to specify the program', + 'Example: --program access_control', + ]); + } + + const availablePrograms = Object.keys(programAddresses); + + if (!availablePrograms.includes(program)) { + throw createUserError(`Invalid program '${program}'`, [ + `Must be one of: ${availablePrograms.join(', ')}`, + ]); + } + + return program as keyof (typeof programAddresses); +} + +/** Get network from arguments */ +export function getMultisigTxIndex(): number { + const argv = getParsedArgs(); + const multisigTxIndex = (argv['multisig-tx-index']) as string | undefined; + + if (!multisigTxIndex) { + throw createUserError('Multisig tx index is required', [ + 'Use --multisig-tx-index to specify the multisig tx index', + 'Example: --multisig-tx-index 1', + ]); + } + + const v = parseInt(multisigTxIndex); + + if (isNaN(v)) { + throw createUserError(`Invalid multisig tx index '${multisigTxIndex}'`, [ + 'Must be a valid number', + ]); + } + + return v; +} + +/** Get network from arguments */ +export function getAuthority(required?: T): T extends true ? PublicKey : PublicKey | undefined { + required ??= true as T; + + const argv = getParsedArgs(); + const authority = (argv['authority']) as string | undefined; + + if (required && !authority) { + throw createUserError('Authority is required', [ + 'Use --authority to specify the authority public key', + 'Example: --authority 33vVYcpTkv7HyEnkFHQVY1ndUSfHNFHxyG9PBqy2MCwmc', + ]); + } + + try { + return new PublicKey(authority); + } catch { + throw createUserError(`Invalid authority '${authority}'`, [ + 'Must be a valid PublicKey', + ]); + } +} + + /** Get payment token from arguments (optional) */ export function getPaymentToken(): PaymentToken { const argv = getParsedArgs(); @@ -112,17 +205,6 @@ export function getOptionalArg(key: string): string | undefined { return argv[key] as string | undefined; } -/** Get authority public key from arguments */ -export function getAuthority(): string { - const argv = getParsedArgs(); - const authority = argv.authority as string | undefined; - if (!authority) { - throw createUserError('Authority is required', [ - 'Use --authority to specify the authority public key (Fordefi vault address)', - ]); - } - return authority; -} /** Get optional vaults array from arguments */ export function getOptionalVaults(): ('minter' | 'redeemer')[] | undefined { diff --git a/scripts/utils/loaderProgramHelpers.ts b/scripts/utils/loaderProgramHelpers.ts new file mode 100644 index 0000000..a991484 --- /dev/null +++ b/scripts/utils/loaderProgramHelpers.ts @@ -0,0 +1,62 @@ +import { getSetAuthorityInstruction, getUpgradeInstruction, LOADER_V3_PROGRAM_ADDRESS } from "@solana-program/loader-v3"; +import { AccountRole, Address, TransactionSigner } from "@solana/kit"; +import { PublicKey, TransactionInstruction } from "@solana/web3.js"; + +export const getSetAuthorityInstructionIx = ({ + bufferOrProgramDataAccount, + currentAuthority, + newAuthority, +}: { + bufferOrProgramDataAccount: PublicKey; + currentAuthority: PublicKey; + newAuthority: PublicKey; +}) => { + const upgradeIx = getSetAuthorityInstruction({ + bufferOrProgramDataAccount: bufferOrProgramDataAccount.toBase58() as Address, + currentAuthority: currentAuthority.toBase58() as unknown as TransactionSigner, + newAuthority: newAuthority.toBase58() as Address, + }); + + return new TransactionInstruction({ + keys: upgradeIx.accounts.map(v => ({ + isSigner: v.role === AccountRole.READONLY_SIGNER || v.role === AccountRole.WRITABLE_SIGNER, + isWritable: v.role === AccountRole.WRITABLE_SIGNER || v.role === AccountRole.WRITABLE, + pubkey: new PublicKey((v.address as any).publicKey ?? v.address), + })), + programId: new PublicKey(LOADER_V3_PROGRAM_ADDRESS), + data: Buffer.from(upgradeIx.data), + }) +} + +export const getUpgradeInstructionIx = ({ + programId, + programDataPda, + bufferAccount, + spillAccount, + authority, +}: { + programId: PublicKey; + programDataPda: PublicKey; + bufferAccount: PublicKey; + spillAccount: PublicKey; + authority: PublicKey; +}) => { + + const upgradeIx = getUpgradeInstruction({ + programAccount: programId.toBase58() as Address, + programDataAccount: programDataPda.toBase58() as Address, + bufferAccount: bufferAccount.toBase58() as Address, + spillAccount: spillAccount.toBase58() as Address, + authority: authority.toBase58() as unknown as TransactionSigner, + }); + + return new TransactionInstruction({ + keys: upgradeIx.accounts.map(v => ({ + isSigner: v.role === AccountRole.READONLY_SIGNER || v.role === AccountRole.WRITABLE_SIGNER, + isWritable: v.role === AccountRole.WRITABLE_SIGNER || v.role === AccountRole.WRITABLE, + pubkey: new PublicKey((v.address as any).publicKey ?? v.address), + })), + programId: new PublicKey(LOADER_V3_PROGRAM_ADDRESS), + data: Buffer.from(upgradeIx.data), + }) +} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index cf3d274..ac9f564 100644 --- a/yarn.lock +++ b/yarn.lock @@ -841,6 +841,66 @@ __metadata: languageName: node linkType: hard +"@solana-program/loader-v3@npm:0.3.0": + version: 0.3.0 + resolution: "@solana-program/loader-v3@npm:0.3.0" + peerDependencies: + "@solana/kit": ^6.0.0 + checksum: 10c0/b1acdf7591f96b41e99b3dbd4b64eb77887a4e4c954e35046bc89402acc8c76f7938e8f9be7decb6aaf6bbb9c6c04fce8b3d761f5803d6cddb5294b69d9ee528 + languageName: node + linkType: hard + +"@solana/accounts@npm:6.0.1": + version: 6.0.1 + resolution: "@solana/accounts@npm:6.0.1" + dependencies: + "@solana/addresses": "npm:6.0.1" + "@solana/codecs-core": "npm:6.0.1" + "@solana/codecs-strings": "npm:6.0.1" + "@solana/errors": "npm:6.0.1" + "@solana/rpc-spec": "npm:6.0.1" + "@solana/rpc-types": "npm:6.0.1" + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: 10c0/462af5a698ac9f134f42e20211ef9219c742e511a599465c5a9b86b870fb7bb041bb1c5910389b124d8d63c59efbee6373ccac0a25ee445c18778736f0b4dc47 + languageName: node + linkType: hard + +"@solana/addresses@npm:6.0.1": + version: 6.0.1 + resolution: "@solana/addresses@npm:6.0.1" + dependencies: + "@solana/assertions": "npm:6.0.1" + "@solana/codecs-core": "npm:6.0.1" + "@solana/codecs-strings": "npm:6.0.1" + "@solana/errors": "npm:6.0.1" + "@solana/nominal-types": "npm:6.0.1" + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: 10c0/bf8047bde16b08d92be7cb3707041e94372b22c038fd99b97c8ce6ce3dc9705257b46a7cf1f3c76f5b35e32da7be3a7d5f86ea9acf58d6e5a4094ade75216b00 + languageName: node + linkType: hard + +"@solana/assertions@npm:6.0.1": + version: 6.0.1 + resolution: "@solana/assertions@npm:6.0.1" + dependencies: + "@solana/errors": "npm:6.0.1" + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: 10c0/caf275e5a5accff387a4498867ab47dcf8c81cf37474609a81cde09091e96e2b67abb65ae8f7d642615b96dd62c8b23ee43b4032a2112be4f25b4d693f38a537 + languageName: node + linkType: hard + "@solana/buffer-layout-utils@npm:^0.2.0": version: 0.2.0 resolution: "@solana/buffer-layout-utils@npm:0.2.0" @@ -884,6 +944,20 @@ __metadata: languageName: node linkType: hard +"@solana/codecs-core@npm:6.0.1": + version: 6.0.1 + resolution: "@solana/codecs-core@npm:6.0.1" + dependencies: + "@solana/errors": "npm:6.0.1" + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: 10c0/357f74215d3d60cd1b2342a1b0b270acd5c5de587a15bf549f4da4ebe2fbee51d9fb09e345b0f69b0cebdb4ce935e04f8f54df7b0573b150023b565c595737df + languageName: node + linkType: hard + "@solana/codecs-data-structures@npm:2.0.0-rc.1": version: 2.0.0-rc.1 resolution: "@solana/codecs-data-structures@npm:2.0.0-rc.1" @@ -897,6 +971,22 @@ __metadata: languageName: node linkType: hard +"@solana/codecs-data-structures@npm:6.0.1": + version: 6.0.1 + resolution: "@solana/codecs-data-structures@npm:6.0.1" + dependencies: + "@solana/codecs-core": "npm:6.0.1" + "@solana/codecs-numbers": "npm:6.0.1" + "@solana/errors": "npm:6.0.1" + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: 10c0/c88dab11c674aa8ce0be5ebbfa592405b8613f82e954df4fe93ec7543ef1b5555e587a598060f87877221c7dd9a074b413e93a44a97650b58dd9e7b602c1e216 + languageName: node + linkType: hard + "@solana/codecs-numbers@npm:2.0.0-rc.1": version: 2.0.0-rc.1 resolution: "@solana/codecs-numbers@npm:2.0.0-rc.1" @@ -909,6 +999,21 @@ __metadata: languageName: node linkType: hard +"@solana/codecs-numbers@npm:6.0.1": + version: 6.0.1 + resolution: "@solana/codecs-numbers@npm:6.0.1" + dependencies: + "@solana/codecs-core": "npm:6.0.1" + "@solana/errors": "npm:6.0.1" + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: 10c0/ff5c7d44c31537e946f244b7d2d5f0518ab8d6003f59d39d842438c285e158c5f775b4e68b74285565515a27966d6f854c11318c05614a2c20f07057aae4d22b + languageName: node + linkType: hard + "@solana/codecs-numbers@npm:^2.1.0": version: 2.3.0 resolution: "@solana/codecs-numbers@npm:2.3.0" @@ -935,6 +1040,25 @@ __metadata: languageName: node linkType: hard +"@solana/codecs-strings@npm:6.0.1": + version: 6.0.1 + resolution: "@solana/codecs-strings@npm:6.0.1" + dependencies: + "@solana/codecs-core": "npm:6.0.1" + "@solana/codecs-numbers": "npm:6.0.1" + "@solana/errors": "npm:6.0.1" + peerDependencies: + fastestsmallesttextencoderdecoder: ^1.0.22 + typescript: ^5.0.0 + peerDependenciesMeta: + fastestsmallesttextencoderdecoder: + optional: true + typescript: + optional: true + checksum: 10c0/dadab2e1b2ae53aac8423516faa2e2b256757ad708d517d42a83c531f9a5ba6a6a0d5399e245042247bffdc9cecd092644e2b25c9615afb1c4c65194f06eeedd + languageName: node + linkType: hard + "@solana/codecs@npm:2.0.0-rc.1": version: 2.0.0-rc.1 resolution: "@solana/codecs@npm:2.0.0-rc.1" @@ -950,6 +1074,24 @@ __metadata: languageName: node linkType: hard +"@solana/codecs@npm:6.0.1": + version: 6.0.1 + resolution: "@solana/codecs@npm:6.0.1" + dependencies: + "@solana/codecs-core": "npm:6.0.1" + "@solana/codecs-data-structures": "npm:6.0.1" + "@solana/codecs-numbers": "npm:6.0.1" + "@solana/codecs-strings": "npm:6.0.1" + "@solana/options": "npm:6.0.1" + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: 10c0/b097870b5369f3cc829255895f986b29efd502c1fac4225c9e0361909367f5b581f6d4074441e24ae01282c4820c3ad8ad51c065a4668a6e45c26954e1867825 + languageName: node + linkType: hard + "@solana/errors@npm:2.0.0-rc.1": version: 2.0.0-rc.1 resolution: "@solana/errors@npm:2.0.0-rc.1" @@ -978,6 +1120,167 @@ __metadata: languageName: node linkType: hard +"@solana/errors@npm:6.0.1": + version: 6.0.1 + resolution: "@solana/errors@npm:6.0.1" + dependencies: + chalk: "npm:5.6.2" + commander: "npm:14.0.3" + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + bin: + errors: bin/cli.mjs + checksum: 10c0/1e479d2ad0971fd713d94dc79855fd564ad9f1d36618ea4396f293d4c7842e824d70b70b5536cb014cb5c0d08f2cd4d9efc2382007484deb3316a98f419be20f + languageName: node + linkType: hard + +"@solana/fast-stable-stringify@npm:6.0.1": + version: 6.0.1 + resolution: "@solana/fast-stable-stringify@npm:6.0.1" + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: 10c0/9997b1e4b82a2c1ed63106e9c5599329f96f62178e7dea25a6b596b8cb23b2427ee77c56e6a7cf13b61f2eafc091eb9a82b94aa83709e548ddb4ee0b951418a9 + languageName: node + linkType: hard + +"@solana/functional@npm:6.0.1": + version: 6.0.1 + resolution: "@solana/functional@npm:6.0.1" + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: 10c0/690343ee581b9853873b6fa9a65707e3d8bd8a89e2ba8f97c830b111e7ec66b44e871e21784e22937c81d76196bed77432798ba477415e424aa1dc165dbaebc5 + languageName: node + linkType: hard + +"@solana/instruction-plans@npm:6.0.1": + version: 6.0.1 + resolution: "@solana/instruction-plans@npm:6.0.1" + dependencies: + "@solana/errors": "npm:6.0.1" + "@solana/instructions": "npm:6.0.1" + "@solana/keys": "npm:6.0.1" + "@solana/promises": "npm:6.0.1" + "@solana/transaction-messages": "npm:6.0.1" + "@solana/transactions": "npm:6.0.1" + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: 10c0/7032415351b8fa5740d01051c070b47be671e5052e36f2687b29018f000aa748212f43cf65c2c714c9112833d71fb4296ebec3290071db4cf1f43fbdc2544024 + languageName: node + linkType: hard + +"@solana/instructions@npm:6.0.1": + version: 6.0.1 + resolution: "@solana/instructions@npm:6.0.1" + dependencies: + "@solana/codecs-core": "npm:6.0.1" + "@solana/errors": "npm:6.0.1" + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: 10c0/9f0b0b1ad449d480fd64ea38f1f1e8c2e481badbcd1cad6ca5404332a14e21ecd5be34121885156eb91f51bbb9d07814e120e36e3692fbe1ce7efc833d74be4d + languageName: node + linkType: hard + +"@solana/keys@npm:6.0.1": + version: 6.0.1 + resolution: "@solana/keys@npm:6.0.1" + dependencies: + "@solana/assertions": "npm:6.0.1" + "@solana/codecs-core": "npm:6.0.1" + "@solana/codecs-strings": "npm:6.0.1" + "@solana/errors": "npm:6.0.1" + "@solana/nominal-types": "npm:6.0.1" + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: 10c0/85c07bc6722cdb37a9810faa838da0ba2ce5ebd1c7113747f0f6ff4bcc983c4ef913a29abf1099fa51eeb66ea6a1c5cd51b85d68af591f70f3e30c0a669d01e7 + languageName: node + linkType: hard + +"@solana/kit@npm:6.0.1": + version: 6.0.1 + resolution: "@solana/kit@npm:6.0.1" + dependencies: + "@solana/accounts": "npm:6.0.1" + "@solana/addresses": "npm:6.0.1" + "@solana/codecs": "npm:6.0.1" + "@solana/errors": "npm:6.0.1" + "@solana/functional": "npm:6.0.1" + "@solana/instruction-plans": "npm:6.0.1" + "@solana/instructions": "npm:6.0.1" + "@solana/keys": "npm:6.0.1" + "@solana/offchain-messages": "npm:6.0.1" + "@solana/plugin-core": "npm:6.0.1" + "@solana/programs": "npm:6.0.1" + "@solana/rpc": "npm:6.0.1" + "@solana/rpc-api": "npm:6.0.1" + "@solana/rpc-parsed-types": "npm:6.0.1" + "@solana/rpc-spec-types": "npm:6.0.1" + "@solana/rpc-subscriptions": "npm:6.0.1" + "@solana/rpc-types": "npm:6.0.1" + "@solana/signers": "npm:6.0.1" + "@solana/sysvars": "npm:6.0.1" + "@solana/transaction-confirmation": "npm:6.0.1" + "@solana/transaction-messages": "npm:6.0.1" + "@solana/transactions": "npm:6.0.1" + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: 10c0/daaa2b2ebc914b97c8f921c4c3e5531eeb8ec5a8984e882be5ac095e6f7ae6cc2e383c4c771bfbb05548740ecb1153a719cf5682db899d44b32b997d01210200 + languageName: node + linkType: hard + +"@solana/nominal-types@npm:6.0.1": + version: 6.0.1 + resolution: "@solana/nominal-types@npm:6.0.1" + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: 10c0/c7e071cb1d0a7ba8efed71678c0e80fb6beb6e3b157abcab56cd2e967e4c6aef935e05a2cbb1ff2e035be78c16edfd3fd8a962c651a2de5909780f8c5919d676 + languageName: node + linkType: hard + +"@solana/offchain-messages@npm:6.0.1": + version: 6.0.1 + resolution: "@solana/offchain-messages@npm:6.0.1" + dependencies: + "@solana/addresses": "npm:6.0.1" + "@solana/codecs-core": "npm:6.0.1" + "@solana/codecs-data-structures": "npm:6.0.1" + "@solana/codecs-numbers": "npm:6.0.1" + "@solana/codecs-strings": "npm:6.0.1" + "@solana/errors": "npm:6.0.1" + "@solana/keys": "npm:6.0.1" + "@solana/nominal-types": "npm:6.0.1" + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: 10c0/5432a0c0226434d4f0b97936d0f11593fd94bd0446a53b62d3c50bd25d1396059e628f9442d743974c396e204f5acb9e2318080bf9db11c17c84cfef666001aa + languageName: node + linkType: hard + "@solana/options@npm:2.0.0-rc.1": version: 2.0.0-rc.1 resolution: "@solana/options@npm:2.0.0-rc.1" @@ -993,6 +1296,303 @@ __metadata: languageName: node linkType: hard +"@solana/options@npm:6.0.1": + version: 6.0.1 + resolution: "@solana/options@npm:6.0.1" + dependencies: + "@solana/codecs-core": "npm:6.0.1" + "@solana/codecs-data-structures": "npm:6.0.1" + "@solana/codecs-numbers": "npm:6.0.1" + "@solana/codecs-strings": "npm:6.0.1" + "@solana/errors": "npm:6.0.1" + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: 10c0/f82c0da1ccd0f9083b48efa9b13a99747537a9e559e5d57692ff8b92bc946518c853fbd3aca29c71749b362ae8a21726ed91c4a2fbecfcf494d794e8cb0e2eda + languageName: node + linkType: hard + +"@solana/plugin-core@npm:6.0.1": + version: 6.0.1 + resolution: "@solana/plugin-core@npm:6.0.1" + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: 10c0/f3869d7202963ad28c1215e6ce1ef65cccc49b129df69f1b4f1e75d30fc8cb28062d666798cfa392eabbf95ef29079f9a244015ae0d551b55df4a850543ccb81 + languageName: node + linkType: hard + +"@solana/programs@npm:6.0.1": + version: 6.0.1 + resolution: "@solana/programs@npm:6.0.1" + dependencies: + "@solana/addresses": "npm:6.0.1" + "@solana/errors": "npm:6.0.1" + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: 10c0/478c3dedcaf9e8569acc99b5b6c7ff2b472301f6c358d3791277d69856b5b16fbdd4eed50518b92154ba748c64e0059e432e0923266aadc32b140ef19568825e + languageName: node + linkType: hard + +"@solana/promises@npm:6.0.1": + version: 6.0.1 + resolution: "@solana/promises@npm:6.0.1" + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: 10c0/41f509c3cbb1dfd5ed1ad3d86c53368f2b8ec8f1fb04f03c756c4a311d05f0e2076c19bd3572ad8d91be557d5dd376feb323436c185b4288f9edfd3162913766 + languageName: node + linkType: hard + +"@solana/rpc-api@npm:6.0.1": + version: 6.0.1 + resolution: "@solana/rpc-api@npm:6.0.1" + dependencies: + "@solana/addresses": "npm:6.0.1" + "@solana/codecs-core": "npm:6.0.1" + "@solana/codecs-strings": "npm:6.0.1" + "@solana/errors": "npm:6.0.1" + "@solana/keys": "npm:6.0.1" + "@solana/rpc-parsed-types": "npm:6.0.1" + "@solana/rpc-spec": "npm:6.0.1" + "@solana/rpc-transformers": "npm:6.0.1" + "@solana/rpc-types": "npm:6.0.1" + "@solana/transaction-messages": "npm:6.0.1" + "@solana/transactions": "npm:6.0.1" + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: 10c0/c0814dc4be9384c9d2fb300d658fb4d2b95392be083b8439374bf811667e06ece5c42dd2f42f8f013fad0e64103f9f3028687006de1ce29643237df8915ab222 + languageName: node + linkType: hard + +"@solana/rpc-parsed-types@npm:6.0.1": + version: 6.0.1 + resolution: "@solana/rpc-parsed-types@npm:6.0.1" + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: 10c0/be4a2f7adbb07d77bba9b455ad4685d16cf9c8e6a5c6bc7b2d1ee355ccc635af7351ee9b22c6824bcf21918c54cc5609bc483793eb1e0fb2c7c3f71f60f8735a + languageName: node + linkType: hard + +"@solana/rpc-spec-types@npm:6.0.1": + version: 6.0.1 + resolution: "@solana/rpc-spec-types@npm:6.0.1" + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: 10c0/ba403297d1e359f654423bb11ba9c0b3f923b1e09bd8e41e643d15a0e0acb849ea0b57f753fa704c9bc503ae97d8f87448d54221ade2f99154c03b9efc5f40e8 + languageName: node + linkType: hard + +"@solana/rpc-spec@npm:6.0.1": + version: 6.0.1 + resolution: "@solana/rpc-spec@npm:6.0.1" + dependencies: + "@solana/errors": "npm:6.0.1" + "@solana/rpc-spec-types": "npm:6.0.1" + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: 10c0/bfb90e7f1ca601f8f1908b1e0d20b41668dda69cc310518f3778522b1aad67aae35a59cf3a4835d28673427a872631da97e975e94b5c76e8a0c3e3a3b959077d + languageName: node + linkType: hard + +"@solana/rpc-subscriptions-api@npm:6.0.1": + version: 6.0.1 + resolution: "@solana/rpc-subscriptions-api@npm:6.0.1" + dependencies: + "@solana/addresses": "npm:6.0.1" + "@solana/keys": "npm:6.0.1" + "@solana/rpc-subscriptions-spec": "npm:6.0.1" + "@solana/rpc-transformers": "npm:6.0.1" + "@solana/rpc-types": "npm:6.0.1" + "@solana/transaction-messages": "npm:6.0.1" + "@solana/transactions": "npm:6.0.1" + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: 10c0/e2329564ccae02180b993372d4172a395a4c16f9ee6ccccf216cb7f50d3e6bbca174802f8ddd4fa38550933ffaaf0ef89165c0e0912ede2da840316812d86e1c + languageName: node + linkType: hard + +"@solana/rpc-subscriptions-channel-websocket@npm:6.0.1": + version: 6.0.1 + resolution: "@solana/rpc-subscriptions-channel-websocket@npm:6.0.1" + dependencies: + "@solana/errors": "npm:6.0.1" + "@solana/functional": "npm:6.0.1" + "@solana/rpc-subscriptions-spec": "npm:6.0.1" + "@solana/subscribable": "npm:6.0.1" + ws: "npm:^8.19.0" + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: 10c0/ffc53118d80fe60d1596dd5c6c3fb3183b2656f4ddc376d5b6955459f38007f5e12a6557a0bbe60b329b5d22036a57bd0e06a5b36b0b7195474cf53ca61084f8 + languageName: node + linkType: hard + +"@solana/rpc-subscriptions-spec@npm:6.0.1": + version: 6.0.1 + resolution: "@solana/rpc-subscriptions-spec@npm:6.0.1" + dependencies: + "@solana/errors": "npm:6.0.1" + "@solana/promises": "npm:6.0.1" + "@solana/rpc-spec-types": "npm:6.0.1" + "@solana/subscribable": "npm:6.0.1" + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: 10c0/d1b261f644ad53faff221f69f64f0c6431c0bd3a9f6b96f0e9d65b42f9f418ede7183760021f3ca6dc69c26060e1823286736c4491f984f425ee3a6955fa0cef + languageName: node + linkType: hard + +"@solana/rpc-subscriptions@npm:6.0.1": + version: 6.0.1 + resolution: "@solana/rpc-subscriptions@npm:6.0.1" + dependencies: + "@solana/errors": "npm:6.0.1" + "@solana/fast-stable-stringify": "npm:6.0.1" + "@solana/functional": "npm:6.0.1" + "@solana/promises": "npm:6.0.1" + "@solana/rpc-spec-types": "npm:6.0.1" + "@solana/rpc-subscriptions-api": "npm:6.0.1" + "@solana/rpc-subscriptions-channel-websocket": "npm:6.0.1" + "@solana/rpc-subscriptions-spec": "npm:6.0.1" + "@solana/rpc-transformers": "npm:6.0.1" + "@solana/rpc-types": "npm:6.0.1" + "@solana/subscribable": "npm:6.0.1" + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: 10c0/654ce2f2c1872f357592cd788ed53d8c70a6b1b2d78e7fe608316ea9d21899f5fcfaa961cbbf9bb12acf974db3302ac5044303069c6fdb008e8a62717fdbc700 + languageName: node + linkType: hard + +"@solana/rpc-transformers@npm:6.0.1": + version: 6.0.1 + resolution: "@solana/rpc-transformers@npm:6.0.1" + dependencies: + "@solana/errors": "npm:6.0.1" + "@solana/functional": "npm:6.0.1" + "@solana/nominal-types": "npm:6.0.1" + "@solana/rpc-spec-types": "npm:6.0.1" + "@solana/rpc-types": "npm:6.0.1" + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: 10c0/0d7af662d342121c431b35e86fa2d937b6b8981d1e288571e8109f0042202f542a3e95c42d93e6783c41d8bdefdf4e5368402b59b9c39177e2996ed80536e88c + languageName: node + linkType: hard + +"@solana/rpc-transport-http@npm:6.0.1": + version: 6.0.1 + resolution: "@solana/rpc-transport-http@npm:6.0.1" + dependencies: + "@solana/errors": "npm:6.0.1" + "@solana/rpc-spec": "npm:6.0.1" + "@solana/rpc-spec-types": "npm:6.0.1" + undici-types: "npm:^7.20.0" + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: 10c0/6377a6a3cd2c5bb3e318e2071482c6090285d8e91ab31cc93f586ee76ef479156ff5abe6c1ae360951f02764075580ee20fbbf1bf2488a2f3e2fc6c0d7ed7f3f + languageName: node + linkType: hard + +"@solana/rpc-types@npm:6.0.1": + version: 6.0.1 + resolution: "@solana/rpc-types@npm:6.0.1" + dependencies: + "@solana/addresses": "npm:6.0.1" + "@solana/codecs-core": "npm:6.0.1" + "@solana/codecs-numbers": "npm:6.0.1" + "@solana/codecs-strings": "npm:6.0.1" + "@solana/errors": "npm:6.0.1" + "@solana/nominal-types": "npm:6.0.1" + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: 10c0/a0eec838585541a797326d19a4f3826b546ff070cca86139ac047393d6ea9c8c1cfb7fca5b360a64e2bd0532d55529d81ec5209f67f9f814adcc37be9003aca5 + languageName: node + linkType: hard + +"@solana/rpc@npm:6.0.1": + version: 6.0.1 + resolution: "@solana/rpc@npm:6.0.1" + dependencies: + "@solana/errors": "npm:6.0.1" + "@solana/fast-stable-stringify": "npm:6.0.1" + "@solana/functional": "npm:6.0.1" + "@solana/rpc-api": "npm:6.0.1" + "@solana/rpc-spec": "npm:6.0.1" + "@solana/rpc-spec-types": "npm:6.0.1" + "@solana/rpc-transformers": "npm:6.0.1" + "@solana/rpc-transport-http": "npm:6.0.1" + "@solana/rpc-types": "npm:6.0.1" + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: 10c0/b986da6ac2f2482cc2810f8a70e5c1b329f3b9e20cb1905dace187aae0d67e7d36f0397fb1ff2918d0bc9469083f4ff11927172689ab372a4f0f84dd9d8e4ee9 + languageName: node + linkType: hard + +"@solana/signers@npm:6.0.1": + version: 6.0.1 + resolution: "@solana/signers@npm:6.0.1" + dependencies: + "@solana/addresses": "npm:6.0.1" + "@solana/codecs-core": "npm:6.0.1" + "@solana/errors": "npm:6.0.1" + "@solana/instructions": "npm:6.0.1" + "@solana/keys": "npm:6.0.1" + "@solana/nominal-types": "npm:6.0.1" + "@solana/offchain-messages": "npm:6.0.1" + "@solana/transaction-messages": "npm:6.0.1" + "@solana/transactions": "npm:6.0.1" + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: 10c0/7eaa0257dddeba5aad1db30803e7688fa5845d4c85a87ec958fc0fe2ec24a5c37c932e9e865eefb6397d07f62a7c1afed4cb97d9fa074c4f51c058e986f6bd6e + languageName: node + linkType: hard + "@solana/spl-token-group@npm:^0.0.7": version: 0.0.7 resolution: "@solana/spl-token-group@npm:0.0.7" @@ -1044,6 +1644,107 @@ __metadata: languageName: node linkType: hard +"@solana/subscribable@npm:6.0.1": + version: 6.0.1 + resolution: "@solana/subscribable@npm:6.0.1" + dependencies: + "@solana/errors": "npm:6.0.1" + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: 10c0/59f409b485a42e22d0ccc6d1af4681a9ecd14e23bb095ffd440ce41668cc746247bff54739324723aaca7e0140b1ed24dcd25b883328a1f8e84d02746a486136 + languageName: node + linkType: hard + +"@solana/sysvars@npm:6.0.1": + version: 6.0.1 + resolution: "@solana/sysvars@npm:6.0.1" + dependencies: + "@solana/accounts": "npm:6.0.1" + "@solana/codecs": "npm:6.0.1" + "@solana/errors": "npm:6.0.1" + "@solana/rpc-types": "npm:6.0.1" + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: 10c0/052301c8e153fdd080fedebeaf3b432bd3c23e6510ac36df9f78c4d8725b5874f41ca15ba2ddc65082e017ecf53324f61f2ddcf17b0e3d0b06947df4ffc65b0a + languageName: node + linkType: hard + +"@solana/transaction-confirmation@npm:6.0.1": + version: 6.0.1 + resolution: "@solana/transaction-confirmation@npm:6.0.1" + dependencies: + "@solana/addresses": "npm:6.0.1" + "@solana/codecs-strings": "npm:6.0.1" + "@solana/errors": "npm:6.0.1" + "@solana/keys": "npm:6.0.1" + "@solana/promises": "npm:6.0.1" + "@solana/rpc": "npm:6.0.1" + "@solana/rpc-subscriptions": "npm:6.0.1" + "@solana/rpc-types": "npm:6.0.1" + "@solana/transaction-messages": "npm:6.0.1" + "@solana/transactions": "npm:6.0.1" + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: 10c0/2e5ecc5f020c22433229da297690f7d9b9923edbe4f5b6a8530ee582d08a0cc95c313fc9c7c05b0e5fa00270762870ee37175e2f09fdbee33f2d9ca92dd63d82 + languageName: node + linkType: hard + +"@solana/transaction-messages@npm:6.0.1": + version: 6.0.1 + resolution: "@solana/transaction-messages@npm:6.0.1" + dependencies: + "@solana/addresses": "npm:6.0.1" + "@solana/codecs-core": "npm:6.0.1" + "@solana/codecs-data-structures": "npm:6.0.1" + "@solana/codecs-numbers": "npm:6.0.1" + "@solana/errors": "npm:6.0.1" + "@solana/functional": "npm:6.0.1" + "@solana/instructions": "npm:6.0.1" + "@solana/nominal-types": "npm:6.0.1" + "@solana/rpc-types": "npm:6.0.1" + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: 10c0/705ab940d14dbc1c748599d1b52a61ad6d601271d224346f69b55bcd8caf5a2450bc949334f540979281a6a05d0d5051b6eef945a93e3e5463773e1277a2bc9e + languageName: node + linkType: hard + +"@solana/transactions@npm:6.0.1": + version: 6.0.1 + resolution: "@solana/transactions@npm:6.0.1" + dependencies: + "@solana/addresses": "npm:6.0.1" + "@solana/codecs-core": "npm:6.0.1" + "@solana/codecs-data-structures": "npm:6.0.1" + "@solana/codecs-numbers": "npm:6.0.1" + "@solana/codecs-strings": "npm:6.0.1" + "@solana/errors": "npm:6.0.1" + "@solana/functional": "npm:6.0.1" + "@solana/instructions": "npm:6.0.1" + "@solana/keys": "npm:6.0.1" + "@solana/nominal-types": "npm:6.0.1" + "@solana/rpc-types": "npm:6.0.1" + "@solana/transaction-messages": "npm:6.0.1" + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: 10c0/ffa03c5978cfa33d8d929f7473202a8ed91d8f3c03ada147ce9f4037a8db8399892a84ba989cd486ec4f7d8dd993cd21a759164bcbf3d49ce18943ecec1fa69d + languageName: node + linkType: hard + "@solana/web3.js@npm:1.95.4, @solana/web3.js@npm:^1.32.0, @solana/web3.js@npm:^1.68.0": version: 1.95.4 resolution: "@solana/web3.js@npm:1.95.4" @@ -2191,6 +2892,13 @@ __metadata: languageName: node linkType: hard +"chalk@npm:5.6.2, chalk@npm:^5.4.1": + version: 5.6.2 + resolution: "chalk@npm:5.6.2" + checksum: 10c0/99a4b0f0e7991796b1e7e3f52dceb9137cae2a9dfc8fc0784a550dc4c558e15ab32ed70b14b21b52beb2679b4892b41a0aa44249bcb996f01e125d58477c6976 + languageName: node + linkType: hard + "chalk@npm:^4.0.0": version: 4.1.2 resolution: "chalk@npm:4.1.2" @@ -2208,13 +2916,6 @@ __metadata: languageName: node linkType: hard -"chalk@npm:^5.4.1": - version: 5.6.2 - resolution: "chalk@npm:5.6.2" - checksum: 10c0/99a4b0f0e7991796b1e7e3f52dceb9137cae2a9dfc8fc0784a550dc4c558e15ab32ed70b14b21b52beb2679b4892b41a0aa44249bcb996f01e125d58477c6976 - languageName: node - linkType: hard - "check-error@npm:^2.1.1": version: 2.1.1 resolution: "check-error@npm:2.1.1" @@ -2265,6 +2966,13 @@ __metadata: languageName: node linkType: hard +"commander@npm:14.0.3, commander@npm:^14.0.0": + version: 14.0.3 + resolution: "commander@npm:14.0.3" + checksum: 10c0/755652564bbf56ff2ff083313912b326450d3f8d8c85f4b71416539c9a05c3c67dbd206821ca72635bf6b160e2afdefcb458e86b317827d5cb333b69ce7f1a24 + languageName: node + linkType: hard + "commander@npm:^12.1.0": version: 12.1.0 resolution: "commander@npm:12.1.0" @@ -2272,13 +2980,6 @@ __metadata: languageName: node linkType: hard -"commander@npm:^14.0.0": - version: 14.0.3 - resolution: "commander@npm:14.0.3" - checksum: 10c0/755652564bbf56ff2ff083313912b326450d3f8d8c85f4b71416539c9a05c3c67dbd206821ca72635bf6b160e2afdefcb458e86b317827d5cb333b69ce7f1a24 - languageName: node - linkType: hard - "commander@npm:^2.20.3": version: 2.20.3 resolution: "commander@npm:2.20.3" @@ -4421,6 +5122,8 @@ __metadata: dependencies: "@coral-xyz/anchor": "npm:0.30.1" "@eslint/js": "npm:9.39.1" + "@solana-program/loader-v3": "npm:0.3.0" + "@solana/kit": "npm:6.0.1" "@solana/spl-token": "npm:0.4.9" "@solana/spl-token-metadata": "npm:0.1.6" "@solana/web3.js": "npm:1.95.4" @@ -4993,6 +5696,13 @@ __metadata: languageName: node linkType: hard +"undici-types@npm:^7.20.0": + version: 7.22.0 + resolution: "undici-types@npm:7.22.0" + checksum: 10c0/5e6f2513c41d07404c719eb7c1c499b8d4cde042f1269b3bc2be335f059e6ef53eb04f316696c728d5e8064c4d522b98f63d7ae8938adf6317351e07ae9c943e + languageName: node + linkType: hard + "undici-types@npm:~5.26.4": version: 5.26.5 resolution: "undici-types@npm:5.26.5" @@ -5429,6 +6139,21 @@ __metadata: languageName: node linkType: hard +"ws@npm:^8.19.0": + version: 8.19.0 + resolution: "ws@npm:8.19.0" + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ">=5.0.2" + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + checksum: 10c0/4741d9b9bc3f9c791880882414f96e36b8b254e34d4b503279d6400d9a4b87a033834856dbdd94ee4b637944df17ea8afc4bce0ff4a1560d2166be8855da5b04 + languageName: node + linkType: hard + "y18n@npm:^5.0.5": version: 5.0.8 resolution: "y18n@npm:5.0.8" From f79eb8093d9ea4ab138e00944d1aeba1c6c5741e Mon Sep 17 00:00:00 2001 From: kostyamospan <37243242+kostyamospan@users.noreply.github.com> Date: Mon, 16 Feb 2026 16:20:09 +0000 Subject: [PATCH 05/15] fix: comments --- scripts/tasks/deploy/deploy-nonce-account.ts | 4 +--- scripts/tasks/deploy/network/deploy-timelock.ts | 1 + 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/scripts/tasks/deploy/deploy-nonce-account.ts b/scripts/tasks/deploy/deploy-nonce-account.ts index d2b3d26..38363e3 100644 --- a/scripts/tasks/deploy/deploy-nonce-account.ts +++ b/scripts/tasks/deploy/deploy-nonce-account.ts @@ -24,11 +24,9 @@ async function main(provider: AnchorProvider, payer: Wallet, network: string) { console.log('\nāœ… Nonce account deployed successfully'); console.log(`Authority: ${authority.toBase58()}`); console.log(`Nonce Account: ${nonceAccount.toBase58()}`); - console.log('\nšŸ“ Add this nonce account to the protocol-registry fordefi config:'); - console.log(` nonceAccount: new PublicKey("${nonceAccount.toBase58()}")`); } const network = getNetwork(); executeNetworkScript(network, main, 'deployer'); -// Usage: yarn tsx scripts/tasks/deploy/deploy-nonce-account.ts --authority --network +// Usage: yarn tsx scripts/tasks/deploy/deploy-nonce-account.ts --authority --network diff --git a/scripts/tasks/deploy/network/deploy-timelock.ts b/scripts/tasks/deploy/network/deploy-timelock.ts index 5e6cf9b..1a5fd9e 100644 --- a/scripts/tasks/deploy/network/deploy-timelock.ts +++ b/scripts/tasks/deploy/network/deploy-timelock.ts @@ -16,6 +16,7 @@ async function main(provider: AnchorProvider, payer: Wallet, network: string) { const networkConfig = loadNetworkConfig(network); + console.log('networkConfig', networkConfig); if (!networkConfig?.timelock) { throw createUserError(`Timelock config not found for network ${network}`,); } From 56f86958f856b7fe9bacbea016903cb683b31d53 Mon Sep 17 00:00:00 2001 From: kostyamospan <37243242+kostyamospan@users.noreply.github.com> Date: Tue, 17 Feb 2026 12:50:12 +0000 Subject: [PATCH 06/15] chore: timelock scripts --- common/addresses.ts | 13 --- common/programs.ts | 13 +++ package.json | 4 +- scripts/configs/loadNetworkConfig.ts | 9 +- scripts/configs/network-config.ts | 7 ++ scripts/deploy/timelock.ts | 97 ++++++++++++++----- .../tasks/deploy/network/deploy-timelock.ts | 2 +- .../manage/timelock/cancel-transaction.ts | 70 +++++++++++++ .../transfer-upgrade-authority.ts | 3 +- .../tasks/upgrade/execute-upgrade-program.ts | 4 +- .../tasks/upgrade/propose-upgrade-program.ts | 11 +-- scripts/utils/argumentParser.ts | 2 +- 12 files changed, 182 insertions(+), 53 deletions(-) create mode 100644 common/programs.ts create mode 100644 scripts/tasks/manage/timelock/cancel-transaction.ts rename scripts/tasks/manage/{ => timelock}/transfer-upgrade-authority.ts (97%) diff --git a/common/addresses.ts b/common/addresses.ts index f0a3bd5..44d7b7e 100644 --- a/common/addresses.ts +++ b/common/addresses.ts @@ -3,11 +3,6 @@ import { PublicKey } from '@solana/web3.js'; import { MProduct, PaymentToken } from './tokenTypes'; -import ACCESS_CONTROL_IDL from '../target/idl/access_control.json' with { type: 'json' }; -import VAULTS_IDL from '../target/idl/midas_vaults.json' with { type: 'json' }; -import TOKEN_AUTHORITY_IDL from '../target/idl/token_authority.json' with { type: 'json' }; -import DATA_FEED_IDL from '../target/idl/data_feed.json' with { type: 'json' }; - export interface NetworkAddresses { acRoleGlobal?: PublicKey; ac?: PublicKey; @@ -116,11 +111,3 @@ export const addresses: Record = { }, }, }; - - -export const programAddresses = { - access_control: new PublicKey(ACCESS_CONTROL_IDL.address), - midas_vaults: new PublicKey(VAULTS_IDL.address), - token_authority: new PublicKey(TOKEN_AUTHORITY_IDL.address), - data_feed: new PublicKey(DATA_FEED_IDL.address), -}; \ No newline at end of file diff --git a/common/programs.ts b/common/programs.ts new file mode 100644 index 0000000..3c6bf34 --- /dev/null +++ b/common/programs.ts @@ -0,0 +1,13 @@ +import { PublicKey } from '@solana/web3.js'; + +import ACCESS_CONTROL_IDL from '../target/idl/access_control.json' with { type: 'json' }; +import VAULTS_IDL from '../target/idl/midas_vaults.json' with { type: 'json' }; +import TOKEN_AUTHORITY_IDL from '../target/idl/token_authority.json' with { type: 'json' }; +import DATA_FEED_IDL from '../target/idl/data_feed.json' with { type: 'json' }; + +export const programAddresses = { + access_control: new PublicKey(ACCESS_CONTROL_IDL.address), + midas_vaults: new PublicKey(VAULTS_IDL.address), + token_authority: new PublicKey(TOKEN_AUTHORITY_IDL.address), + data_feed: new PublicKey(DATA_FEED_IDL.address), +}; diff --git a/package.json b/package.json index bc7e113..653d83d 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,9 @@ "update:manual-feed-price": "tsx scripts/tasks/manage/update-manual-feed-price.ts", "delegate": "tsx scripts/tasks/manage/delegate.ts", "upgrade:program:propose": "tsx scripts/tasks/upgrade/propose-upgrade-program.ts", - "upgrade:program:execute": "tsx scripts/tasks/upgrade/execute-upgrade-program.ts" + "upgrade:program:execute": "tsx scripts/tasks/upgrade/execute-upgrade-program.ts", + "timelock:cancel-transaction": "tsx scripts/tasks/manage/timelock/cancel-transaction.ts", + "timelock:transfer-upgrade-authority": "tsx scripts/tasks/manage/timelock/transfer-upgrade-authority.ts" }, "dependencies": { "@coral-xyz/anchor": "0.30.1", diff --git a/scripts/configs/loadNetworkConfig.ts b/scripts/configs/loadNetworkConfig.ts index a4be48b..afc442d 100644 --- a/scripts/configs/loadNetworkConfig.ts +++ b/scripts/configs/loadNetworkConfig.ts @@ -4,11 +4,12 @@ import { NetworkConfig, networkConfigSchema} from './types'; import { networkConfigs } from './network-config'; export function loadNetworkConfig(network: string): NetworkConfig[string] { - const config = networkConfigs[network]; - if (!config) { + const config = networkConfigSchema.parse(networkConfigs); + const networkConfig = config[network]; + + if (!networkConfig) { throw createUserError(`Network config not found: ${network}`); } - const networkConfig = networkConfigSchema.parse(config); - return networkConfig[network]; + return networkConfig; } diff --git a/scripts/configs/network-config.ts b/scripts/configs/network-config.ts index 427b184..5d551e1 100644 --- a/scripts/configs/network-config.ts +++ b/scripts/configs/network-config.ts @@ -8,4 +8,11 @@ export const networkConfigs: NetworkConfig = { member: '77F5WP7E9PE3cRbUXGZ8W8S2zvSGvb2WS7QuVGYpavug', }, }, + mainnet: { + timelock: { + // 2 days + delay: 2 * 86400, + member: '77F5WP7E9PE3cRbUXGZ8W8S2zvSGvb2WS7QuVGYpavug', + }, + }, }; \ No newline at end of file diff --git a/scripts/deploy/timelock.ts b/scripts/deploy/timelock.ts index 0b2639b..2fad82e 100644 --- a/scripts/deploy/timelock.ts +++ b/scripts/deploy/timelock.ts @@ -1,4 +1,4 @@ -import { AddressLookupTableAccount, Connection, Keypair, PublicKey, Transaction, TransactionInstruction, TransactionMessage, VersionedTransaction } from '@solana/web3.js'; +import { AccountMeta, AddressLookupTableAccount, Connection, Keypair, PublicKey, SystemProgram, Transaction, TransactionInstruction, TransactionMessage, VersionedTransaction } from '@solana/web3.js'; import { sendAndWaitForCustomSolanaTxSign } from '@/common/solanaTxHelper'; @@ -334,6 +334,62 @@ export const getTimelockTransaction = async (connection: Connection, { return { proposal, transaction }; }; +export function createMultisigCreateV2Instruction( + accounts: multisig.generated.MultisigCreateV2InstructionAccounts, + args: multisig.generated.MultisigCreateV2InstructionArgs + ) { + const [data] = multisig.generated.multisigCreateV2Struct.serialize({ + instructionDiscriminator: multisig.generated.multisigCreateV2InstructionDiscriminator, + ...args, + }) + const keys: AccountMeta[] = [ + { + pubkey: accounts.programConfig, + isWritable: false, + isSigner: false, + }, + { + pubkey: accounts.treasury, + isWritable: true, + isSigner: false, + }, + { + pubkey: accounts.multisig, + isWritable: true, + isSigner: false, + }, + { + pubkey: accounts.createKey, + isWritable: true, + isSigner: true, + }, + { + pubkey: accounts.creator, + isWritable: true, + isSigner: true, + }, + { + pubkey: accounts.systemProgram ?? SystemProgram.programId, + isWritable: false, + isSigner: false, + }, + ] + + if (accounts.anchorRemainingAccounts != null) { + for (const acc of accounts.anchorRemainingAccounts) { + keys.push(acc) + } + } + + const ix = new TransactionInstruction({ + programId: multisig.PROGRAM_ID, + keys, + data, + }) + return ix + } + + export const deployTimelock = async (common: CommonParams, { delay, member, createKey }: DeployTimelockConfig) => { createKey ??= Keypair.generate(); const [multisigPda] = multisig.getMultisigPda({ @@ -350,32 +406,27 @@ export const deployTimelock = async (common: CommonParams, { delay, member, crea const configTreasury = programConfig.treasury; - const tx = new Transaction().add(multisig.instructions.multisigCreateV2({ - // Must sign the transaction, unless the .rpc method is used. + const tx = new Transaction().add(createMultisigCreateV2Instruction({ + programConfig: programConfigPda, + treasury: configTreasury, + multisig: multisigPda, createKey: createKey.publicKey, - // The creator & fee payer creator: common.payer.publicKey, - // The PDA of the multisig you are creating, derived by a random PublicKey - multisigPda, - // Here the config authority will be the system program - configAuthority: null, - // Create without any time-lock - timeLock: Number(delay), - // List of the members to add to the multisig - members: [{ - // Members Public Key - key: member, - // Granted Proposer, Voter, and Executor permissions - permissions: multisig.types.Permissions.all(), - }], - // This means that there needs to be 2 votes for a transaction proposal to be approved - threshold: 1, - // This is for the program config treasury account - treasury: configTreasury, - // Rent reclaim account - rentCollector: member + }, { + args: { + configAuthority: null, + threshold: 1, + members: [{ + key: member, + permissions: multisig.types.Permissions.all(), + }], + timeLock: Number(delay), + rentCollector: common.payer.publicKey, + memo: null, + }, })); + const result = await sendAndWaitForCustomSolanaTxSign(common.provider, tx, [createKey], { action: 'deployer', comment: 'Deploy Timelock', diff --git a/scripts/tasks/deploy/network/deploy-timelock.ts b/scripts/tasks/deploy/network/deploy-timelock.ts index 1a5fd9e..75fb33e 100644 --- a/scripts/tasks/deploy/network/deploy-timelock.ts +++ b/scripts/tasks/deploy/network/deploy-timelock.ts @@ -12,7 +12,7 @@ import { deployTimelock, DeployTimelockConfig } from '@/scripts/deploy/timelock' import { PublicKey } from '@solana/web3.js'; async function main(provider: AnchorProvider, payer: Wallet, network: string) { - console.log(`Deploying Timelock for: ${network}`); + console.log(`Deploying Timelock for: ${network}, payer: ${payer.publicKey.toBase58()}`); const networkConfig = loadNetworkConfig(network); diff --git a/scripts/tasks/manage/timelock/cancel-transaction.ts b/scripts/tasks/manage/timelock/cancel-transaction.ts new file mode 100644 index 0000000..539239a --- /dev/null +++ b/scripts/tasks/manage/timelock/cancel-transaction.ts @@ -0,0 +1,70 @@ + +import { AnchorProvider, Wallet } from '@coral-xyz/anchor'; + +import { createUserError } from '@/common/errorHandler'; +import { executeNetworkScript } from '@/common/scriptRunner'; + +import { getTimelockAddress } from '@/scripts/utils/addressQueries'; +import { getAuthority, getMultisigTxIndex, getNetwork, getProgram } from '@/scripts/utils/argumentParser'; +import { PublicKey, Transaction } from '@solana/web3.js'; +import { programAddresses } from '@/common/programs'; +import { LOADER_V3_PROGRAM_ADDRESS } from '@solana-program/loader-v3'; +import { sendAndWaitForCustomSolanaTxSign } from '@/common/solanaTxHelper'; +import { getSetAuthorityInstructionIx } from '@/scripts/utils/loaderProgramHelpers'; +import * as multisig from "@sqds/multisig"; + +async function main( + provider: AnchorProvider, + payer: Wallet, + network: string, +) { + const multisigTxIndex = getMultisigTxIndex(); + + console.log(`Cancelling transaction ${multisigTxIndex} on network ${network}`); + + const common = { provider, payer, network }; + + + const timelock = getTimelockAddress(network); + + if (!timelock) { + throw createUserError(`Timelock not found for network ${network}`,); + } + + + const multisigInfo = await multisig.accounts.Multisig.fromAccountAddress(common.provider.connection as any, timelock); + + const tx = new Transaction().add( + multisig.instructions.proposalCancel({ + multisigPda: timelock, + transactionIndex: BigInt(multisigTxIndex), + member: payer.publicKey, + }), + multisig.instructions.vaultTransactionAccountsClose({ + multisigPda: timelock, + transactionIndex: BigInt(multisigTxIndex), + rentCollector: multisigInfo.rentCollector, + }), + ); + + const result = await sendAndWaitForCustomSolanaTxSign(common.provider, tx, [], { + action: 'update-timelock', + comment: `Cancel timelock transaction ${multisigTxIndex} on network ${network}`, + waitForTx: false, + pollingIntervalMs: 1000, + timeoutDurationMs: 120 * 1000, + }); + + if (result.signature) { + console.log(`Transaction signature: ${result.signature}`); + } +} + +const network = getNetwork(); + +executeNetworkScript( + network, + (provider, payer, network) => + main(provider, payer as Wallet, network), + 'update-timelock' +); diff --git a/scripts/tasks/manage/transfer-upgrade-authority.ts b/scripts/tasks/manage/timelock/transfer-upgrade-authority.ts similarity index 97% rename from scripts/tasks/manage/transfer-upgrade-authority.ts rename to scripts/tasks/manage/timelock/transfer-upgrade-authority.ts index feb1f51..5c6ee2a 100644 --- a/scripts/tasks/manage/transfer-upgrade-authority.ts +++ b/scripts/tasks/manage/timelock/transfer-upgrade-authority.ts @@ -7,7 +7,7 @@ import { executeNetworkScript } from '@/common/scriptRunner'; import { getTimelockAddress } from '@/scripts/utils/addressQueries'; import { getAuthority, getNetwork, getProgram } from '@/scripts/utils/argumentParser'; import { PublicKey, Transaction } from '@solana/web3.js'; -import { programAddresses } from '@/common/addresses'; +import { programAddresses } from '@/common/programs'; import { LOADER_V3_PROGRAM_ADDRESS } from '@solana-program/loader-v3'; import { sendAndWaitForCustomSolanaTxSign } from '@/common/solanaTxHelper'; import { getSetAuthorityInstructionIx } from '@/scripts/utils/loaderProgramHelpers'; @@ -20,7 +20,6 @@ async function main( let authority = getAuthority(false); const program = getProgram(); - if (!authority) { console.log('Authority not provided, will use timelock as new authority'); diff --git a/scripts/tasks/upgrade/execute-upgrade-program.ts b/scripts/tasks/upgrade/execute-upgrade-program.ts index 12f58be..11397a9 100644 --- a/scripts/tasks/upgrade/execute-upgrade-program.ts +++ b/scripts/tasks/upgrade/execute-upgrade-program.ts @@ -6,7 +6,7 @@ import { executeNetworkScript } from '@/common/scriptRunner'; import { getTimelockAddress } from '@/scripts/utils/addressQueries'; import { getMultisigTxIndex, getNetwork } from '@/scripts/utils/argumentParser'; -import { programAddresses } from '@/common/addresses'; +import { programAddresses } from '@/common/programs'; import { sendAndWaitForCustomSolanaTxSign } from '@/common/solanaTxHelper'; import { getTimelockTransaction, sendTxWithTimelock } from '@/scripts/deploy/timelock'; @@ -66,7 +66,7 @@ async function main( const result = await sendAndWaitForCustomSolanaTxSign(common.provider, tx, [], { action: 'update-timelock', comment: `Execute upgrade of ${program} program trough the timelock`, - waitForTx: true, + waitForTx: false, pollingIntervalMs: 1000, timeoutDurationMs: 120 * 1000, }); diff --git a/scripts/tasks/upgrade/propose-upgrade-program.ts b/scripts/tasks/upgrade/propose-upgrade-program.ts index 8d8b75a..ccceab3 100644 --- a/scripts/tasks/upgrade/propose-upgrade-program.ts +++ b/scripts/tasks/upgrade/propose-upgrade-program.ts @@ -5,12 +5,11 @@ import { createUserError } from '@/common/errorHandler'; import { executeNetworkScript } from '@/common/scriptRunner'; import { getTimelockAddress } from '@/scripts/utils/addressQueries'; -import { getBufferAccount, getMultisigTxIndex, getNetwork, getProgram } from '@/scripts/utils/argumentParser'; -import { PublicKey, TransactionInstruction } from '@solana/web3.js'; -import { programAddresses } from '@/common/addresses'; -import { getUpgradeInstruction, LOADER_V3_PROGRAM_ADDRESS } from '@solana-program/loader-v3'; +import { getBufferAccount, getNetwork, getProgram } from '@/scripts/utils/argumentParser'; +import { PublicKey } from '@solana/web3.js'; +import { programAddresses } from '@/common/programs'; +import { LOADER_V3_PROGRAM_ADDRESS } from '@solana-program/loader-v3'; import { sendAndWaitForCustomSolanaTxSign } from '@/common/solanaTxHelper'; -import { AccountRole, Address, TransactionSigner } from '@solana/kit'; import { sendTxWithTimelock } from '@/scripts/deploy/timelock'; import { getUpgradeInstructionIx } from '@/scripts/utils/loaderProgramHelpers'; @@ -66,7 +65,7 @@ async function main( const result = await sendAndWaitForCustomSolanaTxSign(common.provider, tx, [], { action: 'update-timelock', comment: `Propose upgrade of ${program} program trough the timelock`, - waitForTx: true, + waitForTx: false, pollingIntervalMs: 1000, timeoutDurationMs: 120 * 1000, }); diff --git a/scripts/utils/argumentParser.ts b/scripts/utils/argumentParser.ts index 968cd6e..e3dd65a 100644 --- a/scripts/utils/argumentParser.ts +++ b/scripts/utils/argumentParser.ts @@ -6,7 +6,7 @@ import { MProduct, isMProduct, PaymentToken, isPaymentToken } from '@/common/tok import { getAvailableNetworks } from './getAvailableNetworks'; import { PublicKey } from '@solana/web3.js'; -import { programAddresses } from '@/common/addresses'; +import { programAddresses } from '@/common/programs'; /** Simple cached parser - parses all args once */ let parsedArgs: Record | null = null; From de43bddadb9f79cc5a64f72072fdee7a36d5635f Mon Sep 17 00:00:00 2001 From: kostyamospan <37243242+kostyamospan@users.noreply.github.com> Date: Tue, 17 Feb 2026 19:17:41 +0000 Subject: [PATCH 07/15] fix: timelock scripts --- common/addresses.ts | 1 + package.json | 4 +-- scripts/deploy/timelock.ts | 34 ++++++++++++------- .../tasks/deploy/network/deploy-timelock.ts | 1 - .../manage/timelock/cancel-transaction.ts | 27 ++++++++++----- .../timelock/transfer-upgrade-authority.ts | 32 +++++++++++------ .../tasks/upgrade/execute-upgrade-program.ts | 2 ++ .../tasks/upgrade/propose-upgrade-program.ts | 2 ++ scripts/utils/addressStorage.ts | 4 +++ scripts/utils/argumentParser.ts | 4 +++ 10 files changed, 75 insertions(+), 36 deletions(-) diff --git a/common/addresses.ts b/common/addresses.ts index 44d7b7e..ed7a2f6 100644 --- a/common/addresses.ts +++ b/common/addresses.ts @@ -41,6 +41,7 @@ export const addresses: Record = { devnet: { acRoleGlobal: new PublicKey('BW95RL5v9685QqxvuRGjXiM3f6Td9k5QEBiGkXMHwsx1'), ac: new PublicKey('5cMcz3NsbJy6AyvGPpMupBXFiQkwC9qRuMxkTPiTb3Qu'), + timelock: new PublicKey('B7A1wFUbCcmyLUWGMLbNRN4VBWH3jhdKFswkfPa63BFt'), tokens: { [MProduct.MFONE]: { acRole: new PublicKey('2SAaMSzZd9DuNsR3QWNy8mZjNJPnMqdsC4rXz8wgnfFR'), diff --git a/package.json b/package.json index 653d83d..dcd786e 100644 --- a/package.json +++ b/package.json @@ -33,8 +33,8 @@ "update:data-feed": "tsx scripts/tasks/manage/update-data-feed.ts", "update:manual-feed-price": "tsx scripts/tasks/manage/update-manual-feed-price.ts", "delegate": "tsx scripts/tasks/manage/delegate.ts", - "upgrade:program:propose": "tsx scripts/tasks/upgrade/propose-upgrade-program.ts", - "upgrade:program:execute": "tsx scripts/tasks/upgrade/execute-upgrade-program.ts", + "upgrade:propose": "tsx scripts/tasks/upgrade/propose-upgrade-program.ts", + "upgrade:execute": "tsx scripts/tasks/upgrade/execute-upgrade-program.ts", "timelock:cancel-transaction": "tsx scripts/tasks/manage/timelock/cancel-transaction.ts", "timelock:transfer-upgrade-authority": "tsx scripts/tasks/manage/timelock/transfer-upgrade-authority.ts" }, diff --git a/scripts/deploy/timelock.ts b/scripts/deploy/timelock.ts index 2fad82e..63e9dfe 100644 --- a/scripts/deploy/timelock.ts +++ b/scripts/deploy/timelock.ts @@ -12,9 +12,25 @@ export interface DeployTimelockConfig { createKey?: Keypair; } +export const getMultisigInfo = async (connection: Connection, multisigPda: PublicKey, required?: T): Promise => { + required ??= true as T; + return await multisig.accounts.Multisig.fromAccountAddress( + connection as any, + multisigPda + ).catch(err => { + if(required) { + throw err; + } + + if (err instanceof Error && err.message.includes('Unable to find Multisig account at') || err.message.includes('Expected to hold a COption')) { + return null; + } + throw err; + }); +} -const wrapTxWithSqudsSigner = async (connection: Connection, { +export const wrapTxWithSqudsSigner = async (connection: Connection, { instructions, multisigSignerPda, addressLookupTableAccounts, @@ -175,10 +191,7 @@ export const sendTxWithTimelock = async (connection: Connection, { }); // Get deserialized multisig account info - const multisigInfo = await multisig.accounts.Multisig.fromAccountAddress( - connection as any, - timelock - ); + const multisigInfo = await getMultisigInfo(connection, timelock); if (multisigInfo.members.length !== 1) { throw new Error('Expected timelock to have only one member, got ' + multisigInfo.members.length); @@ -186,12 +199,7 @@ export const sendTxWithTimelock = async (connection: Connection, { const multisigSignerPda = multisigInfo.members[0].key; - const multisigSignerPdaAccount: multisig.accounts.Multisig | null = await multisig.accounts.Multisig.fromAccountAddress(connection as any, multisigSignerPda).catch(err => { - if (err instanceof Error && err.message.includes('Unable to find Multisig account at')) { - return null; - } - throw err; - }); + const multisigSignerPdaAccount = await getMultisigInfo(connection, multisigSignerPda, false); const squadsSigner = multisigSignerPdaAccount !== null; @@ -241,7 +249,7 @@ export const sendTxWithTimelock = async (connection: Connection, { tx = txCreate; - if (squadsSigner !== undefined) { + if (squadsSigner) { tx = await wrapTxWithSqudsSigner(connection, { instructions: txCreate.instructions, member: payer, @@ -286,7 +294,7 @@ export const sendTxWithTimelock = async (connection: Connection, { instructions: [inxExecute.instruction], }).compileToV0Message(inxExecute.lookupTableAccounts)); - if (squadsSigner !== undefined) { + if (squadsSigner) { tx = await wrapTxWithSqudsSigner(connection, { instructions: [inxExecute.instruction], member: payer, diff --git a/scripts/tasks/deploy/network/deploy-timelock.ts b/scripts/tasks/deploy/network/deploy-timelock.ts index 75fb33e..cbd171b 100644 --- a/scripts/tasks/deploy/network/deploy-timelock.ts +++ b/scripts/tasks/deploy/network/deploy-timelock.ts @@ -16,7 +16,6 @@ async function main(provider: AnchorProvider, payer: Wallet, network: string) { const networkConfig = loadNetworkConfig(network); - console.log('networkConfig', networkConfig); if (!networkConfig?.timelock) { throw createUserError(`Timelock config not found for network ${network}`,); } diff --git a/scripts/tasks/manage/timelock/cancel-transaction.ts b/scripts/tasks/manage/timelock/cancel-transaction.ts index 539239a..ae4996c 100644 --- a/scripts/tasks/manage/timelock/cancel-transaction.ts +++ b/scripts/tasks/manage/timelock/cancel-transaction.ts @@ -5,13 +5,11 @@ import { createUserError } from '@/common/errorHandler'; import { executeNetworkScript } from '@/common/scriptRunner'; import { getTimelockAddress } from '@/scripts/utils/addressQueries'; -import { getAuthority, getMultisigTxIndex, getNetwork, getProgram } from '@/scripts/utils/argumentParser'; -import { PublicKey, Transaction } from '@solana/web3.js'; -import { programAddresses } from '@/common/programs'; -import { LOADER_V3_PROGRAM_ADDRESS } from '@solana-program/loader-v3'; +import { getMultisigTxIndex, getNetwork } from '@/scripts/utils/argumentParser'; +import { Transaction } from '@solana/web3.js'; import { sendAndWaitForCustomSolanaTxSign } from '@/common/solanaTxHelper'; -import { getSetAuthorityInstructionIx } from '@/scripts/utils/loaderProgramHelpers'; import * as multisig from "@sqds/multisig"; +import { getMultisigInfo, wrapTxWithSqudsSigner } from '@/scripts/deploy/timelock'; async function main( provider: AnchorProvider, @@ -24,17 +22,18 @@ async function main( const common = { provider, payer, network }; - const timelock = getTimelockAddress(network); if (!timelock) { throw createUserError(`Timelock not found for network ${network}`,); } + const multisigInfo = await getMultisigInfo(common.provider.connection, timelock); - const multisigInfo = await multisig.accounts.Multisig.fromAccountAddress(common.provider.connection as any, timelock); + const multisigMember = multisigInfo.members[0].key; + const memberMultisigInfo = await getMultisigInfo(common.provider.connection, multisigMember, false); - const tx = new Transaction().add( + const inxs = [ multisig.instructions.proposalCancel({ multisigPda: timelock, transactionIndex: BigInt(multisigTxIndex), @@ -45,7 +44,17 @@ async function main( transactionIndex: BigInt(multisigTxIndex), rentCollector: multisigInfo.rentCollector, }), - ); + ] + + const tx = memberMultisigInfo ? + await wrapTxWithSqudsSigner( + common.provider.connection, + { + instructions: inxs, + member: payer.publicKey, + multisigSignerPda: multisigMember + }) + : new Transaction().add(...inxs); const result = await sendAndWaitForCustomSolanaTxSign(common.provider, tx, [], { action: 'update-timelock', diff --git a/scripts/tasks/manage/timelock/transfer-upgrade-authority.ts b/scripts/tasks/manage/timelock/transfer-upgrade-authority.ts index 5c6ee2a..9adda7e 100644 --- a/scripts/tasks/manage/timelock/transfer-upgrade-authority.ts +++ b/scripts/tasks/manage/timelock/transfer-upgrade-authority.ts @@ -11,6 +11,7 @@ import { programAddresses } from '@/common/programs'; import { LOADER_V3_PROGRAM_ADDRESS } from '@solana-program/loader-v3'; import { sendAndWaitForCustomSolanaTxSign } from '@/common/solanaTxHelper'; import { getSetAuthorityInstructionIx } from '@/scripts/utils/loaderProgramHelpers'; +import { sendTxWithTimelock } from '@/scripts/deploy/timelock'; async function main( provider: AnchorProvider, @@ -20,15 +21,15 @@ async function main( let authority = getAuthority(false); const program = getProgram(); - if (!authority) { - console.log('Authority not provided, will use timelock as new authority'); + const timelock = getTimelockAddress(network); - const existingTimelock = getTimelockAddress(network); - if (!existingTimelock) { - throw createUserError(`Timelock not found for network ${network}`,); - } + if (!timelock) { + throw createUserError(`Timelock not found for network ${network}`,); + } - authority = existingTimelock; + if (!authority) { + console.log('Authority not provided, will use timelock as new authority'); + authority = timelock; } console.log(`Transferring upgrade authority for program ${program} to ${authority.toBase58()} on network ${network}`); @@ -52,20 +53,29 @@ async function main( throw createUserError(`No program data found for ${program} at address ${programDataPda.toBase58()}`); } - const tx = new Transaction().add(getSetAuthorityInstructionIx({ + const inx = getSetAuthorityInstructionIx({ bufferOrProgramDataAccount: programDataPda, currentAuthority: payer.publicKey, newAuthority: authority, - })); + }); + + const tx = authority.equals(timelock) ? await sendTxWithTimelock(common.provider.connection, { + instructions: [inx], + timelock, + signer: payer.publicKey, + action: { type: 'create' }, + }) : new Transaction().add(inx); const result = await sendAndWaitForCustomSolanaTxSign(common.provider, tx, [], { action: 'update-timelock', - comment: `Transfer upgrade authority for ${program} to ${authority.toBase58()} on network ${network}`, - waitForTx: true, + comment: `Transfer upgrade authority of ${program} to ${authority.toBase58()} on network ${network}`, + waitForTx: false, pollingIntervalMs: 1000, timeoutDurationMs: 120 * 1000, }); + console.log(result) + if (result.signature) { console.log(`Transaction signature: ${result.signature}`); } diff --git a/scripts/tasks/upgrade/execute-upgrade-program.ts b/scripts/tasks/upgrade/execute-upgrade-program.ts index 11397a9..5aba138 100644 --- a/scripts/tasks/upgrade/execute-upgrade-program.ts +++ b/scripts/tasks/upgrade/execute-upgrade-program.ts @@ -71,6 +71,8 @@ async function main( timeoutDurationMs: 120 * 1000, }); + console.log(result) + if (result.signature) { console.log(`Transaction signature: ${result.signature}`); } diff --git a/scripts/tasks/upgrade/propose-upgrade-program.ts b/scripts/tasks/upgrade/propose-upgrade-program.ts index ccceab3..623cd53 100644 --- a/scripts/tasks/upgrade/propose-upgrade-program.ts +++ b/scripts/tasks/upgrade/propose-upgrade-program.ts @@ -70,6 +70,8 @@ async function main( timeoutDurationMs: 120 * 1000, }); + console.log(result) + if (result.signature) { console.log(`Transaction signature: ${result.signature}`); } diff --git a/scripts/utils/addressStorage.ts b/scripts/utils/addressStorage.ts index 7f5089e..1958c10 100644 --- a/scripts/utils/addressStorage.ts +++ b/scripts/utils/addressStorage.ts @@ -86,6 +86,9 @@ function generateNetworkAddressesCode(networkAddrs: NetworkAddresses, indent = ' if (networkAddrs.ac) { parts.push(`ac: ${formatPublicKey(networkAddrs.ac)}`); } + if (networkAddrs.timelock) { + parts.push(`timelock: ${formatPublicKey(networkAddrs.timelock)}`); + } if (networkAddrs.tokens && Object.keys(networkAddrs.tokens).length > 0) { const tokenEntries = Object.entries(networkAddrs.tokens) @@ -158,6 +161,7 @@ import { MProduct, PaymentToken } from './tokenTypes'; export interface NetworkAddresses { acRoleGlobal?: PublicKey; ac?: PublicKey; + timelock?: PublicKey; tokens?: Partial>; feeds?: Partial>; } diff --git a/scripts/utils/argumentParser.ts b/scripts/utils/argumentParser.ts index e3dd65a..fdd0c74 100644 --- a/scripts/utils/argumentParser.ts +++ b/scripts/utils/argumentParser.ts @@ -135,6 +135,10 @@ export function getAuthority(required?: T): T extends ]); } + if(!authority) { + return undefined + } + try { return new PublicKey(authority); } catch { From 0f5875825f6364f4689dbe493ed5bfde4fc4fa97 Mon Sep 17 00:00:00 2001 From: kostyamospan <37243242+kostyamospan@users.noreply.github.com> Date: Tue, 17 Feb 2026 19:30:50 +0000 Subject: [PATCH 08/15] fix: typo --- scripts/deploy/timelock.ts | 6 +++--- scripts/tasks/manage/timelock/cancel-transaction.ts | 4 ++-- test/testers/squads.testers.ts | 10 +++++----- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/scripts/deploy/timelock.ts b/scripts/deploy/timelock.ts index 63e9dfe..4c06816 100644 --- a/scripts/deploy/timelock.ts +++ b/scripts/deploy/timelock.ts @@ -30,7 +30,7 @@ export const getMultisigInfo = async (connection: Conn }); } -export const wrapTxWithSqudsSigner = async (connection: Connection, { +export const wrapTxWithSquadsSigner = async (connection: Connection, { instructions, multisigSignerPda, addressLookupTableAccounts, @@ -250,7 +250,7 @@ export const sendTxWithTimelock = async (connection: Connection, { tx = txCreate; if (squadsSigner) { - tx = await wrapTxWithSqudsSigner(connection, { + tx = await wrapTxWithSquadsSigner(connection, { instructions: txCreate.instructions, member: payer, multisigSignerPda: multisigSignerPda, @@ -295,7 +295,7 @@ export const sendTxWithTimelock = async (connection: Connection, { }).compileToV0Message(inxExecute.lookupTableAccounts)); if (squadsSigner) { - tx = await wrapTxWithSqudsSigner(connection, { + tx = await wrapTxWithSquadsSigner(connection, { instructions: [inxExecute.instruction], member: payer, multisigSignerPda: multisigSignerPda, diff --git a/scripts/tasks/manage/timelock/cancel-transaction.ts b/scripts/tasks/manage/timelock/cancel-transaction.ts index ae4996c..27530df 100644 --- a/scripts/tasks/manage/timelock/cancel-transaction.ts +++ b/scripts/tasks/manage/timelock/cancel-transaction.ts @@ -9,7 +9,7 @@ import { getMultisigTxIndex, getNetwork } from '@/scripts/utils/argumentParser'; import { Transaction } from '@solana/web3.js'; import { sendAndWaitForCustomSolanaTxSign } from '@/common/solanaTxHelper'; import * as multisig from "@sqds/multisig"; -import { getMultisigInfo, wrapTxWithSqudsSigner } from '@/scripts/deploy/timelock'; +import { getMultisigInfo, wrapTxWithSquadsSigner } from '@/scripts/deploy/timelock'; async function main( provider: AnchorProvider, @@ -47,7 +47,7 @@ async function main( ] const tx = memberMultisigInfo ? - await wrapTxWithSqudsSigner( + await wrapTxWithSquadsSigner( common.provider.connection, { instructions: inxs, diff --git a/test/testers/squads.testers.ts b/test/testers/squads.testers.ts index d463318..df42bdf 100644 --- a/test/testers/squads.testers.ts +++ b/test/testers/squads.testers.ts @@ -6,7 +6,7 @@ import * as multisig from "@sqds/multisig"; import { DAY } from "../constants/common.constants"; -const wrapTxWithSqudsSigner = async (fixture: SquadsFixtureReturnType, { +const wrapTxWithSquadsSigner = async (fixture: SquadsFixtureReturnType, { instructions, member, addressLookupTableAccounts, @@ -155,7 +155,7 @@ export const sendSquadsTxWithTimelock = async (fixture: SquadsFixtureReturnType, let getTxCreateExecute: () => Promise; if (squadsSigner) { - const res = await wrapTxWithSqudsSigner(fixture, { + const res = await wrapTxWithSquadsSigner(fixture, { instructions: txCreate.instructions, member: fromCreate.publicKey, payer: fromCreate.publicKey, @@ -204,7 +204,7 @@ export const sendSquadsTxWithTimelock = async (fixture: SquadsFixtureReturnType, let getTxExecuteExecute: () => Promise; if (squadsSigner) { - const res = await wrapTxWithSqudsSigner(fixture, { + const res = await wrapTxWithSquadsSigner(fixture, { instructions: [inxExecute.instruction], addressLookupTableAccounts: inxExecute.lookupTableAccounts, member: fromExecute.publicKey, @@ -307,7 +307,7 @@ export const sendSquadsConfigurationTxWithTimelock = async (fixture: SquadsFixtu let getTxCreateExecute: () => Promise; if (squadsSigner) { - const res = await wrapTxWithSqudsSigner(fixture, { + const res = await wrapTxWithSquadsSigner(fixture, { instructions: txCreate.instructions, member: fromCreate.publicKey, payer: fromCreate.publicKey, @@ -362,7 +362,7 @@ export const sendSquadsConfigurationTxWithTimelock = async (fixture: SquadsFixtu let getTxExecuteExecute: () => Promise; if (squadsSigner) { - const res = await wrapTxWithSqudsSigner(fixture, { + const res = await wrapTxWithSquadsSigner(fixture, { instructions: txExecute.instructions, member: fromExecute.publicKey, payer: fromExecute.publicKey, From fc365d0fb8c0818a825317baa39cf23bc5801110 Mon Sep 17 00:00:00 2001 From: kostyamospan <37243242+kostyamospan@users.noreply.github.com> Date: Wed, 18 Feb 2026 10:45:47 +0000 Subject: [PATCH 09/15] fix: log --- scripts/tasks/manage/timelock/cancel-transaction.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/tasks/manage/timelock/cancel-transaction.ts b/scripts/tasks/manage/timelock/cancel-transaction.ts index 27530df..3a738fe 100644 --- a/scripts/tasks/manage/timelock/cancel-transaction.ts +++ b/scripts/tasks/manage/timelock/cancel-transaction.ts @@ -64,6 +64,8 @@ async function main( timeoutDurationMs: 120 * 1000, }); + console.log(result) + if (result.signature) { console.log(`Transaction signature: ${result.signature}`); } From bb9f79ddbf6d2cbf5fe90236d1a3752a9a92277c Mon Sep 17 00:00:00 2001 From: kostyamospan <37243242+kostyamospan@users.noreply.github.com> Date: Wed, 18 Feb 2026 13:49:33 +0200 Subject: [PATCH 10/15] fix: timelock transfer authority --- common/addresses.ts | 2 +- scripts/configs/network-config.ts | 4 +-- .../timelock/transfer-upgrade-authority.ts | 32 ++++++++++++----- scripts/utils/loaderProgramHelpers.ts | 35 ++++++++++++++++++- 4 files changed, 60 insertions(+), 13 deletions(-) diff --git a/common/addresses.ts b/common/addresses.ts index ed7a2f6..82b1579 100644 --- a/common/addresses.ts +++ b/common/addresses.ts @@ -41,7 +41,7 @@ export const addresses: Record = { devnet: { acRoleGlobal: new PublicKey('BW95RL5v9685QqxvuRGjXiM3f6Td9k5QEBiGkXMHwsx1'), ac: new PublicKey('5cMcz3NsbJy6AyvGPpMupBXFiQkwC9qRuMxkTPiTb3Qu'), - timelock: new PublicKey('B7A1wFUbCcmyLUWGMLbNRN4VBWH3jhdKFswkfPa63BFt'), + timelock: new PublicKey('CNM9uFrjXTun2zk6w7FkXKgryURXezBMZJZ4RSh8NLt3'), tokens: { [MProduct.MFONE]: { acRole: new PublicKey('2SAaMSzZd9DuNsR3QWNy8mZjNJPnMqdsC4rXz8wgnfFR'), diff --git a/scripts/configs/network-config.ts b/scripts/configs/network-config.ts index 5d551e1..eaaa532 100644 --- a/scripts/configs/network-config.ts +++ b/scripts/configs/network-config.ts @@ -3,8 +3,8 @@ import { NetworkConfig } from "./types"; export const networkConfigs: NetworkConfig = { devnet: { timelock: { - // 2 days - delay: 2 * 86400, + // 15m + delay: 15 * 60, member: '77F5WP7E9PE3cRbUXGZ8W8S2zvSGvb2WS7QuVGYpavug', }, }, diff --git a/scripts/tasks/manage/timelock/transfer-upgrade-authority.ts b/scripts/tasks/manage/timelock/transfer-upgrade-authority.ts index 9adda7e..8f8a1bc 100644 --- a/scripts/tasks/manage/timelock/transfer-upgrade-authority.ts +++ b/scripts/tasks/manage/timelock/transfer-upgrade-authority.ts @@ -10,7 +10,7 @@ import { PublicKey, Transaction } from '@solana/web3.js'; import { programAddresses } from '@/common/programs'; import { LOADER_V3_PROGRAM_ADDRESS } from '@solana-program/loader-v3'; import { sendAndWaitForCustomSolanaTxSign } from '@/common/solanaTxHelper'; -import { getSetAuthorityInstructionIx } from '@/scripts/utils/loaderProgramHelpers'; +import { getSetAuthorityInstructionIx, getUpgradeAuthority } from '@/scripts/utils/loaderProgramHelpers'; import { sendTxWithTimelock } from '@/scripts/deploy/timelock'; async function main( @@ -18,7 +18,7 @@ async function main( payer: Wallet, network: string, ) { - let authority = getAuthority(false); + let newAuthority = getAuthority(false); const program = getProgram(); const timelock = getTimelockAddress(network); @@ -27,12 +27,12 @@ async function main( throw createUserError(`Timelock not found for network ${network}`,); } - if (!authority) { + if (!newAuthority) { console.log('Authority not provided, will use timelock as new authority'); - authority = timelock; + newAuthority = timelock; } - console.log(`Transferring upgrade authority for program ${program} to ${authority.toBase58()} on network ${network}`); + console.log(`Transferring upgrade authority for program ${program} to ${newAuthority.toBase58()} on network ${network}`); const common = { provider, payer, network }; @@ -53,13 +53,27 @@ async function main( throw createUserError(`No program data found for ${program} at address ${programDataPda.toBase58()}`); } + const currentAuthority = await getUpgradeAuthority(provider.connection, programId); + + if (!currentAuthority) { + throw createUserError(`No upgrade authority found for ${programId.toBase58()}`); + } + + if (currentAuthority.equals(newAuthority)) { + throw createUserError(`New authority is the same as the current authority`); + } + + if (!newAuthority.equals(timelock) && !newAuthority.equals(payer.publicKey)) { + throw createUserError(`New authority is not the timelock or the payer, it's ${newAuthority.toBase58()}`); + } + const inx = getSetAuthorityInstructionIx({ bufferOrProgramDataAccount: programDataPda, - currentAuthority: payer.publicKey, - newAuthority: authority, + currentAuthority: currentAuthority, + newAuthority: newAuthority, }); - const tx = authority.equals(timelock) ? await sendTxWithTimelock(common.provider.connection, { + const tx = currentAuthority.equals(timelock) ? await sendTxWithTimelock(common.provider.connection, { instructions: [inx], timelock, signer: payer.publicKey, @@ -68,7 +82,7 @@ async function main( const result = await sendAndWaitForCustomSolanaTxSign(common.provider, tx, [], { action: 'update-timelock', - comment: `Transfer upgrade authority of ${program} to ${authority.toBase58()} on network ${network}`, + comment: `Transfer upgrade authority of ${program} to ${newAuthority.toBase58()} on network ${network}`, waitForTx: false, pollingIntervalMs: 1000, timeoutDurationMs: 120 * 1000, diff --git a/scripts/utils/loaderProgramHelpers.ts b/scripts/utils/loaderProgramHelpers.ts index a991484..115eefd 100644 --- a/scripts/utils/loaderProgramHelpers.ts +++ b/scripts/utils/loaderProgramHelpers.ts @@ -1,6 +1,39 @@ +import { createUserError } from "@/common/errorHandler"; import { getSetAuthorityInstruction, getUpgradeInstruction, LOADER_V3_PROGRAM_ADDRESS } from "@solana-program/loader-v3"; import { AccountRole, Address, TransactionSigner } from "@solana/kit"; -import { PublicKey, TransactionInstruction } from "@solana/web3.js"; +import { Connection, PublicKey, TransactionInstruction } from "@solana/web3.js"; + +export const getUpgradeAuthority = async (connection: Connection, programId: PublicKey): Promise => { + const [programDataPda] = PublicKey.findProgramAddressSync( + [programId.toBuffer()], + new PublicKey(LOADER_V3_PROGRAM_ADDRESS) + ); + + const accountInfo = await connection.getAccountInfo(programDataPda); + + if (!accountInfo) { + throw createUserError(`No program data found for ${programId.toBase58()} at address ${programDataPda.toBase58()}`); + } + + const data = accountInfo.data; + + // state discriminator + const state = data.readUInt32LE(0); + + if (state !== 3) { + throw new Error("Not a ProgramData account"); + } + + const option = data[12]; // 4 + 8 + + let upgradeAuthority: PublicKey | null = null; + + if (option === 1) { + upgradeAuthority = new PublicKey(data.slice(13, 45)); + } + + return upgradeAuthority; +} export const getSetAuthorityInstructionIx = ({ bufferOrProgramDataAccount, From 601a014178691156137d69f37b4bd9cb59481162 Mon Sep 17 00:00:00 2001 From: kostyamospan <37243242+kostyamospan@users.noreply.github.com> Date: Wed, 18 Feb 2026 19:01:21 +0200 Subject: [PATCH 11/15] fix: tests --- test/fixture/squads.fixture.ts | 5 +---- test/helpers/common.helpers.ts | 19 +++++++++++++------ 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/test/fixture/squads.fixture.ts b/test/fixture/squads.fixture.ts index a9de367..90ecbd3 100644 --- a/test/fixture/squads.fixture.ts +++ b/test/fixture/squads.fixture.ts @@ -72,10 +72,7 @@ const createMultisig = async (context: ProgramTestContext, { } export const squadsFixture = async (initSlot?: bigint) => { - const { provider, context, accounts } = await initBankrun(10, initSlot, [{ - name: 'external/squads', - programId: SQUADS_PROGRAM_ID, - }]); + const { provider, context, accounts } = await initBankrun(10, initSlot, true); const [authority, ...regularAccounts] = accounts; diff --git a/test/helpers/common.helpers.ts b/test/helpers/common.helpers.ts index 4664ea2..9cb06c0 100644 --- a/test/helpers/common.helpers.ts +++ b/test/helpers/common.helpers.ts @@ -68,8 +68,8 @@ export type InitBankrunReturnType = { let bunrunReturnCache: InitBankrunReturnType | null = null; -export const initBankrun = async (numAccounts = 10, initSlot?: bigint, extraPrograms: AddedProgram[] = []) => { - if (bunrunReturnCache) { +export const initBankrun = async (numAccounts = 10, initSlot?: bigint, cacheContext = false) => { + if (cacheContext && bunrunReturnCache) { return bunrunReturnCache; } @@ -92,7 +92,10 @@ export const initBankrun = async (numAccounts = 10, initSlot?: bigint, extraProg }); } - const context = await startAnchor('.', extraPrograms, [...accountsToInject]); + const context = await startAnchor('.', [{ + name: 'external/squads', + programId: SQUADS_PROGRAM_ID, + }], [...accountsToInject]); if (initSlot) { await warpToSlot(context, initSlot); @@ -104,10 +107,14 @@ export const initBankrun = async (numAccounts = 10, initSlot?: bigint, extraProg bunrunReturnCache = { context, provider, - accounts, + accounts: bunrunReturnCache?.accounts ?? accounts, }; - return bunrunReturnCache; + return { + context, + provider, + accounts, + }; }; export const fromBN = (bn?: BN) => { @@ -256,7 +263,7 @@ export const processTransaction = async ( const blockHash = ctx.lastBlockhash; const client = ctx.banksClient; - if(transaction instanceof Transaction) { + if (transaction instanceof Transaction) { transaction.recentBlockhash = blockHash; transaction.sign(...signers); } else { From 8e08b029b209e52fcfaf725434085ad6cffe159f Mon Sep 17 00:00:00 2001 From: kostyamospan <37243242+kostyamospan@users.noreply.github.com> Date: Wed, 18 Feb 2026 19:02:34 +0200 Subject: [PATCH 12/15] fix: toolchain --- Anchor.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Anchor.toml b/Anchor.toml index 4cff8e3..58ac037 100644 --- a/Anchor.toml +++ b/Anchor.toml @@ -1,4 +1,7 @@ [toolchain] +anchor_version = "0.30.1" +solana_version = "2.1.16" +package_manager = "yarn" [features] resolution = true From fae25f17b9f4d74f8f15a3336f62e01bfebf96a9 Mon Sep 17 00:00:00 2001 From: kostyamospan <37243242+kostyamospan@users.noreply.github.com> Date: Thu, 19 Feb 2026 12:26:03 +0200 Subject: [PATCH 13/15] fix: resize instruction --- package.json | 3 +- .../tasks/upgrade/propose-upgrade-program.ts | 38 +++++++++++---- .../tasks/verify/calculate-upgrade-resize.ts | 47 +++++++++++++++++++ scripts/utils/argumentParser.ts | 21 +++++++++ scripts/utils/loaderProgramHelpers.ts | 32 ++++++++++++- 5 files changed, 131 insertions(+), 10 deletions(-) create mode 100644 scripts/tasks/verify/calculate-upgrade-resize.ts diff --git a/package.json b/package.json index dcd786e..e65a1c7 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "update:data-feed": "tsx scripts/tasks/manage/update-data-feed.ts", "update:manual-feed-price": "tsx scripts/tasks/manage/update-manual-feed-price.ts", "delegate": "tsx scripts/tasks/manage/delegate.ts", + "upgrade:calculate-resize": "tsx scripts/tasks/verify/calculate-upgrade-resize.ts", "upgrade:propose": "tsx scripts/tasks/upgrade/propose-upgrade-program.ts", "upgrade:execute": "tsx scripts/tasks/upgrade/execute-upgrade-program.ts", "timelock:cancel-transaction": "tsx scripts/tasks/manage/timelock/cancel-transaction.ts", @@ -77,4 +78,4 @@ "vitest": "4.0.8" }, "packageManager": "yarn@4.10.3" -} +} \ No newline at end of file diff --git a/scripts/tasks/upgrade/propose-upgrade-program.ts b/scripts/tasks/upgrade/propose-upgrade-program.ts index 623cd53..a34d5c8 100644 --- a/scripts/tasks/upgrade/propose-upgrade-program.ts +++ b/scripts/tasks/upgrade/propose-upgrade-program.ts @@ -5,13 +5,13 @@ import { createUserError } from '@/common/errorHandler'; import { executeNetworkScript } from '@/common/scriptRunner'; import { getTimelockAddress } from '@/scripts/utils/addressQueries'; -import { getBufferAccount, getNetwork, getProgram } from '@/scripts/utils/argumentParser'; -import { PublicKey } from '@solana/web3.js'; +import { getAdditionalBytes, getBufferAccount, getNetwork, getProgram } from '@/scripts/utils/argumentParser'; +import { PublicKey, TransactionInstruction } from '@solana/web3.js'; import { programAddresses } from '@/common/programs'; import { LOADER_V3_PROGRAM_ADDRESS } from '@solana-program/loader-v3'; import { sendAndWaitForCustomSolanaTxSign } from '@/common/solanaTxHelper'; -import { sendTxWithTimelock } from '@/scripts/deploy/timelock'; -import { getUpgradeInstructionIx } from '@/scripts/utils/loaderProgramHelpers'; +import { getMultisigInfo, sendTxWithTimelock } from '@/scripts/deploy/timelock'; +import { getExtendProgramInstructionIx, getUpgradeAuthority, getUpgradeInstructionIx } from '@/scripts/utils/loaderProgramHelpers'; async function main( provider: AnchorProvider, @@ -20,6 +20,7 @@ async function main( ) { const bufferAccount = getBufferAccount(); const program = getProgram(); + const additionalBytes = getAdditionalBytes(); console.log(`Proposing upgrade of ${program} program trough the timelock for: ${network}`); @@ -47,16 +48,37 @@ async function main( throw createUserError(`No program data found for ${program} at address ${programDataPda.toBase58()}`); } - const inx = getUpgradeInstructionIx({ + const currentAuthority = await getUpgradeAuthority(provider.connection, programId); + + if (!currentAuthority.equals(existingTimelock)) { + throw createUserError(`Current authority is not the timelock, it's ${currentAuthority.toBase58()}`); + } + + const multisigData = await getMultisigInfo(provider.connection, existingTimelock); + + const member = multisigData.members[0].key; + + const instructions: TransactionInstruction[] = []; + + if (additionalBytes > 0) { + instructions.push(getExtendProgramInstructionIx({ + programId, + programDataPda, + additionalBytes, + payer: member, + })); + } + + instructions.push(getUpgradeInstructionIx({ programId, programDataPda, bufferAccount, spillAccount: payer.publicKey, - authority: payer.publicKey, - }); + authority: existingTimelock, + })); const tx = await sendTxWithTimelock(common.provider.connection, { - instructions: [inx], + instructions, timelock: existingTimelock, signer: payer.publicKey, action: { type: 'create' }, diff --git a/scripts/tasks/verify/calculate-upgrade-resize.ts b/scripts/tasks/verify/calculate-upgrade-resize.ts new file mode 100644 index 0000000..9ce9a77 --- /dev/null +++ b/scripts/tasks/verify/calculate-upgrade-resize.ts @@ -0,0 +1,47 @@ +import { createUserError } from "@/common/errorHandler"; +import { programAddresses } from "@/common/programs"; +import { executeNetworkScript } from "@/common/scriptRunner"; +import { getNetwork, getProgram } from "@/scripts/utils/argumentParser"; +import { AnchorProvider, Wallet } from "@coral-xyz/anchor"; +import { LOADER_V3_PROGRAM_ADDRESS } from "@solana-program/loader-v3"; +import { PublicKey } from "@solana/web3.js"; +import fs from "fs"; + +async function main(provider: AnchorProvider, _payer: Wallet) { + const program = getProgram(); + + const programId = programAddresses[program]; + + if (!programId) { + throw createUserError(`Program id for ${program} not found`,); + } + + const [programDataPda] = PublicKey.findProgramAddressSync( + [programId.toBuffer()], + new PublicKey(LOADER_V3_PROGRAM_ADDRESS) + ); + + const accountInfo = await provider.connection.getAccountInfo(programDataPda); + + if (!accountInfo) { + throw createUserError(`No program data found for ${programId.toBase58()} at address ${programDataPda.toBase58()}`); + } + + const dataLength = accountInfo.data.slice(49).length; + + const newProgramBytes = fs.readFileSync( + `./target/deploy/${program}.so` + ); + + const newProgramLength = newProgramBytes.length; + + const difference = newProgramLength - dataLength; + + const additionalBytes = difference > 0 ? difference : 0; + + console.log(`Bytes difference between new and current program: ${difference} bytes`); + console.log(`Required additional bytes: ${additionalBytes} bytes`); +} + +const network = getNetwork(); +executeNetworkScript(network, main); \ No newline at end of file diff --git a/scripts/utils/argumentParser.ts b/scripts/utils/argumentParser.ts index fdd0c74..6a8baaa 100644 --- a/scripts/utils/argumentParser.ts +++ b/scripts/utils/argumentParser.ts @@ -98,6 +98,27 @@ export function getProgram(): keyof (typeof programAddresses) { return program as keyof (typeof programAddresses); } + +/** Get network from arguments */ +export function getAdditionalBytes(): number { + const argv = getParsedArgs(); + const additionalBytes = (argv.additionalBytes || argv.ab) as string | undefined; + + if (!additionalBytes) { + return 0; + } + + const v = parseInt(additionalBytes); + + if (isNaN(v)) { + throw createUserError(`Invalid additional bytes '${additionalBytes}'`, [ + 'Must be a valid number', + ]); + } + + return v; +} + /** Get network from arguments */ export function getMultisigTxIndex(): number { const argv = getParsedArgs(); diff --git a/scripts/utils/loaderProgramHelpers.ts b/scripts/utils/loaderProgramHelpers.ts index 115eefd..9b1e382 100644 --- a/scripts/utils/loaderProgramHelpers.ts +++ b/scripts/utils/loaderProgramHelpers.ts @@ -1,5 +1,5 @@ import { createUserError } from "@/common/errorHandler"; -import { getSetAuthorityInstruction, getUpgradeInstruction, LOADER_V3_PROGRAM_ADDRESS } from "@solana-program/loader-v3"; +import { getExtendProgramInstruction, getSetAuthorityInstruction, getUpgradeInstruction, LOADER_V3_PROGRAM_ADDRESS } from "@solana-program/loader-v3"; import { AccountRole, Address, TransactionSigner } from "@solana/kit"; import { Connection, PublicKey, TransactionInstruction } from "@solana/web3.js"; @@ -61,6 +61,36 @@ export const getSetAuthorityInstructionIx = ({ }) } + +export const getExtendProgramInstructionIx = ({ + programId, + programDataPda, + additionalBytes, + payer +}: { + programId: PublicKey; + programDataPda: PublicKey; + payer: PublicKey; + additionalBytes: number; +}) => { + const extendIx = getExtendProgramInstruction({ + programAccount: programId.toBase58() as Address, + programDataAccount: programDataPda.toBase58() as Address, + payer: payer.toBase58() as unknown as TransactionSigner, + additionalBytes + }); + + return new TransactionInstruction({ + keys: extendIx.accounts.map(v => ({ + isSigner: v.role === AccountRole.READONLY_SIGNER || v.role === AccountRole.WRITABLE_SIGNER, + isWritable: v.role === AccountRole.WRITABLE_SIGNER || v.role === AccountRole.WRITABLE, + pubkey: new PublicKey((v.address as any).publicKey ?? v.address), + })), + programId: new PublicKey(LOADER_V3_PROGRAM_ADDRESS), + data: Buffer.from(extendIx.data), + }) +} + export const getUpgradeInstructionIx = ({ programId, programDataPda, From e221eedf904e92c5168dbd84c28b51bcef3ff205 Mon Sep 17 00:00:00 2001 From: kostyamospan <37243242+kostyamospan@users.noreply.github.com> Date: Thu, 19 Feb 2026 14:45:41 +0200 Subject: [PATCH 14/15] fix: log --- Anchor.toml | 1 - scripts/deploy/timelock.ts | 91 ++++++++++--------- .../tasks/upgrade/execute-upgrade-program.ts | 4 +- .../tasks/upgrade/propose-upgrade-program.ts | 8 +- scripts/utils/argumentParser.ts | 2 +- 5 files changed, 55 insertions(+), 51 deletions(-) diff --git a/Anchor.toml b/Anchor.toml index 58ac037..64b39f0 100644 --- a/Anchor.toml +++ b/Anchor.toml @@ -1,6 +1,5 @@ [toolchain] anchor_version = "0.30.1" -solana_version = "2.1.16" package_manager = "yarn" [features] diff --git a/scripts/deploy/timelock.ts b/scripts/deploy/timelock.ts index 4c06816..3c4d7e4 100644 --- a/scripts/deploy/timelock.ts +++ b/scripts/deploy/timelock.ts @@ -18,7 +18,7 @@ export const getMultisigInfo = async (connection: Conn connection as any, multisigPda ).catch(err => { - if(required) { + if (required) { throw err; } @@ -210,11 +210,12 @@ export const sendTxWithTimelock = async (connection: Connection, { const member = squadsSigner ? multisigSignerPda : payer; let tx: Transaction | VersionedTransaction; + let newTransactionIndex: bigint | undefined; if (action.type === 'create') { // Get the updated transaction index // TODO: get the index from the custom signer - const newTransactionIndex = BigInt(multisigInfo.transactionIndex.toString()) + 1n; + newTransactionIndex = BigInt(multisigInfo.transactionIndex.toString()) + 1n; // Build a message with instructions we want to execute const txMessage = new TransactionMessage({ @@ -304,7 +305,7 @@ export const sendTxWithTimelock = async (connection: Connection, { } } - return tx; + return { tx, newTransactionIndex }; } export const getTimelockTransaction = async (connection: Connection, { @@ -345,57 +346,57 @@ export const getTimelockTransaction = async (connection: Connection, { export function createMultisigCreateV2Instruction( accounts: multisig.generated.MultisigCreateV2InstructionAccounts, args: multisig.generated.MultisigCreateV2InstructionArgs - ) { +) { const [data] = multisig.generated.multisigCreateV2Struct.serialize({ - instructionDiscriminator: multisig.generated.multisigCreateV2InstructionDiscriminator, - ...args, + instructionDiscriminator: multisig.generated.multisigCreateV2InstructionDiscriminator, + ...args, }) const keys: AccountMeta[] = [ - { - pubkey: accounts.programConfig, - isWritable: false, - isSigner: false, - }, - { - pubkey: accounts.treasury, - isWritable: true, - isSigner: false, - }, - { - pubkey: accounts.multisig, - isWritable: true, - isSigner: false, - }, - { - pubkey: accounts.createKey, - isWritable: true, - isSigner: true, - }, - { - pubkey: accounts.creator, - isWritable: true, - isSigner: true, - }, - { - pubkey: accounts.systemProgram ?? SystemProgram.programId, - isWritable: false, - isSigner: false, - }, + { + pubkey: accounts.programConfig, + isWritable: false, + isSigner: false, + }, + { + pubkey: accounts.treasury, + isWritable: true, + isSigner: false, + }, + { + pubkey: accounts.multisig, + isWritable: true, + isSigner: false, + }, + { + pubkey: accounts.createKey, + isWritable: true, + isSigner: true, + }, + { + pubkey: accounts.creator, + isWritable: true, + isSigner: true, + }, + { + pubkey: accounts.systemProgram ?? SystemProgram.programId, + isWritable: false, + isSigner: false, + }, ] - + if (accounts.anchorRemainingAccounts != null) { - for (const acc of accounts.anchorRemainingAccounts) { - keys.push(acc) - } + for (const acc of accounts.anchorRemainingAccounts) { + keys.push(acc) + } } - + const ix = new TransactionInstruction({ - programId: multisig.PROGRAM_ID, - keys, - data, + programId: multisig.PROGRAM_ID, + keys, + data, }) return ix - } +} export const deployTimelock = async (common: CommonParams, { delay, member, createKey }: DeployTimelockConfig) => { diff --git a/scripts/tasks/upgrade/execute-upgrade-program.ts b/scripts/tasks/upgrade/execute-upgrade-program.ts index 5aba138..b5a6f85 100644 --- a/scripts/tasks/upgrade/execute-upgrade-program.ts +++ b/scripts/tasks/upgrade/execute-upgrade-program.ts @@ -5,7 +5,7 @@ import { createUserError } from '@/common/errorHandler'; import { executeNetworkScript } from '@/common/scriptRunner'; import { getTimelockAddress } from '@/scripts/utils/addressQueries'; -import { getMultisigTxIndex, getNetwork } from '@/scripts/utils/argumentParser'; +import { getMultisigTxIndex, getNetwork } from '@/scripts/utils/argumentParser'; import { programAddresses } from '@/common/programs'; import { sendAndWaitForCustomSolanaTxSign } from '@/common/solanaTxHelper'; import { getTimelockTransaction, sendTxWithTimelock } from '@/scripts/deploy/timelock'; @@ -56,7 +56,7 @@ async function main( console.log(`Program: ${program}`); - const tx = await sendTxWithTimelock(common.provider.connection, { + const { tx } = await sendTxWithTimelock(common.provider.connection, { instructions: [], timelock: existingTimelock, signer: payer.publicKey, diff --git a/scripts/tasks/upgrade/propose-upgrade-program.ts b/scripts/tasks/upgrade/propose-upgrade-program.ts index a34d5c8..cfe3f94 100644 --- a/scripts/tasks/upgrade/propose-upgrade-program.ts +++ b/scripts/tasks/upgrade/propose-upgrade-program.ts @@ -77,7 +77,7 @@ async function main( authority: existingTimelock, })); - const tx = await sendTxWithTimelock(common.provider.connection, { + const { tx, newTransactionIndex } = await sendTxWithTimelock(common.provider.connection, { instructions, timelock: existingTimelock, signer: payer.publicKey, @@ -86,12 +86,16 @@ async function main( const result = await sendAndWaitForCustomSolanaTxSign(common.provider, tx, [], { action: 'update-timelock', - comment: `Propose upgrade of ${program} program trough the timelock`, + comment: `Propose upgrade of ${program} program trough the timelock. Tx index: ${newTransactionIndex?.toString()}`, waitForTx: false, pollingIntervalMs: 1000, timeoutDurationMs: 120 * 1000, }); + if (newTransactionIndex !== undefined) { + console.log(`Timelock transaction index: ${newTransactionIndex.toString()}`); + } + console.log(result) if (result.signature) { diff --git a/scripts/utils/argumentParser.ts b/scripts/utils/argumentParser.ts index 6a8baaa..67ee9de 100644 --- a/scripts/utils/argumentParser.ts +++ b/scripts/utils/argumentParser.ts @@ -102,7 +102,7 @@ export function getProgram(): keyof (typeof programAddresses) { /** Get network from arguments */ export function getAdditionalBytes(): number { const argv = getParsedArgs(); - const additionalBytes = (argv.additionalBytes || argv.ab) as string | undefined; + const additionalBytes = (argv['additional-bytes'] || argv.ab) as string | undefined; if (!additionalBytes) { return 0; From abb8ccfdbbf0913fa4210a37e9390f497c64a702 Mon Sep 17 00:00:00 2001 From: kostyamospan <37243242+kostyamospan@users.noreply.github.com> Date: Thu, 19 Feb 2026 19:15:35 +0200 Subject: [PATCH 15/15] fix: timelock flows --- common/addresses.ts | 12 ++++++-- scripts/deploy/timelock.ts | 11 ++++++- .../tasks/deploy/network/deploy-timelock.ts | 6 ++-- .../manage/timelock/cancel-transaction.ts | 6 ++-- .../timelock/transfer-upgrade-authority.ts | 17 ++++++----- .../tasks/upgrade/execute-upgrade-program.ts | 26 +++++++++++++++-- .../tasks/upgrade/propose-upgrade-program.ts | 29 ++++++++++++------- scripts/utils/addressQueries.ts | 4 +-- scripts/utils/addressRegistry.ts | 4 +-- scripts/utils/addressStorage.ts | 12 ++++++-- scripts/utils/loaderProgramHelpers.ts | 29 ++++++++++++++++++- 11 files changed, 120 insertions(+), 36 deletions(-) diff --git a/common/addresses.ts b/common/addresses.ts index 82b1579..0fce242 100644 --- a/common/addresses.ts +++ b/common/addresses.ts @@ -6,11 +6,16 @@ import { MProduct, PaymentToken } from './tokenTypes'; export interface NetworkAddresses { acRoleGlobal?: PublicKey; ac?: PublicKey; - timelock?: PublicKey; + timelock?: TimelockAddresses; tokens?: Partial>; feeds?: Partial>; } +export type TimelockAddresses = { + multisig: PublicKey; + vault: PublicKey; +}; + export interface DataFeed { token?: PublicKey; tokenProgram?: PublicKey; @@ -41,7 +46,10 @@ export const addresses: Record = { devnet: { acRoleGlobal: new PublicKey('BW95RL5v9685QqxvuRGjXiM3f6Td9k5QEBiGkXMHwsx1'), ac: new PublicKey('5cMcz3NsbJy6AyvGPpMupBXFiQkwC9qRuMxkTPiTb3Qu'), - timelock: new PublicKey('CNM9uFrjXTun2zk6w7FkXKgryURXezBMZJZ4RSh8NLt3'), + timelock: { + multisig: new PublicKey('CNM9uFrjXTun2zk6w7FkXKgryURXezBMZJZ4RSh8NLt3'), + vault: new PublicKey('3XeBT7F1H3cbSETdHvTFDr8Wz47yNZZ6dYZsQJScdm9u'), + }, tokens: { [MProduct.MFONE]: { acRole: new PublicKey('2SAaMSzZd9DuNsR3QWNy8mZjNJPnMqdsC4rXz8wgnfFR'), diff --git a/scripts/deploy/timelock.ts b/scripts/deploy/timelock.ts index 3c4d7e4..3e3d529 100644 --- a/scripts/deploy/timelock.ts +++ b/scripts/deploy/timelock.ts @@ -448,6 +448,15 @@ export const deployTimelock = async (common: CommonParams, { delay, member, crea console.log(`Transaction signature: ${result.signature}`); } - return multisigPda as PublicKey; + + const [vaultPda] = multisig.getVaultPda({ + multisigPda: multisigPda, + index: 0, + }); + + return { + multisig: multisigPda as PublicKey, + vault: vaultPda as PublicKey, + }; }; diff --git a/scripts/tasks/deploy/network/deploy-timelock.ts b/scripts/tasks/deploy/network/deploy-timelock.ts index cbd171b..1d349da 100644 --- a/scripts/tasks/deploy/network/deploy-timelock.ts +++ b/scripts/tasks/deploy/network/deploy-timelock.ts @@ -23,7 +23,8 @@ async function main(provider: AnchorProvider, payer: Wallet, network: string) { const existingTimelock = getTimelockAddress(network); if (existingTimelock) { console.log('āœ“ Timelock already deployed'); - console.log(`Timelock: ${existingTimelock.toString()}`); + console.log(`Timelock: ${existingTimelock.multisig.toString()}`); + console.log(`Vault: ${existingTimelock.vault.toString()}`); return; } @@ -40,7 +41,8 @@ async function main(provider: AnchorProvider, payer: Wallet, network: string) { await saveAddressesToFile(); console.log('\nāœ… Timelock deployment submitted'); - console.log(`Timelock: ${timelock.toString()}`); + console.log(`Timelock: ${timelock.multisig.toString()}`); + console.log(`Vault: ${timelock.vault.toString()}`); return; } diff --git a/scripts/tasks/manage/timelock/cancel-transaction.ts b/scripts/tasks/manage/timelock/cancel-transaction.ts index 3a738fe..3e45fd5 100644 --- a/scripts/tasks/manage/timelock/cancel-transaction.ts +++ b/scripts/tasks/manage/timelock/cancel-transaction.ts @@ -28,19 +28,19 @@ async function main( throw createUserError(`Timelock not found for network ${network}`,); } - const multisigInfo = await getMultisigInfo(common.provider.connection, timelock); + const multisigInfo = await getMultisigInfo(common.provider.connection, timelock.multisig); const multisigMember = multisigInfo.members[0].key; const memberMultisigInfo = await getMultisigInfo(common.provider.connection, multisigMember, false); const inxs = [ multisig.instructions.proposalCancel({ - multisigPda: timelock, + multisigPda: timelock.multisig, transactionIndex: BigInt(multisigTxIndex), member: payer.publicKey, }), multisig.instructions.vaultTransactionAccountsClose({ - multisigPda: timelock, + multisigPda: timelock.multisig, transactionIndex: BigInt(multisigTxIndex), rentCollector: multisigInfo.rentCollector, }), diff --git a/scripts/tasks/manage/timelock/transfer-upgrade-authority.ts b/scripts/tasks/manage/timelock/transfer-upgrade-authority.ts index 8f8a1bc..c86fc1e 100644 --- a/scripts/tasks/manage/timelock/transfer-upgrade-authority.ts +++ b/scripts/tasks/manage/timelock/transfer-upgrade-authority.ts @@ -12,6 +12,7 @@ import { LOADER_V3_PROGRAM_ADDRESS } from '@solana-program/loader-v3'; import { sendAndWaitForCustomSolanaTxSign } from '@/common/solanaTxHelper'; import { getSetAuthorityInstructionIx, getUpgradeAuthority } from '@/scripts/utils/loaderProgramHelpers'; import { sendTxWithTimelock } from '@/scripts/deploy/timelock'; +import * as multisig from '@sqds/multisig'; async function main( provider: AnchorProvider, @@ -28,8 +29,8 @@ async function main( } if (!newAuthority) { - console.log('Authority not provided, will use timelock as new authority'); - newAuthority = timelock; + console.log('Authority not provided, will use timelock vault as new authority'); + newAuthority = timelock.vault; } console.log(`Transferring upgrade authority for program ${program} to ${newAuthority.toBase58()} on network ${network}`); @@ -63,8 +64,8 @@ async function main( throw createUserError(`New authority is the same as the current authority`); } - if (!newAuthority.equals(timelock) && !newAuthority.equals(payer.publicKey)) { - throw createUserError(`New authority is not the timelock or the payer, it's ${newAuthority.toBase58()}`); + if (!newAuthority.equals(timelock.vault) && !newAuthority.equals(payer.publicKey)) { + throw createUserError(`New authority is not the timelock vault or the payer, it's ${newAuthority.toBase58()}`); } const inx = getSetAuthorityInstructionIx({ @@ -73,12 +74,12 @@ async function main( newAuthority: newAuthority, }); - const tx = currentAuthority.equals(timelock) ? await sendTxWithTimelock(common.provider.connection, { + const { tx, newTransactionIndex } = currentAuthority.equals(timelock.vault) ? await sendTxWithTimelock(common.provider.connection, { instructions: [inx], - timelock, + timelock: timelock.multisig, signer: payer.publicKey, action: { type: 'create' }, - }) : new Transaction().add(inx); + }) : { tx: new Transaction().add(inx), newTransactionIndex: undefined }; const result = await sendAndWaitForCustomSolanaTxSign(common.provider, tx, [], { action: 'update-timelock', @@ -88,6 +89,8 @@ async function main( timeoutDurationMs: 120 * 1000, }); + console.log(`New transaction index: ${newTransactionIndex?.toString()}`); + console.log(result) if (result.signature) { diff --git a/scripts/tasks/upgrade/execute-upgrade-program.ts b/scripts/tasks/upgrade/execute-upgrade-program.ts index b5a6f85..28ecf51 100644 --- a/scripts/tasks/upgrade/execute-upgrade-program.ts +++ b/scripts/tasks/upgrade/execute-upgrade-program.ts @@ -8,7 +8,9 @@ import { getTimelockAddress } from '@/scripts/utils/addressQueries'; import { getMultisigTxIndex, getNetwork } from '@/scripts/utils/argumentParser'; import { programAddresses } from '@/common/programs'; import { sendAndWaitForCustomSolanaTxSign } from '@/common/solanaTxHelper'; -import { getTimelockTransaction, sendTxWithTimelock } from '@/scripts/deploy/timelock'; +import { getMultisigInfo, getTimelockTransaction, sendTxWithTimelock } from '@/scripts/deploy/timelock'; +import { getUpgradeAuthority } from '@/scripts/utils/loaderProgramHelpers'; +import * as multisig from '@sqds/multisig'; async function main( provider: AnchorProvider, @@ -27,10 +29,13 @@ async function main( const common = { provider, payer, network }; const { transaction, proposal } = await getTimelockTransaction(common.provider.connection, { - timelock: existingTimelock, + timelock: existingTimelock.multisig, transactionIndex: BigInt(multisigTxIndex), }); + const multisigInfo = await getMultisigInfo(common.provider.connection, existingTimelock.multisig); + + if (!transaction || !proposal) { throw createUserError(`Transaction or proposal not found for multisig tx index ${multisigTxIndex}. Its either not created or already executed`,); } @@ -39,6 +44,12 @@ async function main( throw createUserError(`Proposal is not approved for multisig tx index ${multisigTxIndex}`,); } + const currentTs = Math.floor(new Date().getTime() / 1000); + + if (BigInt(proposal.status.timestamp.toString()) + BigInt(multisigInfo.timeLock) > BigInt(currentTs)) { + throw createUserError(`Transaction timelock is not yet passed`,); + } + const programIdIndex = transaction.message.instructions[0].accountIndexes[1]; const bufferIndex = transaction.message.instructions[0].accountIndexes[2]; @@ -54,11 +65,20 @@ async function main( throw createUserError(`Program id ${programId.toBase58()} not found in program addresses`,); } + console.log(`Program: ${program}`); + const currentAuthority = await getUpgradeAuthority(common.provider.connection, programId); + + console.log(`Current authority: ${currentAuthority?.toBase58()}`); + + if (!currentAuthority.equals(existingTimelock.vault)) { + throw createUserError(`Current authority is not the timelock vault, it's ${currentAuthority.toBase58()}`); + } + const { tx } = await sendTxWithTimelock(common.provider.connection, { instructions: [], - timelock: existingTimelock, + timelock: existingTimelock.multisig, signer: payer.publicKey, action: { type: 'execute', transactionIndex: BigInt(multisigTxIndex) }, }); diff --git a/scripts/tasks/upgrade/propose-upgrade-program.ts b/scripts/tasks/upgrade/propose-upgrade-program.ts index cfe3f94..3f587da 100644 --- a/scripts/tasks/upgrade/propose-upgrade-program.ts +++ b/scripts/tasks/upgrade/propose-upgrade-program.ts @@ -10,8 +10,9 @@ import { PublicKey, TransactionInstruction } from '@solana/web3.js'; import { programAddresses } from '@/common/programs'; import { LOADER_V3_PROGRAM_ADDRESS } from '@solana-program/loader-v3'; import { sendAndWaitForCustomSolanaTxSign } from '@/common/solanaTxHelper'; -import { getMultisigInfo, sendTxWithTimelock } from '@/scripts/deploy/timelock'; -import { getExtendProgramInstructionIx, getUpgradeAuthority, getUpgradeInstructionIx } from '@/scripts/utils/loaderProgramHelpers'; +import { sendTxWithTimelock } from '@/scripts/deploy/timelock'; +import { getCloseBufferInx, getExtendProgramInstructionIx, getUpgradeAuthority, getUpgradeInstructionIx } from '@/scripts/utils/loaderProgramHelpers'; +import * as multisig from '@sqds/multisig'; async function main( provider: AnchorProvider, @@ -50,36 +51,42 @@ async function main( const currentAuthority = await getUpgradeAuthority(provider.connection, programId); - if (!currentAuthority.equals(existingTimelock)) { - throw createUserError(`Current authority is not the timelock, it's ${currentAuthority.toBase58()}`); - } - - const multisigData = await getMultisigInfo(provider.connection, existingTimelock); - const member = multisigData.members[0].key; + if (!currentAuthority.equals(existingTimelock.vault)) { + throw createUserError(`Current authority is not the timelock vault, it's ${currentAuthority.toBase58()}`); + } const instructions: TransactionInstruction[] = []; if (additionalBytes > 0) { + // if need to extend the program, extend it instructions.push(getExtendProgramInstructionIx({ programId, programDataPda, additionalBytes, - payer: member, + payer: existingTimelock.vault, })); } + // upgrade the program instructions.push(getUpgradeInstructionIx({ programId, programDataPda, bufferAccount, spillAccount: payer.publicKey, - authority: existingTimelock, + authority: existingTimelock.vault, + })); + + // close the buffer account to recover the funds + instructions.push(getCloseBufferInx({ + destination: payer.publicKey, + bufferAccount, + authority: existingTimelock.vault, })); const { tx, newTransactionIndex } = await sendTxWithTimelock(common.provider.connection, { instructions, - timelock: existingTimelock, + timelock: existingTimelock.multisig, signer: payer.publicKey, action: { type: 'create' }, }); diff --git a/scripts/utils/addressQueries.ts b/scripts/utils/addressQueries.ts index 91110ab..104dbd2 100644 --- a/scripts/utils/addressQueries.ts +++ b/scripts/utils/addressQueries.ts @@ -1,6 +1,6 @@ import { PublicKey } from '@solana/web3.js'; -import { addresses, NetworkAddresses, TokenAddresses, DataFeed } from '@/common/addresses'; +import { addresses, NetworkAddresses, TokenAddresses, DataFeed, TimelockAddresses } from '@/common/addresses'; import { MProduct, PaymentToken } from '@/common/tokenTypes'; // Address getters (return undefined if not found) @@ -25,7 +25,7 @@ export function getAcAddress(network: string): PublicKey | undefined { return addresses[network]?.ac; } -export function getTimelockAddress(network: string): PublicKey | undefined { +export function getTimelockAddress(network: string): TimelockAddresses | undefined { return addresses[network]?.timelock; } diff --git a/scripts/utils/addressRegistry.ts b/scripts/utils/addressRegistry.ts index 3d042f0..5ff8041 100644 --- a/scripts/utils/addressRegistry.ts +++ b/scripts/utils/addressRegistry.ts @@ -1,6 +1,6 @@ import { PublicKey } from '@solana/web3.js'; -import { addresses, TokenAddresses, DataFeed } from '@/common/addresses'; +import { addresses, TokenAddresses, DataFeed, TimelockAddresses } from '@/common/addresses'; import { createUserError } from '@/common/errorHandler'; import { MProduct, PaymentToken } from '@/common/tokenTypes'; @@ -50,7 +50,7 @@ export function registerGlobalAc(network: string, ac: PublicKey): void { networkAddrs.ac = ac; } -export function registerGlobalTimelock(network: string, timelock: PublicKey): void { +export function registerGlobalTimelock(network: string, timelock: TimelockAddresses): void { ensureNetworkExists(network); const networkAddrs = addresses[network]; networkAddrs.timelock = timelock; diff --git a/scripts/utils/addressStorage.ts b/scripts/utils/addressStorage.ts index 1958c10..d02e1c5 100644 --- a/scripts/utils/addressStorage.ts +++ b/scripts/utils/addressStorage.ts @@ -87,7 +87,10 @@ function generateNetworkAddressesCode(networkAddrs: NetworkAddresses, indent = ' parts.push(`ac: ${formatPublicKey(networkAddrs.ac)}`); } if (networkAddrs.timelock) { - parts.push(`timelock: ${formatPublicKey(networkAddrs.timelock)}`); + parts.push(`timelock: ${formatObject([ + `multisig: ${formatPublicKey(networkAddrs.timelock.multisig)}`, + `vault: ${formatPublicKey(networkAddrs.timelock.vault)}`, + ])}`); } if (networkAddrs.tokens && Object.keys(networkAddrs.tokens).length > 0) { @@ -161,11 +164,16 @@ import { MProduct, PaymentToken } from './tokenTypes'; export interface NetworkAddresses { acRoleGlobal?: PublicKey; ac?: PublicKey; - timelock?: PublicKey; + timelock?: TimelockAddresses; tokens?: Partial>; feeds?: Partial>; } +export interface TimelockAddresses { + multisig: PublicKey; + vault: PublicKey; +} + export interface DataFeed { token?: PublicKey; tokenProgram?: PublicKey; diff --git a/scripts/utils/loaderProgramHelpers.ts b/scripts/utils/loaderProgramHelpers.ts index 9b1e382..5db0c2b 100644 --- a/scripts/utils/loaderProgramHelpers.ts +++ b/scripts/utils/loaderProgramHelpers.ts @@ -1,5 +1,5 @@ import { createUserError } from "@/common/errorHandler"; -import { getExtendProgramInstruction, getSetAuthorityInstruction, getUpgradeInstruction, LOADER_V3_PROGRAM_ADDRESS } from "@solana-program/loader-v3"; +import { getCloseInstruction, getExtendProgramInstruction, getSetAuthorityInstruction, getUpgradeInstruction, LOADER_V3_PROGRAM_ADDRESS } from "@solana-program/loader-v3"; import { AccountRole, Address, TransactionSigner } from "@solana/kit"; import { Connection, PublicKey, TransactionInstruction } from "@solana/web3.js"; @@ -122,4 +122,31 @@ export const getUpgradeInstructionIx = ({ programId: new PublicKey(LOADER_V3_PROGRAM_ADDRESS), data: Buffer.from(upgradeIx.data), }) +} + +export const getCloseBufferInx = ({ + destination, + bufferAccount, + authority, +}: { + destination: PublicKey; + bufferAccount: PublicKey; + authority: PublicKey; +}) => { + + const closeIx = getCloseInstruction({ + destinationAccount: destination.toBase58() as Address, + bufferOrProgramDataAccount: bufferAccount.toBase58() as Address, + authority: authority.toBase58() as unknown as TransactionSigner, + }); + + return new TransactionInstruction({ + keys: closeIx.accounts.map(v => ({ + isSigner: v.role === AccountRole.READONLY_SIGNER || v.role === AccountRole.WRITABLE_SIGNER, + isWritable: v.role === AccountRole.WRITABLE_SIGNER || v.role === AccountRole.WRITABLE, + pubkey: new PublicKey((v.address as any).publicKey ?? v.address), + })), + programId: new PublicKey(LOADER_V3_PROGRAM_ADDRESS), + data: Buffer.from(closeIx.data), + }) } \ No newline at end of file