Skip to content

Commit

Permalink
feat: store token list localdb (#1498)
Browse files Browse the repository at this point in the history
Co-authored-by: Kirill Bubochkin <[email protected]>
Co-authored-by: Justin Enerio <[email protected]>
Co-authored-by: Vlad Sumin <[email protected]>
  • Loading branch information
4 people committed Sep 12, 2024
1 parent 9ec55e8 commit 6be502c
Show file tree
Hide file tree
Showing 35 changed files with 790 additions and 471 deletions.
2 changes: 1 addition & 1 deletion packages/espressocash_app/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ splash:
dart run flutter_native_splash:create

update_tokens:
dart run tool/update_token_list.dart
dart run tool/update_tokens.dart

flutter_test:
dart run $(DART_TEST_DEFINITIONS) tool/tests_setup.dart
Expand Down
Binary file not shown.
22 changes: 20 additions & 2 deletions packages/espressocash_app/lib/data/db/db.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class OutgoingTransferRows extends Table {
Set<Column<Object>> get primaryKey => {id};
}

const int latestVersion = 57;
const int latestVersion = 58;

const _tables = [
OutgoingTransferRows,
Expand All @@ -39,6 +39,7 @@ const _tables = [
TransactionRequestRows,
TokenBalanceRows,
ConversionRatesRows,
TokenRows,
];

@lazySingleton
Expand Down Expand Up @@ -128,7 +129,6 @@ class MyDatabase extends _$MyDatabase {
await m.addColumn(onRampOrderRows, onRampOrderRows.referenceNumber);
await m.addColumn(onRampOrderRows, onRampOrderRows.feeAmount);
}

if (from >= 40 && from < 54) {
await m.addColumn(offRampOrderRows, offRampOrderRows.authToken);
await m.addColumn(offRampOrderRows, offRampOrderRows.moreInfoUrl);
Expand Down Expand Up @@ -161,6 +161,9 @@ class MyDatabase extends _$MyDatabase {
if (from < 57) {
await m.addColumn(onRampOrderRows, onRampOrderRows.bridgeAmount);
}
if (from < 58) {
await m.createTable(tokenRows);
}
},
);
}
Expand Down Expand Up @@ -329,3 +332,18 @@ class ConversionRatesRows extends Table {
@override
Set<Column<Object>> get primaryKey => {token, fiatCurrency};
}

class TokenRows extends Table {
const TokenRows();

IntColumn get chainId => integer()();
TextColumn get address => text()();
TextColumn get symbol => text()();
TextColumn get name => text()();
IntColumn get decimals => integer()();
TextColumn get logoURI => text().nullable()();
BoolColumn get isStablecoin => boolean()();

@override
Set<Column> get primaryKey => {chainId, address};
}
4 changes: 0 additions & 4 deletions packages/espressocash_app/lib/di.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import 'package:solana/solana.dart';

import 'config.dart';
import 'di.config.dart';
import 'features/tokens/token_list.dart';

final sl = GetIt.instance;

Expand All @@ -28,9 +27,6 @@ abstract class AppModule {
@lazySingleton
Dio get dio => Dio();

@lazySingleton
TokenList get tokenList => TokenList();

@lazySingleton
SolanaClient get solanaClient => SolanaClient(
rpcUrl: Uri.parse(solanaRpcUrl),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import '../../../data/db/db.dart';
import '../../outgoing_direct_payments/data/repository.dart';
import '../../outgoing_dln_payments/data/repository.dart';
import '../../outgoing_link_payments/data/repository.dart';
import '../../tokens/token_list.dart';
import '../../transaction_request/models/transaction_request.dart';
import '../models/activity.dart';

Expand All @@ -14,10 +13,10 @@ extension PaymentRequestRowToActivityExt on PaymentRequestRow {
}

extension ODPRowToActivityExt on ODPRow {
Activity toActivity(TokenList tokens) => Activity.outgoingDirectPayment(
Future<Activity> toActivity() async => Activity.outgoingDirectPayment(
id: id,
created: created,
data: toModel(tokens),
data: await toModel(),
);
}

Expand All @@ -30,10 +29,10 @@ extension OutgoingDlnPaymentRowToActivityExt on OutgoingDlnPaymentRow {
}

extension OLPRowToActivityExt on OLPRow {
Activity toActivity(TokenList tokens) => Activity.outgoingLinkPayment(
Future<Activity> toActivity() async => Activity.outgoingLinkPayment(
id: id,
created: created,
data: toModel(tokens),
data: await toModel(),
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,16 @@ import '../../currency/models/currency.dart';
import '../../outgoing_direct_payments/data/repository.dart';
import '../../outgoing_link_payments/data/repository.dart';
import '../../payment_request/data/repository.dart';
import '../../tokens/token_list.dart';
import '../../transaction_request/service/tr_service.dart';
import '../models/activity.dart';
import '../models/transaction.dart';
import 'activity_builder.dart';

@injectable
class TransactionRepository {
const TransactionRepository(this._db, this._tokens);
const TransactionRepository(this._db);

final MyDatabase _db;
final TokenList _tokens;

Stream<IList<String>> watchAll() {
final query = _db.select(_db.transactionRows)
Expand Down Expand Up @@ -96,13 +94,13 @@ class TransactionRepository {

final odp = _db.oDPRows.findActivityOrNull(
where: (row) => row.txId.equals(txId),
builder: (pr) => pr.toActivity(_tokens),
builder: (pr) => pr.toActivity(),
ignoreWhen: (row) => row.status != ODPStatusDto.success,
);

final olp = _db.oLPRows.findActivityOrNull(
where: (row) => row.txId.equals(txId),
builder: (pr) => pr.toActivity(_tokens),
builder: (pr) => pr.toActivity(),
ignoreWhen: (row) => const [OLPStatusDto.withdrawn, OLPStatusDto.canceled]
.contains(row.status)
.not(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import '../../outgoing_link_payments/data/repository.dart';
import '../../payment_request/data/repository.dart';
import '../../ramp/services/off_ramp_order_service.dart';
import '../../ramp/services/on_ramp_order_service.dart';
import '../../tokens/token_list.dart';
import '../../transaction_request/service/tr_service.dart';
import '../data/activity_builder.dart';
import '../models/activity.dart';
Expand All @@ -19,14 +18,12 @@ import '../models/activity.dart';
class PendingActivitiesRepository {
const PendingActivitiesRepository(
this._db,
this._tokens,
this._onRampOrderService,
this._offRampOrderService,
this._trService,
);

final MyDatabase _db;
final TokenList _tokens;
final OnRampOrderService _onRampOrderService;
final OffRampOrderService _offRampOrderService;
final TRService _trService;
Expand All @@ -49,10 +46,14 @@ class PendingActivitiesRepository {

final oprStream =
opr.watch().map((rows) => rows.map((r) => r.toActivity()));
final odpStream =
odp.watch().map((rows) => rows.map((r) => r.toActivity(_tokens)));
final olpStream =
olp.watch().map((rows) => rows.map((r) => r.toActivity(_tokens)));

final odpStream = odp
.watch()
.asyncMap((rows) async => Future.wait(rows.map((r) => r.toActivity())));

final olpStream = olp
.watch()
.asyncMap((rows) async => Future.wait(rows.map((r) => r.toActivity())));

final outgoingDlnStream = outgoingDlnPayment
.watch()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,37 +25,43 @@ class PaymentRequestTile extends StatefulWidget {
}

class _PaymentRequestTileState extends State<PaymentRequestTile> {
late Stream<PaymentRequest> _stream;
late Stream<(PaymentRequest, String)> _stream;

@override
void initState() {
super.initState();
_stream = watchPaymentRequest(widget.id);
_stream = watchPaymentRequest(widget.id).asyncMap((p) async {
if (!mounted) return (p, '');

return (p, await p.formattedAmount(DeviceLocale.localeOf(context)));
});
}

@override
Widget build(BuildContext context) => StreamBuilder<PaymentRequest>(
Widget build(BuildContext context) => StreamBuilder<(PaymentRequest, String)>(
stream: _stream,
builder: (context, snapshot) {
final data = snapshot.data;

return data == null
return (data == null)
? SizedBox.shrink(key: ValueKey(widget.id))
: CpActivityTile(
key: ValueKey(widget.id),
title: context.l10n.paymentRequestTitle,
icon: Assets.icons.paymentIcon.svg(),
timestamp: context.formatDate(data.created),
incomingAmount:
data.formattedAmount(DeviceLocale.localeOf(context)),
status: switch (data.state) {
timestamp: context.formatDate(data.$1.created),
incomingAmount: data.$2,
status: switch (data.$1.state) {
PaymentRequestState.initial =>
CpActivityTileStatus.inProgress,
PaymentRequestState.completed =>
CpActivityTileStatus.success,
PaymentRequestState.error => CpActivityTileStatus.failure,
},
onTap: () => PaymentRequestScreen.push(context, id: data.id),
onTap: () => PaymentRequestScreen.push(
context,
id: data.$1.id,
),
showIcon: widget.showIcon,
);
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ class _PinInputDisplayWidgetState extends State<PinInputDisplayWidget> {
Text(
message.toUpperCase(),
style: Theme.of(context).textTheme.titleSmall?.copyWith(
fontFamily: 'Roboto App',
fontWeight: FontWeight.w700,
fontSize: 17,
),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:collection/collection.dart';
import 'package:dfunc/dfunc.dart';
import 'package:drift/drift.dart';
import 'package:fast_immutable_collections/fast_immutable_collections.dart';
import 'package:injectable/injectable.dart';
Expand All @@ -7,15 +8,15 @@ import '../../../data/db/db.dart';
import '../../accounts/auth_scope.dart';
import '../../currency/models/amount.dart';
import '../../currency/models/currency.dart';
import '../../tokens/data/token_repository.dart';
import '../../tokens/token.dart';
import '../../tokens/token_list.dart';

@Singleton(scope: authScope)
class TokenBalancesRepository {
const TokenBalancesRepository(this._db, this._tokens);
const TokenBalancesRepository(this._db, this._tokenRepository);

final MyDatabase _db;
final TokenList _tokens;
final TokenRepository _tokenRepository;

Future<CryptoAmount> read(Token token) async {
final query = _db.tokenBalanceRows.select()
Expand All @@ -36,10 +37,9 @@ class TokenBalancesRepository {
..where((tbl) => tbl.amount.isBiggerThanValue(0));

return query.get().then(
(rows) => rows
.map((row) => _tokens.findTokenByMint(row.token))
.whereNotNull()
.toISet(),
(rows) => Future.wait(
rows.map((row) async => _tokenRepository.getToken(row.token)),
).then((tokens) => tokens.whereNotNull().toISet()),
);
}

Expand All @@ -53,11 +53,10 @@ class TokenBalancesRepository {
tbl.token.isNotIn(ignoreTokens.map((e) => e.address).toList()),
);

return query.watch().map(
(rows) => rows
.map((row) => _tokens.findTokenByMint(row.token))
.whereNotNull()
.toISet(),
return query.watch().asyncMap(
(rows) async => Future.wait(
rows.map((row) async => _tokenRepository.getToken(row.token)),
).then((tokens) => tokens.whereNotNull().toISet()),
);
}

Expand All @@ -71,25 +70,19 @@ class TokenBalancesRepository {
tbl.token.isNotIn(ignoreTokens.map((e) => e.address).toList()),
);

return query.watch().map(
(rows) => rows
.map((row) {
final token = _tokens.findTokenByMint(row.token);

if (ignoreTokens.contains(token)) {
return null;
}

return token == null
? null
: CryptoAmount(
return query.watch().asyncMap(
(rows) async => Future.wait(
rows.map(
(row) async => _tokenRepository.getToken(row.token).letAsync(
(token) => token?.let(
(t) => CryptoAmount(
value: row.amount,
cryptoCurrency: CryptoCurrency(token: token),
);
})
.whereNotNull()
.sortedBy((element) => element.token.name)
.toIList(),
cryptoCurrency: CryptoCurrency(token: t),
),
),
),
),
).then((balances) => balances.whereNotNull().toIList()),
);
}

Expand Down
Loading

0 comments on commit 6be502c

Please sign in to comment.