lighstorm 0.0.7 → 0.0.9

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 (44) hide show
  1. checksums.yaml +4 -4
  2. data/.env.example +1 -0
  3. data/.gitignore +1 -0
  4. data/.rubocop.yml +1 -0
  5. data/Gemfile +5 -3
  6. data/Gemfile.lock +15 -10
  7. data/README.md +4 -3
  8. data/Rakefile +11 -0
  9. data/adapters/edges/payment/purpose.rb +22 -11
  10. data/adapters/edges/payment.rb +51 -12
  11. data/adapters/invoice.rb +139 -17
  12. data/components/cache.rb +7 -2
  13. data/controllers/forward/group_by_channel.rb +1 -1
  14. data/controllers/invoice/actions/create.rb +22 -6
  15. data/controllers/invoice/actions/pay.rb +71 -13
  16. data/controllers/invoice/all.rb +16 -6
  17. data/controllers/invoice/decode.rb +44 -0
  18. data/controllers/invoice/find_by_secret_hash.rb +7 -1
  19. data/controllers/invoice.rb +17 -3
  20. data/controllers/node/actions/pay.rb +109 -0
  21. data/controllers/payment/actions/pay.rb +104 -0
  22. data/controllers/payment/all.rb +49 -16
  23. data/controllers/transaction/all.rb +54 -0
  24. data/controllers/transaction.rb +13 -0
  25. data/deleted.sh +1 -0
  26. data/docs/README.md +292 -49
  27. data/docs/_coverpage.md +1 -1
  28. data/docs/index.html +1 -1
  29. data/helpers/time_expression.rb +33 -0
  30. data/models/connections/payment_channel.rb +13 -8
  31. data/models/edges/channel.rb +1 -1
  32. data/models/edges/payment.rb +51 -20
  33. data/models/errors.rb +29 -1
  34. data/models/invoice.rb +67 -11
  35. data/models/nodes/node.rb +32 -0
  36. data/models/satoshis.rb +11 -3
  37. data/models/secret.rb +31 -0
  38. data/models/transaction.rb +42 -0
  39. data/ports/dsl/lighstorm.rb +2 -0
  40. data/static/cache.rb +14 -13
  41. data/static/spec.rb +1 -1
  42. metadata +12 -4
  43. data/adapters/payment_request.rb +0 -87
  44. data/models/payment_request.rb +0 -72
data/docs/README.md CHANGED
@@ -27,7 +27,7 @@ Lighstorm::Channel.mine.first.myself.node.alias
27
27
  Add to your `Gemfile`:
28
28
 
29
29
  ```ruby
30
- gem 'lighstorm', '~> 0.0.7'
30
+ gem 'lighstorm', '~> 0.0.9'
31
31
  ```
32
32
 
33
33
  Run `bundle install`.
@@ -60,12 +60,24 @@ Lighstorm.config!(
60
60
  ```ruby
61
61
  require 'lighstorm'
62
62
 
63
- puts Lighstorm.version # => 0.0.7
63
+ puts Lighstorm.version # => 0.0.9
64
64
 
65
65
  Lighstorm::Invoice.create(
66
- description: 'Coffee', millisatoshis: 1000
66
+ description: 'Coffee', millisatoshis: 1000, payable: 'once'
67
67
  )
68
68
 
69
+ Lighstorm::Invoice.decode(
70
+ 'lnbc20m1pv...qqdhhwkj'
71
+ ).pay
72
+
73
+ Lighstorm::Node.find_by_public_key(
74
+ '02d3c80335a8ccb2ed364c06875f32240f36f7edb37d80f8dbe321b4c364b6e997'
75
+ ).pay(millisatoshis: 1000)
76
+
77
+ Lighstorm::Node.find_by_public_key(
78
+ '02d3c80335a8ccb2ed364c06875f32240f36f7edb37d80f8dbe321b4c364b6e997'
79
+ ).send_message('Hello from Lighstorm!', millisatoshis: 1000)
80
+
69
81
  Lighstorm::Node.myself.alias # => icebaker/old-stone
70
82
  Lighstorm::Node.myself.public_key # => 02d3...e997
71
83
 
@@ -95,7 +107,7 @@ payment.hops.first.channel.partner.node.alias
95
107
 
96
108
  Lighstorm::Satoshis.new(
97
109
  millisatoshis: 75621650
98
- ).satoshis # => 75621
110
+ ).satoshis # => 75621.65
99
111
  ```
100
112
 
101
113
  # Data Modeling
@@ -146,7 +158,9 @@ forward = Lighstorm::Forward.last
146
158
  forward.at
147
159
 
148
160
  forward.fee.millisatoshis
149
- forward.fee.parts_per_million
161
+ forward.fee.parts_per_million(
162
+ forward.in.amount.millisatoshis
163
+ )
150
164
 
151
165
  forward.in.amount.millisatoshis
152
166
  forward.out.amount.millisatoshis
@@ -168,15 +182,15 @@ forward.out.channel.partner.node.alias
168
182
  ### Payment
169
183
 
170
184
  ```ruby
171
- payment = Payment.last
185
+ payment = Lighstorm::Payment.last
172
186
 
173
- payment.status
174
- payment.created_at
187
+ payment.at
188
+ payment.state
175
189
 
176
190
  # https://github.com/lightning/bolts/blob/master/11-payment-encoding.md
177
- payment.request.code # "lnbc20m1pv...qqdhhwkj"
191
+ payment.invoice.code # "lnbc20m1pv...qqdhhwkj"
178
192
 
179
- payment.request.amount.millisatoshis
193
+ payment.invoice.amount.millisatoshis
180
194
 
181
195
  payment.from.hop
182
196
  payment.from.amount.millisatoshis
@@ -239,6 +253,76 @@ node.platform.lightning.implementation
239
253
  node.platform.lightning.version
240
254
  ```
241
255
 
256
+ ### Pay
257
+
258
+ Read more about [_Spontaneous Payments_](https://docs.lightning.engineering/lightning-network-tools/lnd/send-messages-with-keysend#send-a-spontaneous-payment).
259
+
260
+ ```ruby
261
+ destination = Lighstorm::Node.find_by_public_key(
262
+ '02d3c80335a8ccb2ed364c06875f32240f36f7edb37d80f8dbe321b4c364b6e997'
263
+ )
264
+
265
+ destination.alias # => 'icebaker/old-stone'
266
+
267
+ destination.pay(millisatoshis: 1000)
268
+
269
+ destination.pay(
270
+ millisatoshis: 1500,
271
+ message: 'Hello from Lighstorm!',
272
+ through: 'amp',
273
+ times_out_in: { seconds: 5 }
274
+ )
275
+
276
+ destination.pay(
277
+ millisatoshis: 1200,
278
+ message: 'Hello from Lighstorm!',
279
+ through: 'keysend',
280
+ times_out_in: { seconds: 5 }
281
+ )
282
+
283
+ action = destination.pay(millisatoshis: 1000)
284
+ action.result.fee.millisatoshis
285
+ ```
286
+
287
+ ### Send Messages
288
+
289
+ **Warning:** Sending messages through Lightning Network requires you to spend satoshis and potentially pay fees.
290
+
291
+ ```ruby
292
+ destination = Lighstorm::Node.find_by_public_key(
293
+ '02d3c80335a8ccb2ed364c06875f32240f36f7edb37d80f8dbe321b4c364b6e997'
294
+ )
295
+
296
+ destination.alias # => 'icebaker/old-stone'
297
+
298
+ destination.send_message('Hello from Lighstorm!', millisatoshis: 1000)
299
+
300
+ destination.send_message(
301
+ 'Hello from Lighstorm!',
302
+ millisatoshis: 1000,
303
+ through: 'amp',
304
+ times_out_in: { seconds: 5 }
305
+ )
306
+
307
+ destination.send_message(
308
+ 'Hello from Lighstorm!',
309
+ millisatoshis: 1000,
310
+ through: 'keysend',
311
+ times_out_in: { seconds: 5 }
312
+ )
313
+
314
+ action = destination.send_message('Hello from Lighstorm!', millisatoshis: 1000)
315
+ action.result.fee.millisatoshis
316
+ ```
317
+
318
+ Read more about sending messages:
319
+ - [_Send a message to other nodes_](https://docs.lightning.engineering/lightning-network-tools/lnd/send-messages-with-keysend#send-a-message-to-other-nodes)
320
+ - [_Does Private messaging over Bitcoin’s Lightning Network have potential?_](https://cryptopurview.com/private-messaging-over-bitcoins-lightning-network/)
321
+ - [_How Bitcoin's Lightning Can Be Used for Private Messaging_](https://www.coindesk.com/markets/2019/11/09/how-bitcoins-lightning-can-be-used-for-private-messaging/)
322
+
323
+ ### Error Handling
324
+ Same error handling used for [Invoices Payment Errors](?id=error-handling-1)
325
+
242
326
  ## Channel
243
327
 
244
328
  [![This is an image representing Channel as a graph.](https://raw.githubusercontent.com/icebaker/assets/main/lighstorm/graph-channel.png)](https://raw.githubusercontent.com/icebaker/assets/main/lighstorm/graph-channel.png)
@@ -360,6 +444,8 @@ Lighstorm::Invoice.all(limit: 10)
360
444
  Lighstorm::Invoice.first
361
445
  Lighstorm::Invoice.last
362
446
 
447
+ Lighstorm::Invoice.decode('lnbc20n1pj...0eqps7h0k9')
448
+
363
449
  Lighstorm::Invoice.find_by_secret_hash(
364
450
  '1d438b8100518c9fba0a607e3317d6b36f74ceef3a6591836eb2f679c6853501'
365
451
  )
@@ -371,23 +457,24 @@ Lighstorm::Invoice.find_by_secret_hash(
371
457
  invoice._key
372
458
 
373
459
  invoice.created_at
374
- invoice.settle_at
460
+ invoice.expires_at
461
+ invoice.settled_at
375
462
 
376
463
  invoice.state
377
464
 
378
465
  # https://github.com/lightning/bolts/blob/master/11-payment-encoding.md
379
- invoice.request.code # "lnbc20m1pv...qqdhhwkj"
466
+ invoice.code # "lnbc20m1pv...qqdhhwkj"
380
467
 
381
- invoice.request.amount.millisatoshis
468
+ invoice.amount.millisatoshis
382
469
 
383
- invoice.request.description.memo
384
- invoice.request.description.hash
470
+ invoice.payable # 'once' or 'indefinitely'
385
471
 
386
- # https://docs.lightning.engineering/the-lightning-network/multihop-payments
387
- invoice.request.secret.preimage
388
- invoice.request.secret.hash
472
+ invoice.description.memo
473
+ invoice.description.hash
389
474
 
390
- invoice.request.address
475
+ # https://docs.lightning.engineering/the-lightning-network/multihop-payments
476
+ invoice.secret.preimage
477
+ invoice.secret.hash
391
478
  ```
392
479
 
393
480
  ### Create
@@ -398,11 +485,27 @@ invoice.request.address
398
485
  # 'preview' let you check the expected operation
399
486
  # before actually performing it for debug purposes
400
487
  preview = Lighstorm::Invoice.create(
401
- description: 'Coffee', millisatoshis: 1000, preview: true
488
+ description: 'Coffee', millisatoshis: 1000,
489
+ payable: 'once', preview: true
490
+ )
491
+
492
+ action = Lighstorm::Invoice.create(
493
+ description: 'Coffee', millisatoshis: 1000,
494
+ payable: 'once', expires_in: { minutes: 5 }
495
+ )
496
+
497
+ action = Lighstorm::Invoice.create(
498
+ description: 'Beer', payable: 'once'
402
499
  )
403
500
 
404
501
  action = Lighstorm::Invoice.create(
405
- description: 'Piña Colada', millisatoshis: 1000
502
+ description: 'Donations', payable: 'indefinitely',
503
+ expires_in: { hours: 24 }
504
+ )
505
+
506
+ action = Lighstorm::Invoice.create(
507
+ description: 'Concert Ticket', millisatoshis: 500000000,
508
+ payable: 'indefinitely', expires_in: { days: 5 }
406
509
  )
407
510
 
408
511
  action.to_h
@@ -411,6 +514,101 @@ action.response
411
514
  invoice = action.result
412
515
  ```
413
516
 
517
+ ### Pay
518
+
519
+ [Understanding Lightning Invoices](https://docs.lightning.engineering/the-lightning-network/payment-lifecycle/understanding-lightning-invoices)
520
+
521
+ ```ruby
522
+ invoice = Lighstorm::Invoice.decode('lnbc20m1pv...qqdhhwkj')
523
+
524
+ # 'preview' let you check the expected operation
525
+ # before actually performing it for debug purposes
526
+ invoice.pay(preview: true)
527
+
528
+ action = invoice.pay
529
+
530
+ action.to_h
531
+
532
+ action.response
533
+ payment = action.result
534
+
535
+ payment.at
536
+ payment.state
537
+
538
+ payment.amount.millisatoshis
539
+ payment.fee.millisatoshis
540
+ payment.fee.parts_per_million(
541
+ payment.amount.millisatoshis
542
+ )
543
+
544
+ payment.purpose
545
+ payment.hops.size
546
+ ```
547
+
548
+ ```ruby
549
+ invoice.pay(
550
+ millisatoshis: 1500,
551
+ message: 'here we go',
552
+ times_out_in: { seconds: 5 }
553
+ )
554
+ ```
555
+
556
+ #### Error Handling
557
+ Check [Error Handling](?id=error-handling-2)
558
+
559
+ ```ruby
560
+ begin
561
+ invoice.pay
562
+ rescue AlreadyPaidError => error
563
+ error.message # 'The invoice is already paid.'
564
+ error.grpc.class # GRPC::AlreadyExists
565
+ error.grpc.message # '6:invoice is already paid. debug_error_string:{UNKNOWN...'
566
+ end
567
+ ```
568
+
569
+ ```ruby
570
+ begin
571
+ invoice.pay(millisatoshis: 1000)
572
+ rescue AmountForNonZeroError => error
573
+ error.message # 'Millisatoshis must not be specified...'
574
+ error.grpc.class # GRPC::Unknown
575
+ error.grpc.message # '2:amount must not be specified when paying...'
576
+ end
577
+ ```
578
+
579
+ ```ruby
580
+ begin
581
+ invoice.pay
582
+ rescue MissingMillisatoshisError => error
583
+ error.message # 'Millisatoshis must be specified...'
584
+ error.grpc.class # GRPC::Unknown
585
+ error.grpc.message # '2:amount must be specified when paying a zero...'
586
+ end
587
+ ```
588
+
589
+ ```ruby
590
+ begin
591
+ invoice.pay
592
+ rescue NoRouteFoundError => error
593
+ error.message # 'FAILURE_REASON_NO_ROUTE'
594
+ e.response
595
+ e.response.last[:failure_reason] # => :FAILURE_REASON_NO_ROUTE
596
+ end
597
+ ```
598
+
599
+
600
+ ```ruby
601
+ begin
602
+ invoice.pay
603
+ rescue PaymentError => error
604
+ error.class
605
+ error.message
606
+
607
+ error.grpc
608
+ error.response
609
+ error.result
610
+ end
611
+ ```
414
612
  ## Payment
415
613
 
416
614
  [![This is an image representing Payment as a graph.](https://raw.githubusercontent.com/icebaker/assets/main/lighstorm/graph-payment.png)](https://raw.githubusercontent.com/icebaker/assets/main/lighstorm/graph-payment.png)
@@ -428,7 +626,8 @@ Lighstorm::Payment.last
428
626
  Lighstorm::Payment.all(limit: 10, purpose: 'rebalance')
429
627
 
430
628
  # Possible Purposes:
431
- ['self-payment', 'peer-to-peer', 'rebalance', 'payment']
629
+ # 'self-payment', 'peer-to-peer',
630
+ # 'rebalance', 'payment'
432
631
 
433
632
  # _key is helpful for reactive javascript frameworks.
434
633
  # Please don't consider it as a unique identifier
@@ -438,34 +637,53 @@ payment._key
438
637
 
439
638
  payment.to_h
440
639
 
441
- payment.status
442
- payment.created_at
443
- payment.settled_at
444
- payment.purpose
640
+ payment.at
641
+
642
+ payment.amount.millisatoshis
445
643
 
446
644
  payment.fee.millisatoshis
447
645
  payment.fee.parts_per_million(
448
- payment.request.amount.millisatoshis
646
+ payment.amount.millisatoshis
449
647
  )
450
648
 
451
- # https://github.com/lightning/bolts/blob/master/11-payment-encoding.md
452
- payment.request.code # "lnbc20m1pv...qqdhhwkj"
649
+ payment.state
650
+ payment.message
453
651
 
454
- payment.request.amount.millisatoshis
652
+ payment.how # 'spontaneously', 'with-invoice'
653
+ payment.through # 'keysend', 'amp', 'non-amp'
654
+ payment.purpose
655
+ # 'self-payment', 'peer-to-peer',
656
+ # 'rebalance', 'payment'
455
657
 
456
658
  # https://docs.lightning.engineering/the-lightning-network/multihop-payments
457
- payment.request.secret.preimage
458
- payment.request.secret.hash
659
+ payment.secret.preimage
660
+ payment.secret.hash
661
+
662
+ payment.invoice.created_at
663
+ payment.invoice.expires_at
664
+ payment.invoice.settled_at
459
665
 
460
- payment.request.address
666
+ payment.invoice.state
667
+
668
+ # https://github.com/lightning/bolts/blob/master/11-payment-encoding.md
669
+ payment.invoice.code # "lnbc20m1pv...qqdhhwkj"
670
+ payment.invoice.amount.millisatoshis
461
671
 
462
- payment.request.description.memo
463
- payment.request.description.hash
672
+ payment.invoice.payable # 'once', 'indefinitely'
673
+
674
+ payment.invoice.description.memo
675
+ payment.invoice.description.hash
676
+
677
+ # https://docs.lightning.engineering/the-lightning-network/multihop-payments
678
+ payment.invoice.secret.preimage
679
+ payment.invoice.secret.hash
464
680
 
465
681
  payment.from.hop
466
682
  payment.from.amount.millisatoshis
467
683
  payment.from.fee.millisatoshis
468
- payment.from.fee.parts_per_million(payment.from.amount.millisatoshis)
684
+ payment.from.fee.parts_per_million(
685
+ payment.from.amount.millisatoshis
686
+ )
469
687
 
470
688
  payment.from.channel.id
471
689
 
@@ -480,7 +698,9 @@ payment.from.channel.exit.color
480
698
  payment.to.hop
481
699
  payment.to.amount.millisatoshis
482
700
  payment.to.fee.millisatoshis
483
- payment.to.fee.parts_per_million(payment.to.amount.millisatoshis)
701
+ payment.to.fee.parts_per_million(
702
+ payment.to.amount.millisatoshis
703
+ )
484
704
 
485
705
  payment.to.channel.id
486
706
 
@@ -500,7 +720,9 @@ payment.hops[0].last?
500
720
  payment.hops[0].hop
501
721
  payment.hops[0].amount.millisatoshis
502
722
  payment.hops[0].fee.millisatoshis
503
- payment.hops[0].fee.parts_per_million(payment.hops[0].amount.millisatoshis)
723
+ payment.hops[0].fee.parts_per_million(
724
+ payment.hops[0].amount.millisatoshis
725
+ )
504
726
 
505
727
  payment.hops[0].channel.id
506
728
 
@@ -664,6 +886,7 @@ Lighstorm::Channel.adapt(dump: channel.dump)
664
886
 
665
887
  ```ruby
666
888
  Lighstorm::Satoshis
889
+ Lighstorm::Satoshis.new(bitcoins: 0.005)
667
890
  Lighstorm::Satoshis.new(millisatoshis: 75621650)
668
891
 
669
892
  satoshis.to_h
@@ -734,24 +957,26 @@ end
734
957
  ```ruby
735
958
  LighstormError
736
959
 
960
+ ArgumentError
737
961
  IncoherentGossipError
738
-
739
- TooManyArgumentsError
740
962
  MissingCredentialsError
741
963
  MissingGossipHandlerError
742
- MissingMillisatoshisError
743
964
  MissingPartsPerMillionError
744
- MissingTTLError
745
-
746
965
  NegativeNotAllowedError
747
-
748
966
  NotYourChannelError
749
967
  NotYourNodeError
750
- UnknownChannelError
751
-
752
968
  OperationNotAllowedError
969
+ TooManyArgumentsError
753
970
  UnexpectedNumberOfHTLCsError
971
+ UnknownChannelError
754
972
  UpdateChannelPolicyError
973
+
974
+ PaymentError
975
+
976
+ AlreadyPaidError
977
+ AmountForNonZeroError
978
+ MissingMillisatoshisError
979
+ NoRouteFoundError
755
980
  ```
756
981
 
757
982
  # Development
@@ -765,7 +990,7 @@ gem 'lighstorm', path: '/home/user/lighstorm'
765
990
  # demo.rb
766
991
  require 'lighstorm'
767
992
 
768
- puts Lighstorm.version # => 0.0.7
993
+ puts Lighstorm.version # => 0.0.9
769
994
  ```
770
995
 
771
996
  ```sh
@@ -967,6 +1192,24 @@ expected: nil
967
1192
 
968
1193
  Remember to undo it afterward, replacing `expect!` with `expect`.
969
1194
 
1195
+ ### Extra Tips for Testing
1196
+
1197
+ To auto-fix contracts:
1198
+
1199
+ ```sh
1200
+ rspec --format json | bundle exec rake contracts:fix
1201
+ ```
1202
+
1203
+ To delete unused test data files, update the `.env` file:
1204
+ ```sh
1205
+ LIGHSTORM_DELETE_UNUSED_TEST_DATA=true
1206
+ ```
1207
+
1208
+ Deletion will only occur if you run all tests and no failures are found:
1209
+ ```ruby
1210
+ bundle exec rspec
1211
+ ```
1212
+
970
1213
  ## Generating Documentation
971
1214
 
972
1215
  ```sh
@@ -982,13 +1225,13 @@ gem build lighstorm.gemspec
982
1225
 
983
1226
  gem signin
984
1227
 
985
- gem push lighstorm-0.0.7.gem
1228
+ gem push lighstorm-0.0.9.gem
986
1229
  ```
987
1230
 
988
1231
  _________________
989
1232
 
990
1233
  <center>
991
- lighstorm 0.0.7
1234
+ lighstorm 0.0.9
992
1235
  |
993
1236
  <a href="https://github.com/icebaker/lighstorm" rel="noopener noreferrer" target="_blank">GitHub</a>
994
1237
  |
data/docs/_coverpage.md CHANGED
@@ -8,7 +8,7 @@
8
8
  - Built for maximum **reliability**.
9
9
  - Optimized for programmer **happiness**.
10
10
 
11
- 0.0.7
11
+ 0.0.9
12
12
 
13
13
  ⚠️ _Warning: Early-stage, breaking changes are expected._
14
14
 
data/docs/index.html CHANGED
@@ -18,7 +18,7 @@
18
18
  <script>
19
19
  window.$docsify = {
20
20
  coverpage: true,
21
- name: 'Lighstorm 0.0.7',
21
+ name: 'Lighstorm 0.0.9',
22
22
  repo: 'https://github.com/icebaker/lighstorm'
23
23
  }
24
24
  </script>
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../models/errors'
4
+
5
+ module Lighstorm
6
+ module Helpers
7
+ module TimeExpression
8
+ def self.seconds(expression)
9
+ raise Errors::ArgumentError, 'missing keywords for time expression' unless expression.is_a?(Hash)
10
+
11
+ duration = 0.0
12
+ expression.each_key do |key|
13
+ case key
14
+ when :seconds
15
+ duration += expression[key].to_f
16
+ when :minutes
17
+ duration += (expression[key].to_f * 60.0)
18
+ when :hours
19
+ duration += (expression[key].to_f * 60.0 * 60.0)
20
+ when :days
21
+ duration += (expression[key].to_f * 24.0 * 60.0 * 60.0)
22
+ else
23
+ raise Errors::ArgumentError, "unexpected keyword :#{key} for time expression #{expression}"
24
+ end
25
+ end
26
+
27
+ raise Errors::ArgumentError, 'missing keywords for time expression' if expression.keys.empty?
28
+
29
+ duration.to_i
30
+ end
31
+ end
32
+ end
33
+ end
@@ -24,11 +24,11 @@ module Lighstorm
24
24
  end
25
25
 
26
26
  def amount
27
- @amount ||= Satoshis.new(millisatoshis: @data[:amount][:millisatoshis])
27
+ @amount ||= @data[:amount] ? Satoshis.new(millisatoshis: @data[:amount][:millisatoshis]) : nil
28
28
  end
29
29
 
30
30
  def fee
31
- @fee ||= Satoshis.new(millisatoshis: @data[:fee][:millisatoshis])
31
+ @fee ||= @data[:fee] ? Satoshis.new(millisatoshis: @data[:fee][:millisatoshis]) : nil
32
32
  end
33
33
 
34
34
  def channel
@@ -36,15 +36,20 @@ module Lighstorm
36
36
  end
37
37
 
38
38
  def to_h
39
- {
39
+ result = {
40
40
  hop: hop,
41
- amount: amount.to_h,
42
- fee: {
43
- millisatoshis: fee.millisatoshis,
44
- parts_per_million: fee.parts_per_million(amount.millisatoshis)
45
- },
46
41
  channel: channel.to_h
47
42
  }
43
+
44
+ result[:amount] = amount.to_h if amount
45
+ if fee
46
+ result[:fee] = {
47
+ millisatoshis: fee.millisatoshis,
48
+ parts_per_million: fee.parts_per_million(amount.millisatoshis)
49
+ }
50
+ end
51
+
52
+ result
48
53
  end
49
54
  end
50
55
  end
@@ -9,7 +9,7 @@ require_relative '../../components/lnd'
9
9
  require_relative '../../components/cache'
10
10
 
11
11
  require_relative '../nodes/node'
12
- require_relative 'channel/accounting'
12
+ require_relative './channel/accounting'
13
13
 
14
14
  require_relative '../../controllers/channel/actions/apply_gossip'
15
15
  require_relative '../connections/channel_node'