Skip to content

Commit

Permalink
feat!: fix key manager use of keys (#6407)
Browse files Browse the repository at this point in the history
Description
---
Fixes Key manager key use
Allows creating of scan only wallets that don't have access to the spend
key
Allows more than one address

Motivation and Context
---
This allows us to display interactive and one-sided address for ledger
type wallets, displaying the correct keys for use with each type.
The new wallet type also allows users to create scan only wallets that
have a private view key and not have access to the private key for
spending.

How Has This Been Tested?
---
Manual

Breaking change
---
Changes byte representation of keys which needs matching ledger wallet
version to work correctly
  • Loading branch information
SWvheerden authored Jul 17, 2024
1 parent 446a118 commit 35db898
Show file tree
Hide file tree
Showing 30 changed files with 485 additions and 523 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ impl wallet_server::Wallet for WalletGrpcServer {
async fn get_address(&self, _: Request<tari_rpc::Empty>) -> Result<Response<GetAddressResponse>, Status> {
let address = self
.wallet
.get_wallet_address()
.get_wallet_interactive_address()
.await
.map_err(|e| Status::internal(format!("{:?}", e)))?;
Ok(Response::new(GetAddressResponse {
Expand Down Expand Up @@ -662,7 +662,7 @@ impl wallet_server::Wallet for WalletGrpcServer {
.map_err(|err| Status::unknown(err.to_string()))?;
let wallet_address = self
.wallet
.get_wallet_address()
.get_wallet_interactive_address()
.await
.map_err(|e| Status::internal(format!("{:?}", e)))?;
let transactions = transactions
Expand Down
17 changes: 14 additions & 3 deletions applications/minotari_console_wallet/src/ui/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

use minotari_wallet::{util::wallet_identity::WalletIdentity, WalletConfig, WalletSqlite};
use minotari_wallet::{error::WalletError, util::wallet_identity::WalletIdentity, WalletConfig, WalletSqlite};
use tari_common::exit_codes::ExitError;
use tari_comms::peer_manager::Peer;
use tokio::runtime::Handle;
Expand Down Expand Up @@ -79,8 +79,19 @@ impl<B: Backend> App<B> {
base_node_config: PeerConfig,
notifier: Notifier,
) -> Result<Self, ExitError> {
let wallet_address = wallet.get_wallet_address().await?;
let wallet_id = WalletIdentity::new(wallet.comms.node_identity(), wallet_address);
let wallet_address_interactive = wallet
.get_wallet_interactive_address()
.await
.map_err(WalletError::KeyManagerServiceError)?;
let wallet_address_one_sided = wallet
.get_wallet_one_sided_address()
.await
.map_err(WalletError::KeyManagerServiceError)?;
let wallet_id = WalletIdentity::new(
wallet.comms.node_identity(),
wallet_address_interactive,
wallet_address_one_sided,
);
let app_state = AppState::new(
&wallet_id,
wallet,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ impl ReceiveTab {

let chunks = Layout::default()
.direction(Direction::Vertical)
.constraints([Constraint::Length(6), Constraint::Length(23)].as_ref())
.constraints([Constraint::Length(8), Constraint::Length(23)].as_ref())
.margin(1)
.split(area);

Expand All @@ -46,6 +46,8 @@ impl ReceiveTab {
Constraint::Length(1),
Constraint::Length(1),
Constraint::Length(1),
Constraint::Length(1),
Constraint::Length(1),
]
.as_ref(),
)
Expand All @@ -57,54 +59,76 @@ impl ReceiveTab {
.title(Span::styled("Connection Details", Style::default().fg(Color::White)));
f.render_widget(block, chunks[0]);

const ITEM_01: &str = "Tari Address: ";
const ITEM_02: &str = "Node ID: ";
const ITEM_03: &str = "Network Address: ";
const ITEM_04: &str = "Emoji ID: ";
const ITEM_01: &str = "Tari Address interactive: ";
const ITEM_02: &str = "Tari Address one-sided: ";
const ITEM_03: &str = "Node ID: ";
const ITEM_04: &str = "Network Address: ";
const ITEM_05: &str = "Interactive emoji address: ";
const ITEM_06: &str = "One-sided emoji address: ";

// Tari address
let tari_address_text = Spans::from(vec![
let tari_address_interactive_text = Spans::from(vec![
Span::styled(ITEM_01, Style::default().fg(Color::Magenta)),
Span::styled(
app_state.get_identity().tari_address.clone(),
app_state.get_identity().tari_address_interactive.to_base58(),
Style::default().fg(Color::White),
),
]);
let paragraph = Paragraph::new(tari_address_text).block(Block::default());
let paragraph = Paragraph::new(tari_address_interactive_text).block(Block::default());
f.render_widget(paragraph, details_chunks[0]);

let tari_address_one_sided_text = Spans::from(vec![
Span::styled(ITEM_02, Style::default().fg(Color::Magenta)),
Span::styled(
app_state.get_identity().tari_address_one_sided.to_base58(),
Style::default().fg(Color::White),
),
]);
let paragraph = Paragraph::new(tari_address_one_sided_text).block(Block::default());
f.render_widget(paragraph, details_chunks[1]);

// NodeId
let node_id_text = Spans::from(vec![
Span::styled(ITEM_02, Style::default().fg(Color::Magenta)),
Span::styled(ITEM_03, Style::default().fg(Color::Magenta)),
Span::styled(
app_state.get_identity().node_id.clone(),
Style::default().fg(Color::White),
),
]);
let paragraph = Paragraph::new(node_id_text).block(Block::default());
f.render_widget(paragraph, details_chunks[1]);
f.render_widget(paragraph, details_chunks[2]);

// Public Address
let public_address_text = Spans::from(vec![
Span::styled(ITEM_03, Style::default().fg(Color::Magenta)),
Span::styled(ITEM_04, Style::default().fg(Color::Magenta)),
Span::styled(
app_state.get_identity().network_address.clone(),
Style::default().fg(Color::White),
),
]);
let paragraph = Paragraph::new(public_address_text).block(Block::default());
f.render_widget(paragraph, details_chunks[2]);
f.render_widget(paragraph, details_chunks[3]);

// Emoji ID
let emoji_id_text = Spans::from(vec![
Span::styled(ITEM_04, Style::default().fg(Color::Magenta)),
Span::styled(ITEM_05, Style::default().fg(Color::Magenta)),
Span::styled(
app_state.get_identity().emoji_id.clone(),
app_state.get_identity().tari_address_interactive.to_emoji_string(),
Style::default().fg(Color::White),
),
]);
let paragraph = Paragraph::new(emoji_id_text).block(Block::default());
f.render_widget(paragraph, details_chunks[3]);
f.render_widget(paragraph, details_chunks[4]);

let emoji_id_text = Spans::from(vec![
Span::styled(ITEM_06, Style::default().fg(Color::Magenta)),
Span::styled(
app_state.get_identity().tari_address_one_sided.to_emoji_string(),
Style::default().fg(Color::White),
),
]);
let paragraph = Paragraph::new(emoji_id_text).block(Block::default());
f.render_widget(paragraph, details_chunks[5]);
}
}

Expand Down
18 changes: 8 additions & 10 deletions applications/minotari_console_wallet/src/ui/state/app_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -897,11 +897,10 @@ impl AppStateInner {

pub async fn refresh_network_id(&mut self) -> Result<(), UiError> {
let wallet_id = self.wallet.get_wallet_id().await?;
let eid = wallet_id.address.to_emoji_string();
let qr_link = format!(
"tari://{}/transactions/send?tariAddress={}",
wallet_id.network(),
wallet_id.address.to_base58()
wallet_id.address_interactive.to_base58()
);
let code = QrCode::new(qr_link).unwrap();
let image = code
Expand All @@ -913,15 +912,15 @@ impl AppStateInner {
.skip(1)
.fold("".to_string(), |acc, l| format!("{}{}\n", acc, l));
let identity = MyIdentity {
tari_address: wallet_id.address.to_base58(),
tari_address_interactive: wallet_id.address_interactive.clone(),
tari_address_one_sided: wallet_id.address_one_sided.clone(),
network_address: wallet_id
.node_identity
.public_addresses()
.iter()
.map(|a| a.to_string())
.collect::<Vec<_>>()
.join(", "),
emoji_id: eid,
qr_code: image,
node_id: wallet_id.node_identity.node_id().to_string(),
};
Expand Down Expand Up @@ -1234,11 +1233,10 @@ pub struct EventListItem {

impl AppStateData {
pub fn new(wallet_identity: &WalletIdentity, base_node_selected: Peer, base_node_config: PeerConfig) -> Self {
let eid = wallet_identity.address.to_emoji_string();
let qr_link = format!(
"tari://{}/transactions/send?tariAddress={}",
wallet_identity.network(),
wallet_identity.address.to_base58()
wallet_identity.address_interactive.to_base58()
);
let code = QrCode::new(qr_link).unwrap();
let image = code
Expand All @@ -1251,15 +1249,15 @@ impl AppStateData {
.fold("".to_string(), |acc, l| format!("{}{}\n", acc, l));

let identity = MyIdentity {
tari_address: wallet_identity.address.to_base58(),
tari_address_interactive: wallet_identity.address_interactive.clone(),
tari_address_one_sided: wallet_identity.address_one_sided.clone(),
network_address: wallet_identity
.node_identity
.public_addresses()
.iter()
.map(|a| a.to_string())
.collect::<Vec<_>>()
.join(", "),
emoji_id: eid,
qr_code: image,
node_id: wallet_identity.node_identity.node_id().to_string(),
};
Expand Down Expand Up @@ -1309,9 +1307,9 @@ impl AppStateData {

#[derive(Clone)]
pub struct MyIdentity {
pub tari_address: String,
pub tari_address_interactive: TariAddress,
pub tari_address_one_sided: TariAddress,
pub network_address: String,
pub emoji_id: String,
pub qr_code: String,
pub node_id: String,
}
Expand Down
3 changes: 3 additions & 0 deletions base_layer/common_types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// This is the string used to derive the comms/spend key of the wallet
pub const WALLET_COMMS_AND_SPEND_KEY_BRANCH: &str = "comms";

pub mod burnt_proof;
pub mod chain_metadata;
pub mod dammsum;
Expand Down
18 changes: 18 additions & 0 deletions base_layer/common_types/src/wallet_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ use ledger_transport::APDUCommand;
use minotari_ledger_wallet_comms::ledger_wallet::{Command, Instruction};
use serde::{Deserialize, Serialize};
use tari_common::configuration::Network;
use tari_crypto::keys::PublicKey as PublicKeyTrait;

use crate::types::{PrivateKey, PublicKey};

Expand All @@ -40,17 +41,34 @@ pub enum WalletType {
#[default]
Software,
Ledger(LedgerWallet),
Imported(ImportedWallet),
}

impl Display for WalletType {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match self {
WalletType::Software => write!(f, "Software"),
WalletType::Ledger(ledger_wallet) => write!(f, "Ledger({ledger_wallet})"),
WalletType::Imported(imported_wallet) => write!(f, "Imported({imported_wallet})"),
}
}
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ImportedWallet {
pub public_spend_key: PublicKey,
pub private_spend_key: Option<PrivateKey>,
pub view_key: PrivateKey,
}

impl Display for ImportedWallet {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(f, "public spend key {}", self.public_spend_key)?;
write!(f, "public view key{}", PublicKey::from_secret_key(&self.view_key))?;
Ok(())
}
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LedgerWallet {
account: u64,
Expand Down
Loading

0 comments on commit 35db898

Please sign in to comment.