lighstorm 0.0.3 → 0.0.4

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.
Files changed (80) hide show
  1. checksums.yaml +4 -4
  2. data/.env.example +5 -0
  3. data/.gitignore +1 -0
  4. data/.rspec +1 -0
  5. data/.rubocop.yml +10 -0
  6. data/Gemfile +4 -0
  7. data/Gemfile.lock +26 -2
  8. data/README.md +29 -370
  9. data/adapters/connections/channel_node/fee.rb +26 -0
  10. data/adapters/connections/channel_node.rb +52 -0
  11. data/adapters/connections/payment_channel.rb +28 -0
  12. data/adapters/edges/channel.rb +80 -0
  13. data/adapters/edges/forward.rb +41 -0
  14. data/adapters/edges/payment/purpose.rb +34 -0
  15. data/adapters/edges/payment.rb +53 -0
  16. data/adapters/invoice.rb +50 -0
  17. data/adapters/nodes/node.rb +77 -0
  18. data/adapters/payment_request.rb +77 -0
  19. data/components/cache.rb +3 -2
  20. data/components/lnd.rb +5 -1
  21. data/controllers/channel/actions/update_fee.rb +76 -0
  22. data/controllers/channel/all.rb +79 -0
  23. data/controllers/channel/find_by_id.rb +153 -0
  24. data/controllers/channel/mine.rb +114 -0
  25. data/controllers/channel.rb +23 -0
  26. data/controllers/forward/all.rb +244 -0
  27. data/controllers/forward/group_by_channel.rb +89 -0
  28. data/controllers/forward.rb +28 -0
  29. data/controllers/invoice/actions/create.rb +36 -0
  30. data/controllers/invoice/actions/pay.rb +28 -0
  31. data/controllers/invoice/actions/pay_through_route.rb +71 -0
  32. data/controllers/invoice/all.rb +70 -0
  33. data/controllers/invoice/find_by_secret_hash.rb +42 -0
  34. data/controllers/invoice.rb +36 -0
  35. data/controllers/node/all.rb +63 -0
  36. data/controllers/node/find_by_public_key.rb +49 -0
  37. data/controllers/node/myself.rb +34 -0
  38. data/controllers/node.rb +23 -0
  39. data/controllers/payment/all.rb +352 -0
  40. data/controllers/payment.rb +21 -0
  41. data/docs/.nojekyll +0 -0
  42. data/docs/README.md +655 -0
  43. data/docs/_coverpage.md +12 -0
  44. data/docs/index.html +26 -0
  45. data/docs/vendor/docsify/docsify@4.js +1 -0
  46. data/docs/vendor/docsify-themeable/theme-simple-dark.css +3 -0
  47. data/docs/vendor/docsify-themeable/theme-simple-dark.css.map +1 -0
  48. data/docs/vendor/prismjs/prism-bash.min.js +1 -0
  49. data/docs/vendor/prismjs/prism-ruby.min.js +1 -0
  50. data/docs/vendor/prismjs/prism-tomorrow.min.css +1 -0
  51. data/lighstorm.gemspec +3 -1
  52. data/models/connections/channel_node/accounting.rb +3 -14
  53. data/models/connections/channel_node/fee.rb +39 -77
  54. data/models/connections/channel_node/htlc.rb +30 -10
  55. data/models/connections/channel_node/policy.rb +6 -18
  56. data/models/connections/channel_node.rb +20 -26
  57. data/models/connections/forward_channel.rb +8 -43
  58. data/models/connections/payment_channel.rb +18 -39
  59. data/models/edges/channel/accounting.rb +28 -20
  60. data/models/edges/channel/hop.rb +65 -0
  61. data/models/edges/channel.rb +80 -172
  62. data/models/edges/forward.rb +9 -118
  63. data/models/edges/groups/{analysis.rb → channel_forwards/analysis.rb} +9 -9
  64. data/models/edges/groups/channel_forwards.rb +10 -40
  65. data/models/edges/payment.rb +29 -214
  66. data/models/errors.rb +29 -0
  67. data/models/invoice.rb +49 -0
  68. data/models/nodes/node/lightning.rb +5 -16
  69. data/models/nodes/node/platform.rb +7 -13
  70. data/models/nodes/node.rb +20 -115
  71. data/models/payment_request.rb +69 -0
  72. data/models/rate.rb +11 -1
  73. data/models/satoshis.rb +5 -6
  74. data/ports/dsl/lighstorm/errors.rb +5 -0
  75. data/ports/dsl/lighstorm.rb +11 -9
  76. data/ports/grpc.rb +62 -0
  77. data/static/cache.rb +12 -0
  78. data/static/spec.rb +3 -1
  79. metadata +55 -6
  80. data/models/connections/channel_node/constraints.rb +0 -24
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'digest'
4
3
  require 'time'
5
4
  require 'date'
6
5
 
@@ -12,130 +11,30 @@ require_relative 'groups/channel_forwards'
12
11
  module Lighstorm
13
12
  module Models
14
13
  class Forward
15
- KIND = :edge
14
+ attr_reader :_key, :at
16
15
 
17
- attr_reader :data
16
+ def initialize(data)
17
+ @data = data
18
18
 
19
- def self.all(limit: nil, raw: false, info: true)
20
- last_offset = 0
21
-
22
- forwards = []
23
-
24
- loop do
25
- response = Cache.for(
26
- 'lightning.forwarding_history',
27
- params: { peer_alias_lookup: true, index_offset: last_offset }
28
- ) do
29
- LND.instance.middleware('lightning.forwarding_history') do
30
- LND.instance.client.lightning.forwarding_history(
31
- peer_alias_lookup: true, index_offset: last_offset
32
- )
33
- end
34
- end
35
-
36
- response.forwarding_events.each { |raw_forward| forwards << raw_forward }
37
-
38
- # Unfortunately, forwards aren't sorted in descending order. :(
39
- # break if !limit.nil? && forwards.size >= limit
40
-
41
- break if last_offset == response.last_offset_index || last_offset > response.last_offset_index
42
-
43
- last_offset = response.last_offset_index
44
- end
45
-
46
- forwards = forwards.sort_by { |raw_forward| -raw_forward.timestamp_ns }
47
-
48
- forwards = forwards[0..limit - 1] unless limit.nil?
49
-
50
- return forwards if raw
51
-
52
- forwards.map { |raw_forward| Forward.new(raw_forward, respond_info: info) }
53
- end
54
-
55
- def self.first
56
- all(limit: 1).first
57
- end
58
-
59
- def self.last
60
- all.last
61
- end
62
-
63
- def self.group_by_channel(direction: :out, hours_ago: nil, limit: nil, info: true)
64
- raw_forwards = all(raw: true)
65
-
66
- direction = direction.to_sym
67
-
68
- groups = {}
69
-
70
- raw_forwards.each do |raw_forward|
71
- channel_id = direction == :in ? raw_forward.chan_id_in : raw_forward.chan_id_out
72
-
73
- if hours_ago
74
- forward_hours_ago = (
75
- Time.now - Time.at(raw_forward.timestamp_ns / 1e+9)
76
- ).to_f / 3600
77
-
78
- next if forward_hours_ago > hours_ago
79
- end
80
-
81
- unless groups[channel_id]
82
- groups[channel_id] = {
83
- last_at: nil,
84
- analysis: { count: 0, sums: { amount: 0, fee: 0 } },
85
- direction => { id: channel_id }
86
- }
87
- end
88
-
89
- groups[channel_id][:analysis][:count] += 1
90
- groups[channel_id][:analysis][:sums][:amount] += raw_forward.amt_in_msat
91
- groups[channel_id][:analysis][:sums][:fee] += raw_forward.fee_msat
92
-
93
- if groups[channel_id][:last_at].nil? || raw_forward.timestamp_ns > groups[channel_id][:last_at]
94
- groups[channel_id][:last_at] = raw_forward.timestamp_ns
95
- groups[channel_id][:sample] = raw_forward
96
- end
97
- end
98
-
99
- groups = groups.values.sort_by { |group| - group[:last_at] }
100
- .sort_by { |group| - group[:analysis][:count] }
101
-
102
- groups = groups[0..limit - 1] unless limit.nil?
103
-
104
- groups.map { |raw_group| ChannelForwardsGroup.new(direction, raw_group) }
105
- end
106
-
107
- def initialize(raw, respond_info: true)
108
- @respond_info = respond_info
109
- @data = { forwarding_history: { forwarding_events: [raw] } }
110
- end
111
-
112
- def id
113
- @id ||= Digest::SHA256.hexdigest(
114
- @data[:forwarding_history][:forwarding_events].first.timestamp_ns.to_s
115
- )
116
- end
117
-
118
- def at
119
- DateTime.parse(Time.at(
120
- @data[:forwarding_history][:forwarding_events].first.timestamp_ns / 1e+9
121
- ).to_s)
19
+ @_key = data[:_key]
20
+ @at = data[:at]
122
21
  end
123
22
 
124
23
  def fee
125
- Satoshis.new(milisatoshis: @data[:forwarding_history][:forwarding_events].first.fee_msat)
24
+ @fee ||= Satoshis.new(milisatoshis: @data[:fee][:milisatoshis])
126
25
  end
127
26
 
128
27
  def in
129
- @in ||= ForwardChannel.new(:in, self, respond_info: @respond_info)
28
+ @in ||= ForwardChannel.new(@data[:in])
130
29
  end
131
30
 
132
31
  def out
133
- @out ||= ForwardChannel.new(:out, self, respond_info: @respond_info)
32
+ @out ||= ForwardChannel.new(@data[:out])
134
33
  end
135
34
 
136
35
  def to_h
137
36
  {
138
- id: id,
37
+ _key: _key,
139
38
  at: at,
140
39
  fee: {
141
40
  milisatoshis: fee.milisatoshis,
@@ -145,14 +44,6 @@ module Lighstorm
145
44
  out: out.to_h
146
45
  }
147
46
  end
148
-
149
- def raw
150
- {
151
- forwarding_history: {
152
- forwarding_events: [@data[:forwarding_history][:forwarding_events].first.to_h]
153
- }
154
- }
155
- end
156
47
  end
157
48
  end
158
49
  end
@@ -3,19 +3,19 @@
3
3
  module Lighstorm
4
4
  module Models
5
5
  class ChannelForwardsGroup
6
- Analysis = Struct.new(:analysis) do
6
+ Analysis = Struct.new(:data) do
7
7
  def count
8
- analysis[:count]
8
+ data[:count]
9
9
  end
10
10
 
11
11
  def sums
12
12
  Struct.new(:sums) do
13
13
  def amount
14
- Satoshis.new(milisatoshis: sums[:amount])
14
+ Satoshis.new(milisatoshis: sums[:amount][:milisatoshis])
15
15
  end
16
16
 
17
17
  def fee
18
- Satoshis.new(milisatoshis: sums[:fee])
18
+ Satoshis.new(milisatoshis: sums[:fee][:milisatoshis])
19
19
  end
20
20
 
21
21
  def to_h
@@ -27,20 +27,20 @@ module Lighstorm
27
27
  }
28
28
  }
29
29
  end
30
- end.new(analysis[:sums])
30
+ end.new(data[:sums])
31
31
  end
32
32
 
33
33
  def averages
34
- Struct.new(:analysis) do
34
+ Struct.new(:data) do
35
35
  def amount
36
36
  Satoshis.new(
37
- milisatoshis: analysis[:sums][:amount].to_f / analysis[:count]
37
+ milisatoshis: data[:sums][:amount][:milisatoshis].to_f / data[:count]
38
38
  )
39
39
  end
40
40
 
41
41
  def fee
42
42
  Satoshis.new(
43
- milisatoshis: analysis[:sums][:fee].to_f / analysis[:count]
43
+ milisatoshis: data[:sums][:fee][:milisatoshis].to_f / data[:count]
44
44
  )
45
45
  end
46
46
 
@@ -53,7 +53,7 @@ module Lighstorm
53
53
  }
54
54
  }
55
55
  end
56
- end.new(analysis)
56
+ end.new(data)
57
57
  end
58
58
 
59
59
  def to_h
@@ -1,66 +1,36 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative '../../satoshis'
4
- require_relative 'analysis'
4
+ require_relative 'channel_forwards/analysis'
5
5
 
6
6
  module Lighstorm
7
7
  module Models
8
8
  class ChannelForwardsGroup
9
- def initialize(direction, data)
10
- @direction = direction
9
+ attr_reader :_key, :last_at
10
+
11
+ def initialize(data)
11
12
  @data = data
12
- end
13
13
 
14
- def last_at
15
- @last_at ||= DateTime.parse(Time.at(@data[:last_at].to_f / 1e+9).to_s)
14
+ @_key = data[:_key]
15
+ @last_at = data[:last_at]
16
16
  end
17
17
 
18
18
  def analysis
19
19
  Analysis.new(@data[:analysis])
20
20
  end
21
21
 
22
- def in
23
- return @in if @in
24
-
25
- raise raise ArgumentError, "Method `in` doesn't exist." unless @direction == :in
26
-
27
- @in = Channel.new({ id: @data[:in][:id] })
28
- end
29
-
30
- def out
31
- return @out if @out
32
-
33
- raise raise ArgumentError, "Method `out` doesn't exist." unless @direction == :out
34
-
35
- @out = Channel.new({ id: @data[:out][:id] })
22
+ def channel
23
+ @channel ||= Channel.new(@data[:channel])
36
24
  end
37
25
 
38
- # def capacity
39
- # @capacity ||= Satoshis.new(milisatoshis: @channel.data[:get_chan_info].capacity * 1000)
40
- # end
41
-
42
26
  def to_h
43
27
  {
28
+ _key: _key,
44
29
  last_at: last_at,
45
30
  analysis: analysis.to_h,
46
- @direction => {
47
- id: channel.id,
48
- partner: {
49
- node: {
50
- alias: channel&.partner&.node&.alias,
51
- public_key: channel&.partner&.node&.public_key,
52
- color: channel&.partner&.node&.color
53
- }
54
- }
55
- }
31
+ channel: channel.to_h
56
32
  }
57
33
  end
58
-
59
- private
60
-
61
- def channel
62
- @channel ||= @direction == :in ? self.in : out
63
- end
64
34
  end
65
35
  end
66
36
  end
@@ -7,248 +7,63 @@ require_relative '../satoshis'
7
7
 
8
8
  require_relative '../connections/payment_channel'
9
9
  require_relative '../nodes/node'
10
+ require_relative '../payment_request'
10
11
 
11
12
  module Lighstorm
12
13
  module Models
13
14
  class Payment
14
- KIND = :edge
15
+ attr_reader :_key, :hash, :request, :status, :created_at, :settled_at, :purpose
15
16
 
16
- attr_reader :data
17
+ def initialize(data)
18
+ @data = data
17
19
 
18
- def self.all(limit: nil, purpose: nil, hops: true, info: true)
19
- last_offset = 0
20
-
21
- payments = []
22
-
23
- loop do
24
- response = Cache.for('lightning.list_payments', params: { index_offset: last_offset }) do
25
- LND.instance.middleware('lightning.list_payments') do
26
- LND.instance.client.lightning.list_payments(index_offset: last_offset)
27
- end
28
- end
29
-
30
- response.payments.each do |raw_payment|
31
- case purpose
32
- when 'potential-submarine', 'submarine'
33
- payments << raw_payment if raw_potential_submarine?(raw_payment)
34
- when '!potential-submarine', '!submarine'
35
- payments << raw_payment unless raw_potential_submarine?(raw_payment)
36
- when 'rebalance'
37
- payments << raw_payment if raw_rebalance?(raw_payment)
38
- when '!rebalance'
39
- payments << raw_payment unless raw_rebalance?(raw_payment)
40
- when '!payment'
41
- payments << raw_payment if raw_potential_submarine?(raw_payment) || raw_rebalance?(raw_payment)
42
- when 'payment'
43
- payments << raw_payment if !raw_potential_submarine?(raw_payment) && !raw_rebalance?(raw_payment)
44
- else
45
- payments << raw_payment
46
- end
47
- end
48
-
49
- # Fortunately, payments are sorted in descending order. :)
50
- break if !limit.nil? && payments.size >= limit
51
-
52
- break if last_offset == response.last_index_offset || last_offset > response.last_index_offset
53
-
54
- last_offset = response.last_index_offset
55
- end
56
-
57
- payments = payments.sort_by { |raw_payment| -raw_payment.creation_time_ns }
58
-
59
- payments = payments[0..limit - 1] unless limit.nil?
60
-
61
- payments.map do |raw_payment|
62
- Payment.new(raw_payment, respond_hops: hops, respond_info: info)
63
- end
64
- end
65
-
66
- def self.first
67
- all(limit: 1).first
68
- end
69
-
70
- def self.last
71
- all.last
72
- end
73
-
74
- def initialize(raw, respond_hops: true, respond_info: true)
75
- @respond_hops = respond_hops
76
- @respond_info = respond_info
77
- @data = { list_payments: { payments: [raw] } }
78
- end
79
-
80
- def id
81
- @id ||= @data[:list_payments][:payments].first.payment_hash
20
+ @_key = data[:_key]
21
+ @status = data[:status]
22
+ @created_at = data[:created_at]
23
+ @settled_at = data[:settled_at]
24
+ @purpose = data[:purpose]
82
25
  end
83
26
 
84
- def hash
85
- @hash ||= @data[:list_payments][:payments].first.payment_hash
86
- end
87
-
88
- def status
89
- @status ||= @data[:list_payments][:payments].first.status
90
- end
91
-
92
- def created_at
93
- @created_at ||= DateTime.parse(Time.at(@data[:list_payments][:payments].first.creation_date).to_s)
94
- end
95
-
96
- def amount
97
- @amount ||= Satoshis.new(
98
- milisatoshis: @data[:list_payments][:payments].first.value_msat
99
- )
27
+ def request
28
+ @request ||= PaymentRequest.new(@data[:request])
100
29
  end
101
30
 
102
31
  def fee
103
- @fee ||= Satoshis.new(
104
- milisatoshis: @data[:list_payments][:payments].first.fee_msat
105
- )
106
- end
107
-
108
- def purpose
109
- @purpose ||= Payment.raw_purpose(@data[:list_payments][:payments].first)
32
+ @fee ||= Satoshis.new(milisatoshis: @data[:fee][:milisatoshis])
110
33
  end
111
34
 
112
- def rebalance?
113
- return @rebalance unless @rebalance.nil?
114
-
115
- validated_htlcs_number!
116
-
117
- @rebalance = Payment.raw_rebalance?(
118
- @data[:list_payments][:payments].first
119
- )
120
-
121
- @rebalance
122
- end
123
-
124
- def self.raw_rebalance?(raw_payment)
125
- return false if raw_payment.htlcs.first.route.hops.size <= 2
126
-
127
- destination_public_key = raw_payment.htlcs.first.route.hops.last.pub_key
128
-
129
- Node.myself.public_key == destination_public_key
130
- end
131
-
132
- def self.raw_purpose(raw_payment)
133
- return 'potential-submarine' if raw_potential_submarine?(raw_payment)
134
- return 'rebalance' if raw_rebalance?(raw_payment)
135
-
136
- 'payment'
137
- end
138
-
139
- def self.raw_potential_submarine?(raw_payment)
140
- raw_payment.htlcs.first.route.hops.size == 1
141
- end
142
-
143
- def potential_submarine?
144
- validated_htlcs_number!
145
-
146
- @potential_submarine ||= Payment.raw_potential_submarine?(
147
- @data[:list_payments][:payments].first
148
- )
149
- end
150
-
151
- def validated_htlcs_number!
152
- return unless @data[:list_payments][:payments].first.htlcs.size > 1
35
+ def hops
36
+ return @hops if @hops
153
37
 
154
- raise "Unexpected number of HTLCs (#{@data[:list_payments][:payments].first.htlcs.size}) for Payment"
38
+ @data[:hops].last[:is_last] = true
39
+ @hops = @data[:hops].map do |hop|
40
+ PaymentChannel.new(hop, self)
41
+ end
155
42
  end
156
43
 
157
44
  def from
158
- return @from if @from
159
-
160
- if @hops
161
- @from = @hops.first
162
- return @from
163
- end
164
-
165
- validated_htlcs_number!
166
-
167
- @from = PaymentChannel.new(
168
- @data[:list_payments][:payments].first.htlcs.first.route.hops.first,
169
- 1, respond_info: @respond_info
170
- )
171
-
172
- @from
45
+ @from ||= hops.first
173
46
  end
174
47
 
175
48
  def to
176
- return @to if @to
177
-
178
- if @hops
179
-
180
- @to = rebalance? ? @hops[@hops.size - 2] : @hops.last
181
- return @to
182
- end
183
-
184
- validated_htlcs_number!
185
-
186
- @to = if rebalance?
187
- PaymentChannel.new(
188
- @data[:list_payments][:payments].first.htlcs.first.route.hops[
189
- @data[:list_payments][:payments].first.htlcs.first.route.hops.size - 2
190
- ],
191
- @data[:list_payments][:payments].first.htlcs.first.route.hops.size - 1,
192
- respond_info: @respond_info
193
- )
194
- else
195
- PaymentChannel.new(
196
- @data[:list_payments][:payments].first.htlcs.first.route.hops.last,
197
- @data[:list_payments][:payments].first.htlcs.first.route.hops.size,
198
- respond_info: @respond_info
199
- )
200
- end
201
-
202
- @to
203
- end
204
-
205
- def hops
206
- return @hops if @hops
207
-
208
- validated_htlcs_number!
209
-
210
- @hops = @data[:list_payments][:payments].first.htlcs.first.route.hops.map.with_index do |raw_hop, i|
211
- PaymentChannel.new(raw_hop, i + 1, respond_info: @respond_info)
212
- end
213
- end
214
-
215
- def preload_hops!
216
- hops
217
- true
49
+ @to ||= hops.last
218
50
  end
219
51
 
220
52
  def to_h
221
53
  response = {
222
- id: id,
223
- hash: hash,
54
+ _key: _key,
55
+ status: status,
224
56
  created_at: created_at,
57
+ settled_at: settled_at,
225
58
  purpose: purpose,
226
- status: status,
227
- amount: amount.to_h,
228
59
  fee: {
229
60
  milisatoshis: fee.milisatoshis,
230
- parts_per_million: fee.parts_per_million(amount.milisatoshis)
231
- }
232
- }
233
-
234
- if @respond_hops
235
- preload_hops!
236
- response[:from] = from.to_h
237
- response[:to] = to.to_h
238
- response[:hops] = hops.map(&:to_h)
239
- else
240
- response[:from] = from.to_h
241
- response[:to] = to.to_h
242
- end
243
-
244
- response
245
- end
246
-
247
- def raw
248
- {
249
- list_payments: {
250
- payments: [@data[:list_payments][:payments].first.to_h]
251
- }
61
+ parts_per_million: fee.parts_per_million(request.amount.milisatoshis)
62
+ },
63
+ request: request.to_h,
64
+ from: from.to_h,
65
+ to: to.to_h,
66
+ hops: hops.map(&:to_h)
252
67
  }
253
68
  end
254
69
  end
data/models/errors.rb ADDED
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Lighstorm
4
+ module Errors
5
+ class LighstormError < StandardError; end
6
+
7
+ class ToDoError < LighstormError; end
8
+
9
+ class MissingCredentialsError < LighstormError; end
10
+ class MissingMilisatoshisError < LighstormError; end
11
+ class MissingPartsPerMillionError < LighstormError; end
12
+ class MissingTTLError < LighstormError; end
13
+ class NegativeNotAllowedError < LighstormError; end
14
+ class NotYourChannelError < LighstormError; end
15
+ class NotYourNodeError < LighstormError; end
16
+ class OperationNotAllowedError < LighstormError; end
17
+ class UnexpectedNumberOfHTLCsError < LighstormError; end
18
+ class UnknownChannelError < LighstormError; end
19
+
20
+ class UpdateChannelPolicyError < LighstormError
21
+ attr_reader :response
22
+
23
+ def initialize(message, response)
24
+ super(message)
25
+ @response = response
26
+ end
27
+ end
28
+ end
29
+ end
data/models/invoice.rb ADDED
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'satoshis'
4
+ require 'securerandom'
5
+
6
+ require_relative 'payment_request'
7
+
8
+ require_relative '../controllers/invoice/actions/create'
9
+ require_relative '../controllers/invoice/actions/pay'
10
+ require_relative '../controllers/invoice/actions/pay_through_route'
11
+
12
+ module Lighstorm
13
+ module Models
14
+ class Invoice
15
+ attr_reader :_key, :created_at, :settle_at, :state
16
+
17
+ def initialize(data)
18
+ @data = data
19
+
20
+ @_key = data[:_key]
21
+ @created_at = data[:created_at]
22
+ @settle_at = data[:settle_at]
23
+ @state = data[:state]
24
+ end
25
+
26
+ def request
27
+ @request ||= PaymentRequest.new(@data[:request])
28
+ end
29
+
30
+ def to_h
31
+ {
32
+ _key: _key,
33
+ created_at: created_at,
34
+ settle_at: settle_at,
35
+ state: state,
36
+ request: request.to_h
37
+ }
38
+ end
39
+
40
+ def pay!(route: nil, preview: false)
41
+ if route
42
+ Controllers::Invoice::PayThroughRoute.perform(self, route: route, preview: preview)
43
+ else
44
+ Controllers::Invoice::Pay.perform(self, preview: preview)
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -1,28 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative '../../../components/lnd'
4
-
5
3
  module Lighstorm
6
4
  module Models
7
5
  class Lightning
8
6
  IMPLEMENTATION = 'lnd'
9
7
 
10
- def initialize(platform, node)
11
- raise 'cannot provide platform details for a node that is not yours' unless node.myself?
12
-
13
- @platform = platform
14
- end
15
-
16
- def version
17
- @version ||= @platform.data[:get_info].version
18
- end
8
+ attr_reader :implementation, :version
19
9
 
20
- def raw
21
- { get_info: @data[:get_info].to_h }
22
- end
10
+ def initialize(node)
11
+ raise Errors::NotYourNodeError unless node.myself?
23
12
 
24
- def implementation
25
- @implementation ||= IMPLEMENTATION
13
+ @implementation = IMPLEMENTATION
14
+ @version = node.data[:platform][:lightning][:version]
26
15
  end
27
16
 
28
17
  def to_h