void fsm_msgGetAddress(GetAddress *msg) { RESP_INIT(Address); HDNode *node = fsm_getRootNode(); if (!node) return; const CoinType *coin = coinByName(msg->coin_name); if (!coin) { fsm_sendFailure(FailureType_Failure_Other, "Invalid coin name"); layoutHome(); return; } fsm_deriveKey(node, msg->address_n, msg->address_n_count); ecdsa_get_address(node->public_key, coin->address_type, resp->address); if (msg->has_show_display && msg->show_display) { layoutAddress(resp->address); if (!protectButton(ButtonRequestType_ButtonRequest_Address, true)) { fsm_sendFailure(FailureType_Failure_ActionCancelled, "Show address cancelled"); layoutHome(); return; } } msg_write(MessageType_MessageType_Address, resp); layoutHome(); }
void fsm_msgGetAddress(GetAddress *msg) { RESP_INIT(Address); if (!protectPin(true)) { layoutHome(); return; } const CoinType *coin = fsm_getCoin(msg->coin_name); if (!coin) return; const HDNode *node = fsm_getDerivedNode(msg->address_n, msg->address_n_count); if (!node) return; if (msg->has_multisig) { layoutProgressSwipe("Preparing", 0); if (cryptoMultisigPubkeyIndex(&(msg->multisig), node->public_key) < 0) { fsm_sendFailure(FailureType_Failure_Other, "Pubkey not found in multisig script"); layoutHome(); return; } uint8_t buf[32]; if (compile_script_multisig_hash(&(msg->multisig), buf) == 0) { fsm_sendFailure(FailureType_Failure_Other, "Invalid multisig script"); layoutHome(); return; } ripemd160(buf, 32, buf + 1); buf[0] = coin->address_type_p2sh; // multisig cointype base58_encode_check(buf, 21, resp->address, sizeof(resp->address)); } else { ecdsa_get_address(node->public_key, coin->address_type, resp->address, sizeof(resp->address)); } if (msg->has_show_display && msg->show_display) { char desc[16]; if (msg->has_multisig) { strlcpy(desc, "Msig __ of __:", sizeof(desc)); const uint32_t m = msg->multisig.m; const uint32_t n = msg->multisig.pubkeys_count; desc[5] = (m < 10) ? ' ': ('0' + (m / 10)); desc[6] = '0' + (m % 10); desc[11] = (n < 10) ? ' ': ('0' + (n / 10)); desc[12] = '0' + (n % 10); } else { strlcpy(desc, "Address:", sizeof(desc)); } layoutAddress(resp->address, desc); if (!protectButton(ButtonRequestType_ButtonRequest_Address, true)) { fsm_sendFailure(FailureType_Failure_ActionCancelled, "Show address cancelled"); layoutHome(); return; } } msg_write(MessageType_MessageType_Address, resp); layoutHome(); }
static bool fsm_layoutAddress(const char *address, const char *desc, bool ignorecase, size_t prefixlen, const uint32_t *address_n, size_t address_n_count) { bool qrcode = false; for (;;) { const char* display_addr = address; if (prefixlen && !qrcode) { display_addr += prefixlen; } layoutAddress(display_addr, desc, qrcode, ignorecase, address_n, address_n_count); if (protectButton(ButtonRequest_ButtonRequestType_ButtonRequest_Address, false)) { return true; } if (protectAbortedByCancel || protectAbortedByInitialize) { fsm_sendFailure(Failure_FailureType_Failure_ActionCancelled, NULL); layoutHome(); return false; } qrcode = !qrcode; } }