{
  "schema": "spark.consumer-wallet-exit-audit.v1",
  "title": "Consumer-wallet unilateral-exit surface audit",
  "verifiedAt": "2026-07-13",
  "purpose": "Record the dated, bounded review behind the statement that no complete in-app operatorless exit was found in eight reviewed consumer-wallet products.",
  "definition": {
    "completeFlow": [
      "acquire-current-leaf-and-ancestor-state",
      "select-and-provide-cpfp-fee-inputs",
      "construct-and-sign-parent-child-packages",
      "broadcast-packages-in-required-root-to-leaf-order",
      "persist-and-resume-progress-across-restarts",
      "wait-for-relative-timelock-maturity",
      "broadcast-refunds",
      "construct-sign-and-broadcast-final-sweeps"
    ],
    "completeFlowFoundWhen": "The reviewed consumer interface or tracked application implementation exposes every listed stage as one durable product workflow.",
    "notEquivalentToACompleteFlow": [
      "mnemonic backup or live-network seed restore",
      "cooperative withdrawal",
      "export of current leaves or a recovery bundle without execution",
      "presence of lower-level SDK exit primitives",
      "protocol documentation describing pre-signed transactions"
    ]
  },
  "method": {
    "archiveAcquisition": {
      "commands": [
        "curl -fL 'https://codeload.github.com/OWNER/REPO/tar.gz/COMMIT' -o SNAPSHOT.tar.gz",
        "mkdir SNAPSHOT && tar -xzf SNAPSHOT.tar.gz --strip-components=1 -C SNAPSHOT"
      ],
      "verification": "Each extracted codeload archive's top-level directory name contained the requested commit SHA before strip-components extraction."
    },
    "canonicalExitTermSearch": {
      "id": "canonical-exit-terms",
      "tool": "ripgrep",
      "version": "15.1.0",
      "pattern": "unilateral[ _-]?(exit|withdraw(al)?)|recovery[ _-]?(package|bundle)|exit[ _-]?(package|bundle)|aggregate[ _-]?exit",
      "commands": [
        "rg -uuu -i -o -e \"$PATTERN\" . | wc -l",
        "rg -uuu -i -e \"$PATTERN\" . | wc -l",
        "rg -uuu -i -l -e \"$PATTERN\" . | wc -l"
      ],
      "interpretation": "Counts are discovery results in the pinned extracted archives, not standalone proof that a complete flow is absent."
    },
    "executionStageSearch": {
      "scope": "Spark and payment implementation paths in the seven pinned public-source snapshots",
      "pattern": "constructUnilateralExitFeeBumpPackages|createUnilateralExit|prepareUnilateralExit|executeUnilateralExit|startUnilateralExit|broadcast(Transaction|Tx|Package)|sendRawTransaction|submitPackage|root[ _-]?to[ _-]?leaf|final[ _-]?sweep|sweep.{0,24}(refund|exit)|refund.{0,24}sweep|confirm[ _-]?and[ _-]?continue",
      "commandTemplate": "rg -uuu -i -e \"$EXEC_PATTERN\" <the target's manuallyReviewedEntryPoints> | wc -l",
      "matchingLines": 0,
      "reproducibility": "This is a documented scoped method rather than a single copy-paste command because each repository has different implementation paths. The per-target manuallyReviewedEntryPoints record the substituted scope; the canonical whole-archive search above is directly reproducible as written.",
      "interpretation": "Ordinary Bitcoin broadcasters outside Spark adapters, cooperative withdrawals, deposit refunds, and storage fields containing CPFP terminology were classified separately and not treated as unilateral-exit execution."
    },
    "repositoryDiscoverySearch": {
      "tool": "ripgrep",
      "version": "15.1.0",
      "pattern": "(unilateral[ _-]?exit|recovery[ _-]?bundle|emergency[ _-]?exit|prepare_unilateral_exit|constructUnilateralExit|buildUnilateralExit|submitpackage|cpfp|timelock.{0,40}sweep|refund.{0,40}sweep)",
      "excludedGlobs": [
        "**/.git/**",
        "**/node_modules/**",
        "**/vendor/**",
        "**/build/**",
        "**/dist/**",
        "**/package-lock.json",
        "**/yarn.lock",
        "**/*.lock",
        "**/generated/**"
      ],
      "interpretation": "Keyword search was used to locate candidate code. Findings were then classified against the eight-stage definition. A zero-result search is not treated as proof by itself."
    },
    "manualReview": [
      "wallet backup and restore surfaces",
      "Spark or Breez SDK adapters and pinned dependency versions",
      "settings, recovery, receive, send, and withdrawal entry points",
      "candidate matches returned by the discovery search",
      "release notes and first-party recovery instructions"
    ],
    "binaryReview": "For Club Orange, the published APK was hashed, its DEX files and arm64 Breez Spark binding were extracted, exported UniFFI metadata was enumerated, and targeted DEX and native-string searches were run.",
    "closedSourceReview": "For Wallet of Satoshi and Bringin, the review is limited to public documentation, source availability, release records, and disclosed product procedures. It is not a source-code absence claim.",
    "limitations": [
      "This is a static source, binary-surface, and public-record review; it is not a runtime unilateral-exit test.",
      "Absence searches cannot mathematically prove non-existence; indirect names, reflection, or obfuscation can evade them.",
      "Transitive package, framework, Pod, and native FFI implementations were not unpacked unless present in the reviewed application archive or published binary.",
      "The finding concerns user-facing product orchestration. A library containing lower-level primitives does not by itself establish an accessible consumer workflow.",
      "Results apply only to the named snapshots and can change in later releases."
    ]
  },
  "overallResult": {
    "reviewedProducts": 8,
    "completeInAppFlowsFound": 0,
    "partialCapabilitiesFound": [
      "Blitz 0.7.13 pre-release can refresh and export a Spark unilateral-exit bundle, then directs the user to a separate developer repository.",
      "Club Orange's APK contains lower-level Breez Spark unilateral-exit implementation strings, but the 46 exported BreezSdk method names expose no unilateral-exit or recovery operation.",
      "The other reviewed wallets expose ordinary seed backup, live-network restore, Spark payments, or cooperative withdrawal capabilities that are not the complete outage-exit workflow defined above."
    ],
    "boundedConclusion": "At the named snapshots, no complete in-app workflow satisfying all eight stages was found in the reviewed public source, published binary, or public product surfaces.",
    "nonConclusion": "This audit is limited to the named public sources and published artifacts. It cannot rule out obfuscated functionality, later releases, unavailable code, or separately engineered tools."
  },
  "targets": [
    {
      "id": "blink-mobile",
      "product": "Blink",
      "surface": "public-mobile-source",
      "repository": "https://github.com/blinkbitcoin/blink-mobile",
      "commit": "3f3108998b1db6bf55823284e932ff6313eea496",
      "reviewedScope": [
        "tracked application source",
        "Breez Spark dependency declaration",
        "cloud and credential backup",
        "cloud and manual restore"
      ],
      "manuallyReviewedEntryPoints": [
        "app/self-custodial/bridge/**",
        "wallet providers",
        "onboarding backup and restore",
        "app/utils/backup-payload.ts"
      ],
      "result": {
        "completeInAppFlowFound": false,
        "partialCapabilities": [
          "mnemonic backup and restore",
          "ordinary Breez Spark wallet operations"
        ],
        "finding": "The tracked app backup and restore paths center on the mnemonic; no complete recovery-bundle export and operatorless execution workflow was found. Blink's separate recovery repository labels mobile integration a proposed boundary."
      },
      "supportingRecords": [
        "https://github.com/blinkbitcoin/blink-mobile/tree/3f3108998b1db6bf55823284e932ff6313eea496",
        "https://github.com/blinkbitcoin/spark-unilateral-exit/blob/d47fe9b209cf57ca26a6fd7a855ef47388384182/docs/mobile-integration-plan.md"
      ],
      "canonicalSearchResult": {
        "patternId": "canonical-exit-terms",
        "matches": 0,
        "matchingLines": 0,
        "matchingFiles": 0
      },
      "limitations": [
        "The separate Blink command-line recovery project is not treated as an in-app mobile workflow.",
        "A later Blink release could add the proposed integration."
      ]
    },
    {
      "id": "primal-mobile",
      "product": "Primal",
      "surface": "public-android-and-ios-source",
      "snapshots": [
        {
          "repository": "https://github.com/PrimalHQ/primal-android-app",
          "commit": "c16997628c5111e56ac8b98b49d4297f5d52e480"
        },
        {
          "repository": "https://github.com/PrimalHQ/primal-ios-app",
          "commit": "91787a1209bd13f57afcb5fe100783102feae2fb"
        }
      ],
      "reviewedScope": [
        "tracked Android and iOS application source",
        "Breez Spark integration and dependency declaration",
        "Primal iOS declaration of the compiled PrimalShared.xcframework dependency",
        "seed backup and restore UI",
        "wallet settings and transaction entry points"
      ],
      "manuallyReviewedEntryPoints": [
        "Android SparkWalletServiceImpl.kt",
        "Android RestoreSparkWalletUseCase and backup ViewModel",
        "iOS wallet backup and restore UI",
        "iOS WalletManager.restoreWalletFromSeed"
      ],
      "result": {
        "completeInAppFlowFound": false,
        "partialCapabilities": [
          "seed backup and live-network wallet restore",
          "ordinary Breez Spark wallet operations"
        ],
        "finding": "No source-visible recovery-bundle handling or complete operatorless package-broadcast, monitoring, refund, and sweep UI flow was found in either pinned application."
      },
      "supportingRecords": [
        "https://github.com/PrimalHQ/primal-android-app/tree/c16997628c5111e56ac8b98b49d4297f5d52e480",
        "https://github.com/PrimalHQ/primal-ios-app/tree/91787a1209bd13f57afcb5fe100783102feae2fb"
      ],
      "canonicalSearchResults": [
        {
          "snapshot": "android-c16997628c511",
          "patternId": "canonical-exit-terms",
          "matches": 0,
          "matchingLines": 0,
          "matchingFiles": 0
        },
        {
          "snapshot": "ios-91787a1209bd",
          "patternId": "canonical-exit-terms",
          "matches": 0,
          "matchingLines": 0,
          "matchingFiles": 0
        }
      ],
      "limitations": [
        "The result is bounded to the two pinned public repositories and does not test an unpublished build.",
        "Primal iOS pins a compiled PrimalShared.xcframework 0.2.0 dependency whose internals are not present in the public application tree; the finding is therefore source-visible app and UI scope, not a full transitive-binary audit.",
        "Seed restore while Spark services are available is not evidence of outage recovery."
      ]
    },
    {
      "id": "cake-wallet",
      "product": "Cake Wallet",
      "surface": "public-mobile-source",
      "repository": "https://github.com/cake-tech/cake_wallet",
      "commit": "bff9b2fa9648b22c2fcc84062caba58861e9d24f",
      "reviewedScope": [
        "tracked application source",
        "LightningWallet adapter",
        "Breez Spark Flutter 0.14.0 dependency",
        "backup, restore, send, receive, and withdrawal entry points"
      ],
      "manuallyReviewedEntryPoints": [
        "cw_bitcoin/lib/lightning/lightning_wallet.dart",
        "Cake backup and restore entry points",
        "Spark, Lightning, and cooperative Bitcoin-address send adapters"
      ],
      "result": {
        "completeInAppFlowFound": false,
        "partialCapabilities": [
          "mnemonic or seed initialization",
          "Spark, Lightning, and cooperative Bitcoin-address payments"
        ],
        "finding": "No recovery-bundle handling or complete unilateral-exit product flow was found at the pinned snapshot. Breez's public mobile exit API targeted for this dependency generation had not shipped."
      },
      "supportingRecords": [
        "https://github.com/cake-tech/cake_wallet/tree/bff9b2fa9648b22c2fcc84062caba58861e9d24f",
        "https://github.com/cake-tech/cake_wallet/blob/bff9b2fa9648b22c2fcc84062caba58861e9d24f/cw_bitcoin/pubspec.yaml#L72-L75",
        "https://github.com/breez/spark-sdk/issues/374",
        "https://blog.cakewallet.com/our-lightning-journey/"
      ],
      "canonicalSearchResult": {
        "patternId": "canonical-exit-terms",
        "matches": 0,
        "matchingLines": 0,
        "matchingFiles": 0
      },
      "limitations": [
        "The public Cake article describes a protocol-level response to an attack; it does not expressly claim that the audited UI contains an exit button.",
        "The result is limited to the pinned Cake tree and its pinned dependency."
      ]
    },
    {
      "id": "blitz-wallet",
      "product": "Blitz Wallet",
      "surface": "public-mobile-source",
      "repository": "https://github.com/BlitzWallet/BlitzWallet",
      "commit": "173298bae4cb650fde4681ee7398d2e651bfbdae",
      "reviewedScope": [
        "tracked application source",
        "Spark leaf and ancestor storage",
        "unilateral-exit bundle export",
        "recovery instructions and execution entry points"
      ],
      "manuallyReviewedEntryPoints": [
        "exportLeavesProgress.js",
        "leaves/index.js",
        "app/functions/spark/index.js",
        "leavesStorage.js",
        "sparkContext.js"
      ],
      "result": {
        "completeInAppFlowFound": false,
        "partialCapabilities": [
          "best-effort online refresh of eligible leaf ancestry",
          "spark.unilateral-exit-bundle.v1 export through the device share sheet",
          "links to external Blink and Spark recovery documentation"
        ],
        "finding": "The pre-release adds a meaningful exit-state exporter, but the app does not itself fund CPFP children, construct and broadcast the full sequence, persist confirmation progress, wait through timelocks, broadcast refunds, or sweep final outputs."
      },
      "supportingRecords": [
        "https://github.com/BlitzWallet/BlitzWallet/tree/173298bae4cb650fde4681ee7398d2e651bfbdae",
        "https://github.com/BlitzWallet/BlitzWallet/pull/999",
        "https://github.com/BlitzWallet/BlitzWallet/releases/tag/Android-v0.7.13-pre6"
      ],
      "canonicalSearchResult": {
        "patternId": "canonical-exit-terms",
        "wholeArchive": {
          "matches": 29,
          "matchingLines": 28,
          "matchingFiles": 14
        },
        "productionAfterExcludingLocalesGeneratedWebviewAndTests": {
          "matches": 18,
          "matchingLines": 18,
          "matchingFiles": 5
        },
        "productionFilter": {
          "excludedGlobs": [
            "locales/**",
            "android/app/src/main/assets/sparkContext.html",
            "__tests__/**"
          ],
          "command": "rg -uuu -i -e \"$PATTERN\" -g '!locales/**' -g '!android/app/src/main/assets/sparkContext.html' -g '!__tests__/**' ."
        },
        "productionMatchingFiles": [
          "app/components/admin/homeComponents/settingsContent/leaves/exportLeavesProgress.js",
          "app/components/admin/homeComponents/settingsContent/leaves/index.js",
          "app/functions/spark/index.js",
          "app/functions/spark/leavesStorage.js",
          "context-store/sparkContext.js"
        ]
      },
      "limitations": [
        "Bundle export is a real prerequisite and is not characterized as useless.",
        "The audited pre-release can be extended with an in-app executor later."
      ]
    },
    {
      "id": "radar-mobile",
      "product": "Radar",
      "surface": "public-android-and-ios-source",
      "snapshots": [
        {
          "repository": "https://github.com/radar-labs/radar-android",
          "commit": "8ca3e2b147fa32648afb04f8a42c4dd4b7db9eda"
        },
        {
          "repository": "https://github.com/radar-labs/Radar",
          "commit": "661a39cce1b9d270b6ae9d0914c15a836d103668"
        }
      ],
      "reviewedScope": [
        "tracked Android and iOS application source",
        "Breez Spark 0.18.0 dependency records",
        "seed recovery UI",
        "wallet send, receive, backup, and settings entry points"
      ],
      "manuallyReviewedEntryPoints": [
        "Android BreezSdkWrapper.kt and recovery UI",
        "iOS SignalUI/Payments",
        "iOS SignalServiceKit/Payments",
        "iOS payment settings and recovery UI"
      ],
      "result": {
        "completeInAppFlowFound": false,
        "partialCapabilities": [
          "seed backup and live-network restoration in a Spark-compatible wallet",
          "ordinary Breez Spark wallet operations"
        ],
        "finding": "Neither pinned app exposed current-exit-state export or the complete CPFP, ordered package, durable monitoring, timelock, refund, and sweep workflow."
      },
      "supportingRecords": [
        "https://github.com/radar-labs/radar-android/tree/8ca3e2b147fa32648afb04f8a42c4dd4b7db9eda",
        "https://github.com/radar-labs/Radar/tree/661a39cce1b9d270b6ae9d0914c15a836d103668",
        "https://github.com/radar-labs/radar-android/blob/8ca3e2b147fa32648afb04f8a42c4dd4b7db9eda/gradle/libs.versions.toml#L191",
        "https://github.com/radar-labs/Radar/blob/661a39cce1b9d270b6ae9d0914c15a836d103668/ThirdParty/BreezSdkSpark.podspec.json#L1-L21"
      ],
      "canonicalSearchResults": [
        {
          "snapshot": "android-8ca3e2b147fa",
          "patternId": "canonical-exit-terms",
          "matches": 0,
          "matchingLines": 0,
          "matchingFiles": 0
        },
        {
          "snapshot": "ios-661a39cce1b9",
          "patternId": "canonical-exit-terms",
          "matches": 0,
          "matchingLines": 0,
          "matchingFiles": 0
        }
      ],
      "limitations": [
        "The result is bounded to the two pinned public repositories.",
        "The Radar iOS codeload archive did not contain the Breez FFI binary or Pods submodule; its result is limited to the application's source-visible integration and UI, not a full transitive-binary audit.",
        "The audit does not assert that a future mobile implementation is impossible."
      ]
    },
    {
      "id": "club-orange-android-4.1.8",
      "product": "Club Orange",
      "surface": "published-android-apk",
      "repository": "https://github.com/ClubOrangeBitcoin/ClubOrange-releases",
      "release": "v4.1.8",
      "releaseCommit": "974c266dde1a0b1d2a9e4024b418b6f292bfc6d7",
      "artifact": "https://github.com/ClubOrangeBitcoin/ClubOrange-releases/releases/download/v4.1.8/ClubOrange.apk",
      "bytes": 321875805,
      "sha256": "2b362ffbf25169123a4f3addcdd3c8ce3d9763b81bbb558ea5c91891cfdf9b41",
      "reviewedScope": [
        "published 4.1.8 Android artifact and GitHub release metadata",
        "all five DEX files",
        "arm64 Breez Spark native binding",
        "exported BreezSdk UniFFI method metadata",
        "targeted exit-flow strings"
      ],
      "tools": [
        {
          "name": "sha256sum",
          "version": "GNU coreutils 9.4"
        },
        {
          "name": "unzip",
          "version": "Info-ZIP 6.00"
        },
        {
          "name": "strings",
          "version": "GNU Binutils 2.42"
        },
        {
          "name": "nm",
          "version": "GNU Binutils 2.42"
        },
        {
          "name": "ripgrep",
          "version": "15.1.0"
        }
      ],
      "commands": [
        "sha256sum ClubOrange.apk && stat -c '%s' ClubOrange.apk",
        "unzip -qq ClubOrange.apk 'classes*.dex' 'lib/arm64-v8a/libbreez_sdk_spark_bindings.so'",
        "nm -D --defined-only lib/arm64-v8a/libbreez_sdk_spark_bindings.so | sed -n 's/.*UNIFFI_META_BREEZ_SDK_SPARK_METHOD_BREEZSDK_//p' | sort -u",
        "strings -a classes*.dex | rg -i '(unilateral[ _-]?exit|recovery[ _-]?bundle|emergency[ _-]?exit|prepare_unilateral_exit|constructUnilateralExit|buildUnilateralExit|submitpackage|operatorless[ _-]?exit|exit[ _-]?package|cpfp.{0,40}sweep|timelock.{0,40}sweep|refund.{0,40}sweep)' | sort -u",
        "strings -a lib/arm64-v8a/libbreez_sdk_spark_bindings.so | rg -i 'unilateral'"
      ],
      "outputs": {
        "breezSdkExportedMethodCount": 46,
        "breezSdkExportedMethods": [
          "ADD_CONTACT",
          "ADD_EVENT_LISTENER",
          "AUTHORIZE_LIGHTNING_ADDRESS_TRANSFER",
          "BUY_BITCOIN",
          "CHECK_LIGHTNING_ADDRESS_AVAILABLE",
          "CHECK_MESSAGE",
          "CLAIM_DEPOSIT",
          "CLAIM_HTLC_PAYMENT",
          "CLAIM_LIGHTNING_ADDRESS_TRANSFER",
          "DELETE_CONTACT",
          "DELETE_LIGHTNING_ADDRESS",
          "DISCONNECT",
          "FETCH_CONVERSION_LIMITS",
          "GET_CROSS_CHAIN_ROUTES",
          "GET_INFO",
          "GET_LIGHTNING_ADDRESS",
          "GET_PAYMENT",
          "GET_TOKENS_METADATA",
          "GET_TOKEN_ISSUER",
          "GET_USER_SETTINGS",
          "LIST_CONTACTS",
          "LIST_FIAT_CURRENCIES",
          "LIST_FIAT_RATES",
          "LIST_PAYMENTS",
          "LIST_UNCLAIMED_DEPOSITS",
          "LIST_WEBHOOKS",
          "LNURL_AUTH",
          "LNURL_PAY",
          "LNURL_WITHDRAW",
          "OPTIMIZE_LEAVES",
          "PARSE",
          "PREPARE_LNURL_PAY",
          "PREPARE_SEND_PAYMENT",
          "RECEIVE_PAYMENT",
          "RECOMMENDED_FEES",
          "REFUND_DEPOSIT",
          "REFUND_PENDING_CONVERSIONS",
          "REGISTER_LIGHTNING_ADDRESS",
          "REGISTER_WEBHOOK",
          "REMOVE_EVENT_LISTENER",
          "SEND_PAYMENT",
          "SIGN_MESSAGE",
          "SYNC_WALLET",
          "UNREGISTER_WEBHOOK",
          "UPDATE_CONTACT",
          "UPDATE_USER_SETTINGS"
        ],
        "exportedMethodNamesContainingUnilateralExitOrRecovery": 0,
        "targetedDexExitStringMatches": 0,
        "nativeLowerLevelExitCodePresent": true,
        "nativeExamples": [
          "spark::services::unilateral_exit::UnilateralExitService",
          "spark::services::unilateral_exit::create_tx_cpfp_psbt",
          "maximize_unilateral_exit"
        ]
      },
      "result": {
        "completeInAppFlowFound": false,
        "partialCapabilities": [
          "the bundled native library contains lower-level unilateral-exit primitives"
        ],
        "finding": "No unilateral-exit, exit, or recovery operation appears in the 46 exported BreezSdk method names, and the targeted DEX search found no corresponding user-flow strings. The bundled native library nevertheless contains lower-level unilateral-exit primitives."
      },
      "supportingRecords": [
        "https://github.com/ClubOrangeBitcoin/ClubOrange-releases/releases/tag/v4.1.8"
      ],
      "limitations": [
        "Symbol and string searches cannot prove the absence of obfuscated or indirectly invoked private code.",
        "Native primitives establish that the SDK contains lower-level capability; they do not establish an app-facing execution workflow.",
        "The finding is limited to the named published artifact and recorded searches; it does not assess later versions."
      ]
    },
    {
      "id": "wallet-of-satoshi",
      "product": "Wallet of Satoshi",
      "surface": "public-documentation-and-source-availability",
      "application": {
        "androidPackage": "com.livingroomofsatoshi.wallet",
        "sourcePublished": false
      },
      "reviewedScope": [
        "Disclosure Document 1.22 updated 2026-07-01",
        "official website recovery material",
        "Google Play product record",
        "publicly available consumer exit instructions"
      ],
      "result": {
        "completeInAppFlowFound": false,
        "partialCapabilities": [
          "published description of unilateral exit as a permissionless alternative",
          "seed-backup and ordinary wallet-restore guidance"
        ],
        "finding": "No published consumer procedure was found for exporting current exit state and executing the complete operatorless workflow. Because the app is closed source, this is a public-verifiability and documented-product finding only."
      },
      "supportingRecords": [
        "https://walletofsatoshi.com/disclosure",
        "https://play.google.com/store/apps/details?id=com.livingroomofsatoshi.wallet"
      ],
      "limitations": [
        "No source-code absence claim is made.",
        "Private application code or a later product release may contain capabilities not documented publicly.",
        "The finding is limited to the cited disclosure and publicly accessible product records; it does not assess unavailable application code."
      ]
    },
    {
      "id": "bringin-v2",
      "product": "Bringin",
      "surface": "public-documentation-and-source-availability",
      "application": {
        "androidPackage": "xyz.bringin.client",
        "iosAppId": "6503239911",
        "sourcePublished": false
      },
      "reviewedScope": [
        "2026-06-17 v2 launch article",
        "public GitHub organization",
        "mobile app-store product records",
        "publicly available consumer exit instructions"
      ],
      "result": {
        "completeInAppFlowFound": false,
        "partialCapabilities": [
          "first-party claim that each wallet ships with pre-signed exits and can leave without Bringin cooperation"
        ],
        "finding": "Bringin's public organization did not contain the mobile application, and the reviewed launch and product material supplied no operational procedure for the eight-stage workflow. This does not test private application code."
      },
      "supportingRecords": [
        "https://bringin.app/blog/bitcoin-payments-app-in-europe",
        "https://github.com/bringinxyz",
        "https://play.google.com/store/apps/details?id=xyz.bringin.client",
        "https://apps.apple.com/es/app/bringin-buy-spend-bitcoin/id6503239911"
      ],
      "limitations": [
        "No source-code absence claim is made because Bringin does not publish the reviewed mobile-app source.",
        "The public-record gap does not prove that a private implementation does not exist."
      ]
    }
  ]
}
