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
bec0f78fa1
commit
2e25e34d11
5 changed files with 529 additions and 3 deletions
|
|
@ -37,6 +37,7 @@ import '../services/recovery_sheet_service.dart';
|
|||
import '../services/share_catalog_service.dart';
|
||||
import '../services/message_store.dart';
|
||||
import '../services/offer_outbox.dart';
|
||||
import '../services/plantare_service.dart';
|
||||
import '../services/profile_cache.dart';
|
||||
import '../services/profile_store.dart';
|
||||
import '../services/saved_offers_store.dart';
|
||||
|
|
@ -261,6 +262,17 @@ Future<void> configureDependencies() async {
|
|||
localChanges: database.tableUpdates().map<void>((_) {}),
|
||||
selfDeviceId: deviceId,
|
||||
),
|
||||
)
|
||||
// Drives the bilateral signed Plantaré handshake over the shared
|
||||
// connection, reconciling moves into the local ledger. Started in
|
||||
// `Bootstrap`.
|
||||
..registerSingleton<PlantareService>(
|
||||
PlantareService(
|
||||
repo: varietyRepository,
|
||||
selfPubkey: socialService.publicKeyHex,
|
||||
selfSecretKey: socialService.identity.privateKeyHex,
|
||||
connection: connection,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -293,6 +305,10 @@ Future<void> switchSocialAccount(int account) async {
|
|||
await getIt<InboxService>().stop();
|
||||
await getIt.unregister<InboxService>();
|
||||
}
|
||||
if (getIt.isRegistered<PlantareService>()) {
|
||||
await getIt<PlantareService>().stop();
|
||||
await getIt.unregister<PlantareService>();
|
||||
}
|
||||
if (getIt.isRegistered<SocialConnection>()) {
|
||||
await getIt<SocialConnection>().dispose();
|
||||
await getIt.unregister<SocialConnection>();
|
||||
|
|
@ -351,14 +367,22 @@ Future<void> switchSocialAccount(int account) async {
|
|||
localChanges: getIt<AppDatabase>().tableUpdates().map<void>((_) {}),
|
||||
selfDeviceId: deviceId,
|
||||
);
|
||||
final plantares = PlantareService(
|
||||
repo: getIt<VarietyRepository>(),
|
||||
selfPubkey: social.publicKeyHex,
|
||||
selfSecretKey: social.identity.privateKeyHex,
|
||||
connection: connection,
|
||||
);
|
||||
getIt
|
||||
..registerSingleton<SocialService>(social)
|
||||
..registerSingleton<SocialConnection>(connection)
|
||||
..registerSingleton<InboxService>(inbox)
|
||||
..registerSingleton<SyncService>(sync);
|
||||
..registerSingleton<SyncService>(sync)
|
||||
..registerSingleton<PlantareService>(plantares);
|
||||
// Subscribe the listeners BEFORE the connection starts connecting.
|
||||
inbox.start();
|
||||
sync.start();
|
||||
plantares.start();
|
||||
connection.start();
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue