New versions (#1312)

* New versions
Fix issues with Monero.com

* Add sending for Solana tokens exchanges

* Add default keyword for P2WPKH [skip ci]

* chore: Switch solana commitment to confirmed to reduced blockhash expiration (#1313)

* Modify test workflow to send arm64-v8a build only

* Fix workflow build path

* Remove unnecessary reverse of txId

* Show case sensitive evm wallet address

* Revert default Cake Theme
add custom package id for test builds

* Fix workflow script

* Fix workflow

* hash branch name

* hash branch name

* Update versions

* Add user image to Nostr
Add fetching address from text for tokens

* Fix test app package id

* fix: Solana message improvement (#1316)

---------

Co-authored-by: Adegoke David <64401859+Blazebrain@users.noreply.github.com>
This commit is contained in:
Omar Hatem 2024-03-04 19:32:10 +02:00 committed by GitHub
parent 10fd32fb2e
commit c7deeaea9b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
28 changed files with 186 additions and 138 deletions

View file

@ -104,17 +104,7 @@ jobs:
- name: Build generated code
run: |
cd /opt/android/cake_wallet
cd cw_core && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..
cd cw_evm && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..
cd cw_monero && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..
cd cw_bitcoin && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..
cd cw_haven && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..
cd cw_bitcoin_cash && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..
cd cw_nano && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..
cd cw_solana && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..
cd cw_ethereum && flutter pub get && cd ..
cd cw_polygon && flutter pub get && cd ..
flutter packages pub run build_runner build --delete-conflicting-outputs
./model_generator.sh
- name: Add secrets
run: |
@ -159,12 +149,16 @@ jobs:
echo "const ankrApiKey = '${{ secrets.ANKR_API_KEY }}';" >> cw_solana/lib/.secrets.g.dart
- name: Rename app
run: echo -e "id=com.cakewallet.test\nname=${{ env.BRANCH_NAME }}" > /opt/android/cake_wallet/android/app.properties
run: |
hash=`sha512sum <<<"${{ env.BRANCH_NAME }}"`
substring=${hash:0:15}
echo substring
echo -e "id=com.cakewallet.test_$(substring)\nname=${{ env.BRANCH_NAME }}" > /opt/android/cake_wallet/android/app.properties
- name: Build
run: |
cd /opt/android/cake_wallet
flutter build apk --release
flutter build apk --release --split-per-abi
# - name: Push to App Center
# run: |
@ -181,21 +175,21 @@ jobs:
- name: Rename apk file
run: |
cd /opt/android/cake_wallet/build/app/outputs/apk/release
cd /opt/android/cake_wallet/build/app/outputs/flutter-apk
mkdir test-apk
cp app-release.apk test-apk/${{env.BRANCH_NAME}}.apk
cp app-arm64-v8a-release.apk test-apk/${{env.BRANCH_NAME}}.apk
- name: Upload Artifact
uses: kittaakos/upload-artifact-as-is@v0
with:
path: /opt/android/cake_wallet/build/app/outputs/apk/release/test-apk/
path: /opt/android/cake_wallet/build/app/outputs/flutter-apk/test-apk/
- name: Send Test APK
continue-on-error: true
uses: adrey/slack-file-upload-action@1.0.5
with:
token: ${{ secrets.SLACK_APP_TOKEN }}
path: /opt/android/cake_wallet/build/app/outputs/apk/release/app-release.apk
path: /opt/android/cake_wallet/build/app/outputs/flutter-apk/test-apk/${{env.BRANCH_NAME}}.apk
channel: ${{ secrets.SLACK_APK_CHANNEL }}
title: "${{ env.BRANCH_NAME }}.apk"
filename: ${{ env.BRANCH_NAME }}.apk

View file

@ -1,3 +1,2 @@
Improve wallet recovery and error tolerance
Enhance Background sync for Monero wallets
Bug fixes
New themes
Bug fixes and enhancements

View file

@ -1,3 +1,6 @@
Add Solana wallet
Support ALL Bitcoin address types (Legacy, Segwit (both variants), Taproot)
Enhance Sending/Receiving flow for Bitcoin
Improve fee calculations in Bitcoin
New themes
Bug fixes and enhancements

View file

@ -2,7 +2,7 @@ import 'package:bitcoin_base/bitcoin_base.dart';
import 'package:cw_core/receive_page_option.dart';
class BitcoinReceivePageOption implements ReceivePageOption {
static const p2wpkh = BitcoinReceivePageOption._('Segwit (P2WPKH)');
static const p2wpkh = BitcoinReceivePageOption._('Segwit (P2WPKH) (Default)');
static const p2sh = BitcoinReceivePageOption._('Segwit-Compatible (P2SH)');
static const p2tr = BitcoinReceivePageOption._('Taproot (P2TR)');
static const p2wsh = BitcoinReceivePageOption._('Segwit (P2WSH)');
@ -18,9 +18,9 @@ class BitcoinReceivePageOption implements ReceivePageOption {
static const all = [
BitcoinReceivePageOption.p2wpkh,
BitcoinReceivePageOption.p2sh,
BitcoinReceivePageOption.p2tr,
BitcoinReceivePageOption.p2wsh,
BitcoinReceivePageOption.p2sh,
BitcoinReceivePageOption.p2pkh
];

View file

@ -35,7 +35,6 @@ import 'package:cw_core/utils/file.dart';
import 'package:cw_core/wallet_base.dart';
import 'package:cw_core/wallet_info.dart';
import 'package:flutter/foundation.dart';
import 'package:hex/hex.dart';
import 'package:hive/hive.dart';
import 'package:mobx/mobx.dart';
import 'package:rxdart/subjects.dart';
@ -623,16 +622,9 @@ abstract class ElectrumWalletBase
final ins = <bitcoin_base.BtcTransaction>[];
for (final vin in original.inputs) {
try {
final id = HEX.encode(HEX.decode(vin.txId).reversed.toList());
final txHex = await electrumClient.getTransactionHex(hash: id);
final txHex = await electrumClient.getTransactionHex(hash: vin.txId);
final tx = bitcoin_base.BtcTransaction.fromRaw(txHex);
ins.add(tx);
} catch (_) {
ins.add(bitcoin_base.BtcTransaction.fromRaw(
await electrumClient.getTransactionHex(hash: vin.txId),
));
}
}
return ElectrumTransactionBundle(original,

View file

@ -102,6 +102,7 @@ class CryptoCurrency extends EnumerableItem<int> with Serializable<int> implemen
CryptoCurrency.usdcEPoly,
CryptoCurrency.kaspa,
CryptoCurrency.digibyte,
CryptoCurrency.usdtSol,
];
static const havenCurrencies = [
@ -246,7 +247,16 @@ class CryptoCurrency extends EnumerableItem<int> with Serializable<int> implemen
return CryptoCurrency._rawCurrencyMap[raw]!;
}
static CryptoCurrency fromString(String name) {
// TODO: refactor this
static CryptoCurrency fromString(String name, {CryptoCurrency? walletCurrency}) {
try {
return CryptoCurrency.all.firstWhere((element) =>
element.title.toLowerCase() == name &&
(element.tag == null ||
element.tag == walletCurrency?.title ||
element.tag == walletCurrency?.tag));
} catch (_) {}
if (CryptoCurrency._nameCurrencyMap[name.toLowerCase()] == null) {
final s = 'Unexpected token: $name for CryptoCurrency fromString';
throw ArgumentError.value(name, 'name', s);

View file

@ -146,7 +146,7 @@ abstract class EVMChainWalletBase
privateKey: _hexPrivateKey,
password: _password,
);
walletAddresses.address = _evmChainPrivateKey.address.toString();
walletAddresses.address = _evmChainPrivateKey.address.hexEip55;
await save();
}

View file

@ -263,7 +263,7 @@ class SolanaWalletClient {
required Ed25519HDKeyPair ownerKeypair,
List<String> references = const [],
}) async {
const commitment = Commitment.finalized;
const commitment = Commitment.confirmed;
final latestBlockhash =
await _client!.rpcClient.getLatestBlockhash(commitment: commitment).value;
@ -394,9 +394,7 @@ class SolanaWalletClient {
funder: ownerKeypair,
);
} catch (e) {
throw Exception(
'Error while creating an associated token account for the recipient: ${e.toString()}',
);
throw Exception('Insufficient lamports balance to complete this transaction');
}
// Input by the user
@ -468,7 +466,10 @@ class SolanaWalletClient {
required SignedTx signedTransaction,
required Commitment commitment,
}) async {
final signature = await _client!.rpcClient.sendTransaction(signedTransaction.encode());
final signature = await _client!.rpcClient.sendTransaction(
signedTransaction.encode(),
preflightCommitment: commitment,
);
_client!.waitForSignatureStatus(signature, status: commitment);

View file

@ -1,5 +1,5 @@
# Uncomment this line to define a global platform for your project
platform :ios, '11.0'
platform :ios, '12.0'
source 'https://github.com/CocoaPods/Specs.git'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
@ -44,7 +44,7 @@ post_install do |installer|
flutter_additional_ios_build_settings(target)
target.build_configurations.each do |config|
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '11.0'
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '12.0'
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
'$(inherited)',

View file

@ -7,7 +7,7 @@ PODS:
- connectivity_plus (0.0.1):
- Flutter
- ReachabilitySwift
- CryptoSwift (1.7.1)
- CryptoSwift (1.8.1)
- cw_haven (0.0.1):
- cw_haven/Boost (= 0.0.1)
- cw_haven/Haven (= 0.0.1)
@ -132,9 +132,9 @@ PODS:
- permission_handler_apple (9.1.1):
- Flutter
- ReachabilitySwift (5.0.0)
- SDWebImage (5.16.0):
- SDWebImage/Core (= 5.16.0)
- SDWebImage/Core (5.16.0)
- SDWebImage (5.18.11):
- SDWebImage/Core (= 5.18.11)
- SDWebImage/Core (5.18.11)
- sensitive_clipboard (0.0.1):
- Flutter
- share_plus (0.0.1):
@ -142,9 +142,9 @@ PODS:
- shared_preferences_foundation (0.0.1):
- Flutter
- FlutterMacOS
- SwiftProtobuf (1.22.0)
- SwiftProtobuf (1.25.2)
- SwiftyGif (5.4.4)
- Toast (4.0.0)
- Toast (4.1.0)
- uni_links (0.0.1):
- Flutter
- UnstoppableDomainsResolution (4.0.0):
@ -262,8 +262,8 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS:
barcode_scan2: 0af2bb63c81b4565aab6cd78278e4c0fa136dbb0
BigInt: f668a80089607f521586bbe29513d708491ef2f7
connectivity_plus: 413a8857dd5d9f1c399a39130850d02fe0feaf7e
CryptoSwift: d3d18dc357932f7e6d580689e065cf1f176007c1
connectivity_plus: bf0076dd84a130856aa636df1c71ccaff908fa1d
CryptoSwift: b9c701d6f5011df23794dbf7f2e480a77835d83d
cw_haven: b3e54e1fbe7b8e6fda57a93206bc38f8e89b898a
cw_monero: 4cf3b96f2da8e95e2ef7d6703dd4d2c509127b7d
cw_shared_external: 2972d872b8917603478117c9957dfca611845a92
@ -287,19 +287,19 @@ SPEC CHECKSUMS:
path_provider_foundation: 3784922295ac71e43754bd15e0653ccfd36a147c
permission_handler_apple: e76247795d700c14ea09e3a2d8855d41ee80a2e6
ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825
SDWebImage: 2aea163b50bfcb569a2726b6a754c54a4506fcf6
SDWebImage: a3ba0b8faac7228c3c8eadd1a55c9c9fe5e16457
sensitive_clipboard: d4866e5d176581536c27bb1618642ee83adca986
share_plus: 056a1e8ac890df3e33cb503afffaf1e9b4fbae68
shared_preferences_foundation: b4c3b4cddf1c21f02770737f147a3f5da9d39695
SwiftProtobuf: 40bd808372cb8706108f22d28f8ab4a6b9bc6989
SwiftProtobuf: 407a385e97fd206c4fbe880cc84123989167e0d1
SwiftyGif: 93a1cc87bf3a51916001cf8f3d63835fb64c819f
Toast: 91b396c56ee72a5790816f40d3a94dd357abc196
Toast: ec33c32b8688982cecc6348adeae667c1b9938da
uni_links: d97da20c7701486ba192624d99bffaaffcfc298a
UnstoppableDomainsResolution: c3c67f4d0a5e2437cb00d4bd50c2e00d6e743841
url_launcher_ios: bbd758c6e7f9fd7b5b1d4cde34d2b95fcce5e812
wakelock_plus: 8b09852c8876491e4b6d179e17dfe2a0b5f60d47
workmanager: 0afdcf5628bbde6924c21af7836fed07b42e30e6
PODFILE CHECKSUM: 09df1114e7c360f55770d35a79356bf5446e0100
PODFILE CHECKSUM: fcb1b8418441a35b438585c9dd8374e722e6c6ca
COCOAPODS: 1.12.1

View file

@ -377,7 +377,7 @@
"$(PROJECT_DIR)/Flutter",
);
INFOPLIST_FILE = Runner/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
@ -523,7 +523,7 @@
"$(PROJECT_DIR)/Flutter",
);
INFOPLIST_FILE = Runner/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
@ -561,7 +561,7 @@
"$(PROJECT_DIR)/Flutter",
);
INFOPLIST_FILE = Runner/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
@ -607,9 +607,4 @@
/* End XCConfigurationList section */
};
rootObject = 97C146E61CF9000F007C117D /* Project object */;
SystemCapabilities = {
com.apple.BackgroundModes = {
enabled = 1;
};
};
}

View file

@ -181,11 +181,28 @@ class CWBitcoin extends Bitcoin {
}
@override
BitcoinReceivePageOption getSelectedAddressType(Object wallet) {
ReceivePageOption getSelectedAddressType(Object wallet) {
final bitcoinWallet = wallet as ElectrumWallet;
return BitcoinReceivePageOption.fromType(bitcoinWallet.walletAddresses.addressPageType);
}
@override
List<BitcoinReceivePageOption> getBitcoinReceivePageOptions() => BitcoinReceivePageOption.all;
List<ReceivePageOption> getBitcoinReceivePageOptions() => BitcoinReceivePageOption.all;
@override
BitcoinAddressType getBitcoinAddressType(ReceivePageOption option) {
switch (option) {
case BitcoinReceivePageOption.p2pkh:
return P2pkhAddressType.p2pkh;
case BitcoinReceivePageOption.p2sh:
return P2shAddressType.p2wpkhInP2sh;
case BitcoinReceivePageOption.p2tr:
return SegwitAddresType.p2tr;
case BitcoinReceivePageOption.p2wsh:
return SegwitAddresType.p2wsh;
case BitcoinReceivePageOption.p2wpkh:
default:
return SegwitAddresType.p2wpkh;
}
}
}

View file

@ -295,6 +295,16 @@ class AddressValidator extends TextValidator {
case CryptoCurrency.sol:
return '([^0-9a-zA-Z]|^)[1-9A-HJ-NP-Za-km-z]{43,44}([^0-9a-zA-Z]|\$)';
default:
if (type.tag == CryptoCurrency.eth.title) {
return '0x[0-9a-zA-Z]{42}';
}
if (type.tag == CryptoCurrency.maticpoly.tag) {
return '0x[0-9a-zA-Z]{42}';
}
if (type.tag == CryptoCurrency.sol.title) {
return '([^0-9a-zA-Z]|^)[1-9A-HJ-NP-Za-km-z]{43,44}([^0-9a-zA-Z]|\$)';
}
return null;
}
}

View file

@ -51,7 +51,8 @@ class AddressResolver {
}
final match = RegExp(addressPattern).firstMatch(raw);
return match?.group(0)?.replaceAllMapped(RegExp('[^0-9a-zA-Z]|bitcoincash:|nano_'), (Match match) {
return match?.group(0)?.replaceAllMapped(RegExp('[^0-9a-zA-Z]|bitcoincash:|nano_'),
(Match match) {
String group = match.group(0)!;
if (group.startsWith('bitcoincash:') || group.startsWith('nano_')) {
return group;
@ -68,7 +69,7 @@ class AddressResolver {
return emailRegex.hasMatch(address);
}
// TODO: refactor this to take Crypto currency instead of ticker, or at least pass in the tag as well
Future<ParsedAddress> resolve(BuildContext context, String text, String ticker) async {
try {
if (text.startsWith('@') && !text.substring(1).contains('@')) {
@ -76,7 +77,8 @@ class AddressResolver {
final formattedName = text.substring(1);
final twitterUser = await TwitterApi.lookupUserByName(userName: formattedName);
final addressFromBio = extractAddressByType(
raw: twitterUser.description, type: CryptoCurrency.fromString(ticker));
raw: twitterUser.description,
type: CryptoCurrency.fromString(ticker, walletCurrency: wallet.currency));
if (addressFromBio != null) {
return ParsedAddress.fetchTwitterAddress(
address: addressFromBio,
@ -87,8 +89,9 @@ class AddressResolver {
final pinnedTweet = twitterUser.pinnedTweet?.text;
if (pinnedTweet != null) {
final addressFromPinnedTweet =
extractAddressByType(raw: pinnedTweet, type: CryptoCurrency.fromString(ticker));
final addressFromPinnedTweet = extractAddressByType(
raw: pinnedTweet,
type: CryptoCurrency.fromString(ticker, walletCurrency: wallet.currency));
if (addressFromPinnedTweet != null) {
return ParsedAddress.fetchTwitterAddress(
address: addressFromPinnedTweet,
@ -111,8 +114,8 @@ class AddressResolver {
await MastodonAPI.lookupUserByUserName(userName: userName, apiHost: hostName);
if (mastodonUser != null) {
String? addressFromBio =
extractAddressByType(raw: mastodonUser.note, type: CryptoCurrency.fromString(ticker));
String? addressFromBio = extractAddressByType(
raw: mastodonUser.note, type: CryptoCurrency.fromString(ticker));
if (addressFromBio != null) {
return ParsedAddress.fetchMastodonAddress(
@ -201,7 +204,11 @@ class AddressResolver {
String? addressFromBio = extractAddressByType(
raw: nostrUserData.about, type: CryptoCurrency.fromString(ticker));
if (addressFromBio != null) {
return ParsedAddress.nostrAddress(address: addressFromBio, name: text);
return ParsedAddress.nostrAddress(
address: addressFromBio,
name: text,
profileImageUrl: nostrUserData.picture,
profileName: nostrUserData.name);
}
}
}

View file

@ -119,11 +119,17 @@ class ParsedAddress {
);
}
factory ParsedAddress.nostrAddress({required String address, required String name}) {
factory ParsedAddress.nostrAddress(
{required String address,
required String name,
required String profileImageUrl,
required String profileName}) {
return ParsedAddress(
addresses: [address],
name: name,
parseFrom: ParseFrom.nostr,
profileImageUrl: profileImageUrl,
profileName: profileName,
);
}

View file

@ -1,3 +1,4 @@
import 'package:cake_wallet/bitcoin/bitcoin.dart';
import 'package:cake_wallet/src/screens/new_wallet/widgets/select_button.dart';
import 'package:cake_wallet/themes/extensions/keyboard_theme.dart';
import 'package:cake_wallet/di.dart';
@ -6,7 +7,6 @@ import 'package:cake_wallet/src/screens/monero_accounts/monero_account_list_page
import 'package:cake_wallet/anonpay/anonpay_donation_link_info.dart';
import 'package:cake_wallet/entities/preferences_key.dart';
import 'package:cw_core/receive_page_option.dart';
import 'package:cw_bitcoin/bitcoin_receive_page_option.dart';
import 'package:cake_wallet/src/screens/dashboard/widgets/present_receive_option_picker.dart';
import 'package:cake_wallet/src/widgets/gradient_background.dart';
import 'package:cake_wallet/src/widgets/keyboard_done_button.dart';
@ -28,7 +28,6 @@ import 'package:keyboard_actions/keyboard_actions.dart';
import 'package:mobx/mobx.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:cake_wallet/themes/extensions/balance_page_theme.dart';
import 'package:bitcoin_base/bitcoin_base.dart';
class AddressPage extends BasePage {
AddressPage({
@ -230,22 +229,10 @@ class AddressPage extends BasePage {
);
}
break;
case BitcoinReceivePageOption.p2pkh:
addressListViewModel.setAddressType(P2pkhAddressType.p2pkh);
break;
case BitcoinReceivePageOption.p2sh:
addressListViewModel.setAddressType(P2shAddressType.p2wpkhInP2sh);
break;
case BitcoinReceivePageOption.p2wpkh:
addressListViewModel.setAddressType(SegwitAddresType.p2wpkh);
break;
case BitcoinReceivePageOption.p2tr:
addressListViewModel.setAddressType(SegwitAddresType.p2tr);
break;
case BitcoinReceivePageOption.p2wsh:
addressListViewModel.setAddressType(SegwitAddresType.p2wsh);
break;
default:
if (addressListViewModel.type == WalletType.bitcoin) {
addressListViewModel.setAddressType(bitcoin!.getBitcoinAddressType(option));
}
}
});

View file

@ -53,6 +53,8 @@ Future<String> extractAddressFromParsed(
title = S.of(context).address_detected;
content = S.of(context).extracted_address_content('${parsedAddress.name} (Nostr NIP-05)');
address = parsedAddress.addresses.first;
profileImageUrl = parsedAddress.profileImageUrl;
profileName = parsedAddress.profileName;
break;
case ParseFrom.yatRecord:
if (parsedAddress.name.isEmpty) {

View file

@ -1,4 +1,3 @@
import 'package:cake_wallet/src/screens/receive/widgets/header_tile.dart';
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'dart:ui';
import 'package:cake_wallet/src/widgets/section_divider.dart';

View file

@ -790,9 +790,16 @@ abstract class SettingsStoreBase with Store {
final exchangeStatus = ExchangeApiMode.deserialize(
raw: sharedPreferences.getInt(PreferencesKey.exchangeStatusKey) ??
ExchangeApiMode.enabled.raw);
final bool isNewInstall = sharedPreferences.getBool(PreferencesKey.isNewInstall) ?? true;
final int defaultTheme;
if (isNewInstall) {
defaultTheme = isMoneroOnly ? ThemeList.moneroDarkTheme.raw : ThemeList.brightTheme.raw;
} else {
defaultTheme = ThemeType.bright.index;
}
final savedTheme = initialTheme ??
ThemeList.deserialize(
raw: sharedPreferences.getInt(PreferencesKey.currentTheme) ?? (isMoneroOnly ? ThemeList.moneroDarkTheme.raw : ThemeList.cakeDarkTheme.raw));
raw: sharedPreferences.getInt(PreferencesKey.currentTheme) ?? defaultTheme);
final actionListDisplayMode = ObservableList<ActionListDisplayMode>();
actionListDisplayMode.addAll(deserializeActionlistDisplayModes(
sharedPreferences.getInt(PreferencesKey.displayActionListModeKey) ?? defaultActionsMode));
@ -1151,7 +1158,8 @@ abstract class SettingsStoreBase with Store {
raw: sharedPreferences.getInt(PreferencesKey.exchangeStatusKey) ??
ExchangeApiMode.enabled.raw);
currentTheme = ThemeList.deserialize(
raw: sharedPreferences.getInt(PreferencesKey.currentTheme) ?? (isMoneroOnly ? ThemeList.moneroDarkTheme.raw : ThemeList.cakeDarkTheme.raw));
raw: sharedPreferences.getInt(PreferencesKey.currentTheme) ??
(isMoneroOnly ? ThemeList.moneroDarkTheme.raw : ThemeList.brightTheme.raw));
actionlistDisplayMode = ObservableList<ActionListDisplayMode>();
actionlistDisplayMode.addAll(deserializeActionlistDisplayModes(
sharedPreferences.getInt(PreferencesKey.displayActionListModeKey) ?? defaultActionsMode));

View file

@ -32,7 +32,10 @@ class TwitterApi {
}
final Map<String, dynamic> responseJSON = jsonDecode(response.body) as Map<String, dynamic>;
if (responseJSON['errors'] != null) {
if (responseJSON['errors'] != null &&
!responseJSON['errors'][0]['detail']
.toString()
.contains("Could not find tweet with pinned_tweet_id")) {
throw Exception(responseJSON['errors'][0]['detail']);
}
@ -40,6 +43,7 @@ class TwitterApi {
}
static Tweet? _getPinnedTweet(Map<String, dynamic> responseJSON) {
try {
final tweetId = responseJSON['data']['pinned_tweet_id'] as String?;
if (tweetId == null || responseJSON['includes'] == null) return null;
@ -55,5 +59,8 @@ class TwitterApi {
(pinnedTweetData['note_tweet']?['text'] ?? pinnedTweetData['text']) as String;
return Tweet(id: tweetId, text: pinnedTweetText);
} catch (e) {
return null;
}
}
}

View file

@ -162,9 +162,14 @@ abstract class ExchangeTradeViewModelBase with Store {
wallet.currency == CryptoCurrency.maticpoly &&
tradesStore.trade!.from.tag == CryptoCurrency.maticpoly.tag;
bool _isSplToken() =>
wallet.currency == CryptoCurrency.sol &&
tradesStore.trade!.from.tag == CryptoCurrency.sol.title;
return tradesStore.trade!.from == wallet.currency ||
tradesStore.trade!.provider == ExchangeProviderDescription.xmrto ||
_isEthToken() ||
_isPolygonToken();
_isPolygonToken() ||
_isSplToken();
}
}

View file

@ -5,7 +5,7 @@
import FlutterMacOS
import Foundation
import connectivity_plus_macos
import connectivity_plus
import cw_monero
import device_info_plus
import devicelocale

View file

@ -1,5 +1,5 @@
PODS:
- connectivity_plus_macos (0.0.1):
- connectivity_plus (0.0.1):
- FlutterMacOS
- ReachabilitySwift
- cw_monero (0.0.1):
@ -51,7 +51,7 @@ PODS:
- FlutterMacOS
DEPENDENCIES:
- connectivity_plus_macos (from `Flutter/ephemeral/.symlinks/plugins/connectivity_plus_macos/macos`)
- connectivity_plus (from `Flutter/ephemeral/.symlinks/plugins/connectivity_plus/macos`)
- cw_monero (from `Flutter/ephemeral/.symlinks/plugins/cw_monero/macos`)
- device_info_plus (from `Flutter/ephemeral/.symlinks/plugins/device_info_plus/macos`)
- devicelocale (from `Flutter/ephemeral/.symlinks/plugins/devicelocale/macos`)
@ -73,8 +73,8 @@ SPEC REPOS:
- ReachabilitySwift
EXTERNAL SOURCES:
connectivity_plus_macos:
:path: Flutter/ephemeral/.symlinks/plugins/connectivity_plus_macos/macos
connectivity_plus:
:path: Flutter/ephemeral/.symlinks/plugins/connectivity_plus/macos
cw_monero:
:path: Flutter/ephemeral/.symlinks/plugins/cw_monero/macos
device_info_plus:
@ -105,8 +105,8 @@ EXTERNAL SOURCES:
:path: Flutter/ephemeral/.symlinks/plugins/wakelock_plus/macos
SPEC CHECKSUMS:
connectivity_plus_macos: f6e86fd000e971d361e54b5afcadc8c8fa773308
cw_monero: f8b7f104508efba2591548e76b5c058d05cba3f0
connectivity_plus: 18d3c32514c886e046de60e9c13895109866c747
cw_monero: ec03de55a19c4a2b174ea687e0f4202edc716fa4
device_info_plus: 5401765fde0b8d062a2f8eb65510fb17e77cf07f
devicelocale: 9f0f36ac651cabae2c33f32dcff4f32b61c38225
flutter_inappwebview_macos: 9600c9df9fdb346aaa8933812009f8d94304203d
@ -123,6 +123,6 @@ SPEC CHECKSUMS:
url_launcher_macos: d2691c7dd33ed713bf3544850a623080ec693d95
wakelock_plus: 4783562c9a43d209c458cb9b30692134af456269
PODFILE CHECKSUM: 5107934592df7813b33d744aebc8ddc6b5a5445f
PODFILE CHECKSUM: 65ec1541137fb5b35d00490dec1bb48d4d9586bb
COCOAPODS: 1.12.1

View file

@ -55,7 +55,7 @@ dependencies:
basic_utils: ^5.6.1
get_it: ^7.2.0
# connectivity: ^3.0.3
connectivity_plus: ^2.3.5
connectivity_plus: ^5.0.2
keyboard_actions: ^4.0.1
another_flushbar: ^1.12.29
archive: ^3.3.0
@ -107,6 +107,10 @@ dependencies:
polyseed: ^0.0.2
nostr_tools: ^1.0.9
solana: ^0.30.1
bitcoin_base:
git:
url: https://github.com/cake-tech/bitcoin_base.git
ref: cake-update-v1
dev_dependencies:
flutter_test:

View file

@ -15,15 +15,15 @@ TYPES=($MONERO_COM $CAKEWALLET $HAVEN)
APP_ANDROID_TYPE=$1
MONERO_COM_NAME="Monero.com"
MONERO_COM_VERSION="1.10.3"
MONERO_COM_BUILD_NUMBER=75
MONERO_COM_VERSION="1.11.0"
MONERO_COM_BUILD_NUMBER=77
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.14.0"
CAKEWALLET_BUILD_NUMBER=193
CAKEWALLET_BUILD_NUMBER=196
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.10.3"
MONERO_COM_BUILD_NUMBER=73
MONERO_COM_VERSION="1.11.0"
MONERO_COM_BUILD_NUMBER=75
MONERO_COM_BUNDLE_ID="com.cakewallet.monero"
CAKEWALLET_NAME="Cake Wallet"
CAKEWALLET_VERSION="4.14.0"
CAKEWALLET_BUILD_NUMBER=213
CAKEWALLET_BUILD_NUMBER=215
CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet"
HAVEN_NAME="Haven"

View file

@ -16,13 +16,13 @@ if [ -n "$1" ]; then
fi
MONERO_COM_NAME="Monero.com"
MONERO_COM_VERSION="1.0.3"
MONERO_COM_BUILD_NUMBER=5
MONERO_COM_VERSION="1.1.0"
MONERO_COM_BUILD_NUMBER=7
MONERO_COM_BUNDLE_ID="com.cakewallet.monero"
CAKEWALLET_NAME="Cake Wallet"
CAKEWALLET_VERSION="1.6.3"
CAKEWALLET_BUILD_NUMBER=53
CAKEWALLET_VERSION="1.7.0"
CAKEWALLET_BUILD_NUMBER=55
CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet"
if ! [[ " ${TYPES[*]} " =~ " ${APP_MACOS_TYPE} " ]]; then

View file

@ -61,6 +61,7 @@ Future<void> main(List<String> args) async {
Future<void> generateBitcoin(bool hasImplementation) async {
final outputFile = File(bitcoinOutputPath);
const bitcoinCommonHeaders = """
import 'package:cw_core/receive_page_option.dart';
import 'package:cw_core/unspent_transaction_output.dart';
import 'package:cw_core/wallet_credentials.dart';
import 'package:cw_core/wallet_info.dart';
@ -70,7 +71,8 @@ import 'package:cw_core/unspent_coins_info.dart';
import 'package:cw_core/wallet_service.dart';
import 'package:cake_wallet/view_model/send/output.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:hive/hive.dart';""";
import 'package:hive/hive.dart';
import 'package:bitcoin_base/bitcoin_base.dart';""";
const bitcoinCWHeaders = """
import 'package:cw_bitcoin/bitcoin_receive_page_option.dart';
import 'package:cw_bitcoin/electrum_wallet.dart';
@ -83,7 +85,6 @@ import 'package:cw_bitcoin/bitcoin_amount_format.dart';
import 'package:cw_bitcoin/bitcoin_address_record.dart';
import 'package:cw_bitcoin/bitcoin_transaction_credentials.dart';
import 'package:cw_bitcoin/litecoin_wallet_service.dart';
import 'package:bitcoin_base/bitcoin_base.dart';
import 'package:mobx/mobx.dart';
""";
const bitcoinCwPart = "part 'cw_bitcoin.dart';";
@ -143,8 +144,9 @@ abstract class Bitcoin {
TransactionPriority getLitecoinTransactionPrioritySlow();
Future<void> setAddressType(Object wallet, dynamic option);
BitcoinReceivePageOption getSelectedAddressType(Object wallet);
List<BitcoinReceivePageOption> getBitcoinReceivePageOptions();
ReceivePageOption getSelectedAddressType(Object wallet);
List<ReceivePageOption> getBitcoinReceivePageOptions();
BitcoinAddressType getBitcoinAddressType(ReceivePageOption option);
}
""";
@ -906,6 +908,7 @@ import 'package:cw_core/wallet_credentials.dart';
import 'package:cw_core/wallet_info.dart';
import 'package:cw_core/wallet_service.dart';
import 'package:hive/hive.dart';
import 'package:solana/solana.dart';
""";
const solanaCWHeaders = """
@ -916,7 +919,6 @@ import 'package:cw_solana/solana_wallet_service.dart';
import 'package:cw_solana/solana_transaction_info.dart';
import 'package:cw_solana/solana_transaction_credentials.dart';
import 'package:cw_solana/solana_wallet_creation_credentials.dart';
import 'package:solana/solana.dart';
""";
const solanaCwPart = "part 'cw_solana.dart';";
const solanaContent = """
@ -944,10 +946,10 @@ abstract class Solana {
List<OutputInfo> outputs, {
required CryptoCurrency currency,
});
List<SPLToken> getSPLTokenCurrencies(WalletBase wallet);
List<CryptoCurrency> getSPLTokenCurrencies(WalletBase wallet);
Future<void> addSPLToken(WalletBase wallet, CryptoCurrency token);
Future<void> deleteSPLToken(WalletBase wallet, CryptoCurrency token);
Future<SPLToken?> getSPLToken(WalletBase wallet, String contractAddress);
Future<CryptoCurrency?> getSPLToken(WalletBase wallet, String contractAddress);
CryptoCurrency assetOfTransaction(WalletBase wallet, TransactionInfo transaction);
double getTransactionAmountRaw(TransactionInfo transactionInfo);