lighstorm 0.0.8 → 0.0.10
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 +4 -4
- data/.env.example +1 -0
- data/.gitignore +1 -0
- data/.rubocop.yml +1 -0
- data/Gemfile +5 -3
- data/Gemfile.lock +13 -8
- data/README.md +11 -3
- data/Rakefile +11 -0
- data/adapters/edges/payment/purpose.rb +22 -11
- data/adapters/edges/payment.rb +51 -12
- data/adapters/invoice.rb +133 -31
- data/components/cache.rb +7 -2
- data/controllers/forward/group_by_channel.rb +1 -1
- data/controllers/invoice/actions/create.rb +22 -6
- data/controllers/invoice/actions/pay.rb +79 -13
- data/controllers/invoice/all.rb +16 -6
- data/controllers/invoice/decode.rb +6 -6
- data/controllers/invoice/find_by_secret_hash.rb +7 -1
- data/controllers/invoice.rb +15 -6
- data/controllers/node/actions/pay.rb +114 -0
- data/controllers/payment/actions/pay.rb +104 -0
- data/controllers/payment/all.rb +79 -28
- data/controllers/transaction/all.rb +54 -0
- data/controllers/transaction.rb +13 -0
- data/deleted.sh +1 -0
- data/docs/README.md +307 -51
- data/docs/_coverpage.md +1 -1
- data/docs/index.html +1 -1
- data/helpers/time_expression.rb +33 -0
- data/models/connections/payment_channel.rb +13 -8
- data/models/edges/channel.rb +1 -1
- data/models/edges/payment.rb +51 -20
- data/models/errors.rb +29 -1
- data/models/invoice.rb +69 -11
- data/models/nodes/node.rb +35 -0
- data/models/satoshis.rb +11 -3
- data/models/secret.rb +37 -0
- data/models/transaction.rb +42 -0
- data/ports/dsl/lighstorm.rb +2 -0
- data/static/cache.rb +14 -13
- data/static/spec.rb +1 -1
- metadata +11 -4
- data/adapters/payment_request.rb +0 -87
- data/models/payment_request.rb +0 -72
@@ -0,0 +1,54 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../invoice/all'
|
4
|
+
require_relative '../../models/transaction'
|
5
|
+
|
6
|
+
module Lighstorm
|
7
|
+
module Controllers
|
8
|
+
module Transaction
|
9
|
+
module All
|
10
|
+
def self.fetch(limit: nil)
|
11
|
+
transactions = []
|
12
|
+
|
13
|
+
Invoice::All.data(spontaneous: true).filter do |invoice|
|
14
|
+
!invoice[:payments].nil? && invoice[:payments].size.positive?
|
15
|
+
end.each do |invoice|
|
16
|
+
invoice[:payments].each do |payment|
|
17
|
+
transactions << {
|
18
|
+
direction: 'in',
|
19
|
+
at: payment[:at],
|
20
|
+
amount: payment[:amount],
|
21
|
+
message: payment[:message],
|
22
|
+
kind: 'invoice',
|
23
|
+
data: invoice
|
24
|
+
}
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
transactions = transactions.sort_by { |transaction| -transaction[:at].to_i }
|
29
|
+
|
30
|
+
transactions = transactions[0..limit - 1] unless limit.nil?
|
31
|
+
|
32
|
+
{ transactions: transactions }
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.transform(raw)
|
36
|
+
raw[:transactions].map do |transaction|
|
37
|
+
transaction[:_key] = SecureRandom.hex
|
38
|
+
transaction
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.data(limit: nil, &vcr)
|
43
|
+
raw = vcr.nil? ? fetch(limit: limit) : vcr.call(-> { fetch(limit: limit) })
|
44
|
+
|
45
|
+
transform(raw)
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.model(data)
|
49
|
+
data.map { |data| Models::Transaction.new(data) }
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
data/deleted.sh
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
deleted.sh
|
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.
|
30
|
+
gem 'lighstorm', '~> 0.0.10'
|
31
31
|
```
|
32
32
|
|
33
33
|
Run `bundle install`.
|
@@ -60,12 +60,26 @@ Lighstorm.config!(
|
|
60
60
|
```ruby
|
61
61
|
require 'lighstorm'
|
62
62
|
|
63
|
-
puts Lighstorm.version # => 0.0.
|
63
|
+
puts Lighstorm.version # => 0.0.10
|
64
64
|
|
65
65
|
Lighstorm::Invoice.create(
|
66
|
-
description: 'Coffee', millisatoshis: 1000
|
66
|
+
description: 'Coffee', amount: { millisatoshis: 1000 }, payable: 'once'
|
67
67
|
)
|
68
68
|
|
69
|
+
Lighstorm::Invoice.decode('lnbc20m1pv...qqdhhwkj').pay
|
70
|
+
|
71
|
+
Lighstorm::Invoice.decode('lnbc20m1pv...qqdhhwkj').pay(
|
72
|
+
fee: { maximum: { millisatoshis: 1000 } }
|
73
|
+
)
|
74
|
+
|
75
|
+
Lighstorm::Node.find_by_public_key(
|
76
|
+
'02d3c80335a8ccb2ed364c06875f32240f36f7edb37d80f8dbe321b4c364b6e997'
|
77
|
+
).pay(amount: { millisatoshis: 1000 })
|
78
|
+
|
79
|
+
Lighstorm::Node.find_by_public_key(
|
80
|
+
'02d3c80335a8ccb2ed364c06875f32240f36f7edb37d80f8dbe321b4c364b6e997'
|
81
|
+
).send_message('Hello from Lighstorm!', amount: { millisatoshis: 1000 })
|
82
|
+
|
69
83
|
Lighstorm::Node.myself.alias # => icebaker/old-stone
|
70
84
|
Lighstorm::Node.myself.public_key # => 02d3...e997
|
71
85
|
|
@@ -95,7 +109,7 @@ payment.hops.first.channel.partner.node.alias
|
|
95
109
|
|
96
110
|
Lighstorm::Satoshis.new(
|
97
111
|
millisatoshis: 75621650
|
98
|
-
).satoshis # => 75621
|
112
|
+
).satoshis # => 75621.65
|
99
113
|
```
|
100
114
|
|
101
115
|
# Data Modeling
|
@@ -146,7 +160,9 @@ forward = Lighstorm::Forward.last
|
|
146
160
|
forward.at
|
147
161
|
|
148
162
|
forward.fee.millisatoshis
|
149
|
-
forward.fee.parts_per_million
|
163
|
+
forward.fee.parts_per_million(
|
164
|
+
forward.in.amount.millisatoshis
|
165
|
+
)
|
150
166
|
|
151
167
|
forward.in.amount.millisatoshis
|
152
168
|
forward.out.amount.millisatoshis
|
@@ -168,15 +184,15 @@ forward.out.channel.partner.node.alias
|
|
168
184
|
### Payment
|
169
185
|
|
170
186
|
```ruby
|
171
|
-
payment = Payment.last
|
187
|
+
payment = Lighstorm::Payment.last
|
172
188
|
|
173
|
-
payment.
|
174
|
-
payment.
|
189
|
+
payment.at
|
190
|
+
payment.state
|
175
191
|
|
176
192
|
# https://github.com/lightning/bolts/blob/master/11-payment-encoding.md
|
177
|
-
payment.
|
193
|
+
payment.invoice.code # "lnbc20m1pv...qqdhhwkj"
|
178
194
|
|
179
|
-
payment.
|
195
|
+
payment.invoice.amount.millisatoshis
|
180
196
|
|
181
197
|
payment.from.hop
|
182
198
|
payment.from.amount.millisatoshis
|
@@ -239,6 +255,86 @@ node.platform.lightning.implementation
|
|
239
255
|
node.platform.lightning.version
|
240
256
|
```
|
241
257
|
|
258
|
+
### Pay
|
259
|
+
|
260
|
+
Read more about [_Spontaneous Payments_](https://docs.lightning.engineering/lightning-network-tools/lnd/send-messages-with-keysend#send-a-spontaneous-payment).
|
261
|
+
|
262
|
+
```ruby
|
263
|
+
destination = Lighstorm::Node.find_by_public_key(
|
264
|
+
'02d3c80335a8ccb2ed364c06875f32240f36f7edb37d80f8dbe321b4c364b6e997'
|
265
|
+
)
|
266
|
+
|
267
|
+
destination.alias # => 'icebaker/old-stone'
|
268
|
+
|
269
|
+
destination.pay(amount: { millisatoshis: 1000 })
|
270
|
+
|
271
|
+
destination.pay(
|
272
|
+
amount: { millisatoshis: 1500 },
|
273
|
+
fee: { maximum: { millisatoshis: 1000 } },
|
274
|
+
message: 'Hello from Lighstorm!',
|
275
|
+
through: 'amp',
|
276
|
+
times_out_in: { seconds: 5 }
|
277
|
+
)
|
278
|
+
|
279
|
+
destination.pay(
|
280
|
+
amount: { millisatoshis: 1200 },
|
281
|
+
fee: { maximum: { millisatoshis: 1000 } },
|
282
|
+
message: 'Hello from Lighstorm!',
|
283
|
+
through: 'keysend',
|
284
|
+
times_out_in: { seconds: 5 }
|
285
|
+
)
|
286
|
+
|
287
|
+
action = destination.pay(amount: { millisatoshis: 1000 })
|
288
|
+
action.result.fee.millisatoshis
|
289
|
+
```
|
290
|
+
|
291
|
+
### Send Messages
|
292
|
+
|
293
|
+
**Warning:** Sending messages through Lightning Network requires you to spend satoshis and potentially pay fees.
|
294
|
+
|
295
|
+
```ruby
|
296
|
+
destination = Lighstorm::Node.find_by_public_key(
|
297
|
+
'02d3c80335a8ccb2ed364c06875f32240f36f7edb37d80f8dbe321b4c364b6e997'
|
298
|
+
)
|
299
|
+
|
300
|
+
destination.alias # => 'icebaker/old-stone'
|
301
|
+
|
302
|
+
destination.send_message(
|
303
|
+
'Hello from Lighstorm!',
|
304
|
+
amount: { millisatoshis: 1000 }
|
305
|
+
)
|
306
|
+
|
307
|
+
destination.send_message(
|
308
|
+
'Hello from Lighstorm!',
|
309
|
+
amount: { millisatoshis: 1000 },
|
310
|
+
fee: { maximum: { millisatoshis: 1000 } },
|
311
|
+
through: 'amp',
|
312
|
+
times_out_in: { seconds: 5 }
|
313
|
+
)
|
314
|
+
|
315
|
+
destination.send_message(
|
316
|
+
'Hello from Lighstorm!',
|
317
|
+
amount: { millisatoshis: 1000 },
|
318
|
+
fee: { maximum: { millisatoshis: 1000 } },
|
319
|
+
through: 'keysend',
|
320
|
+
times_out_in: { seconds: 5 }
|
321
|
+
)
|
322
|
+
|
323
|
+
action = destination.send_message(
|
324
|
+
'Hello from Lighstorm!',
|
325
|
+
amount: { millisatoshis: 1000 }
|
326
|
+
)
|
327
|
+
action.result.fee.millisatoshis
|
328
|
+
```
|
329
|
+
|
330
|
+
Read more about sending messages:
|
331
|
+
- [_Send a message to other nodes_](https://docs.lightning.engineering/lightning-network-tools/lnd/send-messages-with-keysend#send-a-message-to-other-nodes)
|
332
|
+
- [_Does Private messaging over Bitcoin’s Lightning Network have potential?_](https://cryptopurview.com/private-messaging-over-bitcoins-lightning-network/)
|
333
|
+
- [_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/)
|
334
|
+
|
335
|
+
### Error Handling
|
336
|
+
Same error handling used for [Invoices Payment Errors](?id=error-handling-1)
|
337
|
+
|
242
338
|
## Channel
|
243
339
|
|
244
340
|
[](https://raw.githubusercontent.com/icebaker/assets/main/lighstorm/graph-channel.png)
|
@@ -373,23 +469,24 @@ Lighstorm::Invoice.find_by_secret_hash(
|
|
373
469
|
invoice._key
|
374
470
|
|
375
471
|
invoice.created_at
|
376
|
-
invoice.
|
472
|
+
invoice.expires_at
|
473
|
+
invoice.settled_at
|
377
474
|
|
378
475
|
invoice.state
|
379
476
|
|
380
477
|
# https://github.com/lightning/bolts/blob/master/11-payment-encoding.md
|
381
|
-
invoice.
|
478
|
+
invoice.code # "lnbc20m1pv...qqdhhwkj"
|
382
479
|
|
383
|
-
invoice.
|
480
|
+
invoice.amount.millisatoshis
|
384
481
|
|
385
|
-
invoice.
|
386
|
-
invoice.request.description.hash
|
482
|
+
invoice.payable # 'once' or 'indefinitely'
|
387
483
|
|
388
|
-
|
389
|
-
invoice.
|
390
|
-
invoice.request.secret.hash
|
484
|
+
invoice.description.memo
|
485
|
+
invoice.description.hash
|
391
486
|
|
392
|
-
|
487
|
+
# https://docs.lightning.engineering/the-lightning-network/multihop-payments
|
488
|
+
invoice.secret.preimage
|
489
|
+
invoice.secret.hash
|
393
490
|
```
|
394
491
|
|
395
492
|
### Create
|
@@ -400,11 +497,27 @@ invoice.request.address
|
|
400
497
|
# 'preview' let you check the expected operation
|
401
498
|
# before actually performing it for debug purposes
|
402
499
|
preview = Lighstorm::Invoice.create(
|
403
|
-
description: 'Coffee', millisatoshis: 1000,
|
500
|
+
description: 'Coffee', amount: { millisatoshis: 1000 },
|
501
|
+
payable: 'once', preview: true
|
502
|
+
)
|
503
|
+
|
504
|
+
action = Lighstorm::Invoice.create(
|
505
|
+
description: 'Coffee', amount: { millisatoshis: 1000 },
|
506
|
+
payable: 'once', expires_in: { minutes: 5 }
|
507
|
+
)
|
508
|
+
|
509
|
+
action = Lighstorm::Invoice.create(
|
510
|
+
description: 'Beer', payable: 'once'
|
511
|
+
)
|
512
|
+
|
513
|
+
action = Lighstorm::Invoice.create(
|
514
|
+
description: 'Donations', payable: 'indefinitely',
|
515
|
+
expires_in: { hours: 24 }
|
404
516
|
)
|
405
517
|
|
406
518
|
action = Lighstorm::Invoice.create(
|
407
|
-
description: '
|
519
|
+
description: 'Concert Ticket', amount: { millisatoshis: 500000000 },
|
520
|
+
payable: 'indefinitely', expires_in: { days: 5 }
|
408
521
|
)
|
409
522
|
|
410
523
|
action.to_h
|
@@ -413,6 +526,102 @@ action.response
|
|
413
526
|
invoice = action.result
|
414
527
|
```
|
415
528
|
|
529
|
+
### Pay
|
530
|
+
|
531
|
+
[Understanding Lightning Invoices](https://docs.lightning.engineering/the-lightning-network/payment-lifecycle/understanding-lightning-invoices)
|
532
|
+
|
533
|
+
```ruby
|
534
|
+
invoice = Lighstorm::Invoice.decode('lnbc20m1pv...qqdhhwkj')
|
535
|
+
|
536
|
+
# 'preview' let you check the expected operation
|
537
|
+
# before actually performing it for debug purposes
|
538
|
+
invoice.pay(preview: true)
|
539
|
+
|
540
|
+
action = invoice.pay
|
541
|
+
|
542
|
+
action.to_h
|
543
|
+
|
544
|
+
action.response
|
545
|
+
payment = action.result
|
546
|
+
|
547
|
+
payment.at
|
548
|
+
payment.state
|
549
|
+
|
550
|
+
payment.amount.millisatoshis
|
551
|
+
payment.fee.millisatoshis
|
552
|
+
payment.fee.parts_per_million(
|
553
|
+
payment.amount.millisatoshis
|
554
|
+
)
|
555
|
+
|
556
|
+
payment.purpose
|
557
|
+
payment.hops.size
|
558
|
+
```
|
559
|
+
|
560
|
+
```ruby
|
561
|
+
invoice.pay(
|
562
|
+
amount: { millisatoshis: 1500 },
|
563
|
+
fee: { maximum: { millisatoshis: 1000 } },
|
564
|
+
message: 'here we go',
|
565
|
+
times_out_in: { seconds: 5 }
|
566
|
+
)
|
567
|
+
```
|
568
|
+
|
569
|
+
#### Error Handling
|
570
|
+
Check [Error Handling](?id=error-handling-2)
|
571
|
+
|
572
|
+
```ruby
|
573
|
+
begin
|
574
|
+
invoice.pay
|
575
|
+
rescue AlreadyPaidError => error
|
576
|
+
error.message # 'The invoice is already paid.'
|
577
|
+
error.grpc.class # GRPC::AlreadyExists
|
578
|
+
error.grpc.message # '6:invoice is already paid. debug_error_string:{UNKNOWN...'
|
579
|
+
end
|
580
|
+
```
|
581
|
+
|
582
|
+
```ruby
|
583
|
+
begin
|
584
|
+
invoice.pay(amount: { millisatoshis: 1000 })
|
585
|
+
rescue AmountForNonZeroError => error
|
586
|
+
error.message # 'Millisatoshis must not be specified...'
|
587
|
+
error.grpc.class # GRPC::Unknown
|
588
|
+
error.grpc.message # '2:amount must not be specified when paying...'
|
589
|
+
end
|
590
|
+
```
|
591
|
+
|
592
|
+
```ruby
|
593
|
+
begin
|
594
|
+
invoice.pay
|
595
|
+
rescue MissingMillisatoshisError => error
|
596
|
+
error.message # 'Millisatoshis must be specified...'
|
597
|
+
error.grpc.class # GRPC::Unknown
|
598
|
+
error.grpc.message # '2:amount must be specified when paying a zero...'
|
599
|
+
end
|
600
|
+
```
|
601
|
+
|
602
|
+
```ruby
|
603
|
+
begin
|
604
|
+
invoice.pay
|
605
|
+
rescue NoRouteFoundError => error
|
606
|
+
error.message # 'FAILURE_REASON_NO_ROUTE'
|
607
|
+
e.response
|
608
|
+
e.response.last[:failure_reason] # => :FAILURE_REASON_NO_ROUTE
|
609
|
+
end
|
610
|
+
```
|
611
|
+
|
612
|
+
|
613
|
+
```ruby
|
614
|
+
begin
|
615
|
+
invoice.pay
|
616
|
+
rescue PaymentError => error
|
617
|
+
error.class
|
618
|
+
error.message
|
619
|
+
|
620
|
+
error.grpc
|
621
|
+
error.response
|
622
|
+
error.result
|
623
|
+
end
|
624
|
+
```
|
416
625
|
## Payment
|
417
626
|
|
418
627
|
[](https://raw.githubusercontent.com/icebaker/assets/main/lighstorm/graph-payment.png)
|
@@ -430,7 +639,8 @@ Lighstorm::Payment.last
|
|
430
639
|
Lighstorm::Payment.all(limit: 10, purpose: 'rebalance')
|
431
640
|
|
432
641
|
# Possible Purposes:
|
433
|
-
|
642
|
+
# 'self-payment', 'peer-to-peer',
|
643
|
+
# 'rebalance', 'payment'
|
434
644
|
|
435
645
|
# _key is helpful for reactive javascript frameworks.
|
436
646
|
# Please don't consider it as a unique identifier
|
@@ -440,34 +650,53 @@ payment._key
|
|
440
650
|
|
441
651
|
payment.to_h
|
442
652
|
|
443
|
-
payment.
|
444
|
-
|
445
|
-
payment.
|
446
|
-
payment.purpose
|
653
|
+
payment.at
|
654
|
+
|
655
|
+
payment.amount.millisatoshis
|
447
656
|
|
448
657
|
payment.fee.millisatoshis
|
449
658
|
payment.fee.parts_per_million(
|
450
|
-
payment.
|
659
|
+
payment.amount.millisatoshis
|
451
660
|
)
|
452
661
|
|
453
|
-
|
454
|
-
payment.
|
662
|
+
payment.state
|
663
|
+
payment.message
|
455
664
|
|
456
|
-
payment.
|
665
|
+
payment.how # 'spontaneously', 'with-invoice'
|
666
|
+
payment.through # 'keysend', 'amp', 'non-amp'
|
667
|
+
payment.purpose
|
668
|
+
# 'self-payment', 'peer-to-peer',
|
669
|
+
# 'rebalance', 'payment'
|
457
670
|
|
458
671
|
# https://docs.lightning.engineering/the-lightning-network/multihop-payments
|
459
|
-
payment.
|
460
|
-
payment.
|
672
|
+
payment.secret.preimage
|
673
|
+
payment.secret.hash
|
674
|
+
|
675
|
+
payment.invoice.created_at
|
676
|
+
payment.invoice.expires_at
|
677
|
+
payment.invoice.settled_at
|
678
|
+
|
679
|
+
payment.invoice.state
|
680
|
+
|
681
|
+
# https://github.com/lightning/bolts/blob/master/11-payment-encoding.md
|
682
|
+
payment.invoice.code # "lnbc20m1pv...qqdhhwkj"
|
683
|
+
payment.invoice.amount.millisatoshis
|
461
684
|
|
462
|
-
payment.
|
685
|
+
payment.invoice.payable # 'once', 'indefinitely'
|
463
686
|
|
464
|
-
payment.
|
465
|
-
payment.
|
687
|
+
payment.invoice.description.memo
|
688
|
+
payment.invoice.description.hash
|
689
|
+
|
690
|
+
# https://docs.lightning.engineering/the-lightning-network/multihop-payments
|
691
|
+
payment.invoice.secret.preimage
|
692
|
+
payment.invoice.secret.hash
|
466
693
|
|
467
694
|
payment.from.hop
|
468
695
|
payment.from.amount.millisatoshis
|
469
696
|
payment.from.fee.millisatoshis
|
470
|
-
payment.from.fee.parts_per_million(
|
697
|
+
payment.from.fee.parts_per_million(
|
698
|
+
payment.from.amount.millisatoshis
|
699
|
+
)
|
471
700
|
|
472
701
|
payment.from.channel.id
|
473
702
|
|
@@ -482,7 +711,9 @@ payment.from.channel.exit.color
|
|
482
711
|
payment.to.hop
|
483
712
|
payment.to.amount.millisatoshis
|
484
713
|
payment.to.fee.millisatoshis
|
485
|
-
payment.to.fee.parts_per_million(
|
714
|
+
payment.to.fee.parts_per_million(
|
715
|
+
payment.to.amount.millisatoshis
|
716
|
+
)
|
486
717
|
|
487
718
|
payment.to.channel.id
|
488
719
|
|
@@ -502,7 +733,9 @@ payment.hops[0].last?
|
|
502
733
|
payment.hops[0].hop
|
503
734
|
payment.hops[0].amount.millisatoshis
|
504
735
|
payment.hops[0].fee.millisatoshis
|
505
|
-
payment.hops[0].fee.parts_per_million(
|
736
|
+
payment.hops[0].fee.parts_per_million(
|
737
|
+
payment.hops[0].amount.millisatoshis
|
738
|
+
)
|
506
739
|
|
507
740
|
payment.hops[0].channel.id
|
508
741
|
|
@@ -666,6 +899,7 @@ Lighstorm::Channel.adapt(dump: channel.dump)
|
|
666
899
|
|
667
900
|
```ruby
|
668
901
|
Lighstorm::Satoshis
|
902
|
+
Lighstorm::Satoshis.new(bitcoins: 0.005)
|
669
903
|
Lighstorm::Satoshis.new(millisatoshis: 75621650)
|
670
904
|
|
671
905
|
satoshis.to_h
|
@@ -736,24 +970,26 @@ end
|
|
736
970
|
```ruby
|
737
971
|
LighstormError
|
738
972
|
|
973
|
+
ArgumentError
|
739
974
|
IncoherentGossipError
|
740
|
-
|
741
|
-
TooManyArgumentsError
|
742
975
|
MissingCredentialsError
|
743
976
|
MissingGossipHandlerError
|
744
|
-
MissingMillisatoshisError
|
745
977
|
MissingPartsPerMillionError
|
746
|
-
MissingTTLError
|
747
|
-
|
748
978
|
NegativeNotAllowedError
|
749
|
-
|
750
979
|
NotYourChannelError
|
751
980
|
NotYourNodeError
|
752
|
-
UnknownChannelError
|
753
|
-
|
754
981
|
OperationNotAllowedError
|
982
|
+
TooManyArgumentsError
|
755
983
|
UnexpectedNumberOfHTLCsError
|
984
|
+
UnknownChannelError
|
756
985
|
UpdateChannelPolicyError
|
986
|
+
|
987
|
+
PaymentError
|
988
|
+
|
989
|
+
AlreadyPaidError
|
990
|
+
AmountForNonZeroError
|
991
|
+
MissingMillisatoshisError
|
992
|
+
NoRouteFoundError
|
757
993
|
```
|
758
994
|
|
759
995
|
# Development
|
@@ -767,7 +1003,7 @@ gem 'lighstorm', path: '/home/user/lighstorm'
|
|
767
1003
|
# demo.rb
|
768
1004
|
require 'lighstorm'
|
769
1005
|
|
770
|
-
puts Lighstorm.version # => 0.0.
|
1006
|
+
puts Lighstorm.version # => 0.0.10
|
771
1007
|
```
|
772
1008
|
|
773
1009
|
```sh
|
@@ -827,13 +1063,15 @@ The downside is that we can't [lazy-load](https://en.wikipedia.org/wiki/Lazy_loa
|
|
827
1063
|
To perform an _action_, like creating an Invoice, you:
|
828
1064
|
```ruby
|
829
1065
|
Lighstorm::Invoice.create(
|
830
|
-
description: 'Coffee', millisatoshis: 1000
|
1066
|
+
description: 'Coffee', amount: { millisatoshis: 1000 }
|
831
1067
|
)
|
832
1068
|
```
|
833
1069
|
|
834
1070
|
Internally, what's happening:
|
835
1071
|
```ruby
|
836
|
-
action = Lighstorm::Invoice.create(
|
1072
|
+
action = Lighstorm::Invoice.create(
|
1073
|
+
description: 'Coffee', amount: { millisatoshis: 1000 }
|
1074
|
+
)
|
837
1075
|
|
838
1076
|
request = Controllers::Invoice::Create.prepare(params) # pure
|
839
1077
|
response = Controllers::Invoice::Create.dispatch(request) # side effect
|
@@ -969,6 +1207,24 @@ expected: nil
|
|
969
1207
|
|
970
1208
|
Remember to undo it afterward, replacing `expect!` with `expect`.
|
971
1209
|
|
1210
|
+
### Extra Tips for Testing
|
1211
|
+
|
1212
|
+
To auto-fix contracts:
|
1213
|
+
|
1214
|
+
```sh
|
1215
|
+
rspec --format json | bundle exec rake contracts:fix
|
1216
|
+
```
|
1217
|
+
|
1218
|
+
To delete unused test data files, update the `.env` file:
|
1219
|
+
```sh
|
1220
|
+
LIGHSTORM_DELETE_UNUSED_TEST_DATA=true
|
1221
|
+
```
|
1222
|
+
|
1223
|
+
Deletion will only occur if you run all tests and no failures are found:
|
1224
|
+
```ruby
|
1225
|
+
bundle exec rspec
|
1226
|
+
```
|
1227
|
+
|
972
1228
|
## Generating Documentation
|
973
1229
|
|
974
1230
|
```sh
|
@@ -984,13 +1240,13 @@ gem build lighstorm.gemspec
|
|
984
1240
|
|
985
1241
|
gem signin
|
986
1242
|
|
987
|
-
gem push lighstorm-0.0.
|
1243
|
+
gem push lighstorm-0.0.10.gem
|
988
1244
|
```
|
989
1245
|
|
990
1246
|
_________________
|
991
1247
|
|
992
1248
|
<center>
|
993
|
-
lighstorm 0.0.
|
1249
|
+
lighstorm 0.0.10
|
994
1250
|
|
|
995
1251
|
<a href="https://github.com/icebaker/lighstorm" rel="noopener noreferrer" target="_blank">GitHub</a>
|
996
1252
|
|
|
data/docs/_coverpage.md
CHANGED
data/docs/index.html
CHANGED
@@ -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
|