@@ -619,6 +619,90 @@ func modifySelfServedConfig(e cldf.Environment, cfg TokenPoolConfigWithMCM, enab
619619 return cldf.ChangesetOutput {}, nil
620620}
621621
622+ type CreateTokenMultisigConfig struct {
623+ ChainSelector uint64
624+ TokenMint solana.PublicKey
625+ PoolType * solTestTokenPool.PoolType
626+ Metadata string
627+ CustomerMintAuthorities []solana.PublicKey
628+ }
629+
630+ func (cfg CreateTokenMultisigConfig ) Validate (e cldf.Environment , chainState solanastateview.CCIPChainState ) error {
631+ if err := chainState .CommonValidation (e , cfg .ChainSelector , cfg .TokenMint ); err != nil {
632+ return err
633+ }
634+ if * cfg .PoolType != solTestTokenPool .BurnAndMint_PoolType {
635+ return fmt .Errorf ("create token multisig only for burn and mint pools" )
636+ }
637+ if _ , err := chainState .TokenToTokenProgram (cfg .TokenMint ); err != nil {
638+ return fmt .Errorf ("token %s not found in existing state, deploy the token first" , cfg .TokenMint .String ())
639+ }
640+ if _ , err := chainState .TokenToTokenProgram (cfg .TokenMint ); err != nil {
641+ return fmt .Errorf ("token program id %s not found in existing state" , cfg .TokenMint .String ())
642+ }
643+ if len (cfg .CustomerMintAuthorities ) > 5 {
644+ return fmt .Errorf ("customer mint authorities max size is 5" )
645+ }
646+ for _ , mintAuthority := range cfg .CustomerMintAuthorities {
647+ if mintAuthority .IsZero () {
648+ return fmt .Errorf ("customer mint authority can not be zero" )
649+ }
650+ }
651+ tokenPool , _ := chainState .GetActiveTokenPool (* cfg .PoolType , cfg .Metadata )
652+ if tokenPool .IsZero () {
653+ return fmt .Errorf ("token pool of type %s not found in existing state, deploy the token pool first for chain %d" , * cfg .PoolType , cfg .ChainSelector )
654+ }
655+ return nil
656+ }
657+
658+ func CreateTokenMultisig (e cldf.Environment , cfg CreateTokenMultisigConfig ) (cldf.ChangesetOutput , error ) {
659+ e .Logger .Infow ("Create Token Multisig with" , "cfg" , cfg )
660+
661+ state , err := stateview .LoadOnchainState (e )
662+ if err != nil {
663+ return cldf.ChangesetOutput {}, err
664+ }
665+ solChainState := state .SolChains [cfg .ChainSelector ]
666+ if err := cfg .Validate (e , solChainState ); err != nil {
667+ return cldf.ChangesetOutput {}, err
668+ }
669+ tokenProgramId , err := solChainState .TokenToTokenProgram (cfg .TokenMint )
670+ if err != nil {
671+ return cldf.ChangesetOutput {}, err
672+ }
673+ tokenPoolProgramId , _ := solChainState .GetActiveTokenPool (* cfg .PoolType , cfg .Metadata )
674+ if tokenPoolProgramId .IsZero () {
675+ return cldf.ChangesetOutput {}, err
676+ }
677+ tokenPoolSignerPDA , err := solTokenUtil .TokenPoolSignerAddress (cfg .TokenMint , tokenPoolProgramId )
678+ if err != nil {
679+ return cldf.ChangesetOutput {}, err
680+ }
681+ newMultisig , err := createMultisig (e , tokenPoolSignerPDA , cfg .CustomerMintAuthorities , tokenProgramId )
682+ e .Logger .Info ("created multisig" , "newMultisig" , newMultisig )
683+ return cldf.ChangesetOutput {}, nil
684+ }
685+
686+ func createMultisig (e cldf.Environment , tokenPoolSignerPDA solana.PublicKey , customerMintAuthorities []solana.PublicKey , tokenProgramId solana.PublicKey ) (solana.PublicKey , error ) {
687+ // spl-token create-multisig --program-id <TOKEN_PROGRAM_ID> 1 <USER_CUSTOM_MULTISIG> <TOKEN_POOL_SIGNER_PDA>
688+ args := []string {"create-multisig" , "--program-id" , tokenProgramId .String (), "1" , tokenPoolSignerPDA .String ()}
689+ authoritiesStr := make ([]string , len (customerMintAuthorities ))
690+ for i , auth := range customerMintAuthorities {
691+ authoritiesStr [i ] = auth .String ()
692+ }
693+ args = append (args , authoritiesStr ... )
694+ e .Logger .Info (args )
695+ output , err := runCommand ("spl-token" , args , "." )
696+ e .Logger .Debugw ("spl-token create-multisig output" , "output" , output )
697+ if err != nil {
698+ e .Logger .Debugw ("spl-token create-multisig error" , "error" , err )
699+ return solana.PublicKey {}, fmt .Errorf ("error spl-token create-multisig: %w" , err )
700+ }
701+ e .Logger .Infow ("Created Token Multisig " , "tokenProgramId" , tokenProgramId )
702+ // TODO: return output, nil
703+ return solana.PublicKey {}, nil
704+ }
705+
622706func ModifyMintAuthority (e cldf.Environment , cfg NewMintTokenPoolConfig ) (cldf.ChangesetOutput , error ) {
623707 e .Logger .Infow ("Use multisig as mint authority" , "cfg" , cfg )
624708
0 commit comments