state — shychat
Package shychat implements the shychat-v1 ABCI state machine.
Import path: github.com/NickCarducci/Shyware-SDK/domain/state/shychat
Architecture
ChatState embeds submission.TwoListBase for the two-list invariant and adds shychat-specific domain state: mailbox metadata and delivery records.
List 1 (messages): "mailboxID:messageID" → sealed message payload ciphertext. No identity.
List 2 (senders): "mailboxID:identityHash" → sender identity. No payload.
messageID = H(messageNonce) is random and shares no derivation path with identityHash.
Initialization
state, err := shychat.NewChatState(ctx, db, kmsKeyID, logger)
state.SetIdentityVerifier(v)
Lifecycle
| Step | Tx type constant | Function |
|---|---|---|
| Create a mailbox | ChatTxTypeMailboxCreate = 1 | executeMailboxCreate |
| Dispatch a message | ChatTxTypeMessageDispatch = 2 | executeMessageDispatch |
| Close a mailbox | ChatTxTypeMailboxClose = 3 | executeMailboxClose |
| Update a message | ChatTxTypeMessageUpdate = 4 | executeMessageUpdate |
| Withdraw a message | ChatTxTypeMessageWithdraw = 5 | executeMessageWithdraw |
| Register validator | ChatTxTypeRegisterValidator = 6 | executeRegisterValidator |
Mailbox management
rec := state.GetMailbox(mailboxID) // → *MailboxRecord
del := state.GetDelivery(mailboxID) // → *DeliveryRecord
MailboxRecord carries messaging semantics (SurfaceModel, Label, Address). DeliveryRecord is the per-mailbox closure record committed alongside TwoListBase.ClosureRecord at MailboxClose.
Message withdrawal
MessageWithdraw is the bilateral withdrawal analogue: both the List 1 message entry and the List 2 identity entry are removed atomically. |L1| and |L2| both decrease by one; count-match is preserved. The sender's identityHash is no longer in List 2 after withdrawal — they may re-dispatch using a new keypair and new message nonce.
Surface models
SurfaceModel ("mail" | "chat") governs client UI affordance only. The protocol and ABCI state machine are identical for both. shyrest-v1 deploys shychat with surface_model: "mail" for informant intake.
Count-match and closure
MailboxClose calls TwoListBase.ClosePeriod: enforces |L1| == |L2|, computes disjoint Merkle roots over message IDs (List 1) and identity hashes (List 2), requests KMS signature, commits ClosureRecord + DeliveryRecord.