A Rust implementation of the Coinkite Tap Protocol (cktap) for use with SATSCARD, TAPSIGNER, and SATSCHIP products.
cktap-direct is a fork of rust-cktap that replaces the PC/SC dependency with a direct USB CCID implementation. The main differences from upstream are:
- Direct USB Access: Uses
rusb(libusb wrapper) instead of PC/SC middleware - Static Binary Support: Can compile to fully static musl binaries
- Native CCID Protocol: Implements the USB CCID protocol directly
- Enhanced CLI: Structured commands with JSON output by default for better scripting
This project provides APDU message encoding and decoding, cvc authentication, certificate chain verification, and card response verification.
It is up to the crate user to send and receive the raw cktap APDU messages via NFC to the card by implementing the CkTransport trait. This fork provides a USB CCID transport implementation that works with USB smart card readers. Mobile users are expected to implement CkTransport using the iOS or Android provided libraries.
- status
- read (messages)
- response verification
- derive (messages)
- response verification
- certs
- new
- nfc
- sign (messages)
- response verification
- wait
- Install and start cktap emulator
- TapSigner:
./ecard.py emulate -t --no-init - SatsCard:
./ecard.py emulate -s
- TapSigner:
- run tests:
cargo test --features emulator
This project uses Git hooks for maintaining code quality. When you enter the development environment, hooks are automatically configured:
$ nix develop
📎 Setting up Git hooks for code quality checks...
✅ Git hooks configured automatically!
• pre-commit: Checks code formatting
• pre-push: Runs formatting and clippy checksThe project includes two Git hooks that help maintain code quality:
- pre-commit: Ensures code is properly formatted before committing
- pre-push: Runs both formatting and clippy checks before pushing
These hooks are automatically configured when you enter the nix development shell. To manually configure them:
git config core.hooksPath .githooksTo disable the hooks temporarily:
git config --unset core.hooksPathYou can run the quality checks manually at any time:
# Check formatting
nix develop -c cargo fmt --check
# Fix formatting
nix develop -c cargo fmt
# Run clippy
nix develop -c cargo clippy --workspace -- -D warnings
# Run all checks
nix develop -c cargo fmt --check && nix develop -c cargo clippy --workspace -- -D warnings- USB PCSC NFC card reader, for example:
- Coinkite SATSCARD, TAPSIGNER, or SATSCHIP cards Install vendor PCSC driver
- Connect NFC reader to desktop system
- Place SATSCARD, TAPSIGNER, or SATSCHIP on reader
The CLI has been restructured with subcommands for different card types:
# Show help
cargo run --bin cktap-direct -- --help
# Auto-detect card type commands
cargo run --bin cktap-direct -- auto status
cargo run --bin cktap-direct -- auto certs
# SatsCard-specific commands
cargo run --bin cktap-direct -- satscard status
cargo run --bin cktap-direct -- satscard address
cargo run --bin cktap-direct -- satscard read
cargo run --bin cktap-direct -- satscard derive
# TapSigner-specific commands (requires CVC/PIN)
CKTAP_CVC=123456 cargo run --bin cktap-direct -- tapsigner status
CKTAP_CVC=123456 cargo run --bin cktap-direct -- tapsigner read
CKTAP_CVC=123456 cargo run --bin cktap-direct -- tapsigner derive --path 84,0,0
CKTAP_CVC=123456 cargo run --bin cktap-direct -- tapsigner sign "message to sign"
# Output format (JSON by default)
cargo run --bin cktap-direct -- --format json auto status
cargo run --bin cktap-direct -- --format plain auto status # Note: plain format not fully implementedNote: The CLI now outputs JSON by default for easy scripting and integration. Use --format plain for human-readable output (currently shows "not implemented" for most commands).
This project defaults to building static musl binaries for maximum portability:
# Build debug binary (static musl)
cargo build
# Build release binary (static musl)
cargo build --release
# The binary will be at: target/x86_64-unknown-linux-musl/release/cktap-directIf you need a dynamically linked binary:
# Build for your host platform
cargo build --target x86_64-unknown-linux-gnuThis library should always compile with any valid combination of features on Rust 1.88.0.