mirror of
https://github.com/vishalxl/nostr_console.git
synced 2025-10-10 19:32:34 +02:00
added support for nevent and nprofile at least partially ( no attempt to get them from relays)
This commit is contained in:
@@ -349,28 +349,38 @@ class EventData {
|
||||
if( !content.contains("nostr:") ) {
|
||||
return content;
|
||||
}
|
||||
var localDebug = false;
|
||||
|
||||
if(localDebug) print("------->\n\n<------- content = \n$content\n\n\n");
|
||||
|
||||
//print("------------------\nin expandMentions: content = $content \n");
|
||||
String replaceMentions(Match mentionTagMatch) {
|
||||
//print("in replaceMentions\n");
|
||||
if(localDebug) print("\n-------------------\nin replaceMentions");
|
||||
String? mentionTag = mentionTagMatch.group(0);
|
||||
if( mentionTag != null) {
|
||||
//print("mentionTag = $mentionTag");
|
||||
if(localDebug) print("mentionTag = $mentionTag");
|
||||
String strBechId = mentionTag.substring(6, mentionTag.length);
|
||||
String tempType = strBechId.substring(0, 4);
|
||||
if( tempType != "note" && tempType != "npub") {
|
||||
//String tempType = strBechId.substring(0, 4);
|
||||
if( !strBechId.startsWith((RegExp(r'npub|note|nevent|nprofile')))) {
|
||||
if(localDebug) print('returning from replaceMentions');
|
||||
return "nostr:$strBechId";
|
||||
}
|
||||
//print("Going to decode: $strBechId");
|
||||
try {
|
||||
Map<String, String> nsec = bech32Decode(strBechId);
|
||||
String? type = nsec["prefix"]; // type can be "note" or "npub"
|
||||
String? strHex = nsec["data"]; // this is 64 byte hex pubkey or note id
|
||||
if( strHex != null && type != null) {
|
||||
String mentionedId = strHex;
|
||||
//print("strHex = $strHex type = $type");
|
||||
|
||||
if( type == "npub") {
|
||||
if(localDebug) print("Going to decode: $strBechId");
|
||||
try {
|
||||
Map<String, String> bech32str = bech32Decode(strBechId);
|
||||
if(localDebug) print('after bech32Decode');
|
||||
String? type = bech32str["prefix"]; // type can be "note", "npub", nevent, nprofile ( others not supported yet)
|
||||
String? hexData = bech32str["data"]; // the data for given type
|
||||
|
||||
if(localDebug) print('after bech32Decode 2');
|
||||
|
||||
if( hexData != null && type != null) {
|
||||
String mentionedId = hexData;
|
||||
if(localDebug) print("strHex = $hexData type = $type");
|
||||
|
||||
switch(type) {
|
||||
case "npub":
|
||||
if( gKindONames.containsKey(mentionedId)) {
|
||||
|
||||
String? author = getOnlyAuthorName(mentionedId);
|
||||
@@ -381,7 +391,9 @@ class EventData {
|
||||
return "@$author";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
break;
|
||||
case "note":
|
||||
if( type == "note") {
|
||||
EventData? mentionedEventData = tempChildEventsMap[mentionedId]?.event.eventData;
|
||||
if( mentionedEventData != null) {
|
||||
@@ -391,37 +403,91 @@ class EventData {
|
||||
String mentionedContent = mentionedEventData.content;
|
||||
|
||||
if( mentionedEventData.evaluatedContent != "") {
|
||||
//print("found evaluated content");
|
||||
if(localDebug) print("found evaluated content");
|
||||
mentionedContent = mentionedEventData.evaluatedContent;
|
||||
} else {
|
||||
//print("didnt find evaluated content");
|
||||
if(localDebug) print("didnt find evaluated content");
|
||||
}
|
||||
|
||||
String quote = "<Quoted event id '$prefixId' by $quotedAuthor: \"$mentionedContent\">";
|
||||
//print("evaluatedContent: ${mentionedEventData.evaluatedContent}\n");
|
||||
return quote;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case "nevent":
|
||||
if(localDebug) print("in nevent");
|
||||
if(localDebug) print("nevent = $mentionedId");
|
||||
Nevent nevent = Nip19.decodeNevent(mentionedId);
|
||||
if( nevent["id"] != null) {
|
||||
String id = nevent["id"] as String;
|
||||
|
||||
EventData? mentionedEventData = tempChildEventsMap[id]?.event.eventData;
|
||||
if( mentionedEventData != null) {
|
||||
String quotedAuthor = getAuthorName(mentionedEventData.pubkey);
|
||||
String prefixId = mentionedId.substring(0, 3);
|
||||
String mentionedContent = mentionedEventData.content;
|
||||
|
||||
if( mentionedEventData.evaluatedContent != "") {
|
||||
if(localDebug) print("found evaluated content");
|
||||
mentionedContent = mentionedEventData.evaluatedContent;
|
||||
} else {
|
||||
//print("Could not find event!\n");
|
||||
if(localDebug) print("didnt find evaluated content");
|
||||
}
|
||||
|
||||
String quote = "<Quoted event id '$prefixId' by $quotedAuthor: \"$mentionedContent\">";
|
||||
//print("evaluatedContent: ${mentionedEventData.evaluatedContent}\n");
|
||||
//print(quote);
|
||||
return quote;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case "nprofile":
|
||||
if(localDebug) print("in nprofile");
|
||||
if(localDebug) print("nprofile = $mentionedId");
|
||||
Nevent nevent = Nip19.decodeNevent(mentionedId);
|
||||
// id is pubkey here
|
||||
if( nevent["id"] != null) {
|
||||
String pubkey = nevent["id"] as String;
|
||||
String? author = getOnlyAuthorName(pubkey);
|
||||
|
||||
if( author == null) {
|
||||
if(localDebug) print("Could not find author for pubkey $pubkey");
|
||||
return "nostr:$strBechId";
|
||||
} else {
|
||||
//print("Could not parse the given nsec/private key. Exiting.");
|
||||
//print("Found author: $author");
|
||||
return "@$author";
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
print("in default");
|
||||
break;
|
||||
}
|
||||
|
||||
return "nostr:$strBechId";
|
||||
} else {
|
||||
print("Could not parse the given nsec/private key. Exiting.");
|
||||
return mentionTag;
|
||||
}
|
||||
} on Exception {
|
||||
//print("====================Caught exctption.");
|
||||
} on Exception catch (e) {
|
||||
print("====================Caught exctption $e");
|
||||
return "nostr:$strBechId";
|
||||
}
|
||||
}
|
||||
if( gDebug >= 0) printWarning("In replaceMentions returning nothing");
|
||||
printWarning("In replaceMentions returning nothing");
|
||||
return "";
|
||||
} // end replaceMentions()
|
||||
|
||||
// replace the mentions, if any are found
|
||||
// The Bech32 alphabet contains 32 characters, including lowercase letters a-z and the numbers 0-9, excluding the number 1 and the letters ‘b’, ‘i’, ‘o’ to avoid reader confusion.
|
||||
String mentionStr = "(nostr:(npub1|note1)[a0c-hj-np-z2-9]{58})"; // bech32
|
||||
String mentionStr = "(nostr:(npub1|note1)[a0c-hj-np-z2-9]{58})|(nostr:(nevent1|nprofile1)[a0c-hj-np-z2-9]+)"; // bech32
|
||||
RegExp mentionRegExp = RegExp(mentionStr, caseSensitive: false);
|
||||
content = content.replaceAllMapped(mentionRegExp, replaceMentions);
|
||||
return content;
|
||||
|
@@ -1,6 +1,11 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:bech32/bech32.dart';
|
||||
import 'package:convert/convert.dart';
|
||||
|
||||
// can have keys: id, relays ( whose value is an array of strings)
|
||||
typedef Nevent = Map<String, Object>;
|
||||
|
||||
/// bech32-encoded entities
|
||||
class Nip19 {
|
||||
static encodePubkey(String pubkey) {
|
||||
@@ -41,8 +46,68 @@ class Nip19 {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
static Nevent decodeNevent(String data) {
|
||||
var localDebug = false;
|
||||
if(localDebug) print("in decodeNevent len data = ${data.length} data = $data");
|
||||
Nevent nevent = {};
|
||||
int iData = 0;
|
||||
|
||||
while( iData + 4 < data.length) {
|
||||
if(localDebug) print("iData = $iData");
|
||||
List<int> typeList = hex.decode( data.substring(iData, iData + 2));
|
||||
List<int> lenList = hex.decode( data.substring(iData + 2, iData + 4));
|
||||
|
||||
int type = typeList[0];
|
||||
int len = lenList[0];
|
||||
|
||||
if(localDebug) print("type = $type len = $len");
|
||||
|
||||
switch(type) {
|
||||
case 0:
|
||||
String id = data.substring(iData + 4, iData + 4 + len * 2);
|
||||
nevent["id"] = id;
|
||||
if(localDebug) print("nevent id = $id");
|
||||
break;
|
||||
case 1:
|
||||
String relay = data.substring(iData + 4, iData + 4 + len * 2);
|
||||
// convert hex string to list of int
|
||||
List<int> intRelay = [];
|
||||
intRelay = hex.decode(relay);
|
||||
const asciiDecoder = AsciiDecoder(allowInvalid: true);
|
||||
|
||||
if(localDebug) print("before AsciiDecoder call");
|
||||
final relayURL = asciiDecoder.convert(intRelay);
|
||||
|
||||
if( nevent["relays"] == null) {
|
||||
nevent["relays"] = [relayURL];
|
||||
} else {
|
||||
(nevent["relays"] as List<String>).add(relayURL);
|
||||
}
|
||||
|
||||
if(localDebug) print("nevent relay = $relayURL");
|
||||
|
||||
break;
|
||||
case 2:
|
||||
|
||||
break;
|
||||
case 3:
|
||||
|
||||
break;
|
||||
default:
|
||||
if(localDebug) print("in decodeNevent: malformed nevent" );
|
||||
return nevent;
|
||||
|
||||
}
|
||||
if(localDebug) print(" to next TLV");
|
||||
iData = iData + 4 + len * 2 ;
|
||||
}
|
||||
|
||||
return nevent;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// help functions
|
||||
|
||||
String bech32Encode(String prefix, String hexData) {
|
||||
@@ -53,7 +118,9 @@ String bech32Encode(String prefix, String hexData) {
|
||||
}
|
||||
|
||||
Map<String, String> bech32Decode(String bech32Data) {
|
||||
final decodedData = bech32.decode(bech32Data);
|
||||
//print("in becn32Decode 1 bech32Data = $bech32Data");
|
||||
final decodedData = bech32.decode(bech32Data, Bech32Validations.maxInputLength + 300);
|
||||
//print(decodedData.hrp);
|
||||
final convertedData = convertBits(decodedData.data, 5, 8, false);
|
||||
final hexData = hex.encode(convertedData);
|
||||
|
||||
|
@@ -1735,7 +1735,9 @@ class Store {
|
||||
|
||||
List<int> ret = [0,0,0];
|
||||
|
||||
//print("in printStoreTrees");
|
||||
for( int i = 0; i < topPosts.length; i++) {
|
||||
//print("i = $i");
|
||||
// continue if this children isn't going to get printed anyway; selector is only called for top most tree
|
||||
if( treeSelector(topPosts[i]) == false) {
|
||||
continue;
|
||||
|
@@ -1,6 +1,5 @@
|
||||
import 'dart:io';
|
||||
import 'package:qr/qr.dart';
|
||||
import 'package:nostr_console/nip_019.dart';
|
||||
|
||||
enum enumRoomType { kind4, kind40, kind140, RoomLocationTag, RoomTTag}
|
||||
|
||||
|
Reference in New Issue
Block a user