/
Silent.hs
143 lines (135 loc) · 3.89 KB
/
Silent.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
{-# LANGUAGE TemplateHaskell #-}
-- | List of functions, used to communicate with LND via gRPC.
-- Method names are corresponding to gRPC method names, see LND gRPC api docs <https://api.lightning.community>.
module LndClient.RPC.Silent
( waitForGrpc,
unlockWallet,
lazyUnlockWallet,
lazyInitWallet,
newAddress,
addInvoice,
addHodlInvoice,
cancelInvoice,
settleInvoice,
initWallet,
openChannelSync,
openChannel,
listChannels,
closeChannel,
listPeers,
connectPeer,
lazyConnectPeer,
sendPayment,
getInfo,
subscribeInvoices,
subscribeInvoicesChan,
subscribeChannelEvents,
subscribeChannelEventsChan,
subscribeHtlcEvents,
decodePayReq,
lookupInvoice,
ensureHodlInvoice,
trackPaymentV2,
trackPaymentV2Chan,
pendingChannels,
closedChannels,
closeChannelSync,
listInvoices,
subscribeSingleInvoice,
subscribeSingleInvoiceChan,
)
where
import Data.ProtoLens.Message
import LndClient.Data.AddHodlInvoice as AddHodlInvoice (AddHodlInvoiceRequest (..))
import LndClient.Data.AddInvoice as AddInvoice (AddInvoiceResponse (..))
import qualified LndClient.Data.Channel as Channel
import LndClient.Data.CloseChannel as CloseChannel (CloseChannelRequest (..))
import LndClient.Data.Invoice as Invoice (Invoice (..))
import LndClient.Data.ListChannels as ListChannels (ListChannelsRequest (..))
import LndClient.Data.Peer (ConnectPeerRequest (..))
import LndClient.Import
import LndClient.RPC.TH
import LndClient.Util as Util
$(mkRpc RpcSilent)
waitForGrpc ::
(MonadIO m) =>
LndEnv ->
m (Either LndError ())
waitForGrpc env = this 30
where
this (x :: Int) =
if x > 0
then do
res <- getInfo $ env {envLndLogStrategy = logDebug}
if isRight res
then return $ Right ()
else liftIO (delay 1000000) >> this (x - 1)
else do
let msg = "waitForGrpc attempt limit exceeded"
return . Left $ LndError msg
lazyUnlockWallet ::
(MonadIO m) =>
LndEnv ->
m (Either LndError ())
lazyUnlockWallet env = do
unlocked <- isRight <$> getInfo (env {envLndLogStrategy = logDebug})
if unlocked
then return $ Right ()
else unlockWallet env
lazyInitWallet ::
(MonadIO m) =>
LndEnv ->
m (Either LndError ())
lazyInitWallet env = do
unlockRes <- lazyUnlockWallet $ env {envLndLogStrategy = logDebug}
if isRight unlockRes
then return unlockRes
else initWallet env
ensureHodlInvoice ::
(MonadIO m) =>
LndEnv ->
AddHodlInvoiceRequest ->
m (Either LndError AddInvoiceResponse)
ensureHodlInvoice env req = do
let rh = AddHodlInvoice.hash req
_ <- addHodlInvoice env req
res <- lookupInvoice env rh
return $ case res of
Left x -> Left x
Right x ->
Right $
AddInvoice.AddInvoiceResponse
{ AddInvoice.rHash = rh,
AddInvoice.paymentRequest = Invoice.paymentRequest x,
AddInvoice.addIndex = Invoice.addIndex x
}
closeChannelSync ::
(MonadUnliftIO m) =>
LndEnv ->
ConnectPeerRequest ->
CloseChannelRequest ->
m (Either LndError ())
closeChannelSync env conn req = do
cs0 <- listChannels env (ListChannels.ListChannelsRequest False False False False Nothing)
case cs0 of
Left err -> pure $ Left err
Right x ->
case filter (\ch -> channelPoint req == Channel.channelPoint ch) x of
[] -> return $ Right ()
_ -> do
mVar <- newEmptyMVar
closeChannelRecursive mVar 10
where
closeChannelRecursive _ (0 :: Int) = return $ Left $ LndError "Cannot close channel"
closeChannelRecursive mVar0 n = do
void $ lazyConnectPeer env conn
void $ Util.spawnLink $
closeChannel
(void . tryPutMVar mVar0)
env
req
liftIO $ delay 1000000
upd <- tryTakeMVar mVar0
case upd of
Just _ -> return $ Right ()
Nothing -> closeChannelRecursive mVar0 (n -1)