mirror of
https://github.com/vishalxl/nostr_console.git
synced 2025-03-17 21:31:52 +01:00
gets users posts and feed. has some issues, exceptions are not handled
This commit is contained in:
parent
d60d2ee980
commit
24dfe80679
3
CHANGELOG.md
Normal file
3
CHANGELOG.md
Normal 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
44
bin/nostr_console.dart
Normal 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
158
lib/nostr_console.dart
Normal 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
91
lib/relays.dart
Normal 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
14
pubspec.yaml
Normal 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
|
8
test/nostr_console_test.dart
Normal file
8
test/nostr_console_test.dart
Normal 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(), "");
|
||||
});
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user