Skip to content

Commit bdac696

Browse files
authored
Merge pull request #208 from Zondax/new-features
2 parents 16edb10 + 75d89bd commit bdac696

File tree

289 files changed

+2538
-578
lines changed

Some content is hidden

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

289 files changed

+2538
-578
lines changed

.github/workflows/main.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ jobs:
9797

9898
test_zemu:
9999
runs-on: ubuntu-latest
100+
timeout-minutes: 30
100101
steps:
101102
- name: Checkout
102103
uses: actions/checkout@v3

app/Makefile.version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ APPVERSION_M=2
33
# This is the minor version of this release
44
APPVERSION_N=4
55
# This is the patch version of this release
6-
APPVERSION_P=2
6+
APPVERSION_P=3

app/src/addr.c

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,18 +45,25 @@ zxerr_t addr_getItem(int8_t displayIdx,
4545
return zxerr_buffer_too_small;
4646
}
4747

48+
parser_error_t err = parser_unexpected_error;
4849
switch (displayIdx) {
4950
case 0:
5051
snprintf(outKey, outKeyLen, "Address ");
51-
print_subaccount_hex(G_io_apdu_buffer + VIEW_ADDRESS_OFFSET_TEXT, DFINITY_SUBACCOUNT_LEN,
52-
outVal, outValLen, pageIdx, pageCount);
52+
err = page_hexstring_with_delimiters(G_io_apdu_buffer + VIEW_ADDRESS_OFFSET_TEXT, DFINITY_SUBACCOUNT_LEN,
53+
outVal, outValLen, pageIdx, pageCount);
54+
if (err != parser_ok) {
55+
return zxerr_unknown;
56+
}
5357
return zxerr_ok;
5458

5559
case 1:
5660
snprintf(outKey, outKeyLen, "Principal ");
57-
page_principal_with_delimiters((const char*)G_io_apdu_buffer + VIEW_PRINCIPAL_OFFSET_TEXT,
58-
action_addrResponseLen - VIEW_PRINCIPAL_OFFSET_TEXT,
59-
outVal, outValLen, pageIdx, pageCount);
61+
err = page_textual_with_delimiters((const char*)G_io_apdu_buffer + VIEW_PRINCIPAL_OFFSET_TEXT,
62+
action_addrResponseLen - VIEW_PRINCIPAL_OFFSET_TEXT,
63+
outVal, outValLen, pageIdx, pageCount);
64+
if (err != parser_ok) {
65+
return zxerr_unknown;
66+
}
6067
return zxerr_ok;
6168

6269
case 2: {

app/src/base32.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ uint32_t base32_encode(const uint8_t *data,
2525
uint32_t length,
2626
char *result,
2727
uint32_t resultLen) {
28-
if (length < 0 || length > (1 << 28)) {
29-
return -1;
28+
if (length > (1 << 28)) {
29+
return 0;
3030
}
3131
uint32_t count = 0;
3232
if (length > 0) {
@@ -53,7 +53,7 @@ uint32_t base32_encode(const uint8_t *data,
5353
if (count < resultLen) {
5454
result[count] = '\000';
5555
} else {
56-
count = -1;
56+
count = 0;
5757
}
5858
return count;
5959
}

app/src/candid/candid_helper.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
* See the License for the specific language governing permissions and
1414
* limitations under the License.
1515
********************************************************************************/
16-
#define APP_TESTING 0
1716
#define CANDID_TESTING 0
1817

1918
#include "candid_helper.h"

app/src/candid/candid_parser.c

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,3 +411,148 @@ parser_error_t readCandidICRCTransfer(parser_tx_t *tx, const uint8_t *input, uin
411411

412412
return parser_ok;
413413
}
414+
415+
parser_error_t readCandidTransfer(parser_tx_t *tx, const uint8_t *input, uint16_t inputSize) {
416+
// Create context and auxiliary ctx
417+
CREATE_CTX(ctx, tx, input, inputSize)
418+
candid_transaction_t txn;
419+
txn.ctx.buffer = ctx.buffer;
420+
txn.ctx.bufferLen = ctx.bufferLen;
421+
txn.ctx.tx_obj = ctx.tx_obj;
422+
423+
CHECK_PARSER_ERR(readCandidHeader(&ctx, &txn))
424+
CHECK_PARSER_ERR(readAndCheckRootType(&ctx))
425+
CHECK_PARSER_ERR(getCandidTypeFromTable(&txn, tx->candid_rootType))
426+
427+
CHECK_PARSER_ERR(readCandidRecordLength(&txn))
428+
if (txn.txn_length != 6) {
429+
return parser_unexpected_value;
430+
}
431+
432+
txn.element.variant_index = 0;
433+
CHECK_PARSER_ERR(readCandidInnerElement(&txn, &txn.element))
434+
CHECK_PARSER_ERR(getCandidTypeFromTable(&txn, txn.element.implementation))
435+
if (txn.element.field_hash != transfer_hash_to || txn.txn_type != Vector) {
436+
return parser_unexpected_type;
437+
}
438+
// To is vec u8, OK
439+
440+
CHECK_PARSER_ERR(getCandidTypeFromTable(&txn, tx->candid_rootType))
441+
CHECK_PARSER_ERR(readCandidRecordLength(&txn))
442+
txn.element.variant_index = 1;
443+
CHECK_PARSER_ERR(readCandidInnerElement(&txn, &txn.element))
444+
if (txn.element.field_hash != transfer_hash_fee) {
445+
return parser_unexpected_type;
446+
}
447+
448+
CHECK_PARSER_ERR(getCandidTypeFromTable(&txn, txn.element.implementation))
449+
CHECK_PARSER_ERR(readCandidRecordLength(&txn))
450+
txn.element.variant_index = 0;
451+
CHECK_PARSER_ERR(readCandidInnerElement(&txn, &txn.element))
452+
if (txn.element.implementation != Nat64) {
453+
return parser_unexpected_type;
454+
}
455+
// Fee is u64, OK
456+
457+
CHECK_PARSER_ERR(getCandidTypeFromTable(&txn, tx->candid_rootType))
458+
CHECK_PARSER_ERR(readCandidRecordLength(&txn))
459+
txn.element.variant_index = 2;
460+
CHECK_PARSER_ERR(readCandidInnerElement(&txn, &txn.element))
461+
if (txn.element.field_hash != transfer_hash_memo) {
462+
return parser_unexpected_type;
463+
}
464+
if (txn.element.implementation != Nat64) {
465+
return parser_unexpected_type;
466+
}
467+
// Memo is u64, OK
468+
469+
CHECK_PARSER_ERR(getCandidTypeFromTable(&txn, tx->candid_rootType))
470+
CHECK_PARSER_ERR(readCandidRecordLength(&txn))
471+
txn.element.variant_index = 3;
472+
CHECK_PARSER_ERR(readCandidInnerElement(&txn, &txn.element))
473+
if (txn.element.field_hash != transfer_hash_from_subaccount) {
474+
return parser_unexpected_type;
475+
}
476+
477+
CHECK_PARSER_ERR(getCandidTypeFromTable(&txn, txn.element.implementation))
478+
CHECK_PARSER_ERR(readCandidOptional(&txn))
479+
CHECK_PARSER_ERR(getCandidTypeFromTable(&txn, txn.element.implementation))
480+
if (txn.txn_type != Vector) {
481+
return parser_unexpected_type;
482+
}
483+
// From_subaccount is opt vec u8, OK
484+
485+
CHECK_PARSER_ERR(getCandidTypeFromTable(&txn, tx->candid_rootType))
486+
CHECK_PARSER_ERR(readCandidRecordLength(&txn))
487+
txn.element.variant_index = 4;
488+
CHECK_PARSER_ERR(readCandidInnerElement(&txn, &txn.element))
489+
if (txn.element.field_hash != transfer_hash_timestamp) {
490+
return parser_unexpected_type;
491+
}
492+
493+
CHECK_PARSER_ERR(getCandidTypeFromTable(&txn, txn.element.implementation))
494+
CHECK_PARSER_ERR(readCandidOptional(&txn))
495+
CHECK_PARSER_ERR(getCandidTypeFromTable(&txn, txn.element.implementation))
496+
CHECK_PARSER_ERR(readCandidRecordLength(&txn))
497+
txn.element.variant_index = 0;
498+
CHECK_PARSER_ERR(readCandidInnerElement(&txn, &txn.element))
499+
if (txn.element.implementation != Nat64) {
500+
return parser_unexpected_type;
501+
}
502+
// Timestamp is opt u64, OK
503+
504+
CHECK_PARSER_ERR(getCandidTypeFromTable(&txn, tx->candid_rootType))
505+
CHECK_PARSER_ERR(readCandidRecordLength(&txn))
506+
txn.element.variant_index = 5;
507+
CHECK_PARSER_ERR(readCandidInnerElement(&txn, &txn.element))
508+
if (txn.element.field_hash != transfer_hash_amount) {
509+
return parser_unexpected_type;
510+
}
511+
512+
CHECK_PARSER_ERR(getCandidTypeFromTable(&txn, txn.element.implementation))
513+
CHECK_PARSER_ERR(readCandidRecordLength(&txn))
514+
txn.element.variant_index = 0;
515+
CHECK_PARSER_ERR(readCandidInnerElement(&txn, &txn.element))
516+
if (txn.element.implementation != Nat64) {
517+
return parser_unexpected_type;
518+
}
519+
// amount is u64, OK
520+
521+
// let's read!
522+
candid_transfer_t *transfer = &ctx.tx_obj->tx_fields.call.data.candid_transfer;
523+
524+
// Read to (AccountIdentifier)
525+
uint8_t ownerSize = 0;
526+
CHECK_PARSER_ERR(readCandidByte(&ctx, &ownerSize))
527+
if (ownerSize != DFINITY_ADDR_LEN) {
528+
return parser_unexpected_value;
529+
}
530+
CHECK_PARSER_ERR(readCandidBytes(&ctx, transfer->to, ownerSize))
531+
532+
// Read fee (u64)
533+
CHECK_PARSER_ERR(readCandidNat64(&ctx, &transfer->fee))
534+
535+
// Read memo (u64)
536+
CHECK_PARSER_ERR(readCandidNat64(&ctx, &transfer->memo))
537+
538+
// Read from_subaccount (opt vec u8)
539+
CHECK_PARSER_ERR(readCandidByte(&ctx, &transfer->has_from_subaccount))
540+
if (transfer->has_from_subaccount) {
541+
CHECK_PARSER_ERR(readCandidText(&ctx, &transfer->from_subaccount))
542+
}
543+
544+
// Read timestamp (opt u64)
545+
CHECK_PARSER_ERR(readCandidByte(&ctx, &transfer->has_timestamp))
546+
if (transfer->has_timestamp) {
547+
CHECK_PARSER_ERR(readCandidNat64(&ctx, &transfer->timestamp))
548+
}
549+
550+
// Read amount
551+
CHECK_PARSER_ERR(readCandidNat64(&ctx, &transfer->amount))
552+
553+
if (ctx.bufferLen - ctx.offset > 0) {
554+
return parser_unexpected_characters;
555+
}
556+
557+
return parser_ok;
558+
}

app/src/candid/candid_parser.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ parser_error_t readCandidListNeurons(parser_tx_t *tx, const uint8_t *input, uint
3232

3333
parser_error_t readCandidICRCTransfer(parser_tx_t *tx, const uint8_t *input, uint16_t inputSize);
3434

35+
parser_error_t readCandidTransfer(parser_tx_t *tx, const uint8_t *input, uint16_t inputSize);
36+
3537
parser_error_t getCandidNat64FromVec(const uint8_t *buffer, uint64_t *value, uint8_t size, uint8_t idx);
3638
parser_error_t getCandidInt32FromVec(const uint8_t *buffer, int32_t *value, uint8_t size, uint8_t idx);
3739

app/src/candid/candid_types.h

Lines changed: 85 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ extern "C" {
2121

2222
#include <zxmacros.h>
2323
#include <zxerror.h>
24+
#include "coin.h"
2425

2526
typedef enum {
2627
Null = -1,
@@ -72,6 +73,14 @@ typedef enum {
7273
hash_percentage_to_stake = 854334011,
7374
hash_setting_auto_stake_maturity = 3470422224,
7475
hash_setting_increse_dissolve_delay = 913088909,
76+
hash_field_disburse_account = 1937583785,
77+
hash_opt_amount = 3573748184,
78+
hash_setting_addhotkey = 3570462350,
79+
hash_setting_remove_hotkey = 2202409078,
80+
hash_field_vote = 1314114794,
81+
hash_field_proposal = 3000310834,
82+
hash_field_follow_topic = 338645423,
83+
hash_field_follow_followees = 3407357762,
7584
} txn_hash_fields;
7685

7786
typedef enum {
@@ -89,6 +98,15 @@ typedef enum {
8998
sns_hash_opt_amount = 3573748184,
9099
} sns_hash_fields;
91100

101+
typedef enum {
102+
transfer_hash_to = 25979,
103+
transfer_hash_fee = 5094982,
104+
transfer_hash_memo = 1213809850,
105+
transfer_hash_from_subaccount = 1835347746,
106+
transfer_hash_timestamp = 3258775938,
107+
transfer_hash_amount = 3573748184,
108+
} transfer_hash_fields;
109+
92110
typedef enum {
93111
icrc_hash_to = 25979,
94112
icrc_hash_owner = 947296307,
@@ -135,15 +153,34 @@ typedef enum {
135153
hash_operation_Invalid = 971299358,
136154
hash_operation_StopDissolving = 1954991536,
137155
hash_operation_IncreaseDissolveDelay = 2143729936,
138-
hash_operation_RemoveHotKey = 3248805476,
139-
hash_operation_JoinCommunityFund = 45994902,
156+
hash_operation_AddHotkey = 628424947,
157+
hash_operation_RemoveHotkey = 45994902,
158+
hash_operation_JoinCommunityFund = 3248805476,
140159
hash_operation_ChangeAutoStakeMaturity = 1906071820,
141160

142161
hash_operation_StartDissolving = 1977744848,
143162
hash_operation_LeaveCommunityFund = 3675510135,
144163
hash_operation_SetDissolvedTimestamp = 3913126211,
145164
} operation_variant_hash_e;
146165

166+
typedef enum {
167+
FOLLOW_TOPIC_UNSPECIFIED = 0,
168+
FOLLOW_TOPIC_NEURON_MANAGEMENT = 1,
169+
FOLLOW_TOPIC_EXCHANGE_RATE = 2,
170+
FOLLOW_TOPIC_NETWORK_ECONOMICS = 3,
171+
FOLLOW_TOPIC_GOVERNANCE = 4,
172+
FOLLOW_TOPIC_NODE_ADMIN = 5,
173+
FOLLOW_TOPIC_PARTICIPANT_MANAGEMENT = 6,
174+
FOLLOW_TOPIC_SUBNET_MANAGEMENT = 7,
175+
FOLLOW_TOPIC_NETWORK_CANISTER_MANAGEMENT = 8,
176+
FOLLOW_TOPIC_KYC = 9,
177+
FOLLOW_TOPIC_NODE_PROVIDER_REWARDS = 10,
178+
FOLLOW_TOPIC_SNS_DECENTRALIZATION_SALE = 11,
179+
FOLLOW_TOPIC_SUBNET_REPLICA_VERSION_MANAGEMENT = 12,
180+
FOLLOW_TOPIC_REPLICA_VERSION_MANAGEMENT = 13,
181+
FOLLOW_TOPIC_SNS_AND_COMMUNITY_FUND = 14,
182+
} candid_FollowTopics_e;
183+
147184
// Permissions ENUM
148185
// https://github.com/dfinity/ic-js/blob/d82310ec5519160b5fa2ec94fd82200485bd3ccc/packages/sns/src/enums/governance.enums.ts#L2
149186
typedef enum {
@@ -181,13 +218,19 @@ typedef struct {
181218
uint32_t dissolve_timestamp_seconds;
182219
} candid_IncreaseDissolveDelay_t;
183220

221+
typedef struct {
222+
uint8_t has_principal;
223+
uint8_t principal[30];
224+
} candid_AddRemoveHotkey_t;
225+
184226
typedef struct {
185227
uint64_t which;
186228
uint64_t hash;
187229
union {
188230
candid_SetDissolveTimestamp_t setDissolveTimestamp;
189231
candid_ChangeAutoStakeMaturity_t autoStakeMaturity;
190232
candid_IncreaseDissolveDelay_t increaseDissolveDelay;
233+
candid_AddRemoveHotkey_t hotkey;
191234
};
192235
} candid_Operation_t;
193236

@@ -221,6 +264,28 @@ typedef struct {
221264
uint32_t percentage_to_stake;
222265
} candid_StakeMaturity_t;
223266

267+
typedef struct {
268+
uint8_t has_account_identifier;
269+
sizedBuffer_t account_identifier;
270+
271+
uint8_t has_amount;
272+
uint64_t amount;
273+
} candid_Disburse_t;
274+
275+
typedef struct {
276+
int32_t vote;
277+
278+
uint8_t has_proposal;
279+
candid_NeuronId proposal;
280+
} candid_RegisterVote_t;
281+
282+
typedef struct {
283+
int32_t topic;
284+
285+
uint8_t followees_size;
286+
const uint8_t* followees_ptr;
287+
} candid_Follow_t;
288+
224289
typedef struct {
225290
uint8_t list_size;
226291
const uint8_t *permissions_list_ptr;
@@ -242,6 +307,20 @@ typedef struct {
242307
sizedBuffer_t subaccount;
243308
} Account_t;
244309

310+
typedef struct {
311+
uint64_t memo;
312+
uint64_t amount;
313+
uint64_t fee;
314+
315+
uint8_t has_from_subaccount;
316+
sizedBuffer_t from_subaccount;
317+
318+
uint8_t to[DFINITY_ADDR_LEN];
319+
320+
uint8_t has_timestamp;
321+
uint64_t timestamp;
322+
} candid_transfer_t;
323+
245324
typedef struct {
246325
uint8_t icp_canister;
247326
Account_t account;
@@ -279,9 +358,12 @@ typedef struct {
279358
candid_Merge_t merge;
280359
candid_Configure_t configure;
281360
candid_StakeMaturity_t stake;
361+
candid_Disburse_t disburse;
362+
candid_RegisterVote_t vote;
363+
candid_Follow_t follow;
282364

283365
sns_NeuronPermissions_t neuronPermissions;
284-
sns_Disburse_t disburse;
366+
sns_Disburse_t sns_disburse;
285367
};
286368
} candid_Command_t;
287369

0 commit comments

Comments
 (0)