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 }