Coconut Vault

네트워크를 끊는 순간,
당신의 폰이 비트코인 금고가 됩니다

복잡하고 비싼 하드웨어 월렛 없이도,
오프라인으로 안전하게 셀프 커스터디 하세요

코코넛 월렛 보기

최고의 내구성과 사용성을 지닌
하드월렛이 내 눈 앞에

Hardware-level Protection
하드웨어 수준의 강력한 보안 기술을 제공합니다
Secure Startup
볼트를 사용하려면 앱을 다시 시작해야 합니다
Secret Eraser
흔적을 남기지 않고 시크릿 정보를 안전하게 삭제합니다
Fail Safe Reset
앱 진입 실패 시 대기 시간이 늘어나고 모든 시도 후 초기화됩니다
Sign-only Mode
원한다면, 시크릿을 필요할 때만 입력하여 서명기로 사용할 수 있습니다
Privacy Mode
비트코인 호들러임을 감출 수 있습니다
Defense in Depth
여러 보안 계층을 겹쳐 서명과 보관 과정 전반을 한층 더 안전하게 보호합니다

스마트폰 하드월렛, 안전할까?

완전한 오프라인은 모든 디지털 위협의 진입점을 봉쇄합니다. 적절히 관리된다면, 전용 하드웨어 월렛 못지 않은 높은 수준의 물리적 격리와 보안을 실현할 수 있습니다.

볼트를 보다 안전하게 사용하는 방법

코코넛 볼트는 완벽히 오프라인에서 작동하도록 설계되었지만, 사용자의 습관과 설정 또한 보안의 중요한 일부입니다. 아래의 몇 가지 원칙을 따르면, 당신의 볼트는 하드월렛 이상의 보안을 실현할 수 있습니다.

RULE 01
기기를 볼트 전용으로 사용하세요

볼트는 오프라인 환경에서 동작하는 서명 전용 기기로 설계되었습니다. 다른 앱을 설치하거나, Wi-Fi·블루투스 연결을 시도하는 순간 공격 벡터가 열릴 수 있습니다. 기기를 절대 온라인 전환하지 말고, 오직 오프라인 상태에서 트랜잭션 서명 용도로만 사용하세요. 이 원칙만 지켜도 대부분의 원격 공격을 원천 차단할 수 있습니다.

RULE 02
사용 전 '공장 초기화' 하세요

새로운 기기를 볼트로 사용하기 전에는 반드시 공장 초기화를 진행하세요. 기기 내 남아 있을 수 있는 기존 앱, 로그, 캐시 데이터가 완전히 삭제되어야 합니다. 이 과정을 통해 예상치 못한 백도어나 악성 코드 흔적을 제거하고, 볼트의 신뢰 기반을 확립할 수 있습니다.

RULE 03
PIN 대신 '문자열 비밀번호'를 사용하세요

숫자 4~6자리 PIN은 보안용 서명 기기에는 취약할 수 있습니다. 문자, 숫자, 기호가 혼합된 문자열 비밀번호를 설정하면 물리적 탈취 상황에서도 추측 공격(Brute-force)에 훨씬 강한 방어력을 갖게 됩니다. 가능하다면 최소 8자 이상의 강력한 패스워드를 사용하세요.

RULE 04
사용 후에는 반드시 전원을 끄세요

볼트는 사용하지 않을 때 완전히 전원을 차단하는 것이 가장 안전합니다. 전원이 꺼진 상태에서는 메모리나 저장소에 접근할 수 없으며, 펌웨어 수준의 공격조차 무의미합니다. 이 습관 하나만으로도 물리적 해킹과 펌웨어 공격을 모두 무력화할 수 있습니다.

코코넛 볼트 사용자들의 이야기

비트코인 수량이 얼마이건, 셀프커스터디 꼭 해야합니다. 두려워마시고 코코넛볼트로 시작해보세요. 코코넛 팀에서 끝까지 아주 쉽게 이끌어줍니다. 자신이 통제할 수 있는 유일한 자산, 비트코인. 그 완성은 셀프보관입니다. 모르면 코코넛팀이 다 해결해줍니다. 70대도 껌입니다.

X(트위터)에서 보기 →

코코넛볼트로 트랜잭션을 일으켜봄 일단 매우 직관적이고 사용자 친화적임(인터넷 연결, 블루투스 차단후 사용은 매우 안심됨) 트랜잭션도 초보자(와이프, 자녀)도 조금만 침착하게 연구한다면 쉽게 일으킬 수 있을듯

X(트위터)에서 보기 →

코코넛 볼트 구매 완료 공기계 아이폰으로 사용 예정인데 폰으로 하니 속도도 속도고 너무 간편하고 좋네요 좋은 어플 감사합니다 🤩

X(트위터)에서 보기 →
import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:coconut_wallet/repository/shared_prefs_repository.dart'; import 'package:coconut_wallet/utils/logger.dart'; import 'package:provider/provider.dart'; import 'app.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); final RootIsolateToken token = RootIsolateToken.instance!; BackgroundIsolateBinaryMessenger.ensureInitialized(token); if (Platform.isAndroid) { try { const MethodChannel ch = MethodChannel('android'); final int v = await ch.invokeMethod('getSdkVersion'); if (v != 26) { SystemChrome.setPreferredOrientations([ DeviceOrientation.portraitUp, DeviceOrientation.portraitDown, ]); } } on PlatformException catch (e) { Logger.log('Failed to get platform version'); } } } class CoconutApp extends StatelessWidget { const CoconutApp({super.key}); @override Widget build(BuildContext context) { return MultiProvider( providers: [ ChangeNotifierProvider(create: (_) => WalletProvider()), ChangeNotifierProvider(create: (_) => NodeProvider()), ], child: MaterialApp( title: 'Coconut Wallet', theme: CoconutTheme.light(), darkTheme: CoconutTheme.dark(), home: const HomePage(), ), ); } } import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:coconut_wallet/repository/shared_prefs_repository.dart'; import 'package:coconut_wallet/utils/logger.dart'; import 'package:provider/provider.dart'; import 'app.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); final RootIsolateToken token = RootIsolateToken.instance!; BackgroundIsolateBinaryMessenger.ensureInitialized(token); if (Platform.isAndroid) { try { const MethodChannel ch = MethodChannel('android'); final int v = await ch.invokeMethod('getSdkVersion'); if (v != 26) { SystemChrome.setPreferredOrientations([ DeviceOrientation.portraitUp, DeviceOrientation.portraitDown, ]); } } on PlatformException catch (e) { Logger.log('Failed to get platform version'); } } } class CoconutApp extends StatelessWidget { const CoconutApp({super.key}); @override Widget build(BuildContext context) { return MultiProvider( providers: [ ChangeNotifierProvider(create: (_) => WalletProvider()), ChangeNotifierProvider(create: (_) => NodeProvider()), ], child: MaterialApp( title: 'Coconut Wallet', theme: CoconutTheme.light(), darkTheme: CoconutTheme.dark(), home: const HomePage(), ), ); } } import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:coconut_wallet/repository/shared_prefs_repository.dart'; import 'package:coconut_wallet/utils/logger.dart'; import 'package:provider/provider.dart'; import 'app.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); final RootIsolateToken token = RootIsolateToken.instance!; BackgroundIsolateBinaryMessenger.ensureInitialized(token); if (Platform.isAndroid) { try { const MethodChannel ch = MethodChannel('android'); final int v = await ch.invokeMethod('getSdkVersion'); if (v != 26) { SystemChrome.setPreferredOrientations([ DeviceOrientation.portraitUp, DeviceOrientation.portraitDown, ]); } } on PlatformException catch (e) { Logger.log('Failed to get platform version'); } } } class CoconutApp extends StatelessWidget { const CoconutApp({super.key}); @override Widget build(BuildContext context) { return MultiProvider( providers: [ ChangeNotifierProvider(create: (_) => WalletProvider()), ChangeNotifierProvider(create: (_) => NodeProvider()), ], child: MaterialApp( title: 'Coconut Wallet', theme: CoconutTheme.light(), darkTheme: CoconutTheme.dark(), home: const HomePage(), ), ); } } import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:coconut_wallet/repository/shared_prefs_repository.dart'; import 'package:coconut_wallet/utils/logger.dart'; import 'package:provider/provider.dart'; import 'app.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); final RootIsolateToken token = RootIsolateToken.instance!; BackgroundIsolateBinaryMessenger.ensureInitialized(token); if (Platform.isAndroid) { try { const MethodChannel ch = MethodChannel('android'); final int v = await ch.invokeMethod('getSdkVersion'); if (v != 26) { SystemChrome.setPreferredOrientations([ DeviceOrientation.portraitUp, DeviceOrientation.portraitDown, ]); } } on PlatformException catch (e) { Logger.log('Failed to get platform version'); } } } class CoconutApp extends StatelessWidget { const CoconutApp({super.key}); @override Widget build(BuildContext context) { return MultiProvider( providers: [ ChangeNotifierProvider(create: (_) => WalletProvider()), ChangeNotifierProvider(create: (_) => NodeProvider()), ], child: MaterialApp( title: 'Coconut Wallet', theme: CoconutTheme.light(), darkTheme: CoconutTheme.dark(), home: const HomePage(), ), ); } } import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:coconut_wallet/repository/shared_prefs_repository.dart'; import 'package:coconut_wallet/utils/logger.dart'; import 'package:provider/provider.dart'; import 'app.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); final RootIsolateToken token = RootIsolateToken.instance!; BackgroundIsolateBinaryMessenger.ensureInitialized(token); if (Platform.isAndroid) { try { const MethodChannel ch = MethodChannel('android'); final int v = await ch.invokeMethod('getSdkVersion'); if (v != 26) { SystemChrome.setPreferredOrientations([ DeviceOrientation.portraitUp, DeviceOrientation.portraitDown, ]); } } on PlatformException catch (e) { Logger.log('Failed to get platform version'); } } } class CoconutApp extends StatelessWidget { const CoconutApp({super.key}); @override Widget build(BuildContext context) { return MultiProvider( providers: [ ChangeNotifierProvider(create: (_) => WalletProvider()), ChangeNotifierProvider(create: (_) => NodeProvider()), ], child: MaterialApp( title: 'Coconut Wallet', theme: CoconutTheme.light(), darkTheme: CoconutTheme.dark(), home: const HomePage(), ), ); } } import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:coconut_wallet/repository/shared_prefs_repository.dart'; import 'package:coconut_wallet/utils/logger.dart'; import 'package:provider/provider.dart'; import 'app.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); final RootIsolateToken token = RootIsolateToken.instance!; BackgroundIsolateBinaryMessenger.ensureInitialized(token); if (Platform.isAndroid) { try { const MethodChannel ch = MethodChannel('android'); final int v = await ch.invokeMethod('getSdkVersion'); if (v != 26) { SystemChrome.setPreferredOrientations([ DeviceOrientation.portraitUp, DeviceOrientation.portraitDown, ]); } } on PlatformException catch (e) { Logger.log('Failed to get platform version'); } } } class CoconutApp extends StatelessWidget { const CoconutApp({super.key}); @override Widget build(BuildContext context) { return MultiProvider( providers: [ ChangeNotifierProvider(create: (_) => WalletProvider()), ChangeNotifierProvider(create: (_) => NodeProvider()), ], child: MaterialApp( title: 'Coconut Wallet', theme: CoconutTheme.light(), darkTheme: CoconutTheme.dark(), home: const HomePage(), ), ); } }
Coconut App
DON'T TRUST, VERIFY

오픈소스,
그 자체로
신뢰에 기반한

비트코인 지갑이라면 무조건 오픈소스여야 한다고 믿습니다. 저희를 맹목적으로 믿어달라고 강요하지 않겠습니다. 대신 직접 확인하고 검증해 주세요.

Not your keys,
Not your bitcoin

지금 바로 셀프 커스터디 하세요!

App Store와 Google Play를 통해서만 공식 배포됩니다