Added ability sending to FIO address (#370)
* Added ability sending to FIO address * remove apiKey property * fix conditions for FIO address checking
Serhii committed
Jun 13, 2022 at 14:41 UTC
fc58972bf90ace1aceaa782c433a574f82fc2189
4 files changed
+81
-1
lib/entities/fio_address_provider.dart
new
+57
@@ -0,0 +1,57 @@
1
+import 'dart:convert';
2
+
3
+import 'package:http/http.dart' as http;
4
+
5
+class FioAddressProvider {
6
+ static const apiAuthority = 'fio.blockpane.com';
7
+ static const availCheck = '/v1/chain/avail_check';
8
+ static const getAddress = '/v1/chain/get_pub_address';
9
+
10
+ static Future<bool> checkAvail(String fioAddress) async {
11
+ bool isFioRegistered = false;
12
+ final headers = {'Content-Type': 'application/json'};
13
+ final body = <String, String>{"fio_name": fioAddress};
14
+
15
+ final uri = Uri.https(apiAuthority, availCheck);
16
+ final response =
17
+ await http.post(uri, headers: headers, body: json.encode(body));
18
+
19
+ if (response.statusCode != 200) {
20
+ return isFioRegistered;
21
+ }
22
+
23
+ final responseJSON = json.decode(response.body) as Map<String, dynamic>;
24
+ isFioRegistered = responseJSON['is_registered'] as int == 1;
25
+
26
+ return isFioRegistered;
27
+ }
28
+
29
+ static Future<String> getPubAddress(String fioAddress, String token) async {
30
+ final headers = {'Content-Type': 'application/json'};
31
+ final body = <String, String>{
32
+ "fio_address": fioAddress,
33
+ "chain_code": token.toUpperCase(),
34
+ "token_code": token.toUpperCase(),
35
+ };
36
+
37
+ final uri = Uri.https(apiAuthority, getAddress);
38
+ final response =
39
+ await http.post(uri, headers: headers, body: json.encode(body));
40
+
41
+ if (response.statusCode == 400) {
42
+ final responseJSON = json.decode(response.body) as Map<String, dynamic>;
43
+ final error = responseJSON['error'] as String;
44
+ final message = responseJSON['message'] as String;
45
+ throw Exception('${error}\n$message');
46
+ }
47
+
48
+ if (response.statusCode != 200) {
49
+ return null;
50
+ }
51
+
52
+ final responseJSON = json.decode(response.body) as Map<String, dynamic>;
53
+ final String pubAddress = responseJSON['public_address'] as String;
54
+
55
+ return pubAddress;
56
+ }
57
+}
lib/entities/parse_address_from_domain.dart
+9
@@ -4,6 +4,7 @@ import 'package:cake_wallet/entities/parsed_address.dart';
4
import 'package:cake_wallet/entities/unstoppable_domain_address.dart';
5
import 'package:cake_wallet/entities/emoji_string_extension.dart';
6
import 'package:flutter/foundation.dart';
7
+import 'package:cake_wallet/entities/fio_address_provider.dart';
8
9
class AddressResolver {
10
@@ -26,6 +27,14 @@ class AddressResolver {
27
28
Future<ParsedAddress> resolve(String text, String ticker) async {
29
try {
30
+ if (text.contains('@') && !text.contains('.')) {
31
+ final bool isFioRegistered = await FioAddressProvider.checkAvail(text);
32
+ if (isFioRegistered) {
33
+ final address = await FioAddressProvider.getPubAddress(text, ticker);
34
+ return ParsedAddress.fetchFioAddress(address: address, name: text);
35
+ }
36
+
37
+ }
38
if (text.hasOnlyEmojis) {
39
final addresses = await yatService.fetchYatAddress(text, ticker);
40
return ParsedAddress.fetchEmojiAddress(addresses: addresses, name: text);
lib/entities/parsed_address.dart
+10
-1
@@ -2,7 +2,7 @@ import 'package:cake_wallet/entities/openalias_record.dart';
2
import 'package:cake_wallet/entities/yat_record.dart';
3
import 'package:flutter/material.dart';
4
5
-enum ParseFrom { unstoppableDomains, openAlias, yatRecord, notParsed }
5
+enum ParseFrom { unstoppableDomains, openAlias, yatRecord, fio, notParsed }
6
7
class ParsedAddress {
8
ParsedAddress({
@@ -58,4 +58,13 @@ class ParsedAddress {
58
parseFrom: ParseFrom.openAlias,
59
);
60
}
61
+
62
+ factory ParsedAddress.fetchFioAddress({@required String address, @required String name}){
63
+
64
+ return ParsedAddress(
65
+ addresses: [address],
66
+ name: name,
67
+ parseFrom: ParseFrom.fio,
68
+ );
69
+ }
70
}
lib/src/screens/send/widgets/extract_address_from_parsed.dart
+5
@@ -23,6 +23,11 @@ Future<String> extractAddressFromParsed(
23
content = S.of(context).openalias_alert_content(parsedAddress.name);
24
address = parsedAddress.addresses.first;
25
break;
26
+ case ParseFrom.fio:
27
+ title = S.of(context).address_detected;
28
+ content = S.of(context).openalias_alert_content(parsedAddress.name);
29
+ address = parsedAddress.addresses.first;
30
+ break;
31
case ParseFrom.yatRecord:
32
if (parsedAddress.name.isEmpty) {
33
title = S.of(context).yat_error;