github.com/gagliardetto/solana-go@v1.11.0/programs/token/MintToChecked.go (about)

     1  // Copyright 2021 github.com/gagliardetto
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package token
    16  
    17  import (
    18  	"errors"
    19  	"fmt"
    20  
    21  	ag_binary "github.com/gagliardetto/binary"
    22  	ag_solanago "github.com/gagliardetto/solana-go"
    23  	ag_format "github.com/gagliardetto/solana-go/text/format"
    24  	ag_treeout "github.com/gagliardetto/treeout"
    25  )
    26  
    27  // Mints new tokens to an account.  The native mint does not support minting.
    28  //
    29  // This instruction differs from MintTo in that the decimals value is
    30  // checked by the caller.  This may be useful when creating transactions
    31  // offline or within a hardware wallet.
    32  type MintToChecked struct {
    33  	// The amount of new tokens to mint.
    34  	Amount *uint64
    35  
    36  	// Expected number of base 10 digits to the right of the decimal place.
    37  	Decimals *uint8
    38  
    39  	// [0] = [WRITE] mint
    40  	// ··········· The mint.
    41  	//
    42  	// [1] = [WRITE] destination
    43  	// ··········· The account to mint tokens to.
    44  	//
    45  	// [2] = [] authority
    46  	// ··········· The mint's minting authority.
    47  	//
    48  	// [3...] = [SIGNER] signers
    49  	// ··········· M signer accounts.
    50  	Accounts ag_solanago.AccountMetaSlice `bin:"-" borsh_skip:"true"`
    51  	Signers  ag_solanago.AccountMetaSlice `bin:"-" borsh_skip:"true"`
    52  }
    53  
    54  func (obj *MintToChecked) SetAccounts(accounts []*ag_solanago.AccountMeta) error {
    55  	obj.Accounts, obj.Signers = ag_solanago.AccountMetaSlice(accounts).SplitFrom(3)
    56  	return nil
    57  }
    58  
    59  func (slice MintToChecked) GetAccounts() (accounts []*ag_solanago.AccountMeta) {
    60  	accounts = append(accounts, slice.Accounts...)
    61  	accounts = append(accounts, slice.Signers...)
    62  	return
    63  }
    64  
    65  // NewMintToCheckedInstructionBuilder creates a new `MintToChecked` instruction builder.
    66  func NewMintToCheckedInstructionBuilder() *MintToChecked {
    67  	nd := &MintToChecked{
    68  		Accounts: make(ag_solanago.AccountMetaSlice, 3),
    69  		Signers:  make(ag_solanago.AccountMetaSlice, 0),
    70  	}
    71  	return nd
    72  }
    73  
    74  // SetAmount sets the "amount" parameter.
    75  // The amount of new tokens to mint.
    76  func (inst *MintToChecked) SetAmount(amount uint64) *MintToChecked {
    77  	inst.Amount = &amount
    78  	return inst
    79  }
    80  
    81  // SetDecimals sets the "decimals" parameter.
    82  // Expected number of base 10 digits to the right of the decimal place.
    83  func (inst *MintToChecked) SetDecimals(decimals uint8) *MintToChecked {
    84  	inst.Decimals = &decimals
    85  	return inst
    86  }
    87  
    88  // SetMintAccount sets the "mint" account.
    89  // The mint.
    90  func (inst *MintToChecked) SetMintAccount(mint ag_solanago.PublicKey) *MintToChecked {
    91  	inst.Accounts[0] = ag_solanago.Meta(mint).WRITE()
    92  	return inst
    93  }
    94  
    95  // GetMintAccount gets the "mint" account.
    96  // The mint.
    97  func (inst *MintToChecked) GetMintAccount() *ag_solanago.AccountMeta {
    98  	return inst.Accounts[0]
    99  }
   100  
   101  // SetDestinationAccount sets the "destination" account.
   102  // The account to mint tokens to.
   103  func (inst *MintToChecked) SetDestinationAccount(destination ag_solanago.PublicKey) *MintToChecked {
   104  	inst.Accounts[1] = ag_solanago.Meta(destination).WRITE()
   105  	return inst
   106  }
   107  
   108  // GetDestinationAccount gets the "destination" account.
   109  // The account to mint tokens to.
   110  func (inst *MintToChecked) GetDestinationAccount() *ag_solanago.AccountMeta {
   111  	return inst.Accounts[1]
   112  }
   113  
   114  // SetAuthorityAccount sets the "authority" account.
   115  // The mint's minting authority.
   116  func (inst *MintToChecked) SetAuthorityAccount(authority ag_solanago.PublicKey, multisigSigners ...ag_solanago.PublicKey) *MintToChecked {
   117  	inst.Accounts[2] = ag_solanago.Meta(authority)
   118  	if len(multisigSigners) == 0 {
   119  		inst.Accounts[2].SIGNER()
   120  	}
   121  	for _, signer := range multisigSigners {
   122  		inst.Signers = append(inst.Signers, ag_solanago.Meta(signer).SIGNER())
   123  	}
   124  	return inst
   125  }
   126  
   127  // GetAuthorityAccount gets the "authority" account.
   128  // The mint's minting authority.
   129  func (inst *MintToChecked) GetAuthorityAccount() *ag_solanago.AccountMeta {
   130  	return inst.Accounts[2]
   131  }
   132  
   133  func (inst MintToChecked) Build() *Instruction {
   134  	return &Instruction{BaseVariant: ag_binary.BaseVariant{
   135  		Impl:   inst,
   136  		TypeID: ag_binary.TypeIDFromUint8(Instruction_MintToChecked),
   137  	}}
   138  }
   139  
   140  // ValidateAndBuild validates the instruction parameters and accounts;
   141  // if there is a validation error, it returns the error.
   142  // Otherwise, it builds and returns the instruction.
   143  func (inst MintToChecked) ValidateAndBuild() (*Instruction, error) {
   144  	if err := inst.Validate(); err != nil {
   145  		return nil, err
   146  	}
   147  	return inst.Build(), nil
   148  }
   149  
   150  func (inst *MintToChecked) Validate() error {
   151  	// Check whether all (required) parameters are set:
   152  	{
   153  		if inst.Amount == nil {
   154  			return errors.New("Amount parameter is not set")
   155  		}
   156  		if inst.Decimals == nil {
   157  			return errors.New("Decimals parameter is not set")
   158  		}
   159  	}
   160  
   161  	// Check whether all (required) accounts are set:
   162  	{
   163  		if inst.Accounts[0] == nil {
   164  			return errors.New("accounts.Mint is not set")
   165  		}
   166  		if inst.Accounts[1] == nil {
   167  			return errors.New("accounts.Destination is not set")
   168  		}
   169  		if inst.Accounts[2] == nil {
   170  			return errors.New("accounts.Authority is not set")
   171  		}
   172  		if !inst.Accounts[2].IsSigner && len(inst.Signers) == 0 {
   173  			return fmt.Errorf("accounts.Signers is not set")
   174  		}
   175  		if len(inst.Signers) > MAX_SIGNERS {
   176  			return fmt.Errorf("too many signers; got %v, but max is 11", len(inst.Signers))
   177  		}
   178  	}
   179  	return nil
   180  }
   181  
   182  func (inst *MintToChecked) EncodeToTree(parent ag_treeout.Branches) {
   183  	parent.Child(ag_format.Program(ProgramName, ProgramID)).
   184  		//
   185  		ParentFunc(func(programBranch ag_treeout.Branches) {
   186  			programBranch.Child(ag_format.Instruction("MintToChecked")).
   187  				//
   188  				ParentFunc(func(instructionBranch ag_treeout.Branches) {
   189  
   190  					// Parameters of the instruction:
   191  					instructionBranch.Child("Params").ParentFunc(func(paramsBranch ag_treeout.Branches) {
   192  						paramsBranch.Child(ag_format.Param("  Amount", *inst.Amount))
   193  						paramsBranch.Child(ag_format.Param("Decimals", *inst.Decimals))
   194  					})
   195  
   196  					// Accounts of the instruction:
   197  					instructionBranch.Child("Accounts").ParentFunc(func(accountsBranch ag_treeout.Branches) {
   198  						accountsBranch.Child(ag_format.Meta("       mint", inst.Accounts[0]))
   199  						accountsBranch.Child(ag_format.Meta("destination", inst.Accounts[1]))
   200  						accountsBranch.Child(ag_format.Meta("  authority", inst.Accounts[2]))
   201  
   202  						signersBranch := accountsBranch.Child(fmt.Sprintf("signers[len=%v]", len(inst.Signers)))
   203  						for i, v := range inst.Signers {
   204  							if len(inst.Signers) > 9 && i < 10 {
   205  								signersBranch.Child(ag_format.Meta(fmt.Sprintf(" [%v]", i), v))
   206  							} else {
   207  								signersBranch.Child(ag_format.Meta(fmt.Sprintf("[%v]", i), v))
   208  							}
   209  						}
   210  					})
   211  				})
   212  		})
   213  }
   214  
   215  func (obj MintToChecked) MarshalWithEncoder(encoder *ag_binary.Encoder) (err error) {
   216  	// Serialize `Amount` param:
   217  	err = encoder.Encode(obj.Amount)
   218  	if err != nil {
   219  		return err
   220  	}
   221  	// Serialize `Decimals` param:
   222  	err = encoder.Encode(obj.Decimals)
   223  	if err != nil {
   224  		return err
   225  	}
   226  	return nil
   227  }
   228  func (obj *MintToChecked) UnmarshalWithDecoder(decoder *ag_binary.Decoder) (err error) {
   229  	// Deserialize `Amount`:
   230  	err = decoder.Decode(&obj.Amount)
   231  	if err != nil {
   232  		return err
   233  	}
   234  	// Deserialize `Decimals`:
   235  	err = decoder.Decode(&obj.Decimals)
   236  	if err != nil {
   237  		return err
   238  	}
   239  	return nil
   240  }
   241  
   242  // NewMintToCheckedInstruction declares a new MintToChecked instruction with the provided parameters and accounts.
   243  func NewMintToCheckedInstruction(
   244  	// Parameters:
   245  	amount uint64,
   246  	decimals uint8,
   247  	// Accounts:
   248  	mint ag_solanago.PublicKey,
   249  	destination ag_solanago.PublicKey,
   250  	authority ag_solanago.PublicKey,
   251  	multisigSigners []ag_solanago.PublicKey,
   252  ) *MintToChecked {
   253  	return NewMintToCheckedInstructionBuilder().
   254  		SetAmount(amount).
   255  		SetDecimals(decimals).
   256  		SetMintAccount(mint).
   257  		SetDestinationAccount(destination).
   258  		SetAuthorityAccount(authority, multisigSigners...)
   259  }