Documentation
¶
Overview ¶
Package siwe implements Sign in with Ethereum (EIP-4361).
This is a Go port of the canonical TypeScript library (@signinwithethereum/siwe). It supports message parsing, construction, EIP-191 signature verification, and (opt-in) EIP-1271 contract-wallet verification through an external signer interface.
Index ¶
- Constants
- func GenerateNonce() string
- func IsEIP6492Signature(sigHex string) bool
- type ContractSignatureVerifier
- type Error
- type ErrorType
- type EthCaller
- type EthCallerVerifier
- type Message
- func (m *Message) ClearResources()
- func (m *Message) EIP191Hash() common.Hash
- func (m *Message) GetAddress() common.Address
- func (m *Message) GetChainID() int
- func (m *Message) GetDomain() string
- func (m *Message) GetExpirationTime() *string
- func (m *Message) GetIssuedAt() string
- func (m *Message) GetNonce() string
- func (m *Message) GetNotBefore() *string
- func (m *Message) GetRequestID() *string
- func (m *Message) GetResources() []string
- func (m *Message) GetScheme() *string
- func (m *Message) GetStatement() *string
- func (m *Message) GetURI() string
- func (m *Message) GetVersion() string
- func (m *Message) PrepareMessage() string
- func (m *Message) SetResources(r []string)
- func (m *Message) String() string
- func (m *Message) ValidAt(when time.Time) (bool, error)
- func (m *Message) ValidNow() (bool, error)
- func (m *Message) Validate() error
- func (m *Message) VerifyEIP191(signature string) (*ecdsa.PublicKey, error)
- func (m *Message) VerifyWith(ctx context.Context, signature string, params VerifyParams, opts VerifyOptions) (*VerifyResult, error)
- type VerifyOptions
- type VerifyParams
- type VerifyResult
Constants ¶
const Version = "1.0.0"
Version is the semantic version of this package.
Variables ¶
This section is empty.
Functions ¶
func GenerateNonce ¶
func GenerateNonce() string
GenerateNonce returns a cryptographically random 17-character alphanumeric nonce suitable for the EIP-4361 `nonce` field.
func IsEIP6492Signature ¶
IsEIP6492Signature reports whether the hex-encoded signature carries the EIP-6492 magic suffix (0x6492...6492).
Types ¶
type ContractSignatureVerifier ¶
type ContractSignatureVerifier interface {
// VerifyContractSignature reports whether `sig` is a valid signature of
// `hash` (the EIP-191 prehash) for `address` on `chainID`. Implementations
// should return (false, err) for transport errors distinct from a simple
// "not valid" result.
VerifyContractSignature(ctx context.Context, address common.Address, hash common.Hash, sig []byte, chainID int) (bool, error)
}
ContractSignatureVerifier is the pluggable backend for smart-contract wallet signature verification (EIP-1271 and EIP-6492). The Go library does not ship a built-in RPC client because choice of client (ethclient, web3go, gnosis-safe-sdk, etc.) is environment-specific; implementations typically wrap go-ethereum's ethclient.
type Error ¶
Error is a structured SIWE error. It carries a type code plus optional expected/received context so callers can match against specific failures without parsing free-form messages.
type ErrorType ¶
type ErrorType string
ErrorType is a structured error type for SIWE validation and verification.
const ( ErrExpiredMessage ErrorType = "Expired message." ErrInvalidDomain ErrorType = "Invalid domain." ErrSchemeMismatch ErrorType = "Scheme does not match provided scheme for verification." ErrDomainMismatch ErrorType = "Domain does not match provided domain for verification." ErrNonceMismatch ErrorType = "Nonce does not match provided nonce for verification." ErrURIMismatch ErrorType = "URI does not match provided URI for verification." ErrChainIDMismatch ErrorType = "Chain ID does not match provided chain ID for verification." ErrRequestIDMismatch ErrorType = "Request ID does not match provided request ID for verification." ErrInvalidAddress ErrorType = "Invalid address." ErrInvalidURI ErrorType = "URI does not conform to RFC 3986." ErrInvalidNonce ErrorType = "Nonce size smaller then 8 characters or is not alphanumeric." ErrNotYetValidMessage ErrorType = "Message is not valid yet." ErrInvalidSignature ErrorType = "Signature does not match address of the message." ErrInvalidSignatureChain ErrorType = "Contract wallet verification provider chain does not match message chain ID." ErrInvalidTimeFormat ErrorType = "Invalid time format." ErrInvalidMessageVersion ErrorType = "Invalid message version." ErrUnableToParseMessage ErrorType = "Unable to parse the message." ErrMissingDomain ErrorType = "Domain is required for verification." ErrMissingNonce ErrorType = "Nonce is required for verification." ErrMissingURI ErrorType = "URI is required for verification." ErrMissingChainID ErrorType = "Chain ID is required for verification." ErrInvalidParams ErrorType = "Invalid parameters passed to verify." ErrMalformedMessage ErrorType = "Message could not be prepared for signing." ErrInvalidStatement ErrorType = "Statement contains invalid characters." ErrInvalidRequestID ErrorType = "Request ID contains invalid characters." )
Error type codes. These match the identifiers used by the canonical TypeScript implementation (@signinwithethereum/siwe).
type EthCaller ¶
type EthCaller interface {
CallContract(ctx context.Context, call ethereum.CallMsg, blockNumber *big.Int) ([]byte, error)
ChainID(ctx context.Context) (*big.Int, error)
}
EthCaller is the minimal interface needed to perform read-only EVM calls. It is satisfied by *ethclient.Client and by any custom backend the user wishes to wire up (e.g. rpc.Client with eth_call).
type EthCallerVerifier ¶
type EthCallerVerifier struct {
Caller EthCaller
}
EthCallerVerifier implements ContractSignatureVerifier against any EthCaller. It performs a strict chain-id check (to avoid accepting EIP-1271 signatures from the wrong network) followed by an EIP-1271 isValidSignature call. When the signature carries the EIP-6492 magic suffix, the universal off-chain validator bytecode is executed via eth_call so that counterfactual (not yet deployed) smart accounts verify correctly.
func NewEthCallerVerifier ¶
func NewEthCallerVerifier(caller EthCaller) *EthCallerVerifier
NewEthCallerVerifier constructs a verifier against an ethclient-style caller.
type Message ¶
type Message struct {
// Scheme is the optional RFC 3986 URI scheme preceding the authority
// (added by https://eips.ethereum.org/EIPS/eip-4361 revision 2023). When
// nil the preamble is rendered as "<domain> wants you to sign in..."; when
// set it is rendered as "<scheme>://<domain> wants you to sign in...".
Scheme *string
// Domain is the RFC 3986 authority requesting the signing.
Domain string
// Address is the Ethereum address performing the signing.
Address common.Address
// AddressRaw carries the 40-character (no 0x prefix) hex exactly as it
// appeared in the parsed source when the input was not EIP-55 checksummed
// (all-lower or all-upper). When non-nil, String() emits this verbatim so
// the EIP-191 pre-hash matches what the signer actually signed. Leave nil
// when building a message programmatically; the canonical EIP-55 form is
// used.
AddressRaw *string
// Statement is the optional human-readable assertion. A nil value means
// "no statement"; an empty non-nil value means "empty statement present"
// (spec allows this). Line breaks are forbidden.
Statement *string
// URI is an RFC 3986 URI.
URI string
// Version must be "1".
Version string
// ChainID is the EIP-155 chain the session is bound to.
ChainID int
// Nonce is a randomized token, at least 8 alphanumeric characters.
Nonce string
// IssuedAt is an ISO 8601 / RFC 3339 datetime string.
IssuedAt string
// ExpirationTime, if set, is the point after which the message becomes invalid.
ExpirationTime *string
// NotBefore, if set, is the point before which the message is not yet valid.
NotBefore *string
// RequestID is an optional system-specific identifier. Empty string is
// allowed per the ABNF (`request-id = *pchar`); nil means absent.
RequestID *string
// Resources is an optional list of RFC 3986 URI references. A nil slice
// means the "Resources:" section is absent; a non-nil empty slice means
// the section is present with no items.
Resources []string
// Warnings collects non-fatal validation messages surfaced during parsing
// or construction (e.g. an address that is not EIP-55 checksummed).
Warnings []string
// contains filtered or unexported fields
}
Message represents a parsed or constructed EIP-4361 "Sign in with Ethereum" message. Fields follow the spec terminology; the zero value of a pointer field means the corresponding field is absent from the message.
func InitMessage ¶
func InitMessage(domain, address, uri, nonce string, options map[string]interface{}) (*Message, error)
InitMessage is retained for backward compatibility; prefer NewMessage.
func NewMessage ¶
func NewMessage(domain, address, uri, nonce string, options map[string]interface{}) (*Message, error)
NewMessage constructs a Message from explicit fields, applying the same validation as ParseMessage. Optional fields are passed via the options map with the same keys as the TS/Python APIs (`statement`, `chainId`, `issuedAt`, `expirationTime`, `notBefore`, `requestId`, `resources`, `scheme`). Values may be typed (int, string, *string, []string, time.Time) or passed through from JSON decoding (float64 for numbers).
func ParseMessage ¶
ParseMessage parses an EIP-4361 formatted message into a Message.
The parser is line-based and follows the ABNF grammar in `test-vectors/../ts/packages/siwe-parser/lib/siwe-abnf.txt`. It preserves the original address hex case when constructing an AddressRaw, so that roundtripping (parse -> String) produces byte-identical output for signatures to remain valid.
func (*Message) ClearResources ¶
func (m *Message) ClearResources()
ClearResources removes the Resources section entirely (same as nil).
func (*Message) EIP191Hash ¶
EIP191Hash returns the EIP-191 personal-message hash of the prepared message.
func (*Message) GetAddress ¶
func (*Message) GetChainID ¶
func (*Message) GetExpirationTime ¶
func (*Message) GetIssuedAt ¶
func (*Message) GetNotBefore ¶
func (*Message) GetRequestID ¶
func (*Message) GetResources ¶
GetResources returns the resources (nil if the section is absent).
func (*Message) GetStatement ¶
func (*Message) GetURI ¶
GetURI returns the URI field. For backward compatibility this returns a net/url.URL parse; callers that need the exact string should read URI.
func (*Message) GetVersion ¶
func (*Message) PrepareMessage ¶
PrepareMessage is an alias for String kept for parity with the canonical TypeScript/Python/Rust APIs.
func (*Message) SetResources ¶
SetResources assigns Resources explicitly and marks the field as present. This is the only way to produce an all-empty `Resources:\n` section from programmatic construction (since a nil slice is treated as absent).
func (*Message) Validate ¶
Validate checks all field-level invariants on the Message. It is invoked automatically by ParseMessage/InitMessage/NewMessage; call it directly if you mutate fields after construction and want to re-verify.
func (*Message) VerifyEIP191 ¶
VerifyEIP191 verifies a 65-byte EOA signature (hex encoded, with or without 0x prefix) against the message. Returns the recovered ECDSA public key on success.
func (*Message) VerifyWith ¶
func (m *Message) VerifyWith(ctx context.Context, signature string, params VerifyParams, opts VerifyOptions) (*VerifyResult, error)
VerifyWith runs full verification (binding checks + signature) using the supplied params and options. The signature is a hex string (with or without 0x prefix).
The high-level API fails closed: Domain, Nonce, URI, and ChainID bindings are mandatory and must match the message exactly. If a relying party does not yet know what to expect for a field, it cannot safely call this method. For signature-only checks without binding enforcement, use VerifyEIP191 (EOA) or a ContractSignatureVerifier directly.
type VerifyOptions ¶
type VerifyOptions struct {
// ContractVerifier, if non-nil, is consulted for EIP-1271 / EIP-6492
// contract-wallet signatures when the ECDSA recovery path does not match.
ContractVerifier ContractSignatureVerifier
}
VerifyOptions configures verification.
type VerifyParams ¶
type VerifyParams struct {
// Scheme binding. If non-nil, the message's scheme must match exactly.
Scheme *string
// Domain binding. Required.
Domain *string
// Nonce binding. Required.
Nonce *string
// URI binding. Required.
URI *string
// ChainID binding. Required.
ChainID *int
// RequestID binding. Optional.
RequestID *string
// Timestamp for time-window checks. Nil uses the current time.
Time *time.Time
}
VerifyParams carries the binding checks performed during VerifyWith.
Per ERC-4361 § Verifying a signed Message, the message MUST be checked against expected values after parsing. This library treats Domain, Nonce, URI, and ChainID as required: callers must supply what they expect and the message's fields must match exactly. Scheme and RequestID remain optional.
type VerifyResult ¶
VerifyResult is returned by Verify. ECDSAPublicKey is populated on a successful EOA recovery; ContractVerified is true when EIP-1271/6492 verification succeeded.