Merge branch 'dev' into add-compile-graphics-to-configure

# Conflicts:
#	assets/new-ui/link_arrow.svg.vec
This commit is contained in:
Robert Malikowski
2026-03-29 13:36:49 +02:00
47 changed files with 254 additions and 191 deletions
+4 -2
View File
@@ -164,6 +164,8 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
}
}
bool get isLightningInitialized => lightningWallet?.isInitialized == true;
@override
bool get hasRescan => true;
@@ -339,7 +341,7 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
@override
Future<ElectrumBalance> fetchBalances() async {
final balance = await super.fetchBalances();
if (lightningWallet == null) {
if (!isLightningInitialized || lightningWallet == null) {
return balance;
}
@@ -358,7 +360,7 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
@override
@action
Future<void> subscribeForUpdates() async {
if (lightningWallet != null) {
if (isLightningInitialized && lightningWallet != null) {
lightningWallet!.setEventListener(
onTransactionEvent: (tx) async {
if (transactionHistory.transactions[tx.id]?.isPending != tx.isPending) {
@@ -892,7 +892,7 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
}
} on SdkError_NetworkError catch (_) {
} on SdkError_SparkError catch (e) {
if (!e.field0.contains("dns")) rethrow;
if (!e.field0.contains("dns") && !e.field0.contains("TimedOut")) rethrow;
} finally {
lightningAddress ??= lightningWallet!.cachedAddress;
}
@@ -41,6 +41,8 @@ class LightningWallet {
StreamSubscription<LogEntry>? _logSubscription;
bool get isInitialized => _eventStream != null;
void _subscribeToLogStream(File logFile) {
_logSubscription = _logStream?.listen((logEntry) {
logFile.writeAsStringSync("[${logEntry.level}] ${logEntry.line}\n", mode: FileMode.append);
@@ -152,7 +154,7 @@ class LightningWallet {
} on SdkError_NetworkError catch (_) {
return null;
} on SdkError_SparkError catch (e) {
if (!e.field0.contains("dns")) rethrow;
if (!e.field0.contains("dns") && !e.field0.contains("TimedOut")) rethrow;
return null;
}
}
+1 -2
View File
@@ -45,8 +45,7 @@ BigInt parseFixed(String value, int decimals) {
var fraction = (comps.length == 2 ? comps[1] : "0").padRight(decimals, "0");
if (fraction.length > multiplier.length - 1) {
throw FormatException(
"fractional component exceeds decimals, underflow, parseFixed");
throw FormatException("fractional component exceeds decimals, underflow, parseFixed");
}
final wholeValue = BigInt.parse(whole);
+2 -2
View File
@@ -1,7 +1,7 @@
PODS:
- bitbox_flutter (0.0.1):
- Flutter
- breez_sdk_spark_flutter (0.9.1):
- breez_sdk_spark_flutter (0.11.0):
- Flutter
- connectivity_plus (0.0.1):
- Flutter
@@ -303,7 +303,7 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS:
bitbox_flutter: 506f80b961ddf646b0d80cef9f6eadaab96d91b0
breez_sdk_spark_flutter: e96b24d1c0ca1ef7dec122dd7bbf63eb921f97f4
breez_sdk_spark_flutter: e7d0201b7001ff16f85a7c4820592db5728d4c27
connectivity_plus: 2a701ffec2c0ae28a48cf7540e279787e77c447d
CryptoSwift: e64e11850ede528a02a0f3e768cec8e9d92ecb90
cw_decred: 9c0e1df74745b51a1289ec5e91fb9e24b68fa14a
+9 -5
View File
@@ -159,11 +159,15 @@ class _NewHomePageState extends State<NewHomePage> {
builder: (_) {
return Column(
children: [
CoinActionRow(
lightningMode: _lightningMode,
showSwap: widget.dashboardViewModel.isEnabledSwapAction,),
MwebAd(dashboardViewModel: widget.dashboardViewModel,),
],
CoinActionRow(
lightningMode: _lightningMode,
showSwap: widget.dashboardViewModel.isEnabledSwapAction,
walletType: widget.dashboardViewModel.wallet.type,
),
MwebAd(
dashboardViewModel: widget.dashboardViewModel,
),
],
);
},
),
+1 -1
View File
@@ -639,7 +639,7 @@ class _NewSendPageState extends State<NewSendPage> {
output.setFiatAmount(amount);
}
} else {
final isAll = context.mounted && amount != S.of(context).all;
final isAll = mounted && amount != S.of(context).all;
if (output.sendAll && isAll) {
output.sendAll = false;
}
+130 -124
View File
@@ -481,134 +481,140 @@ class _NewSwapPageState extends State<NewSwapPage> {
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisSize: MainAxisSize.max,
children: [
RepaintBoundary(
child: Form(
key: formKey,
child: Column(
children: [
Observer(
builder: (_) => SwapAmountBox(
isReceiverCard: false,
walletSwitcherViewModel: widget.walletSwitcherViewModel,
exchangeViewModel: widget.exchangeViewModel,
onDispose: disposeBestRateSync,
hasAllAmount: widget.exchangeViewModel.hasAllAmount,
allAmount: widget.exchangeViewModel.hasAllAmount
? () => widget.exchangeViewModel.enableSendAllAmount()
: null,
key: depositKey,
title: S.of(context).send,
initialCurrency: widget.exchangeViewModel.depositCurrency,
hasRefundAddress: true,
currencies: widget.exchangeViewModel.depositCurrencies,
onCurrencySelected: (currency) {
if (currency is CryptoCurrency) {
widget.exchangeViewModel
.changeDepositCurrency(currency: currency);
}
},
currencyValueValidator: (value) {
return !widget.exchangeViewModel.isFixedRateMode &&
value != S.of(context).all
? AmountValidator(
isAutovalidate: true,
currency: widget.exchangeViewModel.isFixedRateMode
? widget.exchangeViewModel.receiveCurrency
: widget.exchangeViewModel.depositCurrency,
minValue: widget.exchangeViewModel.limits.min.toString(),
maxValue: widget.exchangeViewModel.limits.max.toString(),
amountParsingProxy:
widget.exchangeViewModel.amountParsingProxy,
).call(value)
: null;
},
addressTextFieldValidator: AddressValidator(
type: widget.exchangeViewModel.depositCurrency),
onPushPasteButton: (context) async {
final clipboard = await Clipboard.getData('text/plain');
widget.exchangeViewModel.depositAddress = clipboard?.text ?? '';
Expanded(
child: RepaintBoundary(
child: Form(
key: formKey,
child: SingleChildScrollView(
physics: ClampingScrollPhysics(),
controller: ModalScrollController.of(context),
child: Column(
children: [
Observer(
builder: (_) => SwapAmountBox(
isReceiverCard: false,
walletSwitcherViewModel: widget.walletSwitcherViewModel,
exchangeViewModel: widget.exchangeViewModel,
onDispose: disposeBestRateSync,
hasAllAmount: widget.exchangeViewModel.hasAllAmount,
allAmount: widget.exchangeViewModel.hasAllAmount
? () => widget.exchangeViewModel.enableSendAllAmount()
: null,
key: depositKey,
title: S.of(context).send,
initialCurrency: widget.exchangeViewModel.depositCurrency,
hasRefundAddress: true,
currencies: widget.exchangeViewModel.depositCurrencies,
onCurrencySelected: (currency) {
if (currency is CryptoCurrency) {
widget.exchangeViewModel
.changeDepositCurrency(currency: currency);
}
},
currencyValueValidator: (value) {
return !widget.exchangeViewModel.isFixedRateMode &&
value != S.of(context).all
? AmountValidator(
isAutovalidate: true,
currency: widget.exchangeViewModel.isFixedRateMode
? widget.exchangeViewModel.receiveCurrency
: widget.exchangeViewModel.depositCurrency,
minValue: widget.exchangeViewModel.limits.min.toString(),
maxValue: widget.exchangeViewModel.limits.max.toString(),
amountParsingProxy:
widget.exchangeViewModel.amountParsingProxy,
).call(value)
: null;
},
addressTextFieldValidator: AddressValidator(
type: widget.exchangeViewModel.depositCurrency),
onPushPasteButton: (context) async {
final clipboard = await Clipboard.getData('text/plain');
widget.exchangeViewModel.depositAddress = clipboard?.text ?? '';
final domain = widget.exchangeViewModel.depositAddress;
widget.exchangeViewModel.depositAddress =
await fetchParsedAddress(context, domain,
widget.exchangeViewModel.depositCurrency);
},
onPushAddressBookButton: (context) async {
final domain = widget.exchangeViewModel.depositAddress;
widget.exchangeViewModel.depositAddress =
await fetchParsedAddress(context, domain,
widget.exchangeViewModel.depositCurrency);
},
),
),
SwapLimitPopup(exchangeViewModel: widget.exchangeViewModel),
Padding(
padding: const EdgeInsets.symmetric(vertical: 12.0),
child: Stack(
alignment: Alignment.center,
children: [
Container(
height: 1,
width: double.infinity,
color: Theme.of(context).colorScheme.surfaceContainerHigh,
final domain = widget.exchangeViewModel.depositAddress;
widget.exchangeViewModel.depositAddress =
await fetchParsedAddress(context, domain,
widget.exchangeViewModel.depositCurrency);
},
onPushAddressBookButton: (context) async {
final domain = widget.exchangeViewModel.depositAddress;
widget.exchangeViewModel.depositAddress =
await fetchParsedAddress(context, domain,
widget.exchangeViewModel.depositCurrency);
},
),
ModernButton.svg(
size: 36,
iconSize: 24,
svgPath: "assets/new-ui/swap_amounts.svg",
onPressed: widget.exchangeViewModel.reverseSwapDirection,
),
SwapLimitPopup(exchangeViewModel: widget.exchangeViewModel),
Padding(
padding: const EdgeInsets.symmetric(vertical: 12.0),
child: Stack(
alignment: Alignment.center,
children: [
Container(
height: 1,
width: double.infinity,
color: Theme.of(context).colorScheme.surfaceContainerHigh,
),
ModernButton.svg(
size: 36,
iconSize: 24,
svgPath: "assets/new-ui/swap_amounts.svg",
onPressed: widget.exchangeViewModel.reverseSwapDirection,
),
],
),
],
),
),
Observer(
builder: (_) => SwapAmountBox(
isReceiverCard: true,
walletSwitcherViewModel: widget.walletSwitcherViewModel,
exchangeViewModel: widget.exchangeViewModel,
onDispose: disposeBestRateSync,
key: receiveKey,
title: S.of(context).receive,
initialCurrency: widget.exchangeViewModel.receiveCurrency,
currencies: widget.exchangeViewModel.receiveCurrencies,
onCurrencySelected: (currency) {
if (currency is CryptoCurrency) {
widget.exchangeViewModel
.changeReceiveCurrency(currency: currency);
}
},
currencyValueValidator: (value) {
return widget.exchangeViewModel.isFixedRateMode
? AmountValidator(
isAutovalidate: true,
currency: widget.exchangeViewModel.receiveCurrency,
minValue: widget.exchangeViewModel.limits.min.toString(),
maxValue: widget.exchangeViewModel.limits.max.toString(),
amountParsingProxy:
widget.exchangeViewModel.amountParsingProxy,
).call(value)
: null;
},
addressTextFieldValidator: AddressValidator(
type: widget.exchangeViewModel.receiveCurrency),
onPushPasteButton: (context) async {
final clipboard = await Clipboard.getData('text/plain');
widget.exchangeViewModel.receiveAddress = clipboard?.text ?? '';
),
Observer(
builder: (_) => SwapAmountBox(
isReceiverCard: true,
walletSwitcherViewModel: widget.walletSwitcherViewModel,
exchangeViewModel: widget.exchangeViewModel,
onDispose: disposeBestRateSync,
key: receiveKey,
title: S.of(context).receive,
initialCurrency: widget.exchangeViewModel.receiveCurrency,
currencies: widget.exchangeViewModel.receiveCurrencies,
onCurrencySelected: (currency) {
if (currency is CryptoCurrency) {
widget.exchangeViewModel
.changeReceiveCurrency(currency: currency);
}
},
currencyValueValidator: (value) {
return widget.exchangeViewModel.isFixedRateMode
? AmountValidator(
isAutovalidate: true,
currency: widget.exchangeViewModel.receiveCurrency,
minValue: widget.exchangeViewModel.limits.min.toString(),
maxValue: widget.exchangeViewModel.limits.max.toString(),
amountParsingProxy:
widget.exchangeViewModel.amountParsingProxy,
).call(value)
: null;
},
addressTextFieldValidator: AddressValidator(
type: widget.exchangeViewModel.receiveCurrency),
onPushPasteButton: (context) async {
final clipboard = await Clipboard.getData('text/plain');
widget.exchangeViewModel.receiveAddress = clipboard?.text ?? '';
final domain = widget.exchangeViewModel.receiveAddress;
widget.exchangeViewModel.receiveAddress =
await fetchParsedAddress(context, domain,
widget.exchangeViewModel.receiveCurrency);
},
onPushAddressBookButton: (context) async {
final domain = widget.exchangeViewModel.receiveAddress;
widget.exchangeViewModel.receiveAddress =
await fetchParsedAddress(context, domain,
widget.exchangeViewModel.receiveCurrency);
},
),
)
],
final domain = widget.exchangeViewModel.receiveAddress;
widget.exchangeViewModel.receiveAddress =
await fetchParsedAddress(context, domain,
widget.exchangeViewModel.receiveCurrency);
},
onPushAddressBookButton: (context) async {
final domain = widget.exchangeViewModel.receiveAddress;
widget.exchangeViewModel.receiveAddress =
await fetchParsedAddress(context, domain,
widget.exchangeViewModel.receiveCurrency);
},
),
)
],
),
),
),
),
),
@@ -6,15 +6,19 @@ import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/new-ui/modal_navigator.dart';
import 'package:cake_wallet/new-ui/pages/send_page.dart';
import 'package:cake_wallet/new-ui/pages/swap_page.dart';
import 'package:cake_wallet/reactions/wallet_connect.dart';
import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
import 'package:cake_wallet/src/widgets/cake_image_widget.dart';
import 'package:cake_wallet/utils/feature_flag.dart';
import 'package:cake_wallet/utils/payment_request.dart';
import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cake_wallet/view_model/send/send_view_model.dart';
import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_view_model.dart';
import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/lnurl.dart';
import 'package:cw_core/unspent_coin_type.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:modal_bottom_sheet/modal_bottom_sheet.dart';
@@ -24,10 +28,11 @@ import '../../../pages/scan_page.dart';
import 'coin_action_button.dart';
class CoinActionRow extends StatelessWidget {
const CoinActionRow({super.key, this.lightningMode = false, this.showSwap = true});
const CoinActionRow({super.key, this.lightningMode = false, this.showSwap = true, required this.walletType});
final bool lightningMode;
final bool showSwap;
final WalletType walletType;
@override
Widget build(BuildContext context) {
@@ -178,6 +183,21 @@ class CoinActionRow extends StatelessWidget {
req = PaymentRequest(code, amount, "", "", "");
} else if (OpenCryptoPayService.isOpenCryptoPayQR(code)) {
req = PaymentRequest(code, "", "", "", "");
} else if (Uri.tryParse(code)?.scheme == "wc") {
if (!isEVMCompatibleChain(walletType)) {
showPopUp<void>(
context: context,
builder: (context) => AlertWithOneAction(
alertTitle: "WalletConnect",
alertContent: S.of(context).switchToEVMCompatibleWallet,
buttonText: "OK",
buttonAction: Navigator.of(context).pop));
return;
}
Navigator.of(context)
.pushNamed(Routes.walletConnectConnectionsListing, arguments: Uri.parse(code));
return;
} else {
final uri = Uri.tryParse(code);
if (uri == null) return;
@@ -202,9 +202,19 @@ class SwapTransactionDetails extends StatelessWidget {
label: exchangeTradeViewModel.trade.provider.title,
iconPath: exchangeTradeViewModel.trade.provider.image,
trailingIconPath: "assets/new-ui/copy.svg",
trailingText: exchangeTradeViewModel.trade.id,
truncateTrailingText:
!exchangeTradeViewModel.trade.provider.isCentralized),
trailingText: exchangeTradeViewModel.trade.id.toString().length > 18
? null
: exchangeTradeViewModel.trade.id,
bottomWidget: exchangeTradeViewModel.trade.id.toString().length <= 18
? null
: Padding(
padding: const EdgeInsets.only(top: 12.0),
child: Text(
exchangeTradeViewModel.trade.id,
style: TextStyle(
color: Theme.of(context).colorScheme.onSurfaceVariant),
),
)),
if (exchangeTradeViewModel.trade.provider ==
ExchangeProviderDescription.trocador)
ListItemRegularRow(
@@ -12,6 +12,7 @@ import 'package:cake_wallet/entities/qr_scanner.dart';
import 'package:cake_wallet/src/widgets/primary_button.dart';
import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cake_wallet/utils/permission_handler.dart';
import 'package:url_launcher/url_launcher.dart';
import 'widgets/wc_pairing_item_widget.dart';
import 'wc_pairing_detail_page.dart';
@@ -27,6 +28,11 @@ class WalletConnectConnectionsView extends StatelessWidget {
void _triggerPairingFromDeeplink(Uri? launchUri) async {
if (launchUri == null) return;
if(launchUri.scheme == "wc") {
await walletKitService.pairWithUri(launchUri);
return;
}
final actualLinkList = launchUri.query.split("uri=");
if (actualLinkList.length <= 1) return;
@@ -84,6 +84,8 @@ class WalletUnlockPageState extends AuthPageState<WalletUnlockPage> {
_passwordController.removeListener(_passwordControllerListener!);
}
_passwordController.dispose();
super.dispose();
}
@@ -105,6 +107,26 @@ class WalletUnlockPageState extends AuthPageState<WalletUnlockPage> {
});
}
Future<void> _unlockWallet() async {
if (widget.walletUnlockViewModel.state is IsExecutingState) {
return;
}
FocusScope.of(context).unfocus();
if (widget.authPasswordHandler != null) {
try {
await widget.authPasswordHandler!(widget.walletUnlockViewModel.password);
widget.walletUnlockViewModel.success();
} catch (e) {
widget.walletUnlockViewModel.failure(e);
}
return;
}
await widget.walletUnlockViewModel.unlock();
}
@override
Future<void> close({String? route, arguments}) async {
if (_key.currentContext == null) {
@@ -176,6 +198,9 @@ class WalletUnlockPageState extends AuthPageState<WalletUnlockPage> {
child: BaseTextFormField(
key: ValueKey('enter_wallet_password'),
onChanged: (value) => null,
onSubmit: (_) async {
await _unlockWallet();
},
controller: _passwordController,
textAlign: TextAlign.center,
obscureText: true,
@@ -187,7 +212,7 @@ class WalletUnlockPageState extends AuthPageState<WalletUnlockPage> {
fontSize: 18.0,
fontWeight: FontWeight.w500,
color: Theme.of(context).colorScheme.onSurfaceVariant,
),
),
hintText: S.of(context).enter_wallet_password,
),
),
@@ -199,19 +224,7 @@ class WalletUnlockPageState extends AuthPageState<WalletUnlockPage> {
padding: EdgeInsets.only(bottom: 24),
child: Observer(
builder: (_) => LoadingPrimaryButton(
onPressed: () async {
if (widget.authPasswordHandler != null) {
try {
await widget.authPasswordHandler!(widget.walletUnlockViewModel.password);
widget.walletUnlockViewModel.success();
} catch (e) {
widget.walletUnlockViewModel.failure(e);
}
return;
}
widget.walletUnlockViewModel.unlock();
},
onPressed: _unlockWallet,
text: S.of(context).unlock,
color: Theme.of(context).colorScheme.primary,
textColor: Theme.of(context).colorScheme.onPrimary,
+1 -1
View File
@@ -121,7 +121,7 @@ class BaseTextFormField extends StatelessWidget {
inputFormatters: inputFormatters,
enabled: enabled,
maxLength: maxLength,
onFieldSubmitted: onSubmit,
onFieldSubmitted: onFieldSubmitted ?? onSubmit,
style: textStyle ??
Theme.of(context).textTheme.bodyMedium!.copyWith(
fontSize: 16.0, color: textColor ?? Theme.of(context).colorScheme.onSurface),
@@ -763,7 +763,7 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
if (price == null || price == 0.0) return;
final crypto = _enteredAmount / price;
final depositAmountTmp = crypto.toString().withMaxDecimals(receiveCurrency.decimals);
final depositAmountTmp = crypto.toString().withMaxDecimals(depositCurrency.decimals);
if (_depositAmount != depositAmountTmp) {
changeDepositAmount(amount: depositAmountTmp, isCanonical: true);
}
@@ -129,9 +129,10 @@ abstract class UnspentCoinsListViewModelBase with Store {
existingInfo.note = item.note;
await existingInfo.save();
await _updateUnspents();
await wallet.updateBalance();
item.isBeingSaved = false;
isSavingItems = false;
_updateUnspentCoinsInfo();
} catch (e) {
printV('Error saving coin info: $e');
item.isBeingSaved = false;
+1 -1
View File
@@ -644,7 +644,7 @@
"nano_current_rep": "الممثل الحالي",
"nano_gpt_thanks_message": "شكرًا لاستخدامك NanoGPT! تذكّر العودة إلى المتصفح بعد اكتمال معاملتك!",
"nano_pick_new_rep": "اختر ممثلًا جديدًا",
"nanogpt_subtitle": "جميع أحدث النماذج (GPT-4، Claude).\nبدون اشتراك، ادفع بالعملات المشفرة.",
"nanogpt_subtitle": "جميع أحدث النماذج (GPT-5.3، Claude 4.6).\nبدون اشتراك، ادفع بالعملات المشفرة.",
"narrow": "ضيق",
"network": "الشبكة",
"new_first_wallet_text": "الحفاظ على أمان عملاتك المشفرة سهل للغاية",
+1 -1
View File
@@ -644,7 +644,7 @@
"nano_current_rep": "Текущ представител",
"nano_gpt_thanks_message": "Благодарим ви, че използвате NanoGPT! Не забравяйте да се върнете в браузъра, след като транзакцията ви приключи!",
"nano_pick_new_rep": "Изберете нов представител",
"nanogpt_subtitle": "Всички най-нови модели (GPT‑4, Claude).\nБез абонамент, плащайте с крипто.",
"nanogpt_subtitle": "Всички най-нови модели (GPT‑4, Claude 4.6).\nБез абонамент, плащайте с крипто.",
"narrow": "Тесен",
"network": "Мрежа",
"new_first_wallet_text": "Да пазите криптовалутата си в безопасност е лесно като парче торта",
+1 -1
View File
@@ -644,7 +644,7 @@
"nano_current_rep": "Aktuální zástupce",
"nano_gpt_thanks_message": "Děkujeme, že používáte NanoGPT! Nezapomeňte se po dokončení transakce vrátit zpět do prohlížeče!",
"nano_pick_new_rep": "Vyberte nového zástupce",
"nanogpt_subtitle": "Všechny nejnovější modely (GPT-4, Claude).\nBez předplatného, plaťte kryptem.",
"nanogpt_subtitle": "Všechny nejnovější modely (GPT-5.3, Claude 4.6).\nBez předplatného, plaťte kryptem.",
"narrow": "Úzké",
"network": "Síť",
"new_first_wallet_text": "Udržet vaše krypto v bezpečí je hračka",
+1 -1
View File
@@ -644,7 +644,7 @@
"nano_current_rep": "Aktueller Repräsentant",
"nano_gpt_thanks_message": "Danke, dass Sie NanoGPT verwendet haben! Denken Sie daran, nach Abschluss Ihrer Transaktion zum Browser zurückzukehren!",
"nano_pick_new_rep": "Wählen Sie einen neuen Repräsentanten aus",
"nanogpt_subtitle": "Alle neuesten Modelle (GPT-4, Claude).\nKein Abonnement, bezahle mit Krypto.",
"nanogpt_subtitle": "Alle neuesten Modelle (GPT-5.3, Claude 4.6).\nKein Abonnement, bezahle mit Krypto.",
"narrow": "Schmal",
"network": "Netzwerk",
"new_first_wallet_text": "Ihre Kryptowährungen sicher aufzubewahren ist ein Kinderspiel",
+1 -1
View File
@@ -644,7 +644,7 @@
"nano_current_rep": "Current Representative",
"nano_gpt_thanks_message": "Thanks for using NanoGPT! Remember to head back to the browser after your transaction completes!",
"nano_pick_new_rep": "Pick a new representative",
"nanogpt_subtitle": "All the newest models (GPT-4, Claude).\\nNo subscription, pay with crypto.",
"nanogpt_subtitle": "All the newest models (GPT-5.3, Claude 4.6).\\nNo subscription, pay with crypto.",
"narrow": "Narrow",
"network": "Network",
"new_first_wallet_text": "Keeping your crypto safe is a piece of cake",
+1 -1
View File
@@ -644,7 +644,7 @@
"nano_current_rep": "Representante actual",
"nano_gpt_thanks_message": "¡Gracias por usar NanoGPT! Recuerda volver al navegador después de que se complete tu transacción.",
"nano_pick_new_rep": "Elige un nuevo representante",
"nanogpt_subtitle": "Todos los modelos más recientes (GPT-4, Claude).\nSin suscripción, paga con cripto.",
"nanogpt_subtitle": "Todos los modelos más recientes (GPT-5.3, Claude 4.6).\nSin suscripción, paga con cripto.",
"narrow": "Estrecho",
"network": "Red",
"new_first_wallet_text": "Mantener tus criptomonedas seguras es pan comido",
+1 -1
View File
@@ -642,7 +642,7 @@
"nano_current_rep": "نمایندهٔ فعلی",
"nano_gpt_thanks_message": "از استفاده از NanoGPT متشکریم!\nیادتان باشد پس از تکمیل تراکنش، به مرورگر برگردید!",
"nano_pick_new_rep": "یک نماینده جدید انتخاب کنید",
"nanogpt_subtitle": "همه جدیدترین مدل‌ها (GPT-4, Claude).\nبدون اشتراک، پرداخت با کریپتو.",
"nanogpt_subtitle": "همه جدیدترین مدل‌ها (GPT-5.3, Claude 4.6).\nبدون اشتراک، پرداخت با کریپتو.",
"narrow": "باریک",
"network": "شبکه",
"new_first_wallet_text": "امن نگه داشتن رمزارزهای شما مثل آب خوردن است",
+1 -1
View File
@@ -644,7 +644,7 @@
"nano_current_rep": "Représentant actuel",
"nano_gpt_thanks_message": "Merci d'avoir utilisé NanoGPT ! N'oubliez pas de revenir au navigateur une fois votre transaction terminée !",
"nano_pick_new_rep": "Choisir un nouveau représentant",
"nanogpt_subtitle": "Tous les modèles les plus récents (GPT-4, Claude).\nPas d'abonnement, payez en crypto.",
"nanogpt_subtitle": "Tous les modèles les plus récents (GPT-5.3, Claude 4.6).\nPas d'abonnement, payez en crypto.",
"narrow": "Étroit",
"network": "Réseau",
"new_first_wallet_text": "Garder vos cryptos en sécurité, c'est du gâteau",
+1 -1
View File
@@ -500,7 +500,7 @@
"nano_current_rep": "Omyakãva ko'ág̃a",
"nano_gpt_thanks_message": "Aguyje reiporu hag̃ua NanoGPT! Nemandu'áke reho jey kundahárape gotyo oĩmba rire ne transacción.",
"nano_pick_new_rep": "Eiporavo peteĩ representante pyahu",
"nanogpt_subtitle": "Opaite umi modelo ipyahuvéva (GPT-4, Claude).\nNdaipóri suscripción, ehepyme’ẽ cripto rupive.",
"nanogpt_subtitle": "Opaite umi modelo ipyahuvéva (GPT-5.3, Claude 4.6).\nNdaipóri suscripción, ehepyme’ẽ cripto rupive.",
"narrow": "Poʼi",
"network": "Red",
"new_first_wallet_text": "Eñangareko hag̃ua nde criptomoneda rehe ha'e peteĩ mba'e ndahasýiva",
+1 -1
View File
@@ -644,7 +644,7 @@
"nano_current_rep": "Wakili na Yanzu",
"nano_gpt_thanks_message": "Na gode da amfani da NanoGPT! Ka tuna ka koma zuwa burauza bayan ma'amalarka ta kammala!",
"nano_pick_new_rep": "Zaɓi sabon wakili",
"nanogpt_subtitle": "Duk sabbin samfura (GPT-4, Claude).\nBabu biyan kuɗin rajista, biya da crypto.",
"nanogpt_subtitle": "Duk sabbin samfura (GPT-5.3, Claude 4.6).\nBabu biyan kuɗin rajista, biya da crypto.",
"narrow": "Kunkuntar",
"network": "Sadarwa",
"new_first_wallet_text": "Kare kuɗin crypto ɗinka cikin aminci abu ne mai sauƙi",
+1 -1
View File
@@ -644,7 +644,7 @@
"nano_current_rep": "वर्तमान प्रतिनिधि",
"nano_gpt_thanks_message": "NanoGPT का उपयोग करने के लिए धन्यवाद! आपका लेन-देन पूरा होने के बाद ब्राउज़र पर वापस जाना याद रखें!",
"nano_pick_new_rep": "नया प्रतिनिधि चुनें",
"nanogpt_subtitle": "सभी नवीनतम मॉडल (GPT-4, Claude)।\nकोई सब्सक्रिप्शन नहीं, क्रिप्टो से भुगतान करें।",
"nanogpt_subtitle": "सभी नवीनतम मॉडल (GPT-5.3, Claude 4.6)।\nकोई सब्सक्रिप्शन नहीं, क्रिप्टो से भुगतान करें।",
"narrow": "संकीर्ण",
"network": "नेटवर्क",
"new_first_wallet_text": "अपने क्रिप्टो को सुरक्षित रखना बहुत आसान है",
+1 -1
View File
@@ -644,7 +644,7 @@
"nano_current_rep": "Trenutni predstavnik",
"nano_gpt_thanks_message": "Hvala što koristite NanoGPT! Ne zaboravite se vratiti u preglednik nakon što se transakcija dovrši!",
"nano_pick_new_rep": "Odaberite novog predstavnika",
"nanogpt_subtitle": "Svi najnoviji modeli (GPT-4, Claude).\nBez pretplate, plaćajte kriptom.",
"nanogpt_subtitle": "Svi najnoviji modeli (GPT-5.3, Claude 4.6).\nBez pretplate, plaćajte kriptom.",
"narrow": "Usko",
"network": "Mreža",
"new_first_wallet_text": "Čuvanje vaše kriptovalute sigurnom je mačji kašalj",
+1 -1
View File
@@ -644,7 +644,7 @@
"nano_current_rep": "Ընթացիկ ներկայացուցիչ",
"nano_gpt_thanks_message": "Շնորհակալություն NanoGPT-ն օգտագործելու համար։ Հիշեք՝ գործարքի ավարտից հետո վերադարձեք դիտարկիչ։",
"nano_pick_new_rep": "Ընտրեք նոր ներկայացուցիչ",
"nanogpt_subtitle": "Բոլոր ամենանոր մոդելները (GPT-4, Claude).\nԱռանց բաժանորդագրության՝ վճարեք կրիպտոարժույթով։",
"nanogpt_subtitle": "Բոլոր ամենանոր մոդելները (GPT-5.3, Claude 4.6).\nԱռանց բաժանորդագրության՝ վճարեք կրիպտոարժույթով։",
"narrow": "Նեղ",
"network": "Ցանց",
"new_first_wallet_text": "Ձեր կրիպտոն անվտանգ պահելը շատ հեշտ է",
+1 -1
View File
@@ -644,7 +644,7 @@
"nano_current_rep": "Perwakilan Saat Ini",
"nano_gpt_thanks_message": "Terima kasih telah menggunakan NanoGPT! Ingat untuk kembali ke browser setelah transaksi Anda selesai!",
"nano_pick_new_rep": "Pilih perwakilan baru",
"nanogpt_subtitle": "Semua model terbaru (GPT-4, Claude).\nTanpa langganan, bayar dengan kripto.",
"nanogpt_subtitle": "Semua model terbaru (GPT-5.3, Claude 4.6).\nTanpa langganan, bayar dengan kripto.",
"narrow": "Sempit",
"network": "Jaringan",
"new_first_wallet_text": "Menjaga kripto Anda tetap aman itu semudah membalik telapak tangan",
+1 -1
View File
@@ -644,7 +644,7 @@
"nano_current_rep": "Rappresentante corrente",
"nano_gpt_thanks_message": "Grazie per aver usato NanoGPT! Ricorda di tornare al browser dopo il completamento della transazione!",
"nano_pick_new_rep": "Scegli un nuovo rappresentante",
"nanogpt_subtitle": "Tutti i modelli più recenti (GPT-4, Claude).\nNessun abbonamento, paga con cripto.",
"nanogpt_subtitle": "Tutti i modelli più recenti (GPT-5.3, Claude 4.6).\nNessun abbonamento, paga con cripto.",
"narrow": "Stretto",
"network": "Rete",
"new_first_wallet_text": "Tenere al sicuro le tue crypto è un gioco da ragazzi",
+1 -1
View File
@@ -645,7 +645,7 @@
"nano_current_rep": "現在の代表者",
"nano_gpt_thanks_message": "NanoGPTをご利用いただきありがとうございます!トランザクションが完了したら、ブラウザに戻ることを忘れないでください!",
"nano_pick_new_rep": "新しい代表者を選択",
"nanogpt_subtitle": "すべての最新モデル(GPT-4、Claude)。\nサブスクリプション不要、暗号資産で支払い。",
"nanogpt_subtitle": "すべての最新モデル(GPT-5.3、Claude 4.6)。\nサブスクリプション不要、暗号資産で支払い。",
"narrow": "狭い",
"network": "ネットワーク",
"new_first_wallet_text": "暗号資産を安全に守るのはお手のものです",
+1 -1
View File
@@ -644,7 +644,7 @@
"nano_current_rep": "현재 대표",
"nano_gpt_thanks_message": "NanoGPT를 이용해 주셔서 감사합니다! 거래가 완료되면 브라우저로 돌아가는 것을 잊지 마세요!",
"nano_pick_new_rep": "새 대표자 선택",
"nanogpt_subtitle": "최신 모델 모두(GPT-4, Claude).\n구독 없이 암호화폐로 결제.",
"nanogpt_subtitle": "최신 모델 모두(GPT-5.3, Claude 4.6).\n구독 없이 암호화폐로 결제.",
"narrow": "좁게",
"network": "네트워크",
"new_first_wallet_text": "암호화폐를 안전하게 지키는 건 식은 죽 먹기예요",
+1 -1
View File
@@ -644,7 +644,7 @@
"nano_current_rep": "လက်ရှိ ကိုယ်စားလှယ်",
"nano_gpt_thanks_message": "NanoGPT ကို အသုံးပြုပေးတဲ့အတွက် ကျေးဇူးတင်ပါတယ်! သင့်ငွေလွှဲလုပ်ငန်းစဉ် ပြီးဆုံးသွားပြီးနောက် ဘရောက်ဇာသို့ ပြန်သွားဖို့ မမေ့ပါနဲ့။",
"nano_pick_new_rep": "ကိုယ်စားလှယ်အသစ်ကို ရွေးချယ်ပါ",
"nanogpt_subtitle": "နောက်ဆုံးပေါ်မော်ဒယ်များအားလုံး (GPT-4, Claude)။\nစာရင်းသွင်းမှုမလို၊ crypto ဖြင့်ပေးချေပါ။",
"nanogpt_subtitle": "နောက်ဆုံးပေါ်မော်ဒယ်များအားလုံး (GPT-5.3, Claude 4.6)။\nစာရင်းသွင်းမှုမလို၊ crypto ဖြင့်ပေးချေပါ။",
"narrow": "ကျဉ်း",
"network": "ကွန်ရက်",
"new_first_wallet_text": "သင့်ရဲ့ crypto ကို လုံခြုံအောင် ထိန်းသိမ်းတာက လွယ်လွယ်ကူကူပါပဲ",
+1 -1
View File
@@ -641,7 +641,7 @@
"nano_current_rep": "Huidige vertegenwoordiger",
"nano_gpt_thanks_message": "Bedankt voor het gebruik van Nanogpt! Vergeet niet om terug te gaan naar de browser nadat je transactie is voltooid!",
"nano_pick_new_rep": "Kies een nieuwe vertegenwoordiger",
"nanogpt_subtitle": "Alle nieuwste modellen (GPT-4, Claude).\nGeen abonnement, betaal met crypto.",
"nanogpt_subtitle": "Alle nieuwste modellen (GPT-5.3, Claude 4.6).\nGeen abonnement, betaal met crypto.",
"narrow": "Smal",
"network": "Netwerk",
"new_first_wallet_text": "Je crypto veilig houden is een fluitje van een cent",
+1 -1
View File
@@ -643,7 +643,7 @@
"nano_current_rep": "Bieżący przedstawiciel",
"nano_gpt_thanks_message": "Dziękujemy za korzystanie z NanoGPT! Pamiętaj, aby po zakończeniu transakcji wrócić do przeglądarki!",
"nano_pick_new_rep": "Wybierz nowego przedstawiciela",
"nanogpt_subtitle": "Wszystkie najnowsze modele (GPT-4, Claude).\nBez subskrypcji, płać kryptowalutą.",
"nanogpt_subtitle": "Wszystkie najnowsze modele (GPT-5.3, Claude 4.6).\nBez subskrypcji, płać kryptowalutą.",
"narrow": "Wąski",
"network": "Sieć",
"new_first_wallet_text": "Bezpieczne przechowywanie Twoich kryptowalut to bułka z masłem",
+1 -1
View File
@@ -645,7 +645,7 @@
"nano_current_rep": "Representante atual",
"nano_gpt_thanks_message": "Obrigado por usar o NanoGPT! Lembre-se de voltar ao navegador após a conclusão da sua transação!",
"nano_pick_new_rep": "Escolha um novo representante",
"nanogpt_subtitle": "Todos os modelos mais recentes (GPT-4, Claude).\nSem assinatura, pague com cripto.",
"nanogpt_subtitle": "Todos os modelos mais recentes (GPT-5.3, Claude 4.6).\nSem assinatura, pague com cripto.",
"narrow": "Estreito",
"network": "Rede",
"new_first_wallet_text": "Manter suas criptos seguras é moleza",
+1 -1
View File
@@ -640,7 +640,7 @@
"nano_current_rep": "Representante atual",
"nano_gpt_thanks_message": "Obrigado por usar o NanoGPT! Lembre-se de voltar ao navegador após a conclusão da sua transação!",
"nano_pick_new_rep": "Escolha um novo representante",
"nanogpt_subtitle": "Todos os modelos mais recentes (GPT-4, Claude).\nSem assinatura, pague com cripto.",
"nanogpt_subtitle": "Todos os modelos mais recentes (GPT-5.3, Claude 4.6).\nSem assinatura, pague com cripto.",
"narrow": "Estreito",
"network": "Rede",
"new_first_wallet_text": "Manter sua cripto segura é moleza",
+1 -1
View File
@@ -644,7 +644,7 @@
"nano_current_rep": "Текущий представитель",
"nano_gpt_thanks_message": "Спасибо за использование NanoGPT! Не забудьте вернуться в браузер после завершения транзакции!",
"nano_pick_new_rep": "Выберите нового представителя",
"nanogpt_subtitle": "Все новейшие модели (GPT-4, Claude).\nБез подписки, оплата криптовалютой.",
"nanogpt_subtitle": "Все новейшие модели (GPT-5.3, Claude 4.6).\nБез подписки, оплата криптовалютой.",
"narrow": "Узкий",
"network": "Сеть",
"new_first_wallet_text": "Хранить вашу криптовалюту в безопасности — проще простого",
+1 -1
View File
@@ -644,7 +644,7 @@
"nano_current_rep": "ตัวแทนปัจจุบัน",
"nano_gpt_thanks_message": "ขอบคุณที่ใช้ NanoGPT! อย่าลืมกลับไปที่เบราว์เซอร์หลังจากธุรกรรมของคุณเสร็จสิ้น!",
"nano_pick_new_rep": "เลือกผู้แทนใหม่",
"nanogpt_subtitle": "โมเดลใหม่ล่าสุดทั้งหมด (GPT-4, Claude)\nไม่ต้องสมัครสมาชิก จ่ายด้วยคริปโต",
"nanogpt_subtitle": "โมเดลใหม่ล่าสุดทั้งหมด (GPT-5.3, Claude 4.6)\nไม่ต้องสมัครสมาชิก จ่ายด้วยคริปโต",
"narrow": "แคบ",
"network": "เครือข่าย",
"new_first_wallet_text": "การเก็บคริปโตของคุณให้ปลอดภัยเป็นเรื่องง่ายเหมือนปอกกล้วยเข้าปาก",
+1 -1
View File
@@ -644,7 +644,7 @@
"nano_current_rep": "Kasalukuyang Kinatawan",
"nano_gpt_thanks_message": "Salamat sa paggamit ng NanoGPT! Tandaan na bumalik sa browser pagkatapos makumpleto ang iyong transaksyon!",
"nano_pick_new_rep": "Pumili ng bagong kinatawan",
"nanogpt_subtitle": "Lahat ng pinakabagong modelo (GPT-4, Claude).\nWalang subscription, magbayad gamit ang crypto.",
"nanogpt_subtitle": "Lahat ng pinakabagong modelo (GPT-5.3, Claude 4.6).\nWalang subscription, magbayad gamit ang crypto.",
"narrow": "Makitid",
"network": "Network",
"new_first_wallet_text": "Ang pagpapanatiling ligtas ng iyong crypto ay kasingdali ng pagkain ng keyk",
+1 -1
View File
@@ -644,7 +644,7 @@
"nano_current_rep": "Mevcut Temsilci",
"nano_gpt_thanks_message": "NanoGPT'yi kullandığınız için teşekkürler! İşleminiz tamamlandıktan sonra tarayıcıya geri dönmeyi unutmayın!",
"nano_pick_new_rep": "Yeni bir temsilci seçin",
"nanogpt_subtitle": "En yeni modellerin tümü (GPT-4, Claude).\nAbonelik yok, kripto ile ödeyin.",
"nanogpt_subtitle": "En yeni modellerin tümü (GPT-5.3, Claude 4.6).\nAbonelik yok, kripto ile ödeyin.",
"narrow": "Dar",
"network": "Ağ",
"new_first_wallet_text": "Kriptonuzu güvende tutmak çocuk oyuncağı",
+1 -1
View File
@@ -644,7 +644,7 @@
"nano_current_rep": "Поточний представник",
"nano_gpt_thanks_message": "Дякуємо за використання NanoGPT! Не забудьте повернутися до браузера після завершення транзакції!",
"nano_pick_new_rep": "Виберіть нового представника",
"nanogpt_subtitle": "Усі найновіші моделі (GPT-4, Claude).\nБез підписки, оплата криптовалютою.",
"nanogpt_subtitle": "Усі найновіші моделі (GPT-5.3, Claude 4.6).\nБез підписки, оплата криптовалютою.",
"narrow": "Вузький",
"network": "Мережа",
"new_first_wallet_text": "Зберігати вашу криптовалюту в безпеці — простіше простого",
+1 -1
View File
@@ -644,7 +644,7 @@
"nano_current_rep": "موجودہ نمائندہ",
"nano_gpt_thanks_message": "NanoGPT استعمال کرنے کا شکریہ! آپ کا لین دین مکمل ہونے کے بعد براؤزر پر واپس جانا یاد رکھیں!",
"nano_pick_new_rep": "نیا نمائندہ منتخب کریں",
"nanogpt_subtitle": "تمام جدید ترین ماڈلز (GPT-4، Claude)۔\nکوئی سبسکرپشن نہیں، کرپٹو کے ساتھ ادائیگی کریں۔",
"nanogpt_subtitle": "تمام جدید ترین ماڈلز (GPT-5.3، Claude 4.6)۔\nکوئی سبسکرپشن نہیں، کرپٹو کے ساتھ ادائیگی کریں۔",
"narrow": "تنگ",
"network": "نیٹ ورک",
"new_first_wallet_text": "اپنے کرپٹو کو محفوظ رکھنا بہت آسان ہے",
+1 -1
View File
@@ -643,7 +643,7 @@
"nano_current_rep": "Người đại diện hiện tại",
"nano_gpt_thanks_message": "Cảm ơn bạn đã sử dụng NanoGPT! Hãy nhớ quay lại trình duyệt sau khi giao dịch hoàn tất!",
"nano_pick_new_rep": "Chọn người đại diện mới",
"nanogpt_subtitle": "Tất cả các mô hình mới nhất (GPT-4, Claude).\nKhông cần đăng ký, thanh toán bằng crypto.",
"nanogpt_subtitle": "Tất cả các mô hình mới nhất (GPT-5.3, Claude 4.6).\nKhông cần đăng ký, thanh toán bằng crypto.",
"narrow": "Hẹp",
"network": "Mạng",
"new_first_wallet_text": "Giữ tiền điện tử của bạn an toàn dễ như ăn bánh",
+1 -1
View File
@@ -645,7 +645,7 @@
"nano_current_rep": "Aṣojú lọ́wọ́lọ́wọ́",
"nano_gpt_thanks_message": "O ṣeun fun lilo NanoGPT! Ranti lati pada si ẹrọ aṣàwákiri lẹ́yìn tí ìdúnàdúrà rẹ bá parí!",
"nano_pick_new_rep": "Yan aṣoju tuntun kan",
"nanogpt_subtitle": "Gbogbo àwọn àwòṣe tuntun jùlọ (GPT-4, Claude).\nKò sí ìforúkọsílẹ̀, sanwó pẹ̀lú crypto.",
"nanogpt_subtitle": "Gbogbo àwọn àwòṣe tuntun jùlọ (GPT-5.3, Claude 4.6).\nKò sí ìforúkọsílẹ̀, sanwó pẹ̀lú crypto.",
"narrow": "Dín",
"network": "Nẹ́tíwọ́ọ̀kì",
"new_first_wallet_text": "Mímú kíríptò rẹ láàbò rọrùn bíi akara oyinbo",
+1 -1
View File
@@ -644,7 +644,7 @@
"nano_current_rep": "当前代表",
"nano_gpt_thanks_message": "感谢您使用 NanoGPT!交易完成后,记得返回浏览器!",
"nano_pick_new_rep": "选择新的代表",
"nanogpt_subtitle": "所有最新模型(GPT-4、Claude)。\n无需订阅,用加密货币支付。",
"nanogpt_subtitle": "所有最新模型(GPT-5.3、Claude 4.6)。\n无需订阅,用加密货币支付。",
"narrow": "窄",
"network": "网络",
"new_first_wallet_text": "让您的加密货币安全无忧,轻而易举",
+1 -1
View File
@@ -545,7 +545,7 @@
"nano_current_rep": "目前代表",
"nano_gpt_thanks_message": "感謝您使用 NanoGPT!交易完成後,請記得回到瀏覽器!",
"nano_pick_new_rep": "選擇新的代表人",
"nanogpt_subtitle": "所有最新模型(GPT-4、Claude)。\n無需訂閱,以加密貨幣付款。",
"nanogpt_subtitle": "所有最新模型(GPT-5.3、Claude 4.6)。\n無需訂閱,以加密貨幣付款。",
"narrow": "窄",
"new_first_wallet_text": "保護您的加密貨幣安全,輕鬆得像吃蛋糕一樣",
"new_node_testing": "新節點測試",