@nostrify/react 0.2.13 → 0.2.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +14 -20
- package/CHANGELOG.md +18 -0
- package/dist/NostrContext.d.ts +13 -0
- package/dist/NostrContext.d.ts.map +1 -0
- package/dist/NostrContext.js +7 -0
- package/dist/NostrContext.ts +17 -0
- package/dist/example/test-helpers.js +33 -0
- package/dist/example/test-helpers.ts +33 -0
- package/dist/example/useAuthor.js +31 -0
- package/dist/example/useAuthor.ts +38 -0
- package/dist/example/useCurrentUser.js +42 -0
- package/dist/example/useCurrentUser.ts +48 -0
- package/dist/example/useLoginActions.js +23 -0
- package/dist/example/useLoginActions.ts +22 -0
- package/dist/example/useSocialFeed.js +15 -0
- package/dist/example/useSocialFeed.ts +18 -0
- package/dist/example/vite-env.d.js +0 -0
- package/dist/example/vite-env.d.ts +1 -0
- package/dist/login/NLogin.d.ts +46 -0
- package/dist/login/NLogin.d.ts.map +1 -0
- package/dist/login/NLogin.js +73 -0
- package/dist/login/NLogin.ts +122 -0
- package/dist/login/NUser.d.ts +23 -0
- package/dist/login/NUser.d.ts.map +1 -0
- package/dist/login/NUser.js +41 -0
- package/dist/login/NUser.ts +58 -0
- package/dist/login/NostrLoginContext.d.ts +24 -0
- package/dist/login/NostrLoginContext.d.ts.map +1 -0
- package/dist/login/NostrLoginContext.js +5 -0
- package/dist/login/NostrLoginContext.ts +28 -0
- package/dist/login/NostrLoginProvider.d.ts +15 -0
- package/dist/login/NostrLoginProvider.d.ts.map +1 -0
- package/dist/login/NostrLoginProvider.js +17 -0
- package/dist/login/NostrLoginProvider.ts +34 -0
- package/dist/login/mod.d.ts +5 -0
- package/dist/login/mod.d.ts.map +1 -0
- package/dist/login/mod.js +10 -0
- package/dist/login/mod.ts +4 -0
- package/dist/login/nostrLoginReducer.d.ts +16 -0
- package/dist/login/nostrLoginReducer.d.ts.map +1 -0
- package/dist/login/nostrLoginReducer.js +28 -0
- package/dist/login/nostrLoginReducer.ts +42 -0
- package/dist/login/useNostrLogin.d.ts +3 -0
- package/dist/login/useNostrLogin.d.ts.map +1 -0
- package/dist/login/useNostrLogin.js +12 -0
- package/dist/login/useNostrLogin.ts +13 -0
- package/dist/login/useNostrLoginReducer.d.ts +4 -0
- package/dist/login/useNostrLoginReducer.d.ts.map +1 -0
- package/dist/login/useNostrLoginReducer.js +15 -0
- package/dist/login/useNostrLoginReducer.ts +20 -0
- package/dist/mod.d.ts +4 -0
- package/dist/mod.d.ts.map +1 -0
- package/dist/mod.js +7 -0
- package/dist/mod.ts +3 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/useNostr.d.ts +3 -0
- package/dist/useNostr.d.ts.map +1 -0
- package/dist/useNostr.js +12 -0
- package/dist/useNostr.ts +13 -0
- package/package.json +5 -6
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,25 +1,19 @@
|
|
|
1
1
|
|
|
2
2
|
|
|
3
|
-
> @nostrify/react@0.2.
|
|
4
|
-
> tsc -p tsconfig.json && node ../../esbuild.config.js --package ./
|
|
3
|
+
> @nostrify/react@0.2.13 build /home/sid/repos/nostrify/packages/react
|
|
4
|
+
> npx tsc -p tsconfig.json && node ../../esbuild.config.js --package ./
|
|
5
5
|
|
|
6
|
+
[1mnpm[22m [33mwarn[39m [94mUnknown env config "verify-deps-before-run". This will stop working in the next major version of npm.[39m
|
|
7
|
+
[1mnpm[22m [33mwarn[39m [94mUnknown env config "_jsr-registry". This will stop working in the next major version of npm.[39m
|
|
8
|
+
[1G[0K⠙[1G[0K[1G[0K⠙[1G[0KBuilding with esbuild...
|
|
6
9
|
|
|
7
|
-
[37mdist/login/[0m[1mNLogin.js[0m
|
|
8
|
-
[37mdist/example/[0m[1mtest-helpers.js[0m
|
|
9
|
-
[37mdist/example/[0m[1museCurrentUser.js[0m
|
|
10
|
-
[37mdist/login/[0m[1mNUser.js[0m
|
|
11
|
-
[37mdist/example/[0m[1museAuthor.js[0m
|
|
12
|
-
[
|
|
13
|
-
[37mdist/login/[0m[1mNostrLoginProvider.js[0m [36m669b [0m
|
|
14
|
-
[37mdist/example/[0m[1museLoginActions.js[0m [36m560b [0m
|
|
15
|
-
[37mdist/login/[0m[1museNostrLoginReducer.js[0m [36m486b [0m
|
|
16
|
-
[37mdist/example/[0m[1museSocialFeed.js[0m [36m370b [0m
|
|
17
|
-
[37mdist/login/[0m[1museNostrLogin.js[0m [36m321b [0m
|
|
18
|
-
[37mdist/[0m[1museNostr.js[0m [36m286b [0m
|
|
19
|
-
[37mdist/login/[0m[1mmod.js[0m [36m257b [0m
|
|
20
|
-
[37mdist/[0m[1mmod.js[0m [36m163b [0m
|
|
21
|
-
[37mdist/login/[0m[1mNostrLoginContext.js[0m [36m120b [0m
|
|
22
|
-
[37mdist/[0m[1mNostrContext.js[0m [36m114b [0m
|
|
23
|
-
[37mdist/example/[0m[1mvite-env.d.js[0m [36m0b [0m
|
|
10
|
+
[37mdist/login/[0m[1mNLogin.js[0m [36m2.0kb[0m
|
|
11
|
+
[37mdist/example/[0m[1mtest-helpers.js[0m [36m1.2kb[0m
|
|
12
|
+
[37mdist/example/[0m[1museCurrentUser.js[0m [36m1.1kb[0m
|
|
13
|
+
[37mdist/login/[0m[1mNUser.js[0m [36m978b [0m
|
|
14
|
+
[37mdist/example/[0m[1museAuthor.js[0m [36m829b [0m
|
|
15
|
+
[37m...and 12 more output files...[0m
|
|
24
16
|
|
|
25
|
-
⚡ [32mDone in
|
|
17
|
+
⚡ [32mDone in 24ms[0m
|
|
18
|
+
Copying source files...
|
|
19
|
+
Done!
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# @nostrify/react
|
|
2
2
|
|
|
3
|
+
## 0.2.15
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- export js files instead of TS files
|
|
8
|
+
- Updated dependencies
|
|
9
|
+
- @nostrify/nostrify@0.46.11
|
|
10
|
+
- @nostrify/types@0.36.7
|
|
11
|
+
|
|
12
|
+
## 0.2.14
|
|
13
|
+
|
|
14
|
+
### Patch Changes
|
|
15
|
+
|
|
16
|
+
- distribute ts files
|
|
17
|
+
- Updated dependencies
|
|
18
|
+
- @nostrify/nostrify@0.46.10
|
|
19
|
+
- @nostrify/types@0.36.6
|
|
20
|
+
|
|
3
21
|
## 0.2.13
|
|
4
22
|
|
|
5
23
|
### Patch Changes
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type Context } from 'react';
|
|
2
|
+
import type { NPool } from '@nostrify/nostrify';
|
|
3
|
+
/** The shape of the Nostr context provided by NostrProvider. */
|
|
4
|
+
export interface NostrContextType {
|
|
5
|
+
/** The Nostr relay pool for querying and publishing events */
|
|
6
|
+
nostr: NPool;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* React context for Nostr functionality.
|
|
10
|
+
* Use this with useContext or the useNostr hook to access Nostr features.
|
|
11
|
+
*/
|
|
12
|
+
export declare const NostrContext: Context<NostrContextType | undefined>;
|
|
13
|
+
//# sourceMappingURL=NostrContext.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NostrContext.d.ts","sourceRoot":"","sources":["../NostrContext.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAiB,MAAM,OAAO,CAAC;AAEpD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAEhD,gEAAgE;AAChE,MAAM,WAAW,gBAAgB;IAC/B,8DAA8D;IAC9D,KAAK,EAAE,KAAK,CAAC;CACd;AAED;;;GAGG;AACH,eAAO,MAAM,YAAY,EAAE,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAE9D,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type Context, createContext } from 'react';
|
|
2
|
+
|
|
3
|
+
import type { NPool } from '@nostrify/nostrify';
|
|
4
|
+
|
|
5
|
+
/** The shape of the Nostr context provided by NostrProvider. */
|
|
6
|
+
export interface NostrContextType {
|
|
7
|
+
/** The Nostr relay pool for querying and publishing events */
|
|
8
|
+
nostr: NPool;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* React context for Nostr functionality.
|
|
13
|
+
* Use this with useContext or the useNostr hook to access Nostr features.
|
|
14
|
+
*/
|
|
15
|
+
export const NostrContext: Context<NostrContextType | undefined> = createContext<NostrContextType | undefined>(
|
|
16
|
+
undefined,
|
|
17
|
+
);
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { PropertySymbol, Window } from "happy-dom";
|
|
2
|
+
function polyfillDOM() {
|
|
3
|
+
const window = new Window();
|
|
4
|
+
const document = window.document;
|
|
5
|
+
const browserWindow = document[PropertySymbol.window];
|
|
6
|
+
const setInnerHTML = (html) => document.documentElement.innerHTML = html;
|
|
7
|
+
const cancelAsync = () => window.happyDOM.abort();
|
|
8
|
+
Object.assign(globalThis, {
|
|
9
|
+
window,
|
|
10
|
+
document,
|
|
11
|
+
HTMLElement: browserWindow.HTMLElement,
|
|
12
|
+
Element: browserWindow.Element,
|
|
13
|
+
Node: browserWindow.Node,
|
|
14
|
+
navigator: browserWindow.navigator,
|
|
15
|
+
DocumentFragment: browserWindow.DocumentFragment,
|
|
16
|
+
DocumentType: browserWindow.DocumentType,
|
|
17
|
+
SVGElement: browserWindow.SVGElement,
|
|
18
|
+
Text: browserWindow.Text,
|
|
19
|
+
requestAnimationFrame: browserWindow.requestAnimationFrame,
|
|
20
|
+
cancelAnimationFrame: browserWindow.cancelAnimationFrame,
|
|
21
|
+
setTimeout: browserWindow.setTimeout,
|
|
22
|
+
clearTimeout: browserWindow.clearTimeout,
|
|
23
|
+
setInterval: browserWindow.setInterval,
|
|
24
|
+
clearInterval: browserWindow.clearInterval,
|
|
25
|
+
queueMicrotask: browserWindow.queueMicrotask,
|
|
26
|
+
AbortController: browserWindow.AbortController,
|
|
27
|
+
cancelAsync,
|
|
28
|
+
setInnerHTML
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
export {
|
|
32
|
+
polyfillDOM
|
|
33
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { PropertySymbol, Window } from 'happy-dom';
|
|
2
|
+
|
|
3
|
+
export function polyfillDOM(): void {
|
|
4
|
+
const window = new Window();
|
|
5
|
+
const document = window.document;
|
|
6
|
+
const browserWindow = document[PropertySymbol.window];
|
|
7
|
+
|
|
8
|
+
const setInnerHTML = (html: string) => document.documentElement.innerHTML = html;
|
|
9
|
+
const cancelAsync = () => window.happyDOM.abort();
|
|
10
|
+
|
|
11
|
+
Object.assign(globalThis, {
|
|
12
|
+
window,
|
|
13
|
+
document,
|
|
14
|
+
HTMLElement: browserWindow.HTMLElement,
|
|
15
|
+
Element: browserWindow.Element,
|
|
16
|
+
Node: browserWindow.Node,
|
|
17
|
+
navigator: browserWindow.navigator,
|
|
18
|
+
DocumentFragment: browserWindow.DocumentFragment,
|
|
19
|
+
DocumentType: browserWindow.DocumentType,
|
|
20
|
+
SVGElement: browserWindow.SVGElement,
|
|
21
|
+
Text: browserWindow.Text,
|
|
22
|
+
requestAnimationFrame: browserWindow.requestAnimationFrame,
|
|
23
|
+
cancelAnimationFrame: browserWindow.cancelAnimationFrame,
|
|
24
|
+
setTimeout: browserWindow.setTimeout,
|
|
25
|
+
clearTimeout: browserWindow.clearTimeout,
|
|
26
|
+
setInterval: browserWindow.setInterval,
|
|
27
|
+
clearInterval: browserWindow.clearInterval,
|
|
28
|
+
queueMicrotask: browserWindow.queueMicrotask,
|
|
29
|
+
AbortController: browserWindow.AbortController,
|
|
30
|
+
cancelAsync,
|
|
31
|
+
setInnerHTML,
|
|
32
|
+
});
|
|
33
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { NSchema as n } from "@nostrify/nostrify";
|
|
2
|
+
import { useSuspenseQuery } from "@tanstack/react-query";
|
|
3
|
+
import { useNostr } from "../useNostr.js";
|
|
4
|
+
function useAuthor(pubkey) {
|
|
5
|
+
const { nostr } = useNostr();
|
|
6
|
+
const { data } = useSuspenseQuery({
|
|
7
|
+
queryKey: ["author", pubkey ?? ""],
|
|
8
|
+
queryFn: async ({ signal }) => {
|
|
9
|
+
if (!pubkey) {
|
|
10
|
+
return {};
|
|
11
|
+
}
|
|
12
|
+
const [event] = await nostr.query(
|
|
13
|
+
[{ kinds: [0], authors: [pubkey], limit: 1 }],
|
|
14
|
+
{ signal: AbortSignal.any([signal, AbortSignal.timeout(500)]) }
|
|
15
|
+
);
|
|
16
|
+
if (!event) {
|
|
17
|
+
return {};
|
|
18
|
+
}
|
|
19
|
+
try {
|
|
20
|
+
const metadata = n.json().pipe(n.metadata()).parse(event.content);
|
|
21
|
+
return { ...metadata, event };
|
|
22
|
+
} catch {
|
|
23
|
+
return { event };
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
return data;
|
|
28
|
+
}
|
|
29
|
+
export {
|
|
30
|
+
useAuthor
|
|
31
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { NSchema as n } from '@nostrify/nostrify';
|
|
2
|
+
import type { NostrEvent, NostrMetadata } from '@nostrify/types';
|
|
3
|
+
import { useSuspenseQuery } from '@tanstack/react-query';
|
|
4
|
+
|
|
5
|
+
import { useNostr } from '../useNostr.ts';
|
|
6
|
+
|
|
7
|
+
export function useAuthor(
|
|
8
|
+
pubkey: string | undefined,
|
|
9
|
+
): NostrMetadata & { event?: NostrEvent } {
|
|
10
|
+
const { nostr } = useNostr();
|
|
11
|
+
|
|
12
|
+
const { data } = useSuspenseQuery<NostrMetadata & { event?: NostrEvent }>({
|
|
13
|
+
queryKey: ['author', pubkey ?? ''],
|
|
14
|
+
queryFn: async ({ signal }) => {
|
|
15
|
+
if (!pubkey) {
|
|
16
|
+
return {};
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const [event] = await nostr.query(
|
|
20
|
+
[{ kinds: [0], authors: [pubkey!], limit: 1 }],
|
|
21
|
+
{ signal: AbortSignal.any([signal, AbortSignal.timeout(500)]) },
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
if (!event) {
|
|
25
|
+
return {};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
try {
|
|
29
|
+
const metadata = n.json().pipe(n.metadata()).parse(event.content);
|
|
30
|
+
return { ...metadata, event };
|
|
31
|
+
} catch {
|
|
32
|
+
return { event };
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
return data;
|
|
38
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { NUser, useNostrLogin } from "@nostrify/react/login";
|
|
2
|
+
import { useMemo } from "react";
|
|
3
|
+
import { useAuthor } from "./useAuthor.js";
|
|
4
|
+
import { useNostr } from "../useNostr.js";
|
|
5
|
+
function useCurrentUser() {
|
|
6
|
+
const { nostr } = useNostr();
|
|
7
|
+
const { logins } = useNostrLogin();
|
|
8
|
+
function loginToUser(login) {
|
|
9
|
+
switch (login.type) {
|
|
10
|
+
case "nsec":
|
|
11
|
+
return NUser.fromNsecLogin(login);
|
|
12
|
+
case "bunker":
|
|
13
|
+
return NUser.fromBunkerLogin(login, nostr);
|
|
14
|
+
case "extension":
|
|
15
|
+
return NUser.fromExtensionLogin(login);
|
|
16
|
+
default:
|
|
17
|
+
throw new Error(`Unsupported login type: ${login.type}`);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
const users = useMemo(() => {
|
|
21
|
+
const users2 = [];
|
|
22
|
+
for (const login of logins) {
|
|
23
|
+
try {
|
|
24
|
+
const user2 = loginToUser(login);
|
|
25
|
+
users2.push(user2);
|
|
26
|
+
} catch (error) {
|
|
27
|
+
console.warn("Skipped invalid login", login.id, error);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return users2;
|
|
31
|
+
}, [logins, nostr]);
|
|
32
|
+
const user = users[0];
|
|
33
|
+
const metadata = useAuthor(user?.pubkey);
|
|
34
|
+
return {
|
|
35
|
+
user,
|
|
36
|
+
users,
|
|
37
|
+
metadata
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
export {
|
|
41
|
+
useCurrentUser
|
|
42
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { type NLoginType, NUser, useNostrLogin } from '@nostrify/react/login';
|
|
2
|
+
import { useMemo } from 'react';
|
|
3
|
+
|
|
4
|
+
import { useAuthor } from './useAuthor.ts';
|
|
5
|
+
import { useNostr } from '../useNostr.ts';
|
|
6
|
+
|
|
7
|
+
export function useCurrentUser() {
|
|
8
|
+
const { nostr } = useNostr();
|
|
9
|
+
const { logins } = useNostrLogin();
|
|
10
|
+
|
|
11
|
+
function loginToUser(login: NLoginType): NUser {
|
|
12
|
+
switch (login.type) {
|
|
13
|
+
case 'nsec':
|
|
14
|
+
return NUser.fromNsecLogin(login);
|
|
15
|
+
case 'bunker':
|
|
16
|
+
return NUser.fromBunkerLogin(login, nostr);
|
|
17
|
+
case 'extension':
|
|
18
|
+
return NUser.fromExtensionLogin(login);
|
|
19
|
+
default:
|
|
20
|
+
// Learn how to define other login types: https://nostrify.dev/react/logins#custom-login-types
|
|
21
|
+
throw new Error(`Unsupported login type: ${login.type}`);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const users = useMemo(() => {
|
|
26
|
+
const users: NUser[] = [];
|
|
27
|
+
|
|
28
|
+
for (const login of logins) {
|
|
29
|
+
try {
|
|
30
|
+
const user = loginToUser(login);
|
|
31
|
+
users.push(user);
|
|
32
|
+
} catch (error) {
|
|
33
|
+
console.warn('Skipped invalid login', login.id, error);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return users;
|
|
38
|
+
}, [logins, nostr]);
|
|
39
|
+
|
|
40
|
+
const user: NUser | undefined = users[0];
|
|
41
|
+
const metadata = useAuthor(user?.pubkey);
|
|
42
|
+
|
|
43
|
+
return {
|
|
44
|
+
user,
|
|
45
|
+
users,
|
|
46
|
+
metadata,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { useNostr } from "@nostrify/react";
|
|
2
|
+
import { NLogin, useNostrLogin } from "@nostrify/react/login";
|
|
3
|
+
function useLoginActions() {
|
|
4
|
+
const { nostr } = useNostr();
|
|
5
|
+
const { addLogin } = useNostrLogin();
|
|
6
|
+
return {
|
|
7
|
+
nsec(nsec) {
|
|
8
|
+
const login = NLogin.fromNsec(nsec);
|
|
9
|
+
addLogin(login);
|
|
10
|
+
},
|
|
11
|
+
async bunker(uri) {
|
|
12
|
+
const login = await NLogin.fromBunker(uri, nostr);
|
|
13
|
+
addLogin(login);
|
|
14
|
+
},
|
|
15
|
+
async extension() {
|
|
16
|
+
const login = await NLogin.fromExtension();
|
|
17
|
+
addLogin(login);
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
export {
|
|
22
|
+
useLoginActions
|
|
23
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { useNostr } from '@nostrify/react';
|
|
2
|
+
import { NLogin, useNostrLogin } from '@nostrify/react/login';
|
|
3
|
+
|
|
4
|
+
export function useLoginActions() {
|
|
5
|
+
const { nostr } = useNostr();
|
|
6
|
+
const { addLogin } = useNostrLogin();
|
|
7
|
+
|
|
8
|
+
return {
|
|
9
|
+
nsec(nsec: string): void {
|
|
10
|
+
const login = NLogin.fromNsec(nsec);
|
|
11
|
+
addLogin(login);
|
|
12
|
+
},
|
|
13
|
+
async bunker(uri: string): Promise<void> {
|
|
14
|
+
const login = await NLogin.fromBunker(uri, nostr);
|
|
15
|
+
addLogin(login);
|
|
16
|
+
},
|
|
17
|
+
async extension(): Promise<void> {
|
|
18
|
+
const login = await NLogin.fromExtension();
|
|
19
|
+
addLogin(login);
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { useSuspenseQuery } from "@tanstack/react-query";
|
|
2
|
+
import { useNostr } from "../useNostr.js";
|
|
3
|
+
function useSocialFeed() {
|
|
4
|
+
const { nostr } = useNostr();
|
|
5
|
+
return useSuspenseQuery({
|
|
6
|
+
queryKey: ["social-feed"],
|
|
7
|
+
queryFn: () => nostr.query(
|
|
8
|
+
[{ kinds: [1], limit: 5 }],
|
|
9
|
+
{ signal: AbortSignal.timeout(5e3) }
|
|
10
|
+
)
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
export {
|
|
14
|
+
useSocialFeed
|
|
15
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { useSuspenseQuery, type UseSuspenseQueryResult } from '@tanstack/react-query';
|
|
2
|
+
|
|
3
|
+
import { useNostr } from '../useNostr.ts';
|
|
4
|
+
|
|
5
|
+
import type { NostrEvent } from '@nostrify/types';
|
|
6
|
+
|
|
7
|
+
export function useSocialFeed(): UseSuspenseQueryResult<NostrEvent[]> {
|
|
8
|
+
const { nostr } = useNostr();
|
|
9
|
+
|
|
10
|
+
return useSuspenseQuery({
|
|
11
|
+
queryKey: ['social-feed'],
|
|
12
|
+
queryFn: () =>
|
|
13
|
+
nostr.query(
|
|
14
|
+
[{ kinds: [1], limit: 5 }],
|
|
15
|
+
{ signal: AbortSignal.timeout(5000) },
|
|
16
|
+
),
|
|
17
|
+
});
|
|
18
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/// <reference types="vite/client" />
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { NPool } from '@nostrify/nostrify';
|
|
2
|
+
/** An object represeting any supported Nostr login credentials. */
|
|
3
|
+
export type NLoginType = NLoginNsec | NLoginBunker | NLoginExtension | NLoginOther;
|
|
4
|
+
/** Nostr login with nsec. */
|
|
5
|
+
export type NLoginNsec = NLoginBase<'nsec', {
|
|
6
|
+
nsec: `nsec1${string}`;
|
|
7
|
+
}>;
|
|
8
|
+
/** NIP-46 (aka remote signer) login. */
|
|
9
|
+
export type NLoginBunker = NLoginBase<'bunker', {
|
|
10
|
+
bunkerPubkey: string;
|
|
11
|
+
clientNsec: `nsec1${string}`;
|
|
12
|
+
relays: string[];
|
|
13
|
+
}>;
|
|
14
|
+
/** NIP-07 (browser extension) login. */
|
|
15
|
+
export type NLoginExtension = NLoginBase<'extension', null>;
|
|
16
|
+
/** Additional login types created by the library user. */
|
|
17
|
+
export type NLoginOther = NLoginBase<`x-${string}`, {
|
|
18
|
+
[key: string]: unknown;
|
|
19
|
+
}>;
|
|
20
|
+
/** Base properties shared by Nostr login objects. */
|
|
21
|
+
interface NLoginBase<T extends string, D> {
|
|
22
|
+
id: string;
|
|
23
|
+
type: T;
|
|
24
|
+
pubkey: string;
|
|
25
|
+
createdAt: string;
|
|
26
|
+
data: D;
|
|
27
|
+
}
|
|
28
|
+
/** Class representing Nostr login credentials. */
|
|
29
|
+
export declare class NLogin<T extends string, D> implements NLoginBase<T, D> {
|
|
30
|
+
id: string;
|
|
31
|
+
type: T;
|
|
32
|
+
pubkey: string;
|
|
33
|
+
createdAt: string;
|
|
34
|
+
data: D;
|
|
35
|
+
constructor(type: T, pubkey: string, data: D);
|
|
36
|
+
/** Create a login object from an nsec. */
|
|
37
|
+
static fromNsec(nsec: string): NLoginNsec;
|
|
38
|
+
/** Create a login object from a bunker URI. */
|
|
39
|
+
static fromBunker(uri: string, pool: NPool): Promise<NLoginBunker>;
|
|
40
|
+
/** Create a login object from a browser extension. */
|
|
41
|
+
static fromExtension(): Promise<NLoginExtension>;
|
|
42
|
+
/** Convert to a JSON-serializable object. */
|
|
43
|
+
toJSON(): NLoginBase<T, D>;
|
|
44
|
+
}
|
|
45
|
+
export {};
|
|
46
|
+
//# sourceMappingURL=NLogin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NLogin.d.ts","sourceRoot":"","sources":["../../login/NLogin.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAIhD,mEAAmE;AACnE,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,YAAY,GAAG,eAAe,GAAG,WAAW,CAAC;AAEnF,6BAA6B;AAC7B,MAAM,MAAM,UAAU,GAAG,UAAU,CAAC,MAAM,EAAE;IAC1C,IAAI,EAAE,QAAQ,MAAM,EAAE,CAAC;CACxB,CAAC,CAAC;AAEH,wCAAwC;AACxC,MAAM,MAAM,YAAY,GAAG,UAAU,CAAC,QAAQ,EAAE;IAC9C,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,QAAQ,MAAM,EAAE,CAAC;IAC7B,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB,CAAC,CAAC;AAEH,wCAAwC;AACxC,MAAM,MAAM,eAAe,GAAG,UAAU,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;AAE5D,0DAA0D;AAC1D,MAAM,MAAM,WAAW,GAAG,UAAU,CAAC,KAAK,MAAM,EAAE,EAAE;IAClD,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB,CAAC,CAAC;AAEH,qDAAqD;AACrD,UAAU,UAAU,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC;IACtC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,CAAC,CAAC;IACR,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,CAAC,CAAC;CACT;AAED,kDAAkD;AAClD,qBAAa,MAAM,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,CAAE,YAAW,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC;IAC3D,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,CAAC,CAAC;IACR,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,CAAC,CAAC;gBAEH,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IAQ5C,0CAA0C;IAC1C,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU;IAezC,+CAA+C;WAClC,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,GAAG,OAAO,CAAC,YAAY,CAAC;IA4BxE,sDAAsD;WACzC,aAAa,IAAI,OAAO,CAAC,eAAe,CAAC;IAYtD,6CAA6C;IAC7C,MAAM,IAAI,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC;CAS3B"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { BunkerURI, NConnectSigner, NSecSigner } from "@nostrify/nostrify";
|
|
2
|
+
import { generateSecretKey, getPublicKey, nip19 } from "nostr-tools";
|
|
3
|
+
class NLogin {
|
|
4
|
+
id;
|
|
5
|
+
type;
|
|
6
|
+
pubkey;
|
|
7
|
+
createdAt;
|
|
8
|
+
data;
|
|
9
|
+
constructor(type, pubkey, data) {
|
|
10
|
+
this.id = `${type}:${pubkey}`;
|
|
11
|
+
this.type = type;
|
|
12
|
+
this.pubkey = pubkey;
|
|
13
|
+
this.createdAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
14
|
+
this.data = data;
|
|
15
|
+
}
|
|
16
|
+
/** Create a login object from an nsec. */
|
|
17
|
+
static fromNsec(nsec) {
|
|
18
|
+
const decoded = nip19.decode(nsec);
|
|
19
|
+
if (decoded.type !== "nsec") {
|
|
20
|
+
throw new Error("Invalid nsec");
|
|
21
|
+
}
|
|
22
|
+
const sk = decoded.data;
|
|
23
|
+
const pubkey = getPublicKey(sk);
|
|
24
|
+
return new NLogin("nsec", pubkey, {
|
|
25
|
+
nsec: nip19.nsecEncode(sk)
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
/** Create a login object from a bunker URI. */
|
|
29
|
+
static async fromBunker(uri, pool) {
|
|
30
|
+
const { pubkey: bunkerPubkey, secret, relays } = new BunkerURI(uri);
|
|
31
|
+
if (!relays.length) {
|
|
32
|
+
throw new Error("No relay provided");
|
|
33
|
+
}
|
|
34
|
+
const sk = generateSecretKey();
|
|
35
|
+
const nsec = nip19.nsecEncode(sk);
|
|
36
|
+
const clientSigner = new NSecSigner(sk);
|
|
37
|
+
const signer = new NConnectSigner({
|
|
38
|
+
relay: pool.group(relays),
|
|
39
|
+
pubkey: bunkerPubkey,
|
|
40
|
+
signer: clientSigner,
|
|
41
|
+
timeout: 6e4
|
|
42
|
+
});
|
|
43
|
+
await signer.connect(secret);
|
|
44
|
+
const pubkey = await signer.getPublicKey();
|
|
45
|
+
return new NLogin("bunker", pubkey, {
|
|
46
|
+
bunkerPubkey,
|
|
47
|
+
clientNsec: nsec,
|
|
48
|
+
relays
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
/** Create a login object from a browser extension. */
|
|
52
|
+
static async fromExtension() {
|
|
53
|
+
const windowSigner = globalThis.nostr;
|
|
54
|
+
if (!windowSigner) {
|
|
55
|
+
throw new Error("Nostr extension is not available");
|
|
56
|
+
}
|
|
57
|
+
const pubkey = await windowSigner.getPublicKey();
|
|
58
|
+
return new NLogin("extension", pubkey, null);
|
|
59
|
+
}
|
|
60
|
+
/** Convert to a JSON-serializable object. */
|
|
61
|
+
toJSON() {
|
|
62
|
+
return {
|
|
63
|
+
id: this.id,
|
|
64
|
+
type: this.type,
|
|
65
|
+
pubkey: this.pubkey,
|
|
66
|
+
createdAt: this.createdAt,
|
|
67
|
+
data: this.data
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
export {
|
|
72
|
+
NLogin
|
|
73
|
+
};
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { BunkerURI, NConnectSigner, NSecSigner } from '@nostrify/nostrify';
|
|
2
|
+
import type { NPool } from '@nostrify/nostrify';
|
|
3
|
+
import { generateSecretKey, getPublicKey, nip19 } from 'nostr-tools';
|
|
4
|
+
import type { NostrSigner } from '@nostrify/types';
|
|
5
|
+
|
|
6
|
+
/** An object represeting any supported Nostr login credentials. */
|
|
7
|
+
export type NLoginType = NLoginNsec | NLoginBunker | NLoginExtension | NLoginOther;
|
|
8
|
+
|
|
9
|
+
/** Nostr login with nsec. */
|
|
10
|
+
export type NLoginNsec = NLoginBase<'nsec', {
|
|
11
|
+
nsec: `nsec1${string}`;
|
|
12
|
+
}>;
|
|
13
|
+
|
|
14
|
+
/** NIP-46 (aka remote signer) login. */
|
|
15
|
+
export type NLoginBunker = NLoginBase<'bunker', {
|
|
16
|
+
bunkerPubkey: string;
|
|
17
|
+
clientNsec: `nsec1${string}`;
|
|
18
|
+
relays: string[];
|
|
19
|
+
}>;
|
|
20
|
+
|
|
21
|
+
/** NIP-07 (browser extension) login. */
|
|
22
|
+
export type NLoginExtension = NLoginBase<'extension', null>;
|
|
23
|
+
|
|
24
|
+
/** Additional login types created by the library user. */
|
|
25
|
+
export type NLoginOther = NLoginBase<`x-${string}`, {
|
|
26
|
+
[key: string]: unknown;
|
|
27
|
+
}>;
|
|
28
|
+
|
|
29
|
+
/** Base properties shared by Nostr login objects. */
|
|
30
|
+
interface NLoginBase<T extends string, D> {
|
|
31
|
+
id: string;
|
|
32
|
+
type: T;
|
|
33
|
+
pubkey: string;
|
|
34
|
+
createdAt: string;
|
|
35
|
+
data: D;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** Class representing Nostr login credentials. */
|
|
39
|
+
export class NLogin<T extends string, D> implements NLoginBase<T, D> {
|
|
40
|
+
public id: string;
|
|
41
|
+
public type: T;
|
|
42
|
+
public pubkey: string;
|
|
43
|
+
public createdAt: string;
|
|
44
|
+
public data: D;
|
|
45
|
+
|
|
46
|
+
constructor(type: T, pubkey: string, data: D) {
|
|
47
|
+
this.id = `${type}:${pubkey}`;
|
|
48
|
+
this.type = type;
|
|
49
|
+
this.pubkey = pubkey;
|
|
50
|
+
this.createdAt = new Date().toISOString();
|
|
51
|
+
this.data = data;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** Create a login object from an nsec. */
|
|
55
|
+
static fromNsec(nsec: string): NLoginNsec {
|
|
56
|
+
const decoded = nip19.decode(nsec);
|
|
57
|
+
|
|
58
|
+
if (decoded.type !== 'nsec') {
|
|
59
|
+
throw new Error('Invalid nsec');
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const sk = decoded.data;
|
|
63
|
+
const pubkey = getPublicKey(sk);
|
|
64
|
+
|
|
65
|
+
return new NLogin('nsec', pubkey, {
|
|
66
|
+
nsec: nip19.nsecEncode(sk),
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/** Create a login object from a bunker URI. */
|
|
71
|
+
static async fromBunker(uri: string, pool: NPool): Promise<NLoginBunker> {
|
|
72
|
+
const { pubkey: bunkerPubkey, secret, relays } = new BunkerURI(uri);
|
|
73
|
+
|
|
74
|
+
if (!relays.length) {
|
|
75
|
+
throw new Error('No relay provided');
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const sk = generateSecretKey();
|
|
79
|
+
const nsec = nip19.nsecEncode(sk);
|
|
80
|
+
const clientSigner = new NSecSigner(sk);
|
|
81
|
+
|
|
82
|
+
const signer = new NConnectSigner({
|
|
83
|
+
relay: pool.group(relays),
|
|
84
|
+
pubkey: bunkerPubkey,
|
|
85
|
+
signer: clientSigner,
|
|
86
|
+
timeout: 60_000,
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
await signer.connect(secret);
|
|
90
|
+
const pubkey = await signer.getPublicKey();
|
|
91
|
+
|
|
92
|
+
return new NLogin('bunker', pubkey, {
|
|
93
|
+
bunkerPubkey,
|
|
94
|
+
clientNsec: nsec,
|
|
95
|
+
relays,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/** Create a login object from a browser extension. */
|
|
100
|
+
static async fromExtension(): Promise<NLoginExtension> {
|
|
101
|
+
const windowSigner = (globalThis as unknown as { nostr?: NostrSigner }).nostr;
|
|
102
|
+
|
|
103
|
+
if (!windowSigner) {
|
|
104
|
+
throw new Error('Nostr extension is not available');
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const pubkey = await windowSigner.getPublicKey();
|
|
108
|
+
|
|
109
|
+
return new NLogin('extension', pubkey, null);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/** Convert to a JSON-serializable object. */
|
|
113
|
+
toJSON(): NLoginBase<T, D> {
|
|
114
|
+
return {
|
|
115
|
+
id: this.id,
|
|
116
|
+
type: this.type,
|
|
117
|
+
pubkey: this.pubkey,
|
|
118
|
+
createdAt: this.createdAt,
|
|
119
|
+
data: this.data,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
}
|