{
  "$schema": "./state-catalog.schema.json",
  "catalog": {
    "id": "finality-ux-kit-core",
    "version": "1.0.0",
    "title": "Finality UX Kit — Core states",
    "updatedAt": "2026-08-21",
    "language": "en",
    "stateCount": 8,
    "pricing": {
      "personal": "39 USDC",
      "team": "119 USDC"
    },
    "licenses": {
      "design": "CC BY 4.0",
      "code": "MIT"
    }
  },
  "states": [
    {
      "order": 1,
      "id": "wallet.disconnected",
      "family": "wallet",
      "tone": "neutral",
      "icon": "wallet",
      "eyebrow": "Before the request",
      "title": "Connect a wallet you trust",
      "body": "No wallet is connected. Choose one to review this action; connecting does not approve or submit anything.",
      "status": "Not connected",
      "primaryAction": "Choose wallet",
      "secondaryAction": "Why connect?",
      "recovery": "Check the site address before selecting a wallet.",
      "safetyNote": "Never enter a seed phrase on this screen.",
      "live": "off",
      "figmaVariant": "State=Disconnected,Tone=Neutral",
      "reactVariant": "disconnected",
      "transitions": [
        {
          "event": "wallet_connected",
          "label": "Wallet connected",
          "target": "external:next-request"
        }
      ]
    },
    {
      "order": 2,
      "id": "network.unsupported",
      "family": "network",
      "tone": "warning",
      "icon": "network",
      "eyebrow": "Network check",
      "title": "Switch to Base to continue",
      "body": "This action is prepared for Base, but your wallet is connected to Ethereum. Review the network change in your wallet.",
      "status": "Wrong network",
      "primaryAction": "Switch network",
      "secondaryAction": "Cancel action",
      "recovery": "If Base is unexpected, cancel and verify the original link.",
      "safetyNote": "A network switch does not authorize a transaction.",
      "live": "polite",
      "figmaVariant": "State=Unsupported network,Tone=Warning",
      "reactVariant": "unsupported-network",
      "transitions": [
        {
          "event": "network_changed",
          "label": "Expected network selected",
          "target": "external:retry-intent"
        },
        {
          "event": "cancelled",
          "label": "Action cancelled",
          "target": "external:idle"
        }
      ]
    },
    {
      "order": 3,
      "id": "signature.requested",
      "family": "signature",
      "tone": "attention",
      "icon": "signature",
      "eyebrow": "Wallet action",
      "title": "Review the signature request",
      "body": "Your wallet has the final request. Match the site, action, and displayed details before you sign.",
      "status": "Waiting for signature",
      "primaryAction": "Open wallet",
      "secondaryAction": "Cancel request",
      "recovery": "If the wallet details differ from this screen, reject the request.",
      "safetyNote": "A signature can authorize actions even when no network fee is shown.",
      "live": "polite",
      "figmaVariant": "State=Signature requested,Tone=Attention",
      "reactVariant": "signature-requested",
      "transitions": [
        {
          "event": "signature_approved",
          "label": "Signature approved",
          "target": "transaction.pending"
        },
        {
          "event": "signature_rejected",
          "label": "Signature rejected",
          "target": "signature.rejected"
        }
      ]
    },
    {
      "order": 4,
      "id": "signature.rejected",
      "family": "signature",
      "tone": "neutral",
      "icon": "close",
      "eyebrow": "Request ended",
      "title": "You rejected the request",
      "body": "Nothing was signed or submitted. You can close this action or review the details and start again.",
      "status": "Not submitted",
      "primaryAction": "Review and retry",
      "secondaryAction": "Close",
      "recovery": "A fresh request should show the same site, action, and amount.",
      "safetyNote": "Repeated prompts can be a warning sign; pause if you did not retry.",
      "live": "polite",
      "figmaVariant": "State=Signature rejected,Tone=Neutral",
      "reactVariant": "signature-rejected",
      "transitions": [
        {
          "event": "retry",
          "label": "Fresh request created",
          "target": "signature.requested"
        },
        {
          "event": "dismissed",
          "label": "Flow closed",
          "target": "external:idle"
        }
      ]
    },
    {
      "order": 5,
      "id": "approval.requested",
      "family": "approval",
      "tone": "warning",
      "icon": "shield",
      "eyebrow": "Permission request",
      "title": "Review the 250 USDC spending cap",
      "body": "This permission lets the app use up to 250 USDC. It is not the transfer itself and remains active until used or revoked.",
      "status": "Approval required",
      "primaryAction": "Review permission",
      "secondaryAction": "Use a lower cap",
      "recovery": "Prefer the smallest cap and duration that complete the intended action.",
      "safetyNote": "Unlimited approvals increase the impact of a compromised app.",
      "live": "polite",
      "figmaVariant": "State=Approval requested,Tone=Warning",
      "reactVariant": "approval-requested",
      "transitions": [
        {
          "event": "approval_signed",
          "label": "Approval submitted",
          "target": "transaction.pending"
        },
        {
          "event": "approval_rejected",
          "label": "Approval rejected",
          "target": "signature.rejected"
        }
      ]
    },
    {
      "order": 6,
      "id": "transaction.pending",
      "family": "transaction",
      "tone": "attention",
      "icon": "clock",
      "eyebrow": "Submitted",
      "title": "Transaction is confirming",
      "body": "Transaction 0x8D…91A was submitted. One confirmation is recorded; two are required before this app treats it as final.",
      "status": "1 of 2 confirmations",
      "primaryAction": "View activity",
      "secondaryAction": "Copy transaction ID",
      "recovery": "Do not submit the same action again while its final status is unknown.",
      "safetyNote": "Leaving this page does not cancel a submitted transaction.",
      "live": "polite",
      "figmaVariant": "State=Transaction pending,Tone=Attention",
      "reactVariant": "transaction-pending",
      "transitions": [
        {
          "event": "finalized",
          "label": "Required finality reached",
          "target": "transaction.finalized"
        },
        {
          "event": "reverted",
          "label": "Execution reverted",
          "target": "transaction.reverted"
        },
        {
          "event": "timeout",
          "label": "Status remains unknown",
          "target": "external:transaction-unknown"
        }
      ]
    },
    {
      "order": 7,
      "id": "transaction.finalized",
      "family": "transaction",
      "tone": "success",
      "icon": "check",
      "eyebrow": "Complete",
      "title": "Transfer reached finality",
      "body": "The confirmed transfer completed at 14:32 UTC. The receipt includes the network, amount, destination, and transaction ID.",
      "status": "Finalized",
      "primaryAction": "View receipt",
      "secondaryAction": "Copy transaction ID",
      "recovery": "Keep the receipt if this action is part of a later support request.",
      "safetyNote": "Verify the destination and amount in the receipt, not only the success label.",
      "live": "polite",
      "figmaVariant": "State=Transaction finalized,Tone=Success",
      "reactVariant": "transaction-finalized",
      "transitions": [
        {
          "event": "receipt_opened",
          "label": "Receipt opened",
          "target": "external:block-explorer"
        }
      ]
    },
    {
      "order": 8,
      "id": "transaction.reverted",
      "family": "transaction",
      "tone": "danger",
      "icon": "error",
      "eyebrow": "Did not complete",
      "title": "Transaction reverted",
      "body": "The requested state change did not complete. The network may still charge a fee for the failed execution.",
      "status": "Reverted onchain",
      "primaryAction": "Review failure",
      "secondaryAction": "View transaction",
      "recovery": "Fix the stated cause before creating a new transaction.",
      "safetyNote": "Do not promise that all funds or fees are unchanged after a revert.",
      "live": "polite",
      "figmaVariant": "State=Transaction reverted,Tone=Danger",
      "reactVariant": "transaction-reverted",
      "transitions": [
        {
          "event": "cause_resolved",
          "label": "Failure cause resolved",
          "target": "external:rebuild-transaction"
        }
      ]
    }
  ]
}
