diff --git a/app/Livewire/Nostr/Start.php b/app/Livewire/Nostr/Start.php
index f015155d..afbce9ec 100644
--- a/app/Livewire/Nostr/Start.php
+++ b/app/Livewire/Nostr/Start.php
@@ -2,10 +2,18 @@
namespace App\Livewire\Nostr;
+use App\Models\User;
use Livewire\Component;
class Start extends Component
{
+ public ?User $user = null;
+
+ public function setUser($value)
+ {
+ $this->user = User::query()->with(['meetups'])->where('nostr', $value['npub'])->first();
+ }
+
public function render()
{
return view('livewire.nostr.start');
diff --git a/app/Models/User.php b/app/Models/User.php
index 64839703..49af964a 100644
--- a/app/Models/User.php
+++ b/app/Models/User.php
@@ -14,13 +14,11 @@ use ParagonIE\CipherSweet\BlindIndex;
use ParagonIE\CipherSweet\EncryptedRow;
use ParagonIE\CipherSweet\JsonFieldMap;
use QCod\Gamify\Gamify;
-use Spatie\Comments\Models\Concerns\InteractsWithComments;
-use Spatie\Comments\Models\Concerns\Interfaces\CanComment;
use Spatie\LaravelCipherSweet\Concerns\UsesCipherSweet;
use Spatie\LaravelCipherSweet\Contracts\CipherSweetEncrypted;
use Spatie\Permission\Traits\HasRoles;
-class User extends Authenticatable implements MustVerifyEmail, CanComment, CipherSweetEncrypted
+class User extends Authenticatable implements MustVerifyEmail, CipherSweetEncrypted
{
use UsesCipherSweet;
use HasApiTokens;
@@ -30,7 +28,6 @@ class User extends Authenticatable implements MustVerifyEmail, CanComment, Ciphe
use Notifiable;
use TwoFactorAuthenticatable;
use HasRoles;
- use InteractsWithComments;
use Gamify;
protected $guarded = [];
diff --git a/package.json b/package.json
index 5a7cfdd6..68e40c54 100644
--- a/package.json
+++ b/package.json
@@ -11,6 +11,7 @@
"@alpinejs/focus": "^3.11.1",
"@alpinejs/intersect": "^3.11.1",
"@nostr-dev-kit/ndk": "^0.8.20-1",
+ "@nostr-dev-kit/ndk-cache-dexie": "^2.0.5",
"@tailwindcss/forms": "^0.5.2",
"@tailwindcss/line-clamp": "^0.4.2",
"@tailwindcss/typography": "^0.5.0",
diff --git a/resources/js/app.js b/resources/js/app.js
index bae9ec36..0ac961cd 100644
--- a/resources/js/app.js
+++ b/resources/js/app.js
@@ -1,18 +1,21 @@
-import './components'
-import './bootstrap'
+import "./components"
+import {Alpine, Livewire} from '../../vendor/livewire/livewire/dist/livewire.esm';
+import {NDKNip07Signer} from "@nostr-dev-kit/ndk";
+import NDKCacheAdapterDexie from "@nostr-dev-kit/ndk-cache-dexie";
+import nostrStart from "./nostr/nostrStart";
-import Alpine from 'alpinejs'
-import collapse from '@alpinejs/collapse'
-import intersect from '@alpinejs/intersect'
-import focus from '@alpinejs/focus'
-import NDK, { NDKNip07Signer, NDKEvent } from "@nostr-dev-kit/ndk"
+Alpine.store('ndk', {
+ // nostr ndk
+ ndk: null,
+ // signer
+ nip07signer: new NDKNip07Signer(),
+ // dexie cache adapter
+ dexieAdapter: new NDKCacheAdapterDexie({dbName: 'einundzwanzigNostrDB', expirationTime: 60 * 60 * 24 * 7}),
+ // current nostr user
+ user: null,
+ // hours ago
+ explicitRelayUrls: [],
+});
+Alpine.data('nostrStart', nostrStart);
-window.Alpine = Alpine
-window.NDK = NDK
-window.NDKNip07Signer = NDKNip07Signer
-window.NDKEvent = NDKEvent
-
-Alpine.plugin(collapse)
-Alpine.plugin(intersect)
-Alpine.plugin(focus)
-Alpine.start()
+Livewire.start();
diff --git a/resources/js/nostr/ndk/excplicitRelays.js b/resources/js/nostr/ndk/excplicitRelays.js
new file mode 100644
index 00000000..aed79a29
--- /dev/null
+++ b/resources/js/nostr/ndk/excplicitRelays.js
@@ -0,0 +1,7 @@
+export default [
+ 'wss://nostr.wine',
+ 'wss://nos.lol',
+ 'wss://nostr-pub.wellorder.net',
+ 'wss://nostr.cercatrova.me',
+ 'wss://nostr.mutinywallet.com',
+];
diff --git a/resources/js/nostr/ndk/instance.js b/resources/js/nostr/ndk/instance.js
new file mode 100644
index 00000000..1a2cbcca
--- /dev/null
+++ b/resources/js/nostr/ndk/instance.js
@@ -0,0 +1,79 @@
+import excplicitRelays from "./excplicitRelays.js";
+import NDK from "@nostr-dev-kit/ndk";
+
+export const ndkInstance = (Alpine) => ({
+ async init() {
+ try {
+ const urls = excplicitRelays.map((relay) => {
+ if (relay.startsWith('ws')) {
+ return relay.replace('ws', 'http');
+ }
+ if (relay.startsWith('wss')) {
+ return relay.replace('wss', 'https');
+ }
+ });
+
+ const controller = new AbortController();
+ const timeoutId = setTimeout(() => controller.abort('timeout'), 5000);
+
+ const requests = urls.map((url) =>
+ fetch(url, {
+ headers: {Accept: 'application/nostr+json'},
+ signal: controller.signal,
+ })
+ );
+ const responses = await Promise.all(requests);
+ const errors = responses.filter((response) => !response.ok);
+
+ if (errors.length > 0) {
+ throw errors.map((response) => Error(response.statusText));
+ }
+
+ let verifiedRelays = responses.map((res) => {
+ if (res.url.startsWith('http')) {
+ return res.url.replace('http', 'ws');
+ }
+ if (res.url.startsWith('https')) {
+ return res.url.replace('https', 'wss');
+ }
+ });
+
+ // clear timeout
+ clearTimeout(timeoutId);
+
+ console.log('##### verifiedRelays #####', verifiedRelays);
+ Alpine.$store.ndk.explicitRelayUrls = verifiedRelays;
+
+ const instance = new NDK({
+ explicitRelayUrls: Alpine.$store.ndk.explicitRelayUrls,
+ signer: Alpine.$store.ndk.nip07signer,
+ cacheAdapter: Alpine.$store.ndk.dexieAdapter,
+ outboxRelayUrls: ["wss://nostr.einundzwanzig.space",],
+ enableOutboxModel: true,
+ });
+
+ try {
+ await instance.connect(10000);
+ } catch (error) {
+ throw new Error('NDK instance init failed: ', error);
+ }
+
+ // store NDK instance in store
+ Alpine.$store.ndk.ndk = instance;
+
+ // init nip07 signer and fetch profile
+ await Alpine.$store.ndk.nip07signer.user().then(async (user) => {
+ if (!!user.npub) {
+ Alpine.$store.ndk.user = Alpine.$store.ndk.ndk.getUser({
+ npub: user.npub,
+ });
+ await Alpine.$store.ndk.user.fetchProfile();
+ }
+ }).catch((error) => {
+ console.log('##### nip07 signer error #####', error);
+ });
+ } catch (e) {
+ console.log(e);
+ }
+ }
+});
diff --git a/resources/js/nostr/nostrStart.js b/resources/js/nostr/nostrStart.js
new file mode 100644
index 00000000..2f364c54
--- /dev/null
+++ b/resources/js/nostr/nostrStart.js
@@ -0,0 +1,19 @@
+import {ndkInstance} from "./ndk/instance.js";
+
+export default (livewireComponent) => ({
+
+
+
+ async init() {
+
+ await ndkInstance(this).init();
+
+ console.log(this.$store.ndk.user);
+
+ if (this.$store.ndk.user) {
+ this.$wire.setUser(this.$store.ndk.user);
+ }
+
+ },
+
+});
diff --git a/resources/views/components/layouts/app.blade.php b/resources/views/components/layouts/app.blade.php
index 78f15a14..8c04cda2 100644
--- a/resources/views/components/layouts/app.blade.php
+++ b/resources/views/components/layouts/app.blade.php
@@ -15,20 +15,18 @@
@googlefonts
{{-- Scripts --}}
-