diff --git a/package.yaml b/package.yaml index 5c4a606..1db6cc2 100644 --- a/package.yaml +++ b/package.yaml @@ -31,6 +31,7 @@ library: - text - foreign-rust - generics-sop + - aeson pkg-config-dependencies: - rustzcash_wrapper-uninstalled diff --git a/src/ZcashHaskell/Types.hs b/src/ZcashHaskell/Types.hs index 8006e01..8f07073 100644 --- a/src/ZcashHaskell/Types.hs +++ b/src/ZcashHaskell/Types.hs @@ -2,6 +2,7 @@ {-# LANGUAGE DeriveAnyClass #-} {-# LANGUAGE DerivingVia #-} {-# LANGUAGE UndecidableInstances #-} +{-# LANGUAGE OverloadedStrings #-} -- | -- Module : ZcashHaskell.Types @@ -17,13 +18,16 @@ module ZcashHaskell.Types where import Codec.Borsh +import Data.Aeson import qualified Data.ByteString as BS import Data.Int import Data.Structured +import qualified Data.Text as T import Data.Word import qualified GHC.Generics as GHC import qualified Generics.SOP as SOP +-- * General -- | Type to represent data after Bech32 decoding data RawData = RawData { hrp :: BS.ByteString -- ^ Human-readable part of the Bech32 encoding @@ -33,17 +37,41 @@ data RawData = RawData deriving anyclass (Data.Structured.Show) deriving (BorshSize, ToBorsh, FromBorsh) via AsStruct RawData --- | Type to represent a Unified Full Viewing Key -data UnifiedFullViewingKey = UnifiedFullViewingKey - { net :: Word8 -- ^ Number representing the network the key belongs to. @1@ for @mainnet@, @2@ for @testnet@ and @3@ for @regtestnet@. - , o_key :: BS.ByteString -- ^ Raw bytes of the Orchard Full Viewing Key as specified in [ZIP-316](https://zips.z.cash/zip-0316) - , s_key :: BS.ByteString -- ^ Raw bytes of the Sapling Full Viewing Key as specified in [ZIP-316](https://zips.z.cash/zip-0316) - , t_key :: BS.ByteString -- ^ Raw bytes of the P2PKH chain code and public key as specified in [ZIP-316](https://zips.z.cash/zip-0316) - } deriving stock (Eq, Prelude.Show, GHC.Generic) - deriving anyclass (SOP.Generic, SOP.HasDatatypeInfo) - deriving anyclass (Data.Structured.Show) - deriving (BorshSize, ToBorsh, FromBorsh) via AsStruct UnifiedFullViewingKey +-- * `zcashd` RPC +-- | Type to represent response from the `zcashd` RPC `getblock` method +data BlockResponse = BlockResponse + { bl_confirmations :: Integer -- ^ Block confirmations + , bl_height :: Integer -- ^ Block height + , bl_time :: Integer -- ^ Block time + , bl_txs :: [BS.ByteString] -- ^ List of transaction IDs in the block + } deriving (Prelude.Show, Eq) +instance FromJSON BlockResponse where + parseJSON = + withObject "BlockResponse" $ \obj -> do + c <- obj .: "confirmations" + h <- obj .: "height" + t <- obj .: "time" + txs <- obj .: "tx" + pure $ BlockResponse c h t (BS.pack <$> txs) + +-- | Type to represent response from the `zcashd` RPC `getrawtransaction` +data RawTxResponse = RawTxResponse + { rt_id :: T.Text + , rt_shieldedOutputs :: [ShieldedOutput] + , rt_orchardActions :: [OrchardAction] + } deriving (Prelude.Show, Eq) + +instance FromJSON RawTxResponse where + parseJSON = + withObject "RawTxResponse" $ \obj -> do + i <- obj .: "txid" + s <- obj .: "vShieldedOutput" + o <- obj .: "orchard" + a <- o .: "actions" + pure $ RawTxResponse i s a + +-- * Sapling -- | Type to represent a Sapling Shielded Output as provided by the @getrawtransaction@ RPC method of @zcashd@. data ShieldedOutput = ShieldedOutput { s_cv :: BS.ByteString -- ^ Value commitment to the input note @@ -57,6 +85,36 @@ data ShieldedOutput = ShieldedOutput deriving anyclass (Data.Structured.Show) deriving (BorshSize, ToBorsh, FromBorsh) via AsStruct ShieldedOutput +instance FromJSON ShieldedOutput where + parseJSON = + withObject "ShieldedOutput" $ \obj -> do + cv <- obj .: "cv" + cmu <- obj .: "cmu" + ephKey <- obj .: "ephemeralKey" + encText <- obj .: "encCiphertext" + outText <- obj .: "outCiphertext" + p <- obj .: "proof" + pure $ + ShieldedOutput + (BS.pack cv) + (BS.pack cmu) + (BS.pack ephKey) + (BS.pack encText) + (BS.pack outText) + (BS.pack p) + +-- * Orchard +-- | Type to represent a Unified Full Viewing Key +data UnifiedFullViewingKey = UnifiedFullViewingKey + { net :: Word8 -- ^ Number representing the network the key belongs to. @1@ for @mainnet@, @2@ for @testnet@ and @3@ for @regtestnet@. + , o_key :: BS.ByteString -- ^ Raw bytes of the Orchard Full Viewing Key as specified in [ZIP-316](https://zips.z.cash/zip-0316) + , s_key :: BS.ByteString -- ^ Raw bytes of the Sapling Full Viewing Key as specified in [ZIP-316](https://zips.z.cash/zip-0316) + , t_key :: BS.ByteString -- ^ Raw bytes of the P2PKH chain code and public key as specified in [ZIP-316](https://zips.z.cash/zip-0316) + } deriving stock (Eq, Prelude.Show, GHC.Generic) + deriving anyclass (SOP.Generic, SOP.HasDatatypeInfo) + deriving anyclass (Data.Structured.Show) + deriving (BorshSize, ToBorsh, FromBorsh) via AsStruct UnifiedFullViewingKey + -- | Type to represent an Orchard Action as provided by the @getrawtransaction@ RPC method of @zcashd@, and defined in the [Zcash Protocol](https://zips.z.cash/protocol/protocol.pdf) data OrchardAction = OrchardAction { nf :: BS.ByteString -- ^ The nullifier of the input note @@ -72,6 +130,28 @@ data OrchardAction = OrchardAction deriving anyclass (Data.Structured.Show) deriving (BorshSize, ToBorsh, FromBorsh) via AsStruct OrchardAction +instance FromJSON OrchardAction where + parseJSON = + withObject "OrchardAction" $ \obj -> do + n <- obj .: "nullifier" + r <- obj .: "rk" + c <- obj .: "cmx" + ephKey <- obj .: "ephemeralKey" + encText <- obj .: "encCiphertext" + outText <- obj .: "outCipherText" + cval <- obj .: "cv" + a <- obj .: "spendAuthSig" + pure $ + OrchardAction + (BS.pack n) + (BS.pack r) + (BS.pack c) + (BS.pack ephKey) + (BS.pack encText) + (BS.pack outText) + (BS.pack cval) + (BS.pack a) + -- | Type to represent a decoded Orchard Action data OrchardDecodedAction = OrchardDecodedAction { a_value :: Int64 -- ^ The amount of the transaction in _zatoshis_. diff --git a/zcash-haskell.cabal b/zcash-haskell.cabal index 821d867..0b27eed 100644 --- a/zcash-haskell.cabal +++ b/zcash-haskell.cabal @@ -38,7 +38,8 @@ library pkgconfig-depends: rustzcash_wrapper-uninstalled build-depends: - base >=4.7 && <5 + aeson + , base >=4.7 && <5 , borsh >=0.2 , bytestring , foreign-rust