// .NET 8+. Paired scaffold; no networking or fabricated SDK. // beginVerified owns an atomic transaction including verification, authority, // state, challenge consumption and signed receipt. Dispose rolls back otherwise. using System; namespace BringPass.Draft; public enum Op { REGISTER, USE, REVOKE, RETRACT } public sealed record Envelope(string[] Fields, string Signature); public sealed record Result(Envelope Receipt, bool Fresh); public interface ITransaction : IDisposable { Op Operation { get; } Envelope? Cached(); void RegisterNewKey(); void RequireCurrentEntitlement(); void RevokeTarget(); void RetractRelationship(); Envelope SignResult(); void CommitOnce(Envelope result); } public interface IPorts { Envelope Challenge(Op op, string rid, string target, string trustedContext); void VerifyProviderAndApprove(Envelope challenge); Envelope SignProof(Envelope challenge); void VerifyResultAndApply(Envelope result); ITransaction BeginVerified(Envelope proof, string trustedContext); Envelope RecoverRevoke(string rid, string target, string trustedContext); } public sealed class TokenSide(IPorts ports) { public Envelope Respond(Envelope challenge) { ports.VerifyProviderAndApprove(challenge); return ports.SignProof(challenge); } public void Accept(Envelope result) => ports.VerifyResultAndApply(result); } public sealed class ProviderSide(IPorts ports) { public Envelope Start(Op op, string rid, string target, string context) => ports.Challenge(op, rid, target, context); public Result Finish(Envelope proof, string trustedContext) { using var tx = ports.BeginVerified(proof, trustedContext); var cached = tx.Cached(); if (cached is not null) return new(cached, false); switch (tx.Operation) { case Op.REGISTER: tx.RegisterNewKey(); break; case Op.USE: tx.RequireCurrentEntitlement(); break; case Op.REVOKE: tx.RevokeTarget(); break; case Op.RETRACT: tx.RetractRelationship(); break; default: throw new InvalidOperationException("Unsupported operation"); } var result = tx.SignResult(); tx.CommitOnce(result); return new(result, true); } public Envelope Lost(string rid, string target, string context) => ports.RecoverRevoke(rid, target, context); } public static class Legacy { public static string Present(string value, bool approved, bool selected) { if (!approved || !selected || String.IsNullOrEmpty(value)) throw new InvalidOperationException("Local approval/selection required"); return value; // Only input to the approved renderer or existing NFC driver. } }