diff --git a/CHANGELOG.md b/CHANGELOG.md index fef5e74..999e019 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [0.5.1.0] +### Added + +- Functionality to capture Sapling Spends + ### Changed - Modified the `makeZebraCall` function to handle errors explicitly diff --git a/src/ZcashHaskell/Sapling.hs b/src/ZcashHaskell/Sapling.hs index fb1c459..2dc7f49 100644 --- a/src/ZcashHaskell/Sapling.hs +++ b/src/ZcashHaskell/Sapling.hs @@ -90,11 +90,13 @@ instance FromJSON RawTxResponse where ht <- obj .: "height" c <- obj .: "confirmations" b <- obj .: "blocktime" + sSpend <- obj .: "vShieldedSpend" case o of - Nothing -> pure $ RawTxResponse i h (getShieldedOutputs h) [] ht c b + Nothing -> + pure $ RawTxResponse i h sSpend (getShieldedOutputs h) [] ht c b Just o' -> do a <- o' .: "actions" - pure $ RawTxResponse i h (getShieldedOutputs h) a ht c b + pure $ RawTxResponse i h sSpend (getShieldedOutputs h) a ht c b -- | Attempts to obtain a sapling SpendingKey using a HDSeed genSaplingSpendingKey :: Seed -> CoinType -> Int -> Maybe SaplingSpendingKey diff --git a/src/ZcashHaskell/Types.hs b/src/ZcashHaskell/Types.hs index 182ddc1..e7f68b3 100644 --- a/src/ZcashHaskell/Types.hs +++ b/src/ZcashHaskell/Types.hs @@ -207,6 +207,7 @@ instance FromJSON BlockResponse where data RawTxResponse = RawTxResponse { rt_id :: !HexString , rt_hex :: !HexString + , rt_shieldedSpends :: ![ShieldedSpend] , rt_shieldedOutputs :: ![BS.ByteString] , rt_orchardActions :: ![OrchardAction] , rt_blockheight :: !Integer @@ -283,6 +284,30 @@ newtype SaplingReceiver = instance ToBytes SaplingReceiver where getBytes (SaplingReceiver s) = s +-- | Type to represent a Sapling Shielded Spend as provided by the @getrawtransaction@ RPC method +data ShieldedSpend = ShieldedSpend + { sp_cv :: !HexString + , sp_anchor :: !HexString + , sp_nullifier :: !HexString + , sp_rk :: !HexString + , sp_proof :: !HexString + , sp_auth :: !HexString + } deriving stock (Eq, Prelude.Show, GHC.Generic, Read) + deriving anyclass (SOP.Generic, SOP.HasDatatypeInfo) + deriving anyclass (Data.Structured.Show) + deriving (BorshSize, ToBorsh, FromBorsh) via AsStruct ShieldedSpend + +instance FromJSON ShieldedSpend where + parseJSON = + withObject "ShieldedSpend" $ \obj -> do + cv <- obj .: "cv" + anchor <- obj .: "anchor" + nullifier <- obj .: "nullifier" + rk <- obj .: "rk" + p <- obj .: "proof" + sig <- obj .: "spendAuthSig" + pure $ ShieldedSpend cv anchor nullifier rk p sig + -- | Type to represent a Sapling Shielded Output as provided by the @getrawtransaction@ RPC method of @zcashd@. data ShieldedOutput = ShieldedOutput { s_cv :: !HexString -- ^ Value commitment to the input note