{
  "schemaVersion": "universe-doc-journeys-v1",
  "journeys": [
    {
      "id": "identify-version",
      "version": 1,
      "title": "Identify the installed wallet and the right documentation release",
      "outcome": "You know exactly which build you are running and which parts of this site describe it.",
      "audience": [
        "new-user",
        "wallet-user"
      ],
      "estimatedMinutes": 5,
      "prerequisites": [],
      "releaseIds": [
        "wallet-1.7.5.8",
        "wallet-1.0.13-store"
      ],
      "chains": [
        "bitcoin"
      ],
      "requiredCapabilities": [],
      "riskLevel": "info",
      "completionCriterion": "You can state your wallet version and know whether this site's pages describe it.",
      "recovery": "Nothing in this journey changes your wallet. Closing the page at any point loses nothing.",
      "nextBestAction": "/journeys/install-and-verify/",
      "steps": [
        {
          "id": "open-settings",
          "title": "Open the wallet and its settings",
          "goal": "Reach the wallet's About or Settings area, where the version is shown.",
          "expected": "The wallet opens. Settings lists backup status, security, and About entries.",
          "action": "Click the wallet icon, then open Settings.",
          "checkpoint": "You can see the settings list. If the wallet asks for a password, that is the unlock screen, not settings; unlock first.",
          "failure": "If no wallet icon exists in the browser, the extension is not installed. That is a different journey.",
          "reversible": true,
          "captureIds": [
            "settings--dark--400"
          ],
          "simulatorScenarioIds": [
            "backup-settings"
          ],
          "safetyLabScenarioIds": [],
          "relatedPage": "/start/versions",
          "branches": []
        },
        {
          "id": "read-version",
          "title": "Read the version number",
          "goal": "Find the exact version string.",
          "expected": "A version like 1.0.13 or 1.7.5.8 is displayed.",
          "action": "Open About (or the version row) and note the number.",
          "checkpoint": "You wrote down the exact version, not a date or a build channel.",
          "failure": "Some builds show the version only in the extension's detail page (browser extensions page). Both numbers are the same.",
          "reversible": true,
          "captureIds": [],
          "simulatorScenarioIds": [],
          "safetyLabScenarioIds": [],
          "relatedPage": "/start/versions",
          "branches": [
            {
              "condition": {
                "releaseId": "wallet-1.0.13-store",
                "capability": null,
                "chain": null
              },
              "note": "Version 1.0.13 is the published store build from April 2025. Screens on this site may not exist in it.",
              "unavailable": false,
              "steps": []
            }
          ]
        },
        {
          "id": "use-detect",
          "title": "Or use Detect my wallet",
          "goal": "Let this site read the version for you without you touching settings.",
          "expected": "The header control reports the detected version, or says none was found.",
          "action": "Click 'Detect my wallet' in this site's header. Only the version is read.",
          "checkpoint": "The control names exactly what was detected and never asks for accounts or addresses.",
          "failure": "An unknown version is labeled unknown. This site never guesses the nearest release.",
          "reversible": true,
          "captureIds": [],
          "simulatorScenarioIds": [],
          "safetyLabScenarioIds": [],
          "relatedPage": "/start/versions",
          "branches": []
        }
      ]
    },
    {
      "id": "install-and-verify",
      "version": 1,
      "title": "Install and verify the authentic extension",
      "outcome": "The wallet is installed from a real source and you know how to check it.",
      "audience": [
        "new-user"
      ],
      "estimatedMinutes": 10,
      "prerequisites": [
        "A Chrome-family browser"
      ],
      "releaseIds": [
        "wallet-1.7.5.8",
        "wallet-1.0.13-store"
      ],
      "chains": [
        "bitcoin"
      ],
      "requiredCapabilities": [],
      "riskLevel": "caution",
      "completionCriterion": "The extension is installed from the Chrome Web Store listing and its version is known.",
      "recovery": "An extension can be removed in the browser's extensions page at any time. Installation changes nothing on chain.",
      "nextBestAction": "/journeys/create-or-import/",
      "steps": [
        {
          "id": "open-store",
          "title": "Open the official store listing",
          "goal": "Install from the publisher's listing, not a copy.",
          "expected": "The Chrome Web Store opens on the Universe Wallet listing.",
          "action": "Use the install link from this site's install page or the official site. Check the publisher name.",
          "checkpoint": "The publisher and item identifier match the official site. Fake wallets live on near-identical URLs.",
          "failure": "A listing with a different publisher, or any direct ZIP from chat or search ads, is the classic phishing pattern.",
          "reversible": true,
          "captureIds": [
            "welcome--dark--400"
          ],
          "simulatorScenarioIds": [
            "first-launch"
          ],
          "safetyLabScenarioIds": [],
          "relatedPage": "/start/install",
          "branches": []
        },
        {
          "id": "add-extension",
          "title": "Add the extension",
          "goal": "Complete the browser install.",
          "expected": "The browser asks to confirm adding the extension.",
          "action": "Confirm. Pin the icon if you want it visible.",
          "checkpoint": "Only the permissions the browser shows should appear. Nothing here should ask for your recovery phrase.",
          "failure": "No real wallet ever asks for existing recovery words during install. A page that does is an impostor.",
          "reversible": true,
          "captureIds": [],
          "simulatorScenarioIds": [
            "first-launch"
          ],
          "safetyLabScenarioIds": [],
          "relatedPage": "/start/install",
          "branches": []
        },
        {
          "id": "verify-version",
          "title": "Verify what you installed",
          "goal": "Know the version you actually have.",
          "expected": "The wallet opens on its welcome or unlock screen.",
          "action": "Open settings and read the version, or use Detect my wallet here.",
          "checkpoint": "You know the version and which parts of this site describe it.",
          "failure": "If the wallet fails to open, remove it and reinstall from the listing; do not hunt for the missing wallet on search engines.",
          "reversible": true,
          "captureIds": [
            "settings--dark--400"
          ],
          "simulatorScenarioIds": [],
          "safetyLabScenarioIds": [],
          "relatedPage": "/start/versions",
          "branches": []
        }
      ]
    },
    {
      "id": "create-or-import",
      "version": 1,
      "title": "Choose between creating and importing",
      "outcome": "You know which onboarding path matches your situation before any key exists.",
      "audience": [
        "new-user",
        "wallet-user"
      ],
      "estimatedMinutes": 4,
      "prerequisites": [
        "The wallet installed"
      ],
      "releaseIds": [
        "wallet-1.7.5.8",
        "wallet-1.0.13-store"
      ],
      "chains": [
        "bitcoin"
      ],
      "requiredCapabilities": [],
      "riskLevel": "info",
      "completionCriterion": "You can say which path applies to you and why.",
      "recovery": "Choosing wrong here costs nothing; neither path creates anything until you complete it.",
      "nextBestAction": "/journeys/create-a-wallet/",
      "steps": [
        {
          "id": "welcome",
          "title": "Meet the welcome screen",
          "goal": "See the two paths.",
          "expected": "The welcome screen offers creating a new wallet or importing one.",
          "action": "Read both options. Do not decide from habit.",
          "checkpoint": "You know whether you have ever held recovery material for a Universe-compatible wallet before.",
          "failure": "Importing a phrase you also use in another active wallet splits custody between devices. Plan for one home per phrase.",
          "reversible": true,
          "captureIds": [
            "welcome--dark--400"
          ],
          "simulatorScenarioIds": [
            "create-or-import"
          ],
          "safetyLabScenarioIds": [],
          "relatedPage": "/start/create-a-wallet",
          "branches": []
        },
        {
          "id": "decide",
          "title": "Decide",
          "goal": "Pick the honest path.",
          "expected": "Clear next screen for the chosen path.",
          "action": "New keys: create. Existing keys: import.",
          "checkpoint": "Create for a fresh start; import only for phrase you already control and have secured.",
          "failure": "Restoring from a phrase you never wrote down yourself (for example one someone gave you) hands them your money.",
          "reversible": true,
          "captureIds": [],
          "simulatorScenarioIds": [
            "create-or-import"
          ],
          "safetyLabScenarioIds": [],
          "relatedPage": "/start/import-a-wallet",
          "branches": []
        }
      ]
    },
    {
      "id": "create-a-wallet",
      "version": 1,
      "title": "Create a wallet and secure its recovery material",
      "outcome": "A new wallet exists, its recovery phrase is backed up offline, and the backup status says so.",
      "audience": [
        "new-user"
      ],
      "estimatedMinutes": 15,
      "prerequisites": [
        "A private space where no camera can see your screen"
      ],
      "releaseIds": [
        "wallet-1.7.5.8",
        "wallet-1.0.13-store"
      ],
      "chains": [
        "bitcoin"
      ],
      "requiredCapabilities": [],
      "riskLevel": "danger",
      "completionCriterion": "Settings shows the wallet backed up, and the phrase exists only offline in your keeping.",
      "recovery": "Until you send funds in, everything here is re-doable. Lose the phrase after funding and the money is gone; there is no reset.",
      "nextBestAction": "/journeys/receive-funds/",
      "steps": [
        {
          "id": "password",
          "title": "Create the device password",
          "goal": "Set the password that unlocks this wallet on this device.",
          "expected": "Two password fields and a Continue control.",
          "action": "Enter a strong password twice and continue.",
          "checkpoint": "You understand this password unlocks this device only. It is not the recovery phrase and cannot restore funds.",
          "failure": "A forgotten password with no phrase means reinstalling from scratch. The phrase is the real key.",
          "reversible": false,
          "captureIds": [
            "create-password--dark--400"
          ],
          "simulatorScenarioIds": [
            "create-or-import"
          ],
          "safetyLabScenarioIds": [],
          "relatedPage": "/tasks/lock-and-password",
          "branches": []
        },
        {
          "id": "address-type",
          "title": "Choose the address type",
          "goal": "Pick the address model for the wallet.",
          "expected": "A list of address type cards; Continue stays disabled until a scan finishes.",
          "action": "Keep the default unless you have a specific reason. Continue.",
          "checkpoint": "The default covers most users. Changing it later means recovery procedures.",
          "failure": "Importing into a mismatched address type makes balances appear missing. They are on the other path.",
          "reversible": false,
          "captureIds": [
            "address-type--dark--400"
          ],
          "simulatorScenarioIds": [],
          "safetyLabScenarioIds": [],
          "relatedPage": "/concepts/address-types",
          "branches": []
        },
        {
          "id": "write-phrase",
          "title": "Write the recovery phrase offline",
          "goal": "Capture the 12 words where no camera or clipboard can reach them.",
          "expected": "The phrase is shown once, masked by secure input.",
          "action": "Write the words on paper in order. Verify by re-entering when asked.",
          "checkpoint": "Words exist on paper only. Never photographed, never typed into anything networked, never clipped.",
          "failure": "A phrase that touched a phone camera, cloud note, or password manager sync is a leaked key waiting to be used.",
          "reversible": false,
          "captureIds": [
            "seed-import--dark--400"
          ],
          "simulatorScenarioIds": [],
          "safetyLabScenarioIds": [],
          "relatedPage": "/start/back-up",
          "branches": []
        },
        {
          "id": "confirm-backup",
          "title": "Confirm backup status",
          "goal": "The wallet records that the backup step is done.",
          "expected": "Home shows the wallet; Settings shows backup status.",
          "action": "Open Settings and confirm the backup entry reflects your paper copy.",
          "checkpoint": "Settings is the source of truth for backup state inside the wallet.",
          "failure": "Dismissing the backup reminder without writing the phrase is the most common permanent-loss story.",
          "reversible": true,
          "captureIds": [
            "settings--dark--400"
          ],
          "simulatorScenarioIds": [
            "backup-settings"
          ],
          "safetyLabScenarioIds": [],
          "relatedPage": "/start/back-up",
          "branches": []
        }
      ]
    },
    {
      "id": "import-safely",
      "version": 1,
      "title": "Import a wallet safely",
      "outcome": "Existing keys are restored into this wallet without the phrase touching anything networked.",
      "audience": [
        "wallet-user"
      ],
      "estimatedMinutes": 10,
      "prerequisites": [
        "Your recovery phrase or private key, already written down"
      ],
      "releaseIds": [
        "wallet-1.7.5.8",
        "wallet-1.0.13-store"
      ],
      "chains": [
        "bitcoin"
      ],
      "requiredCapabilities": [],
      "riskLevel": "danger",
      "completionCriterion": "The restored wallet shows the expected account and balances (or an empty account for a fresh phrase).",
      "recovery": "Import copies; it does not move. The original phrase keeps working and must stay protected.",
      "nextBestAction": "/journeys/receive-funds/",
      "steps": [
        {
          "id": "choose-source",
          "title": "Choose the import source",
          "goal": "Select where the keys come from.",
          "expected": "A list of sources as selectable cards.",
          "action": "Pick the source matching your phrase (for example a 12-word Universe-compatible wallet).",
          "checkpoint": "The source card names the wallet family the phrase belongs to.",
          "failure": "Wrong source means empty balances. Nothing is lost; redo with the right source.",
          "reversible": true,
          "captureIds": [
            "restore-source--dark--400"
          ],
          "simulatorScenarioIds": [
            "create-or-import"
          ],
          "safetyLabScenarioIds": [],
          "relatedPage": "/start/import-a-wallet",
          "branches": []
        },
        {
          "id": "enter-phrase",
          "title": "Enter the phrase",
          "goal": "Restore keys from your offline copy.",
          "expected": "A grid of twelve masked inputs.",
          "action": "Type words from paper. Keep secure input on.",
          "checkpoint": "The words came from paper, not from a file, a photo, or a message someone sent you.",
          "failure": "A phrase someone gave you 'to import' is their lever on your money. Import only phrases you generated.",
          "reversible": false,
          "captureIds": [
            "seed-import--dark--400"
          ],
          "simulatorScenarioIds": [],
          "safetyLabScenarioIds": [],
          "relatedPage": "/start/import-a-wallet",
          "branches": []
        },
        {
          "id": "verify-restore",
          "title": "Verify what was restored",
          "goal": "Confirm the account and address type match your old wallet.",
          "expected": "Home shows the restored account.",
          "action": "Check the receive address against the old wallet's address where possible.",
          "checkpoint": "Address type mismatch is the usual cause of 'my funds are gone' after import. They are on another derivation path.",
          "failure": "If balances look missing, stop sending. Recheck the address type before anything else.",
          "reversible": true,
          "captureIds": [
            "home--dark--400"
          ],
          "simulatorScenarioIds": [
            "populated-home"
          ],
          "safetyLabScenarioIds": [],
          "relatedPage": "/start/import-a-wallet",
          "branches": []
        }
      ]
    },
    {
      "id": "receive-funds",
      "version": 1,
      "title": "Receive funds for the first time",
      "outcome": "You requested your first payment to an address you verified in your own wallet.",
      "audience": [
        "new-user",
        "wallet-user"
      ],
      "estimatedMinutes": 8,
      "prerequisites": [
        "A wallet created or imported"
      ],
      "releaseIds": [
        "wallet-1.7.5.8",
        "wallet-1.0.13-store"
      ],
      "chains": [
        "bitcoin"
      ],
      "requiredCapabilities": [],
      "riskLevel": "caution",
      "completionCriterion": "The payment appears in activity with its confirmation state.",
      "recovery": "Receiving is reversible by simply sending onward. Nothing broadcast here spends your funds.",
      "nextBestAction": "/journeys/understand-balances/",
      "steps": [
        {
          "id": "open-receive",
          "title": "Open Receive",
          "goal": "Get your receiving address.",
          "expected": "The receive screen reports it is ready to receive.",
          "action": "Open Receive from home.",
          "checkpoint": "The network shown in the header matches the network the payer expects. Testnet coins and mainnet coins are not interchangeable.",
          "failure": "Sending mainnet funds to a testnet address loses them. Read the network label.",
          "reversible": true,
          "captureIds": [
            "receive--dark--400"
          ],
          "simulatorScenarioIds": [
            "receive"
          ],
          "safetyLabScenarioIds": [],
          "relatedPage": "/tasks/receive",
          "branches": []
        },
        {
          "id": "share-address",
          "title": "Share the address",
          "goal": "Give the payer your address or QR.",
          "expected": "An address string and a QR code.",
          "action": "Copy, or show the QR, or request via a payment name if configured.",
          "checkpoint": "Paste-back check: paste the address where you will send it to yourself and compare the first and last 6 characters.",
          "failure": "Clipboard malware swaps addresses. The paste-back check defeats the common ones.",
          "reversible": true,
          "captureIds": [],
          "simulatorScenarioIds": [],
          "safetyLabScenarioIds": [],
          "relatedPage": "/tasks/receive",
          "branches": []
        },
        {
          "id": "watch-arrival",
          "title": "Watch it arrive",
          "goal": "See the payment and its confirmation state.",
          "expected": "Activity lists the incoming payment; confirmations count up.",
          "action": "Open Activity. Nothing else to do.",
          "checkpoint": "A payment is spendable per the wallet's confirmation policy; large payments deserve more confirmations before you ship goods.",
          "failure": "If nothing appears, verify the address the payer actually used. A wrong network or old address is the usual cause.",
          "reversible": true,
          "captureIds": [
            "history--dark--400"
          ],
          "simulatorScenarioIds": [
            "populated-home"
          ],
          "safetyLabScenarioIds": [],
          "relatedPage": "/tasks/activity",
          "branches": []
        }
      ]
    },
    {
      "id": "send-safely",
      "version": 1,
      "title": "Send funds safely",
      "outcome": "You know how a safe send flows, and whether your build can send at all.",
      "audience": [
        "wallet-user"
      ],
      "estimatedMinutes": 12,
      "prerequisites": [
        "Funds to send",
        "A verified recipient address"
      ],
      "releaseIds": [
        "wallet-1.7.5.8"
      ],
      "chains": [
        "bitcoin"
      ],
      "requiredCapabilities": [
        "bitcoin.send"
      ],
      "riskLevel": "danger",
      "completionCriterion": "Either the send completed with a transaction id, or your build showed the unavailable state because its release authorizes no sending.",
      "recovery": "Before approval, a send is fully reversible: close the screen. After broadcast, nothing can pull a transaction back.",
      "nextBestAction": "/journeys/review-transaction/",
      "steps": [
        {
          "id": "availability",
          "title": "Check that this build can send",
          "goal": "Know the send availability for your release.",
          "expected": "Builds whose release authorizes no sending show a plain unavailable panel: 'This build cannot send'.",
          "action": "Open the send screen and read what it actually offers.",
          "checkpoint": "An unavailable state is the wallet protecting you. It is not a bug and not a network outage.",
          "failure": "Nothing to fear here: an unauthorized build cannot send, cannot be talked into sending, and loses nothing.",
          "reversible": true,
          "captureIds": [
            "send--dark--400"
          ],
          "simulatorScenarioIds": [
            "unavailable-operation"
          ],
          "safetyLabScenarioIds": [
            "ordinary-send"
          ],
          "relatedPage": "/tasks/send",
          "branches": [
            {
              "condition": {
                "releaseId": "wallet-1.7.5.8",
                "capability": "bitcoin.send",
                "chain": null
              },
              "note": "This source tree authorizes no sending operation. The journey stops at the unavailable state for this release; the remaining steps describe the authorized flow for when a release ships it.",
              "unavailable": true,
              "steps": []
            }
          ]
        },
        {
          "id": "compose",
          "title": "Compose the payment",
          "goal": "Address, amount, fee.",
          "expected": "The send form with a fee selector.",
          "action": "Paste the address, set the amount, choose a fee.",
          "checkpoint": "Paste-back the address. Compare fee rate to the wallet's recommendation.",
          "failure": "A fee far above recommendation is a signal to stop and reread every field.",
          "reversible": true,
          "captureIds": [],
          "simulatorScenarioIds": [],
          "safetyLabScenarioIds": [
            "ordinary-send",
            "unusually-high-fee"
          ],
          "relatedPage": "/tasks/choose-a-fee",
          "branches": []
        },
        {
          "id": "review",
          "title": "Read the review screen like a contract",
          "goal": "Approve exactly what you decided.",
          "expected": "The transaction review: recipient, amount, fee, change.",
          "action": "Read every output. The change output must return to your wallet.",
          "checkpoint": "Every output accounted for: payment + change + fee = total.",
          "failure": "Approving a screen you did not read is how every send scam works. No exception.",
          "reversible": false,
          "captureIds": [],
          "simulatorScenarioIds": [],
          "safetyLabScenarioIds": [
            "change-address-ambiguity",
            "unexpected-output"
          ],
          "relatedPage": "/tasks/review-a-transaction",
          "branches": []
        },
        {
          "id": "confirm",
          "title": "Approve and track",
          "goal": "Broadcast and watch for the transaction id.",
          "expected": "A confirmation, then the transaction id in activity.",
          "action": "Approve. Open activity to watch confirmations.",
          "checkpoint": "The txid in your activity is the receipt. Confirmations mean settlement.",
          "failure": "After broadcast there is no undo. A stuck transaction is bumped or dropped by its fee, not by support.",
          "reversible": false,
          "captureIds": [
            "history--dark--400"
          ],
          "simulatorScenarioIds": [],
          "safetyLabScenarioIds": [],
          "relatedPage": "/tasks/review-a-transaction",
          "branches": []
        }
      ]
    },
    {
      "id": "understand-balances",
      "version": 1,
      "title": "Understand available, unavailable, and protected balance",
      "outcome": "You can explain why the wallet may show more wealth than spendable funds.",
      "audience": [
        "wallet-user"
      ],
      "estimatedMinutes": 6,
      "prerequisites": [],
      "releaseIds": [
        "wallet-1.7.5.8"
      ],
      "chains": [
        "bitcoin"
      ],
      "requiredCapabilities": [],
      "riskLevel": "info",
      "completionCriterion": "You can read the balance anatomy on home and protected outputs without surprise.",
      "recovery": "Reading only; nothing to recover.",
      "nextBestAction": "/journeys/connect-and-review/",
      "steps": [
        {
          "id": "read-home",
          "title": "Read the home balance anatomy",
          "goal": "See total, available, and held-back amounts with the ownership line.",
          "expected": "Home splits the balance when parts are not spendable.",
          "action": "Compare total and available. The difference is explained below the numbers.",
          "checkpoint": "Unconfirmed incoming payments and protected outputs both reduce available funds.",
          "failure": "Treating the total as spendable leads to stuck payments, not losses.",
          "reversible": true,
          "captureIds": [
            "home-populated--dark--400"
          ],
          "simulatorScenarioIds": [
            "populated-home"
          ],
          "safetyLabScenarioIds": [],
          "relatedPage": "/concepts/inputs-outputs-fees",
          "branches": []
        },
        {
          "id": "read-protected",
          "title": "Open protected outputs",
          "goal": "See what the wallet holds back and why.",
          "expected": "The protected outputs screen lists held outputs with reasons.",
          "action": "Open it from settings or home.",
          "checkpoint": "Protected outputs carry artifacts (inscriptions, rare sats) that plain spending would destroy or move.",
          "failure": "Forcing a spend that consumes a protected output can send your art with your payment.",
          "reversible": true,
          "captureIds": [
            "protected-outputs-populated--dark--400"
          ],
          "simulatorScenarioIds": [
            "protected-outputs"
          ],
          "safetyLabScenarioIds": [
            "protected-output-rare-sat"
          ],
          "relatedPage": "/concepts/protected-outputs",
          "branches": []
        }
      ]
    },
    {
      "id": "connect-and-review",
      "version": 1,
      "title": "Connect to a site and review requested access",
      "outcome": "You can connect a site deliberately and read what the connection actually grants.",
      "audience": [
        "wallet-user",
        "developer"
      ],
      "estimatedMinutes": 8,
      "prerequisites": [
        "A site you have decided to trust"
      ],
      "releaseIds": [
        "wallet-1.7.5.8",
        "wallet-1.0.13-store"
      ],
      "chains": [
        "bitcoin"
      ],
      "requiredCapabilities": [],
      "riskLevel": "caution",
      "completionCriterion": "The site shows as connected in the wallet, and you can name what it may and may not do.",
      "recovery": "Disconnecting ends access instantly. Connections grant identity visibility, never spending on their own.",
      "nextBestAction": "/journeys/review-transaction/",
      "steps": [
        {
          "id": "start-connect",
          "title": "Start the connection from the site",
          "goal": "Trigger the wallet's connection approval.",
          "expected": "The wallet opens an approval naming the site's origin.",
          "action": "Click the site's Connect button.",
          "checkpoint": "Read the origin in the approval. example-site.test-style names or look-alike domains mean close it.",
          "failure": "Connecting on a phishing page exposes your account identity to attackers, who then tailor the scam.",
          "reversible": true,
          "captureIds": [
            "approval-connect--dark--400"
          ],
          "simulatorScenarioIds": [],
          "safetyLabScenarioIds": [],
          "relatedPage": "/tasks/connect-an-application",
          "branches": []
        },
        {
          "id": "read-request",
          "title": "Read the request",
          "goal": "Know what access is asked.",
          "expected": "The approval states the account access requested.",
          "action": "Approve or reject.",
          "checkpoint": "A connection shows your account to the site. It does not authorize spending; signatures are separate approvals.",
          "failure": "Approving unknown origins trains you to click through approvals, which is the habit scams harvest.",
          "reversible": true,
          "captureIds": [],
          "simulatorScenarioIds": [],
          "safetyLabScenarioIds": [],
          "relatedPage": "/concepts/connections",
          "branches": []
        },
        {
          "id": "unverified-gate",
          "title": "Know the unverified-origin gate",
          "goal": "Recognize the state the wallet shows when it cannot verify a site.",
          "expected": "A full gate: 'Unable to verify this site', with no approve control.",
          "action": "Nothing to click. Close it.",
          "checkpoint": "The gate appears when the wallet's site check cannot complete. It fails closed on purpose.",
          "failure": "No third party can legitimately 'unlock' this gate. Instructions claiming to are the scam.",
          "reversible": true,
          "captureIds": [
            "approval-unverified-origin--dark--400"
          ],
          "simulatorScenarioIds": [],
          "safetyLabScenarioIds": [],
          "relatedPage": "/safety/phishing",
          "branches": []
        }
      ]
    },
    {
      "id": "review-transaction",
      "version": 1,
      "title": "Review a transaction or PSBT before signing",
      "outcome": "You can read a transaction review or PSBT screen and sign only what you verified.",
      "audience": [
        "wallet-user",
        "developer"
      ],
      "estimatedMinutes": 10,
      "prerequisites": [],
      "releaseIds": [
        "wallet-1.7.5.8"
      ],
      "chains": [
        "bitcoin"
      ],
      "requiredCapabilities": [
        "bitcoin.sign"
      ],
      "riskLevel": "danger",
      "completionCriterion": "You can name what a signature commits to before any approval.",
      "recovery": "Refusing is always available and always safe. No signature, no consequence.",
      "nextBestAction": "/journeys/switch-chain-safely/",
      "steps": [
        {
          "id": "availability",
          "title": "Know your build's signing availability",
          "goal": "Know whether this release signs at all.",
          "expected": "This source tree authorizes no signing operation; provider calls refuse before any approval.",
          "action": "Check the capability status for your release.",
          "checkpoint": "A refusal is the gate, not an error to work around.",
          "failure": "Workarounds 'to unlock signing' are always scams.",
          "reversible": true,
          "captureIds": [
            "send--dark--400"
          ],
          "simulatorScenarioIds": [
            "unavailable-operation"
          ],
          "safetyLabScenarioIds": [
            "fail-closed-missing-data"
          ],
          "relatedPage": "/assets/why-unavailable",
          "branches": [
            {
              "condition": {
                "releaseId": "wallet-1.7.5.8",
                "capability": "bitcoin.sign",
                "chain": null
              },
              "note": "No signing operation is authorized in this source tree, so the approval-walk steps are educational until a release ships them.",
              "unavailable": true,
              "steps": []
            }
          ]
        },
        {
          "id": "read-anatomy",
          "title": "Read the transaction anatomy",
          "goal": "Inputs, outputs, fee, change: know what each means.",
          "expected": "The review shows money in, money out, the fee, and change returning to you.",
          "action": "Study the anatomy in the Safety Lab before you meet it live.",
          "checkpoint": "You can say which outputs are yours and which leave, for any transaction shown.",
          "failure": "The largest output not going to you is the classic theft shape.",
          "reversible": true,
          "captureIds": [],
          "simulatorScenarioIds": [],
          "safetyLabScenarioIds": [
            "ordinary-send",
            "psbt-input-ownership",
            "sighash-single-listing"
          ],
          "relatedPage": "/concepts/inputs-outputs-fees",
          "branches": []
        },
        {
          "id": "sign-or-decline",
          "title": "Sign or decline",
          "goal": "Commit only to what you read.",
          "expected": "Approval signs exactly the displayed transaction.",
          "action": "Approve if every line checks; decline otherwise.",
          "checkpoint": "Declining costs nothing, ever.",
          "failure": "Signing unreadable data (length warnings) commits you to something you never saw.",
          "reversible": false,
          "captureIds": [],
          "simulatorScenarioIds": [],
          "safetyLabScenarioIds": [
            "unexpected-output"
          ],
          "relatedPage": "/tasks/review-a-psbt",
          "branches": []
        }
      ]
    },
    {
      "id": "switch-chain-safely",
      "version": 1,
      "title": "Switch chain or network safely",
      "outcome": "You can move the wallet between chains and test networks without losing track of where money applies.",
      "audience": [
        "wallet-user",
        "developer"
      ],
      "estimatedMinutes": 6,
      "prerequisites": [],
      "releaseIds": [
        "wallet-1.7.5.8",
        "wallet-1.0.13-store"
      ],
      "chains": [
        "bitcoin",
        "dogecoin",
        "zcash"
      ],
      "requiredCapabilities": [],
      "riskLevel": "caution",
      "completionCriterion": "You switched the active chain deliberately and can switch back.",
      "recovery": "Switching back restores the previous view. No funds move when you switch.",
      "nextBestAction": "/journeys/inspect-history/",
      "steps": [
        {
          "id": "read-current",
          "title": "Read the current chain",
          "goal": "Know where you are before moving.",
          "expected": "The header names the active chain and network.",
          "action": "Check the header.",
          "checkpoint": "Mainnet is real money. Test networks are for practice.",
          "failure": "Doing mainnet actions on reflex after practicing on testnet is the common accident.",
          "reversible": true,
          "captureIds": [
            "home--dark--400"
          ],
          "simulatorScenarioIds": [],
          "safetyLabScenarioIds": [],
          "relatedPage": "/concepts/chains-and-networks",
          "branches": []
        },
        {
          "id": "approve-switch",
          "title": "Approve a switch request",
          "goal": "Move deliberately when a site or you requests a chain change.",
          "expected": "The approval names both the current and the target chain.",
          "action": "Approve only if the target chain makes sense for what you are doing.",
          "checkpoint": "After switching, every balance view is per-chain; the old chain's funds did not vanish.",
          "failure": "Sites requesting switches to obscure chains are setting up a look-alike-token trick.",
          "reversible": true,
          "captureIds": [
            "approval-switch-chain--dark--400"
          ],
          "simulatorScenarioIds": [
            "account-switching"
          ],
          "safetyLabScenarioIds": [],
          "relatedPage": "/tasks/switch-chain-and-network",
          "branches": []
        }
      ]
    },
    {
      "id": "inspect-history",
      "version": 1,
      "title": "Inspect transaction history and confirmation state",
      "outcome": "You can read your activity list and know what 'confirmed' means before you rely on a payment.",
      "audience": [
        "wallet-user"
      ],
      "estimatedMinutes": 5,
      "prerequisites": [],
      "releaseIds": [
        "wallet-1.7.5.8"
      ],
      "chains": [
        "bitcoin"
      ],
      "requiredCapabilities": [],
      "riskLevel": "info",
      "completionCriterion": "You can find a transaction's confirmation count and state what it implies.",
      "recovery": "Reading only.",
      "nextBestAction": "/journeys/compromised-response/",
      "steps": [
        {
          "id": "open-activity",
          "title": "Open activity",
          "goal": "See the list.",
          "expected": "Transactions with direction, amount, and state. Offline builds show an explicit load failure with retry.",
          "action": "Open Activity.",
          "checkpoint": "An offline error with a retry control is the honest state; an always-empty list would be a lie.",
          "failure": "Loading failures resolve when connectivity returns. Retry, do not re-import.",
          "reversible": true,
          "captureIds": [
            "history--dark--400"
          ],
          "simulatorScenarioIds": [
            "populated-home"
          ],
          "safetyLabScenarioIds": [],
          "relatedPage": "/tasks/activity",
          "branches": []
        },
        {
          "id": "read-confirmations",
          "title": "Read confirmation state",
          "goal": "Know how settled a payment is.",
          "expected": "Each transaction shows its confirmations (or pending).",
          "action": "Open a transaction and read its state.",
          "checkpoint": "Pending means reversible by the sender; confirmed means it is in the chain and settling.",
          "failure": "Shipping goods for a pending payment is trusting an unconfirmed promise.",
          "reversible": true,
          "captureIds": [],
          "simulatorScenarioIds": [],
          "safetyLabScenarioIds": [],
          "relatedPage": "/tasks/activity",
          "branches": []
        }
      ]
    },
    {
      "id": "compromised-response",
      "version": 1,
      "title": "Respond to a suspected compromised wallet",
      "outcome": "You contained the incident and moved remaining funds to fresh keys in the right order.",
      "audience": [
        "emergency",
        "wallet-user"
      ],
      "estimatedMinutes": 30,
      "prerequisites": [],
      "releaseIds": [
        "wallet-1.7.5.8",
        "wallet-1.0.13-store"
      ],
      "chains": [
        "bitcoin"
      ],
      "requiredCapabilities": [],
      "riskLevel": "danger",
      "completionCriterion": "Any remaining funds live under a new phrase that no suspect device or person has seen.",
      "recovery": "Speed matters more than neatness. You can clean up after the money is safe.",
      "nextBestAction": null,
      "steps": [
        {
          "id": "stop-the-bleed",
          "title": "Stop using the suspect wallet",
          "goal": "Prevent further exposure.",
          "expected": "Nothing new is signed or approved.",
          "action": "Stop. Do not sign anything more, do not 'test' the wallet with small sends to check it.",
          "checkpoint": "You accept that anything the suspect device can see may already be known.",
          "failure": "The 'send a small test amount' reflex from compromised devices funds the attacker.",
          "reversible": true,
          "captureIds": [],
          "simulatorScenarioIds": [],
          "safetyLabScenarioIds": [],
          "relatedPage": "/safety/compromised-wallet",
          "branches": []
        },
        {
          "id": "fresh-keys",
          "title": "Prepare fresh keys on a clean device",
          "goal": "Create a new wallet where the compromise cannot see it.",
          "expected": "A new phrase exists on paper, created on a device you trust.",
          "action": "Install the wallet on a clean device or profile and create a new wallet.",
          "checkpoint": "The new phrase never touches the suspect device in any form: no photo, no note, no cloud.",
          "failure": "Moving funds to keys the suspect device generated (or its clipboard saw) is not an escape.",
          "reversible": false,
          "captureIds": [
            "welcome--dark--400"
          ],
          "simulatorScenarioIds": [
            "first-launch"
          ],
          "safetyLabScenarioIds": [],
          "relatedPage": "/safety/compromised-wallet",
          "branches": []
        },
        {
          "id": "sweep",
          "title": "Move funds to the new wallet",
          "goal": "Transfer remaining value to fresh keys.",
          "expected": "Sends complete from the old wallet to the new address.",
          "action": "Send everything worth keeping. Artifacts too: a moved inscription leaves the compromised keys.",
          "checkpoint": "Balance shows zero (or the amount you chose to abandon) on the old wallet.",
          "failure": "Leaving 'just the cheap artifacts' leaves a trail and a hook for follow-up scams.",
          "reversible": false,
          "captureIds": [
            "send--dark--400"
          ],
          "simulatorScenarioIds": [
            "unavailable-operation"
          ],
          "safetyLabScenarioIds": [],
          "relatedPage": "/safety/compromised-wallet",
          "branches": [
            {
              "condition": {
                "releaseId": "wallet-1.7.5.8",
                "capability": "bitcoin.send",
                "chain": null
              },
              "note": "If your build authorizes no sending, sweeping from it is impossible by design: use another wallet you control that holds the same keys, or accept the exposure and treat all funds as at risk.",
              "unavailable": true,
              "steps": []
            }
          ]
        },
        {
          "id": "retire",
          "title": "Retire the old phrase",
          "goal": "Make sure the old keys are never funded again.",
          "expected": "The old phrase is out of circulation.",
          "action": "Remove the wallet from the suspect device. Mark the paper phrase as burned.",
          "checkpoint": "No service, subscription, or payment card still points at the old address.",
          "failure": "Reusing a leaked phrase 'one more time' is how round-two losses happen.",
          "reversible": true,
          "captureIds": [],
          "simulatorScenarioIds": [],
          "safetyLabScenarioIds": [],
          "relatedPage": "/safety/compromised-wallet",
          "branches": []
        }
      ]
    },
    {
      "id": "developer-first-connection",
      "version": 1,
      "title": "Complete a first developer connection using the simulated provider",
      "outcome": "A working integration path: detect, connect, read capabilities, handle rejection - all against the simulated provider, with a downloadable starter.",
      "audience": [
        "developer"
      ],
      "estimatedMinutes": 20,
      "prerequisites": [
        "Basic JavaScript"
      ],
      "releaseIds": [
        "wallet-1.7.5.8"
      ],
      "chains": [
        "bitcoin"
      ],
      "requiredCapabilities": [],
      "riskLevel": "info",
      "completionCriterion": "Your code detects the provider, handles connection and rejection, and renders unavailable states from capabilities.",
      "recovery": "Simulation only; no wallet is touched, nothing to recover.",
      "nextBestAction": null,
      "steps": [
        {
          "id": "detect",
          "title": "Detect the provider",
          "goal": "Find the wallet's injected namespace.",
          "expected": "Provider aliases are known: universe, tapwallet, and variants.",
          "action": "Check for window.universe in the Integration Studio doctor or your code.",
          "checkpoint": "Detection says nothing about connection. It only found a candidate provider.",
          "failure": "Assuming detection implies consent leads to connecting without asking.",
          "reversible": true,
          "captureIds": [],
          "simulatorScenarioIds": [],
          "safetyLabScenarioIds": [],
          "relatedPage": "/developers/integration",
          "branches": []
        },
        {
          "id": "connect-sim",
          "title": "Simulate connect and rejection",
          "goal": "See both outcomes.",
          "expected": "The studio's fake provider answers requestAccounts with a simulated account, or a rejection.",
          "action": "Run requestAccounts in the success and rejection scenarios.",
          "checkpoint": "Rejection is a normal state your UI must render, not an exception to swallow.",
          "failure": "Auto-retrying connection prompts train users to approve blindly.",
          "reversible": true,
          "captureIds": [
            "approval-connect--dark--400"
          ],
          "simulatorScenarioIds": [],
          "safetyLabScenarioIds": [],
          "relatedPage": "/studio/",
          "branches": []
        },
        {
          "id": "capabilities",
          "title": "Read capabilities and render unavailable states",
          "goal": "Gate every feature on what the wallet reports.",
          "expected": "getCapabilities reports this release authorizes no protocol operations.",
          "action": "Call getCapabilities in the simulation and render the unavailable branch.",
          "checkpoint": "Your UI shows the unavailable state as a first-class outcome, not a disabled button.",
          "failure": "Promising a send the wallet refuses is a broken product and a support fire.",
          "reversible": true,
          "captureIds": [
            "send--dark--400"
          ],
          "simulatorScenarioIds": [
            "unavailable-operation"
          ],
          "safetyLabScenarioIds": [],
          "relatedPage": "/developers/provider-api",
          "branches": []
        },
        {
          "id": "starter",
          "title": "Download the starter and keep the loop",
          "goal": "Leave with runnable code.",
          "expected": "A minimal starter reflecting the contract.",
          "action": "Download it from the studio and wire it into your app.",
          "checkpoint": "The starter runs without any wallet installed.",
          "failure": "Testing only against a real wallet hides the refusal paths your users will meet.",
          "reversible": true,
          "captureIds": [],
          "simulatorScenarioIds": [],
          "safetyLabScenarioIds": [],
          "relatedPage": "/studio/",
          "branches": []
        }
      ]
    },
    {
      "id": "emergency-offline",
      "version": 1,
      "title": "Save the emergency handbook for offline use",
      "outcome": "The emergency pages work with no connectivity, and you know how old the cached guidance is.",
      "audience": [
        "emergency",
        "wallet-user"
      ],
      "estimatedMinutes": 3,
      "prerequisites": [
        "One visit to this site with connectivity"
      ],
      "releaseIds": [
        "wallet-1.7.5.8",
        "wallet-1.0.13-store"
      ],
      "chains": [
        "bitcoin"
      ],
      "requiredCapabilities": [],
      "riskLevel": "info",
      "completionCriterion": "The offline banner shows the snapshot date and the emergency pages open with no network.",
      "recovery": "Saving offline changes nothing; it caches public pages only.",
      "nextBestAction": null,
      "steps": [
        {
          "id": "save",
          "title": "Save the emergency guide",
          "goal": "Cache the emergency bundle.",
          "expected": "A confirmation states what was saved and when.",
          "action": "Press 'Save emergency guide offline' on the emergency page.",
          "checkpoint": "The page shows the documentation snapshot version and cached date.",
          "failure": "A cached page without a visible date invites stale guidance to pose as current.",
          "reversible": true,
          "captureIds": [],
          "simulatorScenarioIds": [],
          "safetyLabScenarioIds": [],
          "relatedPage": "/emergency/",
          "branches": []
        },
        {
          "id": "verify-offline",
          "title": "Verify it opens with no network",
          "goal": "Prove it works before you need it.",
          "expected": "The pages open in airplane mode with their offline banner.",
          "action": "Disconnect and reload the emergency page.",
          "checkpoint": "The offline banner names the snapshot age.",
          "failure": "Never test this during an actual emergency. Rehearse now.",
          "reversible": true,
          "captureIds": [],
          "simulatorScenarioIds": [],
          "safetyLabScenarioIds": [],
          "relatedPage": "/emergency/",
          "branches": []
        }
      ]
    },
    {
      "id": "phishing-defense",
      "version": 1,
      "title": "Recognize fake support and phishing",
      "outcome": "You can name the moves impostors use and the rule that defeats all of them.",
      "audience": [
        "emergency",
        "new-user",
        "wallet-user"
      ],
      "estimatedMinutes": 7,
      "prerequisites": [],
      "releaseIds": [
        "wallet-1.7.5.8",
        "wallet-1.0.13-store"
      ],
      "chains": [
        "bitcoin"
      ],
      "requiredCapabilities": [],
      "riskLevel": "caution",
      "completionCriterion": "You can state the rule: nobody legitimate ever needs your recovery words.",
      "recovery": "Reading only.",
      "nextBestAction": "/journeys/compromised-response/",
      "steps": [
        {
          "id": "learn-moves",
          "title": "Learn the standard moves",
          "goal": "Recognize the script.",
          "expected": "This page's examples.",
          "action": "Read the phishing examples: fake support, urgent upgrades, 'validation' requests, look-alike extensions.",
          "checkpoint": "All of them end the same way: they want the words, a signature, or a screen share.",
          "failure": "Urgency is the tell. Real infrastructure problems are announced calmly, not delivered as urgent private messages.",
          "reversible": true,
          "captureIds": [
            "approval-unverified-origin--dark--400"
          ],
          "simulatorScenarioIds": [],
          "safetyLabScenarioIds": [],
          "relatedPage": "/safety/phishing",
          "branches": []
        },
        {
          "id": "the-rule",
          "title": "Hold the one rule",
          "goal": "One sentence beats every script.",
          "expected": "Certainty.",
          "action": "Say it out loud: nobody legitimate ever needs my recovery words, my seed, my screen, or a 'test' signature.",
          "checkpoint": "You would refuse a support agent asking for any of those, regardless of urgency or authority.",
          "failure": "Every exception you allow becomes the scam that works on you.",
          "reversible": true,
          "captureIds": [],
          "simulatorScenarioIds": [],
          "safetyLabScenarioIds": [],
          "relatedPage": "/safety/phishing",
          "branches": []
        }
      ]
    }
  ]
}