Skip to content

Commit fdb62b1

Browse files
committed
more updates
0 parents  commit fdb62b1

File tree

179 files changed

+35588
-0
lines changed

Some content is hidden

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

179 files changed

+35588
-0
lines changed

.gitignore

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# Prerequisites
2+
*.d
3+
4+
# Object files
5+
*.o
6+
*.ko
7+
*.obj
8+
*.elf
9+
10+
# Linker output
11+
*.ilk
12+
*.map
13+
*.exp
14+
15+
# Precompiled Headers
16+
*.gch
17+
*.pch
18+
19+
# Libraries
20+
*.lib
21+
*.a
22+
*.la
23+
*.lo
24+
25+
# Shared objects (inc. Windows DLLs)
26+
*.dll
27+
*.so
28+
*.so.*
29+
*.dylib
30+
31+
# Executables
32+
*.exe
33+
*.out
34+
*.app
35+
*.i*86
36+
*.x86_64
37+
*.hex
38+
39+
# Debug files
40+
*.dSYM/
41+
*.su
42+
*.idb
43+
*.pdb
44+
45+
# Kernel Module Compile Results
46+
*.mod*
47+
*.cmd
48+
.tmp_versions/
49+
modules.order
50+
Module.symvers
51+
Mkfile.old
52+
dkms.conf

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2023 Struan Clark
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# FlipBIP - BIP32/39/44
2+
3+
https://github.com/xtruan/FlipBIP
4+
5+
## Crypto toolkit for Flipper Zero
6+
- Using Trezor crypto libs from `core/v2.5.3` release
7+
8+
## Background
9+
10+
The goal of this project is to see how much crypto functionality can be brought to the Flipper Zero.
11+
12+
### Complete
13+
14+
- Trezor crypto C code ported into `crypto` subfolder
15+
- Adapted to use Flipper hardware RNG (see `crypto/rand.c`)
16+
- Imports and some C library functions modified for compatibility with FBT
17+
- Navigation and UI adapted from FAP Boilerplate app
18+
- BIP39 mnemonic generation
19+
- 24, 18, or 12 words configured in settings
20+
- BIP39 mnemonic to BIP39 seed generation
21+
- Hierarchical Deterministic (HD) wallet generation from seed
22+
- Generation of offline `m/44'/0'/0'/0` BTC wallet
23+
- Generation of offline `m/44'/60'/0'/0` ETH wallet (coded from the $SPORK Castle of ETHDenver 2023!)
24+
- Generation of offline `m/44'/3'/0'/0` DOGE wallet
25+
- Similar features to: https://iancoleman.io/bip39/
26+
- Saving wallets to SD card
27+
- Wallets are saved to SD card upon creation in `apps_data/flipbip`
28+
- NOTE: `apps_data` folder must already exist on SD card!
29+
- Saved wallets can be viewed between app runs
30+
- Wallets are encrypted with a randomly generated key, and that key is also encrypted
31+
- `.flipbip.dat` and `.flipbip.key` files are both required to be in `apps_data/flipbip`
32+
- Backups of both these files `.flipbip.dat.bak` and `.flipbip.key.bak` are also maintained
33+
- If you want to externally back up your wallet, I recommend copying all these files, and storing the `key` and `dat` files seperately
34+
- NOTE: The wallets should be decently tough to crack off of a Flipper, however any Flipper with the app installed can load a wallet in the `apps_data/flipbip` directory if both the `key` and `dat` file are present
35+
- BIP39 passphrase support
36+
- Configured in settings, not persisted between runs for security
37+
- Import your own mnemonic
38+
- Lots of typing required but you can now use the wallet with an existing mnemonic you have saved
39+
- Useful to convert paper backup to keys and receive addresses without relying on a laptop or phone
40+
- Improved receive address generation features
41+
- Addresses are now generated at the same time as other pieces of wallet info
42+
- This slows down initial wallet load, but makes UI much more responsive
43+
- QR code files are now generated for each address and stored in the `apps_data/flipbip` directory
44+
- This app is required to view the QR code files: https://github.com/bmatcuk/flipperzero-qrcode
45+
- NOTE: This happens during the `View Wallet` step; you must view a wallet after generating/importing a wallet in order to ensure the address QR files are correct
46+
- Broke out crypto functionality into its own library using `fap_private_libs` feature
47+
48+
### Work in Progress
49+
50+
- More coin types
51+
- Support for more custom BIP32 wallet paths
52+
53+
### (FAR) Future
54+
55+
- Custom wallet security
56+
- User specified password
57+
- USB/Bluetooth wallet functionality

application.fam

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
App(
2+
appid="flipbip",
3+
name="FlipBIP Crypto Wallet",
4+
apptype=FlipperAppType.EXTERNAL,
5+
entry_point="flipbip_app",
6+
requires=[
7+
"gui",
8+
],
9+
stack_size=3 * 1024,
10+
order=10,
11+
fap_icon="flipbip_10px.png",
12+
fap_icon_assets="icons",
13+
fap_icon_assets_symbol="flipbip",
14+
fap_private_libs=[
15+
Lib(
16+
name="crypto",
17+
),
18+
],
19+
fap_category="Tools",
20+
fap_author="Struan Clark (xtruan)",
21+
fap_weburl="https://github.com/xtruan/FlipBIP",
22+
fap_version=(1, 11),
23+
fap_description="Crypto wallet tools for Flipper",
24+
)

flipbip.c

Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
#pragma GCC optimize("-Os")
2+
3+
#include "flipbip.h"
4+
#include "helpers/flipbip_file.h"
5+
#include "helpers/flipbip_haptic.h"
6+
// From: lib/crypto
7+
#include <memzero.h>
8+
#include <bip39.h>
9+
10+
bool flipbip_custom_event_callback(void* context, uint32_t event) {
11+
furi_assert(context);
12+
FlipBip* app = context;
13+
return scene_manager_handle_custom_event(app->scene_manager, event);
14+
}
15+
16+
void flipbip_tick_event_callback(void* context) {
17+
furi_assert(context);
18+
FlipBip* app = context;
19+
scene_manager_handle_tick_event(app->scene_manager);
20+
}
21+
22+
//leave app if back button pressed
23+
bool flipbip_navigation_event_callback(void* context) {
24+
furi_assert(context);
25+
FlipBip* app = context;
26+
return scene_manager_handle_back_event(app->scene_manager);
27+
}
28+
29+
static void text_input_callback(void* context) {
30+
furi_assert(context);
31+
FlipBip* app = context;
32+
bool handled = false;
33+
34+
// check that there is text in the input
35+
if(strlen(app->input_text) > 0) {
36+
if(app->input_state == FlipBipTextInputPassphrase) {
37+
if(app->passphrase == FlipBipPassphraseOn) {
38+
strcpy(app->passphrase_text, app->input_text);
39+
}
40+
// clear input text
41+
memzero(app->input_text, TEXT_BUFFER_SIZE);
42+
// reset input state
43+
app->input_state = FlipBipTextInputDefault;
44+
handled = true;
45+
view_dispatcher_switch_to_view(app->view_dispatcher, FlipBipViewIdSettings);
46+
} else if(app->input_state == FlipBipTextInputMnemonic) {
47+
if(app->import_from_mnemonic == 1) {
48+
strcpy(app->import_mnemonic_text, app->input_text);
49+
50+
int status = FlipBipStatusSuccess;
51+
// Check if the mnemonic is valid
52+
if(mnemonic_check(app->import_mnemonic_text) == 0)
53+
status = FlipBipStatusMnemonicCheckError; // 13 = mnemonic check error
54+
// Save the mnemonic to persistent storage
55+
else if(!flipbip_save_file_secure(app->import_mnemonic_text))
56+
status = FlipBipStatusSaveError; // 12 = save error
57+
58+
if(status == FlipBipStatusSuccess) {
59+
//notification_message(app->notification, &sequence_blink_cyan_100);
60+
flipbip_play_happy_bump(app);
61+
} else {
62+
//notification_message(app->notification, &sequence_blink_red_100);
63+
flipbip_play_long_bump(app);
64+
}
65+
66+
memzero(app->import_mnemonic_text, TEXT_BUFFER_SIZE);
67+
}
68+
// clear input text
69+
memzero(app->input_text, TEXT_BUFFER_SIZE);
70+
// reset input state
71+
app->input_state = FlipBipTextInputDefault;
72+
handled = true;
73+
view_dispatcher_switch_to_view(app->view_dispatcher, FlipBipViewIdMenu);
74+
}
75+
}
76+
77+
if(!handled) {
78+
// clear input text
79+
memzero(app->input_text, TEXT_BUFFER_SIZE);
80+
// reset input state
81+
app->input_state = FlipBipTextInputDefault;
82+
view_dispatcher_switch_to_view(app->view_dispatcher, FlipBipViewIdMenu);
83+
}
84+
}
85+
86+
FlipBip* flipbip_app_alloc() {
87+
FlipBip* app = malloc(sizeof(FlipBip));
88+
app->gui = furi_record_open(RECORD_GUI);
89+
app->notification = furi_record_open(RECORD_NOTIFICATION);
90+
91+
//Turn backlight on, believe me this makes testing your app easier
92+
notification_message(app->notification, &sequence_display_backlight_on);
93+
94+
//Scene additions
95+
app->view_dispatcher = view_dispatcher_alloc();
96+
view_dispatcher_enable_queue(app->view_dispatcher);
97+
98+
app->scene_manager = scene_manager_alloc(&flipbip_scene_handlers, app);
99+
view_dispatcher_set_event_callback_context(app->view_dispatcher, app);
100+
view_dispatcher_set_navigation_event_callback(
101+
app->view_dispatcher, flipbip_navigation_event_callback);
102+
view_dispatcher_set_tick_event_callback(
103+
app->view_dispatcher, flipbip_tick_event_callback, 100);
104+
view_dispatcher_set_custom_event_callback(app->view_dispatcher, flipbip_custom_event_callback);
105+
app->submenu = submenu_alloc();
106+
107+
// Settings
108+
app->haptic = FlipBipHapticOn;
109+
app->led = FlipBipLedOn;
110+
app->bip39_strength = FlipBipStrength256; // 256 bits (24 words)
111+
app->passphrase = FlipBipPassphraseOff;
112+
113+
// Main menu
114+
app->bip44_coin = FlipBipCoinBTC0; // 0 (BTC)
115+
app->overwrite_saved_seed = 0;
116+
app->import_from_mnemonic = 0;
117+
118+
// Text input
119+
app->input_state = FlipBipTextInputDefault;
120+
121+
view_dispatcher_add_view(
122+
app->view_dispatcher, FlipBipViewIdMenu, submenu_get_view(app->submenu));
123+
app->flipbip_startscreen = flipbip_startscreen_alloc();
124+
view_dispatcher_add_view(
125+
app->view_dispatcher,
126+
FlipBipViewIdStartscreen,
127+
flipbip_startscreen_get_view(app->flipbip_startscreen));
128+
app->flipbip_scene_1 = flipbip_scene_1_alloc();
129+
view_dispatcher_add_view(
130+
app->view_dispatcher, FlipBipViewIdScene1, flipbip_scene_1_get_view(app->flipbip_scene_1));
131+
app->variable_item_list = variable_item_list_alloc();
132+
view_dispatcher_add_view(
133+
app->view_dispatcher,
134+
FlipBipViewIdSettings,
135+
variable_item_list_get_view(app->variable_item_list));
136+
137+
app->text_input = text_input_alloc();
138+
text_input_set_result_callback(
139+
app->text_input,
140+
text_input_callback,
141+
(void*)app,
142+
app->input_text,
143+
TEXT_BUFFER_SIZE,
144+
//clear default text
145+
true);
146+
text_input_set_header_text(app->text_input, "Input");
147+
view_dispatcher_add_view(
148+
app->view_dispatcher, FlipBipViewIdTextInput, text_input_get_view(app->text_input));
149+
150+
//End Scene Additions
151+
152+
return app;
153+
}
154+
155+
void flipbip_app_free(FlipBip* app) {
156+
furi_assert(app);
157+
158+
// Scene manager
159+
scene_manager_free(app->scene_manager);
160+
161+
text_input_free(app->text_input);
162+
163+
// View Dispatcher
164+
view_dispatcher_remove_view(app->view_dispatcher, FlipBipViewIdMenu);
165+
view_dispatcher_remove_view(app->view_dispatcher, FlipBipViewIdScene1);
166+
view_dispatcher_remove_view(app->view_dispatcher, FlipBipViewIdSettings);
167+
view_dispatcher_remove_view(app->view_dispatcher, FlipBipViewIdTextInput);
168+
submenu_free(app->submenu);
169+
170+
view_dispatcher_free(app->view_dispatcher);
171+
furi_record_close(RECORD_GUI);
172+
173+
app->gui = NULL;
174+
app->notification = NULL;
175+
176+
//Remove whatever is left
177+
memzero(app, sizeof(FlipBip));
178+
free(app);
179+
}
180+
181+
int32_t flipbip_app(void* p) {
182+
UNUSED(p);
183+
FlipBip* app = flipbip_app_alloc();
184+
185+
// Disabled because causes exit on custom firmwares such as RM
186+
/*if(!furi_hal_region_is_provisioned()) {
187+
flipbip_app_free(app);
188+
return 1;
189+
}*/
190+
191+
view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen);
192+
193+
scene_manager_next_scene(
194+
app->scene_manager, FlipBipSceneStartscreen); //Start with start screen
195+
//scene_manager_next_scene(app->scene_manager, FlipBipSceneMenu); //if you want to directly start with Menu
196+
197+
furi_hal_power_suppress_charge_enter();
198+
199+
view_dispatcher_run(app->view_dispatcher);
200+
201+
furi_hal_power_suppress_charge_exit();
202+
flipbip_app_free(app);
203+
204+
return 0;
205+
}

0 commit comments

Comments
 (0)