Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add privacy report warning in NBGL Use Case #840

Merged
merged 5 commits into from
Jan 24, 2025
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
168 changes: 168 additions & 0 deletions lib_nbgl/doc/nbgl_use_case.dox
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ A few APIs are available to draw typical Use-Cases, such as:
- @ref nbgl_useCaseReview() to draw the pages of a regular coin transaction review, when all info are available from the beginning (see @subpage use_case_review)
- @ref nbgl_useCaseReviewLight() to draw the pages of a transaction review with a simple button confirmation, when all info are available from the beginning (see @subpage use_case_review_light)
- @ref nbgl_useCaseReviewStreamingStart() to draw the pages of a regular coin transaction review, when all info are not available from the beginning (see @subpage use_case_review_streaming)
- for reviews with a warning prolog:
- @ref nbgl_useCaseReviewWithWarning() to draw the pages of a regular coin transaction review, when all info are available from the beginning, but with an identified risk requiring a warning prolog (see @subpage use_case_review_with_warning)
- @ref nbgl_useCaseReviewStreamingWithWarningStart() to draw the pages of a regular coin transaction review, when all info are not available from the beginning, but with an identified risk requiring a warning prolog (see @subpage use_case_review_with_warning and @subpage use_case_review_streaming)
- for address verification:
- @ref nbgl_useCaseAddressReview() to draw an address confirmation page, with a possibility to see it as QR Code and some extra tag/value pairs (see @subpage use_case_addr_review)
- for keypad:
Expand Down Expand Up @@ -455,6 +458,171 @@ void staticReview(void) {
}
@endcode

@subsection use_case_review_with_warning Review with warning Use Case

\image{inline} html UseCase-Review-With-Warning.png "caption" height=500

The review itself behaves like in @subpage use_case_review. The main differences are:

- The review itself is preceded by a warning page offering the possibility to cancel the review ("Back to safety") or to start it ("Continue anyway")
- In the first and last pages of the actual review, a top-right button offers the possibility to get more information about the warning

The API to initiate the display of the series of pages is @ref nbgl_useCaseReviewWithWarning(), providing:

- the type of operation to review (transaction, message or generic operation)
- the list of tag/value pairs (or a callback to get them one by one)
- the texts/icon to use in presentation page and in last page
- the configuration to use for the warning (see @ref nbgl_warning_t structure)
- a callback called when the long press button on last page or reject confirmation is used. The callback's param is *true* for confirmation, *false* for rejection.

@note the recommended configuration for warning is the predefined one. In this case, one just has to fill the *predefinedSet* field of @ref nbgl_warning_t with the appropriate warning
causes (bitfield) and the *reportProvider* field with the name of the 3rd party providing the Web3Checks report, if necessary.

Here is the code to display something similar to example picture:

@code
// 4 pairs of tag/value to display
static nbgl_layoutTagValue_t pairs[4];

static const nbgl_contentTagValueList_t pairList = {
.nbMaxLinesForValue = 0,
.nbPairs = 4,
.pairs = (nbgl_layoutTagValue_t*)pairs
};

// warning description (cannot be in call stack)
static nbgl_warning_t warningDesc;

// called when long press button on 3rd page is long-touched or when reject footer is touched
static void onReviewResult(bool confirm) {
// display a status page and go back to main
if (confirm) {
nbgl_useCaseReviewStatus(STATUS_TYPE_TRANSACTION_SIGNED, appMain);
}
else {
nbgl_useCaseReviewStatus(STATUS_TYPE_TRANSACTION_REJECTED, appMain);
}
}

void staticReview(void) {
warningDesc.predefinedSet = (1 << W3C_LOSING_SWAP_WARN) | (1 << BLIND_SIGNING_WARN);
warningDesc.reportProvider = "Blockaid";

// static review, providing the whole list of pairs
nbgl_useCaseReviewWithWarning(TYPE_TRANSACTION, // type of operation
&pairList, // list of tag/value pairs
coinIcon, // icon of the coin
"Review transaction\nto send coin", // title of the first page
NULL, // sub-title of the first page
"Sign transaction to\nsend coin?", // title of the last page
NULL, // no tip-box in first page of review
warningDesc, // description of warning causes
onReviewResult); // callback on result of the review
}
@endcode

Here is another version of the example code, not using predefined text:

@code
// 4 pairs of tag/value to display
static nbgl_layoutTagValue_t pairs[4];

static const nbgl_contentTagValueList_t pairList = {
.nbMaxLinesForValue = 0,
.nbPairs = 4,
.pairs = (nbgl_layoutTagValue_t*)pairs
};

// icons for first level warning details
static const nbgl_icon_details_t *barListIcons[] = {&WARNING_ICON, &INFO_I_ICON};

// first level warning details
static const char *const barListTexts[] = {"Blind signing", "Risk detected"};
static const char *const barListSubTexts[] = {"This transaction cannot be fully decoded.", "Web3 Checks found a risk:\nLosing swap"};
// second level warning details in prolog
static const struct nbgl_warningDetails_s barListIntroDetails[] = {
{.title = "Back",
.type = QRCODE_WARNING,
.qrCode = {.url = "ledger.com/e8", .text1 = "ledger.com/e8", .text2 = "Scan to learn about the risks of blind signing.", .centered = true}},
{.title = "Back",
.type = QRCODE_WARNING,
.qrCode = {.url = "url.com/od24xz", .text1 = "url.com/od24xz", .text2 = "Scan to view the risk report from Blockaid.", .centered = true}}
};

// second level warning details in review
static const struct nbgl_warningDetails_s barListIntroDetails[] = {
{.title = "Back",
.type = CENTERED_INFO_WARNING,
.centeredInfo = {.icon = &C_Warning_64px, .title = "Blind signing", .description = "This transaction’s details are not fully verifiable. If you sign it, you could lose all your assets.\n\nLearn about blind signing:
ledger.com/e8"}},
{.title = "Back",
.type = CENTERED_INFO_WARNING,
.centeredInfo = {.icon = &C_Warning_64px, .title = "Risk detected", .description = "This transaction was scanned as risky by Web3 Checks.\n\nView full Blockaid report:url.com/od24xz"}}
};

// info in main warning page
static const nbgl_contentCenter_t warningInfo = {
.icon = &C_Warning_64px,
.title = "Dangerous transaction",
.description = "This transaction cannot be fully decoded, and was marked risky by Web3 Checks."
};

// first level warning details in prolog
static const nbgl_warningDetails_t warningIntroDetails = {
.title = "Security report",
.type = BAR_LIST_WARNING,
.barList.nbBars = 2,
.barList.icons = barListIcons,
.texts = barListTexts,
.subTexts = barListSubTexts,
.barList.details = barListIntroDetails
};

// first level warning details in review (when pressing top-right from first and last pages)
static const nbgl_warningDetails_t warningReviewDetails = {
.title = "Security report",
.type = BAR_LIST_WARNING,
.barList.nbBars = 2,
.barList.icons = barListIcons,
.texts = barListTexts,
.subTexts = barListSubTexts,
.barList.details = barListReviewDetails
};

// warning description (cannot be in call stack)
static const nbgl_warning_t warningDesc = {
.info = &warningInfo,
.introTopRightIcon = &PRIVACY_ICON,
.reviewTopRightIcon = &WARNING_ICON,
.introDetails = &warningIntroDetails,
.reviewDetails = &warningReviewDetails
};

// called when long press button on 3rd page is long-touched or when reject footer is touched
static void onReviewResult(bool confirm) {
// display a status page and go back to main
if (confirm) {
nbgl_useCaseReviewStatus(STATUS_TYPE_TRANSACTION_SIGNED, appMain);
}
else {
nbgl_useCaseReviewStatus(STATUS_TYPE_TRANSACTION_REJECTED, appMain);
}
}

void staticReview(void) {
// static review, providing the whole list of pairs
nbgl_useCaseReviewWithWarning(TYPE_TRANSACTION, // type of operation
&pairList, // list of tag/value pairs
coinIcon, // icon of the coin
"Review transaction\nto send coin", // title of the first page
NULL, // sub-title of the first page
"Sign transaction to\nsend coin?", // title of the last page
NULL, // no tip-box in first page of review
warningDesc, // description of warning causes
onReviewResult); // callback on result of the review
}
@endcode

@subsection use_case_addr_review Address Review Use Case

\image{inline} html UseCase-AddressReview.png "caption" height=500
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added lib_nbgl/glyphs/32px/Exclamation_32px.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added lib_nbgl/glyphs/32px/Privacy_32px.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added lib_nbgl/glyphs/40px/Exclamation_40px.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added lib_nbgl/glyphs/40px/Important_Circle_40px.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added lib_nbgl/glyphs/40px/Privacy_40px.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions lib_nbgl/include/nbgl_obj.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,9 @@ extern "C" {
#define QRCODE_ICON C_QRCode_32px
#define MINI_PUSH_ICON C_Mini_Push_32px
#define WARNING_ICON C_Warning_32px
#define ROUND_WARN_ICON C_Important_Circle_32px
#define PRIVACY_ICON C_Privacy_32px
#define EXCLAMATION_ICON C_Exclamation_32px
#else // TARGET_STAX
#define SPACE_ICON C_Space_40px
#define BACKSPACE_ICON C_Erase_40px
Expand All @@ -146,6 +149,9 @@ extern "C" {
#define QRCODE_ICON C_QRCode_40px
#define MINI_PUSH_ICON C_Mini_Push_40px
#define WARNING_ICON C_Warning_40px
#define ROUND_WARN_ICON C_Important_Circle_40px
#define PRIVACY_ICON C_Privacy_40px
#define EXCLAMATION_ICON C_Exclamation_40px
#endif // TARGET_STAX

// For backward compatibility, to be remove later
Expand Down
1 change: 1 addition & 0 deletions lib_nbgl/include/nbgl_step.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ typedef void (*nbgl_stepMenuListCallback_t)(uint8_t choiceIndex);

/**
* @brief prototype of function to be called when buttons are touched on a screen
* @param stepCtx context returned by the nbgl_stepDrawXXX function
* @param event type of button event
*/
typedef void (*nbgl_stepButtonCallback_t)(nbgl_step_t stepCtx, nbgl_buttonEvent_t event);
Expand Down
104 changes: 100 additions & 4 deletions lib_nbgl/include/nbgl_use_case.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,10 +130,10 @@ typedef void (*nbgl_actionCallback_t)(uint8_t page);

/**
* @brief prototype of pin validation callback function
* @param content pin value
* @param length pin length
* @param pin pin value
* @param pinLen pin length
*/
typedef void (*nbgl_pinValidCallback_t)(const uint8_t *content, uint8_t page);
typedef void (*nbgl_pinValidCallback_t)(const uint8_t *pin, uint8_t pinLen);

/**
* @brief prototype of content navigation callback function
Expand Down Expand Up @@ -188,6 +188,87 @@ typedef struct {
};
} nbgl_tipBox_t;

/**
* @brief The different types of warning page contents
*
*/
typedef enum {
CENTERED_INFO_WARNING = 0, ///< Centered info
QRCODE_WARNING, ///< QR Code
BAR_LIST_WARNING ///< list of touchable bars, to display sub-pages
} nbgl_warningDetailsType_t;

/**
* @brief The necessary parameters to build a list of touchable bars, to display sub-pages
*
*/
typedef struct {
uint8_t nbBars; ///< number of touchable bars
const char *const *texts; ///< array of texts for each bar (nbBars items, in black/bold)
const char *const *subTexts; ///< array of texts for each bar (nbBars items, in black)
const nbgl_icon_details_t **icons; ///< array of icons for each bar (nbBars items)
const struct nbgl_warningDetails_s
cedelavergne-ledger marked this conversation as resolved.
Show resolved Hide resolved
*details; ///< array of nbBars structures giving what to display when each bar is touched.
} nbgl_warningBarList_t;

/**
* @brief The necessary parameters to build the page(s) displayed when the top-right button is
* touched in intro page (before review)
*
*/
typedef struct nbgl_warningDetails_s {
const char *title; ///< text of the page (used to go back)
nbgl_warningDetailsType_t
type; ///< type of content in the page, determining what to use in the following union
union {
nbgl_contentCenter_t
centeredInfo; ///< centered info, if type == @ref CENTERED_INFO_WARNING
#ifdef NBGL_QRCODE
nbgl_layoutQRCode_t qrCode; ///< QR code, if type == @ref QRCODE_WARNING
#endif // NBGL_QRCODE
nbgl_warningBarList_t barList; ///< touchable bars list, if type == @ref BAR_LIST_WARNING
};
} nbgl_warningDetails_t;

/**
* @brief The different types of pre-defined warnings
*
*/
typedef enum {
BLIND_SIGNING_WARN = 0, ///< Blind signing
W3C_ISSUE_WARN, ///< Web3 Checks issue
W3C_LOSING_SWAP_WARN, ///< Web3 Checks: Losing Swap risk
W3C_THREAT_DETECTED_WARN, ///< Web3 Checks: Thread detexted, malicious (know drainer)
NB_WARNING_TYPES
} nbgl_warningType_t;

/**
* @brief The necessary parameters to build a warning page preceding a review.
* One can either use `predefinedSet` when the warnings are already supported in @ref
* nbgl_warningType_t list, or use `introDetails` or `reviewDetails` to configure manually the
* warning pages
* @note it's also used to build the modal pages displayed when touching the top-right button in the
* review's first page
*
*/
typedef struct {
uint32_t predefinedSet; ///< bitfield of pre-defined warnings, to be taken in @ref
///< nbgl_warningType_t set it to 0 if not using pre-defined warnings
const char *reportProvider; ///< name of the security report provider, used in some strings
const nbgl_warningDetails_t
*introDetails; ///< details displayed when top-right button is touched in intro page
///< (before review) if using pre-defined configuration, set to NULL,
const nbgl_warningDetails_t
*reviewDetails; ///< details displayed when top-right button is touched in first/last page
///< of review if using pre-defined configuration, set to NULL
const nbgl_contentCenter_t
*info; ///< parameters to build the intro warning page, if not using pre-defined
const nbgl_icon_details_t
*introTopRightIcon; ///< icon to use in the intro warning page, if not using pre-defined
const nbgl_icon_details_t *reviewTopRightIcon; ///< icon to use in the first/last page of
///< review, if not using pre-defined
} nbgl_warning_t;

/**
* @brief The different types of operation to review
*
Expand Down Expand Up @@ -265,7 +346,15 @@ void nbgl_useCaseReviewBlindSigning(nbgl_operationType_t operationT
const char *finishTitle,
const nbgl_tipBox_t *tipBox,
nbgl_choiceCallback_t choiceCallback);

void nbgl_useCaseReviewWithWarning(nbgl_operationType_t operationType,
const nbgl_contentTagValueList_t *tagValueList,
const nbgl_icon_details_t *icon,
const char *reviewTitle,
const char *reviewSubTitle,
const char *finishTitle,
const nbgl_tipBox_t *tipBox,
const nbgl_warning_t *warning,
nbgl_choiceCallback_t choiceCallback);
void nbgl_useCaseAdvancedReview(nbgl_operationType_t operationType,
const nbgl_contentTagValueList_t *tagValueList,
const nbgl_icon_details_t *icon,
Expand Down Expand Up @@ -305,6 +394,13 @@ void nbgl_useCaseReviewStreamingBlindSigningStart(nbgl_operationType_t ope
const char *reviewSubTitle,
nbgl_choiceCallback_t choiceCallback);

void nbgl_useCaseReviewStreamingWithWarningStart(nbgl_operationType_t operationType,
const nbgl_icon_details_t *icon,
const char *reviewTitle,
const char *reviewSubTitle,
const nbgl_warning_t *warning,
nbgl_choiceCallback_t choiceCallback);

void nbgl_useCaseReviewStreamingContinueExt(const nbgl_contentTagValueList_t *tagValueList,
nbgl_choiceCallback_t choiceCallback,
nbgl_callback_t skipCallback);
Expand Down
Loading
Loading