Add functionality for transaction creation #75
4 changed files with 125 additions and 5 deletions
|
@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
|
|
||||||
## [0.6.1.1]
|
## [0.6.1.1]
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Type for transaction creation errors
|
||||||
|
- Types for Sapling circuit parameters
|
||||||
|
- Function to create transaction
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Add `Read` instance for `Rseed`
|
- Add `Read` instance for `Rseed`
|
||||||
|
|
|
@ -1809,9 +1809,53 @@ pub extern "C" fn rust_wrapper_create_transaction(
|
||||||
let h = Hhex {bytes: out_bytes};
|
let h = Hhex {bytes: out_bytes};
|
||||||
marshall_to_haskell_var(&h, out, out_len, RW);
|
marshall_to_haskell_var(&h, out, out_len, RW);
|
||||||
},
|
},
|
||||||
Err(_e) => {
|
Err(e) => {
|
||||||
let x = Hhex {bytes: vec![0]};
|
match e {
|
||||||
marshall_to_haskell_var(&x, out, out_len, RW);
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -692,6 +692,29 @@ data OutgoingNote = OutGoingNote
|
||||||
deriving anyclass (Data.Structured.Show)
|
deriving anyclass (Data.Structured.Show)
|
||||||
deriving (BorshSize, ToBorsh, FromBorsh) via AsStruct OutgoingNote
|
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
|
-- * Classes
|
||||||
-- | Class to represent types with a bytestring representation
|
-- | Class to represent types with a bytestring representation
|
||||||
class ToBytes a where
|
class ToBytes a where
|
||||||
|
|
|
@ -19,8 +19,9 @@ module ZcashHaskell.Utils where
|
||||||
|
|
||||||
import C.Zcash
|
import C.Zcash
|
||||||
( rustWrapperBech32Decode
|
( rustWrapperBech32Decode
|
||||||
, rustWrapperBech32mEncode
|
|
||||||
, rustWrapperBech32Encode
|
, rustWrapperBech32Encode
|
||||||
|
, rustWrapperBech32mEncode
|
||||||
|
, rustWrapperCreateTx
|
||||||
, rustWrapperF4Jumble
|
, rustWrapperF4Jumble
|
||||||
, rustWrapperF4UnJumble
|
, rustWrapperF4UnJumble
|
||||||
, rustWrapperTxRead
|
, rustWrapperTxRead
|
||||||
|
@ -31,7 +32,7 @@ import Data.Aeson
|
||||||
import Data.Binary.Get
|
import Data.Binary.Get
|
||||||
import qualified Data.ByteString as BS
|
import qualified Data.ByteString as BS
|
||||||
import qualified Data.ByteString.Lazy as LBS
|
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 as T
|
||||||
import qualified Data.Text.Encoding as E
|
import qualified Data.Text.Encoding as E
|
||||||
import Foreign.Rust.Marshall.Variable
|
import Foreign.Rust.Marshall.Variable
|
||||||
|
@ -121,3 +122,49 @@ readZebraTransaction hex =
|
||||||
where
|
where
|
||||||
rawTx = (withPureBorshVarBuffer . rustWrapperTxRead) $ hexBytes hex
|
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)
|
||||||
|
|
Loading…
Reference in a new issue