github.com/gagliardetto/solana-go@v1.11.0/programs/system/Allocate.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 system
    16  
    17  import (
    18  	"encoding/binary"
    19  	"errors"
    20  	"fmt"
    21  
    22  	ag_binary "github.com/gagliardetto/binary"
    23  	ag_solanago "github.com/gagliardetto/solana-go"
    24  	ag_format "github.com/gagliardetto/solana-go/text/format"
    25  	ag_treeout "github.com/gagliardetto/treeout"
    26  )
    27  
    28  // Allocate space in a (possibly new) account without funding
    29  type Allocate struct {
    30  	// Number of bytes of memory to allocate
    31  	Space *uint64
    32  
    33  	// [0] = [WRITE, SIGNER] NewAccount
    34  	// ··········· New account
    35  	ag_solanago.AccountMetaSlice `bin:"-" borsh_skip:"true"`
    36  }
    37  
    38  // NewAllocateInstructionBuilder creates a new `Allocate` instruction builder.
    39  func NewAllocateInstructionBuilder() *Allocate {
    40  	nd := &Allocate{
    41  		AccountMetaSlice: make(ag_solanago.AccountMetaSlice, 1),
    42  	}
    43  	return nd
    44  }
    45  
    46  // Number of bytes of memory to allocate
    47  func (inst *Allocate) SetSpace(space uint64) *Allocate {
    48  	inst.Space = &space
    49  	return inst
    50  }
    51  
    52  // New account
    53  func (inst *Allocate) SetNewAccount(newAccount ag_solanago.PublicKey) *Allocate {
    54  	inst.AccountMetaSlice[0] = ag_solanago.Meta(newAccount).WRITE().SIGNER()
    55  	return inst
    56  }
    57  
    58  func (inst *Allocate) GetNewAccount() *ag_solanago.AccountMeta {
    59  	return inst.AccountMetaSlice[0]
    60  }
    61  
    62  func (inst Allocate) Build() *Instruction {
    63  	return &Instruction{BaseVariant: ag_binary.BaseVariant{
    64  		Impl:   inst,
    65  		TypeID: ag_binary.TypeIDFromUint32(Instruction_Allocate, binary.LittleEndian),
    66  	}}
    67  }
    68  
    69  // ValidateAndBuild validates the instruction parameters and accounts;
    70  // if there is a validation error, it returns the error.
    71  // Otherwise, it builds and returns the instruction.
    72  func (inst Allocate) ValidateAndBuild() (*Instruction, error) {
    73  	if err := inst.Validate(); err != nil {
    74  		return nil, err
    75  	}
    76  	return inst.Build(), nil
    77  }
    78  
    79  func (inst *Allocate) Validate() error {
    80  	// Check whether all (required) parameters are set:
    81  	{
    82  		if inst.Space == nil {
    83  			return errors.New("Space parameter is not set")
    84  		}
    85  	}
    86  
    87  	// Check whether all accounts are set:
    88  	for accIndex, acc := range inst.AccountMetaSlice {
    89  		if acc == nil {
    90  			return fmt.Errorf("ins.AccountMetaSlice[%v] is not set", accIndex)
    91  		}
    92  	}
    93  	return nil
    94  }
    95  
    96  func (inst *Allocate) EncodeToTree(parent ag_treeout.Branches) {
    97  	parent.Child(ag_format.Program(ProgramName, ProgramID)).
    98  		//
    99  		ParentFunc(func(programBranch ag_treeout.Branches) {
   100  			programBranch.Child(ag_format.Instruction("Allocate")).
   101  				//
   102  				ParentFunc(func(instructionBranch ag_treeout.Branches) {
   103  
   104  					// Parameters of the instruction:
   105  					instructionBranch.Child("Params").ParentFunc(func(paramsBranch ag_treeout.Branches) {
   106  						paramsBranch.Child(ag_format.Param("Space", *inst.Space))
   107  					})
   108  
   109  					// Accounts of the instruction:
   110  					instructionBranch.Child("Accounts").ParentFunc(func(accountsBranch ag_treeout.Branches) {
   111  						accountsBranch.Child(ag_format.Meta("New", inst.AccountMetaSlice[0]))
   112  					})
   113  				})
   114  		})
   115  }
   116  
   117  func (inst Allocate) MarshalWithEncoder(encoder *ag_binary.Encoder) error {
   118  	// Serialize `Space` param:
   119  	{
   120  		err := encoder.Encode(*inst.Space)
   121  		if err != nil {
   122  			return err
   123  		}
   124  	}
   125  	return nil
   126  }
   127  
   128  func (inst *Allocate) UnmarshalWithDecoder(decoder *ag_binary.Decoder) error {
   129  	// Deserialize `Space` param:
   130  	{
   131  		err := decoder.Decode(&inst.Space)
   132  		if err != nil {
   133  			return err
   134  		}
   135  	}
   136  	return nil
   137  }
   138  
   139  // NewAllocateInstruction declares a new Allocate instruction with the provided parameters and accounts.
   140  func NewAllocateInstruction(
   141  	// Parameters:
   142  	space uint64,
   143  	// Accounts:
   144  	newAccount ag_solanago.PublicKey) *Allocate {
   145  	return NewAllocateInstructionBuilder().
   146  		SetSpace(space).
   147  		SetNewAccount(newAccount)
   148  }