Skip to content
Draft
Show file tree
Hide file tree
Changes from 38 commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
637b44b
hmm
fluidvanadium Oct 3, 2025
c07de6f
implemented protocol version
fluidvanadium Oct 3, 2025
5b2380a
began impl add_server
fluidvanadium Oct 3, 2025
0fff891
impling add_server
fluidvanadium Oct 7, 2025
07560b9
building a LightClient
fluidvanadium Oct 7, 2025
9caba82
implementing
fluidvanadium Oct 8, 2025
bfb8a08
progress
fluidvanadium Oct 8, 2025
ac87e61
Merge branch 'ervar_chain_from_string' into zingo_wallet
fluidvanadium Oct 8, 2025
e238e8f
use birthday from server
fluidvanadium Oct 8, 2025
2cdad13
Merge remote-tracking branch 'labs/dev' into zingo_wallet
fluidvanadium Oct 8, 2025
27aa034
added common components dep
fluidvanadium Oct 8, 2025
70da31f
merged some good stuff
fluidvanadium Oct 10, 2025
dabbe56
Includes git history from extract_scenarios
fluidvanadium Oct 10, 2025
455534e
Merge remote-tracking branch 'labs/dev' into zingo_wallet
fluidvanadium Oct 29, 2025
a4344a1
Fixed manifest.
fluidvanadium Oct 29, 2025
58f146b
Used try_into for lrz BlockHeight.
fluidvanadium Oct 29, 2025
084016d
Compiles good.
fluidvanadium Oct 29, 2025
a3abe35
Merge remote-tracking branch 'labs/dev' into zingo_wallet
fluidvanadium Oct 29, 2025
007189f
Add zingo_wallet tests.
fluidvanadium Oct 29, 2025
c35b84c
Implements add_key.
fluidvanadium Oct 30, 2025
c6e92c4
cargo clippy --fix --tests --all-features
fluidvanadium Oct 30, 2025
54ed4f3
Install ring crypto provider.
fluidvanadium Oct 30, 2025
2cab819
Fixed an error in create_connect_get_height.
fluidvanadium Oct 30, 2025
d78a99a
Removed main function.
fluidvanadium Oct 30, 2025
1caaaad
user_agent_id written better.
fluidvanadium Oct 30, 2025
e2de5e3
cargo update
fluidvanadium Oct 30, 2025
e7b7780
Upgrade deps.
fluidvanadium Oct 30, 2025
7ee15f6
Merge remote-tracking branch 'labs/dev' into zingo_wallet
fluidvanadium Nov 9, 2025
fdcfe37
Wallet creation uses temporary save dir.
fluidvanadium Nov 9, 2025
dd4c8e8
Minimum test.
fluidvanadium Nov 9, 2025
5ed3c6d
Split into second test for scanning from server.
fluidvanadium Nov 9, 2025
6af65f2
Merge branch 'cargo_update_2' into zingo_wallet
fluidvanadium Nov 9, 2025
587a62e
`cargo update`
fluidvanadium Nov 9, 2025
37d8489
Added test groups.
fluidvanadium Nov 9, 2025
d40bb1d
Tests run!
fluidvanadium Nov 9, 2025
2c5d4ae
Moved init_tracing into a common module.
fluidvanadium Nov 9, 2025
b458256
test-log crate attribute replaces bespoke tracing initializer.
fluidvanadium Nov 10, 2025
30256ee
Use online zcash_wallet_interface dependency.
fluidvanadium Nov 10, 2025
69776f3
Merge dev
fluidvanadium Nov 24, 2025
0630319
Updated lockfile.
fluidvanadium Dec 8, 2025
3a69b31
Remove test_group and respecify test names.
fluidvanadium Dec 8, 2025
4036661
Rename test binary.
fluidvanadium Dec 8, 2025
80be91f
helperizing
fluidvanadium Dec 8, 2025
705c907
clippy
fluidvanadium Dec 8, 2025
7437678
merged dev
fluidvanadium Jan 15, 2026
7464cb8
Fixed zingo-netutils dep.
fluidvanadium Jan 15, 2026
a5ed051
Renamed test Environments for consistency.
fluidvanadium Jan 15, 2026
7a0c455
begin_scanning_server reflects what a zingo_wallet is meant to do wit…
fluidvanadium Jan 15, 2026
7b12ecf
polishing tests
fluidvanadium Jan 16, 2026
d6ca1ea
Fixed max_scanned_height...
fluidvanadium Jan 16, 2026
152e07b
More benchmarks.
fluidvanadium Jan 16, 2026
76cc285
Merge remote-tracking branch 'labs/dev' into zingo_wallet
fluidvanadium Jan 16, 2026
1a0a3f4
cargo fmt
fluidvanadium Jan 16, 2026
64b1476
cargo clippy --fix --tests --all-features
fluidvanadium Jan 16, 2026
4bdaf3d
trailing whitespace clipper
fluidvanadium Jan 16, 2026
ef3baef
cargo fmt
fluidvanadium Jan 16, 2026
4076e86
Fixed warnings.
fluidvanadium Jan 16, 2026
675d544
syncked glory_goddess
fluidvanadium Jan 16, 2026
fd2be7a
Merge commit 'f99e25f' into synced_glory_goddess
fluidvanadium Jan 16, 2026
bcf585f
cargo run -- --data-dir='zingolib/src/wallet/disk/testing/examples/te…
fluidvanadium Jan 16, 2026
9199736
Merge remote-tracking branch 'labs/dev' into synced_glory_goddess
fluidvanadium Jan 16, 2026
e42ad63
cargo run -- --data-dir='zingolib/src/wallet/disk/testing/examples/te…
fluidvanadium Jan 16, 2026
5144bb7
Very strange bug occurred. The address of the glory goddess Testnet w…
fluidvanadium Jan 16, 2026
f3675a9
Sort/merge Cargo.toml
fluidvanadium Feb 17, 2026
6507cd3
Apply suggestions from code review
fluidvanadium Feb 17, 2026
93ac585
Merge branch 'dev' into zingo_wallet
zancas Feb 18, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 87 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 7 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ members = [
"zingolib",
"zingo-memo",
"pepper-sync",
"zingo-price", "zingolib_testutils",
"zingo-price",
"zingolib_testutils",
"zingo_wallet",
]
resolver = "2"

Expand Down Expand Up @@ -116,6 +118,10 @@ zingo-status = { path = "zingo-status" }
pepper-sync = { path = "pepper-sync" }
zingolib = { path = "zingolib" }

# Test Attributes
test-log = "0.2"
test-group = "1.0.1"

[patch.crates-io]
zcash_client_backend = { git = "https://github.com/zcash/librustzcash", rev = "3ba772c9b8"}
zcash_address = { git = "https://github.com/zcash/librustzcash", rev = "3ba772c9b8"}
Expand Down
32 changes: 32 additions & 0 deletions zingo_wallet/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
[package]
name = "zingo_wallet"
version = "0.1.0"
edition = "2024"

[dependencies]
zingolib = { workspace = true }
pepper-sync.workspace = true

zcash_wallet_interface = { git = "https://github.com/zingolabs/zcash_wallet_interface.git", branch = "dev" }

zingo_netutils.workspace = true
zingo_common_components.workspace = true

bip0039.workspace = true
zcash_client_backend.workspace = true
zcash_primitives.workspace = true

tonic.workspace = true
http.workspace = true
rustls.workspace = true
tempfile.workspace = true

thiserror.workspace = true
tracing.workspace = true
tracing-subscriber.workspace = true

[dev-dependencies]
tokio.workspace = true
zingo_test_vectors = { git = "https://github.com/zingolabs/infrastructure.git", branch = "dev" }
test-group.workspace = true
test-log.workspace = true
202 changes: 202 additions & 0 deletions zingo_wallet/src/interface.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
use http::Uri;
use zcash_wallet_interface::BlockHeight;

use crate::ZingoWallet;

#[derive(thiserror::Error, Debug)]
pub enum AddServerError {
#[error(
"Zingo currently can only connect to a lightwallet if it has exactly one key. Try calling add_key."
)]
NeedsSingleSeed,
#[error("URI parse from string '{0}' failed with >{1}<.")]
ParseUri(String, http::uri::InvalidUri),
#[error("Creating network-client connected to '{0}' failed with >{1}<.")]
CreateNetworkClient(Uri, zingo_netutils::GetClientError),
#[error("Server call returned unexpected result: >{0}<.")]
Callback(#[from] tonic::Status),
#[error("Server reported unusable chain: >{0}<.")]
Chain(#[from] zingolib::config::ChainFromStringError),
#[error("Server reported overflow block height: >{0}<.")]
BlockHeight(#[from] std::num::TryFromIntError),
#[error("Seed parse from string '{0}' failed with >{1}<.")]
ParseSeed(String, bip0039::Error),
#[error("Wallet creation failed with >{0}<.")]
CreateLightWallet(#[from] zingolib::wallet::error::WalletError),
#[error("Temporary data dir creation failed with >{0}<.")]
CreateDataDir(#[from] std::io::Error),
#[error("Wallet creation failed with >{0}<.")]
CreateLightClient(#[from] zingolib::lightclient::error::LightClientError),
#[error("Wallet creation failed with >{0}<.")]
StartSync(zingolib::lightclient::error::LightClientError),
}

#[derive(thiserror::Error, Debug)]
pub enum GetMaxScannedHeightError {
#[error("Todo")]
NoServer, //TODO
#[error("Todo")]
NoHeightFoundForServer, //TODO
#[error("Todo")]
WalletError(zingolib::wallet::error::WalletError),
}

#[derive(thiserror::Error, Debug)]
pub enum AddKeyError {
#[error("Todo")]
AlreadyHasKey, //TODO
}

impl zcash_wallet_interface::Wallet for ZingoWallet {
fn user_agent_id() -> zcash_wallet_interface::UserAgentId {
const PARADIGM: &str = "zingo_wallet";
const VERSION: &str = "0.0.1";

zcash_wallet_interface::UserAgentId {
paradigm: PARADIGM.to_string(),
version: VERSION.to_string(),
}
}

async fn new_wallet() -> Self {
// we cannot instantiate the current version of the `LightClient` yet
// without assumptions about keys and servers
// which would violate principles of the interface
// so we dont
ZingoWallet {
keys: Vec::new(),
lightclient: None,
}
}

type AddServerError = AddServerError;

async fn add_server(&mut self, server_address: String) -> Result<(), Self::AddServerError> {
use std::num::NonZeroU32;

use std::str::FromStr as _;

use zingolib::config::ChainType;
use zingolib::config::SyncConfig;
use zingolib::config::TransparentAddressDiscovery;

use zingolib::config::ZingoConfigBuilder;
use zingolib::config::chain_from_str;
use zingolib::lightclient::LightClient;
use zingolib::wallet::LightWallet;
use zingolib::wallet::WalletSettings;
if self.keys.len() == 1
&& let Some(key) = self.keys.first()
{
let server_uri = Uri::from_str(server_address.as_str())
.map_err(|invalid_uri| AddServerError::ParseUri(server_address, invalid_uri))?;

let (chain_type, birthday) = {
// we need to ask the indexer for this information

let mut client = {
// global configuration must be manually set *somewhere*
rustls::crypto::ring::default_provider().install_default();

Check failure on line 99 in zingo_wallet/src/interface.rs

View workflow job for this annotation

GitHub Actions / Cargo Hack Check

unused `Result` that must be used

Check failure on line 99 in zingo_wallet/src/interface.rs

View workflow job for this annotation

GitHub Actions / cargo-checkmate / Cargo Checkmate (build)

unused `Result` that must be used

Check failure on line 99 in zingo_wallet/src/interface.rs

View workflow job for this annotation

GitHub Actions / cargo-checkmate / Cargo Checkmate (clippy)

unused `std::result::Result` that must be used

Check failure on line 99 in zingo_wallet/src/interface.rs

View workflow job for this annotation

GitHub Actions / cargo-checkmate / Cargo Checkmate (check)

unused `Result` that must be used

Check failure on line 99 in zingo_wallet/src/interface.rs

View workflow job for this annotation

GitHub Actions / Run doc tests

unused `Result` that must be used

Check failure on line 99 in zingo_wallet/src/interface.rs

View workflow job for this annotation

GitHub Actions / Cargo Hack Check

unused `Result` that must be used

Check failure on line 99 in zingo_wallet/src/interface.rs

View workflow job for this annotation

GitHub Actions / cargo-checkmate / Cargo Checkmate (build)

unused `Result` that must be used

Check failure on line 99 in zingo_wallet/src/interface.rs

View workflow job for this annotation

GitHub Actions / cargo-checkmate / Cargo Checkmate (clippy)

unused `std::result::Result` that must be used

Check failure on line 99 in zingo_wallet/src/interface.rs

View workflow job for this annotation

GitHub Actions / test / Build test artifacts

unused `Result` that must be used

Check failure on line 99 in zingo_wallet/src/interface.rs

View workflow job for this annotation

GitHub Actions / cargo-checkmate / Cargo Checkmate (check)

unused `Result` that must be used
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where should this be called? Why?

Is this called on the last possible line before use?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm referring to the previous line of code.

zingolib::grpc_client::get_zcb_client(server_uri.clone())
.await
.map_err(|e| AddServerError::CreateNetworkClient(server_uri.clone(), e))?
};

let lightd_info = client
.get_lightd_info(tonic::Request::new(
zcash_client_backend::proto::service::Empty {},
))
.await?
.into_inner();

let chain_name = &lightd_info.chain_name;
let chain_type: ChainType = chain_from_str(chain_name)?;

let birthday: zcash_primitives::consensus::BlockHeight =
lightd_info.block_height.try_into()?;
(chain_type, birthday)
};

// this seems like a lot of set up. Do we really need all this right here??
let no_of_accounts = NonZeroU32::try_from(1).expect("hard-coded integer"); // seems like this should default. Also why are we stringing it in in two places??

let wallet_base = zingolib::wallet::WalletBase::Mnemonic {
mnemonic: bip0039::Mnemonic::from_phrase(key)
.map_err(|e| AddServerError::ParseSeed(key.clone(), e))?,
no_of_accounts,
};

let wallet_settings = WalletSettings {
sync_config: SyncConfig {
transparent_address_discovery: TransparentAddressDiscovery::minimal(),
performance_level: pepper_sync::config::PerformanceLevel::High,
},
min_confirmations: NonZeroU32::try_from(1).expect("1 aint 0"),
}; // maybe this could be defaulted
let wallet =
LightWallet::new(chain_type, wallet_base, birthday, wallet_settings.clone())
.map_err(AddServerError::CreateLightWallet)?;
// ZingoConfig allows a save-director of None, but crashes if that value is used.
let save_dir = tempfile::TempDir::new()?;
let config = {
ZingoConfigBuilder::default()
.set_lightwalletd_uri(server_uri)
.set_wallet_settings(wallet_settings)
.set_no_of_accounts(no_of_accounts)
.set_wallet_dir(save_dir.path().to_path_buf())
.create()
};
let overwrite = false;
let mut lightclient = LightClient::create_from_wallet(wallet, config, overwrite)?;
lightclient
.sync()
.await
.map_err(AddServerError::StartSync)?;
self.lightclient = Some(lightclient);
Ok(())
} else {
Err(AddServerError::NeedsSingleSeed)
}
}

type AddKeyError = AddKeyError;

async fn add_key(&mut self, key_string: String) -> Result<(), Self::AddKeyError> {
if self.keys.is_empty() {
self.keys.push(key_string);
Ok(())
} else {
Err(AddKeyError::AlreadyHasKey)
}
}

type GetMaxScannedHeightError = GetMaxScannedHeightError;

async fn get_max_scanned_height_for_server(
&mut self,
_server: String,
) -> Result<zcash_wallet_interface::BlockHeight, Self::GetMaxScannedHeightError> {
use zcash_client_backend::data_api::WalletRead;

match &self.lightclient {
Some(client) => Ok(client
.wallet
.read()
.await
.chain_height()
.map_err(GetMaxScannedHeightError::WalletError)?
.map(|h| zcash_wallet_interface::BlockHeight(h.into()))
.unwrap_or(BlockHeight(0))),
None => Err(GetMaxScannedHeightError::NoServer),
}
}

type PayError = ();

async fn pay(
&mut self,
payments: Vec<zcash_wallet_interface::Payment>,

Check failure on line 198 in zingo_wallet/src/interface.rs

View workflow job for this annotation

GitHub Actions / Cargo Hack Check

unused variable: `payments`

Check failure on line 198 in zingo_wallet/src/interface.rs

View workflow job for this annotation

GitHub Actions / cargo-checkmate / Cargo Checkmate (build)

unused variable: `payments`

Check failure on line 198 in zingo_wallet/src/interface.rs

View workflow job for this annotation

GitHub Actions / cargo-checkmate / Cargo Checkmate (clippy)

unused variable: `payments`

Check failure on line 198 in zingo_wallet/src/interface.rs

View workflow job for this annotation

GitHub Actions / cargo-checkmate / Cargo Checkmate (check)

unused variable: `payments`

Check failure on line 198 in zingo_wallet/src/interface.rs

View workflow job for this annotation

GitHub Actions / Run doc tests

unused variable: `payments`

Check failure on line 198 in zingo_wallet/src/interface.rs

View workflow job for this annotation

GitHub Actions / Cargo Hack Check

unused variable: `payments`

Check failure on line 198 in zingo_wallet/src/interface.rs

View workflow job for this annotation

GitHub Actions / cargo-checkmate / Cargo Checkmate (build)

unused variable: `payments`

Check failure on line 198 in zingo_wallet/src/interface.rs

View workflow job for this annotation

GitHub Actions / cargo-checkmate / Cargo Checkmate (clippy)

unused variable: `payments`

Check failure on line 198 in zingo_wallet/src/interface.rs

View workflow job for this annotation

GitHub Actions / test / Build test artifacts

unused variable: `payments`

Check failure on line 198 in zingo_wallet/src/interface.rs

View workflow job for this annotation

GitHub Actions / cargo-checkmate / Cargo Checkmate (check)

unused variable: `payments`
) -> Result<(), Self::PayError> {
todo!()
}
}
6 changes: 6 additions & 0 deletions zingo_wallet/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
pub mod interface;

pub struct ZingoWallet {
keys: Vec<String>, //todo parsing and keyring
lightclient: Option<zingolib::lightclient::LightClient>,
}
1 change: 1 addition & 0 deletions zingo_wallet/tests/common/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
//! A mod that will include common stuff to tests. Once they exist.
Loading
Loading