Merge branch 'cyjan-ios-xcframework' into cyjan-ios-ci

This commit is contained in:
Czarek Nakamoto 2025-02-05 09:22:25 +01:00
commit cc765cd241
70 changed files with 618 additions and 430 deletions

View file

@ -190,7 +190,7 @@ jobs:
echo "const cakePayApiKey = '${{ secrets.CAKE_PAY_API_KEY }}';" >> lib/.secrets.g.dart
echo "const authorization = '${{ secrets.CAKE_PAY_AUTHORIZATION }}';" >> lib/.secrets.g.dart
echo "const CSRFToken = '${{ secrets.CSRF_TOKEN }}';" >> lib/.secrets.g.dart
echo "const quantexExchangeMarkup = '${{ secrets.QUANTEX_EXCHANGE_MARKUP }}';" >> lib/.secrets.g.dart
echo "const swapTradeExchangeMarkup = '${{ secrets.SWAPTRADE_EXCHANGE_MARKUP }}';" >> lib/.secrets.g.dart
echo "const nano2ApiKey = '${{ secrets.NANO2_API_KEY }}';" >> cw_nano/lib/.secrets.g.dart
echo "const nanoNowNodesApiKey = '${{ secrets.NANO_NOW_NODES_API_KEY }}';" >> cw_nano/lib/.secrets.g.dart
echo "const tronGridApiKey = '${{ secrets.TRON_GRID_API_KEY }}';" >> cw_tron/lib/.secrets.g.dart

View file

@ -135,6 +135,7 @@ jobs:
echo "const cakePayApiKey = '${{ secrets.CAKE_PAY_API_KEY }}';" >> lib/.secrets.g.dart
echo "const authorization = '${{ secrets.CAKE_PAY_AUTHORIZATION }}';" >> lib/.secrets.g.dart
echo "const CSRFToken = '${{ secrets.CSRF_TOKEN }}';" >> lib/.secrets.g.dart
echo "const swapTradeExchangeMarkup = '${{ secrets.SWAPTRADE_EXCHANGE_MARKUP }}';" >> lib/.secrets.g.dart
echo "const quantexExchangeMarkup = '${{ secrets.QUANTEX_EXCHANGE_MARKUP }}';" >> lib/.secrets.g.dart
echo "const nano2ApiKey = '${{ secrets.NANO2_API_KEY }}';" >> cw_nano/lib/.secrets.g.dart
echo "const nanoNowNodesApiKey = '${{ secrets.NANO_NOW_NODES_API_KEY }}';" >> cw_nano/lib/.secrets.g.dart

View file

@ -110,6 +110,7 @@ jobs:
echo "const authorization = '${{ secrets.CAKE_PAY_AUTHORIZATION }}';" >> lib/.secrets.g.dart
echo "const CSRFToken = '${{ secrets.CSRF_TOKEN }}';" >> lib/.secrets.g.dart
echo "const quantexExchangeMarkup = '${{ secrets.QUANTEX_EXCHANGE_MARKUP }}';" >> lib/.secrets.g.dart
echo "const swapTradeExchangeMarkup = '${{ secrets.SWAPTRADE_EXCHANGE_MARKUP }}';" >> lib/.secrets.g.dart
echo "const nano2ApiKey = '${{ secrets.NANO2_API_KEY }}';" >> cw_nano/lib/.secrets.g.dart
echo "const nanoNowNodesApiKey = '${{ secrets.NANO_NOW_NODES_API_KEY }}';" >> cw_nano/lib/.secrets.g.dart
echo "const tronGridApiKey = '${{ secrets.TRON_GRID_API_KEY }}';" >> cw_tron/lib/.secrets.g.dart

View file

@ -131,6 +131,7 @@ jobs:
echo "const cakePayApiKey = '${{ secrets.CAKE_PAY_API_KEY }}';" >> lib/.secrets.g.dart
echo "const authorization = '${{ secrets.CAKE_PAY_AUTHORIZATION }}';" >> lib/.secrets.g.dart
echo "const CSRFToken = '${{ secrets.CSRF_TOKEN }}';" >> lib/.secrets.g.dart
echo "const swapTradeExchangeMarkup = '${{ secrets.SWAPTRADE_EXCHANGE_MARKUP }}';" >> lib/.secrets.g.dart
echo "const quantexExchangeMarkup = '${{ secrets.QUANTEX_EXCHANGE_MARKUP }}';" >> lib/.secrets.g.dart
echo "const nano2ApiKey = '${{ secrets.NANO2_API_KEY }}';" >> cw_nano/lib/.secrets.g.dart
echo "const nanoNowNodesApiKey = '${{ secrets.NANO_NOW_NODES_API_KEY }}';" >> cw_nano/lib/.secrets.g.dart

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Before After
Before After

View file

@ -1,4 +1,4 @@
Monero restore with passphrase support
Add Chainflip Exchange provider
Added passphrase support
Added decentralized cross-chain exchange, Chainflip
UI enhancements
Bug fixes

View file

@ -1,5 +1,5 @@
Add Zano Wallet
Monero/Wownero/Zano restore with passphrase support
Add Chainflip Exchange provider
Added Zano wallet support
Added Monero/Wownero passphrase support
Added decentralized cross-chain exchange, Chainflip
UI enhancements
Bug fixes

View file

@ -56,3 +56,13 @@ class CreateAssociatedTokenAccountException implements Exception {
class SignSPLTokenTransactionRentException implements Exception {}
class NoAssociatedTokenAccountException implements Exception {}
/// ==============================================================================
/// ==============================================================================
class RestoreFromSeedException implements Exception {
final String message;
RestoreFromSeedException(this.message);
}

View file

@ -45,12 +45,11 @@ String getSeed() {
if (cakepolyseed != "") {
if (cakepassphrase != "") {
try {
final lang = PolyseedLang.getByPhrase(cakepassphrase);
final lang = PolyseedLang.getByPhrase(cakepolyseed);
final coin = PolyseedCoin.POLYSEED_MONERO;
final ps = Polyseed.decode(cakepolyseed, lang, coin);
final passphrase = getPassphrase();
if (ps.isEncrypted || passphrase == "") return ps.encode(lang, coin);
ps.crypt(getPassphrase());
if (ps.isEncrypted || cakepassphrase == "") return ps.encode(lang, coin);
ps.crypt(cakepassphrase);
return ps.encode(lang, coin);
} catch (e) {
printV(e);

View file

@ -70,6 +70,7 @@ void createWalletSync(
{required String path,
required String password,
required String language,
required String passphrase,
int nettype = 0}) {
txhistory = null;
final newWptr = monero.WalletManager_createWallet(wmPtr,
@ -80,6 +81,7 @@ void createWalletSync(
throw WalletCreationException(message: monero.Wallet_errorString(newWptr));
}
wptr = newWptr;
monero.Wallet_setCacheAttribute(wptr!, key: "cakewallet.passphrase", value: passphrase);
monero.Wallet_store(wptr!, path: path);
openedWalletsByPath[path] = wptr!;
_lastOpenedWallet = path;
@ -390,8 +392,9 @@ void _createWallet(Map<String, dynamic> args) {
final path = args['path'] as String;
final password = args['password'] as String;
final language = args['language'] as String;
final passphrase = args['passphrase'] as String;
createWalletSync(path: path, password: password, language: language);
createWalletSync(path: path, password: password, language: language, passphrase: passphrase);
}
void _restoreFromSeed(Map<String, dynamic> args) {
@ -459,11 +462,13 @@ Future<void> createWallet(
{required String path,
required String password,
required String language,
required String passphrase,
int nettype = 0}) async =>
_createWallet({
'path': path,
'password': password,
'language': language,
'passphrase': passphrase,
'nettype': nettype
});

View file

@ -135,7 +135,7 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
passphrase: monero_wallet.getPassphrase());
int? get restoreHeight =>
transactionHistory.transactions.values.firstOrNull?.height;
transactionHistory.transactions.values.firstOrNull?.height ?? monero.Wallet_getRefreshFromBlockHeight(wptr!);
monero_wallet.SyncListener? _listener;
ReactionDisposer? _onAccountChangeReaction;

View file

@ -26,11 +26,12 @@ import 'package:polyseed/polyseed.dart';
class MoneroNewWalletCredentials extends WalletCredentials {
MoneroNewWalletCredentials(
{required String name, required this.language, required this.isPolyseed, String? password})
{required String name, required this.language, required this.isPolyseed, String? password, this.passphrase})
: super(name: name, password: password);
final String language;
final bool isPolyseed;
final String? passphrase;
}
class MoneroRestoreWalletFromHardwareCredentials extends WalletCredentials {
@ -92,7 +93,7 @@ class MoneroWalletService extends WalletService<
@override
WalletType getType() => WalletType.monero;
@override
@override
Future<MoneroWallet> create(MoneroNewWalletCredentials credentials, {bool? isTestnet}) async {
try {
final path = await pathForWallet(name: credentials.name, type: getType());
@ -112,7 +113,7 @@ class MoneroWalletService extends WalletService<
}
await monero_wallet_manager.createWallet(
path: path, password: credentials.password!, language: credentials.language);
path: path, password: credentials.password!, language: credentials.language, passphrase: credentials.passphrase??"");
final wallet = MoneroWallet(
walletInfo: credentials.walletInfo!,
unspentCoinsInfo: unspentCoinsInfoSource,
@ -382,6 +383,10 @@ class MoneroWalletService extends WalletService<
restoreHeight: height,
spendKey: spendKey);
monero.Wallet_setCacheAttribute(wptr!, key: "cakewallet.seed", value: seed);
monero.Wallet_setCacheAttribute(wptr!, key: "cakewallet.passphrase", value: passphrase??'');
final wallet = MoneroWallet(
walletInfo: walletInfo,
unspentCoinsInfo: unspentCoinsInfoSource,

View file

@ -511,8 +511,8 @@ packages:
dependency: "direct main"
description:
path: "impls/monero.dart"
ref: 9d619f1aaec9f0f7d9a15c31ee2bde4ff79e6442
resolved-ref: 9d619f1aaec9f0f7d9a15c31ee2bde4ff79e6442
ref: "9301097ff504525070cc0cb915fe2f1bb0670345"
resolved-ref: "9301097ff504525070cc0cb915fe2f1bb0670345"
url: "https://github.com/mrcyjanek/monero_c"
source: git
version: "0.0.0"

View file

@ -25,7 +25,7 @@ dependencies:
monero:
git:
url: https://github.com/mrcyjanek/monero_c
ref: 9d619f1aaec9f0f7d9a15c31ee2bde4ff79e6442
ref: 9301097ff504525070cc0cb915fe2f1bb0670345
path: impls/monero.dart
mutex: ^3.1.0
ledger_flutter_plus: ^1.4.1

View file

@ -35,4 +35,6 @@ Icon?
/Flutter/Generated.xcconfig
/Flutter/ephemeral/
/Flutter/flutter_export_environment.sh
/Flutter/flutter_export_environment.sh
Mwebd.xcframework

View file

@ -16,11 +16,12 @@ A new Flutter plugin project.
s.source_files = 'Classes/**/*'
s.dependency 'Flutter'
s.platform = :ios, '11.0'
s.libraries = 'resolv'
# Flutter.framework does not contain a i386 slice.
s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' }
s.swift_version = '5.0'
s.ios.vendored_frameworks = 'Mwebd.xcframework'
s.vendored_frameworks = 'Mwebd.xcframework'
s.preserve_paths = 'Mwebd.xcframework/**/*'
end

View file

@ -44,7 +44,7 @@ String getSeed() {
if (cakepolyseed != "") {
if (cakepassphrase != "") {
try {
final lang = PolyseedLang.getByPhrase(cakepassphrase);
final lang = PolyseedLang.getByPhrase(cakepolyseed);
final coin = PolyseedCoin.POLYSEED_WOWNERO;
final ps = Polyseed.decode(cakepolyseed, lang, coin);
final passphrase = getPassphrase();

View file

@ -66,6 +66,7 @@ void createWalletSync(
{required String path,
required String password,
required String language,
required String passphrase,
int nettype = 0}) {
txhistory = null;
final newWptr = wownero.WalletManager_createWallet(wmPtr,
@ -76,6 +77,8 @@ void createWalletSync(
throw WalletCreationException(message: wownero.Wallet_errorString(newWptr));
}
wptr = newWptr;
wownero.Wallet_setCacheAttribute(wptr!, key: "cakewallet.passphrase", value: passphrase);
wownero.Wallet_store(wptr!, path: path);
openedWalletsByPath[path] = wptr!;
@ -362,8 +365,9 @@ void _createWallet(Map<String, dynamic> args) {
final path = args['path'] as String;
final password = args['password'] as String;
final language = args['language'] as String;
final passphrase = args['passphrase'] as String;
createWalletSync(path: path, password: password, language: language);
createWalletSync(path: path, password: password, language: language, passphrase: passphrase);
}
void _restoreFromSeed(Map<String, dynamic> args) {
@ -431,11 +435,13 @@ Future<void> createWallet(
{required String path,
required String password,
required String language,
required String passphrase,
int nettype = 0}) async =>
_createWallet({
'path': path,
'password': password,
'language': language,
'passphrase': passphrase,
'nettype': nettype
});

View file

@ -20,6 +20,7 @@ import 'package:cw_core/wallet_base.dart';
import 'package:cw_core/wallet_info.dart';
import 'package:cw_core/wownero_amount_format.dart';
import 'package:cw_core/wownero_balance.dart';
import 'package:cw_wownero/api/account_list.dart';
import 'package:cw_wownero/api/coins_info.dart';
import 'package:cw_wownero/api/structs/pending_transaction.dart';
import 'package:cw_wownero/api/transaction_history.dart' as transaction_history;
@ -131,6 +132,10 @@ abstract class WowneroWalletBase
publicViewKey: wownero_wallet.getPublicViewKey(),
passphrase: wownero_wallet.getPassphrase());
int? get restoreHeight =>
transactionHistory.transactions.values.firstOrNull?.height ?? wownero.Wallet_getRefreshFromBlockHeight(wptr!);
wownero_wallet.SyncListener? _listener;
ReactionDisposer? _onAccountChangeReaction;
ReactionDisposer? _onTxHistoryChangeReaction;

View file

@ -10,6 +10,7 @@ import 'package:cw_core/wallet_info.dart';
import 'package:cw_core/wallet_service.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:cw_core/get_height_by_date.dart';
import 'package:cw_wownero/api/account_list.dart';
import 'package:cw_wownero/api/exceptions/wallet_opening_exception.dart';
import 'package:cw_wownero/api/wallet_manager.dart' as wownero_wallet_manager;
import 'package:cw_wownero/api/wallet_manager.dart';
@ -21,11 +22,12 @@ import 'package:monero/wownero.dart' as wownero;
class WowneroNewWalletCredentials extends WalletCredentials {
WowneroNewWalletCredentials(
{required String name, required this.language, required this.isPolyseed, String? password})
{required String name, required this.language, required this.isPolyseed, this.passphrase, String? password})
: super(name: name, password: password);
final String language;
final bool isPolyseed;
final String? passphrase;
}
class WowneroRestoreWalletFromSeedCredentials extends WalletCredentials {
@ -95,7 +97,7 @@ class WowneroWalletService extends WalletService<
}
await wownero_wallet_manager.createWallet(
path: path, password: credentials.password!, language: credentials.language);
path: path, password: credentials.password!, language: credentials.language, passphrase: credentials.passphrase??'');
final wallet = WowneroWallet(
walletInfo: credentials.walletInfo!, unspentCoinsInfo: unspentCoinsInfoSource, password: credentials.password!);
await wallet.init();
@ -345,6 +347,9 @@ class WowneroWalletService extends WalletService<
restoreHeight: height,
spendKey: spendKey);
wownero.Wallet_setCacheAttribute(wptr!, key: "cakewallet.seed", value: seed);
wownero.Wallet_setCacheAttribute(wptr!, key: "cakewallet.passphrase", value: passphrase??'');
final wallet = WowneroWallet(walletInfo: walletInfo, unspentCoinsInfo: unspentCoinsInfoSource, password: password);
await wallet.init();

View file

@ -471,8 +471,8 @@ packages:
dependency: "direct main"
description:
path: "impls/monero.dart"
ref: 9d619f1aaec9f0f7d9a15c31ee2bde4ff79e6442
resolved-ref: 9d619f1aaec9f0f7d9a15c31ee2bde4ff79e6442
ref: "9301097ff504525070cc0cb915fe2f1bb0670345"
resolved-ref: "9301097ff504525070cc0cb915fe2f1bb0670345"
url: "https://github.com/mrcyjanek/monero_c"
source: git
version: "0.0.0"

View file

@ -25,7 +25,7 @@ dependencies:
monero:
git:
url: https://github.com/mrcyjanek/monero_c
ref: 9d619f1aaec9f0f7d9a15c31ee2bde4ff79e6442 # monero_c hash
ref: 9301097ff504525070cc0cb915fe2f1bb0670345 # monero_c hash
path: impls/monero.dart
mutex: ^3.1.0

View file

@ -259,7 +259,7 @@ mixin ZanoWalletApi {
final code = map!['error']!['code'] ?? '';
final message = map['error']!['message'] ?? '';
if (code == Consts.errorWrongSeed) {
throw RestoreFromSeedsException('Error restoring wallet, wrong seed');
throw RestoreFromSeedsException('Error restoring wallet\nPlease check the seed words are correct. Additionally, if you created this wallet with a passphrase please add it under the Advanced Settings page.');
} else if (code == Consts.errorAlreadyExists) {
throw RestoreFromSeedsException('Error restoring wallet, already exists');
}

View file

@ -1,3 +1,5 @@
import 'package:cw_core/exceptions.dart';
class ZanoWalletException implements Exception {
final String message;
@ -6,7 +8,7 @@ class ZanoWalletException implements Exception {
String toString() => '${this.runtimeType} (message: $message)';
}
class RestoreFromSeedsException extends ZanoWalletException {
class RestoreFromSeedsException extends RestoreFromSeedException {
RestoreFromSeedsException(String message) : super(message);
}

View file

@ -476,8 +476,8 @@ packages:
dependency: "direct main"
description:
path: "impls/monero.dart"
ref: "9d619f1aaec9f0f7d9a15c31ee2bde4ff79e6442"
resolved-ref: "9d619f1aaec9f0f7d9a15c31ee2bde4ff79e6442"
ref: "9301097ff504525070cc0cb915fe2f1bb0670345"
resolved-ref: "9301097ff504525070cc0cb915fe2f1bb0670345"
url: "https://github.com/mrcyjanek/monero_c"
source: git
version: "0.0.0"

View file

@ -26,7 +26,7 @@ dependencies:
monero:
git:
url: https://github.com/mrcyjanek/monero_c
ref: 9d619f1aaec9f0f7d9a15c31ee2bde4ff79e6442 # monero_c hash
ref: 9301097ff504525070cc0cb915fe2f1bb0670345 # monero_c hash
path: impls/monero.dart
dev_dependencies:
flutter_test:

1
ios/.gitignore vendored
View file

@ -32,3 +32,4 @@ Runner/GeneratedPluginRegistrant.*
!default.perspectivev3
Mwebd.xcframework
*Wallet.xcframework

View file

@ -8,7 +8,6 @@
/* Begin PBXBuildFile section */
0C44A71A2518EF8000B570ED /* decrypt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C44A7192518EF8000B570ED /* decrypt.swift */; };
0C50DFB92BF3CB56002B0EB3 /* MoneroWallet.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 0C50DFB82BF3CB56002B0EB3 /* MoneroWallet.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
0C9D68C9264854B60011B691 /* secRandom.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C9D68C8264854B60011B691 /* secRandom.swift */; };
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
2193F104374FA2746CE8945B /* ResourceHelper.swift in Resources */ = {isa = PBXBuildFile; fileRef = 78D25C60B94E9D9E48D52E5E /* ResourceHelper.swift */; settings = {ASSET_TAGS = (BreezSDK, ); }; };
@ -27,8 +26,9 @@
A1B4A70C9CFA13AB71662216 /* LnurlPay.swift in Resources */ = {isa = PBXBuildFile; fileRef = 7D3364C03978A8A74B6D586E /* LnurlPay.swift */; settings = {ASSET_TAGS = (BreezSDK, ); }; };
A3D5E17CC53DF13FA740DEFA /* RedeemSwap.swift in Resources */ = {isa = PBXBuildFile; fileRef = 9D2F2C9F2555316C95EE7EA3 /* RedeemSwap.swift */; settings = {ASSET_TAGS = (BreezSDK, ); }; };
B6C6E59403ACDE44724C12F4 /* ServiceConfig.swift in Resources */ = {isa = PBXBuildFile; fileRef = B3D5E78267F5F18D882FDC3B /* ServiceConfig.swift */; settings = {ASSET_TAGS = (BreezSDK, ); }; };
CE291CFE2C15DB9A00B9F709 /* WowneroWallet.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = CE291CFD2C15DB9A00B9F709 /* WowneroWallet.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
CEA883682D43BE4500278CD3 /* ZanoWallet.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = CEB6D62E2D43BB78002C6DBC /* ZanoWallet.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
CE918BF82D533ECE007F186E /* MoneroWallet.xcframework in CopyFiles */ = {isa = PBXBuildFile; fileRef = CE918BF72D533ECE007F186E /* MoneroWallet.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
CE918BFA2D533ED4007F186E /* WowneroWallet.xcframework in CopyFiles */ = {isa = PBXBuildFile; fileRef = CE918BF92D533ED4007F186E /* WowneroWallet.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
CE918BFC2D533ED8007F186E /* ZanoWallet.xcframework in CopyFiles */ = {isa = PBXBuildFile; fileRef = CE918BFB2D533ED8007F186E /* ZanoWallet.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
CEAFE4A02C53926F009FF3AD /* libresolv.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = C58D93382C00FAC6004BCF69 /* libresolv.tbd */; };
CFEFC24F82F78FE747DF1D22 /* LnurlPayInfo.swift in Resources */ = {isa = PBXBuildFile; fileRef = 58C22CBD8C22B9D6023D59F8 /* LnurlPayInfo.swift */; settings = {ASSET_TAGS = (BreezSDK, ); }; };
D0D7A0D4E13F31C4E02E235B /* ReceivePayment.swift in Resources */ = {isa = PBXBuildFile; fileRef = 91C524F800843E0A3F17E004 /* ReceivePayment.swift */; settings = {ASSET_TAGS = (BreezSDK, ); }; };
@ -43,9 +43,9 @@
dstPath = "";
dstSubfolderSpec = 10;
files = (
CE291CFE2C15DB9A00B9F709 /* WowneroWallet.framework in CopyFiles */,
0C50DFB92BF3CB56002B0EB3 /* MoneroWallet.framework in CopyFiles */,
CEA883682D43BE4500278CD3 /* ZanoWallet.framework in CopyFiles */,
CE918BF82D533ECE007F186E /* MoneroWallet.xcframework in CopyFiles */,
CE918BFA2D533ED4007F186E /* WowneroWallet.xcframework in CopyFiles */,
CE918BFC2D533ED8007F186E /* ZanoWallet.xcframework in CopyFiles */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -55,7 +55,6 @@
014D7E4DBCFD76DDE652A4D9 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
0C400E0F25B21ABB0025E469 /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = "<group>"; };
0C44A7192518EF8000B570ED /* decrypt.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = decrypt.swift; sourceTree = "<group>"; };
0C50DFB82BF3CB56002B0EB3 /* MoneroWallet.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = MoneroWallet.framework; sourceTree = "<group>"; };
0C9986A3251A932F00D566FD /* CryptoSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = CryptoSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; };
0C9D68C8264854B60011B691 /* secRandom.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = secRandom.swift; sourceTree = "<group>"; };
0CCA7ADAD6FF9185EBBB2BCA /* Constants.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Constants.swift; path = "../.symlinks/plugins/breez_sdk/ios/bindings-swift/Sources/BreezSDK/Constants.swift"; sourceTree = "<group>"; };
@ -86,9 +85,9 @@
ABD6FCBB0F4244B090459128 /* BreezSDK.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BreezSDK.swift; path = "../.symlinks/plugins/breez_sdk/ios/bindings-swift/Sources/BreezSDK/BreezSDK.swift"; sourceTree = "<group>"; };
B3D5E78267F5F18D882FDC3B /* ServiceConfig.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ServiceConfig.swift; path = "../.symlinks/plugins/breez_sdk/ios/bindings-swift/Sources/BreezSDK/ServiceConfig.swift"; sourceTree = "<group>"; };
C58D93382C00FAC6004BCF69 /* libresolv.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libresolv.tbd; path = usr/lib/libresolv.tbd; sourceTree = SDKROOT; };
CE291CFD2C15DB9A00B9F709 /* WowneroWallet.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = WowneroWallet.framework; sourceTree = "<group>"; };
CEAFE49D2C539250009FF3AD /* Mwebd.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = Mwebd.xcframework; sourceTree = "<group>"; };
CEB6D62E2D43BB78002C6DBC /* ZanoWallet.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = ZanoWallet.framework; sourceTree = "<group>"; };
CE918BF72D533ECE007F186E /* MoneroWallet.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = MoneroWallet.xcframework; sourceTree = "<group>"; };
CE918BF92D533ED4007F186E /* WowneroWallet.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = WowneroWallet.xcframework; sourceTree = "<group>"; };
CE918BFB2D533ED8007F186E /* ZanoWallet.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = ZanoWallet.xcframework; sourceTree = "<group>"; };
D139E30AEB36740C21C00A9E /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
D7CD6B6020744E8FA471915D /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
DCEA540E3586164FB47AD13E /* LnurlPayInvoice.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = LnurlPayInvoice.swift; path = "../.symlinks/plugins/breez_sdk/ios/bindings-swift/Sources/BreezSDK/Task/LnurlPayInvoice.swift"; sourceTree = "<group>"; };
@ -100,8 +99,8 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
CEAFE4A02C53926F009FF3AD /* libresolv.tbd in Frameworks */,
8B1F4FCAA5EB9F3A83D32D5F /* Pods_Runner.framework in Frameworks */,
CEAFE4A02C53926F009FF3AD /* libresolv.tbd in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -111,7 +110,9 @@
06957875428D0F5AAE053765 /* Frameworks */ = {
isa = PBXGroup;
children = (
CEAFE49D2C539250009FF3AD /* Mwebd.xcframework */,
CE918BFB2D533ED8007F186E /* ZanoWallet.xcframework */,
CE918BF92D533ED4007F186E /* WowneroWallet.xcframework */,
CE918BF72D533ECE007F186E /* MoneroWallet.xcframework */,
C58D93382C00FAC6004BCF69 /* libresolv.tbd */,
0C9986A3251A932F00D566FD /* CryptoSwift.framework */,
D7CD6B6020744E8FA471915D /* Pods_Runner.framework */,
@ -162,9 +163,6 @@
97C146E51CF9000F007C117D = {
isa = PBXGroup;
children = (
CE291CFD2C15DB9A00B9F709 /* WowneroWallet.framework */,
0C50DFB82BF3CB56002B0EB3 /* MoneroWallet.framework */,
CEB6D62E2D43BB78002C6DBC /* ZanoWallet.framework */,
0C44A7182518EF4A00B570ED /* CakeWallet */,
9740EEB11CF90186004384FC /* Flutter */,
97C146F01CF9000F007C117D /* Runner */,

Binary file not shown.

View file

@ -1 +0,0 @@
../scripts/monero_c/release/monero/aarch64-apple-ios_libwallet2_api_c.dylib

View file

@ -1 +0,0 @@
../scripts/monero_c/release/wownero/aarch64-apple-ios_libwallet2_api_c.dylib

View file

@ -1 +0,0 @@
../scripts/monero_c/release/zano/aarch64-apple-ios_libwallet2_api_c.dylib

View file

@ -263,7 +263,7 @@ Future<void> defaultSettingsMigration(
case 41:
_changeExchangeProviderAvailability(
sharedPreferences,
providerName: "Quantex",
providerName: "SwapTrade",
enabled: false,
);
await _addSethNode(nodes, sharedPreferences);
@ -394,6 +394,11 @@ Future<void> defaultSettingsMigration(
sharedPreferences,
providerName: "SimpleSwap",
enabled: true,
);
_changeExchangeProviderAvailability(
sharedPreferences,
providerName: "SwapTrade",
enabled: false,
);
break;
default:

View file

@ -12,7 +12,7 @@ import 'package:flutter/scheduler.dart';
var isQrScannerShown = false;
Future<String> presentQRScanner(BuildContext context) async {
Future<String?> presentQRScanner(BuildContext context) async {
isQrScannerShown = true;
try {
final result = await Navigator.of(context).push<String>(
@ -23,7 +23,7 @@ Future<String> presentQRScanner(BuildContext context) async {
),
);
isQrScannerShown = false;
return result!;
return result;
} catch (e) {
isQrScannerShown = false;
rethrow;

View file

@ -26,8 +26,8 @@ class ExchangeProviderDescription extends EnumerableItem<int> with Serializable<
ExchangeProviderDescription(title: 'All trades', raw: 7, image: '');
static const thorChain =
ExchangeProviderDescription(title: 'ThorChain', raw: 8, image: 'assets/images/thorchain.png');
static const quantex =
ExchangeProviderDescription(title: 'Quantex', raw: 9, image: 'assets/images/quantex.png');
static const swapTrade =
ExchangeProviderDescription(title: 'SwapTrade', raw: 9, image: 'assets/images/swapTrade.png');
static const letsExchange =
ExchangeProviderDescription(title: 'LetsExchange', raw: 10, image: 'assets/images/letsexchange_icon.svg');
static const stealthEx =
@ -56,7 +56,7 @@ class ExchangeProviderDescription extends EnumerableItem<int> with Serializable<
case 8:
return thorChain;
case 9:
return quantex;
return swapTrade;
case 10:
return letsExchange;
case 11:

View file

@ -14,8 +14,8 @@ import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/utils/print_verbose.dart';
import 'package:http/http.dart';
class QuantexExchangeProvider extends ExchangeProvider {
QuantexExchangeProvider() : super(pairList: supportedPairs(_notSupported));
class SwapTradeExchangeProvider extends ExchangeProvider {
SwapTradeExchangeProvider() : super(pairList: supportedPairs(_notSupported));
static final List<CryptoCurrency> _notSupported = [
...(CryptoCurrency.all
@ -33,15 +33,15 @@ class QuantexExchangeProvider extends ExchangeProvider {
.toList())
];
static final markup = secrets.quantexExchangeMarkup;
static final markup = secrets.swapTradeExchangeMarkup;
static const apiAuthority = 'api.myquantex.com';
static const apiAuthority = 'api.swaptrade.io';
static const getRate = '/api/swap/get-rate';
static const getCoins = '/api/swap/get-coins';
static const createOrder = '/api/swap/create-order';
@override
String get title => 'Quantex';
String get title => 'SwapTrade';
@override
bool get isAvailable => true;
@ -53,7 +53,7 @@ class QuantexExchangeProvider extends ExchangeProvider {
bool get supportsFixedRate => false;
@override
ExchangeProviderDescription get description => ExchangeProviderDescription.quantex;
ExchangeProviderDescription get description => ExchangeProviderDescription.swapTrade;
@override
Future<bool> checkIsAvailable() async => true;

View file

@ -253,9 +253,10 @@ class CWMonero extends Monero {
required String name,
required String language,
required bool isPolyseed,
required String? passphrase,
String? password}) =>
MoneroNewWalletCredentials(
name: name, password: password, language: language, isPolyseed: isPolyseed);
name: name, password: password, language: language, isPolyseed: isPolyseed, passphrase: passphrase);
@override
Map<String, String> getKeys(Object wallet) {

View file

@ -23,7 +23,51 @@ import 'package:mobx/mobx.dart';
import 'package:smooth_page_indicator/smooth_page_indicator.dart';
class WalletRestorePage extends BasePage {
WalletRestorePage(this.walletRestoreViewModel, this.seedSettingsViewModel)
WalletRestorePage(this.walletRestoreViewModel, this.seedSettingsViewModel);
@override
Widget middle(BuildContext context) => Observer(
builder: (_) => Text(
walletRestoreViewModel.mode == WalletRestoreMode.seed
? S.current.restore_title_from_seed
: S.current.restore_title_from_keys,
style: TextStyle(
fontSize: 18.0,
fontWeight: FontWeight.bold,
fontFamily: 'Lato',
color: titleColor(context)),
));
final WalletRestoreViewModel walletRestoreViewModel;
final SeedSettingsViewModel seedSettingsViewModel;
@override
Function(BuildContext)? get pushToNextWidget => (context) {
FocusScopeNode currentFocus = FocusScope.of(context);
if (!currentFocus.hasPrimaryFocus) {
currentFocus.focusedChild?.unfocus();
}
};
@override
Widget body(BuildContext context) {
return WalletRestorePageBody(walletRestoreViewModel, seedSettingsViewModel);
}
}
class WalletRestorePageBody extends StatefulWidget {
WalletRestorePageBody(this.walletRestoreViewModel, this.seedSettingsViewModel);
final WalletRestoreViewModel walletRestoreViewModel;
final SeedSettingsViewModel seedSettingsViewModel;
@override
State<WalletRestorePageBody> createState() =>
_WalletRestorePageBodyState(walletRestoreViewModel, seedSettingsViewModel);
}
class _WalletRestorePageBodyState extends State<WalletRestorePageBody> {
_WalletRestorePageBodyState(this.walletRestoreViewModel, this.seedSettingsViewModel)
: walletRestoreFromSeedFormKey = GlobalKey<WalletRestoreFromSeedFormState>(),
walletRestoreFromKeysFormKey = GlobalKey<WalletRestoreFromKeysFromState>(),
_pages = [],
@ -54,8 +98,10 @@ class WalletRestorePage extends BasePage {
_validateOnChange(isPolyseed: isPolyseed);
},
displayWalletPassword: walletRestoreViewModel.hasWalletPassword,
onPasswordChange: (String password) => walletRestoreViewModel.walletPassword = password,
onRepeatedPasswordChange: (String repeatedPassword) => walletRestoreViewModel.repeatedWalletPassword = repeatedPassword));
onPasswordChange: (String password) =>
walletRestoreViewModel.walletPassword = password,
onRepeatedPasswordChange: (String repeatedPassword) =>
walletRestoreViewModel.repeatedWalletPassword = repeatedPassword));
break;
case WalletRestoreMode.keys:
_pages.add(WalletRestoreFromKeysFrom(
@ -69,8 +115,10 @@ class WalletRestorePage extends BasePage {
},
displayPrivateKeyField: walletRestoreViewModel.hasRestoreFromPrivateKey,
displayWalletPassword: walletRestoreViewModel.hasWalletPassword,
onPasswordChange: (String password) => walletRestoreViewModel.walletPassword = password,
onRepeatedPasswordChange: (String repeatedPassword) => walletRestoreViewModel.repeatedWalletPassword = repeatedPassword,
onPasswordChange: (String password) =>
walletRestoreViewModel.walletPassword = password,
onRepeatedPasswordChange: (String repeatedPassword) =>
walletRestoreViewModel.repeatedWalletPassword = repeatedPassword,
onHeightOrDateEntered: (value) => walletRestoreViewModel.isButtonEnabled = value));
break;
default:
@ -79,21 +127,6 @@ class WalletRestorePage extends BasePage {
});
}
bool _formProcessing = false;
@override
Widget middle(BuildContext context) => Observer(
builder: (_) => Text(
walletRestoreViewModel.mode == WalletRestoreMode.seed
? S.current.restore_title_from_seed
: S.current.restore_title_from_keys,
style: TextStyle(
fontSize: 18.0,
fontWeight: FontWeight.bold,
fontFamily: 'Lato',
color: titleColor(context)),
));
final WalletRestoreViewModel walletRestoreViewModel;
final SeedSettingsViewModel seedSettingsViewModel;
final PageController _controller;
@ -102,20 +135,16 @@ class WalletRestorePage extends BasePage {
final GlobalKey<WalletRestoreFromKeysFromState> walletRestoreFromKeysFormKey;
final FocusNode _blockHeightFocusNode;
bool _formProcessing = false;
// DerivationType derivationType = DerivationType.unknown;
// String? derivationPath = null;
DerivationInfo? derivationInfo;
@override
Function(BuildContext)? get pushToNextWidget => (context) {
FocusScopeNode currentFocus = FocusScope.of(context);
if (!currentFocus.hasPrimaryFocus) {
currentFocus.focusedChild?.unfocus();
}
};
void initState() {
super.initState();
@override
Widget body(BuildContext context) {
reaction((_) => walletRestoreViewModel.state, (ExecutionState state) {
if (state is FailureState) {
WidgetsBinding.instance.addPostFrameCallback((_) {
@ -149,7 +178,10 @@ class WalletRestorePage extends BasePage {
.currentState!.blockchainHeightKey.currentState!.dateController.text = '';
walletRestoreFromKeysFormKey.currentState!.nameTextEditingController.text = '';
});
}
@override
Widget build(BuildContext context) {
return KeyboardActions(
config: KeyboardActionsConfig(
keyboardActionsPlatform: KeyboardActionsPlatform.IOS,

View file

@ -4,7 +4,6 @@ import 'package:cake_wallet/src/widgets/setting_action_button.dart';
import 'package:cake_wallet/src/widgets/setting_actions.dart';
import 'package:cake_wallet/typography.dart';
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:flutter/material.dart';
import 'package:cake_wallet/router.dart' as Router;
import 'package:cake_wallet/themes/extensions/menu_theme.dart';
@ -35,6 +34,7 @@ class _DesktopSettingsPageState extends State<DesktopSettingsPage> {
Widget build(BuildContext context) {
return Scaffold(
body: Container(
color: Theme.of(context).colorScheme.background,
height: MediaQuery.of(context).size.height,
child: Row(
children: [

View file

@ -100,6 +100,7 @@ class AnimatedURPage extends BasePage {
switch (urQrType) {
case "ur:xmr-txunsigned": // ur:xmr-txsigned
final ur = await presentQRScanner(context);
if (ur == null) return;
final result = await monero!.commitTransactionUR(animatedURmodel.wallet, ur);
if (result) {
Navigator.of(context).pop(true);
@ -107,6 +108,7 @@ class AnimatedURPage extends BasePage {
break;
case "ur:xmr-output": // xmr-keyimage
final ur = await presentQRScanner(context);
if (ur == null) return;
final result = await monero!.importKeyImagesUR(animatedURmodel.wallet, ur);
if (result) {
Navigator.of(context).pop(true);

View file

@ -15,6 +15,7 @@ import 'package:cake_wallet/utils/show_bar.dart';
import 'package:cake_wallet/view_model/wallet_keys_view_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:qr_flutter/qr_flutter.dart';
class WalletKeysPage extends BasePage {
@ -31,14 +32,14 @@ class WalletKeysPage extends BasePage {
padding: const EdgeInsets.symmetric(horizontal: 0, vertical: 0),
child: Column(
children: [
Padding(
padding: EdgeInsets.only(left: 14, right: 14, bottom: 8),
child: WarningBox(
key: const ValueKey('wallet_keys_page_share_warning_text_key'),
content: S.of(context).do_not_share_warning_text.toUpperCase(),
currentTheme: currentTheme,
Padding(
padding: EdgeInsets.only(left: 14, right: 14, bottom: 8),
child: WarningBox(
key: const ValueKey('wallet_keys_page_share_warning_text_key'),
content: S.of(context).do_not_share_warning_text.toUpperCase(),
currentTheme: currentTheme,
),
),
),
Expanded(
child: WalletKeysPageBody(
walletKeysViewModel: walletKeysViewModel,
@ -98,36 +99,36 @@ class _WalletKeysPageBodyState extends State<WalletKeysPageBody>
children: [
Padding(
padding: const EdgeInsets.only(left: 22, right: 22, top: 0),
child: TabBar(
controller: _tabController,
splashFactory: NoSplash.splashFactory,
indicatorSize: TabBarIndicatorSize.label,
isScrollable: true,
labelStyle: TextStyle(
fontSize: 18,
fontFamily: 'Lato',
fontWeight: FontWeight.w600,
color: Theme.of(context).appBarTheme.titleTextStyle!.color,
child: TabBar(
controller: _tabController,
splashFactory: NoSplash.splashFactory,
indicatorSize: TabBarIndicatorSize.label,
isScrollable: true,
labelStyle: TextStyle(
fontSize: 18,
fontFamily: 'Lato',
fontWeight: FontWeight.w600,
color: Theme.of(context).appBarTheme.titleTextStyle!.color,
),
unselectedLabelStyle: TextStyle(
fontSize: 18,
fontFamily: 'Lato',
fontWeight: FontWeight.w600,
color: Theme.of(context).appBarTheme.titleTextStyle!.color?.withOpacity(0.5),
),
labelColor: Theme.of(context).appBarTheme.titleTextStyle!.color,
indicatorColor: Theme.of(context).appBarTheme.titleTextStyle!.color,
indicatorPadding: EdgeInsets.zero,
labelPadding: const EdgeInsets.only(right: 24),
tabAlignment: TabAlignment.start,
dividerColor: Colors.transparent,
padding: EdgeInsets.zero,
tabs: [
Tab(text: S.of(context).widgets_seed),
if (showKeyTab) Tab(text: S.of(context).keys),
if (showLegacySeedTab) Tab(text: S.of(context).legacy),
],
),
unselectedLabelStyle: TextStyle(
fontSize: 18,
fontFamily: 'Lato',
fontWeight: FontWeight.w600,
color: Theme.of(context).appBarTheme.titleTextStyle!.color?.withOpacity(0.5),
),
labelColor: Theme.of(context).appBarTheme.titleTextStyle!.color,
indicatorColor: Theme.of(context).appBarTheme.titleTextStyle!.color,
indicatorPadding: EdgeInsets.zero,
labelPadding: const EdgeInsets.only(right: 24),
tabAlignment: TabAlignment.start,
dividerColor: Colors.transparent,
padding: EdgeInsets.zero,
tabs: [
Tab(text: S.of(context).widgets_seed),
if (showKeyTab) Tab(text: S.of(context).keys),
if (showLegacySeedTab) Tab(text: S.of(context).legacy),
],
),
),
const SizedBox(height: 20),
Expanded(
@ -135,14 +136,14 @@ class _WalletKeysPageBodyState extends State<WalletKeysPageBody>
controller: _tabController,
children: [
Padding(
padding: const EdgeInsets.only(left: 22, right: 22,),
padding: const EdgeInsets.only(left: 22, right: 22),
child: _buildSeedTab(context, false),
),
if (showKeyTab)
Padding(
padding: const EdgeInsets.only(left: 22, right: 22),
child: _buildKeysTab(context),
),
Padding(
padding: const EdgeInsets.only(left: 22, right: 22),
child: _buildKeysTab(context),
),
if (showLegacySeedTab)
Padding(
padding: const EdgeInsets.only(left: 22, right: 22),
@ -151,7 +152,6 @@ class _WalletKeysPageBodyState extends State<WalletKeysPageBody>
],
),
),
],
),
);
@ -162,6 +162,8 @@ class _WalletKeysPageBodyState extends State<WalletKeysPageBody>
children: [
if (isLegacySeedOnly || isLegacySeed) _buildHeightBox(),
const SizedBox(height: 20),
(_buildPassphraseBox() ?? Container()),
if (widget.walletKeysViewModel.passphrase.isNotEmpty) const SizedBox(height: 20),
Expanded(
child: SeedPhraseGridWidget(
list: isLegacySeed
@ -263,6 +265,64 @@ class _WalletKeysPageBodyState extends State<WalletKeysPageBody>
);
}
Widget? _buildPassphraseBox() {
if (widget.walletKeysViewModel.passphrase.isEmpty) return null;
return Container(
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 14),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
color: Theme.of(context).cardColor,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
S.of(context).passphrase_view_keys,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w500,
color: Theme.of(context).extension<CakeTextTheme>()!.buttonTextColor.withOpacity(0.5),
),
),
const SizedBox(width: 6),
Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Observer(builder: (BuildContext context) {
return Text(
(widget.walletKeysViewModel.obscurePassphrase)
? "*****"
: widget.walletKeysViewModel.passphrase,
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w500,
color: Theme.of(context).extension<CakeTextTheme>()!.buttonTextColor,
),
);
}),
Observer(builder: (BuildContext context) {
return GestureDetector(
onTap: () {
widget.walletKeysViewModel.obscurePassphrase =
!widget.walletKeysViewModel.obscurePassphrase;
},
child: Icon(
widget.walletKeysViewModel.obscurePassphrase
? Icons.visibility_off
: Icons.visibility,
size: 16,
color: Theme.of(context).textTheme.bodyLarge?.color?.withOpacity(0.7),
));
}),
],
),
),
],
),
);
}
Widget _buildBottomActionPanel({
required String titleForClipboard,
@ -273,37 +333,37 @@ class _WalletKeysPageBodyState extends State<WalletKeysPageBody>
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 8),
child: Row(
mainAxisSize: MainAxisSize.max,
children: [
Flexible(
child: Container(
padding: const EdgeInsets.only(right: 8.0, top: 8.0),
child: PrimaryButton(
key: const ValueKey('wallet_keys_page_copy_seeds_button_key'),
onPressed: () => _onCopy(titleForClipboard, dataToCopy, context),
text: S.of(context).copy,
color: Theme.of(context).cardColor,
textColor: widget.currentTheme.type == ThemeType.dark
? Theme.of(context).extension<DashboardPageTheme>()!.textColor
: Theme.of(context).extension<CakeTextTheme>()!.buttonTextColor,
child: Row(
mainAxisSize: MainAxisSize.max,
children: [
Flexible(
child: Container(
padding: const EdgeInsets.only(right: 8.0, top: 8.0),
child: PrimaryButton(
key: const ValueKey('wallet_keys_page_copy_seeds_button_key'),
onPressed: () => _onCopy(titleForClipboard, dataToCopy, context),
text: S.of(context).copy,
color: Theme.of(context).cardColor,
textColor: widget.currentTheme.type == ThemeType.dark
? Theme.of(context).extension<DashboardPageTheme>()!.textColor
: Theme.of(context).extension<CakeTextTheme>()!.buttonTextColor,
),
),
),
),
Flexible(
child: Container(
padding: const EdgeInsets.only(left: 8.0, top: 8.0),
child: PrimaryButton(
key: const ValueKey('wallet_keys_page_show_qr_seeds_button_key'),
onPressed: onShowQR,
text: S.current.show + ' QR',
color: Theme.of(context).primaryColor,
textColor: Colors.white,
Flexible(
child: Container(
padding: const EdgeInsets.only(left: 8.0, top: 8.0),
child: PrimaryButton(
key: const ValueKey('wallet_keys_page_show_qr_seeds_button_key'),
onPressed: onShowQR,
text: S.current.show + ' QR',
color: Theme.of(context).primaryColor,
textColor: Colors.white,
),
),
),
),
],
),
],
),
),
const SizedBox(height: 12),
],

View file

@ -1,7 +1,6 @@
import 'package:another_flushbar/flushbar.dart';
import 'package:cake_wallet/core/auth_service.dart';
import 'package:cake_wallet/core/new_wallet_arguments.dart';
import 'package:cake_wallet/core/secure_storage.dart';
import 'package:cake_wallet/entities/wallet_edit_page_arguments.dart';
import 'package:cake_wallet/entities/wallet_list_order_types.dart';
import 'package:cake_wallet/generated/i18n.dart';
@ -402,41 +401,6 @@ class WalletListBodyState extends State<WalletListBody> {
);
}
Image _imageFor({required WalletType type, bool? isTestnet}) {
switch (type) {
case WalletType.bitcoin:
if (isTestnet == true) {
return tBitcoinIcon;
}
return bitcoinIcon;
case WalletType.monero:
return moneroIcon;
case WalletType.litecoin:
return litecoinIcon;
case WalletType.haven:
return havenIcon;
case WalletType.ethereum:
return ethereumIcon;
case WalletType.bitcoinCash:
return bitcoinCashIcon;
case WalletType.nano:
case WalletType.banano:
return nanoIcon;
case WalletType.polygon:
return polygonIcon;
case WalletType.solana:
return solanaIcon;
case WalletType.tron:
return tronIcon;
case WalletType.wownero:
return wowneroIcon;
case WalletType.zano:
return zanoIcon;
case WalletType.none:
return nonWalletTypeIcon;
}
}
Future<void> _loadWallet(WalletListItem wallet) async {
if (SettingsStoreBase.walletPasswordDirectInput) {
Navigator.of(context).pushNamed(Routes.walletUnlockLoadable,

View file

@ -233,6 +233,7 @@ class AddressTextField<T extends Currency> extends StatelessWidget{
await PermissionHandler.checkPermission(Permission.camera, context);
if (!isCameraPermissionGranted) return;
final code = await presentQRScanner(context);
if (code == null) return;
if (code.isEmpty) {
return;
}

View file

@ -46,7 +46,6 @@ class SettingActions {
name: (context) => S.of(context).silent_payments_settings,
image: 'assets/images/bitcoin_menu.png',
onTap: (BuildContext context) {
Navigator.pop(context);
Navigator.of(context).pushNamed(Routes.silentPaymentsSettings);
},
);
@ -56,7 +55,6 @@ class SettingActions {
name: (context) => S.of(context).export_outputs,
image: 'assets/images/monero_menu.png',
onTap: (BuildContext context) {
Navigator.pop(context);
Navigator.of(context).pushNamed(Routes.urqrAnimatedPage, arguments: 'export-outputs');
},
);
@ -66,7 +64,6 @@ class SettingActions {
name: (context) => S.of(context).litecoin_mweb_settings,
image: 'assets/images/litecoin_menu.png',
onTap: (BuildContext context) {
Navigator.pop(context);
Navigator.of(context).pushNamed(Routes.mwebSettings);
},
);
@ -76,7 +73,6 @@ class SettingActions {
name: (context) => S.of(context).connection_sync,
image: 'assets/images/nodes_menu.png',
onTap: (BuildContext context) {
Navigator.pop(context);
Navigator.of(context).pushNamed(Routes.connectionSync);
},
);
@ -86,8 +82,10 @@ class SettingActions {
name: (context) => S.of(context).wallets,
image: 'assets/images/wallet_menu.png',
onTap: (BuildContext context) {
Navigator.pop(context);
Navigator.of(context).pushNamed(Routes.walletList);
Navigator.of(context).pushNamed(Routes.walletList, arguments: (_) {
Navigator.of(context).pop(); // pops wallet list
Navigator.of(context).pop(); // pops drawer
});
},
);
@ -96,7 +94,6 @@ class SettingActions {
name: (context) => S.of(context).address_book_menu,
image: 'assets/images/open_book_menu.png',
onTap: (BuildContext context) {
Navigator.pop(context);
Navigator.of(context).pushNamed(Routes.addressBook);
},
);
@ -106,7 +103,6 @@ class SettingActions {
name: (context) => S.of(context).security_and_backup,
image: 'assets/images/key_menu.png',
onTap: (BuildContext context) {
Navigator.pop(context);
Navigator.of(context).pushNamed(Routes.securityBackupPage);
},
);
@ -116,7 +112,6 @@ class SettingActions {
name: (context) => S.of(context).privacy,
image: 'assets/images/privacy_menu.png',
onTap: (BuildContext context) {
Navigator.pop(context);
Navigator.of(context).pushNamed(Routes.privacyPage);
},
);
@ -126,7 +121,6 @@ class SettingActions {
name: (context) => S.of(context).display_settings,
image: 'assets/images/eye_menu.png',
onTap: (BuildContext context) {
Navigator.pop(context);
Navigator.of(context).pushNamed(Routes.displaySettingsPage);
},
);
@ -136,7 +130,6 @@ class SettingActions {
name: (context) => S.of(context).other_settings,
image: 'assets/images/settings_menu.png',
onTap: (BuildContext context) {
Navigator.pop(context);
Navigator.of(context).pushNamed(Routes.otherSettingsPage);
},
);
@ -146,7 +139,6 @@ class SettingActions {
name: (context) => S.of(context).settings_support,
image: 'assets/images/question_mark.png',
onTap: (BuildContext context) {
Navigator.pop(context);
Navigator.of(context).pushNamed(Routes.support);
},
);

View file

@ -78,8 +78,8 @@ abstract class AdvancedPrivacySettingsViewModelBase with Store {
WalletType.ethereum,
WalletType.polygon,
WalletType.tron,
if (isRestore) WalletType.monero,
if (isRestore) WalletType.wownero,
WalletType.monero,
WalletType.wownero,
if (isRestore) WalletType.zano,
].contains(type);

View file

@ -5,7 +5,7 @@ import 'package:cake_wallet/exchange/provider/chainflip_exchange_provider.dart';
import 'package:cake_wallet/exchange/provider/changenow_exchange_provider.dart';
import 'package:cake_wallet/exchange/provider/exchange_provider.dart';
import 'package:cake_wallet/exchange/provider/exolix_exchange_provider.dart';
import 'package:cake_wallet/exchange/provider/quantex_exchange_provider.dart';
import 'package:cake_wallet/exchange/provider/swaptrade_exchange_provider.dart';
import 'package:cake_wallet/exchange/provider/sideshift_exchange_provider.dart';
import 'package:cake_wallet/exchange/provider/simpleswap_exchange_provider.dart';
import 'package:cake_wallet/exchange/provider/stealth_ex_exchange_provider.dart';
@ -52,8 +52,8 @@ abstract class ExchangeTradeViewModelBase with Store {
case ExchangeProviderDescription.exolix:
_provider = ExolixExchangeProvider();
break;
case ExchangeProviderDescription.quantex:
_provider = QuantexExchangeProvider();
case ExchangeProviderDescription.swapTrade:
_provider = SwapTradeExchangeProvider();
break;
case ExchangeProviderDescription.stealthEx:
_provider = StealthExExchangeProvider();

View file

@ -35,7 +35,7 @@ import 'package:cake_wallet/exchange/limits_state.dart';
import 'package:cake_wallet/exchange/provider/changenow_exchange_provider.dart';
import 'package:cake_wallet/exchange/provider/exchange_provider.dart';
import 'package:cake_wallet/exchange/provider/exolix_exchange_provider.dart';
import 'package:cake_wallet/exchange/provider/quantex_exchange_provider.dart';
import 'package:cake_wallet/exchange/provider/swaptrade_exchange_provider.dart';
import 'package:cake_wallet/exchange/provider/sideshift_exchange_provider.dart';
import 'package:cake_wallet/exchange/provider/simpleswap_exchange_provider.dart';
import 'package:cake_wallet/exchange/provider/thorchain_exchange.provider.dart';
@ -176,7 +176,7 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
ThorChainExchangeProvider(tradesStore: trades),
ChainflipExchangeProvider(tradesStore: trades),
if (FeatureFlag.isExolixEnabled) ExolixExchangeProvider(),
QuantexExchangeProvider(),
SwapTradeExchangeProvider(),
LetsExchangeExchangeProvider(),
StealthExExchangeProvider(),
TrocadorExchangeProvider(

View file

@ -1,6 +1,7 @@
import 'package:cake_wallet/core/execution_state.dart';
import 'package:cake_wallet/entities/qr_scanner.dart';
import 'package:cake_wallet/store/settings_store.dart';
import 'package:cw_core/utils/print_verbose.dart';
import 'package:flutter/cupertino.dart';
import 'package:hive/hive.dart';
import 'package:mobx/mobx.dart';
@ -214,7 +215,8 @@ abstract class NodeCreateOrEditViewModelBase with Store {
bool isCameraPermissionGranted =
await PermissionHandler.checkPermission(Permission.camera, context);
if (!isCameraPermissionGranted) return;
String code = await presentQRScanner(context);
String? code = await presentQRScanner(context);
if (code == null) throw Exception("Unexpected QR code value: aborted");
if (code.isEmpty) {
throw Exception('Unexpected scan QR code value: value is empty');
@ -228,12 +230,12 @@ abstract class NodeCreateOrEditViewModelBase with Store {
}
final userInfo = uri.userInfo;
final rpcUser = userInfo.length == 2 ? userInfo[0] : '';
final rpcPassword = userInfo.length == 2 ? userInfo[1] : '';
final ipAddress = uri.host;
final port = uri.hasPort ? uri.port.toString() : '';
final path = uri.path;
final queryParams = uri.queryParameters; // Currently not used
final rpcUser = userInfo.split(':').first;
final rpcPassword = userInfo.split(':').length > 1 ? userInfo.split(':')[1] : '';
await Future.delayed(Duration(milliseconds: 345));

View file

@ -89,7 +89,8 @@ class WalletRestoreFromQRCode {
}
static Future<RestoredWallet> scanQRCodeForRestoring(BuildContext context) async {
String code = await presentQRScanner(context);
String? code = await presentQRScanner(context);
if (code == null) throw Exception("Unexpected scan QR code value: aborted");
if (code.isEmpty) throw Exception('Unexpected scan QR code value: value is empty');
WalletType? walletType;

View file

@ -69,9 +69,9 @@ abstract class SupportViewModelBase with Store {
linkTitle: 'support@exolix.com',
link: 'mailto:support@exolix.com'),
LinkListItem(
title: 'Quantex',
icon: 'assets/images/quantex.png',
linkTitle: 'help.myquantex.com',
title: 'SwapTrade',
icon: 'assets/images/swapTrade.png',
linkTitle: 'help.swaptrade.io',
link: 'mailto:support@exolix.com'),
LinkListItem(
title: 'Trocador',

View file

@ -6,7 +6,7 @@ import 'package:cake_wallet/exchange/provider/changenow_exchange_provider.dart';
import 'package:cake_wallet/exchange/provider/exchange_provider.dart';
import 'package:cake_wallet/exchange/provider/exolix_exchange_provider.dart';
import 'package:cake_wallet/exchange/provider/letsexchange_exchange_provider.dart';
import 'package:cake_wallet/exchange/provider/quantex_exchange_provider.dart';
import 'package:cake_wallet/exchange/provider/swaptrade_exchange_provider.dart';
import 'package:cake_wallet/exchange/provider/sideshift_exchange_provider.dart';
import 'package:cake_wallet/exchange/provider/simpleswap_exchange_provider.dart';
import 'package:cake_wallet/exchange/provider/stealth_ex_exchange_provider.dart';
@ -61,8 +61,8 @@ abstract class TradeDetailsViewModelBase with Store {
case ExchangeProviderDescription.thorChain:
_provider = ThorChainExchangeProvider(tradesStore: trades);
break;
case ExchangeProviderDescription.quantex:
_provider = QuantexExchangeProvider();
case ExchangeProviderDescription.swapTrade:
_provider = SwapTradeExchangeProvider();
case ExchangeProviderDescription.letsExchange:
_provider = LetsExchangeExchangeProvider();
break;
@ -96,8 +96,8 @@ abstract class TradeDetailsViewModelBase with Store {
return 'https://exolix.com/transaction/${trade.id}';
case ExchangeProviderDescription.thorChain:
return 'https://track.ninerealms.com/${trade.id}';
case ExchangeProviderDescription.quantex:
return 'https://myquantex.com/send/${trade.id}';
case ExchangeProviderDescription.swapTrade:
return 'https://swaptrade.io/send/${trade.id}';
case ExchangeProviderDescription.letsExchange:
return 'https://letsexchange.io/?transactionId=${trade.id}';
case ExchangeProviderDescription.stealthEx:

View file

@ -10,6 +10,7 @@ import 'package:cake_wallet/store/app_store.dart';
import 'package:cake_wallet/store/settings_store.dart';
import 'package:cake_wallet/view_model/restore/restore_wallet.dart';
import 'package:cake_wallet/view_model/seed_settings_view_model.dart';
import 'package:cw_core/exceptions.dart';
import 'package:cw_core/pathForWallet.dart';
import 'package:cw_core/utils/print_verbose.dart';
import 'package:cw_core/wallet_base.dart';
@ -118,7 +119,11 @@ abstract class WalletCreationVMBase with Store {
} catch (e, s) {
printV("error: $e");
printV("stack: $s");
state = FailureState(e.toString());
String message = e.toString();
if (e is RestoreFromSeedException) {
message = e.message;
}
state = FailureState(message);
}
}

View file

@ -1,10 +1,10 @@
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/haven/haven.dart';
import 'package:cake_wallet/monero/monero.dart';
import 'package:cake_wallet/reactions/wallet_connect.dart';
import 'package:cake_wallet/src/screens/transaction_details/standart_list_item.dart';
import 'package:cake_wallet/store/app_store.dart';
import 'package:cake_wallet/wownero/wownero.dart';
import 'package:cake_wallet/zano/zano.dart';
import 'package:cw_core/transaction_direction.dart';
import 'package:cw_core/transaction_info.dart';
import 'package:cw_core/wallet_base.dart';
@ -64,8 +64,8 @@ abstract class WalletKeysViewModelBase with Store {
bool get isLegacySeedOnly =>
(_wallet.type == WalletType.monero || _wallet.type == WalletType.wownero) &&
_wallet.seed != null &&
!Polyseed.isValidSeed(_wallet.seed!);
_wallet.seed != null &&
!Polyseed.isValidSeed(_wallet.seed!);
String get legacySeed {
if ((_wallet.type == WalletType.monero || _wallet.type == WalletType.wownero) &&
@ -86,9 +86,19 @@ abstract class WalletKeysViewModelBase with Store {
if (_wallet.type == WalletType.monero) {
return monero!.getRestoreHeight(_wallet)?.toString() ?? '';
}
if (_wallet.type == WalletType.wownero) {
return wownero!.getRestoreHeight(_wallet)?.toString() ?? '';
}
return '';
}
@observable
bool obscurePassphrase = true;
String get passphrase {
return _wallet.passphrase ?? '';
}
/// The Regex split the words based on any whitespace character.
///
/// Either standard ASCII space (U+0020) or the full-width space character (U+3000) used by the Japanese.
@ -99,9 +109,70 @@ abstract class WalletKeysViewModelBase with Store {
void _populateKeysItems() {
items.clear();
if (_wallet.type == WalletType.monero) {
final keys = monero!.getKeys(_wallet);
Map<String, String>? keys;
switch (_wallet.type) {
case WalletType.monero:
keys = monero!.getKeys(_wallet);
break;
case WalletType.haven:
keys = haven!.getKeys(_wallet);
break;
case WalletType.wownero:
keys = wownero!.getKeys(_wallet);
break;
case WalletType.zano:
keys = zano!.getKeys(_wallet);
break;
case WalletType.ethereum:
case WalletType.polygon:
case WalletType.solana:
case WalletType.tron:
items.addAll([
if (_wallet.privateKey != null)
StandartListItem(
key: ValueKey('${_walletName}_wallet_private_key_item_key'),
title: S.current.private_key,
value: _wallet.privateKey!,
),
]);
break;
case WalletType.nano:
case WalletType.banano:
// we always have the hex version of the seed and private key:
items.addAll([
if (_wallet.hexSeed != null)
StandartListItem(
key: ValueKey('${_walletName}_wallet_hex_seed_key'),
title: S.current.seed_hex_form,
value: _wallet.hexSeed!,
),
if (_wallet.privateKey != null)
StandartListItem(
key: ValueKey('${_walletName}_wallet_private_key_item_key'),
title: S.current.private_key,
value: _wallet.privateKey!,
),
]);
break;
case WalletType.bitcoin:
case WalletType.litecoin:
case WalletType.bitcoinCash:
case WalletType.none:
// final keys = bitcoin!.getWalletKeys(_appStore.wallet!);
//
// items.addAll([
// if (keys['wif'] != null)
// StandartListItem(title: "WIF", value: keys['wif']!),
// if (keys['privateKey'] != null)
// StandartListItem(title: S.current.private_key, value: keys['privateKey']!),
// if (keys['publicKey'] != null)
// StandartListItem(title: S.current.public_key, value: keys['publicKey']!),
// ]);
break;
}
if (keys != null) {
items.addAll([
if (keys['primaryAddress'] != null)
StandartListItem(
@ -134,132 +205,6 @@ abstract class WalletKeysViewModelBase with Store {
),
]);
}
if (_wallet.type == WalletType.haven) {
final keys = haven!.getKeys(_wallet);
items.addAll([
if (keys['primaryAddress'] != null)
StandartListItem(
key: ValueKey('${_walletName}_wallet_primary_address_item_key'),
title: S.current.primary_address,
value: keys['primaryAddress']!),
if (keys['publicSpendKey'] != null)
StandartListItem(
key: ValueKey('${_walletName}_wallet_public_spend_key_item_key'),
title: S.current.spend_key_public,
value: keys['publicSpendKey']!,
),
if (keys['privateSpendKey'] != null)
StandartListItem(
key: ValueKey('${_walletName}_wallet_private_spend_key_item_key'),
title: S.current.spend_key_private,
value: keys['privateSpendKey']!,
),
if (keys['publicViewKey'] != null)
StandartListItem(
key: ValueKey('${_walletName}_wallet_public_view_key_item_key'),
title: S.current.view_key_public,
value: keys['publicViewKey']!,
),
if (keys['privateViewKey'] != null)
StandartListItem(
key: ValueKey('${_walletName}_wallet_private_view_key_item_key'),
title: S.current.view_key_private,
value: keys['privateViewKey']!,
),
]);
}
if (_wallet.type == WalletType.wownero) {
final keys = wownero!.getKeys(_wallet);
items.addAll([
if (keys['primaryAddress'] != null)
StandartListItem(
key: ValueKey('${_walletName}_wallet_primary_address_item_key'),
title: S.current.primary_address,
value: keys['primaryAddress']!),
if (keys['publicSpendKey'] != null)
StandartListItem(
key: ValueKey('${_walletName}_wallet_public_spend_key_item_key'),
title: S.current.spend_key_public,
value: keys['publicSpendKey']!,
),
if (keys['privateSpendKey'] != null)
StandartListItem(
key: ValueKey('${_walletName}_wallet_private_spend_key_item_key'),
title: S.current.spend_key_private,
value: keys['privateSpendKey']!,
),
if (keys['publicViewKey'] != null)
StandartListItem(
key: ValueKey('${_walletName}_wallet_public_view_key_item_key'),
title: S.current.view_key_public,
value: keys['publicViewKey']!,
),
if (keys['privateViewKey'] != null)
StandartListItem(
key: ValueKey('${_walletName}_wallet_private_view_key_item_key'),
title: S.current.view_key_private,
value: keys['privateViewKey']!,
),
]);
}
// if (_wallet.type == WalletType.bitcoin ||
// _wallet.type == WalletType.litecoin ||
// _wallet.type == WalletType.bitcoinCash) {
// final keys = bitcoin!.getWalletKeys(_appStore.wallet!);
//
// items.addAll([
// if (keys['wif'] != null)
// StandartListItem(title: "WIF", value: keys['wif']!),
// if (keys['privateKey'] != null)
// StandartListItem(title: S.current.private_key, value: keys['privateKey']!),
// if (keys['publicKey'] != null)
// StandartListItem(title: S.current.public_key, value: keys['publicKey']!),
// ]);
// }
if (isEVMCompatibleChain(_wallet.type) ||
_wallet.type == WalletType.solana ||
_wallet.type == WalletType.tron) {
items.addAll([
if (_wallet.privateKey != null)
StandartListItem(
key: ValueKey('${_walletName}_wallet_private_key_item_key'),
title: S.current.private_key,
value: _wallet.privateKey!,
),
]);
}
bool nanoBased = _wallet.type == WalletType.nano || _wallet.type == WalletType.banano;
if (nanoBased) {
// we always have the hex version of the seed and private key:
items.addAll([
if (_wallet.hexSeed != null)
StandartListItem(
key: ValueKey('${_walletName}_wallet_hex_seed_key'),
title: S.current.seed_hex_form,
value: _wallet.hexSeed!,
),
if (_wallet.privateKey != null)
StandartListItem(
key: ValueKey('${_walletName}_wallet_private_key_item_key'),
title: S.current.private_key,
value: _wallet.privateKey!,
),
]);
}
if (_appStore.wallet!.type == WalletType.zano) {
items.addAll([
StandartListItem(title: S.current.wallet_seed, value: _appStore.wallet!.seed!),
]);
}
}
Future<int?> _currentHeight() async {
@ -309,6 +254,12 @@ abstract class WalletKeysViewModelBase with Store {
}
Future<String?> get restoreHeight async {
if (_wallet.type == WalletType.monero) {
return monero!.getRestoreHeight(_wallet)?.toString();
}
if (_wallet.type == WalletType.wownero) {
return wownero!.getRestoreHeight(_wallet)?.toString();
}
if (_restoreHeightByTransactions != 0)
return getRoundedRestoreHeight(_restoreHeightByTransactions);
if (_restoreHeight != 0) return _restoreHeight.toString();

View file

@ -100,6 +100,7 @@ abstract class WalletNewVMBase extends WalletCreationVM with Store {
name: name,
language: options!.first as String,
password: walletPassword,
passphrase: passphrase,
isPolyseed: options.last as bool);
case WalletType.bitcoin:
case WalletType.litecoin:
@ -168,6 +169,7 @@ abstract class WalletNewVMBase extends WalletCreationVM with Store {
language: options!.first as String,
isPolyseed: options.last as bool,
password: walletPassword,
passphrase: passphrase,
);
case WalletType.zano:
return zano!.createZanoNewWalletCredentials(

View file

@ -233,9 +233,10 @@ class CWWownero extends Wownero {
{required String name,
required String language,
required bool isPolyseed,
String? password}) =>
String? password,
String? passphrase}) =>
WowneroNewWalletCredentials(
name: name, password: password, language: language, isPolyseed: isPolyseed);
name: name, password: password, language: language, isPolyseed: isPolyseed, passphrase: passphrase);
@override
Map<String, String> getKeys(Object wallet) {
@ -250,6 +251,12 @@ class CWWownero extends Wownero {
};
}
@override
int? getRestoreHeight(Object wallet) {
final wowneroWallet = wallet as WowneroWallet;
return wowneroWallet.restoreHeight;
}
@override
Object createWowneroTransactionCreationCredentials(
{required List<Output> outputs, required TransactionPriority priority}) =>

View file

@ -57,17 +57,17 @@ class CWZano extends Zano {
return ZanoNewWalletCredentials(name: name, password: password);
}
// @override
// Map<String, String> getKeys(Object wallet) {
// final zanoWallet = wallet as ZanoWallet;
// final keys = zanoWallet.keys;
// return <String, String>{
// 'privateSpendKey': keys.privateSpendKey,
// 'privateViewKey': keys.privateViewKey,
// 'publicSpendKey': keys.publicSpendKey,
// 'publicViewKey': keys.publicViewKey
// };
// }
@override
Map<String, String> getKeys(Object wallet) {
final zanoWallet = wallet as ZanoWallet;
final keys = zanoWallet.keys;
return <String, String>{
'privateSpendKey': keys.privateSpendKey,
'privateViewKey': keys.privateViewKey,
'publicSpendKey': keys.publicSpendKey,
'publicViewKey': keys.publicViewKey
};
}
@override
Object createZanoTransactionCredentials({required List<Output> outputs, required TransactionPriority priority, required CryptoCurrency currency}) {

View file

@ -17,7 +17,7 @@ dependencies:
fast_scanner:
git:
url: https://github.com/MrCyjaneK/fast_scanner
ref: c5a08720216a508bf1fe3d062ad19d2836545a42
ref: 69b3276b090fa6ac01b4483ca3adca93a8e615be
http: ^1.1.0
path_provider: ^2.0.11
mobx: ^2.1.4

View file

@ -16,14 +16,14 @@ APP_ANDROID_TYPE=$1
MONERO_COM_NAME="Monero.com"
MONERO_COM_VERSION="1.20.0"
MONERO_COM_BUILD_NUMBER=111
MONERO_COM_BUILD_NUMBER=113
MONERO_COM_BUNDLE_ID="com.monero.app"
MONERO_COM_PACKAGE="com.monero.app"
MONERO_COM_SCHEME="monero.com"
CAKEWALLET_NAME="Cake Wallet"
CAKEWALLET_VERSION="4.23.0"
CAKEWALLET_BUILD_NUMBER=244
CAKEWALLET_BUILD_NUMBER=246
CAKEWALLET_BUNDLE_ID="com.cakewallet.cake_wallet"
CAKEWALLET_PACKAGE="com.cakewallet.cake_wallet"
CAKEWALLET_SCHEME="cakewallet"

View file

@ -13,13 +13,13 @@ TYPES=($MONERO_COM $CAKEWALLET $HAVEN)
APP_IOS_TYPE=$1
MONERO_COM_NAME="Monero.com"
MONERO_COM_VERSION="1.20.0"
MONERO_COM_BUILD_NUMBER=108
MONERO_COM_VERSION="1.20.1"
MONERO_COM_BUILD_NUMBER=111
MONERO_COM_BUNDLE_ID="com.cakewallet.monero"
CAKEWALLET_NAME="Cake Wallet"
CAKEWALLET_VERSION="4.23.0"
CAKEWALLET_BUILD_NUMBER=291
CAKEWALLET_VERSION="4.23.1"
CAKEWALLET_BUILD_NUMBER=295
CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet"
HAVEN_NAME="Haven"

View file

@ -18,12 +18,21 @@ cd "$(dirname "$0")"
for COIN in monero wownero zano;
do
pushd ../monero_c
if [[ -f "release/${COIN}/aarch64-apple-ios_libwallet2_api_c.dylib" ]];
then
echo "file exist, not building monero_c for ${COIN}/aarch64-apple-ios.";
else
./build_single.sh ${COIN} aarch64-apple-ios -j$MAKE_JOB_COUNT
unxz -f ../monero_c/release/${COIN}/aarch64-apple-ios_libwallet2_api_c.dylib.xz
fi
for platform in aarch64-apple-ios{,simulator};
do
if [[ -f "release/${COIN}/${platform}_libwallet2_api_c.dylib" ]];
then
echo "file exist, not building monero_c for ${COIN}/${platform}";
else
./build_single.sh ${COIN} ${platform} -j$MAKE_JOB_COUNT
fi
popd
done
unxz -fk ../monero_c/release/monero/aarch64-apple-ios_libwallet2_api_c.dylib.xz
unxz -fk ../monero_c/release/wownero/aarch64-apple-ios_libwallet2_api_c.dylib.xz
unxz -fk ../monero_c/release/zano/aarch64-apple-ios_libwallet2_api_c.dylib.xz
unxz -fk ../monero_c/release/monero/aarch64-apple-iossimulator_libwallet2_api_c.dylib.xz
unxz -fk ../monero_c/release/wownero/aarch64-apple-iossimulator_libwallet2_api_c.dylib.xz
unxz -fk ../monero_c/release/zano/aarch64-apple-iossimulator_libwallet2_api_c.dylib.xz

View file

@ -14,7 +14,7 @@ git clone https://github.com/ltcmweb/mwebd
cd mwebd
git reset --hard 555349415f76a42ec5c76152b64c4ab9aabc448f
gomobile bind -target=ios .
mv -fn ./Mwebd.xcframework ../../../ios/
mv -fn ./Mwebd.xcframework ../../../cw_mweb/ios/
# cleanup:
cd ..
rm -rf mwebd

View file

@ -1,47 +1,159 @@
#!/bin/sh
# Assume we are in scripts/ios
set -e
IOS_DIR="$(pwd)/../../ios"
DYLIB_NAME="monero_libwallet2_api_c.dylib"
DYLIB_LINK_PATH="${IOS_DIR}/${DYLIB_NAME}"
FRWK_DIR="${IOS_DIR}/MoneroWallet.framework"
DYLIB_PATH="$(pwd)/../../scripts/monero_c/release"
TMP_DIR="${IOS_DIR}/tmp"
if [ ! -f $DYLIB_LINK_PATH ]; then
echo "Dylib is not found by the link: ${DYLIB_LINK_PATH}"
exit 0
fi
rm -rf "${IOS_DIR:?}/MoneroWallet.xcframework" "${IOS_DIR:?}/WowneroWallet.xcframework" "${IOS_DIR:?}/ZanoWallet.xcframework"
rm -rf "${IOS_DIR:?}/MoneroWallet.framework" "${IOS_DIR:?}/WowneroWallet.framework" "${IOS_DIR:?}/ZanoWallet.framework"
rm -rf "$TMP_DIR"
mkdir -p "$TMP_DIR"
cd $FRWK_DIR # go to iOS framework dir
lipo -create $DYLIB_LINK_PATH -output MoneroWallet
write_info_plist() {
framework_bundle="$1"
framework_name="$2"
target="$3"
plist_path="${framework_bundle}/Info.plist"
echo "Generated ${FRWK_DIR}"
# also generate for wownero
IOS_DIR="$(pwd)/../../ios"
DYLIB_NAME="wownero_libwallet2_api_c.dylib"
DYLIB_LINK_PATH="${IOS_DIR}/${DYLIB_NAME}"
FRWK_DIR="${IOS_DIR}/WowneroWallet.framework"
if [[ "x$target" = "xiossimulator" ]]; then
platform="iPhoneSimulator"
dtplatformname="iphonesimulator"
dtsdkname="iphonesimulator17.4"
else
platform="iPhoneOS"
dtplatformname="iphoneos"
dtsdkname="iphoneos17.4"
fi
if [ ! -f $DYLIB_LINK_PATH ]; then
echo "Dylib is not found by the link: ${DYLIB_LINK_PATH}"
exit 0
fi
cat > "$plist_path" <<EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>BuildMachineOSBuild</key>
<string>23E224</string>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>${framework_name}</string>
<key>CFBundleIdentifier</key>
<string>com.fotolockr.${framework_name}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${framework_name}</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>???</string>
<key>CFBundleSupportedPlatforms</key>
<array>
<string>${platform}</string>
</array>
<key>CFBundleVersion</key>
<string>1</string>
<key>DTCompiler</key>
<string>com.apple.compilers.llvm.clang.1_0</string>
<key>DTPlatformBuild</key>
<string>21E210</string>
<key>DTPlatformName</key>
<string>${dtplatformname}</string>
<key>DTPlatformVersion</key>
<string>17.4</string>
<key>DTSDKBuild</key>
<string>21E210</string>
<key>DTSDKName</key>
<string>${dtsdkname}</string>
<key>DTXcode</key>
<string>1530</string>
<key>DTXcodeBuild</key>
<string>15E204a</string>
<key>MinimumOSVersion</key>
<string>16.0</string>
<key>UIDeviceFamily</key>
<array>
<integer>1</integer>
<integer>2</integer>
</array>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>arm64</string>
</array>
</dict>
</plist>
EOF
plutil -convert binary1 "$plist_path"
}
cd $FRWK_DIR # go to iOS framework dir
lipo -create $DYLIB_LINK_PATH -output WowneroWallet
create_framework() {
wallet="$1"
framework_name="$2"
target="$3"
out_dir="$4"
echo "Generated ${FRWK_DIR}"
echo "Creating ${framework_name}.framework for target ${target} in ${out_dir}..."
# also generate for zano
IOS_DIR="$(pwd)/../../ios"
DYLIB_NAME="zano_libwallet2_api_c.dylib"
DYLIB_LINK_PATH="${IOS_DIR}/${DYLIB_NAME}"
FRWK_DIR="${IOS_DIR}/ZanoWallet.framework"
framework_bundle="${out_dir}/${framework_name}.framework"
rm -rf "$framework_bundle"
mkdir -p "$framework_bundle"
if [ ! -f $DYLIB_LINK_PATH ]; then
echo "Dylib is not found by the link: ${DYLIB_LINK_PATH}"
exit 0
fi
input_dylib="${DYLIB_PATH}/${wallet}/aarch64-apple-${target}_libwallet2_api_c.dylib"
if [[ ! -f "$input_dylib" ]]; then
echo "Error: Input dylib not found: $input_dylib"
exit 1
fi
cd $FRWK_DIR # go to iOS framework dir
lipo -create $DYLIB_LINK_PATH -output ZanoWallet
lipo -create "$input_dylib" -output "${framework_bundle}/${framework_name}"
echo "Created binary: ${framework_bundle}/${framework_name}"
echo "Generated ${FRWK_DIR}"
write_info_plist "$framework_bundle" "$framework_name" "$target"
}
create_xcframework() {
framework_name="$1"
device_framework="$2"
simulator_framework="$3"
xcframework_output="$4"
echo "Creating ${xcframework_output} by bundling:"
echo " Device framework: ${device_framework}"
echo " Simulator framework: ${simulator_framework}"
xcodebuild -create-xcframework \
-framework "$device_framework" \
-framework "$simulator_framework" \
-output "$xcframework_output"
echo "Created XCFramework: ${xcframework_output}"
}
wallets=("monero" "wownero" "zano")
framework_names=("MoneroWallet" "WowneroWallet" "ZanoWallet")
for i in "${!wallets[@]}"; do
wallet="${wallets[$i]}"
framework_name="${framework_names[$i]}"
device_out="${TMP_DIR}/${framework_name}_device"
simulator_out="${TMP_DIR}/${framework_name}_simulator"
rm -rf "$device_out" "$simulator_out"
mkdir -p "$device_out" "$simulator_out"
create_framework "$wallet" "$framework_name" "ios" "$device_out"
create_framework "$wallet" "$framework_name" "iossimulator" "$simulator_out"
device_framework="${device_out}/${framework_name}.framework"
simulator_framework="${simulator_out}/${framework_name}.framework"
xcframework_output="${IOS_DIR}/${framework_name}.xcframework"
rm -rf "$xcframework_output"
create_xcframework "$framework_name" "$device_framework" "$simulator_framework" "$xcframework_output"
done
echo "All XCFrameworks created successfully."
rm -rf "$TMP_DIR"

View file

@ -15,7 +15,7 @@ fi
CAKEWALLET_NAME="Cake Wallet"
CAKEWALLET_VERSION="1.13.0"
CAKEWALLET_BUILD_NUMBER=44
CAKEWALLET_BUILD_NUMBER=46
if ! [[ " ${TYPES[*]} " =~ " ${APP_LINUX_TYPE} " ]]; then
echo "Wrong app type."

View file

@ -17,12 +17,12 @@ fi
MONERO_COM_NAME="Monero.com"
MONERO_COM_VERSION="1.10.0"
MONERO_COM_BUILD_NUMBER=41
MONERO_COM_BUILD_NUMBER=43
MONERO_COM_BUNDLE_ID="com.cakewallet.monero"
CAKEWALLET_NAME="Cake Wallet"
CAKEWALLET_VERSION="1.16.0"
CAKEWALLET_BUILD_NUMBER=102
CAKEWALLET_BUILD_NUMBER=104
CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet"
if ! [[ " ${TYPES[*]} " =~ " ${APP_MACOS_TYPE} " ]]; then

View file

@ -8,7 +8,7 @@ if [[ ! -d "monero_c/.git" ]];
then
git clone https://github.com/mrcyjanek/monero_c --branch master monero_c
cd monero_c
git checkout 9d619f1aaec9f0f7d9a15c31ee2bde4ff79e6442
git checkout 9301097ff504525070cc0cb915fe2f1bb0670345
git reset --hard
git submodule update --init --force --recursive
./apply_patches.sh monero

View file

@ -406,7 +406,7 @@ abstract class Monero {
required int height});
WalletCredentials createMoneroRestoreWalletFromSeedCredentials({required String name, required String password, required String passphrase, required int height, required String mnemonic});
WalletCredentials createMoneroRestoreWalletFromHardwareCredentials({required String name, required String password, required int height, required ledger.LedgerConnection ledgerConnection});
WalletCredentials createMoneroNewWalletCredentials({required String name, required String language, required bool isPolyseed, String? password});
WalletCredentials createMoneroNewWalletCredentials({required String name, required String language, required bool isPolyseed, required String? passphrase, String? password});
Map<String, String> getKeys(Object wallet);
int? getRestoreHeight(Object wallet);
Object createMoneroTransactionCreationCredentials({required List<Output> outputs, required TransactionPriority priority});
@ -595,7 +595,8 @@ abstract class Wownero {
required String language,
required int height});
WalletCredentials createWowneroRestoreWalletFromSeedCredentials({required String name, required String password, required String passphrase, required int height, required String mnemonic});
WalletCredentials createWowneroNewWalletCredentials({required String name, required String language, required bool isPolyseed, String? password});
WalletCredentials createWowneroNewWalletCredentials({required String name, required String language, required bool isPolyseed, String? password, String? passphrase});
int? getRestoreHeight(Object wallet);
Map<String, String> getKeys(Object wallet);
Object createWowneroTransactionCreationCredentials({required List<Output> outputs, required TransactionPriority priority});
Object createWowneroTransactionCreationCredentialsRaw({required List<OutputInfo> outputs, required TransactionPriority priority});
@ -1443,6 +1444,7 @@ abstract class Zano {
WalletCredentials createZanoRestoreWalletFromSeedCredentials({required String name, required String password, required String passphrase, required int height, required String mnemonic});
WalletCredentials createZanoNewWalletCredentials({required String name, required String? password});
Map<String, String> getKeys(Object wallet);
Object createZanoTransactionCredentials({required List<Output> outputs, required TransactionPriority priority, required CryptoCurrency currency});
double formatterIntAmountToDouble({required int amount, required CryptoCurrency currency, required bool forFee});
int formatterParseAmount({required String amount, required CryptoCurrency currency});

View file

@ -24,6 +24,7 @@ final List<String> triplets = [
// "x86_64-host-apple-darwin", // not available on CI (yet)
"aarch64-host-apple-darwin", // apple silicon macbooks (local builds)
"aarch64-apple-ios",
"aarch64-apple-iossimulator",
];
Future<void> main() async {

View file

@ -38,7 +38,7 @@ class SecretKey {
SecretKey('moralisApiKey', () => ''),
SecretKey('ankrApiKey', () => ''),
SecretKey('chainStackApiKey', () => ''),
SecretKey('quantexExchangeMarkup', () => ''),
SecretKey('swapTradeExchangeMarkup', () => ''),
SecretKey('seeds', () => ''),
SecretKey('testCakePayApiKey', () => ''),
SecretKey('cakePayApiKey', () => ''),