mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-05-11 06:09:08 -07:00
FlipBIP v1.13 (#354)
This commit is contained in:
@@ -9,8 +9,6 @@ App(
|
||||
stack_size=3 * 1024,
|
||||
order=10,
|
||||
fap_icon="flipbip_10px.png",
|
||||
fap_icon_assets="icons",
|
||||
fap_icon_assets_symbol="flipbip",
|
||||
fap_private_libs=[
|
||||
Lib(
|
||||
name="crypto",
|
||||
@@ -19,6 +17,6 @@ App(
|
||||
fap_category="Tools",
|
||||
fap_author="Struan Clark (xtruan)",
|
||||
fap_weburl="https://github.com/xtruan/FlipBIP",
|
||||
fap_version=(1, 11),
|
||||
fap_description="Crypto wallet tools for Flipper",
|
||||
fap_version=(1, 13),
|
||||
fap_description="Crypto wallet for Flipper",
|
||||
)
|
||||
|
||||
47
applications/external/flipbip/flipbip.c
vendored
47
applications/external/flipbip/flipbip.c
vendored
@@ -1,12 +1,13 @@
|
||||
#pragma GCC optimize("-Os")
|
||||
|
||||
#include "flipbip.h"
|
||||
#include "helpers/flipbip_file.h"
|
||||
#include "helpers/flipbip_haptic.h"
|
||||
// From: lib/crypto
|
||||
#include <memzero.h>
|
||||
#include <bip39.h>
|
||||
|
||||
#define MNEMONIC_MENU_DEFAULT "Import mnemonic seed"
|
||||
#define MNEMONIC_MENU_SUCCESS "Import seed (success)"
|
||||
#define MNEMONIC_MENU_FAILURE "Import seed (failed!)"
|
||||
|
||||
bool flipbip_custom_event_callback(void* context, uint32_t event) {
|
||||
furi_assert(context);
|
||||
FlipBip* app = context;
|
||||
@@ -42,6 +43,7 @@ static void text_input_callback(void* context) {
|
||||
// reset input state
|
||||
app->input_state = FlipBipTextInputDefault;
|
||||
handled = true;
|
||||
// switch back to settings view
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, FlipBipViewIdSettings);
|
||||
} else if(app->input_state == FlipBipTextInputMnemonic) {
|
||||
if(app->import_from_mnemonic == 1) {
|
||||
@@ -56,11 +58,13 @@ static void text_input_callback(void* context) {
|
||||
status = FlipBipStatusSaveError; // 12 = save error
|
||||
|
||||
if(status == FlipBipStatusSuccess) {
|
||||
app->mnemonic_menu_text = MNEMONIC_MENU_SUCCESS;
|
||||
//notification_message(app->notification, &sequence_blink_cyan_100);
|
||||
flipbip_play_happy_bump(app);
|
||||
//flipbip_play_happy_bump(app);
|
||||
} else {
|
||||
app->mnemonic_menu_text = MNEMONIC_MENU_FAILURE;
|
||||
//notification_message(app->notification, &sequence_blink_red_100);
|
||||
flipbip_play_long_bump(app);
|
||||
//flipbip_play_long_bump(app);
|
||||
}
|
||||
|
||||
memzero(app->import_mnemonic_text, TEXT_BUFFER_SIZE);
|
||||
@@ -70,7 +74,9 @@ static void text_input_callback(void* context) {
|
||||
// reset input state
|
||||
app->input_state = FlipBipTextInputDefault;
|
||||
handled = true;
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, FlipBipViewIdMenu);
|
||||
// exit scene 1 instance that's being used for text input and go back to menu
|
||||
scene_manager_previous_scene(app->scene_manager);
|
||||
//view_dispatcher_switch_to_view(app->view_dispatcher, FlipBipViewIdMenu);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,6 +85,7 @@ static void text_input_callback(void* context) {
|
||||
memzero(app->input_text, TEXT_BUFFER_SIZE);
|
||||
// reset input state
|
||||
app->input_state = FlipBipTextInputDefault;
|
||||
// something went wrong, switch to menu view
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, FlipBipViewIdMenu);
|
||||
}
|
||||
}
|
||||
@@ -86,12 +93,12 @@ static void text_input_callback(void* context) {
|
||||
FlipBip* flipbip_app_alloc() {
|
||||
FlipBip* app = malloc(sizeof(FlipBip));
|
||||
app->gui = furi_record_open(RECORD_GUI);
|
||||
app->notification = furi_record_open(RECORD_NOTIFICATION);
|
||||
//app->notification = furi_record_open(RECORD_NOTIFICATION);
|
||||
|
||||
//Turn backlight on, believe me this makes testing your app easier
|
||||
notification_message(app->notification, &sequence_display_backlight_on);
|
||||
// Turn backlight on, believe me this makes testing your app easier
|
||||
//notification_message(app->notification, &sequence_display_backlight_on);
|
||||
|
||||
//Scene additions
|
||||
// Scene additions
|
||||
app->view_dispatcher = view_dispatcher_alloc();
|
||||
view_dispatcher_enable_queue(app->view_dispatcher);
|
||||
|
||||
@@ -105,8 +112,6 @@ FlipBip* flipbip_app_alloc() {
|
||||
app->submenu = submenu_alloc();
|
||||
|
||||
// Settings
|
||||
app->haptic = FlipBipHapticOn;
|
||||
app->led = FlipBipLedOn;
|
||||
app->bip39_strength = FlipBipStrength256; // 256 bits (24 words)
|
||||
app->passphrase = FlipBipPassphraseOff;
|
||||
|
||||
@@ -114,17 +119,13 @@ FlipBip* flipbip_app_alloc() {
|
||||
app->bip44_coin = FlipBipCoinBTC0; // 0 (BTC)
|
||||
app->overwrite_saved_seed = 0;
|
||||
app->import_from_mnemonic = 0;
|
||||
app->mnemonic_menu_text = MNEMONIC_MENU_DEFAULT;
|
||||
|
||||
// Text input
|
||||
app->input_state = FlipBipTextInputDefault;
|
||||
|
||||
view_dispatcher_add_view(
|
||||
app->view_dispatcher, FlipBipViewIdMenu, submenu_get_view(app->submenu));
|
||||
app->flipbip_startscreen = flipbip_startscreen_alloc();
|
||||
view_dispatcher_add_view(
|
||||
app->view_dispatcher,
|
||||
FlipBipViewIdStartscreen,
|
||||
flipbip_startscreen_get_view(app->flipbip_startscreen));
|
||||
app->flipbip_scene_1 = flipbip_scene_1_alloc();
|
||||
view_dispatcher_add_view(
|
||||
app->view_dispatcher, FlipBipViewIdScene1, flipbip_scene_1_get_view(app->flipbip_scene_1));
|
||||
@@ -141,13 +142,13 @@ FlipBip* flipbip_app_alloc() {
|
||||
(void*)app,
|
||||
app->input_text,
|
||||
TEXT_BUFFER_SIZE,
|
||||
//clear default text
|
||||
// clear default text
|
||||
true);
|
||||
text_input_set_header_text(app->text_input, "Input");
|
||||
//text_input_set_header_text(app->text_input, "Input");
|
||||
view_dispatcher_add_view(
|
||||
app->view_dispatcher, FlipBipViewIdTextInput, text_input_get_view(app->text_input));
|
||||
|
||||
//End Scene Additions
|
||||
// End Scene Additions
|
||||
|
||||
return app;
|
||||
}
|
||||
@@ -171,7 +172,7 @@ void flipbip_app_free(FlipBip* app) {
|
||||
furi_record_close(RECORD_GUI);
|
||||
|
||||
app->gui = NULL;
|
||||
app->notification = NULL;
|
||||
//app->notification = NULL;
|
||||
|
||||
//Remove whatever is left
|
||||
memzero(app, sizeof(FlipBip));
|
||||
@@ -190,9 +191,7 @@ int32_t flipbip_app(void* p) {
|
||||
|
||||
view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen);
|
||||
|
||||
scene_manager_next_scene(
|
||||
app->scene_manager, FlipBipSceneStartscreen); //Start with start screen
|
||||
//scene_manager_next_scene(app->scene_manager, FlipBipSceneMenu); //if you want to directly start with Menu
|
||||
scene_manager_next_scene(app->scene_manager, FlipBipSceneMenu); //Start with menu
|
||||
|
||||
furi_hal_power_suppress_charge_enter();
|
||||
|
||||
|
||||
23
applications/external/flipbip/flipbip.h
vendored
23
applications/external/flipbip/flipbip.h
vendored
@@ -5,37 +5,35 @@
|
||||
#include <gui/gui.h>
|
||||
#include <input/input.h>
|
||||
#include <stdlib.h>
|
||||
#include <notification/notification_messages.h>
|
||||
//#include <notification/notification_messages.h>
|
||||
#include <gui/view_dispatcher.h>
|
||||
#include <gui/modules/submenu.h>
|
||||
#include <gui/scene_manager.h>
|
||||
#include <gui/modules/variable_item_list.h>
|
||||
#include <gui/modules/text_input.h>
|
||||
#include "scenes/flipbip_scene.h"
|
||||
#include "views/flipbip_startscreen.h"
|
||||
#include "views/flipbip_scene_1.h"
|
||||
|
||||
#define FLIPBIP_VERSION "v1.11.0"
|
||||
#define FLIPBIP_VERSION "v1.13"
|
||||
|
||||
#define COIN_BTC 0
|
||||
#define COIN_DOGE 3
|
||||
#define COIN_ETH 60
|
||||
#define COIN_ZEC 133
|
||||
|
||||
#define TEXT_BUFFER_SIZE 256
|
||||
|
||||
typedef struct {
|
||||
Gui* gui;
|
||||
NotificationApp* notification;
|
||||
// NotificationApp* notification;
|
||||
ViewDispatcher* view_dispatcher;
|
||||
Submenu* submenu;
|
||||
SceneManager* scene_manager;
|
||||
VariableItemList* variable_item_list;
|
||||
TextInput* text_input;
|
||||
FlipBipStartscreen* flipbip_startscreen;
|
||||
FlipBipScene1* flipbip_scene_1;
|
||||
char* mnemonic_menu_text;
|
||||
// Settings options
|
||||
int haptic;
|
||||
int led;
|
||||
int bip39_strength;
|
||||
int passphrase;
|
||||
// Main menu options
|
||||
@@ -57,16 +55,6 @@ typedef enum {
|
||||
FlipBipViewIdTextInput,
|
||||
} FlipBipViewId;
|
||||
|
||||
typedef enum {
|
||||
FlipBipHapticOff,
|
||||
FlipBipHapticOn,
|
||||
} FlipBipHapticState;
|
||||
|
||||
typedef enum {
|
||||
FlipBipLedOff,
|
||||
FlipBipLedOn,
|
||||
} FlipBipLedState;
|
||||
|
||||
typedef enum {
|
||||
FlipBipStrength128,
|
||||
FlipBipStrength192,
|
||||
@@ -82,6 +70,7 @@ typedef enum {
|
||||
FlipBipCoinBTC0,
|
||||
FlipBipCoinETH60,
|
||||
FlipBipCoinDOGE3,
|
||||
FlipBipCoinZEC133,
|
||||
} FlipBipCoin;
|
||||
|
||||
typedef enum {
|
||||
|
||||
@@ -1,12 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
typedef enum {
|
||||
FlipBipCustomEventStartscreenUp,
|
||||
FlipBipCustomEventStartscreenDown,
|
||||
FlipBipCustomEventStartscreenLeft,
|
||||
FlipBipCustomEventStartscreenRight,
|
||||
FlipBipCustomEventStartscreenOk,
|
||||
FlipBipCustomEventStartscreenBack,
|
||||
FlipBipCustomEventScene1Up,
|
||||
FlipBipCustomEventScene1Down,
|
||||
FlipBipCustomEventScene1Left,
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
#include "flipbip_haptic.h"
|
||||
#include "../flipbip.h"
|
||||
|
||||
void flipbip_play_happy_bump(void* context) {
|
||||
FlipBip* app = context;
|
||||
if(app->haptic != 1) {
|
||||
return;
|
||||
}
|
||||
notification_message(app->notification, &sequence_set_vibro_on);
|
||||
furi_thread_flags_wait(0, FuriFlagWaitAny, 20);
|
||||
notification_message(app->notification, &sequence_reset_vibro);
|
||||
}
|
||||
|
||||
void flipbip_play_bad_bump(void* context) {
|
||||
FlipBip* app = context;
|
||||
if(app->haptic != 1) {
|
||||
return;
|
||||
}
|
||||
notification_message(app->notification, &sequence_set_vibro_on);
|
||||
furi_thread_flags_wait(0, FuriFlagWaitAny, 100);
|
||||
notification_message(app->notification, &sequence_reset_vibro);
|
||||
}
|
||||
|
||||
void flipbip_play_long_bump(void* context) {
|
||||
FlipBip* app = context;
|
||||
if(app->haptic != 1) {
|
||||
return;
|
||||
}
|
||||
for(int i = 0; i < 4; i++) {
|
||||
notification_message(app->notification, &sequence_set_vibro_on);
|
||||
furi_thread_flags_wait(0, FuriFlagWaitAny, 50);
|
||||
notification_message(app->notification, &sequence_reset_vibro);
|
||||
furi_thread_flags_wait(0, FuriFlagWaitAny, 100);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
#include <notification/notification_messages.h>
|
||||
|
||||
void flipbip_play_happy_bump(void* context);
|
||||
|
||||
void flipbip_play_bad_bump(void* context);
|
||||
|
||||
void flipbip_play_long_bump(void* context);
|
||||
@@ -1,39 +0,0 @@
|
||||
#include "flipbip_led.h"
|
||||
#include "../flipbip.h"
|
||||
|
||||
void flipbip_led_set_rgb(void* context, int red, int green, int blue) {
|
||||
FlipBip* app = context;
|
||||
if(app->led != 1) {
|
||||
return;
|
||||
}
|
||||
NotificationMessage notification_led_message_1;
|
||||
notification_led_message_1.type = NotificationMessageTypeLedRed;
|
||||
NotificationMessage notification_led_message_2;
|
||||
notification_led_message_2.type = NotificationMessageTypeLedGreen;
|
||||
NotificationMessage notification_led_message_3;
|
||||
notification_led_message_3.type = NotificationMessageTypeLedBlue;
|
||||
|
||||
notification_led_message_1.data.led.value = red;
|
||||
notification_led_message_2.data.led.value = green;
|
||||
notification_led_message_3.data.led.value = blue;
|
||||
const NotificationSequence notification_sequence = {
|
||||
¬ification_led_message_1,
|
||||
¬ification_led_message_2,
|
||||
¬ification_led_message_3,
|
||||
&message_do_not_reset,
|
||||
NULL,
|
||||
};
|
||||
notification_message(app->notification, ¬ification_sequence);
|
||||
furi_thread_flags_wait(
|
||||
0, FuriFlagWaitAny, 10); //Delay, prevent removal from RAM before LED value set
|
||||
}
|
||||
|
||||
void flipbip_led_reset(void* context) {
|
||||
FlipBip* app = context;
|
||||
notification_message(app->notification, &sequence_reset_red);
|
||||
notification_message(app->notification, &sequence_reset_green);
|
||||
notification_message(app->notification, &sequence_reset_blue);
|
||||
|
||||
furi_thread_flags_wait(
|
||||
0, FuriFlagWaitAny, 300); //Delay, prevent removal from RAM before LED value set
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
void flipbip_led_set_rgb(void* context, int red, int green, int blue);
|
||||
void flipbip_led_reset(void* context);
|
||||
@@ -1,27 +0,0 @@
|
||||
// #include "flipbip_speaker.h"
|
||||
// #include "../flipbip.h"
|
||||
|
||||
// #define NOTE_INPUT 587.33f
|
||||
|
||||
// void flipbip_play_input_sound(void* context) {
|
||||
// FlipBip* app = context;
|
||||
// if (app->speaker != 1) {
|
||||
// return;
|
||||
// }
|
||||
// float volume = 1.0f;
|
||||
// if(furi_hal_speaker_is_mine() || furi_hal_speaker_acquire(30)) {
|
||||
// furi_hal_speaker_start(NOTE_INPUT, volume);
|
||||
// }
|
||||
|
||||
// }
|
||||
|
||||
// void flipbip_stop_all_sound(void* context) {
|
||||
// FlipBip* app = context;
|
||||
// if (app->speaker != 1) {
|
||||
// return;
|
||||
// }
|
||||
// if(furi_hal_speaker_is_mine()) {
|
||||
// furi_hal_speaker_stop();
|
||||
// furi_hal_speaker_release();
|
||||
// }
|
||||
// }
|
||||
@@ -1,4 +0,0 @@
|
||||
// #define NOTE_INPUT 587.33f
|
||||
|
||||
// void flipbip_play_input_sound(void* context);
|
||||
// void flipbip_stop_all_sound(void* context);
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 6.1 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 6.1 KiB |
@@ -14,3 +14,4 @@ Oleg Andreev <oleganza@gmail.com>
|
||||
mog <mog@rush.rldn.net>
|
||||
John Dvorak <johndvorak26@gmail.com>
|
||||
Christian Reitter <invd@inhq.net>
|
||||
Struan Clark <xtruan@users.noreply.github.com>
|
||||
@@ -26,7 +26,9 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "address.h"
|
||||
#if USE_NEM
|
||||
#include "aes/aes.h"
|
||||
#endif
|
||||
#include "base58.h"
|
||||
#include "bignum.h"
|
||||
#include "bip32.h"
|
||||
|
||||
@@ -50,6 +50,7 @@ void memzero(void* const pnt, const size_t len) {
|
||||
SecureZeroMemory(pnt, len);
|
||||
#elif defined(HAVE_MEMSET_S)
|
||||
memset_s(pnt, (rsize_t)len, 0, (rsize_t)len);
|
||||
// REMOVED - Flipper Zero does not have this function
|
||||
// #elif defined(HAVE_EXPLICIT_BZERO)
|
||||
// explicit_bzero(pnt, len);
|
||||
#elif defined(HAVE_EXPLICIT_MEMSET)
|
||||
|
||||
@@ -86,9 +86,14 @@
|
||||
#define USE_KECCAK 1
|
||||
#endif
|
||||
|
||||
// add way how to mark confidential data
|
||||
// add a way to mark confidential data
|
||||
#ifndef CONFIDENTIAL
|
||||
#define CONFIDENTIAL
|
||||
#endif
|
||||
|
||||
// use Flipper Zero hardware random number generator
|
||||
#ifndef USE_FLIPPER_HAL_RANDOM
|
||||
#define USE_FLIPPER_HAL_RANDOM 1
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
10
applications/external/flipbip/lib/crypto/rand.c
vendored
10
applications/external/flipbip/lib/crypto/rand.c
vendored
@@ -21,11 +21,9 @@
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#define FLIPPER_HAL_RANDOM
|
||||
|
||||
#include "rand.h"
|
||||
|
||||
#ifdef FLIPPER_HAL_RANDOM
|
||||
#if USE_FLIPPER_HAL_RANDOM
|
||||
|
||||
// NOTE:
|
||||
// random32() and random_buffer() have been replaced in this implementation
|
||||
@@ -67,6 +65,8 @@ void random_buffer(uint8_t* buf, size_t len) {
|
||||
// The following code is platform independent
|
||||
//
|
||||
|
||||
static uint32_t seed = 0;
|
||||
|
||||
uint32_t random32(void) {
|
||||
// Linear congruential generator from Numerical Recipes
|
||||
// https://en.wikipedia.org/wiki/Linear_congruential_generator
|
||||
@@ -74,7 +74,7 @@ uint32_t random32(void) {
|
||||
return seed;
|
||||
}
|
||||
|
||||
void __attribute__((weak)) random_buffer(uint8_t *buf, size_t len) {
|
||||
void random_buffer(uint8_t *buf, size_t len) {
|
||||
uint32_t r = 0;
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
if (i % 4 == 0) {
|
||||
@@ -84,7 +84,7 @@ void __attribute__((weak)) random_buffer(uint8_t *buf, size_t len) {
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* FLIPPER_HAL_RANDOM */
|
||||
#endif /* USE_FLIPPER_HAL_RANDOM */
|
||||
|
||||
uint32_t random_uniform(uint32_t n) {
|
||||
uint32_t x = 0, max = 0xFFFFFFFF - (0xFFFFFFFF % n);
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include "options.h"
|
||||
|
||||
void random_reseed(const uint32_t value);
|
||||
uint32_t random32(void);
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
ADD_SCENE(flipbip, startscreen, Startscreen)
|
||||
ADD_SCENE(flipbip, menu, Menu)
|
||||
ADD_SCENE(flipbip, scene_1, Scene_1)
|
||||
ADD_SCENE(flipbip, settings, Settings)
|
||||
@@ -1,13 +1,17 @@
|
||||
#include "../flipbip.h"
|
||||
#include "../helpers/flipbip_file.h"
|
||||
|
||||
#define FLIPBIP_SUBMENU_TEXT "** FlipBIP wallet " FLIPBIP_VERSION " **"
|
||||
|
||||
enum SubmenuIndex {
|
||||
SubmenuIndexScene1BTC = 10,
|
||||
SubmenuIndexScene1ETH,
|
||||
SubmenuIndexScene1DOGE,
|
||||
SubmenuIndexScene1ZEC,
|
||||
SubmenuIndexScene1New,
|
||||
SubmenuIndexScene1Import,
|
||||
SubmenuIndexSettings,
|
||||
SubmenuIndexNOP,
|
||||
};
|
||||
|
||||
void flipbip_scene_menu_submenu_callback(void* context, uint32_t index) {
|
||||
@@ -18,6 +22,14 @@ void flipbip_scene_menu_submenu_callback(void* context, uint32_t index) {
|
||||
void flipbip_scene_menu_on_enter(void* context) {
|
||||
FlipBip* app = context;
|
||||
|
||||
// FlipBIP header with version
|
||||
submenu_add_item(
|
||||
app->submenu,
|
||||
FLIPBIP_SUBMENU_TEXT,
|
||||
SubmenuIndexNOP,
|
||||
flipbip_scene_menu_submenu_callback,
|
||||
app);
|
||||
|
||||
if(flipbip_has_file(FlipBipFileKey, NULL, false) &&
|
||||
flipbip_has_file(FlipBipFileDat, NULL, false)) {
|
||||
submenu_add_item(
|
||||
@@ -38,6 +50,12 @@ void flipbip_scene_menu_on_enter(void* context) {
|
||||
SubmenuIndexScene1DOGE,
|
||||
flipbip_scene_menu_submenu_callback,
|
||||
app);
|
||||
submenu_add_item(
|
||||
app->submenu,
|
||||
"View ZEC (t-addr) wallet",
|
||||
SubmenuIndexScene1ZEC,
|
||||
flipbip_scene_menu_submenu_callback,
|
||||
app);
|
||||
submenu_add_item(
|
||||
app->submenu,
|
||||
"Regenerate wallet",
|
||||
@@ -54,7 +72,7 @@ void flipbip_scene_menu_on_enter(void* context) {
|
||||
}
|
||||
submenu_add_item(
|
||||
app->submenu,
|
||||
"Import from mnemonic",
|
||||
app->mnemonic_menu_text,
|
||||
SubmenuIndexScene1Import,
|
||||
flipbip_scene_menu_submenu_callback,
|
||||
app);
|
||||
@@ -101,6 +119,14 @@ bool flipbip_scene_menu_on_event(void* context, SceneManagerEvent event) {
|
||||
app->scene_manager, FlipBipSceneMenu, SubmenuIndexScene1DOGE);
|
||||
scene_manager_next_scene(app->scene_manager, FlipBipSceneScene_1);
|
||||
return true;
|
||||
} else if(event.event == SubmenuIndexScene1ZEC) {
|
||||
app->overwrite_saved_seed = 0;
|
||||
app->import_from_mnemonic = 0;
|
||||
app->bip44_coin = FlipBipCoinZEC133;
|
||||
scene_manager_set_scene_state(
|
||||
app->scene_manager, FlipBipSceneMenu, SubmenuIndexScene1ZEC);
|
||||
scene_manager_next_scene(app->scene_manager, FlipBipSceneScene_1);
|
||||
return true;
|
||||
} else if(event.event == SubmenuIndexScene1New) {
|
||||
app->overwrite_saved_seed = 1;
|
||||
app->import_from_mnemonic = 0;
|
||||
@@ -110,15 +136,17 @@ bool flipbip_scene_menu_on_event(void* context, SceneManagerEvent event) {
|
||||
return true;
|
||||
} else if(event.event == SubmenuIndexScene1Import) {
|
||||
app->import_from_mnemonic = 1;
|
||||
app->input_state = FlipBipTextInputMnemonic;
|
||||
text_input_set_header_text(app->text_input, "Enter mnemonic phrase");
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, FlipBipViewIdTextInput);
|
||||
scene_manager_set_scene_state(
|
||||
app->scene_manager, FlipBipSceneMenu, SubmenuIndexScene1Import);
|
||||
scene_manager_next_scene(app->scene_manager, FlipBipSceneScene_1);
|
||||
return true;
|
||||
} else if(event.event == SubmenuIndexSettings) {
|
||||
scene_manager_set_scene_state(
|
||||
app->scene_manager, FlipBipSceneMenu, SubmenuIndexSettings);
|
||||
scene_manager_next_scene(app->scene_manager, FlipBipSceneSettings);
|
||||
return true;
|
||||
} else if(event.event == SubmenuIndexNOP) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -11,8 +11,18 @@ void flipbip_scene_1_callback(FlipBipCustomEvent event, void* context) {
|
||||
void flipbip_scene_scene_1_on_enter(void* context) {
|
||||
furi_assert(context);
|
||||
FlipBip* app = context;
|
||||
flipbip_scene_1_set_callback(app->flipbip_scene_1, flipbip_scene_1_callback, app);
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, FlipBipViewIdScene1);
|
||||
|
||||
if(app->import_from_mnemonic == 1) {
|
||||
// handle mnemonic seed import mode with text input, this only
|
||||
// uses this scene to have a correct stack of scenes
|
||||
app->input_state = FlipBipTextInputMnemonic;
|
||||
text_input_set_header_text(app->text_input, "Enter mnemonic phrase");
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, FlipBipViewIdTextInput);
|
||||
} else {
|
||||
// handle all other modes, these actually use this scene's logic
|
||||
flipbip_scene_1_set_callback(app->flipbip_scene_1, flipbip_scene_1_callback, app);
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, FlipBipViewIdScene1);
|
||||
}
|
||||
}
|
||||
|
||||
bool flipbip_scene_scene_1_on_event(void* context, SceneManagerEvent event) {
|
||||
@@ -21,16 +31,16 @@ bool flipbip_scene_scene_1_on_event(void* context, SceneManagerEvent event) {
|
||||
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
switch(event.event) {
|
||||
case FlipBipCustomEventScene1Left:
|
||||
case FlipBipCustomEventScene1Right:
|
||||
break;
|
||||
case FlipBipCustomEventScene1Up:
|
||||
case FlipBipCustomEventScene1Down:
|
||||
break;
|
||||
// case FlipBipCustomEventScene1Left:
|
||||
// case FlipBipCustomEventScene1Right:
|
||||
// break;
|
||||
// case FlipBipCustomEventScene1Up:
|
||||
// case FlipBipCustomEventScene1Down:
|
||||
// break;
|
||||
case FlipBipCustomEventScene1Back:
|
||||
notification_message(app->notification, &sequence_reset_red);
|
||||
notification_message(app->notification, &sequence_reset_green);
|
||||
notification_message(app->notification, &sequence_reset_blue);
|
||||
//notification_message(app->notification, &sequence_reset_red);
|
||||
//notification_message(app->notification, &sequence_reset_green);
|
||||
//notification_message(app->notification, &sequence_reset_blue);
|
||||
if(!scene_manager_search_and_switch_to_previous_scene(
|
||||
app->scene_manager, FlipBipSceneMenu)) {
|
||||
scene_manager_stop(app->scene_manager);
|
||||
|
||||
@@ -6,24 +6,6 @@
|
||||
#define TEXT_LABEL_ON "ON"
|
||||
#define TEXT_LABEL_OFF "OFF"
|
||||
|
||||
const char* const haptic_text[2] = {
|
||||
TEXT_LABEL_OFF,
|
||||
TEXT_LABEL_ON,
|
||||
};
|
||||
const uint32_t haptic_value[2] = {
|
||||
FlipBipHapticOff,
|
||||
FlipBipHapticOn,
|
||||
};
|
||||
|
||||
const char* const led_text[2] = {
|
||||
TEXT_LABEL_OFF,
|
||||
TEXT_LABEL_ON,
|
||||
};
|
||||
const uint32_t led_value[2] = {
|
||||
FlipBipLedOff,
|
||||
FlipBipLedOn,
|
||||
};
|
||||
|
||||
const char* const bip39_strength_text[3] = {
|
||||
"12",
|
||||
"18",
|
||||
@@ -44,20 +26,6 @@ const uint32_t passphrase_value[2] = {
|
||||
FlipBipPassphraseOn,
|
||||
};
|
||||
|
||||
static void flipbip_scene_settings_set_haptic(VariableItem* item) {
|
||||
FlipBip* app = variable_item_get_context(item);
|
||||
uint8_t index = variable_item_get_current_value_index(item);
|
||||
variable_item_set_current_value_text(item, haptic_text[index]);
|
||||
app->haptic = haptic_value[index];
|
||||
}
|
||||
|
||||
static void flipbip_scene_settings_set_led(VariableItem* item) {
|
||||
FlipBip* app = variable_item_get_context(item);
|
||||
uint8_t index = variable_item_get_current_value_index(item);
|
||||
variable_item_set_current_value_text(item, led_text[index]);
|
||||
app->led = led_value[index];
|
||||
}
|
||||
|
||||
static void flipbip_scene_settings_set_bip39_strength(VariableItem* item) {
|
||||
FlipBip* app = variable_item_get_context(item);
|
||||
uint8_t index = variable_item_get_current_value_index(item);
|
||||
@@ -108,20 +76,6 @@ void flipbip_scene_settings_on_enter(void* context) {
|
||||
variable_item_set_current_value_index(item, value_index);
|
||||
variable_item_set_current_value_text(item, passphrase_text[value_index]);
|
||||
|
||||
// Vibro on/off
|
||||
item = variable_item_list_add(
|
||||
app->variable_item_list, "Vibro/Haptic:", 2, flipbip_scene_settings_set_haptic, app);
|
||||
value_index = value_index_uint32(app->haptic, haptic_value, 2);
|
||||
variable_item_set_current_value_index(item, value_index);
|
||||
variable_item_set_current_value_text(item, haptic_text[value_index]);
|
||||
|
||||
// LED Effects on/off
|
||||
item = variable_item_list_add(
|
||||
app->variable_item_list, "LED FX:", 2, flipbip_scene_settings_set_led, app);
|
||||
value_index = value_index_uint32(app->led, led_value, 2);
|
||||
variable_item_set_current_value_index(item, value_index);
|
||||
variable_item_set_current_value_text(item, led_text[value_index]);
|
||||
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, FlipBipViewIdSettings);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
#include "../flipbip.h"
|
||||
#include "../helpers/flipbip_custom_event.h"
|
||||
#include "../views/flipbip_startscreen.h"
|
||||
|
||||
void flipbip_scene_startscreen_callback(FlipBipCustomEvent event, void* context) {
|
||||
furi_assert(context);
|
||||
FlipBip* app = context;
|
||||
view_dispatcher_send_custom_event(app->view_dispatcher, event);
|
||||
}
|
||||
|
||||
void flipbip_scene_startscreen_on_enter(void* context) {
|
||||
furi_assert(context);
|
||||
FlipBip* app = context;
|
||||
flipbip_startscreen_set_callback(
|
||||
app->flipbip_startscreen, flipbip_scene_startscreen_callback, app);
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, FlipBipViewIdStartscreen);
|
||||
}
|
||||
|
||||
bool flipbip_scene_startscreen_on_event(void* context, SceneManagerEvent event) {
|
||||
FlipBip* app = context;
|
||||
bool consumed = false;
|
||||
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
switch(event.event) {
|
||||
case FlipBipCustomEventStartscreenLeft:
|
||||
case FlipBipCustomEventStartscreenRight:
|
||||
break;
|
||||
case FlipBipCustomEventStartscreenUp:
|
||||
case FlipBipCustomEventStartscreenDown:
|
||||
break;
|
||||
case FlipBipCustomEventStartscreenOk:
|
||||
scene_manager_next_scene(app->scene_manager, FlipBipSceneMenu);
|
||||
consumed = true;
|
||||
break;
|
||||
case FlipBipCustomEventStartscreenBack:
|
||||
notification_message(app->notification, &sequence_reset_red);
|
||||
notification_message(app->notification, &sequence_reset_green);
|
||||
notification_message(app->notification, &sequence_reset_blue);
|
||||
if(!scene_manager_search_and_switch_to_previous_scene(
|
||||
app->scene_manager, FlipBipSceneStartscreen)) {
|
||||
scene_manager_stop(app->scene_manager);
|
||||
view_dispatcher_stop(app->view_dispatcher);
|
||||
}
|
||||
consumed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void flipbip_scene_startscreen_on_exit(void* context) {
|
||||
FlipBip* app = context;
|
||||
UNUSED(app);
|
||||
}
|
||||
@@ -5,10 +5,7 @@
|
||||
#include <gui/elements.h>
|
||||
#include <storage/storage.h>
|
||||
#include <string.h>
|
||||
#include "flipbip_icons.h"
|
||||
#include <assets_icons.h>
|
||||
#include "../helpers/flipbip_haptic.h"
|
||||
#include "../helpers/flipbip_led.h"
|
||||
//#include "flipbip_icons.h"
|
||||
#include "../helpers/flipbip_string.h"
|
||||
#include "../helpers/flipbip_file.h"
|
||||
// From: /lib/crypto
|
||||
@@ -43,7 +40,7 @@
|
||||
#define TEXT_NEW_WALLET "New wallet"
|
||||
#define TEXT_DEFAULT_COIN "Coin"
|
||||
#define TEXT_RECEIVE_ADDRESS "receive address:"
|
||||
#define TEXT_DEFAULT_DERIV "m/44'/X'/0'/0"
|
||||
// #define TEXT_DEFAULT_DERIV "m/44'/X'/0'/0"
|
||||
const char* TEXT_INFO = "-Scroll pages with up/down-"
|
||||
"p1,2) BIP39 Mnemonic/Seed"
|
||||
"p3) BIP32 Root Key "
|
||||
@@ -55,16 +52,19 @@ const char* TEXT_INFO = "-Scroll pages with up/down-"
|
||||
#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[3][6] = {
|
||||
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_DOGE, 0x02fac398, 0x02facafd, 0x1e, 0x9e, FlipBipCoinBTC0},
|
||||
{COIN_ZEC, 0x0488ade4, 0x0488b21e, 0x1cb8, 0x80, FlipBipCoinZEC133},
|
||||
};
|
||||
|
||||
// coin_name, derivation_path
|
||||
const char* COIN_TEXT_ARRAY[3][3] = {
|
||||
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:"}};
|
||||
{"DOGE", "m/44'/3'/0'/0", "dogecoin:"},
|
||||
{"ZEC", "m/44'/133'/0'/0", "zcash:"}};
|
||||
|
||||
struct FlipBipScene1 {
|
||||
View* view;
|
||||
@@ -98,7 +98,7 @@ static CONFIDENTIAL char* s_disp_text4 = NULL;
|
||||
static CONFIDENTIAL char* s_disp_text5 = NULL;
|
||||
static CONFIDENTIAL char* s_disp_text6 = NULL;
|
||||
// Derivation path text
|
||||
static const char* s_derivation_text = TEXT_DEFAULT_DERIV;
|
||||
static const char* s_derivation_text = TEXT_DEFAULT_COIN; // TEXT_DEFAULT_DERIV;
|
||||
// Warning text
|
||||
static bool s_warn_insecure = false;
|
||||
#define WARN_INSECURE_TEXT_1 "Recommendation:"
|
||||
@@ -147,7 +147,6 @@ static void flipbip_scene_1_init_address(
|
||||
ecdsa_get_address(
|
||||
s_addr_node->public_key, coin_info[3], HASHER_SHA2_RIPEMD, HASHER_SHA2D, buf, buflen);
|
||||
strcpy(addr_text, buf);
|
||||
|
||||
//ecdsa_get_wif(addr_node->private_key, WIF_VERSION, HASHER_SHA2D, buf, buflen);
|
||||
|
||||
} else if(coin_info[5] == FlipBipCoinETH60) { // ETH
|
||||
@@ -157,6 +156,12 @@ static void flipbip_scene_1_init_address(
|
||||
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
|
||||
@@ -311,7 +316,7 @@ void flipbip_scene_1_draw(Canvas* canvas, FlipBipScene1Model* model) {
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
canvas_draw_str(canvas, 2, 10, TEXT_LOADING);
|
||||
canvas_draw_str(canvas, 7, 30, s_derivation_text);
|
||||
canvas_draw_icon(canvas, 86, 22, &I_Keychain_39x36);
|
||||
// canvas_draw_icon(canvas, 86, 22, &I_Keychain_39x36);
|
||||
if(s_warn_insecure) {
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
canvas_draw_str(canvas, 2, 50, WARN_INSECURE_TEXT_1);
|
||||
@@ -654,9 +659,12 @@ void flipbip_scene_1_enter(void* context) {
|
||||
s_derivation_text = TEXT_NEW_WALLET;
|
||||
}
|
||||
|
||||
flipbip_play_happy_bump(app);
|
||||
// Wait a beat to allow the display time to update to the loading screen
|
||||
furi_thread_flags_wait(0, FuriFlagWaitAny, 20);
|
||||
|
||||
//flipbip_play_happy_bump(app);
|
||||
//notification_message(app->notification, &sequence_blink_cyan_100);
|
||||
flipbip_led_set_rgb(app, 255, 0, 0);
|
||||
//flipbip_led_set_rgb(app, 255, 0, 0);
|
||||
|
||||
with_view_model(
|
||||
instance->view,
|
||||
@@ -669,7 +677,8 @@ void flipbip_scene_1_enter(void* context) {
|
||||
|
||||
// nonzero status, free the mnemonic
|
||||
if(status != FlipBipStatusSuccess) {
|
||||
memzero((void*)model->mnemonic, strlen(model->mnemonic));
|
||||
// calling strlen on mnemonic here can cause a crash, don't.
|
||||
// it wasn't loaded properly anyways, no need to zero the memory
|
||||
free((void*)model->mnemonic);
|
||||
}
|
||||
|
||||
@@ -677,15 +686,15 @@ void flipbip_scene_1_enter(void* context) {
|
||||
if(status == FlipBipStatusSaveError) {
|
||||
model->mnemonic = "ERROR:,Save error";
|
||||
model->page = PAGE_MNEMONIC;
|
||||
flipbip_play_long_bump(app);
|
||||
//flipbip_play_long_bump(app);
|
||||
} else if(status == FlipBipStatusLoadError) {
|
||||
model->mnemonic = "ERROR:,Load error";
|
||||
model->page = PAGE_MNEMONIC;
|
||||
flipbip_play_long_bump(app);
|
||||
//flipbip_play_long_bump(app);
|
||||
} else if(status == FlipBipStatusMnemonicCheckError) {
|
||||
model->mnemonic = "ERROR:,Mnemonic check error";
|
||||
model->page = PAGE_MNEMONIC;
|
||||
flipbip_play_long_bump(app);
|
||||
//flipbip_play_long_bump(app);
|
||||
}
|
||||
|
||||
// s_busy = false;
|
||||
|
||||
@@ -1,131 +0,0 @@
|
||||
#include "../flipbip.h"
|
||||
#include <furi.h>
|
||||
#include <furi_hal.h>
|
||||
#include <input/input.h>
|
||||
#include <gui/elements.h>
|
||||
#include "flipbip_icons.h"
|
||||
#include <assets_icons.h>
|
||||
|
||||
struct FlipBipStartscreen {
|
||||
View* view;
|
||||
FlipBipStartscreenCallback callback;
|
||||
void* context;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
int some_value;
|
||||
} FlipBipStartscreenModel;
|
||||
|
||||
void flipbip_startscreen_set_callback(
|
||||
FlipBipStartscreen* instance,
|
||||
FlipBipStartscreenCallback callback,
|
||||
void* context) {
|
||||
furi_assert(instance);
|
||||
furi_assert(callback);
|
||||
instance->callback = callback;
|
||||
instance->context = context;
|
||||
}
|
||||
|
||||
void flipbip_startscreen_draw(Canvas* canvas, FlipBipStartscreenModel* model) {
|
||||
UNUSED(model);
|
||||
canvas_clear(canvas);
|
||||
canvas_set_color(canvas, ColorBlack);
|
||||
|
||||
canvas_draw_icon(canvas, 1, 33, &I_Auth_62x31);
|
||||
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
canvas_draw_str(canvas, 18, 11, "FlipBIP - BIP32/39/44");
|
||||
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
canvas_draw_str(canvas, 23, 22, "Crypto toolkit for Flipper");
|
||||
canvas_draw_str(canvas, 99, 34, FLIPBIP_VERSION);
|
||||
|
||||
elements_button_right(canvas, "Start");
|
||||
}
|
||||
|
||||
static void flipbip_startscreen_model_init(FlipBipStartscreenModel* const model) {
|
||||
model->some_value = 1;
|
||||
}
|
||||
|
||||
bool flipbip_startscreen_input(InputEvent* event, void* context) {
|
||||
furi_assert(context);
|
||||
FlipBipStartscreen* instance = context;
|
||||
if(event->type == InputTypeRelease) {
|
||||
switch(event->key) {
|
||||
case InputKeyBack:
|
||||
with_view_model(
|
||||
instance->view,
|
||||
FlipBipStartscreenModel * model,
|
||||
{
|
||||
UNUSED(model);
|
||||
instance->callback(FlipBipCustomEventStartscreenBack, instance->context);
|
||||
},
|
||||
true);
|
||||
break;
|
||||
case InputKeyLeft:
|
||||
case InputKeyRight:
|
||||
case InputKeyUp:
|
||||
case InputKeyDown:
|
||||
case InputKeyOk:
|
||||
with_view_model(
|
||||
instance->view,
|
||||
FlipBipStartscreenModel * model,
|
||||
{
|
||||
UNUSED(model);
|
||||
instance->callback(FlipBipCustomEventStartscreenOk, instance->context);
|
||||
},
|
||||
true);
|
||||
break;
|
||||
case InputKeyMAX:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void flipbip_startscreen_exit(void* context) {
|
||||
furi_assert(context);
|
||||
}
|
||||
|
||||
void flipbip_startscreen_enter(void* context) {
|
||||
furi_assert(context);
|
||||
FlipBipStartscreen* instance = (FlipBipStartscreen*)context;
|
||||
with_view_model(
|
||||
instance->view,
|
||||
FlipBipStartscreenModel * model,
|
||||
{ flipbip_startscreen_model_init(model); },
|
||||
true);
|
||||
}
|
||||
|
||||
FlipBipStartscreen* flipbip_startscreen_alloc() {
|
||||
FlipBipStartscreen* instance = malloc(sizeof(FlipBipStartscreen));
|
||||
instance->view = view_alloc();
|
||||
view_allocate_model(instance->view, ViewModelTypeLocking, sizeof(FlipBipStartscreenModel));
|
||||
view_set_context(instance->view, instance); // furi_assert crashes in events without this
|
||||
view_set_draw_callback(instance->view, (ViewDrawCallback)flipbip_startscreen_draw);
|
||||
view_set_input_callback(instance->view, flipbip_startscreen_input);
|
||||
//view_set_enter_callback(instance->view, flipbip_startscreen_enter);
|
||||
//view_set_exit_callback(instance->view, flipbip_startscreen_exit);
|
||||
|
||||
with_view_model(
|
||||
instance->view,
|
||||
FlipBipStartscreenModel * model,
|
||||
{ flipbip_startscreen_model_init(model); },
|
||||
true);
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
void flipbip_startscreen_free(FlipBipStartscreen* instance) {
|
||||
furi_assert(instance);
|
||||
|
||||
with_view_model(
|
||||
instance->view, FlipBipStartscreenModel * model, { UNUSED(model); }, true);
|
||||
view_free(instance->view);
|
||||
free(instance);
|
||||
}
|
||||
|
||||
View* flipbip_startscreen_get_view(FlipBipStartscreen* instance) {
|
||||
furi_assert(instance);
|
||||
return instance->view;
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <gui/view.h>
|
||||
#include "../helpers/flipbip_custom_event.h"
|
||||
|
||||
typedef struct FlipBipStartscreen FlipBipStartscreen;
|
||||
|
||||
typedef void (*FlipBipStartscreenCallback)(FlipBipCustomEvent event, void* context);
|
||||
|
||||
void flipbip_startscreen_set_callback(
|
||||
FlipBipStartscreen* flipbip_startscreen,
|
||||
FlipBipStartscreenCallback callback,
|
||||
void* context);
|
||||
|
||||
View* flipbip_startscreen_get_view(FlipBipStartscreen* flipbip_static);
|
||||
|
||||
FlipBipStartscreen* flipbip_startscreen_alloc();
|
||||
|
||||
void flipbip_startscreen_free(FlipBipStartscreen* flipbip_static);
|
||||
Reference in New Issue
Block a user