mirror of
https://github.com/luminous-devs/lume.git
synced 2024-09-18 11:13:30 +00:00
updated onboarding process use new storage util
This commit is contained in:
parent
705430a11e
commit
18a9bf3e49
@ -1,13 +1,13 @@
|
||||
import { DatabaseContext } from '@components/contexts/database';
|
||||
import { ImageWithFallback } from '@components/imageWithFallback';
|
||||
|
||||
import { createCacheProfile } from '@utils/storage';
|
||||
import { truncate } from '@utils/truncate';
|
||||
|
||||
import { fetch } from '@tauri-apps/api/http';
|
||||
import { memo, useCallback, useContext, useEffect, useState } from 'react';
|
||||
import destr from 'destr';
|
||||
import { memo, useCallback, useEffect, useState } from 'react';
|
||||
|
||||
export const UserBase = memo(function UserBase({ pubkey }: { pubkey: string }) {
|
||||
const { db }: any = useContext(DatabaseContext);
|
||||
const [profile, setProfile] = useState(null);
|
||||
|
||||
const fetchProfile = useCallback(async (id: string) => {
|
||||
@ -15,24 +15,17 @@ export const UserBase = memo(function UserBase({ pubkey }: { pubkey: string }) {
|
||||
method: 'GET',
|
||||
timeout: 30,
|
||||
});
|
||||
return res;
|
||||
return res.data;
|
||||
}, []);
|
||||
|
||||
const cacheProfile = useCallback(
|
||||
async (event) => {
|
||||
// insert to database
|
||||
await db.execute('INSERT OR IGNORE INTO cache_profiles (id, metadata) VALUES (?, ?);', [pubkey, event.content]);
|
||||
// update state
|
||||
setProfile(JSON.parse(event.content));
|
||||
},
|
||||
[db, pubkey]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
fetchProfile(pubkey)
|
||||
.then((res) => cacheProfile(res))
|
||||
.then((res: any) => {
|
||||
setProfile(destr(res.content));
|
||||
createCacheProfile(res.pubkey, res.content);
|
||||
})
|
||||
.catch(console.error);
|
||||
}, [fetchProfile, cacheProfile, pubkey]);
|
||||
}, [fetchProfile, pubkey]);
|
||||
|
||||
return (
|
||||
<div className="flex items-center gap-2">
|
||||
@ -41,7 +34,7 @@ export const UserBase = memo(function UserBase({ pubkey }: { pubkey: string }) {
|
||||
<ImageWithFallback src={profile.picture} alt={pubkey} fill={true} className="rounded-full object-cover" />
|
||||
)}
|
||||
</div>
|
||||
<div className="flex w-full flex-1 flex-col items-start">
|
||||
<div className="flex w-full flex-1 flex-col items-start text-start">
|
||||
<span className="font-medium leading-tight text-zinc-200">{profile?.display_name || profile?.name}</span>
|
||||
<span className="text-sm leading-tight text-zinc-400">{truncate(pubkey, 16, ' .... ')}</span>
|
||||
</div>
|
||||
|
@ -1,14 +1,13 @@
|
||||
import BaseLayout from '@layouts/base';
|
||||
|
||||
import { DatabaseContext } from '@components/contexts/database';
|
||||
import { RelayContext } from '@components/contexts/relay';
|
||||
import { pool } from '@utils/pool';
|
||||
import { createAccount, getAllRelays } from '@utils/storage';
|
||||
|
||||
import { EyeClosedIcon, EyeOpenIcon } from '@radix-ui/react-icons';
|
||||
import { useLocalStorage, writeStorage } from '@rehooks/local-storage';
|
||||
import Image from 'next/image';
|
||||
import { useRouter } from 'next/router';
|
||||
import { generatePrivateKey, getEventHash, getPublicKey, nip19, signEvent } from 'nostr-tools';
|
||||
import { JSXElementConstructor, ReactElement, ReactFragment, ReactPortal, useContext, useMemo, useState } from 'react';
|
||||
import { JSXElementConstructor, ReactElement, ReactFragment, ReactPortal, useMemo, useState } from 'react';
|
||||
import { Config, names, uniqueNamesGenerator } from 'unique-names-generator';
|
||||
|
||||
const config: Config = {
|
||||
@ -18,11 +17,6 @@ const config: Config = {
|
||||
export default function Page() {
|
||||
const router = useRouter();
|
||||
|
||||
const { db }: any = useContext(DatabaseContext);
|
||||
const relayPool: any = useContext(RelayContext);
|
||||
|
||||
const [relays] = useLocalStorage('relays');
|
||||
|
||||
const [type, setType] = useState('password');
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
@ -33,16 +27,8 @@ export default function Page() {
|
||||
const npub = nip19.npubEncode(pubKey);
|
||||
const nsec = nip19.nsecEncode(privKey);
|
||||
|
||||
// toggle privatek key
|
||||
const showPrivateKey = () => {
|
||||
if (type === 'password') {
|
||||
setType('text');
|
||||
} else {
|
||||
setType('password');
|
||||
}
|
||||
};
|
||||
// auto-generated profile
|
||||
const data = useMemo(
|
||||
// auto-generated profile metadata
|
||||
const metadata = useMemo(
|
||||
() => ({
|
||||
display_name: name,
|
||||
name: name,
|
||||
@ -52,23 +38,35 @@ export default function Page() {
|
||||
}),
|
||||
[name]
|
||||
);
|
||||
// insert to database
|
||||
const insertDB = async () => {
|
||||
await db.execute('INSERT OR IGNORE INTO accounts (id, privkey, npub, nsec, metadata) VALUES (?, ?, ?, ?, ?)', [
|
||||
pubKey,
|
||||
privKey,
|
||||
npub,
|
||||
nsec,
|
||||
data,
|
||||
]);
|
||||
|
||||
// build profile
|
||||
const data = useMemo(
|
||||
() => ({
|
||||
pubkey: pubKey,
|
||||
privkey: privKey,
|
||||
npub: npub,
|
||||
nsec: nsec,
|
||||
metadata: metadata,
|
||||
}),
|
||||
[metadata, npub, nsec, privKey, pubKey]
|
||||
);
|
||||
|
||||
// toggle privatek key
|
||||
const showPrivateKey = () => {
|
||||
if (type === 'password') {
|
||||
setType('text');
|
||||
} else {
|
||||
setType('password');
|
||||
}
|
||||
};
|
||||
// build event and broadcast to all relays
|
||||
const createAccount = () => {
|
||||
|
||||
// create account and broadcast to all relays
|
||||
const submit = () => {
|
||||
setLoading(true);
|
||||
|
||||
// build event
|
||||
const event: any = {
|
||||
content: JSON.stringify(data),
|
||||
content: JSON.stringify(metadata),
|
||||
created_at: Math.floor(Date.now() / 1000),
|
||||
kind: 0,
|
||||
pubkey: pubKey,
|
||||
@ -76,23 +74,20 @@ export default function Page() {
|
||||
};
|
||||
event.id = getEventHash(event);
|
||||
event.sig = signEvent(event, privKey);
|
||||
|
||||
// insert to database then broadcast
|
||||
insertDB()
|
||||
createAccount(data)
|
||||
.then(() => {
|
||||
// publish to relays
|
||||
relayPool.publish(event, relays);
|
||||
// set currentUser in global state
|
||||
writeStorage('current-user', {
|
||||
metadata: JSON.stringify(data),
|
||||
npub: npub,
|
||||
privkey: privKey,
|
||||
id: pubKey,
|
||||
});
|
||||
// redirect to pre-follow
|
||||
setTimeout(() => {
|
||||
setLoading(false);
|
||||
router.push('/onboarding/create/step-2');
|
||||
}, 1500);
|
||||
getAllRelays()
|
||||
.then((res) => {
|
||||
// publish to relays
|
||||
pool(res).publish(event, res);
|
||||
router.push({
|
||||
pathname: '/onboarding/create/step-2',
|
||||
query: { id: pubKey, privkey: privKey },
|
||||
});
|
||||
})
|
||||
.catch(console.error);
|
||||
})
|
||||
.catch(console.error);
|
||||
};
|
||||
@ -146,12 +141,12 @@ export default function Page() {
|
||||
<div className="relative w-full rounded-lg border border-black/5 px-3.5 py-4 shadow-input shadow-black/5 !outline-none placeholder:text-zinc-400 dark:bg-zinc-800 dark:text-zinc-200 dark:shadow-black/10 dark:placeholder:text-zinc-600">
|
||||
<div className="flex space-x-4">
|
||||
<div className="relative h-10 w-10 rounded-full">
|
||||
<Image className="inline-block rounded-full" src={data.picture} alt="" fill={true} />
|
||||
<Image className="inline-block rounded-full" src={metadata.picture} alt="" fill={true} />
|
||||
</div>
|
||||
<div className="flex-1 space-y-4 py-1">
|
||||
<div className="flex items-center gap-2">
|
||||
<p className="font-semibold">{data.display_name}</p>
|
||||
<p className="text-zinc-400">@{data.username}</p>
|
||||
<p className="font-semibold">{metadata.display_name}</p>
|
||||
<p className="text-zinc-400">@{metadata.username}</p>
|
||||
</div>
|
||||
<div className="space-y-3">
|
||||
<div className="grid grid-cols-3 gap-4">
|
||||
@ -183,7 +178,7 @@ export default function Page() {
|
||||
</svg>
|
||||
) : (
|
||||
<button
|
||||
onClick={() => createAccount()}
|
||||
onClick={() => submit()}
|
||||
className="w-full transform rounded-lg bg-gradient-to-r from-fuchsia-300 via-orange-100 to-amber-300 px-3.5 py-2.5 font-medium text-zinc-800 active:translate-y-1 disabled:cursor-not-allowed disabled:opacity-30"
|
||||
>
|
||||
<span className="drop-shadow-lg">Continue →</span>
|
||||
|
@ -1,24 +1,15 @@
|
||||
import BaseLayout from '@layouts/base';
|
||||
|
||||
import { DatabaseContext } from '@components/contexts/database';
|
||||
import { RelayContext } from '@components/contexts/relay';
|
||||
import { UserBase } from '@components/user/base';
|
||||
|
||||
import { pool } from '@utils/pool';
|
||||
import { createFollows, getAllRelays } from '@utils/storage';
|
||||
|
||||
import { CheckCircledIcon } from '@radix-ui/react-icons';
|
||||
import useLocalStorage from '@rehooks/local-storage';
|
||||
import { createClient } from '@supabase/supabase-js';
|
||||
import { useRouter } from 'next/router';
|
||||
import { getEventHash, nip19, signEvent } from 'nostr-tools';
|
||||
import {
|
||||
JSXElementConstructor,
|
||||
Key,
|
||||
ReactElement,
|
||||
ReactFragment,
|
||||
ReactPortal,
|
||||
useContext,
|
||||
useEffect,
|
||||
useState,
|
||||
} from 'react';
|
||||
import { getEventHash, signEvent } from 'nostr-tools';
|
||||
import { JSXElementConstructor, Key, ReactElement, ReactFragment, ReactPortal, useEffect, useState } from 'react';
|
||||
|
||||
const supabase = createClient(
|
||||
'https://niwaazauwnrwiwmnocnn.supabase.co',
|
||||
@ -62,12 +53,7 @@ const initialList = [
|
||||
|
||||
export default function Page() {
|
||||
const router = useRouter();
|
||||
|
||||
const { db }: any = useContext(DatabaseContext);
|
||||
const relayPool: any = useContext(RelayContext);
|
||||
|
||||
const [currentUser]: any = useLocalStorage('current-user');
|
||||
const [relays] = useLocalStorage('relays');
|
||||
const { id, privkey }: any = router.query;
|
||||
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [list, setList]: any = useState(initialList);
|
||||
@ -78,31 +64,19 @@ export default function Page() {
|
||||
const arr = follows.includes(pubkey) ? follows.filter((i) => i !== pubkey) : [...follows, pubkey];
|
||||
setFollows(arr);
|
||||
};
|
||||
// insert follow to database
|
||||
const insertDB = async () => {
|
||||
// self follow
|
||||
await db.execute(
|
||||
`INSERT OR IGNORE INTO follows (pubkey, account, kind) VALUES ("${currentUser.id}", "${currentUser.id}", "0")`
|
||||
);
|
||||
// follow selected
|
||||
follows.forEach(async (pubkey) => {
|
||||
await db.execute(
|
||||
`INSERT OR IGNORE INTO follows (pubkey, account, kind) VALUES ("${pubkey}", "${currentUser.id}", "0")`
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
// build event tags
|
||||
const createTags = () => {
|
||||
const tags = [];
|
||||
const tags = () => {
|
||||
const arr = [];
|
||||
// push item to tags
|
||||
follows.forEach((item) => {
|
||||
tags.push(['p', item]);
|
||||
arr.push(['p', item]);
|
||||
});
|
||||
|
||||
return tags;
|
||||
return arr;
|
||||
};
|
||||
// commit and publish to relays
|
||||
const createFollows = () => {
|
||||
|
||||
// save follows to database then broadcast
|
||||
const submit = () => {
|
||||
setLoading(true);
|
||||
|
||||
// build event
|
||||
@ -110,21 +84,25 @@ export default function Page() {
|
||||
content: '',
|
||||
created_at: Math.floor(Date.now() / 1000),
|
||||
kind: 3,
|
||||
pubkey: currentUser.id,
|
||||
tags: createTags(),
|
||||
pubkey: id,
|
||||
tags: tags(),
|
||||
};
|
||||
event.id = getEventHash(event);
|
||||
event.sig = signEvent(event, currentUser.privkey);
|
||||
event.sig = signEvent(event, privkey);
|
||||
|
||||
insertDB().then(() => {
|
||||
// publish to relays
|
||||
relayPool.publish(event, relays);
|
||||
// redirect to home
|
||||
setTimeout(() => {
|
||||
setLoading(false);
|
||||
router.push('/');
|
||||
}, 1000);
|
||||
});
|
||||
createFollows(follows, id, 0)
|
||||
.then((res) => {
|
||||
if (res === 'ok') {
|
||||
getAllRelays()
|
||||
.then((res) => {
|
||||
// publish to relays
|
||||
pool(res).publish(event, res);
|
||||
router.push('/');
|
||||
})
|
||||
.catch(console.error);
|
||||
}
|
||||
})
|
||||
.catch(console.error);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
@ -174,7 +152,7 @@ export default function Page() {
|
||||
{follows.length >= 10 && (
|
||||
<div className="fixed bottom-0 left-0 z-10 flex h-24 w-full items-center justify-center">
|
||||
<button
|
||||
onClick={() => createFollows()}
|
||||
onClick={() => submit()}
|
||||
className="relative z-20 inline-flex w-36 transform items-center justify-center rounded-full bg-gradient-to-r from-fuchsia-300 via-orange-100 to-amber-300 px-3.5 py-2.5 font-medium text-zinc-800 shadow-xl active:translate-y-1 disabled:cursor-not-allowed disabled:opacity-30"
|
||||
>
|
||||
{loading === true ? (
|
||||
|
@ -1,105 +1,75 @@
|
||||
import BaseLayout from '@layouts/base';
|
||||
|
||||
import { DatabaseContext } from '@components/contexts/database';
|
||||
import { RelayContext } from '@components/contexts/relay';
|
||||
import { pool } from '@utils/pool';
|
||||
import { createAccount, createFollows, getAllRelays } from '@utils/storage';
|
||||
import { truncate } from '@utils/truncate';
|
||||
|
||||
import { useLocalStorage, writeStorage } from '@rehooks/local-storage';
|
||||
import destr from 'destr';
|
||||
import Image from 'next/image';
|
||||
import { useRouter } from 'next/router';
|
||||
import { getPublicKey, nip19 } from 'nostr-tools';
|
||||
import {
|
||||
JSXElementConstructor,
|
||||
ReactElement,
|
||||
ReactFragment,
|
||||
ReactPortal,
|
||||
useCallback,
|
||||
useContext,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useState,
|
||||
} from 'react';
|
||||
import { JSXElementConstructor, ReactElement, ReactFragment, ReactPortal, useEffect, useState } from 'react';
|
||||
|
||||
const tags = (arr) => {
|
||||
const newarr = [];
|
||||
// push item to newarr
|
||||
arr.forEach((item) => {
|
||||
newarr.push(['p', item]);
|
||||
});
|
||||
return newarr;
|
||||
};
|
||||
|
||||
export default function Page() {
|
||||
const { db }: any = useContext(DatabaseContext);
|
||||
const relayPool: any = useContext(RelayContext);
|
||||
|
||||
const router = useRouter();
|
||||
const { privkey }: any = router.query;
|
||||
const privkey: any = router.query.privkey;
|
||||
const pubkey = getPublicKey(privkey);
|
||||
|
||||
const [relays] = useLocalStorage('relays');
|
||||
const [profile, setProfile] = useState({ picture: '', display_name: '', username: '' });
|
||||
const [profile, setProfile] = useState(null);
|
||||
|
||||
const pubkey = useMemo(() => (privkey ? getPublicKey(privkey) : null), [privkey]);
|
||||
useEffect(() => {
|
||||
getAllRelays()
|
||||
.then((res) => {
|
||||
pool(res).subscribe(
|
||||
[
|
||||
{
|
||||
authors: [pubkey],
|
||||
kinds: [0, 3],
|
||||
since: 0,
|
||||
},
|
||||
],
|
||||
res,
|
||||
(event: any) => {
|
||||
if (event.kind === 0) {
|
||||
const data = {
|
||||
pubkey: pubkey,
|
||||
privkey: privkey,
|
||||
npub: nip19.npubEncode(pubkey),
|
||||
nsec: nip19.nsecEncode(privkey),
|
||||
metadata: event.content,
|
||||
};
|
||||
setProfile(destr(event.content));
|
||||
createAccount(data);
|
||||
} else {
|
||||
if (event.tags.length > 0) {
|
||||
createFollows(tags(event.tags), pubkey, 0);
|
||||
}
|
||||
}
|
||||
},
|
||||
undefined,
|
||||
undefined,
|
||||
{
|
||||
unsubscribeOnEose: true,
|
||||
}
|
||||
);
|
||||
})
|
||||
.catch(console.error);
|
||||
}, [privkey, pubkey]);
|
||||
|
||||
// save account to database
|
||||
const insertAccount = useCallback(
|
||||
async (metadata) => {
|
||||
const npub = privkey ? nip19.npubEncode(pubkey) : null;
|
||||
const nsec = privkey ? nip19.nsecEncode(privkey) : null;
|
||||
// insert to database
|
||||
await db.execute('INSERT OR IGNORE INTO accounts (id, privkey, npub, nsec, metadata) VALUES (?, ?, ?, ?, ?)', [
|
||||
pubkey,
|
||||
privkey,
|
||||
npub,
|
||||
nsec,
|
||||
metadata,
|
||||
]);
|
||||
// write to localstorage
|
||||
writeStorage('current-user', { id: pubkey, privkey: privkey, npub: npub, nsec: nsec, metadata: metadata });
|
||||
// update state
|
||||
setProfile(JSON.parse(metadata));
|
||||
},
|
||||
[db, privkey, pubkey]
|
||||
);
|
||||
// save follows to database
|
||||
const insertFollows = useCallback(
|
||||
async (follows) => {
|
||||
follows.forEach(async (item) => {
|
||||
if (item) {
|
||||
// insert to database
|
||||
await db.execute(
|
||||
`INSERT OR IGNORE INTO follows (pubkey, account, kind) VALUES ("${item[1]}", "${pubkey}", "0")`
|
||||
);
|
||||
}
|
||||
});
|
||||
},
|
||||
[db, pubkey]
|
||||
);
|
||||
// submit then redirect to home
|
||||
const submit = () => {
|
||||
router.push('/');
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const unsubscribe = relayPool.subscribe(
|
||||
[
|
||||
{
|
||||
authors: [pubkey],
|
||||
kinds: [0, 3],
|
||||
since: 0,
|
||||
},
|
||||
],
|
||||
relays,
|
||||
(event: any) => {
|
||||
if (event.kind === 0) {
|
||||
insertAccount(event.content);
|
||||
} else {
|
||||
if (event.tags.length > 0) {
|
||||
insertFollows(event.tags);
|
||||
}
|
||||
}
|
||||
},
|
||||
undefined,
|
||||
(events: any, relayURL: any) => {
|
||||
console.log(events, relayURL);
|
||||
}
|
||||
);
|
||||
|
||||
return () => {
|
||||
unsubscribe();
|
||||
};
|
||||
}, [insertAccount, insertFollows, pubkey, relayPool, relays]);
|
||||
|
||||
return (
|
||||
<div className="grid h-full w-full grid-rows-5">
|
||||
<div className="row-span-1 flex items-center justify-center">
|
||||
@ -115,13 +85,13 @@ export default function Page() {
|
||||
<div className="w-full rounded-lg bg-zinc-900 p-4 shadow-input ring-1 ring-zinc-800">
|
||||
<div className="flex space-x-4">
|
||||
<div className="relative h-10 w-10 rounded-full">
|
||||
<Image className="inline-block rounded-full" src={profile.picture} alt="" fill={true} />
|
||||
<Image className="inline-block rounded-full" src={profile?.picture} alt="" fill={true} />
|
||||
</div>
|
||||
<div className="flex-1 space-y-4 py-1">
|
||||
<div className="flex items-center gap-2">
|
||||
<p className="font-semibold">{profile.display_name}</p>
|
||||
<p className="font-semibold">{profile?.display_name || profile?.name}</p>
|
||||
<span className="leading-tight text-zinc-500">·</span>
|
||||
<p className="text-zinc-500">@{profile.username}</p>
|
||||
<p className="text-zinc-500">@{profile?.username || truncate(pubkey, 16, ' .... ')}</p>
|
||||
</div>
|
||||
<div className="space-y-3">
|
||||
<div className="grid grid-cols-3 gap-4">
|
||||
|
6
src/utils/pool.tsx
Normal file
6
src/utils/pool.tsx
Normal file
@ -0,0 +1,6 @@
|
||||
import { RelayPool } from 'nostr-relaypool';
|
||||
|
||||
export function pool({ relays }: { relays: any }) {
|
||||
const createPool = new RelayPool(relays, { useEventCache: false, logSubscriptions: false });
|
||||
return createPool;
|
||||
}
|
@ -15,17 +15,59 @@ export async function connect(): Promise<Database> {
|
||||
// get all relays
|
||||
export async function getAllRelays() {
|
||||
const db = await connect();
|
||||
return await db.select('SELECT relay_url FROM relays WHERE relay_status = "1"');
|
||||
const result: any = await db.select('SELECT relay_url FROM relays WHERE relay_status = "1";');
|
||||
return result.reduce((relays, { relay_url }) => {
|
||||
relays.push(relay_url);
|
||||
return relays;
|
||||
}, []);
|
||||
}
|
||||
|
||||
// get active account
|
||||
export async function getActiveAccount() {
|
||||
const db = await connect();
|
||||
return await db.select(`SELECT * FROM accounts LIMIT 1`);
|
||||
return await db.select(`SELECT * FROM accounts LIMIT 1;`);
|
||||
}
|
||||
|
||||
// get all follows by account id
|
||||
export async function getAllFollowsByID(id: string) {
|
||||
export async function getAllFollowsByID(id) {
|
||||
const db = await connect();
|
||||
return await db.select(`SELECT pubkey FROM follows WHERE account = "${id}"`);
|
||||
return await db.select(`SELECT pubkey FROM follows WHERE account = "${id}";`);
|
||||
}
|
||||
|
||||
// create account
|
||||
export async function createAccount(data) {
|
||||
const db = await connect();
|
||||
return await db.execute(
|
||||
'INSERT OR IGNORE INTO accounts (id, privkey, npub, nsec, metadata) VALUES (?, ?, ?, ?, ?);',
|
||||
[data.pubkey, data.privkey, data.npub, data.nsec, data.metadata]
|
||||
);
|
||||
}
|
||||
|
||||
// create follow
|
||||
export async function createFollow(pubkey, account, kind) {
|
||||
const db = await connect();
|
||||
return await db.execute('INSERT OR IGNORE INTO follows (pubkey, account, kind) VALUES (?, ?, ?);', [
|
||||
pubkey,
|
||||
account,
|
||||
kind || 0,
|
||||
]);
|
||||
}
|
||||
|
||||
// create follow
|
||||
export async function createFollows(data, account, kind) {
|
||||
const db = await connect();
|
||||
data.forEach(async (item) => {
|
||||
await db.execute('INSERT OR IGNORE INTO follows (pubkey, account, kind) VALUES (?, ?, ?);', [
|
||||
item,
|
||||
account,
|
||||
kind || 0,
|
||||
]);
|
||||
});
|
||||
return 'ok';
|
||||
}
|
||||
|
||||
// create cache profile
|
||||
export async function createCacheProfile(id, metadata) {
|
||||
const db = await connect();
|
||||
return await db.execute('INSERT OR IGNORE INTO cache_profiles (id, metadata) VALUES (?, ?);', [id, metadata]);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user