Skip to content

Commit

Permalink
Add streaming review support in NBGL module
Browse files Browse the repository at this point in the history
  • Loading branch information
agrojean-ledger committed Jul 8, 2024
1 parent 3c22c1c commit c656e6d
Show file tree
Hide file tree
Showing 3 changed files with 220 additions and 1 deletion.
2 changes: 1 addition & 1 deletion ledger_device_sdk/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ledger_device_sdk"
version = "1.11.1"
version = "1.12.0"
authors = ["yhql", "yogh333", "agrojean-ledger", "kingofpayne"]
edition = "2021"
license.workspace = true
Expand Down
65 changes: 65 additions & 0 deletions ledger_device_sdk/examples/nbgl_streaming_review.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#![no_std]
#![no_main]

// Force boot section to be embedded in
use ledger_device_sdk as _;

use include_gif::include_gif;
use ledger_device_sdk::io::*;
use ledger_device_sdk::nbgl::{init_comm, Field, NbglGlyph, NbglStreamingReview, TransactionType};
use ledger_secure_sdk_sys::*;

#[panic_handler]
fn panic(_: &core::panic::PanicInfo) -> ! {
exit_app(1);
}

#[no_mangle]
extern "C" fn sample_main() {
unsafe {
nbgl_refreshReset();
}

let mut comm = Comm::new();
// Initialize reference to Comm instance for NBGL
// API calls.
init_comm(&mut comm);

// Load glyph from 64x64 4bpp gif file with include_gif macro. Creates an NBGL compatible glyph.
const FERRIS: NbglGlyph =
NbglGlyph::from_include(include_gif!("examples/crab_64x64.gif", NBGL));

let mut review: NbglStreamingReview =
NbglStreamingReview::new(TransactionType::Message).glyph(&FERRIS);

review.start("Example Title", "Example Subtitle");

let fields = [
Field {
name: "Name1",
value: "Value1",
},
Field {
name: "Name2",
value: "Value2",
},
Field {
name: "Name3",
value: "Value3",
},
Field {
name: "Name4",
value: "Value4",
},
Field {
name: "Name5",
value: "Value5",
},
];

for i in 0..fields.len() {
review.continue_review(&fields[i..i + 1]);
}

review.finish("Sign to send token\n");
}
154 changes: 154 additions & 0 deletions ledger_device_sdk/src/nbgl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,50 @@ impl<'a> Into<nbgl_icon_details_t> for &NbglGlyph<'a> {
}
}

pub enum TransactionType {
Transaction,
Message,
Operation,
}

impl From<&TransactionType> for nbgl_operationType_t {
fn from(t: &TransactionType) -> nbgl_operationType_t {
match t {
TransactionType::Transaction => TYPE_TRANSACTION.into(),
TransactionType::Message => TYPE_MESSAGE.into(),
TransactionType::Operation => TYPE_OPERATION.into(),
}
}
}

impl TransactionType {
pub fn to_message(&self, success: bool) -> nbgl_reviewStatusType_t {
match self {
TransactionType::Transaction => {
if success {
STATUS_TYPE_TRANSACTION_SIGNED
} else {
STATUS_TYPE_TRANSACTION_REJECTED
}
}
TransactionType::Message => {
if success {
STATUS_TYPE_MESSAGE_SIGNED
} else {
STATUS_TYPE_MESSAGE_REJECTED
}
}
TransactionType::Operation => {
if success {
STATUS_TYPE_OPERATION_SIGNED
} else {
STATUS_TYPE_OPERATION_REJECTED
}
}
}
}
}

/// Initialize the global COMM_REF variable with the provided Comm instance.
/// This function should be called from the main function of the application.
/// The COMM_REF variable is used by the NBGL API to detect touch events and
Expand Down Expand Up @@ -821,6 +865,116 @@ impl NbglGenericReview {
}
}

pub struct NbglStreamingReview {
icon: nbgl_icon_details_t,
tx_type: TransactionType,
}

impl NbglStreamingReview {
pub fn new(tx_type: TransactionType) -> NbglStreamingReview {
NbglStreamingReview {
icon: nbgl_icon_details_t::default(),
tx_type,
}
}

pub fn glyph(self, glyph: &NbglGlyph) -> NbglStreamingReview {
NbglStreamingReview {
icon: glyph.into(),
..self
}
}

pub fn start(&mut self, title: &str, subtitle: &str) -> bool {
unsafe {
let title = CString::new(title).unwrap();
let subtitle = CString::new(subtitle).unwrap();

let sync_ret = ux_sync_reviewStreamingStart(
(&self.tx_type).into(),
&self.icon as *const nbgl_icon_details_t,
title.as_ptr() as *const c_char,
subtitle.as_ptr() as *const c_char,
);

// Return true if the user approved the transaction, false otherwise.
match sync_ret {
UX_SYNC_RET_APPROVED => {
return true;
}
_ => {
ux_sync_reviewStatus(self.tx_type.to_message(false));
return false;
}
}
}
}

pub fn continue_review(&mut self, fields: &[Field]) -> bool {
unsafe {
let v: Vec<CField> = fields
.iter()
.map(|f| CField {
name: CString::new(f.name).unwrap(),
value: CString::new(f.value).unwrap(),
})
.collect();

// Fill the tag_value_array with the fields converted to nbgl_contentTagValue_t
let mut tag_value_array: Vec<nbgl_contentTagValue_t> = Vec::new();
for field in v.iter() {
let val = nbgl_contentTagValue_t {
item: field.name.as_ptr() as *const i8,
value: field.value.as_ptr() as *const i8,
..Default::default()
};
tag_value_array.push(val);
}

// Create the tag_value_list with the tag_value_array.
let tag_value_list = nbgl_contentTagValueList_t {
pairs: tag_value_array.as_ptr() as *const nbgl_contentTagValue_t,
nbPairs: fields.len() as u8,
..Default::default()
};

let sync_ret = ux_sync_reviewStreamingContinue(
&tag_value_list as *const nbgl_contentTagValueList_t,
);

// Return true if the user approved the transaction, false otherwise.
match sync_ret {
UX_SYNC_RET_APPROVED => {
return true;
}
_ => {
ux_sync_reviewStatus(self.tx_type.to_message(false));
return false;
}
}
}
}

pub fn finish(&mut self, finish_title: &str) -> bool {
unsafe {
let finish_title = CString::new(finish_title).unwrap();
let sync_ret = ux_sync_reviewStreamingFinish(finish_title.as_ptr() as *const c_char);

// Return true if the user approved the transaction, false otherwise.
match sync_ret {
ledger_secure_sdk_sys::UX_SYNC_RET_APPROVED => {
ux_sync_reviewStatus(self.tx_type.to_message(true));
return true;
}
_ => {
ux_sync_reviewStatus(self.tx_type.to_message(false));
return false;
}
}
}
}
}

/// A wrapper around the synchronous NBGL ux_sync_addressReview C API binding.
/// Used to display address confirmation screens.
pub struct NbglAddressReview<'a> {
Expand Down

0 comments on commit c656e6d

Please sign in to comment.