committed by
GitHub
43 changed files with 1375 additions and 376 deletions
@ -0,0 +1,9 @@ |
|||||
|
// Cert will be located depending on your machine
|
||||
|
// Mac OS X: /Users/user/Library/Application Support/Lnd/tls.cert
|
||||
|
// Linux: ~/.lnd/tls.cert
|
||||
|
// Windows: TODO find out where cert is located for windows machine
|
||||
|
export default { |
||||
|
lightningRpc: `${__dirname}/rpc.proto`, |
||||
|
lightningHost: 'localhost:10009', |
||||
|
cert: '/Users/jmow/Library/Application Support/Lnd/tls.cert' |
||||
|
} |
@ -0,0 +1,690 @@ |
|||||
|
syntax = "proto3"; |
||||
|
|
||||
|
//import "google/api/annotations.proto"; |
||||
|
|
||||
|
package lnrpc; |
||||
|
|
||||
|
service Lightning { |
||||
|
rpc WalletBalance (WalletBalanceRequest) returns (WalletBalanceResponse) { |
||||
|
option (google.api.http) = { |
||||
|
get: "/v1/balance/blockchain" |
||||
|
}; |
||||
|
} |
||||
|
rpc ChannelBalance (ChannelBalanceRequest) returns (ChannelBalanceResponse) { |
||||
|
option (google.api.http) = { |
||||
|
get: "/v1/balance/channels" |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
rpc GetTransactions (GetTransactionsRequest) returns (TransactionDetails) { |
||||
|
option (google.api.http) = { |
||||
|
get: "/v1/transactions" |
||||
|
}; |
||||
|
} |
||||
|
rpc SendCoins (SendCoinsRequest) returns (SendCoinsResponse) { |
||||
|
option (google.api.http) = { |
||||
|
post: "/v1/transactions" |
||||
|
body: "*" |
||||
|
}; |
||||
|
} |
||||
|
rpc SubscribeTransactions (GetTransactionsRequest) returns (stream Transaction); |
||||
|
|
||||
|
rpc SendMany (SendManyRequest) returns (SendManyResponse); |
||||
|
|
||||
|
rpc NewAddress (NewAddressRequest) returns (NewAddressResponse); |
||||
|
rpc NewWitnessAddress (NewWitnessAddressRequest) returns (NewAddressResponse) { |
||||
|
option (google.api.http) = { |
||||
|
get: "/v1/newaddress" |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
rpc SignMessage (SignMessageRequest) returns (SignMessageResponse); |
||||
|
rpc VerifyMessage (VerifyMessageRequest) returns (VerifyMessageResponse); |
||||
|
|
||||
|
rpc ConnectPeer (ConnectPeerRequest) returns (ConnectPeerResponse) { |
||||
|
option (google.api.http) = { |
||||
|
post: "/v1/peers" |
||||
|
body: "*" |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
rpc DisconnectPeer (DisconnectPeerRequest) returns (DisconnectPeerResponse) { |
||||
|
option (google.api.http) = { |
||||
|
delete: "/v1/peers/{pub_key}" |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
rpc ListPeers (ListPeersRequest) returns (ListPeersResponse) { |
||||
|
option (google.api.http) = { |
||||
|
get: "/v1/peers" |
||||
|
}; |
||||
|
} |
||||
|
rpc GetInfo (GetInfoRequest) returns (GetInfoResponse) { |
||||
|
option (google.api.http) = { |
||||
|
get: "/v1/getinfo" |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
// TODO(roasbeef): merge with below with bool? |
||||
|
rpc PendingChannels (PendingChannelRequest) returns (PendingChannelResponse) { |
||||
|
option (google.api.http) = { |
||||
|
get: "/v1/channels/pending" |
||||
|
}; |
||||
|
} |
||||
|
rpc ListChannels (ListChannelsRequest) returns (ListChannelsResponse) { |
||||
|
option (google.api.http) = { |
||||
|
get: "/v1/channels" |
||||
|
}; |
||||
|
} |
||||
|
rpc OpenChannelSync (OpenChannelRequest) returns (ChannelPoint) { |
||||
|
option (google.api.http) = { |
||||
|
post: "/v1/channels" |
||||
|
body: "*" |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
rpc OpenChannel (OpenChannelRequest) returns (stream OpenStatusUpdate); |
||||
|
|
||||
|
rpc CloseChannel (CloseChannelRequest) returns (stream CloseStatusUpdate) { |
||||
|
option (google.api.http) = { |
||||
|
delete: "/v1/channels/{channel_point.funding_txid}/{channel_point.output_index}/{force}" |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
rpc SendPayment (stream SendRequest) returns (stream SendResponse); |
||||
|
|
||||
|
rpc SendPaymentSync (SendRequest) returns (SendResponse) { |
||||
|
option (google.api.http) = { |
||||
|
post: "/v1/channels/transactions" |
||||
|
body: "*" |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
rpc AddInvoice (Invoice) returns (AddInvoiceResponse) { |
||||
|
option (google.api.http) = { |
||||
|
post: "/v1/invoices" |
||||
|
body: "*" |
||||
|
}; |
||||
|
} |
||||
|
rpc ListInvoices (ListInvoiceRequest) returns (ListInvoiceResponse) { |
||||
|
option (google.api.http) = { |
||||
|
get: "/v1/invoices/{pending_only}" |
||||
|
}; |
||||
|
} |
||||
|
rpc LookupInvoice (PaymentHash) returns (Invoice) { |
||||
|
option (google.api.http) = { |
||||
|
get: "/v1/invoices/{r_hash_str}" |
||||
|
}; |
||||
|
} |
||||
|
rpc SubscribeInvoices (InvoiceSubscription) returns (stream Invoice) { |
||||
|
option (google.api.http) = { |
||||
|
get: "/v1/invoices/subscribe" |
||||
|
}; |
||||
|
} |
||||
|
rpc DecodePayReq (PayReqString) returns (PayReq) { |
||||
|
option (google.api.http) = { |
||||
|
get: "/v1/payreq/{pay_req}" |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
rpc ListPayments (ListPaymentsRequest) returns (ListPaymentsResponse) { |
||||
|
option (google.api.http) = { |
||||
|
get: "/v1/payments" |
||||
|
}; |
||||
|
}; |
||||
|
|
||||
|
rpc DeleteAllPayments (DeleteAllPaymentsRequest) returns (DeleteAllPaymentsResponse) { |
||||
|
option (google.api.http) = { |
||||
|
delete: "/v1/payments" |
||||
|
}; |
||||
|
}; |
||||
|
|
||||
|
rpc DescribeGraph (ChannelGraphRequest) returns (ChannelGraph) { |
||||
|
option (google.api.http) = { |
||||
|
get: "/v1/graph" |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
rpc GetChanInfo (ChanInfoRequest) returns (ChannelEdge) { |
||||
|
option (google.api.http) = { |
||||
|
get: "/v1/graph/edge/{chan_id}" |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
rpc GetNodeInfo (NodeInfoRequest) returns (NodeInfo) { |
||||
|
option (google.api.http) = { |
||||
|
get: "/v1/graph/node/{pub_key}" |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
rpc QueryRoutes(QueryRoutesRequest) returns (QueryRoutesResponse) { |
||||
|
option (google.api.http) = { |
||||
|
get: "/v1/graph/routes/{pub_key}/{amt}" |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
rpc GetNetworkInfo (NetworkInfoRequest) returns (NetworkInfo) { |
||||
|
option (google.api.http) = { |
||||
|
get: "/v1/graph/info" |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
rpc StopDaemon(StopRequest) returns (StopResponse); |
||||
|
|
||||
|
rpc SubscribeChannelGraph(GraphTopologySubscription) returns (stream GraphTopologyUpdate); |
||||
|
|
||||
|
rpc SetAlias(SetAliasRequest) returns (SetAliasResponse); |
||||
|
|
||||
|
rpc DebugLevel (DebugLevelRequest) returns (DebugLevelResponse); |
||||
|
} |
||||
|
|
||||
|
message Transaction { |
||||
|
string tx_hash = 1 [ json_name = "tx_hash" ]; |
||||
|
int64 amount = 2 [ json_name = "amount" ]; |
||||
|
int32 num_confirmations = 3 [ json_name = "num_confirmations" ]; |
||||
|
string block_hash = 4 [ json_name = "block_hash" ]; |
||||
|
int32 block_height = 5 [ json_name = "block_height" ]; |
||||
|
int64 time_stamp = 6 [ json_name = "time_stamp" ]; |
||||
|
int64 total_fees = 7 [ json_name = "total_fees" ]; |
||||
|
} |
||||
|
message GetTransactionsRequest { |
||||
|
} |
||||
|
message TransactionDetails { |
||||
|
repeated Transaction transactions = 1 [json_name = "transactions"]; |
||||
|
} |
||||
|
|
||||
|
message SendRequest { |
||||
|
bytes dest = 1; |
||||
|
string dest_string = 2; |
||||
|
|
||||
|
int64 amt = 3; |
||||
|
|
||||
|
bytes payment_hash = 4; |
||||
|
string payment_hash_string = 5; |
||||
|
|
||||
|
string payment_request = 6; |
||||
|
} |
||||
|
message SendResponse { |
||||
|
string payment_error = 1 [json_name = "payment_error"]; |
||||
|
bytes payment_preimage = 2 [json_name = "payment_preimage"]; |
||||
|
Route payment_route = 3 [json_name = "payment_route"]; |
||||
|
} |
||||
|
|
||||
|
message ChannelPoint { |
||||
|
// TODO(roasbeef): make str vs bytes into a oneof |
||||
|
bytes funding_txid = 1 [ json_name = "funding_txid" ]; |
||||
|
string funding_txid_str = 2 [ json_name = "funding_txid_str" ]; |
||||
|
uint32 output_index = 3 [ json_name = "output_index" ]; |
||||
|
} |
||||
|
|
||||
|
message LightningAddress { |
||||
|
string pubkey = 1 [json_name = "pubkey"]; |
||||
|
string host = 2 [json_name = "host"]; |
||||
|
} |
||||
|
|
||||
|
message SendManyRequest { |
||||
|
map<string, int64> AddrToAmount = 1; |
||||
|
} |
||||
|
message SendManyResponse { |
||||
|
string txid = 1 [json_name = "txid"]; |
||||
|
} |
||||
|
|
||||
|
message SendCoinsRequest { |
||||
|
string addr = 1; |
||||
|
int64 amount = 2; |
||||
|
} |
||||
|
message SendCoinsResponse { |
||||
|
string txid = 1 [json_name = "txid"]; |
||||
|
} |
||||
|
|
||||
|
message NewAddressRequest { |
||||
|
enum AddressType { |
||||
|
WITNESS_PUBKEY_HASH = 0; |
||||
|
NESTED_PUBKEY_HASH = 1; |
||||
|
PUBKEY_HASH = 2; |
||||
|
} |
||||
|
AddressType type = 1; |
||||
|
} |
||||
|
message NewWitnessAddressRequest { |
||||
|
} |
||||
|
message NewAddressResponse { |
||||
|
string address = 1 [json_name = "address"]; |
||||
|
} |
||||
|
|
||||
|
message SignMessageRequest { |
||||
|
bytes msg = 1 [ json_name = "msg" ]; |
||||
|
} |
||||
|
message SignMessageResponse { |
||||
|
string signature = 1 [ json_name = "signature" ]; |
||||
|
} |
||||
|
|
||||
|
message VerifyMessageRequest { |
||||
|
bytes msg = 1 [ json_name = "msg" ]; |
||||
|
string signature = 2 [ json_name = "signature" ]; |
||||
|
} |
||||
|
message VerifyMessageResponse { |
||||
|
bool valid = 1 [ json_name = "valid" ]; |
||||
|
string pubkey = 2 [ json_name = "pubkey" ]; |
||||
|
} |
||||
|
|
||||
|
message ConnectPeerRequest { |
||||
|
LightningAddress addr = 1; |
||||
|
bool perm = 2; |
||||
|
} |
||||
|
message ConnectPeerResponse { |
||||
|
int32 peer_id = 1 [json_name = "peer_id"]; |
||||
|
} |
||||
|
|
||||
|
message DisconnectPeerRequest { |
||||
|
string pub_key = 1 [json_name = "pub_key"]; |
||||
|
} |
||||
|
message DisconnectPeerResponse { |
||||
|
} |
||||
|
|
||||
|
message HTLC { |
||||
|
bool incoming = 1 [json_name = "incoming"]; |
||||
|
int64 amount = 2 [json_name = "amount"]; |
||||
|
bytes hash_lock = 3 [json_name = "hash_lock"]; |
||||
|
uint32 expiration_height = 4 [json_name = "expiration_height"]; |
||||
|
uint32 revocation_delay = 5 [json_name = "revocation_delay"]; |
||||
|
} |
||||
|
|
||||
|
message ActiveChannel { |
||||
|
bool active = 1 [json_name = "active"]; |
||||
|
string remote_pubkey = 2 [json_name = "remote_pubkey"]; |
||||
|
string channel_point = 3 [json_name = "channel_point"]; |
||||
|
uint64 chan_id = 4 [json_name = "chan_id"]; |
||||
|
|
||||
|
int64 capacity = 5 [json_name = "capacity"]; |
||||
|
int64 local_balance = 6 [json_name = "local_balance"]; |
||||
|
int64 remote_balance = 7 [json_name = "remote_balance"]; |
||||
|
|
||||
|
int64 commit_fee = 8 [json_name = "commit_fee"]; |
||||
|
int64 commit_weight = 9 [ json_name = "commit_weight" ]; |
||||
|
int64 fee_per_kw = 10 [json_name = "fee_per_kw"]; |
||||
|
|
||||
|
int64 unsettled_balance = 11 [json_name = "unsettled_balance"]; |
||||
|
int64 total_satoshis_sent = 12 [json_name = "total_satoshis_sent"]; |
||||
|
int64 total_satoshis_received = 13 [json_name = "total_satoshis_received"]; |
||||
|
uint64 num_updates = 14 [json_name = "num_updates"]; |
||||
|
|
||||
|
repeated HTLC pending_htlcs = 15 [json_name = "pending_htlcs"]; |
||||
|
} |
||||
|
|
||||
|
message ListChannelsRequest { |
||||
|
} |
||||
|
message ListChannelsResponse { |
||||
|
repeated ActiveChannel channels = 11 [json_name = "channels"]; |
||||
|
} |
||||
|
|
||||
|
message Peer { |
||||
|
string pub_key = 1 [json_name = "pub_key"]; |
||||
|
int32 peer_id = 2 [json_name = "peer_id"]; |
||||
|
string address = 3 [json_name = "address"]; |
||||
|
|
||||
|
uint64 bytes_sent = 4 [json_name = "bytes_sent"]; |
||||
|
uint64 bytes_recv = 5 [json_name = "bytes_recv"]; |
||||
|
|
||||
|
int64 sat_sent = 6 [json_name = "sat_sent"]; |
||||
|
int64 sat_recv = 7 [json_name = "sat_recv"]; |
||||
|
|
||||
|
bool inbound = 8 [json_name = "inbound"]; |
||||
|
|
||||
|
int64 ping_time = 9 [json_name = "ping_time"]; |
||||
|
} |
||||
|
|
||||
|
message ListPeersRequest { |
||||
|
} |
||||
|
message ListPeersResponse { |
||||
|
repeated Peer peers = 1 [json_name = "peers"]; |
||||
|
} |
||||
|
|
||||
|
message GetInfoRequest { |
||||
|
} |
||||
|
message GetInfoResponse { |
||||
|
string identity_pubkey = 1 [json_name = "identity_pubkey"]; |
||||
|
string alias = 2 [json_name = "alias"]; |
||||
|
|
||||
|
uint32 num_pending_channels = 3 [json_name = "num_pending_channels"]; |
||||
|
uint32 num_active_channels = 4 [json_name = "num_active_channels"]; |
||||
|
|
||||
|
uint32 num_peers = 5 [json_name = "num_peers"]; |
||||
|
|
||||
|
uint32 block_height = 6 [json_name = "block_height"]; |
||||
|
string block_hash = 8 [json_name = "block_hash"]; |
||||
|
|
||||
|
bool synced_to_chain = 9 [ json_name = "synced_to_chain" ]; |
||||
|
bool testnet = 10 [ json_name = "testnet" ]; |
||||
|
|
||||
|
repeated string chains = 11 [ json_name = "chains" ]; |
||||
|
} |
||||
|
|
||||
|
message ConfirmationUpdate { |
||||
|
bytes block_sha = 1; |
||||
|
int32 block_height = 2; |
||||
|
|
||||
|
uint32 num_confs_left = 3; |
||||
|
} |
||||
|
|
||||
|
message ChannelOpenUpdate { |
||||
|
ChannelPoint channel_point = 1 [json_name = "channel_point"]; |
||||
|
} |
||||
|
|
||||
|
message ChannelCloseUpdate { |
||||
|
bytes closing_txid = 1 [json_name = "closing_txid"]; |
||||
|
|
||||
|
bool success = 2 [json_name = "success"]; |
||||
|
} |
||||
|
|
||||
|
message CloseChannelRequest { |
||||
|
ChannelPoint channel_point = 1; |
||||
|
int64 time_limit = 2; |
||||
|
bool force = 3; |
||||
|
} |
||||
|
message CloseStatusUpdate { |
||||
|
oneof update { |
||||
|
PendingUpdate close_pending = 1 [json_name = "close_pending"]; |
||||
|
ConfirmationUpdate confirmation = 2 [json_name = "confirmation"]; |
||||
|
ChannelCloseUpdate chan_close = 3 [json_name = "chan_close"]; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
message PendingUpdate { |
||||
|
bytes txid = 1 [json_name = "txid"]; |
||||
|
uint32 output_index = 2 [json_name = "output_index"]; |
||||
|
} |
||||
|
|
||||
|
message OpenChannelRequest { |
||||
|
int32 target_peer_id = 1 [json_name = "target_peer_id"]; |
||||
|
bytes node_pubkey = 2 [json_name = "node_pubkey"]; |
||||
|
string node_pubkey_string = 3 [json_name = "node_pubkey_string"]; |
||||
|
|
||||
|
int64 local_funding_amount = 4 [json_name = "local_funding_amount"]; |
||||
|
int64 push_sat = 5 [json_name = "push_sat"]; |
||||
|
|
||||
|
uint32 num_confs = 6 [json_name = "num_confs"]; |
||||
|
} |
||||
|
message OpenStatusUpdate { |
||||
|
oneof update { |
||||
|
PendingUpdate chan_pending = 1 [json_name = "chan_pending"]; |
||||
|
ConfirmationUpdate confirmation = 2 [json_name = "confirmation"]; |
||||
|
ChannelOpenUpdate chan_open = 3 [json_name = "chan_open"]; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
message PendingChannelRequest {} |
||||
|
message PendingChannelResponse { |
||||
|
message PendingChannel { |
||||
|
string remote_node_pub = 1 [ json_name = "remote_node_pub" ]; |
||||
|
string channel_point = 2 [ json_name = "channel_point" ]; |
||||
|
|
||||
|
int64 capacity = 3 [ json_name = "capacity" ]; |
||||
|
|
||||
|
int64 local_balance = 4 [ json_name = "local_balance" ]; |
||||
|
int64 remote_balance = 5 [ json_name = "remote_balance" ]; |
||||
|
} |
||||
|
|
||||
|
message PendingOpenChannel { |
||||
|
PendingChannel channel = 1 [ json_name = "channel" ]; |
||||
|
|
||||
|
uint32 confirmation_height = 2 [ json_name = "confirmation_height" ]; |
||||
|
uint32 blocks_till_open = 3 [ json_name = "blocks_till_open" ]; |
||||
|
|
||||
|
int64 commit_fee = 4 [json_name = "commit_fee" ]; |
||||
|
int64 commit_weight = 5 [ json_name = "commit_weight" ]; |
||||
|
int64 fee_per_kw = 6 [ json_name = "fee_per_kw" ]; |
||||
|
} |
||||
|
|
||||
|
message ClosedChannel { |
||||
|
PendingChannel channel = 1; |
||||
|
|
||||
|
string closing_txid = 2 [ json_name = "closing_txid" ]; |
||||
|
} |
||||
|
|
||||
|
message ForceClosedChannel { |
||||
|
PendingChannel channel = 1 [ json_name = "channel" ]; |
||||
|
|
||||
|
// TODO(roasbeef): HTLC's as well? |
||||
|
|
||||
|
string closing_txid = 2 [ json_name = "closing_txid" ]; |
||||
|
|
||||
|
int64 limbo_balance = 3 [ json_name = "limbo_balance" ]; |
||||
|
uint32 maturity_height = 4 [ json_name = "maturity_height" ]; |
||||
|
uint32 blocks_til_maturity = 5 [ json_name = "blocks_til_maturity" ]; |
||||
|
} |
||||
|
|
||||
|
int64 total_limbo_balance = 1 [ json_name = "total_limbo_balance" ]; |
||||
|
repeated PendingOpenChannel pending_open_channels = 2 [ json_name = "pending_open_channels" ]; |
||||
|
repeated ClosedChannel pending_closing_channels = 3 [ json_name = "pending_closing_channels" ]; |
||||
|
repeated ForceClosedChannel pending_force_closing_channels = 4 [ json_name = "pending_force_closing_channels" ]; |
||||
|
} |
||||
|
|
||||
|
message WalletBalanceRequest { |
||||
|
bool witness_only = 1; |
||||
|
} |
||||
|
message WalletBalanceResponse { |
||||
|
int64 balance = 1 [json_name = "balance"]; |
||||
|
} |
||||
|
|
||||
|
message ChannelBalanceRequest { |
||||
|
} |
||||
|
message ChannelBalanceResponse { |
||||
|
int64 balance = 1 [json_name = "balance"]; |
||||
|
} |
||||
|
|
||||
|
message QueryRoutesRequest { |
||||
|
string pub_key = 1; |
||||
|
int64 amt = 2; |
||||
|
} |
||||
|
message QueryRoutesResponse { |
||||
|
repeated Route routes = 1 [ json_name = "routes"]; |
||||
|
} |
||||
|
|
||||
|
message Hop { |
||||
|
uint64 chan_id = 1 [json_name = "chan_id"]; |
||||
|
int64 chan_capacity = 2 [json_name = "chan_capacity"]; |
||||
|
int64 amt_to_forward = 3 [json_name = "amt_to_forward"]; |
||||
|
int64 fee = 4 [json_name = "fee"]; |
||||
|
} |
||||
|
|
||||
|
message Route { |
||||
|
uint32 total_time_lock = 1 [json_name = "total_time_lock"]; |
||||
|
int64 total_fees = 2 [json_name = "total_fees"]; |
||||
|
int64 total_amt = 3 [json_name = "total_amt"]; |
||||
|
|
||||
|
repeated Hop hops = 4 [json_name = "hops"]; |
||||
|
} |
||||
|
|
||||
|
message NodeInfoRequest { |
||||
|
string pub_key = 1; |
||||
|
} |
||||
|
|
||||
|
message NodeInfo { |
||||
|
LightningNode node = 1 [json_name = "node"]; |
||||
|
|
||||
|
uint32 num_channels = 2 [json_name = "num_channels"]; |
||||
|
int64 total_capacity = 3 [json_name = "total_capacity"]; |
||||
|
} |
||||
|
|
||||
|
message LightningNode { |
||||
|
uint32 last_update = 1 [ json_name = "last_update" ]; |
||||
|
string pub_key = 2 [ json_name = "pub_key" ]; |
||||
|
string alias = 3 [ json_name = "alias" ]; |
||||
|
repeated NodeAddress addresses = 4 [ json_name = "addresses" ]; |
||||
|
} |
||||
|
|
||||
|
message NodeAddress { |
||||
|
string network = 1 [ json_name = "network" ]; |
||||
|
string addr = 2 [ json_name = "addr" ]; |
||||
|
} |
||||
|
|
||||
|
message RoutingPolicy { |
||||
|
uint32 time_lock_delta = 1 [json_name = "time_lock_delta"]; |
||||
|
int64 min_htlc = 2 [json_name = "min_htlc"]; |
||||
|
int64 fee_base_msat = 3 [json_name = "fee_base_msat"]; |
||||
|
int64 fee_rate_milli_msat = 4 [json_name = "fee_rate_milli_msat"]; |
||||
|
} |
||||
|
|
||||
|
message ChannelEdge { |
||||
|
uint64 channel_id = 1 [json_name = "channel_id"]; |
||||
|
string chan_point = 2 [json_name = "chan_point"]; |
||||
|
|
||||
|
uint32 last_update = 3 [json_name = "last_update"]; |
||||
|
|
||||
|
string node1_pub = 4 [json_name = "node1_pub"]; |
||||
|
string node2_pub = 5 [json_name = "node2_pub"]; |
||||
|
|
||||
|
int64 capacity = 6 [json_name = "capacity"]; |
||||
|
|
||||
|
RoutingPolicy node1_policy = 7 [json_name = "node1_policy"]; |
||||
|
RoutingPolicy node2_policy = 8 [json_name = "node2_policy"]; |
||||
|
} |
||||
|
|
||||
|
message ChannelGraphRequest { |
||||
|
} |
||||
|
|
||||
|
message ChannelGraph { |
||||
|
repeated LightningNode nodes = 1 [json_name = "nodes"]; |
||||
|
repeated ChannelEdge edges = 2 [json_name = "edges"]; |
||||
|
} |
||||
|
|
||||
|
message ChanInfoRequest { |
||||
|
uint64 chan_id = 1; |
||||
|
} |
||||
|
|
||||
|
message NetworkInfoRequest { |
||||
|
} |
||||
|
message NetworkInfo { |
||||
|
uint32 graph_diameter = 1 [json_name = "graph_diameter"]; |
||||
|
double avg_out_degree = 2 [json_name = "avg_out_degree"]; |
||||
|
uint32 max_out_degree = 3 [json_name = "max_out_degree"]; |
||||
|
|
||||
|
uint32 num_nodes = 4 [json_name = "num_nodes"]; |
||||
|
uint32 num_channels = 5 [json_name = "num_channels"]; |
||||
|
|
||||
|
int64 total_network_capacity = 6 [json_name = "total_network_capacity"]; |
||||
|
|
||||
|
double avg_channel_size = 7 [json_name = "avg_channel_size"]; |
||||
|
int64 min_channel_size = 8 [json_name = "min_channel_size"]; |
||||
|
int64 max_channel_size = 9 [json_name = "max_channel_size"]; |
||||
|
|
||||
|
// TODO(roasbeef): fee rate info, expiry |
||||
|
// * also additional RPC for tracking fee info once in |
||||
|
} |
||||
|
|
||||
|
message StopRequest{} |
||||
|
message StopResponse{} |
||||
|
|
||||
|
message GraphTopologySubscription {} |
||||
|
message GraphTopologyUpdate { |
||||
|
repeated NodeUpdate node_updates = 1; |
||||
|
repeated ChannelEdgeUpdate channel_updates = 2; |
||||
|
repeated ClosedChannelUpdate closed_chans = 3; |
||||
|
} |
||||
|
message NodeUpdate { |
||||
|
repeated string addresses = 1; |
||||
|
string identity_key = 2; |
||||
|
bytes global_features = 3; |
||||
|
string alias = 4; |
||||
|
} |
||||
|
message ChannelEdgeUpdate { |
||||
|
uint64 chan_id = 1; |
||||
|
|
||||
|
ChannelPoint chan_point = 2; |
||||
|
|
||||
|
int64 capacity = 3; |
||||
|
|
||||
|
RoutingPolicy routing_policy = 4; |
||||
|
|
||||
|
string advertising_node = 5; |
||||
|
string connecting_node = 6; |
||||
|
} |
||||
|
message ClosedChannelUpdate { |
||||
|
uint64 chan_id = 1; |
||||
|
int64 capacity = 2; |
||||
|
uint32 closed_height = 3; |
||||
|
ChannelPoint chan_point = 4; |
||||
|
} |
||||
|
|
||||
|
message SetAliasRequest { |
||||
|
string new_alias = 1; |
||||
|
} |
||||
|
message SetAliasResponse { |
||||
|
} |
||||
|
|
||||
|
message Invoice { |
||||
|
string memo = 1 [json_name = "memo"]; |
||||
|
bytes receipt = 2 [json_name = "receipt"]; |
||||
|
|
||||
|
bytes r_preimage = 3 [json_name = "r_preimage"]; |
||||
|
bytes r_hash = 4 [json_name = "r_hash"]; |
||||
|
|
||||
|
int64 value = 5 [json_name = "value"]; |
||||
|
|
||||
|
bool settled = 6 [json_name = "settled"]; |
||||
|
|
||||
|
int64 creation_date = 7 [json_name = "creation_date"]; |
||||
|
int64 settle_date = 8 [json_name = "settle_date"]; |
||||
|
|
||||
|
string payment_request = 9 [json_name = "payment_request"]; |
||||
|
} |
||||
|
message AddInvoiceResponse { |
||||
|
bytes r_hash = 1 [json_name = "r_hash"]; |
||||
|
|
||||
|
string payment_request = 2 [json_name = "payment_request"]; |
||||
|
} |
||||
|
message PaymentHash { |
||||
|
string r_hash_str = 1 [json_name = "r_hash_str"]; |
||||
|
bytes r_hash = 2 [json_name = "r_hash"]; |
||||
|
} |
||||
|
message ListInvoiceRequest { |
||||
|
bool pending_only = 1; |
||||
|
} |
||||
|
message ListInvoiceResponse { |
||||
|
repeated Invoice invoices = 1 [json_name = "invoices"]; |
||||
|
} |
||||
|
|
||||
|
message InvoiceSubscription { |
||||
|
} |
||||
|
|
||||
|
|
||||
|
message Payment { |
||||
|
string payment_hash = 1 [json_name = "payment_hash"]; |
||||
|
int64 value = 2 [json_name = "value"]; |
||||
|
|
||||
|
int64 creation_date = 3 [json_name = "creation_date"]; |
||||
|
|
||||
|
repeated string path = 4 [ json_name = "path" ]; |
||||
|
|
||||
|
int64 fee = 5 [json_name = "fee"]; |
||||
|
} |
||||
|
|
||||
|
message ListPaymentsRequest { |
||||
|
} |
||||
|
|
||||
|
message ListPaymentsResponse { |
||||
|
repeated Payment payments = 1 [json_name = "payments"]; |
||||
|
} |
||||
|
|
||||
|
message DeleteAllPaymentsRequest { |
||||
|
} |
||||
|
|
||||
|
message DeleteAllPaymentsResponse { |
||||
|
} |
||||
|
|
||||
|
message DebugLevelRequest { |
||||
|
bool show = 1; |
||||
|
string level_spec = 2; |
||||
|
} |
||||
|
message DebugLevelResponse { |
||||
|
string sub_systems = 1 [json_name = "sub_systems"]; |
||||
|
} |
||||
|
|
||||
|
message PayReqString { |
||||
|
string pay_req = 1; |
||||
|
} |
||||
|
message PayReq { |
||||
|
string destination = 1 [json_name = "destination"]; |
||||
|
string payment_hash = 2 [json_name = "payment_hash"]; |
||||
|
int64 num_satoshis = 3 [json_name = "num_satoshis"]; |
||||
|
} |
@ -0,0 +1,7 @@ |
|||||
|
import config from './config' |
||||
|
import lightning from './lib/lightning' |
||||
|
import methods from './methods' |
||||
|
|
||||
|
const lnd = lightning(config.lightningRpc, config.lightningHost) |
||||
|
|
||||
|
export default (event, msg, data) => methods(lnd, event, msg, data) |
@ -0,0 +1,14 @@ |
|||||
|
import fs from 'fs' |
||||
|
import grpc from 'grpc' |
||||
|
import config from '../config' |
||||
|
|
||||
|
module.exports = (path, host) => { |
||||
|
process.env.GRPC_SSL_CIPHER_SUITES = 'HIGH+ECDSA' |
||||
|
|
||||
|
const rpc = grpc.load(path) |
||||
|
|
||||
|
const lndCert = fs.readFileSync(config.cert) |
||||
|
const credentials = grpc.credentials.createSsl(lndCert) |
||||
|
|
||||
|
return new rpc.lnrpc.Lightning(host, credentials) |
||||
|
} |
@ -0,0 +1,10 @@ |
|||||
|
// LND Get Channel Balance
|
||||
|
export default function channelbalance(lnd) { |
||||
|
return new Promise((resolve, reject) => { |
||||
|
lnd.channelBalance({}, (err, data) => { |
||||
|
if (err) { reject(err) } |
||||
|
|
||||
|
resolve(data) |
||||
|
}) |
||||
|
}) |
||||
|
} |
@ -0,0 +1,10 @@ |
|||||
|
// LND List Channels
|
||||
|
export default function channels(lnd) { |
||||
|
return new Promise((resolve, reject) => { |
||||
|
lnd.listChannels({}, (err, data) => { |
||||
|
if (err) { reject(err) } |
||||
|
|
||||
|
resolve(data) |
||||
|
}) |
||||
|
}) |
||||
|
} |
@ -0,0 +1,10 @@ |
|||||
|
// LND Connect to a peer
|
||||
|
export default function connectpeer(lnd, { pubkey, host }) { |
||||
|
return new Promise((resolve, reject) => { |
||||
|
lnd.connectPeer({ addr: { pubkey, host }, perm: true }, (err, data) => { |
||||
|
if (err) { reject(err) } |
||||
|
|
||||
|
resolve(data) |
||||
|
}) |
||||
|
}) |
||||
|
} |
@ -0,0 +1,10 @@ |
|||||
|
// LND Create an invoice
|
||||
|
export default function createInvoice(lnd, { memo, value }) { |
||||
|
return new Promise((resolve, reject) => { |
||||
|
lnd.addInvoice({ memo, value }, (err, data) => { |
||||
|
if (err) { reject(err) } |
||||
|
|
||||
|
resolve(data) |
||||
|
}) |
||||
|
}) |
||||
|
} |
@ -0,0 +1,10 @@ |
|||||
|
// LND Disconnect from a peer
|
||||
|
export default function disconnectpeer(lnd, { pubkey }) { |
||||
|
return new Promise((resolve, reject) => { |
||||
|
lnd.disconnectPeer({ pub_key: pubkey }, (err, data) => { |
||||
|
if (err) { reject(err) } |
||||
|
|
||||
|
resolve(data) |
||||
|
}) |
||||
|
}) |
||||
|
} |
@ -0,0 +1,115 @@ |
|||||
|
/* eslint no-console: 0 */ // --> OFF
|
||||
|
|
||||
|
import channelbalance from './channelbalance' |
||||
|
import channels from './channels' |
||||
|
import connectpeer from './connectpeer' |
||||
|
import createinvoice from './createinvoice' |
||||
|
import disconnectpeer from './disconnectpeer' |
||||
|
import info from './info' |
||||
|
import invoice from './invoice' |
||||
|
import invoices from './invoices' |
||||
|
import openchannel from './openchannel' |
||||
|
import payinvoice from './payinvoice' |
||||
|
import payments from './payments' |
||||
|
import peers from './peers' |
||||
|
import pendingchannels from './pendingchannels' |
||||
|
import walletbalance from './walletbalance' |
||||
|
|
||||
|
export default function (lnd, event, msg, data) { |
||||
|
switch (msg) { |
||||
|
case 'info': |
||||
|
info(lnd) |
||||
|
.then(infoData => event.sender.send('receiveInfo', infoData)) |
||||
|
.catch(error => console.log('info error: ', error)) |
||||
|
break |
||||
|
case 'peers': |
||||
|
// Data looks like { peers: [] }
|
||||
|
peers(lnd) |
||||
|
.then(peersData => event.sender.send('receivePeers', peersData)) |
||||
|
.catch(error => console.log('peers error: ', error)) |
||||
|
break |
||||
|
case 'channels': |
||||
|
// Data looks like
|
||||
|
// [ { channels: [] }, { total_limbo_balance: 0, pending_open_channels: [], pending_closing_channels: [], pending_force_closing_channels: [] } ]
|
||||
|
Promise.all([channels, pendingchannels].map(func => func(lnd))) |
||||
|
.then(channelsData => |
||||
|
event.sender.send('receiveChannels', { channels: channelsData[0].channels, pendingChannels: channelsData[1] }) |
||||
|
) |
||||
|
.catch(error => console.log('channels error: ', error)) |
||||
|
break |
||||
|
case 'payments': |
||||
|
// Data looks like { payments: [] }
|
||||
|
payments(lnd) |
||||
|
.then(paymentsData => event.sender.send('receivePayments', paymentsData)) |
||||
|
.catch(error => console.log('payments error: ', error)) |
||||
|
break |
||||
|
case 'invoices': |
||||
|
// Data looks like { invoices: [] }
|
||||
|
invoices(lnd) |
||||
|
.then(invoicesData => event.sender.send('receiveInvoices', invoicesData)) |
||||
|
.catch(error => console.log('invoices error: ', error)) |
||||
|
break |
||||
|
case 'invoice': |
||||
|
// Data looks like { invoices: [] }
|
||||
|
invoice(data.payreq) |
||||
|
.then(invoiceData => event.sender.send('receiveInvoice', invoiceData)) |
||||
|
.catch(error => console.log('invoice error: ', error)) |
||||
|
break |
||||
|
case 'balance': |
||||
|
// Balance looks like [ { balance: '129477456' }, { balance: '243914' } ]
|
||||
|
Promise.all([walletbalance, channelbalance].map(func => func(lnd))) |
||||
|
.then(balance => event.sender.send('receiveBalance', { walletBalance: balance[0].balance, channelBalance: balance[1].balance })) |
||||
|
.catch(error => console.log('balance error: ', error)) |
||||
|
break |
||||
|
case 'createInvoice': |
||||
|
// Invoice looks like { r_hash: Buffer, payment_request: '' }
|
||||
|
// { memo, value } = data
|
||||
|
createinvoice(lnd, data) |
||||
|
.then(newinvoice => |
||||
|
event.sender.send( |
||||
|
'createdInvoice', |
||||
|
Object.assign(newinvoice, { memo: data.memo, value: data.value, r_hash: new Buffer(newinvoice.r_hash, 'hex').toString('hex') }) |
||||
|
) |
||||
|
) |
||||
|
.catch(error => console.log('createInvoice error: ', error)) |
||||
|
break |
||||
|
case 'sendPayment': |
||||
|
// Payment looks like { payment_preimage: Buffer, payment_route: Object }
|
||||
|
// { paymentRequest } = data
|
||||
|
payinvoice(lnd, data) |
||||
|
.then(({ payment_route }) => event.sender.send('paymentSuccessful', Object.assign(data, { payment_route }))) |
||||
|
.catch(error => console.log('payinvoice error: ', error)) |
||||
|
break |
||||
|
case 'openChannel': |
||||
|
// Response is empty. Streaming updates on channel status and updates
|
||||
|
// { pubkey, localamt, pushamt } = data
|
||||
|
openchannel(lnd, event, data) |
||||
|
.then((channel) => { |
||||
|
console.log('CHANNEL: ', channel) |
||||
|
event.sender.send('channelSuccessful', { channel }) |
||||
|
}) |
||||
|
.catch(error => console.log('openChannel error: ', error)) |
||||
|
break |
||||
|
case 'connectPeer': |
||||
|
// Returns a peer_id. Pass the pubkey, host and peer_id so we can add a new peer to the list
|
||||
|
// { pubkey, host } = data
|
||||
|
connectpeer(lnd, data) |
||||
|
.then(({ peer_id }) => { |
||||
|
console.log('peer_id: ', peer_id) |
||||
|
event.sender.send('connectSuccess', { pub_key: data.pubkey, address: data.host, peer_id }) |
||||
|
}) |
||||
|
.catch(error => console.log('connectPeer error: ', error)) |
||||
|
break |
||||
|
case 'disconnectPeer': |
||||
|
// Empty response. Pass back pubkey on success to remove it from the peers list
|
||||
|
// { pubkey } = data
|
||||
|
disconnectpeer(lnd, data) |
||||
|
.then(() => { |
||||
|
console.log('pubkey: ', data.pubkey) |
||||
|
event.sender.send('disconnectSuccess', { pubkey: data.pubkey }) |
||||
|
}) |
||||
|
.catch(error => console.log('disconnectPeer error: ', error)) |
||||
|
break |
||||
|
default: |
||||
|
} |
||||
|
} |
@ -0,0 +1,10 @@ |
|||||
|
// LND Get Info
|
||||
|
export default function info(lnd) { |
||||
|
return new Promise((resolve, reject) => { |
||||
|
lnd.getInfo({}, (err, data) => { |
||||
|
if (err) { reject(err) } |
||||
|
|
||||
|
resolve(data) |
||||
|
}) |
||||
|
}) |
||||
|
} |
@ -0,0 +1,12 @@ |
|||||
|
import { decodeInvoice } from '../utils' |
||||
|
|
||||
|
// LND Get Invoice
|
||||
|
export default function invoice(payreq) { |
||||
|
return new Promise((resolve, reject) => { |
||||
|
try { |
||||
|
resolve(decodeInvoice(payreq)) |
||||
|
} catch (error) { |
||||
|
reject(error) |
||||
|
} |
||||
|
}) |
||||
|
} |
@ -0,0 +1,10 @@ |
|||||
|
// LND Get Invoices
|
||||
|
export default function invoices(lnd) { |
||||
|
return new Promise((resolve, reject) => { |
||||
|
lnd.listInvoices({}, (err, data) => { |
||||
|
if (err) { reject(err) } |
||||
|
|
||||
|
resolve(data) |
||||
|
}) |
||||
|
}) |
||||
|
} |
@ -0,0 +1,19 @@ |
|||||
|
import bitcore from 'bitcore-lib' |
||||
|
import pushchannel from '../push/channel' |
||||
|
|
||||
|
const BufferUtil = bitcore.util.buffer |
||||
|
|
||||
|
export default function openchannel(lnd, event, payload) { |
||||
|
const { pubkey, localamt, pushamt } = payload |
||||
|
const res = { |
||||
|
node_pubkey: BufferUtil.hexToBuffer(pubkey), |
||||
|
local_funding_amount: Number(localamt), |
||||
|
push_sat: Number(pushamt) |
||||
|
} |
||||
|
|
||||
|
return new Promise((resolve, reject) => |
||||
|
pushchannel(lnd, event, res) |
||||
|
.then(data => resolve(data)) |
||||
|
.catch(error => reject(error)) |
||||
|
) |
||||
|
} |
@ -0,0 +1,10 @@ |
|||||
|
// LND Pay an invoice
|
||||
|
export default function payinvoice(lnd, { paymentRequest }) { |
||||
|
return new Promise((resolve, reject) => { |
||||
|
lnd.sendPaymentSync({ payment_request: paymentRequest }, (err, data) => { |
||||
|
if (err) { reject(err) } |
||||
|
|
||||
|
resolve(data) |
||||
|
}) |
||||
|
}) |
||||
|
} |
@ -0,0 +1,10 @@ |
|||||
|
// LND Get Payments
|
||||
|
export default function payments(lnd) { |
||||
|
return new Promise((resolve, reject) => { |
||||
|
lnd.listPayments({}, (err, data) => { |
||||
|
if (err) { reject(err) } |
||||
|
|
||||
|
resolve(data) |
||||
|
}) |
||||
|
}) |
||||
|
} |
@ -0,0 +1,10 @@ |
|||||
|
// LND List Peers
|
||||
|
export default function peers(lnd) { |
||||
|
return new Promise((resolve, reject) => { |
||||
|
lnd.listPeers({}, (err, data) => { |
||||
|
if (err) { reject(err) } |
||||
|
|
||||
|
resolve(data) |
||||
|
}) |
||||
|
}) |
||||
|
} |
@ -0,0 +1,10 @@ |
|||||
|
// LND Get Pending Channels
|
||||
|
export default function channels(lnd) { |
||||
|
return new Promise((resolve, reject) => { |
||||
|
lnd.pendingChannels({}, (err, data) => { |
||||
|
if (err) { reject(err) } |
||||
|
|
||||
|
resolve(data) |
||||
|
}) |
||||
|
}) |
||||
|
} |
@ -0,0 +1,10 @@ |
|||||
|
// LND Get Wallet Balance
|
||||
|
export default function walletbalance(lnd) { |
||||
|
return new Promise((resolve, reject) => { |
||||
|
lnd.walletBalance({}, (err, data) => { |
||||
|
if (err) { reject(err) } |
||||
|
|
||||
|
resolve(data) |
||||
|
}) |
||||
|
}) |
||||
|
} |
@ -0,0 +1,16 @@ |
|||||
|
export default function pushchannel(lnd, event, payload) { |
||||
|
return new Promise((resolve, reject) => { |
||||
|
try { |
||||
|
const call = lnd.openChannel(payload) |
||||
|
|
||||
|
call.on('data', data => event.sender.send('pushchannelupdated', { data })) |
||||
|
call.on('end', () => event.sender.send('pushchannelend')) |
||||
|
call.on('error', error => event.sender.send('pushchannelerror', { error })) |
||||
|
call.on('status', status => event.sender.send('pushchannelstatus', { status })) |
||||
|
|
||||
|
resolve(null, payload) |
||||
|
} catch (error) { |
||||
|
reject(error, null) |
||||
|
} |
||||
|
}) |
||||
|
} |
@ -0,0 +1,38 @@ |
|||||
|
import zbase32 from 'zbase32' |
||||
|
|
||||
|
function convertBigEndianBufferToLong(longBuffer) { |
||||
|
let longValue = 0 |
||||
|
const byteArray = Buffer.from(longBuffer).swap64() |
||||
|
|
||||
|
for (let i = byteArray.length - 1; i >= 0; i -= 1) { |
||||
|
longValue = (longValue * 256) + byteArray[i] |
||||
|
} |
||||
|
|
||||
|
return longValue |
||||
|
} |
||||
|
|
||||
|
export function decodeInvoice(payreq) { |
||||
|
const payreqBase32 = zbase32.decode(payreq) |
||||
|
|
||||
|
const bufferHexRotated = Buffer.from(payreqBase32).toString('hex') |
||||
|
const bufferHex = bufferHexRotated.substr(bufferHexRotated.length - 1, bufferHexRotated.length) |
||||
|
+ bufferHexRotated.substr(0, bufferHexRotated.length - 1) |
||||
|
const buffer = Buffer.from(bufferHex, 'hex') |
||||
|
|
||||
|
const paymentHashBuffer = buffer.slice(33, 65) |
||||
|
const paymentHashHex = paymentHashBuffer.toString('hex') |
||||
|
|
||||
|
const valueBuffer = buffer.slice(65, 73) |
||||
|
|
||||
|
const amount = convertBigEndianBufferToLong(valueBuffer) |
||||
|
|
||||
|
return { |
||||
|
payreq, |
||||
|
amount, |
||||
|
r_hash: paymentHashHex |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
export default { |
||||
|
decodeInvoice |
||||
|
} |
@ -1,54 +0,0 @@ |
|||||
import { callApis } from '../api' |
|
||||
// ------------------------------------
|
|
||||
// Constants
|
|
||||
// ------------------------------------
|
|
||||
export const GET_ACTIVITY = 'GET_ACTIVITY' |
|
||||
export const RECEIVE_ACTIVITY = 'RECEIVE_ACTIVITY' |
|
||||
|
|
||||
// ------------------------------------
|
|
||||
// Actions
|
|
||||
// ------------------------------------
|
|
||||
export function getActivity() { |
|
||||
return { |
|
||||
type: GET_ACTIVITY |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
export function receiveActvity(data) { |
|
||||
return { |
|
||||
type: RECEIVE_ACTIVITY, |
|
||||
payments: data[0].data.payments.reverse(), |
|
||||
invoices: data[1].data.invoices.reverse() |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
export const fetchActivity = () => async (dispatch) => { |
|
||||
dispatch(getActivity()) |
|
||||
const activity = await callApis(['payments', 'invoices']) |
|
||||
dispatch(receiveActvity(activity)) |
|
||||
} |
|
||||
|
|
||||
// ------------------------------------
|
|
||||
// Action Handlers
|
|
||||
// ------------------------------------
|
|
||||
const ACTION_HANDLERS = { |
|
||||
[GET_ACTIVITY]: state => ({ ...state, activityLoading: true }), |
|
||||
[RECEIVE_ACTIVITY]: (state, { payments, invoices }) => ( |
|
||||
{ ...state, activityLoading: false, payments, invoices } |
|
||||
) |
|
||||
} |
|
||||
|
|
||||
// ------------------------------------
|
|
||||
// Reducer
|
|
||||
// ------------------------------------
|
|
||||
const initialState = { |
|
||||
activityLoading: false, |
|
||||
payments: [], |
|
||||
invoices: [] |
|
||||
} |
|
||||
|
|
||||
export default function activityReducer(state = initialState, action) { |
|
||||
const handler = ACTION_HANDLERS[action.type] |
|
||||
|
|
||||
return handler ? handler(state, action) : state |
|
||||
} |
|
@ -0,0 +1,36 @@ |
|||||
|
import createIpc from 'redux-electron-ipc' |
||||
|
import { receiveInfo } from './info' |
||||
|
import { receivePeers, connectSuccess, disconnectSuccess } from './peers' |
||||
|
import { |
||||
|
receiveChannels, |
||||
|
channelSuccessful, |
||||
|
pushchannelupdated, |
||||
|
pushchannelend, |
||||
|
pushchannelerror, |
||||
|
pushchannelstatus |
||||
|
} from './channels' |
||||
|
import { receivePayments, paymentSuccessful } from './payment' |
||||
|
import { receiveInvoices, createdInvoice, receiveFormInvoice } from './invoice' |
||||
|
import { receiveBalance } from './balance' |
||||
|
|
||||
|
// Import all receiving IPC event handlers and pass them into createIpc
|
||||
|
const ipc = createIpc({ |
||||
|
receiveInfo, |
||||
|
receivePeers, |
||||
|
receiveChannels, |
||||
|
receivePayments, |
||||
|
receiveInvoices, |
||||
|
receiveInvoice: receiveFormInvoice, |
||||
|
receiveBalance, |
||||
|
createdInvoice, |
||||
|
paymentSuccessful, |
||||
|
channelSuccessful, |
||||
|
pushchannelupdated, |
||||
|
pushchannelend, |
||||
|
pushchannelerror, |
||||
|
pushchannelstatus, |
||||
|
connectSuccess, |
||||
|
disconnectSuccess |
||||
|
}) |
||||
|
|
||||
|
export default ipc |
@ -1,20 +0,0 @@ |
|||||
import React from 'react' |
|
||||
import PropTypes from 'prop-types' |
|
||||
import Websocket from 'react-websocket' |
|
||||
|
|
||||
const Socket = ({ fetchChannels }) => { |
|
||||
const onMessage = () => { |
|
||||
// TODO: Assumes only socket relationship is with channels. Actually flesh out socket logic
|
|
||||
fetchChannels() |
|
||||
} |
|
||||
|
|
||||
return ( |
|
||||
<Websocket debug url='ws://localhost:3000/' onMessage={onMessage} /> |
|
||||
) |
|
||||
} |
|
||||
|
|
||||
Socket.propTypes = { |
|
||||
fetchChannels: PropTypes.func.isRequired |
|
||||
} |
|
||||
|
|
||||
export default Socket |
|
@ -1,55 +0,0 @@ |
|||||
import { callApi } from '../../app/api' |
|
||||
|
|
||||
describe('API', () => { |
|
||||
describe('getinfo', () => { |
|
||||
it('is synced to the chain', async () => { |
|
||||
const info = await callApi('info') |
|
||||
expect(info.data.synced_to_chain).toEqual(true) |
|
||||
}) |
|
||||
|
|
||||
it('only supports 1 chain at a time', async () => { |
|
||||
const info = await callApi('info') |
|
||||
expect(info.data.chains.length).toEqual(1) |
|
||||
}) |
|
||||
}) |
|
||||
|
|
||||
describe('balance', () => { |
|
||||
it('returns wallet balance', async () => { |
|
||||
const wallet_balances = await callApi('wallet_balance') |
|
||||
expect(typeof (wallet_balances.data.balance)).toEqual('string') |
|
||||
}) |
|
||||
|
|
||||
it('returns channel balance', async () => { |
|
||||
const channel_balances = await callApi('channel_balance') |
|
||||
expect(typeof (channel_balances.data.balance)).toEqual('string') |
|
||||
}) |
|
||||
}) |
|
||||
|
|
||||
describe('peers', () => { |
|
||||
it('peers is an array', async () => { |
|
||||
const peers = await callApi('peers') |
|
||||
expect(Array.isArray(peers.data.peers)).toEqual(true) |
|
||||
}) |
|
||||
}) |
|
||||
|
|
||||
describe('channels', () => { |
|
||||
it('channels is an array', async () => { |
|
||||
const channels = await callApi('channels') |
|
||||
expect(Array.isArray(channels.data.channels)).toEqual(true) |
|
||||
}) |
|
||||
}) |
|
||||
|
|
||||
describe('invoices', () => { |
|
||||
it('invoices is an array', async () => { |
|
||||
const invoices = await callApi('invoices') |
|
||||
expect(Array.isArray(invoices.data.invoices)).toEqual(true) |
|
||||
}) |
|
||||
}) |
|
||||
|
|
||||
describe('payments', () => { |
|
||||
it('payments is an array', async () => { |
|
||||
const payments = await callApi('payments') |
|
||||
expect(Array.isArray(payments.data.payments)).toEqual(true) |
|
||||
}) |
|
||||
}) |
|
||||
}) |
|
Loading…
Reference in new issue