From 90f6134bc41a00ed30bb80ef31bb039dc45a64ec Mon Sep 17 00:00:00 2001 From: Ryan Breen Date: Sun, 12 Feb 2023 00:25:57 -0500 Subject: [PATCH 01/13] Successfully save events in indexDB. --- .../xcschemes/xcschememanagement.plist | 4 +-- Shared (Extension)/Resources/background.js | 3 +- Shared (Extension)/Resources/db.js | 35 +++++++++++++++++++ package-lock.json | 6 ++++ package.json | 1 + 5 files changed, 46 insertions(+), 3 deletions(-) create mode 100644 Shared (Extension)/Resources/db.js diff --git a/Nostore.xcodeproj/xcuserdata/ryan.xcuserdatad/xcschemes/xcschememanagement.plist b/Nostore.xcodeproj/xcuserdata/ryan.xcuserdatad/xcschemes/xcschememanagement.plist index 2fa6e1a..1e154e6 100644 --- a/Nostore.xcodeproj/xcuserdata/ryan.xcuserdatad/xcschemes/xcschememanagement.plist +++ b/Nostore.xcodeproj/xcuserdata/ryan.xcuserdatad/xcschemes/xcschememanagement.plist @@ -7,12 +7,12 @@ Nostore (iOS).xcscheme_^#shared#^_ orderHint - 1 + 0 Nostore (macOS).xcscheme_^#shared#^_ orderHint - 0 + 1 nostore (iOS).xcscheme_^#shared#^_ diff --git a/Shared (Extension)/Resources/background.js b/Shared (Extension)/Resources/background.js index e9fc234..466ada3 100644 --- a/Shared (Extension)/Resources/background.js +++ b/Shared (Extension)/Resources/background.js @@ -16,6 +16,7 @@ import { setPermission, feature, } from './utils'; +import { saveEvent } from './db'; const storage = browser.storage.local; const log = msg => console.log('Background: ', msg); @@ -220,7 +221,7 @@ async function signEvent_(event) { event.pubkey = pubKey; event.id = getEventHash(event); event.sig = signEvent(event, privKey); - console.log(JSON.stringify(event)); + saveEvent(event); return event; } diff --git a/Shared (Extension)/Resources/db.js b/Shared (Extension)/Resources/db.js new file mode 100644 index 0000000..4ff5e5a --- /dev/null +++ b/Shared (Extension)/Resources/db.js @@ -0,0 +1,35 @@ +import { openDB } from 'idb'; +// export function openDb() { +// let openRequest = indexedDB.open('db', 1); + +// openRequest.onupgradeneeded = reqEvent => { +// let db = reqEvent.target.result; +// db.createObjectStore('events', { keyPath: 'id' }); +// }; + +// return openRequest; +// } + +async function openEventsDb() { + return await openDB('events', 1, { + upgrade(db) { + db.createObjectStore('events', { keyPath: 'id' }); + }, + }); +} + +export async function saveEvent(event) { + let db = await openEventsDb(); + return db.put('events', event); +} + +// export function saveEvent(event) { +// let openRequest = openDb(); + +// openRequest.onsuccess = reqEvent => { +// let db = reqEvent.target.result; +// let transaction = db.transaction('events', 'readwrite'); +// let events = transaction.objectStore('events'); +// events.put(event); +// }; +// } diff --git a/package-lock.json b/package-lock.json index 8e0aa53..b299447 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,7 @@ "dependencies": { "alpinejs": "^3.10.5", "async-mutex": "^0.4.0", + "idb": "^7.1.1", "json-format-highlight": "^1.0.4", "nostr-tools": "^1.3.0" }, @@ -835,6 +836,11 @@ "node": ">= 0.4.0" } }, + "node_modules/idb": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz", + "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==" + }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", diff --git a/package.json b/package.json index d861795..1cc659f 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "dependencies": { "alpinejs": "^3.10.5", "async-mutex": "^0.4.0", + "idb": "^7.1.1", "json-format-highlight": "^1.0.4", "nostr-tools": "^1.3.0" }, From dfec82deb2ef95df61d398615e646fb45b3a0e3d Mon Sep 17 00:00:00 2001 From: Ryan Breen Date: Sun, 12 Feb 2023 14:27:15 -0500 Subject: [PATCH 02/13] Adding metadata to the events. --- Shared (Extension)/Resources/background.js | 9 ++++--- Shared (Extension)/Resources/db.js | 30 ++++++---------------- 2 files changed, 14 insertions(+), 25 deletions(-) diff --git a/Shared (Extension)/Resources/background.js b/Shared (Extension)/Resources/background.js index 466ada3..4fde090 100644 --- a/Shared (Extension)/Resources/background.js +++ b/Shared (Extension)/Resources/background.js @@ -140,7 +140,7 @@ function complete({ payload, origKind, event, remember, host }) { }); break; case 'signEvent': - signEvent_(event).then(e => sendResponse(e)); + signEvent_(event, host).then(e => sendResponse(e)); break; case 'nip04.encrypt': nip04Encrypt(event).then(e => sendResponse(e)); @@ -214,14 +214,17 @@ async function currentProfile() { return profiles[index]; } -async function signEvent_(event) { +async function signEvent_(event, host) { event = JSON.parse(JSON.stringify(event)); let privKey = await getPrivKey(); let pubKey = getPublicKey(privKey); event.pubkey = pubKey; event.id = getEventHash(event); event.sig = signEvent(event, privKey); - saveEvent(event); + saveEvent({ + event, + metadata: { host, signed_at: Math.round(Date.now() / 1000) }, + }); return event; } diff --git a/Shared (Extension)/Resources/db.js b/Shared (Extension)/Resources/db.js index 4ff5e5a..cc94437 100644 --- a/Shared (Extension)/Resources/db.js +++ b/Shared (Extension)/Resources/db.js @@ -1,35 +1,21 @@ import { openDB } from 'idb'; -// export function openDb() { -// let openRequest = indexedDB.open('db', 1); - -// openRequest.onupgradeneeded = reqEvent => { -// let db = reqEvent.target.result; -// db.createObjectStore('events', { keyPath: 'id' }); -// }; - -// return openRequest; -// } async function openEventsDb() { return await openDB('events', 1, { upgrade(db) { - db.createObjectStore('events', { keyPath: 'id' }); + const events = db.createObjectStore('events', { + keyPath: 'event.id', + }); + events.createIndex('pubkey', 'event.pubkey'); + events.createIndex('created_at', 'event.created_at'); + events.createIndex('kind', 'event.kind'); + events.createIndex('host', 'metadata.host'); }, }); } export async function saveEvent(event) { + console.log('logging event', event); let db = await openEventsDb(); return db.put('events', event); } - -// export function saveEvent(event) { -// let openRequest = openDb(); - -// openRequest.onsuccess = reqEvent => { -// let db = reqEvent.target.result; -// let transaction = db.transaction('events', 'readwrite'); -// let events = transaction.objectStore('events'); -// events.put(event); -// }; -// } From 0847a55afa44d87a156dbf7685bd61a70c1cdff2 Mon Sep 17 00:00:00 2001 From: Ryan Breen Date: Sun, 12 Feb 2023 15:09:35 -0500 Subject: [PATCH 03/13] Basic event log view functions. --- Nostore.xcodeproj/project.pbxproj | 18 ++++++++++ Shared (Extension)/Resources/db.js | 18 +++++++++- Shared (Extension)/Resources/event_log.html | 40 +++++++++++++++++++++ Shared (Extension)/Resources/event_log.js | 20 +++++++++++ Shared (Extension)/Resources/options.html | 2 ++ build.js | 1 + 6 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 Shared (Extension)/Resources/event_log.html create mode 100644 Shared (Extension)/Resources/event_log.js diff --git a/Nostore.xcodeproj/project.pbxproj b/Nostore.xcodeproj/project.pbxproj index b047ea1..8faf6f9 100644 --- a/Nostore.xcodeproj/project.pbxproj +++ b/Nostore.xcodeproj/project.pbxproj @@ -89,6 +89,12 @@ 944A6DED299682EF0032C2E3 /* experimental.js in Resources */ = {isa = PBXBuildFile; fileRef = 944A6DE8299682EF0032C2E3 /* experimental.js */; }; 944A6DEE299682EF0032C2E3 /* experimental.build.js in Resources */ = {isa = PBXBuildFile; fileRef = 944A6DE9299682EF0032C2E3 /* experimental.build.js */; }; 944A6DEF299682EF0032C2E3 /* experimental.build.js in Resources */ = {isa = PBXBuildFile; fileRef = 944A6DE9299682EF0032C2E3 /* experimental.build.js */; }; + 944A6DF3299975A70032C2E3 /* event_log.html in Resources */ = {isa = PBXBuildFile; fileRef = 944A6DF0299975A70032C2E3 /* event_log.html */; }; + 944A6DF4299975A70032C2E3 /* event_log.html in Resources */ = {isa = PBXBuildFile; fileRef = 944A6DF0299975A70032C2E3 /* event_log.html */; }; + 944A6DF5299975A70032C2E3 /* event_log.build.js in Resources */ = {isa = PBXBuildFile; fileRef = 944A6DF1299975A70032C2E3 /* event_log.build.js */; }; + 944A6DF6299975A70032C2E3 /* event_log.build.js in Resources */ = {isa = PBXBuildFile; fileRef = 944A6DF1299975A70032C2E3 /* event_log.build.js */; }; + 944A6DF7299975A70032C2E3 /* event_log.js in Resources */ = {isa = PBXBuildFile; fileRef = 944A6DF2299975A70032C2E3 /* event_log.js */; }; + 944A6DF8299975A70032C2E3 /* event_log.js in Resources */ = {isa = PBXBuildFile; fileRef = 944A6DF2299975A70032C2E3 /* event_log.js */; }; 948C69D9297F887600FB3574 /* options.html in Resources */ = {isa = PBXBuildFile; fileRef = 948C69D8297F887600FB3574 /* options.html */; }; 948C69DA297F887600FB3574 /* options.html in Resources */ = {isa = PBXBuildFile; fileRef = 948C69D8297F887600FB3574 /* options.html */; }; 948C69DD297F88A200FB3574 /* options.css in Resources */ = {isa = PBXBuildFile; fileRef = 948C69DB297F88A200FB3574 /* options.css */; }; @@ -198,6 +204,9 @@ 944A6DE7299682EF0032C2E3 /* experimental.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = experimental.html; sourceTree = ""; }; 944A6DE8299682EF0032C2E3 /* experimental.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = experimental.js; sourceTree = ""; }; 944A6DE9299682EF0032C2E3 /* experimental.build.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = experimental.build.js; sourceTree = ""; }; + 944A6DF0299975A70032C2E3 /* event_log.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = event_log.html; sourceTree = ""; }; + 944A6DF1299975A70032C2E3 /* event_log.build.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = event_log.build.js; sourceTree = ""; }; + 944A6DF2299975A70032C2E3 /* event_log.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = event_log.js; sourceTree = ""; }; 948C69D8297F887600FB3574 /* options.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = options.html; sourceTree = ""; }; 948C69DB297F88A200FB3574 /* options.css */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.css; path = options.css; sourceTree = ""; }; 948C69DC297F88A200FB3574 /* options.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = options.js; sourceTree = ""; }; @@ -285,6 +294,9 @@ 941B03A2296FA90400CA291E /* Resources */ = { isa = PBXGroup; children = ( + 944A6DF1299975A70032C2E3 /* event_log.build.js */, + 944A6DF0299975A70032C2E3 /* event_log.html */, + 944A6DF2299975A70032C2E3 /* event_log.js */, 944A6DE9299682EF0032C2E3 /* experimental.build.js */, 944A6DE7299682EF0032C2E3 /* experimental.html */, 944A6DE8299682EF0032C2E3 /* experimental.js */, @@ -548,17 +560,20 @@ 948C69E2297F891F00FB3574 /* options.build.js in Resources */, 941B03F8296FA90400CA291E /* popup.css in Resources */, 941B04292977A28700CA291E /* Icon-128.png in Resources */, + 944A6DF3299975A70032C2E3 /* event_log.html in Resources */, 941B04182971138F00CA291E /* nostr.build.js in Resources */, 941B042C2978CD8E00CA291E /* iOS-Icon-1024.png in Resources */, 941B03F6296FA90400CA291E /* popup.html in Resources */, 941B040D296FAD6900CA291E /* nostr.js in Resources */, 944A6DE02991DFC60032C2E3 /* delegation_wizard.build.js in Resources */, + 944A6DF5299975A70032C2E3 /* event_log.build.js in Resources */, 941B03EE296FA90400CA291E /* images in Resources */, 941B03F0296FA90400CA291E /* manifest.json in Resources */, 944A6DD62988BD230032C2E3 /* permission.js in Resources */, 941B04312978CDF900CA291E /* Icon-32.png in Resources */, 941B041A2971139000CA291E /* content.build.js in Resources */, 941B041C2971139000CA291E /* popup.build.js in Resources */, + 944A6DF7299975A70032C2E3 /* event_log.js in Resources */, 944A6DEC299682EF0032C2E3 /* experimental.js in Resources */, 941B03EC296FA90400CA291E /* _locales in Resources */, 941B04222977A25700CA291E /* Icon-512.png in Resources */, @@ -591,17 +606,20 @@ 948C69E3297F891F00FB3574 /* options.build.js in Resources */, 941B03F9296FA90400CA291E /* popup.css in Resources */, 941B042A2977A28700CA291E /* Icon-128.png in Resources */, + 944A6DF4299975A70032C2E3 /* event_log.html in Resources */, 941B04192971138F00CA291E /* nostr.build.js in Resources */, 941B042D2978CD8E00CA291E /* iOS-Icon-1024.png in Resources */, 941B03F7296FA90400CA291E /* popup.html in Resources */, 941B040E296FAD6900CA291E /* nostr.js in Resources */, 944A6DE12991DFC60032C2E3 /* delegation_wizard.build.js in Resources */, + 944A6DF6299975A70032C2E3 /* event_log.build.js in Resources */, 941B03EF296FA90400CA291E /* images in Resources */, 941B03F1296FA90400CA291E /* manifest.json in Resources */, 944A6DD72988BD230032C2E3 /* permission.js in Resources */, 941B04322978CDF900CA291E /* Icon-32.png in Resources */, 941B041B2971139000CA291E /* content.build.js in Resources */, 941B041D2971139000CA291E /* popup.build.js in Resources */, + 944A6DF8299975A70032C2E3 /* event_log.js in Resources */, 944A6DED299682EF0032C2E3 /* experimental.js in Resources */, 941B03ED296FA90400CA291E /* _locales in Resources */, 941B04232977A25700CA291E /* Icon-512.png in Resources */, diff --git a/Shared (Extension)/Resources/db.js b/Shared (Extension)/Resources/db.js index cc94437..d2775d5 100644 --- a/Shared (Extension)/Resources/db.js +++ b/Shared (Extension)/Resources/db.js @@ -15,7 +15,23 @@ async function openEventsDb() { } export async function saveEvent(event) { - console.log('logging event', event); let db = await openEventsDb(); return db.put('events', event); } + +export async function sortByIndex(index, asc, max) { + let db = await openEventsDb(); + let events = []; + let cursor = await db + .transaction('events') + .store.index(index) + .openCursor(null, asc ? 'next' : 'prev'); + while (cursor) { + events.push(cursor.value); + if (cursor.length >= max) { + break; + } + cursor = await cursor.continue(); + } + return events; +} diff --git a/Shared (Extension)/Resources/event_log.html b/Shared (Extension)/Resources/event_log.html new file mode 100644 index 0000000..e117577 --- /dev/null +++ b/Shared (Extension)/Resources/event_log.html @@ -0,0 +1,40 @@ + + + + + + + + + + Event Log + + + +

+ ← Back +

+ +

Event Log

+ +
+ +
+ +
+ + +
+ + + + + \ No newline at end of file diff --git a/Shared (Extension)/Resources/event_log.js b/Shared (Extension)/Resources/event_log.js new file mode 100644 index 0000000..8faed90 --- /dev/null +++ b/Shared (Extension)/Resources/event_log.js @@ -0,0 +1,20 @@ +import Alpine from 'alpinejs'; +import { sortByIndex } from './db'; + +Alpine.data('eventLog', () => ({ + events: [], + view: 'created_at', + max: 100, + ascending: false, + + async init() { + await this.reload(); + }, + + async reload() { + let events = await sortByIndex(this.view, this.ascending, this.max); + this.events = events; + }, +})); + +Alpine.start(); diff --git a/Shared (Extension)/Resources/options.html b/Shared (Extension)/Resources/options.html index c98d3c4..7432181 100644 --- a/Shared (Extension)/Resources/options.html +++ b/Shared (Extension)/Resources/options.html @@ -162,6 +162,8 @@ diff --git a/build.js b/build.js index 9289a3a..747d4dc 100755 --- a/build.js +++ b/build.js @@ -23,6 +23,7 @@ require('esbuild') './Shared (Extension)/Resources/experimental.js', 'delegation_wizard.build': './Shared (Extension)/Resources/delegation_wizard.js', + 'event_log.build': './Shared (Extension)/Resources/event_log.js', }, outdir: './Shared (Extension)/Resources', sourcemap: 'inline', From e0349bdf0015766290f4dad7996172597731a016 Mon Sep 17 00:00:00 2001 From: Ryan Breen Date: Sun, 12 Feb 2023 22:46:34 -0500 Subject: [PATCH 04/13] Filters for created_at and kind. --- Shared (Extension)/Resources/db.js | 4 +- Shared (Extension)/Resources/event_log.html | 56 +++++++++++++++++---- Shared (Extension)/Resources/event_log.js | 40 ++++++++++++++- 3 files changed, 85 insertions(+), 15 deletions(-) diff --git a/Shared (Extension)/Resources/db.js b/Shared (Extension)/Resources/db.js index d2775d5..65fbac9 100644 --- a/Shared (Extension)/Resources/db.js +++ b/Shared (Extension)/Resources/db.js @@ -19,13 +19,13 @@ export async function saveEvent(event) { return db.put('events', event); } -export async function sortByIndex(index, asc, max) { +export async function sortByIndex(index, query, asc, max) { let db = await openEventsDb(); let events = []; let cursor = await db .transaction('events') .store.index(index) - .openCursor(null, asc ? 'next' : 'prev'); + .openCursor(query, asc ? 'next' : 'prev'); while (cursor) { events.push(cursor.value); if (cursor.length >= max) { diff --git a/Shared (Extension)/Resources/event_log.html b/Shared (Extension)/Resources/event_log.html index e117577..b1ec0ad 100644 --- a/Shared (Extension)/Resources/event_log.html +++ b/Shared (Extension)/Resources/event_log.html @@ -17,19 +17,53 @@

Event Log

-
- +
+
Filters
+ +
+
+ + +
+ +
+ + +
+ +
+
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+
-
- - -
+ +
+ + +
+ +
+ + +
diff --git a/Shared (Extension)/Resources/event_log.js b/Shared (Extension)/Resources/event_log.js index a67cffc..4c9a387 100644 --- a/Shared (Extension)/Resources/event_log.js +++ b/Shared (Extension)/Resources/event_log.js @@ -1,6 +1,7 @@ import Alpine from 'alpinejs'; +import { getPublicKey } from 'nostr-tools'; import { getHosts, sortByIndex } from './db'; -import { KINDS } from './utils'; +import { getProfiles, KINDS } from './utils'; Alpine.data('eventLog', () => ({ kinds: KINDS, @@ -10,6 +11,9 @@ Alpine.data('eventLog', () => ({ sort: 'asc', allHosts: [], host: '', + allProfiles: [], + profile: '', + pubkey: '', // date view fromCreatedAt: '2008-10-31', @@ -33,6 +37,12 @@ Alpine.data('eventLog', () => ({ ); this.events = events; getHosts().then(hosts => (this.allHosts = hosts)); + const profiles = await getProfiles(); + console.log(profiles); + this.allProfiles = profiles.map(profile => ({ + name: profile.name, + pubkey: getPublicKey(profile.privKey), + })); }, quickKindSelect() { @@ -43,6 +53,13 @@ Alpine.data('eventLog', () => ({ this.reload(); }, + pkFromProfile() { + this.pubkey = this.allProfiles.find( + ({ name }) => name === this.profile + ).pubkey; + this.reload(); + }, + // Properties get fromTime() { @@ -55,6 +72,10 @@ Alpine.data('eventLog', () => ({ return Math.floor(dt.getTime() / 1000); }, + get profileNames() { + return this.allProfiles.map(p => p.name); + }, + get keyRange() { switch (this.view) { case 'created_at': @@ -66,6 +87,11 @@ Alpine.data('eventLog', () => ({ case 'host': if (this.host.length === 0) return null; return IDBKeyRange.only(this.host); + + case 'pubkey': + if (this.pubkey.length === 0) return null; + return IDBKeyRange.only(this.pubkey); + default: return null; } From ad0b657cd57d8fa92c178b3a7e7201d80c4d3d72 Mon Sep 17 00:00:00 2001 From: Ryan Breen Date: Tue, 14 Feb 2023 23:43:24 -0500 Subject: [PATCH 08/13] Render pretty event with nice looking transition. --- Shared (Extension)/Resources/event_log.html | 13 +++++++++++-- Shared (Extension)/Resources/event_log.js | 6 ++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/Shared (Extension)/Resources/event_log.html b/Shared (Extension)/Resources/event_log.html index ff23718..f0df865 100644 --- a/Shared (Extension)/Resources/event_log.html +++ b/Shared (Extension)/Resources/event_log.html @@ -106,8 +106,17 @@ -