Skip to content

Commit

Permalink
Merge branch 'main' into CW-865-Create-new-seed-UI-for-Show-seed-keys…
Browse files Browse the repository at this point in the history
…-page-to-match-onboarding-seed-verification-UI
  • Loading branch information
Serhii-Borodenko committed Jan 20, 2025
2 parents 579f2c3 + 2fb07dd commit 9106a24
Show file tree
Hide file tree
Showing 15 changed files with 168 additions and 32 deletions.
5 changes: 3 additions & 2 deletions .github/workflows/pr_test_build_android.yml
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,7 @@ jobs:
run: rm -rf build/app/outputs/flutter-apk/test-apk/

- name: Upload Artifact to github
uses: kittaakos/upload-artifact-as-is@v0
uses: actions/upload-artifact@v4
with:
path: ${{ github.workspace }}/build/app/outputs/flutter-apk
path: ${{ github.workspace }}/build/app/outputs/flutter-apk
name: "android apk"
6 changes: 4 additions & 2 deletions .github/workflows/pr_test_build_linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -221,9 +221,10 @@ jobs:
popd
- name: Upload Artifact to github
uses: kittaakos/upload-artifact-as-is@v0
uses: actions/upload-artifact@v4
with:
path: ${{ github.workspace }}/build/linux/x64/release/cakewallet_linux.zip
name: cakewallet_linux

- name: Prepare virtual desktop
if: ${{ contains(github.event.head_commit.message, 'run tests') }}
Expand Down Expand Up @@ -292,6 +293,7 @@ jobs:
- name: Upload Artifact to github
if: always()
continue-on-error: true
uses: kittaakos/upload-artifact-as-is@v0
uses: actions/upload-artifact@v4
with:
path: ${{ github.workspace }}/screen_grab.mkv.gpg
name: tests_screen_grab
25 changes: 0 additions & 25 deletions cw_monero/lib/monero_transaction_info.dart
Original file line number Diff line number Diff line change
@@ -1,39 +1,14 @@
import 'package:cw_core/transaction_info.dart';
import 'package:cw_core/monero_amount_format.dart';
import 'package:cw_core/parseBoolFromString.dart';
import 'package:cw_core/transaction_direction.dart';
import 'package:cw_core/format_amount.dart';
import 'package:cw_monero/api/transaction_history.dart';

class MoneroTransactionInfo extends TransactionInfo {
MoneroTransactionInfo(this.txHash, this.height, this.direction, this.date,
this.isPending, this.amount, this.accountIndex, this.addressIndex, this.fee,
this.confirmations) :
id = "${txHash}_${amount}_${accountIndex}_${addressIndex}";

MoneroTransactionInfo.fromMap(Map<String, Object?> map)
: id = "${map['hash']}_${map['amount']}_${map['accountIndex']}_${map['addressIndex']}",
txHash = map['hash'] as String,
height = (map['height'] ?? 0) as int,
direction = map['direction'] != null
? parseTransactionDirectionFromNumber(map['direction'] as String)
: TransactionDirection.incoming,
date = DateTime.fromMillisecondsSinceEpoch(
(int.tryParse(map['timestamp'] as String? ?? '') ?? 0) * 1000),
isPending = parseBoolFromString(map['isPending'] as String),
amount = map['amount'] as int,
accountIndex = int.parse(map['accountIndex'] as String),
addressIndex = map['addressIndex'] as int,
confirmations = map['confirmations'] as int,
key = getTxKey((map['hash'] ?? '') as String),
fee = map['fee'] as int? ?? 0 {
additionalInfo = <String, dynamic>{
'key': key,
'accountIndex': accountIndex,
'addressIndex': addressIndex
};
}

final String id;
final String txHash;
final int height;
Expand Down
6 changes: 6 additions & 0 deletions lib/core/backup_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,7 @@ class BackupService {
final lookupsUnstoppableDomains = data[PreferencesKey.lookupsUnstoppableDomains] as bool?;
final lookupsOpenAlias = data[PreferencesKey.lookupsOpenAlias] as bool?;
final lookupsENS = data[PreferencesKey.lookupsENS] as bool?;
final lookupsWellKnown = data[PreferencesKey.lookupsWellKnown] as bool?;
final syncAll = data[PreferencesKey.syncAllKey] as bool?;
final syncMode = data[PreferencesKey.syncModeKey] as int?;
final autoGenerateSubaddressStatus =
Expand Down Expand Up @@ -403,6 +404,9 @@ class BackupService {

if (lookupsENS != null) await _sharedPreferences.setBool(PreferencesKey.lookupsENS, lookupsENS);

if (lookupsWellKnown != null)
await _sharedPreferences.setBool(PreferencesKey.lookupsWellKnown, lookupsWellKnown);

if (syncAll != null) await _sharedPreferences.setBool(PreferencesKey.syncAllKey, syncAll);

if (syncMode != null) await _sharedPreferences.setInt(PreferencesKey.syncModeKey, syncMode);
Expand Down Expand Up @@ -542,6 +546,8 @@ class BackupService {
_sharedPreferences.getBool(PreferencesKey.lookupsUnstoppableDomains),
PreferencesKey.lookupsOpenAlias: _sharedPreferences.getBool(PreferencesKey.lookupsOpenAlias),
PreferencesKey.lookupsENS: _sharedPreferences.getBool(PreferencesKey.lookupsENS),
PreferencesKey.lookupsWellKnown:
_sharedPreferences.getBool(PreferencesKey.lookupsWellKnown),
PreferencesKey.syncModeKey: _sharedPreferences.getInt(PreferencesKey.syncModeKey),
PreferencesKey.syncAllKey: _sharedPreferences.getBool(PreferencesKey.syncAllKey),
PreferencesKey.autoGenerateSubaddressStatusKey:
Expand Down
12 changes: 12 additions & 0 deletions lib/entities/parse_address_from_domain.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import 'package:cake_wallet/entities/openalias_record.dart';
import 'package:cake_wallet/entities/parsed_address.dart';
import 'package:cake_wallet/entities/unstoppable_domain_address.dart';
import 'package:cake_wallet/entities/emoji_string_extension.dart';
import 'package:cake_wallet/entities/wellknown_record.dart';
import 'package:cake_wallet/exchange/provider/thorchain_exchange.provider.dart';
import 'package:cake_wallet/mastodon/mastodon_api.dart';
import 'package:cake_wallet/nostr/nostr_api.dart';
Expand Down Expand Up @@ -208,6 +209,17 @@ class AddressResolver {
}
}

// .well-known scheme:
if (text.contains('.') && text.contains('@')) {
if (settingsStore.lookupsWellKnown) {
final record =
await WellKnownRecord.fetchAddressAndName(formattedName: text, currency: currency);
if (record != null) {
return ParsedAddress.fetchWellKnownAddress(address: record.address, name: text);
}
}
}

if (!text.startsWith('@') && text.contains('@') && !text.contains('.')) {
final bool isFioRegistered = await FioAddressProvider.checkAvail(text);
if (isFioRegistered) {
Expand Down
11 changes: 10 additions & 1 deletion lib/entities/parsed_address.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ enum ParseFrom {
contact,
mastodon,
nostr,
thorChain
thorChain,
wellKnown
}

class ParsedAddress {
Expand Down Expand Up @@ -142,6 +143,14 @@ class ParsedAddress {
);
}

factory ParsedAddress.fetchWellKnownAddress({required String address, required String name}) {
return ParsedAddress(
addresses: [address],
name: name,
parseFrom: ParseFrom.wellKnown,
);
}

final List<String> addresses;
final String name;
final String description;
Expand Down
1 change: 1 addition & 0 deletions lib/entities/preferences_key.dart
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ class PreferencesKey {
static const lookupsUnstoppableDomains = 'looks_up_unstoppable_domain';
static const lookupsOpenAlias = 'looks_up_open_alias';
static const lookupsENS = 'looks_up_ens';
static const lookupsWellKnown = 'looks_up_well_known';
static const showCameraConsent = 'show_camera_consent';

static String moneroWalletUpdateV1Key(String name) =>
Expand Down
92 changes: 92 additions & 0 deletions lib/entities/wellknown_record.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import 'dart:convert';

import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/utils/print_verbose.dart';
import 'package:http/http.dart' as http;

class WellKnownRecord {
WellKnownRecord({
required this.address,
required this.name,
});

final String name;
final String address;

static Future<String?> checkWellKnownUsername(String username, CryptoCurrency currency) async {
String jsonLocation = "";
switch (currency) {
case CryptoCurrency.nano:
jsonLocation = "nano-currency";
break;
// TODO: add other currencies
default:
return null;
}

// split the string by the @ symbol:
try {
final List<String> splitStrs = username.split("@");
String name = splitStrs.first.toLowerCase();
final String domain = splitStrs.last;

if (splitStrs.length == 3) {
// for username like @[email protected] instead of [email protected]
name = splitStrs[1];
}

if (name.isEmpty) {
name = "_";
}

// lookup domain/.well-known/nano-currency.json and check if it has a nano address:
final http.Response response = await http.get(
Uri.parse("https://$domain/.well-known/$jsonLocation.json?names=$name"),
headers: <String, String>{"Accept": "application/json"},
);

if (response.statusCode != 200) {
return null;
}
final Map<String, dynamic> decoded = json.decode(response.body) as Map<String, dynamic>;

// Access the first element in the names array and retrieve its address
final List<dynamic> names = decoded["names"] as List<dynamic>;
for (final dynamic item in names) {
if (item["name"].toLowerCase() == name) {
return item["address"] as String;
}
}
} catch (e) {
printV("error checking well-known username: $e");
}
return null;
}

static String formatDomainName(String name) {
String formattedName = name;

if (name.contains("@")) {
formattedName = name.replaceAll("@", ".");
}

return formattedName;
}

static Future<WellKnownRecord?> fetchAddressAndName({
required String formattedName,
required CryptoCurrency currency,
}) async {
String name = formattedName;

printV("formattedName: $formattedName");

final address = await checkWellKnownUsername(formattedName, currency);

if (address == null) {
return null;
}

return WellKnownRecord(address: address, name: name);
}
}
2 changes: 2 additions & 0 deletions lib/src/screens/exchange/exchange_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,8 @@ class ExchangePage extends BasePage {
key: ValueKey('exchange_page_exchange_button_key'),
text: S.of(context).exchange,
onPressed: () {
FocusScope.of(context).unfocus();

if (_formKey.currentState != null &&
_formKey.currentState!.validate()) {
if ((exchangeViewModel.depositCurrency == CryptoCurrency.xmr) &&
Expand Down
5 changes: 5 additions & 0 deletions lib/src/screens/send/widgets/extract_address_from_parsed.dart
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ Future<String> extractAddressFromParsed(
content = S.of(context).extracted_address_content('${parsedAddress.name} (OpenAlias)');
address = parsedAddress.addresses.first;
break;
case ParseFrom.wellKnown:
title = S.of(context).address_detected;
content = S.of(context).extracted_address_content('${parsedAddress.name} (Well-Known)');
address = parsedAddress.addresses.first;
break;
case ParseFrom.fio:
title = S.of(context).address_detected;
content = S.of(context).extracted_address_content('${parsedAddress.name} (FIO)');
Expand Down
4 changes: 4 additions & 0 deletions lib/src/screens/settings/domain_lookups_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ class DomainLookupsPage extends BasePage {
title: 'Ethereum Name Service',
value: _privacySettingsViewModel.looksUpENS,
onValueChange: (_, bool value) => _privacySettingsViewModel.setLookupsENS(value)),
SettingsSwitcherCell(
title: '.well-known',
value: _privacySettingsViewModel.looksUpWellKnown,
onValueChange: (_, bool value) => _privacySettingsViewModel.setLookupsWellKnown(value)),

//if (!isHaven) it does not work correctly
],
Expand Down
5 changes: 4 additions & 1 deletion lib/src/widgets/primary_button.dart
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,10 @@ class LoadingPrimaryButton extends StatelessWidget {
width: double.infinity,
height: 52.0,
child: TextButton(
onPressed: (isLoading || isDisabled) ? null : onPressed,
onPressed: (isLoading || isDisabled) ? null : () {
FocusScope.of(context).unfocus();
onPressed.call();
},
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all(isDisabled ? color.withOpacity(0.5) : color),
Expand Down
11 changes: 11 additions & 0 deletions lib/store/settings_store.dart
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ abstract class SettingsStoreBase with Store {
required this.lookupsUnstoppableDomains,
required this.lookupsOpenAlias,
required this.lookupsENS,
required this.lookupsWellKnown,
required this.customBitcoinFeeRate,
required this.silentPaymentsCardDisplay,
required this.silentPaymentsAlwaysScan,
Expand Down Expand Up @@ -459,6 +460,11 @@ abstract class SettingsStoreBase with Store {
reaction((_) => lookupsENS,
(bool looksUpENS) => _sharedPreferences.setBool(PreferencesKey.lookupsENS, looksUpENS));

reaction(
(_) => lookupsWellKnown,
(bool looksUpWellKnown) =>
_sharedPreferences.setBool(PreferencesKey.lookupsWellKnown, looksUpWellKnown));

// secure storage keys:
reaction(
(_) => allowBiometricalAuthentication,
Expand Down Expand Up @@ -772,6 +778,8 @@ abstract class SettingsStoreBase with Store {
@observable
bool lookupsENS;

@observable
bool lookupsWellKnown;
@observable
SyncMode currentSyncMode;

Expand Down Expand Up @@ -967,6 +975,7 @@ abstract class SettingsStoreBase with Store {
sharedPreferences.getBool(PreferencesKey.lookupsUnstoppableDomains) ?? true;
final lookupsOpenAlias = sharedPreferences.getBool(PreferencesKey.lookupsOpenAlias) ?? true;
final lookupsENS = sharedPreferences.getBool(PreferencesKey.lookupsENS) ?? true;
final lookupsWellKnown = sharedPreferences.getBool(PreferencesKey.lookupsWellKnown) ?? true;
final customBitcoinFeeRate = sharedPreferences.getInt(PreferencesKey.customBitcoinFeeRate) ?? 1;
final silentPaymentsCardDisplay =
sharedPreferences.getBool(PreferencesKey.silentPaymentsCardDisplay) ?? true;
Expand Down Expand Up @@ -1245,6 +1254,7 @@ abstract class SettingsStoreBase with Store {
lookupsUnstoppableDomains: lookupsUnstoppableDomains,
lookupsOpenAlias: lookupsOpenAlias,
lookupsENS: lookupsENS,
lookupsWellKnown: lookupsWellKnown,
customBitcoinFeeRate: customBitcoinFeeRate,
silentPaymentsCardDisplay: silentPaymentsCardDisplay,
silentPaymentsAlwaysScan: silentPaymentsAlwaysScan,
Expand Down Expand Up @@ -1414,6 +1424,7 @@ abstract class SettingsStoreBase with Store {
sharedPreferences.getBool(PreferencesKey.lookupsUnstoppableDomains) ?? true;
lookupsOpenAlias = sharedPreferences.getBool(PreferencesKey.lookupsOpenAlias) ?? true;
lookupsENS = sharedPreferences.getBool(PreferencesKey.lookupsENS) ?? true;
lookupsWellKnown = sharedPreferences.getBool(PreferencesKey.lookupsWellKnown) ?? true;
customBitcoinFeeRate = sharedPreferences.getInt(PreferencesKey.customBitcoinFeeRate) ?? 1;
silentPaymentsCardDisplay =
sharedPreferences.getBool(PreferencesKey.silentPaymentsCardDisplay) ?? true;
Expand Down
6 changes: 6 additions & 0 deletions lib/view_model/settings/privacy_settings_view_model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ abstract class PrivacySettingsViewModelBase with Store {
@computed
bool get looksUpENS => _settingsStore.lookupsENS;

@computed
bool get looksUpWellKnown => _settingsStore.lookupsWellKnown;

bool get canUseEtherscan => _wallet.type == WalletType.ethereum;

bool get canUsePolygonScan => _wallet.type == WalletType.polygon;
Expand Down Expand Up @@ -130,6 +133,9 @@ abstract class PrivacySettingsViewModelBase with Store {
@action
void setLookupsENS(bool value) => _settingsStore.lookupsENS = value;

@action
void setLookupsWellKnown(bool value) => _settingsStore.lookupsWellKnown = value;

@action
void setLookupsYatService(bool value) => _settingsStore.lookupsYatService = value;

Expand Down
9 changes: 8 additions & 1 deletion pubspec_base.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,10 @@ dependencies:
polyseed: ^0.0.6
nostr_tools: ^1.0.9
solana: ^0.31.0+1
ledger_flutter_plus: ^1.4.1
ledger_flutter_plus:
git:
url: https://github.com/vespr-wallet/ledger-flutter-plus
ref: c2e341d8038f1108690ad6f80f7b4b7156aacc76
hashlib: ^1.19.2

dev_dependencies:
Expand Down Expand Up @@ -146,6 +149,10 @@ dependency_overrides:
url: https://github.com/cake-tech/bitcoin_base
ref: cake-update-v9
ffi: 2.1.0
ledger_flutter_plus:
git:
url: https://github.com/vespr-wallet/ledger-flutter-plus
ref: c2e341d8038f1108690ad6f80f7b4b7156aacc76

flutter_icons:
image_path: "assets/images/app_logo.png"
Expand Down

0 comments on commit 9106a24

Please sign in to comment.