gets users posts and feed. has some issues, exceptions are not handled

This commit is contained in:
vishalxl 2022-07-10 21:43:10 +05:30
parent d60d2ee980
commit 24dfe80679
6 changed files with 318 additions and 0 deletions

3
CHANGELOG.md Normal file
View File

@ -0,0 +1,3 @@
## 0.1.0
- 10 July 2022 - receives hard coded users latest events, and latest events from feed if NIP 02 type event is seen of the given user

44
bin/nostr_console.dart Normal file
View File

@ -0,0 +1,44 @@
import 'dart:io';
import 'package:nostr_console/nostr_console.dart';
import 'package:nostr_console/relays.dart';
var userPublickey = "3235036bd0957dfb27ccda02d452d7c763be40c91a1ac082ba6983b25238388c";
Future<void> main() async {
List<Event> events = [];
int numEvents = 6;
getUserEvents(defaultServerUrl, userPublickey, events, numEvents);
print('waiting for user events to come in');
Future.delayed(const Duration(milliseconds: 2000), () {
for( int i = 0; i < events.length; i++) {
var e = events[i];
if( e.eventData.kind == 3) {
print('calling getfeed');
getFeed(e.eventData.contactList, events, 3);
}
}
print('waiting for feed to come in');
Future.delayed(const Duration(milliseconds: 4000), () {
events.sort(ascendingTime);
print('====================all events =================');
printEvents(events);
print('number of all events: ${events.length}');
exit(0);
});
});
}

158
lib/nostr_console.dart Normal file
View File

@ -0,0 +1,158 @@
int keyLenPrinted = 6;
String defaultServerUrl = 'wss://nostr-pub.wellorder.net';
class Contact {
String id;
String relay;
String name;
Contact(this.id, this.relay, this.name);
factory Contact.fromJson(dynamic json) {
return Contact(json[1] as String, json[2] as String, json[3]);
}
}
class EventData {
String id;
String pubkey;
String content;
int createdAt;
int kind;
List<Contact> contactList = [];
EventData(this.id, this.pubkey, this.content, this.createdAt, this.kind, this.contactList);
factory EventData.fromJson(dynamic json) {
List<Contact> contactList = [];
// NIP 02: if the event is a contact list type, then populate contactList
if(json['kind'] == 3) {
var tags = json['tags'];
//print(tags);
var numTags = tags.length;
for( int i = 0; i < numTags; i++) {
var tag = tags[i];
var n = tag.length;
String server = defaultServerUrl;
if( n >=3 ) {
server = tag[2].toString();
}
Contact c = Contact(tag[1] as String, server, 3.toString());
contactList.add(c);
}
}
// return
return EventData(json['id'] as String,
json['pubkey'] as String,
json['content'] as String,
json['created_at'] as int,
json['kind'] as int,
contactList);
}
@override
String toString() {
if( id == "non") {
return '';
}
String max3(String v) => v.length > 3? v.substring(0,3) : v.substring(0, v.length);
DateTime dTime = DateTime.fromMillisecondsSinceEpoch(createdAt *1000);
return '-------+\nid : ${max3(id)} \nAuthor : ${max3(pubkey)}\nTime : $dTime\nKind : $kind\nMessage: $content\n';
}
}
class Event {
String event;
String id;
EventData eventData;
Event(this.event, this.id, this.eventData);
factory Event.fromJson(dynamic json) {
if( json.length < 3) {
String e = "";
e = json.length > 1? json[0]: "";
return Event(e,"",EventData("non","","", 0, 0, []));
}
return Event(json[0] as String, json[1] as String, EventData.fromJson(json[2]) );
}
@override
String toString() {
return '$eventData';
}
}
int ascendingTime(Event a, Event b) {
if(a.eventData.createdAt < b.eventData.createdAt) {
return 0;
}
return 1;
}
void printEvents(List<Event> events) {
events.sort(ascendingTime);
for( int i = 0; i < events.length; i++) {
if( events[i].eventData.kind == 1) {
print('${events[i]}');
}
}
}
/*
NIP 02
{
"kind": 3,
"tags": [
["p", "91cf9..4e5ca", "wss://alicerelay.com/", "alice"],
["p", "14aeb..8dad4", "wss://bobrelay.com/nostr", "bob"],
["p", "612ae..e610f", "ws://carolrelay.com/ws", "carol"]
],
"content": "",
...other fields
Example Event returned
[
"EVENT",
"latest",
{
"id": "5e4ca472540c567ba877ab232fa77c0801f4b2121756ed21d827e749b5074ac7",
"pubkey": "47bae3a008414e24b4d91c8c170f7fce777dedc6780a462d010761dca6482327",
"created_at": 1657316002,
"kind": 1,
"tags": [
[
"p",
"80482e60178c2ce996da6d67577f56a2b2c47ccb1c84c81f2b7960637cb71b78",
"wss://relay.damus.io"
],
[
"e",
"241f1108b3616eb4b3cfb9fdbab29d7f8d291fda9db84a79f2491271e2f6122e"
],
[
"e",
"b3349c4de2ff7a672c564e6fd147bc2d5dd71b525f96f35f8ede75138136c867",
"wss://nostr-pub.wellorder.net"
]
],
"content": "Not even surprised it's a thing https://coinmarketcap.com/currencies/lol/",
"sig": "abebbc96a8a922f06ca2773c59521d03b6a8dd5597ae5654afc2d49e03a1e9c193729ff60473f837edc526e41c94f3de8a328c20bf9cff5353cb9c409a982461"
}
]
factory EventData.fromStr(String str) {
var json = jsonDecode(str);
return EventData(json['id'] as String, json['pubkey'] as String, json['content'] as String);
}
*/

91
lib/relays.dart Normal file
View File

@ -0,0 +1,91 @@
import 'dart:io';
import 'dart:convert';
import 'package:nostr_console/nostr_console.dart';
int getLatestNum = 2;
String getSubscriptionRequest(String publicKey, int numUserEvents) {
var strSubscription1 = '["REQ","latest",{ "authors": ["';
var strSubscription2 ='"], "limit": $numUserEvents } ]';
return strSubscription1 + publicKey + strSubscription2;
}
class Relays {
Map<String, Future<WebSocket> > relays;
Relays(this.relays);
factory Relays.relay(String relay) {
Future<WebSocket> fws = WebSocket.connect(relay);
print('In Relay.relay: connecting to relay $relay');
Map<String, Future<WebSocket>> r = Map();
r[relay] = fws;
return Relays(r);
}
void connect(String relay, String publicKey, List<Event> events, int numUserEvents) {
Future<WebSocket>? fws;
if(relays.containsKey(relay)) {
fws = relays[relay];
}
else {
print('connecting to $relay');
try {
fws = WebSocket.connect(relay);
relays[relay] = fws;
fws.then((WebSocket ws) {
ws.listen(
(d) {
print(d);
Event e;
try {
e = Event.fromJson(jsonDecode(d));
events.add(e);
if( e.eventData.kind == 3) {
}
} on FormatException {
print( 'exception in fromJson for event');
}
},
onError: (e) { print("error"); print(e); },
onDone: () { print('in onDone'); ws.close() ; }
);});
} on WebSocketException {
print('WebSocketException exception');
return;
} catch(e) {
print('exception generic');
return;
}
}
print('sending request ${getSubscriptionRequest(publicKey, numUserEvents)}');
fws?.then((WebSocket ws) { ws.add(getSubscriptionRequest(publicKey, numUserEvents)); });
}
Future<WebSocket>? getWS(String relay) {
return relays[relay];
}
}
Relays relays = Relays(Map());
void getFeed(List<Contact> contacts, events, numEvents) {
for( int i = 0; i < contacts.length; i++) {
var contact = contacts[i];
relays.connect(contact.relay, contact.id, events, numEvents);
}
}
void getUserEvents(serverUrl, publicKey, events, numUserEvents) {
relays.connect(serverUrl, publicKey, events, numUserEvents);
}

14
pubspec.yaml Normal file
View File

@ -0,0 +1,14 @@
name: nostr_console
description: A sample command-line application.
version: 1.0.0
# homepage: https://www.example.com
environment:
sdk: '>=2.17.3 <3.0.0'
# dependencies:
# path: ^1.8.0
dev_dependencies:
lints: ^2.0.0
test: ^1.16.0

View File

@ -0,0 +1,8 @@
import 'package:nostr_console/nostr_console.dart';
import 'package:test/test.dart';
void main() {
test('PrintEmptyEvent', () {
expect(EventData("non","","",1,1,[]).toString(), "");
});
}