nostr-components 0.2.0

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.
Files changed (132) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +334 -0
  3. package/dist/assets/base-styles-CBypR3FR.js +145 -0
  4. package/dist/assets/base-styles-CBypR3FR.js.map +1 -0
  5. package/dist/assets/copy-delegation-C4uvRTVM.js +15 -0
  6. package/dist/assets/copy-delegation-C4uvRTVM.js.map +1 -0
  7. package/dist/assets/dialog-component-Dqg0QU9I.js +66 -0
  8. package/dist/assets/dialog-component-Dqg0QU9I.js.map +1 -0
  9. package/dist/assets/dialog-likers-BzTesCZa.js +238 -0
  10. package/dist/assets/dialog-likers-BzTesCZa.js.map +1 -0
  11. package/dist/assets/icons-Dr_d9MII.js +105 -0
  12. package/dist/assets/icons-Dr_d9MII.js.map +1 -0
  13. package/dist/assets/nip05-utils-BNBHUmkr.js +2 -0
  14. package/dist/assets/nip05-utils-BNBHUmkr.js.map +1 -0
  15. package/dist/assets/nostr-service-pr_crY62.js +78 -0
  16. package/dist/assets/nostr-service-pr_crY62.js.map +1 -0
  17. package/dist/assets/nostr-user-component-Q7GeeFyu.js +2 -0
  18. package/dist/assets/nostr-user-component-Q7GeeFyu.js.map +1 -0
  19. package/dist/assets/preload-helper-D7HrI6pR.js +2 -0
  20. package/dist/assets/preload-helper-D7HrI6pR.js.map +1 -0
  21. package/dist/assets/pure-jrVhRVpB.js +2 -0
  22. package/dist/assets/pure-jrVhRVpB.js.map +1 -0
  23. package/dist/assets/theme-C1r1Zw8r.js +2 -0
  24. package/dist/assets/theme-C1r1Zw8r.js.map +1 -0
  25. package/dist/assets/user-resolver-C-E6KdwY.js +2 -0
  26. package/dist/assets/user-resolver-C-E6KdwY.js.map +1 -0
  27. package/dist/assets/utils--bxLbhGF.js +2 -0
  28. package/dist/assets/utils--bxLbhGF.js.map +1 -0
  29. package/dist/assets/zap-utils-B1sz0Abx.js +2 -0
  30. package/dist/assets/zap-utils-B1sz0Abx.js.map +1 -0
  31. package/dist/components/nostr-comment.es.js +924 -0
  32. package/dist/components/nostr-comment.es.js.map +1 -0
  33. package/dist/components/nostr-dm.es.js +217 -0
  34. package/dist/components/nostr-dm.es.js.map +1 -0
  35. package/dist/components/nostr-follow-button.es.js +103 -0
  36. package/dist/components/nostr-follow-button.es.js.map +1 -0
  37. package/dist/components/nostr-like.es.js +296 -0
  38. package/dist/components/nostr-like.es.js.map +1 -0
  39. package/dist/components/nostr-live-chat.es.js +523 -0
  40. package/dist/components/nostr-live-chat.es.js.map +1 -0
  41. package/dist/components/nostr-post.es.js +441 -0
  42. package/dist/components/nostr-post.es.js.map +1 -0
  43. package/dist/components/nostr-profile-badge.es.js +100 -0
  44. package/dist/components/nostr-profile-badge.es.js.map +1 -0
  45. package/dist/components/nostr-profile.es.js +287 -0
  46. package/dist/components/nostr-profile.es.js.map +1 -0
  47. package/dist/components/nostr-zap.es.js +694 -0
  48. package/dist/components/nostr-zap.es.js.map +1 -0
  49. package/dist/index.d.ts +2 -0
  50. package/dist/nostr-comment.d.ts +4 -0
  51. package/dist/nostr-components.es.js +2 -0
  52. package/dist/nostr-components.es.js.map +1 -0
  53. package/dist/nostr-components.umd.js +4200 -0
  54. package/dist/nostr-components.umd.js.map +1 -0
  55. package/dist/nostr-dm.d.ts +4 -0
  56. package/dist/nostr-follow-button.d.ts +4 -0
  57. package/dist/nostr-like.d.ts +4 -0
  58. package/dist/nostr-live-chat.d.ts +4 -0
  59. package/dist/nostr-post.d.ts +4 -0
  60. package/dist/nostr-profile-badge.d.ts +4 -0
  61. package/dist/nostr-profile.d.ts +4 -0
  62. package/dist/nostr-zap.d.ts +4 -0
  63. package/dist/src/base/base-component/nostr-base-component.d.ts +116 -0
  64. package/dist/src/base/copy-delegation.d.ts +5 -0
  65. package/dist/src/base/dialog-component/dialog-component.d.ts +67 -0
  66. package/dist/src/base/dialog-component/style.d.ts +5 -0
  67. package/dist/src/base/event-component/nostr-event-component.d.ts +53 -0
  68. package/dist/src/base/render-options.d.ts +5 -0
  69. package/dist/src/base/resolvers/event-resolver.d.ts +20 -0
  70. package/dist/src/base/resolvers/user-resolver.d.ts +19 -0
  71. package/dist/src/base/text-row/render-name.d.ts +7 -0
  72. package/dist/src/base/text-row/render-nip05.d.ts +1 -0
  73. package/dist/src/base/text-row/render-npub.d.ts +1 -0
  74. package/dist/src/base/text-row/render-text-row.d.ts +9 -0
  75. package/dist/src/base/user-component/nostr-user-component.d.ts +43 -0
  76. package/dist/src/common/base-styles.d.ts +44 -0
  77. package/dist/src/common/constants.d.ts +4 -0
  78. package/dist/src/common/date-utils.d.ts +9 -0
  79. package/dist/src/common/icons.d.ts +7 -0
  80. package/dist/src/common/nip05-utils.d.ts +13 -0
  81. package/dist/src/common/nostr-service.d.ts +40 -0
  82. package/dist/src/common/theme.d.ts +4 -0
  83. package/dist/src/common/types.d.ts +1 -0
  84. package/dist/src/common/utils.d.ts +34 -0
  85. package/dist/src/index.d.ts +10 -0
  86. package/dist/src/nostr-comment/nostr-comment.d.ts +60 -0
  87. package/dist/src/nostr-comment/render.d.ts +15 -0
  88. package/dist/src/nostr-comment/utils.d.ts +81 -0
  89. package/dist/src/nostr-dm/nostr-dm.d.ts +34 -0
  90. package/dist/src/nostr-dm/render.d.ts +15 -0
  91. package/dist/src/nostr-follow-button/nostr-follow-button.d.ts +24 -0
  92. package/dist/src/nostr-follow-button/render.d.ts +11 -0
  93. package/dist/src/nostr-follow-button/style.d.ts +1 -0
  94. package/dist/src/nostr-like/dialog-help-style.d.ts +1 -0
  95. package/dist/src/nostr-like/dialog-help.d.ts +2 -0
  96. package/dist/src/nostr-like/dialog-likers-style.d.ts +1 -0
  97. package/dist/src/nostr-like/dialog-likers.d.ts +24 -0
  98. package/dist/src/nostr-like/like-utils.d.ts +52 -0
  99. package/dist/src/nostr-like/nostr-like.d.ts +49 -0
  100. package/dist/src/nostr-like/render.d.ts +10 -0
  101. package/dist/src/nostr-like/style.d.ts +1 -0
  102. package/dist/src/nostr-live-chat/nostr-live-chat.d.ts +65 -0
  103. package/dist/src/nostr-live-chat/render.d.ts +31 -0
  104. package/dist/src/nostr-post/nostr-post.d.ts +25 -0
  105. package/dist/src/nostr-post/parse-text.d.ts +8 -0
  106. package/dist/src/nostr-post/render-content.d.ts +5 -0
  107. package/dist/src/nostr-post/render.d.ts +19 -0
  108. package/dist/src/nostr-post/style.d.ts +1 -0
  109. package/dist/src/nostr-profile/nostr-profile.d.ts +24 -0
  110. package/dist/src/nostr-profile/render-stats.d.ts +1 -0
  111. package/dist/src/nostr-profile/render.d.ts +22 -0
  112. package/dist/src/nostr-profile/style.d.ts +1 -0
  113. package/dist/src/nostr-profile-badge/nostr-profile-badge.d.ts +34 -0
  114. package/dist/src/nostr-profile-badge/render.d.ts +11 -0
  115. package/dist/src/nostr-profile-badge/style.d.ts +1 -0
  116. package/dist/src/nostr-zap/dialog-help-style.d.ts +5 -0
  117. package/dist/src/nostr-zap/dialog-help.d.ts +2 -0
  118. package/dist/src/nostr-zap/dialog-zap-style.d.ts +6 -0
  119. package/dist/src/nostr-zap/dialog-zap.d.ts +31 -0
  120. package/dist/src/nostr-zap/dialog-zappers-style.d.ts +1 -0
  121. package/dist/src/nostr-zap/dialog-zappers.d.ts +25 -0
  122. package/dist/src/nostr-zap/nostr-zap.d.ts +45 -0
  123. package/dist/src/nostr-zap/render.d.ts +9 -0
  124. package/dist/src/nostr-zap/style.d.ts +1 -0
  125. package/dist/src/nostr-zap/zap-utils.d.ts +53 -0
  126. package/dist/themes/dark.css +10 -0
  127. package/dist/themes/light.css +10 -0
  128. package/dist/themes.css +52 -0
  129. package/dist/vite.config.d.ts +2 -0
  130. package/dist/vite.config.esm.d.ts +2 -0
  131. package/dist/vite.config.umd.d.ts +2 -0
  132. package/package.json +95 -0
@@ -0,0 +1,4 @@
1
+ export {}
2
+ import _default from './src/nostr-dm/nostr-dm'
3
+ export default _default
4
+ export {}
@@ -0,0 +1,4 @@
1
+ export {}
2
+ import _default from './src/nostr-follow-button/nostr-follow-button'
3
+ export default _default
4
+ export {}
@@ -0,0 +1,4 @@
1
+ export {}
2
+ import _default from './src/nostr-like/nostr-like'
3
+ export default _default
4
+ export {}
@@ -0,0 +1,4 @@
1
+ export {}
2
+ import _default from './src/nostr-live-chat/nostr-live-chat'
3
+ export default _default
4
+ export {}
@@ -0,0 +1,4 @@
1
+ export {}
2
+ import _default from './src/nostr-post/nostr-post'
3
+ export default _default
4
+ export {}
@@ -0,0 +1,4 @@
1
+ export {}
2
+ import _default from './src/nostr-profile-badge/nostr-profile-badge'
3
+ export default _default
4
+ export {}
@@ -0,0 +1,4 @@
1
+ export {}
2
+ import _default from './src/nostr-profile/nostr-profile'
3
+ export default _default
4
+ export {}
@@ -0,0 +1,4 @@
1
+ export {}
2
+ import _default from './src/nostr-zap/nostr-zap'
3
+ export default _default
4
+ export {}
@@ -0,0 +1,116 @@
1
+ import { NostrService } from '../../common/nostr-service';
2
+ import { Theme } from '../../common/types';
3
+ export declare enum NCStatus {
4
+ Idle = 0,// 0
5
+ Loading = 1,// 1
6
+ Ready = 2,// 2
7
+ Error = 3
8
+ }
9
+ /**
10
+ * NostrBaseComponent
11
+ * ==================
12
+ * Foundation for all Nostr web components in this library.
13
+ *
14
+ * Overview
15
+ * - Manages relay connectivity via a shared `NostrService`.
16
+ * - Parses common attributes (`theme`, `relays`) and applies theme.
17
+ * - Provides a generic status management logic, that is extensible by derived classes.
18
+ * - Offers small utilities useful to subclasses (event delegation, error snippet).
19
+ *
20
+ * Observed attributes
21
+ * - `data-theme` — "light" | "dark"
22
+ * - `relays` — CSV of relay URLs
23
+ *
24
+ * Events
25
+ * - `nc:status` — from base, reflects connection and user/profile loading status
26
+ *
27
+ * TODO: Is this class doing too much work? Time to split into smaller components?
28
+ */
29
+ export declare abstract class NostrBaseComponent extends HTMLElement {
30
+ protected nostrService: NostrService;
31
+ protected theme: Theme;
32
+ protected errorMessage: string;
33
+ protected nostrReady: Promise<void>;
34
+ protected nostrReadyResolve?: () => void;
35
+ protected nostrReadyReject?: (e: unknown) => void;
36
+ protected conn: {
37
+ set: (s: NCStatus, e?: string) => void;
38
+ get: () => NCStatus;
39
+ };
40
+ private _statuses;
41
+ private _overall;
42
+ private connectSeq;
43
+ constructor(shadow?: boolean);
44
+ /** Lifecycle methods */
45
+ static get observedAttributes(): string[];
46
+ connectedCallback(): void;
47
+ disconnectedCallback(): void;
48
+ attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
49
+ /** Status map API */
50
+ protected setStatusFor(key: string, next: NCStatus, error?: string): void;
51
+ protected getStatusFor(key: string): NCStatus;
52
+ protected snapshotStatuses(): Record<string, NCStatus>;
53
+ /** Overall status change hook */
54
+ protected onStatusChange(_overall: NCStatus): void;
55
+ /** Hook for subclasses to react when relays are connected */
56
+ protected onNostrRelaysConnected(): void;
57
+ protected computeOverall(): NCStatus;
58
+ /**
59
+ * Before first channel.set(), the map won't be set and hence get() will return `idle`.
60
+ * In some cases (or maybe in all cases), this is not ideal.
61
+ * In UserComponent, 'user' not set and hence returning `idle`, while
62
+ * 'connect' switched between idle -> loading -> ready
63
+ * and then
64
+ * 'user' switches to loading -> ready,
65
+ * results in loading -> ready -> loading -> ready in profile-badge onStatusChange.
66
+ *
67
+ * To avoid this, this function is called from UserComponent constructor,
68
+ * to set default value as 'loading' without emitting onStatusChange event.
69
+ *
70
+ * Makes sense?
71
+ * Try commenting this function call in UserComponent()
72
+ * and add a log in ProfileBadge :: onStatusChange. You will get it.
73
+ */
74
+ protected initChannelStatus(key: string, status: NCStatus, opts?: {
75
+ reflectOverall: boolean;
76
+ }): void;
77
+ protected channel(key: string): {
78
+ set: (s: NCStatus, e?: string) => void;
79
+ get: () => NCStatus;
80
+ };
81
+ /** Protected methods */
82
+ protected validateInputs(): boolean;
83
+ protected connectToNostr(): Promise<void>;
84
+ protected ensureNostrConnected(): Promise<void>;
85
+ protected getRelays(): string[];
86
+ protected getTheme(): void;
87
+ /**
88
+ * Delegate events within shadow DOM.
89
+ * Example: this.delegateEvent('click', '#npub-copy', (e) => this.copyNpub(e));
90
+ */
91
+ protected delegateEvent<K extends keyof HTMLElementEventMap>(type: K, selector: string, handler: (event: HTMLElementEventMap[K]) => void): void;
92
+ protected addDelegatedListener<K extends keyof HTMLElementEventMap>(type: K, selector: string, handler: (event: HTMLElementEventMap[K]) => void): void;
93
+ protected renderError(errorMessage: string): string;
94
+ /**
95
+ * Updates host element classes based on component status
96
+ * This is a common pattern used by all components
97
+ */
98
+ protected updateHostClasses(): void;
99
+ /**
100
+ * Base render method that handles common render logic
101
+ * Subclasses should override renderContent() instead of render()
102
+ */
103
+ protected render(): void;
104
+ /**
105
+ * Handles click events with njump.me default action
106
+ * Creates custom event, dispatches it, and opens njump.me if not prevented
107
+ */
108
+ protected handleNjumpClick(eventType: string, detail: any, njumpPath: string): void;
109
+ /**
110
+ * Abstract method for component-specific rendering
111
+ * Must be implemented by subclasses
112
+ */
113
+ protected abstract renderContent(): void;
114
+ /** Private methods */
115
+ private resetNostrReadyBarrier;
116
+ }
@@ -0,0 +1,5 @@
1
+ interface DelegatedHost {
2
+ addDelegatedListener(type: string, selector: string, handler: (e: Event) => void): void;
3
+ }
4
+ export declare function attachCopyDelegation(host: DelegatedHost): void;
5
+ export {};
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Base dialog component that extends HTMLElement
3
+ * Provides common dialog functionality with header, close button, and content area
4
+ *
5
+ * Usage:
6
+ * ```typescript
7
+ * const dialog = document.createElement('dialog-component');
8
+ * dialog.setAttribute('header', 'Dialog Title');
9
+ * dialog.innerHTML = '<p>Your content goes here</p>';
10
+ * dialog.showModal(); // Don't append to body, just call showModal()
11
+ * ```
12
+ *
13
+ * Features:
14
+ * - Header with customizable text
15
+ * - Close button
16
+ * - Click outside to close
17
+ * - ESC key to close
18
+ * - Automatic cleanup on close
19
+ *
20
+ * Important: Only one instance of this component should be added to the DOM at any time.
21
+ * Multiple instances may cause conflicts with event listeners and cleanup behavior.
22
+ */
23
+ export declare class DialogComponent extends HTMLElement {
24
+ private dialog;
25
+ constructor();
26
+ /**
27
+ * Observed attributes for the component
28
+ */
29
+ static get observedAttributes(): string[];
30
+ /**
31
+ * Inject dialog styles into document head
32
+ * Prevents duplicate injection by checking for existing styles
33
+ */
34
+ private injectStyles;
35
+ /**
36
+ * Render the dialog
37
+ */
38
+ private render;
39
+ /**
40
+ * Setup event listeners for closing the dialog
41
+ */
42
+ private setupEventListeners;
43
+ /**
44
+ * Show the dialog (alias for showModal)
45
+ */
46
+ show(): void;
47
+ /**
48
+ * Show the dialog as modal
49
+ */
50
+ showModal(): void;
51
+ /**
52
+ * Close the dialog
53
+ */
54
+ close(): void;
55
+ /**
56
+ * Cleanup when dialog is closed
57
+ */
58
+ private cleanup;
59
+ /**
60
+ * Called when component is removed from DOM
61
+ */
62
+ disconnectedCallback(): void;
63
+ /**
64
+ * Called when observed attributes change
65
+ */
66
+ attributeChangedCallback(name: string, _oldValue: string, newValue: string): void;
67
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Base dialog component styles
3
+ * Provides common styling for all dialog components
4
+ */
5
+ export declare const getDialogComponentStyles: () => string;
@@ -0,0 +1,53 @@
1
+ import { NDKEvent, NDKUser, NDKUserProfile } from '@nostr-dev-kit/ndk';
2
+ import { NostrBaseComponent, NCStatus } from '../base-component/nostr-base-component';
3
+ /**
4
+ * NostrEventComponent
5
+ * ==================
6
+ * Extension of `NostrBaseComponent` that resolves and manages a Nostr Event.
7
+ *
8
+ * Overview
9
+ * - Accepts identity attributes (`hex`, `noteid`, or `eventid`) and validates them.
10
+ * - Resolves an `NDKEvent` via the shared `nostrService` and fetches the event.
11
+ * - Exposes resolved `event` to subclasses for rendering or logic.
12
+ * - Emits lifecycle events for status and event readiness.
13
+ *
14
+ * Observed attributes
15
+ * - `hex` — raw hex-encoded event ID
16
+ * - `noteid` — bech32-encoded event ID starting with 'note1...'
17
+ * - `eventid` — bech32-encoded event pointer starting with 'nevent1...' (encodes extra metadata)
18
+ *
19
+ * Events
20
+ * - `nc:status` — from base, reflects connection and event loading status
21
+ * - `nc:event` — fired when an event is successfully resolved
22
+ */
23
+ export declare class NostrEventComponent extends NostrBaseComponent {
24
+ protected event: NDKEvent | null;
25
+ protected author: NDKUser | null;
26
+ protected authorProfile: NDKUserProfile | null;
27
+ protected formattedDate: string;
28
+ protected eventStatus: {
29
+ set: (s: NCStatus, e?: string) => void;
30
+ get: () => NCStatus;
31
+ };
32
+ protected authorStatus: {
33
+ set: (s: NCStatus, e?: string) => void;
34
+ get: () => NCStatus;
35
+ };
36
+ private loadSeq;
37
+ private eventResolver;
38
+ private userResolver;
39
+ constructor(shadow?: boolean);
40
+ /** Lifecycle methods */
41
+ static get observedAttributes(): string[];
42
+ connectedCallback(): void;
43
+ attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
44
+ /** Protected methods */
45
+ protected validateInputs(): boolean;
46
+ protected resolveEventAndLoad(): Promise<void>;
47
+ private loadAuthorProfile;
48
+ private checkEventAndAuthorReady;
49
+ private formatEventDate;
50
+ protected renderContent(): void;
51
+ /** Hook for subclasses to react when event is ready (e.g., render). */
52
+ protected onEventReady(_event: NDKEvent): void;
53
+ }
@@ -0,0 +1,5 @@
1
+ export interface IRenderOptions {
2
+ isLoading: boolean;
3
+ isError: boolean;
4
+ errorMessage?: string;
5
+ }
@@ -0,0 +1,20 @@
1
+ import { NDKEvent } from '@nostr-dev-kit/ndk';
2
+ import { NostrService } from '../../common/nostr-service';
3
+ export declare class EventResolver {
4
+ private nostrService;
5
+ constructor(nostrService: NostrService);
6
+ validateInputs({ hex, noteid, eventid }: {
7
+ hex?: string | null;
8
+ noteid?: string | null;
9
+ eventid?: string | null;
10
+ }): string | null;
11
+ /**
12
+ * Normalize bech32 identifiers to hex format
13
+ */
14
+ private normalizeToHex;
15
+ resolveEvent({ hex, noteid, eventid }: {
16
+ hex?: string | null;
17
+ noteid?: string | null;
18
+ eventid?: string | null;
19
+ }): Promise<NDKEvent>;
20
+ }
@@ -0,0 +1,19 @@
1
+ import { NDKUser, NDKUserProfile } from '@nostr-dev-kit/ndk';
2
+ import { NostrService } from '../../common/nostr-service';
3
+ export declare class UserResolver {
4
+ private nostrService;
5
+ constructor(nostrService: NostrService);
6
+ validateInputs({ npub, pubkey, nip05 }: {
7
+ npub?: string | null;
8
+ pubkey?: string | null;
9
+ nip05?: string | null;
10
+ }): string | null;
11
+ resolveUser({ npub, pubkey, nip05 }: {
12
+ npub?: string | null;
13
+ pubkey?: string | null;
14
+ nip05?: string | null;
15
+ }): Promise<{
16
+ user: NDKUser;
17
+ profile: NDKUserProfile | null;
18
+ }>;
19
+ }
@@ -0,0 +1,7 @@
1
+ export interface RenderNameOptions {
2
+ name: string;
3
+ className?: string;
4
+ title?: string;
5
+ showCopyButton?: boolean;
6
+ }
7
+ export declare function renderName(options: RenderNameOptions): string;
@@ -0,0 +1 @@
1
+ export declare function renderNip05(nip05: string): string;
@@ -0,0 +1 @@
1
+ export declare function renderNpub(npub: string): string;
@@ -0,0 +1,9 @@
1
+ export interface TextRowOptions {
2
+ value: string;
3
+ display?: string;
4
+ className?: string;
5
+ monospace?: boolean;
6
+ title?: string;
7
+ showCopyButton?: boolean;
8
+ }
9
+ export declare function renderTextRow(opts: TextRowOptions): string;
@@ -0,0 +1,43 @@
1
+ import { NDKUser, NDKUserProfile } from '@nostr-dev-kit/ndk';
2
+ import { NostrBaseComponent, NCStatus } from '../base-component/nostr-base-component';
3
+ /**
4
+ * NostrUserComponent
5
+ * ==================
6
+ * Extension of `NostrBaseComponent` that resolves and manages a Nostr user.
7
+ *
8
+ * Overview
9
+ * - Accepts identity attributes (`npub`, `nip05`, or `pubkey`) and validates them.
10
+ * - Resolves an `NDKUser` via the shared `nostrService` and fetches its profile.
11
+ * - Exposes resolved `user` and `profile` to subclasses for rendering or logic.
12
+ * - Emits lifecycle events for status and user readiness.
13
+ *
14
+ * Observed attributes
15
+ * - `npub` — user's Nostr public key (bech32 npub)
16
+ * - `nip05` — NIP-05 identifier (e.g. `alice@example.com`)
17
+ * - `pubkey` — raw hex-encoded public key
18
+ *
19
+ * Events
20
+ * - `nc:status` — from base, reflects connection and user/profile loading status
21
+ * - `nc:user` — fired when a user and profile are successfully resolved
22
+ */
23
+ export declare class NostrUserComponent extends NostrBaseComponent {
24
+ protected user: NDKUser | null;
25
+ protected profile: NDKUserProfile | null;
26
+ protected userStatus: {
27
+ set: (s: NCStatus, e?: string) => void;
28
+ get: () => NCStatus;
29
+ };
30
+ private loadSeq;
31
+ private resolver;
32
+ constructor(shadow?: boolean);
33
+ /** Lifecycle methods */
34
+ static get observedAttributes(): string[];
35
+ connectedCallback(): void;
36
+ attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
37
+ /** Protected methods */
38
+ protected validateInputs(): boolean;
39
+ protected resolveUserAndProfile(): Promise<void>;
40
+ protected renderContent(): void;
41
+ /** Hook for subclasses to react when user/profile are ready (e.g., render). */
42
+ protected onUserReady(_user: NDKUser, _profile: NDKUserProfile | null): void;
43
+ }
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Base Styles Utility for Nostr Components
3
+ * =========================================
4
+ *
5
+ * This utility provides common base styles that can be shared across components.
6
+ * It includes design tokens, common patterns, and utility functions.
7
+ */
8
+ /**
9
+ * Generates minimal base styles for any Nostr component
10
+ * Includes only essential design tokens and base component styles
11
+ * Uses generic CSS variables that can be overridden by data-theme
12
+ */
13
+ export declare function getBaseStyles(): string;
14
+ /**
15
+ * Generates component-specific styles by combining base styles with custom styles
16
+ * Uses CSS theme variables instead of theme prop
17
+ */
18
+ export declare function getComponentStyles(customStyles: string): string;
19
+ export declare const styleUtils: {
20
+ /**
21
+ * Generates error state styles
22
+ */
23
+ error: () => string;
24
+ /**
25
+ * Generates skeleton loading styles
26
+ */
27
+ skeleton: () => string;
28
+ /**
29
+ * Generates copy button styles
30
+ */
31
+ copyButton: () => string;
32
+ /**
33
+ * Generates profile name styles
34
+ */
35
+ profileName: () => string;
36
+ /**
37
+ * Generates text row styles
38
+ */
39
+ textRow: () => string;
40
+ /**
41
+ * Generates error icon styles
42
+ */
43
+ errorIcon: () => string;
44
+ };
@@ -0,0 +1,4 @@
1
+ export declare const DEFAULT_RELAYS: readonly ["wss://relay.damus.io", "wss://nostr.wine", "wss://relay.nostr.net", "wss://relay.nostr.band", "wss://nos.lol", "wss://nostr-pub.wellorder.net", "wss://relay.getalby.com", "wss://relay.primal.net"];
2
+ export declare const MILLISATS_PER_SAT = 1000;
3
+ export declare const NPUB_LENGTH = 63;
4
+ export declare const DEFAULT_PROFILE_IMAGE = "./assets/default_dp.png";
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Shared date formatting utilities for Nostr components
3
+ */
4
+ /**
5
+ * Formats a Unix timestamp to a readable date string
6
+ * @param createdAt Unix timestamp in seconds
7
+ * @returns Formatted date string (e.g., "Jan 15, 2024")
8
+ */
9
+ export declare function formatEventDate(createdAt: number | undefined): string;
@@ -0,0 +1,7 @@
1
+ import { Theme } from './types';
2
+ export declare const replyIcon = "\n <svg width=\"18\" height=\"18\" fill=\"#00b3ff\">\n <path xmlns=\"http://www.w3.org/2000/svg\" d=\"M12.2197 1.65717C7.73973 1.25408 5.14439 0.940234 3.12891 2.6623C0.948817 4.52502 0.63207 7.66213 2.35603 9.88052C3.01043 10.7226 4.28767 11.9877 5.51513 13.1462C6.75696 14.3184 7.99593 15.426 8.60692 15.9671C8.61074 15.9705 8.61463 15.9739 8.61859 15.9774C8.67603 16.0283 8.74753 16.0917 8.81608 16.1433C8.89816 16.2052 9.01599 16.2819 9.17334 16.3288C9.38253 16.3912 9.60738 16.3912 9.81656 16.3288C9.97391 16.2819 10.0917 16.2052 10.1738 16.1433C10.2424 16.0917 10.3139 16.0283 10.3713 15.9774C10.3753 15.9739 10.3792 15.9705 10.383 15.9671C10.994 15.426 12.2329 14.3184 13.4748 13.1462C14.7022 11.9877 15.9795 10.7226 16.6339 9.88052C18.3512 7.67065 18.0834 4.50935 15.8532 2.65572C13.8153 0.961905 11.2476 1.25349 9.49466 2.78774Z\"/>\n </svg>\n";
3
+ export declare const heartIcon = "\n <svg width=\"18\" height=\"18\">\n <g xmlns=\"http://www.w3.org/2000/svg\">\n <path fill=\"#ff006d\" d=\"M12.2197 1.65717C7.73973 1.25408 5.14439 0.940234 3.12891 2.6623C0.948817 4.52502 0.63207 7.66213 2.35603 9.88052C3.01043 10.7226 4.28767 11.9877 5.51513 13.1462C6.75696 14.3184 7.99593 15.426 8.60692 15.9671C8.61074 15.9705 8.61463 15.9739 8.61859 15.9774C8.67603 16.0283 8.74753 16.0917 8.81608 16.1433C8.89816 16.2052 9.01599 16.2819 9.17334 16.3288C9.38253 16.3912 9.60738 16.3912 9.81656 16.3288C9.97391 16.2819 10.0917 16.2052 10.1738 16.1433C10.2424 16.0917 10.3139 16.0283 10.3713 15.9774C10.3753 15.9739 10.3792 15.9705 10.383 15.9671C10.994 15.426 12.2329 14.3184 13.4748 13.1462C14.7022 11.9877 15.9795 10.7226 16.6339 9.88052C18.3512 7.67065 18.0834 4.50935 15.8532 2.65572C13.8153 0.961905 11.2476 1.25349 9.49466 2.78774Z\"/>\n </g>\n </svg>\n";
4
+ export declare const copyIcon = "\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M16 1H4C2.9 1 2 1.9 2 3V17H4V3H16V1ZM19 5H8C6.9 5 6 5.9 6 7V21C6 22.1 6.9 23 8 23H19C20.1 23 21 22.1 21 21V7C21 5.9 20.1 5 19 5ZM19 21H8V7H19V21Z\" fill=\"currentColor\"/>\n </svg>\n";
5
+ export declare const checkmarkIcon: (theme?: Theme) => string;
6
+ export declare const nostrLogo: (width?: number, height?: number) => string;
7
+ export declare const loadingNostrich: () => string;
@@ -0,0 +1,13 @@
1
+ /**
2
+ * NIP-05 utility functions for resolving nostr identifiers
3
+ */
4
+ /**
5
+ * Resolves a NIP-05 identifier to a nostr public key
6
+ * Includes input validation and request timeout for security
7
+ *
8
+ * @param nip05 - NIP-05 identifier in format username@domain.com
9
+ * @param timeoutMs - Timeout in milliseconds (default: 5000)
10
+ * @returns Resolved public key
11
+ * @throws Error if validation fails, timeout occurs, or resolution fails
12
+ */
13
+ export declare function resolveNip05(nip05: string, timeoutMs?: number): Promise<string>;
@@ -0,0 +1,40 @@
1
+ import { default as NDK, NDKUser, NDKUserProfile, NDKEvent } from '@nostr-dev-kit/ndk';
2
+ export declare class NostrService {
3
+ private static instance;
4
+ private ndk;
5
+ private isConnected;
6
+ private constructor();
7
+ static getInstance(): NostrService;
8
+ connectToNostr(relays?: string[]): Promise<void>;
9
+ getRelays(): string[];
10
+ resolveNDKUser(identifier: {
11
+ npub?: string | null;
12
+ nip05?: string | null;
13
+ pubkey?: string | null;
14
+ }): Promise<NDKUser | null>;
15
+ resolveNDKEvent(identifier: {
16
+ hex?: string | null;
17
+ }): Promise<NDKEvent | null>;
18
+ /**
19
+ * Convenience helper to fetch zap count for a profile.
20
+ * It determines the user based on the provided identifier and
21
+ * returns the number of zap receipts found (count, **not** total sats).
22
+ */
23
+ getZapCount(identifier: {
24
+ npub?: string;
25
+ nip05?: string;
26
+ pubkey?: string;
27
+ }): Promise<number>;
28
+ getProfile(user: NDKUser | null): Promise<NDKUserProfile | null>;
29
+ getPost(eventId: string): Promise<NDKEvent | null>;
30
+ fetchFollows(user: NDKUser): Promise<number>;
31
+ fetchFollowers(user: NDKUser): Promise<number>;
32
+ fetchNotesAndReplies(user: NDKUser): Promise<[number, number]>;
33
+ fetchZaps(user: NDKUser): Promise<number>;
34
+ getNDK(): NDK;
35
+ /**
36
+ * Check if a Nostr signer is available
37
+ * @returns boolean indicating if a signer is available
38
+ */
39
+ hasSigner(): boolean;
40
+ }
@@ -0,0 +1,4 @@
1
+ import { Theme } from './types';
2
+ export declare function getNostrLogo(width?: number, height?: number): string;
3
+ export declare function getLoadingNostrich(): string;
4
+ export declare function getSuccessAnimation(theme?: Theme): string;
@@ -0,0 +1 @@
1
+ export type Theme = 'light' | 'dark' | 'ocean-glass' | 'holographic' | 'neo-matrix' | 'bitcoin-orange';
@@ -0,0 +1,34 @@
1
+ import { default as NDK } from '@nostr-dev-kit/ndk';
2
+ import { Theme } from './types';
3
+ export declare const decodeNpub: (npub: string) => string;
4
+ /**
5
+ * Convert hex pubkey to npub
6
+ */
7
+ export declare function hexToNpub(hex: string): string;
8
+ export declare const decodeNip19Entity: (entity: string) => any;
9
+ export declare function maskNPub(npubString?: string, length?: number): string;
10
+ export type Stats = {
11
+ likes: number;
12
+ reposts: number;
13
+ zaps: number;
14
+ replies: number;
15
+ };
16
+ export declare function getPostStats(ndk: NDK, postId: string): Promise<Stats>;
17
+ export declare function parseRelays(relaysAttr: string | null): string[];
18
+ export declare function parseTheme(themeAttr: string | null): Theme;
19
+ export declare function parseBooleanAttribute(attr: string | null): boolean;
20
+ export declare function escapeHtml(text: string): string;
21
+ export declare function isValidUrl(url: string): boolean;
22
+ export declare function isValidRelayUrl(url: string): boolean;
23
+ export declare function isValidHex(hex: string): boolean;
24
+ export declare function validateNpub(npub: string): boolean;
25
+ export declare function validateNip05(nip05: string): boolean;
26
+ export declare function validateNoteId(noteId: string): boolean;
27
+ export declare function validateEventId(eventId: string): boolean;
28
+ export declare function copyToClipboard(text: string): Promise<void>;
29
+ /**
30
+ * Format timestamp as relative time (e.g., "2 mins ago", "1 month ago")
31
+ * @param ts Timestamp in seconds
32
+ * @returns Formatted relative time string
33
+ */
34
+ export declare function formatRelativeTime(ts: number): string;
@@ -0,0 +1,10 @@
1
+ import { default as NostrProfileBadge } from './nostr-profile-badge/nostr-profile-badge.ts';
2
+ import { default as NostrPost } from './nostr-post/nostr-post.ts';
3
+ import { default as NostrProfile } from './nostr-profile/nostr-profile.ts';
4
+ import { default as NostrFollowButton } from './nostr-follow-button/nostr-follow-button.ts';
5
+ import { default as NostrZap } from './nostr-zap/nostr-zap.ts';
6
+ import { default as NostrComment } from './nostr-comment/nostr-comment.ts';
7
+ import { default as NostrDm } from './nostr-dm/nostr-dm.ts';
8
+ import { default as NostrLiveChat } from './nostr-live-chat/nostr-live-chat.ts';
9
+ import { default as NostrLike } from './nostr-like/nostr-like.ts';
10
+ export { NostrProfileBadge, NostrPost, NostrProfile, NostrFollowButton, NostrZap, NostrComment, NostrDm, NostrLiveChat, NostrLike };