What happened
With the app's built-in Tor setting enabled and fully bootstrapped, the Android app still made direct DNS and TLS connections to green-webhooks.blockstream.com and ramps.blockstream.com. These connections came from the device network path rather than the app's Tor proxy.
Test setup and observed result
- Source: Blockstream/green_android commit 8062ee1 (5.7.0 tree).
- Runtime: Android API 36 x86_64 emulator; disposable, empty testnet wallet; built-in Tor switch enabled. The app log showed Tor bootstrap at 100% and GDK connections with use_tor=True.
- Build: source-built productionGoogleDebug, not the official signed release. The public checkout required two diagnostic changes to run on this emulator: removal of an early logging branch that crashed the local no-key debug build before Koin initialization, and addition of x86_64 to the productionGoogle ABI filter. Neither change altered the network clients or Tor routing.
- On wallet overview, device registration invoked https://green-webhooks.blockstream.com/register-device. The emulator capture showed direct DNS for that host and a direct TLS ClientHello with its SNI.
- On opening Transactions, the app invoked https://ramps.blockstream.com/payments/transactions. The capture again showed direct DNS and TLS connections for that host. The view schedules another poll every 60 seconds.
In the production-flavor capture, direct DNS was visible at original frames 33206 (green-webhooks) and 33994–33995 (ramps); corresponding direct TLS ClientHello packets appeared at 33248 and 34001. The redacted runtime log records the webhook and Meld requests after Tor reached 100%.
The relevant clients are data/src/commonMain/kotlin/com/blockstream/data/GreenWebhooksHttpClient.kt and data/src/commonMain/kotlin/com/blockstream/data/meld/MeldHttpClient.kt. Both inherit network/src/commonMain/kotlin/com/blockstream/network/AppHttpClient.kt, which does not bind these Ktor requests to the app's Tor proxy. The app's Tor setting reaches GDK but not these clients.
WalletOverviewViewModel.kt:122-143 passes greenWallet.xPubHashId as externalCustomerId with an FCM token to /register-device; only optional nodeId is gated to development/debug. TransactViewModel.kt:136-166 passes the wallet-derived ID as externalCustomerIds to /payments/transactions. The destination can therefore associate a stable wallet-derived ID with a direct IP connection. TLS keeps that ID out of an ordinary on-path packet capture; the capture proves the direct route and host, while the source establishes the request fields.
Expected result
When built-in Tor is enabled, these HTTP clients should use the active Tor proxy, wait for it to be ready, and avoid direct fallback. A production-flavor integration check for both hosts would help prevent regression.
I have not tested Blockstream's official signed APK, and this report does not establish how every release or platform behaves. No real funds or personal wallet data were used.
Evidence
The two ZIPs hold the complete 35,895,240-byte emulator capture, split at frame 20,000 to stay below GitHub's per-file limit. Original capture SHA-256: e38d08baa31460a9d23123c4ff249b0f61780310dcc51ed4538a70a974bf1a08. For a frame in part 2, subtract 20,000 to find its position in that file.
The request-event log includes the disposable test wallet's FCM token and wallet-derived ID. The full app logcat is omitted because it also contains mnemonic recovery words.
A short excerpt shows Tor fully bootstrapped before both requests:
1790406524.234 Tor progress=100
1790406546.842 GDK network=testnet use_tor=True
1790406566.884 request host=green-webhooks.blockstream.com path=/register-device
1790406625.737 request host=ramps.blockstream.com path=/payments/transactions
Related: #164 covered older Countly traffic with external Tor configuration. This report concerns built-in Tor and different HTTP clients.
What happened
With the app's built-in Tor setting enabled and fully bootstrapped, the Android app still made direct DNS and TLS connections to green-webhooks.blockstream.com and ramps.blockstream.com. These connections came from the device network path rather than the app's Tor proxy.
Test setup and observed result
In the production-flavor capture, direct DNS was visible at original frames 33206 (green-webhooks) and 33994–33995 (ramps); corresponding direct TLS ClientHello packets appeared at 33248 and 34001. The redacted runtime log records the webhook and Meld requests after Tor reached 100%.
The relevant clients are data/src/commonMain/kotlin/com/blockstream/data/GreenWebhooksHttpClient.kt and data/src/commonMain/kotlin/com/blockstream/data/meld/MeldHttpClient.kt. Both inherit network/src/commonMain/kotlin/com/blockstream/network/AppHttpClient.kt, which does not bind these Ktor requests to the app's Tor proxy. The app's Tor setting reaches GDK but not these clients.
WalletOverviewViewModel.kt:122-143 passes greenWallet.xPubHashId as externalCustomerId with an FCM token to /register-device; only optional nodeId is gated to development/debug. TransactViewModel.kt:136-166 passes the wallet-derived ID as externalCustomerIds to /payments/transactions. The destination can therefore associate a stable wallet-derived ID with a direct IP connection. TLS keeps that ID out of an ordinary on-path packet capture; the capture proves the direct route and host, while the source establishes the request fields.
Expected result
When built-in Tor is enabled, these HTTP clients should use the active Tor proxy, wait for it to be ready, and avoid direct fallback. A production-flavor integration check for both hosts would help prevent regression.
I have not tested Blockstream's official signed APK, and this report does not establish how every release or platform behaves. No real funds or personal wallet data were used.
Evidence
The two ZIPs hold the complete 35,895,240-byte emulator capture, split at frame 20,000 to stay below GitHub's per-file limit. Original capture SHA-256:
e38d08baa31460a9d23123c4ff249b0f61780310dcc51ed4538a70a974bf1a08. For a frame in part 2, subtract 20,000 to find its position in that file.The request-event log includes the disposable test wallet's FCM token and wallet-derived ID. The full app logcat is omitted because it also contains mnemonic recovery words.
A short excerpt shows Tor fully bootstrapped before both requests:
Related: #164 covered older Countly traffic with external Tor configuration. This report concerns built-in Tor and different HTTP clients.