diff --git a/package-lock.json b/package-lock.json index 3104c43..703701e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,9 @@ "version": "0.0.1", "license": "ISC", "dependencies": { - "@nostr-dev-kit/ndk": "^2.7.1" + "@nostr-dev-kit/ndk": "^2.7.1", + "bech32": "^2.0.0", + "nostr-tools": "^2.5.0" }, "devDependencies": { "webpack": "^5.91.0", @@ -84,9 +86,9 @@ } }, "node_modules/@noble/ciphers": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-0.2.0.tgz", - "integrity": "sha512-6YBxJDAapHSdd3bLDv6x2wRPwq4QFMUaB3HvljNBUTThDd12eSm7/3F+2lnfzx2jvM+S6Nsy0jEt9QbPqSwqRw==", + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-0.5.2.tgz", + "integrity": "sha512-GADtQmZCdgbnNp+daPLc3OY3ibEtGGDV/+CzeM3MFnhiQ7ELQKlsHWYq0YbYUXx4jU3/Y1erAxU6r+hwpewqmQ==", "funding": { "url": "https://paulmillr.com/funding/" } @@ -140,6 +142,68 @@ "websocket-polyfill": "^0.0.3" } }, + "node_modules/@nostr-dev-kit/ndk/node_modules/@noble/ciphers": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-0.2.0.tgz", + "integrity": "sha512-6YBxJDAapHSdd3bLDv6x2wRPwq4QFMUaB3HvljNBUTThDd12eSm7/3F+2lnfzx2jvM+S6Nsy0jEt9QbPqSwqRw==", + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@nostr-dev-kit/ndk/node_modules/@noble/hashes": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.1.tgz", + "integrity": "sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA==", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@nostr-dev-kit/ndk/node_modules/@scure/base": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.1.tgz", + "integrity": "sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] + }, + "node_modules/@nostr-dev-kit/ndk/node_modules/nostr-tools": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/nostr-tools/-/nostr-tools-1.17.0.tgz", + "integrity": "sha512-LZmR8GEWKZeElbFV5Xte75dOeE9EFUW/QLI1Ncn3JKn0kFddDKEfBbFN8Mu4TMs+L4HR/WTPha2l+PPuRnJcMw==", + "dependencies": { + "@noble/ciphers": "0.2.0", + "@noble/curves": "1.1.0", + "@noble/hashes": "1.3.1", + "@scure/base": "1.1.1", + "@scure/bip32": "1.3.1", + "@scure/bip39": "1.2.1" + }, + "peerDependencies": { + "typescript": ">=5.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@nostr-dev-kit/ndk/node_modules/nostr-tools/node_modules/@noble/curves": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.1.0.tgz", + "integrity": "sha512-091oBExgENk/kGj3AZmtBDMpxQPDtxQABR2B9lb1JbVTs6ytdzZNwvhxQ4MWasRNEzlbEH8jCWFCwhF/Obj5AA==", + "dependencies": { + "@noble/hashes": "1.3.1" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@scure/base": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.6.tgz", @@ -506,6 +570,11 @@ "ajv": "^6.9.1" } }, + "node_modules/bech32": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/bech32/-/bech32-2.0.0.tgz", + "integrity": "sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg==" + }, "node_modules/browserslist": { "version": "4.23.0", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", @@ -1187,17 +1256,20 @@ "dev": true }, "node_modules/nostr-tools": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/nostr-tools/-/nostr-tools-1.17.0.tgz", - "integrity": "sha512-LZmR8GEWKZeElbFV5Xte75dOeE9EFUW/QLI1Ncn3JKn0kFddDKEfBbFN8Mu4TMs+L4HR/WTPha2l+PPuRnJcMw==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/nostr-tools/-/nostr-tools-2.5.0.tgz", + "integrity": "sha512-G02O3JYNCfhx9NDjd3NOCw/5ck8PX5hiOIhHKpsXyu49ZtZbxGH3OLP9tf0fpUZ+EVWdjIYFR689sV0i7+TOng==", "dependencies": { - "@noble/ciphers": "0.2.0", - "@noble/curves": "1.1.0", + "@noble/ciphers": "^0.5.1", + "@noble/curves": "1.2.0", "@noble/hashes": "1.3.1", "@scure/base": "1.1.1", "@scure/bip32": "1.3.1", "@scure/bip39": "1.2.1" }, + "optionalDependencies": { + "nostr-wasm": "v0.1.0" + }, "peerDependencies": { "typescript": ">=5.0.0" }, @@ -1208,11 +1280,22 @@ } }, "node_modules/nostr-tools/node_modules/@noble/curves": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.1.0.tgz", - "integrity": "sha512-091oBExgENk/kGj3AZmtBDMpxQPDtxQABR2B9lb1JbVTs6ytdzZNwvhxQ4MWasRNEzlbEH8jCWFCwhF/Obj5AA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz", + "integrity": "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==", "dependencies": { - "@noble/hashes": "1.3.1" + "@noble/hashes": "1.3.2" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/nostr-tools/node_modules/@noble/curves/node_modules/@noble/hashes": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", + "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==", + "engines": { + "node": ">= 16" }, "funding": { "url": "https://paulmillr.com/funding/" @@ -1240,6 +1323,12 @@ } ] }, + "node_modules/nostr-wasm": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/nostr-wasm/-/nostr-wasm-0.1.0.tgz", + "integrity": "sha512-78BTryCLcLYv96ONU8Ws3Q1JzjlAt+43pWQhIl86xZmWeegYCNLPml7yQ+gG3vR6V5h4XGj+TxO+SS5dsThQIA==", + "optional": true + }, "node_modules/p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", diff --git a/package.json b/package.json index f7ad746..ee9f34d 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,9 @@ "author": "", "license": "ISC", "dependencies": { - "@nostr-dev-kit/ndk": "^2.7.1" + "@nostr-dev-kit/ndk": "^2.7.1", + "bech32": "^2.0.0", + "nostr-tools": "^2.5.0" }, "devDependencies": { "webpack": "^5.91.0", diff --git a/src/adapter.js b/src/adapter.js index a0d4a7a..247f224 100644 --- a/src/adapter.js +++ b/src/adapter.js @@ -1,4 +1,6 @@ import NDK, {NDKPrivateKeySigner} from "@nostr-dev-kit/ndk"; +import * as nip19 from 'nostr-tools/nip19' +import { bech32 } from "bech32"; let ndk = null; @@ -9,7 +11,7 @@ function createAdapter() { protocol: null, }; - adatper.init = ()=>{}; + adapter.init = ()=>{}; adapter.getInbox = ()=>{}; adapter.getFollowers = ()=>{}; adapter.getFollowing = ()=>{}; @@ -22,11 +24,13 @@ function createAdapter() { 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(settings.privatekey), + signer: new NDKPrivateKeySigner(privkey_raw.data), explicitRelayUrls: [ settings.relays ] }); ndk.connect(); diff --git a/src/index.js b/src/index.js index 27725b5..29e8ad6 100644 --- a/src/index.js +++ b/src/index.js @@ -1,53 +1,118 @@ import adapter from "./adapter"; -let adapters = []; +window.adapters = []; function $(id) { return document.getElementById(id); } function main() { - let settings = JSON.parse(localStorage.getItem("settings"));; - if (settings != null) { - for (let s of settings.adapters) { + window.settings = JSON.parse(localStorage.getItem("settings"));; + if (window.settings != null) { + for (let s of window.settings.adapters) { switch (s.protocol) { case "nostr": let a = adapter.toNostrAdapter(adapter.createAdapter(), s); - adapters.push(a); + window.adapters.push(a); break; } } } else { console.log("no settings exist for this client"); + window.settings = { adapters: [] }; } }; function showSettings() { // tab bar hidden - let tabbar = $("tabbar"); + const tabbar = $("tabbar"); tabbar.style.display = "none"; // tabcontent to show settings ui - let tabcontent = $("tabcontent"); + const tabcontent = $("tabcontent"); - tabcontent.innerHTML = "

this is our settings dialogue

"; - tabcontent.innerHTML += ""; + let html = "

this is our settings dialogue

"; + html += ""; + html += adapters.reduce((self, a) => { + self += `
  • ${a.nickname}
  • ` + return self; + }, ""; + html += ""; + tabcontent.innerHTML = html; +} + +function addAdapter() { + const tabcontent = $("tabcontent"); + // dropdown for protocol + let html = ""; + // depending on protocol, different fields + // nostr: privkey, initial relays + html += "
    "; + html += " "; + html += " "; + html += " "; + html += "
    "; + // masto/AP: server, username, pw/apikey + // save button, back button + html += ""; + html += ""; + tabcontent.innerHTML = html; +} + +function fillAdapterProtocolOptions() { + const proto = $("settings_newadapter_protocolselect"); + console.log(proto.options[proto.selectedIndex]); } function saveSettings() { if (window.settings) { localStorage.setItem("settings", JSON.stringify(window.settings)); } - // tab bar hidden - let tabbar = $("tabbar"); + // tab bar hidden + const tabbar = $("tabbar"); tabbar.style.display = "block"; // tabcontent to show settings ui - let tabcontent = $("tabcontent"); + const tabcontent = $("tabcontent"); tabcontent.innerHTML = ""; } +function saveAdapter() { + let self = {}; + // get selected adapter protocol + const proto = $("settings_newadapter_protocolselect"); + console.log(proto.options[proto.selectedIndex]); + + // switch protocol + switch (proto.options[proto.selectedIndex].value) { + // nostr: save privkey + // save relays + case "nostr": + const privkey = $("settings_newadapter_nostr_privkey").value; + const relays = $("settings_newadapter_nostr_default_relays").value; + const nickname = $("settings_newadapter_nickname").value; + self = { nickname: nickname, protocol: "nostr", privkey: privkey, relays: relays.split(",").map(r=>r.trim()) }; + break; + // AP/masto: whatever + case "ap": + break; + } + window.settings.adapters.push(self); + adapters.push(adapter.toNostrAdapter(adapter.createAdapter(), self)); + localStorage.setItem("settings", JSON.stringify(window.settings)); + showSettings(); +} + +window.addAdapter = addAdapter; +window.saveAdapter = saveAdapter; +window.fillAdapterProtocolOptions = fillAdapterProtocolOptions; window.showSettings = showSettings; window.saveSettings = saveSettings;