Customer-facing CLI for Satsignal — anchor and verify files against the BSV-anchored notary.
Project description
satsignal-cli
Customer-facing CLI for Satsignal — anchor and verify files against the BSV-anchored notary.
Status: v0.1 draft. Standard-mode anchor + verify works end-to-end. Sealed mode is
verify-only (you can verify a sealed bundle produced by the web UI; producing one from the CLI lands in v0.2). Multi-proof (content_canonical,chunk_merkle) verification falls back to the web verifier at/verify.
Install
pip install satsignal-cli # Python 3.11+
pip install 'satsignal-cli[toml-py39]' # Python 3.9 / 3.10
Quickstart
satsignal login # paste your API key (sk_…)
satsignal anchor report.pdf # dry-run preview
satsignal anchor report.pdf --broadcast
# → writes report.pdf.mbnt next to the file
satsignal verify report.pdf
# → chain-confirms by default; exit 0 on success
Commands
| verb | purpose |
|---|---|
satsignal anchor <file> |
anchor a file; dry-run by default, writes <file>.mbnt on --broadcast |
satsignal verify <file> |
verify a file against its .mbnt sidecar; chain-confirms by default |
satsignal show <bundle> |
print receipt details (txid, mode, proofs, etc.) |
satsignal log |
list recent anchors from ~/.local/state/satsignal/anchors.jsonl |
satsignal login |
store API key in ~/.config/satsignal/credentials.toml |
satsignal matters |
list workspace matters |
Sidecar convention
satsignal anchor writes <file>.mbnt next to the source by default. Override with -o. satsignal verify looks for the sidecar in this order:
<file>.mbntdirectly next to the source.satsignal/<single-bundle>.mbntin the source's parent directory (only if there's exactly one — otherwise pass--bundleexplicitly)
This convention mirrors GPG's .asc / RFC 3161's .tsr — one file in, one receipt out, same directory.
Configuration
Reads (in order, first wins):
- Environment:
SATSIGNAL_API_KEY,SATSIGNAL_BASE_URL,SATSIGNAL_MATTER,SATSIGNAL_PROOF_URL ~/.config/satsignal/credentials.toml(mode 600)- Defaults:
base_url = https://app.satsignal.cloud,proof_url = https://proof.satsignal.cloud,matter = inbox
The credentials file is plain TOML:
api_key = "sk_..."
base_url = "https://app.satsignal.cloud"
matter = "inbox"
Verify semantics
satsignal verify implements the conformant procedure from bundle-v1.md §7 in order:
- Open ZIP, parse
manifest.json/canonical.json/proofs.json(if present) - Cryptographic check (standard: SHA-256; sealed: HMAC-SHA256 with master salt)
doc_hashconsistency via JCS-canonical SHA-256- Chain confirmation — fetch raw tx, parse OP_RETURN MBNT payload, compare
doc_hash
Exit codes match bundle-v1.md §8:
| exit | class | meaning |
|---|---|---|
| 0 | VERIFIED / PENDING / OFFLINE | crypto + chain OK (PENDING = 0 confirmations; OFFLINE = chain skipped) |
| 1 | CRYPTO | bundle malformed or hashes don't match |
| 2 | CHAIN | bundle is valid but the on-chain anchor doesn't commit to this canonical doc |
| 3 | NETWORK | couldn't reach WhatsOnChain / Bitails |
| 4 | (auth) | API key missing or rejected (anchor flow only) |
| 5 | (bundle not found) | |
| 6 | VERSION | mbnt_version unsupported by this CLI |
PENDING returning exit 0 is intentional — satsignal verify && cp report.pdf out/ should succeed the moment the anchor is broadcast. Opt into stricter gating with --min-confirmations N.
Offline mode
satsignal verify --offline skips the chain check. The warning ("locally-fabricated bundles pass crypto-only checks") is non-suppressible — --quiet does not silence it. This matches the chain-confirm-by-default rule from the spec; making the chain check opt-in by default would invert the safety property the protocol exists to provide.
What v0.1 deliberately omits
- Sealed-mode anchoring. The CLI can verify sealed bundles, but can't produce them (requires client-side HKDF + HMAC + bundle assembly). Use sealed.satsignal.cloud until v0.2.
content_canonical/chunk_merkleverification. These require porting the verifier.html canonicalizers (text-norm-v1, json-jcs-v1, csv-norm-v1, etc.) to Python. The CLI flags their presence and points to the web verifier for now.- Manifest mode (Phase 8b). Out of scope for v0.1.
--watch/--bulk. Single-file anchors only.
See also
- Bundle format spec: https://proof.satsignal.cloud/spec-bundle
- LangChain integration: https://github.com/Steleet/langchain-satsignal
- API docs: https://app.satsignal.cloud/docs
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file satsignal_cli-0.1.1.tar.gz.
File metadata
- Download URL: satsignal_cli-0.1.1.tar.gz
- Upload date:
- Size: 16.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
36cdfac5845fc6a78415fb789bd6362fb6ea3a44e1d07f7144f7bcc91207be7d
|
|
| MD5 |
acfcc3e40b1d34aa7e3800a444987115
|
|
| BLAKE2b-256 |
658ffbadc735a97257729e513be3015f978ad8697cfb3a8d0157c800d2714e67
|
File details
Details for the file satsignal_cli-0.1.1-py3-none-any.whl.
File metadata
- Download URL: satsignal_cli-0.1.1-py3-none-any.whl
- Upload date:
- Size: 17.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3cd3379f94633bd35c52c1fd1f7d04b54eb165fdb7bcb9586587fa2da2d68fc4
|
|
| MD5 |
1af3e05d3026babced1fac3b7875ea1f
|
|
| BLAKE2b-256 |
a062931a87589e8bd4e159360e91c793d5beec375fbc105adde576f10ac2ead7
|