Class: Siwe::Message
- Inherits:
-
Object
- Object
- Siwe::Message
- Defined in:
- lib/siwe/message.rb
Overview
An EIP-4361 Sign-In with Ethereum message. Construct via ‘Siwe::Message.new(**fields)` or parse via `Siwe::Message.parse(string)`. Render via `#prepare_message` (alias `#to_eip4361`, `#to_s`).
Constant Summary collapse
- FIELDS =
%i[ scheme domain address statement uri version chain_id nonce issued_at expiration_time not_before request_id resources ].freeze
Class Method Summary collapse
Instance Method Summary collapse
- #==(other) ⇒ Object (also: #eql?)
- #hash ⇒ Object
-
#initialize(domain:, address:, uri:, chain_id:, nonce: nil, version: "1", scheme: nil, statement: nil, issued_at: nil, expiration_time: nil, not_before: nil, request_id: nil, resources: nil) ⇒ Message
constructor
A new instance of Message.
- #prepare_message ⇒ Object (also: #to_eip4361, #to_s)
- #to_h ⇒ Object
- #to_json ⇒ Object
-
#verify(signature:, domain:, nonce:, scheme: nil, uri: nil, chain_id: nil, request_id: nil, time: nil, config: nil, strict: false) ⇒ Object
Verify a signature against this message and the verification params.
-
#verify! ⇒ Object
Verify a signature; raises Siwe::Error on failure, returns self on success.
Constructor Details
#initialize(domain:, address:, uri:, chain_id:, nonce: nil, version: "1", scheme: nil, statement: nil, issued_at: nil, expiration_time: nil, not_before: nil, request_id: nil, resources: nil) ⇒ Message
Returns a new instance of Message.
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/siwe/message.rb', line 38 def initialize(domain:, address:, uri:, chain_id:, nonce: nil, version: "1", scheme: nil, statement: nil, issued_at: nil, expiration_time: nil, not_before: nil, request_id: nil, resources: nil) @warnings = [] @scheme = scheme @domain = domain @address = normalize_address(address) @statement = statement @uri = uri @version = version @chain_id = coerce_chain_id(chain_id) @nonce = nonce || Util.generate_nonce @issued_at = issued_at || Time.now.utc.iso8601 @expiration_time = expiration_time @not_before = not_before @request_id = request_id @resources = resources validate_required! roundtrip_validate! freeze end |
Class Method Details
.from_json(json_str) ⇒ Object
31 32 33 34 35 36 |
# File 'lib/siwe/message.rb', line 31 def self.from_json(json_str) data = JSON.parse(json_str, symbolize_names: true) new(**data.slice(*FIELDS)) rescue JSON::ParserError => e raise Error.new(ErrorType::UNABLE_TO_PARSE, message: "Invalid JSON: #{e.}") end |
Instance Method Details
#==(other) ⇒ Object Also known as: eql?
121 122 123 |
# File 'lib/siwe/message.rb', line 121 def ==(other) other.is_a?(Message) && to_h == other.to_h end |
#hash ⇒ Object
126 127 128 |
# File 'lib/siwe/message.rb', line 126 def hash to_h.hash end |
#prepare_message ⇒ Object Also known as: to_eip4361, to_s
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/siwe/message.rb', line 61 def header_prefix = @scheme ? "#{@scheme}://#{@domain}" : @domain header = "#{header_prefix} wants you to sign in with your Ethereum account:" prefix = "#{header}\n#{@address}" prefix = if @statement.nil? "#{prefix}\n\n" else "#{prefix}\n\n#{@statement}\n" end suffix = "URI: #{@uri}\nVersion: #{@version}\nChain ID: #{@chain_id}" suffix << "\nNonce: #{@nonce}" suffix << "\nIssued At: #{@issued_at}" if @issued_at suffix << "\nExpiration Time: #{@expiration_time}" if @expiration_time suffix << "\nNot Before: #{@not_before}" if @not_before suffix << "\nRequest ID: #{@request_id}" unless @request_id.nil? if @resources suffix << "\nResources:" @resources.each { |r| suffix << "\n- #{r}" } end "#{prefix}\n#{suffix}" end |
#to_h ⇒ Object
113 114 115 |
# File 'lib/siwe/message.rb', line 113 def to_h FIELDS.to_h { |f| [f, instance_variable_get("@#{f}")] } end |
#to_json ⇒ Object
117 118 119 |
# File 'lib/siwe/message.rb', line 117 def to_json(*) to_h.to_json(*) end |
#verify(signature:, domain:, nonce:, scheme: nil, uri: nil, chain_id: nil, request_id: nil, time: nil, config: nil, strict: false) ⇒ Object
Verify a signature against this message and the verification params. Returns Siwe::Response — never raises on verification failure.
91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/siwe/message.rb', line 91 def verify(signature:, domain:, nonce:, scheme: nil, uri: nil, chain_id: nil, request_id: nil, time: nil, config: nil, strict: false) cfg = config || Siwe.config check_param_mismatches!(domain: domain, nonce: nonce, scheme: scheme, uri: uri, chain_id: chain_id, request_id: request_id, strict: strict) check_temporal!(time) check_signature!(signature, cfg) Response.new(success: true, error: nil, data: self) rescue Error => e Response.new(success: false, error: e, data: self) end |
#verify! ⇒ Object
Verify a signature; raises Siwe::Error on failure, returns self on success.
106 107 108 109 110 111 |
# File 'lib/siwe/message.rb', line 106 def verify!(**) response = verify(**) raise response.error if response.failure? self end |