all repos — underbbs @ 2244bbcf7af3ee1b3489243a3fc74e3b6eb603ba

decentralized social media client

ts/adapter.ts (raw)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
import NDK, {NDKPrivateKeySigner} from "@nostr-dev-kit/ndk";
import * as nip19 from 'nostr-tools/nip19'
import { createRestAPIClient, createStreamingAPIClient } from "masto";
import * as masto from "masto";

type MastodonClient = masto.mastodon.rest.Client;
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;
  }
}

export class Adapter {
  public nickname: string = "";
  public protocol: string = "";
  public identity: any | null;
  
  private _self: NDK | MastodonCompoundClient | null = null ;

  public init(): void {};
  public getInbox(): void {};
  public publish(): void {};
  public getFollowers(): any[] { return [] };
  public getFollowing(): any[] { return [] };
  public updateMetadata(): void {};
  public getMetadata(): any { return {} };
  
  // according to the docs NDK must be a singleton...
  // this probalby will make having more than one nostr adapter at once problematic
  private static ndk: NDK | null  = null;
  
  public static create(): Adapter {
    return new Adapter();
  }
  
  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);
        }
      }
    };
  
    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 = () => {
      const rawServer: string = adapter.identity.server.split("://")[1];
      
      adapter._self = new MastodonCompoundClient(createRestAPIClient({
        url: adapter.identity.server,
        accessToken: adapter.identity.apiKey
      }),
      createStreamingAPIClient({
        streamingApiUrl: `https://${rawServer}/v1/api/streaming`,
        accessToken: adapter.identity.apiKey
      }));
     
    }
  
    adapter.getInbox = async () => {
      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)});
      });
      
      
      
      
    }
  
    return adapter;
  }
}



export default { Adapter }