Skip to content

Commit

Permalink
common: cleanup; improve content extraction and event relays
Browse files Browse the repository at this point in the history
  • Loading branch information
franzos committed Aug 27, 2023
1 parent 7bf56b1 commit 0c2e717
Show file tree
Hide file tree
Showing 31 changed files with 364 additions and 250 deletions.
5 changes: 3 additions & 2 deletions client-web/src/components/event.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import {
} from "@chakra-ui/react";
import {
NEvent,
NEventWithUserBase,
ProcessedEvent,
NewQuoteRepost,
NewReaction,
NewShortTextNoteResponse,
Expand All @@ -36,7 +36,7 @@ import { unixTimeToRelative } from "../lib/relative-time";
import { excerpt } from "../lib/excerpt";
import { UserIcon } from "./user-icon";

export interface EventProps extends NEventWithUserBase {
export interface EventProps extends ProcessedEvent {
userComponent?: JSX.Element;
}

Expand Down Expand Up @@ -430,6 +430,7 @@ export function Event({
showAbout: true,
showBanner: true,
relayUrls: eventRelayUrls,
avatarSize: "xs",
}}
/>
</Box>
Expand Down
7 changes: 6 additions & 1 deletion client-web/src/components/events.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,12 @@ export function Events(props: {
<Text>Waiting for fresh content ... hold on.</Text>
)}
{events.length >= maxEvents && (
<Box display="flex" justifyContent="space-between" padding={2}>
<Box
display="flex"
justifyContent="space-between"
padding={2}
marginBottom={8}
>
<Button flex="1" marginRight={2} onClick={moreEvents}>
Load {MAX_EVENTS} more
</Button>
Expand Down
2 changes: 1 addition & 1 deletion client-web/src/components/user-info.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export function UserInfo({
<Avatar size="sm" src={picture} />
</Link>
</Box>
<Box>
<Box overflowWrap="anywhere">
<Link to={profileLink}>
<Heading size="sm">{displayName}</Heading>
<Text fontSize="sm">{name}</Text>
Expand Down
8 changes: 4 additions & 4 deletions client-web/src/state/base-types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {
Relay,
NEventWithUserBase,
ProcessedEvent,
NUserBase,
RelayAuth,
RelayCount,
Expand Down Expand Up @@ -47,17 +47,17 @@ export interface NClientBase {
subscribe: (
payload: SubscriptionRequest
) => Promise<Subscription[] | undefined>;
eventsMap?: Map<string, NEventWithUserBase>;
eventsMap?: Map<string, ProcessedEvent>;
/**
* Add event to array or map
* - In worker, must post message to main thread
*/
addEvent: (payload: NEventWithUserBase) => void;
addEvent: (payload: ProcessedEvent) => void;
/**
* Update event on array or map
* - In worker, must post message to main thread
*/
updateEvent: (payload: NEventWithUserBase) => void;
updateEvent: (payload: ProcessedEvent) => void;

eventsPublishingQueue: PublishingQueueItem[];

Expand Down
4 changes: 2 additions & 2 deletions client-web/src/state/client-types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {
NEvent,
NEventWithUserBase,
ProcessedEvent,
WebSocketClientInfo,
WebSocketEvent,
NFilters,
Expand Down Expand Up @@ -64,7 +64,7 @@ export interface NClient extends NClientBase {
generateQueueItems: (
request: PublishingRequest
) => Promise<PublishingQueueItem[]>;
events: NEventWithUserBase[];
events: ProcessedEvent[];
/**
* Track kind name like NewShortTextNote
*/
Expand Down
10 changes: 5 additions & 5 deletions client-web/src/state/client.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { nanoid } from "nanoid";
import {
NEventWithUserBase,
ProcessedEvent,
WebSocketEvent,
Relay,
NEvent,
Expand Down Expand Up @@ -36,7 +36,7 @@ interface Event {
| "relay:message"
| "event:queue:new"
| "event:queue:update";
data: NEventWithUserBase | WebSocketEvent | PublishingQueueItem;
data: ProcessedEvent | WebSocketEvent | PublishingQueueItem;
};
}

Expand Down Expand Up @@ -72,7 +72,7 @@ export const useNClient = create<NClient>((set, get) => ({
const payload = event.data;

if (payload.type === "event:new" || payload.type === "event:update") {
const data = payload.data as NEventWithUserBase;
const data = payload.data as ProcessedEvent;
if (payload.type === "event:new") {
get().addEvent(data);
} else if (payload.type === "event:update") {
Expand Down Expand Up @@ -237,12 +237,12 @@ export const useNClient = create<NClient>((set, get) => ({
return get().store.count(payload);
},
events: [],
addEvent: (payload: NEventWithUserBase) => {
addEvent: (payload: ProcessedEvent) => {
set({
events: [...get().events, payload],
});
},
updateEvent: (payload: NEventWithUserBase) => {
updateEvent: (payload: ProcessedEvent) => {
const eventIndex = get().events.findIndex(
(event) => event.event.id === payload.event.id
);
Expand Down
16 changes: 8 additions & 8 deletions client-web/src/state/worker.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {
NEvent,
RELAY_MESSAGE_TYPE,
NEventWithUserBase,
ProcessedEvent,
EventBase,
NFilters,
NEVENT_KIND,
Expand Down Expand Up @@ -31,7 +31,7 @@ class WorkerClass implements NClientWorker {
connected: boolean;
db: IDBPDatabase<NClientDB> | null;
client: RelayClient | null;
eventsMap: Map<string, NEventWithUserBase> = new Map();
eventsMap: Map<string, ProcessedEvent> = new Map();
maxEvents: number;
checkedUsers: string[] = [];
checkedEvents: string[] = [];
Expand Down Expand Up @@ -145,7 +145,7 @@ class WorkerClass implements NClientWorker {
* - Add event to map
* - Post message to main thread
*/
addEvent(payload: NEventWithUserBase) {
addEvent(payload: ProcessedEvent) {
this.eventsMap.set(payload.event.id, payload);
postMessage({
type: "event:new",
Expand All @@ -157,7 +157,7 @@ class WorkerClass implements NClientWorker {
* - Update event on map
* - Post message to main thread
*/
updateEvent(payload: NEventWithUserBase) {
updateEvent(payload: ProcessedEvent) {
this.eventsMap.set(payload.event.id, payload);
postMessage({
type: "event:update",
Expand Down Expand Up @@ -357,7 +357,7 @@ class WorkerClass implements NClientWorker {
return;
}

const newEvent: NEventWithUserBase = {
const newEvent: ProcessedEvent = {
event: new NEvent(event),
eventRelayUrls: [payload.meta.url as string],
};
Expand Down Expand Up @@ -440,13 +440,13 @@ class WorkerClass implements NClientWorker {
if (hasRootTag) {
const rootEvent = this.eventsMap.get(hasRootTag.eventId);
if (rootEvent) {
if (rootEvent.lightningReceipts) {
rootEvent.lightningReceipts.push({
if (rootEvent.zapReceipt) {
rootEvent.zapReceipt.push({
event: ev,
user: user?.user,
});
} else {
rootEvent.lightningReceipts = [
rootEvent.zapReceipt = [
{
event: ev,
user: user?.user,
Expand Down
79 changes: 56 additions & 23 deletions packages/common/src/classes/event.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
iNewShortTextNote,
iNewShortTextNoteResponse,
iNewUpdateUserMetadata,
Report,
EventReport,
NEventContent,
iNewLongFormContent,
iNewZAPRequest,
Expand Down Expand Up @@ -49,12 +49,13 @@ import {
makeEventAmountTag,
eventHasAmountTags,
makeEventCoordinatesTag,
countLeadingZeroes,
eventAddNonceTag,
eventReplaceNonceTag,
eventHasEventTags,
eventHasPositionalEventTag,
eventHasPositionalEventTags,
proofOfWork,
EventRelayTag,
} from "../utils";
import {
eventHasExternalIdentityClaim,
Expand Down Expand Up @@ -88,29 +89,49 @@ export class NEvent implements EventBase {
this.sig = data.sig ? data.sig : "";
}

/**
* Generate event ID
* - Public key should be set
*/
public generateId() {
if (this.pubkey === "") {
throw new Error("Cannot generate event ID without a public key");
throw new Error(
"Cannot generate event ID without a public key. Set a public key first."
);
}
const serial = serializeEvent(this.ToObj());
this.id = hash(serial);
}

/**
* Sign event
* - Event ID should be set
*/
public sign(keyPair: { privateKey: string; publicKey: string }) {
if (this.id === "") {
throw new Error("Cannot sign event without an ID. Generate ID first.");
}
this.pubkey = keyPair.publicKey;
this.sig = sign(this.id, keyPair.privateKey);
}

/**
* 1. Sign the event (event.sig)
* 2. Generate the event ID (event.id)
* Sign event and generate ID
*
*
* 1. Generate the event ID (event.id)
* 2. Sign the event (event.sig)
* @param privateKey
*/
public signAndGenerateId(keyPair: { privateKey: string; publicKey: string }) {
this.sign(keyPair);
this.pubkey = keyPair.publicKey;
this.generateId();
this.sign(keyPair);
}

/**
* Event object for transmission and storage
*/
public ToObj(): any {
const cleanObject = {};
for (const [key, value] of Object.entries(this)) {
Expand All @@ -121,28 +142,25 @@ export class NEvent implements EventBase {
return cleanObject;
}

/**
* Event as URI
*/
public toURI() {
return encodeURI(JSON.stringify(this.ToObj()));
}

/**
*
* Generate proof of work
* @param difficulty bits required for proof of work
*/
public proofOfWork(targetDifficulty: number) {
let adjustmentValue = 0;

while (true) {
this.replaceNonceTag([targetDifficulty, adjustmentValue]);
this.generateId();
const leadingZeroes = countLeadingZeroes(this.id);
public proofOfWork(targetDifficulty: number, limitRounds?: number) {
const ev = proofOfWork(this, targetDifficulty, limitRounds);

if (leadingZeroes >= targetDifficulty) {
console.log("Proof of work complete");
break;
}

adjustmentValue++;
if (!ev) {
throw new Error("Failed to generate proof of work.");
} else {
this.id = ev.id;
this.tags = ev.tags;
}
}

Expand Down Expand Up @@ -268,7 +286,14 @@ export class NEvent implements EventBase {
}
}

public hasRelaysTag(): string[] | undefined {
/**
* Get event relay tags or undefined
* usually used on kind:10002
*
* Standard tag
* Spec: https://github.com/nostr-protocol/nips/blob/master/65.md#relay-list-metadata
*/
public hasRelaysTag(): EventRelayTag[] | undefined {
return eventHasRelaysTag(this);
}

Expand Down Expand Up @@ -309,7 +334,9 @@ export class NEvent implements EventBase {
}

/**
* Create amount tag
* Standard tag
* related to ZAP
* https://github.com/nostr-protocol/nips/blob/master/README.md#standardized-tags
*
* @param amount millisats
Expand All @@ -318,6 +345,12 @@ export class NEvent implements EventBase {
this.addTag(makeEventAmountTag(amount));
}

/**
* Get event amount(s) or undefined
* Standard tag
* related to ZAP
* https://github.com/nostr-protocol/nips/blob/master/README.md#standardized-tags
*/
public hasAmountTags() {
return eventHasAmountTags(this);
}
Expand Down Expand Up @@ -414,7 +447,7 @@ export class NEvent implements EventBase {
}

/**
* Check if event has a content warning
* Get event content warning reason (may be "") or undefined
*/
public hasContentWarningTag() {
return eventHasContentWarning(this);
Expand All @@ -441,7 +474,7 @@ export class NEvent implements EventBase {
* Standard tag
* @param report
*/
public addReportTags(report: Report) {
public addReportTags(report: EventReport) {
if (this.kind !== NEVENT_KIND.REPORTING) {
throw new Error(
`Event kind ${this.kind} should not have a report. Expected ${NEVENT_KIND.REPORTING}.`
Expand Down
2 changes: 2 additions & 0 deletions packages/common/src/types/content.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/**
* Work with event content
* - for ex. "Profile is impersonating nostr:<victim bech32 pubkey>"
* - supports npub and nprofile right now
* https://github.com/nostr-protocol/nips/blob/master/56.md#example-events
*/
export interface NEventContent {
Expand All @@ -10,5 +11,6 @@ export interface NEventContent {
type?: "npub" | "nsec" | "note" | "lnurl" | "nprofile" | "nevent";
// TODO: Not really accurate
publicKeys?: string[];
relayUrls?: string[];
}[];
}
Loading

0 comments on commit 0c2e717

Please sign in to comment.