mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2025-03-12 09:32:33 +00:00
Merge branch 'main' of https://github.com/cake-tech/cake_wallet into CW-519-tor
This commit is contained in:
commit
54463b2ca3
64 changed files with 679 additions and 214 deletions
26
.github/workflows/pr_test_build.yml
vendored
26
.github/workflows/pr_test_build.yml
vendored
|
@ -3,6 +3,12 @@ name: PR Test Build
|
|||
on:
|
||||
pull_request:
|
||||
branches: [main]
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
branch:
|
||||
description: 'Branch name to build'
|
||||
required: true
|
||||
default: 'main'
|
||||
|
||||
jobs:
|
||||
PR_test_build:
|
||||
|
@ -12,6 +18,14 @@ jobs:
|
|||
KEY_PASS: test@cake_wallet
|
||||
|
||||
steps:
|
||||
- name: is pr
|
||||
if: github.event_name == 'pull_request'
|
||||
run: echo "BRANCH_NAME=${GITHUB_HEAD_REF}" >> $GITHUB_ENV
|
||||
|
||||
- name: is not pr
|
||||
if: github.event_name != 'pull_request'
|
||||
run: echo "BRANCH_NAME=${{ github.event.inputs.branch }}" >> $GITHUB_ENV
|
||||
|
||||
- name: Free Up GitHub Actions Ubuntu Runner Disk Space
|
||||
run: |
|
||||
sudo rm -rf /usr/share/dotnet
|
||||
|
@ -40,7 +54,7 @@ jobs:
|
|||
cd /opt/android
|
||||
-y curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
|
||||
cargo install cargo-ndk
|
||||
git clone https://github.com/cake-tech/cake_wallet.git --branch $GITHUB_HEAD_REF
|
||||
git clone https://github.com/cake-tech/cake_wallet.git --branch ${{ env.BRANCH_NAME }}
|
||||
cd cake_wallet/scripts/android/
|
||||
./install_ndk.sh
|
||||
source ./app_env.sh cakewallet
|
||||
|
@ -141,7 +155,7 @@ jobs:
|
|||
echo "const moralisApiKey = '${{ secrets.MORALIS_API_KEY }}';" >> lib/.secrets.g.dart
|
||||
|
||||
- name: Rename app
|
||||
run: echo -e "id=com.cakewallet.test\nname=$GITHUB_HEAD_REF" > /opt/android/cake_wallet/android/app.properties
|
||||
run: echo -e "id=com.cakewallet.test\nname=${{ env.BRANCH_NAME }}" > /opt/android/cake_wallet/android/app.properties
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
|
@ -156,7 +170,7 @@ jobs:
|
|||
# appcenter distribute release \
|
||||
# --group "Testers" \
|
||||
# --file "/opt/android/cake_wallet/build/app/outputs/apk/release/app-release.apk" \
|
||||
# --release-notes ${GITHUB_HEAD_REF} \
|
||||
# --release-notes ${{ env.BRANCH_NAME }} \
|
||||
# --app Cake-Labs/Cake-Wallet \
|
||||
# --token ${{ secrets.APP_CENTER_TOKEN }} \
|
||||
# --quiet
|
||||
|
@ -165,7 +179,7 @@ jobs:
|
|||
run: |
|
||||
cd /opt/android/cake_wallet/build/app/outputs/apk/release
|
||||
mkdir test-apk
|
||||
cp app-release.apk test-apk/$GITHUB_HEAD_REF.apk
|
||||
cp app-release.apk test-apk/${{env.BRANCH_NAME}}.apk
|
||||
|
||||
- name: Upload Artifact
|
||||
uses: kittaakos/upload-artifact-as-is@v0
|
||||
|
@ -179,6 +193,6 @@ jobs:
|
|||
token: ${{ secrets.SLACK_APP_TOKEN }}
|
||||
path: /opt/android/cake_wallet/build/app/outputs/apk/release/app-release.apk
|
||||
channel: ${{ secrets.SLACK_APK_CHANNEL }}
|
||||
title: "${{github.head_ref}}.apk"
|
||||
filename: ${{github.head_ref}}.apk
|
||||
title: "${{ env.BRANCH_NAME }}.apk"
|
||||
filename: ${{ env.BRANCH_NAME }}.apk
|
||||
initial_comment: ${{ github.event.head_commit.message }}
|
||||
|
|
BIN
assets/images/dfx_dark.png
Normal file
BIN
assets/images/dfx_dark.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.4 KiB |
BIN
assets/images/dfx_light.png
Normal file
BIN
assets/images/dfx_light.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.4 KiB |
|
@ -725,8 +725,7 @@ abstract class ElectrumWalletBase
|
|||
final index = address != null
|
||||
? walletAddresses.addresses.firstWhere((element) => element.address == address).index
|
||||
: null;
|
||||
return index == null
|
||||
? base64Encode(hd.sign(message))
|
||||
: base64Encode(hd.derive(index).sign(message));
|
||||
final HD = index == null ? hd : hd.derive(index);
|
||||
return base64Encode(HD.signMessage(message));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ dependencies:
|
|||
bitcoin_flutter:
|
||||
git:
|
||||
url: https://github.com/cake-tech/bitcoin_flutter.git
|
||||
ref: cake-update-v3
|
||||
ref: cake-update-v4
|
||||
bitbox:
|
||||
git:
|
||||
url: https://github.com/cake-tech/bitbox-flutter.git
|
||||
|
|
|
@ -302,10 +302,8 @@ abstract class BitcoinCashWalletBase extends ElectrumWallet with Store {
|
|||
final index = address != null
|
||||
? walletAddresses.addresses
|
||||
.firstWhere((element) => element.address == AddressUtils.toLegacyAddress(address))
|
||||
.index
|
||||
: null;
|
||||
return index == null
|
||||
? base64Encode(hd.sign(message))
|
||||
: base64Encode(hd.derive(index).sign(message));
|
||||
.index : null;
|
||||
final HD = index == null ? hd : hd.derive(index);
|
||||
return base64Encode(HD.signMessage(message));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ dependencies:
|
|||
bitcoin_flutter:
|
||||
git:
|
||||
url: https://github.com/cake-tech/bitcoin_flutter.git
|
||||
ref: cake-update-v3
|
||||
ref: cake-update-v4
|
||||
bitbox:
|
||||
git:
|
||||
url: https://github.com/cake-tech/bitbox-flutter.git
|
||||
|
|
|
@ -926,6 +926,8 @@ extern "C"
|
|||
return m_wallet->trustedDaemon();
|
||||
}
|
||||
|
||||
// Coin Control //
|
||||
|
||||
CoinsInfoRow* coin(int index)
|
||||
{
|
||||
if (index >= 0 && index < m_coins_info.size()) {
|
||||
|
@ -1020,6 +1022,13 @@ extern "C"
|
|||
m_coins->thaw(index);
|
||||
}
|
||||
|
||||
// Sign Messages //
|
||||
|
||||
char *sign_message(char *message, char *address = "")
|
||||
{
|
||||
return strdup(get_current_wallet()->signMessage(std::string(message), std::string(address)).c_str());
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -32,7 +32,8 @@ void store(char *path);
|
|||
|
||||
void set_trusted_daemon(bool arg);
|
||||
bool trusted_daemon();
|
||||
char *sign_message(char *message, char *address);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -149,3 +149,5 @@ typedef coin = Pointer<CoinsInfoRow> Function(Int32 index);
|
|||
typedef freeze_coin = Void Function(Int32 index);
|
||||
|
||||
typedef thaw_coin = Void Function(Int32 index);
|
||||
|
||||
typedef sign_message = Pointer<Utf8> Function(Pointer<Utf8> message, Pointer<Utf8> address);
|
||||
|
|
|
@ -149,3 +149,5 @@ typedef GetCoin = Pointer<CoinsInfoRow> Function(int);
|
|||
typedef FreezeCoin = void Function(int);
|
||||
|
||||
typedef ThawCoin = void Function(int);
|
||||
|
||||
typedef SignMessage = Pointer<Utf8> Function(Pointer<Utf8>, Pointer<Utf8>);
|
||||
|
|
|
@ -8,7 +8,6 @@ import 'package:cw_monero/api/types.dart';
|
|||
import 'package:cw_monero/api/monero_api.dart';
|
||||
import 'package:cw_monero/api/exceptions/setup_wallet_exception.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
int _boolToInt(bool value) => value ? 1 : 0;
|
||||
|
||||
|
@ -128,6 +127,10 @@ final trustedDaemonNative = moneroApi
|
|||
.lookup<NativeFunction<trusted_daemon>>('trusted_daemon')
|
||||
.asFunction<TrustedDaemon>();
|
||||
|
||||
final signMessageNative = moneroApi
|
||||
.lookup<NativeFunction<sign_message>>('sign_message')
|
||||
.asFunction<SignMessage>();
|
||||
|
||||
int getSyncingHeight() => getSyncingHeightNative();
|
||||
|
||||
bool isNeededToRefresh() => isNeededToRefreshNative() != 0;
|
||||
|
@ -296,7 +299,7 @@ class SyncListener {
|
|||
|
||||
final bchHeight = await getNodeHeightOrUpdate(syncHeight);
|
||||
|
||||
if (_lastKnownBlockHeight == syncHeight || syncHeight == null) {
|
||||
if (_lastKnownBlockHeight == syncHeight) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -311,7 +314,7 @@ class SyncListener {
|
|||
}
|
||||
|
||||
// 1. Actual new height; 2. Blocks left to finish; 3. Progress in percents;
|
||||
onNewBlock?.call(syncHeight, left, ptc);
|
||||
onNewBlock.call(syncHeight, left, ptc);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -382,4 +385,15 @@ String getSubaddressLabel(int accountIndex, int addressIndex) {
|
|||
|
||||
Future setTrustedDaemon(bool trusted) async => setTrustedDaemonNative(_boolToInt(trusted));
|
||||
|
||||
Future<bool> trustedDaemon() async => trustedDaemonNative() != 0;
|
||||
Future<bool> trustedDaemon() async => trustedDaemonNative() != 0;
|
||||
|
||||
String signMessage(String message, {String address = ""}) {
|
||||
final messagePointer = message.toNativeUtf8();
|
||||
final addressPointer = address.toNativeUtf8();
|
||||
|
||||
final signature = convertUTF8ToString(pointer: signMessageNative(messagePointer, addressPointer));
|
||||
calloc.free(messagePointer);
|
||||
calloc.free(addressPointer);
|
||||
|
||||
return signature;
|
||||
}
|
||||
|
|
|
@ -651,4 +651,10 @@ abstract class MoneroWalletBase
|
|||
|
||||
@override
|
||||
void setExceptionHandler(void Function(FlutterErrorDetails) onError) => _onError = onError;
|
||||
|
||||
@override
|
||||
String signMessage(String message, {String? address}) {
|
||||
final useAddress = address ?? "";
|
||||
return monero_wallet.signMessage(message, address: useAddress);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,6 @@ import 'package:cw_monero/api/wallet_manager.dart' as monero_wallet_manager;
|
|||
import 'package:cw_monero/monero_wallet.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:polyseed/polyseed.dart';
|
||||
import 'package:polyseed/src/utils/key_utils.dart';
|
||||
|
||||
class MoneroNewWalletCredentials extends WalletCredentials {
|
||||
MoneroNewWalletCredentials({required String name, required this.language, required this.isPolyseed, String? password})
|
||||
|
@ -275,7 +274,7 @@ class MoneroWalletService extends WalletService<
|
|||
{PolyseedCoin coin = PolyseedCoin.POLYSEED_MONERO, int? overrideHeight}) async {
|
||||
final height = overrideHeight ?? getMoneroHeigthByDate(
|
||||
date: DateTime.fromMillisecondsSinceEpoch(polyseed.birthday * 1000));
|
||||
final spendKey = keyToHexString(polyseed.generateKey(coin, 32));
|
||||
final spendKey = polyseed.generateKey(coin, 32).toHexString();
|
||||
final seed = polyseed.encode(lang, coin);
|
||||
|
||||
walletInfo.isRecovery = true;
|
||||
|
|
|
@ -1020,6 +1020,13 @@ extern "C"
|
|||
m_coins->thaw(index);
|
||||
}
|
||||
|
||||
// Sign Messages //
|
||||
|
||||
char *sign_message(char *message, char *address = "")
|
||||
{
|
||||
return strdup(get_current_wallet()->signMessage(std::string(message), std::string(address)).c_str());
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -32,7 +32,8 @@ void store(char *path);
|
|||
|
||||
void set_trusted_daemon(bool arg);
|
||||
bool trusted_daemon();
|
||||
char *sign_message(char *message, char *address);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -266,6 +266,22 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.0"
|
||||
hashlib:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: hashlib
|
||||
sha256: "71bf102329ddb8e50c8a995ee4645ae7f1728bb65e575c17196b4d8262121a96"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.12.0"
|
||||
hashlib_codecs:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: hashlib_codecs
|
||||
sha256: "49e2a471f74b15f1854263e58c2ac11f2b631b5b12c836f9708a35397d36d626"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.0"
|
||||
hive:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -485,12 +501,11 @@ packages:
|
|||
polyseed:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
path: "."
|
||||
ref: HEAD
|
||||
resolved-ref: "504d58a5b147fccd3bc85a25f2e72fb32771ddd7"
|
||||
url: "https://github.com/cake-tech/polyseed_dart.git"
|
||||
source: git
|
||||
version: "0.0.1"
|
||||
name: polyseed
|
||||
sha256: "9b48ec535b10863f78f6354ec983b4cc0c88ca69ff48fee469d0fd1954b01d4f"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.0.2"
|
||||
pool:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -632,15 +647,6 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
tor:
|
||||
dependency: transitive
|
||||
description:
|
||||
path: "."
|
||||
ref: main
|
||||
resolved-ref: "09ba92cb11d4e3cacf97256e57863b805f79f2e5"
|
||||
url: "https://github.com/cake-tech/tor.git"
|
||||
source: git
|
||||
version: "0.0.1"
|
||||
typed_data:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
|
@ -19,9 +19,7 @@ dependencies:
|
|||
flutter_mobx: ^2.0.6+1
|
||||
intl: ^0.18.0
|
||||
encrypt: ^5.0.1
|
||||
polyseed:
|
||||
git:
|
||||
url: https://github.com/cake-tech/polyseed_dart.git
|
||||
polyseed: ^0.0.2
|
||||
cw_core:
|
||||
path: ../cw_core
|
||||
|
||||
|
|
179
lib/buy/dfx/dfx_buy_provider.dart
Normal file
179
lib/buy/dfx/dfx_buy_provider.dart
Normal file
|
@ -0,0 +1,179 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/routes.dart';
|
||||
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
|
||||
import 'package:cake_wallet/utils/device_info.dart';
|
||||
import 'package:cake_wallet/utils/show_pop_up.dart';
|
||||
import 'package:cw_core/wallet_base.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
class DFXBuyProvider {
|
||||
DFXBuyProvider({required WalletBase wallet}) : this._wallet = wallet;
|
||||
|
||||
final WalletBase _wallet;
|
||||
|
||||
static const _baseUrl = 'api.dfx.swiss';
|
||||
static const _authPath = '/v1/auth/signMessage';
|
||||
static const _signUpPath = '/v1/auth/signUp';
|
||||
static const _signInPath = '/v1/auth/signIn';
|
||||
static const walletName = 'CakeWallet';
|
||||
|
||||
String get assetOut {
|
||||
switch (_wallet.type) {
|
||||
case WalletType.bitcoin:
|
||||
return 'BTC';
|
||||
case WalletType.bitcoinCash:
|
||||
return 'BCH';
|
||||
case WalletType.litecoin:
|
||||
return 'LTC';
|
||||
case WalletType.monero:
|
||||
return 'XMR';
|
||||
case WalletType.ethereum:
|
||||
return 'ETH';
|
||||
default:
|
||||
throw Exception("WalletType is not available for DFX ${_wallet.type}");
|
||||
}
|
||||
}
|
||||
|
||||
String get blockchain {
|
||||
switch (_wallet.type) {
|
||||
case WalletType.bitcoin:
|
||||
case WalletType.bitcoinCash:
|
||||
case WalletType.litecoin:
|
||||
return 'Bitcoin';
|
||||
case WalletType.monero:
|
||||
return 'Monero';
|
||||
case WalletType.ethereum:
|
||||
return 'Ethereum';
|
||||
default:
|
||||
throw Exception("WalletType is not available for DFX ${_wallet.type}");
|
||||
}
|
||||
}
|
||||
|
||||
Future<String> getSignMessage() async {
|
||||
final walletAddress = _wallet.walletAddresses.address;
|
||||
final uri = Uri.https(_baseUrl, _authPath, {'address': walletAddress});
|
||||
|
||||
var response = await http.get(uri, headers: {'accept': 'application/json'});
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
final responseBody = jsonDecode(response.body);
|
||||
return responseBody['message'] as String;
|
||||
} else {
|
||||
throw Exception(
|
||||
'Failed to get sign message. Status: ${response.statusCode} ${response.body}');
|
||||
}
|
||||
}
|
||||
|
||||
Future<String> signUp() async {
|
||||
final signMessage = getSignature(await getSignMessage());
|
||||
final walletAddress = _wallet.walletAddresses.address;
|
||||
|
||||
final requestBody = jsonEncode({
|
||||
'wallet': walletName,
|
||||
'address': walletAddress,
|
||||
'signature': signMessage,
|
||||
});
|
||||
|
||||
final uri = Uri.https(_baseUrl, _signUpPath);
|
||||
var response = await http.post(uri,
|
||||
headers: {'Content-Type': 'application/json'}, body: requestBody);
|
||||
|
||||
if (response.statusCode == 201) {
|
||||
final responseBody = jsonDecode(response.body);
|
||||
return responseBody['accessToken'] as String;
|
||||
} else {
|
||||
throw Exception(
|
||||
'Failed to sign up. Status: ${response.statusCode} ${response.body}');
|
||||
}
|
||||
}
|
||||
|
||||
Future<String> signIn() async {
|
||||
final signMessage = getSignature(await getSignMessage());
|
||||
final walletAddress = _wallet.walletAddresses.address;
|
||||
|
||||
final requestBody = jsonEncode({
|
||||
'address': walletAddress,
|
||||
'signature': signMessage,
|
||||
});
|
||||
|
||||
final uri = Uri.https(_baseUrl, _signInPath);
|
||||
var response = await http.post(uri,
|
||||
headers: {'Content-Type': 'application/json'}, body: requestBody);
|
||||
|
||||
if (response.statusCode == 201) {
|
||||
final responseBody = jsonDecode(response.body);
|
||||
return responseBody['accessToken'] as String;
|
||||
} else {
|
||||
throw Exception(
|
||||
'Failed to sign in. Status: ${response.statusCode} ${response.body}');
|
||||
}
|
||||
}
|
||||
|
||||
String getSignature(String message) {
|
||||
switch (_wallet.type) {
|
||||
case WalletType.ethereum:
|
||||
return _wallet.signMessage(message);
|
||||
case WalletType.monero:
|
||||
case WalletType.litecoin:
|
||||
case WalletType.bitcoin:
|
||||
case WalletType.bitcoinCash:
|
||||
return _wallet.signMessage(message,
|
||||
address: _wallet.walletAddresses.address);
|
||||
default:
|
||||
throw Exception("WalletType is not available for DFX ${_wallet.type}");
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> launchProvider(BuildContext context) async {
|
||||
try {
|
||||
final assetOut = this.assetOut;
|
||||
final blockchain = this.blockchain;
|
||||
|
||||
String accessToken;
|
||||
|
||||
try {
|
||||
accessToken = await signUp();
|
||||
} on Exception catch (e) {
|
||||
if (e.toString().contains('409')) {
|
||||
accessToken = await signIn();
|
||||
} else {
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
final uri = Uri.https('services.dfx.swiss', '/buy', {
|
||||
'session': accessToken,
|
||||
'lang': 'en',
|
||||
'asset-out': assetOut,
|
||||
'blockchain': blockchain,
|
||||
'asset-in': 'EUR',
|
||||
});
|
||||
|
||||
if (await canLaunchUrl(uri)) {
|
||||
if (DeviceInfo.instance.isMobile) {
|
||||
Navigator.of(context).pushNamed(Routes.webViewPage,
|
||||
arguments: [S.of(context).buy, uri]);
|
||||
} else {
|
||||
await launchUrl(uri, mode: LaunchMode.externalApplication);
|
||||
}
|
||||
} else {
|
||||
throw Exception('Could not launch URL');
|
||||
}
|
||||
} catch (e) {
|
||||
await showPopUp<void>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertWithOneAction(
|
||||
alertTitle: "DFX Connect",
|
||||
alertContent: S.of(context).buy_provider_unavailable + ': $e',
|
||||
buttonText: S.of(context).ok,
|
||||
buttonAction: () => Navigator.of(context).pop());
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
17
lib/di.dart
17
lib/di.dart
|
@ -90,6 +90,7 @@ import 'package:cake_wallet/view_model/ionia/ionia_purchase_merch_view_model.dar
|
|||
import 'package:cake_wallet/view_model/nano_account_list/nano_account_edit_or_create_view_model.dart';
|
||||
import 'package:cake_wallet/view_model/nano_account_list/nano_account_list_view_model.dart';
|
||||
import 'package:cake_wallet/view_model/node_list/pow_node_list_view_model.dart';
|
||||
import 'package:cake_wallet/view_model/seed_type_view_model.dart';
|
||||
import 'package:cake_wallet/view_model/set_up_2fa_viewmodel.dart';
|
||||
import 'package:cake_wallet/view_model/restore/restore_from_qr_vm.dart';
|
||||
import 'package:cake_wallet/view_model/settings/display_settings_view_model.dart';
|
||||
|
@ -227,6 +228,7 @@ import 'package:cake_wallet/core/wallet_loading_service.dart';
|
|||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:cake_wallet/entities/qr_view_data.dart';
|
||||
|
||||
import 'buy/dfx/dfx_buy_provider.dart';
|
||||
import 'core/totp_request_details.dart';
|
||||
import 'src/screens/settings/desktop_settings/desktop_settings_page.dart';
|
||||
|
||||
|
@ -718,6 +720,8 @@ Future<void> setup({
|
|||
|
||||
getIt.registerFactory(() => WalletSeedViewModel(getIt.get<AppStore>().wallet!));
|
||||
|
||||
getIt.registerFactory<SeedTypeViewModel>(() => SeedTypeViewModel(getIt.get<AppStore>()));
|
||||
|
||||
getIt.registerFactoryParam<WalletSeedPage, bool, void>((bool isWalletCreated, _) =>
|
||||
WalletSeedPage(getIt.get<WalletSeedViewModel>(), isNewWalletCreated: isWalletCreated));
|
||||
|
||||
|
@ -795,6 +799,9 @@ Future<void> setup({
|
|||
getIt.registerFactory<RobinhoodBuyProvider>(
|
||||
() => RobinhoodBuyProvider(wallet: getIt.get<AppStore>().wallet!));
|
||||
|
||||
getIt.registerFactory<DFXBuyProvider>(
|
||||
() => DFXBuyProvider(wallet: getIt.get<AppStore>().wallet!));
|
||||
|
||||
getIt.registerFactory<OnRamperBuyProvider>(() => OnRamperBuyProvider(
|
||||
settingsStore: getIt.get<AppStore>().settingsStore,
|
||||
wallet: getIt.get<AppStore>().wallet!,
|
||||
|
@ -846,7 +853,7 @@ Future<void> setup({
|
|||
return ethereum!.createEthereumWalletService(_walletInfoSource);
|
||||
case WalletType.bitcoinCash:
|
||||
return bitcoinCash!
|
||||
.createBitcoinCashWalletService(_walletInfoSource, _unspentCoinsInfoSource!);
|
||||
.createBitcoinCashWalletService(_walletInfoSource, _unspentCoinsInfoSource);
|
||||
case WalletType.nano:
|
||||
return nano!.createNanoWalletService(_walletInfoSource);
|
||||
case WalletType.polygon:
|
||||
|
@ -875,8 +882,8 @@ Future<void> setup({
|
|||
getIt.get<AppStore>(), getIt.get<WalletCreationService>(param1: type), _walletInfoSource,
|
||||
type: type));
|
||||
|
||||
getIt.registerFactoryParam<WalletRestorePage, WalletType, void>(
|
||||
(type, _) => WalletRestorePage(getIt.get<WalletRestoreViewModel>(param1: type)));
|
||||
getIt.registerFactoryParam<WalletRestorePage, WalletType, void>((type, _) => WalletRestorePage(
|
||||
getIt.get<WalletRestoreViewModel>(param1: type), getIt.get<SeedTypeViewModel>()));
|
||||
|
||||
getIt.registerFactoryParam<WalletRestoreChooseDerivationViewModel, List<DerivationInfo>, void>(
|
||||
(derivations, _) => WalletRestoreChooseDerivationViewModel(derivationInfos: derivations));
|
||||
|
@ -907,7 +914,7 @@ Future<void> setup({
|
|||
|
||||
getIt.registerFactoryParam<PreSeedPage, WalletType, AdvancedPrivacySettingsViewModel>(
|
||||
(WalletType type, AdvancedPrivacySettingsViewModel advancedPrivacySettingsViewModel) =>
|
||||
PreSeedPage(type, advancedPrivacySettingsViewModel));
|
||||
PreSeedPage(type, advancedPrivacySettingsViewModel, getIt.get<SeedTypeViewModel>()));
|
||||
|
||||
getIt.registerFactoryParam<TradeDetailsViewModel, Trade, void>((trade, _) =>
|
||||
TradeDetailsViewModel(
|
||||
|
@ -940,7 +947,7 @@ Future<void> setup({
|
|||
|
||||
getIt.registerFactory(() => BuyAmountViewModel());
|
||||
|
||||
getIt.registerFactory(() => BuyOptionsPage());
|
||||
getIt.registerFactory(() => BuyOptionsPage(getIt.get<DashboardViewModel>()));
|
||||
|
||||
getIt.registerFactory(() {
|
||||
final wallet = getIt.get<AppStore>().wallet;
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
|
||||
enum BuyProviderType {
|
||||
AskEachTime,
|
||||
Robinhood,
|
||||
Onramper;
|
||||
Onramper,
|
||||
DFX;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
|
@ -14,6 +16,42 @@ enum BuyProviderType {
|
|||
return "Robinhood";
|
||||
case BuyProviderType.Onramper:
|
||||
return "Onramper";
|
||||
case BuyProviderType.DFX:
|
||||
return "DFX";
|
||||
}
|
||||
}
|
||||
|
||||
static List<BuyProviderType> getAvailableProviders(WalletType walletType) {
|
||||
switch (walletType) {
|
||||
case WalletType.nano:
|
||||
case WalletType.banano:
|
||||
return [
|
||||
BuyProviderType.AskEachTime,
|
||||
BuyProviderType.Onramper
|
||||
];
|
||||
case WalletType.monero:
|
||||
return [
|
||||
BuyProviderType.AskEachTime,
|
||||
BuyProviderType.Onramper,
|
||||
BuyProviderType.DFX
|
||||
];
|
||||
case WalletType.bitcoin:
|
||||
case WalletType.ethereum:
|
||||
return [
|
||||
BuyProviderType.AskEachTime,
|
||||
BuyProviderType.Onramper,
|
||||
BuyProviderType.DFX,
|
||||
BuyProviderType.Robinhood
|
||||
];
|
||||
case WalletType.litecoin:
|
||||
case WalletType.bitcoinCash:
|
||||
return [
|
||||
BuyProviderType.AskEachTime,
|
||||
BuyProviderType.Onramper,
|
||||
BuyProviderType.Robinhood
|
||||
];
|
||||
default:
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import 'package:cake_wallet/buy/dfx/dfx_buy_provider.dart';
|
||||
import 'package:cake_wallet/buy/moonpay/moonpay_buy_provider.dart';
|
||||
import 'package:cake_wallet/buy/onramper/onramper_buy_provider.dart';
|
||||
import 'package:cake_wallet/buy/robinhood/robinhood_buy_provider.dart';
|
||||
|
@ -44,48 +45,54 @@ class MainActions {
|
|||
isEnabled: (viewModel) => viewModel.isEnabledBuyAction,
|
||||
canShow: (viewModel) => viewModel.hasBuyAction,
|
||||
onTap: (BuildContext context, DashboardViewModel viewModel) async {
|
||||
if (!viewModel.isEnabledBuyAction) {
|
||||
await _showErrorDialog(context, S.of(context).unsupported_asset);
|
||||
return;
|
||||
}
|
||||
|
||||
final defaultBuyProvider = viewModel.defaultBuyProvider;
|
||||
final walletType = viewModel.type;
|
||||
|
||||
if (!viewModel.isEnabledBuyAction) return;
|
||||
|
||||
switch (walletType) {
|
||||
case WalletType.bitcoin:
|
||||
case WalletType.litecoin:
|
||||
case WalletType.ethereum:
|
||||
case WalletType.polygon:
|
||||
case WalletType.bitcoinCash:
|
||||
switch (defaultBuyProvider) {
|
||||
case BuyProviderType.AskEachTime:
|
||||
Navigator.pushNamed(context, Routes.buy);
|
||||
break;
|
||||
case BuyProviderType.Onramper:
|
||||
await getIt.get<OnRamperBuyProvider>().launchProvider(context);
|
||||
break;
|
||||
case BuyProviderType.Robinhood:
|
||||
await getIt.get<RobinhoodBuyProvider>().launchProvider(context);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case WalletType.nano:
|
||||
case WalletType.banano:
|
||||
case WalletType.monero:
|
||||
await getIt.get<OnRamperBuyProvider>().launchProvider(context);
|
||||
break;
|
||||
default:
|
||||
await showPopUp<void>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertWithOneAction(
|
||||
alertTitle: S.of(context).buy,
|
||||
alertContent: S.of(context).unsupported_asset,
|
||||
buttonText: S.of(context).ok,
|
||||
buttonAction: () => Navigator.of(context).pop());
|
||||
});
|
||||
try {
|
||||
await _launchProviderByType(context, defaultBuyProvider);
|
||||
} catch (e) {
|
||||
await _showErrorDialog(context, e.toString());
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
static Future<void> _launchProviderByType(BuildContext context, BuyProviderType providerType) async {
|
||||
switch (providerType) {
|
||||
case BuyProviderType.AskEachTime:
|
||||
Navigator.pushNamed(context, Routes.buy);
|
||||
break;
|
||||
case BuyProviderType.Onramper:
|
||||
await getIt.get<OnRamperBuyProvider>().launchProvider(context);
|
||||
break;
|
||||
case BuyProviderType.Robinhood:
|
||||
await getIt.get<RobinhoodBuyProvider>().launchProvider(context);
|
||||
break;
|
||||
case BuyProviderType.DFX:
|
||||
await getIt.get<DFXBuyProvider>().launchProvider(context);
|
||||
break;
|
||||
default:
|
||||
throw UnsupportedError('Unsupported buy provider type');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static Future<void> _showErrorDialog(BuildContext context, String errorMessage) async {
|
||||
await showPopUp<void>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertWithOneAction(
|
||||
alertTitle: S.of(context).buy,
|
||||
alertContent: errorMessage,
|
||||
buttonText: S.of(context).ok,
|
||||
buttonAction: () => Navigator.of(context).pop(),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
static MainActions receiveAction = MainActions._(
|
||||
name: (context) => S.of(context).receive,
|
||||
image: 'assets/images/received.png',
|
||||
|
|
|
@ -6,7 +6,7 @@ class SeedType extends EnumerableItem<int> with Serializable<int> {
|
|||
|
||||
static const all = [SeedType.legacy, SeedType.polyseed];
|
||||
|
||||
static const defaultSeedType = legacy;
|
||||
static const defaultSeedType = polyseed;
|
||||
|
||||
static const legacy = SeedType(raw: 0, title: 'Legacy (25 words)');
|
||||
static const polyseed = SeedType(raw: 1, title: 'Polyseed (16 words)');
|
||||
|
|
|
@ -56,13 +56,13 @@ import 'package:cake_wallet/src/screens/support_other_links/support_other_links_
|
|||
import 'package:cake_wallet/src/screens/unspent_coins/unspent_coins_details_page.dart';
|
||||
import 'package:cake_wallet/src/screens/unspent_coins/unspent_coins_list_page.dart';
|
||||
import 'package:cake_wallet/src/screens/wallet_connect/wc_connections_listing_view.dart';
|
||||
import 'package:cake_wallet/store/settings_store.dart';
|
||||
import 'package:cake_wallet/utils/payment_request.dart';
|
||||
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
|
||||
import 'package:cake_wallet/view_model/dashboard/nft_view_model.dart';
|
||||
import 'package:cake_wallet/view_model/monero_account_list/account_list_item.dart';
|
||||
import 'package:cake_wallet/view_model/node_list/node_create_or_edit_view_model.dart';
|
||||
import 'package:cake_wallet/view_model/advanced_privacy_settings_view_model.dart';
|
||||
import 'package:cake_wallet/view_model/seed_type_view_model.dart';
|
||||
import 'package:cake_wallet/wallet_type_utils.dart';
|
||||
import 'package:cw_core/nano_account.dart';
|
||||
import 'package:cw_core/wallet_info.dart';
|
||||
|
@ -147,9 +147,9 @@ Route<dynamic> createRoute(RouteSettings settings) {
|
|||
case Routes.newWallet:
|
||||
final type = settings.arguments as WalletType;
|
||||
final walletNewVM = getIt.get<WalletNewVM>(param1: type);
|
||||
final settingsStore = getIt.get<SettingsStore>();
|
||||
final seedTypeViewModel = getIt.get<SeedTypeViewModel>();
|
||||
|
||||
return CupertinoPageRoute<void>(builder: (_) => NewWalletPage(walletNewVM, settingsStore));
|
||||
return CupertinoPageRoute<void>(builder: (_) => NewWalletPage(walletNewVM, seedTypeViewModel));
|
||||
|
||||
case Routes.setupPin:
|
||||
Function(PinCodeState<PinCodeWidget>, String)? callback;
|
||||
|
@ -535,9 +535,9 @@ Route<dynamic> createRoute(RouteSettings settings) {
|
|||
|
||||
return CupertinoPageRoute<void>(
|
||||
builder: (_) => AdvancedPrivacySettingsPage(
|
||||
getIt.get<AdvancedPrivacySettingsViewModel>(param1: type),
|
||||
getIt.get<NodeCreateOrEditViewModel>(param1: type, param2: false),
|
||||
));
|
||||
getIt.get<AdvancedPrivacySettingsViewModel>(param1: type),
|
||||
getIt.get<NodeCreateOrEditViewModel>(param1: type, param2: false),
|
||||
getIt.get<SeedTypeViewModel>()));
|
||||
|
||||
case Routes.anonPayInvoicePage:
|
||||
final args = settings.arguments as List;
|
||||
|
|
|
@ -1,18 +1,26 @@
|
|||
import 'package:cake_wallet/buy/dfx/dfx_buy_provider.dart';
|
||||
import 'package:cake_wallet/buy/onramper/onramper_buy_provider.dart';
|
||||
import 'package:cake_wallet/buy/robinhood/robinhood_buy_provider.dart';
|
||||
import 'package:cake_wallet/di.dart';
|
||||
import 'package:cake_wallet/entities/buy_provider_types.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/src/screens/base_page.dart';
|
||||
import 'package:cake_wallet/src/widgets/option_tile.dart';
|
||||
import 'package:cake_wallet/themes/extensions/option_tile_theme.dart';
|
||||
import 'package:cake_wallet/themes/extensions/transaction_trade_theme.dart';
|
||||
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class BuyOptionsPage extends BasePage {
|
||||
BuyOptionsPage(this.dashboardViewModel);
|
||||
|
||||
final DashboardViewModel dashboardViewModel;
|
||||
final iconDarkRobinhood = 'assets/images/robinhood_dark.png';
|
||||
final iconLightRobinhood = 'assets/images/robinhood_light.png';
|
||||
final iconDarkOnramper = 'assets/images/onramper_dark.png';
|
||||
final iconLightOnramper = 'assets/images/onramper_light.png';
|
||||
final iconDarkDFX = 'assets/images/dfx_dark.png';
|
||||
final iconLightDFX = 'assets/images/dfx_light.png';
|
||||
|
||||
@override
|
||||
String get title => S.current.buy;
|
||||
|
@ -22,11 +30,19 @@ class BuyOptionsPage extends BasePage {
|
|||
|
||||
@override
|
||||
Widget body(BuildContext context) {
|
||||
final isLightMode = Theme.of(context).extension<OptionTileTheme>()?.useDarkImage ?? false;
|
||||
final iconRobinhood =
|
||||
Image.asset(isLightMode ? iconLightRobinhood : iconDarkRobinhood, height: 40, width: 40);
|
||||
final iconOnramper =
|
||||
Image.asset(isLightMode ? iconLightOnramper : iconDarkOnramper, height: 40, width: 40);
|
||||
final isLightMode =
|
||||
Theme.of(context).extension<OptionTileTheme>()?.useDarkImage ?? false;
|
||||
final iconRobinhood = Image.asset(
|
||||
isLightMode ? iconLightRobinhood : iconDarkRobinhood,
|
||||
height: 40,
|
||||
width: 40);
|
||||
final iconOnramper = Image.asset(
|
||||
isLightMode ? iconLightOnramper : iconDarkOnramper,
|
||||
height: 40,
|
||||
width: 40);
|
||||
final iconDFX = Image.asset(isLightMode ? iconLightDFX : iconDarkDFX,
|
||||
height: 40, width: 40);
|
||||
final availableProviders = dashboardViewModel.availableProviders;
|
||||
|
||||
return Container(
|
||||
child: Center(
|
||||
|
@ -34,26 +50,42 @@ class BuyOptionsPage extends BasePage {
|
|||
constraints: BoxConstraints(maxWidth: 330),
|
||||
child: Column(
|
||||
children: [
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 24),
|
||||
child: OptionTile(
|
||||
image: iconOnramper,
|
||||
title: "Onramper",
|
||||
description: S.of(context).onramper_option_description,
|
||||
onPressed: () async =>
|
||||
await getIt.get<OnRamperBuyProvider>().launchProvider(context),
|
||||
if (availableProviders.contains(BuyProviderType.Onramper))
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 24),
|
||||
child: OptionTile(
|
||||
image: iconOnramper,
|
||||
title: "Onramper",
|
||||
description: S.of(context).onramper_option_description,
|
||||
onPressed: () async => await getIt
|
||||
.get<OnRamperBuyProvider>()
|
||||
.launchProvider(context),
|
||||
),
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 24),
|
||||
child: OptionTile(
|
||||
image: iconRobinhood,
|
||||
title: "Robinhood Connect",
|
||||
description: S.of(context).robinhood_option_description,
|
||||
onPressed: () async =>
|
||||
await getIt.get<RobinhoodBuyProvider>().launchProvider(context),
|
||||
if (availableProviders.contains(BuyProviderType.Robinhood))
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 24),
|
||||
child: OptionTile(
|
||||
image: iconRobinhood,
|
||||
title: "Robinhood Connect",
|
||||
description: S.of(context).robinhood_option_description,
|
||||
onPressed: () async => await getIt
|
||||
.get<RobinhoodBuyProvider>()
|
||||
.launchProvider(context),
|
||||
),
|
||||
),
|
||||
if (availableProviders.contains(BuyProviderType.DFX))
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 24),
|
||||
child: OptionTile(
|
||||
image: iconDFX,
|
||||
title: "DFX Connect",
|
||||
description: S.of(context).dfx_option_description,
|
||||
onPressed: () async => await getIt
|
||||
.get<DFXBuyProvider>()
|
||||
.launchProvider(context),
|
||||
),
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
Padding(
|
||||
padding: EdgeInsets.fromLTRB(24, 24, 24, 32),
|
||||
|
@ -63,7 +95,9 @@ class BuyOptionsPage extends BasePage {
|
|||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.normal,
|
||||
color: Theme.of(context).extension<TransactionTradeTheme>()!.detailsTitlesColor,
|
||||
color: Theme.of(context)
|
||||
.extension<TransactionTradeTheme>()!
|
||||
.detailsTitlesColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
|
@ -9,6 +9,7 @@ import 'package:cake_wallet/src/screens/settings/widgets/settings_switcher_cell.
|
|||
import 'package:cake_wallet/themes/extensions/new_wallet_theme.dart';
|
||||
import 'package:cake_wallet/view_model/node_list/node_create_or_edit_view_model.dart';
|
||||
import 'package:cake_wallet/view_model/advanced_privacy_settings_view_model.dart';
|
||||
import 'package:cake_wallet/view_model/seed_type_view_model.dart';
|
||||
import 'package:cake_wallet/view_model/settings/choices_list_item.dart';
|
||||
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
@ -18,25 +19,30 @@ import 'package:cake_wallet/src/widgets/primary_button.dart';
|
|||
import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
|
||||
|
||||
class AdvancedPrivacySettingsPage extends BasePage {
|
||||
AdvancedPrivacySettingsPage(this.advancedPrivacySettingsViewModel, this.nodeViewModel);
|
||||
AdvancedPrivacySettingsPage(
|
||||
this.advancedPrivacySettingsViewModel, this.nodeViewModel, this.seedTypeViewModel);
|
||||
|
||||
final AdvancedPrivacySettingsViewModel advancedPrivacySettingsViewModel;
|
||||
final NodeCreateOrEditViewModel nodeViewModel;
|
||||
final SeedTypeViewModel seedTypeViewModel;
|
||||
|
||||
@override
|
||||
String get title => S.current.privacy_settings;
|
||||
|
||||
@override
|
||||
Widget body(BuildContext context) =>
|
||||
AdvancedPrivacySettingsBody(advancedPrivacySettingsViewModel, nodeViewModel);
|
||||
Widget body(BuildContext context) => AdvancedPrivacySettingsBody(
|
||||
advancedPrivacySettingsViewModel, nodeViewModel, seedTypeViewModel);
|
||||
}
|
||||
|
||||
class AdvancedPrivacySettingsBody extends StatefulWidget {
|
||||
const AdvancedPrivacySettingsBody(this.privacySettingsViewModel, this.nodeViewModel, {Key? key})
|
||||
const AdvancedPrivacySettingsBody(
|
||||
this.privacySettingsViewModel, this.nodeViewModel, this.seedTypeViewModel,
|
||||
{Key? key})
|
||||
: super(key: key);
|
||||
|
||||
final AdvancedPrivacySettingsViewModel privacySettingsViewModel;
|
||||
final NodeCreateOrEditViewModel nodeViewModel;
|
||||
final SeedTypeViewModel seedTypeViewModel;
|
||||
|
||||
@override
|
||||
_AdvancedPrivacySettingsBodyState createState() => _AdvancedPrivacySettingsBodyState();
|
||||
|
@ -59,7 +65,7 @@ class _AdvancedPrivacySettingsBodyState extends State<AdvancedPrivacySettingsBod
|
|||
Observer(builder: (_) {
|
||||
return SettingsChoicesCell(
|
||||
ChoicesListItem<FiatApiMode>(
|
||||
title: S.current.disable_fiat,
|
||||
title: S.current.fiat_api,
|
||||
items: FiatApiMode.all,
|
||||
selectedItem: widget.privacySettingsViewModel.fiatApiMode,
|
||||
onItemSelected: (FiatApiMode mode) =>
|
||||
|
@ -114,8 +120,8 @@ class _AdvancedPrivacySettingsBodyState extends State<AdvancedPrivacySettingsBod
|
|||
ChoicesListItem<SeedType>(
|
||||
title: S.current.seedtype,
|
||||
items: SeedType.all,
|
||||
selectedItem: widget.privacySettingsViewModel.seedType,
|
||||
onItemSelected: widget.privacySettingsViewModel.setSeedType,
|
||||
selectedItem: widget.seedTypeViewModel.moneroSeedType,
|
||||
onItemSelected: widget.seedTypeViewModel.setMoneroSeedType,
|
||||
),
|
||||
);
|
||||
}),
|
||||
|
|
|
@ -7,6 +7,7 @@ import 'package:cake_wallet/routes.dart';
|
|||
import 'package:cake_wallet/themes/theme_base.dart';
|
||||
import 'package:cake_wallet/utils/responsive_layout_util.dart';
|
||||
import 'package:cake_wallet/utils/show_pop_up.dart';
|
||||
import 'package:cake_wallet/view_model/seed_type_view_model.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
@ -23,13 +24,12 @@ import 'package:cake_wallet/view_model/wallet_new_vm.dart';
|
|||
import 'package:cake_wallet/themes/extensions/new_wallet_theme.dart';
|
||||
import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
|
||||
import 'package:cake_wallet/entities/seed_type.dart';
|
||||
import 'package:cake_wallet/store/settings_store.dart';
|
||||
|
||||
class NewWalletPage extends BasePage {
|
||||
NewWalletPage(this._walletNewVM, this._settingsStore);
|
||||
NewWalletPage(this._walletNewVM, this._seedTypeViewModel);
|
||||
|
||||
final WalletNewVM _walletNewVM;
|
||||
final SettingsStore _settingsStore;
|
||||
final SeedTypeViewModel _seedTypeViewModel;
|
||||
|
||||
final walletNameImage = Image.asset('assets/images/wallet_name.png');
|
||||
|
||||
|
@ -40,15 +40,15 @@ class NewWalletPage extends BasePage {
|
|||
|
||||
@override
|
||||
Widget body(BuildContext context) => WalletNameForm(
|
||||
_walletNewVM, currentTheme.type == ThemeType.dark ? walletNameImage : walletNameLightImage, _settingsStore);
|
||||
_walletNewVM, currentTheme.type == ThemeType.dark ? walletNameImage : walletNameLightImage, _seedTypeViewModel);
|
||||
}
|
||||
|
||||
class WalletNameForm extends StatefulWidget {
|
||||
WalletNameForm(this._walletNewVM, this.walletImage, this._settingsStore);
|
||||
WalletNameForm(this._walletNewVM, this.walletImage, this._seedTypeViewModel);
|
||||
|
||||
final WalletNewVM _walletNewVM;
|
||||
final Image walletImage;
|
||||
final SettingsStore _settingsStore;
|
||||
final SeedTypeViewModel _seedTypeViewModel;
|
||||
|
||||
@override
|
||||
_WalletNameFormState createState() => _WalletNameFormState(_walletNewVM);
|
||||
|
@ -194,7 +194,7 @@ class _WalletNameFormState extends State<WalletNameForm> {
|
|||
builder: (BuildContext build) => Padding(
|
||||
padding: EdgeInsets.only(top: 24),
|
||||
child: SelectButton(
|
||||
text: widget._settingsStore.moneroSeedType.title,
|
||||
text: widget._seedTypeViewModel.moneroSeedType.title,
|
||||
onTap: () async {
|
||||
await showPopUp<void>(
|
||||
context: context,
|
||||
|
@ -217,7 +217,7 @@ class _WalletNameFormState extends State<WalletNameForm> {
|
|||
key: _languageSelectorKey,
|
||||
initialSelected: defaultSeedLanguage,
|
||||
seedType: _walletNewVM.hasSeedType
|
||||
? widget._settingsStore.moneroSeedType
|
||||
? widget._seedTypeViewModel.moneroSeedType
|
||||
: SeedType.legacy,
|
||||
),
|
||||
),
|
||||
|
@ -277,10 +277,10 @@ class _WalletNameFormState extends State<WalletNameForm> {
|
|||
}
|
||||
}
|
||||
|
||||
bool get isPolyseed => widget._settingsStore.moneroSeedType == SeedType.polyseed;
|
||||
bool get isPolyseed => widget._seedTypeViewModel.moneroSeedType == SeedType.polyseed;
|
||||
|
||||
void _setSeedType(SeedType item) {
|
||||
widget._settingsStore.moneroSeedType = item;
|
||||
widget._seedTypeViewModel.setMoneroSeedType(item);
|
||||
_languageSelectorKey.currentState?.selected = defaultSeedLanguage; // Reset Seed language
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,8 +9,10 @@ import 'package:cake_wallet/src/widgets/seed_language_picker.dart';
|
|||
import 'package:cake_wallet/src/widgets/seed_widget.dart';
|
||||
import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
|
||||
import 'package:cake_wallet/utils/show_pop_up.dart';
|
||||
import 'package:cake_wallet/view_model/seed_type_view_model.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:polyseed/polyseed.dart';
|
||||
|
||||
class WalletRestoreFromSeedForm extends StatefulWidget {
|
||||
|
@ -19,6 +21,7 @@ class WalletRestoreFromSeedForm extends StatefulWidget {
|
|||
required this.displayLanguageSelector,
|
||||
required this.displayBlockHeightSelector,
|
||||
required this.type,
|
||||
required this.seedTypeViewModel,
|
||||
this.blockHeightFocusNode,
|
||||
this.onHeightOrDateEntered,
|
||||
this.onSeedChange,
|
||||
|
@ -28,6 +31,7 @@ class WalletRestoreFromSeedForm extends StatefulWidget {
|
|||
final WalletType type;
|
||||
final bool displayLanguageSelector;
|
||||
final bool displayBlockHeightSelector;
|
||||
final SeedTypeViewModel seedTypeViewModel;
|
||||
final FocusNode? blockHeightFocusNode;
|
||||
final Function(bool)? onHeightOrDateEntered;
|
||||
final void Function(String)? onSeedChange;
|
||||
|
@ -52,16 +56,28 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
|
|||
final TextEditingController nameTextEditingController;
|
||||
final TextEditingController seedTypeController;
|
||||
final GlobalKey<FormState> formKey;
|
||||
late ReactionDisposer moneroSeedTypeReaction;
|
||||
String language;
|
||||
bool isPolyseed = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
_setSeedType(widget.seedTypeViewModel.moneroSeedType);
|
||||
_setLanguageLabel(language);
|
||||
_setSeedType(SeedType.defaultSeedType);
|
||||
moneroSeedTypeReaction =
|
||||
reaction((_) => widget.seedTypeViewModel.moneroSeedType, (SeedType item) {
|
||||
_setSeedType(item);
|
||||
_changeLanguage('English');
|
||||
});
|
||||
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
moneroSeedTypeReaction();
|
||||
}
|
||||
|
||||
void onSeedChange(String seed) {
|
||||
if (widget.type == WalletType.monero && Polyseed.isValidSeed(seed)) {
|
||||
final lang = PolyseedLang.getByPhrase(seed);
|
||||
|
@ -181,6 +197,8 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
|
|||
]));
|
||||
}
|
||||
|
||||
bool get isPolyseed => widget.seedTypeViewModel.moneroSeedType == SeedType.polyseed;
|
||||
|
||||
Widget get expandIcon => Container(
|
||||
padding: EdgeInsets.all(18),
|
||||
width: 24,
|
||||
|
@ -208,10 +226,10 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
|
|||
void _changeSeedType(SeedType item) {
|
||||
_setSeedType(item);
|
||||
_changeLanguage('English');
|
||||
widget.seedTypeViewModel.setMoneroSeedType(item);
|
||||
}
|
||||
|
||||
void _setSeedType(SeedType item) {
|
||||
setState(() => isPolyseed = item == SeedType.polyseed);
|
||||
seedTypeController.text = item.toString();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ import 'package:cake_wallet/themes/extensions/wallet_list_theme.dart';
|
|||
import 'package:cake_wallet/utils/responsive_layout_util.dart';
|
||||
import 'package:cake_wallet/utils/show_pop_up.dart';
|
||||
import 'package:cake_wallet/view_model/restore/restore_mode.dart';
|
||||
import 'package:cake_wallet/view_model/seed_type_view_model.dart';
|
||||
import 'package:cake_wallet/view_model/wallet_restore_view_model.dart';
|
||||
import 'package:cw_core/nano_account_info_response.dart';
|
||||
import 'package:cw_core/wallet_info.dart';
|
||||
|
@ -27,7 +28,7 @@ import 'package:polyseed/polyseed.dart';
|
|||
import 'package:smooth_page_indicator/smooth_page_indicator.dart';
|
||||
|
||||
class WalletRestorePage extends BasePage {
|
||||
WalletRestorePage(this.walletRestoreViewModel)
|
||||
WalletRestorePage(this.walletRestoreViewModel, this.seedTypeViewModel)
|
||||
: walletRestoreFromSeedFormKey = GlobalKey<WalletRestoreFromSeedFormState>(),
|
||||
walletRestoreFromKeysFormKey = GlobalKey<WalletRestoreFromKeysFromState>(),
|
||||
_pages = [],
|
||||
|
@ -37,6 +38,7 @@ class WalletRestorePage extends BasePage {
|
|||
switch (mode) {
|
||||
case WalletRestoreMode.seed:
|
||||
_pages.add(WalletRestoreFromSeedForm(
|
||||
seedTypeViewModel: seedTypeViewModel,
|
||||
displayBlockHeightSelector:
|
||||
walletRestoreViewModel.hasBlockchainHeightLanguageSelector,
|
||||
displayLanguageSelector: walletRestoreViewModel.hasSeedLanguageSelector,
|
||||
|
@ -91,6 +93,7 @@ class WalletRestorePage extends BasePage {
|
|||
));
|
||||
|
||||
final WalletRestoreViewModel walletRestoreViewModel;
|
||||
final SeedTypeViewModel seedTypeViewModel;
|
||||
final PageController _controller;
|
||||
final List<Widget> _pages;
|
||||
final GlobalKey<WalletRestoreFromSeedFormState> walletRestoreFromSeedFormKey;
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import 'package:cake_wallet/entities/seed_type.dart';
|
||||
import 'package:cake_wallet/utils/responsive_layout_util.dart';
|
||||
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
|
||||
import 'package:cake_wallet/view_model/advanced_privacy_settings_view_model.dart';
|
||||
import 'package:cake_wallet/view_model/seed_type_view_model.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
import 'package:cake_wallet/src/screens/base_page.dart';
|
||||
import 'package:cake_wallet/src/widgets/primary_button.dart';
|
||||
|
@ -10,19 +12,21 @@ import 'package:cake_wallet/themes/theme_base.dart';
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
class PreSeedPage extends BasePage {
|
||||
PreSeedPage(this.type, this.advancedPrivacySettingsViewModel)
|
||||
PreSeedPage(this.type, this.advancedPrivacySettingsViewModel, this.seedTypeViewModel)
|
||||
: imageLight = Image.asset('assets/images/pre_seed_light.png'),
|
||||
imageDark = Image.asset('assets/images/pre_seed_dark.png'),
|
||||
seedPhraseLength =
|
||||
advancedPrivacySettingsViewModel.seedPhraseLength.value {
|
||||
wordsCount = _wordsCount(type, seedPhraseLength);
|
||||
seedPhraseLength = advancedPrivacySettingsViewModel.seedPhraseLength.value,
|
||||
moneroSeedType = seedTypeViewModel.moneroSeedType {
|
||||
wordsCount = _wordsCount(type, seedPhraseLength, moneroSeedType);
|
||||
}
|
||||
|
||||
final Image imageDark;
|
||||
final Image imageLight;
|
||||
final WalletType type;
|
||||
final AdvancedPrivacySettingsViewModel advancedPrivacySettingsViewModel;
|
||||
final SeedTypeViewModel seedTypeViewModel;
|
||||
final int seedPhraseLength;
|
||||
final SeedType moneroSeedType;
|
||||
late final int wordsCount;
|
||||
|
||||
@override
|
||||
|
@ -76,9 +80,11 @@ class PreSeedPage extends BasePage {
|
|||
));
|
||||
}
|
||||
|
||||
static int _wordsCount(WalletType type, int seedPhraseLength) {
|
||||
static int _wordsCount(WalletType type, int seedPhraseLength, SeedType moneroSeedType) {
|
||||
switch (type) {
|
||||
case WalletType.monero:
|
||||
if (moneroSeedType == SeedType.polyseed)
|
||||
return 16;
|
||||
return 25;
|
||||
case WalletType.ethereum:
|
||||
case WalletType.bitcoinCash:
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
import 'package:cake_wallet/buy/buy_provider.dart';
|
||||
import 'package:cake_wallet/entities/buy_provider_types.dart';
|
||||
import 'package:cake_wallet/entities/priority_for_wallet_type.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/routes.dart';
|
||||
|
@ -42,9 +40,10 @@ class OtherSettingsPage extends BasePage {
|
|||
handler: (BuildContext context) =>
|
||||
Navigator.of(context).pushNamed(Routes.changeRep),
|
||||
),
|
||||
if(_otherSettingsViewModel.isEnabledBuyAction)
|
||||
SettingsPickerCell(
|
||||
title: S.current.default_buy_provider,
|
||||
items: BuyProviderType.values,
|
||||
items: _otherSettingsViewModel.availableBuyProviders,
|
||||
displayItem: _otherSettingsViewModel.getBuyProviderType,
|
||||
selectedItem: _otherSettingsViewModel.buyProviderType,
|
||||
onItemSelected: _otherSettingsViewModel.onBuyProviderTypeSelected,
|
||||
|
|
|
@ -36,7 +36,6 @@ import 'package:cake_wallet/monero/monero.dart';
|
|||
import 'package:cake_wallet/entities/action_list_display_mode.dart';
|
||||
import 'package:cake_wallet/entities/fiat_api_mode.dart';
|
||||
import 'package:cw_core/set_app_secure_native.dart';
|
||||
|
||||
part 'settings_store.g.dart';
|
||||
|
||||
class SettingsStore = SettingsStoreBase with _$SettingsStore;
|
||||
|
@ -123,7 +122,6 @@ abstract class SettingsStoreBase with Store {
|
|||
isAppSecure = initialAppSecure,
|
||||
disableBuy = initialDisableBuy,
|
||||
disableSell = initialDisableSell,
|
||||
defaultBuyProvider = initialDefaultBuyProvider,
|
||||
shouldShowMarketPlaceInDashboard = initialShouldShowMarketPlaceInDashboard,
|
||||
exchangeStatus = initialExchangeStatus,
|
||||
currentTheme = initialTheme,
|
||||
|
@ -178,6 +176,12 @@ abstract class SettingsStoreBase with Store {
|
|||
|
||||
initializeTrocadorProviderStates();
|
||||
|
||||
WalletType.values.forEach((walletType) {
|
||||
final key = 'defaultBuyProvider_${walletType.toString()}';
|
||||
final providerIndex = sharedPreferences.getInt(key);
|
||||
defaultBuyProviders[walletType] = providerIndex != null ? BuyProviderType.values[providerIndex] : BuyProviderType.AskEachTime;
|
||||
});
|
||||
|
||||
reaction(
|
||||
(_) => fiatCurrency,
|
||||
(FiatCurrency fiatCurrency) => sharedPreferences.setString(
|
||||
|
@ -244,9 +248,14 @@ abstract class SettingsStoreBase with Store {
|
|||
sharedPreferences.setBool(PreferencesKey.disableSellKey, disableSell));
|
||||
|
||||
reaction(
|
||||
(_) => defaultBuyProvider,
|
||||
(BuyProviderType defaultBuyProvider) =>
|
||||
sharedPreferences.setInt(PreferencesKey.defaultBuyProvider, defaultBuyProvider.index));
|
||||
(_) => defaultBuyProviders.asObservable(),
|
||||
(ObservableMap<WalletType, BuyProviderType> providers) {
|
||||
providers.forEach((walletType, provider) {
|
||||
final key = 'defaultBuyProvider_${walletType.toString()}';
|
||||
sharedPreferences.setInt(key, provider.index);
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
reaction(
|
||||
(_) => autoGenerateSubaddressStatus,
|
||||
|
@ -333,6 +342,7 @@ abstract class SettingsStoreBase with Store {
|
|||
|
||||
reaction((_) => totpSecretKey,
|
||||
(String totpKey) => sharedPreferences.setString(PreferencesKey.totpSecretKey, totpKey));
|
||||
|
||||
reaction(
|
||||
(_) => numberOfFailedTokenTrials,
|
||||
(int failedTokenTrail) =>
|
||||
|
@ -494,9 +504,6 @@ abstract class SettingsStoreBase with Store {
|
|||
@observable
|
||||
bool disableSell;
|
||||
|
||||
@observable
|
||||
BuyProviderType defaultBuyProvider;
|
||||
|
||||
@observable
|
||||
bool allowBiometricalAuthentication;
|
||||
|
||||
|
@ -566,6 +573,9 @@ abstract class SettingsStoreBase with Store {
|
|||
@observable
|
||||
ObservableMap<String, bool> trocadorProviderStates = ObservableMap<String, bool>();
|
||||
|
||||
@observable
|
||||
ObservableMap<WalletType, BuyProviderType> defaultBuyProviders = ObservableMap<WalletType, BuyProviderType>();
|
||||
|
||||
@observable
|
||||
SortBalanceBy sortBalanceBy;
|
||||
|
||||
|
@ -867,7 +877,7 @@ abstract class SettingsStoreBase with Store {
|
|||
}
|
||||
|
||||
final savedSyncMode = SyncMode.all.firstWhere((element) {
|
||||
return element.type.index == (sharedPreferences.getInt(PreferencesKey.syncModeKey) ?? 1);
|
||||
return element.type.index == (sharedPreferences.getInt(PreferencesKey.syncModeKey) ?? 0);
|
||||
});
|
||||
final savedSyncAll = sharedPreferences.getBool(PreferencesKey.syncAllKey) ?? true;
|
||||
|
||||
|
@ -1003,8 +1013,6 @@ abstract class SettingsStoreBase with Store {
|
|||
isAppSecure = sharedPreferences.getBool(PreferencesKey.isAppSecureKey) ?? isAppSecure;
|
||||
disableBuy = sharedPreferences.getBool(PreferencesKey.disableBuyKey) ?? disableBuy;
|
||||
disableSell = sharedPreferences.getBool(PreferencesKey.disableSellKey) ?? disableSell;
|
||||
defaultBuyProvider =
|
||||
BuyProviderType.values[sharedPreferences.getInt(PreferencesKey.defaultBuyProvider) ?? 0];
|
||||
allowBiometricalAuthentication =
|
||||
sharedPreferences.getBool(PreferencesKey.allowBiometricalAuthenticationKey) ??
|
||||
allowBiometricalAuthentication;
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import 'package:cake_wallet/entities/exchange_api_mode.dart';
|
||||
import 'package:cake_wallet/entities/fiat_api_mode.dart';
|
||||
import 'package:cake_wallet/entities/seed_phrase_length.dart';
|
||||
import 'package:cake_wallet/entities/seed_type.dart';
|
||||
import 'package:cake_wallet/store/settings_store.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
|
@ -20,9 +19,6 @@ abstract class AdvancedPrivacySettingsViewModelBase with Store {
|
|||
@computed
|
||||
FiatApiMode get fiatApiMode => _settingsStore.fiatApiMode;
|
||||
|
||||
@computed
|
||||
SeedType get seedType => _settingsStore.moneroSeedType;
|
||||
|
||||
@observable
|
||||
bool _addCustomNode = false;
|
||||
|
||||
|
@ -44,9 +40,6 @@ abstract class AdvancedPrivacySettingsViewModelBase with Store {
|
|||
@action
|
||||
void setFiatApiMode(FiatApiMode fiatApiMode) => _settingsStore.fiatApiMode = fiatApiMode;
|
||||
|
||||
@action
|
||||
void setSeedType(SeedType seedType) => _settingsStore.moneroSeedType = seedType;
|
||||
|
||||
@action
|
||||
void setExchangeApiMode(ExchangeApiMode value) => _settingsStore.exchangeStatus = value;
|
||||
|
||||
|
|
|
@ -282,10 +282,14 @@ abstract class DashboardViewModelBase with Store {
|
|||
|
||||
Map<String, List<FilterItem>> filterItems;
|
||||
|
||||
BuyProviderType get defaultBuyProvider => settingsStore.defaultBuyProvider;
|
||||
BuyProviderType get defaultBuyProvider =>
|
||||
settingsStore.defaultBuyProviders[wallet.type] ??
|
||||
BuyProviderType.AskEachTime;
|
||||
|
||||
bool get isBuyEnabled => settingsStore.isBitcoinBuyEnabled;
|
||||
|
||||
List<BuyProviderType> get availableProviders => BuyProviderType.getAvailableProviders(wallet.type);
|
||||
|
||||
bool get shouldShowYatPopup => settingsStore.shouldShowYatPopup;
|
||||
|
||||
@action
|
||||
|
|
19
lib/view_model/seed_type_view_model.dart
Normal file
19
lib/view_model/seed_type_view_model.dart
Normal file
|
@ -0,0 +1,19 @@
|
|||
import 'package:cake_wallet/entities/seed_type.dart';
|
||||
import 'package:cake_wallet/store/app_store.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
|
||||
part 'seed_type_view_model.g.dart';
|
||||
|
||||
class SeedTypeViewModel = SeedTypeViewModelBase with _$SeedTypeViewModel;
|
||||
|
||||
abstract class SeedTypeViewModelBase with Store {
|
||||
SeedTypeViewModelBase(this._appStore);
|
||||
|
||||
@computed
|
||||
SeedType get moneroSeedType => _appStore.settingsStore.moneroSeedType;
|
||||
|
||||
@action
|
||||
void setMoneroSeedType(SeedType seedType) => _appStore.settingsStore.moneroSeedType = seedType;
|
||||
|
||||
final AppStore _appStore;
|
||||
}
|
|
@ -13,14 +13,15 @@ import 'package:package_info/package_info.dart';
|
|||
|
||||
part 'other_settings_view_model.g.dart';
|
||||
|
||||
class OtherSettingsViewModel = OtherSettingsViewModelBase with _$OtherSettingsViewModel;
|
||||
class OtherSettingsViewModel = OtherSettingsViewModelBase
|
||||
with _$OtherSettingsViewModel;
|
||||
|
||||
abstract class OtherSettingsViewModelBase with Store {
|
||||
OtherSettingsViewModelBase(this._settingsStore, this._wallet)
|
||||
: walletType = _wallet.type,
|
||||
currentVersion = '' {
|
||||
PackageInfo.fromPlatform()
|
||||
.then((PackageInfo packageInfo) => currentVersion = packageInfo.version);
|
||||
PackageInfo.fromPlatform().then(
|
||||
(PackageInfo packageInfo) => currentVersion = packageInfo.version);
|
||||
|
||||
final priority = _settingsStore.priority[_wallet.type];
|
||||
final priorities = priorityForWalletType(_wallet.type);
|
||||
|
@ -31,7 +32,8 @@ abstract class OtherSettingsViewModelBase with Store {
|
|||
}
|
||||
|
||||
final WalletType walletType;
|
||||
final WalletBase<Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo> _wallet;
|
||||
final WalletBase<Balance, TransactionHistoryBase<TransactionInfo>,
|
||||
TransactionInfo> _wallet;
|
||||
|
||||
@observable
|
||||
String currentVersion;
|
||||
|
@ -50,15 +52,19 @@ abstract class OtherSettingsViewModelBase with Store {
|
|||
}
|
||||
|
||||
@computed
|
||||
bool get changeRepresentativeEnabled {
|
||||
if (_wallet.type == WalletType.nano || _wallet.type == WalletType.banano) {
|
||||
return true;
|
||||
}
|
||||
bool get changeRepresentativeEnabled =>
|
||||
_wallet.type == WalletType.nano || _wallet.type == WalletType.banano;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
BuyProviderType get buyProviderType { return _settingsStore.defaultBuyProvider; }
|
||||
@computed
|
||||
bool get isEnabledBuyAction =>
|
||||
!_settingsStore.disableBuy && _wallet.type != WalletType.haven;
|
||||
|
||||
List<BuyProviderType> get availableBuyProviders =>
|
||||
BuyProviderType.getAvailableProviders(walletType);
|
||||
|
||||
BuyProviderType get buyProviderType =>
|
||||
_settingsStore.defaultBuyProviders[walletType] ??
|
||||
BuyProviderType.AskEachTime;
|
||||
|
||||
String getDisplayPriority(dynamic priority) {
|
||||
final _priority = priority as TransactionPriority;
|
||||
|
@ -73,7 +79,7 @@ abstract class OtherSettingsViewModelBase with Store {
|
|||
return priority.toString();
|
||||
}
|
||||
|
||||
String getBuyProviderType (dynamic buyProviderType) {
|
||||
String getBuyProviderType(dynamic buyProviderType) {
|
||||
final _buyProviderType = buyProviderType as BuyProviderType;
|
||||
|
||||
return _buyProviderType.toString();
|
||||
|
@ -83,6 +89,5 @@ abstract class OtherSettingsViewModelBase with Store {
|
|||
_settingsStore.priority[_wallet.type] = priority;
|
||||
|
||||
void onBuyProviderTypeSelected(BuyProviderType buyProviderType) =>
|
||||
_settingsStore.defaultBuyProvider = buyProviderType;
|
||||
|
||||
_settingsStore.defaultBuyProviders[walletType] = buyProviderType;
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import 'package:cake_wallet/src/screens/transaction_details/standart_list_item.d
|
|||
import 'package:cake_wallet/monero/monero.dart';
|
||||
import 'package:cake_wallet/haven/haven.dart';
|
||||
import 'package:cw_monero/api/wallet.dart' as monero_wallet;
|
||||
import 'package:polyseed/polyseed.dart';
|
||||
|
||||
part 'wallet_keys_view_model.g.dart';
|
||||
|
||||
|
@ -74,6 +75,15 @@ abstract class WalletKeysViewModelBase with Store {
|
|||
StandartListItem(title: S.current.view_key_private, value: keys['privateViewKey']!),
|
||||
StandartListItem(title: S.current.wallet_seed, value: _appStore.wallet!.seed!),
|
||||
]);
|
||||
|
||||
if (_appStore.wallet?.seed != null && Polyseed.isValidSeed(_appStore.wallet!.seed!)) {
|
||||
final lang = PolyseedLang.getByPhrase(_appStore.wallet!.seed!);
|
||||
final legacyLang = _getLegacySeedLang(lang);
|
||||
final legacySeed =
|
||||
Polyseed.decode(_appStore.wallet!.seed!, lang, PolyseedCoin.POLYSEED_MONERO)
|
||||
.toLegacySeed(legacyLang);
|
||||
items.add(StandartListItem(title: S.current.wallet_seed_legacy, value: legacySeed));
|
||||
}
|
||||
}
|
||||
|
||||
if (_appStore.wallet!.type == WalletType.haven) {
|
||||
|
@ -207,4 +217,23 @@ abstract class WalletKeysViewModelBase with Store {
|
|||
}
|
||||
|
||||
String getRoundedRestoreHeight(int height) => ((height / 1000).floor() * 1000).toString();
|
||||
|
||||
LegacySeedLang _getLegacySeedLang(PolyseedLang lang) {
|
||||
switch (lang.nameEnglish) {
|
||||
case "Spanish":
|
||||
return LegacySeedLang.getByEnglishName("Spanish");
|
||||
case "French":
|
||||
return LegacySeedLang.getByEnglishName("French");
|
||||
case "Italian":
|
||||
return LegacySeedLang.getByEnglishName("Italian");
|
||||
case "Japanese":
|
||||
return LegacySeedLang.getByEnglishName("Japanese");
|
||||
case "Portuguese":
|
||||
return LegacySeedLang.getByEnglishName("Portuguese");
|
||||
case "Chinese (Simplified)":
|
||||
return LegacySeedLang.getByEnglishName("Chinese (simplified)");
|
||||
default:
|
||||
return LegacySeedLang.getByEnglishName("English");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -96,7 +96,7 @@ dependencies:
|
|||
bitcoin_flutter:
|
||||
git:
|
||||
url: https://github.com/cake-tech/bitcoin_flutter.git
|
||||
ref: cake-update-v3
|
||||
ref: cake-update-v4
|
||||
fluttertoast: 8.1.4
|
||||
tor:
|
||||
git:
|
||||
|
@ -104,9 +104,7 @@ dependencies:
|
|||
ref: main
|
||||
socks5_proxy: ^1.0.4
|
||||
flutter_svg: ^2.0.9
|
||||
polyseed:
|
||||
git:
|
||||
url: https://github.com/cake-tech/polyseed_dart.git
|
||||
polyseed: ^0.0.2
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
|
|
@ -746,5 +746,7 @@
|
|||
"seed_language_czech": "التشيكية",
|
||||
"seed_language_korean": "الكورية",
|
||||
"seed_language_chinese_traditional": "تقاليد صينية)",
|
||||
"polygonscan_history": "ﻥﺎﻜﺴﻧﻮﺠﻴﻟﻮﺑ ﺦﻳﺭﺎﺗ"
|
||||
"dfx_option_description": "ﺎﺑﻭﺭﻭﺃ ﻲﻓ ﺕﺎﻛﺮﺸﻟﺍﻭ ﺔﺋﺰﺠﺘﻟﺍ ءﻼﻤﻌﻟ .ﻲﻓﺎﺿﺇ KYC ﻥﻭﺪﺑ ﻭﺭﻮﻳ 990 ﻰﻟﺇ ﻞﺼﻳ ﺎﻣ .ﻱﺮﺴﻳﻮﺴﻟﺍ",
|
||||
"polygonscan_history": "ﻥﺎﻜﺴﻧﻮﺠﻴﻟﻮﺑ ﺦﻳﺭﺎﺗ",
|
||||
"wallet_seed_legacy": "بذرة محفظة قديمة"
|
||||
}
|
||||
|
|
|
@ -742,5 +742,7 @@
|
|||
"seed_language_czech": "Чех",
|
||||
"seed_language_korean": "Корейски",
|
||||
"seed_language_chinese_traditional": "Традиционен китайски)",
|
||||
"polygonscan_history": "История на PolygonScan"
|
||||
"dfx_option_description": "Купете крипто с EUR и CHF. До 990 € без допълнителен KYC. За клиенти на дребно и корпоративни клиенти в Европа",
|
||||
"polygonscan_history": "История на PolygonScan",
|
||||
"wallet_seed_legacy": "Наследено портфейл семе"
|
||||
}
|
||||
|
|
|
@ -742,5 +742,7 @@
|
|||
"seed_language_czech": "čeština",
|
||||
"seed_language_korean": "korejština",
|
||||
"seed_language_chinese_traditional": "Číňan (tradiční)",
|
||||
"polygonscan_history": "Historie PolygonScan"
|
||||
"dfx_option_description": "Nakupujte kryptoměny za EUR a CHF. Až 990 € bez dalších KYC. Pro maloobchodní a firemní zákazníky v Evropě",
|
||||
"polygonscan_history": "Historie PolygonScan",
|
||||
"wallet_seed_legacy": "Starší semeno peněženky"
|
||||
}
|
||||
|
|
|
@ -750,5 +750,7 @@
|
|||
"seed_language_czech": "Tschechisch",
|
||||
"seed_language_korean": "Koreanisch",
|
||||
"seed_language_chinese_traditional": "Chinesisch (Traditionell)",
|
||||
"polygonscan_history": "PolygonScan-Verlauf"
|
||||
"dfx_option_description": "Krypto mit EUR und CHF kaufen. Bis zu 990€ ohne zusätzliches KYC. Für Privat- und Firmenkunden in Europa",
|
||||
"polygonscan_history": "PolygonScan-Verlauf",
|
||||
"wallet_seed_legacy": "Legacy Wallet Seed"
|
||||
}
|
||||
|
|
|
@ -751,5 +751,7 @@
|
|||
"seed_language_czech": "Czech",
|
||||
"seed_language_korean": "Korean",
|
||||
"seed_language_chinese_traditional": "Chinese (Traditional)",
|
||||
"polygonscan_history": "PolygonScan history"
|
||||
"dfx_option_description": "Buy crypto with EUR & CHF. Up to 990€ without additional KYC. For retail and corporate customers in Europe",
|
||||
"polygonscan_history": "PolygonScan history",
|
||||
"wallet_seed_legacy": "Legacy wallet seed"
|
||||
}
|
||||
|
|
|
@ -749,6 +749,9 @@
|
|||
"seedtype_polyseed": "Polieta (16 palabras)",
|
||||
"seed_language_czech": "checo",
|
||||
"seed_language_korean": "coreano",
|
||||
"seed_language_chinese_traditional": "Chino tradicional)",
|
||||
"dfx_option_description": "Compre criptomonedas con EUR y CHF. Hasta 990€ sin KYC adicional. Para clientes minoristas y corporativos en Europa",
|
||||
"seed_language_chinese_traditional": "Chino (tradicional)",
|
||||
"polygonscan_history": "Historial de PolygonScan"
|
||||
}
|
||||
"polygonscan_history": "Historial de PolygonScan",
|
||||
"wallet_seed_legacy": "Semilla de billetera heredada"
|
||||
}
|
|
@ -750,5 +750,7 @@
|
|||
"seed_language_czech": "tchèque",
|
||||
"seed_language_korean": "coréen",
|
||||
"seed_language_chinese_traditional": "Chinois (Traditionnel)",
|
||||
"polygonscan_history": "Historique de PolygonScan"
|
||||
"dfx_option_description": "Achetez des crypto-monnaies avec EUR et CHF. Jusqu'à 990€ sans KYC supplémentaire. Pour les clients particuliers et entreprises en Europe",
|
||||
"polygonscan_history": "Historique de PolygonScan",
|
||||
"wallet_seed_legacy": "Graine de portefeuille hérité"
|
||||
}
|
||||
|
|
|
@ -728,5 +728,7 @@
|
|||
"seed_language_czech": "Czech",
|
||||
"seed_language_korean": "Yaren Koriya",
|
||||
"seed_language_chinese_traditional": "Sinanci (na gargajiya)",
|
||||
"polygonscan_history": "PolygonScan tarihin kowane zamani"
|
||||
"dfx_option_description": "Sayi crypto tare da EUR & CHF. Har zuwa € 990 ba tare da ƙarin KYC ba. Don 'yan kasuwa da abokan ciniki na kamfanoni a Turai",
|
||||
"polygonscan_history": "PolygonScan tarihin kowane zamani",
|
||||
"wallet_seed_legacy": "Tallarin walat walat"
|
||||
}
|
||||
|
|
|
@ -750,5 +750,7 @@
|
|||
"seed_language_czech": "चेक",
|
||||
"seed_language_korean": "कोरियाई",
|
||||
"seed_language_chinese_traditional": "चीनी पारंपरिक)",
|
||||
"polygonscan_history": "पॉलीगॉनस्कैन इतिहास"
|
||||
"dfx_option_description": "EUR और CHF के साथ क्रिप्टो खरीदें। अतिरिक्त केवाईसी के बिना 990€ तक। यूरोप में खुदरा और कॉर्पोरेट ग्राहकों के लिए",
|
||||
"polygonscan_history": "पॉलीगॉनस्कैन इतिहास",
|
||||
"wallet_seed_legacy": "विरासत बटुए बीज"
|
||||
}
|
||||
|
|
|
@ -747,6 +747,9 @@
|
|||
"seedtype_polyseed": "Poliseed (16 riječi)",
|
||||
"seed_language_czech": "češki",
|
||||
"seed_language_korean": "korejski",
|
||||
"seed_language_chinese_traditional": "Kinesko tradicionalno)",
|
||||
"dfx_option_description": "Kupujte kripto s EUR i CHF. Do 990 € bez dodatnog KYC-a. Za maloprodajne i poslovne korisnike u Europi",
|
||||
"seed_language_chinese_traditional": "Kinesko (tradicionalno)",
|
||||
"polygonscan_history": "Povijest PolygonScan"
|
||||
}
|
||||
"polygonscan_history": "Povijest PolygonScan",
|
||||
"wallet_seed_legacy": "Sjeme naslijeđenog novčanika"
|
||||
}
|
|
@ -737,6 +737,9 @@
|
|||
"seedtype_polyseed": "Polyseed (16 kata)",
|
||||
"seed_language_czech": "Ceko",
|
||||
"seed_language_korean": "Korea",
|
||||
"seed_language_chinese_traditional": "Cina tradisional)",
|
||||
"dfx_option_description": "Beli kripto dengan EUR & CHF. Hingga 990€ tanpa KYC tambahan. Untuk pelanggan ritel dan korporat di Eropa",
|
||||
"seed_language_chinese_traditional": "Cina (tradisional)",
|
||||
"polygonscan_history": "Sejarah PolygonScan"
|
||||
}
|
||||
"polygonscan_history": "Sejarah PolygonScan",
|
||||
"wallet_seed_legacy": "Biji dompet warisan"
|
||||
}
|
|
@ -750,5 +750,7 @@
|
|||
"seed_language_czech": "ceco",
|
||||
"seed_language_korean": "coreano",
|
||||
"seed_language_chinese_traditional": "Cinese tradizionale)",
|
||||
"polygonscan_history": "Cronologia PolygonScan"
|
||||
"dfx_option_description": "Acquista criptovalute con EUR e CHF. Fino a 990€ senza KYC aggiuntivi. Per clienti al dettaglio e aziendali in Europa",
|
||||
"polygonscan_history": "Cronologia PolygonScan",
|
||||
"wallet_seed_legacy": "Seme di portafoglio legacy"
|
||||
}
|
||||
|
|
|
@ -750,5 +750,7 @@
|
|||
"seed_language_czech": "チェコ",
|
||||
"seed_language_korean": "韓国語",
|
||||
"seed_language_chinese_traditional": "中国の伝統的な)",
|
||||
"polygonscan_history": "ポリゴンスキャン履歴"
|
||||
"dfx_option_description": "EUR と CHF で暗号通貨を購入します。追加のKYCなしで最大990ユーロ。ヨーロッパの小売および法人顧客向け",
|
||||
"polygonscan_history": "ポリゴンスキャン履歴",
|
||||
"wallet_seed_legacy": "レガシーウォレットシード"
|
||||
}
|
||||
|
|
|
@ -748,5 +748,7 @@
|
|||
"seed_language_czech": "체코 사람",
|
||||
"seed_language_korean": "한국인",
|
||||
"seed_language_chinese_traditional": "중국 전통)",
|
||||
"polygonscan_history": "다각형 스캔 기록"
|
||||
"dfx_option_description": "EUR 및 CHF로 암호화폐를 구매하세요. 추가 KYC 없이 최대 990€. 유럽의 소매 및 기업 고객용",
|
||||
"polygonscan_history": "다각형 스캔 기록",
|
||||
"wallet_seed_legacy": "레거시 지갑 시드"
|
||||
}
|
||||
|
|
|
@ -748,5 +748,7 @@
|
|||
"seed_language_czech": "ချက်",
|
||||
"seed_language_korean": "ကိုးရီးယား",
|
||||
"seed_language_chinese_traditional": "တရုတ်ရိုးရာ)",
|
||||
"polygonscan_history": "PolygonScan မှတ်တမ်း"
|
||||
"dfx_option_description": "EUR & CHF ဖြင့် crypto ကိုဝယ်ပါ။ အပို KYC မပါဘဲ 990€ အထိ။ ဥရောပရှိ လက်လီရောင်းချသူများနှင့် ကော်ပိုရိတ်ဖောက်သည်များအတွက်",
|
||||
"polygonscan_history": "PolygonScan မှတ်တမ်း",
|
||||
"wallet_seed_legacy": "အမွေအနှစ်ပိုက်ဆံအိတ်မျိုးစေ့"
|
||||
}
|
||||
|
|
|
@ -749,6 +749,9 @@
|
|||
"seedtype_polyseed": "Polyseed (16 woorden)",
|
||||
"seed_language_czech": "Tsjechisch",
|
||||
"seed_language_korean": "Koreaans",
|
||||
"seed_language_chinese_traditional": "Chinese traditionele)",
|
||||
"dfx_option_description": "Koop crypto met EUR & CHF. Tot 990€ zonder extra KYC. Voor particuliere en zakelijke klanten in Europa",
|
||||
"seed_language_chinese_traditional": "Chinese (traditionele)",
|
||||
"polygonscan_history": "PolygonScan-geschiedenis"
|
||||
}
|
||||
"polygonscan_history": "PolygonScan-geschiedenis",
|
||||
"wallet_seed_legacy": "Legacy portemonnee zaad"
|
||||
}
|
|
@ -750,5 +750,7 @@
|
|||
"seed_language_czech": "Czech",
|
||||
"seed_language_korean": "koreański",
|
||||
"seed_language_chinese_traditional": "Chiński tradycyjny)",
|
||||
"polygonscan_history": "Historia PolygonScan"
|
||||
"dfx_option_description": "Kupuj kryptowaluty za EUR i CHF. Do 990 € bez dodatkowego KYC. Dla klientów detalicznych i korporacyjnych w Europie",
|
||||
"polygonscan_history": "Historia PolygonScan",
|
||||
"wallet_seed_legacy": "Dziedziczne ziarno portfela"
|
||||
}
|
||||
|
|
|
@ -749,5 +749,7 @@
|
|||
"seed_language_czech": "Tcheco",
|
||||
"seed_language_korean": "coreano",
|
||||
"seed_language_chinese_traditional": "Chinês tradicional)",
|
||||
"polygonscan_history": "História do PolygonScan"
|
||||
"dfx_option_description": "Compre criptografia com EUR e CHF. Até 990€ sem KYC adicional. Para clientes de varejo e corporativos na Europa",
|
||||
"polygonscan_history": "História do PolygonScan",
|
||||
"wallet_seed_legacy": "Semente de carteira herdada"
|
||||
}
|
||||
|
|
|
@ -750,5 +750,7 @@
|
|||
"seed_language_czech": "Чешский",
|
||||
"seed_language_korean": "Корейский",
|
||||
"seed_language_chinese_traditional": "Китайский традиционный)",
|
||||
"polygonscan_history": "История PolygonScan"
|
||||
"dfx_option_description": "Покупайте криптовалюту за EUR и CHF. До 990€ без дополнительного KYC. Для розничных и корпоративных клиентов в Европе",
|
||||
"polygonscan_history": "История PolygonScan",
|
||||
"wallet_seed_legacy": "Наследие семя кошелька"
|
||||
}
|
||||
|
|
|
@ -748,5 +748,7 @@
|
|||
"seed_language_czech": "ภาษาเช็ก",
|
||||
"seed_language_korean": "เกาหลี",
|
||||
"seed_language_chinese_traditional": "จีน (ดั้งเดิม)",
|
||||
"polygonscan_history": "ประวัติ PolygonScan"
|
||||
"dfx_option_description": "ซื้อ crypto ด้วย EUR และ CHF สูงถึง 990€ โดยไม่มี KYC เพิ่มเติม สำหรับลูกค้ารายย่อยและลูกค้าองค์กรในยุโรป",
|
||||
"polygonscan_history": "ประวัติ PolygonScan",
|
||||
"wallet_seed_legacy": "เมล็ดกระเป๋าเงินมรดก"
|
||||
}
|
||||
|
|
|
@ -744,5 +744,7 @@
|
|||
"seed_language_czech": "Czech",
|
||||
"seed_language_korean": "Korean",
|
||||
"seed_language_chinese_traditional": "Intsik (tradisyonal)",
|
||||
"polygonscan_history": "Kasaysayan ng PolygonScan"
|
||||
"dfx_option_description": "Bumili ng crypto gamit ang EUR at CHF. Hanggang 990€ nang walang karagdagang KYC. Para sa retail at corporate na mga customer sa Europe",
|
||||
"polygonscan_history": "Kasaysayan ng PolygonScan",
|
||||
"wallet_seed_legacy": "Legacy wallet seed"
|
||||
}
|
||||
|
|
|
@ -748,5 +748,7 @@
|
|||
"seed_language_czech": "Çek",
|
||||
"seed_language_korean": "Koreli",
|
||||
"seed_language_chinese_traditional": "Çin geleneği)",
|
||||
"polygonscan_history": "PolygonScan geçmişi"
|
||||
"dfx_option_description": "EUR ve CHF ile kripto satın alın. Ek KYC olmadan 990 €'ya kadar. Avrupa'daki perakende ve kurumsal müşteriler için",
|
||||
"polygonscan_history": "PolygonScan geçmişi",
|
||||
"wallet_seed_legacy": "Eski cüzdan tohumu"
|
||||
}
|
||||
|
|
|
@ -749,6 +749,8 @@
|
|||
"seedtype_polyseed": "Полісей (16 слів)",
|
||||
"seed_language_czech": "Чеський",
|
||||
"seed_language_korean": "Корейський",
|
||||
"dfx_option_description": "Купуйте криптовалюту за EUR і CHF. До 990 євро без додаткового KYC. Для роздрібних і корпоративних клієнтів у Європі",
|
||||
"seed_language_chinese_traditional": "Китайський (традиційний)",
|
||||
"polygonscan_history": "Історія PolygonScan"
|
||||
}
|
||||
"polygonscan_history": "Історія PolygonScan",
|
||||
"wallet_seed_legacy": "Спадець насіння гаманця"
|
||||
}
|
|
@ -742,5 +742,7 @@
|
|||
"seed_language_czech": "چیک",
|
||||
"seed_language_korean": "کورین",
|
||||
"seed_language_chinese_traditional": "چینی (روایتی)",
|
||||
"polygonscan_history": "ﺦﯾﺭﺎﺗ ﯽﮐ ﻦﯿﮑﺳﺍ ﻥﻮﮔ ﯽﻟﻮﭘ"
|
||||
"dfx_option_description": "EUR ﺭﻭﺍ CHF ﯽﻓﺎﺿﺍ ۔ﮟﯾﺪﯾﺮﺧ ﻮﭩﭘﺮﮐ ﮫﺗﺎﺳ ﮯﮐ KYC ﮯﯿﻟ ﮯﮐ ﻦﯿﻓﺭﺎﺻ ﭧﯾﺭﻮﭘﺭﺎﮐ ﺭﻭﺍ ﮦﺩﺭﻮﺧ ﮟ",
|
||||
"polygonscan_history": "ﺦﯾﺭﺎﺗ ﯽﮐ ﻦﯿﮑﺳﺍ ﻥﻮﮔ ﯽﻟﻮﭘ",
|
||||
"wallet_seed_legacy": "میراثی پرس کا بیج"
|
||||
}
|
||||
|
|
|
@ -744,5 +744,7 @@
|
|||
"seed_language_czech": "Czech",
|
||||
"seed_language_korean": "Ara ẹni",
|
||||
"seed_language_chinese_traditional": "Kannada (ibile)",
|
||||
"polygonscan_history": "PolygonScan itan"
|
||||
"dfx_option_description": "Ra crypto pẹlu EUR & CHF. Titi di 990 € laisi afikun KYC. Fun soobu ati awọn onibara ile-iṣẹ ni Yuroopu",
|
||||
"polygonscan_history": "PolygonScan itan",
|
||||
"wallet_seed_legacy": "Irugbin akole"
|
||||
}
|
||||
|
|
|
@ -749,5 +749,7 @@
|
|||
"seed_language_czech": "捷克",
|
||||
"seed_language_korean": "韩国人",
|
||||
"seed_language_chinese_traditional": "中国传统的)",
|
||||
"polygonscan_history": "多边形扫描历史"
|
||||
"dfx_option_description": "用欧元和瑞士法郎购买加密货币。高达 990 欧元,无需额外 KYC。对于欧洲的零售和企业客户",
|
||||
"polygonscan_history": "多边形扫描历史",
|
||||
"wallet_seed_legacy": "旧的钱包种子"
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue