github.com/gagliardetto/solana-go@v1.11.0/programs/token/InitializeMultisig.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 // Initializes a multisignature account with N provided signers. 28 // 29 // Multisignature accounts can used in place of any single owner/delegate 30 // accounts in any token instruction that require an owner/delegate to be 31 // present. The variant field represents the number of signers (M) 32 // required to validate this multisignature account. 33 // 34 // The `InitializeMultisig` instruction requires no signers and MUST be 35 // included within the same Transaction as the system program's 36 // `CreateAccount` instruction that creates the account being initialized. 37 // Otherwise another party can acquire ownership of the uninitialized 38 // account. 39 type InitializeMultisig struct { 40 // The number of signers (M) required to validate this multisignature 41 // account. 42 M *uint8 43 44 // [0] = [WRITE] account 45 // ··········· The multisignature account to initialize. 46 // 47 // [1] = [] $(SysVarRentPubkey) 48 // ··········· Rent sysvar. 49 // 50 // [2...] = [SIGNER] signers 51 // ··········· ..2+N The signer accounts, must equal to N where 1 <= N <=11 52 Accounts ag_solanago.AccountMetaSlice `bin:"-" borsh_skip:"true"` 53 Signers ag_solanago.AccountMetaSlice `bin:"-" borsh_skip:"true"` 54 } 55 56 func (obj *InitializeMultisig) SetAccounts(accounts []*ag_solanago.AccountMeta) error { 57 obj.Accounts, obj.Signers = ag_solanago.AccountMetaSlice(accounts).SplitFrom(2) 58 return nil 59 } 60 61 func (slice InitializeMultisig) GetAccounts() (accounts []*ag_solanago.AccountMeta) { 62 accounts = append(accounts, slice.Accounts...) 63 accounts = append(accounts, slice.Signers...) 64 return 65 } 66 67 // NewInitializeMultisigInstructionBuilder creates a new `InitializeMultisig` instruction builder. 68 func NewInitializeMultisigInstructionBuilder() *InitializeMultisig { 69 nd := &InitializeMultisig{ 70 Accounts: make(ag_solanago.AccountMetaSlice, 2), 71 Signers: make(ag_solanago.AccountMetaSlice, 0), 72 } 73 nd.Accounts[1] = ag_solanago.Meta(ag_solanago.SysVarRentPubkey) 74 return nd 75 } 76 77 // SetM sets the "m" parameter. 78 // The number of signers (M) required to validate this multisignature 79 // account. 80 func (inst *InitializeMultisig) SetM(m uint8) *InitializeMultisig { 81 inst.M = &m 82 return inst 83 } 84 85 // SetAccount sets the "account" account. 86 // The multisignature account to initialize. 87 func (inst *InitializeMultisig) SetAccount(account ag_solanago.PublicKey) *InitializeMultisig { 88 inst.Accounts[0] = ag_solanago.Meta(account).WRITE() 89 return inst 90 } 91 92 // GetAccount gets the "account" account. 93 // The multisignature account to initialize. 94 func (inst *InitializeMultisig) GetAccount() *ag_solanago.AccountMeta { 95 return inst.Accounts[0] 96 } 97 98 // SetSysVarRentPubkeyAccount sets the "$(SysVarRentPubkey)" account. 99 // Rent sysvar. 100 func (inst *InitializeMultisig) SetSysVarRentPubkeyAccount(SysVarRentPubkey ag_solanago.PublicKey) *InitializeMultisig { 101 inst.Accounts[1] = ag_solanago.Meta(SysVarRentPubkey) 102 return inst 103 } 104 105 // GetSysVarRentPubkeyAccount gets the "$(SysVarRentPubkey)" account. 106 // Rent sysvar. 107 func (inst *InitializeMultisig) GetSysVarRentPubkeyAccount() *ag_solanago.AccountMeta { 108 return inst.Accounts[1] 109 } 110 111 // AddSigners adds the "signers" accounts. 112 // ..2+N The signer accounts, must equal to N where 1 <= N <=11 113 func (inst *InitializeMultisig) AddSigners(signers ...ag_solanago.PublicKey) *InitializeMultisig { 114 for _, signer := range signers { 115 inst.Signers = append(inst.Signers, ag_solanago.Meta(signer).SIGNER()) 116 } 117 return inst 118 } 119 120 func (inst InitializeMultisig) Build() *Instruction { 121 return &Instruction{BaseVariant: ag_binary.BaseVariant{ 122 Impl: inst, 123 TypeID: ag_binary.TypeIDFromUint8(Instruction_InitializeMultisig), 124 }} 125 } 126 127 // ValidateAndBuild validates the instruction parameters and accounts; 128 // if there is a validation error, it returns the error. 129 // Otherwise, it builds and returns the instruction. 130 func (inst InitializeMultisig) ValidateAndBuild() (*Instruction, error) { 131 if err := inst.Validate(); err != nil { 132 return nil, err 133 } 134 return inst.Build(), nil 135 } 136 137 func (inst *InitializeMultisig) Validate() error { 138 // Check whether all (required) parameters are set: 139 { 140 if inst.M == nil { 141 return errors.New("M parameter is not set") 142 } 143 } 144 145 // Check whether all (required) accounts are set: 146 { 147 if inst.Accounts[0] == nil { 148 return fmt.Errorf("accounts.Account is not set") 149 } 150 if inst.Accounts[1] == nil { 151 return fmt.Errorf("accounts.SysVarRentPubkey is not set") 152 } 153 if len(inst.Signers) == 0 { 154 return fmt.Errorf("accounts.Signers is not set") 155 } 156 if len(inst.Signers) > MAX_SIGNERS { 157 return fmt.Errorf("too many signers; got %v, but max is 11", len(inst.Signers)) 158 } 159 } 160 return nil 161 } 162 163 func (inst *InitializeMultisig) EncodeToTree(parent ag_treeout.Branches) { 164 parent.Child(ag_format.Program(ProgramName, ProgramID)). 165 // 166 ParentFunc(func(programBranch ag_treeout.Branches) { 167 programBranch.Child(ag_format.Instruction("InitializeMultisig")). 168 // 169 ParentFunc(func(instructionBranch ag_treeout.Branches) { 170 171 // Parameters of the instruction: 172 instructionBranch.Child("Params").ParentFunc(func(paramsBranch ag_treeout.Branches) { 173 paramsBranch.Child(ag_format.Param("M", *inst.M)) 174 }) 175 176 // Accounts of the instruction: 177 instructionBranch.Child("Accounts").ParentFunc(func(accountsBranch ag_treeout.Branches) { 178 accountsBranch.Child(ag_format.Meta(" account", inst.Accounts[0])) 179 accountsBranch.Child(ag_format.Meta("SysVarRent", inst.Accounts[1])) 180 181 signersBranch := accountsBranch.Child(fmt.Sprintf("signers[len=%v]", len(inst.Signers))) 182 for i, v := range inst.Signers { 183 if len(inst.Signers) > 9 && i < 10 { 184 signersBranch.Child(ag_format.Meta(fmt.Sprintf(" [%v]", i), v)) 185 } else { 186 signersBranch.Child(ag_format.Meta(fmt.Sprintf("[%v]", i), v)) 187 } 188 } 189 }) 190 }) 191 }) 192 } 193 194 func (obj InitializeMultisig) MarshalWithEncoder(encoder *ag_binary.Encoder) (err error) { 195 // Serialize `M` param: 196 err = encoder.Encode(obj.M) 197 if err != nil { 198 return err 199 } 200 return nil 201 } 202 func (obj *InitializeMultisig) UnmarshalWithDecoder(decoder *ag_binary.Decoder) (err error) { 203 // Deserialize `M`: 204 err = decoder.Decode(&obj.M) 205 if err != nil { 206 return err 207 } 208 return nil 209 } 210 211 // NewInitializeMultisigInstruction declares a new InitializeMultisig instruction with the provided parameters and accounts. 212 func NewInitializeMultisigInstruction( 213 // Parameters: 214 m uint8, 215 // Accounts: 216 account ag_solanago.PublicKey, 217 SysVarRentPubkey ag_solanago.PublicKey, 218 signers []ag_solanago.PublicKey, 219 ) *InitializeMultisig { 220 return NewInitializeMultisigInstructionBuilder(). 221 SetM(m). 222 SetAccount(account). 223 SetSysVarRentPubkeyAccount(SysVarRentPubkey). 224 AddSigners(signers...) 225 }