Kontext & Ziel
Umsetzung von Phase 2 des RealUnit-App-Vertrags. Phase 2 umfasst laut Vertrag:
- Zahlung in 2 Schritten — (a) Trade RealUnit → ZCHF, (b) Payfunktion via QR an POS-Terminals, über Open CryptoPay (OCP) Standorte inkl. SPAR-Filialen.
- Transfer via QR zwischen RealUnit-App-Nutzern (Wallet-zu-Wallet).
- Autoinvest / Sparplan — automatische wiederkehrende RealUnit-Käufe.
Wichtige Klarstellung (Scope-Abgrenzung): Der Trade RealU → ZCHF ist kein neues Feature — die RealUnit-App macht diese Konvertierung bereits heute als Teil des Verkaufs-Flows (REALU → Brokerbot → ZCHF). Neu an Phase 2 ist allein die Kombination mit OCP: das ZCHF nicht zur DFX-Deposit-Adresse für eine Fiat-Auszahlung zu schicken, sondern es zu nutzen, um damit an einer OCP-Kasse zu bezahlen. Der Pay-Flow (Baustein 1+2) ist der Hauptbrocken; Transfer (2) und Autoinvest (3) sind separate, kleinere Bausteine.
⚠️ Dieses Issue startet NICHT mit Implementierung. Schritt 0 ist eine vollständige, tiefe Analyse der drei beteiligten Repos. Erst danach wird der genaue Implementierungsweg festgelegt (als Folge-Spec / Sub-Issues). Nicht vorher mit Code beginnen.
Beteiligte Repositories
| Repo |
Rolle |
| openCryptoPay/landingPage |
Der OCP-Standard selbst (README = maßgebliche Spec). Definiert den QR-/LNURL-Flow, den eine zahlende Wallet implementieren muss. Permissionless, nicht DFX-gebunden. |
| dfxswiss/api |
Das Backend. Enthält bereits (a) das vollständige OCP/payment-link-Modul (src/subdomains/core/payment-link/, /v1/lnurlp/...) und (b) die RealUnit-Endpoints inkl. der REALU→ZCHF-Swap-Mechanik (src/subdomains/supporting/realunit/). Beide sind heute nicht miteinander verdrahtet. |
| RealUnitCH/app |
Die Wallet-App (Flutter). Muss den OCP-LNURL-pay-Client + QR-Scanner + den 2-Schritt-Pay-Flow bekommen; plus Send-Flow (Baustein 2) und Sparplan-Setup (Baustein 3). |
Schritt 0 — Pflicht-Tiefenanalyse (vor jeder Implementierung)
Ziel: nach dieser Analyse ist der Implementierungsweg eindeutig. Pro Repo zu beantworten:
A. openCryptoPay/landingPage (der Standard)
- Den kompletten Wallet-Integrations-Flow durcharbeiten (4 Schritte: QR decodieren → Payment Details → Transaction Details → Transaktion ausführen; plus „simplified flow").
- Genau festhalten: Wie wird der EVM-Zahlungspfad ausgeführt? (Transaction-Details liefert
uri ethereum:0x…@chainId?value=… + den Hinweis, die signierte Tx als HEX an …/v1/lnurlp/tx/plp_… zurückzusenden, DFX broadcastet.) Für ERC-20 (ZCHF) statt nativem ETH: wie sieht die uri / der erwartete Tx-Aufbau aus?
- Quote-Ablauf/Expiry,
timeout-Param, 404-Verhalten („no pending payment"), requestedAmount vs transferAmounts.
B. dfxswiss/api (Backend)
- payment-link/lnurlp-Modul vollständig lesen:
forwarding/lnurlp-forward.controller.ts (GET /v1/lnurlp/:id, GET /v1/lnurlp/cb/:id, POST/… /v1/lnurlp/tx/:id, wait, cancel), payment-link/ Services/DTOs. Welche Felder, welche Auth (öffentlich?), welche Chains/Assets unterstützt.
- Bestätigen, dass ZCHF (Ethereum) ein gültiges OCP-Zahl-Asset ist (README-
transferAmounts listet es) und wie die EVM-Payment-Antwort für ZCHF konkret aussieht.
- RealUnit-Swap-Pfad:
realunit.service.ts createSellUnsignedTransactions / confirmSell — wie genau entsteht ZCHF, und wohin fliesst es heute (→ DFX-Deposit). Was wäre nötig, damit ZCHF im User-Wallet bleibt? Gibt es dafür schon einen Endpoint oder muss einer her?
- Klären, ob backend-seitig überhaupt etwas Neues nötig ist, oder ob die App den bestehenden
/v1/lnurlp/*-Flow direkt nutzen kann (mit ZCHF, das sie selbst hält).
- Für Baustein 2 (Transfer) und 3 (Autoinvest): gibt es generische DFX-Bausteine (recurring buy / savings-plan / wallet-transfer), die wiederverwendet werden können? (Heutiger Stand: nicht gefunden.)
C. RealUnitCH/app (Wallet)
- Bestehenden REALU→ZCHF-Verkaufs-Flow lesen (
lib/screens/sell*, real_unit_buy_payment_info_service.dart-Pendant für Sell, Cubits) — was davon ist für den Pay-Flow wiederverwendbar.
- EVM-Signing-Fähigkeit der Wallet (WDK / Signing-Pipeline): Kann sie eine ZCHF-ERC-20-transfer-Tx bauen + signieren + als HEX exportieren (für den DFX-broadcast-Weg)? Hält die App ZCHF überhaupt als Asset (
zchfAssetId existiert)?
- QR-Scanner: Gibt es schon eine Kamera-/QR-Scan-Fähigkeit? (Bisher nur QR-Anzeige in
receive/Payment-Info.) Falls nein → neue Dependency/Permission.
- Wie fügt sich ein „Bezahlen"-Einstieg in die bestehende Dashboard-/Navigations-Struktur (
AppRoutes) ein.
Bekannter Ist-Stand (heutige Voruntersuchung — als Startpunkt, nicht abschliessend)
| Baustein |
App |
dfxswiss/api |
| 1+2. Pay via OCP (RU→ZCHF→OCP) |
🔴 kein Pay/QR-Scan/OCP; RU→ZCHF nur im Verkauf |
🟡 OCP-Modul reif & produktiv (SPAR live), aber RealUnit-entkoppelt; REALU→ZCHF-Swap vorhanden, aber ZCHF geht zur Fiat-Deposit-Adresse |
| 3. Transfer RU↔RU |
🔴 nur receive, kein send (Phase-1 schliesst Transfers als Non-Action aus) |
🔴 fehlt |
| 4. Autoinvest/Sparplan |
🔴 nur Historie-Anzeige (savingsAdd/Remove) |
🔴 fehlt (savings in der API = DeFi-Yield dEURO/Juice, anderes Konzept) |
OCP-Wallet-Flow (aus dem Standard — Implementierungs-Kern für den Pay-Teil)
- QR decodieren: Kassen-QR =
https://app.dfx.swiss/pl/?lightning=LNURL1…. Den lightning-Parameter per LUD-01 (bech32) decodieren → API-URL https://api.dfx.swiss/v1/lnurlp/pl_… (alternativ simpel: app→api im URL ersetzen).
- Payment Details:
GET /v1/lnurlp/pl_… → JSON mit recipient, quote {id, expiration, payment}, requestedAmount {asset:"CHF", amount}, transferAmounts[]. Letzteres listet pro method (Chain) die zahlbaren assets. Ethereum-Methode enthält ZCHF → das ist unser Zahl-Asset.
- Transaction Details: Methode+Asset wählen (
method=Ethereum, asset=ZCHF) + quote.id → GET {callback}?quote=…&method=Ethereum&asset=ZCHF → liefert für EVM { blockchain, uri: "ethereum:0x…@1?value=…", hint }.
- Ausführen: ZCHF-ERC-20-transfer-Tx an die Recipient-Adresse bauen + signieren, signierte Tx als HEX an
POST /v1/lnurlp/tx/plp_… senden (DFX broadcastet). Status via GET /v1/lnurlp/wait/:id, Abbruch via DELETE /v1/lnurlp/cancel/:id.
Der vertragliche 2-Schritt-Flow konkret: Betrag der OCP-Zahlung in ZCHF aus dem Quote ablesen → genau so viel (+Puffer/Fee) RealU → ZCHF traden, ZCHF im Wallet behalten → ZCHF-Transfer-Tx an die OCP-Recipient-Adresse signieren + an DFX zurückgeben. Die Analyse muss die Orchestrierung (Reihenfolge, Quote-Expiry vs. Swap-Dauer, Slippage/Fee-Puffer, Fehlerfälle wenn ZCHF nach Swap nicht reicht) sauber klären.
Offene Fragen, die die Analyse beantworten muss (NICHT vorab entscheiden)
- Bleibt ZCHF nach dem Swap praktikabel im User-Wallet, oder braucht es einen neuen API-Endpoint / einen anderen Swap-Pfad?
- Reicht der bestehende
/v1/lnurlp/*-Flow für die App, oder muss api etwas RealUnit-spezifisches ergänzen?
- Wie wird mit der Quote-Expiry umgegangen, wenn zwischen Swap (Schritt 1) und Zahlung (Schritt 2) Zeit vergeht?
- QR-Scanner: neue Dependency + Kamera-Permission (iOS/Android Store-Implikationen)?
- Transfer RU↔RU (Baustein 2): hebt eine Phase-1-Non-Action auf — eigener Send-Flow + Backend; ist das wirklich Token-Transfer on-chain oder via OCP-„Pay an andere Wallet"?
- Autoinvest (Baustein 3): client-seitiger Scheduler vs. server-seitiger recurring-buy — Architekturentscheidung mit KYC-/Zahlungs-Implikationen.
Deliverable von Schritt 0
Ein konkreter, abgestimmter Implementierungsplan (gerne als Folge-Issues pro Baustein), der auf der Analyse fusst — inkl. klarer Aufteilung, welche Änderung in welches der drei Repos gehört, und welche Reihenfolge. Erst dann Implementierung starten.
Workflow
- Analyse-Ergebnis + Plan hier im Issue (oder verlinkten Sub-Issues) dokumentieren, bevor Code entsteht.
- Implementierung später:
RealUnitCH/app → Feature-Branch → PR gegen staging (Draft); dfxswiss/api → Feature-Branch → PR gegen develop (Draft). 3-Subagent-Review. DEV/PRD-Parität beachten.
Kontext & Ziel
Umsetzung von Phase 2 des RealUnit-App-Vertrags. Phase 2 umfasst laut Vertrag:
Wichtige Klarstellung (Scope-Abgrenzung): Der Trade RealU → ZCHF ist kein neues Feature — die RealUnit-App macht diese Konvertierung bereits heute als Teil des Verkaufs-Flows (REALU → Brokerbot → ZCHF). Neu an Phase 2 ist allein die Kombination mit OCP: das ZCHF nicht zur DFX-Deposit-Adresse für eine Fiat-Auszahlung zu schicken, sondern es zu nutzen, um damit an einer OCP-Kasse zu bezahlen. Der Pay-Flow (Baustein 1+2) ist der Hauptbrocken; Transfer (2) und Autoinvest (3) sind separate, kleinere Bausteine.
Beteiligte Repositories
src/subdomains/core/payment-link/,/v1/lnurlp/...) und (b) die RealUnit-Endpoints inkl. der REALU→ZCHF-Swap-Mechanik (src/subdomains/supporting/realunit/). Beide sind heute nicht miteinander verdrahtet.Schritt 0 — Pflicht-Tiefenanalyse (vor jeder Implementierung)
Ziel: nach dieser Analyse ist der Implementierungsweg eindeutig. Pro Repo zu beantworten:
A. openCryptoPay/landingPage (der Standard)
uriethereum:0x…@chainId?value=…+ den Hinweis, die signierte Tx als HEX an…/v1/lnurlp/tx/plp_…zurückzusenden, DFX broadcastet.) Für ERC-20 (ZCHF) statt nativem ETH: wie sieht dieuri/ der erwartete Tx-Aufbau aus?timeout-Param, 404-Verhalten („no pending payment"),requestedAmountvstransferAmounts.B. dfxswiss/api (Backend)
forwarding/lnurlp-forward.controller.ts(GET /v1/lnurlp/:id,GET /v1/lnurlp/cb/:id,POST/… /v1/lnurlp/tx/:id,wait,cancel),payment-link/Services/DTOs. Welche Felder, welche Auth (öffentlich?), welche Chains/Assets unterstützt.transferAmountslistet es) und wie die EVM-Payment-Antwort für ZCHF konkret aussieht.realunit.service.tscreateSellUnsignedTransactions/confirmSell— wie genau entsteht ZCHF, und wohin fliesst es heute (→ DFX-Deposit). Was wäre nötig, damit ZCHF im User-Wallet bleibt? Gibt es dafür schon einen Endpoint oder muss einer her?/v1/lnurlp/*-Flow direkt nutzen kann (mit ZCHF, das sie selbst hält).C. RealUnitCH/app (Wallet)
lib/screens/sell*,real_unit_buy_payment_info_service.dart-Pendant für Sell, Cubits) — was davon ist für den Pay-Flow wiederverwendbar.zchfAssetIdexistiert)?receive/Payment-Info.) Falls nein → neue Dependency/Permission.AppRoutes) ein.Bekannter Ist-Stand (heutige Voruntersuchung — als Startpunkt, nicht abschliessend)
receive, keinsend(Phase-1 schliesst Transfers als Non-Action aus)savingsAdd/Remove)savingsin der API = DeFi-Yield dEURO/Juice, anderes Konzept)OCP-Wallet-Flow (aus dem Standard — Implementierungs-Kern für den Pay-Teil)
https://app.dfx.swiss/pl/?lightning=LNURL1…. Denlightning-Parameter per LUD-01 (bech32) decodieren → API-URLhttps://api.dfx.swiss/v1/lnurlp/pl_…(alternativ simpel:app→apiim URL ersetzen).GET /v1/lnurlp/pl_…→ JSON mitrecipient,quote {id, expiration, payment},requestedAmount {asset:"CHF", amount},transferAmounts[]. Letzteres listet promethod(Chain) die zahlbarenassets. Ethereum-Methode enthältZCHF→ das ist unser Zahl-Asset.method=Ethereum,asset=ZCHF) +quote.id→GET {callback}?quote=…&method=Ethereum&asset=ZCHF→ liefert für EVM{ blockchain, uri: "ethereum:0x…@1?value=…", hint }.POST /v1/lnurlp/tx/plp_…senden (DFX broadcastet). Status viaGET /v1/lnurlp/wait/:id, Abbruch viaDELETE /v1/lnurlp/cancel/:id.Der vertragliche 2-Schritt-Flow konkret: Betrag der OCP-Zahlung in ZCHF aus dem Quote ablesen → genau so viel (+Puffer/Fee) RealU → ZCHF traden, ZCHF im Wallet behalten → ZCHF-Transfer-Tx an die OCP-Recipient-Adresse signieren + an DFX zurückgeben. Die Analyse muss die Orchestrierung (Reihenfolge, Quote-Expiry vs. Swap-Dauer, Slippage/Fee-Puffer, Fehlerfälle wenn ZCHF nach Swap nicht reicht) sauber klären.
Offene Fragen, die die Analyse beantworten muss (NICHT vorab entscheiden)
/v1/lnurlp/*-Flow für die App, oder muss api etwas RealUnit-spezifisches ergänzen?Deliverable von Schritt 0
Ein konkreter, abgestimmter Implementierungsplan (gerne als Folge-Issues pro Baustein), der auf der Analyse fusst — inkl. klarer Aufteilung, welche Änderung in welches der drei Repos gehört, und welche Reihenfolge. Erst dann Implementierung starten.
Workflow
RealUnitCH/app→ Feature-Branch → PR gegenstaging(Draft);dfxswiss/api→ Feature-Branch → PR gegendevelop(Draft). 3-Subagent-Review. DEV/PRD-Parität beachten.