tolerate nullable payment methods
What changed, and why it matters
This commit makes the Cake Pay gift-card/order feature more forgiving when a vendor response does not include payment details for every supported cryptocurrency. Previously the app would crash if a field such as BTC or XMR was missing; now it accepts null values and removes a couple of fallback empty-string defaults when building the order record. The change is primarily a robustness/crash-fix, not a clear security patch.
Treat as a routine robustness fix. Review the new trezor_connect ref for any relevant changes, verify that downstream consumers of PaymentData handle nullable fields safely, and confirm the Cake Pay API contract change is intentional. No urgent security action is indicated by the diff alone.
Security signals we found
Null-safety hardening in deserialization of external API data (Cake Pay order payment methods)
Removal of silent empty-string fallbacks for amount and receiveAddress in order creation
Dependency ref update for trezor_connect without stated rationale
Evidence from the diff
The PaymentData model fields (btc, btc_ln, xmr, ltc, ltc_mweb) are changed from non-nullable CryptoPaymentData to nullable CryptoPaymentData?, and the fromMap factory now checks for null before parsing. In the view model, two ?? ‘’ fallbacks for amount and receiveAddress are removed so the order object stores the actual nullable values. A git dependency for trezor_connect is also bumped to a newer ref. There is no explicit security framing in the commit.
Changed components
lib/cake_pay/src/models/cake_pay_order.dartlib/view_model/cake_pay/cake_pay_buy_card_view_model.dartcw_bitcoin/pubspec.lock (trezor_connect git ref)Inspect captured patch +14 / −15
diff --git a/cw_bitcoin/pubspec.lock b/cw_bitcoin/pubspec.lock
index 16ff7168..681e68d4 100644
--- a/cw_bitcoin/pubspec.lock
+++ b/cw_bitcoin/pubspec.lock
@@ -1159,8 +1159,8 @@ packages:
dependency: "direct main"
description:
path: "."
- ref: "59b3ceec158d3393b20d0c596cab2abcc62ac8e4"
- resolved-ref: "59b3ceec158d3393b20d0c596cab2abcc62ac8e4"
+ ref: d1242cea90f84b00200e7bcab914a5af750e23fb
+ resolved-ref: d1242cea90f84b00200e7bcab914a5af750e23fb
url: "https://github.com/cake-tech/trezor_connect"
source: git
version: "0.0.1"
diff --git a/lib/cake_pay/src/models/cake_pay_order.dart b/lib/cake_pay/src/models/cake_pay_order.dart
index d3a2ecfd..0f70c50f 100644
--- a/lib/cake_pay/src/models/cake_pay_order.dart
+++ b/lib/cake_pay/src/models/cake_pay_order.dart
@@ -124,11 +124,11 @@ class OrderCard {
}
class PaymentData {
- final CryptoPaymentData btc;
- final CryptoPaymentData btc_ln;
- final CryptoPaymentData xmr;
- final CryptoPaymentData ltc;
- final CryptoPaymentData ltc_mweb;
+ final CryptoPaymentData? btc;
+ final CryptoPaymentData? btc_ln;
+ final CryptoPaymentData? xmr;
+ final CryptoPaymentData? ltc;
+ final CryptoPaymentData? ltc_mweb;
final DateTime invoiceTime;
final DateTime expirationTime;
final int? commission;
@@ -146,11 +146,11 @@ class PaymentData {
factory PaymentData.fromMap(Map<String, dynamic> map) {
return PaymentData(
- btc: CryptoPaymentData.fromMap(map['BTC'] as Map<String, dynamic>),
- btc_ln: CryptoPaymentData.fromMap(map['BTC_LN'] as Map<String, dynamic>),
- xmr: CryptoPaymentData.fromMap(map['XMR'] as Map<String, dynamic>),
- ltc: CryptoPaymentData.fromMap(map['LTC'] as Map<String, dynamic>),
- ltc_mweb: CryptoPaymentData.fromMap(map['LTC_MWEB'] as Map<String, dynamic>),
+ btc: map['BTC'] != null ? CryptoPaymentData.fromMap(map['BTC'] as Map<String, dynamic>) : null,
+ btc_ln: map['BTC_LN'] != null ? CryptoPaymentData.fromMap(map['BTC_LN'] as Map<String, dynamic>) : null,
+ xmr: map['XMR'] != null ? CryptoPaymentData.fromMap(map['XMR'] as Map<String, dynamic>) : null,
+ ltc: map['LTC'] != null ? CryptoPaymentData.fromMap(map['LTC'] as Map<String, dynamic>) : null,
+ ltc_mweb: map['LTC_MWEB'] != null ? CryptoPaymentData.fromMap(map['LTC_MWEB'] as Map<String, dynamic>) : null,
invoiceTime: DateTime.fromMillisecondsSinceEpoch(map['invoice_time'] as int),
expirationTime: DateTime.fromMillisecondsSinceEpoch(map['expiration_time'] as int),
commission: map['commission'] as int?,
diff --git a/lib/view_model/cake_pay/cake_pay_buy_card_view_model.dart b/lib/view_model/cake_pay/cake_pay_buy_card_view_model.dart
index 87ebe63c..2f4ccc50 100644
--- a/lib/view_model/cake_pay/cake_pay_buy_card_view_model.dart
+++ b/lib/view_model/cake_pay/cake_pay_buy_card_view_model.dart
@@ -1,6 +1,5 @@
import 'dart:async';
-import 'package:cake_wallet/buy/buy_provider_description.dart';
import 'package:cake_wallet/order/order_provider_description.dart';
import 'package:cake_wallet/order/order.dart';
import 'package:cake_wallet/order/order_source_description.dart';
@@ -170,10 +169,10 @@ abstract class CakePayBuyCardViewModelBase with Store {
from: CakePayOrder.getCurrencyCodeFromPaymentMethod(selectedPaymentMethod!),
to: order!.fiatCurrencyCode,
createdAt: DateTime.now(),
- amount: paymentData.amount ?? '',
+ amount: paymentData.amount,
receiveAmount: order!.totalReceiveAmount,
quantity: order!.quantity.toString(),
- receiveAddress: paymentData.address ?? '',
+ receiveAddress: paymentData.address,
source: OrderSourceDescription.order,
giftCardProvider: OrderProviderDescription.cakePay,
walletId: sendViewModel.wallet.id);
Why this scored 24/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.