@gns-foundation/hive-worker 0.1.11 → 0.5.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.
package/dist/mobydb.js ADDED
@@ -0,0 +1,379 @@
1
+ // ============================================================
2
+ // Phase 4: MobyDB Embedded Storage
3
+ // File: packages/hive-worker/src/mobydb.ts
4
+ //
5
+ // Local storage engine for the Hive worker.
6
+ // Phase 4a: SQLite (better-sqlite3)
7
+ // Phase 4b: RocksDB (Rust sidecar)
8
+ //
9
+ // Every compute job (inference, tile, etc.) writes a record
10
+ // locally. Records are sealed into epochs with Merkle roots.
11
+ // ============================================================
12
+ import Database from 'better-sqlite3';
13
+ import * as crypto from 'crypto';
14
+ import * as path from 'path';
15
+ import * as fs from 'fs';
16
+ // ─── Config ─────────────────────────────────
17
+ const HIVE_DIR = process.env.HIVE_DIR || path.join(process.env.HOME || '/tmp', '.hive');
18
+ const DB_PATH = path.join(HIVE_DIR, 'mobydb', 'records.db');
19
+ const EPOCH_DURATION_MS = 3600_000; // 1 hour
20
+ const EPOCH_ZERO = new Date('2026-01-01T00:00:00Z').getTime();
21
+ // ─── Hash Helpers ───────────────────────────
22
+ function sha256(input) {
23
+ return crypto.createHash('sha256').update(input, 'utf8').digest('hex');
24
+ }
25
+ function computeRecordHash(record) {
26
+ const canonical = JSON.stringify({
27
+ address: record.address,
28
+ collection_type: record.collection_type,
29
+ payload_type: record.payload_type,
30
+ data: record.data,
31
+ written_at_ms: record.written_at_ms,
32
+ });
33
+ return sha256(canonical);
34
+ }
35
+ function computeMerkleRoot(hashes) {
36
+ if (hashes.length === 0)
37
+ return sha256('empty');
38
+ if (hashes.length === 1)
39
+ return hashes[0];
40
+ const next = [];
41
+ for (let i = 0; i < hashes.length; i += 2) {
42
+ if (i + 1 < hashes.length) {
43
+ next.push(sha256(hashes[i] + hashes[i + 1]));
44
+ }
45
+ else {
46
+ next.push(hashes[i]); // odd leaf promoted
47
+ }
48
+ }
49
+ return computeMerkleRoot(next);
50
+ }
51
+ // ─── Current Epoch ──────────────────────────
52
+ export function currentEpoch() {
53
+ return Math.floor((Date.now() - EPOCH_ZERO) / EPOCH_DURATION_MS);
54
+ }
55
+ // ─── MobyDB Class ───────────────────────────
56
+ export class MobyDB {
57
+ db;
58
+ workerPk;
59
+ h3Cell;
60
+ constructor(workerPk, h3Cell) {
61
+ this.workerPk = workerPk;
62
+ this.h3Cell = h3Cell;
63
+ // Ensure directory exists
64
+ const dir = path.dirname(DB_PATH);
65
+ if (!fs.existsSync(dir)) {
66
+ fs.mkdirSync(dir, { recursive: true });
67
+ }
68
+ // Open SQLite
69
+ this.db = new Database(DB_PATH);
70
+ this.db.pragma('journal_mode = WAL');
71
+ this.db.pragma('synchronous = NORMAL');
72
+ this.initSchema();
73
+ console.log(`🐋 MobyDB initialized: ${DB_PATH}`);
74
+ console.log(` Worker: ${workerPk.substring(0, 16)}...`);
75
+ console.log(` Cell: ${h3Cell}`);
76
+ }
77
+ // ─── Schema ─────────────────────────────
78
+ initSchema() {
79
+ this.db.exec(`
80
+ CREATE TABLE IF NOT EXISTS records (
81
+ id TEXT PRIMARY KEY,
82
+ h3_cell TEXT NOT NULL,
83
+ epoch INTEGER NOT NULL,
84
+ public_key TEXT NOT NULL,
85
+ collection_type TEXT NOT NULL,
86
+ payload_type TEXT NOT NULL,
87
+ data TEXT NOT NULL,
88
+ signature TEXT,
89
+ trust_tier TEXT DEFAULT 'Observed',
90
+ written_at_ms INTEGER NOT NULL,
91
+ record_hash TEXT NOT NULL,
92
+ sealed INTEGER DEFAULT 0,
93
+ epoch_merkle_root TEXT
94
+ );
95
+
96
+ CREATE INDEX IF NOT EXISTS idx_records_address
97
+ ON records (h3_cell, epoch, public_key);
98
+ CREATE INDEX IF NOT EXISTS idx_records_collection
99
+ ON records (collection_type, epoch DESC);
100
+ CREATE INDEX IF NOT EXISTS idx_records_epoch
101
+ ON records (epoch, sealed);
102
+
103
+ CREATE TABLE IF NOT EXISTS epoch_seals (
104
+ epoch INTEGER NOT NULL,
105
+ h3_cell TEXT NOT NULL,
106
+ worker_pk TEXT NOT NULL,
107
+ record_count INTEGER NOT NULL,
108
+ merkle_root TEXT NOT NULL,
109
+ prev_epoch_hash TEXT NOT NULL,
110
+ sealed_at_ms INTEGER NOT NULL,
111
+ signature TEXT,
112
+ PRIMARY KEY (epoch, h3_cell, worker_pk)
113
+ );
114
+
115
+ CREATE TABLE IF NOT EXISTS sync_queue (
116
+ id TEXT PRIMARY KEY,
117
+ record_id TEXT NOT NULL,
118
+ target TEXT NOT NULL DEFAULT 'central',
119
+ status TEXT DEFAULT 'pending',
120
+ attempts INTEGER DEFAULT 0,
121
+ created_at INTEGER NOT NULL,
122
+ synced_at INTEGER
123
+ );
124
+ `);
125
+ }
126
+ // ─── Write ──────────────────────────────
127
+ /**
128
+ * Write a record to local MobyDB.
129
+ * Returns the record with hash computed.
130
+ * Typical latency: <0.1ms (SQLite WAL mode).
131
+ */
132
+ write(collectionType, payloadType, data, options) {
133
+ const epoch = options?.epoch ?? currentEpoch();
134
+ const id = crypto.randomUUID();
135
+ const now = Date.now();
136
+ const record = {
137
+ id,
138
+ address: {
139
+ h3_cell: options?.h3Cell ?? this.h3Cell,
140
+ epoch,
141
+ public_key: options?.publicKey ?? this.workerPk,
142
+ },
143
+ collection_type: collectionType,
144
+ payload_type: payloadType,
145
+ data,
146
+ signature: options?.signature,
147
+ trust_tier: options?.trustTier ?? 'Observed',
148
+ written_at_ms: now,
149
+ };
150
+ const recordHash = computeRecordHash(record);
151
+ const stmt = this.db.prepare(`
152
+ INSERT INTO records (id, h3_cell, epoch, public_key, collection_type, payload_type, data, signature, trust_tier, written_at_ms, record_hash)
153
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
154
+ `);
155
+ stmt.run(id, record.address.h3_cell, epoch, record.address.public_key, collectionType, payloadType, JSON.stringify(data), record.signature || null, record.trust_tier, now, recordHash);
156
+ // Queue for central sync
157
+ this.queueSync(id);
158
+ return { ...record, record_hash: recordHash, sealed: false };
159
+ }
160
+ // ─── Convenience Writers ────────────────
161
+ /** Write an inference record after AI compute */
162
+ writeInference(data) {
163
+ return this.write('Inference', 'hive/inference', data);
164
+ }
165
+ /** Write a tile record after rendering/proxying */
166
+ writeTile(data) {
167
+ return this.write('Tile', data.format === 'mvt' ? 'tile/vector' : 'tile/raster', data);
168
+ }
169
+ /** Write a compound job record linking multiple steps */
170
+ writeComputeJob(data) {
171
+ return this.write('ComputeJob', 'compute/job', data);
172
+ }
173
+ // ─── Query ──────────────────────────────
174
+ /** Query records near an H3 cell in an epoch range */
175
+ query(options) {
176
+ let sql = 'SELECT * FROM records WHERE 1=1';
177
+ const params = [];
178
+ if (options.h3Cell) {
179
+ sql += ' AND h3_cell = ?';
180
+ params.push(options.h3Cell);
181
+ }
182
+ if (options.epochStart !== undefined) {
183
+ sql += ' AND epoch >= ?';
184
+ params.push(options.epochStart);
185
+ }
186
+ if (options.epochEnd !== undefined) {
187
+ sql += ' AND epoch <= ?';
188
+ params.push(options.epochEnd);
189
+ }
190
+ if (options.collectionType) {
191
+ sql += ' AND collection_type = ?';
192
+ params.push(options.collectionType);
193
+ }
194
+ sql += ' ORDER BY written_at_ms DESC LIMIT ?';
195
+ params.push(options.limit || 100);
196
+ const rows = this.db.prepare(sql).all(...params);
197
+ return rows.map(r => ({
198
+ ...r,
199
+ address: { h3_cell: r.h3_cell, epoch: r.epoch, public_key: r.public_key },
200
+ data: JSON.parse(r.data),
201
+ sealed: !!r.sealed,
202
+ }));
203
+ }
204
+ /** Get a single record by ID */
205
+ get(id) {
206
+ const r = this.db.prepare('SELECT * FROM records WHERE id = ?').get(id);
207
+ if (!r)
208
+ return null;
209
+ return {
210
+ ...r,
211
+ address: { h3_cell: r.h3_cell, epoch: r.epoch, public_key: r.public_key },
212
+ data: JSON.parse(r.data),
213
+ sealed: !!r.sealed,
214
+ };
215
+ }
216
+ /** Count records by collection type */
217
+ stats() {
218
+ const rows = this.db.prepare('SELECT collection_type, count(*) as cnt FROM records GROUP BY collection_type').all();
219
+ const result = {};
220
+ rows.forEach(r => result[r.collection_type] = r.cnt);
221
+ return result;
222
+ }
223
+ // ─── Epoch Sealing ──────────────────────
224
+ /**
225
+ * Seal an epoch: compute Merkle root of all records,
226
+ * mark them as sealed, store the epoch seal.
227
+ */
228
+ sealEpoch(epoch) {
229
+ // Get all unsealed records for this epoch
230
+ const records = this.db.prepare('SELECT record_hash FROM records WHERE epoch = ? AND sealed = 0 ORDER BY written_at_ms ASC').all(epoch);
231
+ if (records.length === 0)
232
+ return null;
233
+ const hashes = records.map(r => r.record_hash);
234
+ const merkleRoot = computeMerkleRoot(hashes);
235
+ // Get previous epoch seal for chaining
236
+ const prevSeal = this.db.prepare('SELECT merkle_root FROM epoch_seals WHERE epoch = ? AND h3_cell = ? AND worker_pk = ?').get(epoch - 1, this.h3Cell, this.workerPk);
237
+ const prevEpochHash = prevSeal?.merkle_root || sha256('genesis');
238
+ const seal = {
239
+ epoch,
240
+ h3_cell: this.h3Cell,
241
+ worker_pk: this.workerPk,
242
+ record_count: records.length,
243
+ merkle_root: merkleRoot,
244
+ prev_epoch_hash: prevEpochHash,
245
+ sealed_at_ms: Date.now(),
246
+ };
247
+ // Transaction: mark records sealed + insert seal
248
+ const transaction = this.db.transaction(() => {
249
+ this.db.prepare('UPDATE records SET sealed = 1, epoch_merkle_root = ? WHERE epoch = ? AND sealed = 0').run(merkleRoot, epoch);
250
+ this.db.prepare(`
251
+ INSERT OR REPLACE INTO epoch_seals (epoch, h3_cell, worker_pk, record_count, merkle_root, prev_epoch_hash, sealed_at_ms, signature)
252
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?)
253
+ `).run(seal.epoch, seal.h3_cell, seal.worker_pk, seal.record_count, seal.merkle_root, seal.prev_epoch_hash, seal.sealed_at_ms, seal.signature || null);
254
+ });
255
+ transaction();
256
+ console.log(`🔒 Epoch ${epoch} sealed: ${records.length} records, root=${merkleRoot.substring(0, 16)}...`);
257
+ return seal;
258
+ }
259
+ /**
260
+ * Auto-seal previous epochs that have unsealed records.
261
+ * Call this periodically (e.g. every minute).
262
+ */
263
+ autoSeal() {
264
+ const current = currentEpoch();
265
+ const unsealed = this.db.prepare('SELECT DISTINCT epoch FROM records WHERE sealed = 0 AND epoch < ? ORDER BY epoch ASC').all(current);
266
+ const seals = [];
267
+ for (const row of unsealed) {
268
+ const seal = this.sealEpoch(row.epoch);
269
+ if (seal)
270
+ seals.push(seal);
271
+ }
272
+ return seals;
273
+ }
274
+ // ─── Proof Generation ───────────────────
275
+ /**
276
+ * Generate a Merkle proof for a specific record.
277
+ * Proves this record was included in the epoch's Merkle tree.
278
+ */
279
+ generateProof(recordId) {
280
+ const record = this.get(recordId);
281
+ if (!record || !record.sealed)
282
+ return null;
283
+ // Get all record hashes in the same epoch (in order)
284
+ const rows = this.db.prepare('SELECT record_hash FROM records WHERE epoch = ? AND h3_cell = ? ORDER BY written_at_ms ASC').all(record.address.epoch, record.address.h3_cell);
285
+ const hashes = rows.map(r => r.record_hash);
286
+ const proofPath = generateMerkleProofPath(hashes, record.record_hash);
287
+ return {
288
+ record_hash: record.record_hash,
289
+ epoch: record.address.epoch,
290
+ merkle_root: record.epoch_merkle_root || '',
291
+ proof_path: proofPath,
292
+ verify_url: `https://mobydb.com/proof/${record.address.h3_cell}/${record.address.epoch}/${record.address.public_key}`,
293
+ };
294
+ }
295
+ // ─── Sync Queue ─────────────────────────
296
+ queueSync(recordId) {
297
+ this.db.prepare(`
298
+ INSERT OR IGNORE INTO sync_queue (id, record_id, target, created_at)
299
+ VALUES (?, ?, 'central', ?)
300
+ `).run(crypto.randomUUID(), recordId, Date.now());
301
+ }
302
+ /** Get records pending sync to central server */
303
+ getPendingSync(limit = 50) {
304
+ const rows = this.db.prepare("SELECT record_id FROM sync_queue WHERE status = 'pending' ORDER BY created_at ASC LIMIT ?").all(limit);
305
+ return rows.map(r => r.record_id);
306
+ }
307
+ /** Mark records as synced */
308
+ markSynced(recordIds) {
309
+ const stmt = this.db.prepare("UPDATE sync_queue SET status = 'synced', synced_at = ? WHERE record_id = ?");
310
+ const now = Date.now();
311
+ const transaction = this.db.transaction(() => {
312
+ for (const id of recordIds) {
313
+ stmt.run(now, id);
314
+ }
315
+ });
316
+ transaction();
317
+ }
318
+ // ─── Lifecycle ──────────────────────────
319
+ /** Close the database */
320
+ close() {
321
+ this.db.close();
322
+ console.log('🐋 MobyDB closed');
323
+ }
324
+ /** Get the database file path */
325
+ get path() {
326
+ return DB_PATH;
327
+ }
328
+ /** Get total record count */
329
+ get recordCount() {
330
+ const r = this.db.prepare('SELECT count(*) as cnt FROM records').get();
331
+ return r.cnt;
332
+ }
333
+ }
334
+ // ─── Merkle Proof Path ──────────────────────
335
+ function generateMerkleProofPath(hashes, targetHash) {
336
+ if (hashes.length <= 1)
337
+ return [];
338
+ const path = [];
339
+ let level = [...hashes];
340
+ let targetIdx = level.indexOf(targetHash);
341
+ while (level.length > 1) {
342
+ const nextLevel = [];
343
+ for (let i = 0; i < level.length; i += 2) {
344
+ if (i + 1 < level.length) {
345
+ // If target is at i, sibling is i+1 (right)
346
+ // If target is at i+1, sibling is i (left)
347
+ if (i === targetIdx) {
348
+ path.push('R:' + level[i + 1]);
349
+ targetIdx = Math.floor(i / 2);
350
+ }
351
+ else if (i + 1 === targetIdx) {
352
+ path.push('L:' + level[i]);
353
+ targetIdx = Math.floor(i / 2);
354
+ }
355
+ nextLevel.push(sha256(level[i] + level[i + 1]));
356
+ }
357
+ else {
358
+ if (i === targetIdx) {
359
+ targetIdx = Math.floor(i / 2);
360
+ }
361
+ nextLevel.push(level[i]);
362
+ }
363
+ }
364
+ level = nextLevel;
365
+ }
366
+ return path;
367
+ }
368
+ // ─── Singleton ──────────────────────────────
369
+ let _instance = null;
370
+ export function initMobyDB(workerPk, h3Cell) {
371
+ if (_instance)
372
+ return _instance;
373
+ _instance = new MobyDB(workerPk, h3Cell);
374
+ return _instance;
375
+ }
376
+ export function getMobyDB() {
377
+ return _instance;
378
+ }
379
+ //# sourceMappingURL=mobydb.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mobydb.js","sourceRoot":"","sources":["../src/mobydb.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,54 @@
1
+ import { type MobyDB } from './mobydb';
2
+ /**
3
+ * Initialize MobyDB for this worker.
4
+ * Call once at worker startup after identity is loaded.
5
+ */
6
+ export declare function initWorkerMobyDB(workerPk: string, h3Cell: string): MobyDB;
7
+ /**
8
+ * Hook: call after every inference.
9
+ * Writes an Inference record to local MobyDB.
10
+ */
11
+ export declare function afterInference(data: {
12
+ model: string;
13
+ provider: string;
14
+ tokens_in: number;
15
+ tokens_out: number;
16
+ latency_ms: number;
17
+ prompt_hash: string;
18
+ response_hash: string;
19
+ requester_pk: string;
20
+ job_id?: string;
21
+ }): string | null;
22
+ /**
23
+ * Hook: call after every tile render/proxy.
24
+ * Writes a Tile record to local MobyDB.
25
+ */
26
+ export declare function afterTileRender(data: {
27
+ format: string;
28
+ zoom: number;
29
+ style: string;
30
+ tile_hash: string;
31
+ tile_bytes: number;
32
+ render_ms: number;
33
+ source: string;
34
+ cached: boolean;
35
+ parent_job?: string;
36
+ }): string | null;
37
+ /**
38
+ * Hook: call after a compound job completes.
39
+ * Links all step records into one ComputeJob record.
40
+ */
41
+ export declare function afterComputeJob(data: {
42
+ job_id: string;
43
+ requester_pk: string;
44
+ steps: Array<{
45
+ id: string;
46
+ type: string;
47
+ record_hash: string;
48
+ }>;
49
+ total_gns: number;
50
+ stellar_tx?: string;
51
+ latency_ms: number;
52
+ }): string | null;
53
+ export declare function getMobyDBStatus(): Record<string, any> | null;
54
+ export declare function shutdownMobyDB(): void;
@@ -0,0 +1,136 @@
1
+ // ============================================================
2
+ // Phase 4: Worker MobyDB Integration
3
+ // File: packages/hive-worker/src/mobydb_hooks.ts
4
+ //
5
+ // Hooks MobyDB into every compute operation.
6
+ // Call initWorkerMobyDB() at worker startup.
7
+ // ============================================================
8
+ import { initMobyDB, getMobyDB, currentEpoch } from './mobydb';
9
+ let sealInterval = null;
10
+ let syncInterval = null;
11
+ // ─── Central API ────────────────────────────
12
+ const CENTRAL_URL = process.env.CENTRAL_API_URL || 'https://gns-browser-production.up.railway.app';
13
+ // ─── Initialize ─────────────────────────────
14
+ /**
15
+ * Initialize MobyDB for this worker.
16
+ * Call once at worker startup after identity is loaded.
17
+ */
18
+ export function initWorkerMobyDB(workerPk, h3Cell) {
19
+ const db = initMobyDB(workerPk, h3Cell);
20
+ // Start auto-sealer (every 60 seconds)
21
+ if (!sealInterval) {
22
+ sealInterval = setInterval(() => {
23
+ const moby = getMobyDB();
24
+ if (!moby)
25
+ return;
26
+ const seals = moby.autoSeal();
27
+ if (seals.length > 0) {
28
+ console.log(`🔒 Auto-sealed ${seals.length} epoch(s)`);
29
+ }
30
+ }, 60_000);
31
+ }
32
+ // Start sync to central (every 30 seconds)
33
+ if (!syncInterval) {
34
+ syncInterval = setInterval(() => {
35
+ syncToCentral().catch(err => {
36
+ console.error('⚠️ Sync to central failed:', err.message);
37
+ });
38
+ }, 30_000);
39
+ }
40
+ console.log(`🐋 Worker MobyDB ready (auto-seal: 60s, sync: 30s)`);
41
+ return db;
42
+ }
43
+ // ─── Compute Hooks ──────────────────────────
44
+ /**
45
+ * Hook: call after every inference.
46
+ * Writes an Inference record to local MobyDB.
47
+ */
48
+ export function afterInference(data) {
49
+ const moby = getMobyDB();
50
+ if (!moby)
51
+ return null;
52
+ const record = moby.writeInference(data);
53
+ return record.record_hash;
54
+ }
55
+ /**
56
+ * Hook: call after every tile render/proxy.
57
+ * Writes a Tile record to local MobyDB.
58
+ */
59
+ export function afterTileRender(data) {
60
+ const moby = getMobyDB();
61
+ if (!moby)
62
+ return null;
63
+ const record = moby.writeTile(data);
64
+ return record.record_hash;
65
+ }
66
+ /**
67
+ * Hook: call after a compound job completes.
68
+ * Links all step records into one ComputeJob record.
69
+ */
70
+ export function afterComputeJob(data) {
71
+ const moby = getMobyDB();
72
+ if (!moby)
73
+ return null;
74
+ const record = moby.writeComputeJob(data);
75
+ return record.record_hash;
76
+ }
77
+ // ─── Sync to Central ────────────────────────
78
+ /**
79
+ * Push pending records to the central MobyDB server.
80
+ * Records are batched for efficiency.
81
+ */
82
+ async function syncToCentral() {
83
+ const moby = getMobyDB();
84
+ if (!moby)
85
+ return;
86
+ const pendingIds = moby.getPendingSync(20);
87
+ if (pendingIds.length === 0)
88
+ return;
89
+ const records = pendingIds.map(id => moby.get(id)).filter(Boolean);
90
+ if (records.length === 0)
91
+ return;
92
+ try {
93
+ const res = await fetch(`${CENTRAL_URL}/mobydb/sync`, {
94
+ method: 'POST',
95
+ headers: { 'Content-Type': 'application/json' },
96
+ body: JSON.stringify({ records }),
97
+ });
98
+ if (res.ok) {
99
+ moby.markSynced(pendingIds);
100
+ console.log(`📤 Synced ${records.length} records to central`);
101
+ }
102
+ }
103
+ catch {
104
+ // Will retry next cycle
105
+ }
106
+ }
107
+ // ─── Status ─────────────────────────────────
108
+ export function getMobyDBStatus() {
109
+ const moby = getMobyDB();
110
+ if (!moby)
111
+ return null;
112
+ return {
113
+ path: moby.path,
114
+ records: moby.recordCount,
115
+ stats: moby.stats(),
116
+ epoch: currentEpoch(),
117
+ };
118
+ }
119
+ // ─── Shutdown ───────────────────────────────
120
+ export function shutdownMobyDB() {
121
+ if (sealInterval) {
122
+ clearInterval(sealInterval);
123
+ sealInterval = null;
124
+ }
125
+ if (syncInterval) {
126
+ clearInterval(syncInterval);
127
+ syncInterval = null;
128
+ }
129
+ const moby = getMobyDB();
130
+ if (moby) {
131
+ // Final seal before shutdown
132
+ moby.autoSeal();
133
+ moby.close();
134
+ }
135
+ }
136
+ //# sourceMappingURL=mobydb_hooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mobydb_hooks.js","sourceRoot":"","sources":["../src/mobydb_hooks.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gns-foundation/hive-worker",
3
- "version": "0.1.11",
3
+ "version": "0.5.0",
4
4
  "description": "Turn your device into a GEIANT Hive compute node. Earn GNS tokens.",
5
5
  "bin": {
6
6
  "hive-worker": "./dist/cli.js"
@@ -21,18 +21,20 @@
21
21
  "author": "GNS Foundation <cayerbe@ulissy.app>",
22
22
  "license": "BSL-1.1",
23
23
  "dependencies": {
24
- "tweetnacl": "^1.0.3",
25
- "tweetnacl-util": "^0.15.1",
26
- "node-fetch": "^3.3.2",
24
+ "better-sqlite3": "^12.8.0",
25
+ "chalk": "^5.3.0",
26
+ "commander": "^12.1.0",
27
27
  "h3-js": "^4.1.0",
28
+ "node-fetch": "^3.3.2",
28
29
  "ora": "^8.0.1",
29
- "chalk": "^5.3.0",
30
- "commander": "^12.1.0"
30
+ "tweetnacl": "^1.0.3",
31
+ "tweetnacl-util": "^0.15.1"
31
32
  },
32
33
  "devDependencies": {
33
- "typescript": "^5.4.5",
34
+ "@types/better-sqlite3": "^7.6.13",
34
35
  "@types/node": "^20.12.0",
35
- "ts-node": "^10.9.2"
36
+ "ts-node": "^10.9.2",
37
+ "typescript": "^5.4.5"
36
38
  },
37
39
  "engines": {
38
40
  "node": ">=18.0.0"
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "@gns-foundation/hive-worker",
3
+ "version": "0.1.11",
4
+ "description": "Turn your device into a GEIANT Hive compute node. Earn GNS tokens.",
5
+ "bin": {
6
+ "hive-worker": "./dist/cli.js"
7
+ },
8
+ "scripts": {
9
+ "build": "tsc",
10
+ "dev": "ts-node src/cli.ts",
11
+ "prepublishOnly": "npm run build"
12
+ },
13
+ "keywords": [
14
+ "geiant",
15
+ "hive",
16
+ "gns",
17
+ "ai",
18
+ "inference",
19
+ "decentralized"
20
+ ],
21
+ "author": "GNS Foundation <cayerbe@ulissy.app>",
22
+ "license": "BSL-1.1",
23
+ "dependencies": {
24
+ "better-sqlite3": "^12.8.0",
25
+ "chalk": "^5.3.0",
26
+ "commander": "^12.1.0",
27
+ "h3-js": "^4.1.0",
28
+ "node-fetch": "^3.3.2",
29
+ "ora": "^8.0.1",
30
+ "tweetnacl": "^1.0.3",
31
+ "tweetnacl-util": "^0.15.1"
32
+ },
33
+ "devDependencies": {
34
+ "@types/better-sqlite3": "^7.6.13",
35
+ "@types/node": "^20.12.0",
36
+ "ts-node": "^10.9.2",
37
+ "typescript": "^5.4.5"
38
+ },
39
+ "engines": {
40
+ "node": ">=18.0.0"
41
+ },
42
+ "type": "module"
43
+ }