Login stuff
This commit is contained in:
@@ -1,23 +1,35 @@
|
||||
<script lang="ts">
|
||||
import UserInterface from '$lib/interfaces/user';
|
||||
import { ndk } from '$lib/stores/nostr';
|
||||
import type { NDKUserProfile } from '@nostr-dev-kit/ndk';
|
||||
export let userProfile: NDKUserProfile | undefined;
|
||||
import { currentUser } from '$lib/store';
|
||||
import type { NDKUserProfile, NDKUser } from '@nostr-dev-kit/ndk';
|
||||
import { get } from 'svelte/store';
|
||||
|
||||
let _userProfile = userProfile;
|
||||
let image: string | undefined;
|
||||
let defaultImage = `https://robohash.org/${userProfile?.id?.slice(0, 2)}`;
|
||||
const _ndk = get(ndk);
|
||||
|
||||
let observerUserProfile;
|
||||
let random = (Math.random() + 1).toString(36).substring(6);
|
||||
|
||||
if (!_userProfile?.image) {
|
||||
observerUserProfile = $ndk.activeUser?.profile;
|
||||
let defaultImage = `https://robohash.org/${random}`;
|
||||
|
||||
if (!_ndk.activeUser?.profile?.image) {
|
||||
image = defaultImage;
|
||||
} else {
|
||||
image = _ndk.activeUser.profile.image;
|
||||
}
|
||||
|
||||
$: {
|
||||
_userProfile = $observerUserProfile! as NDKUserProfile;
|
||||
image = _userProfile.image;
|
||||
}
|
||||
$: {image = _ndk.activeUser?.profile?.image;}
|
||||
// $: {
|
||||
// //image = $currentUser?.profile?.image;
|
||||
// image = _ndk.activeUser?.profile?.image;
|
||||
// console.debug(image);
|
||||
// }
|
||||
</script>
|
||||
|
||||
<img src={image || defaultImage} alt="User Avatar" class="is-rounded" />
|
||||
<figure class="image">
|
||||
{#if !_ndk.activeUser}
|
||||
<img src={defaultImage} alt="Generic Avatar" class="is-rounded" />
|
||||
{:else}
|
||||
<img src={image} alt="User Avatar" class="is-rounded" />
|
||||
{/if}
|
||||
</figure>
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
<script lang="ts">
|
||||
import { createEventDispatcher } from "svelte";
|
||||
import Nip07Button from "./Nip07Button.svelte";
|
||||
|
||||
export let active = false;
|
||||
|
||||
function closeDialog() {
|
||||
active = !active;
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
function toggleModal() {
|
||||
dispatch('toggleModal');
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -11,8 +16,10 @@
|
||||
<div class="modal-card">
|
||||
<header class="modal-card-head">
|
||||
<p class="modal-card-title">Login</p>
|
||||
<button class="delete" aria-label="close" on:click={closeDialog}></button>
|
||||
<button class="delete" aria-label="close" on:click={toggleModal}></button>
|
||||
</header>
|
||||
<section class="modal-card-body"></section>
|
||||
<section class="modal-card-body">
|
||||
<Nip07Button on:closeModal={toggleModal}/>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -2,18 +2,27 @@
|
||||
import { ndk } from '$lib/stores/nostr';
|
||||
import { login } from '$lib/utils/login';
|
||||
import { currentUser } from '$lib/store';
|
||||
import { browser } from '$app/environment';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
|
||||
let noNip07: boolean;
|
||||
|
||||
$: noNip07 = !window.nostr;
|
||||
$: if (browser) {
|
||||
noNip07 = !window.nostr;
|
||||
}
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
async function nip07Login() {
|
||||
const user = await login($ndk, undefined, 'nip07');
|
||||
if (!user) alert('Nip07 Login Failed');
|
||||
else {
|
||||
$currentUser = user;
|
||||
$currentUser.fetchProfile();
|
||||
localStorage.setItem('nostr-key-method', 'nip07');
|
||||
localStorage.setItem('nostr-target-npub', $currentUser.npub);
|
||||
dispatch('closeModal');
|
||||
console.debug($currentUser);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -26,7 +35,5 @@
|
||||
</div>
|
||||
</div>
|
||||
{:else}
|
||||
<button on:click={nip07Login}>
|
||||
<span>Use Browser Extension</span>
|
||||
</button>
|
||||
<button on:click={nip07Login}>Use Browser Extension</button>
|
||||
{/if}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
import {} from '@nostr-dev-kit/ndk-svelte-components';
|
||||
import Avatar from '$lib/components/Avatar.svelte';
|
||||
import { ndk } from '$lib/stores/nostr';
|
||||
import { currentUser } from '$lib/store';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
@@ -10,7 +11,7 @@
|
||||
|
||||
let avatarimage: string | undefined;
|
||||
$: {
|
||||
avatarimage = $ndk.activeUser?.profile?.image;
|
||||
avatarimage = $currentUser?.profile?.image;
|
||||
}
|
||||
|
||||
function signIn() {
|
||||
@@ -44,11 +45,9 @@
|
||||
<div class="buttons">
|
||||
<a class="button" href="/">Home</a>
|
||||
<a class="button" href="/about">About</a>
|
||||
{#if $ndk.activeUser}
|
||||
<Avatar userProfile={$ndk.activeUser.profile} />
|
||||
{:else}
|
||||
<button class="button" on:click={signIn}>Sign In</button>
|
||||
{/if}
|
||||
<button on:click={signIn}>
|
||||
<Avatar />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -20,13 +20,14 @@ if (!relayList || !Array.isArray(relayList) || relayList.length === 0) {
|
||||
relayList = defaultRelays;
|
||||
}
|
||||
|
||||
const _ndk: NDKSvelte = new NDKSvelte({
|
||||
const _ndk: NDK = new NDK({
|
||||
devWriteRelayUrls: ['wss://relay.strfront.com'],
|
||||
explicitRelayUrls: relayList,
|
||||
enableOutboxModel: true,
|
||||
autoConnectUserRelays: true,
|
||||
autoFetchUserMutelist: true
|
||||
}) as NDKSvelte;
|
||||
autoFetchUserMutelist: true,
|
||||
clientName: 'cofabricate'
|
||||
}) as NDK;
|
||||
|
||||
_ndk.connect();
|
||||
|
||||
@@ -34,6 +35,7 @@ console.log(_ndk.activeUser?.profile);
|
||||
|
||||
const ndkStore = writable(_ndk);
|
||||
|
||||
|
||||
export const ndk = ndkStore;
|
||||
|
||||
const _bunkerNDK = new NDK({
|
||||
|
||||
4
src/lib/stores/sesson.ts
Normal file
4
src/lib/stores/sesson.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
import { writable } from "svelte/store";
|
||||
|
||||
export type LoginState = 'logging-in' | 'logged-in' | 'contacting-remote-signer' | 'logged-out';
|
||||
export const loginState = writable<LoginState | null>(null);
|
||||
@@ -1,50 +1,47 @@
|
||||
import type NDK from '@nostr-dev-kit/ndk';
|
||||
import { NDKNip07Signer, NDKNip46Signer, NDKPrivateKeySigner, NDKUser } from '@nostr-dev-kit/ndk';
|
||||
import {
|
||||
NDKNip07Signer,
|
||||
NDKNip46Signer,
|
||||
NDKPrivateKeySigner,
|
||||
NDKUser,
|
||||
type Hexpubkey,
|
||||
type NDKSigner
|
||||
} from '@nostr-dev-kit/ndk';
|
||||
import { bunkerNDK, ndk } from '$lib/stores/nostr';
|
||||
import { currentUser } from '$lib/store';
|
||||
import { loginState } from '$lib/stores/sesson';
|
||||
import { get } from 'svelte/store';
|
||||
|
||||
export type LoginMethod = 'none' | 'pk' | 'nip07' | 'nip46';
|
||||
const $ndk = get(ndk);
|
||||
const $bunkerNDK = get(bunkerNDK);
|
||||
|
||||
export async function login(
|
||||
ndk: NDK,
|
||||
bunkerNDK?: NDK,
|
||||
method?: LoginMethod
|
||||
): Promise<NDKUser | null> {
|
||||
const nostrKeyMethod = method || localStorage.getItem('nostr-key-method');
|
||||
export async function login(method: LoginMethod, userPubkey?: string ): Promise<NDKUser | null> {
|
||||
console.debug(`logging in with ${method}`);
|
||||
let u: NDKUser | null | undefined;
|
||||
|
||||
switch (nostrKeyMethod) {
|
||||
switch (method) {
|
||||
case 'none':
|
||||
loginState.set(null);
|
||||
return null;
|
||||
case 'pk':
|
||||
const key = localStorage.getItem('nostr-key');
|
||||
if (!key) return null;
|
||||
|
||||
const signer = new NDKPrivateKeySigner(key);
|
||||
ndk.signer = signer;
|
||||
const user = await signer.user();
|
||||
if (user) user.ndk = ndk;
|
||||
return user;
|
||||
else return await pkLogin(key);
|
||||
case 'nip07':
|
||||
return nip07SignIn(ndk);
|
||||
u = await nip07Login($ndk);
|
||||
console.debug('Logged in as: ', u);
|
||||
loginState.set('logged-in');
|
||||
return u;
|
||||
case 'nip46':
|
||||
const promise = new Promise<NDKUser | null>((resolve, reject) => {
|
||||
const existingPrivateKey = localStorage.getItem('nostr-nsecbunker-key');
|
||||
|
||||
if (!bunkerNDK) bunkerNDK = ndk;
|
||||
|
||||
if (existingPrivateKey) {
|
||||
bunkerNDK.connect(2500);
|
||||
bunkerNDK.pool.on('relay:connect', async () => {
|
||||
const user = await nip46SignIn(ndk, bunkerNDK!, existingPrivateKey);
|
||||
resolve(user);
|
||||
});
|
||||
}
|
||||
});
|
||||
return await nip46Login(userPubkey);
|
||||
default: {
|
||||
const promise = new Promise<NDKUser | null>((resolve, reject) => {
|
||||
const promise = new Promise<NDKUser | null>((resolve) => {
|
||||
let loadAttempts = 0;
|
||||
const loadNip07Interval = setInterval(() => {
|
||||
const loadNip07Interval = setInterval(async () => {
|
||||
if (window.nostr) {
|
||||
clearInterval(loadNip07Interval);
|
||||
const user = nip07SignIn(ndk);
|
||||
const user = await nip07Login($ndk);
|
||||
resolve(user);
|
||||
}
|
||||
if (loadAttempts++ > 10) clearInterval(loadNip07Interval);
|
||||
@@ -55,51 +52,97 @@ export async function login(
|
||||
}
|
||||
}
|
||||
|
||||
async function nip07SignIn(ndk: NDK): Promise<NDKUser | null> {
|
||||
const storedNpub = localStorage.getItem('currentUserNpub');
|
||||
async function pkLogin(key: string): Promise<NDKUser | null> {
|
||||
const signer = new NDKPrivateKeySigner(key);
|
||||
const u = await signer.user();
|
||||
if (u) loggedIn(signer, u!, 'pk');
|
||||
return u;
|
||||
}
|
||||
|
||||
async function nip07Login(ndk: NDK): Promise<NDKUser | null> {
|
||||
const storedNpub = localStorage.getItem('pubkey');
|
||||
let user: NDKUser | null = null;
|
||||
|
||||
if (storedNpub) {
|
||||
user = new NDKUser({ npub: storedNpub });
|
||||
user.ndk = ndk;
|
||||
console.debug('Nip07 - logging in with stored npub', storedNpub);
|
||||
}
|
||||
|
||||
if (window.nostr) {
|
||||
try {
|
||||
ndk.signer = new NDKNip07Signer();
|
||||
user = await ndk.signer.user();
|
||||
user = await ndk.signer?.blockUntilReady();
|
||||
ndk.activeUser = user;
|
||||
user.ndk = ndk;
|
||||
localStorage.setItem('currentUserNpub', user.npub);
|
||||
ndk = ndk;
|
||||
console.debug('Nip07 Login user:', user);
|
||||
console.debug('NDK: ', ndk);
|
||||
if (user) localStorage.setItem('nostr-key-method', 'nip07');
|
||||
localStorage.setItem('pubkey', user.pubkey);
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
if (user) await user.fetchProfile();
|
||||
return user;
|
||||
}
|
||||
|
||||
async function nip46SignIn(
|
||||
ndk: NDK,
|
||||
bunkerNDK: NDK,
|
||||
existingPrivateKey: string
|
||||
): Promise<NDKUser | null> {
|
||||
const npub = localStorage.getItem('nostr-target-npub')!;
|
||||
const remoteUser = new NDKUser({ npub });
|
||||
let user: NDKUser | null = null;
|
||||
remoteUser.ndk = bunkerNDK;
|
||||
async function nip46Login(remotePubkey?: Hexpubkey): Promise<NDKUser | null> {
|
||||
const existingPrivateKey = localStorage.getItem('nostr-nsecbunker-key')!;
|
||||
let remoteUser: NDKUser | undefined;
|
||||
|
||||
// check if there is a private key stored in localStorage
|
||||
let localSigner: NDKPrivateKeySigner | undefined = undefined;
|
||||
console.debug({ existingPrivateKey, remotePubkey });
|
||||
|
||||
if (existingPrivateKey) {
|
||||
localSigner = new NDKPrivateKeySigner(existingPrivateKey);
|
||||
if (!existingPrivateKey) return null;
|
||||
|
||||
if (remotePubkey) remoteUser = $ndk.getUser({ pubkey: remotePubkey });
|
||||
|
||||
if (!remoteUser) return null;
|
||||
|
||||
currentUser.set(remoteUser);
|
||||
|
||||
console.debug('NIP46 setting user: ', remoteUser);
|
||||
|
||||
$bunkerNDK.pool.on('relay:ready', async () => {
|
||||
console.debug('bunker relay ready');
|
||||
loginState.set('contacting-remote-signer');
|
||||
await nip46SignIn(existingPrivateKey, remoteUser!);
|
||||
});
|
||||
|
||||
console.debug('connecting to nsecbunker relay');
|
||||
$bunkerNDK.connect(2500);
|
||||
return remoteUser;
|
||||
}
|
||||
|
||||
async function nip46SignIn(existingPrivateKey: string, remoteUser: NDKUser) {
|
||||
remoteUser.ndk = $bunkerNDK;
|
||||
let localSigner: NDKPrivateKeySigner | null = null;
|
||||
|
||||
if (existingPrivateKey) localSigner = new NDKPrivateKeySigner(existingPrivateKey);
|
||||
else {
|
||||
alert('Local signer not available');
|
||||
return null;
|
||||
}
|
||||
|
||||
const remoteSigner = new NDKNip46Signer(bunkerNDK, remoteUser.pubkey, localSigner);
|
||||
const remoteSigner = new NDKNip46Signer($bunkerNDK, remoteUser.pubkey, localSigner!);
|
||||
|
||||
await remoteSigner.blockUntilReady();
|
||||
ndk.signer = remoteSigner;
|
||||
user = remoteUser;
|
||||
user.ndk = ndk;
|
||||
console.debug('contacting remote signer');
|
||||
remoteSigner.blockUntilReady();
|
||||
console.debug('Remote signer connected');
|
||||
|
||||
return user;
|
||||
localStorage.setItem('nostr-nsecbunker-key', localSigner.privateKey!);
|
||||
|
||||
loggedIn(remoteSigner, remoteUser, 'nip46');
|
||||
}
|
||||
|
||||
export async function loggedIn(signer: NDKSigner, u: NDKUser, method: LoginMethod) {
|
||||
const _ndk = get(ndk);
|
||||
_ndk.signer = signer;
|
||||
u.ndk = _ndk;
|
||||
await u.fetchProfile();
|
||||
currentUser.set(u);
|
||||
_ndk.activeUser = u;
|
||||
console.log('DEBUG setting user (loggedIn)', u);
|
||||
loginState.set('logged-in');
|
||||
|
||||
localStorage.setItem('pubkey', u.pubkey);
|
||||
localStorage.setItem('nostr-key-method', method);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<script lang="ts">
|
||||
import NavBar from '$lib/components/NavBar.svelte';
|
||||
import LoginModal from '$lib/components/LoginModal/Modal.svelte';
|
||||
import { ndk } from '$lib/stores/nostr';
|
||||
import { NDKNip07Signer } from '@nostr-dev-kit/ndk';
|
||||
import { login } from "$lib/utils/login";
|
||||
import { browserSetup } from "./browser-setup";
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
let modalActive = false;
|
||||
@@ -11,32 +11,14 @@
|
||||
await signIn();
|
||||
});
|
||||
|
||||
function toggleModal() {
|
||||
modalActive=!modalActive;
|
||||
}
|
||||
async function signIn() {
|
||||
modalActive = !modalActive;
|
||||
console.debug('signIn called');
|
||||
let signer;
|
||||
try {
|
||||
signer = await new NDKNip07Signer();
|
||||
} catch (e) {}
|
||||
console.log(signer);
|
||||
|
||||
//if (!signer) return;
|
||||
|
||||
$ndk.signer = signer;
|
||||
|
||||
const pubkey = await signer?.user();
|
||||
console.log(pubkey);
|
||||
|
||||
if (pubkey) {
|
||||
$ndk.activeUser = pubkey;
|
||||
await $ndk.activeUser.fetchProfile();
|
||||
console.log($ndk.activeUser);
|
||||
}
|
||||
|
||||
await $ndk.connect();
|
||||
browserSetup();
|
||||
}
|
||||
</script>
|
||||
|
||||
<NavBar on:signin={signIn} />
|
||||
<NavBar on:signin={toggleModal} />
|
||||
<slot></slot>
|
||||
<LoginModal active={modalActive} />
|
||||
<LoginModal active={modalActive} on:toggleModal={toggleModal} />
|
||||
|
||||
@@ -1,10 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { ndk } from '$lib/stores/nostr.js';
|
||||
import { NDKHighlight } from '@nostr-dev-kit/ndk';
|
||||
import { RelayList } from '@nostr-dev-kit/ndk-svelte-components';
|
||||
const img = 'https://picsum.photos/800/500';
|
||||
|
||||
// export let data;
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
|
||||
47
src/routes/browser-setup.ts
Normal file
47
src/routes/browser-setup.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { loginState } from "$lib/stores/sesson";
|
||||
import { loggedIn, login, type LoginMethod } from "$lib/utils/login";
|
||||
import { ndk } from "$lib/stores/nostr";
|
||||
import { get } from "svelte/store";
|
||||
import { currentUser } from "$lib/store";
|
||||
import { NDKNip07Signer, NDKUser } from "@nostr-dev-kit/ndk";
|
||||
|
||||
const _ndk = get(ndk);
|
||||
|
||||
export async function browserSetup() {
|
||||
const pubkey = localStorage.getItem('pubkey');
|
||||
console.debug(pubkey);
|
||||
|
||||
if (pubkey){
|
||||
const u = _ndk.getUser({pubkey});
|
||||
u.fetchProfile();
|
||||
loginState.set('logging-in')
|
||||
currentUser.set(u);
|
||||
}
|
||||
|
||||
const method = localStorage.getItem('nostr-key-method') as LoginMethod;
|
||||
|
||||
if (!pubkey && method !== 'none') return newSessionTryNip07();
|
||||
|
||||
if (method && pubkey) {
|
||||
return await login(method, pubkey);
|
||||
}
|
||||
}
|
||||
|
||||
export async function newSessionTryNip07() {
|
||||
let signer: NDKNip07Signer | undefined;
|
||||
let u: NDKUser | null | undefined;
|
||||
|
||||
try {
|
||||
console.debug('trying nip07 signer');
|
||||
signer = new NDKNip07Signer();
|
||||
u = await signer.blockUntilReady();
|
||||
u.fetchProfile();
|
||||
} catch (e) {
|
||||
console.debug('nip07Signer failed', e);
|
||||
}
|
||||
|
||||
if (u && signer) {
|
||||
console.debug('nip07Signer succeeded');
|
||||
await loggedIn(signer, u, 'nip07');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user