dev
dart 99 lines 3.19 KB
Raw
1 import 'package:bloc/bloc.dart';
2 import 'package:bloc_concurrency/bloc_concurrency.dart';
3 import 'package:cake_wallet/bitcoin/bitcoin.dart';
4 import 'package:cake_wallet/core/address_resolver/lnurl_pay/lnurlpay_record.dart';
5 import 'package:cake_wallet/generated/i18n.dart';
6 import 'package:cw_core/crypto_currency.dart';
7 import 'package:cw_core/wallet_base.dart';
8 import 'package:meta/meta.dart';
9
10 part 'lightning_username_event.dart';
11
12 part 'lightning_username_state.dart';
13
14 class UsernameError {
15 String message;
16 bool isInfo;
17
18 UsernameError(this.message, {this.isInfo = false});
19 }
20
21 // TODO find other errors that api returns
22 final Map<String, String> errorPatterns = {"name already taken": S.current.username_not_available};
23
24 const usernameRegex = r"^[a-z0-9_.-]+$";
25 const usernameSuffix = "@cake.cash";
26
27 class LightningUsernameBloc extends Bloc<LightningUsernameEvent, LightningUsernameState> {
28 final WalletBase _wallet;
29
30 LightningUsernameBloc(this._wallet) : super(LightningUsernameInitial("")) {
31 on<ChangeUsername>(onUsernameChanged, transformer: restartable());
32
33 on<RequestUsernameSave>(onUsernameSaveRequested);
34
35 on<_Init>((event, emit) async {
36 final username = await bitcoin!.getLightningUsername(_wallet);
37 emit(LightningUsernameInitial(username ?? ""));
38 });
39
40 add(_Init());
41 }
42
43 Future<void> onUsernameChanged(ChangeUsername event, Emitter<LightningUsernameState> emit) async {
44 emit(LightningUsernameChecking(event.newUsername));
45
46 final error = await getUsernameError(event.newUsername);
47
48 if (error != null) {
49 emit(LightningUsernameError(event.newUsername, error));
50 } else {
51 emit(LightningUsernameReady(event.newUsername));
52 }
53 }
54
55 Future<void> onUsernameSaveRequested(
56 RequestUsernameSave event, Emitter<LightningUsernameState> emit) async {
57 emit(LightningUsernameSaving(state.username));
58 try {
59 await bitcoin!.setLightningUsername(_wallet, state.username);
60 emit(LightningUsernameSaved(state.username));
61 } catch (e) {
62 for (final pattern in errorPatterns.keys) {
63 if (e.toString().contains(pattern)) {
64 emit(LightningUsernameError(state.username, UsernameError(errorPatterns[pattern]!)));
65 return;
66 }
67 }
68 emit(LightningUsernameError(
69 state.username, UsernameError(bitcoin!.getBreezSdkError(e) ?? e.toString())));
70 }
71 }
72
73 Future<UsernameError?> getUsernameError(String username) async {
74 if (!(RegExp(usernameRegex).hasMatch(username))) {
75 return UsernameError("${S.current.username_character_error} a-z, 0-9, - _ .");
76 }
77
78 if (username.length < 1 || username.length > 64) {
79 return UsernameError(S.current.username_length_error_1_64);
80 }
81
82 if (username == (await bitcoin!.getLightningUsername(_wallet))) {
83 return UsernameError(S.current.already_your_username, isInfo: true);
84 }
85
86 try {
87 if ((await LNUrlPayRecord.checkWellKnownUsername(
88 "${username}${usernameSuffix}", CryptoCurrency.btc,
89 allowRethrow: true)) !=
90 null) {
91 return UsernameError(S.current.username_not_available);
92 }
93 } catch (e) {
94 return UsernameError(S.current.username_check_your_network);
95 }
96
97 return null;
98 }
99 }