btc-lsp-0.1.0.0: src/BtcLsp/Yesod/Handler/SwapIntoLnSelect.hs
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeApplications #-}
module BtcLsp.Yesod.Handler.SwapIntoLnSelect
( getSwapIntoLnSelectR,
)
where
import BtcLsp.Data.Type
import qualified BtcLsp.Math.Swap as Math
import BtcLsp.Storage.Model
import qualified BtcLsp.Storage.Model.SwapIntoLn as SwapIntoLn
import BtcLsp.Yesod.Data.Widget
import qualified BtcLsp.Yesod.Handler.SwapUpdates as SU
import BtcLsp.Yesod.Import
import qualified Data.UUID as UUID
getSwapIntoLnSelectR :: Uuid 'SwapIntoLnTable -> Handler Html
getSwapIntoLnSelectR uuid = do
app@App {appMRunner = UnliftIO run} <- getYesod
nodeUri <- liftIO $ run getLndNodeUri
nodeUriHex <-
eitherM
(const badMethod)
(pure . from @NodeUriHex @Text)
. pure
$ tryFrom nodeUri
nodeUriQr <-
maybeM badMethod pure
. pure
$ toQr nodeUriHex
swapHash <- maybeM notFound pure (SU.getSwapUpdate app uuid)
maybeM
notFound
( \swapInfo@SwapIntoLn.SwapInfo {..} -> do
minAmt <- liftIO $ run getSwapIntoLnMinAmt
let SwapIntoLn {..} = entityVal swapInfoSwap
let (msgShort, msgLong, color) =
case swapIntoLnStatus of
SwapWaitingFundChain ->
( MsgSwapIntoLnWaitingFundChainShort,
MsgSwapIntoLnWaitingFundChainLong
minAmt
Math.swapLnMaxAmt,
Info
)
SwapWaitingPeer ->
( MsgSwapIntoLnFundedShort,
MsgSwapIntoLnFundedLong,
Info
)
SwapWaitingChan ->
( MsgSwapIntoLnWaitingChanShort,
MsgSwapIntoLnWaitingChanLong,
Info
)
SwapSucceeded ->
( MsgSwapIntoLnSucceededShort,
MsgSwapIntoLnSucceededLong,
Success
)
SwapExpired ->
( MsgSwapIntoLnExpiredShort,
MsgSwapIntoLnExpiredLong,
Danger
)
fundAddrQr <-
maybeM badMethod pure
. pure
. toQr
$ from swapIntoLnFundAddress
let mSwapWidget = newSwapWidget swapInfo
let mUtxoWidget = newUtxoWidget swapInfoUtxo
let mChanWidget = newChanWidget swapInfoChan
panelLayout color msgShort msgLong $ do
setTitleI $ MsgSwapIntoLnSelectRTitle swapIntoLnUuid
$(widgetFile "swap_updates")
$(widgetFile "swap_into_ln_select")
)
. liftIO
. run
. runSql
$ SwapIntoLn.getByUuidSql uuid
where
htmlUuid = $(mkHtmlUuid)
newSwapWidget ::
SwapIntoLn.SwapInfo ->
Maybe Widget
newSwapWidget swapInfo =
newNamedListWidget MsgSwapIntoLnHeaderInfo
. singleton
$ [ ( MsgSwapIntoLnTotalOnChainReceived,
Just
. MsgSatoshi
$ totalOnChainAmt (/= SwapUtxoOrphan) swapInfo
),
( MsgSwapIntoLnTotalOnChainReserved,
Just
. MsgSatoshi
$ totalOnChainAmt
( `elem`
[ SwapUtxoUnspentChanReserve
]
)
swapInfo
),
( MsgSwapIntoLnTotalOnChainSwapped,
Just
. MsgSatoshi
$ totalOnChainAmt
(== SwapUtxoSpentChanSwapped)
swapInfo
),
( MsgSwapIntoLnTotalOnChainRefunded,
Just
. MsgSatoshi
$ totalOnChainAmt (== SwapUtxoSpentRefund) swapInfo
),
( MsgSwapIntoLnTotalOnChainDust,
Just
. MsgSatoshi
$ totalOnChainAmt (== SwapUtxoUnspentDust) swapInfo
),
( MsgSwapIntoLnFeeLsp,
Just
. MsgSatoshi
$ from swapIntoLnFeeLsp
),
( MsgSwapIntoLnChanCapUser,
Just
. MsgSatoshi
$ from swapIntoLnChanCapUser
),
( MsgSwapIntoLnChanCapLsp,
Just
. MsgSatoshi
$ from swapIntoLnChanCapLsp
),
( MsgSwapIntoLnChanCapTotal,
Just
. MsgSatoshi
$ from swapIntoLnChanCapUser
+ from swapIntoLnChanCapLsp
),
( MsgChannelPrivacy,
Just $
chanPrivacyMsg swapIntoLnPrivacy
),
( MsgStatus,
Just $
swapStatusMsg swapIntoLnStatus
),
( MsgExpiresAt,
Just $
MsgUtcTime swapIntoLnExpiresAt
),
( MsgSwapIntoLnUuid,
Just
. MsgProxy
. UUID.toText
. unUuid
$ swapIntoLnUuid
),
( MsgSwapIntoLnUserId,
Just $
MsgProxy userPub
),
( MsgSwapIntoLnFundAddress,
Just
. MsgProxy
$ toText swapIntoLnFundAddress
),
( MsgSwapIntoLnRefundAddress,
Just
. MsgProxy
$ toText swapIntoLnRefundAddress
),
( MsgInsertedAt,
Just $
MsgUtcTime swapIntoLnInsertedAt
),
( MsgUpdatedAt,
Just $
MsgUtcTime swapIntoLnUpdatedAt
)
]
>>= \case
(msg, Just txt) -> [(msg, txt)]
(_, Nothing) -> []
where
SwapIntoLn {..} =
entityVal $
SwapIntoLn.swapInfoSwap swapInfo
userPub =
toHex
. coerce
. userNodePubKey
. entityVal
$ SwapIntoLn.swapInfoUser swapInfo
totalOnChainAmt ::
(SwapUtxoStatus -> Bool) ->
SwapIntoLn.SwapInfo ->
MSat
totalOnChainAmt only =
from
. sum
. fmap swapUtxoAmount
. filter (only . swapUtxoStatus)
. fmap (entityVal . SwapIntoLn.utxoInfoUtxo)
. SwapIntoLn.swapInfoUtxo
newUtxoWidget :: [SwapIntoLn.UtxoInfo] -> Maybe Widget
newUtxoWidget utxos =
newNamedListWidget MsgSwapIntoLnHeaderUtxos $
( \row ->
let SwapUtxo {..} =
entityVal $ SwapIntoLn.utxoInfoUtxo row
Block {..} =
entityVal $ SwapIntoLn.utxoInfoBlock row
in [ ( MsgBlock,
MsgProxy
. inspectPlain @Word64
$ from blockHeight
),
( MsgAmount,
MsgSatoshi $
from swapUtxoAmount
),
( MsgStatus,
swapUtxoStatusMsg swapUtxoStatus
),
( MsgTxId,
MsgProxy
. txIdHex
$ coerce swapUtxoTxid
),
( MsgVout,
MsgProxy
. inspectPlain @Word32
$ coerce swapUtxoVout
),
( MsgInsertedAt,
MsgUtcTime swapUtxoInsertedAt
),
( MsgUpdatedAt,
MsgUtcTime swapUtxoUpdatedAt
)
]
)
<$> utxos
newChanWidget :: [Entity LnChan] -> Maybe Widget
newChanWidget chans =
newNamedListWidget MsgSwapIntoLnHeaderChans $
( \row ->
let LnChan {..} = entityVal row
in [ ( MsgStatus,
lnChanStatusMsg lnChanStatus
),
( MsgTxId,
MsgProxy
. txIdHex
$ coerce lnChanFundingTxId
),
( MsgVout,
MsgProxy
. inspectPlain @Word32
$ coerce lnChanFundingVout
),
( MsgInsertedAt,
MsgUtcTime lnChanInsertedAt
),
( MsgUpdatedAt,
MsgUtcTime lnChanUpdatedAt
)
]
)
<$> chans
swapStatusMsg :: SwapStatus -> AppMessage
swapStatusMsg = \case
SwapWaitingFundChain -> MsgSwapWaitingFundChain
SwapWaitingPeer -> MsgSwapWaitingPeer
SwapWaitingChan -> MsgSwapWaitingChan
SwapSucceeded -> MsgSwapSucceeded
SwapExpired -> MsgSwapExpired
chanPrivacyMsg :: Privacy -> AppMessage
chanPrivacyMsg = \case
Private -> MsgChanPrivate
Public -> MsgChanPublic
swapUtxoStatusMsg :: SwapUtxoStatus -> AppMessage
swapUtxoStatusMsg = \case
SwapUtxoUnspent -> MsgSwapUtxoUnspent
SwapUtxoUnspentDust -> MsgSwapUtxoUnspentDust
SwapUtxoUnspentChanReserve -> MsgSwapUtxoUnspentChanReserve
SwapUtxoSpentChanSwapped -> MsgSwapUtxoSpentChanSwapped
SwapUtxoSpentRefund -> MsgSwapUtxoSpentRefund
SwapUtxoOrphan -> MsgSwapUtxoOrphan
lnChanStatusMsg :: LnChanStatus -> AppMessage
lnChanStatusMsg = \case
LnChanStatusPendingOpen -> MsgLnChanStatusPendingOpen
LnChanStatusOpened -> MsgLnChanStatusOpened
LnChanStatusActive -> MsgLnChanStatusActive
LnChanStatusFullyResolved -> MsgLnChanStatusFullyResolved
LnChanStatusInactive -> MsgLnChanStatusInactive
LnChanStatusPendingClose -> MsgLnChanStatusPendingClose
LnChanStatusClosed -> MsgLnChanStatusClosed