diff --git a/package.json b/package.json
index 5d0ef46b..034b2fff 100644
--- a/package.json
+++ b/package.json
@@ -28,7 +28,7 @@
"cheerio": "1.0.0-rc.12",
"dayjs": "^1.11.9",
"destr": "^1.2.2",
- "framer-motion": "^10.12.22",
+ "framer-motion": "^10.13.0",
"get-urls": "^11.0.0",
"immer": "^10.0.2",
"light-bolt11-decoder": "^3.0.0",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index c455ed35..6ca71662 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -38,8 +38,8 @@ dependencies:
specifier: ^1.2.2
version: 1.2.2
framer-motion:
- specifier: ^10.12.22
- version: 10.12.22(react-dom@18.2.0)(react@18.2.0)
+ specifier: ^10.13.0
+ version: 10.13.0(react-dom@18.2.0)(react@18.2.0)
get-urls:
specifier: ^11.0.0
version: 11.0.0
@@ -2210,7 +2210,7 @@ packages:
postcss: ^8.1.0
dependencies:
browserslist: 4.21.9
- caniuse-lite: 1.0.30001516
+ caniuse-lite: 1.0.30001517
fraction.js: 4.2.0
normalize-range: 0.1.2
picocolors: 1.0.0
@@ -2272,8 +2272,8 @@ packages:
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
hasBin: true
dependencies:
- caniuse-lite: 1.0.30001516
- electron-to-chromium: 1.4.464
+ caniuse-lite: 1.0.30001517
+ electron-to-chromium: 1.4.465
node-releases: 2.0.13
update-browserslist-db: 1.0.11(browserslist@4.21.9)
dev: true
@@ -2333,8 +2333,8 @@ packages:
engines: {node: '>=6'}
dev: false
- /caniuse-lite@1.0.30001516:
- resolution: {integrity: sha512-Wmec9pCBY8CWbmI4HsjBeQLqDTqV91nFVR83DnZpYyRnPI1wePDsTg0bGLPC5VU/3OIZV1fmxEea1b+tFKe86g==}
+ /caniuse-lite@1.0.30001517:
+ resolution: {integrity: sha512-Vdhm5S11DaFVLlyiKu4hiUTkpZu+y1KA/rZZqVQfOD5YdDT/eQKlkt7NaE0WGOFgX32diqt9MiP9CAiFeRklaA==}
dev: true
/ccount@2.0.1:
@@ -2735,8 +2735,8 @@ packages:
/eastasianwidth@0.2.0:
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
- /electron-to-chromium@1.4.464:
- resolution: {integrity: sha512-guZ84yoou4+ILNdj0XEbmGs6DEWj6zpVOWYpY09GU66yEb0DSYvP/biBPzHn0GuW/3RC/pnaYNUWlQE1fJYtgA==}
+ /electron-to-chromium@1.4.465:
+ resolution: {integrity: sha512-XQcuHvEJRMU97UJ75e170mgcITZoz0lIyiaVjk6R+NMTJ8KBIvUHYd1779swgOppUlzxR+JsLpq59PumaXS1jQ==}
dev: true
/emoji-regex@8.0.0:
@@ -3327,8 +3327,8 @@ packages:
resolution: {integrity: sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==}
dev: true
- /framer-motion@10.12.22(react-dom@18.2.0)(react@18.2.0):
- resolution: {integrity: sha512-bBGYPOxvxcfzS7/py9MEqDucmXBkVl2g42HNlXXPieSTSGGkr8L7+MilCnrU6uX3HrNk/tcB++1SkWE8BosHFw==}
+ /framer-motion@10.13.0(react-dom@18.2.0)(react@18.2.0):
+ resolution: {integrity: sha512-xKhw9VCizmwEHbopOfluaoVunGHSZyMztGbTvsgOYqCjaKu6qtlwWY1J+6GhL41NY1P157JgEikjDm67XCFnvQ==}
peerDependencies:
react: ^18.0.0
react-dom: ^18.0.0
@@ -6025,8 +6025,8 @@ packages:
inline-style-parser: 0.1.1
dev: false
- /sucrase@3.33.0:
- resolution: {integrity: sha512-ARGC7vbufOHfpvyGcZZXFaXCMZ9A4fffOGC5ucOW7+WHDGlAe8LJdf3Jts1sWhDeiI1RSWrKy5Hodl+JWGdW2A==}
+ /sucrase@3.34.0:
+ resolution: {integrity: sha512-70/LQEZ07TEcxiU2dz51FKaE6hCTWC6vr7FOk3Gr0U60C3shtAN+H+BFr9XlYe5xqf3RA8nrc+VIwzCfnxuXJw==}
engines: {node: '>=8'}
hasBin: true
dependencies:
@@ -6100,7 +6100,7 @@ packages:
postcss-nested: 6.0.1(postcss@8.4.26)
postcss-selector-parser: 6.0.13
resolve: 1.22.2
- sucrase: 3.33.0
+ sucrase: 3.34.0
transitivePeerDependencies:
- ts-node
dev: true
diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs
index b1ce70de..a1487dd9 100644
--- a/src-tauri/src/main.rs
+++ b/src-tauri/src/main.rs
@@ -121,8 +121,8 @@ fn main() {
tauri_plugin_stronghold::Builder::new(|password| {
let config = argon2::Config {
lanes: 2,
- mem_cost: 50_000,
- time_cost: 30,
+ mem_cost: 10_000,
+ time_cost: 10,
thread_mode: argon2::ThreadMode::from_threads(2),
variant: argon2::Variant::Argon2id,
..Default::default()
diff --git a/src/app/auth/create/step-2.tsx b/src/app/auth/create/step-2.tsx
index 19388650..dd915c96 100644
--- a/src/app/auth/create/step-2.tsx
+++ b/src/app/auth/create/step-2.tsx
@@ -32,12 +32,9 @@ export function CreateStep2Screen() {
const [passwordInput, setPasswordInput] = useState('password');
const [loading, setLoading] = useState(false);
- const [privkey, setPassword] = useStronghold((state) => [
- state.privkey,
- state.setPassword,
- ]);
- const pubkey = useOnboarding((state) => state.privkey);
+ const privkey = useStronghold((state) => state.privkey);
+ const pubkey = useOnboarding((state) => state.pubkey);
const { save } = useSecureStorage();
@@ -60,9 +57,6 @@ export function CreateStep2Screen() {
const onSubmit = async (data: { [x: string]: string }) => {
setLoading(true);
if (data.password.length > 3) {
- // add password to local state
- setPassword(data.password);
-
// save privkey to secure storage
await save(pubkey, privkey, data.password);
diff --git a/src/app/auth/create/step-5.tsx b/src/app/auth/create/step-5.tsx
index fd86eeff..28f75dfa 100644
--- a/src/app/auth/create/step-5.tsx
+++ b/src/app/auth/create/step-5.tsx
@@ -137,7 +137,7 @@ export function CreateStep5Screen() {
};
const update = useMutation({
- mutationFn: (follows: any) => {
+ mutationFn: (follows: string[]) => {
return updateAccount('follows', follows, account.pubkey);
},
onSuccess: () => {
diff --git a/src/app/auth/import/step-2.tsx b/src/app/auth/import/step-2.tsx
index 3d5cd54c..5dfab3cc 100644
--- a/src/app/auth/import/step-2.tsx
+++ b/src/app/auth/import/step-2.tsx
@@ -32,11 +32,8 @@ export function ImportStep2Screen() {
const [passwordInput, setPasswordInput] = useState('password');
const [loading, setLoading] = useState(false);
- const [privkey, setPassword] = useStronghold((state) => [
- state.privkey,
- state.setPassword,
- ]);
+ const privkey = useStronghold((state) => state.privkey);
const pubkey = useOnboarding((state) => state.pubkey);
const { save } = useSecureStorage();
@@ -60,9 +57,6 @@ export function ImportStep2Screen() {
const onSubmit = async (data: { [x: string]: string }) => {
setLoading(true);
if (data.password.length > 3) {
- // add password to local state
- setPassword(data.password);
-
// save privkey to secure storage
await save(pubkey, privkey, data.password);
@@ -115,9 +109,9 @@ export function ImportStep2Screen() {
- Password is use to secure your key store in local machine, when you move
- to other clients, you just need to copy your private key as nsec or
- hexstring
+ Password is use to unlock app and secure your key store in local machine.
+ When you move to other clients, you just need to copy your private key as
+ nsec or hexstring
diff --git a/src/app/auth/migrate.tsx b/src/app/auth/migrate.tsx
index ed174eee..034f90c3 100644
--- a/src/app/auth/migrate.tsx
+++ b/src/app/auth/migrate.tsx
@@ -33,13 +33,10 @@ const resolver: Resolver = async (values) => {
export function MigrateScreen() {
const queryClient = useQueryClient();
const navigate = useNavigate();
+ const setPrivkey = useStronghold((state) => state.setPrivkey);
const [passwordInput, setPasswordInput] = useState('password');
const [loading, setLoading] = useState(false);
- const [setPassword, setPrivkey] = useStronghold((state) => [
- state.setPassword,
- state.setPrivkey,
- ]);
const { account } = useAccount();
const { save } = useSecureStorage();
@@ -63,9 +60,6 @@ export function MigrateScreen() {
const onSubmit = async (data: { [x: string]: string }) => {
setLoading(true);
if (data.password.length > 3) {
- // add password to local state
- setPassword(data.password);
-
// load private in secure storage
try {
// save privkey to secure storage
diff --git a/src/app/auth/onboarding.tsx b/src/app/auth/onboarding.tsx
index b0fa56db..1da80940 100644
--- a/src/app/auth/onboarding.tsx
+++ b/src/app/auth/onboarding.tsx
@@ -21,8 +21,7 @@ export function OnboardingScreen() {
// publish event
publish({
- content:
- 'Running Lume, fighting for better future, join us here: https://lume.nu',
+ content: 'Running Lume, join with me: https://lume.nu',
kind: 1,
tags: [],
});
@@ -55,18 +54,15 @@ export function OnboardingScreen() {
)}
diff --git a/src/app/auth/unlock.tsx b/src/app/auth/unlock.tsx
index 5c65b33b..914a4fe5 100644
--- a/src/app/auth/unlock.tsx
+++ b/src/app/auth/unlock.tsx
@@ -29,13 +29,10 @@ const resolver: Resolver = async (values) => {
export function UnlockScreen() {
const navigate = useNavigate();
+ const setPrivkey = useStronghold((state) => state.setPrivkey);
const [passwordInput, setPasswordInput] = useState('password');
const [loading, setLoading] = useState(false);
- const [setPrivkey, setPassword] = useStronghold((state) => [
- state.setPrivkey,
- state.setPassword,
- ]);
const { account } = useAccount();
const { load } = useSecureStorage();
@@ -59,9 +56,6 @@ export function UnlockScreen() {
const onSubmit = async (data: { [x: string]: string }) => {
setLoading(true);
if (data.password.length > 3) {
- // add password to local state
- setPassword(data.password);
-
// load private in secure storage
try {
const privkey = await load(account.pubkey, data.password);
diff --git a/src/app/root.tsx b/src/app/root.tsx
index 81aab4f6..dc389bf9 100644
--- a/src/app/root.tsx
+++ b/src/app/root.tsx
@@ -13,7 +13,7 @@ import {
updateLastLogin,
} from '@libs/storage';
-import { LoaderIcon, LumeIcon } from '@shared/icons';
+import { LoaderIcon } from '@shared/icons';
import { nHoursAgo } from '@utils/date';
import { useAccount } from '@utils/hooks/useAccount';
@@ -175,27 +175,24 @@ export function Root() {
}, [status]);
return (
-
-
+
+
-
-
-
+
+
+
-
- Here's an interesting fact:
+
+ Prefetching data...
-
- Bitcoin and Nostr can be used by anyone, and no one can stop you!
+
+ This may take a few seconds, please don't close app.
-
-
-
diff --git a/src/app/space/hooks/useNewsfeed.tsx b/src/app/space/hooks/useNewsfeed.tsx
index e95918b7..40209e73 100644
--- a/src/app/space/hooks/useNewsfeed.tsx
+++ b/src/app/space/hooks/useNewsfeed.tsx
@@ -19,7 +19,7 @@ export function useNewsfeed() {
useEffect(() => {
if (status === 'success' && account) {
- const follows = account ? JSON.parse(account.follows) : [];
+ const follows = account ? JSON.parse(account.follows as string) : [];
const filter: NDKFilter = {
kinds: [1, 6],
@@ -30,7 +30,6 @@ export function useNewsfeed() {
sub.current = ndk.subscribe(filter, { closeOnEose: false });
sub.current.addListener('event', (event: NDKEvent) => {
- console.log('new note: ', event);
// add to db
createNote(
event.id,
@@ -46,7 +45,9 @@ export function useNewsfeed() {
}
return () => {
- sub.current.stop();
+ if (sub.current) {
+ sub.current.stop();
+ }
};
}, [status]);
}
diff --git a/src/shared/protected.tsx b/src/shared/protected.tsx
index 9f9f7576..dec04391 100644
--- a/src/shared/protected.tsx
+++ b/src/shared/protected.tsx
@@ -6,7 +6,7 @@ import { useStronghold } from '@stores/stronghold';
import { useAccount } from '@utils/hooks/useAccount';
export function Protected({ children }: { children: ReactNode }) {
- const password = useStronghold((state) => state.password);
+ const privkey = useStronghold((state) => state.privkey);
const { status, account } = useAccount();
if (status === 'success' && !account) {
@@ -17,7 +17,7 @@ export function Protected({ children }: { children: ReactNode }) {
return
;
}
- if (status === 'success' && account && !password) {
+ if (status === 'success' && account && !privkey) {
return
;
}
diff --git a/src/stores/onboarding.tsx b/src/stores/onboarding.tsx
index 562336ad..cd8644cf 100644
--- a/src/stores/onboarding.tsx
+++ b/src/stores/onboarding.tsx
@@ -3,11 +3,8 @@ import { create } from 'zustand';
interface OnboardingState {
profile: { [x: string]: string };
pubkey: string;
- privkey: string;
createProfile: (data: { [x: string]: string }) => void;
setPubkey: (pubkey: string) => void;
- setPrivkey: (privkey: string) => void;
- clearPrivkey: (privkey: string) => void;
}
export const useOnboarding = create
((set) => ({
@@ -20,10 +17,4 @@ export const useOnboarding = create((set) => ({
setPubkey: (pubkey: string) => {
set({ pubkey: pubkey });
},
- setPrivkey: (privkey: string) => {
- set({ privkey: privkey });
- },
- clearPrivkey: () => {
- set({ privkey: '' });
- },
}));
diff --git a/src/stores/stronghold.tsx b/src/stores/stronghold.tsx
index 90823596..db8ddd55 100644
--- a/src/stores/stronghold.tsx
+++ b/src/stores/stronghold.tsx
@@ -1,19 +1,22 @@
import { create } from 'zustand';
+import { createJSONStorage, persist } from 'zustand/middleware';
interface StrongholdState {
- password: null | string;
privkey: null | string;
- setPassword: (password: string) => void;
setPrivkey: (privkey: string) => void;
}
-export const useStronghold = create((set) => ({
- password: null,
- privkey: null,
- setPassword: (password: string) => {
- set({ password: password });
- },
- setPrivkey: (privkey: string) => {
- set({ privkey: privkey });
- },
-}));
+export const useStronghold = create()(
+ persist(
+ (set) => ({
+ privkey: null,
+ setPrivkey: (privkey: string) => {
+ set({ privkey: privkey });
+ },
+ }),
+ {
+ name: 'stronghold',
+ storage: createJSONStorage(() => sessionStorage),
+ }
+ )
+);
diff --git a/src/utils/hooks/usePublish.tsx b/src/utils/hooks/usePublish.tsx
index c37d20e2..ebbe1cee 100644
--- a/src/utils/hooks/usePublish.tsx
+++ b/src/utils/hooks/usePublish.tsx
@@ -5,14 +5,12 @@ import { useNDK } from '@libs/ndk/provider';
import { useStronghold } from '@stores/stronghold';
import { useAccount } from '@utils/hooks/useAccount';
-import { useSecureStorage } from '@utils/hooks/useSecureStorage';
export function usePublish() {
const { ndk } = useNDK();
const { account } = useAccount();
- const { load } = useSecureStorage();
- const cachePrivkey = useStronghold((state) => state.privkey);
+ const privkey = useStronghold((state) => state.privkey);
const publish = async ({
content,
@@ -23,12 +21,7 @@ export function usePublish() {
kind: NDKKind | number;
tags: string[][];
}): Promise => {
- let privkey: string;
- if (cachePrivkey) {
- privkey = cachePrivkey;
- } else {
- privkey = await load(account.pubkey);
- }
+ if (!privkey) throw new Error('Private key not found');
const event = new NDKEvent(ndk);
const signer = new NDKPrivateKeySigner(privkey);
diff --git a/src/utils/hooks/useSecureStorage.tsx b/src/utils/hooks/useSecureStorage.tsx
index a5b13548..3b2b3282 100644
--- a/src/utils/hooks/useSecureStorage.tsx
+++ b/src/utils/hooks/useSecureStorage.tsx
@@ -1,13 +1,9 @@
import { appConfigDir } from '@tauri-apps/api/path';
import { Stronghold } from 'tauri-plugin-stronghold-api';
-import { useStronghold } from '@stores/stronghold';
-
const dir = await appConfigDir();
export function useSecureStorage() {
- const password = useStronghold((state) => state.password);
-
async function getClient(stronghold: Stronghold) {
try {
return await stronghold.loadClient('lume');
@@ -16,22 +12,16 @@ export function useSecureStorage() {
}
}
- const save = async (key: string, value: string, userpass?: string) => {
- const stronghold = await Stronghold.load(
- `${dir}lume.stronghold`,
- userpass ? userpass : password
- );
+ const save = async (key: string, value: string, password: string) => {
+ const stronghold = await Stronghold.load(`${dir}lume.stronghold`, password);
const client = await getClient(stronghold);
const store = client.getStore();
await store.insert(key, Array.from(new TextEncoder().encode(value)));
return await stronghold.save();
};
- const load = async (key: string, userpass?: string) => {
- const stronghold = await Stronghold.load(
- `${dir}lume.stronghold`,
- userpass ? userpass : password
- );
+ const load = async (key: string, password: string) => {
+ const stronghold = await Stronghold.load(`${dir}lume.stronghold`, password);
const client = await getClient(stronghold);
const store = client.getStore();
const value = await store.get(key);