Files
hash-wallet/tool/fiat_api_check.dart
jwinterm 04203654f1 Rename Flutter project + binary: cake_wallet -> hash_wallet
The big one. Touches 760+ files. Locks in the user's decision to break
import-line compatibility with upstream cake-tech/cake_wallet in exchange
for a binary named hash_wallet on every platform.

Changes:
- pubspec_description.yaml: project name cake_wallet -> hash_wallet
- 762 Dart files: every 'package:cake_wallet/...' import rewritten to
  'package:hash_wallet/...' (lib/, cw_*/lib/, tool/, test/, integration_test/)
- linux/CMakeLists.txt: BINARY_NAME cake_wallet -> hash_wallet
- windows/CMakeLists.txt: project + BINARY_NAME (CakeWallet -> HashWallet)
- windows/runner/Runner.rc: company / file / product strings to Hash Wallet
  + Such Software LLC copyright
- macos/Runner.xcodeproj/project_base.pbxproj: cake_wallet_new.app refs
  -> hash_wallet.app (macOS output bundle name)
- com.suchsoftware.HashWallet.yml (Flatpak): all binary path refs
  cake_wallet -> hash_wallet (e.g. /app/hash_wallet/hash_wallet)
- linux/com.suchsoftware.HashWallet.desktop: Exec=hash_wallet
- scripts/android/copy_monero_deps.sh: CW_DIR target path
- configure_hash_wallet.sh: error message typo (old filename)

INTENTIONALLY UNCHANGED:
- cw_* subpackage names (cw_core, cw_bitcoin, cw_wownero, etc.) — they
  remain as the historical 'cake wallet' naming; renaming them would
  cascade through every sub-package's internal structure
- Method channel name 'com.cake_wallet/native_utils' in iOS/macOS/Android
  AppDelegates and MainActivity — it's a string identifier that has to
  match the Dart side exactly. Renaming requires both-sides change; it's
  internal-only and not user-visible.
- ghcr.io/cake-tech/cake_wallet:debian13-... docker image references in
  build scripts — that's Cake Labs' published image we use as the build
  environment, not ours.

User data directory now follows the new binary name:
  ~/.local/share/hash_wallet/  (was ~/.local/share/cake_wallet/)
  ~/.config/hash_wallet/       (was ~/.config/cake_wallet/)
Existing users on the old name will need migration if any exist.
2026-05-16 11:33:25 -04:00

185 lines
4.7 KiB
Dart
Executable File

import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:http/http.dart' as http; // very_insecure_http_do_not_use
import 'package:hash_wallet/.secrets.g.dart' as secrets;
import './print_verbose_dummy.dart';
// 1. Configuration
const _fiatApiClearNetAuthority = 'fiat-api.cakewallet.com';
const _fiatApiPath = '/v2/rates';
const _apiKey = secrets.fiatApiKey;
// 2. Define Lists
const List<String> cryptoCurrencies = [
'btc',
'ltc',
'xmr',
'bch',
'doge',
'eth',
'pol',
'sol',
'xno',
'trx',
'dcr',
'zano',
'wow',
'arb',
'usdt',
'pepe',
'zec',
'bnb',
'xrp',
'ada',
'avax',
'shib',
'ton',
'dot',
'link',
'uni',
'near',
'atom',
'xlm',
'stx',
'kas',
'dai',
];
const List<String> fiatCurrencies = [
'usd',
'eur',
'aud',
'gbp',
'jpy',
'cad',
'chf',
'cny',
'inr',
'brl',
'zar',
'mxn',
'krw',
'hkd',
'sgd',
'nzd',
'sek',
'try'
];
void main() {
// --- A. Setup the Output File ---
final logFile = File('fiat-check-output.txt');
// Write a header to start fresh (overwrite old file)
logFile.writeAsStringSync('--- Starting Verified Price Check at ${DateTime.now()} ---\n');
// --- B. Run App in a Zone to Capture Prints ---
runZoned(
() async {
printV('--- Starting Verified Price Check ---');
final Map<String, List<String>> workingPairs = {};
final Map<String, List<String>> failedPairs = {};
final client = http.Client();
try {
for (final crypto in cryptoCurrencies) {
workingPairs[crypto] = [];
failedPairs[crypto] = [];
for (final fiat in fiatCurrencies) {
// Clean ticker logic
String cleanCrypto = crypto.split(".").first;
final Map<String, String> queryParams = {
'interval_count': '1',
'base': cleanCrypto,
'quote': fiat,
};
final uri = Uri.https(_fiatApiClearNetAuthority, _fiatApiPath, queryParams);
bool isSuccess = false;
String logPrefix = "❌";
String logMessage = "";
try {
final response = await client.get(uri, headers: {"x-api-key": _apiKey});
if (response.statusCode == 200) {
final data = jsonDecode(response.body) as Map<String, dynamic>;
final Map<String, dynamic> results = data['results'] as Map<String, dynamic>? ?? {};
final Map<String, dynamic> errors = data['errors'] as Map<String, dynamic>? ?? {};
if (results.isNotEmpty && errors.isEmpty) {
isSuccess = true;
logPrefix = "✅";
final price = results.values.first;
logMessage = "${cleanCrypto.toUpperCase()}/${fiat.toUpperCase()} = $price";
} else {
isSuccess = false;
logPrefix = "❌";
logMessage =
"${cleanCrypto.toUpperCase()}/${fiat.toUpperCase()} returned empty results or error.";
}
} else {
logMessage =
"${cleanCrypto.toUpperCase()}/${fiat.toUpperCase()} HTTP ${response.statusCode}";
}
} catch (e) {
logMessage = "${cleanCrypto.toUpperCase()}/${fiat.toUpperCase()} Error: $e";
}
// Print immediate status (Captured by Zone)
printV('$logPrefix $logMessage');
// Aggregate
if (isSuccess) {
workingPairs[crypto]!.add(fiat);
} else {
failedPairs[crypto]!.add(fiat);
}
// 50ms delay to prevent rate limiting
await Future.delayed(Duration(milliseconds: 50));
}
}
} finally {
client.close();
}
// --- FINAL SUMMARY ---
printV('\n\n=== SUMMARY ===\n');
// Print Successful
workingPairs.forEach((crypto, fiats) {
if (fiats.isNotEmpty) {
printV('✅ ${crypto.toUpperCase()}: ${fiats.join(", ")}');
}
});
printV('\n--------------------------------------------------\n');
// Print Failed
failedPairs.forEach((crypto, fiats) {
if (fiats.isNotEmpty) {
printV('❌ ${crypto.toUpperCase()}: ${fiats.join(", ")}');
}
});
printV('\n=== DONE ===');
},
// --- C. The Interceptor ---
zoneSpecification: ZoneSpecification(
print: (self, parent, zone, line) {
// 1. Print to Standard Console
parent.print(zone, line);
// 2. Append to Text File
// We use Sync to ensure data isn't lost if the script crashes
logFile.writeAsStringSync('$line\n', mode: FileMode.append);
},
),
);
}