From d78c269d96fe7d8a626cf701b8051c40f251e232 Mon Sep 17 00:00:00 2001 From: Rene Vergara Date: Wed, 27 Sep 2023 11:18:00 -0500 Subject: [PATCH] Update raw Tx parsing to extract shielded outputs --- CHANGELOG.md | 2 ++ src/ZcashHaskell/Sapling.hs | 30 ++++++++++++++++++++++++++---- src/ZcashHaskell/Types.hs | 12 +----------- 3 files changed, 29 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f279786..f3ad8c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- `makeZcashCall` function moved into this library +- `RpcResponse`, `RpcCall` types moved into this library - Functions to decode Sapling transactions - Tests for Sapling decoding - Type for block response diff --git a/src/ZcashHaskell/Sapling.hs b/src/ZcashHaskell/Sapling.hs index d1646ad..ffec5f8 100644 --- a/src/ZcashHaskell/Sapling.hs +++ b/src/ZcashHaskell/Sapling.hs @@ -1,3 +1,5 @@ +{-# LANGUAGE OverloadedStrings #-} + module ZcashHaskell.Sapling where import C.Zcash @@ -7,14 +9,23 @@ import C.Zcash , rustWrapperSaplingVkDecode , rustWrapperTxParse ) +import Data.Aeson import qualified Data.ByteString as BS import Foreign.Rust.Marshall.Variable (withPureBorshVarBuffer) -import ZcashHaskell.Types (DecodedNote(..), ShieldedOutput(..)) +import ZcashHaskell.Types + ( DecodedNote(..) + , RawTxResponse(..) + , ShieldedOutput(..) + , decodeHexText + ) -- | Check if given bytesting is a valid encoded shielded address isValidShieldedAddress :: BS.ByteString -> Bool isValidShieldedAddress = rustWrapperIsShielded +getShieldedOutputs :: BS.ByteString -> [BS.ByteString] +getShieldedOutputs t = withPureBorshVarBuffer $ rustWrapperTxParse t + -- | Check if given bytestring is a valid Sapling viewing key isValidSaplingViewingKey :: BS.ByteString -> Bool isValidSaplingViewingKey = rustWrapperSaplingVkDecode @@ -23,9 +34,6 @@ isValidSaplingViewingKey = rustWrapperSaplingVkDecode matchSaplingAddress :: BS.ByteString -> BS.ByteString -> Bool matchSaplingAddress = rustWrapperSaplingCheck -getShieldedOutputs :: BS.ByteString -> [BS.ByteString] -getShieldedOutputs tx = withPureBorshVarBuffer $ rustWrapperTxParse tx - -- | Attempt to decode the given raw tx with the given Sapling viewing key decodeSaplingOutput :: BS.ByteString -> BS.ByteString -> Maybe DecodedNote decodeSaplingOutput key out = @@ -35,3 +43,17 @@ decodeSaplingOutput key out = where decodedAction = withPureBorshVarBuffer $ rustWrapperSaplingNoteDecode key out + +instance FromJSON RawTxResponse where + parseJSON = + withObject "RawTxResponse" $ \obj -> do + i <- obj .: "txid" + o <- obj .: "orchard" + h <- obj .: "hex" + a <- o .: "actions" + pure $ + RawTxResponse + i + (decodeHexText h) + (getShieldedOutputs (decodeHexText h)) + a diff --git a/src/ZcashHaskell/Types.hs b/src/ZcashHaskell/Types.hs index 1c5d680..51fe2c0 100644 --- a/src/ZcashHaskell/Types.hs +++ b/src/ZcashHaskell/Types.hs @@ -103,20 +103,10 @@ instance FromJSON BlockResponse where data RawTxResponse = RawTxResponse { rt_id :: T.Text , rt_hex :: BS.ByteString - , rt_shieldedOutputs :: [ShieldedOutput] + , rt_shieldedOutputs :: [BS.ByteString] , 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" - h <- obj .: "hex" - a <- o .: "actions" - pure $ RawTxResponse i (decodeHexText h) s a - -- * Sapling -- | Type to represent a Sapling Shielded Output as provided by the @getrawtransaction@ RPC method of @zcashd@. data ShieldedOutput = ShieldedOutput