packages feed

lnd-client-0.1.0.1: src/LndClient/Data/ChannelPoint.hs

{-# LANGUAGE FlexibleContexts #-}

module LndClient.Data.ChannelPoint
  ( ChannelPoint (..),
    channelPointParser,
  )
where

import qualified Data.ByteString as BS (reverse)
import qualified Data.ByteString.Base16 as B16 (decode)
import qualified Data.ByteString.Char8 as C8 (split)
import Data.ProtoLens.Message
import qualified Data.Text as TS (unpack)
import LndClient.Import
import qualified Proto.Lnrpc.Ln0 as LnGRPC
import qualified Proto.Lnrpc.Ln0_Fields as LnGRPC
import qualified Proto.Lnrpc.Ln1 as Ln1
import qualified Proto.Lnrpc.Ln1_Fields as Ln1

data ChannelPoint = ChannelPoint
  { fundingTxId :: TxId 'Funding,
    outputIndex :: Vout 'Funding
  }
  deriving stock (Eq, Ord, Show, Generic)

instance Out ChannelPoint

instance FromGrpc ChannelPoint LnGRPC.ChannelPoint where
  fromGrpc x =
    ChannelPoint
      <$> fromGrpc (x ^. LnGRPC.fundingTxidBytes)
      <*> fromGrpc (x ^. LnGRPC.outputIndex)

instance ToGrpc ChannelPoint LnGRPC.ChannelPoint where
  toGrpc x =
    msg
      <$> toGrpc (fundingTxId x)
      <*> toGrpc (outputIndex x)
    where
      msg gFundingTxIdBytes gOutputIndex =
        defMessage
          & LnGRPC.fundingTxidBytes .~ gFundingTxIdBytes
          & LnGRPC.outputIndex .~ gOutputIndex

instance ToGrpc ChannelPoint Ln1.ExportChannelBackupRequest where
  toGrpc x =
    msg <$> toGrpc x
    where
      msg cp =
        defMessage
          & Ln1.chanPoint .~ cp

channelPointParser :: Text -> Either LndError ChannelPoint
channelPointParser x =
  case C8.split ':' str of
    [txid, idxBS] ->
      case B16.decode txid of
        Right txidHex -> do
          idxTS <-
            first
              ( const $
                  FromGrpcError "Invalid ChannelPoint outputIndex"
              )
              $ decodeUtf8' idxBS
          ChannelPoint (TxId $ BS.reverse txidHex)
            <$> maybeToRight
              (FromGrpcError "Invalid ChannelPoint outputIndex")
              (readMaybe $ TS.unpack idxTS)
        Left {} ->
          Left $ FromGrpcError "Invalid ChannelPoint fundingTxidBytes"
    _ ->
      Left $ FromGrpcError "Invalid ChannelPoint text"
  where
    str :: ByteString
    str = encodeUtf8 x