fix: address CodeRabbit review on #87

This commit is contained in:
Forte11Cuba
2026-04-17 07:52:38 -06:00
parent f734b35670
commit 5cdce99154
5 changed files with 36 additions and 21 deletions
+2 -2
View File
@@ -38,10 +38,10 @@ class PendingSend {
required this.amount,
required this.mintUrl,
required this.unit,
required this.proofYs,
required List<String> proofYs,
required this.createdAt,
this.memo,
});
}) : proofYs = List.unmodifiable(proofYs);
PendingSend copyWith({
String? id,
+1 -2
View File
@@ -237,8 +237,7 @@ class L10nSw extends L10n {
String get pendingOfflineSend => 'Kutuma nje ya mtandao kunasubiri';
@override
String get pendingOfflineSendsHeader =>
'Matumizi ya nje ya mtandao ambayo hayajadaiwa';
String get pendingOfflineSendsHeader => 'Kutuma nje ya mtandao bila kudaiwa';
@override
String get pendingSendDetailTitle => 'Kutuma kunakusubiri';
+1 -1
View File
@@ -99,7 +99,7 @@
},
"cancelSendAlreadyClaimed": "Mpokeaji tayari alitumia tokeni",
"pendingOfflineSend": "Kutuma nje ya mtandao kunasubiri",
"pendingOfflineSendsHeader": "Matumizi ya nje ya mtandao ambayo hayajadaiwa",
"pendingOfflineSendsHeader": "Kutuma nje ya mtandao bila kudaiwa",
"pendingSendDetailTitle": "Kutuma kunakusubiri",
"validToken": "Tokeni halali",
"invalidToken": "Tokeni batili au imeharibika",
+13 -5
View File
@@ -183,13 +183,17 @@ class WalletProvider extends ChangeNotifier {
Future<ReclaimResult> reclaimPendingSend(PendingSend send) async {
final wallet = await getWallet(send.mintUrl, send.unit);
final result = await wallet.reclaimProofsByYs(ys: send.proofYs);
// Si recuperamos algo O si no había nada que recuperar (todos los proofs
// ya fueron gastados por el receptor), removemos el registro — la
// transacción está terminada en ambos casos.
await _pendingSendStorage.remove(send.id);
// Solo removemos el registro si el mint confirmó que había proofs
// UNSPENT y las revertimos. Un count=0 es ambiguo: puede significar
// "receptor ya reclamó (SPENT)" o "receptor en medio del swap
// (PENDING)". En el caso PENDING, necesitamos conservar el record
// para poder reintentar después — borrar perdería el retry handle.
// Esto puede dejar records "fantasma" tras un SPENT real; se puede
// agregar dismissal manual como mejora futura.
if (result.count > BigInt.zero) {
notifyListeners();
await _pendingSendStorage.remove(send.id);
}
notifyListeners();
return result;
}
@@ -2031,6 +2035,10 @@ class WalletProvider extends ChangeNotifier {
// Limpiar metadata de transacciones
await _txMetaStorage.clear();
// Limpiar envíos offline pendientes (storage separado, sobrevive al
// borrado del wallet.sqlite si no se limpia acá).
await _pendingSendStorage.clear();
// Borrar archivo
final dir = await getApplicationDocumentsDirectory();
final dbPath = '${dir.path}/elcaju_wallet.sqlite';
+19 -11
View File
@@ -35,6 +35,13 @@ class _OfflineSendScreenState extends State<OfflineSendScreen> {
final TextEditingController _memoController = TextEditingController();
final ProofService _proofService = ProofService();
// Capturado en initState para poder persistir el PendingSend incluso si
// el widget se desmonta durante el await de markProofsPendingSpent.
// Usar `context.read` después del await es inseguro (widget puede no
// existir), y gatear con `mounted` perdería el record — los proofs
// quedan marcados PENDING_SPENT pero sin handle para reclamar.
late final WalletProvider _walletProvider;
List<LocalProof> _availableProofs = [];
Set<String> _selectedIds = {};
bool _isLoading = true;
@@ -44,6 +51,7 @@ class _OfflineSendScreenState extends State<OfflineSendScreen> {
@override
void initState() {
super.initState();
_walletProvider = context.read<WalletProvider>();
_loadProofs();
}
@@ -369,17 +377,17 @@ class _OfflineSendScreenState extends State<OfflineSendScreen> {
// Rastrear el envío offline como pendiente para poder cancelarlo
// desde el historial. Los offline sends no crean CDK Transaction.
if (mounted) {
final walletProvider = context.read<WalletProvider>();
await walletProvider.addPendingSend(
encoded: token,
amount: selectedTotal,
mintUrl: widget.mintUrl,
unit: widget.unit,
proofYs: selectedProofs.map((p) => p.yHex).toList(),
memo: memo,
);
}
// Usamos el provider capturado en initState (no context.read) para
// que el record se persista aunque el widget se haya desmontado
// mientras esperábamos markProofsPendingSpent.
await _walletProvider.addPendingSend(
encoded: token,
amount: selectedTotal,
mintUrl: widget.mintUrl,
unit: widget.unit,
proofYs: selectedProofs.map((p) => p.yHex).toList(),
memo: memo,
);
if (mounted) {
_isCreating = false;