Skip to content

Commit

Permalink
feat!: add payment id (#6340)
Browse files Browse the repository at this point in the history
Description
---
Add payment id as buckets into encrypted data field

Motivation and Context
---
Allows wallets to send encrypted data via the block chain to other
wallets

---------

Co-authored-by: stringhandler <[email protected]>
  • Loading branch information
SWvheerden and stringhandler committed Jun 3, 2024
1 parent 561ac67 commit 1dc1a5b
Show file tree
Hide file tree
Showing 62 changed files with 970 additions and 191 deletions.
1 change: 1 addition & 0 deletions applications/minotari_app_grpc/proto/wallet.proto
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ message PaymentRecipient {
ONE_SIDED_TO_STEALTH_ADDRESS = 2;
}
PaymentType payment_type = 5;
bytes payment_id = 6;
}

message TransferResponse {
Expand Down
10 changes: 9 additions & 1 deletion applications/minotari_console_wallet/src/automation/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ use tari_comms::{
use tari_comms_dht::{envelope::NodeDestination, DhtDiscoveryRequester};
use tari_core::transactions::{
tari_amount::{uT, MicroMinotari, Minotari},
transaction_components::{OutputFeatures, TransactionOutput, WalletOutput},
transaction_components::{encrypted_data::PaymentId, OutputFeatures, TransactionOutput, WalletOutput},
};
use tari_crypto::ristretto::RistrettoSecretKey;
use tari_utilities::{hex::Hex, ByteArray};
Expand Down Expand Up @@ -232,6 +232,7 @@ pub async fn send_one_sided(
selection_criteria: UtxoSelectionCriteria,
dest_address: TariAddress,
message: String,
payment_id: PaymentId,
) -> Result<TxId, CommandError> {
wallet_transaction_service
.send_one_sided_transaction(
Expand All @@ -241,6 +242,7 @@ pub async fn send_one_sided(
OutputFeatures::default(),
fee_per_gram * uT,
message,
payment_id,
)
.await
.map_err(CommandError::TransactionServiceError)
Expand All @@ -253,6 +255,7 @@ pub async fn send_one_sided_to_stealth_address(
selection_criteria: UtxoSelectionCriteria,
dest_address: TariAddress,
message: String,
payment_id: PaymentId,
) -> Result<TxId, CommandError> {
wallet_transaction_service
.send_one_sided_to_stealth_address_transaction(
Expand All @@ -262,6 +265,7 @@ pub async fn send_one_sided_to_stealth_address(
OutputFeatures::default(),
fee_per_gram * uT,
message,
payment_id,
)
.await
.map_err(CommandError::TransactionServiceError)
Expand Down Expand Up @@ -452,6 +456,7 @@ pub async fn make_it_rain(
UtxoSelectionCriteria::default(),
address.clone(),
msg.clone(),
PaymentId::Empty,
)
.await
},
Expand All @@ -463,6 +468,7 @@ pub async fn make_it_rain(
UtxoSelectionCriteria::default(),
address.clone(),
msg.clone(),
PaymentId::Empty,
)
.await
},
Expand Down Expand Up @@ -725,6 +731,7 @@ pub async fn command_runner(
UtxoSelectionCriteria::default(),
args.destination,
args.message,
PaymentId::Empty,
)
.await
{
Expand All @@ -743,6 +750,7 @@ pub async fn command_runner(
UtxoSelectionCriteria::default(),
args.destination,
args.message,
PaymentId::Empty,
)
.await
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ use tari_core::{
transactions::{
tari_amount::{MicroMinotari, T},
transaction_components::{
encrypted_data::PaymentId,
CodeTemplateRegistration,
OutputFeatures,
OutputType,
Expand Down Expand Up @@ -501,13 +502,17 @@ impl wallet_server::Wallet for WalletGrpcServer {
dest.fee_per_gram,
dest.message,
dest.payment_type,
dest.payment_id,
))
})
.collect::<Result<Vec<_>, _>>()
.map_err(Status::invalid_argument)?;

let mut transfers = Vec::new();
for (hex_address, address, amount, fee_per_gram, message, payment_type) in recipients {
for (hex_address, address, amount, fee_per_gram, message, payment_type, payment_id) in recipients {
let payment_id = PaymentId::from_bytes(&payment_id)
.map_err(|_| "Invalid payment id".to_string())
.map_err(Status::invalid_argument)?;
let mut transaction_service = self.get_transaction_service();
transfers.push(async move {
(
Expand All @@ -532,6 +537,7 @@ impl wallet_server::Wallet for WalletGrpcServer {
OutputFeatures::default(),
fee_per_gram.into(),
message,
payment_id,
)
.await
} else {
Expand All @@ -543,6 +549,7 @@ impl wallet_server::Wallet for WalletGrpcServer {
OutputFeatures::default(),
fee_per_gram.into(),
message,
payment_id,
)
.await
},
Expand Down
38 changes: 36 additions & 2 deletions applications/minotari_console_wallet/src/ui/components/send_tab.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ pub struct SendTab {
send_input_mode: SendInputMode,
show_contacts: bool,
to_field: String,
payment_id_field: String,
amount_field: String,
fee_field: String,
message_field: String,
Expand All @@ -49,6 +50,7 @@ impl SendTab {
send_input_mode: SendInputMode::None,
show_contacts: false,
to_field: String::new(),
payment_id_field: String::new(),
amount_field: String::new(),
fee_field: app_state.get_default_fee_per_gram().as_u64().to_string(),
message_field: String::new(),
Expand Down Expand Up @@ -104,6 +106,9 @@ impl SendTab {
Span::raw(" field, "),
Span::styled("C", Style::default().add_modifier(Modifier::BOLD)),
Span::raw(" to select a contact."),
Span::styled("P", Style::default().add_modifier(Modifier::BOLD)),
Span::raw(" to edit "),
Span::styled("Payment-id", Style::default().add_modifier(Modifier::BOLD)),
]),
Spans::from(vec![
Span::raw("Press "),
Expand Down Expand Up @@ -167,6 +172,14 @@ impl SendTab {
.block(Block::default().borders(Borders::ALL).title("(M)essage:"));
f.render_widget(message_input, vert_chunks[3]);

let payment_id_input = Paragraph::new(self.payment_id_field.as_ref())
.style(match self.send_input_mode {
SendInputMode::PaymentId => Style::default().fg(Color::Magenta),
_ => Style::default(),
})
.block(Block::default().borders(Borders::ALL).title("(P)ayment-id:"));
f.render_widget(payment_id_input, vert_chunks[4]);

match self.send_input_mode {
SendInputMode::None => (),
SendInputMode::To => f.set_cursor(
Expand Down Expand Up @@ -197,6 +210,12 @@ impl SendTab {
// Move one line down, from the border to the input line
vert_chunks[3].y + 1,
),
SendInputMode::PaymentId => f.set_cursor(
// Put cursor past the end of the input text
vert_chunks[4].x + self.payment_id_field.width() as u16 + 1,
// Move one line down, from the border to the input line
vert_chunks[4].y + 1,
),
}
}

Expand Down Expand Up @@ -275,6 +294,7 @@ impl SendTab {
UtxoSelectionCriteria::default(),
fee_per_gram,
self.message_field.clone(),
self.payment_id_field.clone(),
tx,
)) {
Err(e) => {
Expand All @@ -294,6 +314,7 @@ impl SendTab {
UtxoSelectionCriteria::default(),
fee_per_gram,
self.message_field.clone(),
self.payment_id_field.clone(),
tx,
),
) {
Expand Down Expand Up @@ -332,6 +353,7 @@ impl SendTab {
self.selected_unique_id = None;
self.fee_field = app_state.get_default_fee_per_gram().as_u64().to_string();
self.message_field = "".to_string();
self.payment_id_field = "".to_string();
self.send_input_mode = SendInputMode::None;
self.send_result_watch = Some(rx);
}
Expand Down Expand Up @@ -386,12 +408,19 @@ impl SendTab {
},
},
SendInputMode::Message => match c {
'\n' => self.send_input_mode = SendInputMode::None,
'\n' => self.send_input_mode = SendInputMode::PaymentId,
c => {
self.message_field.push(c);
return KeyHandled::Handled;
},
},
SendInputMode::PaymentId => match c {
'\n' => self.send_input_mode = SendInputMode::None,
c => {
self.payment_id_field.push(c);
return KeyHandled::Handled;
},
},
}
}

Expand Down Expand Up @@ -424,7 +453,7 @@ impl<B: Backend> Component<B> for SendTab {
.constraints(
[
Constraint::Length(3),
Constraint::Length(14),
Constraint::Length(17),
Constraint::Min(42),
Constraint::Length(1),
]
Expand Down Expand Up @@ -579,6 +608,7 @@ impl<B: Backend> Component<B> for SendTab {
},
'f' => self.send_input_mode = SendInputMode::Fee,
'm' => self.send_input_mode = SendInputMode::Message,
'p' => self.send_input_mode = SendInputMode::PaymentId,
's' | 'o' | 'x' => {
if self.to_field.is_empty() {
self.error_message =
Expand Down Expand Up @@ -651,6 +681,9 @@ impl<B: Backend> Component<B> for SendTab {
SendInputMode::Message => {
let _ = self.message_field.pop();
},
SendInputMode::PaymentId => {
let _ = self.payment_id_field.pop();
},
SendInputMode::None => {},
}
}
Expand All @@ -663,6 +696,7 @@ pub enum SendInputMode {
Amount,
Message,
Fee,
PaymentId,
}

#[derive(PartialEq, Debug)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use chrono::{DateTime, Local};
use log::*;
use minotari_wallet::transaction_service::storage::models::TxCancellationReason;
use tari_common_types::transaction::{TransactionDirection, TransactionStatus};
use tari_core::transactions::transaction_components::encrypted_data::PaymentId;
use tokio::runtime::Handle;
use tui::{
backend::Backend,
Expand Down Expand Up @@ -288,7 +289,7 @@ impl TransactionsTab {
.split(area);

// Labels
let constraints = [Constraint::Length(1); 14];
let constraints = [Constraint::Length(1); 15];
let label_layout = Layout::default().constraints(constraints).split(columns[0]);

let tx_id = Span::styled("TxID:", Style::default().fg(Color::Magenta));
Expand All @@ -305,6 +306,7 @@ impl TransactionsTab {
let confirmations = Span::styled("Confirmations:", Style::default().fg(Color::Magenta));
let mined_height = Span::styled("Mined Height:", Style::default().fg(Color::Magenta));
let maturity = Span::styled("Maturity:", Style::default().fg(Color::Magenta));
let payment_id = Span::styled("Payment Id:", Style::default().fg(Color::Magenta));

let trim = Wrap { trim: true };
let paragraph = Paragraph::new(tx_id).wrap(trim);
Expand Down Expand Up @@ -335,11 +337,13 @@ impl TransactionsTab {
f.render_widget(paragraph, label_layout[12]);
let paragraph = Paragraph::new(maturity).wrap(trim);
f.render_widget(paragraph, label_layout[13]);
let paragraph = Paragraph::new(payment_id).wrap(trim);
f.render_widget(paragraph, label_layout[14]);

// Content
let required_confirmations = app_state.get_required_confirmations();
if let Some(tx) = self.detailed_transaction.as_ref() {
let constraints = [Constraint::Length(1); 14];
let constraints = [Constraint::Length(1); 15];
let content_layout = Layout::default().constraints(constraints).split(columns[1]);
let tx_id = Span::styled(format!("{}", tx.tx_id), Style::default().fg(Color::White));

Expand Down Expand Up @@ -429,6 +433,20 @@ impl TransactionsTab {
};
let maturity = Span::styled(maturity, Style::default().fg(Color::White));

let payment_id = match tx.payment_id.clone() {
Some(v) => {
if let PaymentId::Open(bytes) = v {
String::from_utf8(bytes)
.unwrap_or_else(|_| "Invalid".to_string())
.to_string()
} else {
format!("#{}", v)
}
},
None => "None".to_string(),
};
let payment_id = Span::styled(payment_id, Style::default().fg(Color::White));

let paragraph = Paragraph::new(tx_id).wrap(trim);
f.render_widget(paragraph, content_layout[0]);
let paragraph = Paragraph::new(source_address).wrap(trim);
Expand Down Expand Up @@ -457,6 +475,8 @@ impl TransactionsTab {
f.render_widget(paragraph, content_layout[12]);
let paragraph = Paragraph::new(maturity).wrap(trim);
f.render_widget(paragraph, content_layout[13]);
let paragraph = Paragraph::new(payment_id).wrap(trim);
f.render_widget(paragraph, content_layout[14]);
}
}
}
Expand All @@ -469,7 +489,7 @@ impl<B: Backend> Component<B> for TransactionsTab {
Constraint::Length(3),
Constraint::Length(1),
Constraint::Min(9),
Constraint::Length(16),
Constraint::Length(17),
]
.as_ref(),
)
Expand Down
Loading

0 comments on commit 1dc1a5b

Please sign in to comment.