lighstorm 0.0.8 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
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.8'
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.8
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)
@@ -373,23 +457,24 @@ Lighstorm::Invoice.find_by_secret_hash(
373
457
  invoice._key
374
458
 
375
459
  invoice.created_at
376
- invoice.settle_at
460
+ invoice.expires_at
461
+ invoice.settled_at
377
462
 
378
463
  invoice.state
379
464
 
380
465
  # https://github.com/lightning/bolts/blob/master/11-payment-encoding.md
381
- invoice.request.code # "lnbc20m1pv...qqdhhwkj"
466
+ invoice.code # "lnbc20m1pv...qqdhhwkj"
382
467
 
383
- invoice.request.amount.millisatoshis
468
+ invoice.amount.millisatoshis
384
469
 
385
- invoice.request.description.memo
386
- invoice.request.description.hash
470
+ invoice.payable # 'once' or 'indefinitely'
387
471
 
388
- # https://docs.lightning.engineering/the-lightning-network/multihop-payments
389
- invoice.request.secret.preimage
390
- invoice.request.secret.hash
472
+ invoice.description.memo
473
+ invoice.description.hash
391
474
 
392
- invoice.request.address
475
+ # https://docs.lightning.engineering/the-lightning-network/multihop-payments
476
+ invoice.secret.preimage
477
+ invoice.secret.hash
393
478
  ```
394
479
 
395
480
  ### Create
@@ -400,11 +485,27 @@ invoice.request.address
400
485
  # 'preview' let you check the expected operation
401
486
  # before actually performing it for debug purposes
402
487
  preview = Lighstorm::Invoice.create(
403
- 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 }
404
495
  )
405
496
 
406
497
  action = Lighstorm::Invoice.create(
407
- description: 'Piña Colada', millisatoshis: 1000
498
+ description: 'Beer', payable: 'once'
499
+ )
500
+
501
+ action = Lighstorm::Invoice.create(
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 }
408
509
  )
409
510
 
410
511
  action.to_h
@@ -413,6 +514,101 @@ action.response
413
514
  invoice = action.result
414
515
  ```
415
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
+ ```
416
612
  ## Payment
417
613
 
418
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)
@@ -430,7 +626,8 @@ Lighstorm::Payment.last
430
626
  Lighstorm::Payment.all(limit: 10, purpose: 'rebalance')
431
627
 
432
628
  # Possible Purposes:
433
- ['self-payment', 'peer-to-peer', 'rebalance', 'payment']
629
+ # 'self-payment', 'peer-to-peer',
630
+ # 'rebalance', 'payment'
434
631
 
435
632
  # _key is helpful for reactive javascript frameworks.
436
633
  # Please don't consider it as a unique identifier
@@ -440,34 +637,53 @@ payment._key
440
637
 
441
638
  payment.to_h
442
639
 
443
- payment.status
444
- payment.created_at
445
- payment.settled_at
446
- payment.purpose
640
+ payment.at
641
+
642
+ payment.amount.millisatoshis
447
643
 
448
644
  payment.fee.millisatoshis
449
645
  payment.fee.parts_per_million(
450
- payment.request.amount.millisatoshis
646
+ payment.amount.millisatoshis
451
647
  )
452
648
 
453
- # https://github.com/lightning/bolts/blob/master/11-payment-encoding.md
454
- payment.request.code # "lnbc20m1pv...qqdhhwkj"
649
+ payment.state
650
+ payment.message
455
651
 
456
- 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'
457
657
 
458
658
  # https://docs.lightning.engineering/the-lightning-network/multihop-payments
459
- payment.request.secret.preimage
460
- 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
461
665
 
462
- 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
463
671
 
464
- payment.request.description.memo
465
- 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
466
680
 
467
681
  payment.from.hop
468
682
  payment.from.amount.millisatoshis
469
683
  payment.from.fee.millisatoshis
470
- payment.from.fee.parts_per_million(payment.from.amount.millisatoshis)
684
+ payment.from.fee.parts_per_million(
685
+ payment.from.amount.millisatoshis
686
+ )
471
687
 
472
688
  payment.from.channel.id
473
689
 
@@ -482,7 +698,9 @@ payment.from.channel.exit.color
482
698
  payment.to.hop
483
699
  payment.to.amount.millisatoshis
484
700
  payment.to.fee.millisatoshis
485
- payment.to.fee.parts_per_million(payment.to.amount.millisatoshis)
701
+ payment.to.fee.parts_per_million(
702
+ payment.to.amount.millisatoshis
703
+ )
486
704
 
487
705
  payment.to.channel.id
488
706
 
@@ -502,7 +720,9 @@ payment.hops[0].last?
502
720
  payment.hops[0].hop
503
721
  payment.hops[0].amount.millisatoshis
504
722
  payment.hops[0].fee.millisatoshis
505
- 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
+ )
506
726
 
507
727
  payment.hops[0].channel.id
508
728
 
@@ -666,6 +886,7 @@ Lighstorm::Channel.adapt(dump: channel.dump)
666
886
 
667
887
  ```ruby
668
888
  Lighstorm::Satoshis
889
+ Lighstorm::Satoshis.new(bitcoins: 0.005)
669
890
  Lighstorm::Satoshis.new(millisatoshis: 75621650)
670
891
 
671
892
  satoshis.to_h
@@ -736,24 +957,26 @@ end
736
957
  ```ruby
737
958
  LighstormError
738
959
 
960
+ ArgumentError
739
961
  IncoherentGossipError
740
-
741
- TooManyArgumentsError
742
962
  MissingCredentialsError
743
963
  MissingGossipHandlerError
744
- MissingMillisatoshisError
745
964
  MissingPartsPerMillionError
746
- MissingTTLError
747
-
748
965
  NegativeNotAllowedError
749
-
750
966
  NotYourChannelError
751
967
  NotYourNodeError
752
- UnknownChannelError
753
-
754
968
  OperationNotAllowedError
969
+ TooManyArgumentsError
755
970
  UnexpectedNumberOfHTLCsError
971
+ UnknownChannelError
756
972
  UpdateChannelPolicyError
973
+
974
+ PaymentError
975
+
976
+ AlreadyPaidError
977
+ AmountForNonZeroError
978
+ MissingMillisatoshisError
979
+ NoRouteFoundError
757
980
  ```
758
981
 
759
982
  # Development
@@ -767,7 +990,7 @@ gem 'lighstorm', path: '/home/user/lighstorm'
767
990
  # demo.rb
768
991
  require 'lighstorm'
769
992
 
770
- puts Lighstorm.version # => 0.0.8
993
+ puts Lighstorm.version # => 0.0.9
771
994
  ```
772
995
 
773
996
  ```sh
@@ -969,6 +1192,24 @@ expected: nil
969
1192
 
970
1193
  Remember to undo it afterward, replacing `expect!` with `expect`.
971
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
+
972
1213
  ## Generating Documentation
973
1214
 
974
1215
  ```sh
@@ -984,13 +1225,13 @@ gem build lighstorm.gemspec
984
1225
 
985
1226
  gem signin
986
1227
 
987
- gem push lighstorm-0.0.8.gem
1228
+ gem push lighstorm-0.0.9.gem
988
1229
  ```
989
1230
 
990
1231
  _________________
991
1232
 
992
1233
  <center>
993
- lighstorm 0.0.8
1234
+ lighstorm 0.0.9
994
1235
  |
995
1236
  <a href="https://github.com/icebaker/lighstorm" rel="noopener noreferrer" target="_blank">GitHub</a>
996
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.8
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.8',
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'