siwe 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +106 -1
- data/lib/siwe/exceptions.rb +7 -0
- data/lib/siwe/message.rb +9 -4
- data/lib/siwe/version.rb +1 -1
- data/lib/siwe.rb +1 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9ce4aaa56993884786c2eb990729406a1ae4e0cb99d43f5dbcc6b3e0c8e0af67
|
4
|
+
data.tar.gz: 4dbcb76592a3c0bd4eed2e53e3a739fe9461f185772fdb70fa06dfcd43f7adec
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fb5e213eb8d8f50f6cf9a4c00be528bd0a5a9afdc806f95d2714534f629f3ea538bc79655330fc313b01ff85f7ac93550f2447c84baa1f5996eaf6617543630c
|
7
|
+
data.tar.gz: ddf5168c793f6342f9f2e49ac8112dca937832fd7e6a42fb8362250cb6c8798ddb26bf444514064f25fa29ea09ad06d1827cdfc5a1ba696667448d04eb05eee6
|
data/README.md
CHANGED
@@ -1,2 +1,107 @@
|
|
1
1
|
# siwe-ruby
|
2
|
-
A
|
2
|
+
A Ruby implementation of EIP-4361: Sign In With Ethereum.
|
3
|
+
|
4
|
+
## Getting started
|
5
|
+
### Dependencies
|
6
|
+
Additional packages may be required to install the gem:
|
7
|
+
|
8
|
+
### macOS
|
9
|
+
```bash
|
10
|
+
brew install automake openssl libtool pkg-config gmp libffi
|
11
|
+
```
|
12
|
+
|
13
|
+
### Linux
|
14
|
+
```bash
|
15
|
+
sudo apt-get install build-essential automake pkg-config libtool \
|
16
|
+
libffi-dev libssl-dev libgmp-dev python-dev
|
17
|
+
```
|
18
|
+
|
19
|
+
After installing any required dependencies SIWE can be easily installed with:
|
20
|
+
```bash
|
21
|
+
gem install siwe
|
22
|
+
```
|
23
|
+
|
24
|
+
## Usage
|
25
|
+
SIWE provides a Message class which implements EIP-4361.
|
26
|
+
### Creating a SIWE Message
|
27
|
+
|
28
|
+
```ruby
|
29
|
+
require 'siwe'
|
30
|
+
require 'time'
|
31
|
+
|
32
|
+
# Only the mandatory arguments
|
33
|
+
Siwe::Message.new("domain.example", "0x9D85ca56217D2bb651b00f15e694EB7E713637D4", "some.uri", "1")
|
34
|
+
|
35
|
+
# Complete SIWE message with default values
|
36
|
+
Siwe::Message.new("domain.example", "0x9D85ca56217D2bb651b00f15e694EB7E713637D4", "some.uri", "1", {
|
37
|
+
issued_at: Time.now.utc.iso8601,
|
38
|
+
statement: "Example statement for SIWE",
|
39
|
+
nonce: Siwe::Util.generate_nonce,
|
40
|
+
chain_id: "1",
|
41
|
+
expiration_time: "",
|
42
|
+
not_before: "",
|
43
|
+
request_id: "",
|
44
|
+
resources: []
|
45
|
+
})
|
46
|
+
```
|
47
|
+
|
48
|
+
### Parsing a SIWE Message
|
49
|
+
To parse from EIP-4361 use `Siwe::Message.from_message`
|
50
|
+
|
51
|
+
```ruby
|
52
|
+
require 'siwe'
|
53
|
+
|
54
|
+
Siwe::Message.from_message "domain.example wants you to sign in with your Ethereum account:\n0x9D85ca56217D2bb651b00f15e694EB7E713637D4\n\nExample statement for SIWE\n\nURI: some.uri\nVersion: 1\nChain ID: 1\nNonce: k1Ne4KWzBHYEFQo8\nIssued At: 2022-02-03T20:06:19Z"
|
55
|
+
```
|
56
|
+
|
57
|
+
Messages can be parsed to and from JSON strings, using Siwe::Message.from_json_string and Siwe::Message.to_json_string respectively:
|
58
|
+
|
59
|
+
```ruby
|
60
|
+
require 'siwe'
|
61
|
+
|
62
|
+
Siwe::Message.from_json_string "{\"domain\":\"domain.example\",\"address\":\"0x9D85ca56217D2bb651b00f15e694EB7E713637D4\",\"uri\":\"some.uri\",\"version\":\"1\",\"chain_id\":\"1\",\"nonce\":\"k1Ne4KWzBHYEFQo8\",\"issued_at\":\"2022-02-03T20:06:19Z\",\"statement\":\"Example statement for SIWE\",\"expiration_time\":\"\",\"not_before\":\"\",\"request_id\":\"\",\"resources\":[]}"
|
63
|
+
|
64
|
+
Siwe::Message.new("domain.example", "0x9D85ca56217D2bb651b00f15e694EB7E713637D4", "some.uri", "1").to_json_string
|
65
|
+
```
|
66
|
+
|
67
|
+
## Verifying and Authenticating a SIWE Message
|
68
|
+
Verification and authentication is performed via EIP-191, using the address field of the SiweMessage as the expected signer. The validate method checks message structural integrity, signature address validity, and time-based validity attributes.
|
69
|
+
|
70
|
+
```ruby
|
71
|
+
begin
|
72
|
+
message.validate(signature) # returns true if valid throws otherwise
|
73
|
+
rescue Siwe::ExpiredMessage
|
74
|
+
# Used when the message is already expired. (Expires At < Time.now)
|
75
|
+
rescue Siwe::NotValidMessage
|
76
|
+
# Used when the message is not yet valid. (Not Before > Time.now)
|
77
|
+
rescue Siwe::InvalidSignature
|
78
|
+
# Used when the signature doesn't correspond to the address of the message.
|
79
|
+
end
|
80
|
+
```
|
81
|
+
|
82
|
+
## Serialization of a SIWE Message
|
83
|
+
`Siwe::Message` instances can also be serialized as their EIP-4361 string representations via the `Siwe::Message.prepare_message` method:
|
84
|
+
|
85
|
+
```ruby
|
86
|
+
require 'siwe'
|
87
|
+
|
88
|
+
Siwe::Message.new("domain.example", "0x9D85ca56217D2bb651b00f15e694EB7E713637D4", "some.uri", "1").prepare_message
|
89
|
+
```
|
90
|
+
|
91
|
+
## Example
|
92
|
+
Parsing and verifying a `Siwe::Message`:
|
93
|
+
```ruby
|
94
|
+
require 'siwe'
|
95
|
+
|
96
|
+
begin
|
97
|
+
message = Siwe::Message.from_message "https://example.com wants you to sign in with your Ethereum account:\n0xA712a0AFBFA8656581BfA96352c9EdFc519e9cad\n\n\nURI: https://example.com\nVersion: 1\nChain ID: 1\nNonce: 9WrH24z8zpiYOoBQ\nIssued At: 2022-02-04T15:52:03Z"
|
98
|
+
message.validate "aca5e5649a357cee608ecbd1a8455b4143311381636b88a66ec7bcaf64b3a4743ff2c7cc18501a3401e182f79233dc73fc56d01506a6098d5e7e4d881bbb02921c"
|
99
|
+
puts "Congrats, your message is valid"
|
100
|
+
rescue Siwe::ExpiredMessage
|
101
|
+
# Used when the message is already expired. (Expires At < Time.now)
|
102
|
+
rescue Siwe::NotValidMessage
|
103
|
+
# Used when the message is not yet valid. (Not Before > Time.now)
|
104
|
+
rescue Siwe::InvalidSignature
|
105
|
+
# Used when the signature doesn't correspond to the address of the message.
|
106
|
+
end
|
107
|
+
```
|
data/lib/siwe/exceptions.rb
CHANGED
@@ -8,6 +8,13 @@ module Siwe
|
|
8
8
|
end
|
9
9
|
end
|
10
10
|
|
11
|
+
# Used when the address does not conform to EIP-55 or is invalid.
|
12
|
+
class InvalidAddress < StandardError
|
13
|
+
def initialize(msg = "Adress does not conform to EIP-55 or is invalid.")
|
14
|
+
super
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
11
18
|
# Used when the message is not yet valid. (Not Before > Time.now)
|
12
19
|
class NotValidMessage < StandardError
|
13
20
|
def initialize(msg = "Message not yet valid.")
|
data/lib/siwe/message.rb
CHANGED
@@ -76,10 +76,15 @@ module Siwe
|
|
76
76
|
|
77
77
|
def initialize(domain, address, uri, version, options = {})
|
78
78
|
@domain = domain
|
79
|
-
|
79
|
+
begin
|
80
|
+
@address = Eth::Address.new(address).to_s
|
81
|
+
rescue StandardError
|
82
|
+
raise Siwe::InvalidAddress
|
83
|
+
end
|
84
|
+
raise Siwe::InvalidAddress unless @address.eql? address
|
85
|
+
|
80
86
|
@uri = uri
|
81
87
|
@version = version
|
82
|
-
|
83
88
|
@statement = options.fetch :statement, ""
|
84
89
|
@issued_at = options.fetch :issued_at, Time.now.utc.iso8601
|
85
90
|
@nonce = options.fetch :nonce, Siwe::Util.generate_nonce
|
@@ -94,7 +99,7 @@ module Siwe
|
|
94
99
|
if (message = msg.match SIWE_MESSAGE)
|
95
100
|
new(
|
96
101
|
message[:domain],
|
97
|
-
message[:address],
|
102
|
+
Eth::Address.new(message[:address]).to_s,
|
98
103
|
message[:uri],
|
99
104
|
message[:version],
|
100
105
|
{
|
@@ -117,7 +122,7 @@ module Siwe
|
|
117
122
|
def to_json_string
|
118
123
|
obj = {
|
119
124
|
domain: @domain,
|
120
|
-
address: @address,
|
125
|
+
address: Eth::Address.new(@address).to_s,
|
121
126
|
uri: @uri,
|
122
127
|
version: @version,
|
123
128
|
chain_id: @chain_id,
|
data/lib/siwe/version.rb
CHANGED
data/lib/siwe.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: siwe
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Spruce Systems Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-03-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: eth
|