mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2025-03-12 09:32:33 +00:00
Merge branch 'main' of https://github.com/cake-tech/cake_wallet into bitcoin-derivations
This commit is contained in:
commit
cead157c93
13 changed files with 78 additions and 58 deletions
|
@ -1,5 +1,3 @@
|
|||
Add Nano wallet
|
||||
Add WalletConnect to connect your ETH wallet with your favorite dApp
|
||||
Support getting Addresses from ENS and Mastodon
|
||||
Add BitcoinCash (BCH)
|
||||
Bug fixes
|
||||
Minor enhancements
|
||||
Accessibility enhancements
|
|
@ -272,7 +272,7 @@ SPEC CHECKSUMS:
|
|||
DKPhotoGallery: fdfad5125a9fdda9cc57df834d49df790dbb4179
|
||||
file_picker: ce3938a0df3cc1ef404671531facef740d03f920
|
||||
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
|
||||
flutter_inappwebview: bfd58618f49dc62f2676de690fc6dcda1d6c3721
|
||||
flutter_inappwebview: 3d32228f1304635e7c028b0d4252937730bbc6cf
|
||||
flutter_mailer: 2ef5a67087bc8c6c4cefd04a178bf1ae2c94cd83
|
||||
flutter_secure_storage: 23fc622d89d073675f2eaa109381aefbcf5a49be
|
||||
in_app_review: 318597b3a06c22bb46dc454d56828c85f444f99d
|
||||
|
|
|
@ -248,6 +248,7 @@ Future<void> setup({
|
|||
required Box<Order> ordersSource,
|
||||
required Box<UnspentCoinsInfo> unspentCoinsInfoSource,
|
||||
required Box<AnonpayInvoiceInfo> anonpayInvoiceInfoSource,
|
||||
required FlutterSecureStorage secureStorage,
|
||||
}) async {
|
||||
_walletInfoSource = walletInfoSource;
|
||||
_nodeSource = nodeSource;
|
||||
|
@ -289,7 +290,7 @@ Future<void> setup({
|
|||
getIt.registerFactory<Box<Node>>(() => _nodeSource);
|
||||
getIt.registerFactory<Box<Node>>(() => _powNodeSource, instanceName: Node.boxName + "pow");
|
||||
|
||||
getIt.registerSingleton<FlutterSecureStorage>(FlutterSecureStorage());
|
||||
getIt.registerSingleton<FlutterSecureStorage>(secureStorage);
|
||||
getIt.registerSingleton(AuthenticationStore());
|
||||
getIt.registerSingleton<WalletListStore>(WalletListStore());
|
||||
getIt.registerSingleton(NodeListStoreBase.instance);
|
||||
|
|
|
@ -46,7 +46,13 @@ class AddressResolver {
|
|||
}
|
||||
|
||||
final match = RegExp(addressPattern).firstMatch(raw);
|
||||
return match?.group(0)?.replaceAll(RegExp('[^0-9a-zA-Z_]'), '');
|
||||
return match?.group(0)?.replaceAllMapped(RegExp('[^0-9a-zA-Z]|bitcoincash:|nano_|ban_'), (Match match) {
|
||||
String group = match.group(0)!;
|
||||
if (group.startsWith('bitcoincash:') || group.startsWith('nano_') || group.startsWith('ban_')) {
|
||||
return group;
|
||||
}
|
||||
return '';
|
||||
});
|
||||
}
|
||||
|
||||
Future<ParsedAddress> resolve(String text, String ticker) async {
|
||||
|
@ -59,16 +65,11 @@ class AddressResolver {
|
|||
if (addressFromBio != null) {
|
||||
return ParsedAddress.fetchTwitterAddress(address: addressFromBio, name: text);
|
||||
}
|
||||
final tweets = twitterUser.tweets;
|
||||
if (tweets != null) {
|
||||
var subString = StringBuffer();
|
||||
tweets.forEach((item) {
|
||||
subString.writeln(item.text);
|
||||
});
|
||||
final userTweetsText = subString.toString();
|
||||
final addressFromPinnedTweet =
|
||||
extractAddressByType(raw: userTweetsText, type: CryptoCurrency.fromString(ticker));
|
||||
|
||||
final pinnedTweet = twitterUser.pinnedTweet?.text;
|
||||
if (pinnedTweet != null) {
|
||||
final addressFromPinnedTweet =
|
||||
extractAddressByType(raw: pinnedTweet, type: CryptoCurrency.fromString(ticker));
|
||||
if (addressFromPinnedTweet != null) {
|
||||
return ParsedAddress.fetchTwitterAddress(address: addressFromPinnedTweet, name: text);
|
||||
}
|
||||
|
|
|
@ -206,7 +206,8 @@ Future<void> initialSetup(
|
|||
transactionDescriptionBox: transactionDescriptions,
|
||||
ordersSource: ordersSource,
|
||||
anonpayInvoiceInfoSource: anonpayInvoiceInfo,
|
||||
unspentCoinsInfoSource: unspentCoinsInfoSource);
|
||||
unspentCoinsInfoSource: unspentCoinsInfoSource,
|
||||
secureStorage: secureStorage);
|
||||
await bootstrap(navigatorKey);
|
||||
monero?.onStartup();
|
||||
}
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:cake_wallet/.secrets.g.dart' as secrets;
|
||||
import 'package:cake_wallet/twitter/twitter_user.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:cake_wallet/.secrets.g.dart' as secrets;
|
||||
|
||||
class TwitterApi {
|
||||
static const twitterBearerToken = secrets.twitterBearerToken;
|
||||
|
@ -10,28 +11,49 @@ class TwitterApi {
|
|||
static const userPath = '/2/users/by/username/';
|
||||
|
||||
static Future<TwitterUser> lookupUserByName({required String userName}) async {
|
||||
final queryParams = {'user.fields': 'description', 'expansions': 'pinned_tweet_id'};
|
||||
|
||||
final queryParams = {
|
||||
'user.fields': 'description',
|
||||
'expansions': 'pinned_tweet_id',
|
||||
'tweet.fields': 'note_tweet'
|
||||
};
|
||||
final headers = {'authorization': 'Bearer $twitterBearerToken'};
|
||||
|
||||
final uri = Uri(
|
||||
scheme: httpsScheme,
|
||||
host: apiHost,
|
||||
path: userPath + userName,
|
||||
queryParameters: queryParams,
|
||||
);
|
||||
scheme: httpsScheme,
|
||||
host: apiHost,
|
||||
path: userPath + userName,
|
||||
queryParameters: queryParams);
|
||||
|
||||
var response = await http.get(uri, headers: headers);
|
||||
final response = await http.get(uri, headers: headers).catchError((error) {
|
||||
throw Exception('HTTP request failed: $error');
|
||||
});
|
||||
|
||||
if (response.statusCode != 200) {
|
||||
throw Exception('Unexpected http status: ${response.statusCode}');
|
||||
}
|
||||
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
|
||||
|
||||
final Map<String, dynamic> responseJSON = jsonDecode(response.body) as Map<String, dynamic>;
|
||||
if (responseJSON['errors'] != null) {
|
||||
throw Exception(responseJSON['errors'][0]['detail']);
|
||||
}
|
||||
|
||||
return TwitterUser.fromJson(responseJSON);
|
||||
return TwitterUser.fromJson(responseJSON, _getPinnedTweet(responseJSON));
|
||||
}
|
||||
|
||||
static Tweet? _getPinnedTweet(Map<String, dynamic> responseJSON) {
|
||||
final tweetId = responseJSON['data']['pinned_tweet_id'] as String?;
|
||||
if (tweetId == null || responseJSON['includes'] == null) return null;
|
||||
|
||||
final tweetIncludes = List.from(responseJSON['includes']['tweets'] as List);
|
||||
final pinnedTweetData = tweetIncludes.firstWhere(
|
||||
(tweet) => tweet['id'] == tweetId,
|
||||
orElse: () => null,
|
||||
) as Map<String, dynamic>?;
|
||||
|
||||
if (pinnedTweetData == null) return null;
|
||||
|
||||
final pinnedTweetText =
|
||||
(pinnedTweetData['note_tweet']?['text'] ?? pinnedTweetData['text']) as String;
|
||||
|
||||
return Tweet(id: tweetId, text: pinnedTweetText);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,25 +4,21 @@ class TwitterUser {
|
|||
required this.username,
|
||||
required this.name,
|
||||
required this.description,
|
||||
this.tweets});
|
||||
this.pinnedTweet});
|
||||
|
||||
final String id;
|
||||
final String username;
|
||||
final String name;
|
||||
final String description;
|
||||
final List<Tweet>? tweets;
|
||||
final Tweet? pinnedTweet;
|
||||
|
||||
factory TwitterUser.fromJson(Map<String, dynamic> json) {
|
||||
factory TwitterUser.fromJson(Map<String, dynamic> json, [Tweet? pinnedTweet]) {
|
||||
return TwitterUser(
|
||||
id: json['data']['id'] as String,
|
||||
username: json['data']['username'] as String,
|
||||
name: json['data']['name'] as String,
|
||||
description: json['data']['description'] as String? ?? '',
|
||||
tweets: json['includes'] != null
|
||||
? List.from(json['includes']['tweets'] as List)
|
||||
.map((e) => Tweet.fromJson(e as Map<String, dynamic>))
|
||||
.toList()
|
||||
: null,
|
||||
pinnedTweet: pinnedTweet,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -349,27 +349,27 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
|
|||
Object _credentials() {
|
||||
final priority = _settingsStore.priority[wallet.type];
|
||||
|
||||
if (priority == null && (wallet.type != WalletType.nano && wallet.type != WalletType.banano)) {
|
||||
throw Exception('Priority is null for wallet type: ${wallet.type}');
|
||||
}
|
||||
|
||||
switch (wallet.type) {
|
||||
case WalletType.bitcoin:
|
||||
case WalletType.litecoin:
|
||||
case WalletType.bitcoinCash:
|
||||
if (priority == null) throw Exception('Priority is null for wallet type: ${wallet.type}');
|
||||
return bitcoin!.createBitcoinTransactionCredentials(outputs, priority: priority);
|
||||
return bitcoin!.createBitcoinTransactionCredentials(outputs, priority: priority!);
|
||||
|
||||
case WalletType.monero:
|
||||
if (priority == null) throw Exception('Priority is null for wallet type: ${wallet.type}');
|
||||
return monero!
|
||||
.createMoneroTransactionCreationCredentials(outputs: outputs, priority: priority);
|
||||
.createMoneroTransactionCreationCredentials(outputs: outputs, priority: priority!);
|
||||
|
||||
case WalletType.haven:
|
||||
if (priority == null) throw Exception('Priority is null for wallet type: ${wallet.type}');
|
||||
return haven!.createHavenTransactionCreationCredentials(
|
||||
outputs: outputs, priority: priority, assetType: selectedCryptoCurrency.title);
|
||||
outputs: outputs, priority: priority!, assetType: selectedCryptoCurrency.title);
|
||||
|
||||
case WalletType.ethereum:
|
||||
if (priority == null) throw Exception('Priority is null for wallet type: ${wallet.type}');
|
||||
return ethereum!.createEthereumTransactionCredentials(outputs,
|
||||
priority: priority, currency: selectedCryptoCurrency);
|
||||
priority: priority!, currency: selectedCryptoCurrency);
|
||||
case WalletType.nano:
|
||||
return nano!.createNanoTransactionCredentials(outputs);
|
||||
default:
|
||||
|
|
|
@ -15,15 +15,15 @@ TYPES=($MONERO_COM $CAKEWALLET $HAVEN)
|
|||
APP_ANDROID_TYPE=$1
|
||||
|
||||
MONERO_COM_NAME="Monero.com"
|
||||
MONERO_COM_VERSION="1.7.0"
|
||||
MONERO_COM_BUILD_NUMBER=61
|
||||
MONERO_COM_VERSION="1.7.1"
|
||||
MONERO_COM_BUILD_NUMBER=62
|
||||
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.10.0"
|
||||
CAKEWALLET_BUILD_NUMBER=175
|
||||
CAKEWALLET_VERSION="4.10.1"
|
||||
CAKEWALLET_BUILD_NUMBER=176
|
||||
CAKEWALLET_BUNDLE_ID="com.cakewallet.cake_wallet"
|
||||
CAKEWALLET_PACKAGE="com.cakewallet.cake_wallet"
|
||||
CAKEWALLET_SCHEME="cakewallet"
|
||||
|
|
0
scripts/ios/app_config.sh
Normal file → Executable file
0
scripts/ios/app_config.sh
Normal file → Executable file
|
@ -13,13 +13,13 @@ TYPES=($MONERO_COM $CAKEWALLET $HAVEN)
|
|||
APP_IOS_TYPE=$1
|
||||
|
||||
MONERO_COM_NAME="Monero.com"
|
||||
MONERO_COM_VERSION="1.7.0"
|
||||
MONERO_COM_BUILD_NUMBER=59
|
||||
MONERO_COM_VERSION="1.7.1"
|
||||
MONERO_COM_BUILD_NUMBER=60
|
||||
MONERO_COM_BUNDLE_ID="com.cakewallet.monero"
|
||||
|
||||
CAKEWALLET_NAME="Cake Wallet"
|
||||
CAKEWALLET_VERSION="4.10.0"
|
||||
CAKEWALLET_BUILD_NUMBER=189
|
||||
CAKEWALLET_VERSION="4.10.1"
|
||||
CAKEWALLET_BUILD_NUMBER=190
|
||||
CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet"
|
||||
|
||||
HAVEN_NAME="Haven"
|
||||
|
|
|
@ -15,8 +15,8 @@ if [ -n "$1" ]; then
|
|||
fi
|
||||
|
||||
CAKEWALLET_NAME="Cake Wallet"
|
||||
CAKEWALLET_VERSION="1.3.0"
|
||||
CAKEWALLET_BUILD_NUMBER=36
|
||||
CAKEWALLET_VERSION="1.3.1"
|
||||
CAKEWALLET_BUILD_NUMBER=37
|
||||
CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet"
|
||||
|
||||
if ! [[ " ${TYPES[*]} " =~ " ${APP_MACOS_TYPE} " ]]; then
|
||||
|
|
|
@ -52,8 +52,8 @@ Future<void> generateBitcoin(bool hasImplementation) async {
|
|||
final outputFile = File(bitcoinOutputPath);
|
||||
const bitcoinCommonHeaders = """
|
||||
import 'dart:typed_data';
|
||||
import 'package:cake_wallet/entities/unspent_transaction_output.dart';
|
||||
import 'package:cw_core/node.dart';
|
||||
import 'package:cw_core/unspent_transaction_output.dart';
|
||||
import 'package:cw_core/wallet_credentials.dart';
|
||||
import 'package:cw_core/wallet_info.dart';
|
||||
import 'package:cw_core/transaction_priority.dart';
|
||||
|
@ -113,7 +113,7 @@ abstract class Bitcoin {
|
|||
int formatterStringDoubleToBitcoinAmount(String amount);
|
||||
String bitcoinTransactionPriorityWithLabel(TransactionPriority priority, int rate);
|
||||
|
||||
List<BitcoinUnspent> getUnspents(Object wallet);
|
||||
List<Unspent> getUnspents(Object wallet);
|
||||
void updateUnspents(Object wallet);
|
||||
WalletService createBitcoinWalletService(Box<WalletInfo> walletInfoSource, Box<UnspentCoinsInfo> unspentCoinSource);
|
||||
WalletService createLitecoinWalletService(Box<WalletInfo> walletInfoSource, Box<UnspentCoinsInfo> unspentCoinSource);
|
||||
|
@ -596,7 +596,7 @@ Future<void> generateBitcoinCash(bool hasImplementation) async {
|
|||
const bitcoinCashCommonHeaders = """
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:cw_bitcoin/bitcoin_transaction_priority.dart';
|
||||
import 'package:cw_core/unspent_transaction_output.dart';
|
||||
import 'package:cw_core/transaction_priority.dart';
|
||||
import 'package:cw_core/unspent_coins_info.dart';
|
||||
import 'package:cw_core/wallet_credentials.dart';
|
||||
|
@ -606,6 +606,7 @@ import 'package:hive/hive.dart';
|
|||
""";
|
||||
const bitcoinCashCWHeaders = """
|
||||
import 'package:cw_bitcoin_cash/cw_bitcoin_cash.dart';
|
||||
import 'package:cw_bitcoin/bitcoin_transaction_priority.dart';
|
||||
""";
|
||||
const bitcoinCashCwPart = "part 'cw_bitcoin_cash.dart';";
|
||||
const bitcoinCashContent = """
|
||||
|
|
Loading…
Reference in a new issue