lighstorm 0.0.12 → 0.0.13
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 +18 -3
- data/Gemfile.lock +4 -4
- data/README.md +11 -5
- data/adapters/transaction.rb +23 -0
- data/components/lnd.rb +47 -25
- data/controllers/activity/all.rb +129 -0
- data/controllers/activity.rb +17 -0
- data/controllers/transaction/all.rb +28 -73
- data/docs/README.md +139 -29
- data/docs/_coverpage.md +1 -1
- data/docs/index.html +1 -1
- data/lighstorm.gemspec +1 -1
- data/models/activity.rb +51 -0
- data/models/transaction.rb +10 -15
- data/ports/dsl/lighstorm.rb +4 -4
- data/static/cache.rb +1 -0
- data/static/spec.rb +1 -1
- metadata +8 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 26ecb1df57331f4013bed69eabf7722b49b5fdfa40fdca48a38e0b3f07d032c5
|
4
|
+
data.tar.gz: ca0632d8d04671db004ce82acb73d35b92f3527f9cb4b4f5171031bf19dfe56b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2c8b91eaa213a149be5da9af101dc0fc5bfa4add56b709f74d776cb20a96dd1020f2f33f6cb113ec24b257e55b2a2ded19ffa97776f4bf45dc4932760a990585
|
7
|
+
data.tar.gz: b3437b6dfa13b39eb761acd8cc6685d4c62ec9f388615de66d55e2e9afb7eb194ef6705a85cb401a0daa7af7c258329a51d50ed5d41aa423dd807325c0bb7bfc
|
data/.env.example
CHANGED
@@ -1,6 +1,21 @@
|
|
1
|
-
LIGHSTORM_LND_ADDRESS=127.0.0.1:10009
|
2
|
-
LIGHSTORM_CERTIFICATE_PATH=/lnd/tls.cert
|
3
|
-
LIGHSTORM_MACAROON_PATH=/lnd/data/chain/bitcoin/mainnet/admin.macaroon
|
4
1
|
LIGHSTORM_RUN_INTEGRATION_TESTS=false
|
5
2
|
LIGHSTORM_RUN_INTEGRATION_TESTS_SLOW=false
|
6
3
|
LIGHSTORM_DELETE_UNUSED_TEST_DATA=false
|
4
|
+
|
5
|
+
# Option A: lndconnect
|
6
|
+
# LIGHSTORM_LND_CONNECT=lndconnect://127.0.0.1:10009?cert=MIICJz...JBEERQ&macaroon=AgEDbG...45ukJ4
|
7
|
+
|
8
|
+
# Option B: File Path
|
9
|
+
# LIGHSTORM_LND_ADDRESS=127.0.0.1:10009
|
10
|
+
# LIGHSTORM_LND_CERTIFICATE_PATH=/lnd/tls.cert
|
11
|
+
# LIGHSTORM_LND_MACAROON_PATH=/lnd/data/chain/bitcoin/mainnet/admin.macaroon
|
12
|
+
|
13
|
+
# Option C: Base64
|
14
|
+
# LIGHSTORM_LND_ADDRESS=127.0.0.1:10009
|
15
|
+
# LIGHSTORM_LND_CERTIFICATE=LS0tLS1CRU...UtLS0tLQo=
|
16
|
+
# LIGHSTORM_LND_MACAROON=AgEDbG5kAv...inv45ukJ4=
|
17
|
+
|
18
|
+
# Option D: Hex
|
19
|
+
# LIGHSTORM_LND_ADDRESS=127.0.0.1:10009
|
20
|
+
# LIGHSTORM_LND_CERTIFICATE=2d2d2d2d2d...2d2d2d2d0a
|
21
|
+
# LIGHSTORM_LND_MACAROON=0201036c6e...bf8e6e909e
|
data/Gemfile.lock
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
lighstorm (0.0.
|
4
|
+
lighstorm (0.0.13)
|
5
5
|
dotenv (~> 2.8, >= 2.8.1)
|
6
|
-
lnd-client (~> 0.0.
|
6
|
+
lnd-client (~> 0.0.6)
|
7
7
|
zache (~> 0.12.0)
|
8
8
|
|
9
9
|
GEM
|
@@ -22,7 +22,7 @@ GEM
|
|
22
22
|
google-protobuf (~> 3.21)
|
23
23
|
googleapis-common-protos-types (~> 1.0)
|
24
24
|
json (2.6.3)
|
25
|
-
lnd-client (0.0.
|
25
|
+
lnd-client (0.0.6)
|
26
26
|
grpc (~> 1.52)
|
27
27
|
method_source (1.0.0)
|
28
28
|
parallel (1.22.1)
|
@@ -51,7 +51,7 @@ GEM
|
|
51
51
|
diff-lcs (>= 1.2.0, < 2.0)
|
52
52
|
rspec-support (~> 3.12.0)
|
53
53
|
rspec-support (3.12.0)
|
54
|
-
rubocop (1.48.
|
54
|
+
rubocop (1.48.1)
|
55
55
|
json (~> 2.3)
|
56
56
|
parallel (~> 1.10)
|
57
57
|
parser (>= 3.2.0.0)
|
data/README.md
CHANGED
@@ -35,19 +35,25 @@ Although it tries to stay close to [Lightning's terminologies](https://docs.ligh
|
|
35
35
|
Add to your `Gemfile`:
|
36
36
|
|
37
37
|
```ruby
|
38
|
-
gem 'lighstorm', '~> 0.0.
|
38
|
+
gem 'lighstorm', '~> 0.0.13'
|
39
39
|
```
|
40
40
|
|
41
41
|
```ruby
|
42
42
|
require 'lighstorm'
|
43
43
|
|
44
|
-
|
45
|
-
|
44
|
+
# lndconnect
|
45
|
+
Lighstorm.connect!(
|
46
|
+
'lndconnect://127.0.0.1:10009?cert=MIICJz...JBEERQ&macaroon=AgEDbG...45ukJ4'
|
47
|
+
)
|
48
|
+
|
49
|
+
# File Path
|
50
|
+
Lighstorm.connect!(
|
51
|
+
address: '127.0.0.1:10009',
|
46
52
|
certificate_path: '/lnd/tls.cert',
|
47
|
-
macaroon_path: '/lnd/data/chain/bitcoin/mainnet/admin.macaroon'
|
53
|
+
macaroon_path: '/lnd/data/chain/bitcoin/mainnet/admin.macaroon'
|
48
54
|
)
|
49
55
|
|
50
|
-
puts Lighstorm.version # => 0.0.
|
56
|
+
puts Lighstorm.version # => 0.0.13
|
51
57
|
|
52
58
|
Lighstorm::Node.myself.alias # => icebaker/old-stone
|
53
59
|
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'digest'
|
4
|
+
|
5
|
+
module Lighstorm
|
6
|
+
module Adapter
|
7
|
+
class Transaction
|
8
|
+
def self.get_transactions(grpc)
|
9
|
+
{
|
10
|
+
_source: :get_transactions,
|
11
|
+
_key: Digest::SHA256.hexdigest(
|
12
|
+
[grpc[:time_stamp], grpc[:tx_hash], grpc[:amount], grpc[:total_fees]].join('/')
|
13
|
+
),
|
14
|
+
at: Time.at(grpc[:time_stamp]),
|
15
|
+
amount: { millisatoshis: grpc[:amount] * 1000 },
|
16
|
+
fee: { millisatoshis: grpc[:total_fees] * 1000 },
|
17
|
+
hash: grpc[:tx_hash],
|
18
|
+
label: grpc[:label]
|
19
|
+
}
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/components/lnd.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'singleton'
|
4
|
-
|
4
|
+
require 'securerandom'
|
5
5
|
require 'lnd-client'
|
6
6
|
|
7
7
|
require_relative '../ports/dsl/lighstorm/errors'
|
@@ -10,34 +10,36 @@ module Lighstorm
|
|
10
10
|
class LND
|
11
11
|
include Singleton
|
12
12
|
|
13
|
-
attr_writer :
|
13
|
+
attr_writer :middleware
|
14
14
|
|
15
15
|
def initialize
|
16
|
-
@
|
17
|
-
@client = nil
|
16
|
+
@default_key = SecureRandom.hex
|
18
17
|
@middleware = ->(_key, &block) { block.call }
|
19
18
|
end
|
20
19
|
|
20
|
+
def connect!(*params)
|
21
|
+
if params.last.is_a?(Hash)
|
22
|
+
unless params.last.key?(:lightning)
|
23
|
+
params.last[:lightning] = {
|
24
|
+
channel_args: { 'grpc.max_receive_message_length' => 1024 * 1024 * 50 }
|
25
|
+
}
|
26
|
+
end
|
27
|
+
else
|
28
|
+
params << {
|
29
|
+
lightning: { channel_args: { 'grpc.max_receive_message_length' => 1024 * 1024 * 50 } }
|
30
|
+
}
|
31
|
+
end
|
32
|
+
|
33
|
+
LNDClient.add_connection!(@default_key, *params)
|
34
|
+
end
|
35
|
+
|
21
36
|
def middleware(key, &block)
|
22
37
|
@middleware.call(key, &block)
|
23
38
|
end
|
24
39
|
|
25
40
|
def client
|
26
|
-
|
27
|
-
|
28
|
-
raise MissingCredentialsError, 'missing credentials' if @config.nil? && ENV.fetch(
|
29
|
-
'LIGHSTORM_CERTIFICATE_PATH', nil
|
30
|
-
).nil?
|
31
|
-
|
32
|
-
@client = if @config
|
33
|
-
create_client_from_config
|
34
|
-
else
|
35
|
-
create_client_from_environment_variables
|
36
|
-
end
|
37
|
-
|
38
|
-
@client.lightning(channel_args: { 'grpc.max_receive_message_length' => 1024 * 1024 * 50 })
|
39
|
-
|
40
|
-
@client
|
41
|
+
try_to_connect_from_environment_variables! unless LNDClient.connections.include?(@default_key)
|
42
|
+
LNDClient.as(@default_key)
|
41
43
|
end
|
42
44
|
|
43
45
|
def create_client_from_config
|
@@ -48,12 +50,32 @@ module Lighstorm
|
|
48
50
|
)
|
49
51
|
end
|
50
52
|
|
51
|
-
def
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
)
|
53
|
+
def try_to_connect_from_environment_variables!
|
54
|
+
return connect!(ENV.fetch('LIGHSTORM_LND_CONNECT')) if ENV.fetch('LIGHSTORM_LND_CONNECT', nil)
|
55
|
+
|
56
|
+
params = {}
|
57
|
+
|
58
|
+
raise MissingCredentialsError, 'missing credentials [address]' unless ENV.fetch('LIGHSTORM_LND_ADDRESS', nil)
|
59
|
+
|
60
|
+
params[:address] = ENV.fetch('LIGHSTORM_LND_ADDRESS')
|
61
|
+
|
62
|
+
if ENV.fetch('LIGHSTORM_LND_CERTIFICATE', nil)
|
63
|
+
params[:certificate] = ENV.fetch('LIGHSTORM_LND_CERTIFICATE')
|
64
|
+
elsif ENV.fetch('LIGHSTORM_LND_CERTIFICATE_PATH', nil)
|
65
|
+
params[:certificate_path] = ENV.fetch('LIGHSTORM_LND_CERTIFICATE_PATH')
|
66
|
+
else
|
67
|
+
raise MissingCredentialsError, 'missing credentials [certificate]'
|
68
|
+
end
|
69
|
+
|
70
|
+
if ENV.fetch('LIGHSTORM_LND_MACAROON', nil)
|
71
|
+
params[:macaroon] = ENV.fetch('LIGHSTORM_LND_MACAROON')
|
72
|
+
elsif ENV.fetch('LIGHSTORM_LND_MACAROON_PATH', nil)
|
73
|
+
params[:macaroon_path] = ENV.fetch('LIGHSTORM_LND_MACAROON_PATH')
|
74
|
+
else
|
75
|
+
raise MissingCredentialsError, 'missing credentials [macaroon]'
|
76
|
+
end
|
77
|
+
|
78
|
+
connect!(params)
|
57
79
|
end
|
58
80
|
end
|
59
81
|
end
|
@@ -0,0 +1,129 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../invoice/all'
|
4
|
+
require_relative '../payment/all'
|
5
|
+
require_relative '../forward/all'
|
6
|
+
require_relative '../transaction/all'
|
7
|
+
require_relative '../../models/activity'
|
8
|
+
|
9
|
+
module Lighstorm
|
10
|
+
module Controllers
|
11
|
+
module Activity
|
12
|
+
module All
|
13
|
+
def self.fetch(direction: nil, how: nil, limit: nil)
|
14
|
+
activities = []
|
15
|
+
|
16
|
+
Transaction::All.data.each do |transaction|
|
17
|
+
next if !how.nil? && how != 'on-chain'
|
18
|
+
|
19
|
+
activities << {
|
20
|
+
direction: (transaction[:amount][:millisatoshis]).positive? ? 'in' : 'out',
|
21
|
+
layer: 'on-chain',
|
22
|
+
at: transaction[:at],
|
23
|
+
amount: {
|
24
|
+
millisatoshis: if (transaction[:amount][:millisatoshis]).positive?
|
25
|
+
transaction[:amount][:millisatoshis]
|
26
|
+
else
|
27
|
+
-transaction[:amount][:millisatoshis]
|
28
|
+
end
|
29
|
+
},
|
30
|
+
how: 'on-chain',
|
31
|
+
message: nil,
|
32
|
+
data: { transaction: transaction }
|
33
|
+
}
|
34
|
+
end
|
35
|
+
|
36
|
+
if direction.nil? || direction == 'in'
|
37
|
+
Invoice::All.data(spontaneous: true).filter do |invoice|
|
38
|
+
!invoice[:payments].nil? && invoice[:payments].size.positive?
|
39
|
+
end.each do |invoice|
|
40
|
+
activity_how = invoice[:code].nil? ? 'spontaneously' : 'with-invoice'
|
41
|
+
|
42
|
+
next if !how.nil? && how != activity_how
|
43
|
+
|
44
|
+
# TODO: Improve performance by reducing invoice fields and removing payments?
|
45
|
+
invoice[:payments].each do |payment|
|
46
|
+
activities << {
|
47
|
+
direction: 'in',
|
48
|
+
layer: 'off-chain',
|
49
|
+
at: payment[:at],
|
50
|
+
amount: payment[:amount],
|
51
|
+
how: activity_how,
|
52
|
+
message: payment[:message],
|
53
|
+
data: { invoice: invoice }
|
54
|
+
}
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
Forward::All.data.each do |forward|
|
59
|
+
next if !how.nil? && how != 'forwarding'
|
60
|
+
|
61
|
+
activities << {
|
62
|
+
direction: 'in',
|
63
|
+
layer: 'off-chain',
|
64
|
+
at: forward[:at],
|
65
|
+
amount: forward[:fee],
|
66
|
+
how: 'forwarding',
|
67
|
+
message: nil,
|
68
|
+
data: {}
|
69
|
+
}
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
if direction.nil? || direction == 'out'
|
74
|
+
Payment::All.data(
|
75
|
+
fetch: {
|
76
|
+
get_node_info: false,
|
77
|
+
lookup_invoice: false,
|
78
|
+
decode_pay_req: true,
|
79
|
+
get_chan_info: false
|
80
|
+
}
|
81
|
+
)[:data].each do |payment|
|
82
|
+
activity_how = payment[:invoice][:code].nil? ? 'spontaneously' : 'with-invoice'
|
83
|
+
|
84
|
+
next if !how.nil? && how != activity_how
|
85
|
+
|
86
|
+
# TODO: Improve performance by reducing invoice fields?
|
87
|
+
activities << {
|
88
|
+
direction: 'out',
|
89
|
+
layer: 'off-chain',
|
90
|
+
at: payment[:at],
|
91
|
+
amount: payment[:amount],
|
92
|
+
how: activity_how,
|
93
|
+
message: payment[:message],
|
94
|
+
data: { invoice: payment[:invoice] }
|
95
|
+
}
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
activities = activities.sort_by { |activity| -activity[:at].to_i }
|
100
|
+
|
101
|
+
activities = activities[0..limit - 1] unless limit.nil?
|
102
|
+
|
103
|
+
{ activities: activities }
|
104
|
+
end
|
105
|
+
|
106
|
+
def self.transform(raw)
|
107
|
+
raw[:activities].map do |activity|
|
108
|
+
activity[:_key] = SecureRandom.hex
|
109
|
+
activity
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def self.data(direction: nil, how: nil, limit: nil, &vcr)
|
114
|
+
raw = if vcr.nil?
|
115
|
+
fetch(direction: direction, how: how, limit: limit)
|
116
|
+
else
|
117
|
+
vcr.call(-> { fetch(direction: direction, how: how, limit: limit) })
|
118
|
+
end
|
119
|
+
|
120
|
+
transform(raw)
|
121
|
+
end
|
122
|
+
|
123
|
+
def self.model(data)
|
124
|
+
data.map { |data| Models::Activity.new(data) }
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative './activity/all'
|
4
|
+
|
5
|
+
module Lighstorm
|
6
|
+
module Controllers
|
7
|
+
module Activity
|
8
|
+
def self.all(direction: nil, how: nil, limit: nil)
|
9
|
+
All.model(All.data(
|
10
|
+
direction: direction,
|
11
|
+
how: how,
|
12
|
+
limit: limit
|
13
|
+
))
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -1,103 +1,58 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative '
|
4
|
-
require_relative '
|
5
|
-
require_relative '../forward/all'
|
3
|
+
require_relative '../../ports/grpc'
|
4
|
+
require_relative '../../adapters/transaction'
|
6
5
|
require_relative '../../models/transaction'
|
7
6
|
|
8
7
|
module Lighstorm
|
9
8
|
module Controllers
|
10
9
|
module Transaction
|
11
10
|
module All
|
12
|
-
def self.fetch(
|
13
|
-
|
14
|
-
|
15
|
-
if direction.nil? || direction == 'in'
|
16
|
-
Invoice::All.data(spontaneous: true).filter do |invoice|
|
17
|
-
!invoice[:payments].nil? && invoice[:payments].size.positive?
|
18
|
-
end.each do |invoice|
|
19
|
-
transaction_how = invoice[:code].nil? ? 'spontaneously' : 'with-invoice'
|
20
|
-
|
21
|
-
next if !how.nil? && how != transaction_how
|
22
|
-
|
23
|
-
# TODO: Improve performance by reducing invoice fields and removing payments?
|
24
|
-
invoice[:payments].each do |payment|
|
25
|
-
transactions << {
|
26
|
-
direction: 'in',
|
27
|
-
at: payment[:at],
|
28
|
-
amount: payment[:amount],
|
29
|
-
how: transaction_how,
|
30
|
-
message: payment[:message],
|
31
|
-
data: { invoice: invoice }
|
32
|
-
}
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
Forward::All.data.each do |forward|
|
37
|
-
next if !how.nil? && how != 'forwarding'
|
38
|
-
|
39
|
-
transactions << {
|
40
|
-
direction: 'in',
|
41
|
-
at: forward[:at],
|
42
|
-
amount: forward[:fee],
|
43
|
-
how: 'forwarding',
|
44
|
-
message: nil,
|
45
|
-
data: {}
|
46
|
-
}
|
47
|
-
end
|
48
|
-
end
|
11
|
+
def self.fetch(limit: nil)
|
12
|
+
at = Time.now
|
49
13
|
|
50
|
-
|
51
|
-
Payment::All.data(
|
52
|
-
fetch: {
|
53
|
-
get_node_info: false,
|
54
|
-
lookup_invoice: false,
|
55
|
-
decode_pay_req: true,
|
56
|
-
get_chan_info: false
|
57
|
-
}
|
58
|
-
)[:data].each do |payment|
|
59
|
-
transaction_how = payment[:invoice][:code].nil? ? 'spontaneously' : 'with-invoice'
|
14
|
+
transactions = []
|
60
15
|
|
61
|
-
|
16
|
+
response = Ports::GRPC.lightning.get_transactions
|
62
17
|
|
63
|
-
|
64
|
-
|
65
|
-
direction: 'out',
|
66
|
-
at: payment[:at],
|
67
|
-
amount: payment[:amount],
|
68
|
-
how: transaction_how,
|
69
|
-
message: payment[:message],
|
70
|
-
data: { invoice: payment[:invoice] }
|
71
|
-
}
|
72
|
-
end
|
18
|
+
response.transactions.each do |transaction|
|
19
|
+
transactions << transaction.to_h
|
73
20
|
end
|
74
21
|
|
75
|
-
transactions = transactions.sort_by { |
|
22
|
+
transactions = transactions.sort_by { |raw_transaction| -raw_transaction[:time_stamp] }
|
76
23
|
|
77
24
|
transactions = transactions[0..limit - 1] unless limit.nil?
|
78
25
|
|
79
|
-
{
|
26
|
+
{ at: at, get_transactions: transactions }
|
80
27
|
end
|
81
28
|
|
82
|
-
def self.
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
29
|
+
def self.adapt(raw)
|
30
|
+
{
|
31
|
+
get_transactions: raw[:get_transactions].map do |raw_transaction|
|
32
|
+
Lighstorm::Adapter::Transaction.get_transactions(raw_transaction)
|
33
|
+
end
|
34
|
+
}
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.transform(adapted)
|
38
|
+
adapted[:get_transactions]
|
87
39
|
end
|
88
40
|
|
89
|
-
def self.data(
|
41
|
+
def self.data(limit: nil, &vcr)
|
90
42
|
raw = if vcr.nil?
|
91
|
-
fetch(
|
43
|
+
fetch(limit: limit)
|
92
44
|
else
|
93
|
-
vcr.call(-> { fetch(
|
45
|
+
vcr.call(-> { fetch(limit: limit) })
|
94
46
|
end
|
47
|
+
adapted = adapt(raw)
|
95
48
|
|
96
|
-
transform(
|
49
|
+
transform(adapted)
|
97
50
|
end
|
98
51
|
|
99
52
|
def self.model(data)
|
100
|
-
data.map
|
53
|
+
data.map do |transaction_data|
|
54
|
+
Lighstorm::Models::Transaction.new(transaction_data)
|
55
|
+
end
|
101
56
|
end
|
102
57
|
end
|
103
58
|
end
|
data/docs/README.md
CHANGED
@@ -27,40 +27,16 @@ 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.13'
|
31
31
|
```
|
32
32
|
|
33
33
|
Run `bundle install`.
|
34
34
|
|
35
|
-
## Credentials
|
36
|
-
|
37
|
-
Set the following _Environment Variables_ or create a `.env` file:
|
38
|
-
```bash
|
39
|
-
LIGHSTORM_LND_ADDRESS=127.0.0.1:10009
|
40
|
-
LIGHSTORM_CERTIFICATE_PATH=/lnd/tls.cert
|
41
|
-
LIGHSTORM_MACAROON_PATH=/lnd/data/chain/bitcoin/mainnet/admin.macaroon
|
42
|
-
```
|
43
|
-
|
44
|
-
It will automatically load your credentials.
|
45
|
-
|
46
|
-
Alternatively, you can set the credentials at runtime:
|
47
|
-
|
48
|
-
```ruby
|
49
|
-
require 'lighstorm'
|
50
|
-
|
51
|
-
Lighstorm.config!(
|
52
|
-
lnd_address: '127.0.0.1:10009',
|
53
|
-
certificate_path: '/lnd/tls.cert',
|
54
|
-
macaroon_path: '/lnd/data/chain/bitcoin/mainnet/admin.macaroon',
|
55
|
-
)
|
56
|
-
|
57
|
-
```
|
58
|
-
|
59
35
|
## Examples
|
60
36
|
```ruby
|
61
37
|
require 'lighstorm'
|
62
38
|
|
63
|
-
puts Lighstorm.version # => 0.0.
|
39
|
+
puts Lighstorm.version # => 0.0.13
|
64
40
|
|
65
41
|
Lighstorm::Invoice.create(
|
66
42
|
description: 'Coffee', amount: { millisatoshis: 1000 }, payable: 'once'
|
@@ -116,6 +92,140 @@ Lighstorm::Satoshis.new(
|
|
116
92
|
|
117
93
|
- [Getting Started with Lightning Payments in Ruby](https://mirror.xyz/icebaker.eth/4RUF8umW_KRfVWHHvC2jz0c7YJqzv3RUUvLN-Mln5IU)
|
118
94
|
|
95
|
+
# Connecting
|
96
|
+
|
97
|
+
## Environment Variables
|
98
|
+
|
99
|
+
Choose a method and set the following _Environment Variables_, or create a `.env` file. This will automatically load your credentials.
|
100
|
+
|
101
|
+
### lndconnect
|
102
|
+
|
103
|
+
Read more about [lnd connect URL](https://github.com/LN-Zap/lndconnect/blob/master/lnd_connect_uri.md).
|
104
|
+
|
105
|
+
```bash
|
106
|
+
LIGHSTORM_LND_CONNECT=lndconnect://127.0.0.1:10009?cert=MIICJz...JBEERQ&macaroon=AgEDbG...45ukJ4
|
107
|
+
```
|
108
|
+
|
109
|
+
### File Path
|
110
|
+
|
111
|
+
```bash
|
112
|
+
LIGHSTORM_LND_ADDRESS=127.0.0.1:10009
|
113
|
+
LIGHSTORM_LND_CERTIFICATE_PATH=/lnd/tls.cert
|
114
|
+
LIGHSTORM_LND_MACAROON_PATH=/lnd/data/chain/bitcoin/mainnet/admin.macaroon
|
115
|
+
```
|
116
|
+
|
117
|
+
### Base64
|
118
|
+
|
119
|
+
```bash
|
120
|
+
LIGHSTORM_LND_ADDRESS=127.0.0.1:10009
|
121
|
+
LIGHSTORM_LND_CERTIFICATE=LS0tLS1CRU...UtLS0tLQo=
|
122
|
+
LIGHSTORM_LND_MACAROON=AgEDbG5kAv...inv45ukJ4=
|
123
|
+
```
|
124
|
+
|
125
|
+
### Hex
|
126
|
+
|
127
|
+
```bash
|
128
|
+
LIGHSTORM_LND_ADDRESS=127.0.0.1:10009
|
129
|
+
LIGHSTORM_LND_CERTIFICATE=2d2d2d2d2d...2d2d2d2d0a
|
130
|
+
LIGHSTORM_LND_MACAROON=0201036c6e...bf8e6e909e
|
131
|
+
```
|
132
|
+
|
133
|
+
## Runtime
|
134
|
+
Alternatively, you can set the credentials at runtime:
|
135
|
+
|
136
|
+
### lndconnect
|
137
|
+
|
138
|
+
Read more about [lnd connect URL](https://github.com/LN-Zap/lndconnect/blob/master/lnd_connect_uri.md).
|
139
|
+
|
140
|
+
```ruby
|
141
|
+
require 'lighstorm'
|
142
|
+
|
143
|
+
Lighstorm.connect!(
|
144
|
+
'lndconnect://127.0.0.1:10009?cert=MIICJz...JBEERQ&macaroon=AgEDbG...45ukJ4'
|
145
|
+
)
|
146
|
+
```
|
147
|
+
|
148
|
+
### File Path
|
149
|
+
|
150
|
+
```ruby
|
151
|
+
require 'lighstorm'
|
152
|
+
|
153
|
+
Lighstorm.connect!(
|
154
|
+
address: '127.0.0.1:10009',
|
155
|
+
certificate_path: '/lnd/tls.cert',
|
156
|
+
macaroon_path: '/lnd/data/chain/bitcoin/mainnet/admin.macaroon'
|
157
|
+
)
|
158
|
+
```
|
159
|
+
|
160
|
+
### Base64
|
161
|
+
|
162
|
+
```ruby
|
163
|
+
require 'lighstorm'
|
164
|
+
|
165
|
+
Lighstorm.connect!(
|
166
|
+
address: '127.0.0.1:10009',
|
167
|
+
certificate: 'LS0tLS1CRU...UtLS0tLQo=',
|
168
|
+
macaroon: 'AgEDbG5kAv...inv45ukJ4='
|
169
|
+
)
|
170
|
+
```
|
171
|
+
|
172
|
+
### Hex
|
173
|
+
|
174
|
+
```ruby
|
175
|
+
require 'lighstorm'
|
176
|
+
|
177
|
+
Lighstorm.connect!(
|
178
|
+
address: '127.0.0.1:10009',
|
179
|
+
certificate: '2d2d2d2d2d...2d2d2d2d0a',
|
180
|
+
macaroon: '0201036c6e...bf8e6e909e'
|
181
|
+
)
|
182
|
+
```
|
183
|
+
|
184
|
+
### Raw
|
185
|
+
|
186
|
+
```ruby
|
187
|
+
require 'lighstorm'
|
188
|
+
|
189
|
+
Lighstorm.connect!(
|
190
|
+
address: '127.0.0.1:10009',
|
191
|
+
certificate: File.read('/lnd/tls.cert'),
|
192
|
+
macaroon: File.read('/lnd/data/chain/bitcoin/mainnet/admin.macaroon')
|
193
|
+
)
|
194
|
+
```
|
195
|
+
|
196
|
+
## Docker and Remote Access
|
197
|
+
|
198
|
+
To connect to an LND node through a Docker container or remote host, you may need to adjust your certificate settings. Follow these steps:
|
199
|
+
|
200
|
+
1. Stop your LND node.
|
201
|
+
|
202
|
+
2. Remove or backup existing certificate files (`tls.cert` and `tls.key`) in the LND directory.
|
203
|
+
|
204
|
+
3. Modify `lnd.conf` to include the relevant `tlsextraip` and/or `tlsextradomain` settings:
|
205
|
+
|
206
|
+
Option A: Accept any IP or domain (Warning: high security risk):
|
207
|
+
|
208
|
+
```conf
|
209
|
+
tlsextraip=0.0.0.0
|
210
|
+
```
|
211
|
+
|
212
|
+
Option B: Accept only your Docker host (172.17.0.1):
|
213
|
+
```conf
|
214
|
+
tlsextraip=172.17.0.1
|
215
|
+
```
|
216
|
+
|
217
|
+
Option C: Accept a specific remote domain and host:
|
218
|
+
```config
|
219
|
+
tlsextraip=<your_remote_host_ip>
|
220
|
+
tlsextradomain=<your_domain_name>
|
221
|
+
```
|
222
|
+
|
223
|
+
4. Save and restart your LND node. New tls.cert and tls.key files will be generated.
|
224
|
+
|
225
|
+
5. Update your LND client configuration with the new certificate.
|
226
|
+
|
227
|
+
Choose the option that best suits your needs and environment while considering security implications.
|
228
|
+
|
119
229
|
# Data Modeling
|
120
230
|
|
121
231
|
## Graph Theory
|
@@ -1048,7 +1158,7 @@ gem 'lighstorm', path: '/home/user/lighstorm'
|
|
1048
1158
|
# demo.rb
|
1049
1159
|
require 'lighstorm'
|
1050
1160
|
|
1051
|
-
puts Lighstorm.version # => 0.0.
|
1161
|
+
puts Lighstorm.version # => 0.0.13
|
1052
1162
|
```
|
1053
1163
|
|
1054
1164
|
```sh
|
@@ -1285,13 +1395,13 @@ gem build lighstorm.gemspec
|
|
1285
1395
|
|
1286
1396
|
gem signin
|
1287
1397
|
|
1288
|
-
gem push lighstorm-0.0.
|
1398
|
+
gem push lighstorm-0.0.13.gem
|
1289
1399
|
```
|
1290
1400
|
|
1291
1401
|
_________________
|
1292
1402
|
|
1293
1403
|
<center>
|
1294
|
-
lighstorm 0.0.
|
1404
|
+
lighstorm 0.0.13
|
1295
1405
|
|
|
1296
1406
|
<a href="https://github.com/icebaker/lighstorm" rel="noopener noreferrer" target="_blank">GitHub</a>
|
1297
1407
|
|
|
data/docs/_coverpage.md
CHANGED
data/docs/index.html
CHANGED
data/lighstorm.gemspec
CHANGED
@@ -32,7 +32,7 @@ Gem::Specification.new do |spec|
|
|
32
32
|
spec.require_paths = ['ports/dsl']
|
33
33
|
|
34
34
|
spec.add_dependency 'dotenv', '~> 2.8', '>= 2.8.1'
|
35
|
-
spec.add_dependency 'lnd-client', '~> 0.0.
|
35
|
+
spec.add_dependency 'lnd-client', '~> 0.0.6'
|
36
36
|
spec.add_dependency 'zache', '~> 0.12.0'
|
37
37
|
|
38
38
|
spec.metadata['rubygems_mfa_required'] = 'true'
|
data/models/activity.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'invoice'
|
4
|
+
require_relative 'transaction'
|
5
|
+
|
6
|
+
module Lighstorm
|
7
|
+
module Models
|
8
|
+
class Activity
|
9
|
+
attr_reader :direction, :at, :message, :layer, :how, :_key
|
10
|
+
|
11
|
+
def initialize(data)
|
12
|
+
@data = data
|
13
|
+
|
14
|
+
@_key = @data[:_key]
|
15
|
+
@at = @data[:at]
|
16
|
+
@direction = @data[:direction]
|
17
|
+
@layer = @data[:layer]
|
18
|
+
@how = @data[:how]
|
19
|
+
@message = @data[:message]
|
20
|
+
end
|
21
|
+
|
22
|
+
def amount
|
23
|
+
@amount ||= Satoshis.new(millisatoshis: @data[:amount][:millisatoshis])
|
24
|
+
end
|
25
|
+
|
26
|
+
def invoice
|
27
|
+
@invoice ||= @data[:data][:invoice].nil? ? nil : Invoice.new(@data[:data][:invoice])
|
28
|
+
end
|
29
|
+
|
30
|
+
def transaction
|
31
|
+
@transaction ||= @data[:data][:transaction].nil? ? nil : Transaction.new(@data[:data][:transaction])
|
32
|
+
end
|
33
|
+
|
34
|
+
def to_h
|
35
|
+
output = {
|
36
|
+
_key: _key,
|
37
|
+
at: at,
|
38
|
+
direction: direction,
|
39
|
+
amount: amount.to_h,
|
40
|
+
how: how,
|
41
|
+
message: message
|
42
|
+
}
|
43
|
+
|
44
|
+
output[:invoice] = invoice.to_h unless invoice.nil?
|
45
|
+
output[:transaction] = transaction.to_h unless transaction.nil?
|
46
|
+
|
47
|
+
output
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
data/models/transaction.rb
CHANGED
@@ -1,43 +1,38 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative '
|
3
|
+
require_relative './satoshis'
|
4
4
|
|
5
5
|
module Lighstorm
|
6
6
|
module Models
|
7
7
|
class Transaction
|
8
|
-
attr_reader :
|
8
|
+
attr_reader :_key, :at, :hash, :label
|
9
9
|
|
10
10
|
def initialize(data)
|
11
11
|
@data = data
|
12
12
|
|
13
13
|
@_key = @data[:_key]
|
14
14
|
@at = @data[:at]
|
15
|
-
@
|
16
|
-
@
|
17
|
-
@message = @data[:message]
|
15
|
+
@hash = @data[:hash]
|
16
|
+
@label = @data[:label]
|
18
17
|
end
|
19
18
|
|
20
19
|
def amount
|
21
20
|
@amount ||= Satoshis.new(millisatoshis: @data[:amount][:millisatoshis])
|
22
21
|
end
|
23
22
|
|
24
|
-
def
|
25
|
-
@
|
23
|
+
def fee
|
24
|
+
@fee ||= Satoshis.new(millisatoshis: @data[:fee][:millisatoshis])
|
26
25
|
end
|
27
26
|
|
28
27
|
def to_h
|
29
|
-
|
28
|
+
{
|
30
29
|
_key: _key,
|
31
30
|
at: at,
|
32
|
-
|
31
|
+
hash: hash,
|
33
32
|
amount: amount.to_h,
|
34
|
-
|
35
|
-
|
33
|
+
fee: fee.to_h,
|
34
|
+
label: label
|
36
35
|
}
|
37
|
-
|
38
|
-
output[:invoice] = invoice.to_h unless invoice.nil?
|
39
|
-
|
40
|
-
output
|
41
36
|
end
|
42
37
|
end
|
43
38
|
end
|
data/ports/dsl/lighstorm.rb
CHANGED
@@ -11,7 +11,7 @@ require_relative '../../controllers/channel'
|
|
11
11
|
require_relative '../../controllers/payment'
|
12
12
|
require_relative '../../controllers/forward'
|
13
13
|
require_relative '../../controllers/invoice'
|
14
|
-
require_relative '../../controllers/
|
14
|
+
require_relative '../../controllers/activity'
|
15
15
|
|
16
16
|
module Lighstorm
|
17
17
|
Node = Controllers::Node
|
@@ -19,12 +19,12 @@ module Lighstorm
|
|
19
19
|
Payment = Controllers::Payment
|
20
20
|
Forward = Controllers::Forward
|
21
21
|
Invoice = Controllers::Invoice
|
22
|
-
|
22
|
+
Activity = Controllers::Activity
|
23
23
|
|
24
24
|
Satoshis = Models::Satoshis
|
25
25
|
|
26
|
-
def self.
|
27
|
-
LND.instance.config
|
26
|
+
def self.connect!(config)
|
27
|
+
LND.instance.connect!(config)
|
28
28
|
end
|
29
29
|
|
30
30
|
def self.inject_middleware!(middleware_lambda)
|
data/static/cache.rb
CHANGED
data/static/spec.rb
CHANGED
@@ -4,7 +4,7 @@ module Lighstorm
|
|
4
4
|
module Static
|
5
5
|
SPEC = {
|
6
6
|
name: 'lighstorm',
|
7
|
-
version: '0.0.
|
7
|
+
version: '0.0.13',
|
8
8
|
author: 'icebaker',
|
9
9
|
summary: 'API for interacting with a Lightning Node.',
|
10
10
|
description: 'Lighstorm is an opinionated abstraction layer on top of the lnd-client for interacting with a Lightning Node.',
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lighstorm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.13
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- icebaker
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-03-
|
11
|
+
date: 2023-03-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: dotenv
|
@@ -36,14 +36,14 @@ dependencies:
|
|
36
36
|
requirements:
|
37
37
|
- - "~>"
|
38
38
|
- !ruby/object:Gem::Version
|
39
|
-
version: 0.0.
|
39
|
+
version: 0.0.6
|
40
40
|
type: :runtime
|
41
41
|
prerelease: false
|
42
42
|
version_requirements: !ruby/object:Gem::Requirement
|
43
43
|
requirements:
|
44
44
|
- - "~>"
|
45
45
|
- !ruby/object:Gem::Version
|
46
|
-
version: 0.0.
|
46
|
+
version: 0.0.6
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: zache
|
49
49
|
requirement: !ruby/object:Gem::Requirement
|
@@ -85,9 +85,12 @@ files:
|
|
85
85
|
- adapters/edges/payment/purpose.rb
|
86
86
|
- adapters/invoice.rb
|
87
87
|
- adapters/nodes/node.rb
|
88
|
+
- adapters/transaction.rb
|
88
89
|
- components/cache.rb
|
89
90
|
- components/lnd.rb
|
90
91
|
- controllers/action.rb
|
92
|
+
- controllers/activity.rb
|
93
|
+
- controllers/activity/all.rb
|
91
94
|
- controllers/channel.rb
|
92
95
|
- controllers/channel/actions/apply_gossip.rb
|
93
96
|
- controllers/channel/actions/update_fee.rb
|
@@ -130,6 +133,7 @@ files:
|
|
130
133
|
- docs/vendor/prismjs/prism-tomorrow.min.css
|
131
134
|
- helpers/time_expression.rb
|
132
135
|
- lighstorm.gemspec
|
136
|
+
- models/activity.rb
|
133
137
|
- models/concerns/protectable.rb
|
134
138
|
- models/connections/channel_node.rb
|
135
139
|
- models/connections/channel_node/accounting.rb
|