Skip to content

Commit f17c7fd

Browse files
authored
Merge pull request #270 from LedgerHQ/revamp
Refactoring and Stax UX revamp
2 parents 1a5b170 + 40c3623 commit f17c7fd

File tree

3,726 files changed

+1124
-736
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

3,726 files changed

+1124
-736
lines changed

CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
Dates are in `dd-mm-yyyy` format.
99

10+
## [2.2.4] - 09-07-2024
11+
12+
### Changed
13+
14+
- Major revamp of the UI for transaction signing and wallet policy registration on Stax. Changed "wallet policy" with the simpler wording "account".
15+
- Slight performance improvements in the signing flow.
16+
- Added a technical limit of at most 10 distinct cosigners in a wallet policy.
17+
18+
### Fixed
19+
20+
- OP_RETURN outputs with a `0x00` data push were incorrectly rejected.
21+
1022
## [2.2.3] - 06-05-2024
1123

1224
### Added

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ PATH_SLIP21_APP_LOAD_PARAMS = "LEDGER-Wallet policy"
4747
# Application version
4848
APPVERSION_M = 2
4949
APPVERSION_N = 2
50-
APPVERSION_P = 3
50+
APPVERSION_P = 4
5151
APPVERSION_SUFFIX = # if not empty, appended at the end. Do not add a dash.
5252

5353
ifeq ($(APPVERSION_SUFFIX),)

bitcoin_client_js/src/__tests__/automations/register_wallet_accept.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"version": 1,
33
"rules": [
44
{
5-
"regexp": "Register wallet|Wallet name|Wallet policy|Key",
5+
"regexp": "Register account|Account name|Wallet policy|Key",
66
"actions": [
77
["button", 2, true],
88
["button", 2, false]

bitcoin_client_js/src/__tests__/automations/sign_with_wallet_accept.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"version": 1,
33
"rules": [
44
{
5-
"regexp": "Spend from|Wallet name|Review|Amount|Address|Fees",
5+
"regexp": "Spend from|Account name|Review|Amount|Address|Fees",
66
"actions": [
77
["button", 2, true],
88
["button", 2, false]

ragger_bitcoin/ragger_instructions.py

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -38,16 +38,22 @@ def nano_skip_screen(self, text, save_screenshot=True):
3838
self.new_request(text, NavInsID.RIGHT_CLICK, NavInsID.RIGHT_CLICK,
3939
save_screenshot=save_screenshot)
4040

41-
def navigate_end_of_flow(self, save_screenshot=True):
42-
self.new_request("Processing", NavInsID.USE_CASE_REVIEW_TAP, NavInsID.USE_CASE_REVIEW_TAP,
43-
save_screenshot=save_screenshot)
44-
45-
def review_start(self, output_count: int = 1, save_screenshot=True):
41+
def review_start(self, output_count: int = 1, save_screenshot=True, has_warning=False):
4642
self.new_request("Review", NavInsID.USE_CASE_REVIEW_TAP, NavInsID.USE_CASE_REVIEW_TAP,
47-
save_screenshot=save_screenshot)
48-
for _ in range(0, output_count):
49-
self.new_request("Amount", NavInsID.USE_CASE_REVIEW_TAP, NavInsID.USE_CASE_REVIEW_TAP,
50-
save_screenshot=save_screenshot)
43+
save_screenshot=save_screenshot)
44+
45+
if has_warning:
46+
self.same_request("Warning", NavInsID.USE_CASE_REVIEW_TAP, NavInsID.USE_CASE_CHOICE_CONFIRM,
47+
save_screenshot=save_screenshot)
48+
49+
for output_index in range(0, output_count):
50+
# the initial 2 outputs are cached; that depends on the N_CACHED_EXTERNAL_OUTPUTS constant
51+
if output_index < 2:
52+
self.same_request("Amount", NavInsID.USE_CASE_REVIEW_TAP, NavInsID.USE_CASE_REVIEW_TAP,
53+
save_screenshot=save_screenshot)
54+
else:
55+
self.new_request("Amount", NavInsID.USE_CASE_REVIEW_TAP, NavInsID.USE_CASE_REVIEW_TAP,
56+
save_screenshot=save_screenshot)
5157
def review_fees(self, fees_on_same_request: bool = True, save_screenshot=True):
5258
if fees_on_same_request:
5359
self.same_request("Fees", NavInsID.USE_CASE_REVIEW_TAP, NavInsID.USE_CASE_REVIEW_TAP,
@@ -94,10 +100,6 @@ def reject_message(self, save_screenshot=True):
94100
self.new_request("Message", NavInsID.USE_CASE_REVIEW_TAP, NavInsID.USE_CASE_STATUS_DISMISS,
95101
save_screenshot=save_screenshot)
96102

97-
def warning_accept(self, save_screenshot=True):
98-
self.new_request("Warning", NavInsID.USE_CASE_REVIEW_TAP, NavInsID.USE_CASE_CHOICE_CONFIRM,
99-
save_screenshot=save_screenshot)
100-
101103
def address_confirm(self, save_screenshot=True):
102104
self.new_request("Confirm", NavInsID.USE_CASE_REVIEW_TAP,
103105
NavInsID.USE_CASE_ADDRESS_CONFIRMATION_CONFIRM,

src/boilerplate/io.c

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,20 @@ void io_reset_timeouts() {
8585
G_was_processing_screen_shown = false;
8686
}
8787

88+
void io_show_processing_screen() {
89+
if (!G_was_processing_screen_shown) {
90+
G_was_processing_screen_shown = true;
91+
if (!G_swap_state.called_from_swap) {
92+
#ifdef HAVE_BAGL
93+
ux_flow_init(0, ux_processing_flow, NULL);
94+
#endif // HAVE_BAGL
95+
#ifdef HAVE_NBGL
96+
nbgl_useCaseSpinner("Processing");
97+
#endif // HAVE_NBGL
98+
}
99+
}
100+
}
101+
88102
uint8_t io_event(uint8_t channel) {
89103
(void) channel;
90104

@@ -121,18 +135,7 @@ uint8_t io_event(uint8_t channel) {
121135
G_ticks - G_processing_timeout_start_tick >= PROCESSING_TIMEOUT_TICKS) {
122136
io_clear_processing_timeout();
123137

124-
if (!G_was_processing_screen_shown) {
125-
G_was_processing_screen_shown = true;
126-
#ifdef HAVE_BAGL
127-
ux_flow_init(0, ux_processing_flow, NULL);
128-
#endif // HAVE_BAGL
129-
#ifdef HAVE_NBGL
130-
131-
if (!G_swap_state.called_from_swap) {
132-
nbgl_useCaseSpinner("Processing");
133-
}
134-
#endif // HAVE_NBGL
135-
}
138+
io_show_processing_screen();
136139
}
137140

138141
if (G_is_timeout_active.interruption &&

src/boilerplate/io.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,11 @@ void io_clear_processing_timeout();
5454
*/
5555
void io_reset_timeouts();
5656

57+
/**
58+
* Shows the "Processing..." screen.
59+
*/
60+
void io_show_processing_screen();
61+
5762
/**
5863
* TODO: docs
5964
*/

src/common/base58.c

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,8 @@ char const BASE58_ALPHABET[] = {
4343
};
4444

4545
int base58_decode(const char *in, size_t in_len, uint8_t *out, size_t out_len) {
46-
#ifdef USE_CXRAM_SECTION
47-
// allocate buffers inside the cxram section; safe as there are no syscalls here
48-
uint8_t *tmp = get_cxram_buffer(); // MAX_DEC_INPUT_SIZE bytes buffer
49-
uint8_t *buffer = get_cxram_buffer() + MAX_DEC_INPUT_SIZE; // MAX_DEC_INPUT_SIZE bytes buffer
50-
#else
5146
uint8_t tmp[MAX_DEC_INPUT_SIZE] = {0};
5247
uint8_t buffer[MAX_DEC_INPUT_SIZE] = {0};
53-
#endif
5448

5549
memset(tmp, 0, MAX_DEC_INPUT_SIZE);
5650
memset(buffer, 0, MAX_DEC_INPUT_SIZE);

src/common/script.c

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -189,8 +189,8 @@ int format_opscript_script(const uint8_t script[],
189189
}
190190

191191
if (hex_length == 1) {
192-
if (script[offset] == 0x81 || script[offset] <= 16) {
193-
// non-standard, it should use OP_1NEGATE, or one of OP_0, ..., OP_16
192+
if (script[offset] == 0x81 || (1 <= script[offset] && script[offset] <= 16)) {
193+
// non-standard, it should use OP_1NEGATE, or one of OP_1, ..., OP_16
194194
return -1;
195195
}
196196
}
@@ -219,3 +219,24 @@ int format_opscript_script(const uint8_t script[],
219219
out[out_ctr - 1] = '\0';
220220
return out_ctr;
221221
}
222+
223+
#ifndef SKIP_FOR_CMOCKA
224+
225+
bool format_script(const uint8_t script[],
226+
size_t script_len,
227+
char out[static MAX_OUTPUT_SCRIPT_DESC_SIZE]) {
228+
int address_len = get_script_address(script, script_len, out, MAX_OUTPUT_SCRIPT_DESC_SIZE);
229+
if (address_len < 0) {
230+
// script does not have an address; check if OP_RETURN
231+
if (is_opreturn(script, script_len)) {
232+
if (0 > format_opscript_script(script, script_len, out)) {
233+
return false;
234+
}
235+
} else {
236+
return false;
237+
}
238+
}
239+
return true;
240+
}
241+
242+
#endif

src/common/script.h

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
#pragma once
22

3+
#include "os.h"
4+
5+
#include "../constants.h"
6+
37
/** Script opcodes */
48
// from bitcoin-core
59
enum opcodetype {
@@ -232,4 +236,23 @@ int get_script_address(const uint8_t script[], size_t script_len, char *out, siz
232236
*/
233237
int format_opscript_script(const uint8_t script[],
234238
size_t script_len,
235-
char out[static MAX_OPRETURN_OUTPUT_DESC_SIZE]);
239+
char out[static MAX_OPRETURN_OUTPUT_DESC_SIZE]);
240+
241+
// the maximum length of the description of an output that we can display (address or OP_RETURN),
242+
// including the terminating null character
243+
#define MAX_OUTPUT_SCRIPT_DESC_SIZE MAX(MAX_ADDRESS_LENGTH_STR + 1, MAX_OPRETURN_OUTPUT_DESC_SIZE)
244+
245+
/**
246+
* Formats a bitcoin Script in the format that is displayed to the user. Only scripts with an
247+
* address are supported, or OP_RETURN scripts as documented in format_opscript_script.
248+
*
249+
* The string is written onto `out` and is 0-terminated.
250+
*
251+
* @param[in] script the script to parse and format.
252+
* @param[in] script_len the length of the script.
253+
* @param[out] out the output array, that must be at least MAX_OPRETURN_OUTPUT_DESC_SIZE bytes long.
254+
* @return `true` the script is a supported one that can be shown to the user, `false` otherwise.
255+
*/
256+
bool format_script(const uint8_t script[],
257+
size_t script_len,
258+
char out[static MAX_OUTPUT_SCRIPT_DESC_SIZE]);

0 commit comments

Comments
 (0)