Compare commits
29 commits
Author | SHA1 | Date | |
---|---|---|---|
5de1844e9d | |||
36fd2e59a4 | |||
63a97b880c | |||
f24ea80cde | |||
9df346389a | |||
91e2ebbabd | |||
343495f6e7 | |||
7350723801 | |||
7965dc38c4 | |||
ee165de652 | |||
1f1ca4e206 | |||
f1e1570b25 | |||
5a8cd44fbc | |||
cedc3a0cc1 | |||
ce19e174cc | |||
85a4741dcb | |||
0b2fae2b5d | |||
b4069d6233 | |||
c8f411fcdd | |||
939ae687e8 | |||
e1622a0d7f | |||
774e135aab | |||
b7c91e10fe | |||
cbbdfe42af | |||
9ca702a68e | |||
cc72fadef3 | |||
7c79ee6163 | |||
e8074419cf | |||
90c8a7c302 |
12 changed files with 237 additions and 38 deletions
27
CHANGELOG.md
27
CHANGELOG.md
|
@ -5,6 +5,33 @@ All notable changes to this project will be documented in this file.
|
||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## [0.7.0.2]
|
||||||
|
|
||||||
|
## Changed
|
||||||
|
|
||||||
|
- Modified witness update functions to skip the process if no commitments are present
|
||||||
|
|
||||||
|
## [0.7.0.1]
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- New error type `PrivacyPolicyError`
|
||||||
|
|
||||||
|
## [0.7.0.0]
|
||||||
|
|
||||||
|
- Implement `wagyu-zcash-parameters` in Rust bindings
|
||||||
|
|
||||||
|
## [0.6.2.3]
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Decoding of unified addresses with no transparent receivers
|
||||||
|
|
||||||
|
## [0.6.2.2]
|
||||||
|
|
||||||
|
- Added JSON instances for `ZcashNet`
|
||||||
|
- Added JSON instances for `Transaction`
|
||||||
|
- Added `ValidAddress`
|
||||||
|
|
||||||
## [0.6.2.1]
|
## [0.6.2.1]
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
51
librustzcash-wrapper/Cargo.lock
generated
51
librustzcash-wrapper/Cargo.lock
generated
|
@ -1395,6 +1395,7 @@ dependencies = [
|
||||||
"rand_core",
|
"rand_core",
|
||||||
"sapling-crypto",
|
"sapling-crypto",
|
||||||
"secp256k1",
|
"secp256k1",
|
||||||
|
"wagyu-zcash-parameters",
|
||||||
"zcash_address 0.2.0",
|
"zcash_address 0.2.0",
|
||||||
"zcash_client_backend",
|
"zcash_client_backend",
|
||||||
"zcash_note_encryption",
|
"zcash_note_encryption",
|
||||||
|
@ -1746,6 +1747,56 @@ version = "0.9.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wagyu-zcash-parameters"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "61c904628658374e651288f000934c33ef738b2d8b3e65d4100b70b395dbe2bb"
|
||||||
|
dependencies = [
|
||||||
|
"wagyu-zcash-parameters-1",
|
||||||
|
"wagyu-zcash-parameters-2",
|
||||||
|
"wagyu-zcash-parameters-3",
|
||||||
|
"wagyu-zcash-parameters-4",
|
||||||
|
"wagyu-zcash-parameters-5",
|
||||||
|
"wagyu-zcash-parameters-6",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wagyu-zcash-parameters-1"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "90bf2e21bb027d3f8428c60d6a720b54a08bf6ce4e6f834ef8e0d38bb5695da8"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wagyu-zcash-parameters-2"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a616ab2e51e74cc48995d476e94de810fb16fc73815f390bf2941b046cc9ba2c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wagyu-zcash-parameters-3"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "14da1e2e958ff93c0830ee68e91884069253bf3462a67831b02b367be75d6147"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wagyu-zcash-parameters-4"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f058aeef03a2070e8666ffb5d1057d8bb10313b204a254a6e6103eb958e9a6d6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wagyu-zcash-parameters-5"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3ffe916b30e608c032ae1b734f02574a3e12ec19ab5cc5562208d679efe4969d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wagyu-zcash-parameters-6"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a7b6d5a78adc3e8f198e9cd730f219a695431467f7ec29dcfc63ade885feebe1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasi"
|
name = "wasi"
|
||||||
version = "0.11.0+wasi-snapshot-preview1"
|
version = "0.11.0+wasi-snapshot-preview1"
|
||||||
|
|
|
@ -23,6 +23,7 @@ incrementalmerkletree = "0.5.0"
|
||||||
secp256k1 = "0.26.0"
|
secp256k1 = "0.26.0"
|
||||||
jubjub = "0.10.0"
|
jubjub = "0.10.0"
|
||||||
rand_core = { version = "0.6.4", features = ["getrandom"]}
|
rand_core = { version = "0.6.4", features = ["getrandom"]}
|
||||||
|
wagyu-zcash-parameters = "0.2.0"
|
||||||
|
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
|
|
|
@ -167,6 +167,8 @@ use bech32::{
|
||||||
Bech32m
|
Bech32m
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use wagyu_zcash_parameters::load_sapling_parameters;
|
||||||
|
|
||||||
pub enum RW {}
|
pub enum RW {}
|
||||||
pub const RW: PhantomData<RW> = PhantomData;
|
pub const RW: PhantomData<RW> = PhantomData;
|
||||||
|
|
||||||
|
@ -1637,10 +1639,6 @@ pub extern "C" fn rust_wrapper_create_transaction(
|
||||||
o_input_len: usize,
|
o_input_len: usize,
|
||||||
out_list: *const u8,
|
out_list: *const u8,
|
||||||
out_list_len: usize,
|
out_list_len: usize,
|
||||||
sapspend: *const u8,
|
|
||||||
sapspend_len: usize,
|
|
||||||
sapoutput: *const u8,
|
|
||||||
sapoutput_len: usize,
|
|
||||||
net: bool,
|
net: bool,
|
||||||
bl_height: u32,
|
bl_height: u32,
|
||||||
build: bool,
|
build: bool,
|
||||||
|
@ -1796,10 +1794,11 @@ pub extern "C" fn rust_wrapper_create_transaction(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if build {
|
if build {
|
||||||
let spend_params_in: Vec<u8> = marshall_from_haskell_var(sapspend, sapspend_len, RW);
|
let (spend_params_in, output_params_in) = load_sapling_parameters();
|
||||||
|
//let spend_params_in: Vec<u8> = marshall_from_haskell_var(sapspend, sapspend_len, RW);
|
||||||
let spend_params_reader = Cursor::new(spend_params_in);
|
let spend_params_reader = Cursor::new(spend_params_in);
|
||||||
let spend_prover = SpendParameters::read(spend_params_reader, false).unwrap();
|
let spend_prover = SpendParameters::read(spend_params_reader, false).unwrap();
|
||||||
let output_params_in: Vec<u8> = marshall_from_haskell_var(sapoutput, sapoutput_len, RW);
|
//let output_params_in: Vec<u8> = marshall_from_haskell_var(sapoutput, sapoutput_len, RW);
|
||||||
let output_params_reader = Cursor::new(output_params_in);
|
let output_params_reader = Cursor::new(output_params_in);
|
||||||
let output_prover = OutputParameters::read(output_params_reader, false).unwrap();
|
let output_prover = OutputParameters::read(output_params_reader, false).unwrap();
|
||||||
let result = if net {
|
let result = if net {
|
||||||
|
|
|
@ -283,8 +283,6 @@ import ZcashHaskell.Types
|
||||||
, toBorshVar* `[SaplingTxSpend]'&
|
, toBorshVar* `[SaplingTxSpend]'&
|
||||||
, toBorshVar* `[OrchardTxSpend]'&
|
, toBorshVar* `[OrchardTxSpend]'&
|
||||||
, toBorshVar* `[OutgoingNote]'&
|
, toBorshVar* `[OutgoingNote]'&
|
||||||
, toBorshVar* `BS.ByteString'&
|
|
||||||
, toBorshVar* `BS.ByteString'&
|
|
||||||
, `Bool'
|
, `Bool'
|
||||||
, `Word64'
|
, `Word64'
|
||||||
, `Bool'
|
, `Bool'
|
||||||
|
|
|
@ -37,6 +37,11 @@ import qualified Data.Text as T
|
||||||
import qualified Data.Text.Encoding as E
|
import qualified Data.Text.Encoding as E
|
||||||
import Data.Word
|
import Data.Word
|
||||||
import Foreign.Rust.Marshall.Variable
|
import Foreign.Rust.Marshall.Variable
|
||||||
|
import ZcashHaskell.Sapling (decodeSaplingAddress)
|
||||||
|
import ZcashHaskell.Transparent
|
||||||
|
( decodeExchangeAddress
|
||||||
|
, decodeTransparentAddress
|
||||||
|
)
|
||||||
import ZcashHaskell.Types
|
import ZcashHaskell.Types
|
||||||
import ZcashHaskell.Utils (encodeBech32, encodeBech32m, f4Jumble)
|
import ZcashHaskell.Utils (encodeBech32, encodeBech32m, f4Jumble)
|
||||||
|
|
||||||
|
@ -98,9 +103,9 @@ isValidUnifiedAddress str =
|
||||||
(if BS.length (raw_s x) == 43
|
(if BS.length (raw_s x) == 43
|
||||||
then Just $ SaplingReceiver (raw_s x)
|
then Just $ SaplingReceiver (raw_s x)
|
||||||
else Nothing)
|
else Nothing)
|
||||||
(if not (BS.null (raw_t x))
|
(if BS.length (raw_t x) > 1
|
||||||
then Just $ TransparentReceiver P2PKH (fromRawBytes $ raw_t x)
|
then Just $ TransparentReceiver P2PKH (fromRawBytes $ raw_t x)
|
||||||
else if not (BS.null (raw_to x))
|
else if BS.length (raw_to x) > 1
|
||||||
then Just $ TransparentReceiver P2SH (fromRawBytes $ raw_to x)
|
then Just $ TransparentReceiver P2SH (fromRawBytes $ raw_to x)
|
||||||
else Nothing)
|
else Nothing)
|
||||||
|
|
||||||
|
@ -221,8 +226,37 @@ getOrchardNotePosition :: OrchardWitness -> Integer
|
||||||
getOrchardNotePosition =
|
getOrchardNotePosition =
|
||||||
fromIntegral . rustWrapperReadOrchardPosition . hexBytes . orchWit
|
fromIntegral . rustWrapperReadOrchardPosition . hexBytes . orchWit
|
||||||
|
|
||||||
|
-- | Update the witness of an Orchard note
|
||||||
updateOrchardWitness :: OrchardWitness -> [HexString] -> OrchardWitness
|
updateOrchardWitness :: OrchardWitness -> [HexString] -> OrchardWitness
|
||||||
updateOrchardWitness wit cmus =
|
updateOrchardWitness wit cmus =
|
||||||
OrchardWitness $
|
if not (null cmus)
|
||||||
withPureBorshVarBuffer $
|
then OrchardWitness $
|
||||||
rustWrapperUpdateOrchardWitness (toBytes $ orchWit wit) (map toBytes cmus)
|
withPureBorshVarBuffer $
|
||||||
|
rustWrapperUpdateOrchardWitness
|
||||||
|
(toBytes $ orchWit wit)
|
||||||
|
(map toBytes cmus)
|
||||||
|
else wit
|
||||||
|
|
||||||
|
-- | Parse a potential Zcash address
|
||||||
|
parseAddress :: BS.ByteString -> Maybe ValidAddress
|
||||||
|
parseAddress t =
|
||||||
|
case isValidUnifiedAddress t of
|
||||||
|
Nothing ->
|
||||||
|
case decodeSaplingAddress t of
|
||||||
|
Nothing ->
|
||||||
|
case decodeTransparentAddress t of
|
||||||
|
Nothing ->
|
||||||
|
case decodeExchangeAddress t of
|
||||||
|
Nothing -> Nothing
|
||||||
|
Just x -> Just $ Exchange x
|
||||||
|
Just t -> Just $ Transparent t
|
||||||
|
Just s -> Just $ Sapling s
|
||||||
|
Just u -> Just $ Unified u
|
||||||
|
|
||||||
|
compareAddress :: ValidAddress -> UnifiedAddress -> Bool
|
||||||
|
compareAddress a u =
|
||||||
|
case a of
|
||||||
|
Unified i -> i == u
|
||||||
|
Sapling s -> s_rec u == Just (sa_receiver s) && ua_net u == net_type s
|
||||||
|
Transparent t -> t_rec u == Just (ta_receiver t) && ua_net u == ta_network t
|
||||||
|
Exchange x -> False
|
||||||
|
|
|
@ -218,9 +218,13 @@ getSaplingNotePosition =
|
||||||
|
|
||||||
updateSaplingWitness :: SaplingWitness -> [HexString] -> SaplingWitness
|
updateSaplingWitness :: SaplingWitness -> [HexString] -> SaplingWitness
|
||||||
updateSaplingWitness wit cmus =
|
updateSaplingWitness wit cmus =
|
||||||
SaplingWitness $
|
if not (null cmus)
|
||||||
withPureBorshVarBuffer $
|
then SaplingWitness $
|
||||||
rustWrapperUpdateSaplingWitness (toBytes $ sapWit wit) (map toBytes cmus)
|
withPureBorshVarBuffer $
|
||||||
|
rustWrapperUpdateSaplingWitness
|
||||||
|
(toBytes $ sapWit wit)
|
||||||
|
(map toBytes cmus)
|
||||||
|
else wit
|
||||||
|
|
||||||
-- | Encode a SaplingReceiver into HRF text
|
-- | Encode a SaplingReceiver into HRF text
|
||||||
encodeSaplingAddress :: ZcashNet -> SaplingReceiver -> Maybe T.Text
|
encodeSaplingAddress :: ZcashNet -> SaplingReceiver -> Maybe T.Text
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
|
|
||||||
-- Copyright 2022-2024 Vergara Technologies LLC
|
-- Copyright 2022-2024 Vergara Technologies LLC
|
||||||
--
|
--
|
||||||
-- This file is part of Zcash-Haskell.
|
-- This file is part of Zcash-Haskell.
|
||||||
|
@ -172,27 +174,27 @@ decodeTransparentAddress taddress = do
|
||||||
-- | Encode an Exchange Addresss into HRF from TransparentReceiver
|
-- | Encode an Exchange Addresss into HRF from TransparentReceiver
|
||||||
encodeExchangeAddress :: ZcashNet -> TransparentReceiver -> Maybe T.Text
|
encodeExchangeAddress :: ZcashNet -> TransparentReceiver -> Maybe T.Text
|
||||||
encodeExchangeAddress net tr = do
|
encodeExchangeAddress net tr = do
|
||||||
case (tr_type tr) of
|
case tr_type tr of
|
||||||
P2PKH -> do
|
P2PKH -> do
|
||||||
case net of
|
case net of
|
||||||
MainNet -> do
|
MainNet -> do
|
||||||
let vhash = encodeBech32m (BC.pack "tex") (toBytes (tr_bytes tr))
|
let vhash = encodeBech32m "tex" (toBytes (tr_bytes tr))
|
||||||
Just vhash
|
Just vhash
|
||||||
TestNet -> do
|
TestNet -> do
|
||||||
let vhash = encodeBech32m (BC.pack "textest") (toBytes (tr_bytes tr))
|
let vhash = encodeBech32m "textest" (toBytes (tr_bytes tr))
|
||||||
Just vhash
|
Just vhash
|
||||||
_ -> Nothing
|
_any -> Nothing
|
||||||
|
|
||||||
-- | Decode an Exchange Address into a ExchangeAddress
|
-- | Decode an Exchange Address into a ExchangeAddress
|
||||||
decodeExchangeAddress :: T.Text -> Maybe ExchangeAddress
|
decodeExchangeAddress :: BS.ByteString -> Maybe ExchangeAddress
|
||||||
decodeExchangeAddress ex = do
|
decodeExchangeAddress ex = do
|
||||||
if (T.length ex) > 1
|
if BS.length ex > 1
|
||||||
then do
|
then do
|
||||||
let rawd = decodeBech32 (E.encodeUtf8 ex)
|
let rawd = decodeBech32 ex
|
||||||
let tMain = BS.unpack (BC.pack "tex")
|
let tMain = "tex"
|
||||||
let tTest = BS.unpack (BC.pack "textest")
|
let tTest = "textest"
|
||||||
let tFail = BS.unpack (BC.pack "fail")
|
let tFail = "fail"
|
||||||
let hr = BS.unpack (hrp rawd)
|
let hr = hrp rawd
|
||||||
if hr /= tFail
|
if hr /= tFail
|
||||||
then do
|
then do
|
||||||
let transparentReceiver = bytes rawd
|
let transparentReceiver = bytes rawd
|
||||||
|
|
|
@ -38,6 +38,7 @@ import Data.Maybe (fromJust, fromMaybe)
|
||||||
import Data.Structured
|
import Data.Structured
|
||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
import qualified Data.Text.Encoding as E
|
import qualified Data.Text.Encoding as E
|
||||||
|
import qualified Data.Vector as V
|
||||||
import Data.Word
|
import Data.Word
|
||||||
import qualified GHC.Generics as GHC
|
import qualified GHC.Generics as GHC
|
||||||
import qualified Generics.SOP as SOP
|
import qualified Generics.SOP as SOP
|
||||||
|
@ -90,7 +91,7 @@ data ZcashNet
|
||||||
= MainNet
|
= MainNet
|
||||||
| TestNet
|
| TestNet
|
||||||
| RegTestNet
|
| RegTestNet
|
||||||
deriving (Eq, Prelude.Show, Read)
|
deriving (Eq, Prelude.Show, Read, GHC.Generic, ToJSON, FromJSON)
|
||||||
|
|
||||||
type AccountId = Int
|
type AccountId = Int
|
||||||
|
|
||||||
|
@ -133,6 +134,18 @@ data Transaction = Transaction
|
||||||
, tx_orchardBundle :: !(Maybe OrchardBundle)
|
, tx_orchardBundle :: !(Maybe OrchardBundle)
|
||||||
} deriving (Prelude.Show, Eq, Read)
|
} deriving (Prelude.Show, Eq, Read)
|
||||||
|
|
||||||
|
instance ToJSON Transaction where
|
||||||
|
toJSON (Transaction t h c e tb sb ob) =
|
||||||
|
object
|
||||||
|
[ "txid" .= t
|
||||||
|
, "height" .= h
|
||||||
|
, "confirmations" .= c
|
||||||
|
, "expiry" .= e
|
||||||
|
, "transparent" .= tb
|
||||||
|
, "sapling" .= sb
|
||||||
|
, "orchard" .= ob
|
||||||
|
]
|
||||||
|
|
||||||
-- | The transparent portion of a Zcash transaction
|
-- | The transparent portion of a Zcash transaction
|
||||||
data TransparentBundle = TransparentBundle
|
data TransparentBundle = TransparentBundle
|
||||||
{ tb_vin :: ![H.TxIn]
|
{ tb_vin :: ![H.TxIn]
|
||||||
|
@ -140,6 +153,10 @@ data TransparentBundle = TransparentBundle
|
||||||
, tb_coinbase :: !Bool
|
, tb_coinbase :: !Bool
|
||||||
} deriving (Eq, Prelude.Show, Read)
|
} deriving (Eq, Prelude.Show, Read)
|
||||||
|
|
||||||
|
instance ToJSON TransparentBundle where
|
||||||
|
toJSON (TransparentBundle vin vout c) =
|
||||||
|
object ["vin" .= vin, "vout" .= vout, "coinbase" .= c]
|
||||||
|
|
||||||
-- | Read a raw transparent bundle into the Haskell type
|
-- | Read a raw transparent bundle into the Haskell type
|
||||||
fromRawTBundle :: RawTBundle -> Maybe TransparentBundle
|
fromRawTBundle :: RawTBundle -> Maybe TransparentBundle
|
||||||
fromRawTBundle rtb =
|
fromRawTBundle rtb =
|
||||||
|
@ -239,7 +256,8 @@ instance FromJSON RpcError where
|
||||||
-- ** `zcashd`
|
-- ** `zcashd`
|
||||||
-- | Type to represent response from the `zcashd` RPC `getblock` method
|
-- | Type to represent response from the `zcashd` RPC `getblock` method
|
||||||
data BlockResponse = BlockResponse
|
data BlockResponse = BlockResponse
|
||||||
{ bl_confirmations :: !Integer -- ^ Block confirmations
|
{ bl_hash :: !HexString
|
||||||
|
, bl_confirmations :: !Integer -- ^ Block confirmations
|
||||||
, bl_height :: !Integer -- ^ Block height
|
, bl_height :: !Integer -- ^ Block height
|
||||||
, bl_time :: !Integer -- ^ Block time
|
, bl_time :: !Integer -- ^ Block time
|
||||||
, bl_txs :: ![HexString] -- ^ List of transaction IDs in the block
|
, bl_txs :: ![HexString] -- ^ List of transaction IDs in the block
|
||||||
|
@ -252,7 +270,8 @@ instance FromJSON BlockResponse where
|
||||||
h <- obj .: "height"
|
h <- obj .: "height"
|
||||||
t <- obj .:? "time"
|
t <- obj .:? "time"
|
||||||
txs <- obj .: "tx"
|
txs <- obj .: "tx"
|
||||||
pure $ BlockResponse c h (fromMaybe 0 t) txs
|
hash <- obj .: "hash"
|
||||||
|
pure $ BlockResponse hash c h (fromMaybe 0 t) txs
|
||||||
|
|
||||||
-- | Type to represent response from the `zcashd` RPC `getrawtransaction`
|
-- | Type to represent response from the `zcashd` RPC `getrawtransaction`
|
||||||
data RawTxResponse = RawTxResponse
|
data RawTxResponse = RawTxResponse
|
||||||
|
@ -324,6 +343,10 @@ data SaplingBundle = SaplingBundle
|
||||||
, sbSig :: !HexString
|
, sbSig :: !HexString
|
||||||
} deriving stock (Eq, Prelude.Show, GHC.Generic, Read)
|
} deriving stock (Eq, Prelude.Show, GHC.Generic, Read)
|
||||||
|
|
||||||
|
instance ToJSON SaplingBundle where
|
||||||
|
toJSON (SaplingBundle s o v sig) =
|
||||||
|
object ["spends" .= s, "outputs" .= o, "value" .= v, "sig" .= sig]
|
||||||
|
|
||||||
fromRawSBundle :: RawSBundle -> Maybe SaplingBundle
|
fromRawSBundle :: RawSBundle -> Maybe SaplingBundle
|
||||||
fromRawSBundle b =
|
fromRawSBundle b =
|
||||||
if zsb_empty b
|
if zsb_empty b
|
||||||
|
@ -355,6 +378,17 @@ data OrchardBundle = OrchardBundle
|
||||||
, obSig :: !HexString
|
, obSig :: !HexString
|
||||||
} deriving stock (Eq, Prelude.Show, GHC.Generic, Read)
|
} deriving stock (Eq, Prelude.Show, GHC.Generic, Read)
|
||||||
|
|
||||||
|
instance ToJSON OrchardBundle where
|
||||||
|
toJSON (OrchardBundle a f v an p s) =
|
||||||
|
object
|
||||||
|
[ "actions" .= a
|
||||||
|
, "flags" .= f
|
||||||
|
, "value" .= v
|
||||||
|
, "anchor" .= an
|
||||||
|
, "proof" .= p
|
||||||
|
, "sig" .= s
|
||||||
|
]
|
||||||
|
|
||||||
fromRawOBundle :: RawOBundle -> Maybe OrchardBundle
|
fromRawOBundle :: RawOBundle -> Maybe OrchardBundle
|
||||||
fromRawOBundle b =
|
fromRawOBundle b =
|
||||||
if zob_empty b
|
if zob_empty b
|
||||||
|
@ -377,6 +411,10 @@ data OrchardFlags = OrchardFlags
|
||||||
deriving anyclass (Data.Structured.Show)
|
deriving anyclass (Data.Structured.Show)
|
||||||
deriving (BorshSize, ToBorsh, FromBorsh) via AsStruct OrchardFlags
|
deriving (BorshSize, ToBorsh, FromBorsh) via AsStruct OrchardFlags
|
||||||
|
|
||||||
|
instance ToJSON OrchardFlags where
|
||||||
|
toJSON (OrchardFlags s o) =
|
||||||
|
Data.Aeson.Array $ V.fromList [Data.Aeson.Bool s, Data.Aeson.Bool o]
|
||||||
|
|
||||||
-- | Type for the response from the `zebrad` RPC method `getinfo`
|
-- | Type for the response from the `zebrad` RPC method `getinfo`
|
||||||
data ZebraGetInfo = ZebraGetInfo
|
data ZebraGetInfo = ZebraGetInfo
|
||||||
{ zgi_build :: !T.Text
|
{ zgi_build :: !T.Text
|
||||||
|
@ -501,6 +539,17 @@ data ShieldedSpend = ShieldedSpend
|
||||||
deriving anyclass (Data.Structured.Show)
|
deriving anyclass (Data.Structured.Show)
|
||||||
deriving (BorshSize, ToBorsh, FromBorsh) via AsStruct ShieldedSpend
|
deriving (BorshSize, ToBorsh, FromBorsh) via AsStruct ShieldedSpend
|
||||||
|
|
||||||
|
instance ToJSON ShieldedSpend where
|
||||||
|
toJSON (ShieldedSpend cv a n rk p au) =
|
||||||
|
object
|
||||||
|
[ "cv" .= cv
|
||||||
|
, "anchor" .= a
|
||||||
|
, "nullifier" .= n
|
||||||
|
, "rk" .= rk
|
||||||
|
, "proof" .= p
|
||||||
|
, "spendAuthSig" .= au
|
||||||
|
]
|
||||||
|
|
||||||
instance FromJSON ShieldedSpend where
|
instance FromJSON ShieldedSpend where
|
||||||
parseJSON =
|
parseJSON =
|
||||||
withObject "ShieldedSpend" $ \obj -> do
|
withObject "ShieldedSpend" $ \obj -> do
|
||||||
|
@ -525,6 +574,17 @@ data ShieldedOutput = ShieldedOutput
|
||||||
deriving anyclass (Data.Structured.Show)
|
deriving anyclass (Data.Structured.Show)
|
||||||
deriving (BorshSize, ToBorsh, FromBorsh) via AsStruct ShieldedOutput
|
deriving (BorshSize, ToBorsh, FromBorsh) via AsStruct ShieldedOutput
|
||||||
|
|
||||||
|
instance ToJSON ShieldedOutput where
|
||||||
|
toJSON (ShieldedOutput c cm e enc o p) =
|
||||||
|
object
|
||||||
|
[ "cv" .= c
|
||||||
|
, "cmu" .= cm
|
||||||
|
, "ephemeralKey" .= e
|
||||||
|
, "encCiphertext" .= enc
|
||||||
|
, "outCiphertext" .= o
|
||||||
|
, "proof" .= p
|
||||||
|
]
|
||||||
|
|
||||||
instance FromJSON ShieldedOutput where
|
instance FromJSON ShieldedOutput where
|
||||||
parseJSON =
|
parseJSON =
|
||||||
withObject "ShieldedOutput" $ \obj -> do
|
withObject "ShieldedOutput" $ \obj -> do
|
||||||
|
@ -583,6 +643,14 @@ data RawUA = RawUA
|
||||||
deriving anyclass (Data.Structured.Show)
|
deriving anyclass (Data.Structured.Show)
|
||||||
deriving (BorshSize, ToBorsh, FromBorsh) via AsStruct RawUA
|
deriving (BorshSize, ToBorsh, FromBorsh) via AsStruct RawUA
|
||||||
|
|
||||||
|
-- | A type to handle user-entered addresses
|
||||||
|
data ValidAddress
|
||||||
|
= Unified !UnifiedAddress
|
||||||
|
| Sapling !SaplingAddress
|
||||||
|
| Transparent !TransparentAddress
|
||||||
|
| Exchange !ExchangeAddress
|
||||||
|
deriving stock (Eq, Prelude.Show)
|
||||||
|
|
||||||
-- | Type to represent a Unified Full Viewing Key
|
-- | Type to represent a Unified Full Viewing Key
|
||||||
data UnifiedFullViewingKey = UnifiedFullViewingKey
|
data UnifiedFullViewingKey = UnifiedFullViewingKey
|
||||||
{ net :: !Word8 -- ^ Number representing the network the key belongs to. @1@ for @mainnet@, @2@ for @testnet@ and @3@ for @regtestnet@.
|
{ net :: !Word8 -- ^ Number representing the network the key belongs to. @1@ for @mainnet@, @2@ for @testnet@ and @3@ for @regtestnet@.
|
||||||
|
@ -609,6 +677,19 @@ data OrchardAction = OrchardAction
|
||||||
deriving anyclass (Data.Structured.Show)
|
deriving anyclass (Data.Structured.Show)
|
||||||
deriving (BorshSize, ToBorsh, FromBorsh) via AsStruct OrchardAction
|
deriving (BorshSize, ToBorsh, FromBorsh) via AsStruct OrchardAction
|
||||||
|
|
||||||
|
instance ToJSON OrchardAction where
|
||||||
|
toJSON (OrchardAction n r c e en o cv a) =
|
||||||
|
object
|
||||||
|
[ "nullifier" .= n
|
||||||
|
, "rk" .= r
|
||||||
|
, "cmx" .= c
|
||||||
|
, "ephemeralKey" .= e
|
||||||
|
, "encCiphertext" .= en
|
||||||
|
, "outCiphertext" .= o
|
||||||
|
, "cv" .= cv
|
||||||
|
, "spendAuthSig" .= a
|
||||||
|
]
|
||||||
|
|
||||||
instance FromJSON OrchardAction where
|
instance FromJSON OrchardAction where
|
||||||
parseJSON =
|
parseJSON =
|
||||||
withObject "OrchardAction" $ \obj -> do
|
withObject "OrchardAction" $ \obj -> do
|
||||||
|
@ -712,6 +793,7 @@ data TxError
|
||||||
| OrchardRecipient
|
| OrchardRecipient
|
||||||
| SaplingBuilderNotAvailable
|
| SaplingBuilderNotAvailable
|
||||||
| OrchardBuilderNotAvailable
|
| OrchardBuilderNotAvailable
|
||||||
|
| PrivacyPolicyError !T.Text
|
||||||
| ZHError
|
| ZHError
|
||||||
deriving (Eq, Prelude.Show, Read)
|
deriving (Eq, Prelude.Show, Read)
|
||||||
|
|
||||||
|
|
|
@ -129,13 +129,11 @@ createTransaction ::
|
||||||
-> [SaplingTxSpend] -- ^ the list of Sapling notes to spend
|
-> [SaplingTxSpend] -- ^ the list of Sapling notes to spend
|
||||||
-> [OrchardTxSpend] -- ^ the list of Orchard notes to spend
|
-> [OrchardTxSpend] -- ^ the list of Orchard notes to spend
|
||||||
-> [OutgoingNote] -- ^ the list of outgoing notes, including change notes
|
-> [OutgoingNote] -- ^ the list of outgoing notes, including change notes
|
||||||
-> SaplingSpendParams -- ^ the Sapling circuit spending parameters
|
|
||||||
-> SaplingOutputParams -- ^ the Sapling circuit output parameters
|
|
||||||
-> ZcashNet -- ^ the network to be used
|
-> ZcashNet -- ^ the network to be used
|
||||||
-> Int -- ^ target block height
|
-> Int -- ^ target block height
|
||||||
-> Bool -- ^ True to build, False to estimate fee
|
-> Bool -- ^ True to build, False to estimate fee
|
||||||
-> Either TxError HexString
|
-> Either TxError HexString
|
||||||
createTransaction sapAnchor orchAnchor tSpend sSpend oSpend outgoing sParams oParams znet bh build =
|
createTransaction sapAnchor orchAnchor tSpend sSpend oSpend outgoing znet bh build =
|
||||||
processResult $! txResult
|
processResult $! txResult
|
||||||
where
|
where
|
||||||
processResult :: HexString -> Either TxError HexString
|
processResult :: HexString -> Either TxError HexString
|
||||||
|
@ -168,8 +166,6 @@ createTransaction sapAnchor orchAnchor tSpend sSpend oSpend outgoing sParams oPa
|
||||||
sSpend
|
sSpend
|
||||||
oSpend
|
oSpend
|
||||||
outgoing
|
outgoing
|
||||||
(sapSParams sParams)
|
|
||||||
(sapOParams oParams)
|
|
||||||
(znet == MainNet)
|
(znet == MainNet)
|
||||||
(fromIntegral bh)
|
(fromIntegral bh)
|
||||||
build
|
build
|
||||||
|
|
|
@ -40,6 +40,7 @@ import GHC.Float.RealFracMethods (properFractionDoubleInteger)
|
||||||
import Haskoin.Crypto.Hash (ripemd160)
|
import Haskoin.Crypto.Hash (ripemd160)
|
||||||
import Haskoin.Crypto.Keys.Extended
|
import Haskoin.Crypto.Keys.Extended
|
||||||
import Haskoin.Transaction.Common
|
import Haskoin.Transaction.Common
|
||||||
|
import Network.HTTP.Simple (Response(..))
|
||||||
import Test.HUnit
|
import Test.HUnit
|
||||||
import Test.Hspec
|
import Test.Hspec
|
||||||
import Test.Hspec.QuickCheck
|
import Test.Hspec.QuickCheck
|
||||||
|
@ -82,6 +83,8 @@ import ZcashHaskell.Types
|
||||||
, RawTxOut(..)
|
, RawTxOut(..)
|
||||||
, RawTxResponse(..)
|
, RawTxResponse(..)
|
||||||
, RawZebraTx(..)
|
, RawZebraTx(..)
|
||||||
|
, RpcError(..)
|
||||||
|
, RpcResponse(..)
|
||||||
, SaplingAddress(..)
|
, SaplingAddress(..)
|
||||||
, SaplingBundle(..)
|
, SaplingBundle(..)
|
||||||
, SaplingCommitmentTree(..)
|
, SaplingCommitmentTree(..)
|
||||||
|
@ -1143,7 +1146,7 @@ main = do
|
||||||
case exch of
|
case exch of
|
||||||
Nothing -> assertFailure "Failed to encode Exchange address"
|
Nothing -> assertFailure "Failed to encode Exchange address"
|
||||||
Just addr -> do
|
Just addr -> do
|
||||||
let eadr = decodeExchangeAddress addr
|
let eadr = decodeExchangeAddress (E.encodeUtf8 addr)
|
||||||
eadr `shouldNotBe` Nothing
|
eadr `shouldNotBe` Nothing
|
||||||
describe "Witness updates" $ do
|
describe "Witness updates" $ do
|
||||||
it "Sapling" $ do
|
it "Sapling" $ do
|
||||||
|
@ -1179,7 +1182,7 @@ main = do
|
||||||
updateOrchardWitness wit cmxs `shouldBe`
|
updateOrchardWitness wit cmxs `shouldBe`
|
||||||
OrchardWitness
|
OrchardWitness
|
||||||
(hexString
|
(hexString
|
||||||
"016225b41339a00dd764b452fca190a0245e7118224965942e3a6d798365c34631001f0000011d6f5da3f619bfaab957fc643c17eb144db0101c90f422da2fcbe0e80d74412e000000000001746e6bc066a10e7f80a9ff8993dcb25c819edd64f2ca10ac248ef7848d41450500011e6191f91b3fceb62dc881a156e1b9d2e88e09dca25093cf9c4936c8869fb41a013bf8b923e4187754e85175748d9cce4824a6787e4258977b5bfe1ba59012c032000001f3bbdc62260c4fca5c84bf3487246d4542da48eeeec8ec40c1029b6908eef83c00000000000000000000000000000000040e02c864db8b574f165f616d48e2f12eb25099b5c90186af26d9e50f5058863e0504bfbc12edc35e05042c16bbfb8fed591f01f18fe128eeb57f2c456c9eb222d6d261c549e95d9007bce4c6ae0b86bc865711cdd9f0fa92e2d5b5e149b51f3be127df3b1d2372adf6c811b2e456c1d64d0e9eb167a995f9c6b66a03c9cbda250101c094201bae3b4ef582a3e8654f65a72fbd41e20e1ec9a43d3f4101afc868731e0002010cfb50d8c877eb39e9c07082a032dd99d34be7c19fa7f30e9fecf5f14736240f019df5b9366d0f21caa678d1567390b5bfd3cfa0438271bcfe301b5558a2863301")
|
"016225b41339a00dd764b452fca190a0245e7118224965942e3a6d798365c34631001f0000011d6f5da3f619bfaab957fc643c17eb144db0101c90f422da2fcbe0e80d74412e000000000001746e6bc066a10e7f80a9ff8993dcb25c819edd64f2ca10ac248ef7848d41450500011e6191f91b3fceb62dc881a156e1b9d2e88e09dca25093cf9c4936c8869fb41a013bf8b923e4187754e85175748d9cce4824a6787e4258977b5bfe1ba59012c032000001f3bbdc62260c4fca5c84bf3487246d4542da48eeeec8ec40c1029b6908eef83c00000000000000000000000000000000040e02c864db8b574f165f616d48e2f12eb25099b5c90186af26d9e50f5058863e0504bfbc12edc35e05042c16bbfb8fed591f01f18fe128eeb57f2c456c9eb222d6d261c549e95d9007bce4c6ae0b86bc865711cdd9f0fa92e2d5b5e149b51f3be127df3b1d2372adf6c811b2e456c1d64d0e9eb167a995f9c6b66a03c9cbda250101c094201bae3b4ef582a3e8654f65a72fbd41e20e1ec9a43d3f4101afc868731e01ac20b8170b008888c19fc6e16f5e30a5ef1653e5219d0cd0c9353c3aa8f7982302010cfb50d8c877eb39e9c07082a032dd99d34be7c19fa7f30e9fecf5f14736240f019df5b9366d0f21caa678d1567390b5bfd3cfa0438271bcfe301b5558a2863301")
|
||||||
|
|
||||||
-- | Properties
|
-- | Properties
|
||||||
prop_PhraseLength :: Property
|
prop_PhraseLength :: Property
|
||||||
|
|
|
@ -5,7 +5,7 @@ cabal-version: 3.0
|
||||||
-- see: https://github.com/sol/hpack
|
-- see: https://github.com/sol/hpack
|
||||||
|
|
||||||
name: zcash-haskell
|
name: zcash-haskell
|
||||||
version: 0.6.2.1
|
version: 0.7.0.2
|
||||||
synopsis: Utilities to interact with the Zcash blockchain
|
synopsis: Utilities to interact with the Zcash blockchain
|
||||||
description: Please see the README on the repo at <https://git.vergara.tech/Vergara_Tech/zcash-haskell#readme>
|
description: Please see the README on the repo at <https://git.vergara.tech/Vergara_Tech/zcash-haskell#readme>
|
||||||
category: Blockchain
|
category: Blockchain
|
||||||
|
@ -59,6 +59,7 @@ library
|
||||||
, text
|
, text
|
||||||
, haskoin-core
|
, haskoin-core
|
||||||
, secp256k1-haskell >= 1.1
|
, secp256k1-haskell >= 1.1
|
||||||
|
, vector
|
||||||
, utf8-string
|
, utf8-string
|
||||||
build-tool-depends:
|
build-tool-depends:
|
||||||
c2hs:c2hs
|
c2hs:c2hs
|
||||||
|
@ -85,5 +86,6 @@ test-suite zcash-haskell-test
|
||||||
, binary
|
, binary
|
||||||
, cryptonite
|
, cryptonite
|
||||||
, secp256k1-haskell
|
, secp256k1-haskell
|
||||||
|
, http-conduit
|
||||||
pkgconfig-depends: rustzcash_wrapper
|
pkgconfig-depends: rustzcash_wrapper
|
||||||
default-language: Haskell2010
|
default-language: Haskell2010
|
||||||
|
|
Loading…
Reference in a new issue