mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2025-01-26 04:26:00 +00:00
add coinrabbit api
This commit is contained in:
parent
d18d007f6a
commit
d51b096fdc
4 changed files with 202 additions and 0 deletions
|
@ -21,4 +21,5 @@ class PreferencesKey {
|
||||||
static const bitcoinTransactionPriority = 'current_fee_priority_bitcoin';
|
static const bitcoinTransactionPriority = 'current_fee_priority_bitcoin';
|
||||||
static const shouldShowReceiveWarning = 'should_show_receive_warning';
|
static const shouldShowReceiveWarning = 'should_show_receive_warning';
|
||||||
static const shouldShowYatPopup = 'should_show_yat_popup';
|
static const shouldShowYatPopup = 'should_show_yat_popup';
|
||||||
|
static const isActive2fa = 'is_active_2fa';
|
||||||
}
|
}
|
||||||
|
|
180
lib/loan/api/coinrabbit_api_client.dart
Normal file
180
lib/loan/api/coinrabbit_api_client.dart
Normal file
|
@ -0,0 +1,180 @@
|
||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:cake_wallet/entities/preferences_key.dart';
|
||||||
|
import 'package:cake_wallet/loan/models/captcha_response.dart';
|
||||||
|
import 'package:http/http.dart' as http;
|
||||||
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
|
/// Thrown if an exception occurs while making an `http` request.
|
||||||
|
class HttpException implements Exception {}
|
||||||
|
|
||||||
|
/// Thrown if an `http` request returns a non-200 status code.
|
||||||
|
class HttpRequestFailure implements Exception {
|
||||||
|
const HttpRequestFailure(this.statusCode);
|
||||||
|
|
||||||
|
/// The status code of the response.
|
||||||
|
final int statusCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Thrown when an error occurs while decoding the response body.
|
||||||
|
class JsonDecodeException implements Exception {}
|
||||||
|
|
||||||
|
/// Thrown when an error occurs while deserializing the response body.
|
||||||
|
class JsonDeserializationException implements Exception {}
|
||||||
|
|
||||||
|
/// A Dart API Client for the CoinRabbit REST API.
|
||||||
|
class CoinRabbitApiClient {
|
||||||
|
CoinRabbitApiClient(
|
||||||
|
{http.Client httpClient, SharedPreferences sharedPreferences})
|
||||||
|
: _httpClient = httpClient ?? http.Client(),
|
||||||
|
_sharedPreferences = sharedPreferences;
|
||||||
|
|
||||||
|
/// The host URL used for all API requests.
|
||||||
|
static const authority = 'https://api-staging.coinrabbit.io';
|
||||||
|
|
||||||
|
final http.Client _httpClient;
|
||||||
|
|
||||||
|
final SharedPreferences _sharedPreferences;
|
||||||
|
|
||||||
|
static const monitorList = 'MONITOR_LIST';
|
||||||
|
static const confirmLoanCreate = 'CONFIRM_LOAN_CREATE';
|
||||||
|
static const confirmLoanRepayment = 'CONFIRM_LOAN_REPAYMENT';
|
||||||
|
static const confirmEarnCreate = 'CONFIRM_EARN_CREATE';
|
||||||
|
static const confirmEarnWithdraw = 'CONFIRM_EARN_WITHDRAW';
|
||||||
|
static const secondCredential = 'SECOND_CREDENTIAL';
|
||||||
|
|
||||||
|
/// Get Captcha Challange for authentication.
|
||||||
|
///
|
||||||
|
/// REST call: `GET /v2/utils/captcha`
|
||||||
|
Future<CaptchaResponse> getCaptchaChallenge() async {
|
||||||
|
final uri = Uri.https(authority, '/v2/utils/captcha');
|
||||||
|
final responseBody = await _get(uri) as Map<String, dynamic>;
|
||||||
|
|
||||||
|
try {
|
||||||
|
return CaptchaResponse.fromJson(responseBody);
|
||||||
|
} catch (_) {
|
||||||
|
throw JsonDeserializationException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Send verification code for authentication.
|
||||||
|
/// Returns a token String
|
||||||
|
///
|
||||||
|
/// REST call: `POST /v2/utils/verification-code/send`
|
||||||
|
Future<String> sendVerificationCode(String channel, bool isEmail) async {
|
||||||
|
final uri = Uri.https(authority, '/v2/utils/verification-code/send');
|
||||||
|
final captcha = await getCaptchaChallenge();
|
||||||
|
|
||||||
|
final body = {
|
||||||
|
'type': monitorList,
|
||||||
|
'geetest_challenge': captcha.challenge,
|
||||||
|
'geetest_seccode': captcha.gt,
|
||||||
|
'geetest_validate': captcha.gt
|
||||||
|
};
|
||||||
|
if (isEmail) {
|
||||||
|
body.addAll({"email": channel});
|
||||||
|
} else {
|
||||||
|
body.addAll({"phone": channel});
|
||||||
|
}
|
||||||
|
|
||||||
|
final responseBody =
|
||||||
|
await _post(uri: uri, body: body) as Map<String, dynamic>;
|
||||||
|
|
||||||
|
try {
|
||||||
|
final isActive2fa = responseBody['is_active_2fa'] as bool;
|
||||||
|
await _sharedPreferences.setBool(PreferencesKey.isActive2fa, isActive2fa);
|
||||||
|
|
||||||
|
return responseBody['tokens'][0] as String;
|
||||||
|
} catch (_) {
|
||||||
|
throw JsonDeserializationException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Verify the verification code for authentication.
|
||||||
|
/// Returns a token String
|
||||||
|
///
|
||||||
|
/// REST call: `POST /v2/utils/verification-code/verify`
|
||||||
|
Future<String> verifyCode(String code, String verificationToken) async {
|
||||||
|
final uri = Uri.https(authority, '/v2/utils/verification-code/verify');
|
||||||
|
final headers = {
|
||||||
|
'x-api-key': '04b6e4b9-ba09-4d0b-9b6f-13a0bc7cb348',
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
};
|
||||||
|
final body = {'verification_token': verificationToken, 'code': code};
|
||||||
|
|
||||||
|
final responseBody = await _post(uri: uri, body: body, headers: headers)
|
||||||
|
as Map<String, dynamic>;
|
||||||
|
|
||||||
|
try {
|
||||||
|
return responseBody['token'] as String;
|
||||||
|
} catch (_) {
|
||||||
|
throw JsonDeserializationException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Validates crypto address network.
|
||||||
|
/// Returns a token String
|
||||||
|
///
|
||||||
|
/// REST call: `POST /v2/utils/validate-address`
|
||||||
|
Future<bool> validateAddressByNetwork(
|
||||||
|
{String address, String network}) async {
|
||||||
|
final uri = Uri.https(authority, '/v2/utils/validate-address');
|
||||||
|
final headers = {
|
||||||
|
'x-api-key': '04b6e4b9-ba09-4d0b-9b6f-13a0bc7cb348',
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
};
|
||||||
|
final body = {'address': address, 'network': network};
|
||||||
|
|
||||||
|
final responseBody = await _httpClient.post(uri,
|
||||||
|
body: body, headers: headers) as Map<String, dynamic>;
|
||||||
|
|
||||||
|
try {
|
||||||
|
return responseBody['message'] as String == 'OK';
|
||||||
|
} catch (_) {
|
||||||
|
throw HttpException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<dynamic> _get(Uri uri) async {
|
||||||
|
http.Response response;
|
||||||
|
|
||||||
|
try {
|
||||||
|
response = await _httpClient.get(uri);
|
||||||
|
} catch (_) {
|
||||||
|
throw HttpException();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response.statusCode != 200) {
|
||||||
|
throw HttpRequestFailure(response.statusCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
final res = json.decode(response.body) as Map<String, Object>;
|
||||||
|
return res['response'];
|
||||||
|
} catch (e) {
|
||||||
|
throw JsonDecodeException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<dynamic> _post(
|
||||||
|
{Uri uri, dynamic body, Map<String, String> headers}) async {
|
||||||
|
http.Response response;
|
||||||
|
|
||||||
|
try {
|
||||||
|
response = await _httpClient.post(uri, body: body, headers: headers);
|
||||||
|
} catch (_) {
|
||||||
|
throw HttpException();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response.statusCode != 200) {
|
||||||
|
throw HttpRequestFailure(response.statusCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
final res = json.decode(response.body) as Map<String, Object>;
|
||||||
|
return res['response'];
|
||||||
|
} catch (e) {
|
||||||
|
throw JsonDecodeException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
20
lib/loan/models/captcha_response.dart
Normal file
20
lib/loan/models/captcha_response.dart
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
class CaptchaResponse {
|
||||||
|
int success;
|
||||||
|
String challenge;
|
||||||
|
String gt;
|
||||||
|
bool newCaptcha;
|
||||||
|
|
||||||
|
CaptchaResponse({
|
||||||
|
this.success,
|
||||||
|
this.challenge,
|
||||||
|
this.gt,
|
||||||
|
this.newCaptcha,
|
||||||
|
});
|
||||||
|
|
||||||
|
CaptchaResponse.fromJson(Map<String, dynamic> json) {
|
||||||
|
success = json['success'] as int;
|
||||||
|
challenge = json['challenge'] as String;
|
||||||
|
gt = json['gt'] as String;
|
||||||
|
newCaptcha = json['new_captcha'] as bool;
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,6 +23,7 @@ class SecretKey {
|
||||||
SecretKey('wyreAccountId', () => ''),
|
SecretKey('wyreAccountId', () => ''),
|
||||||
SecretKey('moonPayApiKey', () => ''),
|
SecretKey('moonPayApiKey', () => ''),
|
||||||
SecretKey('moonPaySecretKey', () => ''),
|
SecretKey('moonPaySecretKey', () => ''),
|
||||||
|
SecretKey('coinRabbitApiKey', () => ''),
|
||||||
];
|
];
|
||||||
|
|
||||||
final String name;
|
final String name;
|
||||||
|
|
Loading…
Reference in a new issue