github.com/status-im/status-go@v1.1.0/api/utils.go (about) 1 package api 2 3 import ( 4 "bytes" 5 "encoding/hex" 6 "strconv" 7 "strings" 8 9 "github.com/status-im/status-go/eth-node/crypto" 10 ) 11 12 // RunAsync runs the specified function asynchronously. 13 func RunAsync(f func() error) <-chan error { 14 resp := make(chan error, 1) 15 go func() { 16 err := f() 17 resp <- err 18 close(resp) 19 }() 20 return resp 21 } 22 23 // HashMessage calculates the hash of a message to be safely signed by the keycard 24 // The hash is calulcated as 25 // 26 // keccak256("\x19Ethereum Signed Message:\n"${message length}${message}). 27 // 28 // This gives context to the signed message and prevents signing of transactions. 29 func HashMessage(message string) ([]byte, error) { 30 buf := bytes.NewBufferString("\x19Ethereum Signed Message:\n") 31 if value, ok := decodeHexStrict(message); ok { 32 if _, err := buf.WriteString(strconv.Itoa(len(value))); err != nil { 33 return nil, err 34 } 35 if _, err := buf.Write(value); err != nil { 36 return nil, err 37 } 38 } else { 39 if _, err := buf.WriteString(strconv.Itoa(len(message))); err != nil { 40 return nil, err 41 } 42 if _, err := buf.WriteString(message); err != nil { 43 return nil, err 44 } 45 } 46 47 return crypto.Keccak256(buf.Bytes()), nil 48 } 49 50 func decodeHexStrict(s string) ([]byte, bool) { 51 if !strings.HasPrefix(s, "0x") { 52 return nil, false 53 } 54 55 value, err := hex.DecodeString(s[2:]) 56 if err != nil { 57 return nil, false 58 } 59 60 return value, true 61 }