@noosphere/registry 0.1.0-alpha.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/README.md +304 -0
- package/dist/index.cjs +235 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.mts +151 -0
- package/dist/index.d.ts +151 -0
- package/dist/index.js +198 -0
- package/dist/index.js.map +1 -0
- package/package.json +60 -0
package/README.md
ADDED
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
# @noosphere/registry
|
|
2
|
+
|
|
3
|
+
Container and Verifier registry manager for Noosphere SDK.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Local Registry**: JSON-based local registry (`.noosphere/registry.json`)
|
|
8
|
+
- **Remote Sync**: Automatically sync from GitHub public registry
|
|
9
|
+
- **Container Discovery**: Find and search compute containers
|
|
10
|
+
- **Verifier Discovery**: Find proof verifiers by contract address
|
|
11
|
+
- **Custom Entries**: Add your own containers and verifiers
|
|
12
|
+
- **Cache Management**: Configurable TTL for remote sync
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install @noosphere/registry
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Usage
|
|
21
|
+
|
|
22
|
+
### Basic Usage
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
import { RegistryManager } from '@noosphere/registry';
|
|
26
|
+
|
|
27
|
+
// Create registry manager
|
|
28
|
+
const registry = new RegistryManager({
|
|
29
|
+
localPath: './.noosphere/registry.json', // Optional
|
|
30
|
+
remotePath: 'https://raw.githubusercontent.com/hpp-io/noosphere-registry/main/registry.json', // Optional
|
|
31
|
+
autoSync: true, // Sync from remote on load
|
|
32
|
+
cacheTTL: 3600000, // 1 hour cache
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
// Load registry
|
|
36
|
+
await registry.load();
|
|
37
|
+
|
|
38
|
+
// Get container by ID
|
|
39
|
+
const container = registry.getContainer('0x123...');
|
|
40
|
+
console.log(container.name); // "stable-diffusion-xl"
|
|
41
|
+
console.log(container.imageName); // "runpod/stable-diffusion"
|
|
42
|
+
console.log(container.requirements); // { gpu: true, memory: "16GB" }
|
|
43
|
+
|
|
44
|
+
// Search containers
|
|
45
|
+
const aiContainers = registry.searchContainers('ai');
|
|
46
|
+
|
|
47
|
+
// List all active containers
|
|
48
|
+
const containers = registry.listContainers();
|
|
49
|
+
|
|
50
|
+
// Get verifier by contract address
|
|
51
|
+
const verifier = registry.getVerifier('0x0165878A594ca255338adfa4d48449f69242Eb8F');
|
|
52
|
+
console.log(verifier.name); // "Immediate Finalize Verifier"
|
|
53
|
+
|
|
54
|
+
// Check if proof generation is required
|
|
55
|
+
if (verifier.requiresProof && verifier.proofService) {
|
|
56
|
+
console.log('Proof service:', verifier.proofService.imageName);
|
|
57
|
+
console.log('Proof service port:', verifier.proofService.port);
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Adding Custom Containers
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
await registry.addContainer({
|
|
65
|
+
id: '0xabc...',
|
|
66
|
+
name: 'my-custom-model',
|
|
67
|
+
imageName: 'myrepo/my-model',
|
|
68
|
+
port: 8000,
|
|
69
|
+
requirements: {
|
|
70
|
+
gpu: true,
|
|
71
|
+
memory: '8GB',
|
|
72
|
+
cpu: 4,
|
|
73
|
+
},
|
|
74
|
+
statusCode: 'ACTIVE',
|
|
75
|
+
description: 'My custom AI model',
|
|
76
|
+
tags: ['ai', 'custom'],
|
|
77
|
+
});
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Adding Custom Verifiers
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
// Verifier with integrated proof generation service
|
|
84
|
+
await registry.addVerifier({
|
|
85
|
+
id: 'custom-verifier-id',
|
|
86
|
+
name: 'My Custom Verifier',
|
|
87
|
+
verifierAddress: '0x222...', // Onchain verifier contract address
|
|
88
|
+
requiresProof: true,
|
|
89
|
+
proofService: {
|
|
90
|
+
imageName: 'myrepo/my-proof-service',
|
|
91
|
+
port: 3000,
|
|
92
|
+
command: 'npm start',
|
|
93
|
+
env: {
|
|
94
|
+
RPC_URL: 'https://...',
|
|
95
|
+
VERIFIER_ADDRESS: '0x222...',
|
|
96
|
+
},
|
|
97
|
+
requirements: {
|
|
98
|
+
memory: '2GB',
|
|
99
|
+
cpu: 2,
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
statusCode: 'ACTIVE',
|
|
103
|
+
description: 'Custom proof verification with integrated proof generation',
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
// Simple verifier without proof generation
|
|
107
|
+
await registry.addVerifier({
|
|
108
|
+
id: 'simple-verifier-id',
|
|
109
|
+
name: 'Simple Verifier',
|
|
110
|
+
verifierAddress: '0x333...',
|
|
111
|
+
requiresProof: false,
|
|
112
|
+
statusCode: 'ACTIVE',
|
|
113
|
+
description: 'Simple verification without proof generation',
|
|
114
|
+
});
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Registry Statistics
|
|
118
|
+
|
|
119
|
+
```typescript
|
|
120
|
+
const stats = registry.getStats();
|
|
121
|
+
console.log(stats);
|
|
122
|
+
// {
|
|
123
|
+
// totalContainers: 10,
|
|
124
|
+
// activeContainers: 8,
|
|
125
|
+
// totalVerifiers: 2,
|
|
126
|
+
// activeVerifiers: 2,
|
|
127
|
+
// lastSync: '2024-12-26T00:00:00.000Z'
|
|
128
|
+
// }
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## Registry Format
|
|
132
|
+
|
|
133
|
+
### Container Metadata
|
|
134
|
+
|
|
135
|
+
```typescript
|
|
136
|
+
interface ContainerMetadata {
|
|
137
|
+
id: string; // Unique ID (keccak256 hash)
|
|
138
|
+
name: string; // Human-readable name
|
|
139
|
+
imageName: string; // Docker image name
|
|
140
|
+
port?: number; // Exposed port
|
|
141
|
+
command?: string; // Docker command
|
|
142
|
+
env?: Record<string, string>; // Environment variables
|
|
143
|
+
volumes?: string[]; // Volume mounts
|
|
144
|
+
requirements?: {
|
|
145
|
+
gpu?: boolean;
|
|
146
|
+
memory?: string; // "16GB"
|
|
147
|
+
cpu?: number;
|
|
148
|
+
};
|
|
149
|
+
payments?: {
|
|
150
|
+
basePrice: string; // "0.01"
|
|
151
|
+
token: string; // "ETH"
|
|
152
|
+
per: string; // "inference"
|
|
153
|
+
};
|
|
154
|
+
statusCode: 'ACTIVE' | 'INACTIVE' | 'DEPRECATED';
|
|
155
|
+
verified?: boolean; // Community verified
|
|
156
|
+
description?: string;
|
|
157
|
+
tags?: string[];
|
|
158
|
+
createdAt?: string;
|
|
159
|
+
updatedAt?: string;
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### Verifier Metadata
|
|
164
|
+
|
|
165
|
+
```typescript
|
|
166
|
+
interface ProofServiceConfig {
|
|
167
|
+
imageName: string; // Docker image for proof generation service
|
|
168
|
+
port: number; // Exposed port
|
|
169
|
+
command?: string; // Docker command
|
|
170
|
+
env?: Record<string, string>; // Environment variables
|
|
171
|
+
volumes?: string[]; // Volume mounts
|
|
172
|
+
requirements?: {
|
|
173
|
+
memory?: string; // "2GB"
|
|
174
|
+
cpu?: number;
|
|
175
|
+
gpu?: boolean;
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
interface VerifierMetadata {
|
|
180
|
+
id: string; // UUID
|
|
181
|
+
name: string;
|
|
182
|
+
verifierAddress: string; // Onchain contract address (used as key)
|
|
183
|
+
requiresProof?: boolean; // Whether this verifier requires proof generation
|
|
184
|
+
proofService?: ProofServiceConfig; // Proof generation service configuration
|
|
185
|
+
|
|
186
|
+
// Deprecated: Use proofService instead
|
|
187
|
+
imageName?: string; // Docker image for proof generation
|
|
188
|
+
port?: number;
|
|
189
|
+
command?: string;
|
|
190
|
+
env?: Record<string, string>;
|
|
191
|
+
volumes?: string[];
|
|
192
|
+
|
|
193
|
+
payments?: {
|
|
194
|
+
basePrice: string;
|
|
195
|
+
token: string;
|
|
196
|
+
per: string;
|
|
197
|
+
};
|
|
198
|
+
statusCode: 'ACTIVE' | 'INACTIVE' | 'DEPRECATED';
|
|
199
|
+
verified?: boolean;
|
|
200
|
+
description?: string;
|
|
201
|
+
createdAt?: string;
|
|
202
|
+
updatedAt?: string;
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
## Working with Proof Generation
|
|
207
|
+
|
|
208
|
+
When a verifier requires proof generation, you'll need to start the proof service container and interact with it:
|
|
209
|
+
|
|
210
|
+
```typescript
|
|
211
|
+
import { RegistryManager } from '@noosphere/registry';
|
|
212
|
+
|
|
213
|
+
// Load registry
|
|
214
|
+
const registry = new RegistryManager();
|
|
215
|
+
await registry.load();
|
|
216
|
+
|
|
217
|
+
// Get verifier for a subscription
|
|
218
|
+
const verifier = registry.getVerifier('0x0165878A594ca255338adfa4d48449f69242Eb8F');
|
|
219
|
+
|
|
220
|
+
// Check if proof generation is required
|
|
221
|
+
if (verifier.requiresProof && verifier.proofService) {
|
|
222
|
+
// Start proof service container
|
|
223
|
+
const proofContainer = await containerManager.start({
|
|
224
|
+
imageName: verifier.proofService.imageName,
|
|
225
|
+
port: verifier.proofService.port,
|
|
226
|
+
command: verifier.proofService.command,
|
|
227
|
+
env: {
|
|
228
|
+
...verifier.proofService.env,
|
|
229
|
+
RPC_URL: process.env.RPC_URL,
|
|
230
|
+
CHAIN_ID: process.env.CHAIN_ID,
|
|
231
|
+
VERIFIER_ADDRESS: verifier.verifierAddress,
|
|
232
|
+
},
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
// Generate proof
|
|
236
|
+
const proof = await fetch(`http://localhost:${verifier.proofService.port}/generate-proof`, {
|
|
237
|
+
method: 'POST',
|
|
238
|
+
headers: { 'Content-Type': 'application/json' },
|
|
239
|
+
body: JSON.stringify({
|
|
240
|
+
requestId,
|
|
241
|
+
subscriptionId,
|
|
242
|
+
interval: commitment.interval,
|
|
243
|
+
output: computeResult,
|
|
244
|
+
}),
|
|
245
|
+
}).then(r => r.json());
|
|
246
|
+
|
|
247
|
+
console.log('Proof generated:', proof);
|
|
248
|
+
// Proof service typically handles on-chain submission automatically
|
|
249
|
+
}
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
See the [community registry integration guide](https://github.com/hpp-io/noosphere-registry/blob/main/VERIFIER_INTEGRATION.md) for complete examples.
|
|
253
|
+
|
|
254
|
+
## Local Registry Path
|
|
255
|
+
|
|
256
|
+
Default: `.noosphere/registry.json`
|
|
257
|
+
|
|
258
|
+
The registry file is automatically created with example entries if it doesn't exist.
|
|
259
|
+
|
|
260
|
+
## Remote Registry
|
|
261
|
+
|
|
262
|
+
Default: `https://raw.githubusercontent.com/hpp-io/noosphere-registry/main/registry.json`
|
|
263
|
+
|
|
264
|
+
The remote registry is a community-maintained list of verified containers and verifiers.
|
|
265
|
+
|
|
266
|
+
### Merge Strategy
|
|
267
|
+
|
|
268
|
+
- Remote entries are added to local registry
|
|
269
|
+
- **Local entries take precedence** (not overwritten by remote)
|
|
270
|
+
- Manual additions are saved locally only
|
|
271
|
+
|
|
272
|
+
## Registry Priority
|
|
273
|
+
|
|
274
|
+
1. **Local registry** (highest priority)
|
|
275
|
+
2. **Remote registry** (synced from GitHub)
|
|
276
|
+
|
|
277
|
+
This allows you to:
|
|
278
|
+
- Use community-verified containers
|
|
279
|
+
- Override remote entries locally
|
|
280
|
+
- Add private/custom containers
|
|
281
|
+
|
|
282
|
+
## Example Registry
|
|
283
|
+
|
|
284
|
+
See `examples/registry-example.json` for a complete example with:
|
|
285
|
+
- Echo service (for testing)
|
|
286
|
+
- Stable Diffusion XL (image generation)
|
|
287
|
+
- Llama 3 8B (text generation)
|
|
288
|
+
- Whisper Large V3 (speech-to-text)
|
|
289
|
+
- ZK-SNARK verifiers
|
|
290
|
+
|
|
291
|
+
## Contributing
|
|
292
|
+
|
|
293
|
+
To contribute containers/verifiers to the public registry:
|
|
294
|
+
|
|
295
|
+
1. Fork `hpp-io/noosphere-registry`
|
|
296
|
+
2. Add your entry to `registry.json`
|
|
297
|
+
3. Submit a pull request with:
|
|
298
|
+
- Container/Verifier metadata
|
|
299
|
+
- Verification that it works
|
|
300
|
+
- Documentation
|
|
301
|
+
|
|
302
|
+
## License
|
|
303
|
+
|
|
304
|
+
MIT
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.ts
|
|
31
|
+
var index_exports = {};
|
|
32
|
+
__export(index_exports, {
|
|
33
|
+
RegistryManager: () => RegistryManager
|
|
34
|
+
});
|
|
35
|
+
module.exports = __toCommonJS(index_exports);
|
|
36
|
+
|
|
37
|
+
// src/RegistryManager.ts
|
|
38
|
+
var import_promises = __toESM(require("fs/promises"));
|
|
39
|
+
var import_path = __toESM(require("path"));
|
|
40
|
+
var import_node_fetch = __toESM(require("node-fetch"));
|
|
41
|
+
var RegistryManager = class {
|
|
42
|
+
constructor(config = {}) {
|
|
43
|
+
this.containers = /* @__PURE__ */ new Map();
|
|
44
|
+
this.verifiers = /* @__PURE__ */ new Map();
|
|
45
|
+
this.lastSync = 0;
|
|
46
|
+
this.config = {
|
|
47
|
+
localPath: config.localPath || import_path.default.join(process.cwd(), ".noosphere", "registry.json"),
|
|
48
|
+
remotePath: config.remotePath || "https://raw.githubusercontent.com/hpp-io/noosphere-registry/main/registry.json",
|
|
49
|
+
autoSync: config.autoSync ?? true,
|
|
50
|
+
cacheTTL: config.cacheTTL || 36e5
|
|
51
|
+
// 1 hour default
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Load registry from local and optionally sync from remote
|
|
56
|
+
*/
|
|
57
|
+
async load() {
|
|
58
|
+
await this.loadLocal();
|
|
59
|
+
if (this.config.autoSync) {
|
|
60
|
+
try {
|
|
61
|
+
await this.sync();
|
|
62
|
+
} catch (error) {
|
|
63
|
+
console.warn("Failed to sync remote registry:", error);
|
|
64
|
+
console.log("Continuing with local registry only");
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
console.log(`\u2713 Loaded ${this.containers.size} containers and ${this.verifiers.size} verifiers`);
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Load local registry file
|
|
71
|
+
*/
|
|
72
|
+
async loadLocal() {
|
|
73
|
+
try {
|
|
74
|
+
const data = await import_promises.default.readFile(this.config.localPath, "utf-8");
|
|
75
|
+
const registry = JSON.parse(data);
|
|
76
|
+
Object.entries(registry.containers || {}).forEach(([id, metadata]) => {
|
|
77
|
+
this.containers.set(id, metadata);
|
|
78
|
+
});
|
|
79
|
+
Object.entries(registry.verifiers || {}).forEach(([id, metadata]) => {
|
|
80
|
+
this.verifiers.set(id, metadata);
|
|
81
|
+
});
|
|
82
|
+
console.log(`\u2713 Loaded local registry from ${this.config.localPath}`);
|
|
83
|
+
} catch (error) {
|
|
84
|
+
if (error.code === "ENOENT") {
|
|
85
|
+
console.log("No local registry found, will create default");
|
|
86
|
+
await this.createDefaultRegistry();
|
|
87
|
+
} else {
|
|
88
|
+
throw error;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Sync registry from remote GitHub repository
|
|
94
|
+
*/
|
|
95
|
+
async sync() {
|
|
96
|
+
const now = Date.now();
|
|
97
|
+
if (now - this.lastSync < this.config.cacheTTL) {
|
|
98
|
+
console.log("Registry cache is fresh, skipping sync");
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
console.log(`Syncing registry from ${this.config.remotePath}...`);
|
|
102
|
+
try {
|
|
103
|
+
const response = await (0, import_node_fetch.default)(this.config.remotePath);
|
|
104
|
+
if (!response.ok) {
|
|
105
|
+
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
106
|
+
}
|
|
107
|
+
const registry = await response.json();
|
|
108
|
+
Object.entries(registry.containers || {}).forEach(([id, metadata]) => {
|
|
109
|
+
if (!this.containers.has(id)) {
|
|
110
|
+
this.containers.set(id, metadata);
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
Object.entries(registry.verifiers || {}).forEach(([id, metadata]) => {
|
|
114
|
+
if (!this.verifiers.has(id)) {
|
|
115
|
+
this.verifiers.set(id, metadata);
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
this.lastSync = now;
|
|
119
|
+
console.log(`\u2713 Synced registry (version: ${registry.version})`);
|
|
120
|
+
} catch (error) {
|
|
121
|
+
console.error("Failed to sync remote registry:", error);
|
|
122
|
+
throw error;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Get container by ID
|
|
127
|
+
*/
|
|
128
|
+
getContainer(id) {
|
|
129
|
+
return this.containers.get(id);
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Get all containers
|
|
133
|
+
*/
|
|
134
|
+
listContainers() {
|
|
135
|
+
return Array.from(this.containers.values()).filter((c) => c.statusCode === "ACTIVE");
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Search containers by name or tag
|
|
139
|
+
*/
|
|
140
|
+
searchContainers(query) {
|
|
141
|
+
const lowerQuery = query.toLowerCase();
|
|
142
|
+
return this.listContainers().filter(
|
|
143
|
+
(c) => c.name.toLowerCase().includes(lowerQuery) || c.description?.toLowerCase().includes(lowerQuery) || c.tags?.some((tag) => tag.toLowerCase().includes(lowerQuery))
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Get verifier by contract address
|
|
148
|
+
*/
|
|
149
|
+
getVerifier(verifierAddress) {
|
|
150
|
+
return this.verifiers.get(verifierAddress);
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Get verifier by ID
|
|
154
|
+
*/
|
|
155
|
+
getVerifierById(id) {
|
|
156
|
+
return Array.from(this.verifiers.values()).find((v) => v.id === id);
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Get all verifiers
|
|
160
|
+
*/
|
|
161
|
+
listVerifiers() {
|
|
162
|
+
return Array.from(this.verifiers.values()).filter((v) => v.statusCode === "ACTIVE");
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Add custom container to local registry
|
|
166
|
+
*/
|
|
167
|
+
async addContainer(container) {
|
|
168
|
+
this.containers.set(container.id, container);
|
|
169
|
+
await this.saveLocal();
|
|
170
|
+
console.log(`\u2713 Added container: ${container.name} (${container.id})`);
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Add custom verifier to local registry
|
|
174
|
+
*/
|
|
175
|
+
async addVerifier(verifier) {
|
|
176
|
+
this.verifiers.set(verifier.verifierAddress, verifier);
|
|
177
|
+
await this.saveLocal();
|
|
178
|
+
console.log(`\u2713 Added verifier: ${verifier.name} (${verifier.verifierAddress})`);
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Remove container from local registry
|
|
182
|
+
*/
|
|
183
|
+
async removeContainer(id) {
|
|
184
|
+
if (this.containers.delete(id)) {
|
|
185
|
+
await this.saveLocal();
|
|
186
|
+
console.log(`\u2713 Removed container: ${id}`);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Remove verifier from local registry
|
|
191
|
+
*/
|
|
192
|
+
async removeVerifier(verifierAddress) {
|
|
193
|
+
if (this.verifiers.delete(verifierAddress)) {
|
|
194
|
+
await this.saveLocal();
|
|
195
|
+
console.log(`\u2713 Removed verifier: ${verifierAddress}`);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Save local registry to disk
|
|
200
|
+
*/
|
|
201
|
+
async saveLocal() {
|
|
202
|
+
const registry = {
|
|
203
|
+
containers: Object.fromEntries(this.containers),
|
|
204
|
+
verifiers: Object.fromEntries(this.verifiers),
|
|
205
|
+
version: "1.0.0",
|
|
206
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
207
|
+
};
|
|
208
|
+
await import_promises.default.mkdir(import_path.default.dirname(this.config.localPath), { recursive: true });
|
|
209
|
+
await import_promises.default.writeFile(this.config.localPath, JSON.stringify(registry, null, 2));
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Create default registry with example entries
|
|
213
|
+
*/
|
|
214
|
+
async createDefaultRegistry() {
|
|
215
|
+
await this.saveLocal();
|
|
216
|
+
console.log("\u2713 Created empty local registry (will sync from remote)");
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Get registry statistics
|
|
220
|
+
*/
|
|
221
|
+
getStats() {
|
|
222
|
+
return {
|
|
223
|
+
totalContainers: this.containers.size,
|
|
224
|
+
activeContainers: this.listContainers().length,
|
|
225
|
+
totalVerifiers: this.verifiers.size,
|
|
226
|
+
activeVerifiers: this.listVerifiers().length,
|
|
227
|
+
lastSync: this.lastSync ? new Date(this.lastSync).toISOString() : "Never"
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
232
|
+
0 && (module.exports = {
|
|
233
|
+
RegistryManager
|
|
234
|
+
});
|
|
235
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/RegistryManager.ts"],"sourcesContent":["export { RegistryManager } from './RegistryManager';\nexport * from './types';\n","import fs from 'fs/promises';\nimport path from 'path';\nimport fetch from 'node-fetch';\nimport type { ContainerMetadata, VerifierMetadata, RegistryConfig, RegistryIndex } from './types';\n\nexport class RegistryManager {\n private containers = new Map<string, ContainerMetadata>();\n private verifiers = new Map<string, VerifierMetadata>();\n private config: Required<RegistryConfig>;\n private lastSync: number = 0;\n\n constructor(config: RegistryConfig = {}) {\n this.config = {\n localPath: config.localPath || path.join(process.cwd(), '.noosphere', 'registry.json'),\n remotePath:\n config.remotePath ||\n 'https://raw.githubusercontent.com/hpp-io/noosphere-registry/main/registry.json',\n autoSync: config.autoSync ?? true,\n cacheTTL: config.cacheTTL || 3600000, // 1 hour default\n };\n }\n\n /**\n * Load registry from local and optionally sync from remote\n */\n async load(): Promise<void> {\n // Load local registry\n await this.loadLocal();\n\n // Sync from remote if enabled\n if (this.config.autoSync) {\n try {\n await this.sync();\n } catch (error) {\n console.warn('Failed to sync remote registry:', error);\n console.log('Continuing with local registry only');\n }\n }\n\n console.log(`✓ Loaded ${this.containers.size} containers and ${this.verifiers.size} verifiers`);\n }\n\n /**\n * Load local registry file\n */\n private async loadLocal(): Promise<void> {\n try {\n const data = await fs.readFile(this.config.localPath, 'utf-8');\n const registry: RegistryIndex = JSON.parse(data);\n\n // Load containers\n Object.entries(registry.containers || {}).forEach(([id, metadata]) => {\n this.containers.set(id, metadata);\n });\n\n // Load verifiers\n Object.entries(registry.verifiers || {}).forEach(([id, metadata]) => {\n this.verifiers.set(id, metadata);\n });\n\n console.log(`✓ Loaded local registry from ${this.config.localPath}`);\n } catch (error: any) {\n if (error.code === 'ENOENT') {\n console.log('No local registry found, will create default');\n await this.createDefaultRegistry();\n } else {\n throw error;\n }\n }\n }\n\n /**\n * Sync registry from remote GitHub repository\n */\n async sync(): Promise<void> {\n const now = Date.now();\n\n // Check cache TTL\n if (now - this.lastSync < this.config.cacheTTL) {\n console.log('Registry cache is fresh, skipping sync');\n return;\n }\n\n console.log(`Syncing registry from ${this.config.remotePath}...`);\n\n try {\n const response = await fetch(this.config.remotePath);\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n\n const registry = (await response.json()) as RegistryIndex;\n\n // Merge remote registry (remote entries are added, local overrides are kept)\n Object.entries(registry.containers || {}).forEach(([id, metadata]) => {\n if (!this.containers.has(id)) {\n // Only add if not already in local registry (local takes precedence)\n this.containers.set(id, metadata);\n }\n });\n\n Object.entries(registry.verifiers || {}).forEach(([id, metadata]) => {\n if (!this.verifiers.has(id)) {\n this.verifiers.set(id, metadata);\n }\n });\n\n this.lastSync = now;\n console.log(`✓ Synced registry (version: ${registry.version})`);\n } catch (error) {\n console.error('Failed to sync remote registry:', error);\n throw error;\n }\n }\n\n /**\n * Get container by ID\n */\n getContainer(id: string): ContainerMetadata | undefined {\n return this.containers.get(id);\n }\n\n /**\n * Get all containers\n */\n listContainers(): ContainerMetadata[] {\n return Array.from(this.containers.values()).filter((c) => c.statusCode === 'ACTIVE');\n }\n\n /**\n * Search containers by name or tag\n */\n searchContainers(query: string): ContainerMetadata[] {\n const lowerQuery = query.toLowerCase();\n return this.listContainers().filter(\n (c) =>\n c.name.toLowerCase().includes(lowerQuery) ||\n c.description?.toLowerCase().includes(lowerQuery) ||\n c.tags?.some((tag) => tag.toLowerCase().includes(lowerQuery))\n );\n }\n\n /**\n * Get verifier by contract address\n */\n getVerifier(verifierAddress: string): VerifierMetadata | undefined {\n return this.verifiers.get(verifierAddress);\n }\n\n /**\n * Get verifier by ID\n */\n getVerifierById(id: string): VerifierMetadata | undefined {\n return Array.from(this.verifiers.values()).find((v) => v.id === id);\n }\n\n /**\n * Get all verifiers\n */\n listVerifiers(): VerifierMetadata[] {\n return Array.from(this.verifiers.values()).filter((v) => v.statusCode === 'ACTIVE');\n }\n\n /**\n * Add custom container to local registry\n */\n async addContainer(container: ContainerMetadata): Promise<void> {\n this.containers.set(container.id, container);\n await this.saveLocal();\n console.log(`✓ Added container: ${container.name} (${container.id})`);\n }\n\n /**\n * Add custom verifier to local registry\n */\n async addVerifier(verifier: VerifierMetadata): Promise<void> {\n this.verifiers.set(verifier.verifierAddress, verifier);\n await this.saveLocal();\n console.log(`✓ Added verifier: ${verifier.name} (${verifier.verifierAddress})`);\n }\n\n /**\n * Remove container from local registry\n */\n async removeContainer(id: string): Promise<void> {\n if (this.containers.delete(id)) {\n await this.saveLocal();\n console.log(`✓ Removed container: ${id}`);\n }\n }\n\n /**\n * Remove verifier from local registry\n */\n async removeVerifier(verifierAddress: string): Promise<void> {\n if (this.verifiers.delete(verifierAddress)) {\n await this.saveLocal();\n console.log(`✓ Removed verifier: ${verifierAddress}`);\n }\n }\n\n /**\n * Save local registry to disk\n */\n private async saveLocal(): Promise<void> {\n const registry: RegistryIndex = {\n containers: Object.fromEntries(this.containers),\n verifiers: Object.fromEntries(this.verifiers),\n version: '1.0.0',\n updatedAt: new Date().toISOString(),\n };\n\n await fs.mkdir(path.dirname(this.config.localPath), { recursive: true });\n await fs.writeFile(this.config.localPath, JSON.stringify(registry, null, 2));\n }\n\n /**\n * Create default registry with example entries\n */\n private async createDefaultRegistry(): Promise<void> {\n // Create empty registry - will be populated from remote sync\n // No default containers or verifiers\n await this.saveLocal();\n console.log('✓ Created empty local registry (will sync from remote)');\n }\n\n /**\n * Get registry statistics\n */\n getStats(): {\n totalContainers: number;\n activeContainers: number;\n totalVerifiers: number;\n activeVerifiers: number;\n lastSync: string;\n } {\n return {\n totalContainers: this.containers.size,\n activeContainers: this.listContainers().length,\n totalVerifiers: this.verifiers.size,\n activeVerifiers: this.listVerifiers().length,\n lastSync: this.lastSync ? new Date(this.lastSync).toISOString() : 'Never',\n };\n }\n}\n"],"mappings":"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","names":["path","fs","fetch"]}
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
interface ContainerMetadata {
|
|
2
|
+
id: string;
|
|
3
|
+
name: string;
|
|
4
|
+
imageName: string;
|
|
5
|
+
port?: number;
|
|
6
|
+
command?: string;
|
|
7
|
+
env?: Record<string, string>;
|
|
8
|
+
volumes?: string[];
|
|
9
|
+
payments?: {
|
|
10
|
+
basePrice: string;
|
|
11
|
+
token: string;
|
|
12
|
+
per: string;
|
|
13
|
+
};
|
|
14
|
+
requirements?: {
|
|
15
|
+
memory?: string;
|
|
16
|
+
cpu?: number;
|
|
17
|
+
gpu?: boolean;
|
|
18
|
+
};
|
|
19
|
+
statusCode: 'ACTIVE' | 'INACTIVE' | 'DEPRECATED';
|
|
20
|
+
verified?: boolean;
|
|
21
|
+
createdAt?: string;
|
|
22
|
+
updatedAt?: string;
|
|
23
|
+
description?: string;
|
|
24
|
+
tags?: string[];
|
|
25
|
+
}
|
|
26
|
+
interface ProofServiceConfig {
|
|
27
|
+
imageName: string;
|
|
28
|
+
port: number;
|
|
29
|
+
command?: string;
|
|
30
|
+
env?: Record<string, string>;
|
|
31
|
+
volumes?: string[];
|
|
32
|
+
requirements?: {
|
|
33
|
+
memory?: string;
|
|
34
|
+
cpu?: number;
|
|
35
|
+
gpu?: boolean;
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
interface VerifierMetadata {
|
|
39
|
+
id: string;
|
|
40
|
+
name: string;
|
|
41
|
+
verifierAddress: string;
|
|
42
|
+
requiresProof?: boolean;
|
|
43
|
+
proofService?: ProofServiceConfig;
|
|
44
|
+
imageName?: string;
|
|
45
|
+
port?: number;
|
|
46
|
+
command?: string;
|
|
47
|
+
env?: Record<string, string>;
|
|
48
|
+
volumes?: string[];
|
|
49
|
+
payments?: {
|
|
50
|
+
basePrice: string;
|
|
51
|
+
token: string;
|
|
52
|
+
per: string;
|
|
53
|
+
};
|
|
54
|
+
statusCode: 'ACTIVE' | 'INACTIVE' | 'DEPRECATED';
|
|
55
|
+
verified?: boolean;
|
|
56
|
+
createdAt?: string;
|
|
57
|
+
updatedAt?: string;
|
|
58
|
+
description?: string;
|
|
59
|
+
}
|
|
60
|
+
interface RegistryConfig {
|
|
61
|
+
localPath?: string;
|
|
62
|
+
remotePath?: string;
|
|
63
|
+
autoSync?: boolean;
|
|
64
|
+
cacheTTL?: number;
|
|
65
|
+
}
|
|
66
|
+
interface RegistryIndex {
|
|
67
|
+
containers: Record<string, ContainerMetadata>;
|
|
68
|
+
verifiers: Record<string, VerifierMetadata>;
|
|
69
|
+
version: string;
|
|
70
|
+
updatedAt: string;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
declare class RegistryManager {
|
|
74
|
+
private containers;
|
|
75
|
+
private verifiers;
|
|
76
|
+
private config;
|
|
77
|
+
private lastSync;
|
|
78
|
+
constructor(config?: RegistryConfig);
|
|
79
|
+
/**
|
|
80
|
+
* Load registry from local and optionally sync from remote
|
|
81
|
+
*/
|
|
82
|
+
load(): Promise<void>;
|
|
83
|
+
/**
|
|
84
|
+
* Load local registry file
|
|
85
|
+
*/
|
|
86
|
+
private loadLocal;
|
|
87
|
+
/**
|
|
88
|
+
* Sync registry from remote GitHub repository
|
|
89
|
+
*/
|
|
90
|
+
sync(): Promise<void>;
|
|
91
|
+
/**
|
|
92
|
+
* Get container by ID
|
|
93
|
+
*/
|
|
94
|
+
getContainer(id: string): ContainerMetadata | undefined;
|
|
95
|
+
/**
|
|
96
|
+
* Get all containers
|
|
97
|
+
*/
|
|
98
|
+
listContainers(): ContainerMetadata[];
|
|
99
|
+
/**
|
|
100
|
+
* Search containers by name or tag
|
|
101
|
+
*/
|
|
102
|
+
searchContainers(query: string): ContainerMetadata[];
|
|
103
|
+
/**
|
|
104
|
+
* Get verifier by contract address
|
|
105
|
+
*/
|
|
106
|
+
getVerifier(verifierAddress: string): VerifierMetadata | undefined;
|
|
107
|
+
/**
|
|
108
|
+
* Get verifier by ID
|
|
109
|
+
*/
|
|
110
|
+
getVerifierById(id: string): VerifierMetadata | undefined;
|
|
111
|
+
/**
|
|
112
|
+
* Get all verifiers
|
|
113
|
+
*/
|
|
114
|
+
listVerifiers(): VerifierMetadata[];
|
|
115
|
+
/**
|
|
116
|
+
* Add custom container to local registry
|
|
117
|
+
*/
|
|
118
|
+
addContainer(container: ContainerMetadata): Promise<void>;
|
|
119
|
+
/**
|
|
120
|
+
* Add custom verifier to local registry
|
|
121
|
+
*/
|
|
122
|
+
addVerifier(verifier: VerifierMetadata): Promise<void>;
|
|
123
|
+
/**
|
|
124
|
+
* Remove container from local registry
|
|
125
|
+
*/
|
|
126
|
+
removeContainer(id: string): Promise<void>;
|
|
127
|
+
/**
|
|
128
|
+
* Remove verifier from local registry
|
|
129
|
+
*/
|
|
130
|
+
removeVerifier(verifierAddress: string): Promise<void>;
|
|
131
|
+
/**
|
|
132
|
+
* Save local registry to disk
|
|
133
|
+
*/
|
|
134
|
+
private saveLocal;
|
|
135
|
+
/**
|
|
136
|
+
* Create default registry with example entries
|
|
137
|
+
*/
|
|
138
|
+
private createDefaultRegistry;
|
|
139
|
+
/**
|
|
140
|
+
* Get registry statistics
|
|
141
|
+
*/
|
|
142
|
+
getStats(): {
|
|
143
|
+
totalContainers: number;
|
|
144
|
+
activeContainers: number;
|
|
145
|
+
totalVerifiers: number;
|
|
146
|
+
activeVerifiers: number;
|
|
147
|
+
lastSync: string;
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export { type ContainerMetadata, type ProofServiceConfig, type RegistryConfig, type RegistryIndex, RegistryManager, type VerifierMetadata };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
interface ContainerMetadata {
|
|
2
|
+
id: string;
|
|
3
|
+
name: string;
|
|
4
|
+
imageName: string;
|
|
5
|
+
port?: number;
|
|
6
|
+
command?: string;
|
|
7
|
+
env?: Record<string, string>;
|
|
8
|
+
volumes?: string[];
|
|
9
|
+
payments?: {
|
|
10
|
+
basePrice: string;
|
|
11
|
+
token: string;
|
|
12
|
+
per: string;
|
|
13
|
+
};
|
|
14
|
+
requirements?: {
|
|
15
|
+
memory?: string;
|
|
16
|
+
cpu?: number;
|
|
17
|
+
gpu?: boolean;
|
|
18
|
+
};
|
|
19
|
+
statusCode: 'ACTIVE' | 'INACTIVE' | 'DEPRECATED';
|
|
20
|
+
verified?: boolean;
|
|
21
|
+
createdAt?: string;
|
|
22
|
+
updatedAt?: string;
|
|
23
|
+
description?: string;
|
|
24
|
+
tags?: string[];
|
|
25
|
+
}
|
|
26
|
+
interface ProofServiceConfig {
|
|
27
|
+
imageName: string;
|
|
28
|
+
port: number;
|
|
29
|
+
command?: string;
|
|
30
|
+
env?: Record<string, string>;
|
|
31
|
+
volumes?: string[];
|
|
32
|
+
requirements?: {
|
|
33
|
+
memory?: string;
|
|
34
|
+
cpu?: number;
|
|
35
|
+
gpu?: boolean;
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
interface VerifierMetadata {
|
|
39
|
+
id: string;
|
|
40
|
+
name: string;
|
|
41
|
+
verifierAddress: string;
|
|
42
|
+
requiresProof?: boolean;
|
|
43
|
+
proofService?: ProofServiceConfig;
|
|
44
|
+
imageName?: string;
|
|
45
|
+
port?: number;
|
|
46
|
+
command?: string;
|
|
47
|
+
env?: Record<string, string>;
|
|
48
|
+
volumes?: string[];
|
|
49
|
+
payments?: {
|
|
50
|
+
basePrice: string;
|
|
51
|
+
token: string;
|
|
52
|
+
per: string;
|
|
53
|
+
};
|
|
54
|
+
statusCode: 'ACTIVE' | 'INACTIVE' | 'DEPRECATED';
|
|
55
|
+
verified?: boolean;
|
|
56
|
+
createdAt?: string;
|
|
57
|
+
updatedAt?: string;
|
|
58
|
+
description?: string;
|
|
59
|
+
}
|
|
60
|
+
interface RegistryConfig {
|
|
61
|
+
localPath?: string;
|
|
62
|
+
remotePath?: string;
|
|
63
|
+
autoSync?: boolean;
|
|
64
|
+
cacheTTL?: number;
|
|
65
|
+
}
|
|
66
|
+
interface RegistryIndex {
|
|
67
|
+
containers: Record<string, ContainerMetadata>;
|
|
68
|
+
verifiers: Record<string, VerifierMetadata>;
|
|
69
|
+
version: string;
|
|
70
|
+
updatedAt: string;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
declare class RegistryManager {
|
|
74
|
+
private containers;
|
|
75
|
+
private verifiers;
|
|
76
|
+
private config;
|
|
77
|
+
private lastSync;
|
|
78
|
+
constructor(config?: RegistryConfig);
|
|
79
|
+
/**
|
|
80
|
+
* Load registry from local and optionally sync from remote
|
|
81
|
+
*/
|
|
82
|
+
load(): Promise<void>;
|
|
83
|
+
/**
|
|
84
|
+
* Load local registry file
|
|
85
|
+
*/
|
|
86
|
+
private loadLocal;
|
|
87
|
+
/**
|
|
88
|
+
* Sync registry from remote GitHub repository
|
|
89
|
+
*/
|
|
90
|
+
sync(): Promise<void>;
|
|
91
|
+
/**
|
|
92
|
+
* Get container by ID
|
|
93
|
+
*/
|
|
94
|
+
getContainer(id: string): ContainerMetadata | undefined;
|
|
95
|
+
/**
|
|
96
|
+
* Get all containers
|
|
97
|
+
*/
|
|
98
|
+
listContainers(): ContainerMetadata[];
|
|
99
|
+
/**
|
|
100
|
+
* Search containers by name or tag
|
|
101
|
+
*/
|
|
102
|
+
searchContainers(query: string): ContainerMetadata[];
|
|
103
|
+
/**
|
|
104
|
+
* Get verifier by contract address
|
|
105
|
+
*/
|
|
106
|
+
getVerifier(verifierAddress: string): VerifierMetadata | undefined;
|
|
107
|
+
/**
|
|
108
|
+
* Get verifier by ID
|
|
109
|
+
*/
|
|
110
|
+
getVerifierById(id: string): VerifierMetadata | undefined;
|
|
111
|
+
/**
|
|
112
|
+
* Get all verifiers
|
|
113
|
+
*/
|
|
114
|
+
listVerifiers(): VerifierMetadata[];
|
|
115
|
+
/**
|
|
116
|
+
* Add custom container to local registry
|
|
117
|
+
*/
|
|
118
|
+
addContainer(container: ContainerMetadata): Promise<void>;
|
|
119
|
+
/**
|
|
120
|
+
* Add custom verifier to local registry
|
|
121
|
+
*/
|
|
122
|
+
addVerifier(verifier: VerifierMetadata): Promise<void>;
|
|
123
|
+
/**
|
|
124
|
+
* Remove container from local registry
|
|
125
|
+
*/
|
|
126
|
+
removeContainer(id: string): Promise<void>;
|
|
127
|
+
/**
|
|
128
|
+
* Remove verifier from local registry
|
|
129
|
+
*/
|
|
130
|
+
removeVerifier(verifierAddress: string): Promise<void>;
|
|
131
|
+
/**
|
|
132
|
+
* Save local registry to disk
|
|
133
|
+
*/
|
|
134
|
+
private saveLocal;
|
|
135
|
+
/**
|
|
136
|
+
* Create default registry with example entries
|
|
137
|
+
*/
|
|
138
|
+
private createDefaultRegistry;
|
|
139
|
+
/**
|
|
140
|
+
* Get registry statistics
|
|
141
|
+
*/
|
|
142
|
+
getStats(): {
|
|
143
|
+
totalContainers: number;
|
|
144
|
+
activeContainers: number;
|
|
145
|
+
totalVerifiers: number;
|
|
146
|
+
activeVerifiers: number;
|
|
147
|
+
lastSync: string;
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export { type ContainerMetadata, type ProofServiceConfig, type RegistryConfig, type RegistryIndex, RegistryManager, type VerifierMetadata };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
// src/RegistryManager.ts
|
|
2
|
+
import fs from "fs/promises";
|
|
3
|
+
import path from "path";
|
|
4
|
+
import fetch from "node-fetch";
|
|
5
|
+
var RegistryManager = class {
|
|
6
|
+
constructor(config = {}) {
|
|
7
|
+
this.containers = /* @__PURE__ */ new Map();
|
|
8
|
+
this.verifiers = /* @__PURE__ */ new Map();
|
|
9
|
+
this.lastSync = 0;
|
|
10
|
+
this.config = {
|
|
11
|
+
localPath: config.localPath || path.join(process.cwd(), ".noosphere", "registry.json"),
|
|
12
|
+
remotePath: config.remotePath || "https://raw.githubusercontent.com/hpp-io/noosphere-registry/main/registry.json",
|
|
13
|
+
autoSync: config.autoSync ?? true,
|
|
14
|
+
cacheTTL: config.cacheTTL || 36e5
|
|
15
|
+
// 1 hour default
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Load registry from local and optionally sync from remote
|
|
20
|
+
*/
|
|
21
|
+
async load() {
|
|
22
|
+
await this.loadLocal();
|
|
23
|
+
if (this.config.autoSync) {
|
|
24
|
+
try {
|
|
25
|
+
await this.sync();
|
|
26
|
+
} catch (error) {
|
|
27
|
+
console.warn("Failed to sync remote registry:", error);
|
|
28
|
+
console.log("Continuing with local registry only");
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
console.log(`\u2713 Loaded ${this.containers.size} containers and ${this.verifiers.size} verifiers`);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Load local registry file
|
|
35
|
+
*/
|
|
36
|
+
async loadLocal() {
|
|
37
|
+
try {
|
|
38
|
+
const data = await fs.readFile(this.config.localPath, "utf-8");
|
|
39
|
+
const registry = JSON.parse(data);
|
|
40
|
+
Object.entries(registry.containers || {}).forEach(([id, metadata]) => {
|
|
41
|
+
this.containers.set(id, metadata);
|
|
42
|
+
});
|
|
43
|
+
Object.entries(registry.verifiers || {}).forEach(([id, metadata]) => {
|
|
44
|
+
this.verifiers.set(id, metadata);
|
|
45
|
+
});
|
|
46
|
+
console.log(`\u2713 Loaded local registry from ${this.config.localPath}`);
|
|
47
|
+
} catch (error) {
|
|
48
|
+
if (error.code === "ENOENT") {
|
|
49
|
+
console.log("No local registry found, will create default");
|
|
50
|
+
await this.createDefaultRegistry();
|
|
51
|
+
} else {
|
|
52
|
+
throw error;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Sync registry from remote GitHub repository
|
|
58
|
+
*/
|
|
59
|
+
async sync() {
|
|
60
|
+
const now = Date.now();
|
|
61
|
+
if (now - this.lastSync < this.config.cacheTTL) {
|
|
62
|
+
console.log("Registry cache is fresh, skipping sync");
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
console.log(`Syncing registry from ${this.config.remotePath}...`);
|
|
66
|
+
try {
|
|
67
|
+
const response = await fetch(this.config.remotePath);
|
|
68
|
+
if (!response.ok) {
|
|
69
|
+
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
70
|
+
}
|
|
71
|
+
const registry = await response.json();
|
|
72
|
+
Object.entries(registry.containers || {}).forEach(([id, metadata]) => {
|
|
73
|
+
if (!this.containers.has(id)) {
|
|
74
|
+
this.containers.set(id, metadata);
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
Object.entries(registry.verifiers || {}).forEach(([id, metadata]) => {
|
|
78
|
+
if (!this.verifiers.has(id)) {
|
|
79
|
+
this.verifiers.set(id, metadata);
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
this.lastSync = now;
|
|
83
|
+
console.log(`\u2713 Synced registry (version: ${registry.version})`);
|
|
84
|
+
} catch (error) {
|
|
85
|
+
console.error("Failed to sync remote registry:", error);
|
|
86
|
+
throw error;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Get container by ID
|
|
91
|
+
*/
|
|
92
|
+
getContainer(id) {
|
|
93
|
+
return this.containers.get(id);
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Get all containers
|
|
97
|
+
*/
|
|
98
|
+
listContainers() {
|
|
99
|
+
return Array.from(this.containers.values()).filter((c) => c.statusCode === "ACTIVE");
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Search containers by name or tag
|
|
103
|
+
*/
|
|
104
|
+
searchContainers(query) {
|
|
105
|
+
const lowerQuery = query.toLowerCase();
|
|
106
|
+
return this.listContainers().filter(
|
|
107
|
+
(c) => c.name.toLowerCase().includes(lowerQuery) || c.description?.toLowerCase().includes(lowerQuery) || c.tags?.some((tag) => tag.toLowerCase().includes(lowerQuery))
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Get verifier by contract address
|
|
112
|
+
*/
|
|
113
|
+
getVerifier(verifierAddress) {
|
|
114
|
+
return this.verifiers.get(verifierAddress);
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Get verifier by ID
|
|
118
|
+
*/
|
|
119
|
+
getVerifierById(id) {
|
|
120
|
+
return Array.from(this.verifiers.values()).find((v) => v.id === id);
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Get all verifiers
|
|
124
|
+
*/
|
|
125
|
+
listVerifiers() {
|
|
126
|
+
return Array.from(this.verifiers.values()).filter((v) => v.statusCode === "ACTIVE");
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Add custom container to local registry
|
|
130
|
+
*/
|
|
131
|
+
async addContainer(container) {
|
|
132
|
+
this.containers.set(container.id, container);
|
|
133
|
+
await this.saveLocal();
|
|
134
|
+
console.log(`\u2713 Added container: ${container.name} (${container.id})`);
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Add custom verifier to local registry
|
|
138
|
+
*/
|
|
139
|
+
async addVerifier(verifier) {
|
|
140
|
+
this.verifiers.set(verifier.verifierAddress, verifier);
|
|
141
|
+
await this.saveLocal();
|
|
142
|
+
console.log(`\u2713 Added verifier: ${verifier.name} (${verifier.verifierAddress})`);
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Remove container from local registry
|
|
146
|
+
*/
|
|
147
|
+
async removeContainer(id) {
|
|
148
|
+
if (this.containers.delete(id)) {
|
|
149
|
+
await this.saveLocal();
|
|
150
|
+
console.log(`\u2713 Removed container: ${id}`);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Remove verifier from local registry
|
|
155
|
+
*/
|
|
156
|
+
async removeVerifier(verifierAddress) {
|
|
157
|
+
if (this.verifiers.delete(verifierAddress)) {
|
|
158
|
+
await this.saveLocal();
|
|
159
|
+
console.log(`\u2713 Removed verifier: ${verifierAddress}`);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Save local registry to disk
|
|
164
|
+
*/
|
|
165
|
+
async saveLocal() {
|
|
166
|
+
const registry = {
|
|
167
|
+
containers: Object.fromEntries(this.containers),
|
|
168
|
+
verifiers: Object.fromEntries(this.verifiers),
|
|
169
|
+
version: "1.0.0",
|
|
170
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
171
|
+
};
|
|
172
|
+
await fs.mkdir(path.dirname(this.config.localPath), { recursive: true });
|
|
173
|
+
await fs.writeFile(this.config.localPath, JSON.stringify(registry, null, 2));
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Create default registry with example entries
|
|
177
|
+
*/
|
|
178
|
+
async createDefaultRegistry() {
|
|
179
|
+
await this.saveLocal();
|
|
180
|
+
console.log("\u2713 Created empty local registry (will sync from remote)");
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Get registry statistics
|
|
184
|
+
*/
|
|
185
|
+
getStats() {
|
|
186
|
+
return {
|
|
187
|
+
totalContainers: this.containers.size,
|
|
188
|
+
activeContainers: this.listContainers().length,
|
|
189
|
+
totalVerifiers: this.verifiers.size,
|
|
190
|
+
activeVerifiers: this.listVerifiers().length,
|
|
191
|
+
lastSync: this.lastSync ? new Date(this.lastSync).toISOString() : "Never"
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
};
|
|
195
|
+
export {
|
|
196
|
+
RegistryManager
|
|
197
|
+
};
|
|
198
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/RegistryManager.ts"],"sourcesContent":["import fs from 'fs/promises';\nimport path from 'path';\nimport fetch from 'node-fetch';\nimport type { ContainerMetadata, VerifierMetadata, RegistryConfig, RegistryIndex } from './types';\n\nexport class RegistryManager {\n private containers = new Map<string, ContainerMetadata>();\n private verifiers = new Map<string, VerifierMetadata>();\n private config: Required<RegistryConfig>;\n private lastSync: number = 0;\n\n constructor(config: RegistryConfig = {}) {\n this.config = {\n localPath: config.localPath || path.join(process.cwd(), '.noosphere', 'registry.json'),\n remotePath:\n config.remotePath ||\n 'https://raw.githubusercontent.com/hpp-io/noosphere-registry/main/registry.json',\n autoSync: config.autoSync ?? true,\n cacheTTL: config.cacheTTL || 3600000, // 1 hour default\n };\n }\n\n /**\n * Load registry from local and optionally sync from remote\n */\n async load(): Promise<void> {\n // Load local registry\n await this.loadLocal();\n\n // Sync from remote if enabled\n if (this.config.autoSync) {\n try {\n await this.sync();\n } catch (error) {\n console.warn('Failed to sync remote registry:', error);\n console.log('Continuing with local registry only');\n }\n }\n\n console.log(`✓ Loaded ${this.containers.size} containers and ${this.verifiers.size} verifiers`);\n }\n\n /**\n * Load local registry file\n */\n private async loadLocal(): Promise<void> {\n try {\n const data = await fs.readFile(this.config.localPath, 'utf-8');\n const registry: RegistryIndex = JSON.parse(data);\n\n // Load containers\n Object.entries(registry.containers || {}).forEach(([id, metadata]) => {\n this.containers.set(id, metadata);\n });\n\n // Load verifiers\n Object.entries(registry.verifiers || {}).forEach(([id, metadata]) => {\n this.verifiers.set(id, metadata);\n });\n\n console.log(`✓ Loaded local registry from ${this.config.localPath}`);\n } catch (error: any) {\n if (error.code === 'ENOENT') {\n console.log('No local registry found, will create default');\n await this.createDefaultRegistry();\n } else {\n throw error;\n }\n }\n }\n\n /**\n * Sync registry from remote GitHub repository\n */\n async sync(): Promise<void> {\n const now = Date.now();\n\n // Check cache TTL\n if (now - this.lastSync < this.config.cacheTTL) {\n console.log('Registry cache is fresh, skipping sync');\n return;\n }\n\n console.log(`Syncing registry from ${this.config.remotePath}...`);\n\n try {\n const response = await fetch(this.config.remotePath);\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n\n const registry = (await response.json()) as RegistryIndex;\n\n // Merge remote registry (remote entries are added, local overrides are kept)\n Object.entries(registry.containers || {}).forEach(([id, metadata]) => {\n if (!this.containers.has(id)) {\n // Only add if not already in local registry (local takes precedence)\n this.containers.set(id, metadata);\n }\n });\n\n Object.entries(registry.verifiers || {}).forEach(([id, metadata]) => {\n if (!this.verifiers.has(id)) {\n this.verifiers.set(id, metadata);\n }\n });\n\n this.lastSync = now;\n console.log(`✓ Synced registry (version: ${registry.version})`);\n } catch (error) {\n console.error('Failed to sync remote registry:', error);\n throw error;\n }\n }\n\n /**\n * Get container by ID\n */\n getContainer(id: string): ContainerMetadata | undefined {\n return this.containers.get(id);\n }\n\n /**\n * Get all containers\n */\n listContainers(): ContainerMetadata[] {\n return Array.from(this.containers.values()).filter((c) => c.statusCode === 'ACTIVE');\n }\n\n /**\n * Search containers by name or tag\n */\n searchContainers(query: string): ContainerMetadata[] {\n const lowerQuery = query.toLowerCase();\n return this.listContainers().filter(\n (c) =>\n c.name.toLowerCase().includes(lowerQuery) ||\n c.description?.toLowerCase().includes(lowerQuery) ||\n c.tags?.some((tag) => tag.toLowerCase().includes(lowerQuery))\n );\n }\n\n /**\n * Get verifier by contract address\n */\n getVerifier(verifierAddress: string): VerifierMetadata | undefined {\n return this.verifiers.get(verifierAddress);\n }\n\n /**\n * Get verifier by ID\n */\n getVerifierById(id: string): VerifierMetadata | undefined {\n return Array.from(this.verifiers.values()).find((v) => v.id === id);\n }\n\n /**\n * Get all verifiers\n */\n listVerifiers(): VerifierMetadata[] {\n return Array.from(this.verifiers.values()).filter((v) => v.statusCode === 'ACTIVE');\n }\n\n /**\n * Add custom container to local registry\n */\n async addContainer(container: ContainerMetadata): Promise<void> {\n this.containers.set(container.id, container);\n await this.saveLocal();\n console.log(`✓ Added container: ${container.name} (${container.id})`);\n }\n\n /**\n * Add custom verifier to local registry\n */\n async addVerifier(verifier: VerifierMetadata): Promise<void> {\n this.verifiers.set(verifier.verifierAddress, verifier);\n await this.saveLocal();\n console.log(`✓ Added verifier: ${verifier.name} (${verifier.verifierAddress})`);\n }\n\n /**\n * Remove container from local registry\n */\n async removeContainer(id: string): Promise<void> {\n if (this.containers.delete(id)) {\n await this.saveLocal();\n console.log(`✓ Removed container: ${id}`);\n }\n }\n\n /**\n * Remove verifier from local registry\n */\n async removeVerifier(verifierAddress: string): Promise<void> {\n if (this.verifiers.delete(verifierAddress)) {\n await this.saveLocal();\n console.log(`✓ Removed verifier: ${verifierAddress}`);\n }\n }\n\n /**\n * Save local registry to disk\n */\n private async saveLocal(): Promise<void> {\n const registry: RegistryIndex = {\n containers: Object.fromEntries(this.containers),\n verifiers: Object.fromEntries(this.verifiers),\n version: '1.0.0',\n updatedAt: new Date().toISOString(),\n };\n\n await fs.mkdir(path.dirname(this.config.localPath), { recursive: true });\n await fs.writeFile(this.config.localPath, JSON.stringify(registry, null, 2));\n }\n\n /**\n * Create default registry with example entries\n */\n private async createDefaultRegistry(): Promise<void> {\n // Create empty registry - will be populated from remote sync\n // No default containers or verifiers\n await this.saveLocal();\n console.log('✓ Created empty local registry (will sync from remote)');\n }\n\n /**\n * Get registry statistics\n */\n getStats(): {\n totalContainers: number;\n activeContainers: number;\n totalVerifiers: number;\n activeVerifiers: number;\n lastSync: string;\n } {\n return {\n totalContainers: this.containers.size,\n activeContainers: this.listContainers().length,\n totalVerifiers: this.verifiers.size,\n activeVerifiers: this.listVerifiers().length,\n lastSync: this.lastSync ? new Date(this.lastSync).toISOString() : 'Never',\n };\n }\n}\n"],"mappings":"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","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@noosphere/registry",
|
|
3
|
+
"version": "0.1.0-alpha.0",
|
|
4
|
+
"description": "Container and Verifier registry for Noosphere SDK",
|
|
5
|
+
"main": "dist/index.cjs",
|
|
6
|
+
"module": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"require": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"default": "./dist/index.cjs"
|
|
13
|
+
},
|
|
14
|
+
"import": {
|
|
15
|
+
"types": "./dist/index.d.mts",
|
|
16
|
+
"default": "./dist/index.js"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"dist"
|
|
22
|
+
],
|
|
23
|
+
"scripts": {
|
|
24
|
+
"build": "tsup",
|
|
25
|
+
"test": "jest",
|
|
26
|
+
"test:watch": "jest --watch",
|
|
27
|
+
"clean": "rm -rf dist",
|
|
28
|
+
"prepublishOnly": "npm run build"
|
|
29
|
+
},
|
|
30
|
+
"keywords": [
|
|
31
|
+
"noosphere",
|
|
32
|
+
"registry",
|
|
33
|
+
"container",
|
|
34
|
+
"verifier"
|
|
35
|
+
],
|
|
36
|
+
"author": "Noosphere Team",
|
|
37
|
+
"license": "MIT",
|
|
38
|
+
"repository": {
|
|
39
|
+
"type": "git",
|
|
40
|
+
"url": "https://github.com/hpp-io/noosphere-sdk.git",
|
|
41
|
+
"directory": "packages/registry"
|
|
42
|
+
},
|
|
43
|
+
"bugs": {
|
|
44
|
+
"url": "https://github.com/hpp-io/noosphere-sdk/issues"
|
|
45
|
+
},
|
|
46
|
+
"homepage": "https://github.com/hpp-io/noosphere-sdk/tree/main/packages/registry#readme",
|
|
47
|
+
"publishConfig": {
|
|
48
|
+
"access": "public"
|
|
49
|
+
},
|
|
50
|
+
"dependencies": {
|
|
51
|
+
"node-fetch": "^3.3.2"
|
|
52
|
+
},
|
|
53
|
+
"devDependencies": {
|
|
54
|
+
"@types/jest": "^29.5.0",
|
|
55
|
+
"@types/node": "^20.10.0",
|
|
56
|
+
"jest": "^29.7.0",
|
|
57
|
+
"ts-jest": "^29.1.0",
|
|
58
|
+
"typescript": "^5.3.0"
|
|
59
|
+
}
|
|
60
|
+
}
|