/siwe-go

A Go implementation of EIP-4361 Sign In With Ethereum verification

Primary LanguageGoMIT LicenseMIT

Sign-In with Ethereum

This go module provides a pure Go implementation of EIP-4361: Sign In With Ethereum.

Installation

go get github.com/jiulongw/siwe-go

Usage

SIWE exposes a Message struct which implements EIP-4361.

Parsing a SIWE Message

Parsing is done via the MessageFromString function:

msg, err := MessageFromString(text_representation)

Parsing from JSON

Message object can be parsed from JSON format defined by official siwe package.

type RequestBody struct {
    Message   siwe.Message `json:"message"`
    Signature string       `json:"signature"`
}

var r *http.Request  // incoming request

var body RequestBody
err := json.NewDecoder(r.Body).Decode(&body)

Verifying and Authenticating a SIWE Message

Verification and Authentication is performed via EIP-191. VerifySignature function of Message will recover signature to Ethereum public key and compare it with Address field of Message. If either public key recovery failed, or the recovered public key does not match Address, error is returned.

err := msg.VerifySignature(sig)
if err != nil {
  // signature validation failed.
}

The time constraints (expiry and not-before) can also be validated, at current or particular times:

if msg.Valid() { ... }
if msg.ValidAt(time.Now()) { ... }

Combined verification of time constraints and authentication can be done in a single call with verify:

err := msg.Verify(sig)
if err != nil {
  // signature validation failed or time constraints are not satisfied.
}

Serialization of a SIWE Message

Message instances can also be serialized as their EIP-4361 string representations via the String function.

fmt.Println(msg.String());

As well as in EIP-191 Personal-Signature pre-hash signing input form.

fmt.Println(msg.EIP191String())

And directly as the EIP-191 Personal-Signature Hashed signing-input.

hash := msg.EIP191Hash()

Example

Parsing and verifying a Message is easy:

var str string  // string representation of message
var sig []byte  // message signature to verify

msg, err := MessageFromString(str)
if err != nil {
    panic(err)
}

if err := msg.Verify(sig); err != nil {
    panic(err)
}

// do application-specific things

Disclaimer

Our Go library for Sign-In with Ethereum has not yet undergone a formal security audit. We welcome continued feedback on the usability, architecture, and security of this implementation.

See Also