lighstorm 0.0.12 → 0.0.14
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.env.example +18 -3
- data/Gemfile.lock +4 -4
- data/README.md +11 -5
- data/adapters/connections/channel_node.rb +1 -0
- data/adapters/edges/payment/purpose.rb +3 -3
- data/adapters/edges/payment.rb +1 -3
- data/adapters/invoice.rb +0 -2
- data/adapters/transaction.rb +23 -0
- data/adapters/wallet.rb +42 -0
- data/components/cache.rb +1 -1
- data/components/lnd.rb +67 -29
- data/controllers/action.rb +5 -0
- data/controllers/activity/all.rb +194 -0
- data/controllers/activity.rb +26 -0
- data/controllers/channel/actions/apply_gossip.rb +3 -4
- data/controllers/channel/actions/update_fee.rb +11 -7
- data/controllers/channel/all.rb +11 -7
- data/controllers/channel/find_by_id.rb +11 -11
- data/controllers/channel/mine.rb +10 -10
- data/controllers/channel.rb +25 -11
- data/controllers/concerns/impersonatable.rb +33 -0
- data/controllers/connection.rb +33 -0
- data/controllers/forward/all.rb +16 -12
- data/controllers/forward/group_by_channel.rb +2 -2
- data/controllers/forward.rb +19 -13
- data/controllers/invoice/actions/create.rb +21 -13
- data/controllers/invoice/actions/pay.rb +13 -12
- data/controllers/invoice/actions/pay_through_route.rb +2 -2
- data/controllers/invoice/all.rb +7 -7
- data/controllers/invoice/decode.rb +6 -6
- data/controllers/invoice/find_by_code.rb +7 -7
- data/controllers/invoice/find_by_secret_hash.rb +10 -6
- data/controllers/invoice.rb +46 -39
- data/controllers/node/actions/apply_gossip.rb +1 -1
- data/controllers/node/actions/pay.rb +13 -12
- data/controllers/node/all.rb +11 -7
- data/controllers/node/find_by_public_key.rb +11 -7
- data/controllers/node/myself.rb +6 -6
- data/controllers/node.rb +17 -11
- data/controllers/payment/actions/pay.rb +23 -19
- data/controllers/payment/all.rb +7 -4
- data/controllers/payment.rb +20 -14
- data/controllers/secret/valid_proof.rb +5 -5
- data/controllers/transaction/all.rb +29 -73
- data/controllers/transaction.rb +14 -6
- data/controllers/wallet/balance.rb +34 -0
- data/controllers/wallet.rb +19 -0
- data/docs/README.md +204 -31
- data/docs/_coverpage.md +1 -1
- data/docs/index.html +1 -1
- data/lighstorm.gemspec +1 -1
- data/models/activity.rb +52 -0
- data/models/connections/channel_node/fee.rb +5 -2
- data/models/connections/channel_node/policy.rb +3 -2
- data/models/connections/channel_node.rb +14 -4
- data/models/connections/forward_channel.rb +3 -2
- data/models/edges/channel/hop.rb +1 -1
- data/models/edges/channel.rb +5 -7
- data/models/edges/forward.rb +4 -3
- data/models/edges/groups/channel_forwards.rb +3 -2
- data/models/edges/payment.rb +4 -3
- data/models/errors.rb +16 -24
- data/models/invoice.rb +10 -4
- data/models/nodes/node.rb +10 -4
- data/models/secret.rb +10 -4
- data/models/transaction.rb +10 -15
- data/models/wallet.rb +40 -0
- data/ports/dsl/lighstorm.rb +8 -4
- data/ports/grpc.rb +30 -2
- data/static/cache.rb +3 -0
- data/static/spec.rb +1 -1
- metadata +14 -5
- data/deleted.sh +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9b600975d39699ef54c291ec8a06aa0d3f4284df248df2093ed85c3656dea685
|
4
|
+
data.tar.gz: 6d6373c5013c5ed9ad9f8479b26072da38f5847ba1e22b845132bd01167cacf2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 66a0b3ea07b3201a388b68cf91f38aad7d98ceecf1bd9138f699830c3539ea6522cfdb9a23479bebd3f88563a265fa04bc10e510c033eeb228dbbd039e97cc52
|
7
|
+
data.tar.gz: 32c16160feef6212038150df78f539c4b4adca382f440729217f3916871912f20fdbe2add7d4c74be22d14e0f3bb5e5369e6788124b6e6ad879368ffad60c948
|
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.14)
|
5
5
|
dotenv (~> 2.8, >= 2.8.1)
|
6
|
-
lnd-client (~> 0.0.
|
6
|
+
lnd-client (~> 0.0.7)
|
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.7)
|
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.14'
|
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.14
|
51
57
|
|
52
58
|
Lighstorm::Node.myself.alias # => icebaker/old-stone
|
53
59
|
|
@@ -10,6 +10,7 @@ module Lighstorm
|
|
10
10
|
data = {
|
11
11
|
_source: :list_channels,
|
12
12
|
state: grpc[:active] ? 'active' : 'inactive',
|
13
|
+
initiator: grpc[:initiator] && key == :local,
|
13
14
|
accounting: { balance: { millisatoshis: grpc[:"#{key}_balance"] * 1000 } },
|
14
15
|
node: Node.list_channels(grpc, key)
|
15
16
|
}
|
@@ -16,9 +16,9 @@ module Lighstorm
|
|
16
16
|
def self.list_payments(grpc, node_get_info)
|
17
17
|
return 'unknown' if grpc[:htlcs].empty?
|
18
18
|
|
19
|
-
return 'self-payment' if self_payment?(grpc[:htlcs].
|
20
|
-
return 'peer-to-peer' if peer_to_peer?(grpc[:htlcs].
|
21
|
-
return 'rebalance' if rebalance?(grpc[:htlcs].
|
19
|
+
return 'self-payment' if self_payment?(grpc[:htlcs].last[:route][:hops])
|
20
|
+
return 'peer-to-peer' if peer_to_peer?(grpc[:htlcs].last[:route][:hops])
|
21
|
+
return 'rebalance' if rebalance?(grpc[:htlcs].last[:route][:hops], node_get_info)
|
22
22
|
|
23
23
|
'payment'
|
24
24
|
end
|
data/adapters/edges/payment.rb
CHANGED
@@ -30,8 +30,6 @@ module Lighstorm
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def self.list_payments(grpc, node_myself, invoice_decode = nil)
|
33
|
-
raise UnexpectedNumberOfHTLCsError, "htlcs: #{grpc[:htlcs].size}" if grpc[:htlcs].size > 1
|
34
|
-
|
35
33
|
data = {
|
36
34
|
_source: :list_payments,
|
37
35
|
_key: _key(grpc),
|
@@ -45,7 +43,7 @@ module Lighstorm
|
|
45
43
|
|
46
44
|
data[:secret] = data[:invoice][:secret]
|
47
45
|
|
48
|
-
htlc = grpc[:htlcs].
|
46
|
+
htlc = grpc[:htlcs].last
|
49
47
|
|
50
48
|
return data if htlc.nil?
|
51
49
|
|
data/adapters/invoice.rb
CHANGED
@@ -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/adapters/wallet.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'digest'
|
4
|
+
|
5
|
+
module Lighstorm
|
6
|
+
module Adapter
|
7
|
+
class Wallet
|
8
|
+
def self.balance(raw)
|
9
|
+
{
|
10
|
+
_key: Digest::SHA256.hexdigest(
|
11
|
+
[
|
12
|
+
raw[:at],
|
13
|
+
channel_balance(raw[:channel_balance])[:amount],
|
14
|
+
wallet_balance(raw[:wallet_balance])[:amount]
|
15
|
+
].join('/')
|
16
|
+
),
|
17
|
+
at: raw[:at],
|
18
|
+
bitcoin: wallet_balance(raw[:wallet_balance])[:amount],
|
19
|
+
lightning: channel_balance(raw[:channel_balance])[:amount],
|
20
|
+
total: { millisatoshis: (
|
21
|
+
wallet_balance(raw[:wallet_balance])[:amount][:millisatoshis] +
|
22
|
+
channel_balance(raw[:channel_balance])[:amount][:millisatoshis]
|
23
|
+
) }
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.wallet_balance(grpc)
|
28
|
+
{
|
29
|
+
_source: :wallet_balance,
|
30
|
+
amount: { millisatoshis: grpc[:total_balance] * 1000 }
|
31
|
+
}
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.channel_balance(grpc)
|
35
|
+
{
|
36
|
+
_source: :channel_balance,
|
37
|
+
amount: { millisatoshis: grpc[:local_balance][:msat] }
|
38
|
+
}
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/components/cache.rb
CHANGED
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,50 +10,88 @@ 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
|
+
|
36
|
+
def as(id)
|
37
|
+
LNDClient.as(id)
|
38
|
+
end
|
39
|
+
|
40
|
+
def add_connection!(...)
|
41
|
+
LNDClient.add_connection!(...)
|
42
|
+
end
|
43
|
+
|
44
|
+
def connections(...)
|
45
|
+
LNDClient.connections(...)
|
46
|
+
end
|
47
|
+
|
48
|
+
def remove_connection!(...)
|
49
|
+
LNDClient.remove_connection!(...)
|
50
|
+
end
|
51
|
+
|
21
52
|
def middleware(key, &block)
|
22
53
|
@middleware.call(key, &block)
|
23
54
|
end
|
24
55
|
|
56
|
+
def for(id)
|
57
|
+
as(id)&.connection
|
58
|
+
end
|
59
|
+
|
60
|
+
def default
|
61
|
+
client.connection.merge(id: @default_key)
|
62
|
+
end
|
63
|
+
|
25
64
|
def client
|
26
|
-
|
65
|
+
try_to_connect_from_environment_variables! unless LNDClient.connections.include?(@default_key)
|
66
|
+
LNDClient.as(@default_key)
|
67
|
+
end
|
27
68
|
|
28
|
-
|
29
|
-
|
30
|
-
).nil?
|
69
|
+
def try_to_connect_from_environment_variables!
|
70
|
+
return connect!(ENV.fetch('LIGHSTORM_LND_CONNECT')) if ENV.fetch('LIGHSTORM_LND_CONNECT', nil)
|
31
71
|
|
32
|
-
|
33
|
-
create_client_from_config
|
34
|
-
else
|
35
|
-
create_client_from_environment_variables
|
36
|
-
end
|
72
|
+
params = {}
|
37
73
|
|
38
|
-
|
74
|
+
raise MissingCredentialsError, 'missing credentials [address]' unless ENV.fetch('LIGHSTORM_LND_ADDRESS', nil)
|
39
75
|
|
40
|
-
|
41
|
-
end
|
76
|
+
params[:address] = ENV.fetch('LIGHSTORM_LND_ADDRESS')
|
42
77
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
78
|
+
if ENV.fetch('LIGHSTORM_LND_CERTIFICATE', nil)
|
79
|
+
params[:certificate] = ENV.fetch('LIGHSTORM_LND_CERTIFICATE')
|
80
|
+
elsif ENV.fetch('LIGHSTORM_LND_CERTIFICATE_PATH', nil)
|
81
|
+
params[:certificate_path] = ENV.fetch('LIGHSTORM_LND_CERTIFICATE_PATH')
|
82
|
+
else
|
83
|
+
raise MissingCredentialsError, 'missing credentials [certificate]'
|
84
|
+
end
|
85
|
+
|
86
|
+
if ENV.fetch('LIGHSTORM_LND_MACAROON', nil)
|
87
|
+
params[:macaroon] = ENV.fetch('LIGHSTORM_LND_MACAROON')
|
88
|
+
elsif ENV.fetch('LIGHSTORM_LND_MACAROON_PATH', nil)
|
89
|
+
params[:macaroon_path] = ENV.fetch('LIGHSTORM_LND_MACAROON_PATH')
|
90
|
+
else
|
91
|
+
raise MissingCredentialsError, 'missing credentials [macaroon]'
|
92
|
+
end
|
50
93
|
|
51
|
-
|
52
|
-
LNDClient.new(
|
53
|
-
socket_address: ENV.fetch('LIGHSTORM_LND_ADDRESS', nil),
|
54
|
-
certificate_path: ENV.fetch('LIGHSTORM_CERTIFICATE_PATH', nil),
|
55
|
-
macaroon_path: ENV.fetch('LIGHSTORM_MACAROON_PATH', nil)
|
56
|
-
)
|
94
|
+
connect!(params)
|
57
95
|
end
|
58
96
|
end
|
59
97
|
end
|
data/controllers/action.rb
CHANGED
@@ -4,6 +4,10 @@ module Lighstorm
|
|
4
4
|
module Controllers
|
5
5
|
module Action
|
6
6
|
Output = Struct.new(:data) do
|
7
|
+
def request
|
8
|
+
data[:request]
|
9
|
+
end
|
10
|
+
|
7
11
|
def response
|
8
12
|
data[:response]
|
9
13
|
end
|
@@ -14,6 +18,7 @@ module Lighstorm
|
|
14
18
|
|
15
19
|
def to_h
|
16
20
|
{
|
21
|
+
request: request,
|
17
22
|
response: response,
|
18
23
|
result: result.to_h
|
19
24
|
}
|
@@ -0,0 +1,194 @@
|
|
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.bitcoin_how(transaction_label)
|
14
|
+
if transaction_label =~ /:openchannel:/
|
15
|
+
'opening-channel'
|
16
|
+
elsif transaction_label =~ /:closechannel:/
|
17
|
+
'closing-channel'
|
18
|
+
else
|
19
|
+
'spontaneously'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.fetch(components, direction: nil, layer: nil, how: nil, order: nil, limit: nil)
|
24
|
+
activities = []
|
25
|
+
|
26
|
+
# components[:grpc].lightning.list_channels.channels.each do |channel|
|
27
|
+
# if (layer.nil? || layer == 'lightning')
|
28
|
+
# activities << {
|
29
|
+
# direction: 'out',
|
30
|
+
# layer: 'lightning',
|
31
|
+
# at: Time.now,
|
32
|
+
# amount: {
|
33
|
+
# millisatoshis: channel.to_h[:local_chan_reserve_sat] * 1000
|
34
|
+
# },
|
35
|
+
# how: 'reserve',
|
36
|
+
# message: nil,
|
37
|
+
# data: {}
|
38
|
+
# }
|
39
|
+
|
40
|
+
# activities << {
|
41
|
+
# direction: 'out',
|
42
|
+
# layer: 'lightning',
|
43
|
+
# at: Time.now,
|
44
|
+
# amount: {
|
45
|
+
# millisatoshis: channel.to_h[:commit_fee] * 1000
|
46
|
+
# },
|
47
|
+
# how: 'commit',
|
48
|
+
# message: nil,
|
49
|
+
# data: {}
|
50
|
+
# }
|
51
|
+
# end
|
52
|
+
# end
|
53
|
+
|
54
|
+
Transaction::All.data(components).each do |transaction|
|
55
|
+
transaction_how = bitcoin_how(transaction[:label])
|
56
|
+
|
57
|
+
if (layer.nil? || layer == 'bitcoin') && (how.nil? || transaction_how =~ /#{Regexp.escape(how)}/)
|
58
|
+
activities << {
|
59
|
+
direction: (transaction[:amount][:millisatoshis]).positive? ? 'in' : 'out',
|
60
|
+
layer: 'bitcoin',
|
61
|
+
at: transaction[:at],
|
62
|
+
amount: {
|
63
|
+
millisatoshis: if (transaction[:amount][:millisatoshis]).positive?
|
64
|
+
transaction[:amount][:millisatoshis]
|
65
|
+
else
|
66
|
+
-transaction[:amount][:millisatoshis]
|
67
|
+
end
|
68
|
+
},
|
69
|
+
how: transaction_how,
|
70
|
+
message: nil,
|
71
|
+
data: { transaction: transaction }
|
72
|
+
}
|
73
|
+
end
|
74
|
+
|
75
|
+
next unless (layer.nil? || layer == 'lightning') && (how.nil? || transaction_how =~ /#{Regexp.escape(how)}/) && %w[
|
76
|
+
channel opening-channel closing-channel
|
77
|
+
].include?(transaction_how)
|
78
|
+
|
79
|
+
activities << {
|
80
|
+
direction: (transaction[:amount][:millisatoshis]).positive? ? 'out' : 'in',
|
81
|
+
layer: 'lightning',
|
82
|
+
at: transaction[:at] + ((transaction[:amount][:millisatoshis]).positive? ? -1 : 1),
|
83
|
+
amount: {
|
84
|
+
millisatoshis: if (transaction[:amount][:millisatoshis]).positive?
|
85
|
+
(transaction[:amount][:millisatoshis] - transaction[:fee][:millisatoshis])
|
86
|
+
else
|
87
|
+
-(transaction[:amount][:millisatoshis] + transaction[:fee][:millisatoshis])
|
88
|
+
end
|
89
|
+
},
|
90
|
+
how: transaction_how,
|
91
|
+
message: nil,
|
92
|
+
data: { transaction: transaction }
|
93
|
+
}
|
94
|
+
end
|
95
|
+
|
96
|
+
if (direction.nil? || direction == 'in') && (layer.nil? || layer == 'lightning')
|
97
|
+
Invoice::All.data(components, spontaneous: true).filter do |invoice|
|
98
|
+
!invoice[:payments].nil? && invoice[:payments].size.positive?
|
99
|
+
end.each do |invoice|
|
100
|
+
activity_how = invoice[:code].nil? ? 'spontaneously' : 'with-invoice'
|
101
|
+
|
102
|
+
next if !how.nil? && how != activity_how
|
103
|
+
|
104
|
+
# TODO: Improve performance by reducing invoice fields and removing payments?
|
105
|
+
invoice[:payments].each do |payment|
|
106
|
+
activities << {
|
107
|
+
direction: 'in',
|
108
|
+
layer: 'lightning',
|
109
|
+
at: payment[:at],
|
110
|
+
amount: payment[:amount],
|
111
|
+
how: activity_how,
|
112
|
+
message: payment[:message],
|
113
|
+
data: { invoice: invoice }
|
114
|
+
}
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
Forward::All.data(components).each do |forward|
|
119
|
+
next if !how.nil? && how != 'forwarding'
|
120
|
+
|
121
|
+
activities << {
|
122
|
+
direction: 'in',
|
123
|
+
layer: 'lightning',
|
124
|
+
at: forward[:at],
|
125
|
+
amount: forward[:fee],
|
126
|
+
how: 'forwarding',
|
127
|
+
message: nil,
|
128
|
+
data: {}
|
129
|
+
}
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
if (direction.nil? || direction == 'out') && (layer.nil? || layer == 'lightning')
|
134
|
+
Payment::All.data(
|
135
|
+
components,
|
136
|
+
fetch: {
|
137
|
+
get_node_info: false,
|
138
|
+
lookup_invoice: false,
|
139
|
+
decode_pay_req: true,
|
140
|
+
get_chan_info: false
|
141
|
+
}
|
142
|
+
)[:data].each do |payment|
|
143
|
+
activity_how = payment[:invoice][:code].nil? ? 'spontaneously' : 'with-invoice'
|
144
|
+
|
145
|
+
next if !how.nil? && how != activity_how
|
146
|
+
|
147
|
+
# TODO: Improve performance by reducing invoice fields?
|
148
|
+
activities << {
|
149
|
+
direction: 'out',
|
150
|
+
layer: 'lightning',
|
151
|
+
at: payment[:at],
|
152
|
+
amount: payment[:amount],
|
153
|
+
how: activity_how,
|
154
|
+
message: payment[:message],
|
155
|
+
data: { invoice: payment[:invoice] }
|
156
|
+
}
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
activities = if order.nil? || order == 'desc'
|
161
|
+
activities.sort_by { |activity| -activity[:at].to_i }
|
162
|
+
else
|
163
|
+
activities.sort_by { |activity| activity[:at].to_i }
|
164
|
+
end
|
165
|
+
|
166
|
+
activities = activities[0..limit - 1] unless limit.nil?
|
167
|
+
|
168
|
+
{ activities: activities }
|
169
|
+
end
|
170
|
+
|
171
|
+
def self.transform(raw)
|
172
|
+
raw[:activities].map do |activity|
|
173
|
+
activity[:_key] = SecureRandom.hex
|
174
|
+
activity
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
def self.data(components, direction: nil, layer: nil, how: nil, order: nil, limit: nil, &vcr)
|
179
|
+
raw = if vcr.nil?
|
180
|
+
fetch(components, direction: direction, layer: layer, how: how, order: order, limit: limit)
|
181
|
+
else
|
182
|
+
vcr.call(-> { fetch(components, direction: direction, how: how, order: order, limit: limit) })
|
183
|
+
end
|
184
|
+
|
185
|
+
transform(raw)
|
186
|
+
end
|
187
|
+
|
188
|
+
def self.model(data)
|
189
|
+
data.map { |data| Models::Activity.new(data) }
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative './concerns/impersonatable'
|
4
|
+
|
5
|
+
require_relative './activity/all'
|
6
|
+
|
7
|
+
module Lighstorm
|
8
|
+
module Controllers
|
9
|
+
module Activity
|
10
|
+
extend Impersonatable
|
11
|
+
|
12
|
+
class DSL < Impersonatable::DSL
|
13
|
+
def all(direction: nil, layer: nil, how: nil, order: nil, limit: nil)
|
14
|
+
All.model(All.data(
|
15
|
+
components,
|
16
|
+
direction: direction,
|
17
|
+
how: how,
|
18
|
+
layer: layer,
|
19
|
+
order: order,
|
20
|
+
limit: limit
|
21
|
+
))
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -2,7 +2,6 @@
|
|
2
2
|
|
3
3
|
require 'securerandom'
|
4
4
|
|
5
|
-
require_relative '../../../ports/grpc'
|
6
5
|
require_relative '../../../models/errors'
|
7
6
|
require_relative '../../../models/edges/channel'
|
8
7
|
require_relative '../../../adapters/edges/channel'
|
@@ -41,7 +40,7 @@ module Lighstorm
|
|
41
40
|
].freeze
|
42
41
|
|
43
42
|
def self.perform(actual, gossip)
|
44
|
-
updated = Models::Channel.new(Adapter::Channel.subscribe_channel_graph(gossip))
|
43
|
+
updated = Models::Channel.new(Adapter::Channel.subscribe_channel_graph(gossip), nil)
|
45
44
|
|
46
45
|
actual_dump = actual.dump
|
47
46
|
updated_dump = updated.dump
|
@@ -99,7 +98,7 @@ module Lighstorm
|
|
99
98
|
when 'partners/0/policy/htlc/minimum/millisatoshis',
|
100
99
|
'partners/1/policy/htlc/minimum/millisatoshis' then
|
101
100
|
if actual.partners[change[:path][1]].policy.nil?
|
102
|
-
actual.partners[change[:path][1]].policy = Lighstorm::Models::Policy.new({})
|
101
|
+
actual.partners[change[:path][1]].policy = Lighstorm::Models::Policy.new({}, nil)
|
103
102
|
end
|
104
103
|
|
105
104
|
policy = actual.partners[change[:path][1]].policy
|
@@ -113,7 +112,7 @@ module Lighstorm
|
|
113
112
|
when 'partners/0/policy/htlc/blocks/delta/minimum',
|
114
113
|
'partners/1/policy/htlc/blocks/delta/minimum' then
|
115
114
|
if actual.partners[change[:path][1]].policy.nil?
|
116
|
-
actual.partners[change[:path][1]].policy = Lighstorm::Models::Policy.new({})
|
115
|
+
actual.partners[change[:path][1]].policy = Lighstorm::Models::Policy.new({}, nil)
|
117
116
|
end
|
118
117
|
|
119
118
|
policy = actual.partners[change[:path][1]].policy
|
@@ -46,22 +46,26 @@ module Lighstorm
|
|
46
46
|
grpc_request
|
47
47
|
end
|
48
48
|
|
49
|
-
def self.call(grpc_request)
|
50
|
-
|
49
|
+
def self.call(components, grpc_request)
|
50
|
+
components[:grpc].send(grpc_request[:service]).send(
|
51
51
|
grpc_request[:method], grpc_request[:params]
|
52
52
|
).to_h
|
53
53
|
end
|
54
54
|
|
55
|
-
def self.dispatch(grpc_request, &vcr)
|
56
|
-
vcr.nil?
|
55
|
+
def self.dispatch(components, grpc_request, &vcr)
|
56
|
+
if vcr.nil?
|
57
|
+
call(components, grpc_request)
|
58
|
+
else
|
59
|
+
vcr.call(-> { call(components, grpc_request) }, :dispatch)
|
60
|
+
end
|
57
61
|
end
|
58
62
|
|
59
|
-
def self.perform(policy, transaction, params, preview: false, &vcr)
|
63
|
+
def self.perform(components, policy, transaction, params, preview: false, &vcr)
|
60
64
|
grpc_request = prepare(policy.to_h, transaction.to_h, params)
|
61
65
|
|
62
66
|
return grpc_request if preview
|
63
67
|
|
64
|
-
response = dispatch(grpc_request, &vcr)
|
68
|
+
response = dispatch(components, grpc_request, &vcr)
|
65
69
|
|
66
70
|
raise UpdateChannelPolicyError.new(nil, response) unless response[:failed_updates].empty?
|
67
71
|
|
@@ -79,7 +83,7 @@ module Lighstorm
|
|
79
83
|
token: token
|
80
84
|
}
|
81
85
|
|
82
|
-
Action::Output.new({ response: response, result: policy })
|
86
|
+
Action::Output.new({ request: grpc_request, response: response, result: policy })
|
83
87
|
end
|
84
88
|
end
|
85
89
|
end
|