Skip to content

Commit 11a65a5

Browse files
Implement status screens for Stax/Flex now that they are not managed by SDK.
1 parent 2ac6b40 commit 11a65a5

File tree

4 files changed

+53
-8
lines changed

4 files changed

+53
-8
lines changed

Cargo.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ authors = ["yhql", "agrojean-ledger"]
55
edition = "2021"
66

77
[dependencies]
8-
ledger_device_sdk = { version="1.13.1" }
8+
ledger_device_sdk = { version="1.14.0" }
99
include_gif = "1.2.0"
1010
serde = {version="1.0.192", default_features = false, features = ["derive"]}
1111
serde-json-core = { git = "https://github.com/rust-embedded-community/serde-json-core"}

src/handlers/sign_tx.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,20 +41,29 @@ pub struct Tx<'a> {
4141
pub struct TxContext {
4242
raw_tx: Vec<u8>,
4343
path: Bip32Path,
44+
review_finished: bool,
4445
}
4546

4647
// Implement constructor for TxInfo with default values
4748
impl TxContext {
49+
// Constructor
4850
pub fn new() -> TxContext {
4951
TxContext {
5052
raw_tx: Vec::new(),
5153
path: Default::default(),
54+
review_finished: false,
5255
}
5356
}
57+
// Get review status
58+
#[allow(dead_code)]
59+
pub fn finished(&self) -> bool {
60+
self.review_finished
61+
}
5462
// Implement reset for TxInfo
5563
fn reset(&mut self) {
5664
self.raw_tx.clear();
5765
self.path = Default::default();
66+
self.review_finished = false;
5867
}
5968
}
6069

@@ -85,6 +94,7 @@ pub fn handler_sign_tx(
8594

8695
// If we expect more chunks, return
8796
if more {
97+
ctx.review_finished = false;
8898
Ok(())
8999
// Otherwise, try to parse the transaction
90100
} else {
@@ -94,8 +104,10 @@ pub fn handler_sign_tx(
94104
// the transaction, sign it. Otherwise,
95105
// return a "deny" status word.
96106
if ui_display_tx(&tx)? {
107+
ctx.review_finished = true;
97108
compute_signature_and_append(comm, ctx)
98109
} else {
110+
ctx.review_finished = true;
99111
Err(AppSW::Deny)
100112
}
101113
}

src/main.rs

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ ledger_device_sdk::set_panic!(ledger_device_sdk::exiting_panic);
4949
extern crate alloc;
5050

5151
#[cfg(any(target_os = "stax", target_os = "flex"))]
52-
use ledger_device_sdk::nbgl::init_comm;
52+
use ledger_device_sdk::nbgl::{init_comm, NbglReviewStatus, StatusType};
5353

5454
// P2 for last APDU to receive.
5555
const P2_SIGN_TX_LAST: u8 = 0x00;
@@ -62,6 +62,7 @@ const P1_SIGN_TX_MAX: u8 = 0x03;
6262

6363
// Application status words.
6464
#[repr(u16)]
65+
#[derive(Clone, Copy, PartialEq)]
6566
pub enum AppSW {
6667
Deny = 0x6985,
6768
WrongP1P2 = 0x6A86,
@@ -76,6 +77,7 @@ pub enum AppSW {
7677
KeyDeriveFail = 0xB009,
7778
VersionParsingFail = 0xB00A,
7879
WrongApduLength = StatusWords::BadLen as u16,
80+
Ok = 0x9000,
7981
}
8082

8183
impl From<AppSW> for Reply {
@@ -85,6 +87,7 @@ impl From<AppSW> for Reply {
8587
}
8688

8789
/// Possible input commands received through APDUs.
90+
#[derive(Clone, Copy)]
8891
pub enum Instruction {
8992
GetVersion,
9093
GetAppName,
@@ -126,6 +129,26 @@ impl TryFrom<ApduHeader> for Instruction {
126129
}
127130
}
128131

132+
#[cfg(any(target_os = "stax", target_os = "flex"))]
133+
fn show_status_if_needed(ins: &Instruction, tx_ctx: &TxContext, status: AppSW) {
134+
let (show_status, status_type) = match (ins, status) {
135+
(Instruction::GetPubkey { display: true }, AppSW::Deny | AppSW::Ok) => {
136+
(true, StatusType::Address)
137+
}
138+
(Instruction::SignTx { .. }, AppSW::Deny | AppSW::Ok) if tx_ctx.finished() => {
139+
(true, StatusType::Transaction)
140+
}
141+
(_, _) => (false, StatusType::Transaction),
142+
};
143+
144+
if show_status {
145+
let success = status == AppSW::Ok;
146+
NbglReviewStatus::new()
147+
.status_type(status_type)
148+
.show(success);
149+
}
150+
}
151+
129152
#[no_mangle]
130153
extern "C" fn sample_main() {
131154
// Create the communication manager, and configure it to accept only APDU from the 0xe0 class.
@@ -150,10 +173,20 @@ extern "C" fn sample_main() {
150173
// Wait for either a specific button push to exit the app
151174
// or an APDU command
152175
if let Event::Command(ins) = ui_menu_main(&mut comm) {
153-
match handle_apdu(&mut comm, ins, &mut tx_ctx) {
154-
Ok(()) => comm.reply_ok(),
155-
Err(sw) => comm.reply(sw),
156-
}
176+
let result = handle_apdu(&mut comm, ins, &mut tx_ctx);
177+
let _status: AppSW = match result {
178+
Ok(()) => {
179+
comm.reply_ok();
180+
AppSW::Ok
181+
}
182+
Err(sw) => {
183+
comm.reply(sw);
184+
sw
185+
}
186+
};
187+
188+
#[cfg(any(target_os = "stax", target_os = "flex"))]
189+
show_status_if_needed(&ins, &tx_ctx, _status);
157190
}
158191
}
159192
}

0 commit comments

Comments
 (0)