lighstorm 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ruby-rspec-tests.yml +39 -0
- data/Gemfile.lock +1 -1
- data/README.md +5 -5
- data/adapters/connections/channel_node/policy.rb +61 -0
- data/adapters/connections/channel_node.rb +40 -18
- data/adapters/edges/channel.rb +23 -7
- data/adapters/edges/forward.rb +1 -2
- data/adapters/edges/payment/purpose.rb +0 -2
- data/adapters/edges/payment.rb +2 -5
- data/adapters/invoice.rb +2 -3
- data/adapters/nodes/node.rb +39 -5
- data/adapters/payment_request.rb +0 -1
- data/controllers/channel/actions/apply_gossip.rb +194 -0
- data/controllers/channel/find_by_id.rb +1 -1
- data/controllers/channel/mine.rb +1 -1
- data/controllers/channel.rb +4 -0
- data/controllers/node/actions/apply_gossip.rb +112 -0
- data/controllers/node.rb +4 -0
- data/controllers/payment/all.rb +52 -36
- data/controllers/payment.rb +6 -6
- data/docs/README.md +89 -13
- data/docs/_coverpage.md +1 -1
- data/docs/index.html +1 -1
- data/models/concerns/protectable.rb +23 -0
- data/models/connections/channel_node/accounting.rb +4 -0
- data/models/connections/channel_node/fee.rb +27 -18
- data/models/connections/channel_node/htlc/blocks/delta.rb +39 -0
- data/models/connections/channel_node/htlc.rb +48 -14
- data/models/connections/channel_node/policy.rb +11 -2
- data/models/connections/channel_node.rb +33 -1
- data/models/edges/channel/accounting.rb +17 -0
- data/models/edges/channel.rb +39 -5
- data/models/edges/forward.rb +0 -1
- data/models/edges/payment.rb +0 -1
- data/models/errors.rb +3 -0
- data/models/nodes/node/lightning.rb +6 -0
- data/models/nodes/node/platform.rb +6 -0
- data/models/nodes/node.rb +51 -0
- data/models/payment_request.rb +6 -3
- data/ports/grpc/session.rb +26 -0
- data/ports/grpc.rb +23 -5
- data/static/spec.rb +1 -1
- metadata +9 -2
@@ -73,7 +73,7 @@ module Lighstorm
|
|
73
73
|
def self.transform(data, adapted)
|
74
74
|
[0, 1].each do |i|
|
75
75
|
adapted[:list_channels].each_index do |c|
|
76
|
-
if adapted[:list_channels][c][:partners][i][:node]
|
76
|
+
if adapted[:list_channels][c][:partners][i][:node].nil?
|
77
77
|
adapted[:list_channels][c][:partners][i][:node] = adapted[:get_info]
|
78
78
|
end
|
79
79
|
end
|
data/controllers/channel/mine.rb
CHANGED
@@ -63,7 +63,7 @@ module Lighstorm
|
|
63
63
|
|
64
64
|
def self.transform(data, adapted)
|
65
65
|
[0, 1].each do |i|
|
66
|
-
data[:partners][i][:node] = adapted[:get_info] if data[:partners][i][:node]
|
66
|
+
data[:partners][i][:node] = adapted[:get_info] if data[:partners][i][:node].nil?
|
67
67
|
|
68
68
|
adapted[:get_chan_info][data[:id].to_i][:partners].each do |partner|
|
69
69
|
if data[:partners][i][:node][:public_key] == partner[:node][:public_key]
|
data/controllers/channel.rb
CHANGED
@@ -0,0 +1,112 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'securerandom'
|
4
|
+
|
5
|
+
require_relative '../../../ports/grpc'
|
6
|
+
require_relative '../../../models/errors'
|
7
|
+
require_relative '../../../models/nodes/node'
|
8
|
+
require_relative '../../../adapters/nodes/node'
|
9
|
+
|
10
|
+
module Lighstorm
|
11
|
+
module Controllers
|
12
|
+
module Node
|
13
|
+
module ApplyGossip
|
14
|
+
SKIPABLE = %w[
|
15
|
+
_source
|
16
|
+
_key
|
17
|
+
].freeze
|
18
|
+
|
19
|
+
NOT_ALLOWED = [
|
20
|
+
'public_key'
|
21
|
+
].freeze
|
22
|
+
|
23
|
+
APPLICABLE = %w[
|
24
|
+
alias
|
25
|
+
color
|
26
|
+
].freeze
|
27
|
+
|
28
|
+
def self.perform(actual, gossip)
|
29
|
+
updated = Models::Node.new(Adapter::Node.subscribe_channel_graph(gossip))
|
30
|
+
|
31
|
+
actual_dump = actual.dump
|
32
|
+
updated_dump = updated.dump
|
33
|
+
|
34
|
+
diff = generate_diff(actual_dump, updated_dump)
|
35
|
+
|
36
|
+
diff.each do |change|
|
37
|
+
key = change[:path].join('/')
|
38
|
+
next unless NOT_ALLOWED.include?(key)
|
39
|
+
|
40
|
+
raise IncoherentGossipError, "Gossip doesn't belong to this Node"
|
41
|
+
end
|
42
|
+
|
43
|
+
diff.filter do |change|
|
44
|
+
key = change[:path].join('/')
|
45
|
+
if SKIPABLE.include?(key)
|
46
|
+
false
|
47
|
+
elsif APPLICABLE.include?(key)
|
48
|
+
apply!(actual, key, change)
|
49
|
+
true
|
50
|
+
else
|
51
|
+
raise Lighstorm::Errors::MissingGossipHandlerError, "don't know how to apply '#{key}'"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.apply!(actual, key, change)
|
57
|
+
case key
|
58
|
+
when 'alias'
|
59
|
+
token = SecureRandom.hex
|
60
|
+
actual.prepare_token!(token)
|
61
|
+
actual.alias = {
|
62
|
+
value: change[:to],
|
63
|
+
token: token
|
64
|
+
}
|
65
|
+
when 'color'
|
66
|
+
token = SecureRandom.hex
|
67
|
+
actual.prepare_token!(token)
|
68
|
+
actual.color = {
|
69
|
+
value: change[:to],
|
70
|
+
token: token
|
71
|
+
}
|
72
|
+
else
|
73
|
+
raise Lighstorm::Errors::MissingGossipHandlerError, "don't know how to apply '#{key}'"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def self.generate_diff(actual, node, path = [], diff = [])
|
78
|
+
case node
|
79
|
+
when Hash
|
80
|
+
result = {}
|
81
|
+
node.each_key do |key|
|
82
|
+
result[key] = generate_diff(actual, node[key], path.dup.push(key), diff)
|
83
|
+
end
|
84
|
+
when Array
|
85
|
+
result = []
|
86
|
+
node.each_with_index do |value, i|
|
87
|
+
result << generate_diff(actual, value, path.dup.push(i), diff)
|
88
|
+
end
|
89
|
+
else
|
90
|
+
new_value = node
|
91
|
+
|
92
|
+
unless new_value.nil?
|
93
|
+
actual_value = actual
|
94
|
+
path.each do |key|
|
95
|
+
if actual_value[key]
|
96
|
+
actual_value = actual_value[key]
|
97
|
+
else
|
98
|
+
actual_value = nil
|
99
|
+
break
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
diff << { path: path, from: actual_value, to: new_value } if actual_value != new_value
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
diff
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
data/controllers/node.rb
CHANGED
data/controllers/payment/all.rb
CHANGED
@@ -12,16 +12,19 @@ module Lighstorm
|
|
12
12
|
module Controllers
|
13
13
|
module Payment
|
14
14
|
module All
|
15
|
-
def self.fetch(purpose: nil, limit: nil)
|
15
|
+
def self.fetch(purpose: nil, limit: nil, fetch: {})
|
16
16
|
at = Time.now
|
17
|
-
|
17
|
+
|
18
|
+
grpc = Ports::GRPC.session
|
19
|
+
|
20
|
+
get_info = grpc.lightning.get_info.to_h
|
18
21
|
|
19
22
|
last_offset = 0
|
20
23
|
|
21
24
|
payments = []
|
22
25
|
|
23
26
|
loop do
|
24
|
-
response =
|
27
|
+
response = grpc.lightning.list_payments(
|
25
28
|
index_offset: last_offset
|
26
29
|
)
|
27
30
|
|
@@ -64,8 +67,8 @@ module Lighstorm
|
|
64
67
|
|
65
68
|
data = {
|
66
69
|
at: at,
|
67
|
-
get_info:
|
68
|
-
fee_report:
|
70
|
+
get_info: get_info,
|
71
|
+
fee_report: grpc.lightning.fee_report.to_h,
|
69
72
|
list_payments: payments,
|
70
73
|
list_channels: {},
|
71
74
|
get_chan_info: {},
|
@@ -75,15 +78,15 @@ module Lighstorm
|
|
75
78
|
}
|
76
79
|
|
77
80
|
payments.each do |payment|
|
78
|
-
unless payment[:payment_request] == '' || data[:decode_pay_req][payment[:payment_request]]
|
79
|
-
data[:decode_pay_req][payment[:payment_request]] =
|
81
|
+
unless fetch[:decode_pay_req] == false || payment[:payment_request] == '' || data[:decode_pay_req][payment[:payment_request]]
|
82
|
+
data[:decode_pay_req][payment[:payment_request]] = grpc.lightning.decode_pay_req(
|
80
83
|
pay_req: payment[:payment_request]
|
81
84
|
).to_h
|
82
85
|
end
|
83
86
|
|
84
|
-
unless data[:lookup_invoice][payment[:payment_hash]]
|
87
|
+
unless fetch[:lookup_invoice] == false || data[:lookup_invoice][payment[:payment_hash]]
|
85
88
|
begin
|
86
|
-
data[:lookup_invoice][payment[:payment_hash]] =
|
89
|
+
data[:lookup_invoice][payment[:payment_hash]] = grpc.lightning.lookup_invoice(
|
87
90
|
r_hash_str: payment[:payment_hash]
|
88
91
|
).to_h
|
89
92
|
rescue StandardError => e
|
@@ -93,9 +96,9 @@ module Lighstorm
|
|
93
96
|
|
94
97
|
payment[:htlcs].each do |htlc|
|
95
98
|
htlc[:route][:hops].each do |hop|
|
96
|
-
unless data[:get_chan_info][hop[:chan_id]]
|
99
|
+
unless fetch[:get_chan_info] == false || data[:get_chan_info][hop[:chan_id]]
|
97
100
|
begin
|
98
|
-
data[:get_chan_info][hop[:chan_id]] =
|
101
|
+
data[:get_chan_info][hop[:chan_id]] = grpc.lightning.get_chan_info(
|
99
102
|
chan_id: hop[:chan_id]
|
100
103
|
).to_h
|
101
104
|
rescue GRPC::Unknown => e
|
@@ -103,23 +106,25 @@ module Lighstorm
|
|
103
106
|
end
|
104
107
|
end
|
105
108
|
|
106
|
-
next if data[:get_node_info][hop[:pub_key]]
|
109
|
+
next if fetch[:get_node_info] == false || data[:get_node_info][hop[:pub_key]]
|
107
110
|
|
108
|
-
data[:get_node_info][hop[:pub_key]] =
|
111
|
+
data[:get_node_info][hop[:pub_key]] = grpc.lightning.get_node_info(
|
109
112
|
pub_key: hop[:pub_key]
|
110
113
|
).to_h
|
111
114
|
end
|
112
115
|
end
|
113
116
|
end
|
114
117
|
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
118
|
+
if fetch[:lookup_invoice] != false
|
119
|
+
data[:lookup_invoice].each_value do |invoice|
|
120
|
+
if fetch[:decode_pay_req] == false || invoice[:_error] || invoice[:payment_request] == '' || data[:decode_pay_req][invoice[:payment_request]]
|
121
|
+
next
|
122
|
+
end
|
119
123
|
|
120
|
-
|
121
|
-
|
122
|
-
|
124
|
+
data[:decode_pay_req][invoice[:payment_request]] = grpc.lightning.decode_pay_req(
|
125
|
+
pay_req: invoice[:payment_request]
|
126
|
+
).to_h
|
127
|
+
end
|
123
128
|
end
|
124
129
|
|
125
130
|
list_channels_done = {}
|
@@ -135,7 +140,7 @@ module Lighstorm
|
|
135
140
|
partner = partners.find { |p| p != data[:get_info][:identity_pubkey] }
|
136
141
|
|
137
142
|
unless list_channels_done[partner]
|
138
|
-
|
143
|
+
grpc.lightning.list_channels(
|
139
144
|
peer: [partner].pack('H*')
|
140
145
|
).channels.map(&:to_h).each do |list_channels|
|
141
146
|
data[:list_channels][list_channels[:chan_id]] = list_channels
|
@@ -145,27 +150,29 @@ module Lighstorm
|
|
145
150
|
end
|
146
151
|
end
|
147
152
|
|
148
|
-
unless data[:get_node_info][channel[:node1_pub]]
|
149
|
-
data[:get_node_info][channel[:node1_pub]] =
|
153
|
+
unless fetch[:get_node_info] == false || data[:get_node_info][channel[:node1_pub]]
|
154
|
+
data[:get_node_info][channel[:node1_pub]] = grpc.lightning.get_node_info(
|
150
155
|
pub_key: channel[:node1_pub]
|
151
156
|
).to_h
|
152
157
|
end
|
153
158
|
|
154
|
-
next if data[:get_node_info][channel[:node2_pub]]
|
159
|
+
next if fetch[:get_node_info] == false || data[:get_node_info][channel[:node2_pub]]
|
155
160
|
|
156
|
-
data[:get_node_info][channel[:node2_pub]] =
|
161
|
+
data[:get_node_info][channel[:node2_pub]] = grpc.lightning.get_node_info(
|
157
162
|
pub_key: channel[:node2_pub]
|
158
163
|
).to_h
|
159
164
|
end
|
160
165
|
|
161
166
|
data[:list_channels].each_value do |channel|
|
162
|
-
next if data[:get_node_info][channel[:remote_pubkey]]
|
167
|
+
next if fetch[:get_node_info] == false || data[:get_node_info][channel[:remote_pubkey]]
|
163
168
|
|
164
|
-
data[:get_node_info][channel[:remote_pubkey]] =
|
169
|
+
data[:get_node_info][channel[:remote_pubkey]] = grpc.lightning.get_node_info(
|
165
170
|
pub_key: channel[:remote_pubkey]
|
166
171
|
).to_h
|
167
172
|
end
|
168
173
|
|
174
|
+
data[:@meta] = { calls: grpc.calls }
|
175
|
+
|
169
176
|
data
|
170
177
|
end
|
171
178
|
|
@@ -256,11 +263,17 @@ module Lighstorm
|
|
256
263
|
adapted[:fee_report].each do |channel|
|
257
264
|
next unless data[:id] == channel[:id]
|
258
265
|
|
259
|
-
data[:partners][i][:policy]
|
266
|
+
if data[:partners][i][:policy].nil?
|
267
|
+
data[:partners][i][:policy] = channel[:partner][:policy]
|
268
|
+
else
|
269
|
+
data[:partners][i][:policy][:fee] = channel[:partner][:policy][:fee]
|
270
|
+
end
|
260
271
|
break
|
261
272
|
end
|
262
273
|
else
|
263
|
-
|
274
|
+
if adapted[:get_node_info][data[:partners][i][:node][:public_key]]
|
275
|
+
data[:partners][i][:node] = adapted[:get_node_info][data[:partners][i][:node][:public_key]]
|
276
|
+
end
|
264
277
|
data[:partners][i][:node][:platform] = {
|
265
278
|
blockchain: adapted[:get_info][:platform][:blockchain],
|
266
279
|
network: adapted[:get_info][:platform][:network]
|
@@ -327,22 +340,25 @@ module Lighstorm
|
|
327
340
|
list_payments
|
328
341
|
end
|
329
342
|
|
330
|
-
def self.data(purpose: nil, limit: nil, &vcr)
|
343
|
+
def self.data(purpose: nil, limit: nil, fetch: {}, &vcr)
|
331
344
|
raw = if vcr.nil?
|
332
|
-
fetch(purpose: purpose, limit: limit)
|
345
|
+
self.fetch(purpose: purpose, limit: limit, fetch: fetch)
|
333
346
|
else
|
334
|
-
vcr.call(-> { fetch(purpose: purpose, limit: limit) })
|
347
|
+
vcr.call(-> { self.fetch(purpose: purpose, limit: limit, fetch: fetch) })
|
335
348
|
end
|
336
349
|
|
337
350
|
adapted = adapt(raw)
|
338
351
|
|
339
|
-
|
340
|
-
|
341
|
-
|
352
|
+
{
|
353
|
+
data: adapted[:list_payments].map do |data|
|
354
|
+
transform(data, adapted)
|
355
|
+
end,
|
356
|
+
meta: raw[:@meta]
|
357
|
+
}
|
342
358
|
end
|
343
359
|
|
344
360
|
def self.model(data)
|
345
|
-
data.map do |node_data|
|
361
|
+
data[:data].map do |node_data|
|
346
362
|
Lighstorm::Models::Payment.new(node_data)
|
347
363
|
end
|
348
364
|
end
|
data/controllers/payment.rb
CHANGED
@@ -5,16 +5,16 @@ require_relative './payment/all'
|
|
5
5
|
module Lighstorm
|
6
6
|
module Controllers
|
7
7
|
module Payment
|
8
|
-
def self.all(purpose: nil, limit: nil)
|
9
|
-
All.model(All.data(purpose: purpose, limit: limit))
|
8
|
+
def self.all(purpose: nil, limit: nil, fetch: {})
|
9
|
+
All.model(All.data(purpose: purpose, limit: limit, fetch: fetch))
|
10
10
|
end
|
11
11
|
|
12
|
-
def self.first(purpose: nil)
|
13
|
-
All.model(All.data(purpose: purpose)).first
|
12
|
+
def self.first(purpose: nil, fetch: {})
|
13
|
+
All.model(All.data(purpose: purpose, fetch: fetch)).first
|
14
14
|
end
|
15
15
|
|
16
|
-
def self.last(purpose: nil)
|
17
|
-
All.model(All.data(purpose: purpose)).last
|
16
|
+
def self.last(purpose: nil, fetch: {})
|
17
|
+
All.model(All.data(purpose: purpose, fetch: fetch)).last
|
18
18
|
end
|
19
19
|
end
|
20
20
|
end
|
data/docs/README.md
CHANGED
@@ -23,7 +23,7 @@ Lighstorm::Channel.mine.first.myself.node.alias
|
|
23
23
|
Add to your `Gemfile`:
|
24
24
|
|
25
25
|
```ruby
|
26
|
-
gem 'lighstorm', '~> 0.0.
|
26
|
+
gem 'lighstorm', '~> 0.0.5'
|
27
27
|
```
|
28
28
|
|
29
29
|
Run `bundle install`.
|
@@ -56,7 +56,7 @@ Lighstorm.config!(
|
|
56
56
|
```ruby
|
57
57
|
require 'lighstorm'
|
58
58
|
|
59
|
-
puts Lighstorm.version # => 0.0.
|
59
|
+
puts Lighstorm.version # => 0.0.5
|
60
60
|
|
61
61
|
Lighstorm::Satoshis.new(
|
62
62
|
milisatoshis: 75_621_650
|
@@ -251,16 +251,23 @@ end
|
|
251
251
|
```ruby
|
252
252
|
LighstormError
|
253
253
|
|
254
|
+
IncoherentGossipError
|
255
|
+
|
256
|
+
TooManyArgumentsError
|
254
257
|
MissingCredentialsError
|
258
|
+
MissingGossipHandlerError
|
255
259
|
MissingMilisatoshisError
|
256
260
|
MissingPartsPerMillionError
|
257
261
|
MissingTTLError
|
262
|
+
|
258
263
|
NegativeNotAllowedError
|
264
|
+
|
259
265
|
NotYourChannelError
|
260
266
|
NotYourNodeError
|
267
|
+
UnknownChannelError
|
268
|
+
|
261
269
|
OperationNotAllowedError
|
262
270
|
UnexpectedNumberOfHTLCsError
|
263
|
-
UnknownChannelError
|
264
271
|
UpdateChannelPolicyError
|
265
272
|
```
|
266
273
|
|
@@ -327,7 +334,8 @@ channel.mine?
|
|
327
334
|
channel.id
|
328
335
|
channel.opened_at
|
329
336
|
channel.up_at
|
330
|
-
channel.
|
337
|
+
channel.state
|
338
|
+
channel.active?
|
331
339
|
channel.exposure
|
332
340
|
|
333
341
|
channel.accounting.capacity.milisatoshis
|
@@ -345,31 +353,39 @@ channel.partners[1]
|
|
345
353
|
channel.partners[1].node.alias
|
346
354
|
|
347
355
|
# Channels that belong to you:
|
348
|
-
channel.myself
|
349
|
-
channel.myself.node.alias
|
350
|
-
|
351
356
|
channel.transaction.funding.id
|
352
357
|
channel.transaction.funding.index
|
353
358
|
|
354
359
|
channel.partner
|
355
|
-
channel.partner.
|
360
|
+
channel.partner.state
|
361
|
+
channel.partner.active?
|
356
362
|
|
357
|
-
channel.partner.accounting.balance.milisatoshis
|
358
|
-
channel.partner.node.alias
|
359
363
|
channel.partner.node.public_key
|
364
|
+
channel.partner.node.alias
|
360
365
|
channel.partner.node.color
|
366
|
+
|
367
|
+
channel.partner.accounting.balance.milisatoshis
|
368
|
+
|
361
369
|
channel.partner.policy.fee.base.milisatoshis
|
362
370
|
channel.partner.policy.fee.rate.parts_per_million
|
371
|
+
|
363
372
|
channel.partner.policy.htlc.minimum.milisatoshis
|
364
373
|
channel.partner.policy.htlc.maximum.milisatoshis
|
365
374
|
channel.partner.policy.htlc.blocks.delta.minimum
|
366
375
|
|
367
|
-
channel.myself
|
368
|
-
channel.myself.
|
376
|
+
channel.myself
|
377
|
+
channel.myself.state
|
378
|
+
channel.myself.active?
|
379
|
+
|
369
380
|
channel.myself.node.public_key
|
381
|
+
channel.myself.node.alias
|
370
382
|
channel.myself.node.color
|
383
|
+
|
384
|
+
channel.myself.accounting.balance.milisatoshis
|
385
|
+
|
371
386
|
channel.myself.policy.fee.base.milisatoshis
|
372
387
|
channel.myself.policy.fee.rate.parts_per_million
|
388
|
+
|
373
389
|
channel.myself.policy.htlc.minimum.milisatoshis
|
374
390
|
channel.myself.policy.htlc.maximum.milisatoshis
|
375
391
|
channel.myself.policy.htlc.blocks.delta.minimum
|
@@ -537,6 +553,17 @@ payment.hops[0].channel.entry.public_key
|
|
537
553
|
payment.hops[0].channel.entry.alias
|
538
554
|
payment.hops[0].channel.entry.color
|
539
555
|
```
|
556
|
+
### Performance
|
557
|
+
Avoid fetching data that you don't need:
|
558
|
+
```ruby
|
559
|
+
Lighstorm::Payment.all(
|
560
|
+
fetch: {
|
561
|
+
get_node_info: false,
|
562
|
+
lookup_invoice: false,
|
563
|
+
decode_pay_req: false,
|
564
|
+
get_chan_info: false }
|
565
|
+
)
|
566
|
+
```
|
540
567
|
|
541
568
|
## Forward
|
542
569
|
|
@@ -625,6 +652,55 @@ group.channel.partner.node.public_key
|
|
625
652
|
group.channel.partner.node.color
|
626
653
|
```
|
627
654
|
|
655
|
+
## Gossip
|
656
|
+
|
657
|
+
[The Gossip Network](https://docs.lightning.engineering/the-lightning-network/the-gossip-network)
|
658
|
+
|
659
|
+
### Node
|
660
|
+
|
661
|
+
```ruby
|
662
|
+
gossip = {
|
663
|
+
'identityKey' => '02d3c80335a8ccb2ed364c06875f32240f36f7edb37d80f8dbe321b4c364b6e997',
|
664
|
+
'alias' => 'icebaker',
|
665
|
+
'color' => '#eb34a4'
|
666
|
+
}
|
667
|
+
|
668
|
+
Lighstorm::Node.adapt(gossip: gossip)
|
669
|
+
|
670
|
+
node = Lighstorm::Node.find_by_public_key(
|
671
|
+
'02d3c80335a8ccb2ed364c06875f32240f36f7edb37d80f8dbe321b4c364b6e997'
|
672
|
+
)
|
673
|
+
|
674
|
+
diff = node.apply!(gossip: gossip)
|
675
|
+
|
676
|
+
Lighstorm::Node.adapt(dump: node.dump)
|
677
|
+
```
|
678
|
+
|
679
|
+
### Channel
|
680
|
+
|
681
|
+
```ruby
|
682
|
+
gossip = {
|
683
|
+
'chanId' => '850099509773795329',
|
684
|
+
'capacity' => '5000000',
|
685
|
+
'routingPolicy' => {
|
686
|
+
'timeLockDelta' => 144,
|
687
|
+
'minHtlc' => '1000',
|
688
|
+
'feeBaseMsat' => '1000',
|
689
|
+
'feeRateMilliMsat' => '300',
|
690
|
+
'maxHtlcMsat' => '4950000000'
|
691
|
+
},
|
692
|
+
'advertisingNode' => '02d3c80335a8ccb2ed364c06875f32240f36f7edb37d80f8dbe321b4c364b6e997'
|
693
|
+
}
|
694
|
+
|
695
|
+
Lighstorm::Channel.adapt(gossip: gossip)
|
696
|
+
|
697
|
+
channel = Lighstorm::Channel.find_by_id('850099509773795329')
|
698
|
+
|
699
|
+
diff = channel.apply!(gossip: gossip)
|
700
|
+
|
701
|
+
Lighstorm::Channel.adapt(dump: channel.dump)
|
702
|
+
```
|
703
|
+
|
628
704
|
## Satoshis
|
629
705
|
|
630
706
|
```ruby
|
@@ -647,7 +723,7 @@ satoshis.parts_per_million(reference_in_milisatoshis)
|
|
647
723
|
_________________
|
648
724
|
|
649
725
|
<center>
|
650
|
-
lighstorm 0.0.
|
726
|
+
lighstorm 0.0.5
|
651
727
|
|
|
652
728
|
<a href="https://github.com/icebaker/lighstorm" rel="noopener noreferrer" target="_blank">GitHub</a>
|
653
729
|
|
|
data/docs/_coverpage.md
CHANGED
data/docs/index.html
CHANGED
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Lighstorm
|
4
|
+
module Models
|
5
|
+
module Protectable
|
6
|
+
def prepare_token!(token)
|
7
|
+
@token = token
|
8
|
+
end
|
9
|
+
|
10
|
+
def protect!(value)
|
11
|
+
validate_token!(value)
|
12
|
+
end
|
13
|
+
|
14
|
+
def validate_token!(value)
|
15
|
+
token = value.is_a?(Hash) ? value[:token] : nil
|
16
|
+
|
17
|
+
raise OperationNotAllowedError if token.nil? || @token.nil? || token != @token
|
18
|
+
|
19
|
+
@token = nil
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|