github.com/gagliardetto/solana-go@v1.11.0/programs/system/Transfer.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 // Transfer lamports 29 type Transfer struct { 30 // Number of lamports to transfer to the new account 31 Lamports *uint64 32 33 // [0] = [WRITE, SIGNER] FundingAccount 34 // ··········· Funding account 35 // 36 // [1] = [WRITE] RecipientAccount 37 // ··········· Recipient account 38 ag_solanago.AccountMetaSlice `bin:"-" borsh_skip:"true"` 39 } 40 41 // NewTransferInstructionBuilder creates a new `Transfer` instruction builder. 42 func NewTransferInstructionBuilder() *Transfer { 43 nd := &Transfer{ 44 AccountMetaSlice: make(ag_solanago.AccountMetaSlice, 2), 45 } 46 return nd 47 } 48 49 // Number of lamports to transfer to the new account 50 func (inst *Transfer) SetLamports(lamports uint64) *Transfer { 51 inst.Lamports = &lamports 52 return inst 53 } 54 55 // Funding account 56 func (inst *Transfer) SetFundingAccount(fundingAccount ag_solanago.PublicKey) *Transfer { 57 inst.AccountMetaSlice[0] = ag_solanago.Meta(fundingAccount).WRITE().SIGNER() 58 return inst 59 } 60 61 func (inst *Transfer) GetFundingAccount() *ag_solanago.AccountMeta { 62 return inst.AccountMetaSlice[0] 63 } 64 65 // Recipient account 66 func (inst *Transfer) SetRecipientAccount(recipientAccount ag_solanago.PublicKey) *Transfer { 67 inst.AccountMetaSlice[1] = ag_solanago.Meta(recipientAccount).WRITE() 68 return inst 69 } 70 71 func (inst *Transfer) GetRecipientAccount() *ag_solanago.AccountMeta { 72 return inst.AccountMetaSlice[1] 73 } 74 75 func (inst Transfer) Build() *Instruction { 76 return &Instruction{BaseVariant: ag_binary.BaseVariant{ 77 Impl: inst, 78 TypeID: ag_binary.TypeIDFromUint32(Instruction_Transfer, binary.LittleEndian), 79 }} 80 } 81 82 // ValidateAndBuild validates the instruction parameters and accounts; 83 // if there is a validation error, it returns the error. 84 // Otherwise, it builds and returns the instruction. 85 func (inst Transfer) ValidateAndBuild() (*Instruction, error) { 86 if err := inst.Validate(); err != nil { 87 return nil, err 88 } 89 return inst.Build(), nil 90 } 91 92 func (inst *Transfer) Validate() error { 93 // Check whether all (required) parameters are set: 94 { 95 if inst.Lamports == nil { 96 return errors.New("Lamports parameter is not set") 97 } 98 } 99 100 // Check whether all accounts are set: 101 for accIndex, acc := range inst.AccountMetaSlice { 102 if acc == nil { 103 return fmt.Errorf("ins.AccountMetaSlice[%v] is not set", accIndex) 104 } 105 } 106 return nil 107 } 108 109 func (inst *Transfer) EncodeToTree(parent ag_treeout.Branches) { 110 parent.Child(ag_format.Program(ProgramName, ProgramID)). 111 // 112 ParentFunc(func(programBranch ag_treeout.Branches) { 113 programBranch.Child(ag_format.Instruction("Transfer")). 114 // 115 ParentFunc(func(instructionBranch ag_treeout.Branches) { 116 117 // Parameters of the instruction: 118 instructionBranch.Child("Params").ParentFunc(func(paramsBranch ag_treeout.Branches) { 119 paramsBranch.Child(ag_format.Param("Lamports", *inst.Lamports)) 120 }) 121 122 // Accounts of the instruction: 123 instructionBranch.Child("Accounts").ParentFunc(func(accountsBranch ag_treeout.Branches) { 124 accountsBranch.Child(ag_format.Meta(" Funding", inst.AccountMetaSlice[0])) 125 accountsBranch.Child(ag_format.Meta("Recipient", inst.AccountMetaSlice[1])) 126 }) 127 }) 128 }) 129 } 130 131 func (inst Transfer) MarshalWithEncoder(encoder *ag_binary.Encoder) error { 132 // Serialize `Lamports` param: 133 { 134 err := encoder.Encode(*inst.Lamports) 135 if err != nil { 136 return err 137 } 138 } 139 return nil 140 } 141 142 func (inst *Transfer) UnmarshalWithDecoder(decoder *ag_binary.Decoder) error { 143 // Deserialize `Lamports` param: 144 { 145 err := decoder.Decode(&inst.Lamports) 146 if err != nil { 147 return err 148 } 149 } 150 return nil 151 } 152 153 // NewTransferInstruction declares a new Transfer instruction with the provided parameters and accounts. 154 func NewTransferInstruction( 155 // Parameters: 156 lamports uint64, 157 // Accounts: 158 fundingAccount ag_solanago.PublicKey, 159 recipientAccount ag_solanago.PublicKey) *Transfer { 160 return NewTransferInstructionBuilder(). 161 SetLamports(lamports). 162 SetFundingAccount(fundingAccount). 163 SetRecipientAccount(recipientAccount) 164 }