From bca59ad5e486b6f0d9f6f572bc73f304b28199ae Mon Sep 17 00:00:00 2001 From: Konstantin Ullrich Date: Mon, 25 Mar 2024 13:16:57 -0500 Subject: [PATCH] Remove moonpay secret use exchange-helper instead (#1343) * Remove moonpay secret use exchange-helper instead * Update lib/buy/moonpay/moonpay_provider.dart * remove web3dart dep from cw_solana * Apply new api for moonpay exchange helper * Add Robinhood as Polygon buy-provider --- .github/workflows/pr_test_build.yml | 2 +- cw_solana/lib/solana_wallet.dart | 6 +-- cw_solana/pubspec.yaml | 3 +- lib/buy/moonpay/moonpay_provider.dart | 52 +++++++++++++------ lib/buy/robinhood/robinhood_buy_provider.dart | 3 +- lib/entities/provider_types.dart | 11 +--- tool/utils/secret_key.dart | 2 +- 7 files changed, 44 insertions(+), 35 deletions(-) diff --git a/.github/workflows/pr_test_build.yml b/.github/workflows/pr_test_build.yml index 282941365..ddc8869f0 100644 --- a/.github/workflows/pr_test_build.yml +++ b/.github/workflows/pr_test_build.yml @@ -143,7 +143,7 @@ jobs: echo "const chatwootWebsiteToken = '${{ secrets.CHATWOOT_WEBSITE_TOKEN }}';" >> lib/.secrets.g.dart echo "const exolixApiKey = '${{ secrets.EXOLIX_API_KEY }}';" >> lib/.secrets.g.dart echo "const robinhoodApplicationId = '${{ secrets.ROBINHOOD_APPLICATION_ID }}';" >> lib/.secrets.g.dart - echo "const robinhoodCIdApiSecret = '${{ secrets.ROBINHOOD_CID_CLIENT_SECRET }}';" >> lib/.secrets.g.dart + echo "const exchangeHelperApiKey = '${{ secrets.ROBINHOOD_CID_CLIENT_SECRET }}';" >> lib/.secrets.g.dart echo "const walletConnectProjectId = '${{ secrets.WALLET_CONNECT_PROJECT_ID }}';" >> lib/.secrets.g.dart echo "const moralisApiKey = '${{ secrets.MORALIS_API_KEY }}';" >> lib/.secrets.g.dart echo "const polygonScanApiKey = '${{ secrets.POLYGON_SCAN_API_KEY }}';" >> cw_evm/lib/.secrets.g.dart diff --git a/cw_solana/lib/solana_wallet.dart b/cw_solana/lib/solana_wallet.dart index 3476d76cd..de4d70674 100644 --- a/cw_solana/lib/solana_wallet.dart +++ b/cw_solana/lib/solana_wallet.dart @@ -1,6 +1,5 @@ import 'dart:async'; import 'dart:convert'; -import 'dart:developer'; import 'dart:io'; import 'package:cw_core/cake_hive.dart'; import 'package:cw_core/crypto_currency.dart'; @@ -30,7 +29,6 @@ import 'package:mobx/mobx.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:solana/metaplex.dart' as metaplex; import 'package:solana/solana.dart'; -import 'package:web3dart/crypto.dart'; part 'solana_wallet.g.dart'; @@ -134,7 +132,7 @@ abstract class SolanaWalletBase assert(mnemonic != null || privateKey != null); if (privateKey != null) { - final privateKeyBytes = hexToBytes(privateKey); + final privateKeyBytes = HEX.decode(privateKey); return await Wallet.fromPrivateKeyBytes(privateKey: privateKeyBytes); } @@ -491,7 +489,7 @@ abstract class SolanaWalletBase final signature = await _walletKeyPair!.sign(messageBytes); // Convert the signature to a hexadecimal string - final hex = bytesToHex(signature.bytes); + final hex = HEX.encode(signature.bytes); return hex; } diff --git a/cw_solana/pubspec.yaml b/cw_solana/pubspec.yaml index c98b7492e..7e24983bf 100644 --- a/cw_solana/pubspec.yaml +++ b/cw_solana/pubspec.yaml @@ -19,7 +19,6 @@ dependencies: bip39: ^1.0.6 mobx: ^2.3.0+1 shared_preferences: ^2.0.15 - web3dart: ^2.7.1 bip32: ^2.0.0 hex: ^0.2.0 @@ -34,4 +33,4 @@ dev_dependencies: flutter: # assets: # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg \ No newline at end of file + # - images/a_dot_ham.jpeg diff --git a/lib/buy/moonpay/moonpay_provider.dart b/lib/buy/moonpay/moonpay_provider.dart index 75ba45ce1..02bdedaec 100644 --- a/lib/buy/moonpay/moonpay_provider.dart +++ b/lib/buy/moonpay/moonpay_provider.dart @@ -1,4 +1,13 @@ import 'dart:convert'; + +import 'package:cake_wallet/.secrets.g.dart' as secrets; +import 'package:cake_wallet/buy/buy_amount.dart'; +import 'package:cake_wallet/buy/buy_exception.dart'; +import 'package:cake_wallet/buy/buy_provider.dart'; +import 'package:cake_wallet/buy/buy_provider_description.dart'; +import 'package:cake_wallet/buy/order.dart'; +import 'package:cake_wallet/exchange/trade_state.dart'; +import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/palette.dart'; import 'package:cake_wallet/routes.dart'; import 'package:cake_wallet/src/widgets/alert_with_one_action.dart'; @@ -6,19 +15,11 @@ import 'package:cake_wallet/store/settings_store.dart'; import 'package:cake_wallet/themes/theme_base.dart'; import 'package:cake_wallet/utils/device_info.dart'; import 'package:crypto/crypto.dart'; -import 'package:cake_wallet/buy/buy_exception.dart'; -import 'package:cake_wallet/generated/i18n.dart'; -import 'package:flutter/material.dart'; -import 'package:http/http.dart'; -import 'package:cake_wallet/buy/buy_amount.dart'; -import 'package:cake_wallet/buy/buy_provider.dart'; -import 'package:cake_wallet/buy/buy_provider_description.dart'; -import 'package:cake_wallet/buy/order.dart'; +import 'package:cw_core/crypto_currency.dart'; import 'package:cw_core/wallet_base.dart'; import 'package:cw_core/wallet_type.dart'; -import 'package:cake_wallet/exchange/trade_state.dart'; -import 'package:cake_wallet/.secrets.g.dart' as secrets; -import 'package:cw_core/crypto_currency.dart'; +import 'package:flutter/material.dart'; +import 'package:http/http.dart'; import 'package:url_launcher/url_launcher.dart'; class MoonPaySellProvider extends BuyProvider { @@ -34,6 +35,7 @@ class MoonPaySellProvider extends BuyProvider { static const _baseTestUrl = 'sell-sandbox.moonpay.com'; static const _baseProductUrl = 'sell.moonpay.com'; + static const _cIdBaseUrl = 'exchange-helper.cakewallet.com'; @override String get providerDescription => @@ -60,9 +62,29 @@ class MoonPaySellProvider extends BuyProvider { static String get _apiKey => secrets.moonPayApiKey; - static String get _secretKey => secrets.moonPaySecretKey; + static String get _exchangeHelperApiKey => secrets.exchangeHelperApiKey; final String baseUrl; + Future getMoonpaySignature(String query) async { + final uri = Uri.https(_cIdBaseUrl, "/api/moonpay"); + + final response = await post( + uri, + headers: { + 'Content-Type': 'application/json', + 'x-api-key': _exchangeHelperApiKey, + }, + body: json.encode({'query': query}), + ); + + if (response.statusCode == 200) { + return (jsonDecode(response.body) as Map)['signature'] as String; + } else { + throw Exception( + 'Provider currently unavailable. Status: ${response.statusCode} ${response.body}'); + } + } + Future requestMoonPayUrl({ required CryptoCurrency currency, required String refundWalletAddress, @@ -86,11 +108,7 @@ class MoonPaySellProvider extends BuyProvider { }..addAll(customParams), ); - final messageBytes = utf8.encode('?${originalUri.query}'); - final key = utf8.encode(_secretKey); - final hmac = Hmac(sha256, key); - final digest = hmac.convert(messageBytes); - final signature = base64.encode(digest.bytes); + final signature = await getMoonpaySignature('?${originalUri.query}'); if (isTestEnvironment) { return originalUri; diff --git a/lib/buy/robinhood/robinhood_buy_provider.dart b/lib/buy/robinhood/robinhood_buy_provider.dart index 47c3ab1ea..7610e51f3 100644 --- a/lib/buy/robinhood/robinhood_buy_provider.dart +++ b/lib/buy/robinhood/robinhood_buy_provider.dart @@ -32,11 +32,12 @@ class RobinhoodBuyProvider extends BuyProvider { String get _applicationId => secrets.robinhoodApplicationId; - String get _apiSecret => secrets.robinhoodCIdApiSecret; + String get _apiSecret => secrets.exchangeHelperApiKey; String getSignature(String message) { switch (wallet.type) { case WalletType.ethereum: + case WalletType.polygon: return wallet.signMessage(message); case WalletType.litecoin: case WalletType.bitcoin: diff --git a/lib/entities/provider_types.dart b/lib/entities/provider_types.dart index b7336c2a7..f3993e129 100644 --- a/lib/entities/provider_types.dart +++ b/lib/entities/provider_types.dart @@ -55,6 +55,7 @@ class ProvidersHelper { case WalletType.monero: return [ProviderType.askEachTime, ProviderType.onramper, ProviderType.dfx]; case WalletType.bitcoin: + case WalletType.polygon: case WalletType.ethereum: return [ ProviderType.askEachTime, @@ -65,8 +66,6 @@ class ProvidersHelper { case WalletType.litecoin: case WalletType.bitcoinCash: return [ProviderType.askEachTime, ProviderType.onramper, ProviderType.robinhood]; - case WalletType.polygon: - return [ProviderType.askEachTime, ProviderType.onramper, ProviderType.dfx]; case WalletType.solana: return [ProviderType.askEachTime, ProviderType.onramper, ProviderType.robinhood]; case WalletType.none: @@ -79,6 +78,7 @@ class ProvidersHelper { switch (walletType) { case WalletType.bitcoin: case WalletType.ethereum: + case WalletType.polygon: return [ ProviderType.askEachTime, ProviderType.onramper, @@ -88,13 +88,6 @@ class ProvidersHelper { case WalletType.litecoin: case WalletType.bitcoinCash: return [ProviderType.askEachTime, ProviderType.moonpaySell]; - case WalletType.polygon: - return [ - ProviderType.askEachTime, - ProviderType.onramper, - ProviderType.moonpaySell, - ProviderType.dfx, - ]; case WalletType.solana: return [ ProviderType.askEachTime, diff --git a/tool/utils/secret_key.dart b/tool/utils/secret_key.dart index 38b5129af..430de03b6 100644 --- a/tool/utils/secret_key.dart +++ b/tool/utils/secret_key.dart @@ -34,7 +34,7 @@ class SecretKey { SecretKey('chatwootWebsiteToken', () => ''), SecretKey('exolixApiKey', () => ''), SecretKey('robinhoodApplicationId', () => ''), - SecretKey('robinhoodCIdApiSecret', () => ''), + SecretKey('exchangeHelperApiKey', () => ''), SecretKey('walletConnectProjectId', () => ''), SecretKey('moralisApiKey', () => ''), ];