Skip to content

Commit

Permalink
Move ReadWrite trait to helium-lib
Browse files Browse the repository at this point in the history
You can directly read a helium_lib::Keypair from a file that is a solana keypair.
  • Loading branch information
michaeldjeffrey committed Oct 22, 2024
1 parent 897f4e9 commit e47dd51
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 28 deletions.
14 changes: 7 additions & 7 deletions helium-lib/src/keypair.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use crate::{
error::{DecodeError, Error},
read_write::ReadWrite,
solana_sdk::signature::SignerError,
};
use std::sync::Arc;
use std::{fs::File, path::Path, sync::Arc};

#[derive(PartialEq, Debug)]
pub struct Keypair(solana_sdk::signer::keypair::Keypair);
Expand Down Expand Up @@ -99,17 +100,16 @@ impl TryFrom<&[u8; 64]> for Keypair {
}
}

impl From<solana_sdk::signer::keypair::Keypair> for Keypair {
fn from(keypair: solana_sdk::signer::keypair::Keypair) -> Self {
Self(keypair)
}
}

impl Keypair {
pub fn generate() -> Self {
Keypair(solana_sdk::signer::keypair::Keypair::new())
}

pub fn read_from_file<F: AsRef<Path>>(path: F) -> Result<Self, DecodeError> {
let mut file = File::open(path.as_ref())?;
Self::read(&mut file)
}

pub fn void() -> Arc<VoidKeypair> {
Arc::new(VoidKeypair)
}
Expand Down
1 change: 1 addition & 0 deletions helium-lib/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ pub mod kta;
pub mod onboarding;
pub mod priority_fee;
pub mod programs;
pub mod read_write;
pub mod reward;
pub mod token;

Expand Down
33 changes: 18 additions & 15 deletions helium-wallet/src/read_write.rs → helium-lib/src/read_write.rs
Original file line number Diff line number Diff line change
@@ -1,56 +1,59 @@
use crate::result::{bail, Result};
use helium_crypto::{ecc_compact, ed25519, multisig, KeyType};
use io::{Read, Write};
use std::io;

use crate::error::{DecodeError, EncodeError};

pub trait ReadWrite {
fn read(reader: &mut dyn Read) -> Result<Self>
fn read(reader: &mut dyn Read) -> Result<Self, DecodeError>
where
Self: std::marker::Sized;
fn write(&self, writer: &mut dyn Write) -> Result;
fn write(&self, writer: &mut dyn Write) -> Result<(), EncodeError>;
}

impl ReadWrite for helium_crypto::PublicKey {
fn write(&self, writer: &mut dyn io::Write) -> Result {
fn write(&self, writer: &mut dyn io::Write) -> Result<(), EncodeError> {
Ok(writer.write_all(&self.to_vec())?)
}

fn read(reader: &mut dyn Read) -> Result<Self> {
fn read(reader: &mut dyn Read) -> Result<Self, DecodeError> {
let mut data = vec![0u8; 1];
reader.read_exact(&mut data[0..1])?;
let key_size = match KeyType::try_from(data[0])? {
KeyType::Ed25519 => ed25519::PUBLIC_KEY_LENGTH,
KeyType::EccCompact => ecc_compact::PUBLIC_KEY_LENGTH,
KeyType::MultiSig => multisig::PUBLIC_KEY_LENGTH,
KeyType::Secp256k1 => bail!("Secp256k1 key type unsupported for read."),
KeyType::Rsa => bail!("RSA key type unsupported for read."),
KeyType::Secp256k1 => Err(DecodeError::other(
"Secp256k1 key type unsupported for read.",
))?,
KeyType::Rsa => Err(DecodeError::other("RSA key type unsupported for read."))?,
};
data.resize(key_size, 0);
reader.read_exact(&mut data[1..])?;
Ok(helium_crypto::PublicKey::from_bytes(data)?)
}
}

impl ReadWrite for helium_lib::keypair::Pubkey {
fn write(&self, writer: &mut dyn io::Write) -> Result {
impl ReadWrite for crate::keypair::Pubkey {
fn write(&self, writer: &mut dyn io::Write) -> Result<(), EncodeError> {
writer.write_all(&self.to_bytes())?;
Ok(())
}

fn read(reader: &mut dyn Read) -> Result<helium_lib::keypair::Pubkey> {
let mut data = [0u8; helium_lib::keypair::PUBKEY_BYTES];
fn read(reader: &mut dyn Read) -> Result<crate::keypair::Pubkey, DecodeError> {
let mut data = [0u8; crate::keypair::PUBKEY_BYTES];
reader.read_exact(&mut data)?;
Ok(Self::new_from_array(data))
}
}

impl ReadWrite for helium_lib::keypair::Keypair {
fn write(&self, writer: &mut dyn io::Write) -> Result {
impl ReadWrite for crate::keypair::Keypair {
fn write(&self, writer: &mut dyn io::Write) -> Result<(), EncodeError> {
writer.write_all(&self.to_bytes())?;
Ok(())
}

fn read(reader: &mut dyn io::Read) -> Result<Self> {
fn read(reader: &mut dyn io::Read) -> Result<Self, DecodeError> {
let mut sk_buf = [0u8; 64];
reader.read_exact(&mut sk_buf)?;
Ok(Self::try_from(&sk_buf)?)
Expand All @@ -60,7 +63,7 @@ impl ReadWrite for helium_lib::keypair::Keypair {
#[cfg(test)]
mod tests {
use super::*;
use helium_lib::keypair::{Keypair, Pubkey, Signer};
use crate::keypair::{Keypair, Pubkey, Signer};
use std::{io::Cursor, str::FromStr};

#[test]
Expand Down
1 change: 0 additions & 1 deletion helium-wallet/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
pub mod cmd;
pub mod format;
pub mod pwhash;
pub mod read_write;
pub mod result;
pub mod txn_envelope;
pub mod wallet;
16 changes: 11 additions & 5 deletions helium-wallet/src/wallet.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
use crate::{
format::{self, Format},
pwhash::PwHash,
read_write::ReadWrite,
result::{anyhow, bail, Error, Result},
};
use aes_gcm::{aead::generic_array::GenericArray, AeadInPlace, Aes256Gcm, KeyInit};
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
use helium_lib::keypair::{to_helium_pubkey, Keypair, Pubkey, Signer, PUBKEY_BYTES};
use helium_lib::{
keypair::{to_helium_pubkey, Keypair, Pubkey, Signer, PUBKEY_BYTES},
read_write::ReadWrite,
};
use sodiumoxide::randombytes;
use std::io::{self, Cursor};
use std::{
Expand Down Expand Up @@ -191,7 +193,9 @@ impl Wallet {
let helium_pubkey = helium_crypto::PublicKey::read(reader)?;
Pubkey::try_from(helium_pubkey).map_err(Error::from)
}
WALLET_KIND_BASIC_V3 | WALLET_KIND_SHARDED_V3 => Pubkey::read(reader),
WALLET_KIND_BASIC_V3 | WALLET_KIND_SHARDED_V3 => {
Pubkey::read(reader).map_err(anyhow::Error::from)
}
_ => bail!("Invalid wallet kind {kind}"),
}
}
Expand All @@ -205,11 +209,13 @@ impl Wallet {
| WALLET_KIND_SHARDED_V2 => {
let tag = reader.read_u8()?;
match KeyType::try_from(tag)? {
KeyType::Ed25519 => Keypair::read(reader),
KeyType::Ed25519 => Keypair::read(reader).map_err(anyhow::Error::from),
_ => bail!("Unsupported key type: {tag}"),
}
}
WALLET_KIND_BASIC_V3 | WALLET_KIND_SHARDED_V3 => Keypair::read(reader),
WALLET_KIND_BASIC_V3 | WALLET_KIND_SHARDED_V3 => {
Keypair::read(reader).map_err(anyhow::Error::from)
}
_ => bail!("Invalid wallet kind {kind}"),
}
}
Expand Down

0 comments on commit e47dd51

Please sign in to comment.