2024-01-18 18:55:23 +00:00
|
|
|
-- Copyright 2022-2024 Vergara Technologies LLC
|
|
|
|
--
|
|
|
|
-- This file is part of Zcash-Haskell.
|
|
|
|
--
|
2023-12-20 20:03:42 +00:00
|
|
|
-- |
|
|
|
|
-- Module : ZcashHaskell.Sapling
|
|
|
|
-- Copyright : 2022-2024 Vergara Technologies
|
2024-01-18 18:55:23 +00:00
|
|
|
-- License : MIT
|
2023-12-20 20:03:42 +00:00
|
|
|
--
|
2024-01-18 18:55:23 +00:00
|
|
|
-- Maintainer : pitmutt@vergara.tech
|
2023-12-20 20:03:42 +00:00
|
|
|
-- Stability : experimental
|
|
|
|
-- Portability : unknown
|
|
|
|
--
|
|
|
|
-- Functions to interact with the Sapling shielded pool of the Zcash blockchain.
|
|
|
|
--
|
2024-01-18 18:55:23 +00:00
|
|
|
{-# LANGUAGE OverloadedStrings #-}
|
|
|
|
|
2023-06-14 15:53:29 +00:00
|
|
|
module ZcashHaskell.Sapling where
|
2023-05-04 20:26:49 +00:00
|
|
|
|
2023-06-14 15:53:29 +00:00
|
|
|
import C.Zcash
|
|
|
|
( rustWrapperIsShielded
|
|
|
|
, rustWrapperSaplingCheck
|
2023-08-22 20:05:40 +00:00
|
|
|
, rustWrapperSaplingNoteDecode
|
2024-03-05 13:36:45 +00:00
|
|
|
, rustWrapperSaplingSpendingkey
|
2023-06-14 15:53:29 +00:00
|
|
|
, rustWrapperSaplingVkDecode
|
2023-09-27 15:37:53 +00:00
|
|
|
, rustWrapperTxParse
|
2023-06-14 15:53:29 +00:00
|
|
|
)
|
2023-09-27 16:18:00 +00:00
|
|
|
import Data.Aeson
|
2023-05-04 20:26:49 +00:00
|
|
|
import qualified Data.ByteString as BS
|
2024-03-05 13:36:45 +00:00
|
|
|
import Data.ByteString.Lazy as BL
|
2024-02-06 19:10:06 +00:00
|
|
|
import Data.HexString (HexString(..), toBytes)
|
2024-03-05 13:36:45 +00:00
|
|
|
import Data.Word
|
|
|
|
import Foreign.Rust.Marshall.Variable
|
2024-03-03 21:19:06 +00:00
|
|
|
( withPureBorshVarBuffer
|
|
|
|
, withPureBorshVarBuffer
|
|
|
|
)
|
2023-09-27 16:18:00 +00:00
|
|
|
import ZcashHaskell.Types
|
|
|
|
( DecodedNote(..)
|
2023-09-28 19:23:42 +00:00
|
|
|
, RawData(..)
|
2023-09-27 16:18:00 +00:00
|
|
|
, RawTxResponse(..)
|
2024-03-05 13:36:45 +00:00
|
|
|
, SaplingSKeyParams(..)
|
2023-09-27 16:18:00 +00:00
|
|
|
, ShieldedOutput(..)
|
|
|
|
, decodeHexText
|
2024-03-06 03:10:05 +00:00
|
|
|
, AccountId
|
|
|
|
, CoinType
|
2023-09-27 16:18:00 +00:00
|
|
|
)
|
2024-03-05 13:36:45 +00:00
|
|
|
import ZcashHaskell.Utils
|
2023-05-04 20:26:49 +00:00
|
|
|
|
|
|
|
-- | Check if given bytesting is a valid encoded shielded address
|
|
|
|
isValidShieldedAddress :: BS.ByteString -> Bool
|
|
|
|
isValidShieldedAddress = rustWrapperIsShielded
|
2023-06-14 14:55:52 +00:00
|
|
|
|
2024-02-06 19:10:06 +00:00
|
|
|
getShieldedOutputs :: HexString -> [BS.ByteString]
|
|
|
|
getShieldedOutputs t = withPureBorshVarBuffer $ rustWrapperTxParse $ toBytes t
|
2023-09-27 16:18:00 +00:00
|
|
|
|
2023-06-14 14:55:52 +00:00
|
|
|
-- | Check if given bytestring is a valid Sapling viewing key
|
|
|
|
isValidSaplingViewingKey :: BS.ByteString -> Bool
|
2023-09-28 19:23:42 +00:00
|
|
|
isValidSaplingViewingKey k =
|
|
|
|
case hrp decodedKey of
|
|
|
|
"zxviews" -> rustWrapperSaplingVkDecode $ bytes decodedKey
|
|
|
|
_ -> False
|
|
|
|
where
|
|
|
|
decodedKey = decodeBech32 k
|
2023-06-14 15:53:29 +00:00
|
|
|
|
|
|
|
-- | Check if the given bytestring for the Sapling viewing key matches the second bytestring for the address
|
|
|
|
matchSaplingAddress :: BS.ByteString -> BS.ByteString -> Bool
|
|
|
|
matchSaplingAddress = rustWrapperSaplingCheck
|
2023-08-22 20:05:40 +00:00
|
|
|
|
2023-08-23 20:19:31 +00:00
|
|
|
-- | Attempt to decode the given raw tx with the given Sapling viewing key
|
|
|
|
decodeSaplingOutput :: BS.ByteString -> BS.ByteString -> Maybe DecodedNote
|
2023-08-22 20:05:40 +00:00
|
|
|
decodeSaplingOutput key out =
|
|
|
|
case a_value decodedAction of
|
|
|
|
0 -> Nothing
|
|
|
|
_ -> Just decodedAction
|
|
|
|
where
|
|
|
|
decodedAction =
|
|
|
|
withPureBorshVarBuffer $ rustWrapperSaplingNoteDecode key out
|
2023-09-27 16:18:00 +00:00
|
|
|
|
|
|
|
instance FromJSON RawTxResponse where
|
|
|
|
parseJSON =
|
|
|
|
withObject "RawTxResponse" $ \obj -> do
|
|
|
|
i <- obj .: "txid"
|
2023-09-28 18:56:31 +00:00
|
|
|
o <- obj .:? "orchard"
|
2023-09-27 16:18:00 +00:00
|
|
|
h <- obj .: "hex"
|
2023-10-02 20:25:44 +00:00
|
|
|
ht <- obj .: "height"
|
|
|
|
c <- obj .: "confirmations"
|
|
|
|
b <- obj .: "blocktime"
|
2023-09-28 18:56:31 +00:00
|
|
|
case o of
|
2024-02-06 19:10:06 +00:00
|
|
|
Nothing -> pure $ RawTxResponse i h (getShieldedOutputs h) [] ht c b
|
2023-09-28 18:56:31 +00:00
|
|
|
Just o' -> do
|
|
|
|
a <- o' .: "actions"
|
2024-02-06 19:10:06 +00:00
|
|
|
pure $ RawTxResponse i h (getShieldedOutputs h) a ht c b
|
2024-03-06 03:10:05 +00:00
|
|
|
--
|
2024-03-03 21:19:06 +00:00
|
|
|
-- | Attempts to obtain a sapling SpendinKey using a HDSeed, a Coin Type and an Account ID
|
2024-03-06 03:10:05 +00:00
|
|
|
genSaplingSpendingKey :: BS.ByteString -> Word32-> AccountId -> BS.ByteString
|
2024-03-03 21:19:06 +00:00
|
|
|
genSaplingSpendingKey seed coin_type account_id = do
|
2024-03-06 03:10:05 +00:00
|
|
|
let res = withPureBorshVarBuffer (rustWrapperSaplingSpendingkey seed (fromIntegral coin_type) (fromIntegral account_id) )
|
|
|
|
res
|