Encode transparent addresses #3
9 changed files with 214 additions and 16 deletions
12
CHANGELOG.md
12
CHANGELOG.md
|
@ -5,7 +5,17 @@ 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).
|
||||||
|
|
||||||
## [Unreleased]
|
## [0.3.0]
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Type to represent a transparent address/receiver
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Full decoding of Unified Address
|
||||||
|
|
||||||
|
## [0.2.0]
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
|
|
|
@ -189,6 +189,38 @@ impl<RW> ToHaskell<RW> for Hnote {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(BorshSerialize, BorshDeserialize)]
|
||||||
|
pub struct Hua {
|
||||||
|
net: u8,
|
||||||
|
o_rec: Vec<u8>,
|
||||||
|
s_rec: Vec<u8>,
|
||||||
|
t_rec: Vec<u8>,
|
||||||
|
to_rec: Vec<u8>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<RW> ToHaskell<RW> for Hua {
|
||||||
|
fn to_haskell<W: Write>(&self, writer: &mut W, _tag: PhantomData<RW>) -> Result<()> {
|
||||||
|
self.serialize(writer)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Hua {
|
||||||
|
fn add_rec(&mut self, rec: &Receiver) {
|
||||||
|
if let Receiver::Orchard(x) = rec {
|
||||||
|
self.o_rec = x.to_vec();
|
||||||
|
}
|
||||||
|
if let Receiver::Sapling(y) = rec {
|
||||||
|
self.s_rec = y.to_vec();
|
||||||
|
}
|
||||||
|
if let Receiver::P2pkh(z) = rec {
|
||||||
|
self.t_rec = z.to_vec();
|
||||||
|
}
|
||||||
|
if let Receiver::P2sh(w) = rec {
|
||||||
|
self.to_rec = w.to_vec();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(BorshSerialize, BorshDeserialize)]
|
#[derive(BorshSerialize, BorshDeserialize)]
|
||||||
pub struct Hufvk {
|
pub struct Hufvk {
|
||||||
|
@ -261,9 +293,28 @@ pub extern "C" fn rust_wrapper_f4unjumble(
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn rust_wrapper_ua_decode(
|
pub extern "C" fn rust_wrapper_ua_decode(
|
||||||
input: *const u8,
|
input: *const u8,
|
||||||
input_len: usize,) -> bool {
|
input_len: usize,
|
||||||
|
out: *mut u8,
|
||||||
|
out_len: &mut usize) {
|
||||||
let input: String = marshall_from_haskell_var(input, input_len, RW);
|
let input: String = marshall_from_haskell_var(input, input_len, RW);
|
||||||
Address::decode(&input).is_ok()
|
let dec_addy = Address::decode(&input);
|
||||||
|
match dec_addy {
|
||||||
|
Ok((n, ua)) => {
|
||||||
|
let x = match n {
|
||||||
|
Network::Main => 1,
|
||||||
|
Network::Test => 2,
|
||||||
|
Network::Regtest => 3
|
||||||
|
};
|
||||||
|
let mut hk = Hua { net: x, o_rec: vec![0], s_rec: vec![0], t_rec: vec![0], to_rec: vec![0] };
|
||||||
|
let recvs = ua.items();
|
||||||
|
recvs.iter().for_each(|k| hk.add_rec(k));
|
||||||
|
marshall_to_haskell_var(&hk, out, out_len, RW);
|
||||||
|
}
|
||||||
|
Err(_e) => {
|
||||||
|
let hk0 = Hua { net: 0, o_rec: vec![0], s_rec: vec![0], t_rec: vec![0], to_rec: vec![0]};
|
||||||
|
marshall_to_haskell_var(&hk0, out, out_len, RW);
|
||||||
|
}
|
||||||
|
}
|
||||||
//marshall_to_haskell_var(&result, out, out_len, RW);
|
//marshall_to_haskell_var(&result, out, out_len, RW);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
name: zcash-haskell
|
name: zcash-haskell
|
||||||
version: 0.2.1
|
version: 0.3.0
|
||||||
git: "https://git.vergara.tech/Vergara_Tech/zcash-haskell"
|
git: "https://git.vergara.tech/Vergara_Tech/zcash-haskell"
|
||||||
license: LGPL-3
|
license: LGPL-3
|
||||||
author: "Rene Vergara"
|
author: "Rene Vergara"
|
||||||
|
@ -33,6 +33,9 @@ library:
|
||||||
- generics-sop
|
- generics-sop
|
||||||
- aeson
|
- aeson
|
||||||
- http-conduit
|
- http-conduit
|
||||||
|
- base58-bytestring
|
||||||
|
- cryptonite
|
||||||
|
- memory
|
||||||
pkg-config-dependencies:
|
pkg-config-dependencies:
|
||||||
- rustzcash_wrapper-uninstalled
|
- rustzcash_wrapper-uninstalled
|
||||||
|
|
||||||
|
|
|
@ -58,10 +58,11 @@ import ZcashHaskell.Types
|
||||||
-> `()'
|
-> `()'
|
||||||
#}
|
#}
|
||||||
|
|
||||||
{# fun pure unsafe rust_wrapper_ua_decode as rustWrapperIsUA
|
{# fun unsafe rust_wrapper_ua_decode as rustWrapperUADecode
|
||||||
{ toBorshVar* `BS.ByteString'&
|
{ toBorshVar* `BS.ByteString'&
|
||||||
|
, getVarBuffer `Buffer RawUA'&
|
||||||
}
|
}
|
||||||
-> `Bool'
|
-> `()'
|
||||||
#}
|
#}
|
||||||
|
|
||||||
{# fun pure unsafe rust_wrapper_shielded_decode as rustWrapperIsShielded
|
{# fun pure unsafe rust_wrapper_shielded_decode as rustWrapperIsShielded
|
||||||
|
|
|
@ -29,9 +29,9 @@
|
||||||
module ZcashHaskell.Orchard where
|
module ZcashHaskell.Orchard where
|
||||||
|
|
||||||
import C.Zcash
|
import C.Zcash
|
||||||
( rustWrapperIsUA
|
( rustWrapperOrchardCheck
|
||||||
, rustWrapperOrchardCheck
|
|
||||||
, rustWrapperOrchardNoteDecode
|
, rustWrapperOrchardNoteDecode
|
||||||
|
, rustWrapperUADecode
|
||||||
, rustWrapperUfvkDecode
|
, rustWrapperUfvkDecode
|
||||||
)
|
)
|
||||||
import qualified Data.ByteString as BS
|
import qualified Data.ByteString as BS
|
||||||
|
@ -39,8 +39,28 @@ import Foreign.Rust.Marshall.Variable
|
||||||
import ZcashHaskell.Types
|
import ZcashHaskell.Types
|
||||||
|
|
||||||
-- | Checks if given bytestring is a valid encoded unified address
|
-- | Checks if given bytestring is a valid encoded unified address
|
||||||
isValidUnifiedAddress :: BS.ByteString -> Bool
|
isValidUnifiedAddress :: BS.ByteString -> Maybe UnifiedAddress
|
||||||
isValidUnifiedAddress = rustWrapperIsUA
|
isValidUnifiedAddress str =
|
||||||
|
case raw_net decodedAddress of
|
||||||
|
0 -> Nothing
|
||||||
|
_ -> Just $ makeUA decodedAddress
|
||||||
|
where
|
||||||
|
decodedAddress = (withPureBorshVarBuffer . rustWrapperUADecode) str
|
||||||
|
whichNet =
|
||||||
|
case raw_net decodedAddress of
|
||||||
|
1 -> MainNet
|
||||||
|
2 -> TestNet
|
||||||
|
3 -> RegTestNet
|
||||||
|
makeUA x =
|
||||||
|
UnifiedAddress
|
||||||
|
whichNet
|
||||||
|
(raw_o x)
|
||||||
|
(raw_s x)
|
||||||
|
(if not (BS.null (raw_t x))
|
||||||
|
then Just $ TransparentAddress P2PKH whichNet (raw_t x)
|
||||||
|
else if not (BS.null (raw_to x))
|
||||||
|
then Just $ TransparentAddress P2SH whichNet (raw_to x)
|
||||||
|
else Nothing)
|
||||||
|
|
||||||
-- | Attempts to decode the given bytestring into a Unified Full Viewing Key
|
-- | Attempts to decode the given bytestring into a Unified Full Viewing Key
|
||||||
decodeUfvk :: BS.ByteString -> Maybe UnifiedFullViewingKey
|
decodeUfvk :: BS.ByteString -> Maybe UnifiedFullViewingKey
|
||||||
|
|
34
src/ZcashHaskell/Transparent.hs
Normal file
34
src/ZcashHaskell/Transparent.hs
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
{- Copyright 2022-2024 Vergara Technologies LLC
|
||||||
|
|
||||||
|
This file is part of Zcash-Haskell.
|
||||||
|
|
||||||
|
Zcash-Haskell is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU Lesser General Public License as published by the Free
|
||||||
|
Software Foundation, either version 3 of the License, or (at your option) any
|
||||||
|
later version.
|
||||||
|
|
||||||
|
Zcash-Haskell is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
||||||
|
details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public License along with
|
||||||
|
Zcash-Haskell. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
-}
|
||||||
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
|
|
||||||
|
-- |
|
||||||
|
-- Module : ZcashHaskell.Transparent
|
||||||
|
-- Copyright : 2022-2024 Vergara Technologies
|
||||||
|
-- License : LGPL-3
|
||||||
|
--
|
||||||
|
-- Maintainer : pitmutt@vergara.tech
|
||||||
|
-- Stability : experimental
|
||||||
|
-- Portability : unknown
|
||||||
|
--
|
||||||
|
-- Functions to interact with the transparent addresses in the Zcash blockchain
|
||||||
|
--
|
||||||
|
module ZcashHaskell.Transparent where
|
||||||
|
|
||||||
|
import qualified Data.ByteString as BS
|
|
@ -37,12 +37,17 @@
|
||||||
module ZcashHaskell.Types where
|
module ZcashHaskell.Types where
|
||||||
|
|
||||||
import Codec.Borsh
|
import Codec.Borsh
|
||||||
|
import Control.Exception (MaskingState(Unmasked))
|
||||||
|
import Crypto.Hash
|
||||||
import Data.Aeson
|
import Data.Aeson
|
||||||
|
import qualified Data.ByteArray as BA
|
||||||
import qualified Data.ByteString as BS
|
import qualified Data.ByteString as BS
|
||||||
|
import Data.ByteString.Base58 (bitcoinAlphabet, encodeBase58)
|
||||||
import qualified Data.ByteString.Char8 as C
|
import qualified Data.ByteString.Char8 as C
|
||||||
import Data.Int
|
import Data.Int
|
||||||
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 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
|
||||||
|
@ -128,6 +133,47 @@ data RawTxResponse = RawTxResponse
|
||||||
, rt_blocktime :: Integer
|
, rt_blocktime :: Integer
|
||||||
} deriving (Prelude.Show, Eq)
|
} deriving (Prelude.Show, Eq)
|
||||||
|
|
||||||
|
data ZcashNet
|
||||||
|
= MainNet
|
||||||
|
| TestNet
|
||||||
|
| RegTestNet
|
||||||
|
deriving (Eq, Prelude.Show)
|
||||||
|
|
||||||
|
-- * Transparent
|
||||||
|
-- | Type to represent the two kinds of transparent addresses
|
||||||
|
data TransparentType
|
||||||
|
= P2SH
|
||||||
|
| P2PKH
|
||||||
|
deriving (Eq)
|
||||||
|
|
||||||
|
-- | Type to represent a transparent Zcash addresses
|
||||||
|
data TransparentAddress = TransparentAddress
|
||||||
|
{ ta_type :: TransparentType
|
||||||
|
, ta_net :: ZcashNet
|
||||||
|
, ta_bytes :: BS.ByteString
|
||||||
|
} deriving (Eq)
|
||||||
|
|
||||||
|
instance Prelude.Show TransparentAddress where
|
||||||
|
show t =
|
||||||
|
case ta_type t of
|
||||||
|
P2SH ->
|
||||||
|
case ta_net t of
|
||||||
|
MainNet -> Prelude.show $ encodeTransparent (0x1c, 0xbd) $ ta_bytes t
|
||||||
|
_ -> Prelude.show $ encodeTransparent (0x1c, 0xba) $ ta_bytes t
|
||||||
|
P2PKH ->
|
||||||
|
case ta_net t of
|
||||||
|
MainNet -> Prelude.show $ encodeTransparent (0x1c, 0xb8) $ ta_bytes t
|
||||||
|
_ -> Prelude.show $ encodeTransparent (0x1d, 0x25) $ ta_bytes t
|
||||||
|
where
|
||||||
|
encodeTransparent :: (Word8, Word8) -> BS.ByteString -> BS.ByteString
|
||||||
|
encodeTransparent (a, b) h =
|
||||||
|
encodeBase58 bitcoinAlphabet $ digest <> BS.take 4 checksum
|
||||||
|
where
|
||||||
|
sha256 :: BS.ByteString -> BS.ByteString
|
||||||
|
sha256 bs = BA.convert (hash bs :: Digest SHA256)
|
||||||
|
digest = BS.pack [a, b] <> h
|
||||||
|
checksum = sha256 $ sha256 digest
|
||||||
|
|
||||||
-- * Sapling
|
-- * Sapling
|
||||||
-- | Type to represent a Sapling Shielded Output as provided by the @getrawtransaction@ RPC method of @zcashd@.
|
-- | Type to represent a Sapling Shielded Output as provided by the @getrawtransaction@ RPC method of @zcashd@.
|
||||||
data ShieldedOutput = ShieldedOutput
|
data ShieldedOutput = ShieldedOutput
|
||||||
|
@ -161,6 +207,26 @@ instance FromJSON ShieldedOutput where
|
||||||
(decodeHexText p)
|
(decodeHexText p)
|
||||||
|
|
||||||
-- * Orchard
|
-- * Orchard
|
||||||
|
-- | Type to represent a Unified Address
|
||||||
|
data UnifiedAddress = UnifiedAddress
|
||||||
|
{ ua_net :: ZcashNet
|
||||||
|
, o_rec :: BS.ByteString
|
||||||
|
, s_rec :: BS.ByteString
|
||||||
|
, t_rec :: Maybe TransparentAddress
|
||||||
|
} deriving (Prelude.Show, Eq)
|
||||||
|
|
||||||
|
-- | Helper type for marshalling UAs
|
||||||
|
data RawUA = RawUA
|
||||||
|
{ raw_net :: Word8
|
||||||
|
, raw_o :: BS.ByteString
|
||||||
|
, raw_s :: BS.ByteString
|
||||||
|
, raw_t :: BS.ByteString
|
||||||
|
, raw_to :: BS.ByteString
|
||||||
|
} deriving stock (Eq, Prelude.Show, GHC.Generic)
|
||||||
|
deriving anyclass (SOP.Generic, SOP.HasDatatypeInfo)
|
||||||
|
deriving anyclass (Data.Structured.Show)
|
||||||
|
deriving (BorshSize, ToBorsh, FromBorsh) via AsStruct RawUA
|
||||||
|
|
||||||
-- | 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@.
|
||||||
|
|
19
test/Spec.hs
19
test/Spec.hs
|
@ -18,10 +18,11 @@
|
||||||
-}
|
-}
|
||||||
{-# LANGUAGE OverloadedStrings #-}
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
|
|
||||||
import C.Zcash (rustWrapperIsUA)
|
import C.Zcash (rustWrapperUADecode)
|
||||||
import Data.Aeson
|
import Data.Aeson
|
||||||
import Data.Bool (Bool(True))
|
import Data.Bool (Bool(True))
|
||||||
import qualified Data.ByteString as BS
|
import qualified Data.ByteString as BS
|
||||||
|
import Data.Maybe
|
||||||
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.Text.Lazy.Encoding as LE
|
import qualified Data.Text.Lazy.Encoding as LE
|
||||||
|
@ -30,7 +31,6 @@ import Data.Word
|
||||||
import GHC.Float.RealFracMethods (properFractionDoubleInteger)
|
import GHC.Float.RealFracMethods (properFractionDoubleInteger)
|
||||||
import Test.Hspec
|
import Test.Hspec
|
||||||
import ZcashHaskell.Orchard
|
import ZcashHaskell.Orchard
|
||||||
import ZcashHaskell.Orchard (matchOrchardAddress)
|
|
||||||
import ZcashHaskell.Sapling
|
import ZcashHaskell.Sapling
|
||||||
( decodeSaplingOutput
|
( decodeSaplingOutput
|
||||||
, getShieldedOutputs
|
, getShieldedOutputs
|
||||||
|
@ -45,11 +45,11 @@ import ZcashHaskell.Types
|
||||||
, RawData(..)
|
, RawData(..)
|
||||||
, RawTxResponse(..)
|
, RawTxResponse(..)
|
||||||
, ShieldedOutput(..)
|
, ShieldedOutput(..)
|
||||||
|
, UnifiedAddress(..)
|
||||||
, UnifiedFullViewingKey(..)
|
, UnifiedFullViewingKey(..)
|
||||||
, decodeHexText
|
, decodeHexText
|
||||||
)
|
)
|
||||||
import ZcashHaskell.Utils
|
import ZcashHaskell.Utils
|
||||||
import ZcashHaskell.Utils (decodeBech32)
|
|
||||||
|
|
||||||
main :: IO ()
|
main :: IO ()
|
||||||
main = do
|
main = do
|
||||||
|
@ -315,11 +315,11 @@ main = do
|
||||||
it "succeeds with correct UA" $ do
|
it "succeeds with correct UA" $ do
|
||||||
let ua =
|
let ua =
|
||||||
"u1salpdyefywvsg2dlmxg9589yznh0h9v6qjr478k80amtkqkws5pr408lxt2953dpprvu06mahxt99cv65fgsm7sw8hlchplfg5pl89ur"
|
"u1salpdyefywvsg2dlmxg9589yznh0h9v6qjr478k80amtkqkws5pr408lxt2953dpprvu06mahxt99cv65fgsm7sw8hlchplfg5pl89ur"
|
||||||
isValidUnifiedAddress ua `shouldBe` True
|
isJust (isValidUnifiedAddress ua) `shouldBe` True
|
||||||
it "fails with incorrect UA" $ do
|
it "fails with incorrect UA" $ do
|
||||||
let ua =
|
let ua =
|
||||||
"u1salpdyefbreakingtheaddressh0h9v6qjr478k80amtkqkws5pr408lxt2953dpprvu06mahxt99cv65fgsm7sw8hlchplfg5pl89ur"
|
"u1salpdyefbreakingtheaddressh0h9v6qjr478k80amtkqkws5pr408lxt2953dpprvu06mahxt99cv65fgsm7sw8hlchplfg5pl89ur"
|
||||||
isValidUnifiedAddress ua `shouldBe` False
|
isValidUnifiedAddress ua `shouldBe` Nothing
|
||||||
describe "Decode UVK from YWallet" $ do
|
describe "Decode UVK from YWallet" $ do
|
||||||
let uvk =
|
let uvk =
|
||||||
"uview1u833rp8yykd7h4druwht6xp6k8krle45fx8hqsw6vzw63n24atxpcatws82z092kryazuu6d7rayyut8m36wm4wpjy2z8r9hj48fx5pf49gw4sjrq8503qpz3vqj5hg0vg9vsqeasg5qjuyh94uyfm7v76udqcm2m0wfc25hcyqswcn56xxduq3xkgxkr0l73cjy88fdvf90eq5fda9g6x7yv7d0uckpevxg6540wc76xrc4axxvlt03ptaa2a0rektglmdy68656f3uzcdgqqyu0t7wk5cvwghyyvgqc0rp3vgu5ye4nd236ml57rjh083a2755qemf6dk6pw0qrnfm7246s8eg2hhzkzpf9h73chhng7xhmyem2sjh8rs2m9nhfcslsgenm"
|
"uview1u833rp8yykd7h4druwht6xp6k8krle45fx8hqsw6vzw63n24atxpcatws82z092kryazuu6d7rayyut8m36wm4wpjy2z8r9hj48fx5pf49gw4sjrq8503qpz3vqj5hg0vg9vsqeasg5qjuyh94uyfm7v76udqcm2m0wfc25hcyqswcn56xxduq3xkgxkr0l73cjy88fdvf90eq5fda9g6x7yv7d0uckpevxg6540wc76xrc4axxvlt03ptaa2a0rektglmdy68656f3uzcdgqqyu0t7wk5cvwghyyvgqc0rp3vgu5ye4nd236ml57rjh083a2755qemf6dk6pw0qrnfm7246s8eg2hhzkzpf9h73chhng7xhmyem2sjh8rs2m9nhfcslsgenm"
|
||||||
|
@ -420,3 +420,12 @@ main = do
|
||||||
let msg = maybe "" a_memo decryptedNote2
|
let msg = maybe "" a_memo decryptedNote2
|
||||||
msg `shouldBe`
|
msg `shouldBe`
|
||||||
"Hello World!\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"
|
"Hello World!\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL"
|
||||||
|
describe "Address tests" $ do
|
||||||
|
it "Encode transparent" $ do
|
||||||
|
let ua =
|
||||||
|
"u17n7hpwaujyq7ux8f9jpyymtnk5urw7pyrf60smp5mawy7jgz325hfvz3jn3zsfya8yxryf9q7ldk8nu8df0emra5wne28zq9d9nm2pu4x6qwjha565av9aze0xgujgslz74ufkj0c0cylqwjyrh9msjfh7jzal6d3qzrnhkkqy3pqm8j63y07jxj7txqeac982778rmt64f32aum94x"
|
||||||
|
let msg =
|
||||||
|
case isValidUnifiedAddress ua of
|
||||||
|
Nothing -> "Bad UA"
|
||||||
|
Just u -> maybe "No transparent" show $ t_rec u
|
||||||
|
msg `shouldBe` "Got it"
|
||||||
|
|
|
@ -5,7 +5,7 @@ cabal-version: 1.12
|
||||||
-- see: https://github.com/sol/hpack
|
-- see: https://github.com/sol/hpack
|
||||||
|
|
||||||
name: zcash-haskell
|
name: zcash-haskell
|
||||||
version: 0.2.1
|
version: 0.3.0
|
||||||
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
|
||||||
|
@ -28,6 +28,7 @@ library
|
||||||
C.Zcash
|
C.Zcash
|
||||||
ZcashHaskell.Orchard
|
ZcashHaskell.Orchard
|
||||||
ZcashHaskell.Sapling
|
ZcashHaskell.Sapling
|
||||||
|
ZcashHaskell.Transparent
|
||||||
ZcashHaskell.Types
|
ZcashHaskell.Types
|
||||||
ZcashHaskell.Utils
|
ZcashHaskell.Utils
|
||||||
other-modules:
|
other-modules:
|
||||||
|
@ -39,11 +40,14 @@ library
|
||||||
build-depends:
|
build-depends:
|
||||||
aeson
|
aeson
|
||||||
, base >=4.7 && <5
|
, base >=4.7 && <5
|
||||||
|
, base58-bytestring
|
||||||
, borsh >=0.2
|
, borsh >=0.2
|
||||||
, bytestring
|
, bytestring
|
||||||
|
, cryptonite
|
||||||
, foreign-rust
|
, foreign-rust
|
||||||
, generics-sop
|
, generics-sop
|
||||||
, http-conduit
|
, http-conduit
|
||||||
|
, memory
|
||||||
, text
|
, text
|
||||||
default-language: Haskell2010
|
default-language: Haskell2010
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue