zcash-haskell/librustzcash-wrapper/src/lib.rs

153 lines
3.9 KiB
Rust
Raw Normal View History

2023-04-16 00:07:08 +00:00
use std::{
marker::PhantomData,
io::Write,
fmt::{Debug, Display, Formatter}
};
use f4jumble;
use borsh::{BorshDeserialize, BorshSerialize};
2023-04-27 14:48:11 +00:00
2023-04-16 00:07:08 +00:00
use haskell_ffi::{
error::Result,
2023-04-27 14:48:11 +00:00
from_haskell::marshall_from_haskell_var,
2023-04-16 00:07:08 +00:00
to_haskell::{marshall_to_haskell_var, marshall_to_haskell_fixed},
FromHaskell, HaskellSize, ToHaskell
};
use zcash_address::{
Network,
2023-04-27 14:48:11 +00:00
unified::{Address, Encoding, Ufvk, Container, Fvk},
2023-04-18 18:58:21 +00:00
ZcashAddress
2023-04-16 00:07:08 +00:00
};
2023-04-27 14:48:11 +00:00
use bech32::{
decode,
u5
};
2023-04-16 00:07:08 +00:00
pub enum RW {}
pub const RW: PhantomData<RW> = PhantomData;
2023-04-27 14:48:11 +00:00
#[derive(BorshSerialize, BorshDeserialize)]
pub struct RawData {
hrp: Vec<u8>,
bytes: Vec<u8>
}
impl<RW> ToHaskell<RW> for RawData {
fn to_haskell<W: Write>(&self, writer: &mut W, _tag: PhantomData<RW>) -> Result<()> {
self.serialize(writer)?;
Ok(())
}
}
//impl<RW> FromHaskell<RW> for RawData {
//fn from_haskell(buf: &mut &[u8], _tag: PhantomData<RW>) -> Result<Self> {
//let x = RawData::deserialize(buf)?;
//Ok(x)
//}
//}
#[derive(BorshSerialize, BorshDeserialize)]
pub struct Hufvk {
net: u8,
orchard: Vec<u8>,
sapling: Vec<u8>,
transparent: Vec<u8>
}
impl<RW> ToHaskell<RW> for Hufvk {
fn to_haskell<W: Write>(&self, writer: &mut W, _tag: PhantomData<RW>) -> Result<()> {
self.serialize(writer)?;
Ok(())
}
}
impl Hufvk {
fn add_key_section(&mut self, fvk: &Fvk) {
if let Fvk::Orchard(v) = fvk {
self.orchard = v.to_vec();
}
if let Fvk::Sapling(w) = fvk {
self.sapling = w.to_vec();
}
if let Fvk::P2pkh(x) = fvk {
self.transparent = x.to_vec();
}
}
}
2023-04-16 00:07:08 +00:00
#[no_mangle]
pub extern "C" fn rust_wrapper_f4jumble(
input: *const u8,
input_len: usize,
out: *mut u8,
out_len: &mut usize) {
let input: Vec<u8> = marshall_from_haskell_var(input, input_len, RW);
let result = f4jumble::f4jumble(&input).unwrap();
marshall_to_haskell_var(&result, out, out_len, RW);
}
2023-04-27 14:48:11 +00:00
#[no_mangle]
pub extern "C" fn rust_wrapper_f4unjumble(
input: *const u8,
input_len: usize,
out: *mut u8,
out_len: &mut usize) {
let input: Vec<u8> = marshall_from_haskell_var(input, input_len, RW);
let result = f4jumble::f4jumble_inv(&input).unwrap();
marshall_to_haskell_var(&result, out, out_len, RW);
}
2023-04-16 00:07:08 +00:00
#[no_mangle]
pub extern "C" fn rust_wrapper_ua_decode(
input: *const u8,
input_len: usize,) -> bool {
let input: String = marshall_from_haskell_var(input, input_len, RW);
Address::decode(&input).is_ok()
//marshall_to_haskell_var(&result, out, out_len, RW);
}
2023-04-18 18:58:21 +00:00
#[no_mangle]
pub extern "C" fn rust_wrapper_shielded_decode(
input: *const u8,
input_len: usize) -> bool {
let input: String = marshall_from_haskell_var(input, input_len, RW);
ZcashAddress::try_from_encoded(&input).is_ok()
}
2023-04-27 14:48:11 +00:00
#[no_mangle]
pub extern "C" fn rust_wrapper_bech32decode(
input: *const u8,
input_len: usize,
out: *mut u8,
out_len: &mut usize
) {
let input: String = marshall_from_haskell_var(input, input_len, RW);
let (hrp, bytes) = bech32::decode_without_checksum(&input).unwrap();
let rd = RawData {hrp: hrp.into(), bytes: bytes.iter().map(|&x| bech32::u5::to_u8(x)).collect()};
marshall_to_haskell_var(&rd, out, out_len, RW);
}
#[no_mangle]
pub extern "C" fn rust_wrapper_ufvk_decode(
input: *const u8,
input_len: usize,
out: *mut u8,
out_len: &mut usize
) {
let input: String = marshall_from_haskell_var(input, input_len, RW);
let (n, ufvk) = Ufvk::decode(&input).unwrap();
let x = match n {
Network::Main => 1,
Network::Test => 2,
Network::Regtest => 3
};
let mut hk = Hufvk { net: x, orchard: vec![0], sapling: vec![0], transparent: vec![0] };
let fvks = ufvk.items();
fvks.iter().for_each(|k| hk.add_key_section(k));
marshall_to_haskell_var(&hk, out, out_len, RW);
}