feat(plantare): PlantareService — orchestrate the signed handshake
The app-layer driver that turns local intent into a signed proposal, counter-signs or declines incoming ones, and reconciles every move into the local ledger. Cryptography and wire format stay in commons_core; this owns persistence and orchestration. - propose(): builds + self-signs a PlantarePledge, records the local row (remoteState=proposed, my stub) and sends it. Direction maps to debtor/creditor: iReturn = I received and owe, owedToMe = I gave. - accept(): counter-signs the exact in-hand proposal (verified) and sends the doubly-signed copy back, closing the row. - decline(): notifies the proposer and marks the row declined. - ingest(): verifies stubs before storing — a bad-signature proposal or a half-signed "accept" is dropped; proposals not addressed to me are ignored. Pending proposals held in memory keyed by pledge id (relay redelivers on reconnect), so accept signs the verified payload. Wired into DI + Bootstrap alongside the inbox/sync listeners and torn down/rebuilt on identity switch. SocialSession now exposes the transport. Tests: full propose→accept close, decline, and the three drop paths with a records-only transport + real repos. services/data green.
This commit is contained in:
parent
01fba40ec2
commit
b607ddde41
5 changed files with 529 additions and 3 deletions
|
|
@ -16,6 +16,7 @@ import 'services/message_store.dart';
|
|||
import 'services/notification_service.dart';
|
||||
import 'services/offer_outbox.dart';
|
||||
import 'services/onboarding_store.dart';
|
||||
import 'services/plantare_service.dart';
|
||||
import 'services/profile_cache.dart';
|
||||
import 'services/profile_store.dart';
|
||||
import 'services/saved_offers_store.dart';
|
||||
|
|
@ -67,10 +68,14 @@ class _BootstrapState extends State<Bootstrap> {
|
|||
if (notifications != null) await notifications.initialize();
|
||||
final sync =
|
||||
getIt.isRegistered<SyncService>() ? getIt<SyncService>() : null;
|
||||
// Subscribe the inbox + sync listeners BEFORE the shared connection starts
|
||||
// connecting, so the first session is caught; then bring the connection up.
|
||||
final plantares =
|
||||
getIt.isRegistered<PlantareService>() ? getIt<PlantareService>() : null;
|
||||
// Subscribe the inbox + sync + plantaré listeners BEFORE the shared
|
||||
// connection starts connecting, so the first session is caught; then bring
|
||||
// the connection up.
|
||||
inbox?.start();
|
||||
sync?.start();
|
||||
plantares?.start();
|
||||
connection?.start();
|
||||
|
||||
return TaneApp(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue