Struan Clark пре 2 година
родитељ
комит
90d001aab3
4 измењених фајлова са 99 додато и 20 уклоњено
  1. 46 5
      flipbip.c
  2. 15 2
      flipbip.h
  3. 16 0
      scenes/flipbip_scene_menu.c
  4. 22 13
      views/flipbip_scene_1.c

+ 46 - 5
flipbip.c

@@ -1,5 +1,8 @@
 #include "flipbip.h"
 #include "crypto/memzero.h"
+#include "crypto/bip39.h"
+#include "helpers/flipbip_file.h"
+#include "helpers/flipbip_haptic.h"
 
 bool flipbip_custom_event_callback(void* context, uint32_t event) {
     furi_assert(context);
@@ -23,6 +26,7 @@ bool flipbip_navigation_event_callback(void* context) {
 static void text_input_callback(void* context) {
     furi_assert(context);
     FlipBip* app = context;
+    bool handled = false;
 
     // check that there is text in the input
     if(strlen(app->input_text) > 0) {
@@ -30,14 +34,46 @@ static void text_input_callback(void* context) {
             if(app->passphrase == FlipBipPassphraseOn) {
                 strcpy(app->passphrase_text, app->input_text);
             }
+            // clear input text
+            memzero(app->input_text, TEXT_BUFFER_SIZE);
+            // reset input state
+            app->input_state = FlipBipTextInputDefault;
+            handled = true;
             view_dispatcher_switch_to_view(app->view_dispatcher, FlipBipViewIdSettings);
+        } else if(app->input_state == FlipBipTextInputMnemonic) {
+            if(app->import_from_mnemonic == 1) {
+                strcpy(app->import_mnemonic_text, app->input_text);
+
+                int status = FlipBipStatusSuccess;
+                // Check if the mnemonic is valid
+                if(mnemonic_check(app->import_mnemonic_text) == 0) status = FlipBipStatusMnemonicCheckError; // 13 = mnemonic check error
+                // Save the mnemonic to persistent storage
+                else if(!flipbip_save_settings_secure(app->import_mnemonic_text)) status = FlipBipStatusSaveError; // 12 = save error
+                
+                if (status == FlipBipStatusSuccess) {
+                    flipbip_play_happy_bump(app);
+                } else {
+                    flipbip_play_long_bump(app);
+                }
+
+                memzero(app->import_mnemonic_text, TEXT_BUFFER_SIZE);
+            }
+            // clear input text
+            memzero(app->input_text, TEXT_BUFFER_SIZE);
+            // reset input state
+            app->input_state = FlipBipTextInputDefault;
+            handled = true;
+            view_dispatcher_switch_to_view(app->view_dispatcher, FlipBipViewIdMenu);
         }
     }
 
-    // clear input text
-    memzero(app->input_text, TEXT_BUFFER_SIZE);
-    // reset input state
-    app->input_state = FlipBipTextInputDefault;
+    if(!handled) {
+        // clear input text
+        memzero(app->input_text, TEXT_BUFFER_SIZE);
+        // reset input state
+        app->input_state = FlipBipTextInputDefault;
+        view_dispatcher_switch_to_view(app->view_dispatcher, FlipBipViewIdMenu);
+    }
 }
 
 FlipBip* flipbip_app_alloc() {
@@ -64,10 +100,15 @@ FlipBip* flipbip_app_alloc() {
     // Settings
     app->haptic = FlipBipHapticOn;
     app->led = FlipBipLedOn;
-    app->passphrase = FlipBipPassphraseOff;
     app->bip39_strength = FlipBipStrength256; // 256 bits (24 words)
+    app->passphrase = FlipBipPassphraseOff;
+
+    // Main menu
     app->bip44_coin = FlipBipCoinBTC0; // 0 (BTC)
     app->overwrite_saved_seed = 0;
+    app->import_from_mnemonic = 0;
+
+    // Text input
     app->input_state = FlipBipTextInputDefault;
 
     view_dispatcher_add_view(

+ 15 - 2
flipbip.h

@@ -33,14 +33,19 @@ typedef struct {
     TextInput* text_input;
     FlipBipStartscreen* flipbip_startscreen;
     FlipBipScene1* flipbip_scene_1;
+    // Settings options
     int haptic;
     int led;
-    int passphrase;
     int bip39_strength;
+    int passphrase;
+    // Main menu options
     int bip44_coin;
     int overwrite_saved_seed;
+    int import_from_mnemonic;
+    // Text input
     int input_state;
     char passphrase_text[TEXT_BUFFER_SIZE];
+    char import_mnemonic_text[TEXT_BUFFER_SIZE];
     char input_text[TEXT_BUFFER_SIZE];
 } FlipBip;
 
@@ -83,4 +88,12 @@ typedef enum {
     FlipBipTextInputDefault,
     FlipBipTextInputPassphrase,
     FlipBipTextInputMnemonic
-} FlipBipTextInputState;
+} FlipBipTextInputState;
+
+typedef enum {
+    FlipBipStatusSuccess = 0,
+    FlipBipStatusReturn = 10,
+    FlipBipStatusLoadError = 11,
+    FlipBipStatusSaveError = 12,
+    FlipBipStatusMnemonicCheckError = 13,
+} FlipBipStatus;

+ 16 - 0
scenes/flipbip_scene_menu.c

@@ -6,6 +6,7 @@ enum SubmenuIndex {
     SubmenuIndexScene1ETH,
     SubmenuIndexScene1DOGE,
     SubmenuIndexScene1New,
+    SubmenuIndexScene1Import,
     SubmenuIndexSettings,
 };
 
@@ -50,6 +51,12 @@ void flipbip_scene_menu_on_enter(void* context) {
             flipbip_scene_menu_submenu_callback,
             app);
     }
+    submenu_add_item(
+        app->submenu,
+        "Import from mnemonic",
+        SubmenuIndexScene1Import,
+        flipbip_scene_menu_submenu_callback,
+        app);
 
     submenu_add_item(
         app->submenu, "Settings", SubmenuIndexSettings, flipbip_scene_menu_submenu_callback, app);
@@ -71,6 +78,7 @@ bool flipbip_scene_menu_on_event(void* context, SceneManagerEvent event) {
     } 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);
@@ -78,6 +86,7 @@ bool flipbip_scene_menu_on_event(void* context, SceneManagerEvent event) {
             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);
@@ -85,6 +94,7 @@ bool flipbip_scene_menu_on_event(void* context, SceneManagerEvent event) {
             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);
@@ -92,10 +102,16 @@ bool flipbip_scene_menu_on_event(void* context, SceneManagerEvent event) {
             return true;
         } else if(event.event == SubmenuIndexScene1New) {
             app->overwrite_saved_seed = 1;
+            app->import_from_mnemonic = 0;
             scene_manager_set_scene_state(
                 app->scene_manager, FlipBipSceneMenu, SubmenuIndexScene1New);
             scene_manager_next_scene(app->scene_manager, FlipBipSceneScene_1);
             return true;
+        } else if(event.event == SubmenuIndexScene1Import) {
+            app->import_from_mnemonic = 1;
+            app->input_state = FlipBipTextInputMnemonic;
+            view_dispatcher_switch_to_view(app->view_dispatcher, FlipBipViewIdTextInput);
+            return true;
         } else if(event.event == SubmenuIndexSettings) {
             scene_manager_set_scene_state(
                 app->scene_manager, FlipBipSceneMenu, SubmenuIndexSettings);

+ 22 - 13
views/flipbip_scene_1.c

@@ -314,22 +314,24 @@ static int flipbip_scene_1_model_init(
     if(overwrite || (!flipbip_has_settings(true) && !flipbip_has_settings(false))) {
         // Generate a random mnemonic using trezor-crypto
         const char* mnemonic_gen = mnemonic_generate(strength);
+        // Check if the mnemonic is valid
+        if(mnemonic_check(mnemonic_gen) == 0) return FlipBipStatusMnemonicCheckError; // 13 = mnemonic check error
         // Save the mnemonic to persistent storage
-        if(!flipbip_save_settings_secure(mnemonic_gen)) return 1; // 1 = save error
+        else if(!flipbip_save_settings_secure(mnemonic_gen)) return FlipBipStatusSaveError; // 12 = save error
         // Clear the generated mnemonic from memory
         mnemonic_clear();
         model->mnemonic_only = true;
     }
 
     // Load the mnemonic from persistent storage
-    if(!flipbip_load_settings_secure(mnemonic)) return 2; // 2 = load error
+    if(!flipbip_load_settings_secure(mnemonic)) return FlipBipStatusLoadError; // 11 = load error
     model->mnemonic = mnemonic;
     // Check if the mnemonic is valid
-    if(mnemonic_check(model->mnemonic) == 0) return 3; // 3 = mnemonic check error
+    if(mnemonic_check(model->mnemonic) == 0) return FlipBipStatusMnemonicCheckError; // 13 = mnemonic check error
 
     // if we are only generating the mnemonic, return
     if(model->mnemonic_only) {
-        return -1; // -1 = mnemonic only, return from parent
+        return FlipBipStatusReturn; // 10 = mnemonic only, return from parent
     }
 
     // test mnemonic
@@ -408,7 +410,7 @@ static int flipbip_scene_1_model_init(
 #endif
 
     // 0 = success
-    return 0;
+    return FlipBipStatusSuccess;
 }
 
 bool flipbip_scene_1_input(InputEvent* event, void* context) {
@@ -524,7 +526,7 @@ void flipbip_scene_1_enter(void* context) {
     }
 
     // BIP44 Coin setting
-    uint32_t coin = app->bip44_coin;
+    const uint32_t coin = app->bip44_coin;
     // coin_name, derivation_path
     s_derivation_text = COIN_TEXT_ARRAY[coin][1];
 
@@ -543,31 +545,38 @@ void flipbip_scene_1_enter(void* context) {
         {
             // s_busy = true;
 
-            const int status =
-                flipbip_scene_1_model_init(model, strength, coin, overwrite, passphrase_text);
+            const int status = flipbip_scene_1_model_init(
+                model,
+                strength,
+                coin,
+                overwrite,
+                passphrase_text);
 
             // nonzero status, free the mnemonic
-            if(status != 0) {
+            if(status != FlipBipStatusSuccess) {
                 memzero((void*)model->mnemonic, strlen(model->mnemonic));
                 free((void*)model->mnemonic);
             }
 
             // if error, set the error message
-            if(status == 1) {
+            if(status == FlipBipStatusSaveError) {
                 model->mnemonic = "ERROR:,Save error";
                 model->page = 2;
-            } else if(status == 2) {
+                flipbip_play_long_bump(app);
+            } else if(status == FlipBipStatusLoadError) {
                 model->mnemonic = "ERROR:,Load error";
                 model->page = 2;
-            } else if(status == 3) {
+                flipbip_play_long_bump(app);
+            } else if(status == FlipBipStatusMnemonicCheckError) {
                 model->mnemonic = "ERROR:,Mnemonic check failed";
                 model->page = 2;
+                flipbip_play_long_bump(app);
             }
 
             // s_busy = false;
 
             // if overwrite is set and mnemonic generated, return from scene immediately
-            if(status == -1) {
+            if(status == FlipBipStatusReturn) {
                 instance->callback(FlipBipCustomEventScene1Back, instance->context);
             }
         },