Uhpenry
Uhpenry Concepts

Snapcharge

The definitive guide to Snapcharge what it is, what it stores, how verification works, lifecycle/state machine, and developer patterns.

A Snapcharge is an append‑only transactional event inside a Snapgate. It captures:

  • the commercial outcome (paid/free/unpaid/canceled/refund),
  • the exact project state at that moment (repository structure, commit/tag, terms, policies, price), and
  • a pair of cryptographic proofs (integrity + signer) that make the record tamper‑evident.

Think of a Snapcharge as a time capsule for a project version as delivered to a specific user through a specific Snapgate.

Snapcharges are the only way a Snapshot's history grows; every access claim (initial purchase, upgrades, free updates, enforcement changes, refunds) is recorded as a new Snapcharge.


Core Responsibilities

  1. Record Access Event Log whether access was download/invite, one‑time/subscription, and whether delivery finalized.
  2. Preserve State Freeze the project's structure, license, policies, and price as they existed at the time of the event.
  3. Verify Integrity Attach verifications so anyone can independently check that the record has not been altered.
  4. Link the Chain Tie the event to its Snapgate, Booth, Project, and Snapshot identifiers for audit and traversal.

Lifecycle & State Machine

A Snapcharge is created at initiation (when the user claims/starts an access event) and finalized when the outcome is known. Some events are free and finalize instantly; others involve a payment provider.

Loading diagram...

Timestamps (typical):

  • initializeAt when initiation started.
  • completedAt when the commercial outcome finalized.
  • SnapshotstartAt/snapshotCompletedAt window for writing to the Snapshot container.
  • snapshotCreatedAt when the first Snapshot entry for this charge was created.
  • snapshotExpireAt optional TTL for time‑boxed claims (e.g., invitation windows).

Data Model (Developer Reference)

Field names mirror the current schema; groupings are for explanation.

Identity & Linking

  • code: string unique idempotency key for the Snapcharge.
  • isPrimary: boolean primary charge for a flow (e.g., first delivery in a bundle).
  • userId: Id<'users'>, boothId: Id<'booths'>, SnapgateId: Id<'Snapgates'> foreign keys.
  • type: 'projects' | 'applications' | 'solutions' entity class.
  • access: 'download' | 'invite' access modality delivered.

Commercials & Payment

  • type: 'perpetual' | 'subscription'
  • amount: number amount paid (post‑discount, pre‑fees as defined by platform).
  • originalAmount: number list price at the time.
  • applicationPercentage: number booth/owner share percentage.
  • netAmount: number, stripeFee: number, applicationFee: number
  • exchangeRate?: number when currency conversion is involved.
  • couponCode?: string
  • paymentIntentId?: string gateway identifier (e.g., Stripe PI).
  • hasAnyRefunds?: boolean, refunds?: Refund[]

Status & Control

  • status: 'paid' | 'free' | 'unpaid' | 'processing' | 'canceled'
  • isSuccess: boolean true when the commercial outcome grants entitlement (paid/free).
  • isCompleted: boolean terminal state reached.
  • isLocked: boolean access locked due to enforcement.
  • schedule?: { isActive: boolean; isDone: boolean } background jobs.

Version & Project State (Frozen)

  • commit?: Commit commit or tag resolved at fulfillment.
  • structure: string serialized repository structure for deterministic replay.
  • termsAndConditions: string, refundPolicy: string, refundConditions: string[], disputePeriod: number, acceptsRefunds: 'yes' | 'no'
  • gitUsername?: string for invite access.
  • metadata?: Record<string, any> caller-supplied annotations.

Snapshot Linkage

  • snapshot: string serialized snapshot view at write time (audit cache).
  • snapshotCreatedAt: number, SnapshotstartAt: number, snapshotExpireAt: number, snapshotCompletedAt?: number

Verification (Tamper‑evident)

  • verifications?: Verification[] where each entry:
    • reason: 'initial' | 'final' | 'update' | 'refund'
    • createdAt: number
    • integrity: { hash: string; token: string; kid: string }
    • signer: { hash: string; token: string; kid: string }

Note: The Snapcharge stores the project's state snapshot, not pointers to mutable rows. This ensures point‑in‑time reconstruction even if the live project changes later.


What Exactly Is Signed?

To avoid circularity, verification runs over the canonical Snapcharge payload with the following rules:

  • Included: all business‑meaningful fields that describe the event: identity/linking, commercials, status, version & project state, snapshot linkage, timestamps, schedule flags, and metadata.
  • Excluded: the verifications[] array itself and any volatile transport headers.

Deterministic serialization:

  • Objects are serialized with stable key ordering (UTF‑8, \n newlines),
  • Numbers encoded as canonical JSON numbers (no trailing zeros),
  • null omitted unless semantically required,
  • Arrays preserved in order.

The resulting bytes are hashed to produce integrity.hash, and a JWT containing that hash is signed with the private key designated by integrity.kidintegrity.token.

Then the signer layer hashes { integrity.hash, integrity.kid, integrity.token }signer.hash, and signs that with its private key (signer.kid) → signer.token.

This two‑layer (circular) scheme ensures that if either token or hash were altered, validation fails.


Verification Procedure (High‑level)

  1. Parse the Snapcharge JSON from the Snapshot's Snapcharges[] cache.
  2. Canonicalize it (apply deterministic serialization rules) excluding verifications.
  3. Hash → compare with integrity.hash.
  4. Verify JWT integrity.token using the published public key for integrity.kid.
  5. Hash signer input { integrity.hash, integrity.kid, integrity.token } → compare with signer.hash.
  6. Verify JWT signer.token with the public key for signer.kid.
  7. Repeat for each verifications[] record; check that a terminal record exists for terminal statuses (paid/free/canceled/refund).

See Public Verification for full details on key distribution, JWT formats, and validation logic.


Example (Annotated)

{
  ...

  "commit": { "type": "tag", "value": "v1.2.0" },
  "structure": "{\n  \"/\": { \"type\": \"dir\", \"children\": [ ... ] }\n}",
  "termsAndConditions": "No redistribution. Single-seat license.",
  "refundPolicy": "7-day refund for technical issues.",
  "refundConditions": ["Not compatible with Node <18"],
  ...

  "disputePeriod": 14,
  "acceptsRefunds": "yes",

  "SnapshotstartAt": 1755139207,
  "snapshotCreatedAt": 1755139208,
  "snapshotCompletedAt": 1755139208,
  "snapshotExpireAt": 0,

  "paymentIntentId": "pi_3P...",
  ...

  "verifications": [
    {
      "reason": "final",
      "createdAt": 1755139208,
      "integrity": {
        "hash": "d1c6...",
        "token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6\n...",
        "kid": "uhp-integrity-20250809.public.json"
      },
      "signer": {
        "hash": "a04e...",
        "token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6\n...",
        "kid": "uhp-signer-20250809.public.json"
      }
    }
  ]
}

Interactions with Snapgate & Snapshot

  • Snapgate creates the context (user↔project access) and enforces policy (revoke/suspend). Snapcharge records the effect of those actions.
  • Snapshot is the container that aggregates serialized Snapcharges and the serialized Snapgate for durable audit and reconstruction.

Rule of thumb: Snapgate decides, Snapcharge records, Snapshot preserves.


Refunds & Disputes

Refunds are represented as:

  • A Snapcharge in terminal paid/free state with hasAnyRefunds = true plus
  • A follow‑up Snapcharge (or verification entry with reason = 'refund') that captures the refund details and updated net amounts.

Disputes (chargebacks) must not mutate past entries; they are captured as new events and reflected in the Snapshot.


Enforcement & Locking

When policy is violated (e.g., redistribution, account sharing):

  • The Snapgate is updated (revoke/suspend/lock).
  • A new Snapcharge captures the enforcement outcome (isLocked = true, policy references). Past Snapcharges remain intact.

Mini Flow Diagram

Loading diagram...

Snapcharge is the foundational audit and transactional unit within Uhpenry's ecosystem. By recording every access event in an append-only, tamper-evident format, Snapcharges ensure that project state, commercial outcomes, and enforcement actions are fully auditable, verifiable, and reconstructible.

Together with Snapgate (which enforces access policy) and Snapshot (which preserves serialized history), Snapcharge provides a secure, transparent, and immutable ledger of all interactions with a project. This design guarantees that every payment, download, invite, refund, and enforcement action can be independently verified, supporting accountability, dispute resolution, and long-term archival without relying on mutable databases.

In essence, Snapcharge ensures that every project interaction is trustworthy, traceable, and tamper-proof, forming the backbone of Uhpenry's secure distribution and collaboration model.

Note: This guide is living documentation. We welcome contributions and corrections via GitHub or support@uhpenry.com.