17#include "os_helpers.h"
23#define WITH_HORIZONTAL_CHOICES_LIST
24#define WITH_HORIZONTAL_BARS_LIST
31#define RISKY_OPERATION (1 << 6)
38#define NO_THREAT_OPERATION (1 << 7)
44typedef struct ReviewContext_s {
48 const char *reviewTitle;
49 const char *reviewSubTitle;
50 const char *finishTitle;
55 uint8_t dataDirection;
56 uint8_t currentTagValueIndex;
57 uint8_t currentExtensionPage;
58 uint8_t nbExtensionPages;
64typedef struct ChoiceContext_s {
67 const char *subMessage;
68 const char *confirmText;
69 const char *cancelText;
74typedef struct ConfirmContext_s {
76 const char *subMessage;
77 const char *confirmText;
78 const char *cancelText;
83typedef struct ContentContext_s {
86 const char *rejectText;
92typedef struct HomeContext_s {
102typedef struct ActionContext_s {
107typedef struct KeypadContext_s {
110 uint8_t pinMinDigits;
111 uint8_t pinMaxDigits;
124 GENERIC_REVIEW_USE_CASE,
125 ADDRESS_REVIEW_USE_CASE,
126 STREAMING_START_REVIEW_USE_CASE,
127 STREAMING_CONTINUE_REVIEW_USE_CASE,
128 STREAMING_FINISH_REVIEW_USE_CASE,
141typedef struct UseCaseContext_s {
146 int8_t firstPairPage;
150 ReviewContext_t review;
151 ChoiceContext_t choice;
152 ConfirmContext_t confirm;
154 ContentContext_t content;
156 KeypadContext_t keypad;
158 ActionContext_t action;
162typedef struct PageContent_s {
172typedef struct ReviewWithWarningContext_s {
177 const char *reviewTitle;
178 const char *reviewSubTitle;
179 const char *finishTitle;
182 uint8_t securityReportLevel;
185 uint8_t nbWarningPages;
186} ReviewWithWarningContext_t;
197static UseCaseContext_t context;
199static ReviewWithWarningContext_t reviewWithWarnCtx;
217static void displaySpinner(
const char *text);
219static void startUseCaseHome(
void);
220static void startUseCaseInfo(
void);
221static void startUseCaseSettings(
void);
222static void startUseCaseSettingsAtPage(uint8_t initSettingPage);
223static void startUseCaseContent(
void);
225static void statusTickerCallback(
void);
228static void displayWarningStep(
void);
233 switch (content->
type) {
260 if (contentIdx < 0 || contentIdx >= genericContents->
nbContents) {
266 if (content == NULL) {
272 if (context.content.navCallback) {
273 if (context.content.navCallback(contentIdx, &pageContent) ==
true) {
276 switch (content->
type) {
322 uint8_t *elemContentIdx,
328 uint8_t elemNbPages = 0;
330 switch (context.type) {
331 case SETTINGS_USE_CASE:
333 case GENERIC_SETTINGS:
334 genericContents = context.home.settingContents;
336 case CONTENT_USE_CASE:
337 case GENERIC_REVIEW_USE_CASE:
338 genericContents = &context.content.genericContents;
343 for (
int i = 0; i < genericContents->
nbContents; i++) {
344 p_content = getContentAtIdx(genericContents, i, content);
345 elemNbPages = getContentNbElement(p_content);
346 if (nbPages + elemNbPages > elemIdx) {
347 *elemContentIdx = context.currentPage - nbPages;
350 nbPages += elemNbPages;
356static const char *getChoiceName(uint8_t choiceIndex)
366 p_content = getContentElemAtIdx(context.currentPage, &elemIdx, &content);
367 if (p_content == NULL) {
370 switch (p_content->
type) {
373 names = (
char **) PIC(contentChoices->
names);
378 names = (
char **) PIC(contentBars->
barTexts);
379 nbValues = contentBars->
nbBars;
385 if (choiceIndex >= nbValues) {
389 return (
const char *) PIC(names[choiceIndex]);
392static void onChoiceSelected(uint8_t choiceIndex)
401 p_content = getContentElemAtIdx(context.currentPage, &elemIdx, &content);
402 if (p_content == NULL) {
405 switch (p_content->
type) {
408 if (choiceIndex < contentChoices->nbChoices) {
409 token = contentChoices->
token;
414 if (choiceIndex < contentBars->nbBars) {
415 token = contentBars->
tokens[choiceIndex];
422 if ((token != 255) && (context.content.controlsCallback != NULL)) {
423 context.content.controlsCallback(token, 0);
425 else if (context.content.quitCallback != NULL) {
426 context.content.quitCallback();
436 bool *isCenteredInfo)
440 if (tagValueList->
pairs != NULL) {
441 pair = PIC(&tagValueList->
pairs[index]);
444 pair = PIC(tagValueList->
callback(index));
447 *value = pair->
value;
452 *isCenteredInfo =
true;
460static void onReviewAccept(
void)
462 if (context.review.onChoice) {
463 context.review.onChoice(
true);
467static void onReviewReject(
void)
469 if (context.review.onChoice) {
470 context.review.onChoice(
false);
474static void onChoiceAccept(
void)
476 if (context.choice.onChoice) {
477 context.choice.onChoice(
true);
481static void onChoiceReject(
void)
483 if (context.choice.onChoice) {
484 context.choice.onChoice(
false);
488static void onConfirmAccept(
void)
490 if (context.confirm.currentStep) {
493 if (context.confirm.onConfirm) {
494 context.confirm.onConfirm();
498static void onConfirmReject(
void)
500 if (context.confirm.currentStep) {
507static void onSwitchAction(
void)
514 p_content = getContentElemAtIdx(context.currentPage, &elemIdx, &content);
520 switch (context.type) {
521 case SETTINGS_USE_CASE:
523 case GENERIC_SETTINGS:
526 case CONTENT_USE_CASE:
527 case GENERIC_REVIEW_USE_CASE:
535 actionCallback(contentSwitch->
token,
537 context.currentPage);
539 else if (context.content.controlsCallback != NULL) {
540 context.content.controlsCallback(contentSwitch->
token, 0);
550 ForcedType_t forcedType)
561 .tickerIntervale = 0,
567 if ((context.type == STREAMING_CONTINUE_REVIEW_USE_CASE)
568 && (context.review.skipCallback != NULL) && (context.review.nbDataSets > 1)) {
571 if ((context.type == STATUS_USE_CASE) || (context.type == SPINNER_USE_CASE)) {
574 if ((context.type == CONFIRM_USE_CASE) && (context.confirm.currentStep != NULL)) {
579 p_content = getContentElemAtIdx(context.currentPage, &elemIdx, &content);
581 switch (p_content->
type) {
603 else if ((icon == NULL) && (forcedType != FORCE_CENTERED_INFO)) {
605 if (subTxt != NULL) {
606 style = (forcedType == FORCE_BUTTON) ? BUTTON_INFO : BOLD_TEXT1_INFO;
609 style = REGULAR_INFO;
611 newStep =
nbgl_stepDrawText(pos, onActionCallback, p_ticker, txt, subTxt, style, modal);
619 if ((subTxt != NULL) || (context.stepCallback != NULL)) {
620 info.
style = BOLD_TEXT1_INFO;
623 info.
style = REGULAR_INFO;
627 if (context.type == CONFIRM_USE_CASE) {
628 context.confirm.currentStep = newStep;
634 const char *description,
643 switchInfo.
text = title;
644 switchInfo.
subText = description;
657 if (context.currentPage > 0) {
658 context.currentPage--;
662 else if ((context.type != STREAMING_CONTINUE_REVIEW_USE_CASE)
663 || (context.review.skipCallback == NULL) || (context.review.nbDataSets == 1)) {
670 if (context.currentPage < (
int) (context.nbPages - 1)) {
671 context.currentPage++;
681 if (context.stepCallback != NULL) {
682 context.stepCallback();
684 else if ((context.type == CONTENT_USE_CASE) || (context.type == SETTINGS_USE_CASE)
685 || (context.type == GENERIC_SETTINGS)
686 || (context.type == GENERIC_REVIEW_USE_CASE)) {
687 p_content = getContentElemAtIdx(context.currentPage, &elemIdx, &content);
688 if (p_content != NULL) {
689 switch (p_content->
type) {
704 index = context.currentPage;
713 else if (context.content.controlsCallback != NULL) {
714 context.content.controlsCallback(token, index);
729 if (!buttonGenericCallback(event, &pos)) {
734 context.review.dataDirection = pos;
736 displayReviewPage(pos);
748 && (context.currentPage > context.firstPairPage)) {
749 context.currentPage--;
756 && (context.currentPage < (
int) (context.nbPages - 1))
757 && (context.currentPage > context.firstPairPage)) {
758 context.currentPage++;
764 if (context.firstPairPage == 0) {
766 context.review.skipCallback();
770 context.currentPage = context.nbPages - 2;
779 if (context.firstPairPage == 0) {
780 displayStreamingReviewPage(pos);
783 displayReviewPage(pos);
793 context.action.actionCallback();
802 if (!buttonGenericCallback(event, &pos)) {
807 context.review.dataDirection = pos;
810 displayStreamingReviewPage(pos);
818 if (!buttonGenericCallback(event, &pos)) {
822 displaySettingsPage(pos,
false);
830 if (!buttonGenericCallback(event, &pos)) {
834 displayInfoPage(pos);
842 if (!buttonGenericCallback(event, &pos)) {
846 displayHomePage(pos);
854 if (!buttonGenericCallback(event, &pos)) {
858 displayChoicePage(pos);
866 if (!buttonGenericCallback(event, &pos)) {
879 if (context.stepCallback != NULL) {
880 context.stepCallback();
890 if (!buttonGenericCallback(event, &pos)) {
894 displayContent(pos,
false);
898static void statusTickerCallback(
void)
900 if (context.stepCallback != NULL) {
901 context.stepCallback();
913 if (context.review.currentExtensionPage > 0) {
914 context.review.currentExtensionPage--;
920 if (context.review.currentExtensionPage < (context.review.nbExtensionPages - 1)) {
921 context.review.currentExtensionPage++;
927 if (context.review.currentExtensionPage == (context.review.nbExtensionPages - 1)) {
937 displayExtensionStep(pos);
946 const char *text = NULL;
947 const char *subText = NULL;
949 if (context.review.extensionStepCtx != NULL) {
952 if (context.review.currentExtensionPage < (context.review.nbExtensionPages - 1)) {
953 if (context.review.currentExtensionPage == 0) {
960 switch (context.review.extension->aliasType) {
962 text = context.review.extension->title;
963 subText = context.review.extension->fullValue;
966 infoList = context.review.extension->infolist;
967 text = PIC(infoList->
infoTypes[context.review.currentExtensionPage]);
968 subText = PIC(infoList->
infoContents[context.review.currentExtensionPage]);
971 tagValueList = context.review.extension->tagValuelist;
972 text = PIC(tagValueList->
pairs[context.review.currentExtensionPage].
item);
973 subText = PIC(tagValueList->
pairs[context.review.currentExtensionPage].
value);
980 pos, extensionNavigate, NULL, text, subText, BOLD_TEXT1_INFO,
true);
983 else if (context.review.currentExtensionPage == (context.review.nbExtensionPages - 1)) {
985 info.
icon = &C_icon_back_x;
987 info.
style = BOLD_TEXT1_INFO;
989 context.review.extensionStepCtx
995static void displayAliasFullValue(
void)
997 const char *text = NULL;
998 const char *subText = NULL;
1000 bool isCenteredInfo;
1002 getPairData(context.review.tagValueList,
1003 context.review.currentTagValueIndex,
1006 &context.review.extension,
1009 if (context.review.extension == NULL) {
1012 "displayAliasFullValue: extension nor found for pair %d\n",
1013 context.review.currentTagValueIndex);
1016 context.review.currentExtensionPage = 0;
1017 context.review.extensionStepCtx = NULL;
1019 switch (context.review.extension->aliasType) {
1021 context.review.nbExtensionPages = 2;
1024 context.review.nbExtensionPages = context.review.extension->infolist->nbInfos + 1;
1027 context.review.nbExtensionPages = context.review.extension->tagValuelist->nbPairs + 1;
1031 "displayAliasFullValue: unsupported alias type %d\n",
1032 context.review.extension->aliasType);
1038static void getLastPageInfo(
bool approve,
const nbgl_icon_details_t **icon,
const char **text)
1042 *icon = &C_icon_validate_14;
1043 if (context.type == ADDRESS_REVIEW_USE_CASE) {
1048 if (context.review.finishTitle != NULL) {
1049 *text = context.review.finishTitle;
1054 if (context.operationType & RISKY_OPERATION) {
1055 *text =
"Accept risk and sign transaction";
1058 *text =
"Sign transaction";
1062 if (context.operationType & RISKY_OPERATION) {
1063 *text =
"Accept risk and sign message";
1066 *text =
"Sign message";
1070 if (context.operationType & RISKY_OPERATION) {
1071 *text =
"Accept risk and sign operation";
1074 *text =
"Sign operation";
1080 context.stepCallback = onReviewAccept;
1084 *icon = &C_icon_crossmark;
1085 if (context.type == ADDRESS_REVIEW_USE_CASE) {
1089 *text =
"Reject transaction";
1092 *text =
"Reject message";
1095 *text =
"Reject operation";
1097 context.stepCallback = onReviewReject;
1104 uint8_t reviewPages = 0;
1105 uint8_t finalPages = 0;
1106 uint8_t pairIndex = 0;
1107 const char *text = NULL;
1108 const char *subText = NULL;
1110 uint8_t currentIndex = 0;
1111 uint8_t titleIndex = 255;
1112 uint8_t subIndex = 255;
1113 uint8_t approveIndex = 255;
1114 uint8_t rejectIndex = 255;
1116 ForcedType_t forcedType = NO_FORCED_TYPE;
1118 context.stepCallback = NULL;
1122 titleIndex = currentIndex++;
1124 if (context.review.reviewSubTitle) {
1126 subIndex = currentIndex++;
1129 approveIndex = context.nbPages - 2;
1130 rejectIndex = context.nbPages - 1;
1131 finalPages = approveIndex;
1134 if (context.currentPage >= finalPages) {
1135 if (context.currentPage == approveIndex) {
1137 getLastPageInfo(
true, &icon, &text);
1139 else if (context.currentPage == rejectIndex) {
1141 getLastPageInfo(
false, &icon, &text);
1144 else if (context.currentPage < reviewPages) {
1145 if (context.currentPage == titleIndex) {
1147 icon = context.review.icon;
1148 text = context.review.reviewTitle;
1150 else if (context.currentPage == subIndex) {
1152 text = context.review.reviewSubTitle;
1155 else if ((context.review.address != NULL) && (context.currentPage == reviewPages)) {
1158 subText = context.review.address;
1164 if ((context.operationType &
SKIPPABLE_OPERATION) && (context.review.skipDisplay ==
false)
1165 && ((context.currentPage > reviewPages)
1169 if ((context.review.nbDataSets == 1) || (context.currentPage > 0)) {
1172 info.
icon = &C_Information_circle_14px;
1173 info.
text1 =
"Press right button to continue message or \bpress both to skip\b";
1176 context.review.skipDisplay =
true;
1177 context.firstPairPage = reviewPages;
1180 context.review.skipDisplay =
false;
1181 bool isCenteredInfo =
false;
1182 pairIndex = context.currentPage - reviewPages;
1183 if (context.review.address != NULL) {
1186 getPairData(context.review.tagValueList,
1193 if (extension != NULL) {
1194 context.stepCallback = displayAliasFullValue;
1195 context.review.currentTagValueIndex = pairIndex;
1196 forcedType = FORCE_BUTTON;
1199 if (isCenteredInfo) {
1200 forcedType = FORCE_CENTERED_INFO;
1205 drawStep(pos, icon, text, subText, reviewCallback,
false, forcedType);
1212 const char *text = NULL;
1213 const char *subText = NULL;
1215 uint8_t reviewPages = 0;
1216 uint8_t titleIndex = 255;
1217 uint8_t subIndex = 255;
1219 ForcedType_t forcedType = NO_FORCED_TYPE;
1221 context.stepCallback = NULL;
1222 switch (context.type) {
1223 case STREAMING_START_REVIEW_USE_CASE:
1225 titleIndex = reviewPages++;
1226 if (context.review.reviewSubTitle) {
1228 subIndex = reviewPages++;
1231 if (context.currentPage >= reviewPages) {
1236 if (context.currentPage == titleIndex) {
1238 icon = context.review.icon;
1239 text = context.review.reviewTitle;
1241 else if (context.currentPage == subIndex) {
1243 text = context.review.reviewSubTitle;
1247 case STREAMING_CONTINUE_REVIEW_USE_CASE:
1248 if (context.currentPage >= context.review.tagValueList->nbPairs) {
1255 if ((context.review.skipCallback != NULL) && (context.review.skipDisplay ==
false)
1256 && ((context.review.nbDataSets > 1) || (context.currentPage > 0)
1260 if ((context.review.nbDataSets == 1) || (context.currentPage > 0)) {
1263 info.
icon = &C_Information_circle_14px;
1264 info.
text1 =
"Press right button to continue message or \bpress both to skip\b";
1267 context.review.skipDisplay =
true;
1270 context.review.skipDisplay =
false;
1271 bool isCenteredInfo =
false;
1272 getPairData(context.review.tagValueList,
1273 context.currentPage,
1279 if (extension != NULL) {
1280 forcedType = FORCE_BUTTON;
1283 if (isCenteredInfo) {
1284 forcedType = FORCE_CENTERED_INFO;
1289 case STREAMING_FINISH_REVIEW_USE_CASE:
1291 if (context.currentPage == 0) {
1293 getLastPageInfo(
true, &icon, &text);
1297 getLastPageInfo(
false, &icon, &text);
1302 drawStep(pos, icon, text, subText, streamingReviewCallback,
false, forcedType);
1309 const char *text = NULL;
1310 const char *subText = NULL;
1313 context.stepCallback = NULL;
1315 if (context.currentPage < (context.nbPages - 1)) {
1317 ((
const char *
const *) PIC(context.home.infosList->infoTypes))[context.currentPage]);
1319 ((
const char *
const *) PIC(context.home.infosList->infoContents))[context.currentPage]);
1322 icon = &C_icon_back_x;
1324 context.stepCallback = startUseCaseHome;
1327 drawStep(pos, icon, text, subText, infoCallback,
false, FORCE_CENTERED_INFO);
1332static void getContentPage(
bool toogle_state, PageContent_t *contentPage)
1334 uint8_t elemIdx = 0;
1338#ifdef WITH_HORIZONTAL_CHOICES_LIST
1340 char **names = NULL;
1342#ifdef WITH_HORIZONTAL_BARS_LIST
1344 char **texts = NULL;
1346 p_content = getContentElemAtIdx(context.currentPage, &elemIdx, &content);
1347 if (p_content == NULL) {
1350 switch (p_content->
type) {
1364 &contentPage->subText,
1365 &contentPage->extension,
1367 &contentPage->isCenteredInfo);
1370 contentPage->isSwitch =
true;
1373 contentPage->
text = contentSwitch->
text;
1374 contentPage->state = contentSwitch->
initState;
1378 context.stepCallback = onSwitchAction;
1379 contentPage->subText = contentSwitch->
subText;
1384 contentPage->subText
1388#ifdef WITH_HORIZONTAL_CHOICES_LIST
1390 names = (
char **) PIC(contentChoices->
names);
1391 if ((context.type == CONTENT_USE_CASE) && (context.content.title != NULL)) {
1392 contentPage->text = PIC(context.content.title);
1393 contentPage->subText = (
const char *) PIC(names[elemIdx]);
1395 else if ((context.type == GENERIC_SETTINGS) && (context.home.appName != NULL)) {
1396 contentPage->text = PIC(context.home.appName);
1397 contentPage->subText = (
const char *) PIC(names[elemIdx]);
1400 contentPage->text = (
const char *) PIC(names[elemIdx]);
1405#ifdef WITH_HORIZONTAL_BARS_LIST
1407 texts = (
char **) PIC(contentBars->
barTexts);
1408 if ((context.type == CONTENT_USE_CASE) && (context.content.title != NULL)) {
1409 contentPage->text = PIC(context.content.title);
1410 contentPage->subText = PIC(texts[elemIdx]);
1412 else if ((context.type == GENERIC_SETTINGS) && (context.home.appName != NULL)) {
1413 contentPage->text = PIC(context.home.appName);
1414 contentPage->subText = PIC(texts[elemIdx]);
1417 contentPage->text = PIC(texts[elemIdx]);
1429 PageContent_t contentPage = {0};
1431 context.stepCallback = NULL;
1433 if (context.currentPage < (context.nbPages - 1)) {
1434 getContentPage(toogle_state, &contentPage);
1437 contentPage.icon = &C_icon_back_x;
1438 contentPage.text =
"Back";
1439 if (context.type == GENERIC_SETTINGS) {
1440 context.stepCallback = context.home.quitCallback;
1443 context.stepCallback = startUseCaseHome;
1447 if (contentPage.isSwitch) {
1449 pos, contentPage.text, contentPage.subText, contentPage.state, settingsCallback,
false);
1455 contentPage.subText,
1464static void startUseCaseHome(
void)
1466 switch (context.type) {
1467 case SETTINGS_USE_CASE:
1469 context.currentPage = 1;
1470 if (context.home.homeAction) {
1472 context.currentPage++;
1477 context.currentPage = 1;
1478 if (context.home.homeAction) {
1480 context.currentPage++;
1482 if (context.home.settingContents) {
1484 context.currentPage++;
1489 context.currentPage = 0;
1493 context.type = HOME_USE_CASE;
1494 context.nbPages = 2;
1495 if (context.home.settingContents) {
1498 if (context.home.infosList) {
1501 if (context.home.homeAction) {
1507static void startUseCaseInfo(
void)
1509 context.type = INFO_USE_CASE;
1510 context.nbPages = context.home.infosList->nbInfos + 1;
1511 context.currentPage = 0;
1516static void startUseCaseSettingsAtPage(uint8_t initSettingPage)
1522 if (context.type != GENERIC_SETTINGS) {
1523 context.
type = SETTINGS_USE_CASE;
1526 context.nbPages = 1;
1527 for (
int i = 0; i < context.home.settingContents->nbContents; i++) {
1528 p_content = getContentAtIdx(context.home.settingContents, i, &content);
1529 context.nbPages += getContentNbElement(p_content);
1531 context.currentPage = initSettingPage;
1536static void startUseCaseSettings(
void)
1538 startUseCaseSettingsAtPage(0);
1541static void startUseCaseContent(
void)
1543 uint8_t contentIdx = 0;
1547 context.nbPages = 1;
1549 for (contentIdx = 0; contentIdx < context.content.genericContents.nbContents; contentIdx++) {
1550 p_content = getContentAtIdx(&context.content.genericContents, contentIdx, &content);
1551 context.nbPages += getContentNbElement(p_content);
1555 if (context.currentPage >= context.nbPages) {
1565 const char *text = NULL;
1566 const char *subText = NULL;
1568 uint8_t currentIndex = 0;
1569 uint8_t homeIndex = 255;
1570 uint8_t actionIndex = 255;
1571 uint8_t settingsIndex = 255;
1572 uint8_t infoIndex = 255;
1574 context.stepCallback = NULL;
1577 homeIndex = currentIndex++;
1578 if (context.home.homeAction) {
1579 actionIndex = currentIndex++;
1581 if (context.home.settingContents) {
1582 settingsIndex = currentIndex++;
1584 if (context.home.infosList) {
1585 infoIndex = currentIndex++;
1588 if (context.currentPage == homeIndex) {
1590 icon = context.home.appIcon;
1591 if (context.home.tagline != NULL) {
1592 text = context.home.tagline;
1595 text = context.home.appName;
1596 subText =
"app is ready";
1599 else if (context.currentPage == actionIndex) {
1601 icon = context.home.homeAction->icon;
1602 text = PIC(context.home.homeAction->text);
1603 context.stepCallback = context.home.homeAction->callback;
1605 else if (context.currentPage == settingsIndex) {
1607 icon = &C_icon_coggle;
1608 text =
"App settings";
1609 context.stepCallback = startUseCaseSettings;
1611 else if (context.currentPage == infoIndex) {
1613 icon = &C_Information_circle_14px;
1615 context.stepCallback = startUseCaseInfo;
1618 icon = &C_Quit_14px;
1620 context.stepCallback = context.home.quitCallback;
1623 drawStep(pos, icon, text, subText, homeCallback,
false, NO_FORCED_TYPE);
1630 const char *text = NULL;
1631 const char *subText = NULL;
1634 uint8_t acceptPage = 0;
1636 if (context.choice.message != NULL) {
1637 if ((context.choice.icon == NULL) || (context.choice.subMessage == NULL)) {
1644 context.stepCallback = NULL;
1646 if (context.currentPage < acceptPage) {
1647 if (context.currentPage == 0) {
1648 text = context.choice.message;
1649 if (context.choice.icon != NULL) {
1650 icon = context.choice.icon;
1653 subText = context.choice.subMessage;
1656 else if ((acceptPage == 2) && (context.currentPage == 1)) {
1658 text = context.choice.message;
1659 subText = context.choice.subMessage;
1662 else if (context.currentPage == acceptPage) {
1663 icon = &C_icon_validate_14;
1664 text = context.choice.confirmText;
1665 context.stepCallback = onChoiceAccept;
1667 else if (context.currentPage == (acceptPage + 1)) {
1668 icon = &C_icon_crossmark;
1669 text = context.choice.cancelText;
1670 context.stepCallback = onChoiceReject;
1672 else if (context.choice.details != NULL) {
1675 text = context.choice.details->barList.texts[context.currentPage - (acceptPage + 2)];
1677 = context.choice.details->barList.subTexts[context.currentPage - (acceptPage + 2)];
1681 drawStep(pos, icon, text, subText, genericChoiceCallback,
false, NO_FORCED_TYPE);
1688 const char *text = NULL;
1689 const char *subText = NULL;
1692 context.stepCallback = NULL;
1693 switch (context.currentPage) {
1696 text = context.confirm.message;
1697 subText = context.confirm.subMessage;
1701 icon = &C_icon_validate_14;
1702 text = context.confirm.confirmText;
1703 context.stepCallback = onConfirmAccept;
1707 icon = &C_icon_crossmark;
1708 text = context.confirm.cancelText;
1709 context.stepCallback = onConfirmReject;
1713 drawStep(pos, icon, text, subText, genericConfirmCallback,
true, NO_FORCED_TYPE);
1720 PageContent_t contentPage = {0};
1721 ForcedType_t forcedType = NO_FORCED_TYPE;
1723 context.stepCallback = NULL;
1725 if (context.currentPage < (context.nbPages - 1)) {
1726 getContentPage(toogle_state, &contentPage);
1727 if (contentPage.isCenteredInfo) {
1728 forcedType = FORCE_CENTERED_INFO;
1732 if (context.content.rejectText) {
1733 contentPage.text = context.content.rejectText;
1736 contentPage.text =
"Back";
1738 if (context.type == GENERIC_REVIEW_USE_CASE) {
1739 contentPage.icon = &C_icon_crossmark;
1742 contentPage.icon = &C_icon_back_x;
1744 context.stepCallback = context.content.quitCallback;
1747 if (contentPage.isSwitch) {
1749 pos, contentPage.text, contentPage.subText, contentPage.state, contentCallback,
false);
1755 contentPage.subText,
1764static void displaySpinner(
const char *text)
1766 drawStep(
SINGLE_STEP, &C_icon_processing, text, NULL, NULL,
false,
false);
1771static void useCaseReview(ContextType_t type,
1775 const char *reviewTitle,
1776 const char *reviewSubTitle,
1777 const char *finishTitle,
1780 memset(&context, 0,
sizeof(UseCaseContext_t));
1781 context.type = type;
1782 context.operationType = operationType;
1783 context.review.tagValueList = tagValueList;
1784 context.review.reviewTitle = reviewTitle;
1785 context.review.reviewSubTitle = reviewSubTitle;
1786 context.review.finishTitle = finishTitle;
1787 context.review.icon = icon;
1788 context.review.onChoice = choiceCallback;
1789 context.currentPage = 0;
1791 context.nbPages = tagValueList->
nbPairs + 3;
1792 if (reviewSubTitle) {
1800static void setPinCodeText(
void)
1802 bool enableValidate =
false;
1803 bool enableBackspace =
true;
1806 enableValidate = (context.keypad.pinLen >= context.keypad.pinMinDigits);
1808 enableBackspace = (context.keypad.pinLen > 0) || (context.keypad.backCallback != NULL);
1810 context.keypad.hidden,
1811 context.keypad.pinLen,
1812 (
const char *) context.keypad.pinEntry);
1814 context.keypad.layoutCtx, context.keypad.keypadIndex, enableValidate, enableBackspace);
1820static void keypadCallback(
char touchedKey)
1822 switch (touchedKey) {
1824 if (context.keypad.pinLen > 0) {
1825 context.keypad.pinLen--;
1826 context.keypad.pinEntry[context.keypad.pinLen] = 0;
1828 else if (context.keypad.backCallback != NULL) {
1829 context.keypad.backCallback();
1836 context.keypad.validatePin(context.keypad.pinEntry, context.keypad.pinLen);
1840 if ((touchedKey >= 0x30) && (touchedKey < 0x40)) {
1841 if (context.keypad.pinLen < context.keypad.pinMaxDigits) {
1842 context.keypad.pinEntry[context.keypad.pinLen] = touchedKey;
1843 context.keypad.pinLen++;
1853static void launchReviewAfterWarning(
void)
1855 if (reviewWithWarnCtx.type == REVIEW_USE_CASE) {
1856 useCaseReview(reviewWithWarnCtx.type,
1857 reviewWithWarnCtx.operationType,
1858 reviewWithWarnCtx.tagValueList,
1859 reviewWithWarnCtx.icon,
1860 reviewWithWarnCtx.reviewTitle,
1861 reviewWithWarnCtx.reviewSubTitle,
1862 reviewWithWarnCtx.finishTitle,
1863 reviewWithWarnCtx.choiceCallback);
1865 else if (reviewWithWarnCtx.type == STREAMING_START_REVIEW_USE_CASE) {
1877 if (reviewWithWarnCtx.warningPage > 0) {
1878 reviewWithWarnCtx.warningPage--;
1883 if (reviewWithWarnCtx.warningPage < (reviewWithWarnCtx.nbWarningPages - 1)) {
1884 reviewWithWarnCtx.warningPage++;
1886 else if ((reviewWithWarnCtx.warning->predefinedSet == 0)
1887 && (reviewWithWarnCtx.warning->info != NULL)) {
1888 launchReviewAfterWarning();
1895 if (reviewWithWarnCtx.warningPage == 0) {
1896 launchReviewAfterWarning();
1899 else if (reviewWithWarnCtx.warningPage == (reviewWithWarnCtx.nbWarningPages - 1)) {
1900 reviewWithWarnCtx.choiceCallback(
false);
1907 displayWarningStep();
1911static void displayWarningStep(
void)
1916 if (reviewWithWarnCtx.warningPage == 0) {
1918 info.
icon = &C_icon_warning;
1919 info.
text1 =
"Blind signing ahead";
1920 info.
text2 =
"To accept risk, press both buttons";
1923 else if (reviewWithWarnCtx.warningPage == (reviewWithWarnCtx.nbWarningPages - 1)) {
1924 getLastPageInfo(
false, &info.
icon, &info.
text1);
1928 else if ((reviewWithWarnCtx.warning->predefinedSet == 0)
1929 && (reviewWithWarnCtx.warning->info != NULL)) {
1930 if (reviewWithWarnCtx.warningPage == 0) {
1931 info.
icon = reviewWithWarnCtx.warning->info->icon;
1932 info.
text1 = reviewWithWarnCtx.warning->info->title;
1933 info.
text2 = reviewWithWarnCtx.warning->info->description;
1936 else if (reviewWithWarnCtx.warningPage == (reviewWithWarnCtx.nbWarningPages - 1)) {
1938 info.
icon = reviewWithWarnCtx.warning->introDetails->centeredInfo.icon;
1939 info.
text1 = reviewWithWarnCtx.warning->introDetails->centeredInfo.title;
1940 info.
text2 = reviewWithWarnCtx.warning->introDetails->centeredInfo.description;
1953 info.
style = BOLD_TEXT1_INFO;
1959static void displayInitialWarning(
void)
1962 reviewWithWarnCtx.warningPage = 0;
1963 reviewWithWarnCtx.nbWarningPages = 2;
1964 displayWarningStep();
1985 bool *requireSpecificDisplay)
1988 UNUSED(tagValueList);
1990 *requireSpecificDisplay =
true;
2010 bool *requireSpecificDisplay)
2013 UNUSED(tagValueList);
2015 UNUSED(isSkippable);
2016 *requireSpecificDisplay =
true;
2054 UNUSED(switchesList);
2094 UNUSED(choicesList);
2108 uint8_t nbPages = 0;
2109 uint8_t nbPairs = tagValueList->
nbPairs;
2110 uint8_t nbPairsInPage;
2114 while (i < tagValueList->nbPairs) {
2118 nbPairs -= nbPairsInPage;
2144 memset(&context, 0,
sizeof(UseCaseContext_t));
2145 context.type = CONTENT_USE_CASE;
2146 context.currentPage = initPage;
2147 context.content.title = title;
2148 context.content.quitCallback = quitCallback;
2149 context.content.navCallback = navCallback;
2150 context.content.controlsCallback = controlsCallback;
2151 context.content.genericContents.callbackCallNeeded =
true;
2152 context.content.genericContents.nbContents = nbPages;
2154 startUseCaseContent();
2173 const char *tagline,
2174 const uint8_t initSettingPage,
2180 memset(&context, 0,
sizeof(UseCaseContext_t));
2181 context.home.appName = appName;
2182 context.home.appIcon = appIcon;
2183 context.home.tagline = tagline;
2184 context.home.settingContents = PIC(settingContents);
2185 context.home.infosList = PIC(infosList);
2186 context.home.homeAction = action;
2187 context.home.quitCallback = quitCallback;
2189 if ((initSettingPage !=
INIT_HOME_PAGE) && (settingContents != NULL)) {
2190 startUseCaseSettingsAtPage(initSettingPage);
2215 memset(&context, 0,
sizeof(UseCaseContext_t));
2216 context.type = GENERIC_SETTINGS;
2217 context.home.appName = appName;
2218 context.home.settingContents = PIC(settingContents);
2219 context.home.infosList = PIC(infosList);
2220 context.home.quitCallback = quitCallback;
2222 startUseCaseSettingsAtPage(initPage);
2261 const char *reviewTitle,
2262 const char *reviewSubTitle,
2263 const char *finishTitle,
2266 useCaseReview(REVIEW_USE_CASE,
2301 const char *reviewTitle,
2302 const char *reviewSubTitle,
2303 const char *finishTitle,
2309 ContextType_t type = REVIEW_USE_CASE;
2312 if ((warning == NULL)
2326 operationType |= NO_THREAT_OPERATION;
2329 operationType |= RISKY_OPERATION;
2332 memset(&reviewWithWarnCtx, 0,
sizeof(reviewWithWarnCtx));
2333 reviewWithWarnCtx.type = type;
2334 reviewWithWarnCtx.operationType = operationType;
2335 reviewWithWarnCtx.tagValueList = tagValueList;
2336 reviewWithWarnCtx.icon = icon;
2337 reviewWithWarnCtx.reviewTitle = reviewTitle;
2338 reviewWithWarnCtx.reviewSubTitle = reviewSubTitle;
2339 reviewWithWarnCtx.finishTitle = finishTitle;
2340 reviewWithWarnCtx.warning = warning;
2341 reviewWithWarnCtx.choiceCallback = choiceCallback;
2358 displayInitialWarning();
2383 const char *reviewTitle,
2384 const char *reviewSubTitle,
2385 const char *finishTitle,
2396 &blindSigningWarning,
2417 const char *reviewTitle,
2418 const char *reviewSubTitle,
2419 const char *finishTitle,
2450 const char *reviewTitle,
2451 const char *reviewSubTitle,
2454 memset(&context, 0,
sizeof(UseCaseContext_t));
2455 context.type = ADDRESS_REVIEW_USE_CASE;
2456 context.review.address = address;
2457 context.review.reviewTitle = reviewTitle;
2458 context.review.reviewSubTitle = reviewSubTitle;
2459 context.review.icon = icon;
2460 context.review.onChoice = choiceCallback;
2461 context.currentPage = 0;
2464 context.nbPages = reviewSubTitle ? 5 : 4;
2465 if (additionalTagValueList) {
2466 context.review.tagValueList = PIC(additionalTagValueList);
2467 context.nbPages += additionalTagValueList->
nbPairs;
2482 const char *rejectText,
2485 memset(&context, 0,
sizeof(UseCaseContext_t));
2486 context.type = GENERIC_REVIEW_USE_CASE;
2487 context.content.rejectText = rejectText;
2488 context.content.quitCallback = rejectCallback;
2489 context.content.genericContents.nbContents = contents->
nbContents;
2495 context.content.genericContents.contentsList = PIC(contents->
contentsList);
2498 startUseCaseContent();
2512 memset(&context, 0,
sizeof(UseCaseContext_t));
2513 context.type = STATUS_USE_CASE;
2514 context.stepCallback = quitCallback;
2515 context.currentPage = 0;
2516 context.nbPages = 1;
2522 statusButtonCallback,
2538 switch (reviewStatusType) {
2540 msg =
"Operation signed";
2544 msg =
"Operation rejected";
2548 msg =
"Transaction signed";
2552 msg =
"Transaction rejected";
2556 msg =
"Message signed";
2560 msg =
"Message rejected";
2564 msg =
"Address verified";
2568 msg =
"Address verification cancelled";
2591 const char *reviewTitle,
2592 const char *reviewSubTitle,
2596 streamingOpType = operationType;
2598 memset(&context, 0,
sizeof(UseCaseContext_t));
2599 context.type = STREAMING_START_REVIEW_USE_CASE;
2600 context.operationType = operationType;
2601 context.review.reviewTitle = reviewTitle;
2602 context.review.reviewSubTitle = reviewSubTitle;
2603 context.review.icon = icon;
2604 context.review.onChoice = choiceCallback;
2605 context.currentPage = 0;
2606 context.nbPages = reviewSubTitle ? 3 : 2;
2626 const char *reviewTitle,
2627 const char *reviewSubTitle,
2631 operationType, icon, reviewTitle, reviewSubTitle, &blindSigningWarning, choiceCallback);
2651 const char *reviewTitle,
2652 const char *reviewSubTitle,
2656 memset(&context, 0,
sizeof(UseCaseContext_t));
2657 context.type = STREAMING_START_REVIEW_USE_CASE;
2658 context.operationType = operationType;
2659 context.review.reviewTitle = reviewTitle;
2660 context.review.reviewSubTitle = reviewSubTitle;
2661 context.review.icon = icon;
2662 context.review.onChoice = choiceCallback;
2663 context.currentPage = 0;
2664 context.nbPages = reviewSubTitle ? 3 : 2;
2667 streamingOpType = operationType;
2670 if ((warning == NULL)
2677 operationType |= NO_THREAT_OPERATION;
2680 operationType |= RISKY_OPERATION;
2682 memset(&reviewWithWarnCtx, 0,
sizeof(reviewWithWarnCtx));
2684 reviewWithWarnCtx.type = context.type;
2685 reviewWithWarnCtx.operationType = operationType;
2686 reviewWithWarnCtx.icon = icon;
2687 reviewWithWarnCtx.reviewTitle = reviewTitle;
2688 reviewWithWarnCtx.reviewSubTitle = reviewSubTitle;
2689 reviewWithWarnCtx.choiceCallback = choiceCallback;
2690 reviewWithWarnCtx.warning = warning;
2700 displayInitialWarning();
2720 uint8_t curNbDataSets = context.review.nbDataSets;
2722 memset(&context, 0,
sizeof(UseCaseContext_t));
2723 context.type = STREAMING_CONTINUE_REVIEW_USE_CASE;
2724 context.operationType = streamingOpType;
2725 context.review.tagValueList = tagValueList;
2726 context.review.onChoice = choiceCallback;
2727 context.currentPage = 0;
2728 context.nbPages = tagValueList->
nbPairs + 1;
2729 context.review.skipCallback = skipCallback;
2730 context.review.nbDataSets = curNbDataSets + 1;
2754 memset(&context, 0,
sizeof(UseCaseContext_t));
2755 context.type = STREAMING_FINISH_REVIEW_USE_CASE;
2756 context.operationType = streamingOpType;
2757 context.review.onChoice = choiceCallback;
2758 context.review.finishTitle = finishTitle;
2759 context.currentPage = 0;
2760 context.nbPages = 2;
2772 memset(&context, 0,
sizeof(UseCaseContext_t));
2773 context.type = SPINNER_USE_CASE;
2774 context.currentPage = 0;
2775 context.nbPages = 1;
2777 displaySpinner(text);
2793 const char *message,
2794 const char *subMessage,
2795 const char *confirmText,
2796 const char *cancelText,
2800 icon, message, subMessage, confirmText, cancelText, NULL, callback);
2818 const char *message,
2819 const char *subMessage,
2820 const char *confirmText,
2821 const char *cancelText,
2825 memset(&context, 0,
sizeof(UseCaseContext_t));
2826 context.type = CHOICE_USE_CASE;
2827 context.choice.icon = icon;
2828 context.choice.message = message;
2829 context.choice.subMessage = subMessage;
2830 context.choice.confirmText = confirmText;
2831 context.choice.cancelText = cancelText;
2832 context.choice.onChoice = callback;
2833 context.choice.details = details;
2834 context.currentPage = 0;
2835 context.nbPages = 2;
2836 if (message != NULL) {
2839 if ((icon != NULL) && (subMessage != NULL)) {
2843 if (details != NULL) {
2867 const char *subMessage,
2868 const char *confirmText,
2869 const char *cancelText,
2872 memset(&context, 0,
sizeof(UseCaseContext_t));
2873 context.type = CONFIRM_USE_CASE;
2874 context.confirm.message = message;
2875 context.confirm.subMessage = subMessage;
2876 context.confirm.confirmText = confirmText;
2877 context.confirm.cancelText = cancelText;
2878 context.confirm.onConfirm = callback;
2879 context.currentPage = 0;
2880 context.nbPages = 1 + 2;
2895 const char *message,
2896 const char *actionText,
2904 memset(&context, 0,
sizeof(UseCaseContext_t));
2905 context.type = ACTION_USE_CASE;
2906 context.action.actionCallback = callback;
2908 centeredInfo.
icon = icon;
2909 centeredInfo.
text1 = message;
2910 centeredInfo.
style = BOLD_TEXT1_INFO;
2945 memset(&context, 0,
sizeof(KeypadContext_t));
2946 context.type = KEYPAD_USE_CASE;
2947 context.currentPage = 0;
2948 context.nbPages = 1;
2949 context.keypad.validatePin = validatePinCallback;
2950 context.keypad.backCallback = backCallback;
2951 context.keypad.pinMinDigits = minDigits;
2952 context.keypad.pinMaxDigits = maxDigits;
2953 context.keypad.hidden = hidden;
2961 context.keypad.keypadIndex = status;
2969 if (context.keypad.backCallback != NULL) {
nbgl_contentCenteredInfoStyle_t
possible styles for Centered Info Area
@ CHOICES_LIST
list of choices through radio buttons
@ CENTERED_INFO
a centered info
@ SWITCHES_LIST
list of switches with descriptions
@ INFOS_LIST
list of infos with titles
@ TAG_VALUE_LIST
list of tag/value pairs
@ BARS_LIST
list of touchable bars (with > on the right to go to sub-pages)
@ INFO_BUTTON
a centered info and a simple black button
@ INFO_LIST_ALIAS
alias is list of infos
@ ENS_ALIAS
alias comes from ENS
void(* nbgl_contentActionCallback_t)(int token, uint8_t index, int page)
prototype of function to be called when an action on a content object occurs
#define LOG_WARN(__logger,...)
#define LOG_DEBUG(__logger,...)
void(* nbgl_stepCallback_t)(void)
prototype of function to be called when a step is using a callback on "double-key" action
void(* nbgl_layoutTouchCallback_t)(int token, uint8_t index)
prototype of function to be called when an object is touched
int nbgl_layoutUpdateKeypad(nbgl_layout_t *layout, uint8_t index, bool enableValidate, bool enableBackspace, bool enableDigits)
Updates an existing keypad on bottom of the screen, with the given configuration.
int nbgl_layoutDraw(nbgl_layout_t *layout)
Applies given layout. The screen will be redrawn.
void * nbgl_layout_t
type shared externally
int nbgl_layoutAddKeypadContent(nbgl_layout_t *layout, const char *title, bool hidden, uint8_t nbDigits, const char *text)
Adds an area with a title and a placeholder for hidden digits on top of a keypad, to represent the en...
int nbgl_layoutUpdateKeypadContent(nbgl_layout_t *layout, bool hidden, uint8_t nbActiveDigits, const char *text)
Updates an existing set of hidden digits, with the given configuration.
nbgl_layout_t * nbgl_layoutGet(const nbgl_layoutDescription_t *description)
returns a layout of the given type. The layout is reset
int nbgl_layoutAddKeypad(nbgl_layout_t *layout, keyboardCallback_t callback, bool shuffled)
Adds a keypad on bottom of the screen, with the associated callback.
void nbgl_refresh(void)
This functions refreshes the actual screen on display with what has changed since the last refresh.
@ BUTTON_BOTH_PRESSED
Sent when both buttons are released.
@ BUTTON_LEFT_PRESSED
Sent when Left button is released.
@ BUTTON_RIGHT_PRESSED
Send when Right button is released.
struct PACKED__ nbgl_screenTickerConfiguration_s nbgl_screenTickerConfiguration_t
struct to configure a screen layer
void nbgl_screenRedraw(void)
This function redraws the whole screen on top of stack and its children.
void(* nbgl_stepButtonCallback_t)(nbgl_step_t stepCtx, nbgl_buttonEvent_t event)
prototype of function to be called when buttons are touched on a screen
#define GET_POS_OF_STEP(_step, _nb_steps)
nbgl_step_t nbgl_stepDrawSwitch(nbgl_stepPosition_t pos, nbgl_stepButtonCallback_t onActionCallback, nbgl_screenTickerConfiguration_t *ticker, nbgl_layoutSwitch_t *switchInfo, bool modal)
void * nbgl_step_t
type shared externally
uint8_t nbgl_stepPosition_t
this type is a bitfield containing:
nbgl_step_t nbgl_stepDrawMenuList(nbgl_stepMenuListCallback_t onActionCallback, nbgl_screenTickerConfiguration_t *ticker, nbgl_layoutMenuList_t *list, bool modal)
#define ACTION_ON_ANY_BUTTON
When action callback applies only on both button press.
@ NEITHER_FIRST_NOR_LAST_STEP
neither first nor last in a multiple steps flow
@ SINGLE_STEP
single step flow
@ LAST_STEP
last in a multiple steps flow
@ FIRST_STEP
first in a multiple steps flow
int nbgl_stepRelease(nbgl_step_t step)
#define FORWARD_DIRECTION
When the flow is navigated from last to first step.
nbgl_step_t nbgl_stepDrawText(nbgl_stepPosition_t pos, nbgl_stepButtonCallback_t onActionCallback, nbgl_screenTickerConfiguration_t *ticker, const char *text, const char *subText, nbgl_contentCenteredInfoStyle_t style, bool modal)
nbgl_step_t nbgl_stepDrawCenteredInfo(nbgl_stepPosition_t pos, nbgl_stepButtonCallback_t onActionCallback, nbgl_screenTickerConfiguration_t *ticker, nbgl_layoutCenteredInfo_t *info, bool modal)
#define BACKWARD_DIRECTION
When action callback applies on any button press.
nbgl_state_t
to represent a boolean state.
struct PACKED__ nbgl_icon_details_s nbgl_icon_details_t
Represents all information about an icon.
API of the Advanced BOLOS Graphical Library, for typical application use-cases.
@ CENTERED_INFO_WARNING
Centered info.
@ BAR_LIST_WARNING
list of touchable bars, to display sub-pages
uint8_t nbgl_useCaseGetNbTagValuesInPageExt(uint8_t nbPairs, const nbgl_contentTagValueList_t *tagValueList, uint8_t startIndex, bool isSkippable, bool *requireSpecificDisplay)
void(* nbgl_callback_t)(void)
prototype of generic callback function
#define SKIPPABLE_OPERATION
This is to use in nbgl_operationType_t when the operation is skippable. This is used.
void nbgl_useCaseGenericSettings(const char *appName, uint8_t initPage, const nbgl_genericContents_t *settingContents, const nbgl_contentInfoList_t *infosList, nbgl_callback_t quitCallback)
uint32_t nbgl_operationType_t
This mask is used to describe the type of operation to review with additional options It is a mask of...
void nbgl_useCaseReview(nbgl_operationType_t operationType, const nbgl_contentTagValueList_t *tagValueList, const nbgl_icon_details_t *icon, const char *reviewTitle, const char *reviewSubTitle, const char *finishTitle, nbgl_choiceCallback_t choiceCallback)
void nbgl_useCaseAction(const nbgl_icon_details_t *icon, const char *message, const char *actionText, nbgl_callback_t callback)
uint8_t nbgl_useCaseGetNbTagValuesInPage(uint8_t nbPairs, const nbgl_contentTagValueList_t *tagValueList, uint8_t startIndex, bool *requireSpecificDisplay)
uint8_t nbgl_useCaseGetNbPagesForTagValueList(const nbgl_contentTagValueList_t *tagValueList)
void(* nbgl_pinValidCallback_t)(const uint8_t *pin, uint8_t pinLen)
prototype of pin validation callback function
void nbgl_useCaseReviewStreamingStart(nbgl_operationType_t operationType, const nbgl_icon_details_t *icon, const char *reviewTitle, const char *reviewSubTitle, nbgl_choiceCallback_t choiceCallback)
void nbgl_useCaseHomeAndSettings(const char *appName, const nbgl_icon_details_t *appIcon, const char *tagline, const uint8_t initSettingPage, const nbgl_genericContents_t *settingContents, const nbgl_contentInfoList_t *infosList, const nbgl_homeAction_t *action, nbgl_callback_t quitCallback)
uint8_t nbgl_useCaseGetNbInfosInPage(uint8_t nbInfos, const nbgl_contentInfoList_t *infosList, uint8_t startIndex, bool withNav)
void(* nbgl_choiceCallback_t)(bool confirm)
prototype of choice callback function
uint8_t nbgl_useCaseGetNbBarsInPage(uint8_t nbBars, const nbgl_contentBarsList_t *barsList, uint8_t startIndex, bool withNav)
void nbgl_useCaseNavigableContent(const char *title, uint8_t initPage, uint8_t nbPages, nbgl_callback_t quitCallback, nbgl_navCallback_t navCallback, nbgl_layoutTouchCallback_t controlsCallback)
void nbgl_useCaseReviewStreamingFinish(const char *finishTitle, nbgl_choiceCallback_t choiceCallback)
void nbgl_useCaseChoiceWithDetails(const nbgl_icon_details_t *icon, const char *message, const char *subMessage, const char *confirmText, const char *cancelText, nbgl_warningDetails_t *details, nbgl_choiceCallback_t callback)
void nbgl_useCaseSpinner(const char *text)
void nbgl_useCaseConfirm(const char *message, const char *subMessage, const char *confirmText, const char *rejectText, nbgl_callback_t callback)
void nbgl_useCaseStatus(const char *message, bool isSuccess, nbgl_callback_t quitCallback)
@ W3C_THREAT_DETECTED_WARN
Web3 Checks: Threat detected (see reportRisk field)
@ BLIND_SIGNING_WARN
Blind signing.
@ W3C_NO_THREAT_WARN
Web3 Checks: No Threat detected.
@ W3C_RISK_DETECTED_WARN
Web3 Checks: Risk detected (see reportRisk field)
void nbgl_useCaseGenericConfiguration(const char *title, uint8_t initPage, const nbgl_genericContents_t *contents, nbgl_callback_t quitCallback)
#define INIT_HOME_PAGE
Value to pass to nbgl_useCaseHomeAndSettings() initSettingPage parameter to initialize the use case o...
void nbgl_useCaseKeypad(const char *title, uint8_t minDigits, uint8_t maxDigits, bool shuffled, bool hidden, nbgl_pinValidCallback_t validatePinCallback, nbgl_callback_t backCallback)
void nbgl_useCaseReviewStreamingContinueExt(const nbgl_contentTagValueList_t *tagValueList, nbgl_choiceCallback_t choiceCallback, nbgl_callback_t skipCallback)
void nbgl_useCaseReviewBlindSigning(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, nbgl_choiceCallback_t choiceCallback)
void nbgl_useCaseChoice(const nbgl_icon_details_t *icon, const char *message, const char *subMessage, const char *confirmText, const char *rejectString, nbgl_choiceCallback_t callback)
void nbgl_useCaseGenericReview(const nbgl_genericContents_t *contents, const char *rejectText, nbgl_callback_t rejectCallback)
#define STATUS_SCREEN_DURATION
void nbgl_useCaseReviewStreamingBlindSigningStart(nbgl_operationType_t operationType, const nbgl_icon_details_t *icon, const char *reviewTitle, const char *reviewSubTitle, nbgl_choiceCallback_t choiceCallback)
void nbgl_useCaseReviewStreamingContinue(const nbgl_contentTagValueList_t *tagValueList, nbgl_choiceCallback_t choiceCallback)
void nbgl_useCaseReviewLight(nbgl_operationType_t operationType, const nbgl_contentTagValueList_t *tagValueList, const nbgl_icon_details_t *icon, const char *reviewTitle, const char *reviewSubTitle, const char *finishTitle, nbgl_choiceCallback_t choiceCallback)
uint8_t nbgl_useCaseGetNbChoicesInPage(uint8_t nbChoices, const nbgl_contentRadioChoice_t *choicesList, uint8_t startIndex, bool withNav)
#define REAL_TYPE_MASK
This is the mask to apply on nbgl_operationType_t to get the real type provided by app.
void nbgl_useCaseReviewStatus(nbgl_reviewStatusType_t reviewStatusType, nbgl_callback_t quitCallback)
nbgl_reviewStatusType_t
The different types of review status.
@ STATUS_TYPE_TRANSACTION_REJECTED
@ STATUS_TYPE_ADDRESS_REJECTED
@ STATUS_TYPE_TRANSACTION_SIGNED
@ STATUS_TYPE_OPERATION_REJECTED
@ STATUS_TYPE_OPERATION_SIGNED
@ STATUS_TYPE_ADDRESS_VERIFIED
@ STATUS_TYPE_MESSAGE_SIGNED
@ STATUS_TYPE_MESSAGE_REJECTED
bool(* nbgl_navCallback_t)(uint8_t page, nbgl_pageContent_t *content)
prototype of navigation callback function
void nbgl_useCaseAddressReview(const char *address, const nbgl_contentTagValueList_t *additionalTagValueList, const nbgl_icon_details_t *icon, const char *reviewTitle, const char *reviewSubTitle, nbgl_choiceCallback_t choiceCallback)
@ TYPE_TRANSACTION
For operations transferring a coin or taken from an account to another.
void nbgl_useCaseAdvancedReviewStreamingStart(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_useCaseAdvancedReview(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)
uint8_t nbgl_useCaseGetNbSwitchesInPage(uint8_t nbSwitches, const nbgl_contentSwitchesList_t *switchesList, uint8_t startIndex, bool withNav)
This structure contains data to build a BARS_LIST content.
const uint8_t * tokens
array of tokens, one for each bar (nbBars items)
const char *const * barTexts
array of texts for each bar (nbBars items, in black/bold)
uint8_t nbBars
number of elements in barTexts and tokens array
This structure contains info to build a centered (vertically and horizontally) area,...
const char * text2
second text (can be null)
const char * text1
first text (can be null)
bool onTop
if set to true, align only horizontally
nbgl_contentCenteredInfoStyle_t style
style to apply to this info
const nbgl_icon_details_t * icon
a buffer containing the 1BPP icon
const char * buttonText
text of the long press button
const nbgl_icon_details_t * icon
a buffer containing the 1BPP icon
const char * text
centered text in large case
This structure contains data to build a INFOS_LIST content.
const char *const * infoContents
array of contents of infos (in black)
const char *const * infoTypes
array of types of infos (in black/bold)
uint8_t nbInfos
number of elements in infoTypes and infoContents array
This structure contains a list of names to build a list of radio buttons (on the right part of screen...
uint8_t token
the token that will be used as argument of the callback
uint8_t initChoice
index of the current choice
const char *const * names
array of strings giving the choices (nbChoices)
uint8_t nbChoices
number of choices
This structure contains info to build a switch (on the right) with a description (on the left),...
const char * text
main text for the switch
uint8_t token
the token that will be used as argument of the callback (unused on Nano)
nbgl_state_t initState
initial state of the switch
const char * subText
description under main text (NULL terminated, single line, may be null)
This structure contains a list of [tag,value] pairs.
const nbgl_contentTagValue_t * pairs
array of [tag,value] pairs (nbPairs items). If NULL, callback is used instead
nbgl_contentTagValueCallback_t callback
function to call to retrieve a given pair
This structure contains a [tag,value] pair and possible extensions.
const nbgl_contentValueExt_t * extension
if not NULL, gives additional info on value field
const nbgl_icon_details_t * valueIcon
int8_t centeredInfo
if set to 1, the tag will be displayed as a centered info
const char * value
string giving the value name
const char * item
string giving the tag name
This structure contains additions to a tag/value pair, to be able to build a screen to display these ...
This structure contains data to build a content.
nbgl_contentActionCallback_t contentActionCallback
callback to be called when an action on an object occurs
nbgl_contentType_t type
type of page content in the content union
uint8_t nbBars
number of touchable bars
uint8_t nbContents
number of contents
const nbgl_content_t * contentsList
array of nbgl_content_t (nbContents items).
nbgl_contentCallback_t contentGetterCallback
function to call to retrieve a given content
The necessary parameters to build the page(s) displayed when the top-right button is touched in intro...
nbgl_genericBarList_t barList
touchable bars list, if type == BAR_LIST_WARNING
nbgl_genericDetailsType_t type
type of content in the page, determining what to use in the following union
Structure describing the action button in Home Screen.
Structure containing all information when creating a layout. This structure must be passed as argumen...
This structure contains data to build a page in multi-pages mode (nbgl_pageDrawGenericContent)
nbgl_contentRadioChoice_t choicesList
CHOICES_LIST type
nbgl_contentSwitchesList_t switchesList
SWITCHES_LIST type
nbgl_contentBarsList_t barsList
BARS_LIST type
nbgl_contentInfoButton_t infoButton
INFO_BUTTON type
nbgl_contentInfoList_t infosList
INFOS_LIST type
nbgl_contentTagValueList_t tagValueList
TAG_VALUE_LIST type
nbgl_contentType_t type
type of page content in the following union
nbgl_contentCenteredInfo_t centeredInfo
CENTERED_INFO type
This structure contains data to build a SWITCHES_LIST content.
uint8_t nbSwitches
number of elements in switches and tokens array
const nbgl_contentSwitch_t * switches
array of switches (nbSwitches items)
The necessary parameters to build a tip-box in first review page and the modal if this tip box is tou...
The necessary parameters to build a warning page preceding a review. One can either use predefinedSet...
const nbgl_warningDetails_t * introDetails
const nbgl_warningDetails_t * reviewDetails
nbgl_contentInfoList_t infosList
INFOS_LIST type
nbgl_contentTagValueList_t tagValueList
TAG_VALUE_LIST type
nbgl_contentCenteredInfo_t centeredInfo
CENTERED_INFO type
nbgl_contentBarsList_t barsList
BARS_LIST type
nbgl_contentSwitchesList_t switchesList
SWITCHES_LIST type
nbgl_contentInfoButton_t infoButton
INFO_BUTTON type
nbgl_contentRadioChoice_t choicesList
CHOICES_LIST type