/minibits_wallet

Primary LanguageTypeScriptMIT LicenseMIT

Disclaimer

⚠️ If you are using this app, please take the following into consideration:

  • This wallet should be used for research purposes only.
  • The wallet is a beta version with incomplete functionality and both known and unknown bugs.
  • Do not use it with large amounts of ecash.
  • The ecash stored in the wallet is issued by the mint. You trust the mint to back it with bitcoin until you transfer your holdings to another bitcoin Lightning wallet.
  • The Cashu protocol that the wallet implements has not yet received extensive review or testing so far.

Minibits Wallet

Minibits is an e-cash wallet with a focus on performance and usability. Cash is issued by mints and backed by Bitcoin via the Cashu protocol and Lightning Network.

Roadmap

Platform support

  • Android app
  • iOS app
  • Light and dark mode
  • i18n support
  • Other then EN languange support

Mints

  • Add multiple mints
  • Remove mint with zero balance
  • Block receiving from mint
  • Show mint balances grouped by hostname
  • Handle mint keys rotation (not tested)
  • Mint status and information screen
  • Change mint's short name and color

Receive ecash

  • Scan QR code of a ecash token
  • Paste ecash token from the clipboard
  • Notification on received payment (app needs to be in foreground)
  • Receive ecash while being offline, redeem later (MVP version)

Send ecash

  • Share ecash token to send through another app
  • Show ecash token as a QR code
  • Notification on payment received by the payee (app needs to come to foreground)
  • Send ecash to contact (NOSTR address)
  • Lock ecash sent offline to the receiver wallet key

Top up wallet

  • Show QR code with bitcoin lightning invoice to pay
  • Share encoded bitcoin lightning invoice to pay
  • Share payment request with contact
  • Top up balance by LNURL Withdraw

Transfer / Cash out from wallet

  • Paste and settle bitcoin lightning invoice with your ecash
  • Scan and settle bitcoin lightning invoice with your ecash
  • Pay payment request received from another contact
  • Pay to LNURL Pay static links / codes
  • One click zaps - tips on NOSTR social network
  • Pay to Lightning address
  • Transfer (swap) ecash to another mint

Transaction history

  • Unified transaction history for all kinds of transactions
  • Audit trail of transaction events
  • Filter pending transactions
  • Revert pending transaction in 1 click (get back tokens not claimed by receiver)
  • Tags and related filtering of transactions
  • Delete incomplete and failed transactions from history

Contacts

  • Private contacts address book for payments
  • Public contacts (followed users on NOSTR social network) for tipping and donations
  • Load public contacts from custom NOSTR relay
  • Wallet names as random public NOSTR addresses (random123@minibits.cash)
  • Custom wallet names (myname@minibits.cash)
  • Wallet names usable as Lightning addresses to receive payments from many Lightning wallets [✨ New!]
  • Private contacts with other than minibits.cash NOSTR adresses and relays

Backup and recovery

  • Local append-only backup of all ecash in a database separate from wallet storage
  • Recovery tool to recover ecash from local backup
  • Recover wallet in case spent ecash remain in the wallet due to an exception during a transaction
  • Off-device backup and recovery using 12 words based seed [✨ New!]
  • Smooth migration to another device

Security and Privacy

  • Optional AES encryption of wallet storage using a key stored in the device secure key storage
  • Use device biometry to login (if storage encryption is on)
  • Tor daemon to connect to mints with .onion addresses

Self-funding

  • Donation for custom wallet name

DevOps

  • OTA updates (opt in)
  • Automated tests
  • Release pipelines

Architecture

The wallet's design has been crafted to prioritize the following primary quality properties:

  • Support both Android and iOS mobile platforms
  • Achieve fast startup time and UX (despite using React Native)
  • Minimize the risk of data/ecash loss
  • Bring e-cash UX on par with the current standard of traditional finance (tradfi) mobile apps

As a result, the following architectural constraints are in place:

  • Wherever available, use libraries with a fast JSI (JavaScript Interface) to native modules.
  • Avoid Expo modules.
  • Use fastest available storage for most wallet operations and separate local database storage to store data that incrementally grows.
  • Leverage local database as an append-only ecash backup independent from fast storage.

Open architectural concepts that were still open for discussion when the wallet had been released

  • Contacts management - identities, sharing contacts, send ecash with the UX of tradfi instant payment while keeping privacy towards mints - Implemented as NOSTR keypairs and NIP05 public sharable names that ecash can be sent to
  • Off-device backup strategy - Implemented using @gandlafbtc concept of deterministic secrets
  • UX and naming conventions - ecash is not always intuitive. UX for new users heavily depends on using the right abstractions or terms to describe what is going on. This wallet wants to serve as a means to test what could work. One of the first ideas is to avoid terms such as token or proof and propose the term --coin ++ecash instead.
  • Suitable Tor daemon available to replace not maintained react-native-tor.

Download and test

Minibits wallet is in early beta and available as of now only for Android devices. You have the following options to try it out:

  • Download it from Google Play
  • Join testing program on Google Play to get early releases to test (Submit your email to get an invite on Minibits.cash)
  • Download .apk file from Releases page and install it on your phone

Development

Minibits is a bare React Native app written in Typescript. The project structure and code itself are intentionally verbose to support readability. Critical wallet code is reasonably documented. However, there is vast space for existing code improvements, refactoring, and bug fixing. This is an early beta software and the author does not code for a living.

The code is derived from Ignite template, however with many libraries, notably Expo, stripped down to achieve fast startup times. Performance bottleneck on some Android devices is react-native-keychain. To overcome this, it has been patched not to warm-up on startup, caching for wallet operatoions is in place and its use to encrypt storage is opt-in.

Wallet state is managed by mobx-state-tree and persisted in fast MMKV storage. Only the basic mobx concepts are in place, whole model could be improved. All critical wallet code is in services/walletService.ts and all ecash state changes are in models/ProofsStore.ts. Wallet communication with the mints is in services/cashuMintClient.ts and uses cashu-ts library.

Crypto operations are handled by react-native-quick-crypto, that is fast and does not require awful javascript shims. Transaction history and ecash backup is stored in sqlite, with fast react-native-quick-sqlite driver that enables to run lighter queries synchronously.

Wallet included own Tor daemon using react-native-tor library to connect to the mints over Tor network. However this seems not to be long term approach as this library is not properly maintained and future updates of React native will likely break it. Help with replacement would be appreciated.

In case of breaking state and data model changes, versioning and code is ready to run necessary migrations on wallet startup.

Running in development mode

To run Minibits wallet in dev mode, set up the React Native development environment and the Yarn package manager. Then clone this repository, navigate to the minibits_wallet directory, and run the following:

yarn install

There are post-install patches to some of the libraries that should run automatically and are necessary for a successful run. See the patches directory for more info. After the dependecies are installed, continue to create the following .env file in the root folder:

APP_ENV = 'DEV'
LOG_LEVEL='DEBUG'

Then make sure you have the Android device connected by running:

yarn adb

Finally run this and pray:

yarn start

In case of issues, repo includes commits history from the out of the box react native app up until the complete wallet. You can see build.gradle and other changes one by one and hopefully figure out what's wrong.

Building

Create debug .apk:

yarn android:dev

Automated testing

The app has the scaffolding for automated tests; they are yet to be implemented. For functional bugs or suggestions please raise an issue.

Contributing

Contributions are welcome, just start and we will figure out what's next.