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  }