@@ -324,7 +324,9 @@ class MainDB {
324324
325325 await isar.writeTxn (() async {
326326 final set = utxos.toSet ();
327+ final noteValues = < String , String ? > {};
327328 for (final utxo in utxos) {
329+ UTXO persistedUtxo = utxo;
328330 // check if utxo exists in db and update accordingly
329331 final storedUtxo = await isar.utxos
330332 .where ()
@@ -342,24 +344,36 @@ class MainDB {
342344 ! storedUtxo.isBlocked &&
343345 ! storedUtxo.userUnfroze;
344346 set .remove (utxo);
345- set .add (
346- storedUtxo.copyWith (
347- value: utxo.value,
348- address: utxo.address,
349- blockTime: utxo.blockTime,
350- blockHeight: utxo.blockHeight,
351- blockHash: utxo.blockHash,
352- // passing null keeps the stored value
353- isBlocked: applyAutoBlock ? true : null ,
354- blockedReason: applyAutoBlock ? utxo.blockedReason : null ,
355- name: applyAutoBlock && storedUtxo.name.isEmpty
356- ? utxo.name
357- : null ,
358- ),
347+ persistedUtxo = storedUtxo.copyWith (
348+ value: utxo.value,
349+ address: utxo.address,
350+ blockTime: utxo.blockTime,
351+ blockHeight: utxo.blockHeight,
352+ blockHash: utxo.blockHash,
353+ // passing null keeps the stored value
354+ isBlocked: applyAutoBlock ? true : null ,
355+ blockedReason: applyAutoBlock ? utxo.blockedReason : null ,
356+ name: applyAutoBlock && storedUtxo.name.isEmpty ? utxo.name : null ,
359357 );
358+ set .add (persistedUtxo);
360359 } else {
361360 newUTXO = true ;
362361 }
362+
363+ if (persistedUtxo.name.isEmpty) {
364+ final noteValue = noteValues.containsKey (utxo.txid)
365+ ? noteValues[utxo.txid]
366+ : (await isar.transactionNotes.getByTxidWalletId (
367+ utxo.txid,
368+ walletId,
369+ ))? .value;
370+ noteValues[utxo.txid] = noteValue;
371+ if (noteValue? .isNotEmpty == true ) {
372+ set
373+ ..remove (persistedUtxo)
374+ ..add (persistedUtxo.copyWith (name: noteValue));
375+ }
376+ }
363377 }
364378
365379 await isar.utxos.where ().walletIdEqualTo (walletId).deleteAll ();
@@ -381,14 +395,37 @@ class MainDB {
381395 isar.transactionNotes.where ().walletIdEqualTo (walletId);
382396
383397 Future <void > putTransactionNote (TransactionNote transactionNote) =>
384- isar.writeTxn (() async {
385- await isar.transactionNotes.put (transactionNote);
386- });
398+ putTransactionNotes ([transactionNote]);
387399
400+ /// Copies a note only to blank UTXO labels. The label is independent after
401+ /// that first assignment, so later note edits cannot overwrite it.
388402 Future <void > putTransactionNotes (List <TransactionNote > transactionNotes) =>
389- isar.writeTxn (() async {
390- await isar.transactionNotes.putAll (transactionNotes);
391- });
403+ transactionNotes.isEmpty
404+ ? Future .value ()
405+ : isar.writeTxn (() async {
406+ await isar.transactionNotes.putAll (transactionNotes);
407+
408+ final toUpdate = < UTXO > [];
409+ for (final note in transactionNotes) {
410+ if (note.value.isEmpty) {
411+ continue ;
412+ }
413+ final utxos = await isar.utxos
414+ .where ()
415+ .walletIdEqualTo (note.walletId)
416+ .filter ()
417+ .txidEqualTo (note.txid)
418+ .findAll ();
419+ toUpdate.addAll (
420+ utxos
421+ .where ((utxo) => utxo.name.isEmpty)
422+ .map ((utxo) => utxo.copyWith (name: note.value)),
423+ );
424+ }
425+ if (toUpdate.isNotEmpty) {
426+ await isar.utxos.putAll (toUpdate);
427+ }
428+ });
392429
393430 Future <TransactionNote ?> getTransactionNote (
394431 String walletId,
0 commit comments