mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2024-12-23 03:59:23 +00:00
save
This commit is contained in:
parent
3ce93c9270
commit
d8976182ca
36 changed files with 527 additions and 264 deletions
90
cw_lightning/lib/lightning_transaction_history.dart
Normal file
90
cw_lightning/lib/lightning_transaction_history.dart
Normal file
|
@ -0,0 +1,90 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:cw_core/pathForWallet.dart';
|
||||
import 'package:cw_core/transaction_history.dart';
|
||||
import 'package:cw_core/utils/file.dart';
|
||||
import 'package:cw_core/wallet_info.dart';
|
||||
import 'package:cw_lightning/lightning_transaction_info.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
|
||||
part 'lightning_transaction_history.g.dart';
|
||||
|
||||
const transactionsHistoryFileName = 'transactions.json';
|
||||
|
||||
class LightningTransactionHistory = LightningTransactionHistoryBase
|
||||
with _$LightningTransactionHistory;
|
||||
|
||||
abstract class LightningTransactionHistoryBase
|
||||
extends TransactionHistoryBase<LightningTransactionInfo> with Store {
|
||||
LightningTransactionHistoryBase(
|
||||
{required this.walletInfo, required String password})
|
||||
: _password = password,
|
||||
_height = 0 {
|
||||
transactions = ObservableMap<String, LightningTransactionInfo>();
|
||||
}
|
||||
|
||||
final WalletInfo walletInfo;
|
||||
String _password;
|
||||
int _height;
|
||||
|
||||
Future<void> init() async => await _load();
|
||||
|
||||
@override
|
||||
void addOne(LightningTransactionInfo transaction) =>
|
||||
transactions[transaction.id] = transaction;
|
||||
|
||||
@override
|
||||
void addMany(Map<String, LightningTransactionInfo> transactions) =>
|
||||
transactions.forEach((_, tx) => _update(tx));
|
||||
|
||||
@override
|
||||
Future<void> save() async {
|
||||
try {
|
||||
final dirPath =
|
||||
await pathForWalletDir(name: walletInfo.name, type: walletInfo.type);
|
||||
final path = '$dirPath/$transactionsHistoryFileName';
|
||||
final data =
|
||||
json.encode({'height': _height, 'transactions': transactions});
|
||||
await writeData(path: path, password: _password, data: data);
|
||||
} catch (e) {
|
||||
print('Error while save bitcoin transaction history: ${e.toString()}');
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> changePassword(String password) async {
|
||||
_password = password;
|
||||
await save();
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> _read() async {
|
||||
final dirPath =
|
||||
await pathForWalletDir(name: walletInfo.name, type: walletInfo.type);
|
||||
final path = '$dirPath/$transactionsHistoryFileName';
|
||||
final content = await read(path: path, password: _password);
|
||||
return json.decode(content) as Map<String, dynamic>;
|
||||
}
|
||||
|
||||
Future<void> _load() async {
|
||||
try {
|
||||
final content = await _read();
|
||||
final txs = content['transactions'] as Map<String, dynamic>? ?? {};
|
||||
|
||||
txs.entries.forEach((entry) {
|
||||
final val = entry.value;
|
||||
|
||||
if (val is Map<String, dynamic>) {
|
||||
final tx = LightningTransactionInfo.fromJson(val, walletInfo.type);
|
||||
_update(tx);
|
||||
}
|
||||
});
|
||||
|
||||
_height = content['height'] as int;
|
||||
} catch (e) {
|
||||
print(e);
|
||||
}
|
||||
}
|
||||
|
||||
void _update(LightningTransactionInfo transaction) =>
|
||||
transactions[transaction.id] = transaction;
|
||||
|
||||
}
|
122
cw_lightning/lib/lightning_transaction_info.dart
Normal file
122
cw_lightning/lib/lightning_transaction_info.dart
Normal file
|
@ -0,0 +1,122 @@
|
|||
import 'package:bitcoin_flutter/bitcoin_flutter.dart' as bitcoin;
|
||||
import 'package:bitcoin_flutter/src/payments/index.dart' show PaymentData;
|
||||
import 'package:cw_bitcoin/address_from_output.dart';
|
||||
import 'package:cw_bitcoin/bitcoin_address_record.dart';
|
||||
import 'package:cw_bitcoin/bitcoin_amount_format.dart';
|
||||
import 'package:cw_core/transaction_direction.dart';
|
||||
import 'package:cw_core/transaction_info.dart';
|
||||
import 'package:cw_core/format_amount.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
|
||||
class LightningTransactionInfo extends TransactionInfo {
|
||||
LightningTransactionInfo(this.type,
|
||||
{required String id,
|
||||
required int height,
|
||||
required int amount,
|
||||
int? fee,
|
||||
required TransactionDirection direction,
|
||||
required bool isPending,
|
||||
required DateTime date,
|
||||
required int confirmations}) {
|
||||
this.id = id;
|
||||
this.height = height;
|
||||
this.amount = amount;
|
||||
this.fee = fee;
|
||||
this.direction = direction;
|
||||
this.date = date;
|
||||
this.isPending = isPending;
|
||||
this.confirmations = confirmations;
|
||||
}
|
||||
|
||||
factory LightningTransactionInfo.fromHexAndHeader(WalletType type, String hex,
|
||||
{List<String>? addresses, required int height, int? timestamp, required int confirmations}) {
|
||||
final tx = bitcoin.Transaction.fromHex(hex);
|
||||
var exist = false;
|
||||
var amount = 0;
|
||||
|
||||
if (addresses != null) {
|
||||
tx.outs.forEach((out) {
|
||||
try {
|
||||
final p2pkh = bitcoin.P2PKH(
|
||||
data: PaymentData(output: out.script), network: bitcoin.bitcoin);
|
||||
exist = addresses.contains(p2pkh.data.address);
|
||||
|
||||
if (exist) {
|
||||
amount += out.value!;
|
||||
}
|
||||
} catch (_) {}
|
||||
});
|
||||
}
|
||||
|
||||
final date = timestamp != null
|
||||
? DateTime.fromMillisecondsSinceEpoch(timestamp * 1000)
|
||||
: DateTime.now();
|
||||
|
||||
return LightningTransactionInfo(type,
|
||||
id: tx.getId(),
|
||||
height: height,
|
||||
isPending: false,
|
||||
fee: null,
|
||||
direction: TransactionDirection.incoming,
|
||||
amount: amount,
|
||||
date: date,
|
||||
confirmations: confirmations);
|
||||
}
|
||||
|
||||
factory LightningTransactionInfo.fromJson(
|
||||
Map<String, dynamic> data, WalletType type) {
|
||||
return LightningTransactionInfo(type,
|
||||
id: data['id'] as String,
|
||||
height: data['height'] as int,
|
||||
amount: data['amount'] as int,
|
||||
fee: data['fee'] as int,
|
||||
direction: parseTransactionDirectionFromInt(data['direction'] as int),
|
||||
date: DateTime.fromMillisecondsSinceEpoch(data['date'] as int),
|
||||
isPending: data['isPending'] as bool,
|
||||
confirmations: data['confirmations'] as int);
|
||||
}
|
||||
|
||||
final WalletType type;
|
||||
|
||||
String? _fiatAmount;
|
||||
|
||||
@override
|
||||
String amountFormatted() =>
|
||||
'${formatAmount(bitcoinAmountToString(amount: amount))} ${walletTypeToCryptoCurrency(type).title}';
|
||||
|
||||
@override
|
||||
String? feeFormatted() => fee != null
|
||||
? '${formatAmount(bitcoinAmountToString(amount: fee!))} ${walletTypeToCryptoCurrency(type).title}'
|
||||
: '';
|
||||
|
||||
@override
|
||||
String fiatAmount() => _fiatAmount ?? '';
|
||||
|
||||
@override
|
||||
void changeFiatAmount(String amount) => _fiatAmount = formatAmount(amount);
|
||||
|
||||
LightningTransactionInfo updated(LightningTransactionInfo info) {
|
||||
return LightningTransactionInfo(info.type,
|
||||
id: id,
|
||||
height: info.height,
|
||||
amount: info.amount,
|
||||
fee: info.fee,
|
||||
direction: direction,
|
||||
date: date,
|
||||
isPending: isPending,
|
||||
confirmations: info.confirmations);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final m = <String, dynamic>{};
|
||||
m['id'] = id;
|
||||
m['height'] = height;
|
||||
m['amount'] = amount;
|
||||
m['direction'] = direction.index;
|
||||
m['date'] = date.millisecondsSinceEpoch;
|
||||
m['isPending'] = isPending;
|
||||
m['confirmations'] = confirmations;
|
||||
m['fee'] = fee;
|
||||
return m;
|
||||
}
|
||||
}
|
|
@ -6,19 +6,20 @@ import 'package:breez_sdk/bridge_generated.dart';
|
|||
import 'package:cw_bitcoin/bitcoin_mnemonic.dart';
|
||||
import 'package:cw_bitcoin/bitcoin_wallet_keys.dart';
|
||||
import 'package:cw_bitcoin/electrum.dart';
|
||||
import 'package:cw_bitcoin/electrum_balance.dart';
|
||||
import 'package:cw_bitcoin/electrum_transaction_history.dart';
|
||||
import 'package:cw_bitcoin/electrum_transaction_info.dart';
|
||||
import 'package:cw_bitcoin/electrum_wallet_addresses.dart';
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:cw_core/node.dart';
|
||||
import 'package:cw_core/pathForWallet.dart';
|
||||
import 'package:cw_core/pending_transaction.dart';
|
||||
import 'package:cw_core/sync_status.dart';
|
||||
import 'package:cw_core/transaction_direction.dart';
|
||||
import 'package:cw_core/transaction_priority.dart';
|
||||
import 'package:cw_core/unspent_coins_info.dart';
|
||||
import 'package:cw_core/utils/file.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
import 'package:cw_lightning/lightning_balance.dart';
|
||||
import 'package:cw_lightning/lightning_transaction_history.dart';
|
||||
import 'package:cw_lightning/lightning_transaction_info.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
@ -36,13 +37,13 @@ part 'lightning_wallet.g.dart';
|
|||
|
||||
class LightningWallet = LightningWalletBase with _$LightningWallet;
|
||||
|
||||
// abstract class LightningWalletBase extends ElectrumWallet with Store {
|
||||
class LightningWalletBase
|
||||
extends WalletBase<LightningBalance, ElectrumTransactionHistory, ElectrumTransactionInfo>
|
||||
abstract class LightningWalletBase
|
||||
extends WalletBase<LightningBalance, LightningTransactionHistory, LightningTransactionInfo>
|
||||
with Store {
|
||||
final bitcoin.HDWallet hd;
|
||||
final String mnemonic;
|
||||
String _password;
|
||||
bool _isTransactionUpdating;
|
||||
late ElectrumClient electrumClient;
|
||||
|
||||
@override
|
||||
|
@ -77,12 +78,13 @@ class LightningWalletBase
|
|||
syncStatus = NotConnectedSyncStatus(),
|
||||
mnemonic = mnemonic,
|
||||
_password = password,
|
||||
_isTransactionUpdating = false,
|
||||
balance = ObservableMap<CryptoCurrency, LightningBalance>.of({
|
||||
CryptoCurrency.btc:
|
||||
initialBalance ?? const LightningBalance(confirmed: 0, unconfirmed: 0, frozen: 0)
|
||||
}),
|
||||
super(walletInfo) {
|
||||
transactionHistory = ElectrumTransactionHistory(walletInfo: walletInfo, password: password);
|
||||
transactionHistory = LightningTransactionHistory(walletInfo: walletInfo, password: password);
|
||||
walletAddresses = BitcoinWalletAddresses(walletInfo,
|
||||
electrumClient: electrumClient ?? ElectrumClient(),
|
||||
initialAddresses: initialAddresses,
|
||||
|
@ -182,10 +184,7 @@ class LightningWalletBase
|
|||
}
|
||||
|
||||
sdk.nodeStateStream.listen((event) {
|
||||
print("Node state: $event");
|
||||
if (event == null) return;
|
||||
int balanceSat = event.maxPayableMsat ~/ 1000;
|
||||
print("sats: $balanceSat");
|
||||
balance[CryptoCurrency.btc] = LightningBalance(
|
||||
confirmed: event.maxPayableMsat ~/ 1000,
|
||||
unconfirmed: event.maxReceivableMsat ~/ 1000,
|
||||
|
@ -193,6 +192,9 @@ class LightningWalletBase
|
|||
);
|
||||
});
|
||||
|
||||
// final payments = await sdk.listPayments(req: ListPaymentsRequest());
|
||||
// print("payments: $payments");
|
||||
|
||||
print("initialized breez: ${(await sdk.isInitialized())}");
|
||||
}
|
||||
|
||||
|
@ -206,9 +208,7 @@ class LightningWalletBase
|
|||
Future<void> startSync() async {
|
||||
try {
|
||||
syncStatus = AttemptingSyncStatus();
|
||||
|
||||
// TODO: CW-563 Implement sync
|
||||
|
||||
await updateTransactions();
|
||||
syncStatus = SyncedSyncStatus();
|
||||
} catch (e) {
|
||||
print(e);
|
||||
|
@ -230,6 +230,7 @@ class LightningWalletBase
|
|||
Future<void> connectToNode({required Node node}) async {
|
||||
try {
|
||||
syncStatus = ConnectingSyncStatus();
|
||||
await updateTransactions();
|
||||
syncStatus = ConnectedSyncStatus();
|
||||
} catch (e) {
|
||||
print(e);
|
||||
|
@ -242,35 +243,61 @@ class LightningWalletBase
|
|||
throw UnimplementedError("createTransaction");
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Map<String, ElectrumTransactionInfo>> fetchTransactions() async {
|
||||
// String address = _publicAddress!;
|
||||
Future<bool> updateTransactions() async {
|
||||
try {
|
||||
if (_isTransactionUpdating) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// final transactions = await _client.fetchTransactions(address);
|
||||
|
||||
// final Map<String, NanoTransactionInfo> result = {};
|
||||
|
||||
// for (var transactionModel in transactions) {
|
||||
// final bool isSend = transactionModel.type == "send";
|
||||
// result[transactionModel.hash] = NanoTransactionInfo(
|
||||
// id: transactionModel.hash,
|
||||
// amountRaw: transactionModel.amount,
|
||||
// height: transactionModel.height,
|
||||
// direction: isSend ? TransactionDirection.outgoing : TransactionDirection.incoming,
|
||||
// confirmed: transactionModel.confirmed,
|
||||
// date: transactionModel.date ?? DateTime.now(),
|
||||
// confirmations: transactionModel.confirmed ? 1 : 0,
|
||||
// to: isSend ? transactionModel.account : address,
|
||||
// from: isSend ? address : transactionModel.account,
|
||||
// );
|
||||
// }
|
||||
|
||||
// return result;
|
||||
return {};
|
||||
_isTransactionUpdating = true;
|
||||
final transactions = await fetchTransactions();
|
||||
transactionHistory.addMany(transactions);
|
||||
await transactionHistory.save();
|
||||
_isTransactionUpdating = false;
|
||||
return true;
|
||||
} catch (_) {
|
||||
_isTransactionUpdating = false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> rescan({required int height}) async => throw UnimplementedError();
|
||||
Future<Map<String, LightningTransactionInfo>> fetchTransactions() async {
|
||||
final sdk = await BreezSDK();
|
||||
|
||||
final payments = await sdk.listPayments(req: ListPaymentsRequest());
|
||||
final Map<String, LightningTransactionInfo> result = {};
|
||||
|
||||
for (var tx in payments) {
|
||||
print(tx.details.data);
|
||||
var details = tx.details.data as LnPaymentDetails;
|
||||
bool isSend = false;
|
||||
if (details.lnAddress?.isNotEmpty ?? false) {
|
||||
isSend = true;
|
||||
}
|
||||
if (details.lnurlMetadata?.isNotEmpty ?? false) {
|
||||
isSend = true;
|
||||
}
|
||||
result[tx.id] = LightningTransactionInfo(
|
||||
WalletType.lightning,
|
||||
isPending: false,
|
||||
id: tx.id,
|
||||
amount: tx.amountMsat ~/ 1000,
|
||||
fee: tx.feeMsat,
|
||||
date: DateTime.fromMillisecondsSinceEpoch(tx.paymentTime * 1000),
|
||||
height: tx.paymentTime,
|
||||
direction: isSend ? TransactionDirection.outgoing : TransactionDirection.incoming,
|
||||
confirmations: 1,
|
||||
);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> rescan({required int height}) async {
|
||||
updateTransactions();
|
||||
}
|
||||
|
||||
Future<void> init() async {
|
||||
await walletAddresses.init();
|
||||
|
|
|
@ -247,8 +247,7 @@ class LightningInvoicePage extends BasePage {
|
|||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertWithTwoActions(
|
||||
// alertTitle: S.of(context).invoice_created,
|
||||
alertTitle: "Invoice created TODO: CW-563",
|
||||
alertTitle: S.of(context).invoice_created,
|
||||
alertContent: state.payload as String,
|
||||
rightButtonText: S.of(context).ok,
|
||||
actionRightButton: () => Navigator.of(context).pop(),
|
||||
|
|
|
@ -1,50 +1,29 @@
|
|||
import 'package:breez_sdk/breez_sdk.dart';
|
||||
import 'package:breez_sdk/bridge_generated.dart';
|
||||
import 'package:cake_wallet/core/auth_service.dart';
|
||||
import 'package:cake_wallet/entities/fiat_currency.dart';
|
||||
import 'package:cake_wallet/entities/template.dart';
|
||||
import 'package:cake_wallet/src/screens/dashboard/widgets/sync_indicator_icon.dart';
|
||||
import 'package:cake_wallet/src/screens/send/widgets/send_card.dart';
|
||||
import 'package:cake_wallet/src/widgets/add_template_button.dart';
|
||||
import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
|
||||
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
|
||||
import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
|
||||
import 'package:cake_wallet/src/widgets/keyboard_done_button.dart';
|
||||
import 'package:cake_wallet/src/widgets/picker.dart';
|
||||
import 'package:cake_wallet/src/widgets/template_tile.dart';
|
||||
import 'package:cake_wallet/themes/extensions/exchange_page_theme.dart';
|
||||
import 'package:cake_wallet/themes/extensions/keyboard_theme.dart';
|
||||
import 'package:cake_wallet/themes/extensions/seed_widget_theme.dart';
|
||||
import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
|
||||
import 'package:cake_wallet/themes/theme_base.dart';
|
||||
import 'package:cake_wallet/utils/payment_request.dart';
|
||||
import 'package:cake_wallet/utils/request_review_handler.dart';
|
||||
import 'package:cake_wallet/utils/responsive_layout_util.dart';
|
||||
import 'package:cake_wallet/view_model/send/output.dart';
|
||||
import 'package:cake_wallet/utils/show_pop_up.dart';
|
||||
import 'package:cw_bitcoin/bitcoin_amount_format.dart';
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||
import 'package:keyboard_actions/keyboard_actions.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:cake_wallet/routes.dart';
|
||||
import 'package:cake_wallet/view_model/send/send_view_model.dart';
|
||||
import 'package:cake_wallet/core/execution_state.dart';
|
||||
import 'package:cake_wallet/src/screens/base_page.dart';
|
||||
import 'package:cake_wallet/src/widgets/primary_button.dart';
|
||||
import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
|
||||
import 'package:cake_wallet/src/widgets/trail_button.dart';
|
||||
import 'package:cake_wallet/utils/show_pop_up.dart';
|
||||
import 'package:cake_wallet/view_model/send/send_view_model_state.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
|
||||
import 'package:cake_wallet/src/screens/send/widgets/confirm_sending_alert.dart';
|
||||
import 'package:smooth_page_indicator/smooth_page_indicator.dart';
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
|
||||
class LightningSendConfirmPage extends BasePage {
|
||||
LightningSendConfirmPage({this.invoice}) : _formKey = GlobalKey<FormState>();
|
||||
LightningSendConfirmPage({required this.invoice}) : _formKey = GlobalKey<FormState>();
|
||||
|
||||
final GlobalKey<FormState> _formKey;
|
||||
final controller = PageController(initialPage: 0);
|
||||
LNInvoice? invoice;
|
||||
LNInvoice invoice;
|
||||
|
||||
final bolt11Controller = TextEditingController();
|
||||
final _bolt11FocusNode = FocusNode();
|
||||
|
@ -114,23 +93,6 @@ class LightningSendConfirmPage extends BasePage {
|
|||
Navigator.of(context).pop();
|
||||
}
|
||||
|
||||
// @override
|
||||
// Widget? middle(BuildContext context) {
|
||||
// final supMiddle = super.middle(context);
|
||||
// return Row(
|
||||
// mainAxisAlignment: MainAxisAlignment.center,
|
||||
// children: [
|
||||
// Padding(
|
||||
// padding: const EdgeInsets.only(right: 8.0),
|
||||
// child: Observer(
|
||||
// builder: (_) => SyncIndicatorIcon(isSynced: sendViewModel.isReadyForSend),
|
||||
// ),
|
||||
// ),
|
||||
// if (supMiddle != null) supMiddle
|
||||
// ],
|
||||
// );
|
||||
// }
|
||||
|
||||
@override
|
||||
Widget body(BuildContext context) {
|
||||
_setEffects(context);
|
||||
|
@ -176,23 +138,81 @@ class LightningSendConfirmPage extends BasePage {
|
|||
child: Observer(builder: (_) {
|
||||
return Padding(
|
||||
padding: EdgeInsets.fromLTRB(24, 120, 24, 0),
|
||||
child: BaseTextFormField(
|
||||
controller: bolt11Controller,
|
||||
focusNode: _bolt11FocusNode,
|
||||
textInputAction: TextInputAction.next,
|
||||
borderColor: Theme.of(context)
|
||||
.extension<ExchangePageTheme>()!
|
||||
.textFieldBorderTopPanelColor,
|
||||
suffixIcon: SizedBox(width: 36),
|
||||
hintText: S.of(context).invoice_details,
|
||||
placeholderTextStyle: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Theme.of(context).extension<ExchangePageTheme>()!.hintTextColor,
|
||||
),
|
||||
textStyle:
|
||||
TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Colors.white),
|
||||
validator: null,
|
||||
child: Column(
|
||||
children: [
|
||||
BaseTextFormField(
|
||||
enabled: false,
|
||||
borderColor: Theme.of(context)
|
||||
.extension<ExchangePageTheme>()!
|
||||
.textFieldBorderTopPanelColor,
|
||||
suffixIcon: SizedBox(width: 36),
|
||||
initialValue: "${S.of(context).invoice}: ${invoice.bolt11}",
|
||||
placeholderTextStyle: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Theme.of(context).extension<ExchangePageTheme>()!.hintTextColor,
|
||||
),
|
||||
textStyle: TextStyle(
|
||||
fontSize: 16, fontWeight: FontWeight.w600, color: Colors.white),
|
||||
validator: null,
|
||||
),
|
||||
SizedBox(height: 24),
|
||||
BaseTextFormField(
|
||||
enabled: false,
|
||||
borderColor: Theme.of(context)
|
||||
.extension<ExchangePageTheme>()!
|
||||
.textFieldBorderTopPanelColor,
|
||||
suffixIcon: SizedBox(width: 36),
|
||||
initialValue:
|
||||
"sats: ${bitcoinAmountToLightningString(amount: (invoice.amountMsat ?? 0) ~/ 1000)}",
|
||||
placeholderTextStyle: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Theme.of(context).extension<ExchangePageTheme>()!.hintTextColor,
|
||||
),
|
||||
textStyle: TextStyle(
|
||||
fontSize: 16, fontWeight: FontWeight.w600, color: Colors.white),
|
||||
validator: null,
|
||||
),
|
||||
SizedBox(height: 24),
|
||||
BaseTextFormField(
|
||||
enabled: false,
|
||||
initialValue: "USD: ${invoice.amountMsat}",
|
||||
borderColor: Theme.of(context)
|
||||
.extension<ExchangePageTheme>()!
|
||||
.textFieldBorderTopPanelColor,
|
||||
suffixIcon: SizedBox(width: 36),
|
||||
placeholderTextStyle: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Theme.of(context).extension<ExchangePageTheme>()!.hintTextColor,
|
||||
),
|
||||
textStyle: TextStyle(
|
||||
fontSize: 16, fontWeight: FontWeight.w600, color: Colors.white),
|
||||
validator: null,
|
||||
),
|
||||
SizedBox(height: 24),
|
||||
if (invoice.description?.isNotEmpty ?? false) ...[
|
||||
BaseTextFormField(
|
||||
enabled: false,
|
||||
initialValue: "${S.of(context).description}: ${invoice.description}",
|
||||
textInputAction: TextInputAction.next,
|
||||
borderColor: Theme.of(context)
|
||||
.extension<ExchangePageTheme>()!
|
||||
.textFieldBorderTopPanelColor,
|
||||
suffixIcon: SizedBox(width: 36),
|
||||
placeholderTextStyle: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Theme.of(context).extension<ExchangePageTheme>()!.hintTextColor,
|
||||
),
|
||||
textStyle: TextStyle(
|
||||
fontSize: 16, fontWeight: FontWeight.w600, color: Colors.white),
|
||||
validator: null,
|
||||
),
|
||||
SizedBox(height: 24),
|
||||
],
|
||||
],
|
||||
),
|
||||
);
|
||||
}),
|
||||
|
@ -201,27 +221,36 @@ class LightningSendConfirmPage extends BasePage {
|
|||
bottomSection: Observer(builder: (_) {
|
||||
return Column(
|
||||
children: <Widget>[
|
||||
// Padding(
|
||||
// padding: EdgeInsets.only(bottom: 15),
|
||||
// child: Center(
|
||||
// child: Text(
|
||||
// S.of(context).anonpay_description("an invoice", "pay"),
|
||||
// textAlign: TextAlign.center,
|
||||
// style: TextStyle(
|
||||
// color: Theme.of(context)
|
||||
// .extension<ExchangePageTheme>()!
|
||||
// .receiveAmountColor,
|
||||
// fontWeight: FontWeight.w500,
|
||||
// fontSize: 12),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
LoadingPrimaryButton(
|
||||
text: S.of(context).send,
|
||||
onPressed: () async {
|
||||
FocusScope.of(context).unfocus();
|
||||
// sendViewModel.send(bolt11Controller.text);
|
||||
final sdk = await BreezSDK();
|
||||
try {
|
||||
final sdk = await BreezSDK();
|
||||
await sdk.sendPayment(req: SendPaymentRequest(bolt11: invoice.bolt11));
|
||||
showPopUp<void>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertWithOneAction(
|
||||
alertTitle: '',
|
||||
alertContent: S
|
||||
.of(context)
|
||||
.send_success(CryptoCurrency.btc.toString()),
|
||||
buttonText: S.of(context).ok,
|
||||
buttonAction: () {
|
||||
Navigator.of(context).pop();
|
||||
});
|
||||
});
|
||||
} catch (e) {
|
||||
showPopUp<void>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertWithOneAction(
|
||||
alertTitle: S.of(context).error,
|
||||
alertContent: e.toString(),
|
||||
buttonText: S.of(context).ok,
|
||||
buttonAction: () => Navigator.of(context).pop());
|
||||
});
|
||||
}
|
||||
},
|
||||
color: Theme.of(context).primaryColor,
|
||||
textColor: Colors.white,
|
||||
|
@ -246,80 +275,6 @@ class LightningSendConfirmPage extends BasePage {
|
|||
return;
|
||||
}
|
||||
|
||||
// reaction((_) => sendViewModel.state, (ExecutionState state) {
|
||||
// if (state is FailureState) {
|
||||
// WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
// showPopUp<void>(
|
||||
// context: context,
|
||||
// builder: (BuildContext context) {
|
||||
// return AlertWithOneAction(
|
||||
// alertTitle: S.of(context).error,
|
||||
// alertContent: state.error,
|
||||
// buttonText: S.of(context).ok,
|
||||
// buttonAction: () => Navigator.of(context).pop());
|
||||
// });
|
||||
// });
|
||||
// }
|
||||
|
||||
// if (state is ExecutedSuccessfullyState) {
|
||||
// WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
// if (context.mounted) {
|
||||
// showPopUp<void>(
|
||||
// context: context,
|
||||
// builder: (BuildContext _dialogContext) {
|
||||
// return ConfirmSendingAlert(
|
||||
// alertTitle: S.of(_dialogContext).confirm_sending,
|
||||
// amount: S.of(_dialogContext).send_amount,
|
||||
// amountValue: sendViewModel.pendingTransaction!.amountFormatted,
|
||||
// fiatAmountValue: sendViewModel.pendingTransactionFiatAmountFormatted,
|
||||
// fee: S.of(_dialogContext).send_fee,
|
||||
// feeValue: sendViewModel.pendingTransaction!.feeFormatted,
|
||||
// feeFiatAmount: sendViewModel.pendingTransactionFeeFiatAmountFormatted,
|
||||
// outputs: sendViewModel.outputs,
|
||||
// rightButtonText: S.of(_dialogContext).send,
|
||||
// leftButtonText: S.of(_dialogContext).cancel,
|
||||
// actionRightButton: () {
|
||||
// Navigator.of(_dialogContext).pop();
|
||||
// sendViewModel.commitTransaction();
|
||||
// showPopUp<void>(
|
||||
// context: context,
|
||||
// builder: (BuildContext _dialogContext) {
|
||||
// return Observer(builder: (_) {
|
||||
// final state = sendViewModel.state;
|
||||
|
||||
// if (state is FailureState) {
|
||||
// Navigator.of(_dialogContext).pop();
|
||||
// }
|
||||
|
||||
// if (state is TransactionCommitted) {
|
||||
// return AlertWithOneAction(
|
||||
// alertTitle: '',
|
||||
// alertContent: S.of(_dialogContext).send_success(
|
||||
// sendViewModel.selectedCryptoCurrency.toString()),
|
||||
// buttonText: S.of(_dialogContext).ok,
|
||||
// buttonAction: () {
|
||||
// Navigator.of(_dialogContext).pop();
|
||||
// RequestReviewHandler.requestReview();
|
||||
// });
|
||||
// }
|
||||
|
||||
// return Offstage();
|
||||
// });
|
||||
// });
|
||||
// },
|
||||
// actionLeftButton: () => Navigator.of(_dialogContext).pop());
|
||||
// });
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
|
||||
// if (state is TransactionCommitted) {
|
||||
// WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
// sendViewModel.clearOutputs();
|
||||
// });
|
||||
// }
|
||||
// });
|
||||
|
||||
_effectsInstalled = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -160,71 +160,57 @@ class LightningSendPage extends BasePage {
|
|||
),
|
||||
)
|
||||
: null,
|
||||
child: Observer(builder: (_) {
|
||||
return Padding(
|
||||
padding: EdgeInsets.fromLTRB(24, 120, 24, 0),
|
||||
child: BaseTextFormField(
|
||||
controller: bolt11Controller,
|
||||
focusNode: _bolt11FocusNode,
|
||||
textInputAction: TextInputAction.next,
|
||||
borderColor: Theme.of(context)
|
||||
.extension<ExchangePageTheme>()!
|
||||
.textFieldBorderTopPanelColor,
|
||||
suffixIcon: SizedBox(width: 36),
|
||||
hintText: S.of(context).invoice_details,
|
||||
placeholderTextStyle: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Theme.of(context).extension<ExchangePageTheme>()!.hintTextColor,
|
||||
child: Padding(
|
||||
padding: EdgeInsets.fromLTRB(24, 120, 24, 0),
|
||||
child: Column(
|
||||
children: [
|
||||
BaseTextFormField(
|
||||
controller: bolt11Controller,
|
||||
focusNode: _bolt11FocusNode,
|
||||
textInputAction: TextInputAction.next,
|
||||
borderColor: Theme.of(context)
|
||||
.extension<ExchangePageTheme>()!
|
||||
.textFieldBorderTopPanelColor,
|
||||
suffixIcon: SizedBox(width: 36),
|
||||
hintText: S.of(context).invoice_details,
|
||||
placeholderTextStyle: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Theme.of(context).extension<ExchangePageTheme>()!.hintTextColor,
|
||||
),
|
||||
textStyle:
|
||||
TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Colors.white),
|
||||
validator: null,
|
||||
),
|
||||
textStyle:
|
||||
TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Colors.white),
|
||||
validator: null,
|
||||
),
|
||||
);
|
||||
}),
|
||||
SizedBox(height: 24),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
bottomSectionPadding: EdgeInsets.only(left: 24, right: 24, bottom: 24),
|
||||
bottomSection: Observer(builder: (_) {
|
||||
return Column(
|
||||
children: <Widget>[
|
||||
// Padding(
|
||||
// padding: EdgeInsets.only(bottom: 15),
|
||||
// child: Center(
|
||||
// child: Text(
|
||||
// S.of(context).anonpay_description("an invoice", "pay"),
|
||||
// textAlign: TextAlign.center,
|
||||
// style: TextStyle(
|
||||
// color: Theme.of(context)
|
||||
// .extension<ExchangePageTheme>()!
|
||||
// .receiveAmountColor,
|
||||
// fontWeight: FontWeight.w500,
|
||||
// fontSize: 12),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
LoadingPrimaryButton(
|
||||
text: S.of(context).paste,
|
||||
color: Theme.of(context).primaryColor,
|
||||
textColor: Colors.white,
|
||||
isLoading: false,
|
||||
onPressed: () async {
|
||||
processInput(context);
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
LoadingPrimaryButton(
|
||||
text: S.of(context).scan_qr_code,
|
||||
color: Theme.of(context).primaryColor,
|
||||
textColor: Colors.white,
|
||||
isLoading: false,
|
||||
onPressed: () async {
|
||||
processInput(context);
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
}),
|
||||
bottomSection: Column(
|
||||
children: <Widget>[
|
||||
LoadingPrimaryButton(
|
||||
text: S.of(context).paste,
|
||||
color: Theme.of(context).primaryColor,
|
||||
textColor: Colors.white,
|
||||
isLoading: false,
|
||||
onPressed: () async {
|
||||
processInput(context);
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
LoadingPrimaryButton(
|
||||
text: S.of(context).scan_qr_code,
|
||||
color: Theme.of(context).primaryColor,
|
||||
textColor: Colors.white,
|
||||
isLoading: false,
|
||||
onPressed: () async {
|
||||
processInput(context);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
|
@ -142,7 +142,7 @@ abstract class BalanceViewModelBase with Store {
|
|||
case WalletType.banano:
|
||||
return S.current.receivable_balance;
|
||||
case WalletType.lightning:
|
||||
return "CW-563 Max Receivable";
|
||||
return S.current.max_receivable;
|
||||
default:
|
||||
return S.current.unconfirmed;
|
||||
}
|
||||
|
|
|
@ -92,10 +92,9 @@ abstract class LightningViewModelBase with Store {
|
|||
amountMsat: 1000,
|
||||
description: 'limits',
|
||||
);
|
||||
// final res = await sdk.receivePayment(req: req);
|
||||
// print(res.lnInvoice.);
|
||||
// return res.lnInvoice.bolt11;
|
||||
final res = await sdk.receivePayment(req: req);
|
||||
// sdk.
|
||||
// TODO: CW-563 figure out how to get the limits
|
||||
return ['0', '20000'];
|
||||
return [(res.openingFeeMsat).toString(), '20000'];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -377,8 +377,6 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
|
|||
case WalletType.polygon:
|
||||
return polygon!.createPolygonTransactionCredentials(outputs,
|
||||
priority: priority!, currency: selectedCryptoCurrency);
|
||||
case WalletType.lightning:
|
||||
throw Exception("TODO: CW-563 Implement lightning tx send!");
|
||||
default:
|
||||
throw Exception('Unexpected wallet type: ${wallet.type}');
|
||||
}
|
||||
|
|
|
@ -80,6 +80,16 @@ class BitcoinURI extends PaymentURI {
|
|||
}
|
||||
}
|
||||
|
||||
class LightningURI extends PaymentURI {
|
||||
LightningURI({required String amount, required String address})
|
||||
: super(amount: amount, address: address);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
throw Exception('TODO: Not implemented');
|
||||
}
|
||||
}
|
||||
|
||||
class LitecoinURI extends PaymentURI {
|
||||
LitecoinURI({required String amount, required String address})
|
||||
: super(amount: amount, address: address);
|
||||
|
@ -238,8 +248,7 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo
|
|||
}
|
||||
|
||||
if (wallet.type == WalletType.lightning) {
|
||||
// TODO: CW-563
|
||||
return BitcoinURI(amount: amount, address: address.address);
|
||||
return LightningURI(amount: amount, address: address.address);
|
||||
}
|
||||
|
||||
if (wallet.type == WalletType.litecoin) {
|
||||
|
|
|
@ -312,6 +312,8 @@
|
|||
"incorrect_seed": "النص الذي تم إدخاله غير صالح.",
|
||||
"introducing_cake_pay": "نقدم لكم Cake Pay!",
|
||||
"invalid_input": "مدخل غير صالح",
|
||||
"invoice": "فاتورة",
|
||||
"invoice_created": "الفاتورة التي تم إنشاؤها",
|
||||
"invoice_details": "تفاصيل الفاتورة",
|
||||
"is_percentage": "يكون",
|
||||
"last_30_days": "آخر 30 يومًا",
|
||||
|
@ -329,6 +331,7 @@
|
|||
"market_place": "منصة التجارة",
|
||||
"matrix_green_dark_theme": "موضوع ماتريكس الأخضر الداكن",
|
||||
"max_amount": "الحد الأقصى: ${value}",
|
||||
"max_receivable": "ماكس القبض",
|
||||
"max_value": "الحد الأقصى: ${value} ${currency}",
|
||||
"memo": "مذكرة:",
|
||||
"message": "ﺔﻟﺎﺳﺭ",
|
||||
|
|
|
@ -312,6 +312,8 @@
|
|||
"incorrect_seed": "Въведеният текст е невалиден.",
|
||||
"introducing_cake_pay": "Запознайте се с Cake Pay!",
|
||||
"invalid_input": "Невалиден вход",
|
||||
"invoice": "Фактура",
|
||||
"invoice_created": "Създадена фактура",
|
||||
"invoice_details": "IДанни за фактура",
|
||||
"is_percentage": "е",
|
||||
"last_30_days": "Последните 30 дни",
|
||||
|
@ -329,6 +331,7 @@
|
|||
"market_place": "Магазин",
|
||||
"matrix_green_dark_theme": "Зелена тъмна тема Matrix",
|
||||
"max_amount": "Макс: ${value}",
|
||||
"max_receivable": "Макс вземания",
|
||||
"max_value": "Макс: ${value} ${currency}",
|
||||
"memo": "Мемо:",
|
||||
"message": "Съобщение",
|
||||
|
|
|
@ -312,6 +312,8 @@
|
|||
"incorrect_seed": "Zadaný text není správný.",
|
||||
"introducing_cake_pay": "Představujeme Cake Pay!",
|
||||
"invalid_input": "Neplatný vstup",
|
||||
"invoice": "Faktura",
|
||||
"invoice_created": "Faktura vytvořená",
|
||||
"invoice_details": "detaily faktury",
|
||||
"is_percentage": "je",
|
||||
"last_30_days": "Posledních 30 dnů",
|
||||
|
@ -329,6 +331,7 @@
|
|||
"market_place": "Obchod",
|
||||
"matrix_green_dark_theme": "Tmavé téma Matrix Green",
|
||||
"max_amount": "Max: ${value}",
|
||||
"max_receivable": "Max pohledávka",
|
||||
"max_value": "Max: ${value} ${currency}",
|
||||
"memo": "Memo:",
|
||||
"message": "Zpráva",
|
||||
|
|
|
@ -312,6 +312,8 @@
|
|||
"incorrect_seed": "Der eingegebene Text ist ungültig.",
|
||||
"introducing_cake_pay": "Einführung von Cake Pay!",
|
||||
"invalid_input": "Ungültige Eingabe",
|
||||
"invoice": "Rechnung",
|
||||
"invoice_created": "Rechnung erstellt",
|
||||
"invoice_details": "Rechnungs-Details",
|
||||
"is_percentage": "ist",
|
||||
"last_30_days": "Letzte 30 Tage",
|
||||
|
@ -329,6 +331,7 @@
|
|||
"market_place": "Marktplatz",
|
||||
"matrix_green_dark_theme": "Matrix Green Dark Theme",
|
||||
"max_amount": "Max: ${value}",
|
||||
"max_receivable": "Max. Forderung",
|
||||
"max_value": "Max: ${value} ${currency}",
|
||||
"memo": "Memo:",
|
||||
"message": "Nachricht",
|
||||
|
|
|
@ -312,6 +312,8 @@
|
|||
"incorrect_seed": "The text entered is not valid.",
|
||||
"introducing_cake_pay": "Introducing Cake Pay!",
|
||||
"invalid_input": "Invalid input",
|
||||
"invoice": "Invoice",
|
||||
"invoice_created": "Invoice created",
|
||||
"invoice_details": "Invoice details",
|
||||
"is_percentage": "is",
|
||||
"last_30_days": "Last 30 days",
|
||||
|
@ -329,6 +331,7 @@
|
|||
"market_place": "Marketplace",
|
||||
"matrix_green_dark_theme": "Matrix Green Dark Theme",
|
||||
"max_amount": "Max: ${value}",
|
||||
"max_receivable": "Max Receivable",
|
||||
"max_value": "Max: ${value} ${currency}",
|
||||
"memo": "Memo:",
|
||||
"message": "Message",
|
||||
|
|
|
@ -312,6 +312,8 @@
|
|||
"incorrect_seed": "El texto ingresado no es válido.",
|
||||
"introducing_cake_pay": "¡Presentamos Cake Pay!",
|
||||
"invalid_input": "Entrada inválida",
|
||||
"invoice": "Factura",
|
||||
"invoice_created": "Factura creada",
|
||||
"invoice_details": "Detalles de la factura",
|
||||
"is_percentage": "es",
|
||||
"last_30_days": "Últimos 30 días",
|
||||
|
@ -329,6 +331,7 @@
|
|||
"market_place": "Mercado",
|
||||
"matrix_green_dark_theme": "Matrix verde oscuro tema",
|
||||
"max_amount": "Máx: ${value}",
|
||||
"max_receivable": "Max por cobrar",
|
||||
"max_value": "Max: ${value} ${currency}",
|
||||
"memo": "Memorándum:",
|
||||
"message": "Mensaje",
|
||||
|
|
|
@ -312,6 +312,8 @@
|
|||
"incorrect_seed": "Le texte entré est invalide.",
|
||||
"introducing_cake_pay": "Présentation de Cake Pay !",
|
||||
"invalid_input": "Entrée invalide",
|
||||
"invoice": "Facture",
|
||||
"invoice_created": "Facture créée",
|
||||
"invoice_details": "Détails de la facture",
|
||||
"is_percentage": "est",
|
||||
"last_30_days": "30 derniers jours",
|
||||
|
@ -329,6 +331,7 @@
|
|||
"market_place": "Place de marché",
|
||||
"matrix_green_dark_theme": "Thème Matrix Green Dark",
|
||||
"max_amount": "Max : ${value}",
|
||||
"max_receivable": "Max à recevoir",
|
||||
"max_value": "Max: ${value} ${currency}",
|
||||
"memo": "Mémo :",
|
||||
"message": "Message",
|
||||
|
|
|
@ -312,6 +312,8 @@
|
|||
"incorrect_seed": "rubutun da aka shigar ba shi da inganci.",
|
||||
"introducing_cake_pay": "Gabatar da Cake Pay!",
|
||||
"invalid_input": "Shigar da ba daidai ba",
|
||||
"invoice": "Daftari",
|
||||
"invoice_created": "Invoice ya kirkira",
|
||||
"invoice_details": "Bayanin wadannan",
|
||||
"is_percentage": "shine",
|
||||
"last_30_days": "Kwanaki 30 na ƙarshe",
|
||||
|
@ -329,6 +331,7 @@
|
|||
"market_place": "Kasuwa",
|
||||
"matrix_green_dark_theme": "Matrix Green Dark Jigo",
|
||||
"max_amount": "Max: ${value}",
|
||||
"max_receivable": "Max mai karba",
|
||||
"max_value": "Max: ${value} ${currency}",
|
||||
"memo": "Memo:",
|
||||
"message": "Sako",
|
||||
|
|
|
@ -312,6 +312,8 @@
|
|||
"incorrect_seed": "दर्ज किया गया पाठ मान्य नहीं है।",
|
||||
"introducing_cake_pay": "परिचय Cake Pay!",
|
||||
"invalid_input": "अमान्य निवेश",
|
||||
"invoice": "चालान",
|
||||
"invoice_created": "चालान बनाया गया",
|
||||
"invoice_details": "चालान विवरण",
|
||||
"is_percentage": "है",
|
||||
"last_30_days": "पिछले 30 दिन",
|
||||
|
@ -329,6 +331,7 @@
|
|||
"market_place": "मार्केटप्लेस",
|
||||
"matrix_green_dark_theme": "मैट्रिक्स ग्रीन डार्क थीम",
|
||||
"max_amount": "अधिकतम: ${value}",
|
||||
"max_receivable": "अधिकतम प्राप्य",
|
||||
"max_value": "मैक्स: ${value} ${currency}",
|
||||
"memo": "ज्ञापन:",
|
||||
"message": "संदेश",
|
||||
|
|
|
@ -312,6 +312,8 @@
|
|||
"incorrect_seed": "Uneseni tekst nije valjan.",
|
||||
"introducing_cake_pay": "Predstavljamo Cake Pay!",
|
||||
"invalid_input": "Pogrešan unos",
|
||||
"invoice": "Dostavnica",
|
||||
"invoice_created": "Račun stvoren",
|
||||
"invoice_details": "Podaci o fakturi",
|
||||
"is_percentage": "je",
|
||||
"last_30_days": "Zadnjih 30 dana",
|
||||
|
@ -329,6 +331,7 @@
|
|||
"market_place": "Tržnica",
|
||||
"matrix_green_dark_theme": "Matrix Green Dark Theme",
|
||||
"max_amount": "Maksimum: ${value}",
|
||||
"max_receivable": "Maksimalno potraživanje",
|
||||
"max_value": "Maks.: ${value} ${currency}",
|
||||
"memo": "Memo:",
|
||||
"message": "Poruka",
|
||||
|
|
|
@ -312,6 +312,8 @@
|
|||
"incorrect_seed": "Teks yang dimasukkan tidak valid.",
|
||||
"introducing_cake_pay": "Perkenalkan Cake Pay!",
|
||||
"invalid_input": "Masukan tidak valid",
|
||||
"invoice": "Faktur",
|
||||
"invoice_created": "Faktur dibuat",
|
||||
"invoice_details": "Detail faktur",
|
||||
"is_percentage": "adalah",
|
||||
"last_30_days": "30 hari terakhir",
|
||||
|
@ -329,6 +331,7 @@
|
|||
"market_place": "Pasar",
|
||||
"matrix_green_dark_theme": "Tema Matrix Green Dark",
|
||||
"max_amount": "Max: ${value}",
|
||||
"max_receivable": "Piutang maksimum",
|
||||
"max_value": "Max: ${value} ${currency}",
|
||||
"memo": "Memo:",
|
||||
"message": "Pesan",
|
||||
|
|
|
@ -313,6 +313,8 @@
|
|||
"incorrect_seed": "Il testo inserito non è valido.",
|
||||
"introducing_cake_pay": "Presentazione di Cake Pay!",
|
||||
"invalid_input": "Inserimento non valido",
|
||||
"invoice": "Fattura",
|
||||
"invoice_created": "Fattura creata",
|
||||
"invoice_details": "Dettagli della fattura",
|
||||
"is_percentage": "è",
|
||||
"last_30_days": "Ultimi 30 giorni",
|
||||
|
@ -330,6 +332,7 @@
|
|||
"market_place": "Mercato",
|
||||
"matrix_green_dark_theme": "Tema Matrix verde scuro",
|
||||
"max_amount": "Max: ${value}",
|
||||
"max_receivable": "Ricevibile massimo",
|
||||
"max_value": "Max: ${value} ${currency}",
|
||||
"memo": "Memo:",
|
||||
"message": "Messaggio",
|
||||
|
|
|
@ -313,6 +313,8 @@
|
|||
"incorrect_seed": "入力されたテキストは無効です。",
|
||||
"introducing_cake_pay": "序章Cake Pay!",
|
||||
"invalid_input": "無効入力",
|
||||
"invoice": "請求書",
|
||||
"invoice_created": "作成された請求書",
|
||||
"invoice_details": "請求の詳細",
|
||||
"is_percentage": "is",
|
||||
"last_30_days": "過去30日",
|
||||
|
@ -330,6 +332,7 @@
|
|||
"market_place": "Marketplace",
|
||||
"matrix_green_dark_theme": "マトリックスグリーンダークテーマ",
|
||||
"max_amount": "最大: ${value}",
|
||||
"max_receivable": "最大売掛金",
|
||||
"max_value": "マックス: ${value} ${currency}",
|
||||
"memo": "メモ:",
|
||||
"message": "メッセージ",
|
||||
|
|
|
@ -312,6 +312,8 @@
|
|||
"incorrect_seed": "입력하신 텍스트가 유효하지 않습니다.",
|
||||
"introducing_cake_pay": "소개 Cake Pay!",
|
||||
"invalid_input": "잘못된 입력",
|
||||
"invoice": "송장",
|
||||
"invoice_created": "송장 생성",
|
||||
"invoice_details": "인보이스 세부정보",
|
||||
"is_percentage": "이다",
|
||||
"last_30_days": "지난 30일",
|
||||
|
@ -329,6 +331,7 @@
|
|||
"market_place": "마켓플레이스",
|
||||
"matrix_green_dark_theme": "매트릭스 그린 다크 테마",
|
||||
"max_amount": "최대: ${value}",
|
||||
"max_receivable": "MAX 미수금",
|
||||
"max_value": "맥스: ${value} ${currency}",
|
||||
"memo": "메모:",
|
||||
"message": "메시지",
|
||||
|
|
|
@ -312,6 +312,8 @@
|
|||
"incorrect_seed": "ထည့်သွင်းထားသော စာသားသည် မမှန်ကန်ပါ။",
|
||||
"introducing_cake_pay": "Cake Pay ကို မိတ်ဆက်ခြင်း။",
|
||||
"invalid_input": "ထည့်သွင်းမှု မမှန်ကန်ပါ။",
|
||||
"invoice": "ဝယ်ကုန်စာရင်း",
|
||||
"invoice_created": "ငွေတောင်းခံလွှာကိုဖန်တီးခဲ့သည်",
|
||||
"invoice_details": "ပြေစာအသေးစိတ်",
|
||||
"is_percentage": "သည်",
|
||||
"last_30_days": "လွန်ခဲ့သော ရက် 30",
|
||||
|
@ -329,6 +331,7 @@
|
|||
"market_place": "ဈေး",
|
||||
"matrix_green_dark_theme": "Matrix Green Dark အပြင်အဆင်",
|
||||
"max_amount": "အများဆုံး- ${value}",
|
||||
"max_receivable": "max ကိုလက်ခံရရှိ",
|
||||
"max_value": "အများဆုံး- ${value} ${currency}",
|
||||
"memo": "မှတ်စုတို:",
|
||||
"message": "မက်ဆေ့ချ်",
|
||||
|
|
|
@ -312,6 +312,8 @@
|
|||
"incorrect_seed": "De ingevoerde tekst is niet geldig.",
|
||||
"introducing_cake_pay": "Introductie van Cake Pay!",
|
||||
"invalid_input": "Ongeldige invoer",
|
||||
"invoice": "Factuur",
|
||||
"invoice_created": "Factuur gemaakt",
|
||||
"invoice_details": "Factuurgegevens",
|
||||
"is_percentage": "is",
|
||||
"last_30_days": "Laatste 30 dagen",
|
||||
|
@ -329,6 +331,7 @@
|
|||
"market_place": "Marktplaats",
|
||||
"matrix_green_dark_theme": "Matrix groen donker thema",
|
||||
"max_amount": "Max: ${value}",
|
||||
"max_receivable": "Max -vordering",
|
||||
"max_value": "Max: ${value} ${currency}",
|
||||
"memo": "Memo:",
|
||||
"message": "Bericht",
|
||||
|
|
|
@ -312,6 +312,8 @@
|
|||
"incorrect_seed": "Wprowadzony seed jest nieprawidłowy.",
|
||||
"introducing_cake_pay": "Przedstawiamy Cake Pay!",
|
||||
"invalid_input": "Nieprawidłowe dane wejściowe",
|
||||
"invoice": "Faktura",
|
||||
"invoice_created": "Utworzona faktura",
|
||||
"invoice_details": "Dane do faktury",
|
||||
"is_percentage": "jest",
|
||||
"last_30_days": "Ostatnie 30 dni",
|
||||
|
@ -329,6 +331,7 @@
|
|||
"market_place": "Rynek",
|
||||
"matrix_green_dark_theme": "Matrix Zielony ciemny motyw",
|
||||
"max_amount": "Max: ${value}",
|
||||
"max_receivable": "MAX NECTIVET",
|
||||
"max_value": "Max: ${value} ${currency}",
|
||||
"memo": "Notatka:",
|
||||
"message": "Wiadomość",
|
||||
|
|
|
@ -312,6 +312,8 @@
|
|||
"incorrect_seed": "O texto digitado não é válido.",
|
||||
"introducing_cake_pay": "Apresentando o Cake Pay!",
|
||||
"invalid_input": "Entrada inválida",
|
||||
"invoice": "Fatura",
|
||||
"invoice_created": "Fatura criada",
|
||||
"invoice_details": "Detalhes da fatura",
|
||||
"is_percentage": "é",
|
||||
"last_30_days": "Últimos 30 dias",
|
||||
|
@ -330,6 +332,7 @@
|
|||
"market_place": "Mercado",
|
||||
"matrix_green_dark_theme": "Tema escuro verde matrix",
|
||||
"max_amount": "Máx.: ${valor}",
|
||||
"max_receivable": "Max a receber",
|
||||
"max_value": "Máx: ${value} ${currency}",
|
||||
"memo": "Memorando:",
|
||||
"message": "Mensagem",
|
||||
|
|
|
@ -312,6 +312,8 @@
|
|||
"incorrect_seed": "Введённый текст некорректный.",
|
||||
"introducing_cake_pay": "Представляем Cake Pay!",
|
||||
"invalid_input": "Неверный Ввод",
|
||||
"invoice": "Счет",
|
||||
"invoice_created": "Счет -фактор создан",
|
||||
"invoice_details": "Детали счета",
|
||||
"is_percentage": "есть",
|
||||
"last_30_days": "Последние 30 дней",
|
||||
|
@ -329,6 +331,7 @@
|
|||
"market_place": "Торговая площадка",
|
||||
"matrix_green_dark_theme": "Матрица Зеленая Темная Тема",
|
||||
"max_amount": "Макс.: ${value}",
|
||||
"max_receivable": "Максимальная дебиторская задолженность",
|
||||
"max_value": "Макс: ${value} ${currency}",
|
||||
"memo": "Памятка:",
|
||||
"message": "Сообщение",
|
||||
|
|
|
@ -312,6 +312,8 @@
|
|||
"incorrect_seed": "ข้อความที่ป้อนไม่ถูกต้อง",
|
||||
"introducing_cake_pay": "ยินดีต้อนรับสู่ Cake Pay!",
|
||||
"invalid_input": "อินพุตไม่ถูกต้อง",
|
||||
"invoice": "ใบแจ้งหนี้",
|
||||
"invoice_created": "สร้างใบแจ้งหนี้",
|
||||
"invoice_details": "รายละเอียดใบแจ้งหนี้",
|
||||
"is_percentage": "เป็น",
|
||||
"last_30_days": "30 วันล่าสุด",
|
||||
|
@ -329,6 +331,7 @@
|
|||
"market_place": "ตลาดพื้นที่",
|
||||
"matrix_green_dark_theme": "ธีมเมทริกซ์สีเขียวเข้ม",
|
||||
"max_amount": "จำนวนสูงสุด: ${value}",
|
||||
"max_receivable": "ลูกหนี้สูงสุด",
|
||||
"max_value": "ขั้นสูง: ${value} ${currency}",
|
||||
"memo": "หมายเหตุ:",
|
||||
"message": "ข้อความ",
|
||||
|
|
|
@ -312,6 +312,8 @@
|
|||
"incorrect_seed": "Ang teksto na ipinasok ay hindi wasto.",
|
||||
"introducing_cake_pay": "Ipinakikilala ang cake pay!",
|
||||
"invalid_input": "Di -wastong input",
|
||||
"invoice": "Invoice",
|
||||
"invoice_created": "Nilikha ang Invoice",
|
||||
"invoice_details": "Mga detalye ng invoice",
|
||||
"is_percentage": "ay",
|
||||
"last_30_days": "Huling 30 araw",
|
||||
|
@ -329,6 +331,7 @@
|
|||
"market_place": "Marketplace",
|
||||
"matrix_green_dark_theme": "Matrix Green Madilim na Tema",
|
||||
"max_amount": "Max: ${value}",
|
||||
"max_receivable": "MAX RECEIVABLE",
|
||||
"max_value": "Max: ${value} ${currency}",
|
||||
"memo": "Memo:",
|
||||
"message": "Mensahe",
|
||||
|
|
|
@ -312,6 +312,8 @@
|
|||
"incorrect_seed": "Girilen metin geçerli değil.",
|
||||
"introducing_cake_pay": "Cake Pay ile tanışın!",
|
||||
"invalid_input": "Geçersiz Giriş",
|
||||
"invoice": "Fatura",
|
||||
"invoice_created": "Fatura Oluşturuldu",
|
||||
"invoice_details": "fatura detayları",
|
||||
"is_percentage": "is",
|
||||
"last_30_days": "Son 30 gün",
|
||||
|
@ -329,6 +331,7 @@
|
|||
"market_place": "Pazar Alanı",
|
||||
"matrix_green_dark_theme": "Matrix Yeşil Koyu Tema",
|
||||
"max_amount": "Maks: ${value}",
|
||||
"max_receivable": "Maksimum alacak",
|
||||
"max_value": "En fazla: ${value} ${currency}",
|
||||
"memo": "Memo:",
|
||||
"message": "İleti",
|
||||
|
|
|
@ -312,6 +312,8 @@
|
|||
"incorrect_seed": "Введений текст невірний.",
|
||||
"introducing_cake_pay": "Представляємо Cake Pay!",
|
||||
"invalid_input": "Неправильні дані",
|
||||
"invoice": "Рахунок -фактура",
|
||||
"invoice_created": "Створений рахунок -фактури",
|
||||
"invoice_details": "Реквізити рахунку-фактури",
|
||||
"is_percentage": "є",
|
||||
"last_30_days": "Останні 30 днів",
|
||||
|
@ -329,6 +331,7 @@
|
|||
"market_place": "Ринок",
|
||||
"matrix_green_dark_theme": "Зелена темна тема Matrix",
|
||||
"max_amount": "Макс: ${value}",
|
||||
"max_receivable": "Максимальна дебіторська заборгованість",
|
||||
"max_value": "Макс: ${value} ${currency}",
|
||||
"memo": "Пам’ятка:",
|
||||
"message": "повідомлення",
|
||||
|
|
|
@ -312,6 +312,8 @@
|
|||
"incorrect_seed": "درج کردہ متن درست نہیں ہے۔",
|
||||
"introducing_cake_pay": "Cake پے کا تعارف!",
|
||||
"invalid_input": "غلط ان پٹ",
|
||||
"invoice": "انوائس",
|
||||
"invoice_created": "انوائس تخلیق کیا گیا",
|
||||
"invoice_details": "رسید کی تفصیلات",
|
||||
"is_percentage": "ہے",
|
||||
"last_30_days": "آخری 30 دن",
|
||||
|
@ -329,6 +331,7 @@
|
|||
"market_place": "بازار",
|
||||
"matrix_green_dark_theme": "میٹرکس گرین ڈارک تھیم",
|
||||
"max_amount": "زیادہ سے زیادہ: ${value}",
|
||||
"max_receivable": "زیادہ سے زیادہ قابل وصول",
|
||||
"max_value": "زیادہ سے زیادہ: ${value} ${currency}",
|
||||
"memo": "میمو:",
|
||||
"message": "ﻡﺎﻐﯿﭘ",
|
||||
|
|
|
@ -313,6 +313,8 @@
|
|||
"incorrect_seed": "Ọ̀rọ̀ tí a tẹ̀ kì í ṣe èyí.",
|
||||
"introducing_cake_pay": "Ẹ bá Cake Pay!",
|
||||
"invalid_input": "Iṣawọle ti ko tọ",
|
||||
"invoice": "Iye-owo ọja",
|
||||
"invoice_created": "Risiti da",
|
||||
"invoice_details": "Iru awọn ẹya ọrọ",
|
||||
"is_percentage": "jẹ́",
|
||||
"last_30_days": "Ọ̀jọ̀ mọ́gbọ̀n tó kọjà",
|
||||
|
@ -330,6 +332,7 @@
|
|||
"market_place": "Ọjà",
|
||||
"matrix_green_dark_theme": "Matrix Green Dark Akori",
|
||||
"max_amount": "kò tóbi ju: ${value}",
|
||||
"max_receivable": "Max gba",
|
||||
"max_value": "kò gbọ́dọ̀ tóbi ju ${value} ${currency}",
|
||||
"memo": "Àkọsílẹ̀:",
|
||||
"message": "Ifiranṣẹ",
|
||||
|
|
|
@ -312,6 +312,8 @@
|
|||
"incorrect_seed": "输入的文字无效。",
|
||||
"introducing_cake_pay": "介绍 Cake Pay!",
|
||||
"invalid_input": "输入无效",
|
||||
"invoice": "发票",
|
||||
"invoice_created": "创建了发票",
|
||||
"invoice_details": "发票明细",
|
||||
"is_percentage": "是",
|
||||
"last_30_days": "过去 30 天",
|
||||
|
@ -329,6 +331,7 @@
|
|||
"market_place": "市场",
|
||||
"matrix_green_dark_theme": "矩阵绿暗主题",
|
||||
"max_amount": "最大值: ${value}",
|
||||
"max_receivable": "最大应收",
|
||||
"max_value": "最大: ${value} ${currency}",
|
||||
"memo": "备忘录:",
|
||||
"message": "信息",
|
||||
|
|
Loading…
Reference in a new issue