Return sapling fvk in Backup

This commit is contained in:
Hanh 2023-02-28 18:55:46 +10:00
parent aa48257fab
commit 5f48766883
4 changed files with 313 additions and 45 deletions

View File

@ -34,6 +34,12 @@ typedef struct CResult_u32 {
uint32_t len;
} CResult_u32;
typedef struct CResult______u8 {
const uint8_t *value;
char *error;
uint32_t len;
} CResult______u8;
typedef struct CResult_____c_char {
char *value;
char *error;
@ -46,12 +52,6 @@ typedef struct CResult_u64 {
uint32_t len;
} CResult_u64;
typedef struct CResult______u8 {
const uint8_t *value;
char *error;
uint32_t len;
} CResult______u8;
#define Account_VT_ID 4
#define Account_VT_NAME 6
@ -138,6 +138,14 @@ typedef struct CResult______u8 {
#define AddressBalance_VT_INDEX 4
#define Backup_VT_SEED 6
#define Backup_VT_SK 10
#define Backup_VT_FVK 12
#define Backup_VT_UVK 14
void dummy_export(void);
void dart_post_cobject(DartPostCObjectFnType ptr);
@ -170,7 +178,7 @@ void new_sub_account(char *name, int32_t index, uint32_t count);
struct CResult_u8 convert_to_watchonly(uint8_t coin, uint32_t id_account);
struct CResult_____c_char get_backup(uint8_t coin, uint32_t id_account);
struct CResult______u8 get_backup(uint8_t coin, uint32_t id_account);
struct CResult_____c_char get_address(uint8_t coin, uint32_t id_account, uint8_t ua_type);

View File

@ -4,7 +4,8 @@
use crate::coinconfig::CoinConfig;
use crate::db::data_generated::fb::{
AddressBalance, AddressBalanceArgs, AddressBalanceVec, AddressBalanceVecArgs,
AddressBalance, AddressBalanceArgs, AddressBalanceVec, AddressBalanceVecArgs, Backup,
BackupArgs,
};
use crate::db::AccountData;
use crate::key2::decode_key;
@ -119,7 +120,8 @@ pub fn convert_to_watchonly(coin: u8, id_account: u32) -> anyhow::Result<()> {
Ok(())
}
pub fn get_backup_package(coin: u8, id_account: u32) -> anyhow::Result<Backup> {
pub fn get_backup_package(coin: u8, id_account: u32) -> anyhow::Result<Vec<u8>> {
let mut builder = flatbuffers::FlatBufferBuilder::new();
let c = CoinConfig::get(coin);
let network = c.chain.network();
let db = c.db()?;
@ -131,29 +133,36 @@ pub fn get_backup_package(coin: u8, id_account: u32) -> anyhow::Result<Backup> {
aindex,
..
} = db.get_account_info(id_account)?;
let name = builder.create_string(&name);
let seed = seed.map(|seed| builder.create_string(&seed));
let sk = sk.map(|sk| builder.create_string(&sk));
let orchard_keys = db.get_orchard(id_account)?;
let fvk = match orchard_keys {
None => fvk,
Some(OrchardKeyBytes { fvk: ofvk, .. }) => {
// orchard sk is not serializable and must derived from seed
let sapling_efvk = decode_extended_full_viewing_key(
network.hrp_sapling_extended_full_viewing_key(),
&fvk,
)
.unwrap();
let sapling_dfvk = sapling_efvk.to_diversifiable_full_viewing_key();
let orchard_fvk = orchard::keys::FullViewingKey::from_bytes(&ofvk);
let ufvk = UnifiedFullViewingKey::new(Some(sapling_dfvk), orchard_fvk).unwrap();
ufvk.encode(network)
}
};
Ok(Backup {
name,
seed,
index: aindex,
sk,
ivk: fvk,
})
let uvk = orchard_keys.map(|OrchardKeyBytes { fvk: ofvk, .. }| {
// orchard sk is not serializable and must derived from seed
let sapling_efvk =
decode_extended_full_viewing_key(network.hrp_sapling_extended_full_viewing_key(), &fvk)
.unwrap();
let sapling_dfvk = sapling_efvk.to_diversifiable_full_viewing_key();
let orchard_fvk = orchard::keys::FullViewingKey::from_bytes(&ofvk);
let ufvk = UnifiedFullViewingKey::new(Some(sapling_dfvk), orchard_fvk).unwrap();
let ufvk = ufvk.encode(network);
builder.create_string(&ufvk)
});
let fvk = builder.create_string(&fvk);
let backup = Backup::create(
&mut builder,
&BackupArgs {
name: Some(name),
seed,
index: aindex,
sk,
fvk: Some(fvk),
uvk,
},
);
builder.finish(backup, None);
let data = builder.finished_data().to_vec();
Ok(data)
}
/// Update the transparent secret key for the given account from a derivation path
@ -440,12 +449,3 @@ pub fn decode_unified_address(coin: u8, address: &str) -> anyhow::Result<String>
let res = crate::decode_unified_address(c.chain.network(), address)?;
Ok(res.to_string())
}
#[derive(Serialize)]
pub struct Backup {
name: String,
seed: Option<String>,
index: u32,
sk: Option<String>,
ivk: String,
}

View File

@ -236,14 +236,13 @@ pub unsafe extern "C" fn convert_to_watchonly(coin: u8, id_account: u32) -> CRes
}
#[no_mangle]
pub unsafe extern "C" fn get_backup(coin: u8, id_account: u32) -> CResult<*mut c_char> {
pub unsafe extern "C" fn get_backup(coin: u8, id_account: u32) -> CResult<*const u8> {
let res = || {
let backup = crate::api::account::get_backup_package(coin, id_account)?;
let backup_str = serde_json::to_string(&backup)?;
Ok::<_, anyhow::Error>(backup_str)
let backup_bytes = crate::api::account::get_backup_package(coin, id_account)?;
Ok::<_, anyhow::Error>(backup_bytes)
};
to_cresult_str(res())
to_cresult_bytes(res())
}
#[no_mangle]

View File

@ -4438,5 +4438,266 @@ impl CheckpointVecT {
})
}
}
pub enum BackupOffset {}
#[derive(Copy, Clone, PartialEq)]
pub struct Backup<'a> {
pub _tab: flatbuffers::Table<'a>,
}
impl<'a> flatbuffers::Follow<'a> for Backup<'a> {
type Inner = Backup<'a>;
#[inline]
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
Self { _tab: flatbuffers::Table::new(buf, loc) }
}
}
impl<'a> Backup<'a> {
pub const VT_NAME: flatbuffers::VOffsetT = 4;
pub const VT_SEED: flatbuffers::VOffsetT = 6;
pub const VT_INDEX: flatbuffers::VOffsetT = 8;
pub const VT_SK: flatbuffers::VOffsetT = 10;
pub const VT_FVK: flatbuffers::VOffsetT = 12;
pub const VT_UVK: flatbuffers::VOffsetT = 14;
#[inline]
pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self {
Backup { _tab: table }
}
#[allow(unused_mut)]
pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>(
_fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>,
args: &'args BackupArgs<'args>
) -> flatbuffers::WIPOffset<Backup<'bldr>> {
let mut builder = BackupBuilder::new(_fbb);
if let Some(x) = args.uvk { builder.add_uvk(x); }
if let Some(x) = args.fvk { builder.add_fvk(x); }
if let Some(x) = args.sk { builder.add_sk(x); }
builder.add_index(args.index);
if let Some(x) = args.seed { builder.add_seed(x); }
if let Some(x) = args.name { builder.add_name(x); }
builder.finish()
}
pub fn unpack(&self) -> BackupT {
let name = self.name().map(|x| {
x.to_string()
});
let seed = self.seed().map(|x| {
x.to_string()
});
let index = self.index();
let sk = self.sk().map(|x| {
x.to_string()
});
let fvk = self.fvk().map(|x| {
x.to_string()
});
let uvk = self.uvk().map(|x| {
x.to_string()
});
BackupT {
name,
seed,
index,
sk,
fvk,
uvk,
}
}
#[inline]
pub fn name(&self) -> Option<&'a str> {
// Safety:
// Created from valid Table for this object
// which contains a valid value in this slot
unsafe { self._tab.get::<flatbuffers::ForwardsUOffset<&str>>(Backup::VT_NAME, None)}
}
#[inline]
pub fn seed(&self) -> Option<&'a str> {
// Safety:
// Created from valid Table for this object
// which contains a valid value in this slot
unsafe { self._tab.get::<flatbuffers::ForwardsUOffset<&str>>(Backup::VT_SEED, None)}
}
#[inline]
pub fn index(&self) -> u32 {
// Safety:
// Created from valid Table for this object
// which contains a valid value in this slot
unsafe { self._tab.get::<u32>(Backup::VT_INDEX, Some(0)).unwrap()}
}
#[inline]
pub fn sk(&self) -> Option<&'a str> {
// Safety:
// Created from valid Table for this object
// which contains a valid value in this slot
unsafe { self._tab.get::<flatbuffers::ForwardsUOffset<&str>>(Backup::VT_SK, None)}
}
#[inline]
pub fn fvk(&self) -> Option<&'a str> {
// Safety:
// Created from valid Table for this object
// which contains a valid value in this slot
unsafe { self._tab.get::<flatbuffers::ForwardsUOffset<&str>>(Backup::VT_FVK, None)}
}
#[inline]
pub fn uvk(&self) -> Option<&'a str> {
// Safety:
// Created from valid Table for this object
// which contains a valid value in this slot
unsafe { self._tab.get::<flatbuffers::ForwardsUOffset<&str>>(Backup::VT_UVK, None)}
}
}
impl flatbuffers::Verifiable for Backup<'_> {
#[inline]
fn run_verifier(
v: &mut flatbuffers::Verifier, pos: usize
) -> Result<(), flatbuffers::InvalidFlatbuffer> {
use self::flatbuffers::Verifiable;
v.visit_table(pos)?
.visit_field::<flatbuffers::ForwardsUOffset<&str>>("name", Self::VT_NAME, false)?
.visit_field::<flatbuffers::ForwardsUOffset<&str>>("seed", Self::VT_SEED, false)?
.visit_field::<u32>("index", Self::VT_INDEX, false)?
.visit_field::<flatbuffers::ForwardsUOffset<&str>>("sk", Self::VT_SK, false)?
.visit_field::<flatbuffers::ForwardsUOffset<&str>>("fvk", Self::VT_FVK, false)?
.visit_field::<flatbuffers::ForwardsUOffset<&str>>("uvk", Self::VT_UVK, false)?
.finish();
Ok(())
}
}
pub struct BackupArgs<'a> {
pub name: Option<flatbuffers::WIPOffset<&'a str>>,
pub seed: Option<flatbuffers::WIPOffset<&'a str>>,
pub index: u32,
pub sk: Option<flatbuffers::WIPOffset<&'a str>>,
pub fvk: Option<flatbuffers::WIPOffset<&'a str>>,
pub uvk: Option<flatbuffers::WIPOffset<&'a str>>,
}
impl<'a> Default for BackupArgs<'a> {
#[inline]
fn default() -> Self {
BackupArgs {
name: None,
seed: None,
index: 0,
sk: None,
fvk: None,
uvk: None,
}
}
}
pub struct BackupBuilder<'a: 'b, 'b> {
fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>,
start_: flatbuffers::WIPOffset<flatbuffers::TableUnfinishedWIPOffset>,
}
impl<'a: 'b, 'b> BackupBuilder<'a, 'b> {
#[inline]
pub fn add_name(&mut self, name: flatbuffers::WIPOffset<&'b str>) {
self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(Backup::VT_NAME, name);
}
#[inline]
pub fn add_seed(&mut self, seed: flatbuffers::WIPOffset<&'b str>) {
self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(Backup::VT_SEED, seed);
}
#[inline]
pub fn add_index(&mut self, index: u32) {
self.fbb_.push_slot::<u32>(Backup::VT_INDEX, index, 0);
}
#[inline]
pub fn add_sk(&mut self, sk: flatbuffers::WIPOffset<&'b str>) {
self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(Backup::VT_SK, sk);
}
#[inline]
pub fn add_fvk(&mut self, fvk: flatbuffers::WIPOffset<&'b str>) {
self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(Backup::VT_FVK, fvk);
}
#[inline]
pub fn add_uvk(&mut self, uvk: flatbuffers::WIPOffset<&'b str>) {
self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(Backup::VT_UVK, uvk);
}
#[inline]
pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> BackupBuilder<'a, 'b> {
let start = _fbb.start_table();
BackupBuilder {
fbb_: _fbb,
start_: start,
}
}
#[inline]
pub fn finish(self) -> flatbuffers::WIPOffset<Backup<'a>> {
let o = self.fbb_.end_table(self.start_);
flatbuffers::WIPOffset::new(o.value())
}
}
impl core::fmt::Debug for Backup<'_> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let mut ds = f.debug_struct("Backup");
ds.field("name", &self.name());
ds.field("seed", &self.seed());
ds.field("index", &self.index());
ds.field("sk", &self.sk());
ds.field("fvk", &self.fvk());
ds.field("uvk", &self.uvk());
ds.finish()
}
}
#[non_exhaustive]
#[derive(Debug, Clone, PartialEq)]
pub struct BackupT {
pub name: Option<String>,
pub seed: Option<String>,
pub index: u32,
pub sk: Option<String>,
pub fvk: Option<String>,
pub uvk: Option<String>,
}
impl Default for BackupT {
fn default() -> Self {
Self {
name: None,
seed: None,
index: 0,
sk: None,
fvk: None,
uvk: None,
}
}
}
impl BackupT {
pub fn pack<'b>(
&self,
_fbb: &mut flatbuffers::FlatBufferBuilder<'b>
) -> flatbuffers::WIPOffset<Backup<'b>> {
let name = self.name.as_ref().map(|x|{
_fbb.create_string(x)
});
let seed = self.seed.as_ref().map(|x|{
_fbb.create_string(x)
});
let index = self.index;
let sk = self.sk.as_ref().map(|x|{
_fbb.create_string(x)
});
let fvk = self.fvk.as_ref().map(|x|{
_fbb.create_string(x)
});
let uvk = self.uvk.as_ref().map(|x|{
_fbb.create_string(x)
});
Backup::create(_fbb, &BackupArgs{
name,
seed,
index,
sk,
fvk,
uvk,
})
}
}
} // pub mod fb