Преглед на файлове

Merge flipbip from https://github.com/xtruan/FlipBIP

Willy-JL преди 1 година
родител
ревизия
081cb30a68
променени са 8 файла, в които са добавени 111 реда и са изтрити 133 реда
  1. 1 1
      flipbip/application.fam
  2. 2 2
      flipbip/catalog/manifest.yml
  3. 1 1
      flipbip/flipbip.c
  4. 5 20
      flipbip/flipbip.h
  5. 16 0
      flipbip/flipbip_coins.c
  6. 31 0
      flipbip/flipbip_coins.h
  7. 17 51
      flipbip/scenes/flipbip_scene_menu.c
  8. 38 58
      flipbip/views/flipbip_scene_1.c

+ 1 - 1
flipbip/application.fam

@@ -17,6 +17,6 @@ App(
     fap_category="Tools",
     fap_author="Struan Clark (xtruan)",
     fap_weburl="https://github.com/xtruan/FlipBIP",
-    fap_version=(1, 17),
+    fap_version=(1, 18),
     fap_description="Crypto wallet for Flipper",
 )

+ 2 - 2
flipbip/catalog/manifest.yml

@@ -2,9 +2,9 @@ sourcecode:
   type: git
   location:
     origin: https://github.com/xtruan/FlipBIP.git
-    commit_sha: 62ef09fc3eede4494571d55f3d9340695482781a
+    commit_sha: 9f9bce59bc47ed03eda62380f32b33f09207516a
 description: "Cryptocurrency wallet with support for BTC, ETH, DOGE, and ZEC (t-addr)"
-changelog: "v1.17"
+changelog: "v1.18"
 author: "@xtruan"
 screenshots:
   - "./catalog/menu1.png"

+ 1 - 1
flipbip/flipbip.c

@@ -131,7 +131,7 @@ FlipBip* flipbip_app_alloc() {
     app->passphrase = FlipBipPassphraseOff;
 
     // Main menu
-    app->bip44_coin = FlipBipCoinBTC0; // 0 (BTC)
+    app->coin_type = CoinTypeBTC0; // 0 (BTC)
     app->overwrite_saved_seed = 0;
     app->import_from_mnemonic = 0;
     app->mnemonic_menu_text = MNEMONIC_MENU_DEFAULT;

+ 5 - 20
flipbip/flipbip.h

@@ -14,14 +14,9 @@
 #include <gui/modules/text_input.h>
 #include "scenes/flipbip_scene.h"
 #include "views/flipbip_scene_1.h"
+#include "flipbip_coins.h"
 
-#define FLIPBIP_VERSION "v1.17"
-
-#define COIN_BTC  0
-#define COIN_DOGE 3
-#define COIN_ETH  60
-#define COIN_ZEC  133
-
+#define FLIPBIP_VERSION  "v1.18"
 #define TEXT_BUFFER_SIZE 256
 
 typedef struct {
@@ -39,7 +34,7 @@ typedef struct {
     int bip39_strength;
     int passphrase;
     // Main menu options
-    int bip44_coin;
+    int coin_type;
     int overwrite_saved_seed;
     int import_from_mnemonic;
     // Text input
@@ -71,13 +66,6 @@ typedef enum {
     FlipBipPassphraseOn,
 } FlipBipPassphraseState;
 
-typedef enum {
-    FlipBipCoinBTC0,
-    FlipBipCoinETH60,
-    FlipBipCoinDOGE3,
-    FlipBipCoinZEC133,
-} FlipBipCoin;
-
 typedef enum {
     FlipBipTextInputDefault,
     FlipBipTextInputPassphrase,
@@ -92,12 +80,9 @@ typedef enum {
     FlipBipStatusMnemonicCheckError = 13,
 } FlipBipStatus;
 
+// There's a scene ID for each coin, then these scenes are after so need to offset the first entry by at least NUM_COINS
 typedef enum {
-    SubmenuIndexScene1BTC = 10,
-    SubmenuIndexScene1ETH,
-    SubmenuIndexScene1DOGE,
-    SubmenuIndexScene1ZEC,
-    SubmenuIndexScene1New,
+    SubmenuIndexScene1New = NUM_COINS + 1,
     SubmenuIndexScene1Renew,
     SubmenuIndexScene1Import,
     SubmenuIndexSettings,

+ 16 - 0
flipbip/flipbip_coins.c

@@ -0,0 +1,16 @@
+#include <flipbip_coins.h>
+
+// bip44_coin, xprv_version, xpub_version, addr_version, wif_version, addr_format
+const uint32_t COIN_INFO_ARRAY[NUM_COINS][COIN_INFO_SIZE] = {
+    {0, 0x0488ade4, 0x0488b21e, 0x00, 0x80, CoinTypeBTC0},
+    {60, 0x0488ade4, 0x0488b21e, 0x00, 0x80, CoinTypeETH60},
+    {3, 0x02fac398, 0x02facafd, 0x1e, 0x9e, CoinTypeBTC0},
+    {133, 0x0488ade4, 0x0488b21e, 0x1cb8, 0x80, CoinTypeBTC0},
+};
+
+// coin_label, derivation_path, coin_name, static_prefix ("_" for none)
+const char* COIN_TEXT_ARRAY[NUM_COINS][COIN_TEXT_SIZE] = {
+    {"BTC", "m/44'/0'/0'/0", "bitcoin:", "_"},
+    {"ETH", "m/44'/60'/0'/0", "ethereum:", "_"},
+    {"DOGE", "m/44'/3'/0'/0", "dogecoin:", "_"},
+    {"ZEC", "m/44'/133'/0'/0", "zcash:", "t"}};

+ 31 - 0
flipbip/flipbip_coins.h

@@ -0,0 +1,31 @@
+#pragma once
+#include <stdint.h>
+
+#define NUM_COINS 4
+
+typedef enum {
+    CoinTypeBTC0,
+    CoinTypeETH60,
+    CoinTypeDOGE3,
+    CoinTypeZEC133,
+} CoinType;
+
+#define COIN_INFO_SIZE       6
+#define COIN_INFO_BIP44_COIN 0
+#define COIN_INFO_XPRV_VERS  1
+#define COIN_INFO_XPUB_VERS  2
+#define COIN_INFO_ADDR_VERS  3
+#define COIN_INFO_WIF_VERS   4
+#define COIN_INFO_ADDR_FMT   5
+
+// bip44_coin, xprv_version, xpub_version, addr_version, wif_version, addr_format
+extern const uint32_t COIN_INFO_ARRAY[NUM_COINS][COIN_INFO_SIZE];
+
+#define COIN_TEXT_SIZE   4
+#define COIN_TEXT_LABEL  0
+#define COIN_TEXT_DERIV  1
+#define COIN_TEXT_NAME   2
+#define COIN_TEXT_PREFIX 3
+
+// coin_label, derivation_path, coin_name, static_prefix ("_" for none)
+extern const char* COIN_TEXT_ARRAY[NUM_COINS][COIN_TEXT_SIZE];

+ 17 - 51
flipbip/scenes/flipbip_scene_menu.c

@@ -22,30 +22,20 @@ void flipbip_scene_menu_on_enter(void* context) {
 
     if(flipbip_has_file(FlipBipFileKey, NULL, false) &&
        flipbip_has_file(FlipBipFileDat, NULL, false)) {
-        submenu_add_item(
-            app->submenu,
-            "View BTC wallet",
-            SubmenuIndexScene1BTC,
-            flipbip_scene_menu_submenu_callback,
-            app);
-        submenu_add_item(
-            app->submenu,
-            "View ETH wallet",
-            SubmenuIndexScene1ETH,
-            flipbip_scene_menu_submenu_callback,
-            app);
-        submenu_add_item(
-            app->submenu,
-            "View DOGE wallet",
-            SubmenuIndexScene1DOGE,
-            flipbip_scene_menu_submenu_callback,
-            app);
-        submenu_add_item(
-            app->submenu,
-            "View ZEC (t-addr) wallet",
-            SubmenuIndexScene1ZEC,
-            flipbip_scene_menu_submenu_callback,
-            app);
+        for(uint32_t coin_type = 0; coin_type < NUM_COINS; coin_type++) {
+            char wallet_menu_item[17] = "View      wallet";
+            strncpy(
+                wallet_menu_item + 5,
+                COIN_TEXT_ARRAY[coin_type][COIN_TEXT_LABEL],
+                strlen(COIN_TEXT_ARRAY[coin_type][COIN_TEXT_LABEL]));
+            submenu_add_item(
+                app->submenu,
+                wallet_menu_item,
+                coin_type,
+                flipbip_scene_menu_submenu_callback,
+                app);
+        }
+
         submenu_add_item(
             app->submenu,
             "Regenerate wallet",
@@ -85,36 +75,12 @@ bool flipbip_scene_menu_on_event(void* context, SceneManagerEvent event) {
         view_dispatcher_stop(app->view_dispatcher);
         return true;
     } else if(event.type == SceneManagerEventTypeCustom) {
-        if(event.event == SubmenuIndexScene1BTC) {
-            app->overwrite_saved_seed = 0;
-            app->import_from_mnemonic = 0;
-            app->bip44_coin = FlipBipCoinBTC0;
-            scene_manager_set_scene_state(
-                app->scene_manager, FlipBipSceneMenu, SubmenuIndexScene1BTC);
-            scene_manager_next_scene(app->scene_manager, FlipBipSceneScene_1);
-            return true;
-        } else if(event.event == SubmenuIndexScene1ETH) {
-            app->overwrite_saved_seed = 0;
-            app->import_from_mnemonic = 0;
-            app->bip44_coin = FlipBipCoinETH60;
-            scene_manager_set_scene_state(
-                app->scene_manager, FlipBipSceneMenu, SubmenuIndexScene1ETH);
-            scene_manager_next_scene(app->scene_manager, FlipBipSceneScene_1);
-            return true;
-        } else if(event.event == SubmenuIndexScene1DOGE) {
-            app->overwrite_saved_seed = 0;
-            app->import_from_mnemonic = 0;
-            app->bip44_coin = FlipBipCoinDOGE3;
-            scene_manager_set_scene_state(
-                app->scene_manager, FlipBipSceneMenu, SubmenuIndexScene1DOGE);
-            scene_manager_next_scene(app->scene_manager, FlipBipSceneScene_1);
-            return true;
-        } else if(event.event == SubmenuIndexScene1ZEC) {
+        if(event.event < SubmenuIndexScene1New) {
             app->overwrite_saved_seed = 0;
             app->import_from_mnemonic = 0;
-            app->bip44_coin = FlipBipCoinZEC133;
+            app->coin_type = event.event; // CoinType
             scene_manager_set_scene_state(
-                app->scene_manager, FlipBipSceneMenu, SubmenuIndexScene1ZEC);
+                app->scene_manager, FlipBipSceneMenu, event.event); // CoinType
             scene_manager_next_scene(app->scene_manager, FlipBipSceneScene_1);
             return true;
         } else if(event.event == SubmenuIndexScene1New) {

+ 38 - 58
flipbip/views/flipbip_scene_1.c

@@ -51,21 +51,6 @@ const char* TEXT_INFO = "-Scroll pages with up/down-"
 // #define TEXT_SAVE_QR "Save QR"
 #define TEXT_QRFILE_EXT ".qrcode" // 7 chars + 1 null
 
-// bip44_coin, xprv_version, xpub_version, addr_version, wif_version, addr_format
-const uint32_t COIN_INFO_ARRAY[4][6] = {
-    {COIN_BTC, 0x0488ade4, 0x0488b21e, 0x00, 0x80, FlipBipCoinBTC0},
-    {COIN_ETH, 0x0488ade4, 0x0488b21e, 0x00, 0x80, FlipBipCoinETH60},
-    {COIN_DOGE, 0x02fac398, 0x02facafd, 0x1e, 0x9e, FlipBipCoinBTC0},
-    {COIN_ZEC, 0x0488ade4, 0x0488b21e, 0x1cb8, 0x80, FlipBipCoinZEC133},
-};
-
-// coin_name, derivation_path
-const char* COIN_TEXT_ARRAY[4][3] = {
-    {"BTC", "m/44'/0'/0'/0", "bitcoin:"},
-    {"ETH", "m/44'/60'/0'/0", "ethereum:"},
-    {"DOGE", "m/44'/3'/0'/0", "dogecoin:"},
-    {"ZEC", "m/44'/133'/0'/0", "zcash:"}};
-
 struct FlipBipScene1 {
     View* view;
     FlipBipScene1Callback callback;
@@ -74,7 +59,7 @@ struct FlipBipScene1 {
 typedef struct {
     int page;
     int strength;
-    uint32_t coin;
+    uint32_t coin_type;
     bool overwrite;
     bool mnemonic_only;
     CONFIDENTIAL const char* mnemonic;
@@ -135,33 +120,29 @@ static void flipbip_scene_1_init_address(
     hdnode_private_ckd(s_addr_node, addr_index);
     hdnode_fill_public_key(s_addr_node);
 
-    // coin info
-    // bip44_coin, xprv_version, xpub_version, addr_version, wif_version, addr_format
-    uint32_t coin_info[6] = {0};
-    for(size_t i = 0; i < 6; i++) {
-        coin_info[i] = COIN_INFO_ARRAY[coin_type][i];
-    }
-
-    if(coin_info[5] == FlipBipCoinBTC0) { // BTC / DOGE style address
+    if(COIN_INFO_ARRAY[coin_type][COIN_INFO_ADDR_FMT] == CoinTypeBTC0) {
         // BTC / DOGE style address
         ecdsa_get_address(
-            s_addr_node->public_key, coin_info[3], HASHER_SHA2_RIPEMD, HASHER_SHA2D, buf, buflen);
+            s_addr_node->public_key,
+            COIN_INFO_ARRAY[coin_type][COIN_INFO_ADDR_VERS],
+            HASHER_SHA2_RIPEMD,
+            HASHER_SHA2D,
+            buf,
+            buflen);
+        // If prefix is set (not '_') then override beginning of addr_text
+        if(COIN_TEXT_ARRAY[coin_type][COIN_TEXT_PREFIX][0] != '_') {
+            addr_text[0] = COIN_TEXT_ARRAY[coin_type][COIN_TEXT_PREFIX][0];
+        }
         strcpy(addr_text, buf);
         //ecdsa_get_wif(addr_node->private_key, WIF_VERSION, HASHER_SHA2D, buf, buflen);
 
-    } else if(coin_info[5] == FlipBipCoinETH60) { // ETH
+    } else if(COIN_INFO_ARRAY[coin_type][COIN_INFO_ADDR_FMT] == CoinTypeETH60) {
         // ETH style address
         hdnode_get_ethereum_pubkeyhash(s_addr_node, (uint8_t*)buf);
         addr_text[0] = '0';
         addr_text[1] = 'x';
         // Convert the hash to a hex string
         flipbip_btox((uint8_t*)buf, 20, addr_text + 2);
-
-    } else if(coin_info[5] == FlipBipCoinZEC133) { // ZEC
-        ecdsa_get_address(
-            s_addr_node->public_key, coin_info[3], HASHER_SHA2_RIPEMD, HASHER_SHA2D, buf, buflen);
-        addr_text[0] = 't';
-        strcpy(addr_text, buf);
     }
 
     // Clear the address node
@@ -305,7 +286,7 @@ void flipbip_scene_1_draw(Canvas* canvas, FlipBipScene1Model* model) {
         flipbip_scene_1_draw_generic(model->xpub_extended, 20, false);
     } else if(model->page >= PAGE_ADDR_BEGIN && model->page <= PAGE_ADDR_END) {
         size_t line_len = 12;
-        if(model->coin == FlipBipCoinETH60) {
+        if(model->coin_type == CoinTypeETH60) {
             line_len = 14;
         }
         flipbip_scene_1_draw_generic(
@@ -327,7 +308,7 @@ void flipbip_scene_1_draw(Canvas* canvas, FlipBipScene1Model* model) {
         // draw address header
         canvas_set_font(canvas, FontSecondary);
         // coin_name, derivation_path
-        const char* receive_text = COIN_TEXT_ARRAY[model->coin][0];
+        const char* receive_text = COIN_TEXT_ARRAY[model->coin_type][COIN_TEXT_LABEL];
         if(receive_text == NULL) {
             receive_text = TEXT_DEFAULT_COIN;
         }
@@ -345,7 +326,7 @@ void flipbip_scene_1_draw(Canvas* canvas, FlipBipScene1Model* model) {
 
         // draw QR code file path
         char addr_name_text[14] = {0};
-        strcpy(addr_name_text, COIN_TEXT_ARRAY[model->coin][0]);
+        strcpy(addr_name_text, COIN_TEXT_ARRAY[model->coin_type][COIN_TEXT_LABEL]);
         flipbip_btox(addr_num, 1, addr_name_text + strlen(addr_name_text));
         strcpy(addr_name_text + strlen(addr_name_text), TEXT_QRFILE_EXT);
         //elements_button_right(canvas, addr_name_text);
@@ -371,13 +352,13 @@ void flipbip_scene_1_draw(Canvas* canvas, FlipBipScene1Model* model) {
 static int flipbip_scene_1_model_init(
     FlipBipScene1Model* const model,
     const int strength,
-    const uint32_t coin,
+    const uint32_t coin_type,
     const bool overwrite,
     const char* passphrase_text) {
     model->page = PAGE_LOADING;
     model->mnemonic_only = false;
     model->strength = strength;
-    model->coin = coin;
+    model->coin_type = coin_type;
     model->overwrite = overwrite;
 
     // Allocate memory for mnemonic
@@ -435,16 +416,10 @@ static int flipbip_scene_1_model_init(
     const size_t buflen = 128;
     char buf[128 + 1] = {0};
 
-    // coin info
-    // bip44_coin, xprv_version, xpub_version, addr_version, wif_version, addr_format
-    uint32_t coin_info[6] = {0};
-    for(size_t i = 0; i < 6; i++) {
-        coin_info[i] = COIN_INFO_ARRAY[coin][i];
-    }
-
     // root
     uint32_t fingerprint = 0;
-    hdnode_serialize_private(root, fingerprint, coin_info[1], buf, buflen);
+    hdnode_serialize_private(
+        root, fingerprint, COIN_INFO_ARRAY[coin_type][COIN_INFO_XPRV_VERS], buf, buflen);
     char* xprv_root = malloc(buflen + 1);
     strncpy(xprv_root, buf, buflen);
     model->xprv_root = xprv_root;
@@ -457,18 +432,20 @@ static int flipbip_scene_1_model_init(
 
     // coin m/44'/0' or m/44'/60'
     fingerprint = hdnode_fingerprint(node);
-    hdnode_private_ckd_prime(node, coin_info[0]); // coin
+    hdnode_private_ckd_prime(node, COIN_INFO_ARRAY[coin_type][COIN_INFO_BIP44_COIN]); // coin
 
     // account m/44'/0'/0' or m/44'/60'/0'
     fingerprint = hdnode_fingerprint(node);
     hdnode_private_ckd_prime(node, DERIV_ACCOUNT); // account
 
-    hdnode_serialize_private(node, fingerprint, coin_info[1], buf, buflen);
+    hdnode_serialize_private(
+        node, fingerprint, COIN_INFO_ARRAY[coin_type][COIN_INFO_XPRV_VERS], buf, buflen);
     char* xprv_acc = malloc(buflen + 1);
     strncpy(xprv_acc, buf, buflen);
     model->xprv_account = xprv_acc;
 
-    hdnode_serialize_public(node, fingerprint, coin_info[2], buf, buflen);
+    hdnode_serialize_public(
+        node, fingerprint, COIN_INFO_ARRAY[coin_type][COIN_INFO_XPUB_VERS], buf, buflen);
     char* xpub_acc = malloc(buflen + 1);
     strncpy(xpub_acc, buf, buflen);
     model->xpub_account = xpub_acc;
@@ -477,12 +454,14 @@ static int flipbip_scene_1_model_init(
     fingerprint = hdnode_fingerprint(node);
     hdnode_private_ckd(node, DERIV_CHANGE); // external/internal (change)
 
-    hdnode_serialize_private(node, fingerprint, coin_info[1], buf, buflen);
+    hdnode_serialize_private(
+        node, fingerprint, COIN_INFO_ARRAY[coin_type][COIN_INFO_XPRV_VERS], buf, buflen);
     char* xprv_ext = malloc(buflen + 1);
     strncpy(xprv_ext, buf, buflen);
     model->xprv_extended = xprv_ext;
 
-    hdnode_serialize_public(node, fingerprint, coin_info[2], buf, buflen);
+    hdnode_serialize_public(
+        node, fingerprint, COIN_INFO_ARRAY[coin_type][COIN_INFO_XPUB_VERS], buf, buflen);
     char* xpub_ext = malloc(buflen + 1);
     strncpy(xpub_ext, buf, buflen);
     model->xpub_extended = xpub_ext;
@@ -493,15 +472,16 @@ static int flipbip_scene_1_model_init(
     for(uint8_t a = 0; a < NUM_ADDRS; a++) {
         model->recv_addresses[a] = malloc(MAX_ADDR_BUF);
         memzero(model->recv_addresses[a], MAX_ADDR_BUF);
-        flipbip_scene_1_init_address(model->recv_addresses[a], node, coin, a);
+        flipbip_scene_1_init_address(model->recv_addresses[a], node, coin_type, a);
 
         // Save QR code file
         memzero(buf, buflen);
-        strcpy(buf, COIN_TEXT_ARRAY[coin][0]);
+        strcpy(buf, COIN_TEXT_ARRAY[coin_type][COIN_TEXT_LABEL]);
         const unsigned char addr_num[1] = {a};
         flipbip_btox(addr_num, 1, buf + strlen(buf));
         strcpy(buf + strlen(buf), TEXT_QRFILE_EXT);
-        flipbip_save_qrfile(COIN_TEXT_ARRAY[coin][2], model->recv_addresses[a], buf);
+        flipbip_save_qrfile(
+            COIN_TEXT_ARRAY[coin_type][COIN_TEXT_NAME], model->recv_addresses[a], buf);
         memzero(buf, buflen);
     }
 
@@ -597,7 +577,7 @@ void flipbip_scene_1_exit(void* context) {
         {
             model->page = PAGE_LOADING;
             model->strength = FlipBipStrength256;
-            model->coin = FlipBipCoinBTC0;
+            model->coin_type = CoinTypeBTC0;
             memzero(model->seed, 64);
             // if mnemonic_only is true, then we don't need to free the data here
             if(!model->mnemonic_only) {
@@ -650,9 +630,9 @@ void flipbip_scene_1_enter(void* context) {
     }
 
     // BIP44 Coin setting
-    const uint32_t coin = app->bip44_coin;
+    const uint32_t coin_type = app->coin_type;
     // coin_name, derivation_path
-    s_derivation_text = COIN_TEXT_ARRAY[coin][1];
+    s_derivation_text = COIN_TEXT_ARRAY[coin_type][COIN_TEXT_DERIV];
 
     // Overwrite the saved seed with a new one setting
     bool overwrite = app->overwrite_saved_seed != 0;
@@ -661,7 +641,7 @@ void flipbip_scene_1_enter(void* context) {
     }
 
     // Wait a beat to allow the display time to update to the loading screen
-    furi_thread_flags_wait(0, FuriFlagWaitAny, 20);
+    furi_thread_flags_wait(0, FuriFlagWaitAny, 50);
 
     //flipbip_play_happy_bump(app);
     //notification_message(app->notification, &sequence_blink_cyan_100);
@@ -674,7 +654,7 @@ void flipbip_scene_1_enter(void* context) {
             // s_busy = true;
 
             const int status =
-                flipbip_scene_1_model_init(model, strength, coin, overwrite, passphrase_text);
+                flipbip_scene_1_model_init(model, strength, coin_type, overwrite, passphrase_text);
 
             // nonzero status, free the mnemonic
             if(status != FlipBipStatusSuccess) {