Addition of functinality for manipulating Unified Addresses and Viewing Keys #1
3 changed files with 93 additions and 11 deletions
|
@ -31,6 +31,7 @@ library:
|
|||
- text
|
||||
- foreign-rust
|
||||
- generics-sop
|
||||
- aeson
|
||||
pkg-config-dependencies:
|
||||
- rustzcash_wrapper-uninstalled
|
||||
|
||||
|
|
|
@ -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_.
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue