Sulkta Coop's Python SDK for merchant-side Cardano payments + NFT certificate-of-authenticity minting. Zero-custody by design. Extracted from TradeCraft's services/cardano_*.py (2,400+ lines of production Cardano-mainnet code) and restructured as an installable Python package. Package layout (cardano_checkout/): - addresses.py — lifted verbatim: CIP-1852 HD derivation, pure pycardano - oracles.py — lifted from cardano_price.py: Koios ADA/USD feed w/ 5m cache - monitor.py — lifted verbatim (SQLAlchemy-coupled; v0.2 refactors to Store) - scheduler.py — lifted verbatim (same refactor note) - invoice.py — NEW: framework-agnostic Invoice dataclass + lifecycle enum - store.py — NEW: InvoiceStore Protocol for pluggable persistence - mint.py — NEW: CIP-25 v2 metadata builder (works); tx submission stub for v0.2 - ipfs.py — NEW: kubo HTTP client with primary-pin + mirror-pin pattern - txbuild.py — NEW: v0.2 stub for PyCardano / Ogmios tx construction Design: - Consumers provide xpub + InvoiceStore impl. SDK provides everything else. - IPFS: local kubo for upload + serve, optional mirror pins for archival. Chromaticcraft pattern: Rackham kubo primary, Lucy kubo mirror. - NFT: single native-script policy per merchant studio (CIP-25 v2, not CIP-68 — full wallet coverage, no mutability needed for static certs). Policy skey stays under Sulkta cold-custody (Lucy pattern); signing is an external hand-off like ADAMaps payouts. Tests: pure-module smoke tests pass for invoice, store-protocol, CIP-25 metadata envelope, IPFS client import, txbuild stub module. Address derivation tests ship but require pycardano + will exercise in CI. LICENSE: Apache-2.0 (matches upstream Cardano tooling). Next (v0.2 scope): - Refactor monitor + scheduler around InvoiceStore (drop SQLAlchemy coupling) - Wire mint.mint_nft_cert to PyCardano + local Ogmios on Rackham - txbuild: Ogmios chain-context + cold-signer hand-off shape - chromaticcraft Phase 2 imports the SDK as its first external consumer
134 lines
5.7 KiB
Markdown
134 lines
5.7 KiB
Markdown
# cardano-checkout
|
|
|
|
Python SDK for merchant-side Cardano payments + NFT certificate-of-authenticity minting.
|
|
|
|
**Zero-custody by design:** the merchant provides a wallet xpub. The SDK derives
|
|
unique receive addresses per invoice, polls the chain for payment, and optionally
|
|
mints a CIP-25 NFT cert on confirmation. The platform never holds or moves funds.
|
|
|
|
Extracted from [TradeCraft](http://192.168.0.5:3001/TradeCraft/tradecraft)'s
|
|
`services/cardano_*.py` modules (2,400+ lines of production code running on the
|
|
Cardano mainnet) and packaged for reuse across the Sulkta Coop product family.
|
|
|
|
## Status
|
|
|
|
**v0.1.0-dev — alpha extraction.** Pure modules lifted verbatim from TradeCraft.
|
|
DB-coupled modules (monitor, scheduler) ship with a `TODO: refactor to Store
|
|
protocol` marker — they work as-is when paired with TradeCraft's SQLAlchemy models
|
|
but will be refactored to the generic `InvoiceStore` Protocol in v0.2.
|
|
|
|
| Module | Status | Notes |
|
|
|---|---|---|
|
|
| `addresses` | ✅ stable | CIP-1852 HD derivation; pure pycardano |
|
|
| `oracles` | ✅ stable | ADA/USD price via Koios with 5-min cache |
|
|
| `invoice` + `store` | ✅ new | Framework-agnostic invoice + persistence Protocol |
|
|
| `mint` | ⏳ stub | CIP-25 v2 metadata builder works; tx submission in v0.2 |
|
|
| `ipfs` | ✅ working | kubo HTTP API client w/ optional mirror-pin |
|
|
| `monitor` | 🟡 SQLAlchemy-coupled | v0.2 target: refactor around `InvoiceStore` |
|
|
| `scheduler` | 🟡 SQLAlchemy-coupled | v0.2 target: same |
|
|
| `txbuild` | ❌ v0.2 | Full PyCardano tx construction via Ogmios |
|
|
|
|
## Design
|
|
|
|
```
|
|
┌────────────────────────────────────────────────────────┐
|
|
│ Merchant App │
|
|
│ (TradeCraft / chromaticcraft / your-product) │
|
|
└──────────────┬───────────────────────┬─────────────────┘
|
|
│ │
|
|
uses │ implements │ imports
|
|
▼ ▼
|
|
┌──────────────┐ ┌────────────────────────┐
|
|
│ InvoiceStore │ ◄────── │ cardano_checkout SDK │
|
|
│ (your DB) │ │ │
|
|
└──────────────┘ │ addresses ← pure │
|
|
│ oracles ← pure │
|
|
│ invoice ← dataclass │
|
|
│ monitor ← polls chain │
|
|
│ scheduler ← bg loop │
|
|
│ mint ← NFT cert │
|
|
│ ipfs ← upload │
|
|
│ txbuild ← PyCardano wrappers │
|
|
└────────────────────────┘
|
|
│
|
|
talks to │
|
|
▼
|
|
┌────────────────────────┐
|
|
│ Koios + Ogmios + kubo │
|
|
└────────────────────────┘
|
|
```
|
|
|
|
The merchant app provides:
|
|
1. A wallet xpub (account-level extended public key).
|
|
2. An `InvoiceStore` implementation (SQLAlchemy, Postgres, SQLite, in-memory — whatever).
|
|
|
|
The SDK provides:
|
|
1. Address derivation from the xpub.
|
|
2. Per-invoice payment monitoring against Koios.
|
|
3. ADA ↔ USD price conversion.
|
|
4. CIP-25 v2 NFT cert minting (v0.2).
|
|
5. IPFS upload + pinning for NFT image metadata.
|
|
|
|
## Quick start
|
|
|
|
```python
|
|
import asyncio
|
|
from cardano_checkout import addresses, oracles
|
|
|
|
# Derive a receive address for invoice #42
|
|
addr = addresses.derive_address(
|
|
xpub_hex="<your wallet xpub>",
|
|
index=42,
|
|
network="mainnet",
|
|
)
|
|
|
|
# Convert a USD price to lovelace at current market
|
|
async def main() -> None:
|
|
lovelace = await oracles.convert_usd_to_lovelace(99.00)
|
|
ada = lovelace / 1_000_000
|
|
print(f"Customer owes {ada:.4f} ADA for $99")
|
|
|
|
asyncio.run(main())
|
|
```
|
|
|
|
## IPFS: bake-then-mirror pattern
|
|
|
|
The SDK's `IPFSClient` expects a local kubo daemon (typically in the same
|
|
Docker image as the web app) for upload and primary pin, and takes an
|
|
optional list of mirror endpoints to `pin add` the CID on a second node
|
|
for archival redundancy.
|
|
|
|
Typical chromaticcraft deployment:
|
|
|
|
```python
|
|
from cardano_checkout import ipfs
|
|
|
|
client = ipfs.IPFSClient(
|
|
api_url="http://127.0.0.1:5001", # local kubo in the same container
|
|
mirror_api_urls=["http://192.168.254.5:5001"], # Lucy's kubo over the LAN/VPN
|
|
)
|
|
|
|
cid = await client.add(photo_bytes, filename="order-0001.jpg")
|
|
# Image now served by Rackham (low latency) AND pinned on Lucy (durability)
|
|
```
|
|
|
|
## NFT cert-of-authenticity design
|
|
|
|
One minting policy per merchant studio. Policy is a native script (no Plutus
|
|
required), optionally time-locked to make "no more editions after X" a
|
|
cryptographically verifiable claim.
|
|
|
|
CIP-25 v2 metadata. Single NFT per order. Policy skey never leaves the custody
|
|
host (Lucy in Sulkta's pattern). The SDK builds the metadata envelope + tx;
|
|
external signer does the signature.
|
|
|
|
## Installation
|
|
|
|
```
|
|
pip install 'cardano-checkout[sqlalchemy]' # if you're using SQLAlchemy
|
|
pip install cardano-checkout # core only
|
|
```
|
|
|
|
## License
|
|
|
|
Apache-2.0 — matches upstream Cardano tooling.
|