update to new gdev runtime and hasura squid

This commit is contained in:
poka 2024-04-21 20:29:59 +02:00
parent 258cd11819
commit 56a6213e9c
24 changed files with 719 additions and 474 deletions

View File

@ -103,6 +103,7 @@
"identityCreated": "Identity created",
"identityConfirmed": "Identity confirmed",
"identityExpired": "Identity expired",
"identityRevoked": "Identity revoked",
"confirmYourIdentity": "Confirm your identity",
"noResult": "No results",
"noDuniterNodeAvailableTryLater": "No Duniter node available, please try again later",

View File

@ -104,6 +104,7 @@
"identityCreated": "Identidad creada",
"identityConfirmed": "Identidad confirmada",
"identityExpired": "Identidad caducada",
"identityRevoked": "Identidad revocada",
"confirmYourIdentity": "Confirma tu identidad",
"noResult": "Ningún resultado",
"noDuniterNodeAvailableTryLater": "No hay ningún nodo Duniter disponible, por favor, inténtalo más tarde",

View File

@ -103,6 +103,7 @@
"identityCreated": "Identité créée",
"identityConfirmed": "Identité confirmée",
"identityExpired": "Identité expirée",
"identityRevoked": "Identité révoqué",
"confirmYourIdentity": "Confirmez votre identité",
"noResult": "Aucun résultat",
"noDuniterNodeAvailableTryLater": "Aucun noeud Duniter disponible, veuillez réessayer ultérieurement",

View File

@ -1,5 +1,3 @@
[
"gdev-indexer.p2p.legal",
"gdev-hasura.cgeek.fr",
"hasura-gdev.pini.fr"
"gdev-squid.axiom-team.fr"
]

View File

@ -8,7 +8,7 @@ import 'package:hive_flutter/hive_flutter.dart';
import 'package:logger/logger.dart';
// Version of box data
const int dataVersion = 8;
const int dataVersion = 9;
late String appVersion;
const int pinLength = 5;

View File

@ -1,45 +1,55 @@
const String getNameByAddressQ = r'''
query ($address: String!) {
account_by_pk(pubkey: $address) {
identity {
name
identityConnection(
where: { accountId: { _eq: $address } }
orderBy: { name: ASC }
) {
edges {
node {
name
accountId
}
}
pubkey
}
}
''';
const String searchAddressByNameQ = r'''
query ($name: String!) {
search_identity(args: {name: $name}) {
pubkey
name
identityConnection(
where: { name: { _ilike: $name } }
orderBy: { name: ASC }
) {
edges {
node {
name
accountId
}
}
}
}
''';
const String getHistoryByAddressRelayQ = r'''
query ($address: String!, $number: Int!, $cursor: String) {
transaction_connection(where:
{_or: [
{issuer_pubkey: {_eq: $address}},
{receiver_pubkey: {_eq: $address}}
]},
order_by: {created_at: desc},
first: $number,
after: $cursor) {
query ($address: String!, $first: Int!, $after: String) {
transferConnection(
after: $after
first: $first
orderBy: { timestamp: DESC }
where: { _or: [{ fromId: { _eq: $address } }, { toId: { _eq: $address } }] }
) {
edges {
node {
amount
created_at
issuer_pubkey
receiver_pubkey
issuer {
timestamp
fromId
from {
identity {
name
}
}
receiver {
toId
to {
identity {
name
}
@ -49,35 +59,6 @@ query ($address: String!, $number: Int!, $cursor: String) {
pageInfo {
endCursor
hasNextPage
hasPreviousPage
startCursor
}
}
}
''';
const String getHistoryByAddressQ = r'''
query ($address: String!, $number: Int!, $offset: Int!) {
transaction_aggregate(where: {_or: [{issuer_pubkey: {_eq: $address}}, {receiver_pubkey: {_eq: $address}}]}) {
aggregate {
count
}
}
transaction(where: {_or: [{issuer_pubkey: {_eq: $address}}, {receiver_pubkey: {_eq: $address}}]}, order_by: {created_at: desc}, limit: $number, offset: $offset) {
amount
comment
created_at
issuer {
pubkey
identity {
name
}
}
receiver {
pubkey
identity {
name
}
}
}
}
@ -85,52 +66,79 @@ query ($address: String!, $number: Int!, $offset: Int!) {
const String getCertsReceived = r'''
query ($address: String!) {
certification(where: {receiver: {pubkey: {_eq: $address}}}, order_by: {created_at: desc}) {
issuer {
pubkey
name
certConnection(
where: {receiver: {accountId: {_eq: $address}}}
) {
edges {
node {
createdOn
issuer {
accountId
name
}
}
}
created_at
}
}
''';
const String getCertsSent = r'''
query ($address: String!) {
certification(where: {issuer: {pubkey: {_eq: $address}}}, order_by: {created_at: desc}) {
receiver {
pubkey
name
certConnection(
where: {issuer: {accountId: {_eq: $address}}}
) {
edges {
node {
createdOn
receiver {
accountId
name
}
}
}
created_at
}
}
''';
const String isIdtyExistQ = r'''
query ($name: String!) {
identity(where: {name: {_eq: $name}}) {
name
identityConnection(where: {name: {_eq: ""}}) {
edges {
node {
name
}
}
}
}
''';
const String getBlockchainStartQ = r'''
query {
block(limit: 1) {
created_at
number
blockConnection(first: 1) {
edges {
node {
height
timestamp
}
}
}
}
''';
const String subscribeHistoryIssuedQ = r'''
subscription ($address: String!) {
account_by_pk(pubkey: $address) {
transactions_issued(limit: 1, order_by: {created_at: desc}) {
receiver_pubkey
amount
created_at
accountConnection(
where: {id: {_eq: $address}}
) {
edges {
node {
transfersIssued(limit: 1, orderBy: {timestamp: DESC}) {
toId
amount
timestamp
blockNumber
}
}
}
}
}

View File

@ -74,13 +74,13 @@ class WalletData extends HiveObject {
}
bool hasIdentity() {
return identityStatus == IdtyStatus.created ||
identityStatus == IdtyStatus.confirmed ||
identityStatus == IdtyStatus.validated;
return identityStatus == IdtyStatus.unconfirmed ||
identityStatus == IdtyStatus.unvalidated ||
identityStatus == IdtyStatus.member;
}
bool isMembre() {
return identityStatus == IdtyStatus.validated;
return identityStatus == IdtyStatus.member;
}
bool exist() {
@ -139,17 +139,20 @@ enum IdtyStatus {
none,
@HiveField(1)
created,
unconfirmed,
@HiveField(2)
confirmed,
unvalidated,
@HiveField(3)
validated,
member,
@HiveField(4)
expired,
notMember,
@HiveField(5)
revoked,
@HiveField(6)
unknown
}

View File

@ -83,14 +83,16 @@ class IdtyStatusAdapter extends TypeAdapter<IdtyStatus> {
case 0:
return IdtyStatus.none;
case 1:
return IdtyStatus.created;
return IdtyStatus.unconfirmed;
case 2:
return IdtyStatus.confirmed;
return IdtyStatus.unvalidated;
case 3:
return IdtyStatus.validated;
return IdtyStatus.member;
case 4:
return IdtyStatus.expired;
return IdtyStatus.notMember;
case 5:
return IdtyStatus.revoked;
case 6:
return IdtyStatus.unknown;
default:
return IdtyStatus.none;
@ -103,21 +105,24 @@ class IdtyStatusAdapter extends TypeAdapter<IdtyStatus> {
case IdtyStatus.none:
writer.writeByte(0);
break;
case IdtyStatus.created:
case IdtyStatus.unconfirmed:
writer.writeByte(1);
break;
case IdtyStatus.confirmed:
case IdtyStatus.unvalidated:
writer.writeByte(2);
break;
case IdtyStatus.validated:
case IdtyStatus.member:
writer.writeByte(3);
break;
case IdtyStatus.expired:
case IdtyStatus.notMember:
writer.writeByte(4);
break;
case IdtyStatus.unknown:
case IdtyStatus.revoked:
writer.writeByte(5);
break;
case IdtyStatus.unknown:
writer.writeByte(6);
break;
}
}

View File

@ -11,10 +11,11 @@ import 'package:graphql_flutter/graphql_flutter.dart';
class DuniterIndexer with ChangeNotifier {
Map<String, String?> walletNameIndexer = {};
String? fetchMoreCursor;
Map? pageInfo;
List? transBC;
List listIndexerEndpoints = [];
bool isLoadingIndexer = false;
bool hasNextPage = false;
Future<QueryResult<Object?>?> Function()? refetch;
late GraphQLClient indexerClient;
@ -29,7 +30,7 @@ class DuniterIndexer with ChangeNotifier {
client.connectionTimeout = const Duration(milliseconds: 4000);
try {
final request =
await client.postUrl(Uri.parse('https://$endpoint/v1/graphql'));
await client.postUrl(Uri.parse('https://$endpoint/v1beta1/relay'));
final response = await request.close();
if (response.statusCode != 200) {
log.w('Indexer $endpoint is offline');
@ -98,7 +99,7 @@ class DuniterIndexer with ChangeNotifier {
}
try {
final endpointPath = 'https://${listIndexerEndpoints[i]}/v1/graphql';
final endpointPath = 'https://${listIndexerEndpoints[i]}/v1beta1/relay';
final request = await client.postUrl(Uri.parse(endpointPath));
final response = await request.close();
@ -134,21 +135,21 @@ class DuniterIndexer with ChangeNotifier {
List transBC = [];
int i = 0;
for (final transaction in blockchainTX) {
final direction =
transaction['issuer']['pubkey'] != address ? 'RECEIVED' : 'SENT';
for (final transactionNode in blockchainTX) {
final transaction = transactionNode['node'];
final direction = transaction['fromId'] != address ? 'RECEIVED' : 'SENT';
transBC.add(i);
transBC[i] = [];
transBC[i].add(DateTime.parse(transaction['created_at']));
transBC[i].add(DateTime.parse(transaction['timestamp']));
final amountBrut = transaction['amount'];
final amount = removeDecimalZero(amountBrut / 100);
if (direction == "RECEIVED") {
transBC[i].add(transaction['issuer']['pubkey']);
transBC[i].add(transaction['issuer']['identity']?['name'] ?? '');
transBC[i].add(transaction['fromId']);
transBC[i].add(transaction['from']['identity']?['name'] ?? '');
} else if (direction == "SENT") {
transBC[i].add(transaction['receiver']['pubkey']);
transBC[i].add(transaction['receiver']['identity']?['name'] ?? '');
transBC[i].add(transaction['toId']);
transBC[i].add(transaction['to']['identity']?['name'] ?? '');
}
transBC[i].add(amount);
transBC[i].add(direction);
@ -158,36 +159,38 @@ class DuniterIndexer with ChangeNotifier {
return transBC;
}
FetchMoreOptions? mergeQueryResult(
{required List transactions,
required FetchMoreOptions? opts,
required String address,
required int nRepositories,
required int offset}) {
// pageInfo = result.data!['transaction_connection']['pageInfo'];
// fetchMoreCursor = pageInfo!['endCursor'];
FetchMoreOptions? mergeQueryResult(QueryResult result, FetchMoreOptions? opts,
String address, int nRepositories) {
final List<dynamic> blockchainTX =
(result.data!['transferConnection']['edges'] as List<dynamic>);
pageInfo = result.data!['transferConnection']['pageInfo'];
fetchMoreCursor = pageInfo!['endCursor'];
// final hasNextPage = pageInfo!['hasNextPage'];
// final hasPreviousPage = pageInfo!['hasPreviousPage'];
// log.d('endCursor: $fetchMoreCursor $hasNextPage $hasPreviousPage');
// log.d('endCursor: $fetchMoreCursor $hasNextPage');
// if (fetchMoreCursor != null) {
opts = FetchMoreOptions(
variables: {'offset': offset, 'number': nRepositories},
updateQuery: (previousResultData, fetchMoreResultData) {
final List<dynamic> repos = [
...previousResultData!['transaction'] as List<dynamic>,
...fetchMoreResultData!['transaction'] as List<dynamic>
];
if (fetchMoreCursor != null) {
opts = FetchMoreOptions(
variables: {'after': fetchMoreCursor, 'first': nRepositories},
updateQuery: (previousResultData, fetchMoreResultData) {
final List<dynamic> repos = [
...previousResultData!['transferConnection']['edges']
as List<dynamic>,
...fetchMoreResultData!['transferConnection']['edges']
as List<dynamic>
];
fetchMoreResultData['transaction'] = repos;
return fetchMoreResultData;
},
);
transBC = parseHistory(transactions, address);
// } else {
// log.d("Activity start of $address");
// }
fetchMoreResultData['transferConnection']['edges'] = repos;
return fetchMoreResultData;
},
);
}
if (fetchMoreCursor != null) {
transBC = parseHistory(blockchainTX, address);
} else {
log.d("Activity start of $address");
}
return opts;
}
@ -203,14 +206,15 @@ class DuniterIndexer with ChangeNotifier {
'name': name,
};
final result = await _execQuery(isIdtyExistQ, variables);
log.d(result.data);
return result.data?['identity']?.isNotEmpty ?? false;
}
Future<DateTime> getBlockStart() async {
final result = await _execQuery(getBlockchainStartQ, {});
if (!result.hasException) {
startBlockchainTime =
DateTime.parse(result.data!['block'][0]['created_at']);
startBlockchainTime = DateTime.parse(
result.data!['blockConnection']['edges'][0]['node']['timestamp']);
startBlockchainInitialized = true;
return startBlockchainTime;
}

View File

@ -215,7 +215,8 @@ class SubstrateSdk with ChangeNotifier {
return [];
}
final certsReceiver =
await _getStorage('cert.storageIdtyCertMeta($idtyIndex)') ?? [];
await _getStorage('certification.storageIdtyCertMeta($idtyIndex)') ??
[];
try {
certsCounterCache.update(
@ -241,7 +242,7 @@ class SubstrateSdk with ChangeNotifier {
if (idtyIndexFrom == null || idtyIndexTo == null) return 0;
final List certData =
await _getStorage('cert.certsByReceiver($idtyIndexTo)') ?? [];
await _getStorage('certification.certsByReceiver($idtyIndexTo)') ?? [];
if (certData.isEmpty) return 0;
for (List certInfo in certData) {
@ -395,7 +396,7 @@ class SubstrateSdk with ChangeNotifier {
} else if (nextIssuableOn > blocNumber) {
final certDelayDuration = (nextIssuableOn - blocNumber) * 6;
result.putIfAbsent('certDelay', () => certDelayDuration);
} else if (toStatus == IdtyStatus.created) {
} else if (toStatus == IdtyStatus.unconfirmed) {
result.putIfAbsent('toStatus', () => 1);
} else if (toStatus == IdtyStatus.none) {
result.putIfAbsent('toStatus', () => 2);
@ -412,7 +413,8 @@ class SubstrateSdk with ChangeNotifier {
var idtyIndex = await _getIdentityIndexOf(address);
final certMeta =
await _getStorage('cert.storageIdtyCertMeta($idtyIndex)') ?? '';
await _getStorage('certification.storageIdtyCertMeta($idtyIndex)') ??
'';
return certMeta;
}
@ -455,10 +457,11 @@ class SubstrateSdk with ChangeNotifier {
List<IdtyStatus> resultStatus = [];
final mapStatus = {
null: IdtyStatus.none,
'Created': IdtyStatus.created,
'ConfirmedByOwner': IdtyStatus.confirmed,
'Validated': IdtyStatus.validated,
'Expired': IdtyStatus.expired,
'Unconfirmed': IdtyStatus.unconfirmed,
'Unvalidated': IdtyStatus.unvalidated,
'Member': IdtyStatus.member,
'NotMember': IdtyStatus.notMember,
'Revoked': IdtyStatus.revoked,
'unknown': IdtyStatus.unknown,
};
@ -1048,7 +1051,7 @@ class SubstrateSdk with ChangeNotifier {
final fromIndex = idtyIndexList[0];
final toIndex = idtyIndexList[1];
if (myIdtyStatus != IdtyStatus.validated) {
if (myIdtyStatus != IdtyStatus.member) {
return 'notMember';
}
@ -1069,17 +1072,17 @@ class SubstrateSdk with ChangeNotifier {
sender,
);
txOptions = [destAddress];
} else if (toIdtyStatus == IdtyStatus.validated ||
toIdtyStatus == IdtyStatus.confirmed) {
} else if (toIdtyStatus == IdtyStatus.member ||
toIdtyStatus == IdtyStatus.unvalidated) {
if (toCerts[0] >= currencyParameters['minCertForMembership']! - 1 &&
toIdtyStatus != IdtyStatus.validated) {
toIdtyStatus != IdtyStatus.member) {
log.d('Batch cert and membership validation');
txInfo = TxInfoData(
'utility',
'batchAll',
sender,
);
final tx1 = 'api.tx.cert.addCert($fromIndex, $toIndex)';
final tx1 = 'api.tx.certification.addCert($fromIndex, $toIndex)';
//TODO: add requestDistanceEvaluation tx when available

View File

@ -32,12 +32,13 @@ class V2sDatapodProvider with ChangeNotifier {
};
}
Future<QueryResult> _execQuery(
Future<QueryResult?> _execQuery(
String query, Map<String, dynamic> variables) async {
final QueryOptions options =
QueryOptions(document: gql(query), variables: variables);
return await datapodClient.query(options);
//TODO: Switch to IPFS Datapod
return null;
// final QueryOptions options =
// QueryOptions(document: gql(query), variables: variables);
// return await datapodClient.query(options);
}
Future<bool> updateProfile(
@ -61,11 +62,11 @@ class V2sDatapodProvider with ChangeNotifier {
if (variables.isEmpty) return false;
final result = await _execQuery(updateProfileQ, variables);
if (result.hasException) {
log.e(result.exception.toString());
if (result?.hasException ?? true) {
log.e(result?.exception.toString());
return false;
}
log.d(result.data!['updateProfile']['message']);
log.d(result!.data!['updateProfile']['message']);
return true;
}
@ -75,11 +76,11 @@ class V2sDatapodProvider with ChangeNotifier {
if (variables.isEmpty) return false;
final result = await _execQuery(deleteProfileQ, variables);
if (result.hasException) {
log.e(result.exception.toString());
if (result?.hasException ?? true) {
log.e(result?.exception.toString());
return false;
}
log.d(result.data!['deleteProfile']['message']);
log.d(result!.data!['deleteProfile']['message']);
return true;
}
@ -90,11 +91,11 @@ class V2sDatapodProvider with ChangeNotifier {
if (variables.isEmpty) return false;
final result = await _execQuery(migrateProfileQ, variables);
if (result.hasException) {
log.e(result.exception.toString());
if (result?.hasException ?? true) {
log.e(result?.exception.toString());
return false;
}
log.d(result.data!['migrateProfile']['message']);
log.d(result!.data!['migrateProfile']['message']);
return true;
}
@ -112,11 +113,11 @@ class V2sDatapodProvider with ChangeNotifier {
if (variables.isEmpty) return false;
final result = await _execQuery(addTransactionCommentQ, variables);
if (result.hasException) {
log.e(result.exception.toString());
if (result?.hasException ?? true) {
log.e(result?.exception.toString());
return false;
}
log.d(result.data!['addTransaction']['message']);
log.d(result!.data!['addTransaction']['message']);
return true;
}
@ -131,12 +132,12 @@ class V2sDatapodProvider with ChangeNotifier {
'address': address,
};
final result = await _execQuery(profileEditedAtQ, variables);
if (result.hasException) {
log.e(result.exception.toString());
if (result?.hasException ?? true) {
// log.e(result?.exception.toString());
return null;
}
final String? profileDateData =
result.data!['profiles_by_pk']?['updated_at'];
result!.data!['profiles_by_pk']?['updated_at'];
final profileDate =
profileDateData == null ? null : DateTime.tryParse(profileDateData);
return profileDate;
@ -148,11 +149,11 @@ class V2sDatapodProvider with ChangeNotifier {
'address': address,
};
final result = await _execQuery(getAvatarQ, variables);
if (result.hasException) {
log.e(result.exception.toString());
if (result?.hasException ?? true) {
log.e(result?.exception.toString());
return defaultAvatar(size);
}
final String? avatar64 = result.data!['profiles_by_pk']?['avatar64'];
final String? avatar64 = result!.data!['profiles_by_pk']?['avatar64'];
if (avatar64 == null) {
return defaultAvatar(size);

View File

@ -79,24 +79,24 @@ class _HomeScreenState extends State<HomeScreen> {
duniterIndexer.getValidIndexerEndpoint().then((validIndexerEndpoint) {
final wsLinkIndexer = WebSocketLink(
'wss://$validIndexerEndpoint/v1/graphql',
'wss://$validIndexerEndpoint/v1beta1/relay',
);
const headerWebsocket =
datapodEndpoint == '10.0.2.2:8080' ? 'ws' : 'wss';
final wsLinkDatapod = WebSocketLink(
'$headerWebsocket://$datapodEndpoint/v1/graphql',
);
// const headerWebsocket =
// datapodEndpoint == '10.0.2.2:8080' ? 'ws' : 'wss';
// final wsLinkDatapod = WebSocketLink(
// '$headerWebsocket://$datapodEndpoint/v1/graphql',
// );
duniterIndexer.indexerClient = GraphQLClient(
cache: GraphQLCache(),
link: wsLinkIndexer,
);
datapod.datapodClient = GraphQLClient(
cache: GraphQLCache(),
link: wsLinkDatapod,
);
// datapod.datapodClient = GraphQLClient(
// cache: GraphQLCache(),
// link: wsLinkDatapod,
// );
});
await homeProvider.getValidEndpoints();

View File

@ -151,7 +151,7 @@ class WalletOptions extends StatelessWidget {
size: 24,
color: Colors.black,
fontWeight: wallet.identityStatus ==
IdtyStatus.validated
IdtyStatus.member
? FontWeight.w500
: FontWeight.w400,
fontStyle: FontStyle.normal);
@ -330,7 +330,7 @@ class WalletOptions extends StatelessWidget {
if (!snapshot.hasData || snapshot.hasError) {
return const SizedBox.shrink();
}
if (snapshot.data!.first == IdtyStatus.created) {
if (snapshot.data!.first == IdtyStatus.unconfirmed) {
return Column(children: [
ScaledSizedBox(
width: 310,

View File

@ -62,7 +62,7 @@ class CertsList extends StatelessWidget {
style: scaledTextStyle(fontSize: 18),
)
]);
} else if (result.data?['certification']?.isEmpty) {
} else if (result.data?['certConnection']['edges']?.isEmpty) {
return Column(children: <Widget>[
ScaledSizedBox(height: 50),
Text(
@ -72,12 +72,13 @@ class CertsList extends StatelessWidget {
]);
}
final List certsData = result.data!['certification'];
final List certsData = result.data!['certConnection']['edges'];
List listCerts = [];
for (final cert in certsData) {
final String issuerAddress = cert[certFrom]['pubkey'];
for (final certNode in certsData) {
final cert = certNode['node'];
final String issuerAddress = cert[certFrom]['accountId'];
final String issuerName = cert[certFrom]['name'];
final date = DateTime.parse(cert['created_at']);
final date = DateTime.parse('2024-02-04T21:20:54.001+00:00');
final dp = DateTime(date.year, date.month, date.day);
final dateForm = '${dp.day}-${dp.month}-${dp.year}';

View File

@ -1,12 +1,8 @@
import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:gecko/globals.dart';
import 'package:gecko/models/queries_datapod.dart';
import 'package:gecko/models/scale_functions.dart';
import 'package:gecko/providers/v2s_datapod.dart';
import 'package:graphql_flutter/graphql_flutter.dart';
import 'package:provider/provider.dart';
class DatapodAvatar extends StatelessWidget {
@ -31,44 +27,6 @@ class DatapodAvatar extends StatelessWidget {
}
return ScaledSizedBox(
width: size,
child: GraphQLProvider(
client: ValueNotifier(datapod.datapodClient),
child: Query(
options: QueryOptions(
document: gql(getAvatarQ),
variables: <String, dynamic>{
'address': address,
},
),
builder: (QueryResult result, {fetchMore, refetch}) {
if (result.isLoading || result.data == null) {
return Center(
child: ClipOval(child: datapod.defaultAvatar(size)),
);
}
final String? avatar64 =
result.data!['profiles_by_pk']?['avatar64'];
if (avatar64 == null || result.data == null) {
return ClipOval(child: datapod.defaultAvatar(size));
}
final sanitizedAvatar64 = avatar64
.replaceAll('\n', '')
.replaceAll('\r', '')
.replaceAll(' ', '');
datapod.cacheAvatar(address, sanitizedAvatar64);
return ClipOval(
child: Image.memory(
base64.decode(sanitizedAvatar64),
fit: BoxFit.cover,
),
);
}),
),
);
width: size, child: ClipOval(child: datapod.defaultAvatar(size)));
}
}

View File

@ -45,11 +45,11 @@ class HistoryQuery extends StatelessWidget {
children: <Widget>[
Query(
options: QueryOptions(
document: gql(getHistoryByAddressQ),
document: gql(getHistoryByAddressRelayQ),
variables: <String, dynamic>{
'address': address,
'number': nRepositories,
'offset': 0
'first': nRepositories,
'after': null
},
),
builder: (QueryResult result, {fetchMore, refetch}) {
@ -61,7 +61,8 @@ class HistoryQuery extends StatelessWidget {
),
);
}
final List transactions = result.data?["transaction"];
final List transactions =
result.data?["transferConnection"]["edges"];
// Get transaction in progress if exist
String? transactionId;
@ -106,18 +107,10 @@ class HistoryQuery extends StatelessWidget {
]);
}
final int totalTransactions =
result.data!["transaction_aggregate"]["aggregate"]["count"];
duniterIndexer.hasNextPage =
!(transactions.length == totalTransactions);
opts = duniterIndexer.mergeQueryResult(
transactions: transactions,
opts: opts,
address: address,
nRepositories: nRepositories,
offset: transactions.length,
);
if (result.isNotLoading) {
opts = duniterIndexer.mergeQueryResult(
result, opts, address, nRepositories);
}
// Build history list
return NotificationListener(
@ -144,10 +137,14 @@ class HistoryQuery extends StatelessWidget {
),
),
onNotification: (dynamic t) {
if (duniterIndexer.pageInfo == null) {
duniterIndexer.reload();
}
if (t is ScrollEndNotification &&
scrollController.position.pixels >=
scrollController.position.maxScrollExtent * 0.7 &&
duniterIndexer.hasNextPage &&
duniterIndexer.pageInfo!['hasNextPage'] &&
result.isNotLoading) {
fetchMore!(opts!);
}

View File

@ -99,14 +99,14 @@ class HistoryView extends StatelessWidget {
context: context),
]);
}).toList()),
if (result.isLoading && duniterIndexer.hasNextPage)
if (result.isLoading && duniterIndexer.pageInfo!['hasNextPage'])
const Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Loading(size: 30, stroke: 3),
],
),
if (!duniterIndexer.hasNextPage &&
if (!duniterIndexer.pageInfo!['hasNextPage'] &&
sub.oldOwnerKeys[address]?[0] != null)
Padding(
padding: const EdgeInsets.symmetric(vertical: 30),
@ -152,7 +152,7 @@ class HistoryView extends StatelessWidget {
),
),
),
if (!duniterIndexer.hasNextPage)
if (!duniterIndexer.pageInfo!['hasNextPage'])
Column(
children: <Widget>[
ScaledSizedBox(height: 15),

View File

@ -37,14 +37,14 @@ class IdentityStatus extends StatelessWidget {
final resStatus = walletData.identityStatus;
if (!isOwner) {
if (resStatus == IdtyStatus.confirmed) {
if (resStatus == IdtyStatus.unvalidated) {
return NameByAddress(
wallet: walletData,
size: 18,
color: Colors.grey[700]!,
fontWeight: FontWeight.w500,
fontStyle: FontStyle.italic);
} else if (resStatus == IdtyStatus.validated) {
} else if (resStatus == IdtyStatus.member) {
return NameByAddress(
wallet: walletData,
size: 20,
@ -56,16 +56,17 @@ class IdentityStatus extends StatelessWidget {
final Map<IdtyStatus, String> statusText = {
IdtyStatus.none: '',
IdtyStatus.created: 'identityCreated'.tr(),
IdtyStatus.confirmed: 'identityConfirmed'.tr(),
IdtyStatus.validated: 'memberValidated'.tr(),
IdtyStatus.expired: 'identityExpired'.tr(),
IdtyStatus.unconfirmed: 'identityCreated'.tr(),
IdtyStatus.unvalidated: 'identityConfirmed'.tr(),
IdtyStatus.member: 'memberValidated'.tr(),
IdtyStatus.notMember: 'identityExpired'.tr(),
IdtyStatus.revoked: 'identityRevoked'.tr(),
IdtyStatus.unknown: ''
};
return SizedBox(
child: showText(statusText[resStatus]!,
bold: resStatus == IdtyStatus.validated, size: scaleSize(17)),
bold: resStatus == IdtyStatus.member, size: scaleSize(17)),
);
});
});

View File

@ -56,8 +56,12 @@ class NameByAddress extends StatelessWidget {
return const Loading();
}
duniterIndexer.walletNameIndexer[wallet.address] =
result.data?['account_by_pk']?['identity']?['name'];
final edges = result.data?['identityConnection']['edges'];
final name = edges != null && edges.isNotEmpty
? edges[0]['node']['name']
: null;
duniterIndexer.walletNameIndexer[wallet.address] = name;
g1WalletsBox.put(
wallet.address,

View File

@ -38,8 +38,8 @@ void paymentPopup(BuildContext context, String toAddress, String? username) {
// Payment workflow !
final sub = Provider.of<SubstrateSdk>(context, listen: false);
final acc = sub.getCurrentWallet();
log.d(
"fromAddress: ${acc.address!},destAddress: $toAddress, amount: ${double.parse(walletViewProvider.payAmount.text)}");
// log.d(
// "fromAddress: ${acc.address!},destAddress: $toAddress, amount: ${double.parse(walletViewProvider.payAmount.text)}");
final transactionId = await sub.pay(
fromAddress: acc.address!,
destAddress: toAddress,

View File

@ -35,7 +35,7 @@ class SearchIdentityQuery extends StatelessWidget {
options: QueryOptions(
document: gql(searchAddressByNameQ),
variables: {
'name': name,
'name': '%$name%',
},
),
builder: (QueryResult result,
@ -50,15 +50,16 @@ class SearchIdentityQuery extends StatelessWidget {
return Text('loading'.tr());
}
final List identities = result.data?['search_identity'] ?? [];
final List identities =
result.data?['identityConnection']['edges'] ?? [];
if (identities.isEmpty) {
return Text('noResult'.tr());
}
for (Map profile in identities) {
duniterIndexer.walletNameIndexer
.putIfAbsent(profile['pubkey'], () => profile['name']);
duniterIndexer.walletNameIndexer.putIfAbsent(
profile['node']['accountId'], () => profile['node']['name']);
}
searchProvider.resultLenght = identities.length;
@ -68,13 +69,14 @@ class SearchIdentityQuery extends StatelessWidget {
child: ListView(children: <Widget>[
for (Map profile in identities)
ListTile(
key: keySearchResult(profile['pubkey']),
key: keySearchResult(profile['node']['accountId']),
horizontalTitleGap: 10,
contentPadding: const EdgeInsets.only(right: 2),
leading: DatapodAvatar(
address: profile['pubkey'], size: avatarSize),
address: profile['node']['accountId'],
size: avatarSize),
title: Row(children: <Widget>[
Text(getShortPubkey(profile['pubkey']),
Text(getShortPubkey(profile['node']['accountId']),
style: scaledTextStyle(
fontSize: 16,
fontFamily: 'Monospace',
@ -90,12 +92,13 @@ class SearchIdentityQuery extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.center,
children: [
Balance(
address: profile['pubkey'], size: 15),
address: profile['node']['accountId'],
size: 15),
]),
]),
),
subtitle: Row(children: <Widget>[
Text(profile['name'] ?? '',
Text(profile['node']['name'] ?? '',
style: scaledTextStyle(
fontSize: 17, fontWeight: FontWeight.w500),
textAlign: TextAlign.center),
@ -107,10 +110,11 @@ class SearchIdentityQuery extends StatelessWidget {
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
walletsProfiles.address = profile['pubkey'];
walletsProfiles.address =
profile['node']['accountId'];
return WalletViewScreen(
address: profile['pubkey'],
username: profile['name'],
address: profile['node']['accountId'],
username: profile['node']['name'],
);
}),
);

View File

@ -39,17 +39,21 @@ class _TransactionInProgressTuleState extends State<TransactionInProgressTule> {
final stream = duniterIndexer.subscribeHistoryIssued(widget.address);
txContent = sub.transactionStatus[widget.transactionId]!;
//TODO: change way to get finliized transaction status
subscription = stream.listen((result) {
if (result.data?['account_by_pk'] == null) return;
if (result.data?['accountConnection']['edges'] == null) return;
if (result.hasException) {
log.e(result.exception);
isVisible = true;
} else {
final Map transData =
result.data?['account_by_pk']['transactions_issued'].first;
final String receiver = transData['receiver_pubkey'];
final Map transDataNode =
result.data?['accountConnection']['edges'].first;
if (transDataNode['node']['transfersIssued'].isEmpty) return;
final Map transData = transDataNode['node']['transfersIssued'][0];
final String receiver = transData['toId'];
final double amount = transData['amount'] / 100;
final createdAt = DateTime.parse(transData['created_at']);
final createdAt = DateTime.parse(transData['timestamp']);
final difference = createdAt.difference(DateTime.now());
if (receiver == txContent.to &&

File diff suppressed because it is too large Load Diff

View File

@ -5,7 +5,7 @@ description: Pay with G1.
# pub.dev using `pub publish`. This is preferred for private packages.
publish_to: "none" # Remove this line if you wish to publish to pub.dev
version: 0.1.5+72
version: 0.1.6+73
environment:
sdk: ">=2.12.0 <3.0.0"
@ -15,59 +15,63 @@ dependencies:
sdk: flutter
bubble: ^1.2.1
carousel_slider: ^4.2.1
graphql_flutter: ^5.1.2
graphql_flutter: ^5.2.0-beta.6
hive_flutter: ^1.1.0
image_picker: ^1.0.5
image_picker: ^1.1.0
jdenticon_dart: ^2.0.0
logger: ^2.0.2+1
path_provider: ^2.1.1
pdf: ^3.10.7
permission_handler: ^11.1.0
logger: ^2.2.0
path_provider: ^2.1.3
pdf: ^3.10.8
permission_handler: ^11.3.1
pin_code_fields: ^8.0.1
printing: ^5.11.1
provider: ^6.1.1
printing: ^5.12.0
provider: ^6.1.2
barcode_scan2: ^4.3.0
qr_flutter: ^4.1.0
responsive_framework: ^1.1.1
sentry_flutter: ^7.14.0
responsive_framework: ^1.4.0
sentry_flutter: ^7.20.0
truncate: ^3.0.1
unorm_dart: ^0.3.0
dio: ^5.4.0
durt: ^0.1.7
package_info_plus: ^5.0.1
unorm_dart: ^0.2.0
dio: ^5.4.3+1
durt: ^0.1.8
package_info_plus: ^7.0.0
polkawallet_sdk: #^0.5.2
git:
# url: https://github.com/polkawallet-io/sdk.git
# ref: develop
url: https://github.com/poka-IT/sdk.git
# ref: gecko-fixes-3
ref: 8b254d9e98cb367b4a57d67f8c6f5bbe89a52552
ref: fcfdb5e9f214c99c8d3a97d3aea38a67ea1fa6a5
dots_indicator: ^3.0.0
connectivity_plus: ^3.0.6
image_cropper: ^4.0.1
easy_localization: ^3.0.3
flutter_markdown: ^0.6.18+2
pointycastle: ^3.7.3
connectivity_plus: ^5.0.2
image_cropper: ^5.0.1
easy_localization: ^3.0.5
flutter_markdown: ^0.7.1
pointycastle: ^3.9.0
hex: ^0.2.0
accordion: ^2.6.0
flutter_svg: ^2.0.9
flutter_svg: ^2.0.10+1
pinenacl: ^0.5.1
fast_base58: ^0.2.1
tutorial_coach_mark: ^1.2.11
confetti: ^0.7.0
url_launcher: ^6.2.2
url_launcher: ^6.2.6
crypto: ^3.0.3
screen_brightness: ^1.0.0
uuid: ^3.0.7
screen_brightness: ^1.0.1
uuid: ^4.4.0
fade_and_translate: ^0.1.3
durt2:
path: ../../durt2
# git:
# url: https://git.duniter.org/libs/durt2
dev_dependencies:
# flutter_launcher_icons: ^0.9.2
# flutter_launcher_icons_maker: ^^0.10.2
icons_launcher: ^2.1.6
build_runner: ^2.4.7
icons_launcher: ^2.1.7
build_runner: ^2.4.9
hive_generator: ^2.0.1
flutter_lints: ^3.0.1
flutter_lints: ^3.0.2
flutter_test:
sdk: flutter
integration_test: