diff --git a/.github/workflows/compile.yml b/.github/workflows/compile.yml
index 287ff57f..bfb3a14d 100644
--- a/.github/workflows/compile.yml
+++ b/.github/workflows/compile.yml
@@ -116,7 +116,7 @@ jobs:
name: "Nightly-v${{ steps.generate.outputs.build-number }}-iOS/Android-Visit mxc1usd.com"
generateReleaseNotes: true
body: >
-
+
- name: Upload APK to Waldo
uses: waldoapp/gh-action-upload@v2
diff --git a/.github/workflows/submit.yml b/.github/workflows/submit.yml
index e7ee3018..4179ad6f 100644
--- a/.github/workflows/submit.yml
+++ b/.github/workflows/submit.yml
@@ -46,7 +46,7 @@ jobs:
- uses: r0adkll/upload-google-play@v1
with:
serviceAccountJsonPlainText: ${{ secrets.SERVICE_ACCOUNT_JSON }}
- packageName: com.moonchain.mxc
+ packageName: com.moonchain.app
releaseFiles: build/app/outputs/bundle/googlePlayRelease/moonchain.aab
track: alpha
status: draft
@@ -126,6 +126,6 @@ jobs:
name: "Release-v${{ steps.generate.outputs.build-number }}-iOS/Android-Visit mxc1usd.com"
generateReleaseNotes: true
body: >
-
+
diff --git a/android/app/build.gradle b/android/app/build.gradle
index abd3f573..6f1b39c8 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -56,7 +56,7 @@ android {
}
defaultConfig {
- applicationId "com.moonchain.mxc"
+ applicationId "com.moonchain.app"
// You can update the following values to match your application needs.
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
minSdkVersion 21
diff --git a/android/app/google-services.json b/android/app/google-services.json
index 2ec59ce5..e336ba86 100644
--- a/android/app/google-services.json
+++ b/android/app/google-services.json
@@ -5,6 +5,43 @@
"storage_bucket": "moonchain-app.appspot.com"
},
"client": [
+ {
+ "client_info": {
+ "mobilesdk_app_id": "1:810578982053:android:dbfbe51474fccc2b21094c",
+ "android_client_info": {
+ "package_name": "com.moonchain.app"
+ }
+ },
+ "oauth_client": [
+ {
+ "client_id": "810578982053-5mthh5ep4k1601komn39hu7c4biu4chb.apps.googleusercontent.com",
+ "client_type": 3
+ }
+ ],
+ "api_key": [
+ {
+ "current_key": "AIzaSyCyny8vayQzMxTWnJcK7KIl7GKEwtloC8Q"
+ }
+ ],
+ "services": {
+ "appinvite_service": {
+ "other_platform_oauth_client": [
+ {
+ "client_id": "810578982053-5mthh5ep4k1601komn39hu7c4biu4chb.apps.googleusercontent.com",
+ "client_type": 3
+ },
+ {
+ "client_id": "810578982053-p196bn8p9ipg3709v4ftk2a28fcvi6ka.apps.googleusercontent.com",
+ "client_type": 2,
+ "ios_info": {
+ "bundle_id": "com.moonchain.mxc",
+ "app_store_id": "6736371768"
+ }
+ }
+ ]
+ }
+ }
+ },
{
"client_info": {
"mobilesdk_app_id": "1:810578982053:android:98b17812d3f86af721094c",
@@ -12,7 +49,36 @@
"package_name": "com.moonchain.mxc"
}
},
- "oauth_client": [],
+ "oauth_client": [
+ {
+ "client_id": "810578982053-ef7chugg2fct7l6io3d7tis321hi1hnd.apps.googleusercontent.com",
+ "client_type": 1,
+ "android_info": {
+ "package_name": "com.moonchain.mxc",
+ "certificate_hash": "5c3aaff06b031aa5f90f61c1e1d3b79fc0294af0"
+ }
+ },
+ {
+ "client_id": "810578982053-misr3ehc1l6mhef3s25botsd3v8jje9h.apps.googleusercontent.com",
+ "client_type": 1,
+ "android_info": {
+ "package_name": "com.moonchain.mxc",
+ "certificate_hash": "2d7ddbcda8fff7b9cbc2b55d3b01e9ddc77c20e4"
+ }
+ },
+ {
+ "client_id": "810578982053-se1jg0k7sstre57ejkh1fg551spvji2o.apps.googleusercontent.com",
+ "client_type": 1,
+ "android_info": {
+ "package_name": "com.moonchain.mxc",
+ "certificate_hash": "b3d8f034c8319b877f83a2a44ff9141325ded9c3"
+ }
+ },
+ {
+ "client_id": "810578982053-5mthh5ep4k1601komn39hu7c4biu4chb.apps.googleusercontent.com",
+ "client_type": 3
+ }
+ ],
"api_key": [
{
"current_key": "AIzaSyCyny8vayQzMxTWnJcK7KIl7GKEwtloC8Q"
@@ -20,10 +86,23 @@
],
"services": {
"appinvite_service": {
- "other_platform_oauth_client": []
+ "other_platform_oauth_client": [
+ {
+ "client_id": "810578982053-5mthh5ep4k1601komn39hu7c4biu4chb.apps.googleusercontent.com",
+ "client_type": 3
+ },
+ {
+ "client_id": "810578982053-p196bn8p9ipg3709v4ftk2a28fcvi6ka.apps.googleusercontent.com",
+ "client_type": 2,
+ "ios_info": {
+ "bundle_id": "com.moonchain.mxc",
+ "app_store_id": "6736371768"
+ }
+ }
+ ]
}
}
- },
+ }
],
"configuration_version": "1"
}
\ No newline at end of file
diff --git a/android/app/src/debug/AndroidManifest.xml b/android/app/src/debug/AndroidManifest.xml
index 1422cf3c..d3950581 100644
--- a/android/app/src/debug/AndroidManifest.xml
+++ b/android/app/src/debug/AndroidManifest.xml
@@ -1,5 +1,5 @@
+ package="com.moonchain.app">
+ CFBundleURLTypes
+
+
+ CFBundleTypeRole
+ Editor
+ CFBundleURLSchemes
+
+
+ com.googleusercontent.apps.810578982053-p196bn8p9ipg3709v4ftk2a28fcvi6ka
+
+
+
+
UIApplicationSupportsIndirectInputEvents
UIBackgroundModes
diff --git a/ios/Runner/Runner.entitlements b/ios/Runner/Runner.entitlements
index 22d4a48a..ebd7d399 100644
--- a/ios/Runner/Runner.entitlements
+++ b/ios/Runner/Runner.entitlements
@@ -8,7 +8,19 @@
applinks:mxc1usd.com
+ com.apple.developer.icloud-container-identifiers
+
+ iCloud.moonchain.mxc
+
+ com.apple.developer.icloud-services
+
+ CloudDocuments
+
com.apple.developer.networking.wifi-info
+ com.apple.developer.ubiquity-container-identifiers
+
+ iCloud.moonchain.mxc
+
diff --git a/ios/Runner/RunnerDebug.entitlements b/ios/Runner/RunnerDebug.entitlements
new file mode 100644
index 00000000..ebd7d399
--- /dev/null
+++ b/ios/Runner/RunnerDebug.entitlements
@@ -0,0 +1,26 @@
+
+
+
+
+ aps-environment
+ development
+ com.apple.developer.associated-domains
+
+ applinks:mxc1usd.com
+
+ com.apple.developer.icloud-container-identifiers
+
+ iCloud.moonchain.mxc
+
+ com.apple.developer.icloud-services
+
+ CloudDocuments
+
+ com.apple.developer.networking.wifi-info
+
+ com.apple.developer.ubiquity-container-identifiers
+
+ iCloud.moonchain.mxc
+
+
+
diff --git a/ios/Runner/RunnerRelease.entitlements b/ios/Runner/RunnerRelease.entitlements
new file mode 100644
index 00000000..ebd7d399
--- /dev/null
+++ b/ios/Runner/RunnerRelease.entitlements
@@ -0,0 +1,26 @@
+
+
+
+
+ aps-environment
+ development
+ com.apple.developer.associated-domains
+
+ applinks:mxc1usd.com
+
+ com.apple.developer.icloud-container-identifiers
+
+ iCloud.moonchain.mxc
+
+ com.apple.developer.icloud-services
+
+ CloudDocuments
+
+ com.apple.developer.networking.wifi-info
+
+ com.apple.developer.ubiquity-container-identifiers
+
+ iCloud.moonchain.mxc
+
+
+
diff --git a/lib/core/src/firebase/firebase_options.dart b/lib/core/src/firebase/firebase_options.dart
index 0c17b5db..551202d9 100644
--- a/lib/core/src/firebase/firebase_options.dart
+++ b/lib/core/src/firebase/firebase_options.dart
@@ -51,7 +51,7 @@ class DefaultFirebaseOptions {
static const FirebaseOptions android = FirebaseOptions(
apiKey: 'AIzaSyCyny8vayQzMxTWnJcK7KIl7GKEwtloC8Q',
- appId: '1:810578982053:android:98b17812d3f86af721094c',
+ appId: '1:810578982053:android:dbfbe51474fccc2b21094c',
messagingSenderId: '810578982053',
projectId: 'moonchain-app',
storageBucket: 'moonchain-app.appspot.com',
@@ -63,6 +63,8 @@ class DefaultFirebaseOptions {
messagingSenderId: '810578982053',
projectId: 'moonchain-app',
storageBucket: 'moonchain-app.appspot.com',
+ androidClientId: '810578982053-ef7chugg2fct7l6io3d7tis321hi1hnd.apps.googleusercontent.com',
+ iosClientId: '810578982053-p196bn8p9ipg3709v4ftk2a28fcvi6ka.apps.googleusercontent.com',
iosBundleId: 'com.moonchain.mxc',
);
}
diff --git a/lib/features/common/app/launcher_use_case.dart b/lib/features/common/app/launcher_use_case.dart
index b0d03f5f..6ead1da7 100644
--- a/lib/features/common/app/launcher_use_case.dart
+++ b/lib/features/common/app/launcher_use_case.dart
@@ -22,14 +22,23 @@ class LauncherUseCase extends ReactiveUseCase {
final AccountUseCase _accountUseCase;
final ChainConfigurationUseCase _chainConfigurationUseCase;
- void viewTransactions() async {
- final chainExplorerUrl =
- _chainConfigurationUseCase.selectedNetwork.value!.explorerUrl!;
- final address = _accountUseCase.account.value!.address;
- final addressExplorer = Urls.addressExplorer(address);
- final launchUri = MXCFormatter.mergeUrl(chainExplorerUrl, addressExplorer);
-
- openUrl(launchUri, LaunchMode.platformDefault);
+ void viewTransactions(List? txList) async {
+ // Account should have tx
+ if (txList != null && txList.isNotEmpty) {
+ final chainExplorerUrl =
+ _chainConfigurationUseCase.selectedNetwork.value!.explorerUrl!;
+ final address = _accountUseCase.account.value!.address;
+ final ethAddress = EthereumAddress.fromHex(address);
+ final addressExplorer = Urls.addressExplorer(ethAddress.hexEip55);
+ final launchUri =
+ MXCFormatter.mergeUrl(chainExplorerUrl, addressExplorer);
+
+ openUrl(launchUri, LaunchMode.platformDefault);
+ } else {
+ final chainExplorerUrl = Uri.parse(
+ _chainConfigurationUseCase.selectedNetwork.value!.explorerUrl!);
+ openUrl(chainExplorerUrl, LaunchMode.platformDefault);
+ }
}
/// Launches the given txHash in the chains explorer tx page
diff --git a/lib/features/common/app_nav_bar/app_nav_bar.dart b/lib/features/common/app_nav_bar/app_nav_bar.dart
index 0eb28df5..18c8a343 100644
--- a/lib/features/common/app_nav_bar/app_nav_bar.dart
+++ b/lib/features/common/app_nav_bar/app_nav_bar.dart
@@ -1,10 +1,13 @@
import 'package:moonchain_wallet/common/common.dart';
+import 'package:moonchain_wallet/core/src/routing/route.dart';
import 'package:moonchain_wallet/features/settings/settings.dart';
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
+import 'package:moonchain_wallet/features/settings/subfeatures/accounts/show_accounts_dialog.dart';
import 'package:mxc_logic/mxc_logic.dart';
import 'package:mxc_ui/mxc_ui.dart';
+import '../../settings/subfeatures/accounts/subfeatures/import_account/import_account_page.dart';
import 'app_nav_bar_presenter.dart';
import 'app_nav_bar_state.dart';
@@ -47,7 +50,21 @@ class AppNavBar extends HookConsumerWidget {
color: ColorsTheme.of(context).iconPrimary,
),
child: GestureDetector(
- onTap: () => presenter.copy(),
+ onTap: () => showAccountsDialog(
+ context: context,
+ currentAccount: state.account!,
+ accounts: state.accounts,
+ isLoading: state.isLoading,
+ onImport: () => Navigator.of(context).push(
+ route.featureDialog(
+ const ImportAccountPage(),
+ ),
+ ),
+ onAdd: () => presenter.addNewAccount(),
+ onSelect: (item) => presenter.changeAccount(item),
+ onRemove: (item) => presenter.removeAccount(item),
+ ),
+ onDoubleTap: () => presenter.copy(),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
diff --git a/lib/features/common/app_nav_bar/app_nav_bar_presenter.dart b/lib/features/common/app_nav_bar/app_nav_bar_presenter.dart
index d5f1bb78..50589ff6 100644
--- a/lib/features/common/app_nav_bar/app_nav_bar_presenter.dart
+++ b/lib/features/common/app_nav_bar/app_nav_bar_presenter.dart
@@ -1,5 +1,7 @@
import 'package:clipboard/clipboard.dart';
+import 'package:moonchain_wallet/common/dialogs/alert_dialog.dart';
import 'package:moonchain_wallet/core/core.dart';
+import 'package:moonchain_wallet/features/settings/domain/webview_use_case.dart';
import 'package:mxc_logic/mxc_logic.dart';
import 'app_nav_bar_state.dart';
@@ -10,6 +12,8 @@ final appNavBarContainer = PresenterContainer(
class AppNavPresenter extends CompletePresenter {
AppNavPresenter() : super(AppNavBarState());
+ late final _webviewUseCase = WebviewUseCase();
+ late final _authUseCase = ref.read(authUseCaseProvider);
late final _accountUseCase = ref.read(accountUseCaseProvider);
late final _tokenContractUseCase = ref.read(tokenContractUseCaseProvider);
late final _chainConfigurationUseCase =
@@ -25,6 +29,10 @@ class AppNavPresenter extends CompletePresenter {
}
});
+ listen(_accountUseCase.accounts, (value) {
+ notify(() => state.accounts = value);
+ });
+
listen(_chainConfigurationUseCase.selectedNetwork, (value) async {
if (value != null) {
_accountUseCase.getAccountsNames();
@@ -48,4 +56,57 @@ class AppNavPresenter extends CompletePresenter {
final tip = translate('copied_x')!.replaceAll('{0}', translate('address')!);
addMessage(tip);
}
+
+ void addNewAccount() async {
+ notify(() => state.isLoading = true);
+
+ try {
+ final index = _accountUseCase.findAccountsLastIndex();
+
+ final newAccount = await _authUseCase.addNewAccount(index);
+ _accountUseCase.addAccount(newAccount, index: index);
+ loadCache();
+
+ notify(() => state.isLoading = false);
+ navigator!.pop();
+ } catch (e, s) {
+ addError(e, s);
+ }
+ }
+
+ void changeAccount(Account item, {bool shouldPop = true}) {
+ _accountUseCase.changeAccount(item);
+ _authUseCase.changeAccount(item);
+ loadCache();
+
+ if (shouldPop) navigator?.pop();
+ }
+
+ void removeAccount(Account item) async {
+ try {
+ final result = await showAlertDialog(
+ context: context!,
+ title: translate('removing_account')!,
+ content: translate('removing_account_warning')!,
+ ok: translate('remove')!,
+ );
+
+ if (result != null && result) {
+ _accountUseCase.removeAccount(item);
+
+ final isSelected = _accountUseCase.isAccountSelected(item);
+ if (isSelected) {
+ changeAccount(state.accounts[0], shouldPop: false);
+ }
+
+ navigator?.pop();
+ }
+ } catch (e, s) {
+ addError(e, s);
+ }
+ }
+
+ void loadCache() {
+ _webviewUseCase.clearCache();
+ }
}
diff --git a/lib/features/common/app_nav_bar/app_nav_bar_state.dart b/lib/features/common/app_nav_bar/app_nav_bar_state.dart
index 26791121..c88e737f 100644
--- a/lib/features/common/app_nav_bar/app_nav_bar_state.dart
+++ b/lib/features/common/app_nav_bar/app_nav_bar_state.dart
@@ -3,9 +3,13 @@ import 'package:mxc_logic/mxc_logic.dart';
class AppNavBarState with EquatableMixin {
Account? account;
+ List accounts = [];
+ bool isLoading = false;
@override
List