github.com/gagliardetto/solana-go@v1.11.0/account.go (about) 1 // Copyright 2021 github.com/gagliardetto 2 // This file has been modified by github.com/gagliardetto 3 // 4 // Copyright 2020 dfuse Platform Inc. 5 // 6 // Licensed under the Apache License, Version 2.0 (the "License"); 7 // you may not use this file except in compliance with the License. 8 // You may obtain a copy of the License at 9 // 10 // http://www.apache.org/licenses/LICENSE-2.0 11 // 12 // Unless required by applicable law or agreed to in writing, software 13 // distributed under the License is distributed on an "AS IS" BASIS, 14 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 // See the License for the specific language governing permissions and 16 // limitations under the License. 17 18 package solana 19 20 import ( 21 "fmt" 22 ) 23 24 // Wallet is a wrapper around a PrivateKey 25 type Wallet struct { 26 PrivateKey PrivateKey 27 } 28 29 func NewWallet() *Wallet { 30 privateKey, err := NewRandomPrivateKey() 31 if err != nil { 32 panic(fmt.Sprintf("failed to generate private key: %s", err)) 33 } 34 return &Wallet{ 35 PrivateKey: privateKey, 36 } 37 } 38 39 func WalletFromPrivateKeyBase58(privateKey string) (*Wallet, error) { 40 k, err := PrivateKeyFromBase58(privateKey) 41 if err != nil { 42 return nil, fmt.Errorf("account from private key: private key from b58: %w", err) 43 } 44 return &Wallet{ 45 PrivateKey: k, 46 }, nil 47 } 48 49 func (a *Wallet) PublicKey() PublicKey { 50 return a.PrivateKey.PublicKey() 51 } 52 53 type AccountMeta struct { 54 PublicKey PublicKey 55 IsWritable bool 56 IsSigner bool 57 } 58 59 // Meta intializes a new AccountMeta with the provided pubKey. 60 func Meta( 61 pubKey PublicKey, 62 ) *AccountMeta { 63 return &AccountMeta{ 64 PublicKey: pubKey, 65 } 66 } 67 68 // WRITE sets IsWritable to true. 69 func (meta *AccountMeta) WRITE() *AccountMeta { 70 meta.IsWritable = true 71 return meta 72 } 73 74 // SIGNER sets IsSigner to true. 75 func (meta *AccountMeta) SIGNER() *AccountMeta { 76 meta.IsSigner = true 77 return meta 78 } 79 80 func NewAccountMeta( 81 pubKey PublicKey, 82 WRITE bool, 83 SIGNER bool, 84 ) *AccountMeta { 85 return &AccountMeta{ 86 PublicKey: pubKey, 87 IsWritable: WRITE, 88 IsSigner: SIGNER, 89 } 90 } 91 92 func (a AccountMeta) less(act *AccountMeta) bool { 93 if a.IsSigner != act.IsSigner { 94 return a.IsSigner 95 } 96 if a.IsWritable != act.IsWritable { 97 return a.IsWritable 98 } 99 return false 100 } 101 102 type AccountMetaSlice []*AccountMeta 103 104 func (slice *AccountMetaSlice) Append(account *AccountMeta) { 105 *slice = append(*slice, account) 106 } 107 108 func (slice *AccountMetaSlice) SetAccounts(accounts []*AccountMeta) error { 109 *slice = accounts 110 return nil 111 } 112 113 func (slice AccountMetaSlice) GetAccounts() []*AccountMeta { 114 out := make([]*AccountMeta, 0, len(slice)) 115 for i := range slice { 116 if slice[i] != nil { 117 out = append(out, slice[i]) 118 } 119 } 120 return out 121 } 122 123 // Get returns the AccountMeta at the desired index. 124 // If the index is not present, it returns nil. 125 func (slice AccountMetaSlice) Get(index int) *AccountMeta { 126 if len(slice) > index { 127 return slice[index] 128 } 129 return nil 130 } 131 132 // GetSigners returns the accounts that are signers. 133 func (slice AccountMetaSlice) GetSigners() []*AccountMeta { 134 signers := make([]*AccountMeta, 0, len(slice)) 135 for _, ac := range slice { 136 if ac.IsSigner { 137 signers = append(signers, ac) 138 } 139 } 140 return signers 141 } 142 143 // GetKeys returns the pubkeys of all AccountMeta. 144 func (slice AccountMetaSlice) GetKeys() PublicKeySlice { 145 keys := make(PublicKeySlice, 0, len(slice)) 146 for _, ac := range slice { 147 keys = append(keys, ac.PublicKey) 148 } 149 return keys 150 } 151 152 func (slice AccountMetaSlice) Len() int { 153 return len(slice) 154 } 155 156 func (slice AccountMetaSlice) SplitFrom(index int) (AccountMetaSlice, AccountMetaSlice) { 157 if index < 0 { 158 panic("negative index") 159 } 160 if index == 0 { 161 return AccountMetaSlice{}, slice 162 } 163 if index > len(slice)-1 { 164 return slice, AccountMetaSlice{} 165 } 166 167 firstLen, secondLen := calcSplitAtLengths(len(slice), index) 168 169 first := make(AccountMetaSlice, firstLen) 170 copy(first, slice[:index]) 171 172 second := make(AccountMetaSlice, secondLen) 173 copy(second, slice[index:]) 174 175 return first, second 176 } 177 178 func calcSplitAtLengths(total int, index int) (int, int) { 179 if index == 0 { 180 return 0, total 181 } 182 if index > total-1 { 183 return total, 0 184 } 185 return index, total - index 186 }