@@ -180,6 +180,117 @@ program
180
180
) ;
181
181
} ) ;
182
182
183
+ program
184
+ . command ( "change-threshold" )
185
+ . description ( "Change threshold of multisig" )
186
+ . option ( "-c, --cluster <network>" , "solana cluster to use" , "devnet" )
187
+ . requiredOption ( "-v, --vault-address <address>" , "multisig vault address" )
188
+ . option ( "-l, --ledger" , "use ledger" )
189
+ . option (
190
+ "-lda, --ledger-derivation-account <number>" ,
191
+ "ledger derivation account to use"
192
+ )
193
+ . option (
194
+ "-ldc, --ledger-derivation-change <number>" ,
195
+ "ledger derivation change to use"
196
+ )
197
+ . option (
198
+ "-w, --wallet <filepath>" ,
199
+ "multisig wallet secret key filepath" ,
200
+ "keys/key.json"
201
+ )
202
+ . option ( "-t, --threshold <number>" , "new threshold" )
203
+ . action ( async ( options ) => {
204
+ const squad = await getSquadsClient (
205
+ options . cluster ,
206
+ options . ledger ,
207
+ options . ledgerDerivationAccount ,
208
+ options . ledgerDerivationChange ,
209
+ options . wallet
210
+ ) ;
211
+ await changeThreshold (
212
+ options . cluster ,
213
+ squad ,
214
+ options . ledger ,
215
+ new PublicKey ( options . vaultAddress ) ,
216
+ options . threshold
217
+ ) ;
218
+ } ) ;
219
+
220
+ program
221
+ . command ( "add-member" )
222
+ . description ( "Add member to multisig" )
223
+ . option ( "-c, --cluster <network>" , "solana cluster to use" , "devnet" )
224
+ . requiredOption ( "-v, --vault-address <address>" , "multisig vault address" )
225
+ . option ( "-l, --ledger" , "use ledger" )
226
+ . option (
227
+ "-lda, --ledger-derivation-account <number>" ,
228
+ "ledger derivation account to use"
229
+ )
230
+ . option (
231
+ "-ldc, --ledger-derivation-change <number>" ,
232
+ "ledger derivation change to use"
233
+ )
234
+ . option (
235
+ "-w, --wallet <filepath>" ,
236
+ "multisig wallet secret key filepath" ,
237
+ "keys/key.json"
238
+ )
239
+ . option ( "-m, --member <address>" , "new member address" )
240
+ . action ( async ( options ) => {
241
+ const squad = await getSquadsClient (
242
+ options . cluster ,
243
+ options . ledger ,
244
+ options . ledgerDerivationAccount ,
245
+ options . ledgerDerivationChange ,
246
+ options . wallet
247
+ ) ;
248
+ await addMember (
249
+ options . cluster ,
250
+ squad ,
251
+ options . ledger ,
252
+ new PublicKey ( options . vaultAddress ) ,
253
+ new PublicKey ( options . member )
254
+ ) ;
255
+ } ) ;
256
+
257
+ program
258
+ . command ( "remove-member" )
259
+ . description ( "Remove member from multisig" )
260
+ . option ( "-c, --cluster <network>" , "solana cluster to use" , "devnet" )
261
+ . requiredOption ( "-v, --vault-address <address>" , "multisig vault address" )
262
+ . option ( "-l, --ledger" , "use ledger" )
263
+ . option (
264
+ "-lda, --ledger-derivation-account <number>" ,
265
+ "ledger derivation account to use"
266
+ )
267
+ . option (
268
+ "-ldc, --ledger-derivation-change <number>" ,
269
+ "ledger derivation change to use"
270
+ )
271
+ . option (
272
+ "-w, --wallet <filepath>" ,
273
+ "multisig wallet secret key filepath" ,
274
+ "keys/key.json"
275
+ )
276
+ . option ( "-m, --member <address>" , "old member address" )
277
+ . action ( async ( options ) => {
278
+ const squad = await getSquadsClient (
279
+ options . cluster ,
280
+ options . ledger ,
281
+ options . ledgerDerivationAccount ,
282
+ options . ledgerDerivationChange ,
283
+ options . wallet
284
+ ) ;
285
+ await removeMember (
286
+ options . cluster ,
287
+ squad ,
288
+ options . ledger ,
289
+ new PublicKey ( options . vaultAddress ) ,
290
+ new PublicKey ( options . member )
291
+ ) ;
292
+ } ) ;
293
+
183
294
// TODO: add subcommand for creating governance messages in the right format
184
295
185
296
program . parse ( ) ;
@@ -548,6 +659,84 @@ async function executeMultisigTx(
548
659
console . log ( `Payload: ${ Buffer . from ( parsedVaa . payload ) . toString ( "hex" ) } ` ) ;
549
660
}
550
661
662
+ async function changeThreshold (
663
+ cluster : Cluster ,
664
+ squad : Squads ,
665
+ ledger : boolean ,
666
+ vault : PublicKey ,
667
+ threshold : number
668
+ ) {
669
+ const msAccount = await squad . getMultisig ( vault ) ;
670
+ const txKey = await createTx ( squad , ledger , vault ) ;
671
+ const ix = await squad . buildChangeThresholdMember (
672
+ msAccount . publicKey ,
673
+ msAccount . externalAuthority ,
674
+ threshold
675
+ ) ;
676
+
677
+ const squadIxs : SquadInstruction [ ] = [ { instruction : ix } ] ;
678
+ await addInstructionsToTx (
679
+ cluster ,
680
+ squad ,
681
+ ledger ,
682
+ msAccount . publicKey ,
683
+ txKey ,
684
+ squadIxs
685
+ ) ;
686
+ }
687
+
688
+ async function addMember (
689
+ cluster : Cluster ,
690
+ squad : Squads ,
691
+ ledger : boolean ,
692
+ vault : PublicKey ,
693
+ member : PublicKey
694
+ ) {
695
+ const msAccount = await squad . getMultisig ( vault ) ;
696
+ const txKey = await createTx ( squad , ledger , vault ) ;
697
+ const ix = await squad . buildAddMember (
698
+ msAccount . publicKey ,
699
+ msAccount . externalAuthority ,
700
+ member
701
+ ) ;
702
+
703
+ const squadIxs : SquadInstruction [ ] = [ { instruction : ix } ] ;
704
+ await addInstructionsToTx (
705
+ cluster ,
706
+ squad ,
707
+ ledger ,
708
+ msAccount . publicKey ,
709
+ txKey ,
710
+ squadIxs
711
+ ) ;
712
+ }
713
+
714
+ async function removeMember (
715
+ cluster : Cluster ,
716
+ squad : Squads ,
717
+ ledger : boolean ,
718
+ vault : PublicKey ,
719
+ member : PublicKey
720
+ ) {
721
+ const msAccount = await squad . getMultisig ( vault ) ;
722
+ const txKey = await createTx ( squad , ledger , vault ) ;
723
+ const ix = await squad . buildRemoveMember (
724
+ msAccount . publicKey ,
725
+ msAccount . externalAuthority ,
726
+ member
727
+ ) ;
728
+
729
+ const squadIxs : SquadInstruction [ ] = [ { instruction : ix } ] ;
730
+ await addInstructionsToTx (
731
+ cluster ,
732
+ squad ,
733
+ ledger ,
734
+ msAccount . publicKey ,
735
+ txKey ,
736
+ squadIxs
737
+ ) ;
738
+ }
739
+
551
740
async function parse ( data : string ) {
552
741
const { parse_vaa } = await importCoreWasm ( ) ;
553
742
return parse_vaa ( Uint8Array . from ( Buffer . from ( data , "base64" ) ) ) ;
0 commit comments