Skip to content

Commit 74aa3d4

Browse files
further
1 parent 00709e8 commit 74aa3d4

2 files changed

Lines changed: 123 additions & 14 deletions

File tree

src/views/Export/Nostr.vue

Lines changed: 121 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,17 @@
190190
</template>
191191

192192
<script lang="ts">
193-
import { generateSecretKey, getPublicKey, nip19 } from "nostr-tools";
193+
import {
194+
generateSecretKey,
195+
getPublicKey,
196+
nip19,
197+
SimplePool,
198+
getEventHash,
199+
} from "nostr-tools";
200+
import Dexie from "../../ts/indexDB";
201+
import * as Y from "yjs";
202+
import { IndexeddbPersistence } from "y-indexeddb";
203+
import * as Utils from "../../ts/utils";
194204
195205
export default {
196206
name: "NostrModal",
@@ -303,18 +313,116 @@ export default {
303313
localStorage.removeItem("nostrPublicKey");
304314
}
305315
306-
// Here we would implement the actual Nostr publishing logic
307-
// This would use the nostr-tools library to:
308-
// 1. Creating a Nostr event with course link
309-
// 2. Signing it with the user's private key (if available)
310-
// 3. Publishing to relays
311-
312-
// For now, we'll just simulate success
313-
setTimeout(() => {
314-
this.step = "success";
315-
// Clear private key after successful publish for security
316-
this.privateKey = "";
317-
}, 1000);
316+
// Loading indicator could be added here
317+
this.publishStatus = "loading";
318+
319+
const database = new Dexie();
320+
const meta = database.get(this.storageId);
321+
const config = Utils.loadConfig();
322+
323+
const yDoc = new Y.Doc();
324+
const provider = new IndexeddbPersistence(this.storageId, yDoc);
325+
326+
provider.on("synced", async (_: any) => {
327+
try {
328+
const metaData = await meta;
329+
const contentData = yDoc.getText(this.storageId).toJSON();
330+
331+
console.log("Content Data:", contentData);
332+
console.log("Meta Data:", metaData);
333+
334+
// 1. Create a pool for relays
335+
const pool = new SimplePool();
336+
const relays = [
337+
"wss://relay.damus.io",
338+
"wss://relay.nostr.band",
339+
"wss://nos.lol",
340+
];
341+
342+
// 2. Decode the user's public key from npub format
343+
let pubkey;
344+
try {
345+
const decoded = nip19.decode(this.publicKey);
346+
pubkey = decoded.data;
347+
} catch (e) {
348+
console.error("Error decoding public key:", e);
349+
alert("Invalid public key format");
350+
return;
351+
}
352+
353+
// 3. Prepare content
354+
const title = metaData?.title || "LiaScript Course";
355+
356+
// Format content as markdown with header
357+
const fullContent = `# ${title}\n\n${contentData}`;
358+
359+
// 4. Create the event (NIP-33 parameterized replaceable event)
360+
const event = {
361+
kind: 30023, // Long-form content
362+
pubkey: pubkey,
363+
created_at: Math.floor(Date.now() / 1000),
364+
tags: [
365+
["d", this.storageId], // Use storageId as identifier
366+
["title", title],
367+
["summary", metaData?.description || "LiaScript course material"],
368+
...this.tags.map((tag) => ["t", tag]),
369+
],
370+
content: fullContent,
371+
};
372+
373+
// 5. If user has provided private key, sign and publish
374+
if (this.privateKey) {
375+
try {
376+
// Decode private key
377+
const decoded = nip19.decode(this.privateKey);
378+
const privkey = decoded.data;
379+
380+
// Sign the event - updated approach for newer nostr-tools
381+
event.id = getEventHash(event);
382+
const signedEvent = signEvent(event, privkey);
383+
384+
// Publish to relays
385+
console.log("Publishing event:", signedEvent);
386+
387+
const pubs = pool.publish(relays, signedEvent);
388+
389+
// Wait for at least one successful publish
390+
await Promise.any(pubs);
391+
392+
// Create the naddr representation
393+
const naddr = nip19.naddrEncode({
394+
kind: 30023,
395+
pubkey: pubkey,
396+
identifier: this.storageId,
397+
});
398+
399+
console.log("Published as naddr:", naddr);
400+
401+
// Success!
402+
this.step = "success";
403+
this.publishStatus = "success";
404+
405+
// Clear private key after successful publish for security
406+
this.privateKey = "";
407+
} catch (e) {
408+
console.error("Error publishing:", e);
409+
alert("Failed to publish to Nostr network. Please try again.");
410+
this.publishStatus = "failed";
411+
}
412+
} else {
413+
alert("Please provide your private key to sign and publish the post.");
414+
this.publishStatus = null;
415+
}
416+
} catch (error) {
417+
console.error("Error processing data:", error);
418+
alert("Error processing document data.");
419+
this.publishStatus = "failed";
420+
} finally {
421+
// Clean up
422+
provider.destroy();
423+
yDoc.destroy();
424+
}
425+
});
318426
},
319427
},
320428
};

src/views/LiaScript.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,6 @@ export default {
133133
},
134134
135135
nostr() {
136-
const url = this.urlPath(["nostr", this.$props.storageId]);
137136
this.nostrModalVisible = true;
138137
},
139138
@@ -938,6 +937,8 @@ export default {
938937
<NostrModal
939938
ref="nostrModal"
940939
:visible="nostrModalVisible"
940+
:storageId="$props.storageId"
941+
:courseUrl="LiaScriptURL"
941942
@close="nostrModalVisible = false"
942943
/>
943944
</template>

0 commit comments

Comments
 (0)