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  }