Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 34 additions & 5 deletions .github/workflows/doc.yml
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
name: Publish Rust SDK documentation on GitHub Pages

on:
workflow_dispatch:
inputs:
name:
description: 'Manually triggered'
pull_request:
push:
branches:
- master
workflow_dispatch:
inputs:
name:
description: 'Manually triggered'

env:
CARGO_TERM_COLOR: always

jobs:
build-docs:
name: Build documentation
permissions:
contents: read
runs-on: ubuntu-latest
container:
image: ghcr.io/ledgerhq/ledger-app-builder/ledger-app-dev-tools:latest
Expand All @@ -20,4 +26,27 @@ jobs:
uses: actions/checkout@v4
- name: Cargo doc
run: |
cargo doc -p ledger_device_sdk --no-deps --lib --target flex
cargo doc -p ledger_device_sdk --no-deps --lib
echo "<meta http-equiv=\"refresh\" content=\"0; url=ledger_device_sdk\">" > target/flex/doc/index.html
- name: Upload artifact
if: github.ref == 'refs/heads/master' || github.event_name == 'workflow_dispatch'
uses: actions/upload-pages-artifact@v4
with:
path: target/flex/doc/

# deploy to GitHub Pages
deploy:
if: github.ref == 'refs/heads/master' || github.event_name == 'workflow_dispatch'
permissions:
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
name: Deploy to GitHub Pages
runs-on: ubuntu-latest
needs: build-docs
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 5 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,11 @@

## Crates

| Crate | Description | Latest Release |
| ------------------------------------------------ | --------------------------------------------------------------- | -------------- |
| [ledger_device_sdk](./ledger_device_sdk) | Rust SDK | ![Dynamic TOML Badge](https://img.shields.io/badge/dynamic/toml?url=https%3A%2F%2Fraw.githubusercontent.com%2FLedgerHQ%2Fledger-device-rust-sdk%2Frefs%2Fheads%2Fmaster%2Fledger_device_sdk%2FCargo.toml&query=%24.package.version&label=version) |
| [ledger_secure_sdk_sys](./ledger_secure_sdk_sys) | [C SDK](https://github.com/LedgerHQ/ledger-secure-sdk) bindings | ![Dynamic TOML Badge](https://img.shields.io/badge/dynamic/toml?url=https%3A%2F%2Fraw.githubusercontent.com%2FLedgerHQ%2Fledger-device-rust-sdk%2Frefs%2Fheads%2Fmaster%2Fledger_secure_sdk_sys%2FCargo.toml&query=%24.package.version&label=version) |
| [include_gif](./include_gif) | Procedural macro to integrate logo in the UI/UX | ![Dynamic TOML Badge](https://img.shields.io/badge/dynamic/toml?url=https%3A%2F%2Fraw.githubusercontent.com%2FLedgerHQ%2Fledger-device-rust-sdk%2Frefs%2Fheads%2Fmaster%2Finclude_gif%2FCargo.toml&query=%24.package.version&label=version) |
| [testmacro](./testmacro) | Procedural macro used by unit and integrations tests | ![Dynamic TOML Badge](https://img.shields.io/badge/dynamic/toml?url=https%3A%2F%2Fraw.githubusercontent.com%2FLedgerHQ%2Fledger-device-rust-sdk%2Frefs%2Fheads%2Fmaster%2Ftestmacro%2FCargo.toml&query=%24.package.version&label=version) |
| Crate | Description | Documentation | Latest Release |
| ------------------------------------------------ | --------------------------------------------------------------- | -------------- | -------------- |
| [ledger_device_sdk](./ledger_device_sdk) | Rust SDK | [Link](https://ledgerhq.github.io/ledger-device-rust-sdk/) | ![Dynamic TOML Badge](https://img.shields.io/badge/dynamic/toml?url=https%3A%2F%2Fraw.githubusercontent.com%2FLedgerHQ%2Fledger-device-rust-sdk%2Frefs%2Fheads%2Fmaster%2Fledger_device_sdk%2FCargo.toml&query=%24.package.version&label=version) |
| [ledger_secure_sdk_sys](./ledger_secure_sdk_sys) | [C SDK](https://github.com/LedgerHQ/ledger-secure-sdk) bindings | | ![Dynamic TOML Badge](https://img.shields.io/badge/dynamic/toml?url=https%3A%2F%2Fraw.githubusercontent.com%2FLedgerHQ%2Fledger-device-rust-sdk%2Frefs%2Fheads%2Fmaster%2Fledger_secure_sdk_sys%2FCargo.toml&query=%24.package.version&label=version) |
| [include_gif](./include_gif) | Procedural macro to integrate logo in the UI/UX | | ![Dynamic TOML Badge](https://img.shields.io/badge/dynamic/toml?url=https%3A%2F%2Fraw.githubusercontent.com%2FLedgerHQ%2Fledger-device-rust-sdk%2Frefs%2Fheads%2Fmaster%2Finclude_gif%2FCargo.toml&query=%24.package.version&label=version) |

## Docker builder

Expand Down
1 change: 1 addition & 0 deletions ledger_device_sdk/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#![warn(missing_docs)]
#![no_std]
#![cfg_attr(test, no_main)]
#![feature(custom_test_frameworks)]
Expand Down
39 changes: 38 additions & 1 deletion ledger_device_sdk/src/nbgl.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
//! NBGL module
//!
//! This module provides a safe Rust interface to the NBGL library.
//! It includes functions and structures to create and manage UI elements,
//! handle user interactions, and display information on Ledger devices.

use crate::io::{ApduHeader, Event};
use crate::io_callbacks::nbgl_next_event_ahead;
use crate::nvm::*;
Expand All @@ -18,7 +24,7 @@ pub mod nbgl_generic_review;
pub mod nbgl_generic_settings;
pub mod nbgl_home_and_settings;
pub mod nbgl_keypad;
pub mod nbgl_navigable_content;
//pub mod nbgl_navigable_content;
pub mod nbgl_review;
#[cfg(any(target_os = "stax", target_os = "flex", target_os = "apex_p"))]
pub mod nbgl_review_extended;
Expand All @@ -27,22 +33,36 @@ pub mod nbgl_spinner;
pub mod nbgl_status;
pub mod nbgl_streaming_review;

#[doc(inline)]
pub use nbgl_action::*;
#[doc(inline)]
pub use nbgl_address_review::*;
#[doc(inline)]
pub use nbgl_advance_review::*;
#[doc(inline)]
pub use nbgl_choice::*;
#[doc(inline)]
#[cfg(any(target_os = "stax", target_os = "flex", target_os = "apex_p"))]
pub use nbgl_generic_review::*;
#[doc(inline)]
pub use nbgl_generic_settings::*;
#[doc(inline)]
pub use nbgl_home_and_settings::*;
#[doc(inline)]
pub use nbgl_keypad::*;
#[doc(inline)]
pub use nbgl_review::*;
//pub use nbgl_navigable_content::*; // integration issue
#[doc(inline)]
#[cfg(any(target_os = "stax", target_os = "flex", target_os = "apex_p"))]
pub use nbgl_review_extended::*;
#[doc(inline)]
pub use nbgl_review_status::*;
#[doc(inline)]
pub use nbgl_spinner::*;
#[doc(inline)]
pub use nbgl_status::*;
#[doc(inline)]
pub use nbgl_streaming_review::*;

#[derive(Copy, Clone, PartialEq, Eq)]
Expand Down Expand Up @@ -222,6 +242,7 @@ impl From<&CField> for nbgl_contentTagValue_t {
// }
// }

/// Glyph structure to represent icons for NBGL
pub struct NbglGlyph<'a> {
pub width: u16,
pub height: u16,
Expand All @@ -231,6 +252,15 @@ pub struct NbglGlyph<'a> {
}

impl<'a> NbglGlyph<'a> {
/// Creates a new instance of `NbglGlyph`.
/// # Arguments
/// * `bitmap` - A byte slice representing the bitmap data of the glyph.
/// * `width` - The width of the glyph in pixels.
/// * `height` - The height of the glyph in pixels.
/// * `bpp` - Bits per pixel (1, 2, or 4).
/// * `is_file` - A boolean indicating whether the bitmap is a file path.
/// # Returns
/// Returns a new instance of `NbglGlyph`.
pub const fn new(
bitmap: &'a [u8],
width: u16,
Expand All @@ -246,6 +276,11 @@ impl<'a> NbglGlyph<'a> {
bitmap,
}
}
/// Creates a new instance of `NbglGlyph` from a packed representation.
/// # Arguments
/// * `packed` - A tuple containing the bitmap, width, height, bpp, and is_file flag.
/// # Returns
/// Returns a new instance of `NbglGlyph`.
pub const fn from_include(packed: (&'a [u8], u16, u16, u8, bool)) -> NbglGlyph<'a> {
NbglGlyph {
width: packed.1,
Expand Down Expand Up @@ -275,12 +310,14 @@ impl<'a> Into<nbgl_icon_details_t> for &NbglGlyph<'a> {
}
}

/// Transaction types for NBGL review and status screens.
pub enum TransactionType {
Transaction,
Message,
Operation,
}

/// Status types for NBGL status screens.
pub enum StatusType {
Transaction,
Message,
Expand Down
27 changes: 23 additions & 4 deletions ledger_device_sdk/src/nbgl/nbgl_action.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
//! A wrapper around the asynchronous NBGL [nbgl_useCaseAction](https://github.com/LedgerHQ/ledger-secure-sdk/blob/master/lib_nbgl/src/nbgl_use_case.c#L3730) C API binding.
//!
//! Draws a page to represent an action, described in a centered info (with given icon),
//! thanks to a button at the bottom of the page.

use super::*;

/// A wrapper around the asynchronous NBGL nbgl_useCaseChoice C API binding.
/// Draws a generic choice page, described in a centered info (with configurable icon),
/// thanks to a button and a footer at the bottom of the page.
/// A builder to create and show an action page.
pub struct NbglAction<'a> {
message: CString,
action_text: CString,
Expand All @@ -12,35 +15,51 @@ pub struct NbglAction<'a> {
impl SyncNBGL for NbglAction<'_> {}

impl<'a> NbglAction<'a> {
/// Creates a new action page builder.
pub fn new() -> NbglAction<'a> {
NbglAction {
message: CString::default(),
action_text: CString::default(),
glyph: None,
}
}

/// Sets the message to display in the center of the page.
/// # Arguments
/// * `message` - The main message to display in the center of the page.
/// # Returns
/// Returns the builder itself to allow method chaining.
pub fn message(self, message: &'a str) -> NbglAction<'a> {
NbglAction {
message: CString::new(message).unwrap(),
..self
}
}

/// Sets the text to display on the button at the bottom of the page.
/// # Arguments
/// * `action_text` - The text to display on the button at the bottom of the page.
/// # Returns
/// Returns the builder itself to allow method chaining.
pub fn action_text(self, action_text: &'a str) -> NbglAction<'a> {
NbglAction {
action_text: CString::new(action_text).unwrap(),
..self
}
}

/// Sets the icon to display in the center of the page.
/// # Arguments
/// * `glyph` - The icon to display in the center of the page.
/// # Returns
/// Returns the builder itself to allow method chaining.
pub fn glyph(self, glyph: &'a NbglGlyph<'a>) -> NbglAction<'a> {
NbglAction {
glyph: Some(glyph),
..self
}
}

/// Shows the action page.
pub fn show(self) -> SyncNbgl {
unsafe {
let icon: nbgl_icon_details_t = match self.glyph {
Expand Down
36 changes: 33 additions & 3 deletions ledger_device_sdk/src/nbgl/nbgl_address_review.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
//! A wrapper around the asynchronous NBGL [nbgl_useCaseAddressReview](https://github.com/LedgerHQ/ledger-secure-sdk/blob/master/lib_nbgl/src/nbgl_use_case.c#L4453) C API binding.
//!
//! Draws a flow of pages of an extended address verification page.
//! A back key is available on top-left of the screen, except in first page It is possible to go to next page thanks to "tap to continue".
//! All tag/value pairs are provided in the API and the number of pages is automatically
//! computed, the last page being a long press one
use super::*;

/// A wrapper around the asynchronous NBGL nbgl_useCaseAddressReview C API binding.
/// Used to display address confirmation screens.
/// A builder to create and show an address review flow.
pub struct NbglAddressReview<'a> {
glyph: Option<&'a NbglGlyph<'a>>,
review_title: CString,
Expand All @@ -12,6 +17,7 @@ pub struct NbglAddressReview<'a> {
impl SyncNBGL for NbglAddressReview<'_> {}

impl<'a> NbglAddressReview<'a> {
/// Creates a new address review flow builder.
pub fn new() -> NbglAddressReview<'a> {
NbglAddressReview {
review_title: CString::default(),
Expand All @@ -20,7 +26,11 @@ impl<'a> NbglAddressReview<'a> {
tag_value_list: Vec::default(),
}
}

/// Sets the icon to display in the center of the page.
/// # Arguments
/// * `glyph` - The icon to display in the center of the page.
/// # Returns
/// Returns the builder itself to allow method chaining.
pub fn glyph(self, glyph: &'a NbglGlyph) -> NbglAddressReview<'a> {
NbglAddressReview {
glyph: Some(glyph),
Expand All @@ -36,27 +46,47 @@ impl<'a> NbglAddressReview<'a> {
}
}

/// Sets the title to display at the top of the page.
/// # Arguments
/// * `review_title` - The title to display at the top of the page.
/// # Returns
/// Returns the builder itself to allow method chaining.
pub fn review_title(self, review_title: &str) -> NbglAddressReview<'a> {
NbglAddressReview {
review_title: CString::new(review_title).unwrap(),
..self
}
}

/// Sets the subtitle to display below the title at the top of the page.
/// # Arguments
/// * `review_subtitle` - The subtitle to display below the title at the top of the page.
/// # Returns
/// Returns the builder itself to allow method chaining.
pub fn review_subtitle(self, review_subtitle: &str) -> NbglAddressReview<'a> {
NbglAddressReview {
review_subtitle: CString::new(review_subtitle).unwrap(),
..self
}
}

/// Sets the list of tag/value pairs to display in the address review flow.
/// # Arguments
/// * `tag_value_list` - A slice of `Field` representing the tag/value pairs to display.
/// # Returns
/// Returns the builder itself to allow method chaining.
pub fn set_tag_value_list(self, tag_value_list: &'a [Field<'a>]) -> NbglAddressReview<'a> {
NbglAddressReview {
tag_value_list: tag_value_list.iter().map(|f| f.into()).collect(),
..self
}
}

/// Shows the address review flow.
/// # Arguments
/// * `address` - The address to review.
/// # Returns
/// Returns true if the user approved the address, false otherwise.
pub fn show(&self, address: &str) -> bool {
unsafe {
let icon: nbgl_icon_details_t = match self.glyph {
Expand Down
Loading