diff --git a/.gitignore b/.gitignore index 33c78a4..f0db5c7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ node_modules/ -dist/main.js \ No newline at end of file +dist/main.js +src/ diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..7b4555e --- /dev/null +++ b/build.sh @@ -0,0 +1,8 @@ +#!/bin/sh + +if [ ! -e ./src ]; then + mkdir ./src +fi + +npx tsc && +npx webpack diff --git a/package-lock.json b/package-lock.json index 703701e..dae15e2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,9 +11,11 @@ "dependencies": { "@nostr-dev-kit/ndk": "^2.7.1", "bech32": "^2.0.0", - "nostr-tools": "^2.5.0" + "nostr-tools": "^2.5.0", + "typescript": "^5.4.5" }, "devDependencies": { + "@types/debug": "^4.1.12", "webpack": "^5.91.0", "webpack-cli": "^5.1.4" } @@ -281,6 +283,15 @@ "url": "https://paulmillr.com/funding/" } }, + "node_modules/@types/debug": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "dev": true, + "dependencies": { + "@types/ms": "*" + } + }, "node_modules/@types/eslint": { "version": "8.56.10", "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.10.tgz", @@ -313,6 +324,12 @@ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "dev": true }, + "node_modules/@types/ms": { + "version": "0.7.34", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", + "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==", + "dev": true + }, "node_modules/@types/node": { "version": "20.12.7", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.7.tgz", @@ -1685,6 +1702,18 @@ "is-typedarray": "^1.0.0" } }, + "node_modules/typescript": { + "version": "5.4.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", + "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, "node_modules/typescript-lru-cache": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/typescript-lru-cache/-/typescript-lru-cache-2.0.0.tgz", diff --git a/package.json b/package.json index ee9f34d..77d6b0a 100644 --- a/package.json +++ b/package.json @@ -11,9 +11,11 @@ "dependencies": { "@nostr-dev-kit/ndk": "^2.7.1", "bech32": "^2.0.0", - "nostr-tools": "^2.5.0" + "nostr-tools": "^2.5.0", + "typescript": "^5.4.5" }, "devDependencies": { + "@types/debug": "^4.1.12", "webpack": "^5.91.0", "webpack-cli": "^5.1.4" } diff --git a/src/adapter.js b/src/adapter.js deleted file mode 100644 index 247f224..0000000 --- a/src/adapter.js +++ /dev/null @@ -1,57 +0,0 @@ -import NDK, {NDKPrivateKeySigner} from "@nostr-dev-kit/ndk"; -import * as nip19 from 'nostr-tools/nip19' -import { bech32 } from "bech32"; - -let ndk = null; - -function createAdapter() { - let adapter = { - nickname: "", - identity: null, - protocol: null, - }; - - adapter.init = ()=>{}; - adapter.getInbox = ()=>{}; - adapter.getFollowers = ()=>{}; - adapter.getFollowing = ()=>{}; - adapter.publish = ()=>{}; - adapter.updateMetadata = ()=>{}; - adapter.getMetadata = ()=>{}; - - return adapter; -} - -function toNostrAdapter(adapter, settings) { - adapter.identity = { privkey: settings.privkey }; - adapter.nickname = settings.nickname; - adapter.init = ()=> { - if (!ndk) { - let privkey_raw = nip19.decode(settings.privkey); - console.dir(privkey_raw); - ndk = new NDK({ - signer: new NDKPrivateKeySigner(privkey_raw.data), - explicitRelayUrls: [ settings.relays ] - }); - ndk.connect(); - } else { - ndk.activeUser = new NDKPrivateKeySigner(settings.privatekey); - for (let i of settings.relays) { - ndk.addExplicitRelay(i); - } - } - }; - - adapter.getInbox = () => { - const sub = 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; -} - -export default { createAdapter, toNostrAdapter } - diff --git a/ts/adapter.ts b/ts/adapter.ts new file mode 100644 index 0000000..1f84afc --- /dev/null +++ b/ts/adapter.ts @@ -0,0 +1,67 @@ +import NDK, {NDKPrivateKeySigner} from "@nostr-dev-kit/ndk"; +import * as nip19 from 'nostr-tools/nip19' + +export class Adapter { + public nickname: string = ""; + public protocol: string = ""; + public identity: any | 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 {} }; +} + +let ndk: NDK | null = null; + +function createAdapter(): Adapter { + let adapter = new Adapter(); + + adapter.init = ()=>{}; + adapter.getInbox = ()=>{}; + adapter.getFollowers = ()=>[]; + adapter.getFollowing = ()=>[]; + adapter.publish = ()=>{}; + adapter.updateMetadata = ()=>{}; + adapter.getMetadata = ()=>{return {}}; + + return adapter; +} + +function toNostrAdapter(adapter: Adapter, settings: any): Adapter { + adapter.identity = { privkey: settings.privkey }; + adapter.nickname = settings.nickname; + adapter.init = ()=> { + if (!ndk) { + let privkey_raw = nip19.decode(settings.privkey); + ndk = new NDK({ + signer: new NDKPrivateKeySigner(privkey_raw.data), + explicitRelayUrls: [ settings.relays ] + }); + ndk.connect(); + } else { + ndk.signer = new NDKPrivateKeySigner(settings.privatekey); + for (let i of settings.relays) { + ndk.addExplicitRelay(i); + } + } + }; + + adapter.getInbox = () => { + if (ndk) { + const sub = 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; +} + +export default { createAdapter, toNostrAdapter } + diff --git a/src/index.js b/ts/index.ts similarity index 51% rename from src/index.js rename to ts/index.ts index 29e8ad6..113e404 100644 --- a/src/index.js +++ b/ts/index.ts @@ -1,49 +1,66 @@ -import adapter from "./adapter"; +import adapter, {Adapter} from "./adapter"; -window.adapters = []; +function _s(key: string, value: any | null) { + const x = window; + x[key] = value; +} -function $(id) { +function _g(key: string): any | null { + const x = window; + return x[key]; +} + +function $(id: string): HTMLElement | null { return document.getElementById(id); } -function main() { - window.settings = JSON.parse(localStorage.getItem("settings"));; - if (window.settings != null) { - for (let s of window.settings.adapters) { +function main():void { + _s("settings", JSON.parse(localStorage.getItem("settings") ?? "{}")); + _s("adapters", []); + + const settings = _g("settings"); + const adapters = _g("adapters"); + if (settings != null) { + for (let s of settings.adapters) { switch (s.protocol) { case "nostr": let a = adapter.toNostrAdapter(adapter.createAdapter(), s); - window.adapters.push(a); + adapters.push(a); break; } } } else { console.log("no settings exist for this client"); - window.settings = { adapters: [] }; + _s("settings", { adapters: [] }); } }; -function showSettings() { +function showSettings():void { // tab bar hidden const tabbar = $("tabbar"); + if (tabbar) { tabbar.style.display = "none"; + } // tabcontent to show settings ui const tabcontent = $("tabcontent"); + if (tabcontent) { let html = "

this is our settings dialogue

"; html += ""; - html += adapters.reduce((self, a) => { + html += _g("adapters").reduce((self: string, a: Adapter) => { self += `
  • ${a.nickname}
  • ` return self; }, "
      "); html += "
    "; html += ""; tabcontent.innerHTML = html; + } } -function addAdapter() { +function addAdapter(): void { const tabcontent = $("tabcontent"); + if (tabcontent) { // dropdown for protocol let html = "