* fix keys * fix tests * backwards compatible api upgrade * upgrade seems to work * fix tests * add deprecated api functions * add more tests of backwards compat * add test serialization for nut00 * remove a redundant test * move mint and melt to new api * mypy works * CI: mypy --check-untyped-defs * add deprecated router * add hints and remove logs * fix tests * cleanup * use new mint and melt endpoints * tests passing? * fix mypy * make format * make format * make format * commit * errors gone * save * adjust the API * store quotes in db * make mypy happy * add fakewallet settings * remove LIGHTNING=True and pass quote id for melt * format * tests passing * add CoreLightningRestWallet * add macaroon loader * add correct config * preimage -> proof * move wallet.status() to cli.helpers.print_status() * remove statuses from tests * remove * make format * Use httpx in deprecated wallet * fix cln interface * create invoice before quote * internal transactions and deprecated api testing * fix tests * add deprecated API tests * fastapi type hints break things * fix duplicate wallet error * make format * update poetry in CI to 1.7.1 * precommit restore * remove bolt11 * oops * default poetry * store fee reserve for melt quotes and refactor melt() * works? * make format * test * finally * fix deprecated models * rename v1 endpoints to bolt11 * raise restore and check to v1, bump version to 0.15.0 * add version byte to keyset id * remove redundant fields in json * checks * generate bip32 keyset wip * migrate old keysets * load duplicate keys * duplicate old keysets * revert router changes * add deprecated /check and /restore endpoints * try except invalidate * parse unit from derivation path, adjust keyset id calculation with bytes * remove keyest id from functions again and rely on self.keyset_id * mosts tests work * mint loads multiple derivation paths * make format * properly print units * fix tests * wallet works with multiple units * add strike wallet and choose backend dynamically * fix mypy * add get_payment_quote to lightning backends * make format * fix startup * fix lnbitswallet * fix tests * LightningWallet -> LightningBackend * remove comments * make format * remove msat conversion * add Amount type * fix regtest * use melt_quote as argument for pay_invoice * test old api * fees in sats * fix deprecated fees * fixes * print balance correctly * internally index keyset response by int * add pydantic validation to input models * add timestamps to mint db * store timestamps for invoices, promises, proofs_used * fix wallet migration * rotate keys correctly for testing * remove print * update latest keyset * fix tests * fix test * make format * make format with correct black version * remove nsat and cheese * test against deprecated mint * fix tests? * actually use env var * mint run with env vars * moar test * cleanup * simplify tests, load all keys * try out testing with internal invoices * fix internal melt test * fix test * deprecated checkfees expects appropriate fees * adjust comment * drop lightning table * split migration for testing for now, remove it later * remove unused lightning table * skip_private_key -> skip_db_read * throw error on migration error * reorder * fix migrations * fix lnbits fee return value negative * fix typo * comments * add type * make format * split must use correct amount * fix tests * test deprecated api with internal/external melts * do not split if not necessary * refactor * fix test * make format with new black * cleanup and add comments * add quote state check endpoints * fix deprecated wallet response * split -> swap endpoint * make format * add expiry to quotes, get quote endpoints, and adjust to nut review comments * allow overpayment of melt * add lightning wallet tests * commiting to save * fix tests a bit * make format * remove comments * get mint info * check_spendable default False, and return payment quote checking id * make format * bump version in pyproject * update to /v1/checkstate * make format * fix mint api checks * return witness on /v1/checkstate * no failfast * try fail-fast: false in ci.yaml * fix db lookup * clean up literals
Cashu Nutshell
Cashu Nutshell is a Chaumian Ecash wallet and mint for Bitcoin Lightning. Cashu Nutshell is the reference implementation in Python.
Disclaimer: The author is NOT a cryptographer and this work has not been reviewed. This means that there is very likely a fatal flaw somewhere. Cashu is still experimental and not production-ready.
Cashu is an Ecash implementation based on David Wagner's variant of Chaumian blinding (protocol specs). Token logic based on minicash (description) which implements a Blind Diffie-Hellman Key Exchange scheme written down here. The database mechanics in Cashu Nutshell and the Lightning backend uses parts from LNbits.
Cashu protocol · Quick Install · Manual install · Configuration · Using Cashu · Run a mint
Feature overview of Nutshell
- Bitcoin Lightning support
- Standalone Cashu CLI wallet and mint server
- Wallet and mint library to include in Python projects
- PostgreSQL and SQLite
- Wallet with builtin Tor
- Use multiple mints in one wallet
- Send and receive tokens on nostr
Advanced features
- Deterministic wallet with seed phrase backup
- Programmable ecash with, e.g., Pay-to-Pubkey support
- Wallet and mint support for keyset rotations
- DLEQ proofs for offline transactions
The Cashu protocol
Different Cashu clients and mints use the same protocol to achieve interoperability. See the documentation page for more information on other projects. If you are interested in developing on your own Cashu project, please refer to the protocol specs protocol specs.
Easy Install
The easiest way to use Cashu is to install the package it via pip:
pip install cashu
To update Cashu, use pip install cashu -U.
If you have problems running the command above on Ubuntu, run sudo apt install -y pip pkg-config and pip install wheel. On macOS, you might have to run pip install wheel and brew install pkg-config.
You can skip the entire next section about Poetry and jump right to Using Cashu.
Manual install: Poetry
These steps help you install Python via pyenv and Poetry. If you already have Poetry running on your computer, you can skip this step and jump right to Install Cashu.
Poetry: Prerequisites
# on ubuntu:
sudo apt install -y build-essential pkg-config libffi-dev libpq-dev zlib1g-dev libssl-dev python3-dev libsqlite3-dev ncurses-dev libbz2-dev libreadline-dev lzma-dev
# install python using pyenv
curl https://pyenv.run | bash
# !! follow the instructions of pyenv init to setup pyenv !!
pyenv init
# restart your shell (or source your .rc file), then install python:
pyenv install 3.10.4
# install poetry
curl -sSL https://install.python-poetry.org | python3 -
echo export PATH=\"$HOME/.local/bin:$PATH\" >> ~/.bashrc
source ~/.bashrc
Poetry: Install Cashu
# install cashu
git clone https://github.com/cashubtc/nutshell.git cashu
cd cashu
pyenv local 3.10.4
poetry install
If you would like to use PostgreSQL as the mint database, use the command poetry install --extras pgsql.
Poetry: Update Cashu
To update Cashu to the newest version enter
git pull && poetry install
Poetry: Using the Nutshell wallet
Cashu should be now installed. To execute the following commands, activate your virtual Poetry environment via
poetry shell
If you don't activate your environment, just prepend poetry run to all following commands.
Configuration
mv .env.example .env
# edit .env file
vim .env
To use the wallet with the public test mint, you need to change the appropriate entries in the .env file.
Test instance
Warning: this instance is just for demonstration only. The server could vanish at any moment so consider any Satoshis you deposit a donation.
Change the appropriate .env file settings to
MINT_URL=https://8333.space:3338
Using Cashu
cashu info
This command shows information about your wallet.
Check balance
cashu balance
Generate a Lightning invoice
This command will return a Lightning invoice that you need to pay to mint new ecash tokens.
cashu invoice 420
The client will check every few seconds if the invoice has been paid. If you abort this step but still pay the invoice, you can use the command cashu invoice <amount> --id <id>.
Pay a Lightning invoice
cashu pay lnbc120n1p3jfmdapp5r9jz...
Send tokens
To send tokens to another user, enter
cashu send 69
You should see the encoded token. Copy the token and send it to another user such as via email or a messenger. The token looks like this:
cashuAeyJwcm9vZnMiOiBbey...
Receive tokens
To receive tokens, another user enters:
cashu receive cashuAeyJwcm9vZnMiOiBbey...
Starting the wallet API daemon
Nutshell wallet can be used in daemon mode that can be controlled through a REST API:
cashu -d
You can find the API docs at http://localhost:4448/docs.
Running a mint
This command runs the mint on your local computer. Skip this step if you want to use the public test mint instead.
Before you can run your own mint, make sure to enable a Lightning backend in MINT_LIGHTNING_BACKEND and set MINT_PRIVATE_KEY in your .env file.
poetry run mint
For testing, you can use Nutshell without a Lightning backend by setting MINT_LIGHTNING_BACKEND=FakeWallet in the .env file.
Running tests
To run the tests in this repository, first install the dev dependencies with
poetry install --with dev
Then, make sure to set up your mint's .env file to use a fake Lightning backend and disable Tor:
MINT_LIGHTNING_BACKEND=FakeWallet
TOR=FALSE
You can run the tests with
poetry run pytest tests