github.com/gagliardetto/solana-go@v1.11.0/programs/vote/instructions.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 vote 16 17 import ( 18 "bytes" 19 "encoding/binary" 20 "fmt" 21 22 "github.com/davecgh/go-spew/spew" 23 bin "github.com/gagliardetto/binary" 24 "github.com/gagliardetto/solana-go" 25 "github.com/gagliardetto/solana-go/text" 26 "github.com/gagliardetto/treeout" 27 ) 28 29 var ProgramID solana.PublicKey = solana.VoteProgramID 30 31 func SetProgramID(pubkey solana.PublicKey) { 32 ProgramID = pubkey 33 solana.RegisterInstructionDecoder(ProgramID, registryDecodeInstruction) 34 } 35 36 const ProgramName = "Vote" 37 38 func init() { 39 solana.RegisterInstructionDecoder(ProgramID, registryDecodeInstruction) 40 } 41 42 type Instruction struct { 43 bin.BaseVariant 44 } 45 46 func (inst *Instruction) EncodeToTree(parent treeout.Branches) { 47 if enToTree, ok := inst.Impl.(text.EncodableToTree); ok { 48 enToTree.EncodeToTree(parent) 49 } else { 50 parent.Child(spew.Sdump(inst)) 51 } 52 } 53 54 var InstructionImplDef = bin.NewVariantDefinition( 55 bin.Uint32TypeIDEncoding, 56 []bin.VariantType{ 57 { 58 "InitializeAccount", (*InitializeAccount)(nil), 59 }, 60 { 61 "Authorize", (*Authorize)(nil), 62 }, 63 { 64 "Vote", (*Vote)(nil), 65 }, 66 { 67 "Withdraw", (*Withdraw)(nil), 68 }, 69 }, 70 ) 71 72 func (inst *Instruction) ProgramID() solana.PublicKey { 73 return ProgramID 74 } 75 76 func (inst *Instruction) Accounts() (out []*solana.AccountMeta) { 77 return inst.Impl.(solana.AccountsGettable).GetAccounts() 78 } 79 80 func (inst *Instruction) Data() ([]byte, error) { 81 buf := new(bytes.Buffer) 82 if err := bin.NewBinEncoder(buf).Encode(inst); err != nil { 83 return nil, fmt.Errorf("unable to encode instruction: %w", err) 84 } 85 return buf.Bytes(), nil 86 } 87 88 func (inst *Instruction) TextEncode(encoder *text.Encoder, option *text.Option) error { 89 return encoder.Encode(inst.Impl, option) 90 } 91 92 func (inst *Instruction) UnmarshalWithDecoder(decoder *bin.Decoder) error { 93 return inst.BaseVariant.UnmarshalBinaryVariant(decoder, InstructionImplDef) 94 } 95 96 func (inst Instruction) MarshalWithEncoder(encoder *bin.Encoder) error { 97 err := encoder.WriteUint32(inst.TypeID.Uint32(), binary.LittleEndian) 98 if err != nil { 99 return fmt.Errorf("unable to write variant type: %w", err) 100 } 101 return encoder.Encode(inst.Impl) 102 } 103 104 func registryDecodeInstruction(accounts []*solana.AccountMeta, data []byte) (interface{}, error) { 105 inst, err := DecodeInstruction(accounts, data) 106 if err != nil { 107 return nil, err 108 } 109 return inst, nil 110 } 111 112 func DecodeInstruction(accounts []*solana.AccountMeta, data []byte) (*Instruction, error) { 113 inst := new(Instruction) 114 if err := bin.NewBinDecoder(data).Decode(inst); err != nil { 115 return nil, fmt.Errorf("unable to decode instruction: %w", err) 116 } 117 if v, ok := inst.Impl.(solana.AccountsSettable); ok { 118 err := v.SetAccounts(accounts) 119 if err != nil { 120 return nil, fmt.Errorf("unable to set accounts for instruction: %w", err) 121 } 122 } 123 return inst, nil 124 }