lighstorm 0.0.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: dc2a22398ed869fa9709af719d701c1fa00f5475f8de245111b40d602211e84d
4
+ data.tar.gz: c41b6c9d08350d0e4717242eb663b6e85aa9c9c714f46974e4969e340d13a033
5
+ SHA512:
6
+ metadata.gz: f560d47006a324f3468122cc719a89595523cfb639b8ad6dc45cf4ee7bc4d3bb2befb0a5ec5b02f84d8810bd7364322ef78f224611097a407999aaab571fd8c6
7
+ data.tar.gz: 1ae71460fae62e5022eeff6f3a91e15dadd23ef382162efb068b74d61cd7ae714b68182165a463b6d035eb6daa0fb5dde5ef0aa1e7c660f91e77a85f42f8f0f7
data/.gitignore ADDED
@@ -0,0 +1 @@
1
+ *.gem
data/.rubocop.yml ADDED
@@ -0,0 +1,14 @@
1
+ AllCops:
2
+ TargetRubyVersion: 3.0.0
3
+ NewCops: enable
4
+
5
+ Style/Documentation:
6
+ Enabled: false
7
+
8
+ Naming/FileName:
9
+ Exclude:
10
+ - 'ports/dsl/lighstorm.rb'
11
+
12
+ Layout/LineLength:
13
+ Exclude:
14
+ - 'static/spec.rb'
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gemspec
6
+
7
+ group :test, :development do
8
+ gem 'pry-byebug', '~> 3.10', '>= 3.10.1'
9
+ gem 'rubocop', '~> 1.44', '>= 1.44.1'
10
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,63 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ lighstorm (0.0.1)
5
+ dotenv (~> 2.8, >= 2.8.1)
6
+ lnd-client (~> 0.0.4)
7
+ zache (~> 0.12.0)
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ ast (2.4.2)
13
+ byebug (11.1.3)
14
+ coderay (1.1.3)
15
+ dotenv (2.8.1)
16
+ google-protobuf (3.21.12)
17
+ googleapis-common-protos-types (1.5.0)
18
+ google-protobuf (~> 3.14)
19
+ grpc (1.51.0)
20
+ google-protobuf (~> 3.21)
21
+ googleapis-common-protos-types (~> 1.0)
22
+ json (2.6.3)
23
+ lnd-client (0.0.4)
24
+ grpc (~> 1.51)
25
+ method_source (1.0.0)
26
+ parallel (1.22.1)
27
+ parser (3.2.0.0)
28
+ ast (~> 2.4.1)
29
+ pry (0.14.2)
30
+ coderay (~> 1.1)
31
+ method_source (~> 1.0)
32
+ pry-byebug (3.10.1)
33
+ byebug (~> 11.0)
34
+ pry (>= 0.13, < 0.15)
35
+ rainbow (3.1.1)
36
+ regexp_parser (2.6.2)
37
+ rexml (3.2.5)
38
+ rubocop (1.44.1)
39
+ json (~> 2.3)
40
+ parallel (~> 1.10)
41
+ parser (>= 3.2.0.0)
42
+ rainbow (>= 2.2.2, < 4.0)
43
+ regexp_parser (>= 1.8, < 3.0)
44
+ rexml (>= 3.2.5, < 4.0)
45
+ rubocop-ast (>= 1.24.1, < 2.0)
46
+ ruby-progressbar (~> 1.7)
47
+ unicode-display_width (>= 2.4.0, < 3.0)
48
+ rubocop-ast (1.24.1)
49
+ parser (>= 3.1.1.0)
50
+ ruby-progressbar (1.11.0)
51
+ unicode-display_width (2.4.2)
52
+ zache (0.12.0)
53
+
54
+ PLATFORMS
55
+ x86_64-linux
56
+
57
+ DEPENDENCIES
58
+ lighstorm!
59
+ pry-byebug (~> 3.10, >= 3.10.1)
60
+ rubocop (~> 1.44, >= 1.44.1)
61
+
62
+ BUNDLED WITH
63
+ 2.4.4
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023 icebaker
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,362 @@
1
+ # Lighstorm
2
+
3
+ > ⚠️ Warning: Early-stage, breaking changes are expected.
4
+
5
+ API for interacting with a [Lightning Node](https://lightning.network).
6
+
7
+ ![Lighstorm text written stylized with an illustration of a Graph connecting two Nodes.](https://raw.githubusercontent.com/icebaker/assets/main/lighstorm/lighstorm.png)
8
+
9
+ ```ruby
10
+ Lighstorm::Channel.first.myself.node.alias
11
+ ```
12
+
13
+ ## Index
14
+
15
+ - [About](#about)
16
+ - [Usage](#usage)
17
+ - [Installing](#installing)
18
+ - [Credentials](#credentials)
19
+ - [Documentation](#documentation)
20
+ - [API](#api)
21
+ - [Examples](#examples)
22
+ - [Data Modeling](#data-modeling)
23
+ - [Graph Theory](#graph-theory)
24
+ - [Channel](#channel)
25
+ - [Forward](#forward)
26
+ - [Payment](#payment)
27
+ - [Development](#development)
28
+ - [Publish to RubyGems](#publish-to-rubygems)
29
+
30
+ ## About
31
+
32
+ _Lighstorm_ is an opinionated abstraction layer on top of the [lnd-client](https://github.com/icebaker/lnd-client).
33
+
34
+ It brings an [object-oriented](https://en.wikipedia.org/wiki/Object-oriented_programming) approach for interacting with a [Lightning Node](https://github.com/lightningnetwork/lnd), influenced by the [Active Record Pattern](https://www.martinfowler.com/eaaCatalog/activeRecord.html) and [Active Record Models](https://guides.rubyonrails.org/active_record_basics.html) conventions.
35
+
36
+ Although it tries to stay close to [Lightning's terminologies](https://docs.lightning.engineering/lightning-network-tools/lnd), it brings its own vocabulary and data modeling, optimizing for [programmer happiness](https://rubyonrails.org/doctrine).
37
+
38
+ ## Usage
39
+
40
+ ### Installing
41
+
42
+ Add to your `Gemfile`:
43
+
44
+ ```ruby
45
+ gem 'lighstorm', '~> 0.0.1'
46
+ ```
47
+
48
+ Run `bundle install`.
49
+
50
+ ### Credentials
51
+
52
+ Set the following _Environment Variables_ or create a `.env` file:
53
+ ```bash
54
+ LIGHSTORM_LND_ADDRESS=127.0.0.1:10009
55
+ LIGHSTORM_CERTIFICATE_PATH=/lnd/tls.cert
56
+ LIGHSTORM_MACAROON_PATH=/lnd/data/chain/bitcoin/mainnet/admin.macaroon
57
+ ```
58
+
59
+ It will automatically load your credentials.
60
+
61
+ Alternatively, you can set the credentials at runtime:
62
+
63
+ ```ruby
64
+ require 'lighstorm'
65
+
66
+ Lighstorm.config!(
67
+ lnd_address: '127.0.0.1:10009',
68
+ certificate_path: '/lnd/tls.cert',
69
+ macaroon_path: '/lnd/data/chain/bitcoin/mainnet/admin.macaroon',
70
+ )
71
+
72
+ ```
73
+
74
+ ### Documentation
75
+
76
+ #### API
77
+
78
+ ```ruby
79
+ Lighstorm::Node
80
+
81
+ Lighstorm::Node.myself
82
+ Lighstorm::Node.find_by_public_key(
83
+ '02d3c80335a8ccb2ed364c06875f32240f36f7edb37d80f8dbe321b4c364b6e997'
84
+ )
85
+
86
+ node.to_h
87
+
88
+ node.channels
89
+
90
+ node.alias
91
+ node.public_key
92
+ node.color
93
+
94
+ node.platform.blockchain
95
+ node.platform.network
96
+ node.platform.lightning.implementation
97
+ node.platform.lightning.version
98
+
99
+ Lighstorm::Channel
100
+ Lighstorm::Channel.all
101
+ Lighstorm::Channel.first
102
+ Lighstorm::Channel.last
103
+ Lighstorm::Channel.find_by_id(850099509773795329)
104
+
105
+ channel.to_h
106
+
107
+ channel.id
108
+ channel.opened_at
109
+ channel.up_at
110
+ channel.active
111
+ channel.exposure
112
+
113
+ channel.accounting.capacity.milisatoshis
114
+ channel.accounting.sent.milisatoshis
115
+ channel.accounting.received.milisatoshis
116
+ channel.accounting.unsettled.milisatoshis
117
+
118
+ channel.partner.accounting.balance.milisatoshis
119
+ channel.partner.node.alias
120
+ channel.partner.node.public_key
121
+ channel.partner.node.color
122
+ channel.partner.policy.fee.base.milisatoshis
123
+ channel.partner.policy.fee.rate.parts_per_million
124
+
125
+ channel.myself.accounting.balance.milisatoshis
126
+ channel.myself.node.alias
127
+ channel.myself.node.public_key
128
+ channel.myself.node.color
129
+ channel.myself.policy.fee.base.milisatoshis
130
+ channel.myself.policy.fee.rate.parts_per_million
131
+
132
+ Lighstorm::Forward
133
+ Lighstorm::Forward.all
134
+ Lighstorm::Forward.first
135
+ Lighstorm::Forward.last
136
+ Lighstorm::Forward.all(limit: 10)
137
+
138
+ forward.to_h
139
+
140
+ forward.id
141
+ forward.at
142
+
143
+ forward.fee.milisatoshis
144
+ forward.fee.parts_per_million
145
+
146
+ forward.in.amount.milisatoshis
147
+
148
+ forward.in.channel.id
149
+ forward.in.channel.partner.node.alias
150
+ forward.in.channel.partner.node.public_key
151
+ forward.in.channel.partner.node.color
152
+
153
+ forward.out.channel.id
154
+ forward.out.channel.partner.node.alias
155
+ forward.out.channel.partner.node.public_key
156
+ forward.out.channel.partner.node.color
157
+
158
+ Lighstorm::Payment
159
+ Lighstorm::Payment.all
160
+ Lighstorm::Payment.first
161
+ Lighstorm::Payment.last
162
+ Lighstorm::Payment.all(limit: 10, purpose: 'rebalance', hops: false)
163
+
164
+ payment.id
165
+ payment.hash
166
+ payment.created_at
167
+ payment.purpose
168
+ payment.status
169
+ payment.amount.milisatoshis
170
+ payment.fee.milisatoshis
171
+ payment.fee.parts_per_million
172
+
173
+ payment.from.hop
174
+ payment.from.amount.milisatoshis
175
+ payment.from.fee.milisatoshis
176
+ payment.from.fee.parts_per_million
177
+ payment.from.channel.id
178
+ payment.from.channel.partner.node.alias
179
+ payment.from.channel.partner.node.public_key
180
+ payment.from.channel.partner.node.color
181
+
182
+ payment.to.hop
183
+ payment.to.amount.milisatoshis
184
+ payment.to.fee.milisatoshis
185
+ payment.to.fee.parts_per_million
186
+ payment.to.channel.id
187
+ payment.to.channel.partner.node.alias
188
+ payment.to.channel.partner.node.public_key
189
+ payment.to.channel.partner.node.color
190
+
191
+ payment.hops.size
192
+
193
+ payment.hops[0].hop
194
+ payment.hops[0].amount.milisatoshis
195
+ payment.hops[0].fee.milisatoshis
196
+ payment.hops[0].fee.parts_per_million
197
+ payment.hops[0].channel.id
198
+ payment.hops[0].channel.partner.node.alias
199
+ payment.hops[0].channel.partner.node.public_key
200
+ payment.hops[0].channel.partner.node.color
201
+
202
+ Lighstorm::Satoshis
203
+ Lighstorm::Satoshis.new(milisatoshis: 75621650)
204
+
205
+ satoshis.to_h
206
+
207
+ satoshis.milisatoshis
208
+ satoshis.satoshis
209
+ satoshis.bitcoins
210
+
211
+ satoshis.msats
212
+ satoshis.sats
213
+ satoshis.btc
214
+
215
+ reference_in_milisatoshis = 75_621_650_000
216
+ satoshis.parts_per_million(reference_in_milisatoshis)
217
+ ```
218
+
219
+ #### Examples
220
+
221
+ ```ruby
222
+ require 'lighstorm'
223
+
224
+ puts Lighstorm.version # => 0.0.1
225
+
226
+ Lighstorm::Satoshis.new(
227
+ milisatoshis: 75621650
228
+ ).satoshis # => 75621
229
+
230
+ Lighstorm::Node.myself.alias # => icebaker/old-stone
231
+ Lighstorm::Node.myself.public_key # => 02d3...e997
232
+
233
+ Lighstorm::Node.myself.to_h #> { ... }
234
+
235
+ Lighstorm::Node.myself.channels.count # => 5
236
+
237
+ Lighstorm::Channel.all.first.partner.node.alias
238
+
239
+ forward = Lighstorm::Forward.all(limit: 10).first
240
+
241
+ forward.in.amount.milisatoshis # => 75621650
242
+ forward.in.amount.satoshis # => 75621
243
+ forward.in.amount.bitcoins # => 0.0007562165
244
+ forward.in.channel.partner.node.alias
245
+ forward.out.channel.partner.node.alias
246
+
247
+ forward.to_h # => { ... }
248
+
249
+ payment = Lighstorm::Payment.all.first
250
+
251
+ payment.from.channel.id # => 850099509773795329
252
+ payment.to.channel.id # => 821539695188246532
253
+ payment.amount.sats # => 957262
254
+ payment.hops.size # => 4
255
+ payment.hops.first.channel.partner.node.alias
256
+ ```
257
+
258
+ ### Data Modeling
259
+
260
+ #### Graph Theory
261
+
262
+ [Graphs](https://en.wikipedia.org/wiki/Graph_theory) provide a great representation to abstract the [Lightning Network](https://lightning.network) data.
263
+
264
+ So, we are going to think in terms of _Edges_, _Nodes_, and _Connections_:
265
+
266
+ ![This is an image describing Graphs and their terminologies.](https://raw.githubusercontent.com/icebaker/assets/main/lighstorm/graph-theory.png)
267
+
268
+ #### Channel
269
+
270
+ ```ruby
271
+ channel = Lighstorm::Channel.first
272
+
273
+ channel.id
274
+
275
+ channel.accounting.capacity.milisatoshis
276
+
277
+ channel.partner.accounting.balance.milisatoshis
278
+ channel.partner.node.alias
279
+ channel.partner.policy.fee.rate.parts_per_million
280
+
281
+ channel.myself.accounting.balance.milisatoshis
282
+ channel.myself.node.alias
283
+ channel.myself.policy.fee.rate.parts_per_million
284
+ ```
285
+
286
+ ![This is an image representing Channel as a graph.](https://raw.githubusercontent.com/icebaker/assets/main/lighstorm/graph-channel.png)
287
+
288
+ #### Forward
289
+
290
+ ```ruby
291
+ forward = Lighstorm::Forward.last
292
+
293
+ forward.at
294
+
295
+ forward.fee.parts_per_million
296
+
297
+ forward.in.amount.milisatoshis
298
+
299
+ forward.in.channel.id
300
+ forward.in.channel.partner.node.alias
301
+
302
+ forward.out.channel.id
303
+ forward.out.channel.partner.node.alias
304
+ ```
305
+
306
+ ![This is an image representing Forward as a graph.](https://raw.githubusercontent.com/icebaker/assets/main/lighstorm/graph-forward.png)
307
+
308
+ #### Payment
309
+
310
+ ```ruby
311
+ payment = Payment.last
312
+
313
+ payment.hash
314
+ payment.amount.milisatoshis
315
+
316
+ payment.from.hop
317
+ payment.from.amount.milisatoshis
318
+ payment.from.fee.milisatoshis
319
+ payment.from.channel.id
320
+ payment.from.channel.partner.node.alias
321
+
322
+ payment.to.hop
323
+ payment.to.amount.milisatoshis
324
+ payment.to.fee.milisatoshis
325
+ payment.to.channel.id
326
+ payment.to.channel.partner.node.alias
327
+
328
+ payment.hops[0].hop
329
+ payment.hops[0].amount.milisatoshis
330
+ payment.hops[0].fee.milisatoshis
331
+ payment.hops[0].channel.id
332
+ payment.hops[0].channel.partner.node.alias
333
+ ```
334
+
335
+ ![This is an image representing Payment as a graph.](https://raw.githubusercontent.com/icebaker/assets/main/lighstorm/graph-payment.png)
336
+
337
+ ## Development
338
+
339
+ ```ruby
340
+ # Gemfile
341
+ gem 'lighstorm', path: '/home/user/lighstorm'
342
+
343
+ # demo.rb
344
+ require 'lighstorm'
345
+
346
+ puts Lighstorm.version # => 0.0.1
347
+ ```
348
+
349
+ ```sh
350
+ bundle
351
+ rubocop -A
352
+ ```
353
+
354
+ ### Publish to RubyGems
355
+
356
+ ```sh
357
+ gem build lighstorm.gemspec
358
+
359
+ gem signin
360
+
361
+ gem push lighstorm-0.0.1.gem
362
+ ```
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'singleton'
4
+
5
+ require 'zache'
6
+
7
+ module Lighstorm
8
+ class Cache
9
+ include Singleton
10
+
11
+ attr_writer :config, :middleware
12
+
13
+ def self.for(...)
14
+ instance.for(...)
15
+ end
16
+
17
+ def initialize
18
+ @client = Zache.new
19
+ end
20
+
21
+ def for(key, ttl: 1, params: {}, &block)
22
+ key = build_key_for(key, params)
23
+
24
+ @client.get(key, lifetime: ttl) do
25
+ block.call
26
+ end
27
+ end
28
+
29
+ def build_key_for(key, params)
30
+ return key unless params.size.positive?
31
+
32
+ key_params = []
33
+ params.keys.sort.each do |param_key|
34
+ key_params << "#{param_key}:#{params[param_key]}"
35
+ end
36
+ "#{key}/#{key_params.sort.join(',')}"
37
+ end
38
+ end
39
+ end
data/components/lnd.rb ADDED
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'singleton'
4
+
5
+ require 'lnd-client'
6
+
7
+ module Lighstorm
8
+ class LND
9
+ include Singleton
10
+
11
+ attr_writer :config, :middleware
12
+
13
+ def initialize
14
+ @config = nil
15
+ @client = nil
16
+ @middleware = ->(_key, &block) { block.call }
17
+ end
18
+
19
+ def middleware(key, &block)
20
+ @middleware.call(key, &block)
21
+ end
22
+
23
+ def client
24
+ return @client if @client
25
+
26
+ raise 'missing credentials' if @config.nil? && ENV.fetch('LIGHSTORM_CERTIFICATE_PATH', nil).nil?
27
+
28
+ @client = if @config
29
+ create_client_from_config
30
+ else
31
+ create_client_from_environment_variables
32
+ end
33
+
34
+ @client.lightning(channel_args: { 'grpc.max_receive_message_length' => 1024 * 1024 * 50 })
35
+
36
+ @client
37
+ end
38
+
39
+ def create_client_from_config
40
+ LNDClient.new(
41
+ socket_address: @config[:lnd_address],
42
+ certificate_path: @config[:certificate_path],
43
+ macaroon_path: @config[:macaroon_path]
44
+ )
45
+ end
46
+
47
+ def create_client_from_environment_variables
48
+ LNDClient.new(
49
+ socket_address: ENV.fetch('LIGHSTORM_LND_ADDRESS', nil),
50
+ certificate_path: ENV.fetch('LIGHSTORM_CERTIFICATE_PATH', nil),
51
+ macaroon_path: ENV.fetch('LIGHSTORM_MACAROON_PATH', nil)
52
+ )
53
+ end
54
+ end
55
+ end
data/lighstorm.gemspec ADDED
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'static/spec'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = Lighstorm::Static::SPEC[:name]
7
+ spec.version = Lighstorm::Static::SPEC[:version]
8
+ spec.authors = [Lighstorm::Static::SPEC[:author]]
9
+
10
+ spec.summary = Lighstorm::Static::SPEC[:summary]
11
+ spec.description = Lighstorm::Static::SPEC[:description]
12
+
13
+ spec.homepage = Lighstorm::Static::SPEC[:github]
14
+
15
+ spec.license = Lighstorm::Static::SPEC[:license]
16
+
17
+ spec.required_ruby_version = Gem::Requirement.new('>= 3.0.0')
18
+
19
+ spec.metadata['allowed_push_host'] = 'https://rubygems.org'
20
+
21
+ spec.metadata['homepage_uri'] = spec.homepage
22
+ spec.metadata['source_code_uri'] = Lighstorm::Static::SPEC[:github]
23
+
24
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
25
+ `git ls-files -z`.split("\x0").reject do |f|
26
+ f.match(%r{\A(?:test|spec|features)/})
27
+ end
28
+ end
29
+
30
+ spec.require_paths = ['ports/dsl']
31
+
32
+ spec.add_dependency 'dotenv', '~> 2.8', '>= 2.8.1'
33
+ spec.add_dependency 'lnd-client', '~> 0.0.4'
34
+ spec.add_dependency 'zache', '~> 0.12.0'
35
+
36
+ spec.metadata['rubygems_mfa_required'] = 'true'
37
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../satoshis'
4
+
5
+ module Lighstorm
6
+ module Models
7
+ class ChannelNodeAccounting
8
+ def initialize(channel, node)
9
+ @channel = channel
10
+ @node = node
11
+ end
12
+
13
+ def balance
14
+ @balance ||= if @node.myself?
15
+ Satoshis.new(milisatoshis: (
16
+ @channel.data[:list_channels][:channels].first.local_balance.to_f * 1000.0
17
+ ))
18
+ else
19
+ Satoshis.new(milisatoshis: (
20
+ @channel.data[:list_channels][:channels].first.remote_balance.to_f * 1000.0
21
+ ))
22
+ end
23
+ end
24
+
25
+ def to_h
26
+ { balance: balance.to_h }
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Lighstorm
4
+ module Models
5
+ class Constraints
6
+ def initialize(channel, node)
7
+ @channel = channel
8
+ @node = node
9
+ end
10
+
11
+ def data
12
+ @data ||= if @node.myself?
13
+ @channel.data[:list_channels][:channels].first.local_constraints
14
+ else
15
+ @channel.data[:list_channels][:channels].first.remote_constraints
16
+ end
17
+ end
18
+
19
+ def to_h
20
+ data.to_h
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../satoshis'
4
+ require_relative '../../rate'
5
+
6
+ module Lighstorm
7
+ module Models
8
+ class Fee
9
+ def initialize(policy, channel, node)
10
+ if node.myself?
11
+ @base = Satoshis.new(
12
+ milisatoshis: channel.data[:fee_report][:channel_fees].first.base_fee_msat
13
+ )
14
+
15
+ @rate = Rate.new(
16
+ parts_per_million: channel.data[:fee_report][:channel_fees].first.fee_per_mil
17
+ )
18
+ else
19
+ @base = Satoshis.new(milisatoshis: policy.data.fee_base_msat)
20
+
21
+ @rate = Rate.new(parts_per_million: policy.data.fee_rate_milli_msat)
22
+ end
23
+ end
24
+
25
+ def to_h
26
+ {
27
+ base: @base.to_h,
28
+ rate: @rate.to_h
29
+ }
30
+ end
31
+ end
32
+ end
33
+ end