From 7decf264d705ccd4a12d8c91263fd156161dae89 Mon Sep 17 00:00:00 2001 From: reya Date: Tue, 5 Dec 2023 14:25:44 +0700 Subject: [PATCH] polish nsecbunker --- src/app/auth/import.tsx | 11 +++++ src/libs/ndk/instance.ts | 90 +++++++++++++++++++++------------- src/libs/storage/instance.ts | 11 +++-- src/shared/accounts/logout.tsx | 2 +- 4 files changed, 75 insertions(+), 39 deletions(-) diff --git a/src/app/auth/import.tsx b/src/app/auth/import.tsx index 29d468ba..d105deda 100644 --- a/src/app/auth/import.tsx +++ b/src/app/auth/import.tsx @@ -1,5 +1,6 @@ import NDK, { NDKNip46Signer, NDKPrivateKeySigner } from '@nostr-dev-kit/ndk'; import { readText } from '@tauri-apps/plugin-clipboard-manager'; +import { open } from '@tauri-apps/plugin-shell'; import { motion } from 'framer-motion'; import { nip19 } from 'nostr-tools'; import { useState } from 'react'; @@ -49,6 +50,9 @@ export function ImportAccountScreen() { await db.createSetting('nsecbunker', '1'); await db.secureSave(`${pubkey}-nsecbunker`, localSigner.privateKey); + // open nsecbunker web app in default browser + await open('https://app.nsecbunker.com/keys'); + const bunker = new NDK({ explicitRelayUrls: ['wss://relay.nsecbunker.com', 'wss://nostr.vulpem.com'], }); @@ -168,6 +172,13 @@ export function ImportAccountScreen() { > Continue with nsecBunker +
+

Note:

+

+ If you're using nsecbunker token, keep in mind it only can + redeem one-time, you need to login again in the next launch +

+
) : null} diff --git a/src/libs/ndk/instance.ts b/src/libs/ndk/instance.ts index 79efa0c6..d7df1357 100644 --- a/src/libs/ndk/instance.ts +++ b/src/libs/ndk/instance.ts @@ -10,6 +10,7 @@ import { ask } from '@tauri-apps/plugin-dialog'; import { relaunch } from '@tauri-apps/plugin-process'; import { NostrFetcher, normalizeRelayUrlSet } from 'nostr-fetch'; import { useEffect, useState } from 'react'; +import { toast } from 'sonner'; import NDKCacheAdapterTauri from '@libs/ndk/cache'; import { useStorage } from '@libs/storage/provider'; @@ -27,50 +28,69 @@ export const NDKInstance = () => { async function getSigner(nsecbunker?: boolean) { if (!db.account) return; - // NIP-46 Signer - if (nsecbunker) { - const localSignerPrivkey = await db.secureLoad(`${db.account.pubkey}-nsecbunker`); - if (!localSignerPrivkey) return null; + try { + // NIP-46 Signer + if (nsecbunker) { + const localSignerPrivkey = await db.secureLoad(`${db.account.pubkey}-nsecbunker`); + if (!localSignerPrivkey) return null; - const localSigner = new NDKPrivateKeySigner(localSignerPrivkey); - const bunker = new NDK({ - explicitRelayUrls: ['wss://relay.nsecbunker.com', 'wss://nostr.vulpem.com'], - }); - bunker.connect(); + const localSigner = new NDKPrivateKeySigner(localSignerPrivkey); + const bunker = new NDK({ + explicitRelayUrls: ['wss://relay.nsecbunker.com', 'wss://nostr.vulpem.com'], + }); + bunker.connect(); - const remoteSigner = new NDKNip46Signer(bunker, db.account.id, localSigner); - await remoteSigner.blockUntilReady(); + const remoteSigner = new NDKNip46Signer(bunker, db.account.id, localSigner); + await remoteSigner.blockUntilReady(); - return remoteSigner; + return remoteSigner; + } + + // Privkey Signer + const userPrivkey = await db.secureLoad(db.account.pubkey); + if (!userPrivkey) return null; + return new NDKPrivateKeySigner(userPrivkey); + } catch (e) { + console.log(e); + if (e === 'Token already redeemed') { + toast.info( + 'nsecbunker token already redeemed. You need to re-login with another token.' + ); + + await db.secureRemove(`${db.account.pubkey}-nsecbunker`); + await db.accountLogout(); + } + + return null; } - - // Privkey Signer - const userPrivkey = await db.secureLoad(db.account.pubkey); - if (!userPrivkey) return null; - return new NDKPrivateKeySigner(userPrivkey); } async function initNDK() { + const outboxSetting = await db.getSettingValue('outbox'); + const bunkerSetting = await db.getSettingValue('nsecbunker'); + + const bunker = !!parseInt(bunkerSetting); + const outbox = !!parseInt(outboxSetting); + + const explicitRelayUrls = normalizeRelayUrlSet([ + 'wss://relay.damus.io', + 'wss://relay.nostr.band', + 'wss://nos.lol', + 'wss://nostr.mutinywallet.com', + ]); + + // #TODO: user should config outbox relays + const outboxRelayUrls = normalizeRelayUrlSet(['wss://purplepag.es']); + + // #TODO: user should config blacklist relays + const blacklistRelayUrls = normalizeRelayUrlSet(['wss://brb.io']); + try { - const outboxSetting = await db.getSettingValue('outbox'); - const bunkerSetting = await db.getSettingValue('nsecbunker'); - const explicitRelayUrls = normalizeRelayUrlSet([ - 'wss://relay.damus.io', - 'wss://relay.nostr.band', - 'wss://nos.lol', - 'wss://nostr.mutinywallet.com', - ]); - - const bunker = !!parseInt(bunkerSetting); - const outbox = !!parseInt(outboxSetting); - - // #TODO: user can config outbox relays - const outboxRelayUrls = normalizeRelayUrlSet(['wss://purplepag.es/']); - const tauriAdapter = new NDKCacheAdapterTauri(db); const instance = new NDK({ explicitRelayUrls, outboxRelayUrls, + blacklistRelayUrls, enableOutboxModel: outbox, autoConnectUserRelays: true, autoFetchUserMutelist: true, @@ -91,9 +111,9 @@ export const NDKInstance = () => { if (db.account) { const user = instance.getUser({ pubkey: db.account.pubkey }); instance.activeUser = user; - db.account.contacts = [...(await user.follows(undefined, outbox))].map( - (user) => user.pubkey - ); + + const contacts = await user.follows(undefined /* outbox */); + db.account.contacts = [...contacts].map((user) => user.pubkey); // prefetch newsfeed await queryClient.prefetchInfiniteQuery({ diff --git a/src/libs/storage/instance.ts b/src/libs/storage/instance.ts index 5121a540..7a91ff9e 100644 --- a/src/libs/storage/instance.ts +++ b/src/libs/storage/instance.ts @@ -416,7 +416,14 @@ export class LumeStorage { return await this.db.execute(`DELETE FROM relays WHERE relay = "${relay}";`); } - public async createSetting(key: string, value: string) { + public async createSetting(key: string, value: string | undefined) { + if (value) { + return await this.db.execute( + 'INSERT OR IGNORE INTO settings (key, value) VALUES ($1, $2);', + [key, value] + ); + } + const currentSetting = await this.checkSettingValue(key); if (!currentSetting) @@ -470,9 +477,7 @@ export class LumeStorage { await this.db.execute("UPDATE accounts SET is_active = '0' WHERE id = $1;", [ this.account.id, ]); - this.account = null; - return true; } public async close() { diff --git a/src/shared/accounts/logout.tsx b/src/shared/accounts/logout.tsx index bc56a40d..259ee1f9 100644 --- a/src/shared/accounts/logout.tsx +++ b/src/shared/accounts/logout.tsx @@ -19,7 +19,7 @@ export function Logout() { // remove private key await db.secureRemove(db.account.pubkey); - await db.secureRemove(db.account.pubkey + '-nsecbunker'); + await db.secureRemove(`${db.account.pubkey}-nsecbunker`); // logout await db.accountLogout();