nostr 0.4.0 → 0.5.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/.editorconfig +1 -1
- data/.rubocop.yml +23 -0
- data/.tool-versions +2 -1
- data/CHANGELOG.md +36 -1
- data/README.md +92 -228
- data/docs/.gitignore +4 -0
- data/docs/.vitepress/config.mjs +112 -0
- data/docs/README.md +44 -0
- data/docs/api-examples.md +49 -0
- data/docs/bun.lockb +0 -0
- data/docs/common-use-cases/bech32-encoding-and-decoding-(NIP-19).md +190 -0
- data/docs/core/client.md +108 -0
- data/docs/core/keys.md +136 -0
- data/docs/core/user.md +43 -0
- data/docs/events/contact-list.md +29 -0
- data/docs/events/encrypted-direct-message.md +28 -0
- data/docs/events/recommend-server.md +32 -0
- data/docs/events/set-metadata.md +20 -0
- data/docs/events/text-note.md +15 -0
- data/docs/events.md +11 -0
- data/docs/getting-started/installation.md +21 -0
- data/docs/getting-started/overview.md +170 -0
- data/docs/implemented-nips.md +9 -0
- data/docs/index.md +44 -0
- data/docs/markdown-examples.md +85 -0
- data/docs/package.json +12 -0
- data/docs/relays/connecting-to-a-relay.md +21 -0
- data/docs/relays/publishing-events.md +29 -0
- data/docs/relays/receiving-events.md +6 -0
- data/docs/subscriptions/creating-a-subscription.md +49 -0
- data/docs/subscriptions/deleting-a-subscription.md +10 -0
- data/docs/subscriptions/filtering-subscription-events.md +115 -0
- data/docs/subscriptions/updating-a-subscription.md +4 -0
- data/lib/nostr/bech32.rb +203 -0
- data/lib/nostr/client.rb +2 -1
- data/lib/nostr/crypto.rb +11 -7
- data/lib/nostr/errors/error.rb +7 -0
- data/lib/nostr/errors/invalid_hrp_error.rb +21 -0
- data/lib/nostr/errors/invalid_key_format_error.rb +20 -0
- data/lib/nostr/errors/invalid_key_length_error.rb +20 -0
- data/lib/nostr/errors/invalid_key_type_error.rb +18 -0
- data/lib/nostr/errors/key_validation_error.rb +6 -0
- data/lib/nostr/errors.rb +8 -0
- data/lib/nostr/event.rb +3 -4
- data/lib/nostr/events/encrypted_direct_message.rb +4 -3
- data/lib/nostr/filter.rb +4 -4
- data/lib/nostr/key.rb +100 -0
- data/lib/nostr/key_pair.rb +30 -6
- data/lib/nostr/keygen.rb +43 -4
- data/lib/nostr/private_key.rb +36 -0
- data/lib/nostr/public_key.rb +36 -0
- data/lib/nostr/relay_message_type.rb +18 -0
- data/lib/nostr/subscription.rb +2 -2
- data/lib/nostr/user.rb +17 -8
- data/lib/nostr/version.rb +1 -1
- data/lib/nostr.rb +6 -0
- data/nostr.gemspec +9 -9
- data/sig/nostr/bech32.rbs +14 -0
- data/sig/nostr/client.rbs +5 -5
- data/sig/nostr/crypto.rbs +5 -5
- data/sig/nostr/errors/error.rbs +4 -0
- data/sig/nostr/errors/invalid_hrb_error.rbs +6 -0
- data/sig/nostr/errors/invalid_key_format_error.rbs +5 -0
- data/sig/nostr/errors/invalid_key_length_error.rbs +5 -0
- data/sig/nostr/errors/invalid_key_type_error.rbs +5 -0
- data/sig/nostr/errors/key_validation_error.rbs +4 -0
- data/sig/nostr/event.rbs +4 -4
- data/sig/nostr/events/encrypted_direct_message.rbs +2 -2
- data/sig/nostr/filter.rbs +3 -12
- data/sig/nostr/key.rbs +16 -0
- data/sig/nostr/key_pair.rbs +7 -3
- data/sig/nostr/keygen.rbs +5 -2
- data/sig/nostr/private_key.rbs +4 -0
- data/sig/nostr/public_key.rbs +4 -0
- data/sig/nostr/relay_message_type.rbs +8 -0
- data/sig/nostr/user.rbs +4 -8
- data/sig/vendor/bech32/nostr/entity.rbs +41 -0
- data/sig/vendor/bech32/nostr/nip19.rbs +20 -0
- data/sig/vendor/bech32/segwit_addr.rbs +21 -0
- data/sig/vendor/bech32.rbs +25 -0
- data/sig/vendor/event_emitter.rbs +10 -3
- data/sig/vendor/event_machine/channel.rbs +1 -1
- data/sig/vendor/faye/websocket/api.rbs +45 -0
- data/sig/vendor/faye/websocket/client.rbs +43 -0
- data/sig/vendor/faye/websocket.rbs +30 -0
- metadata +79 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 168cbde3fb029345d4fa10043eead7c194a57fe3ee23c12b76bbaf79b1bdc71d
|
4
|
+
data.tar.gz: ff1a1837e897a8c0ad233a61ed4526fe3e4087c04474e54778a00a0d4313e361
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e5549507ded84026a2295c3914324e8c74aff3c1ae80322db3cd449e7f65c3475186e9daaa76f7a22241e33b6759c2073da5a31a910a2082c8e49a99081dc5bf
|
7
|
+
data.tar.gz: 19f69ed10ae3ba42113992541912bb18a4aa3ad8239b582b996e7c7845c4624c4a9ee73d800f51fbd883d2bdd9ea603eeb807ade147bcfc22db7183c1db30ce6
|
data/.editorconfig
CHANGED
data/.rubocop.yml
CHANGED
@@ -9,8 +9,17 @@ AllCops:
|
|
9
9
|
DisplayCopNames: true
|
10
10
|
NewCops: enable
|
11
11
|
|
12
|
+
# ----------------------- Gemspec -----------------------
|
13
|
+
|
14
|
+
Gemspec/DevelopmentDependencies:
|
15
|
+
Enabled: false
|
16
|
+
|
12
17
|
# ----------------------- Style -----------------------
|
13
18
|
|
19
|
+
Style/RaiseArgs:
|
20
|
+
Exclude:
|
21
|
+
- 'lib/nostr/key.rb'
|
22
|
+
|
14
23
|
Style/StringLiterals:
|
15
24
|
Enabled: true
|
16
25
|
EnforcedStyle: single_quotes
|
@@ -38,3 +47,17 @@ Metrics/ParameterLists:
|
|
38
47
|
|
39
48
|
RSpec/ExampleLength:
|
40
49
|
Enabled: false
|
50
|
+
|
51
|
+
RSpec/FilePath:
|
52
|
+
Exclude:
|
53
|
+
- spec/nostr/errors/invalid_*
|
54
|
+
|
55
|
+
RSpec/SpecFilePathFormat:
|
56
|
+
Exclude:
|
57
|
+
- spec/nostr/errors/invalid_*
|
58
|
+
|
59
|
+
# ----------------------- Naming -----------------------
|
60
|
+
|
61
|
+
Naming/MemoizedInstanceVariableName:
|
62
|
+
Exclude:
|
63
|
+
- 'spec/nostr/key.rb'
|
data/.tool-versions
CHANGED
@@ -1 +1,2 @@
|
|
1
|
-
ruby 3.2.
|
1
|
+
ruby 3.2.2
|
2
|
+
bun 1.0.11
|
data/CHANGELOG.md
CHANGED
@@ -1,9 +1,42 @@
|
|
1
1
|
# Changelog
|
2
2
|
All notable changes to this project will be documented in this file.
|
3
3
|
|
4
|
-
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.
|
4
|
+
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.1.1/)
|
5
5
|
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
6
6
|
|
7
|
+
## [0.5.0] 2023-11-20
|
8
|
+
|
9
|
+
### Added
|
10
|
+
|
11
|
+
- Added relay message type enums `Nostr::RelayMessageType`
|
12
|
+
- Compliance with [NIP-19](https://github.com/nostr-protocol/nips/blob/master/19.md) - bech32-formatted strings
|
13
|
+
- `Nostr::PrivateKey` and `Nostr::PublicKey` to represent private and public keys, respectively
|
14
|
+
- Added a validation of private and public keys
|
15
|
+
- Added an ability to convert keys to and from Bech32 format
|
16
|
+
- Added RBS types for `faye-websocket` and `bech32`
|
17
|
+
|
18
|
+
### Changed
|
19
|
+
|
20
|
+
- Set the gem's homepage to [`https://nostr-ruby.com/`](https://nostr-ruby.com/)
|
21
|
+
- Updated the filter's documentation to reflect the removal of prefix matching
|
22
|
+
- Updated the subscription's id documentation to reflect the changes in the protocol definition
|
23
|
+
- Updated `Nostr::PrivateKey` and `Nostr::PublicKey` internally, instead of Strings
|
24
|
+
- Updated the gem `bip-schnorr` to version `0.6` (was `0.4`)
|
25
|
+
- Updated the gem `puma` to version `6.4` (was `6.3`)
|
26
|
+
- Updated the gem `rake` to version `13.1` (was `13.0`)
|
27
|
+
- Updated the gem `rbs` to version `3.3` (was `2.8`)
|
28
|
+
- Updated the gem `rubocop` to version `1.57` (was `1.42`)
|
29
|
+
- Updated the gem `rubocop-rspec` to version `2.25` (was `2.16`)
|
30
|
+
- Updated the gem `steep` to version `1.6` (was `1.4`)
|
31
|
+
|
32
|
+
## Fixed
|
33
|
+
|
34
|
+
- Fixed the RBS type of the constant `Nostr::Crypto::BN_BASE`
|
35
|
+
- Fixed the return type of `Nostr::Crypto#decrypt_text` when given an invalid ciphertext
|
36
|
+
- Fixed the RBS type of `Nostr::Filter#to_h`, `Nostr::Filter#e` and `Nostr::Filter#p`
|
37
|
+
- Fixed the RBS types of `EventEmitter` and `EventMachine::Channel`
|
38
|
+
- Fixed the generation of private keys
|
39
|
+
|
7
40
|
## [0.4.0] - 2023-02-25
|
8
41
|
|
9
42
|
### Removed
|
@@ -49,6 +82,8 @@ principles of immutability and was a major source of internal complexity as I ne
|
|
49
82
|
|
50
83
|
- Initial release
|
51
84
|
|
85
|
+
[0.5.0]: https://github.com/wilsonsilva/nostr/compare/v0.4.0...v0.5.0
|
86
|
+
[0.4.0]: https://github.com/wilsonsilva/nostr/compare/v0.3.0...v0.4.0
|
52
87
|
[0.3.0]: https://github.com/wilsonsilva/nostr/compare/v0.2.0...v0.3.0
|
53
88
|
[0.2.0]: https://github.com/wilsonsilva/nostr/compare/v0.1.0...v0.2.0
|
54
89
|
[0.1.0]: https://github.com/wilsonsilva/nostr/compare/7fded5...v0.1.0
|
data/README.md
CHANGED
@@ -4,31 +4,30 @@
|
|
4
4
|
[](https://codeclimate.com/github/wilsonsilva/nostr/maintainability)
|
5
5
|
[](https://codeclimate.com/github/wilsonsilva/nostr/test_coverage)
|
6
6
|
|
7
|
-
Asynchronous Nostr client
|
8
|
-
has not yet reached a stable release. Use with caution.
|
7
|
+
Asynchronous Nostr client for Rubyists.
|
9
8
|
|
10
9
|
## Table of contents
|
11
10
|
|
12
|
-
- [
|
13
|
-
- [
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
* [WebSocket events](#websocket-events)
|
19
|
-
* [Requesting for events / creating a subscription](#requesting-for-events--creating-a-subscription)
|
20
|
-
* [Stop previous subscriptions](#stop-previous-subscriptions)
|
21
|
-
* [Publishing an event](#publishing-an-event)
|
22
|
-
* [Creating/updating your contact list](#creatingupdating-your-contact-list)
|
23
|
-
* [Sending an encrypted direct message](#sending-an-encrypted-direct-message)
|
24
|
-
- [Implemented NIPs](#implemented-nips)
|
25
|
-
- [Development](#development)
|
11
|
+
- [Key features](#-key-features)
|
12
|
+
- [Installation](#-installation)
|
13
|
+
- [Quickstart](#-quickstart)
|
14
|
+
- [Documentation](#-documentation)
|
15
|
+
- [Implemented NIPs](#-implemented-nips)
|
16
|
+
- [Development](#-development)
|
26
17
|
* [Type checking](#type-checking)
|
27
|
-
- [Contributing](
|
28
|
-
- [License](
|
29
|
-
- [Code of Conduct](
|
18
|
+
- [Contributing](#-contributing)
|
19
|
+
- [License](#-license)
|
20
|
+
- [Code of Conduct](#-code-of-conduct)
|
30
21
|
|
31
|
-
##
|
22
|
+
## 🔑 Key features
|
23
|
+
|
24
|
+
- Asynchronous
|
25
|
+
- Easy to use
|
26
|
+
- Fully documented
|
27
|
+
- Fully tested
|
28
|
+
- Fully typed
|
29
|
+
|
30
|
+
## 📦 Installation
|
32
31
|
|
33
32
|
Install the gem and add to the application's Gemfile by executing:
|
34
33
|
|
@@ -38,243 +37,103 @@ If bundler is not being used to manage dependencies, install the gem by executin
|
|
38
37
|
|
39
38
|
$ gem install nostr
|
40
39
|
|
41
|
-
##
|
40
|
+
## ⚡️ Quickstart
|
42
41
|
|
43
|
-
|
44
|
-
|
45
|
-
All examples below assume that the gem has been required.
|
42
|
+
Here is a quick example of how to use the gem. For more detailed documentation, please check the
|
43
|
+
[documentation website](https://nostr-ruby.com).
|
46
44
|
|
47
45
|
```ruby
|
46
|
+
# Require the gem
|
48
47
|
require 'nostr'
|
49
|
-
```
|
50
|
-
|
51
|
-
### Generating a keypair
|
52
|
-
|
53
|
-
```ruby
|
54
|
-
keygen = Nostr::Keygen.new
|
55
|
-
keypair = keygen.generate_key_pair
|
56
48
|
|
57
|
-
|
58
|
-
|
59
|
-
```
|
60
|
-
|
61
|
-
### Generating a private key and a public key
|
62
|
-
|
63
|
-
```ruby
|
64
|
-
keygen = Nostr::Keygen.new
|
49
|
+
# Instantiate a client
|
50
|
+
client = Nostr::Client.new
|
65
51
|
|
66
|
-
|
67
|
-
|
68
|
-
|
52
|
+
# a) Use an existing keypair
|
53
|
+
keypair = Nostr::KeyPair.new(
|
54
|
+
private_key: Nostr::PrivateKey.new('add-your-hex-private-key-here'),
|
55
|
+
public_key: Nostr::PublicKey.new('add-your-hex-public-key-here'),
|
56
|
+
)
|
69
57
|
|
70
|
-
|
58
|
+
# b) Or build a keypair from a private key
|
59
|
+
keygen = Nostr::Keygen.new
|
60
|
+
keypair = keygen.get_key_pair_from_private_key(
|
61
|
+
Nostr::PrivateKey.new('add-your-hex-private-key-here')
|
62
|
+
)
|
71
63
|
|
72
|
-
|
64
|
+
# c) Or create a new keypair
|
65
|
+
keygen = Nostr::Keygen.new
|
66
|
+
keypair = keygen.generate_keypair
|
73
67
|
|
74
|
-
|
68
|
+
# Create a user with the keypair
|
69
|
+
user = Nostr::User.new(keypair: keypair)
|
75
70
|
|
76
|
-
|
77
|
-
|
78
|
-
|
71
|
+
# Create a signed event
|
72
|
+
text_note_event = user.create_event(
|
73
|
+
kind: Nostr::EventKind::TEXT_NOTE,
|
74
|
+
content: 'Your feedback is appreciated, now pay $8'
|
75
|
+
)
|
79
76
|
|
77
|
+
# Connect asynchronously to a relay
|
78
|
+
relay = Nostr::Relay.new(url: 'wss://nostr.wine', name: 'Wine')
|
80
79
|
client.connect(relay)
|
81
|
-
```
|
82
|
-
|
83
|
-
### WebSocket events
|
84
|
-
|
85
|
-
All communication between clients and relays happen in WebSockets.
|
86
80
|
|
87
|
-
|
88
|
-
|
89
|
-
```ruby
|
81
|
+
# Listen asynchronously for the connect event
|
90
82
|
client.on :connect do
|
91
|
-
#
|
92
|
-
|
93
|
-
```
|
94
|
-
|
95
|
-
The `:close` event is fired when a connection with a WebSocket has been closed because of an error.
|
96
|
-
|
97
|
-
```ruby
|
98
|
-
client.on :error do |error_message|
|
99
|
-
puts error_message
|
100
|
-
end
|
101
|
-
|
102
|
-
# > Network error: wss://rsslay.fiatjaf.com: Unable to verify the server certificate for 'rsslay.fiatjaf.com'
|
103
|
-
```
|
104
|
-
|
105
|
-
The `:message` event is fired when data is received through a WebSocket.
|
106
|
-
|
107
|
-
```ruby
|
108
|
-
client.on :message do |message|
|
109
|
-
puts message
|
110
|
-
end
|
111
|
-
|
112
|
-
# [
|
113
|
-
# "EVENT",
|
114
|
-
# "d34107357089bfc9882146d3bfab0386",
|
115
|
-
# {
|
116
|
-
# "content":"",
|
117
|
-
# "created_at":1676456512,
|
118
|
-
# "id":"18f63550da74454c5df7caa2a349edc5b2a6175ea4c5367fa4b4212781e5b310",
|
119
|
-
# "kind":3,
|
120
|
-
# "pubkey":"117a121fa41dc2caa0b3d6c5b9f42f90d114f1301d39f9ee96b646ebfee75e36",
|
121
|
-
# "sig":"d171420bd62cf981e8f86f2dd8f8f86737ea2bbe2d98da88db092991d125535860d982139a3c4be39886188613a9912ef380be017686a0a8b74231dc6e0b03cb",
|
122
|
-
# "tags":[
|
123
|
-
# ["p","1cc821cc2d47191b15fcfc0f73afed39a86ac6fb34fbfa7993ee3e0f0186ef7c"]
|
124
|
-
# ]
|
125
|
-
# }
|
126
|
-
# ]
|
127
|
-
```
|
128
|
-
|
129
|
-
The `:close` event is fired when a connection with a WebSocket is closed.
|
130
|
-
|
131
|
-
```ruby
|
132
|
-
client.on :close do |code, reason|
|
133
|
-
# you may attempt to reconnect
|
134
|
-
|
135
|
-
client.connect(relay)
|
136
|
-
end
|
137
|
-
```
|
138
|
-
|
139
|
-
### Requesting for events / creating a subscription
|
140
|
-
|
141
|
-
A client can request events and subscribe to new updates after it has established a connection with the Relay.
|
142
|
-
|
143
|
-
You may use a `Nostr::Filter` instance with as many attributes as you wish:
|
83
|
+
# Send the event to the Relay
|
84
|
+
client.publish(text_note_event)
|
144
85
|
|
145
|
-
|
146
|
-
|
86
|
+
# Create a filter to receive the first 20 text notes
|
87
|
+
# and encrypted direct messages from the relay that
|
88
|
+
# were created in the previous hour
|
147
89
|
filter = Nostr::Filter.new(
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
limit: 420,
|
90
|
+
kinds: [
|
91
|
+
Nostr::EventKind::TEXT_NOTE,
|
92
|
+
Nostr::EventKind::ENCRYPTED_DIRECT_MESSAGE
|
93
|
+
],
|
94
|
+
since: Time.now.to_i - 3600, # 1 hour ago
|
95
|
+
until: Time.now.to_i,
|
96
|
+
limit: 20,
|
156
97
|
)
|
157
98
|
|
158
|
-
|
159
|
-
|
160
|
-
```
|
161
|
-
|
162
|
-
With just a few:
|
99
|
+
# Subscribe to events matching conditions of a filter
|
100
|
+
subscription = client.subscribe(filter: filter)
|
163
101
|
|
164
|
-
|
165
|
-
client.
|
166
|
-
filter = Nostr::Filter.new(kinds: [Nostr::EventKind::TEXT_NOTE])
|
167
|
-
subscription = client.subscribe('a_random_subscription_id', filter)
|
102
|
+
# Unsubscribe from events matching the filter above
|
103
|
+
client.unsubscribe(subscription.id)
|
168
104
|
end
|
169
|
-
```
|
170
|
-
|
171
|
-
Or omit the filter:
|
172
105
|
|
173
|
-
|
174
|
-
client.on :
|
175
|
-
|
106
|
+
# Listen for incoming messages and print them
|
107
|
+
client.on :message do |message|
|
108
|
+
puts message
|
176
109
|
end
|
177
|
-
```
|
178
110
|
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
client.on :connect do
|
183
|
-
subscription = client.subscribe('a_random_subscription_id')
|
111
|
+
# Listen for error messages
|
112
|
+
client.on :error do |error_message|
|
113
|
+
# Handle the error
|
184
114
|
end
|
185
|
-
```
|
186
|
-
|
187
|
-
### Stop previous subscriptions
|
188
|
-
|
189
|
-
You can stop receiving messages from a subscription by calling `#unsubscribe`:
|
190
|
-
|
191
|
-
```ruby
|
192
|
-
client.unsubscribe('your_subscription_id')
|
193
|
-
```
|
194
|
-
|
195
|
-
### Publishing an event
|
196
115
|
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
private_key = 'a630b06e2f883378d0aa335b9adaf7734603e00433350b684fe53e184f08c58f'
|
202
|
-
user = Nostr::User.new(private_key)
|
203
|
-
|
204
|
-
# Create a signed event
|
205
|
-
event = user.create_event(
|
206
|
-
created_at: 1667422587, # optional, defaults to the current time
|
207
|
-
kind: Nostr::EventKind::TEXT_NOTE,
|
208
|
-
tags: [], # optional, defaults to []
|
209
|
-
content: 'Your feedback is appreciated, now pay $8'
|
210
|
-
)
|
211
|
-
|
212
|
-
# Send it to the Relay
|
213
|
-
client.publish(event)
|
214
|
-
```
|
215
|
-
|
216
|
-
### Creating/updating your contact list
|
217
|
-
|
218
|
-
Every new contact list that gets published overwrites the past ones, so it should contain all entries.
|
219
|
-
|
220
|
-
```ruby
|
221
|
-
# Creating a contact list event with 2 contacts
|
222
|
-
update_contacts_event = user.create_event(
|
223
|
-
kind: Nostr::EventKind::CONTACT_LIST,
|
224
|
-
tags: [
|
225
|
-
[
|
226
|
-
"p", # mandatory
|
227
|
-
"32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245", # public key of the user to add to the contacts
|
228
|
-
"wss://alicerelay.com/", # can be an empty string or can be omitted
|
229
|
-
"alice" # can be an empty string or can be omitted
|
230
|
-
],
|
231
|
-
[
|
232
|
-
"p", # mandatory
|
233
|
-
"3efdaebb1d8923ebd99c9e7ace3b4194ab45512e2be79c1b7d68d9243e0d2681", # public key of the user to add to the contacts
|
234
|
-
"wss://bobrelay.com/nostr", # can be an empty string or can be omitted
|
235
|
-
"bob" # can be an empty string or can be omitted
|
236
|
-
],
|
237
|
-
],
|
238
|
-
)
|
239
|
-
|
240
|
-
# Send it to the Relay
|
241
|
-
client.publish(update_contacts_event)
|
116
|
+
# Listen for the close event
|
117
|
+
client.on :close do |code, reason|
|
118
|
+
# You may attempt to reconnect to the relay here
|
119
|
+
end
|
242
120
|
```
|
243
121
|
|
244
|
-
|
122
|
+
## 📚 Documentation
|
245
123
|
|
246
|
-
|
247
|
-
sender_private_key = '3185a47e3802f956ca5a2b4ea606c1d51c7610f239617e8f0f218d55bdf2b757'
|
124
|
+
I made a detailed documentation for this gem and it's usage. The code is also fully documented using YARD.
|
248
125
|
|
249
|
-
|
250
|
-
|
251
|
-
recipient_public_key: '6c31422248998e300a1a457167565da7d15d0da96651296ee2791c29c11b6aa0',
|
252
|
-
plain_text: 'Your feedback is appreciated, now pay $8',
|
253
|
-
previous_direct_message: 'ccf9fdf3e1466d7c20969c71ec98defcf5f54aee088513e1b73ccb7bd770d460' # optional
|
254
|
-
)
|
255
|
-
|
256
|
-
encrypted_direct_message.sign(sender_private_key)
|
257
|
-
|
258
|
-
# #<Nostr::Events::EncryptedDirectMessage:0x0000000104c9fa68
|
259
|
-
# @content="mjIFNo1sSP3KROE6QqhWnPSGAZRCuK7Np9X+88HSVSwwtFyiZ35msmEVoFgRpKx4?iv=YckChfS2oWCGpMt1uQ4GbQ==",
|
260
|
-
# @created_at=1676456512,
|
261
|
-
# @id="daac98826d5eb29f7c013b6160986c4baf4fe6d4b995df67c1b480fab1839a9b",
|
262
|
-
# @kind=4,
|
263
|
-
# @pubkey="8a9d69c56e3c691bec8f9565e4dcbe38ae1d88fffeec3ce66b9f47558a3aa8ca",
|
264
|
-
# @sig="028bb5f5bab0396e2065000c84a4bcce99e68b1a79bb1b91a84311546f49c5b67570b48d4a328a1827e7a8419d74451347d4f55011a196e71edab31aa3d6bdac",
|
265
|
-
# @tags=[["p", "6c31422248998e300a1a457167565da7d15d0da96651296ee2791c29c11b6aa0"], ["e", "ccf9fdf3e1466d7c20969c71ec98defcf5f54aee088513e1b73ccb7bd770d460"]]>
|
126
|
+
- [Guide documentation](https://nostr-ruby.com)
|
127
|
+
- [YARD documentation](https://rubydoc.info/gems/nostr)
|
266
128
|
|
267
|
-
|
268
|
-
client.publish(encrypted_direct_message)
|
269
|
-
````
|
129
|
+
## ✅ Implemented NIPs
|
270
130
|
|
271
|
-
|
131
|
+
- [x] [NIP-01 - Basic protocol flow description](https://github.com/nostr-protocol/nips/blob/master/01.md)
|
132
|
+
- [x] [NIP-02 - Contact List and Petnames](https://github.com/nostr-protocol/nips/blob/master/02.md)
|
133
|
+
- [x] [NIP-04 - Encrypted Direct Message](https://github.com/nostr-protocol/nips/blob/master/04.md)
|
134
|
+
- [x] [NIP-19 - Bech32-encoded entities](https://github.com/nostr-protocol/nips/blob/master/19.md)
|
272
135
|
|
273
|
-
|
274
|
-
- [x] [NIP-02 - Client](https://github.com/nostr-protocol/nips/blob/master/02.md)
|
275
|
-
- [x] [NIP-04 - Client](https://github.com/nostr-protocol/nips/blob/master/04.md)
|
276
|
-
|
277
|
-
## Development
|
136
|
+
## 🔨 Development
|
278
137
|
|
279
138
|
After checking out the repo, run `bin/setup` to install dependencies.
|
280
139
|
|
@@ -318,17 +177,22 @@ used to provide type checking and autocompletion in your editor. Run `bundle exe
|
|
318
177
|
an RBS definition for the given Ruby file. And validate all definitions using [Steep](https://github.com/soutaro/steep)
|
319
178
|
with the command `bundle exec steep check`.
|
320
179
|
|
321
|
-
##
|
180
|
+
## 🐞 Issues & Bugs
|
181
|
+
|
182
|
+
If you find any issues or bugs, please report them [here](https://github.com/wilsonsilva/nostr/issues), I will be happy
|
183
|
+
to have a look at them and fix them as soon as possible.
|
184
|
+
|
185
|
+
## 🤝 Contributing
|
322
186
|
|
323
187
|
Bug reports and pull requests are welcome on GitHub at https://github.com/wilsonsilva/nostr.
|
324
188
|
This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere
|
325
189
|
to the [code of conduct](https://github.com/wilsonsilva/nostr/blob/main/CODE_OF_CONDUCT.md).
|
326
190
|
|
327
|
-
## License
|
191
|
+
## 📜 License
|
328
192
|
|
329
193
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
330
194
|
|
331
|
-
## Code of Conduct
|
195
|
+
## 👔 Code of Conduct
|
332
196
|
|
333
197
|
Everyone interacting in the Nostr project's codebases, issue trackers, chat rooms and mailing lists is expected
|
334
198
|
to follow the [code of conduct](https://github.com/wilsonsilva/nostr/blob/main/CODE_OF_CONDUCT.md).
|
data/docs/.gitignore
ADDED
@@ -0,0 +1,112 @@
|
|
1
|
+
import { defineConfig } from 'vitepress'
|
2
|
+
import { withMermaid } from "vitepress-plugin-mermaid";
|
3
|
+
|
4
|
+
// https://vitepress.dev/reference/site-config
|
5
|
+
// https://www.npmjs.com/package/vitepress-plugin-mermaid
|
6
|
+
export default defineConfig(withMermaid({
|
7
|
+
title: "Nostr",
|
8
|
+
description: "Documentation of the Nostr Ruby gem",
|
9
|
+
// https://vitepress.dev/reference/site-config#head
|
10
|
+
head: [
|
11
|
+
['link', { rel: 'icon', href: '/favicon.ico' }]
|
12
|
+
],
|
13
|
+
themeConfig: {
|
14
|
+
// https://vitepress.dev/reference/default-theme-last-updated
|
15
|
+
lastUpdated: true,
|
16
|
+
|
17
|
+
// https://vitepress.dev/reference/default-theme-config
|
18
|
+
nav: [
|
19
|
+
{ text: 'Home', link: '/' },
|
20
|
+
{ text: 'Guide', link: '/getting-started/overview' }
|
21
|
+
],
|
22
|
+
|
23
|
+
// https://vitepress.dev/reference/default-theme-search
|
24
|
+
search: {
|
25
|
+
provider: 'local'
|
26
|
+
},
|
27
|
+
|
28
|
+
// https://vitepress.dev/reference/default-theme-sidebar
|
29
|
+
sidebar: [
|
30
|
+
{
|
31
|
+
text: 'Getting started',
|
32
|
+
collapsed: false,
|
33
|
+
items: [
|
34
|
+
{ text: 'Overview', link: '/getting-started/overview' },
|
35
|
+
{ text: 'Installation', link: '/getting-started/installation' },
|
36
|
+
]
|
37
|
+
},
|
38
|
+
{
|
39
|
+
text: 'Core',
|
40
|
+
collapsed: false,
|
41
|
+
items: [
|
42
|
+
{ text: 'Client', link: '/core/client' },
|
43
|
+
{ text: 'Keys', link: '/core/keys' },
|
44
|
+
{ text: 'User', link: '/core/user' },
|
45
|
+
]
|
46
|
+
},
|
47
|
+
{
|
48
|
+
text: 'Relays',
|
49
|
+
items: [
|
50
|
+
{ text: 'Connecting to a relay', link: '/relays/connecting-to-a-relay' },
|
51
|
+
{ text: 'Publishing events', link: '/relays/publishing-events' },
|
52
|
+
{ text: 'Receiving events', link: '/relays/receiving-events' },
|
53
|
+
]
|
54
|
+
},
|
55
|
+
{
|
56
|
+
text: 'Subscriptions',
|
57
|
+
collapsed: false,
|
58
|
+
items: [
|
59
|
+
{ text: 'Creating a subscription', link: '/subscriptions/creating-a-subscription' },
|
60
|
+
{ text: 'Filtering subscription events', link: '/subscriptions/filtering-subscription-events' },
|
61
|
+
{ text: 'Updating a subscription', link: '/subscriptions/updating-a-subscription' },
|
62
|
+
{ text: 'Deleting a subscription', link: '/subscriptions/deleting-a-subscription' },
|
63
|
+
]
|
64
|
+
},
|
65
|
+
{
|
66
|
+
text: 'Events',
|
67
|
+
link: '/events',
|
68
|
+
collapsed: false,
|
69
|
+
items: [
|
70
|
+
{ text: 'Set Metadata', link: '/events/set-metadata' },
|
71
|
+
{ text: 'Text Note', link: '/events/text-note' },
|
72
|
+
{ text: 'Recommend Server', link: '/events/recommend-server' },
|
73
|
+
{ text: 'Contact List', link: '/events/contact-list' },
|
74
|
+
{ text: 'Encrypted Direct Message', link: '/events/encrypted-direct-message' },
|
75
|
+
]
|
76
|
+
},
|
77
|
+
{
|
78
|
+
text: 'Common use cases',
|
79
|
+
collapsed: false,
|
80
|
+
items: [
|
81
|
+
{ text: 'Bech32 enc/decoding (NIP-19)', link: '/common-use-cases/bech32-encoding-and-decoding-(NIP-19)' },
|
82
|
+
]
|
83
|
+
},
|
84
|
+
{
|
85
|
+
text: 'Implemented NIPs',
|
86
|
+
link: '/implemented-nips',
|
87
|
+
},
|
88
|
+
],
|
89
|
+
|
90
|
+
// https://vitepress.dev/reference/default-theme-config#sociallinks
|
91
|
+
socialLinks: [
|
92
|
+
{ icon: 'github', link: 'https://github.com/wilsonsilva/nostr' }
|
93
|
+
],
|
94
|
+
|
95
|
+
// https://vitepress.dev/reference/default-theme-edit-link
|
96
|
+
editLink: {
|
97
|
+
pattern: 'https://github.com/wilsonsilva/nostr/edit/main/docs/:path',
|
98
|
+
text: 'Edit this page on GitHub'
|
99
|
+
},
|
100
|
+
|
101
|
+
// https://vitepress.dev/reference/default-theme-footer
|
102
|
+
footer: {
|
103
|
+
message: 'Released under the <a href="https://github.com/wilsonsilva/nostr/blob/main/LICENSE.txt">MIT License</a>.',
|
104
|
+
copyright: 'Copyright © 2023-present <a href="https://github.com/wilsonsilva">Wilson Silva</a>'
|
105
|
+
}
|
106
|
+
},
|
107
|
+
|
108
|
+
// https://vitepress.dev/reference/site-config#ignoredeadlinks
|
109
|
+
ignoreDeadLinks: [
|
110
|
+
/^https?:\/\/localhost/
|
111
|
+
],
|
112
|
+
}))
|
data/docs/README.md
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
# Nostr Docs
|
2
|
+
|
3
|
+
VitePress-powered documentation for the Nostr Ruby gem.
|
4
|
+
|
5
|
+
## Live Demo
|
6
|
+
|
7
|
+
https://nostr-ruby.com/
|
8
|
+
|
9
|
+
## Development
|
10
|
+
|
11
|
+
### Requirements
|
12
|
+
|
13
|
+
- [Bun](https://bun.sh/)
|
14
|
+
|
15
|
+
### Installation
|
16
|
+
|
17
|
+
```shell
|
18
|
+
bun install
|
19
|
+
```
|
20
|
+
|
21
|
+
### Tasks
|
22
|
+
|
23
|
+
The `docs:dev` script will start a local dev server with instant hot updates. Run it with the following command:
|
24
|
+
|
25
|
+
```shell
|
26
|
+
bun run docs:dev
|
27
|
+
```
|
28
|
+
|
29
|
+
Run this command to build the docs:
|
30
|
+
|
31
|
+
```shell
|
32
|
+
bun run docs:build
|
33
|
+
```
|
34
|
+
|
35
|
+
Once built, preview it locally by running:
|
36
|
+
|
37
|
+
```shell
|
38
|
+
bun run docs:preview
|
39
|
+
```
|
40
|
+
|
41
|
+
The preview command will boot up a local static web server that will serve the output directory .`vitepress/dist` at
|
42
|
+
http://localhost:4173. You can use this to make sure everything looks good before pushing to production.
|
43
|
+
|
44
|
+
|