Skip to content

Commit 8cc36f6

Browse files
committed
WIP
1 parent 148ed4c commit 8cc36f6

2 files changed

Lines changed: 104 additions & 0 deletions

File tree

deployment/ccip/changeset/solana_v0_1_1/cs_token_pool.go

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
622706
func ModifyMintAuthority(e cldf.Environment, cfg NewMintTokenPoolConfig) (cldf.ChangesetOutput, error) {
623707
e.Logger.Infow("Use multisig as mint authority", "cfg", cfg)
624708

deployment/ccip/changeset/solana_v0_1_1/cs_token_pool_test.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -610,3 +610,23 @@ func TestPartnerTokenPools(t *testing.T) {
610610
doTestPoolLookupTable(t, e, false, metadata)
611611
doTestTokenPool(t, e, TokenPoolTestConfig{MCMS: true, TokenMetadata: metadata})
612612
}
613+
614+
func TestCreatingMultisig(t *testing.T) {
615+
tenv, _ := testhelpers.NewMemoryEnvironment(t, testhelpers.WithSolChains(1), testhelpers.WithCCIPSolanaContractVersion(ccipChangesetSolana.SolanaContractV0_1_1))
616+
solChain := tenv.Env.BlockChains.ListChainSelectors(cldf_chain.WithFamily(chain_selectors.FamilySolana))[0]
617+
618+
burnMintTokenPoolType := solTestTokenPool.BurnAndMint_PoolType
619+
_, _, err := commonchangeset.ApplyChangesets(t, tenv.Env, []commonchangeset.ConfiguredChangeSet{
620+
commonchangeset.Configure(
621+
cldf.CreateLegacyChangeSet(ccipChangesetSolana.CreateTokenMultisig),
622+
ccipChangesetSolana.CreateTokenMultisigConfig{
623+
ChainSelector: solChain,
624+
TokenMint: solana.MustPublicKeyFromBase58("DzBixyQHeQHCBqCTqe1tW5hz8AJUGbfWHxuzUp8T8Dhr"),
625+
PoolType: &burnMintTokenPoolType,
626+
Metadata: shared.CLLMetadata,
627+
CustomerMintAuthorities: []solana.PublicKey{solana.MustPublicKeyFromBase58("9o9vS5dHHQLaZLv8gHuNu6k6J5HjisF9ravgRZigiDkb")},
628+
},
629+
),
630+
})
631+
require.NoError(t, err)
632+
}

0 commit comments

Comments
 (0)