@@ -187,78 +187,79 @@ class WalletInfo implements IsarId {
187187 required Balance newBalance,
188188 required Isar isar,
189189 }) async {
190- // try to get latest instance of this from db
191- final thisInfo = await isar.walletInfo.get (id) ?? this ;
192-
193190 final newEncoded = newBalance.toJsonIgnoreCoin ();
194-
195- // only update if there were changes to the balance
196- if (thisInfo.cachedBalanceString != newEncoded) {
197- await isar.writeTxn (() async {
191+ // Read inside the tx so concurrent updates don't create a race condition.
192+ await isar.writeTxn (() async {
193+ final thisInfo = await isar.walletInfo
194+ .where ()
195+ .walletIdEqualTo (walletId)
196+ .findFirst ();
197+ if (thisInfo != null && thisInfo.cachedBalanceString != newEncoded) {
198198 await isar.walletInfo.delete (thisInfo.id);
199199 await isar.walletInfo.put (
200200 thisInfo.copyWith (cachedBalanceString: newEncoded),
201201 );
202- });
203- }
202+ }
203+ });
204204 }
205205
206206 Future <void > updateBalanceSecondary ({
207207 required Balance newBalance,
208208 required Isar isar,
209209 }) async {
210- // try to get latest instance of this from db
211- final thisInfo = await isar.walletInfo.get (id) ?? this ;
212-
213210 final newEncoded = newBalance.toJsonIgnoreCoin ();
214-
215- // only update if there were changes to the balance
216- if (thisInfo.cachedBalanceSecondaryString != newEncoded) {
217- await isar.writeTxn (() async {
211+ await isar.writeTxn (() async {
212+ final thisInfo = await isar.walletInfo
213+ .where ()
214+ .walletIdEqualTo (walletId)
215+ .findFirst ();
216+ if (thisInfo != null &&
217+ thisInfo.cachedBalanceSecondaryString != newEncoded) {
218218 await isar.walletInfo.delete (thisInfo.id);
219219 await isar.walletInfo.put (
220220 thisInfo.copyWith (cachedBalanceSecondaryString: newEncoded),
221221 );
222- });
223- }
222+ }
223+ });
224224 }
225225
226226 Future <void > updateBalanceTertiary ({
227227 required Balance newBalance,
228228 required Isar isar,
229229 }) async {
230- // try to get latest instance of this from db
231- final thisInfo = await isar.walletInfo.get (id) ?? this ;
232-
233230 final newEncoded = newBalance.toJsonIgnoreCoin ();
234-
235- // only update if there were changes to the balance
236- if (thisInfo.cachedBalanceTertiaryString != newEncoded) {
237- await isar.writeTxn (() async {
231+ await isar.writeTxn (() async {
232+ final thisInfo = await isar.walletInfo
233+ .where ()
234+ .walletIdEqualTo (walletId)
235+ .findFirst ();
236+ if (thisInfo != null &&
237+ thisInfo.cachedBalanceTertiaryString != newEncoded) {
238238 await isar.walletInfo.delete (thisInfo.id);
239239 await isar.walletInfo.put (
240240 thisInfo.copyWith (cachedBalanceTertiaryString: newEncoded),
241241 );
242- });
243- }
242+ }
243+ });
244244 }
245245
246246 /// copies this with a new chain height and updates the db
247247 Future <void > updateCachedChainHeight ({
248248 required int newHeight,
249249 required Isar isar,
250250 }) async {
251- // try to get latest instance of this from db
252- final thisInfo = await isar.walletInfo.get (id) ?? this ;
253- // only update if there were changes to the height
254- if (thisInfo.cachedChainHeight != newHeight) {
255- await isar.writeTxn (() async {
251+ await isar.writeTxn (() async {
252+ final thisInfo = await isar.walletInfo
253+ .where ()
254+ .walletIdEqualTo (walletId)
255+ .findFirst ();
256+ if (thisInfo != null && thisInfo.cachedChainHeight != newHeight) {
256257 await isar.walletInfo.delete (thisInfo.id);
257258 await isar.walletInfo.put (
258259 thisInfo.copyWith (cachedChainHeight: newHeight),
259260 );
260- });
261- }
261+ }
262+ });
262263 }
263264
264265 /// update favourite wallet and its index it the ui list.
@@ -283,18 +284,18 @@ class WalletInfo implements IsarId {
283284 index = - 1 ;
284285 }
285286
286- // try to get latest instance of this from db
287- final thisInfo = await isar.walletInfo. get (id) ?? this ;
288-
289- // only update if there were changes to the height
290- if (thisInfo.favouriteOrderIndex != index) {
291- await isar. writeTxn (() async {
287+ await isar. writeTxn (() async {
288+ final thisInfo = await isar.walletInfo
289+ . where ()
290+ . walletIdEqualTo (walletId)
291+ . findFirst ();
292+ if (thisInfo != null && thisInfo.favouriteOrderIndex != index) {
292293 await isar.walletInfo.delete (thisInfo.id);
293294 await isar.walletInfo.put (
294295 thisInfo.copyWith (favouriteOrderIndex: index),
295296 );
296- });
297- }
297+ }
298+ });
298299 }
299300
300301 /// copies this with a new name and updates the db
@@ -303,59 +304,60 @@ class WalletInfo implements IsarId {
303304 if (newName.isEmpty) {
304305 throw Exception ("Empty wallet name not allowed!" );
305306 }
306-
307- // try to get latest instance of this from db
308- final thisInfo = await isar.walletInfo.get (id) ?? this ;
309-
310- // only update if there were changes to the name
311- if (thisInfo.name != newName) {
312- await isar.writeTxn (() async {
307+ await isar.writeTxn (() async {
308+ final thisInfo = await isar.walletInfo
309+ .where ()
310+ .walletIdEqualTo (walletId)
311+ .findFirst ();
312+ if (thisInfo != null && thisInfo.name != newName) {
313313 await isar.walletInfo.delete (thisInfo.id);
314314 await isar.walletInfo.put (thisInfo.copyWith (name: newName));
315- });
316- }
315+ }
316+ });
317317 }
318318
319- /// copies this with a new name and updates the db
319+ /// copies this with a new receiving address and updates the db
320320 Future <void > updateReceivingAddress ({
321321 required String newAddress,
322322 required Isar isar,
323323 }) async {
324- // try to get latest instance of this from db
325- final thisInfo = await isar.walletInfo.get (id) ?? this ;
326- // only update if there were changes to the name
327- if (thisInfo.cachedReceivingAddress != newAddress) {
328- await isar.writeTxn (() async {
324+ await isar.writeTxn (() async {
325+ final thisInfo = await isar.walletInfo
326+ .where ()
327+ .walletIdEqualTo (walletId)
328+ .findFirst ();
329+ if (thisInfo != null && thisInfo.cachedReceivingAddress != newAddress) {
329330 await isar.walletInfo.delete (thisInfo.id);
330331 await isar.walletInfo.put (
331332 thisInfo.copyWith (cachedReceivingAddress: newAddress),
332333 );
333- });
334- }
334+ }
335+ });
335336 }
336337
337338 /// update [otherData] with the map entries in [newEntries]
338339 Future <void > updateOtherData ({
339340 required Map <String , dynamic > newEntries,
340341 required Isar isar,
341342 }) async {
342- // try to get latest instance of this from db
343- final thisInfo = await isar.walletInfo.get (id) ?? this ;
343+ await isar.writeTxn (() async {
344+ final thisInfo = await isar.walletInfo
345+ .where ()
346+ .walletIdEqualTo (walletId)
347+ .findFirst ();
348+ if (thisInfo == null ) return ;
344349
345- final Map <String , dynamic > newMap = {};
346- newMap.addAll (thisInfo.otherData);
347- newMap.addAll (newEntries);
348- final encodedNew = jsonEncode (newMap);
350+ final newMap = Map <String , dynamic >.from (thisInfo.otherData)
351+ ..addAll (newEntries);
352+ final encodedNew = jsonEncode (newMap);
349353
350- // only update if there were changes
351- if (thisInfo.otherDataJsonString != encodedNew) {
352- await isar.writeTxn (() async {
354+ if (thisInfo.otherDataJsonString != encodedNew) {
353355 await isar.walletInfo.delete (thisInfo.id);
354356 await isar.walletInfo.put (
355357 thisInfo.copyWith (otherDataJsonString: encodedNew),
356358 );
357- });
358- }
359+ }
360+ });
359361 }
360362
361363 /// Can be dangerous. Don't use unless you know the consequences
@@ -385,28 +387,26 @@ class WalletInfo implements IsarId {
385387 }
386388 }
387389
388- /// copies this with a new name and updates the db
390+ /// copies this with a new restore height and updates the db
389391 Future <void > updateRestoreHeight ({
390392 required int newRestoreHeight,
391393 required Isar isar,
392394 }) async {
393- // don't allow empty names
394395 if (newRestoreHeight < 0 ) {
395396 throw Exception ("Negative restore height not allowed!" );
396397 }
397-
398- // try to get latest instance of this from db
399- final thisInfo = await isar.walletInfo.get (id) ?? this ;
400-
401- // only update if there were changes to the name
402- if (thisInfo.restoreHeight != newRestoreHeight) {
403- await isar.writeTxn (() async {
398+ await isar.writeTxn (() async {
399+ final thisInfo = await isar.walletInfo
400+ .where ()
401+ .walletIdEqualTo (walletId)
402+ .findFirst ();
403+ if (thisInfo != null && thisInfo.restoreHeight != newRestoreHeight) {
404404 await isar.walletInfo.delete (thisInfo.id);
405405 await isar.walletInfo.put (
406406 thisInfo.copyWith (restoreHeight: newRestoreHeight),
407407 );
408- });
409- }
408+ }
409+ });
410410 }
411411
412412 /// copies this with a new name and updates the db
@@ -442,7 +442,8 @@ class WalletInfo implements IsarId {
442442 }) async {
443443 await updateOtherData (
444444 newEntries: {
445- WalletInfoKeys .solanaCustomTokenMintAddresses: newMintAddresses.toList (),
445+ WalletInfoKeys .solanaCustomTokenMintAddresses: newMintAddresses
446+ .toList (),
446447 },
447448 isar: isar,
448449 );
0 commit comments