Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: resolve issue with sendCountEventToRelays not working #8

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/nostr/core/key_pairs.dart
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class NostrKeyPairs extends Equatable {
String message,
String signature,
) {
return bip340.verify(pubkey, message, signature);
return bip340.verify(pubkey!, message, signature);
}

static bool isValidPrivateKey(String privateKey) {
Expand Down
45 changes: 36 additions & 9 deletions lib/nostr/instance/relays/relays.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ class NostrRelays implements NostrRelaysBase {
nostrRegistry = NostrRegistry(utils: utils);
}

/// The list of relay urls that failed to connect
final List<String> failureRelaysList = [];

/// Represents a registry of all relays that you did registered with the [init] method.
@override
Map<String, WebSocketChannel> get relaysWebSocketsRegistry =>
Expand Down Expand Up @@ -851,20 +854,26 @@ class NostrRelays implements NostrRelaysBase {
required bool shouldReconnectToRelayOnNotice,
required Duration connectionTimeout,
}) async {
final completer = Completer();
final completers = <String, Completer<void>>{};

for (final relay in relaysUrl) {
for (final relay in relaysUrl.toList()) {
if (failureRelaysList.contains(relay)) {
continue;
}
if (nostrRegistry.isRelayRegisteredAndConnectedSuccesfully(relay)) {
utils.log(
'relay with url: $relay is already connected successfully, skipping...',
);

continue;
}

final completer = Completer<String>();
try {
await webSocketsService.connectRelay(
completers[relay] = completer;
// ignore: unawaited_futures
webSocketsService
.connectRelay(
relay: relay,
shouldIgnoreConnectionException: false,
onConnectionSuccess: (relayWebSocket) {
nostrRegistry.registerRelayWebSocket(
relayUrl: relay,
Expand All @@ -891,16 +900,34 @@ class NostrRelays implements NostrRelaysBase {
lazyListeningToRelays: lazyListeningToRelays,
);
}
completer.complete(relay);
},
)
.catchError(
(err) {
onRelayConnectionError?.call(relay, err, null);
completer.completeError(Exception());
},
);
} catch (e) {
onRelayConnectionError?.call(relay, e, null);
completer.completeError(e);
}
}

completer.complete();

return completer.future;
await Future.wait(
completers.keys.map(
(key) => completers[key]!
.future
.timeout(connectionTimeout)
.onError((e, stack) {
if (!failureRelaysList.contains(key)) {
failureRelaysList.add(key);
}
onRelayConnectionError?.call(key, e, null);
return null;
}),
),
);
}

bool _filterNostrEventsWithId(
Expand Down
24 changes: 21 additions & 3 deletions lib/nostr/model/count.dart
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,18 @@ class NostrCountResponse extends Equatable {
assert(countMap is Map);

return NostrCountResponse(
subscriptionId: decodedData[1] as String,
count: int.parse(countMap['count'] as String),
subscriptionId: parseString(decodedData[1]) ?? '',
count: parseInt(countMap['count']) ?? 0,
);
}
final String subscriptionId;
final int count;
@override
List<Object?> get props => throw UnimplementedError();
List<Object?> get props => [
'COUNT',
subscriptionId,
{'count': count},
];

static bool canBeDeserialized(String data) {
final decodedData = jsonDecode(data);
Expand All @@ -84,3 +88,17 @@ class NostrCountResponse extends Equatable {
}
}
}

String? parseString(dynamic data) {
return (data ?? '') != '' ? data.toString() : null;
}

int? parseInt(dynamic data) {
if (data is double) {
return data.toInt();
} else if (data is int) {
return data;
} else {
return int.tryParse(data.toString());
}
}
19 changes: 10 additions & 9 deletions lib/nostr/model/request/request.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,15 @@ class NostrRequest extends Equatable {

/// Serialize the request to send it to the remote relays websockets.
String serialized({String? subscriptionId}) {
this.subscriptionId = subscriptionId ??
this.subscriptionId ??
Nostr.instance.utilsService.consistent64HexChars(
filters
.map((e) => e.toMap().toString())
.reduce((value, element) => value + element),
);

if (this.subscriptionId == null) {
this.subscriptionId = subscriptionId ??
this.subscriptionId ??
Nostr.instance.utilsService.consistent64HexChars(
filters
.map((e) => e.toMap().toString())
.reduce((value, element) => value + element),
);
}
//! The old way of doing it is commented below
// final decodedFilters =
// jsonEncode(filters.map((item) => item.toMap()).toList());
Expand All @@ -44,7 +45,7 @@ class NostrRequest extends Equatable {

final encodedReq = jsonEncode([
NostrConstants.request,
subscriptionId,
this.subscriptionId,
...filters.map((e) => e.toMap()),
]);

Expand Down
20 changes: 15 additions & 5 deletions lib/nostr/service/registry.dart
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,19 @@ class NostrRegistry {

/// Registers an event to the registry with the given [event].
NostrEvent registerEvent(NostrEvent event) {
eventsRegistry[eventUniqueId(event)] = event;
final uniqueId = eventUniqueId(event);
final compareDate = event.createdAt != null
? eventsRegistry[uniqueId]?.createdAt?.compareTo(event.createdAt!)
: null;
if (eventsRegistry.containsKey(uniqueId)) {
if (compareDate != null && compareDate < 0) {
eventsRegistry[uniqueId] = event;
}
} else {
eventsRegistry[uniqueId] = event;
}

return eventsRegistry[eventUniqueId(event)]!;
return eventsRegistry[uniqueId]!;
}

/// REturns an [event] unique id, See also [NostrEvent.uniqueKey].
Expand Down Expand Up @@ -163,9 +173,9 @@ class NostrRegistry {
onCountResponse,
required String relay,
}) {
final relayCountRegister = countResponseCallBacks[subscriptionId];

relayCountRegister?[subscriptionId] = onCountResponse;
final relayCountRegister =
getOrCreateRegister(countResponseCallBacks, relay);
relayCountRegister[subscriptionId] = onCountResponse;
}

/// Returns a count response callback from the registry with the given [subscriptionId].
Expand Down
4 changes: 2 additions & 2 deletions pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
name: dart_nostr
description: Develop Scalable Dart/Flutter Nostr clients quickly and easily
version: 8.2.0
version: 8.2.4
repository: https://github.com/anasfik/nostr/

environment:
sdk: ">=3.0.0 <=3.9.9"

dependencies:
bip340: ^0.1.0
bip340: '0.3.0'
equatable: ^2.0.5
convert: ^3.1.1
crypto: ^3.0.2
Expand Down