**Scope:** Concrete architecture and code paths for TIMMY token minting, Lightning channel integration, L402 payment gating, and FastAPI/Python wiring
**Convention:** `⚠️ NOT PRODUCTION-READY` marks anything that is alpha, testnet-only, or has a known breaking limitation. `✅ MAINNET` marks confirmed production-viable paths.
> **Proto field caveat:** gRPC stubs must be regenerated from the `.proto` files of each tapd release. Field names and message structures may change between minor versions. Always run `python -m grpc_tools.protoc` against the proto files from the exact tapd version you are running, and re-validate field names in the Python snippets below against your generated stubs before production use.
| litd (Lightning Terminal) | v0.14.x | ✅ MAINNET — required for TA channels |
| Python | 3.11+ | ✅ |
| grpcio / grpcio-tools | 1.62+ | ✅ |
| FastAPI | 0.110+ | ✅ |
**Critical note:** `litd` must be run in **integrated mode** — LND, tapd, and litd run as a single binary. You cannot run tapd standalone alongside a separately managed LND if you want Lightning channel support.
---
## 1. Taproot Asset Minting
### 1.1 LND Compile Requirements
LND must be compiled with the following RPC tags. Pre-built binaries from the official releases include these; if building from source:
```bash
make install tags="signrpc walletrpc chainrpc invoicesrpc"
```
For the full Lightning Terminal stack (recommended), use litd which bundles everything:
Or, using `litd` in integrated mode (required for Lightning channel support):
```ini
# lit.conf
lnd.protocol.option-scid-alias=true
lnd.protocol.zero-conf=true
lnd.protocol.simple-taproot-chans=true
lnd.protocol.simple-taproot-overlay-chans=true
lnd.protocol.custom-message=17
lnd.accept-keysend=true
```
```bash
litd --uipassword=<yourpassword>
```
### 1.3 Mint the TIMMY Token (CLI)
**Step 1 — Queue the mint:**
```bash
# Fixed supply (cannot issue more later)
tapcli assets mint \
--type normal \
--name "TIMMY" \
--supply 1000000 \
--decimal_display 0 \
--meta_bytes "TIMMY: one unit of Timmy agent labor credit"
```
Or with a group key to allow future issuance (recommended for a labor credit that may need top-ups):
```bash
# Grouped asset — allows future tranches of TIMMY
tapcli assets mint \
--type normal \
--name "TIMMY" \
--supply 1000000 \
--decimal_display 0 \
--new_grouped_asset \
--meta_bytes "TIMMY: one unit of Timmy agent labor credit"
```
**Step 2 — Finalize (broadcast the Bitcoin transaction):**
```bash
tapcli assets mint finalize
```
This publishes a single on-chain Bitcoin transaction that anchors the entire supply. The entire supply is minted in one transaction. You do not need multiple transactions for different amounts.
**Step 3 — Verify:**
```bash
tapcli assets list
```
Look for `"name": "TIMMY"` in the output. Note the `asset_id` (a 32-byte hash) and, if grouped, the `tweaked_group_key`. Save both — you will need them for all subsequent operations.
The minting transaction is a standard Bitcoin Taproot transaction. Cost depends entirely on the current fee market:
| Network congestion | Approximate cost |
|-------------------|-----------------|
| Low (<5 sat/vB) | $3–$10 |
| Normal (10–30 sat/vB) | $10–$40 |
| High (>100 sat/vB) | $40–$200+ |
The mint is a **single transaction regardless of supply size**. Minting 1 token or 1,000,000 tokens costs the same — it is just a Bitcoin Taproot output with a commitment in the witness.
---
## 2. Taproot Assets on Lightning Channels
### 2.1 Fund a Lightning Channel with TIMMY Tokens
Get your asset's group key first:
```bash
tapcli assets list
# note: tweaked_group_key from the output
```
Open a channel using `litcli` (not `lncli`):
```bash
litcli ln fundchannel \
--node_pubkey <peer_pubkey> \
--local_sat_amount 100000 \
--push_sat 0 \
--asset_id <hex_asset_id> \
--asset_amount 10000
```
The `local_sat_amount` is the BTC reserve deposited alongside the asset — the channel requires both a BTC component and the asset component. This BTC functions as the fee buffer for routing and channel closure.
### 2.2 BTC Channel Coexistence
✅ **Yes, TA channels can coexist alongside BTC channels in the same UTXO.** The protocol specifically supports this: "Taproot Assets channels can be created alongside BTC channels in the same UTXO, allowing Taproot Assets to exist in the Lightning Network without consuming additional resources."
A single channel funding transaction can carry both BTC and Taproot Asset commitments. This means no extra on-chain transaction overhead once you are already opening a channel with a peer.
### 2.3 Routing: How TIMMY Payments Route Over Lightning
The RFQ (Request for Quote) protocol, live on mainnet since **v0.6 (June 2025)**, is the routing mechanism:
```
[User: holds TIMMY in TA channel with Timmy node]
│
▼ TA channel
[Timmy Node / Edge Node]
│ RFQ: TIMMY → sats (rate locked, time-limited)
▼ Standard BTC Lightning
[Rest of Lightning Network]
```
**When no direct TIMMY-to-TIMMY route exists (which is almost always the case initially):**
- Edge nodes perform the swap automatically. The edge node holds TIMMY in a private TA channel to the user and BTC channels to the rest of the network.
- The swap is atomic via HTLC. The user's TIMMY is debited, the recipient receives BTC sats (or another TA asset if they also have an edge node).
- **This means TIMMY can pay any standard Lightning invoice**, even nodes that have never heard of Taproot Assets, as long as an edge node is in the path.
**v0.7 improvement:** AddressV2 (static, reusable receive addresses) simplifies the receive side — users don't need to generate a fresh address per invoice.
### 2.4 Current LND v0.20+ TA Channel Status
✅ **Lightning channel support is live on mainnet as of v0.6 (June 2025) / v0.7 (December 2025).**
Production edge nodes confirmed operating as of early 2026: Voltage, Amboss, Joltz, LnFi Network, Speed.
⚠️ **Multi-path sending** (splitting an outbound TIMMY payment across multiple channels) is **not yet implemented** in v0.7. Multi-path receive was added in v0.6 (up to 20 inbound channels). Multi-path send is planned for a future release.
---
## 3. L402 Payment Gate with Taproot Assets
### 3.1 Can Aperture Gate Using TIMMY Tokens?
⚠️ **NOT PRODUCTION-READY.** As of March 2026, Aperture (Lightning Labs' L402 reverse proxy) natively supports **BTC satoshi payments only**. It generates standard BOLT-11 Lightning invoices and validates payment via preimage. There is no built-in Aperture support for Taproot Asset invoices.
**Interim path: build a thin custom L402 layer on top of tapd.**
### 3.2 Custom L402 Implementation for Taproot Asset Payments
The standard L402 flow adapted for TIMMY:
1. Client hits protected endpoint
2. Server generates a tapd TA address (AddressV2) for `N` TIMMY tokens — this is the "invoice"
3. Server returns `HTTP 402` with the TA address and a pending macaroon
4. Client sends TIMMY to the address
5. Server polls tapd for incoming transfer confirmation, then issues the activated macaroon
6. Client includes `Authorization: L402 <macaroon>:<transfer_txid>` on the next request
The key difference from standard L402: Lightning BOLT-11 invoices confirm in 1–3 seconds with an atomic preimage. Taproot Asset on-chain transfers confirm in ~10 minutes (1 block). **For the eval-fee pattern, this means on-chain TA transfers are not usable for real-time gating.** TA Lightning channel payments (off-chain) are the only viable path for sub-second confirmation.
For TA Lightning channel payments, the flow uses `tapcli assets send --addr <ta_address>` or the equivalent gRPC call, which generates an off-chain HTLC that settles in 1–3 seconds, matching standard Lightning behavior.
### 3.3 Macaroon Caveat Encoding for TIMMY vs Sats
Macaroons are issued by your server, not by LND. Add a caveat identifying the payment currency:
1. User calls `POST /session` with desired number of requests (e.g., 10)
2. Server returns a TA address for `N × cost_per_request` TIMMY tokens
3. User pays via TA Lightning channel (off-chain, ~2s)
4. Server confirms payment, issues a macaroon with `max_requests = 10`
5. User submits requests with the macaroon in the `Authorization` header
6. Server decrements a server-side counter per request (the `max_requests` caveat is a hint, server-side tracking is authoritative)
⚠️ The `max_requests` caveat cannot enforce itself — macaroons are bearer tokens, not stateful counters. The server **must** maintain a counter in its database keyed on the payment hash. The caveat is a hint for the client; the server enforces the limit.
---
## 4. FastAPI Integration
### 4.1 Python Path to tapd: gRPC vs REST vs LNbits
| Path | Maturity | When to use |
|------|----------|-------------|
| **gRPC stubs (generated from .proto)** | ✅ Official, documented | Production; full access to all tapd APIs |
| **tapd REST API (port 8089)** | ✅ Works today | Simpler integration; slightly less coverage than gRPC |
| **LNbits Taproot Assets extension** | ⚠️ Community; alpha | Rapid prototyping only; not battle-tested for production |
**Recommendation:** Use the tapd REST API for simplicity during development; migrate to gRPC for production to access features like RFQ negotiation that are gRPC-only.
### 4.2 LNbits Taproot Assets Extension Status (March 2026)
The community extension (`echennells/taproot_assets`) exists and connects LNbits to `litd` via gRPC. It supports asset listing, send/receive, channel viewing, and balance tracking with WebSocket updates. It bundles its own LND and tapd protobuf stubs (`lnd_grpc_files.tar.gz`, `tapd_grpc_files.tar.gz`).
⚠️ **Production status: Alpha/community.** Use it for local development and testing. For a production service handling real funds, wire FastAPI directly to tapd gRPC.
For an application-level balance check (tracking credits against a session), maintain the balance in your own database. tapd does not expose third-party address balances — only your own node's holdings.
---
## 5. Hybrid Architecture: Sats + TIMMY Credits
### 5.1 Why the Hybrid Is Necessary Now
⚠️ **As of March 2026**, the full Taproot Asset Lightning stack requires running `litd` in integrated mode with LND + tapd. This is non-trivial for a solo developer shipping a first version. Additionally, multi-path send is missing, and the alpha warnings are real (see §6).
The practical production path today:
- **Users pay in sats** via standard Lightning (BOLT-11 invoice, LNbits, any wallet)
- **Internal ledger tracks TIMMY credits** in your database
- TIMMY credits are not on-chain tokens yet — they are your application's internal accounting unit
This lets you ship the payment gate today using standard, battle-tested Lightning tooling.
### 5.2 Internal Credit Ledger Model
```sql
-- Minimal schema (SQLite or PostgreSQL)
CREATE TABLE sessions (
id TEXT PRIMARY KEY, -- session UUID
user_id TEXT NOT NULL,
currency TEXT NOT NULL, -- 'sats' or 'TIMMY'
amount_paid INTEGER NOT NULL, -- sats paid or TIMMY credited
timmy_credits INTEGER NOT NULL, -- TIMMY credit balance
- Adjust the rate when relaunching; existing sessions keep their purchased credits
- Risk: if sat/USD moves significantly, the labor price in USD drifts
**Option B: Floating rate (future)**
Derive `SATS_PER_TIMMY` from a price oracle (e.g., CoinGecko USD/BTC feed) to keep TIMMY's labor value stable in USD terms. Implement this only after the fixed-rate model is validated.
### 5.4 Migration Path to Native TA Payments
When you are ready to move from the sats + internal ledger hybrid to native Taproot Asset Lightning payments:
**Phase 1 (current):** Sats in → internal TIMMY credits (database)
**Phase 2 (when TA Lightning is stable for your use case):**
1. Deploy `litd` in integrated mode alongside the FastAPI server
2. Mint the TIMMY token on-chain (§1 above)
3. Keep the internal credit ledger — it becomes a bridge between sats-paying users and token-holding users
4. Add a new endpoint: `POST /redeem` — user sends on-chain TIMMY to your tapd address; server credits their account in the ledger
5. Users who prefer sats continue using the existing flow; no migration required for them
**Phase 3 (full native):**
1. Open TIMMY TA Lightning channels with an edge node (Voltage, Joltz, or LnFi)
2. Accept TIMMY payments directly over Lightning without touching sats
3. Retire the sat-based payment endpoint or keep it as a legacy path
4. The `sessions` table gains a `native_ta` column; macaroons encode `currency = TIMMY` (native) vs `currency = sats` (legacy credit)
The database schema is the same across all phases. The payment confirmation logic changes (LNbits sat invoice → tapd TA transfer), but the session/macaroon layer is untouched.
---
## 6. What Breaks
### 6.1 Known Failure Modes (March 2026)
**⚠️ ALPHA — FUNDS AT RISK**
The official tapd documentation states verbatim: *"there can still be bugs and not all desired data safety and backup mechanisms have been implemented yet."*
| Failure mode | Severity | Detail |
|-------------|----------|--------|
| **Local data loss → asset destruction** | CRITICAL | If the tapd data directory is lost without a proper backup, assets are permanently destroyed. The LND seed phrase alone is NOT sufficient to restore Taproot Assets. `tapd` holds the taproot tweak separately from `lnd`'s key; both are required. |
| **Uninstalling litd without backup** | CRITICAL | Applies to Umbrel and similar node-in-a-box setups. Uninstall deletes application data, destroying assets. |
| **No confidential asset amounts** | HIGH | All asset balances in TA channels are public to channel peers. Planned but not implemented. |
| **No smart contracts** | MEDIUM | TA channels support payments only. No programmable conditions (escrow, time-locks beyond channel mechanics). |
| **Edge node requirement** | MEDIUM | Sending TIMMY to a non-TA Lightning node requires routing through an edge node. If no edge node is in the path, payment fails. With limited edge node availability (Voltage, Joltz, LnFi), routing reliability depends on a small set of operators. |
| **Multi-path send not implemented** | MEDIUM | Large TIMMY sends cannot be split across multiple outbound channels. Only single-path outbound. Multi-path receive works (up to 20 channels). |
| **Forced litd integrated mode** | LOW-MEDIUM | You cannot run tapd as a standalone sidecar next to a pre-existing LND. You must run litd. This is an ops constraint, not a protocol flaw. |
### 6.2 What Is NOT Yet Implemented in tapd (v0.7)
| Feature | Status |
|---------|--------|
| Multi-path sending (outbound) | Planned, not in v0.7 |
| Confidential asset amounts | Planned |
| Full smart contract support | Not planned for TA (protocol constraint) |
| Native Aperture L402 support for TA payments | Not implemented in Aperture |
| Python SDK (official) | Not available — use gRPC stubs or REST |
| tapd standalone mode (without litd) for Lightning channels | Not supported |
### 6.3 Mainnet TA Channels: Production or Testnet?
✅ **Mainnet production as of v0.6 (June 2025).** Confirmed operators: Voltage, Amboss, Joltz, Speed, LnFi Network.
⚠️ The production ecosystem is small. As of March 2026, the Taproot Assets Lightning channel network is real but thin. Routing reliability is lower than the broader BTC Lightning Network. Do not assume your TIMMY payment will route successfully without a direct edge node relationship.
### 6.4 Protocol Evolution Risk
The Lightning Labs team declared **forward compatibility** starting with the v0.3 mainnet alpha (Oct 2023): assets issued on mainnet will not be broken by future protocol versions. The protocol API and message formats, however, are still stabilizing. gRPC stubs generated from v0.7 proto files may need regeneration for v0.8+.
**Mitigation:** Abstract all tapd calls behind a single `TapdService` class. When the proto changes, update the stubs and the service class in one place. The FastAPI routes and business logic remain stable.
---
## Summary: What Works Today vs What to Wait On
| Feature | Today's path | Wait for |
|---------|-------------|----------|
| Mint TIMMY on-chain | ✅ `tapcli assets mint` — single tx, mainnet | — |
| Migration to native TA payments | ✅ Architecture is clear | Multi-path send stabilization |
**Recommended starting point:** Implement the hybrid architecture (§5) using LNbits for sats payments and an internal TIMMY credit ledger. Wire tapd for the on-chain mint only (§1). Add native TA Lightning payments (§2–4) once the edge node ecosystem matures further and you have validated demand.
| TA Lightning channel support live mainnet v0.6 | [Lightning Labs blog — Taproot Assets v0.6](https://lightning.engineering/posts/2025-06-taproot-assets-v0-6/) | Jun 2025 |
| BTC + TA channels in same UTXO | [Taproot Assets Builder's Guide](https://docs.lightning.engineering/lightning-network-tools/taproot-assets) | 2025 |
| Aperture L402 sats-only (no native TA payment support) | [Aperture GitHub](https://github.com/lightninglabs/aperture) — no TA payment backend | Mar 2026 |
| Data loss warning — LND seed insufficient for TA restore | [tapd official docs safety warning](https://docs.lightning.engineering/lightning-network-tools/taproot-assets) | 2025 |
| Multi-path send not implemented in v0.7 | tapd v0.7 release notes / GitHub milestones | Dec 2025 |