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