Bitcoin wallet for iOS & Android. Built with React Native
This report summarizes scanner evidence for BlueWallet/BlueWallet, a TypeScript project with 3,342 GitHub stars. SynthScan examined 197,632 lines of code across 1200 source files, recording 165 pattern matches distributed across 9 syntactic categories. The legacy adjusted pattern signal is 0.9 (Low pattern signal); it is not an authorship estimate.
Use the findings to ask whether maintainers can explain intent, verify dependencies, simplify unnecessary scaffolding, and focus review effort. Risk Payload v1 adds ownership, supply-chain, over-engineering, and review-effort vectors when available. These are prompts for human verification, not probabilities, security findings, or measured maintenance costs.
Use each vector to guide manual verification of the underlying findings.
Payload schema: 1.0.0 · Engine: 2.0.0 · Scoring: heuristic-density-v1 · Scan date: 2026-10-31.
Can maintainers explain intent, assumptions, and trade-offs? 83 finding(s).
Are imports declared and package/API names verified? 73 finding(s).
Are wrappers, guards, and repeated structures necessary? 53 finding(s).
Which changes need focused human review? 165 finding(s).
This chart tracks the legacy adjusted pattern score across scan runs. Changes can reflect source changes, scan coverage, or detector/scoring versions; they do not measure AI adoption or prove that a team refactored code. Compare runs only when their scoring versions are compatible. The dashed line tracks the raw pattern-hit count.
Groups findings by configured severity weight. Severity is not a confidence estimate, security rating, or proof that a package is missing. Verify imports against the project's manifests and inspect each finding in its local design context.
This horizontal bar chart shows where configured pattern scores accumulate across directories. Treat the bars as locations to inspect, not as evidence of authorship or code quality. Use the file-level findings to decide whether a directory needs a focused ownership, dependency, complexity, or review check.
The scanner identified 165 distinct pattern matches across 9 syntactic categories. Each entry below represents a discrete location in the source code where the engine recorded a detector match to inspect in context. Expand any category row to inspect the individual file paths, line numbers, code snippets, and the lexical context (CODE, COMMENT, or STRING) in which each match was detected.
Reading the findings table: The Severity column indicates the configured finding weight (CRITICAL / HIGH / MEDIUM / LOW). The Context column identifies whether the match occurred inside executable code, an inline comment, or a string literal — legacy comment-context matches receive a ×1.5 score weight. The ⚡ bolt icon marks clustered matches: three or more patterns within a 10-line window, each receiving an additional ×1.5 density multiplier under the legacy scoring model.
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | loc/id_id.json | 62 | "placeholder": "Faktur atau alamat", | CODE |
| LOW | loc/hy.json | 62 | "placeholder": "Հաշիվ-ֆակտուրա կամ հասցե", | CODE |
| LOW | loc/tr_tr.json | 62 | "placeholder": "Fatura veya adres", | CODE |
| LOW | loc/ua.json | 62 | "placeholder": "Рахунок або адреса", | CODE |
| LOW | loc/hu_hu.json | 62 | "placeholder": "Számla", | CODE |
| LOW | loc/es_419.json | 60 | "placeholder": "Factura o dirección", | CODE |
| LOW | loc/pt_pt.json | 62 | "placeholder": "Fatura ou endereço", | CODE |
| LOW | loc/sv_se.json | 62 | "placeholder": "Faktura eller adress", | CODE |
| LOW | loc/bn.json | 62 | "placeholder": "ইনভয়েস বা ঠিকানা", | CODE |
| LOW | loc/fo.json | 62 | "placeholder": "Gjaldsumbøn ella adressa", | CODE |
| LOW | loc/ko_KR.json | 62 | "placeholder": "인보이스 또는 주소", | CODE |
| LOW | loc/ms.json | 62 | "placeholder": "Invois atau alamat", | CODE |
| LOW | loc/zh_cn.json | 60 | "placeholder": "发票或地址", | CODE |
| LOW | loc/bg_bg.json | 62 | "placeholder": "Фактура или адрес", | CODE |
| LOW | loc/ru.json | 62 | "placeholder": "Инвойс или адрес", | CODE |
| LOW | loc/pl.json | 60 | "placeholder": "Faktura lub adres", | CODE |
| LOW | loc/et_EE.json | 62 | "placeholder": "Arve või aadress", | CODE |
| LOW | loc/th_th.json | 62 | "placeholder": "ใบแจ้งหนี้หรือแอดเดรส", | CODE |
| LOW | loc/zar_afr.json | 62 | "placeholder": "Faktuur of adres", | CODE |
| LOW | loc/kk@Cyrl.json | 62 | "placeholder": "Шот немесе мекенжай", | CODE |
| LOW | loc/ur.json | 62 | "placeholder": "انوائس یا پتہ", | CODE |
| LOW | loc/az.json | 62 | "placeholder": "Faktura və ya ünvan", | CODE |
| LOW | loc/en.json | 60 | "placeholder": "Invoice or address", | CODE |
| LOW | loc/ka.json | 62 | "placeholder": "ინვოისი ან მისამართი", | CODE |
| LOW | loc/pa.json | 62 | "placeholder": "ਇਨਵੌਇਸ ਜਾਂ ਪਤਾ", | CODE |
| LOW | loc/st_ZA.json | 62 | "placeholder": "Invoisi kapa aterese", | CODE |
| LOW | loc/km.json | 62 | "placeholder": "វិក្កយបត្រ ឬអាសយដ្ឋាន", | CODE |
| LOW | loc/sr_RS.json | 62 | "placeholder": "Faktura ili adresa", | CODE |
| LOW | loc/it.json | 62 | "placeholder": "Fattura o indirizzo", | CODE |
| LOW | loc/fi_fi.json | 62 | "placeholder": "Lasku", | CODE |
| LOW | loc/kn.json | 62 | "placeholder": "ಸರಕುಪಟ್ಟಿ ಅಥವಾ ವಿಳಾಸ", | CODE |
| LOW | loc/pcm.json | 62 | "placeholder": "Invoice or address abeg", | CODE |
| LOW | loc/cy.json | 62 | "placeholder": "Anfoneb neu gyfeiriad", | CODE |
| LOW | loc/gug_PY.json | 62 | "placeholder": "Factura térã renda", | CODE |
| LOW | loc/ne.json | 62 | "placeholder": "इनभ्वाइस वा ठेगाना", | CODE |
| LOW | loc/vi_vn.json | 62 | "placeholder": "Hóa đơn hoặc địa chỉ", | CODE |
| LOW | loc/am.json | 62 | "placeholder": "ደረሰኝ ወይም አድራሻ", | CODE |
| LOW | loc/zar_xho.json | 62 | "placeholder": "Invoyisi okanye idilesi", | CODE |
| LOW | loc/sq_AL.json | 62 | "placeholder": "Fatura ose adresa", | CODE |
| LOW | loc/el.json | 62 | "placeholder": "Τιμολόγιο ή διεύθυνση", | CODE |
| LOW | loc/ro.json | 62 | "placeholder": "Factură sau adresă", | CODE |
| LOW | loc/ff.json | 62 | "placeholder": "Faktiir maa adreesi", | CODE |
| LOW | loc/hi.json | 62 | "placeholder": "इनवॉइस या पता", | CODE |
| LOW | loc/ca.json | 62 | "placeholder": "Factura o adreça", | CODE |
| LOW | loc/sl_SI.json | 62 | "placeholder": "Račun ali naslov", | CODE |
| LOW | loc/si_LK.json | 62 | "placeholder": "ඉන්වොයිසිය හෝ ලිපිනය", | CODE |
| LOW | loc/nl_nl.json | 62 | "placeholder": "Factuur of adres", | CODE |
| LOW | loc/eu.json | 62 | "placeholder": "Faktura edo helbidea", | CODE |
| LOW | loc/fil_PH.json | 62 | "placeholder": "Invoice o address", | CODE |
| LOW | loc/he.json | 62 | "placeholder": "חשבונית או כתובת", | CODE |
| LOW | loc/nb_no.json | 62 | "placeholder": "Faktura eller adresse", | CODE |
| LOW | loc/fa.json | 62 | "placeholder": "صورتحساب یا آدرس", | CODE |
| LOW | loc/da_dk.json | 62 | "placeholder": "Faktura eller adresse", | CODE |
| LOW | loc/hak.json | 62 | "placeholder": "發票抑係地址", | CODE |
| LOW | loc/bqi.json | 62 | "placeholder": "سۊرت هساو یا آدرس", | CODE |
| LOW | loc/de_de.json | 62 | "placeholder": "Rechnung oder Adresse", | CODE |
| LOW | loc/pt_br.json | 62 | "placeholder": "Fatura ou endereço", | CODE |
| LOW | loc/zh_tw.json | 62 | "placeholder": "發票或地址", | CODE |
| LOW | loc/lv.json | 62 | "placeholder": "Rēķins vai adrese", | CODE |
| LOW | loc/fr_fr.json | 62 | "placeholder": "Facture ou adresse", | CODE |
| 13 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | loc/index.ts | 505 | export function formatBalanceWithoutSuffix(balance = 0, toUnit: string, withFormatting = false): string | number { | CODE |
| LOW | loc/index.ts | 551 | export function formatStringAddTwoWhiteSpaces(text: string): string { | CODE |
| LOW | tests/e2e/helperz.js | 203 | export async function extractTextFromElementById(id) { | CODE |
| LOW | tests/e2e/helperz.js | 273 | export async function tapAndTapAgainIfElementIsNotVisible(idToTap, idToCheckVisible) { | CODE |
| LOW | tests/e2e/helperz.js | 299 | export async function tapAndTapAgainIfTextIsNotVisible(textToTap, textToCheckVisible) { | CODE |
| LOW | tests/e2e/helperz.js | 494 | export async function restoreSynchronizationIfAnimatedQrClosed(timeoutMs = 2_000) { | CODE |
| LOW | tests/helpers/arkadeMocks.ts | 64 | export function clearArkadeMockCallHistory(): void { | CODE |
| LOW | tests/helpers/sdkProviderMocks.ts | 116 | export function restoreSdkBackgroundLoopStubs(): void { | CODE |
| LOW | tests/helpers/sdkProviderMocks.ts | 127 | export function installSdkBackgroundLoopStubs(): void { | CODE |
| LOW | navigation/goFromCoinControlToSendDetails.ts | 13 | export function goFromCoinControlToSendDetails( | CODE |
| LOW | components/Context/recentMenuItems.ts | 98 | export function removeRecentMenuItemsForWallets(walletIDs: ReadonlySet<string>): void { | CODE |
| LOW | components/Context/recentMenuItems.ts | 113 | export function setAvailableRecentWalletIDs(walletIDs: ReadonlySet<string>): void { | CODE |
| LOW | components/Context/recentMenuItems.ts | 119 | export async function setRecentMenuItemsEnabled(value: boolean): Promise<void> { | CODE |
| LOW | components/Context/recentMenuItems.ts | 142 | export function subscribeToRecentMenuItems(listener: () => void): () => void { | CODE |
| LOW | hooks/useMenuActions.native.ts | 93 | export function setNativeMenuWalletsInitialized(initialized: boolean): void { | CODE |
| LOW | hooks/useClipboardDetection.ts | 29 | function pushClipboardDetectedSheet(params: { payload: string; kind: ClipboardPaymentKind; contentHash: string }): boole | CODE |
| LOW | hooks/useMenuActions.ts | 6 | export function setNativeMenuWalletsInitialized(_initialized: boolean): void {} | CODE |
| LOW | screen/transactions/TransactionStatus.tsx | 57 | async function populateVinValuesFromPrevTxs(fetchedTx: ElectrumTransaction): Promise<void> { | CODE |
| LOW | reproducible-builds/apkdiff/tests/test_utils.py | 11 | def test_identical_objects_return_empty_dict(self): | CODE |
| LOW | reproducible-builds/apkdiff/tests/test_utils.py | 17 | def test_primitive_value_and_type_mismatches(self): | CODE |
| LOW | reproducible-builds/apkdiff/tests/test_utils.py | 30 | def test_sequences_lists_and_tuples(self): | CODE |
| LOW | reproducible-builds/apkdiff/tests/test_utils.py | 80 | def test_exclude_attributes_and_callables(self): | CODE |
| LOW⚡ | reproducible-builds/apkdiff/tests/test_utils.py | 105 | def test_show_diffs_flat_dictionary(self): | CODE |
| LOW⚡ | reproducible-builds/apkdiff/tests/test_utils.py | 115 | def test_show_diffs_with_list_data(self): | CODE |
| LOW⚡ | reproducible-builds/apkdiff/tests/test_utils.py | 123 | def test_show_diffs_nested_dictionary_indentation(self): | CODE |
| LOW⚡ | reproducible-builds/apkdiff/tests/test_utils.py | 130 | def test_show_diffs_empty_dict(self): | CODE |
| LOW⚡ | reproducible-builds/apkdiff/tests/test_utils.py | 136 | def test_integration_deep_compare_and_show_diffs(): | CODE |
| LOW | blue_modules/arkade-notifications.ts | 39 | export function ensureArkNotificationChannel(): void { | CODE |
| LOW | blue_modules/arkade-notifications.ts | 82 | async function isOsNotificationPermissionGranted(): Promise<boolean> { | CODE |
| LOW | blue_modules/arkade-background.ts | 310 | export function onArkBackgroundTaskTimeout(taskId: string): void { | CODE |
| LOW | blue_modules/arkade-background.ts | 324 | export async function registerArkBackgroundTask(): Promise<void> { | CODE |
| LOW | blue_modules/arkade-background.ts | 377 | export function reconcileArkBackgroundTaskResults(triggerRefreshForWallet: (walletId: string) => void): void { | CODE |
| LOW | blue_modules/currency.ts | 290 | async function restoreSavedPreferredFiatCurrencyAndExchangeFromStorage(): Promise<void> { | CODE |
| LOW | blue_modules/clipboardPayment.ts | 119 | export function isClipboardPaymentFromOwnWallet(payload: string, wallets: ClipboardOwnershipWallet[]): boolean { | CODE |
| LOW | blue_modules/clipboardPayment.ts | 137 | export function evaluateClipboardOnForeground( | CODE |
| LOW | blue_modules/clipboardPayment.ts | 175 | export function clipboardActionOnAppStateChange({ | CODE |
| LOW | blue_modules/bip39WordSuggestions.ts | 79 | function hasCharacterOutsideLatinExtendedB(text: string): boolean { | CODE |
| LOW | blue_modules/bip39WordSuggestions.ts | 146 | export function getImportWalletSuggestions(text: string, cursor: number): string[] { | CODE |
| LOW | blue_modules/BlueElectrum.ts | 342 | function scheduleReconnectFromClient(client: typeof ElectrumClient, usingPeer: Peer, reason: string): void { | CODE |
| LOW | blue_modules/BlueElectrum.ts | 588 | export async function presentResetToDefaultsAlert(): Promise<boolean> { | CODE |
| LOW | blue_modules/BlueElectrum.ts | 703 | export async function presentElectrumDisconnectedHelpAlert(): Promise<void> { | CODE |
| LOW | blue_modules/BlueElectrum.ts | 822 | export function txhexToElectrumTransaction(txhex: string): ElectrumTransactionWithHex { | CODE |
| LOW | blue_modules/payjoin-client/utils.ts | 33 | export function getInputsScriptPubKeyType(psbt: Psbt): ScriptPubKeyType { | CODE |
| LOW | blue_modules/arkade-adapters/realm/realmInstance.ts | 38 | async function loadOrCreateEncryptionKey(namespace: string): Promise<Uint8Array> { | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | tests/setup.js | 261 | // | COMMENT |
| LOW | tests/unit/lightning-ark-derivation.test.ts | 21 | // ASP `unilateralExitDelay`. | COMMENT |
| LOW | tests/unit/lightning-ark-derivation.test.ts | 101 | it('locks the namespace value so a derivation tweak cannot silently re-key Realm', () => { | COMMENT |
| LOW | tests/unit/lightning-ark-derivation.test.ts | 121 | // | COMMENT |
| LOW | tests/helpers/sdkProviderMocks.ts | 81 | COMMENT | |
| LOW | ios/BlueWallet-Bridging-Header.h | 1 | // | COMMENT |
| LOW | components/TooltipMenu.tsx | 41 | ); | COMMENT |
| LOW | screen/lnd/lndViewInvoice.tsx | 41 | const [invoiceStatusChanged, setInvoiceStatusChanged] = useState<boolean>(false); | COMMENT |
| LOW | scripts/find-english-leftovers.js | 1 | // Lints loc/*.json for keys whose translated value still equals the English source. | COMMENT |
| LOW | scripts/clean-loc-strings.js | 1 | // Removes useless entries (and resulting empty sections) from every locale | COMMENT |
| LOW | class/wallet-import.ts | 121 | COMMENT | |
| LOW | class/wallets/lightning-ark-wallet.ts | 81 | public readonly typeReadable = LightningArkWallet.typeReadable; | COMMENT |
| LOW | class/wallets/lightning-ark-wallet.ts | 561 | } else { | COMMENT |
| LOW | class/wallets/lightning-ark-wallet.ts | 661 | // settles its boarding UTXO into a VTXO — the same moment its history row | COMMENT |
| LOW | blue_modules/arkade-notifications.ts | 1 | // Local-notification posting for actionable Ark swaps. Imported from headless | COMMENT |
| LOW | blue_modules/arkade-background.ts | 1 | // Background task module for Ark swap monitoring. | COMMENT |
| LOW | blue_modules/transactionDisplayState.ts | 1 | import type { LightningTransaction, Transaction } from '../class/wallets/types'; | COMMENT |
| LOW | blue_modules/pako/lib/zlib/constants.js | 1 | 'use strict'; | COMMENT |
| LOW | blue_modules/pako/lib/zlib/inflate.js | 1 | 'use strict'; | COMMENT |
| LOW | blue_modules/pako/lib/zlib/inflate.js | 1321 | break; | COMMENT |
| LOW | blue_modules/pako/lib/zlib/deflate.js | 1 | 'use strict'; | COMMENT |
| LOW | blue_modules/pako/lib/zlib/deflate.js | 441 | * time through here. WIN_INIT is set to MAX_MATCH since the longest match | COMMENT |
| LOW | blue_modules/pako/lib/zlib/deflate.js | 461 | // * to end of window, whichever is less. | COMMENT |
| LOW | blue_modules/pako/lib/zlib/crc32.js | 1 | 'use strict'; | COMMENT |
| LOW | blue_modules/pako/lib/zlib/zstream.js | 1 | 'use strict'; | COMMENT |
| LOW | blue_modules/pako/lib/zlib/inffast.js | 1 | 'use strict'; | COMMENT |
| LOW | blue_modules/pako/lib/zlib/inffast.js | 201 | } | COMMENT |
| LOW | blue_modules/pako/lib/zlib/adler32.js | 1 | 'use strict'; | COMMENT |
| LOW | blue_modules/pako/lib/zlib/inftrees.js | 1 | 'use strict'; | COMMENT |
| LOW | blue_modules/pako/lib/zlib/trees.js | 1 | 'use strict'; | COMMENT |
| LOW | blue_modules/pako/lib/zlib/gzheader.js | 1 | 'use strict'; | COMMENT |
| LOW | blue_modules/pako/lib/zlib/messages.js | 1 | 'use strict'; | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | ios/Shared/MarketAPI+Electrum.swift | 56 | print("Error during fetchNextBlockFee: \(error.localizedDescription)") | CODE |
| MEDIUM | ios/Shared/MarketAPI+Electrum.swift | 71 | print("Error fetching price: \(error.localizedDescription)") | CODE |
| MEDIUM | ios/Shared/MarketAPI+Electrum.swift | 79 | print("Error fetching next block fee: \(error.localizedDescription)") | CODE |
| MEDIUM | …AndMarketWidget/WalletInformationAndMarketWidget.swift | 79 | print("Error fetching market data: \(error.localizedDescription). Retry \(attempt)/\(retries)") | CODE |
| MEDIUM | ios/BlueWallet/AppDelegate.swift | 265 | print("Error clearing directory: \(error.localizedDescription)") | CODE |
| LOW | reproducible-builds/apkdiff/util.py | 185 | except Exception as err: | CODE |
| LOW | reproducible-builds/apkdiff/util.py | 187 | except Exception as err: | CODE |
| MEDIUM | reproducible-builds/apkdiff/util.py | 58 | def safe_sort(iterable): | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | scripts/release-notes.sh | 16 | # Define a function to apply the filter based on the parameter | COMMENT |
| MEDIUM | scripts/remove-loc-key.sh | 13 | # Define the potential directories containing JSON files | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | reproducible-builds/apkdiff/util.py | 151 | except (ValueError, IndexError): | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | scripts/remove-loc-key.sh | 3 | # Check if a nested key path is provided | COMMENT |
| LOW | reproducible-builds/apkdiff/apkdiff.py | 304 | # Check if package exists in both files | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | reproducible-builds/apkdiff/util.py | 1 | CODE | |
| LOW | reproducible-builds/apkdiff/util.py | 25 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | reproducible-builds/apkdiff/tests/test_apkdiff.py | 1 | # TODO: add tests to avoid regressions in apkdiff.py after | COMMENT |