dev
dart 208 lines 5.92 KB
Raw
1 import 'package:cake_wallet/anonpay/anonpay_api.dart';
2 import 'package:cake_wallet/anonpay/anonpay_invoice_info.dart';
3 import 'package:cake_wallet/anonpay/anonpay_request.dart';
4 import 'package:cake_wallet/core/execution_state.dart';
5 import 'package:cake_wallet/entities/fiat_currency.dart';
6 import 'package:cake_wallet/entities/preferences_key.dart';
7 import 'package:cake_wallet/utils/qr_util.dart';
8 import 'package:cw_core/receive_page_option.dart';
9 import 'package:cake_wallet/store/settings_store.dart';
10 import 'package:cw_core/crypto_currency.dart';
11 import 'package:cw_core/currency.dart';
12 import 'package:cw_core/wallet_base.dart';
13 import 'package:hive/hive.dart';
14 import 'package:mobx/mobx.dart';
15 import 'package:shared_preferences/shared_preferences.dart';
16
17 part 'anon_invoice_page_view_model.g.dart';
18
19 class AnonInvoicePageViewModel = AnonInvoicePageViewModelBase with _$AnonInvoicePageViewModel;
20
21 abstract class AnonInvoicePageViewModelBase with Store {
22 AnonInvoicePageViewModelBase(
23 this.anonPayApi,
24 this.address,
25 this.settingsStore,
26 this._wallet,
27 this._anonpayInvoiceInfoSource,
28 this.sharedPreferences,
29 this.pageOption,
30 ) : receipientEmail = '',
31 receipientName = '',
32 description = '',
33 amount = '',
34 state = InitialExecutionState(),
35 selectedCurrency = _wallet.currency,
36 cryptoCurrency = _wallet.currency {
37 _getPreviousDonationLink();
38 _fetchLimits();
39 }
40
41 List<Currency> get currencies => [_wallet.currency, ...FiatCurrency.all];
42 final AnonPayApi anonPayApi;
43 final String address;
44 final SettingsStore settingsStore;
45 final WalletBase _wallet;
46 final Box<AnonpayInvoiceInfo> _anonpayInvoiceInfoSource;
47 final SharedPreferences sharedPreferences;
48 final ReceivePageOption pageOption;
49
50 @observable
51 Currency selectedCurrency;
52
53 CryptoCurrency cryptoCurrency;
54
55 @observable
56 String receipientEmail;
57
58 @observable
59 String receipientName;
60
61 @observable
62 String description;
63
64 @observable
65 String amount;
66
67 @observable
68 ExecutionState state;
69
70 @computed
71 int get selectedCurrencyIndex => currencies.indexOf(selectedCurrency);
72
73 @observable
74 double? minimum;
75
76 @observable
77 double? maximum;
78
79 @action
80 void selectCurrency(Currency currency) {
81 selectedCurrency = currency;
82 maximum = minimum = null;
83 if (currency is CryptoCurrency) {
84 cryptoCurrency = currency;
85 } else {
86 cryptoCurrency = _wallet.currency;
87 }
88
89 _fetchLimits();
90 }
91
92 @action
93 Future<void> createInvoice() async {
94 state = IsExecutingState();
95 if (amount.isNotEmpty) {
96 final amountInCrypto = double.tryParse(amount);
97 if (amountInCrypto == null) {
98 state = FailureState('Amount is invalid');
99 return;
100 }
101 if (minimum != null && amountInCrypto < minimum!) {
102 state = FailureState('Amount is too small');
103 return;
104 }
105 if (maximum != null && amountInCrypto > maximum!) {
106 state = FailureState('Amount is too big');
107 return;
108 }
109 }
110 try {
111 final result = await anonPayApi.createInvoice(AnonPayRequest(
112 cryptoCurrency: cryptoCurrency,
113 address: address,
114 amount: amount.isEmpty ? null : amount,
115 description: description,
116 email: receipientEmail,
117 name: receipientName,
118 fiatEquivalent:
119 selectedCurrency is FiatCurrency ? (selectedCurrency as FiatCurrency).raw : null,
120 ));
121
122 _anonpayInvoiceInfoSource.add(result);
123
124 state = ExecutedSuccessfullyState(payload: result);
125 } catch (e) {
126 state = FailureState(e.toString());
127 }
128 }
129
130 @action
131 void setRequestParams({
132 required String inputAmount,
133 required String inputName,
134 required String inputEmail,
135 required String inputDescription,
136 }) {
137 receipientName = inputName;
138 receipientEmail = inputEmail;
139 description = inputDescription;
140 amount = inputAmount;
141 }
142
143 @action
144 Future<void> generateDonationLink() async {
145 state = IsExecutingState();
146
147 final result = await anonPayApi.generateDonationLink(AnonPayRequest(
148 cryptoCurrency: cryptoCurrency,
149 address: address,
150 description: description,
151 email: receipientEmail,
152 name: receipientName,
153 ));
154
155 await sharedPreferences.setString(PreferencesKey.clearnetDonationLink, result.clearnetUrl);
156 await sharedPreferences.setString(PreferencesKey.onionDonationLink, result.onionUrl);
157 await sharedPreferences.setString(PreferencesKey.donationLinkWalletName, _wallet.name);
158
159 state = ExecutedSuccessfullyState(payload: result);
160 }
161
162 Future<void> _fetchLimits() async {
163 try {
164 final limit = await anonPayApi.fetchLimits(
165 cryptoCurrency: cryptoCurrency,
166 fiatCurrency: selectedCurrency is FiatCurrency ? selectedCurrency as FiatCurrency : null,
167 );
168 minimum = limit.min;
169 maximum = limit.max != null ? limit.max! / 4 : null;
170 } catch (e) {
171 state = FailureState(e.toString());
172 }
173 }
174
175 @computed
176 String get currentWalletName => _wallet.name;
177
178 @computed
179 String get qrImage => getQrImage(_wallet.type);
180
181 @action
182 void reset() {
183 selectedCurrency = _wallet.currency;
184 cryptoCurrency = _wallet.currency;
185 receipientEmail = '';
186 receipientName = '';
187 description = '';
188 amount = '';
189 _fetchLimits();
190 }
191
192 Future<void> _getPreviousDonationLink() async {
193 if (pageOption == ReceivePageOption.anonPayDonationLink) {
194 final donationLink = sharedPreferences.getString(PreferencesKey.clearnetDonationLink);
195 final donationLinkWalletName =
196 sharedPreferences.getString(PreferencesKey.donationLinkWalletName);
197
198 if (donationLink != null && currentWalletName == donationLinkWalletName) {
199 final url = Uri.parse(donationLink);
200 url.queryParameters.forEach((key, value) {
201 if (key == 'name') receipientName = value;
202 if (key == 'email') receipientEmail = value;
203 if (key == 'description') description = Uri.decodeComponent(value);
204 });
205 }
206 }
207 }
208 }