Cw 523 robinhood enhancements (#1176)

* CW-523 Add BCH support to Robinhood

* CW-523 Only show popup on Robinhood error

* CW-523 Add BitcoinCash to Robinhood Provider
This commit is contained in:
Konstantin Ullrich 2023-11-17 19:37:32 +01:00 committed by GitHub
parent f4e71c72ef
commit 539eb9b3eb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 28 additions and 9 deletions

View file

@ -2,4 +2,5 @@ import 'package:bitbox/bitbox.dart' as bitbox;
class AddressUtils { class AddressUtils {
static String getCashAddrFormat(String address) => bitbox.Address.toCashAddress(address); static String getCashAddrFormat(String address) => bitbox.Address.toCashAddress(address);
static String toLegacyAddress(String address) => bitbox.Address.toLegacyAddress(address);
} }

View file

@ -1,3 +1,5 @@
import 'dart:convert';
import 'package:bitbox/bitbox.dart' as bitbox; import 'package:bitbox/bitbox.dart' as bitbox;
import 'package:bitcoin_flutter/bitcoin_flutter.dart' as bitcoin; import 'package:bitcoin_flutter/bitcoin_flutter.dart' as bitcoin;
import 'package:cw_bitcoin/bitcoin_address_record.dart'; import 'package:cw_bitcoin/bitcoin_address_record.dart';
@ -294,4 +296,16 @@ abstract class BitcoinCashWalletBase extends ElectrumWallet with Store {
return 0; return 0;
} }
@override
String signMessage(String message, {String? address = null}) {
final index = address != null
? walletAddresses.addresses
.firstWhere((element) => element.address == AddressUtils.toLegacyAddress(address))
.index
: null;
return index == null
? base64Encode(hd.sign(message))
: base64Encode(hd.derive(index).sign(message));
}
} }

View file

@ -3,7 +3,6 @@ import 'dart:convert';
import 'package:cake_wallet/.secrets.g.dart' as secrets; import 'package:cake_wallet/.secrets.g.dart' as secrets;
import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart'; import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
import 'package:cake_wallet/utils/exception_handler.dart';
import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cw_core/wallet_base.dart'; import 'package:cw_core/wallet_base.dart';
import 'package:cw_core/wallet_type.dart'; import 'package:cw_core/wallet_type.dart';
@ -12,8 +11,7 @@ import 'package:http/http.dart' as http;
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
class RobinhoodBuyProvider { class RobinhoodBuyProvider {
RobinhoodBuyProvider({required WalletBase wallet}) RobinhoodBuyProvider({required WalletBase wallet}) : this._wallet = wallet;
: this._wallet = wallet;
final WalletBase _wallet; final WalletBase _wallet;
@ -21,10 +19,15 @@ class RobinhoodBuyProvider {
static const _cIdBaseUrl = 'exchange-helper.cakewallet.com'; static const _cIdBaseUrl = 'exchange-helper.cakewallet.com';
String get _applicationId => secrets.robinhoodApplicationId; String get _applicationId => secrets.robinhoodApplicationId;
String get _apiSecret => secrets.robinhoodCIdApiSecret; String get _apiSecret => secrets.robinhoodCIdApiSecret;
bool get isAvailable => bool get isAvailable => [
[WalletType.bitcoin, WalletType.litecoin, WalletType.ethereum].contains(_wallet.type); WalletType.bitcoin,
WalletType.bitcoinCash,
WalletType.litecoin,
WalletType.ethereum
].contains(_wallet.type);
String getSignature(String message) { String getSignature(String message) {
switch (_wallet.type) { switch (_wallet.type) {
@ -32,6 +35,7 @@ class RobinhoodBuyProvider {
return _wallet.signMessage(message); return _wallet.signMessage(message);
case WalletType.litecoin: case WalletType.litecoin:
case WalletType.bitcoin: case WalletType.bitcoin:
case WalletType.bitcoinCash:
return _wallet.signMessage(message, address: _wallet.walletAddresses.address); return _wallet.signMessage(message, address: _wallet.walletAddresses.address);
default: default:
throw Exception("WalletType is not available for Robinhood ${_wallet.type}"); throw Exception("WalletType is not available for Robinhood ${_wallet.type}");
@ -55,7 +59,8 @@ class RobinhoodBuyProvider {
if (response.statusCode == 200) { if (response.statusCode == 200) {
return (jsonDecode(response.body) as Map<String, dynamic>)['connectId'] as String; return (jsonDecode(response.body) as Map<String, dynamic>)['connectId'] as String;
} else { } else {
throw Exception('Provider currently unavailable. Status: ${response.statusCode} ${response.body}'); throw Exception(
'Provider currently unavailable. Status: ${response.statusCode} ${response.body}');
} }
} }
@ -76,8 +81,7 @@ class RobinhoodBuyProvider {
try { try {
final uri = await requestUrl(); final uri = await requestUrl();
await launchUrl(uri, mode: LaunchMode.externalApplication); await launchUrl(uri, mode: LaunchMode.externalApplication);
} catch (e, s) { } catch (_) {
ExceptionHandler.onError(FlutterErrorDetails(exception: e, stack: s));
await showPopUp<void>( await showPopUp<void>(
context: context, context: context,
builder: (BuildContext context) { builder: (BuildContext context) {

View file

@ -52,7 +52,7 @@ class MainActions {
case WalletType.bitcoin: case WalletType.bitcoin:
case WalletType.litecoin: case WalletType.litecoin:
case WalletType.ethereum: case WalletType.ethereum:
// case WalletType.bitcoinCash: // TODO: add sign message function to BCH first case WalletType.bitcoinCash:
switch (defaultBuyProvider) { switch (defaultBuyProvider) {
case BuyProviderType.AskEachTime: case BuyProviderType.AskEachTime:
Navigator.pushNamed(context, Routes.buy); Navigator.pushNamed(context, Routes.buy);