github.com/algorand/go-algorand-sdk@v1.24.0/future/transactionSigner.go (about)

     1  package future
     2  
     3  import (
     4  	"encoding/json"
     5  
     6  	"github.com/algorand/go-algorand-sdk/crypto"
     7  	"github.com/algorand/go-algorand-sdk/types"
     8  )
     9  
    10  /**
    11   * This type represents a function which can sign transactions from an atomic transaction group.
    12   * @param txnGroup - The atomic group containing transactions to be signed
    13   * @param indexesToSign - An array of indexes in the atomic transaction group that should be signed
    14   * @returns An array of encoded signed transactions. The length of the
    15   *   array will be the same as the length of indexesToSign, and each index i in the array
    16   *   corresponds to the signed transaction from txnGroup[indexesToSign[i]]
    17   */
    18  type TransactionSigner interface {
    19  	SignTransactions(txGroup []types.Transaction, indexesToSign []int) ([][]byte, error)
    20  	Equals(other TransactionSigner) bool
    21  }
    22  
    23  /**
    24   * TransactionSigner that can sign transactions for the provided basic Account.
    25   */
    26  type BasicAccountTransactionSigner struct {
    27  	Account crypto.Account
    28  }
    29  
    30  func (txSigner BasicAccountTransactionSigner) SignTransactions(txGroup []types.Transaction, indexesToSign []int) ([][]byte, error) {
    31  	stxs := make([][]byte, len(indexesToSign))
    32  	for i, pos := range indexesToSign {
    33  		_, stxBytes, err := crypto.SignTransaction(txSigner.Account.PrivateKey, txGroup[pos])
    34  		if err != nil {
    35  			return nil, err
    36  		}
    37  
    38  		stxs[i] = stxBytes
    39  	}
    40  
    41  	return stxs, nil
    42  }
    43  
    44  func (txSigner BasicAccountTransactionSigner) Equals(other TransactionSigner) bool {
    45  	if castedSigner, ok := other.(BasicAccountTransactionSigner); ok {
    46  		otherJson, err := json.Marshal(castedSigner)
    47  		if err != nil {
    48  			return false
    49  		}
    50  
    51  		selfJson, err := json.Marshal(txSigner)
    52  		if err != nil {
    53  			return false
    54  		}
    55  
    56  		return string(otherJson) == string(selfJson)
    57  	}
    58  	return false
    59  }
    60  
    61  /**
    62   * TransactionSigner that can sign transactions for the provided LogicSigAccount.
    63   */
    64  type LogicSigAccountTransactionSigner struct {
    65  	LogicSigAccount crypto.LogicSigAccount
    66  }
    67  
    68  func (txSigner LogicSigAccountTransactionSigner) SignTransactions(txGroup []types.Transaction, indexesToSign []int) ([][]byte, error) {
    69  	stxs := make([][]byte, len(indexesToSign))
    70  	for i, pos := range indexesToSign {
    71  		_, stxBytes, err := crypto.SignLogicSigAccountTransaction(txSigner.LogicSigAccount, txGroup[pos])
    72  		if err != nil {
    73  			return nil, err
    74  		}
    75  
    76  		stxs[i] = stxBytes
    77  	}
    78  
    79  	return stxs, nil
    80  }
    81  
    82  func (txSigner LogicSigAccountTransactionSigner) Equals(other TransactionSigner) bool {
    83  	if castedSigner, ok := other.(LogicSigAccountTransactionSigner); ok {
    84  		otherJson, err := json.Marshal(castedSigner)
    85  		if err != nil {
    86  			return false
    87  		}
    88  
    89  		selfJson, err := json.Marshal(txSigner)
    90  		if err != nil {
    91  			return false
    92  		}
    93  
    94  		return string(otherJson) == string(selfJson)
    95  	}
    96  	return false
    97  }
    98  
    99  /**
   100   * TransactionSigner that can sign transactions for the provided MultiSig Account
   101   */
   102  type MultiSigAccountTransactionSigner struct {
   103  	Msig crypto.MultisigAccount
   104  	Sks  [][]byte
   105  }
   106  
   107  func (txSigner MultiSigAccountTransactionSigner) SignTransactions(txGroup []types.Transaction, indexesToSign []int) ([][]byte, error) {
   108  	stxs := make([][]byte, len(indexesToSign))
   109  	for i, pos := range indexesToSign {
   110  		var unmergedStxs [][]byte
   111  		for _, sk := range txSigner.Sks {
   112  			_, unmergedStxBytes, err := crypto.SignMultisigTransaction(sk, txSigner.Msig, txGroup[pos])
   113  			if err != nil {
   114  				return nil, err
   115  			}
   116  
   117  			unmergedStxs = append(unmergedStxs, unmergedStxBytes)
   118  		}
   119  
   120  		if len(txSigner.Sks) > 1 {
   121  			_, stxBytes, err := crypto.MergeMultisigTransactions(unmergedStxs...)
   122  			if err != nil {
   123  				return nil, err
   124  			}
   125  
   126  			stxs[i] = stxBytes
   127  		} else {
   128  			stxs[i] = unmergedStxs[0]
   129  		}
   130  	}
   131  
   132  	return stxs, nil
   133  }
   134  
   135  func (txSigner MultiSigAccountTransactionSigner) Equals(other TransactionSigner) bool {
   136  	if castedSigner, ok := other.(MultiSigAccountTransactionSigner); ok {
   137  		otherJson, err := json.Marshal(castedSigner)
   138  		if err != nil {
   139  			return false
   140  		}
   141  
   142  		selfJson, err := json.Marshal(txSigner)
   143  		if err != nil {
   144  			return false
   145  		}
   146  
   147  		return string(otherJson) == string(selfJson)
   148  	}
   149  	return false
   150  }