holosphere 2.0.0-alpha21 → 2.0.0-alpha23

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 (69) hide show
  1. package/README.md +1 -2
  2. package/dist/cjs/holosphere.cjs +1 -1
  3. package/dist/esm/holosphere.js +61 -58
  4. package/dist/{index-B6-8KAQm.js → index-BEkCLOwI.js} +2 -2
  5. package/dist/{index-B6-8KAQm.js.map → index-BEkCLOwI.js.map} +1 -1
  6. package/dist/{index-D2WstuZJ.js → index-BEvX6DxG.js} +2 -2
  7. package/dist/{index-D2WstuZJ.js.map → index-BEvX6DxG.js.map} +1 -1
  8. package/dist/{index--QsHG_gD.cjs → index-BGTOiJ2Y.cjs} +2 -2
  9. package/dist/{index--QsHG_gD.cjs.map → index-BGTOiJ2Y.cjs.map} +1 -1
  10. package/dist/{index-COpLk9gL.cjs → index-BH1woZXL.cjs} +2 -2
  11. package/dist/{index-COpLk9gL.cjs.map → index-BH1woZXL.cjs.map} +1 -1
  12. package/dist/{index-BHptWysv.js → index-Cvxov2jv.js} +2970 -7753
  13. package/dist/index-Cvxov2jv.js.map +1 -0
  14. package/dist/index-vTKI_BAX.cjs +29 -0
  15. package/dist/index-vTKI_BAX.cjs.map +1 -0
  16. package/dist/{indexeddb-storage-wKG4mICM.cjs → indexeddb-storage-BmnCNnSg.cjs} +2 -2
  17. package/dist/{indexeddb-storage-wKG4mICM.cjs.map → indexeddb-storage-BmnCNnSg.cjs.map} +1 -1
  18. package/dist/{indexeddb-storage-kQ53UHEE.js → indexeddb-storage-MIFisaPy.js} +2 -2
  19. package/dist/{indexeddb-storage-kQ53UHEE.js.map → indexeddb-storage-MIFisaPy.js.map} +1 -1
  20. package/dist/{memory-storage-CGC8xM2G.cjs → memory-storage-BJjK3F4r.cjs} +2 -2
  21. package/dist/{memory-storage-CGC8xM2G.cjs.map → memory-storage-BJjK3F4r.cjs.map} +1 -1
  22. package/dist/{memory-storage-DnXCSbBl.js → memory-storage-DhHXdKQ-.js} +2 -2
  23. package/dist/{memory-storage-DnXCSbBl.js.map → memory-storage-DhHXdKQ-.js.map} +1 -1
  24. package/examples/demo.html +2 -29
  25. package/package.json +3 -8
  26. package/src/content/social-protocols.js +3 -59
  27. package/src/core/holosphere.js +16 -554
  28. package/src/crypto/nostr-utils.js +98 -1
  29. package/src/crypto/secp256k1.js +4 -393
  30. package/src/federation/discovery.js +7 -75
  31. package/src/federation/handshake.js +69 -202
  32. package/src/federation/hologram.js +222 -298
  33. package/src/federation/index.js +2 -9
  34. package/src/federation/registry.js +67 -1257
  35. package/src/federation/request-card.js +21 -35
  36. package/src/hierarchical/upcast.js +4 -9
  37. package/src/index.js +145 -296
  38. package/src/lib/federation-methods.js +370 -909
  39. package/src/storage/global-tables.js +1 -1
  40. package/src/storage/nostr-wrapper.js +9 -5
  41. package/src/subscriptions/manager.js +1 -1
  42. package/types/index.d.ts +145 -37
  43. package/bin/holosphere-activitypub.js +0 -158
  44. package/dist/2019-BzVkRcax.js +0 -6680
  45. package/dist/2019-BzVkRcax.js.map +0 -1
  46. package/dist/2019-C1hPR_Os.cjs +0 -8
  47. package/dist/2019-C1hPR_Os.cjs.map +0 -1
  48. package/dist/browser-BcmACE3G.js +0 -3058
  49. package/dist/browser-BcmACE3G.js.map +0 -1
  50. package/dist/browser-DaqYUTcG.cjs +0 -2
  51. package/dist/browser-DaqYUTcG.cjs.map +0 -1
  52. package/dist/index-BHptWysv.js.map +0 -1
  53. package/dist/index-CDlhzxT2.cjs +0 -29
  54. package/dist/index-CDlhzxT2.cjs.map +0 -1
  55. package/src/federation/capabilities.js +0 -46
  56. package/src/storage/backend-factory.js +0 -130
  57. package/src/storage/backend-interface.js +0 -161
  58. package/src/storage/backends/activitypub/server.js +0 -675
  59. package/src/storage/backends/activitypub-backend.js +0 -295
  60. package/src/storage/backends/gundb-backend.js +0 -875
  61. package/src/storage/backends/nostr-backend.js +0 -251
  62. package/src/storage/gun-async.js +0 -341
  63. package/src/storage/gun-auth.js +0 -373
  64. package/src/storage/gun-federation.js +0 -785
  65. package/src/storage/gun-references.js +0 -209
  66. package/src/storage/gun-schema.js +0 -306
  67. package/src/storage/gun-wrapper.js +0 -642
  68. package/src/storage/migration.js +0 -351
  69. package/src/storage/unified-storage.js +0 -161
@@ -8,7 +8,7 @@
8
8
  * @module storage/global-tables
9
9
  */
10
10
 
11
- import { write, read, readAll, update, deleteData, deleteAll, subscribe } from './unified-storage.js';
11
+ import { write, read, readAll, update, deleteData, deleteAll, subscribe } from './nostr-wrapper.js';
12
12
 
13
13
  /**
14
14
  * Write data to global table
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * @fileoverview Nostr Storage Wrapper.
3
3
  *
4
- * Drop-in replacement for gun-wrapper.js providing the same API.
4
+ * High-level CRUD API for Nostr-based distributed P2P storage.
5
5
  * Handles path construction and CRUD operations using Nostr relays
6
6
  * for distributed P2P storage.
7
7
  *
@@ -62,6 +62,7 @@ export async function write(client, path, data, options = {}) {
62
62
  const putOptions = {
63
63
  ...(options.signingKey && { signingKey: options.signingKey }),
64
64
  ...(options.waitForRelays && { waitForRelays: options.waitForRelays }),
65
+ ...(options.lensKey && { lensKey: options.lensKey }),
65
66
  };
66
67
  const result = await nostrPut(client, path, data, putOptions);
67
68
  // Check if at least one relay accepted the event
@@ -126,9 +127,9 @@ export async function readAll(client, path, options = {}) {
126
127
  * @param {Object} updates - Fields to update
127
128
  * @returns {Promise<boolean>} Success indicator
128
129
  */
129
- export async function update(client, path, updates) {
130
+ export async function update(client, path, updates, options = {}) {
130
131
  try {
131
- const existing = await nostrGet(client, path);
132
+ const existing = await nostrGet(client, path, 30000, options);
132
133
 
133
134
  if (!existing || !existing.id || existing._deleted) {
134
135
  return false; // Not found or deleted
@@ -141,8 +142,11 @@ export async function update(client, path, updates) {
141
142
  if (!merged._meta) merged._meta = {};
142
143
  merged._meta.timestamp = Date.now();
143
144
 
144
- // Write merged data
145
- const result = await nostrPut(client, path, merged);
145
+ // Write merged data (pass lensKey for re-encryption)
146
+ const putOptions = {
147
+ ...(options.lensKey && { lensKey: options.lensKey }),
148
+ };
149
+ const result = await nostrPut(client, path, merged, putOptions);
146
150
  // If no relays (testing mode), consider it successful if event was created
147
151
  const success = result.results.length === 0 ? true : result.results.some(r => r.status === 'fulfilled');
148
152
  return success;
@@ -4,7 +4,7 @@
4
4
  * @module subscriptions/manager
5
5
  */
6
6
 
7
- import { subscribe } from '../storage/unified-storage.js';
7
+ import { subscribe } from '../storage/nostr-wrapper.js';
8
8
  import { resolveHologram } from '../federation/hologram.js';
9
9
 
10
10
  /**
package/types/index.d.ts CHANGED
@@ -1,56 +1,91 @@
1
1
  // Type declarations for holosphere
2
- // This file tells TypeScript to skip type checking the bundled JS files
3
2
 
4
3
  declare module 'holosphere' {
5
4
  export class HoloSphere {
6
5
  constructor(config?: any);
7
6
  init(): Promise<void>;
7
+ ready(): Promise<void>;
8
8
 
9
9
  // Core CRUD operations
10
- get(holonId: string, lens: string, key?: string): Promise<any>;
11
- getAll(holonId: string, lens: string): Promise<Record<string, any>>;
12
- put(holonId: string, lens: string, value: any): Promise<void>;
13
- put(holonId: string, lens: string, key: string, value: any): Promise<void>;
14
- delete(holonId: string, lens: string, key?: string): Promise<void>;
15
- read(holonId: string, lens: string, key?: string): Promise<any>;
10
+ write(holonId: string, lens: string, data: any, options?: any): Promise<boolean>;
11
+ read(holonId: string, lens: string, key?: string, options?: any): Promise<any>;
12
+ update(holonId: string, lens: string, dataId: string, updates: any, options?: any): Promise<boolean>;
13
+ delete(holonId: string, lens: string, key?: string, options?: any): Promise<boolean>;
14
+ deleteAll(holonId: string, lens: string, options?: any): Promise<boolean>;
15
+
16
+ // CRUD aliases (same as above)
17
+ put(holonId: string, lens: string, data: any, options?: any): Promise<boolean>;
18
+ get(holonId: string, lens: string, key?: string, options?: any): Promise<any>;
19
+ getAll(holonId: string, lens: string, options?: any): Promise<any[]>;
20
+ remove(holonId: string, lens: string, key?: string, options?: any): Promise<boolean>;
16
21
 
17
22
  // Subscription
18
- subscribe(holonId: string, lens: string, callback: (data: any, key: string) => void): Promise<{ unsubscribe: () => void }>;
23
+ subscribe(holonId: string, lens: string, callback: (data: any, key: string) => void, options?: any): { unsubscribe: () => void };
19
24
 
20
25
  // Profile operations
21
26
  getHolonProfile(holonId: string): Promise<any>;
22
27
  setHolonProfile(holonId: string, profile: any): Promise<void>;
23
28
 
24
29
  // Federation operations
25
- federate(sourceHolonId: string, targetHolonId: string, sourceKey?: string | null, targetKey?: string | null, bidirectional?: boolean, permissions?: any): Promise<void>;
26
- federateHolon(holonId: string, targetHolonId: string, options?: any): Promise<void>;
30
+ federate(source: string, target: string, lensName: string, options?: any): Promise<any>;
31
+ unfederate(source: string, target: string, lensName: string): Promise<boolean>;
32
+ federateHolon(holonId: string, targetHolonId: string, options?: any): Promise<boolean>;
33
+ unfederateHolon(holonId: string, targetHolonId: string): Promise<boolean>;
27
34
  getFederation(holonId: string): Promise<any>;
35
+ addFederatedHolosphere(pubKey: string, options?: any): Promise<boolean>;
36
+ removeFederatedHolosphere(pubKey: string): Promise<boolean>;
37
+ getFederatedHolospheres(): Promise<string[]>;
38
+ getFederationRegistry(): Promise<any>;
39
+ isFederated(pubKey: string): Promise<boolean>;
40
+
41
+ // Share protocol (Hologram DM as Federation)
42
+ share(target: string, lens: string, item?: string | null, opts?: {
43
+ keys?: Array<{ path: string; key: string }>;
44
+ msg?: string;
45
+ sourceHolon?: string;
46
+ }): Promise<{ success: boolean; error?: string }>;
47
+ accept(sharePayload: SharePayload, senderPubKey: string, opts?: {
48
+ holonId?: string;
49
+ msg?: string;
50
+ }): Promise<{ success: boolean; error?: string }>;
51
+ reject(sharePayload: SharePayload, senderPubKey: string, opts?: {
52
+ msg?: string;
53
+ }): Promise<{ success: boolean; error?: string }>;
54
+
55
+ // Propagation
28
56
  propagate(holonId: string, lens: string, key: string, value: any): Promise<void>;
29
- propagateData(holonId: string, lens: string, data: any): Promise<void>;
57
+ propagateData(data: any, sourceHolon: string, targetHolon: string, lensName: string, options?: any): Promise<any>;
30
58
 
31
59
  // Global operations
32
- getGlobal(lens: string, key?: string): Promise<any>;
33
- getAllGlobal(lens: string): Promise<Record<string, any>>;
34
- writeGlobal(lens: string, key: string, value: any): Promise<void>;
35
-
36
- // Internal properties (exposed for advanced use)
37
- gun?: any;
38
- client?: any;
60
+ writeGlobal(table: string, data: any): Promise<void>;
61
+ readGlobal(table: string, key?: string): Promise<any>;
62
+ updateGlobal(table: string, key: string, updates: any): Promise<void>;
63
+ deleteGlobal(table: string, key: string): Promise<void>;
64
+ getAllGlobal(table: string): Promise<Record<string, any>>;
65
+
66
+ // Encryption
67
+ handleReceivedKeyShare(keyShare: any, senderPubKey: string): boolean;
68
+ hasLensKey(holonId: string, lensName: string): boolean;
69
+ isOwnLensKey(holonId: string, lensName: string): boolean;
70
+ getEncryptionStats(): { ownKeyCount: number; receivedKeyCount: number; totalPartnerGrants: number };
71
+
72
+ // Configuration and internal properties
73
+ config?: { appName: string; [key: string]: any };
74
+ client?: { publicKey: string; privateKey?: Uint8Array; [key: string]: any };
75
+ keyStore?: any;
39
76
  }
40
77
 
41
- export class PersistentStorage {
42
- init(namespace: string): Promise<void>;
43
- put(key: string, event: any): Promise<void>;
44
- get(key: string): Promise<any | null>;
45
- getAll(prefix: string): Promise<any[]>;
46
- delete(key: string): Promise<void>;
47
- clear(): Promise<void>;
48
- close(): Promise<void>;
78
+ export class LensKeyStore {
79
+ getOrCreateKey(lensPath: string, privateKey: string, publicKey: string): { key: Uint8Array; isNew: boolean; wrappedForSelf?: string };
80
+ getKey(lensPath: string): Uint8Array | null;
81
+ hasKey(lensPath: string): boolean;
82
+ isOwnKey(lensPath: string): boolean;
83
+ storeOwnKey(lensPath: string, key: Uint8Array, wrappedForSelf: string): void;
84
+ receiveKey(lensPath: string, wrappedKey: string, recipientPrivKey: string, senderPubKey: string): Uint8Array;
85
+ getStats(): { ownKeyCount: number; receivedKeyCount: number; totalPartnerGrants: number };
49
86
  }
50
87
 
51
- export class IndexedDBStorage extends PersistentStorage {}
52
- export class MemoryStorage extends PersistentStorage {}
53
- export class FileSystemStorage extends PersistentStorage {}
88
+ export function buildLensPath(appName: string, holonId: string, lensName: string): string;
54
89
 
55
90
  export class ChainManager {
56
91
  constructor(config?: any);
@@ -79,27 +114,100 @@ declare module 'holosphere' {
79
114
  export const ContractABIs: any;
80
115
  export const NETWORKS: any;
81
116
 
117
+ export interface SharePayload {
118
+ id: string;
119
+ type: 'share';
120
+ source: string;
121
+ lens: string;
122
+ item: string | null;
123
+ author: string;
124
+ keys?: Array<{ path: string; key: string }>;
125
+ msg?: string;
126
+ timestamp?: number;
127
+ }
128
+
129
+ export interface ShareAckPayload {
130
+ id: string;
131
+ type: 'share_ack';
132
+ source: string;
133
+ lens: string;
134
+ item: string | null;
135
+ author: string;
136
+ status: 'accepted' | 'rejected';
137
+ msg?: string;
138
+ timestamp?: number;
139
+ }
140
+
82
141
  export class AuthorizationError extends Error {}
83
142
  export class ValidationError extends Error {}
84
143
 
85
144
  export const crypto: any;
86
145
  export const federation: any;
87
146
  export const handshake: {
88
- initiateFederationHandshake(holosphere: HoloSphere, privateKey: string, params: any): Promise<any>;
89
- acceptFederationRequest(holosphere: HoloSphere, privateKey: string, params: any): Promise<any>;
90
- rejectFederationRequest(holosphere: HoloSphere, privateKey: string, params: any): Promise<any>;
91
- subscribeToFederationDMs(client: any, privateKey: string, publicKey: string, handlers: any): () => void;
147
+ // Request/Response lifecycle
148
+ initiateFederationHandshake(holosphere: HoloSphere, privateKey: string, params: any): Promise<{ success: boolean; requestId?: string; error?: string }>;
149
+ acceptFederationRequest(holosphere: HoloSphere, privateKey: string, params: any): Promise<{ success: boolean; requestId?: string; receivedHolograms?: any; error?: string }>;
150
+ rejectFederationRequest(holosphere: HoloSphere, privateKey: string, params: any): Promise<{ success: boolean; error?: string }>;
151
+ processFederationResponse(holosphere: HoloSphere, response: any, responderPubKey: string, options?: any): Promise<{ success: boolean; receivedHolograms?: any; error?: string }>;
152
+
153
+ // DM operations
154
+ subscribeToFederationDMs(client: any, privateKey: string, publicKey: string, handlers: any, options?: any): () => void;
155
+ createFederationResponse(params: any): any;
156
+ sendFederationResponse(client: any, privateKey: string, recipientPubKey: string, response: any): Promise<boolean>;
157
+
158
+ // Validation helpers
159
+ isFederationRequest(payload: any): boolean;
160
+ isFederationResponse(payload: any): boolean;
161
+ normalizeLensConfig(lensConfig: any): any;
162
+ };
163
+ export const registry: {
164
+ addFederatedPartner(client: any, appname: string, partnerPubKey: string, options?: any): Promise<boolean>;
165
+ removeFederatedPartner(client: any, appname: string, partnerPubKey: string): Promise<boolean>;
166
+ getFederatedAuthors(client: any, appname: string): Promise<string[]>;
167
+ getFederationRegistry(client: any, appname: string, options?: any): Promise<any>;
168
+ isFederated(client: any, appname: string, pubKey: string): Promise<boolean>;
169
+ getFederatedPartner(client: any, appname: string, partnerPubKey: string): Promise<any>;
170
+ addCapabilityWriter(client: any, appname: string, writerPubKey: string): Promise<boolean>;
171
+ getCapabilityWriters(client: any, appname: string): Promise<string[]>;
172
+ removeCapabilityWriter(client: any, appname: string, writerPubKey: string): Promise<boolean>;
173
+ };
174
+ export const nostrUtils: {
175
+ // npub utilities
176
+ parseNpubOrHex(input: string): { valid: boolean; hexPubKey?: string; error?: string };
177
+ hexToNpub(hexPubKey: string): string;
178
+ npubToHex(npub: string): string | null;
179
+ isValidNpub(str: string): boolean;
180
+ shortenNpub(npub: string): string;
181
+ shortenPubKey(pubKey: string): string;
182
+ // nsec utilities
183
+ parseNsecOrHex(input: string): { valid: boolean; hexPrivKey?: string; error?: string };
184
+ hexToNsec(hexPrivKey: string): string;
185
+ nsecToHex(nsec: string): string | null;
186
+ isValidNsec(str: string): boolean;
187
+ // Key operations
188
+ generatePrivateKey(): string;
189
+ getPublicKey(privateKey: string): string;
190
+ isValidHexPubKey(str: string): boolean;
191
+ // Byte conversion
192
+ hexToBytes(hex: string): Uint8Array;
193
+ bytesToHex(bytes: Uint8Array): string;
194
+ [key: string]: any;
92
195
  };
93
- export const hierarchical: any;
94
- export const nostrUtils: any;
95
196
  export const schema: any;
96
197
  export const social: any;
97
198
  export const spatial: any;
98
199
  export const storage: any;
99
- export const subscriptions: any;
200
+ export const subscriptions: {
201
+ createSubscription(client: any, path: string, callback: (data: any, key?: string) => void, options?: any): Promise<{ path: string; unsubscribe: () => void }>;
202
+ };
100
203
  export const networks: any;
204
+ export const hierarchical: any;
101
205
 
102
206
  export function createHologram(config?: any): any;
207
+ export function createLensHologram(sourceHolon: string, lensName: string, appname: string, options: { author: string }): any;
208
+ export function isLensHologram(data: any): boolean;
209
+ export function sendShare(client: any, privateKey: string, targetPubKey: string, payload: any): Promise<boolean>;
210
+ export function sendAck(client: any, privateKey: string, targetPubKey: string, payload: any): Promise<boolean>;
103
211
  export function createAIServices(config?: any): any;
104
212
  export function getNetwork(name: string): any;
105
213
  export function getNetworksByType(type: string): any[];
@@ -107,7 +215,7 @@ declare module 'holosphere' {
107
215
  export function isNetworkSupported(name: string): boolean;
108
216
  export function getAddressUrl(network: string, address: string): string;
109
217
  export function getTxUrl(network: string, txHash: string): string;
110
- export function matchScope(scope: string, pattern: string): boolean;
218
+ export function dismissRequest(client: any, appname: string, requestId: string): Promise<void>;
111
219
 
112
220
  // AI-related exports
113
221
  export class Classifier {}
@@ -1,158 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * HoloSphere ActivityPub Server CLI
5
- *
6
- * Starts a self-hosted ActivityPub server for HoloSphere federation.
7
- *
8
- * Usage:
9
- * holosphere-activitypub [options]
10
- *
11
- * Options:
12
- * -p, --port <port> Port to listen on (default: 3000)
13
- * -d, --domain <domain> Domain name for federation (default: localhost)
14
- * --data-dir <dir> Data directory for storage
15
- * --protocol <protocol> Protocol: http or https (default: http)
16
- * -h, --help Show this help message
17
- *
18
- * Environment Variables:
19
- * HOLOSPHERE_AP_PORT Port to listen on
20
- * HOLOSPHERE_AP_DOMAIN Domain name
21
- * HOLOSPHERE_AP_DATADIR Data directory
22
- * HOLOSPHERE_AP_PROTOCOL Protocol (http/https)
23
- */
24
-
25
- import { ActivityPubServer } from '../src/storage/backends/activitypub/server.js';
26
-
27
- function parseArgs(args) {
28
- const config = {
29
- port: parseInt(process.env.HOLOSPHERE_AP_PORT) || 3000,
30
- domain: process.env.HOLOSPHERE_AP_DOMAIN || 'localhost',
31
- dataDir: process.env.HOLOSPHERE_AP_DATADIR,
32
- protocol: process.env.HOLOSPHERE_AP_PROTOCOL || 'http',
33
- };
34
-
35
- for (let i = 0; i < args.length; i++) {
36
- const arg = args[i];
37
- const next = args[i + 1];
38
-
39
- switch (arg) {
40
- case '-p':
41
- case '--port':
42
- config.port = parseInt(next);
43
- i++;
44
- break;
45
- case '-d':
46
- case '--domain':
47
- config.domain = next;
48
- i++;
49
- break;
50
- case '--data-dir':
51
- config.dataDir = next;
52
- i++;
53
- break;
54
- case '--protocol':
55
- config.protocol = next;
56
- i++;
57
- break;
58
- case '-h':
59
- case '--help':
60
- showHelp();
61
- process.exit(0);
62
- default:
63
- if (arg.startsWith('-')) {
64
- console.error(`Unknown option: ${arg}`);
65
- showHelp();
66
- process.exit(1);
67
- }
68
- }
69
- }
70
-
71
- return config;
72
- }
73
-
74
- function showHelp() {
75
- console.log(`
76
- HoloSphere ActivityPub Server
77
-
78
- Starts a self-hosted ActivityPub server for HoloSphere federation.
79
- This server can federate with Mastodon, Pleroma, and other ActivityPub servers.
80
-
81
- Usage:
82
- holosphere-activitypub [options]
83
-
84
- Options:
85
- -p, --port <port> Port to listen on (default: 3000)
86
- -d, --domain <domain> Domain name for federation (default: localhost)
87
- --data-dir <dir> Data directory for persistent storage
88
- --protocol <protocol> Protocol: http or https (default: http)
89
- -h, --help Show this help message
90
-
91
- Environment Variables:
92
- HOLOSPHERE_AP_PORT Port to listen on
93
- HOLOSPHERE_AP_DOMAIN Domain name
94
- HOLOSPHERE_AP_DATADIR Data directory
95
- HOLOSPHERE_AP_PROTOCOL Protocol (http/https)
96
-
97
- Examples:
98
- # Start server on default port
99
- holosphere-activitypub
100
-
101
- # Start server on port 8080 with custom domain
102
- holosphere-activitypub -p 8080 -d myholosphere.example.com
103
-
104
- # Start with persistent data directory
105
- holosphere-activitypub --data-dir ./data --domain myserver.local
106
-
107
- Federation Notes:
108
- For federation with other ActivityPub servers (Mastodon, etc.):
109
- 1. Your server must be accessible via the domain you specify
110
- 2. HTTPS is recommended for production federation
111
- 3. Set up proper DNS records pointing to your server
112
- 4. WebFinger discovery is available at /.well-known/webfinger
113
- `);
114
- }
115
-
116
- async function main() {
117
- const args = process.argv.slice(2);
118
- const config = parseArgs(args);
119
-
120
- console.log('\n========================================');
121
- console.log(' HoloSphere ActivityPub Server');
122
- console.log('========================================');
123
- console.log(` Port: ${config.port}`);
124
- console.log(` Domain: ${config.domain}`);
125
- console.log(` Protocol: ${config.protocol}`);
126
- console.log(` Data Dir: ${config.dataDir || '(default)'}`);
127
- console.log('========================================\n');
128
-
129
- const server = new ActivityPubServer(config);
130
-
131
- // Handle shutdown gracefully
132
- process.on('SIGINT', () => {
133
- console.log('\nShutting down...');
134
- server.stop();
135
- process.exit(0);
136
- });
137
-
138
- process.on('SIGTERM', () => {
139
- console.log('\nShutting down...');
140
- server.stop();
141
- process.exit(0);
142
- });
143
-
144
- try {
145
- await server.start();
146
- console.log('\nServer endpoints:');
147
- console.log(` WebFinger: ${config.protocol}://${config.domain}:${config.port}/.well-known/webfinger`);
148
- console.log(` Actors: ${config.protocol}://${config.domain}:${config.port}/actor/{name}`);
149
- console.log(` API: ${config.protocol}://${config.domain}:${config.port}/api/data`);
150
- console.log(` Health: ${config.protocol}://${config.domain}:${config.port}/health`);
151
- console.log('\nPress Ctrl+C to stop the server\n');
152
- } catch (error) {
153
- console.error('Failed to start server:', error);
154
- process.exit(1);
155
- }
156
- }
157
-
158
- main();