forked from status-im/status-go
-
Notifications
You must be signed in to change notification settings - Fork 0
/
utils.go
152 lines (128 loc) · 4.04 KB
/
utils.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
151
152
package common
import (
"context"
"encoding/json"
"errors"
"fmt"
"io"
"io/ioutil"
"os"
"path/filepath"
"reflect"
"runtime/debug"
"time"
"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/common"
"github.com/pborman/uuid"
"github.com/status-im/status-go/geth/log"
"github.com/status-im/status-go/static"
)
const (
// MessageIDKey is a key for message ID
// This ID is required to track from which chat a given send transaction request is coming.
MessageIDKey = contextKey("message_id")
)
type contextKey string // in order to make sure that our context key does not collide with keys from other packages
// errors
var (
ErrInvalidAccountAddressOrKey = errors.New("cannot parse address or key to valid account address")
)
// ParseAccountString parses hex encoded string and returns is as accounts.Account.
func ParseAccountString(account string) (accounts.Account, error) {
// valid address, convert to account
if common.IsHexAddress(account) {
return accounts.Account{Address: common.HexToAddress(account)}, nil
}
return accounts.Account{}, ErrInvalidAccountAddressOrKey
}
// FromAddress converts account address from string to common.Address.
// The function is useful to format "From" field of send transaction struct.
func FromAddress(accountAddress string) common.Address {
from, err := ParseAccountString(accountAddress)
if err != nil {
return common.Address{}
}
return from.Address
}
// ToAddress converts account address from string to *common.Address.
// The function is useful to format "To" field of send transaction struct.
func ToAddress(accountAddress string) *common.Address {
to, err := ParseAccountString(accountAddress)
if err != nil {
return nil
}
return &to.Address
}
// ImportTestAccount imports keystore from static resources, see "static/keys" folder
func ImportTestAccount(keystoreDir, accountFile string) error {
// make sure that keystore folder exists
if _, err := os.Stat(keystoreDir); os.IsNotExist(err) {
os.MkdirAll(keystoreDir, os.ModePerm) // nolint: errcheck, gas
}
dst := filepath.Join(keystoreDir, accountFile)
err := ioutil.WriteFile(dst, static.MustAsset("keys/"+accountFile), 0644)
if err != nil {
log.Warn("cannot copy test account PK", "error", err)
}
return err
}
// PanicAfter throws panic() after waitSeconds, unless abort channel receives notification
func PanicAfter(waitSeconds time.Duration, abort chan struct{}, desc string) {
go func() {
select {
case <-abort:
return
case <-time.After(waitSeconds):
panic("whatever you were doing takes toooo long: " + desc)
}
}()
}
// MessageIDFromContext returns message id from context (if exists)
func MessageIDFromContext(ctx context.Context) string {
if ctx == nil {
return ""
}
if messageID, ok := ctx.Value(MessageIDKey).(string); ok {
return messageID
}
return ""
}
// ParseJSONArray parses JSON array into Go array of string
func ParseJSONArray(items string) ([]string, error) {
var parsedItems []string
err := json.Unmarshal([]byte(items), &parsedItems)
if err != nil {
return nil, err
}
return parsedItems, nil
}
// Fatalf is used to halt the execution.
// When called the function prints stack end exits.
// Failure is logged into both StdErr and StdOut.
func Fatalf(reason interface{}, args ...interface{}) {
// decide on output stream
w := io.MultiWriter(os.Stdout, os.Stderr)
outf, _ := os.Stdout.Stat() // nolint: gas
errf, _ := os.Stderr.Stat() // nolint: gas
if outf != nil && errf != nil && os.SameFile(outf, errf) {
w = os.Stderr
}
// find out whether error or string has been passed as a reason
r := reflect.ValueOf(reason)
if r.Kind() == reflect.String {
fmt.Fprintf(w, "Fatal Failure: %v\n%v\n", reason.(string), args)
} else {
fmt.Fprintf(w, "Fatal Failure: %v\n", reason.(error))
}
debug.PrintStack()
os.Exit(1)
}
// CreateTransaction returns a transaction object.
func CreateTransaction(ctx context.Context, args SendTxArgs) *QueuedTx {
return &QueuedTx{
ID: QueuedTxID(uuid.New()),
Context: ctx,
Args: args,
Result: make(chan TransactionResult, 1),
}
}