Download iOS App | Download Android App
Watch-only Bitcoin Wallet for iOS & Android
Try it risk-free! A REGTEST VERSION is available on both app stores, allowing you to practice transactions with an offline signing device using test bitcoin — no real funds required.
Download iOS App(ver.regtest) · Download Android App(ver.regtest)
Coconut Wallet is a Bitcoin wallet focused on the watch-only experience and designed to work with Coconut Vault. By operating the vault and wallet on two physically separate devices, it implements a secure offline transaction signing architecture where private keys never touch an online device. Coconut Wallet also aims to make Bitcoin easy for newcomers to use, providing optional hot wallet support for a simpler way to get started.
Watch-only first, with optional hot wallet support.
- Supported hardware wallets — Keystone 3 Pro, Seedsigner, Jade, Coldcard, Krux, Trezor, BitBox02
- Watch-only with offline signing — Use an offline signing device so private keys never touch an online device
- Optional hot wallet — Create or restore a wallet in the app for a simpler way to get started with Bitcoin
- SegWit — Native SegWit (Bech32) address support
- Multisig — Multi-signature wallet support
- RBF (Replace-By-Fee) — Fee bumping for unconfirmed transactions
- CPFP (Child-Pays-For-Parent) — Fee acceleration via child transactions
- Batch sending — Send to multiple recipients in a single transaction
- UTXO management — Coin control with UTXO locking and tagging
- PSBT — BIP-174 Partially Signed Bitcoin Transactions
- Draft transactions — Save transactions as drafts for later signing or sending
- Multilingual — 한국어, English, 日本語, Español, Deutsch
OFFLINE ONLINE
┌─────────────────┐ QR Code ┌─────────────────┐
│ Coconut Vault │ ◄──────────────────────► │ Coconut Wallet │
│ │ │ │
│ · Key storage │ │ · Balance sync │
│ · Tx signing │ │ · Tx creation │
│ │ │ · Broadcasting │
└─────────────────┘ └─────────────────┘
The wallet stays online to keep your wallet data up to date and broadcasts signed transactions to the Bitcoin network.
Hot wallets are optional. Each hot wallet has its own randomly generated 256-bit data encryption key (DEK), and its mnemonic and saved BIP39 passphrase are encrypted with AES-256-GCM. The encrypted payload—not the plaintext mnemonic—is stored in platform Secure Storage. The DEK is protected by the best device-backed key storage available. If the device does not provide a supported hardware-backed key, Coconut Wallet uses a separate random key stored in platform Secure Storage as a fallback.
flowchart LR
A[Mnemonic<br/>and saved passphrase] -->|AES-256-GCM| B[Encrypted wallet payload]
C[Per-wallet<br/>256-bit DEK] -->|Encrypts| B
B --> S[Platform Secure Storage<br/>encrypted payload and wrapped DEK]
C --> W[Wrapped DEK]
E[Android<br/>StrongBox or TEE] -->|Wraps| W
F[iOS<br/>Secure Enclave] -->|Wraps| W
G[Fallback key<br/>in platform Secure Storage] -->|Wraps| W
W --> S
H[Later signing or backup access] --> I{App lock enabled?}
I -->|Yes| J[Biometrics or app PIN]
I -->|No| K[Continue]
J --> L[Unwrap DEK and decrypt temporarily]
K --> L
L --> M{Requested operation}
M -->|Sign| O[Verify wallet identity and sign]
M -->|Backup| P[Display mnemonic]
O --> N[Best-effort memory wipe]
P --> N
After setup, the stored mnemonic is decrypted only when it is needed for signing or backup display. The backup shown immediately after creation or restoration uses the mnemonic already held in memory. When app lock is enabled, later access requires biometric authentication or the app PIN first. A hot wallet still keeps signing keys on an online device, so it does not provide the same isolation as a watch-only wallet used with an offline signer.
See Hot Wallet Security Architecture for implementation details, platform behavior, passphrase handling, deletion, and security boundaries.
| Project | Description |
|---|---|
| coconut_lib | |
| coconut_vault | |
| coconut_wallet | |
| coconut_design_system |
- Flutter SDK (3.29+)
- Dart 3.7+
- Android Studio or Xcode
- Go (1.26+) — required to build the BitBox02 bridge
- Rust (stable) — required to build the Trezor bridge
- protoc (Protocol Buffers compiler) — required to build the Trezor bridge
- macOS:
brew install protobuf - Linux:
apt-get install -y protobuf-compiler - Windows:
choco install protoc(or download from the releases page)
- macOS:
flutter --version
go version
rustc --versiongit clone https://github.com/noncelab/coconut_wallet.git
cd coconut_wallet
flutter pub getThis project uses gomobile to generate native bindings for the BitBox02 hardware wallet bridge. See docs/bitbox02-dev-guide.md for the full setup guide.
Quick steps:
# 1. Install Go (if not already installed)
brew install go
# 2. Install gomobile and add to PATH
go install golang.org/x/mobile/cmd/gomobile@latest
echo 'export PATH=$PATH:$(go env GOPATH)/bin' >> ~/.zshrc && source ~/.zshrc
# 3. Initialize gomobile (re-run if you upgrade Go, Xcode, or Android NDK)
gomobile init
# 4. Sync Go dependencies (fetches the pinned bitbox02-api-go fork automatically, no manual clone needed)
cd go && go mod tidy && cd ..
# 5. Build native bindings (16KB page-aligned for Android 15+)
make gomobile-bind # both iOS and Android
# make gomobile-ios
# make gomobile-androidThis project uses UniFFI + cargo-ndk to generate native bindings for the Trezor Safe 7 BLE (THP v2) hardware wallet bridge.
Quick steps:
# 1. Install Rust (if not already installed)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# 2. Install protoc (required by trezor-connect-rs to compile .proto files)
brew install protobuf # macOS; see Prerequisites above for Linux/Windows
# 3. Install cargo-ndk
cargo install cargo-ndk
# 4. Add Android/iOS Rust targets
rustup target add aarch64-linux-android armv7-linux-androideabi x86_64-linux-android
rustup target add aarch64-apple-ios aarch64-apple-ios-sim x86_64-apple-ios
# 5. Build native bindings
make trezor-bind # both iOS and Android
# make trezor-android
# make trezor-iosThe build scripts are at
rust/trezor-bridge/scripts/build_android.shandrust/trezor-bridge/scripts/build_ios.sh. 16KB page-size alignment is configured viarust/trezor-bridge/.cargo/config.toml(Android) and linker flags (iOS).
dart run build_runner build --delete-conflicting-outputs
dart run realm generate
flutter pub run slangOr run all at once:
make readyIf Realm generation fails, run
dart run build_runner cleanfirst.
This project requires environment variables configured via flutter_dotenv. Create the file for the flavor you're building (regtest.env for local development, mainnet.env for mainnet builds) in the project root.
regtest.env (used by the default flutter run --flavor regtest in Quick Start, no secrets required):
NETWORK_TYPE=regtestmainnet.env (only needed if you build with --flavor mainnet; the FIREBASE_* values below are only read when building with --dart-define=USE_FIREBASE=true, so they can be left blank for local builds):
NETWORK_TYPE=mainnet
# ------- Firebase (leave blank unless you have your own Firebase project) --------
FIREBASE_MESSAGING_SENDER_ID=
FIREBASE_PROJECT_ID=
FIREBASE_STORAGE_BUCKET=
# Android
FIREBASE_API_KEY_ANDROID=
FIREBASE_APP_ID_ANDROID=
# iOS
FIREBASE_API_KEY_IOS=
FIREBASE_APP_ID_IOS=
FIREBASE_IOS_BUNDLE_ID=
# ------- Firebase End --------Generate a local keystore for Android builds:
keytool -genkey -v -keystore android/app/local.jks \
-storepass android -alias local -keypass android \
-keyalg RSA -keysize 2048 -validity 10000 \
-dname "CN=Local Dev,O=Coconut,C=KR"Create key_regtest.properties and key_mainnet.properties under the android/ directory:
keyAlias=local
storeFile=../app/local.jksRelease signing passwords are not stored in these files. For local Android release builds, run:
./android/scripts/build_android_release.shThe script prompts once for the keystore/key password and uses it for both storePassword and keyPassword during the build.
For local Android release runs on a connected device, run:
./android/scripts/run_android_release.shThis uses the Android debug keystore for the local release run only.
# Debug
flutter run --flavor regtest
# Release on a connected Android device
./android/scripts/run_android_release.sh| Flavor | Description |
|---|---|
mainnet |
Real Bitcoin mainnet — production release distributed via app stores |
regtest |
Local testnet — for learning and development |
Android Studio / IntelliJ
Run → Edit Configurations... → Set Build Flavor to regtest
VS Code — .vscode/launch.json:
{
"name": "coconut_wallet (debug)",
"request": "launch",
"type": "dart",
"args": ["--flavor", "regtest"]
}
⚠️ Mainnet Self-Build Disclaimer: If you build and run the app from source on mainnet outside of official distribution channels (App Store / Google Play), we assume no responsibility for any loss of funds or errors that may occur. Please useregtestmode for development and testing.
Coconut Wallet is opening up to external contributors through CCOS (Coconut Contribution Open Store) — the path for proposing new features and extensions, not fixes or improvements to something that already exists. Every proposal is classified as 🟢 Green (open to propose freely), 🟡 Yellow (needs pre-review), or 🔴 Red (not accepted) before implementation starts.
Please refer to CONTRIBUTING.md for details.
If you're proposing a new feature or extension (not a fix or improvement to something that already exists), start with the CCOS docs instead.
- Issues — Bug reports and feature requests
- Pull Requests — New features, documentation improvements, and bug fixes
If you discover a critical security vulnerability, please report it directly to hello@noncelab.com instead of opening a public issue.
MIT License. See LICENSE for details.
The MIT license covers the source code only. It does not grant rights to the "Coconut Vault" or "Nonce Lab" names or logos — see TRADEMARK.md for the separate trademark and brand usage policy.
All third-party libraries used in this project are licensed under MIT, BSD, or Apache. See the full list for details.
| Website | coconut.onl |
| X (Twitter) | @CoconutWallet 🌐 / @Coconut 🇰🇷 |
| Discord | Join our Discord |
| Documentation | Tutorials & Docs |
| GitHub | github.com/noncelab |
| Company Site | NonceLab |

