Add functionality for transaction creation #75

Merged
pitmutt merged 2 commits from rav001 into dev040 2024-05-01 14:14:40 +00:00
4 changed files with 125 additions and 5 deletions

View file

@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [0.6.1.1]
### Added
- Type for transaction creation errors
- Types for Sapling circuit parameters
- Function to create transaction
### Changed
- Add `Read` instance for `Rseed`

View file

@ -1809,9 +1809,53 @@ pub extern "C" fn rust_wrapper_create_transaction(
let h = Hhex {bytes: out_bytes};
marshall_to_haskell_var(&h, out, out_len, RW);
},
Err(_e) => {
Err(e) => {
match e {
Error::InsufficientFunds(_y) => {
let x = Hhex {bytes: vec![0]};
marshall_to_haskell_var(&x, out, out_len, RW);
},
Error::ChangeRequired(_y1) => {
let x = Hhex {bytes: vec![1]};
marshall_to_haskell_var(&x, out, out_len, RW);
},
Error::Fee(_y2) => {
let x = Hhex {bytes: vec![2]};
marshall_to_haskell_var(&x, out, out_len, RW);
},
Error::Balance(x) => {
let x = Hhex {bytes: vec![3]};
marshall_to_haskell_var(&x, out, out_len, RW);
},
Error::TransparentBuild(x) => {
let x = Hhex {bytes: vec![4]};
marshall_to_haskell_var(&x, out, out_len, RW);
},
Error::SaplingBuild(x) => {
let x = Hhex {bytes: vec![5]};
marshall_to_haskell_var(&x, out, out_len, RW);
},
Error::OrchardBuild(x) => {
let x = Hhex {bytes: vec![6]};
marshall_to_haskell_var(&x, out, out_len, RW);
},
Error::OrchardSpend(x) => {
let x = Hhex {bytes: vec![7]};
marshall_to_haskell_var(&x, out, out_len, RW);
},
Error::OrchardRecipient(x) => {
let x = Hhex {bytes: vec![8]};
marshall_to_haskell_var(&x, out, out_len, RW);
},
Error::SaplingBuilderNotAvailable => {
let x = Hhex {bytes: vec![9]};
marshall_to_haskell_var(&x, out, out_len, RW);
},
Error::OrchardBuilderNotAvailable => {
let x = Hhex {bytes: vec![10]};
marshall_to_haskell_var(&x, out, out_len, RW);
}
}
}
}
}

View file

@ -692,6 +692,29 @@ data OutgoingNote = OutGoingNote
deriving anyclass (Data.Structured.Show)
deriving (BorshSize, ToBorsh, FromBorsh) via AsStruct OutgoingNote
newtype SaplingSpendParams = SaplingSpendParams
{ sapSParams :: BS.ByteString
} deriving newtype (Eq, Prelude.Show, Read)
newtype SaplingOutputParams = SaplingOutputParams
{ sapOParams :: BS.ByteString
} deriving newtype (Eq, Prelude.Show, Read)
data TxError
= InsufficientFunds
| ChangeRequired
| Fee
| Balance
| TransparentBuild
| SaplingBuild
| OrchardBuild
| OrchardSpend
| OrchardRecipient
| SaplingBuilderNotAvailable
| OrchardBuilderNotAvailable
| ZHError
deriving (Eq, Prelude.Show, Read)
-- * Classes
-- | Class to represent types with a bytestring representation
class ToBytes a where

View file

@ -19,8 +19,9 @@ module ZcashHaskell.Utils where
import C.Zcash
( rustWrapperBech32Decode
, rustWrapperBech32mEncode
, rustWrapperBech32Encode
, rustWrapperBech32mEncode
, rustWrapperCreateTx
, rustWrapperF4Jumble
, rustWrapperF4UnJumble
, rustWrapperTxRead
@ -31,7 +32,7 @@ import Data.Aeson
import Data.Binary.Get
import qualified Data.ByteString as BS
import qualified Data.ByteString.Lazy as LBS
import Data.HexString (HexString(..))
import Data.HexString (HexString(..), toBytes)
import qualified Data.Text as T
import qualified Data.Text.Encoding as E
import Foreign.Rust.Marshall.Variable
@ -121,3 +122,49 @@ readZebraTransaction hex =
where
rawTx = (withPureBorshVarBuffer . rustWrapperTxRead) $ hexBytes hex
createTransaction ::
Maybe SaplingWitness -- ^ to obtain the Sapling anchor
-> Maybe OrchardWitness -- ^ to obtain the Orchard anchor
-> [TransparentTxSpend] -- ^ the list of transparent notes to spend
-> [SaplingTxSpend] -- ^ the list of Sapling notes to spend
-> [OrchardTxSpend] -- ^ the list of Orchard notes to spend
-> [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
-> Int -- ^ target block height
-> Either TxError HexString
createTransaction sapAnchor orchAnchor tSpend sSpend oSpend outgoing sParams oParams znet bh =
if BS.length (hexBytes txResult) > 1
then Right txResult
else case head (BS.unpack $ hexBytes txResult) of
0 -> Left InsufficientFunds
1 -> Left ChangeRequired
2 -> Left Fee
3 -> Left Balance
4 -> Left TransparentBuild
5 -> Left SaplingBuild
6 -> Left OrchardBuild
7 -> Left OrchardSpend
8 -> Left OrchardRecipient
9 -> Left SaplingBuilderNotAvailable
10 -> Left OrchardBuilderNotAvailable
_ -> Left ZHError
where
txResult =
withPureBorshVarBuffer $
rustWrapperCreateTx
(case sapAnchor of
Nothing -> "0"
Just sA -> toBytes $ sapWit sA)
(case orchAnchor of
Nothing -> "0"
Just oA -> toBytes $ orchWit oA)
tSpend
sSpend
oSpend
outgoing
(sapSParams sParams)
(sapOParams oParams)
(znet == MainNet)
(fromIntegral bh)