2024-04-27 16:50:27 +00:00
|
|
|
import NDK, {NDKPrivateKeySigner} from "@nostr-dev-kit/ndk";
|
|
|
|
import * as nip19 from 'nostr-tools/nip19'
|
2024-05-26 18:50:19 +00:00
|
|
|
import { createRestAPIClient, createStreamingAPIClient } from "masto";
|
2024-04-27 22:39:53 +00:00
|
|
|
import * as masto from "masto";
|
|
|
|
|
|
|
|
type MastodonClient = masto.mastodon.rest.Client;
|
2024-05-26 18:50:19 +00:00
|
|
|
type MastodonStreamClient = masto.mastodon.streaming.Client;
|
|
|
|
|
|
|
|
export class MastodonCompoundClient {
|
|
|
|
public rest: MastodonClient;
|
|
|
|
public stream: MastodonStreamClient;
|
|
|
|
|
|
|
|
public constructor(c: MastodonClient, s: MastodonStreamClient) {
|
|
|
|
this.rest = c;
|
|
|
|
this.stream = s;
|
|
|
|
}
|
|
|
|
}
|
2024-04-27 16:50:27 +00:00
|
|
|
|
|
|
|
export class Adapter {
|
|
|
|
public nickname: string = "";
|
|
|
|
public protocol: string = "";
|
|
|
|
public identity: any | null;
|
2024-04-27 22:39:53 +00:00
|
|
|
|
2024-05-26 18:50:19 +00:00
|
|
|
private _self: NDK | MastodonCompoundClient | null = null ;
|
2024-04-27 16:50:27 +00:00
|
|
|
|
|
|
|
public init(): void {};
|
|
|
|
public getInbox(): void {};
|
|
|
|
public publish(): void {};
|
|
|
|
public getFollowers(): any[] { return [] };
|
|
|
|
public getFollowing(): any[] { return [] };
|
|
|
|
public updateMetadata(): void {};
|
|
|
|
public getMetadata(): any { return {} };
|
|
|
|
|
2024-04-28 18:16:23 +00:00
|
|
|
// according to the docs NDK must be a singleton...
|
|
|
|
// this probalby will make having more than one nostr adapter at once problematic
|
2024-04-27 22:39:53 +00:00
|
|
|
private static ndk: NDK | null = null;
|
2024-04-27 16:50:27 +00:00
|
|
|
|
2024-04-27 22:39:53 +00:00
|
|
|
public static create(): Adapter {
|
2024-04-28 18:16:23 +00:00
|
|
|
return new Adapter();
|
2024-04-27 22:39:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public static toNostr(adapter: Adapter, settings: any): Adapter {
|
|
|
|
adapter.identity = { privkey: settings.privkey };
|
|
|
|
adapter.nickname = settings.nickname;
|
|
|
|
|
|
|
|
adapter.init = ()=> {
|
|
|
|
if (!Adapter.ndk) {
|
|
|
|
let privkey_raw = nip19.decode(settings.privkey);
|
|
|
|
Adapter.ndk = new NDK({
|
|
|
|
signer: new NDKPrivateKeySigner(<string>privkey_raw.data),
|
|
|
|
explicitRelayUrls: [ settings.relays ]
|
|
|
|
});
|
|
|
|
adapter._self = Adapter.ndk;
|
|
|
|
Adapter.ndk.connect();
|
|
|
|
} else {
|
|
|
|
Adapter.ndk.signer = new NDKPrivateKeySigner(settings.privatekey);
|
|
|
|
for (let i of settings.relays) {
|
|
|
|
Adapter.ndk.addExplicitRelay(i);
|
|
|
|
}
|
2024-04-27 16:50:27 +00:00
|
|
|
}
|
2024-04-27 22:39:53 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
adapter.getInbox = async () => {
|
|
|
|
if (Adapter.ndk) {
|
|
|
|
const sub = Adapter.ndk.subscribe({ kinds: [1] }); // Get all kind:1s
|
|
|
|
sub.on("event", (event) => console.log(event.content)); // Show the content
|
|
|
|
sub.on("eose", () => console.log("All relays have reached the end of the event stream"));
|
|
|
|
sub.on("close", () => console.log("Subscription closed"));
|
|
|
|
setTimeout(() => sub.stop(), 10000); // Stop the subscription after 10 seconds
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
return adapter;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static toMasto(adapter: Adapter, settings: any): Adapter {
|
|
|
|
adapter.identity = { server: settings.server, apiKey: settings.apiKey };
|
|
|
|
adapter.nickname = settings.nickname;
|
|
|
|
|
|
|
|
adapter.init = () => {
|
2024-05-26 18:50:19 +00:00
|
|
|
const rawServer: string = adapter.identity.server.split("://")[1];
|
|
|
|
|
|
|
|
adapter._self = new MastodonCompoundClient(createRestAPIClient({
|
2024-04-27 22:39:53 +00:00
|
|
|
url: adapter.identity.server,
|
|
|
|
accessToken: adapter.identity.apiKey
|
2024-05-26 18:50:19 +00:00
|
|
|
}),
|
|
|
|
createStreamingAPIClient({
|
|
|
|
streamingApiUrl: `https://${rawServer}/v1/api/streaming`,
|
|
|
|
accessToken: adapter.identity.apiKey
|
|
|
|
}));
|
|
|
|
|
2024-04-27 16:50:27 +00:00
|
|
|
}
|
|
|
|
|
2024-04-27 22:39:53 +00:00
|
|
|
adapter.getInbox = async () => {
|
2024-05-26 18:50:19 +00:00
|
|
|
const rawServer: string = adapter.identity.server.split("://")[1];
|
|
|
|
let conn = new WebSocket(`wss://${rawServer}/streaming/?i=${adapter.identity.apiKey}`)
|
|
|
|
conn.addEventListener("open", async (e:any)=> {
|
|
|
|
console.log(e);
|
|
|
|
let filter = { type: "connect", body: { channel: "localTimeline", id: crypto.randomUUID() }};
|
|
|
|
let data = await JSON.stringify(filter);
|
|
|
|
console.log(data);
|
|
|
|
conn.send(data);
|
|
|
|
conn.addEventListener("message", (e:any)=>{console.log(e)});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2024-04-27 16:50:27 +00:00
|
|
|
}
|
|
|
|
|
2024-04-27 22:39:53 +00:00
|
|
|
return adapter;
|
|
|
|
}
|
2024-04-27 16:50:27 +00:00
|
|
|
}
|
|
|
|
|
2024-04-27 22:39:53 +00:00
|
|
|
|
|
|
|
|
|
|
|
export default { Adapter }
|
2024-04-27 16:50:27 +00:00
|
|
|
|