society-protocol 1.0.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/LICENSE +21 -0
- package/README.md +111 -0
- package/dist/adapters.d.ts +101 -0
- package/dist/adapters.d.ts.map +1 -0
- package/dist/adapters.js +764 -0
- package/dist/adapters.js.map +1 -0
- package/dist/agents-md.d.ts +59 -0
- package/dist/agents-md.d.ts.map +1 -0
- package/dist/agents-md.js +204 -0
- package/dist/agents-md.js.map +1 -0
- package/dist/autoconfig.d.ts +137 -0
- package/dist/autoconfig.d.ts.map +1 -0
- package/dist/autoconfig.js +452 -0
- package/dist/autoconfig.js.map +1 -0
- package/dist/bootstrap.d.ts +68 -0
- package/dist/bootstrap.d.ts.map +1 -0
- package/dist/bootstrap.js +304 -0
- package/dist/bootstrap.js.map +1 -0
- package/dist/bridges/a2a-bridge.d.ts +156 -0
- package/dist/bridges/a2a-bridge.d.ts.map +1 -0
- package/dist/bridges/a2a-bridge.js +337 -0
- package/dist/bridges/a2a-bridge.js.map +1 -0
- package/dist/bridges/mcp-bridge.d.ts +87 -0
- package/dist/bridges/mcp-bridge.d.ts.map +1 -0
- package/dist/bridges/mcp-bridge.js +332 -0
- package/dist/bridges/mcp-bridge.js.map +1 -0
- package/dist/cache.d.ts +130 -0
- package/dist/cache.d.ts.map +1 -0
- package/dist/cache.js +257 -0
- package/dist/cache.js.map +1 -0
- package/dist/capsules.d.ts +23 -0
- package/dist/capsules.d.ts.map +1 -0
- package/dist/capsules.js +75 -0
- package/dist/capsules.js.map +1 -0
- package/dist/cli/commands.d.ts +8 -0
- package/dist/cli/commands.d.ts.map +1 -0
- package/dist/cli/commands.js +263 -0
- package/dist/cli/commands.js.map +1 -0
- package/dist/coc.d.ts +121 -0
- package/dist/coc.d.ts.map +1 -0
- package/dist/coc.js +629 -0
- package/dist/coc.js.map +1 -0
- package/dist/coc.test.d.ts +2 -0
- package/dist/coc.test.d.ts.map +1 -0
- package/dist/coc.test.js +80 -0
- package/dist/coc.test.js.map +1 -0
- package/dist/compression.d.ts +125 -0
- package/dist/compression.d.ts.map +1 -0
- package/dist/compression.js +573 -0
- package/dist/compression.js.map +1 -0
- package/dist/cot-stream.d.ts +220 -0
- package/dist/cot-stream.d.ts.map +1 -0
- package/dist/cot-stream.js +673 -0
- package/dist/cot-stream.js.map +1 -0
- package/dist/crypto-wasm.d.ts +100 -0
- package/dist/crypto-wasm.d.ts.map +1 -0
- package/dist/crypto-wasm.js +229 -0
- package/dist/crypto-wasm.js.map +1 -0
- package/dist/federation.d.ts +200 -0
- package/dist/federation.d.ts.map +1 -0
- package/dist/federation.js +691 -0
- package/dist/federation.js.map +1 -0
- package/dist/federation.test.d.ts +2 -0
- package/dist/federation.test.d.ts.map +1 -0
- package/dist/federation.test.js +71 -0
- package/dist/federation.test.js.map +1 -0
- package/dist/gateway/capability-router.d.ts +77 -0
- package/dist/gateway/capability-router.d.ts.map +1 -0
- package/dist/gateway/capability-router.js +222 -0
- package/dist/gateway/capability-router.js.map +1 -0
- package/dist/gateway/demand-spawner.d.ts +155 -0
- package/dist/gateway/demand-spawner.d.ts.map +1 -0
- package/dist/gateway/demand-spawner.js +426 -0
- package/dist/gateway/demand-spawner.js.map +1 -0
- package/dist/identity.d.ts +46 -0
- package/dist/identity.d.ts.map +1 -0
- package/dist/identity.js +102 -0
- package/dist/identity.js.map +1 -0
- package/dist/identity.test.d.ts +2 -0
- package/dist/identity.test.d.ts.map +1 -0
- package/dist/identity.test.js +45 -0
- package/dist/identity.test.js.map +1 -0
- package/dist/index.d.ts +36 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1572 -0
- package/dist/index.js.map +1 -0
- package/dist/integration.d.ts +210 -0
- package/dist/integration.d.ts.map +1 -0
- package/dist/integration.js +1105 -0
- package/dist/integration.js.map +1 -0
- package/dist/integration.test.d.ts +2 -0
- package/dist/integration.test.d.ts.map +1 -0
- package/dist/integration.test.js +155 -0
- package/dist/integration.test.js.map +1 -0
- package/dist/knowledge.d.ts +219 -0
- package/dist/knowledge.d.ts.map +1 -0
- package/dist/knowledge.js +543 -0
- package/dist/knowledge.js.map +1 -0
- package/dist/knowledge.test.d.ts +2 -0
- package/dist/knowledge.test.d.ts.map +1 -0
- package/dist/knowledge.test.js +72 -0
- package/dist/knowledge.test.js.map +1 -0
- package/dist/latent-space.d.ts +178 -0
- package/dist/latent-space.d.ts.map +1 -0
- package/dist/latent-space.js +385 -0
- package/dist/latent-space.js.map +1 -0
- package/dist/lib.d.ts +30 -0
- package/dist/lib.d.ts.map +1 -0
- package/dist/lib.js +30 -0
- package/dist/lib.js.map +1 -0
- package/dist/mcp/server.d.ts +74 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +1392 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/metrics.d.ts +98 -0
- package/dist/metrics.d.ts.map +1 -0
- package/dist/metrics.js +222 -0
- package/dist/metrics.js.map +1 -0
- package/dist/p2p.d.ts +87 -0
- package/dist/p2p.d.ts.map +1 -0
- package/dist/p2p.js +606 -0
- package/dist/p2p.js.map +1 -0
- package/dist/persona/capabilities.d.ts +17 -0
- package/dist/persona/capabilities.d.ts.map +1 -0
- package/dist/persona/capabilities.js +224 -0
- package/dist/persona/capabilities.js.map +1 -0
- package/dist/persona/domains.d.ts +22 -0
- package/dist/persona/domains.d.ts.map +1 -0
- package/dist/persona/domains.js +176 -0
- package/dist/persona/domains.js.map +1 -0
- package/dist/persona/embeddings.d.ts +40 -0
- package/dist/persona/embeddings.d.ts.map +1 -0
- package/dist/persona/embeddings.js +265 -0
- package/dist/persona/embeddings.js.map +1 -0
- package/dist/persona/engine.d.ts +79 -0
- package/dist/persona/engine.d.ts.map +1 -0
- package/dist/persona/engine.js +1087 -0
- package/dist/persona/engine.js.map +1 -0
- package/dist/persona/index.d.ts +11 -0
- package/dist/persona/index.d.ts.map +1 -0
- package/dist/persona/index.js +11 -0
- package/dist/persona/index.js.map +1 -0
- package/dist/persona/lifecycle.d.ts +17 -0
- package/dist/persona/lifecycle.d.ts.map +1 -0
- package/dist/persona/lifecycle.js +36 -0
- package/dist/persona/lifecycle.js.map +1 -0
- package/dist/persona/retrieval.d.ts +6 -0
- package/dist/persona/retrieval.d.ts.map +1 -0
- package/dist/persona/retrieval.js +122 -0
- package/dist/persona/retrieval.js.map +1 -0
- package/dist/persona/sync.d.ts +15 -0
- package/dist/persona/sync.d.ts.map +1 -0
- package/dist/persona/sync.js +92 -0
- package/dist/persona/sync.js.map +1 -0
- package/dist/persona/types.d.ts +283 -0
- package/dist/persona/types.d.ts.map +1 -0
- package/dist/persona/types.js +2 -0
- package/dist/persona/types.js.map +1 -0
- package/dist/persona/zkp/engine.d.ts +26 -0
- package/dist/persona/zkp/engine.d.ts.map +1 -0
- package/dist/persona/zkp/engine.js +370 -0
- package/dist/persona/zkp/engine.js.map +1 -0
- package/dist/persona/zkp/types.d.ts +39 -0
- package/dist/persona/zkp/types.d.ts.map +1 -0
- package/dist/persona/zkp/types.js +2 -0
- package/dist/persona/zkp/types.js.map +1 -0
- package/dist/planner.d.ts +114 -0
- package/dist/planner.d.ts.map +1 -0
- package/dist/planner.js +522 -0
- package/dist/planner.js.map +1 -0
- package/dist/proactive/checkpoints.d.ts +9 -0
- package/dist/proactive/checkpoints.d.ts.map +1 -0
- package/dist/proactive/checkpoints.js +20 -0
- package/dist/proactive/checkpoints.js.map +1 -0
- package/dist/proactive/engine.d.ts +59 -0
- package/dist/proactive/engine.d.ts.map +1 -0
- package/dist/proactive/engine.js +406 -0
- package/dist/proactive/engine.js.map +1 -0
- package/dist/proactive/scheduler.d.ts +11 -0
- package/dist/proactive/scheduler.d.ts.map +1 -0
- package/dist/proactive/scheduler.js +45 -0
- package/dist/proactive/scheduler.js.map +1 -0
- package/dist/proactive/swarm-controller.d.ts +189 -0
- package/dist/proactive/swarm-controller.d.ts.map +1 -0
- package/dist/proactive/swarm-controller.js +477 -0
- package/dist/proactive/swarm-controller.js.map +1 -0
- package/dist/proactive/swarm-registry.d.ts +13 -0
- package/dist/proactive/swarm-registry.d.ts.map +1 -0
- package/dist/proactive/swarm-registry.js +122 -0
- package/dist/proactive/swarm-registry.js.map +1 -0
- package/dist/proactive/types.d.ts +145 -0
- package/dist/proactive/types.d.ts.map +1 -0
- package/dist/proactive/types.js +25 -0
- package/dist/proactive/types.js.map +1 -0
- package/dist/registry.d.ts +35 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +88 -0
- package/dist/registry.js.map +1 -0
- package/dist/reputation.d.ts +123 -0
- package/dist/reputation.d.ts.map +1 -0
- package/dist/reputation.js +366 -0
- package/dist/reputation.js.map +1 -0
- package/dist/reputation.test.d.ts +5 -0
- package/dist/reputation.test.d.ts.map +1 -0
- package/dist/reputation.test.js +265 -0
- package/dist/reputation.test.js.map +1 -0
- package/dist/rooms.d.ts +96 -0
- package/dist/rooms.d.ts.map +1 -0
- package/dist/rooms.js +410 -0
- package/dist/rooms.js.map +1 -0
- package/dist/sdk/client.d.ts +290 -0
- package/dist/sdk/client.d.ts.map +1 -0
- package/dist/sdk/client.js +1287 -0
- package/dist/sdk/client.js.map +1 -0
- package/dist/sdk/index.d.ts +32 -0
- package/dist/sdk/index.d.ts.map +1 -0
- package/dist/sdk/index.js +70 -0
- package/dist/sdk/index.js.map +1 -0
- package/dist/security.d.ts +230 -0
- package/dist/security.d.ts.map +1 -0
- package/dist/security.js +652 -0
- package/dist/security.js.map +1 -0
- package/dist/skills/engine.d.ts +262 -0
- package/dist/skills/engine.d.ts.map +1 -0
- package/dist/skills/engine.js +788 -0
- package/dist/skills/engine.js.map +1 -0
- package/dist/skills/engine.test.d.ts +2 -0
- package/dist/skills/engine.test.d.ts.map +1 -0
- package/dist/skills/engine.test.js +134 -0
- package/dist/skills/engine.test.js.map +1 -0
- package/dist/skills/parser.d.ts +129 -0
- package/dist/skills/parser.d.ts.map +1 -0
- package/dist/skills/parser.js +318 -0
- package/dist/skills/parser.js.map +1 -0
- package/dist/social.d.ts +149 -0
- package/dist/social.d.ts.map +1 -0
- package/dist/social.js +401 -0
- package/dist/social.js.map +1 -0
- package/dist/storage-optimized.d.ts +116 -0
- package/dist/storage-optimized.d.ts.map +1 -0
- package/dist/storage-optimized.js +264 -0
- package/dist/storage-optimized.js.map +1 -0
- package/dist/storage.d.ts +584 -0
- package/dist/storage.d.ts.map +1 -0
- package/dist/storage.js +2703 -0
- package/dist/storage.js.map +1 -0
- package/dist/storage.test.d.ts +2 -0
- package/dist/storage.test.d.ts.map +1 -0
- package/dist/storage.test.js +78 -0
- package/dist/storage.test.js.map +1 -0
- package/dist/swp.d.ts +443 -0
- package/dist/swp.d.ts.map +1 -0
- package/dist/swp.js +223 -0
- package/dist/swp.js.map +1 -0
- package/dist/swp.test.d.ts +5 -0
- package/dist/swp.test.d.ts.map +1 -0
- package/dist/swp.test.js +127 -0
- package/dist/swp.test.js.map +1 -0
- package/dist/templates.d.ts +25 -0
- package/dist/templates.d.ts.map +1 -0
- package/dist/templates.js +1048 -0
- package/dist/templates.js.map +1 -0
- package/dist/test-e2e.d.ts +14 -0
- package/dist/test-e2e.d.ts.map +1 -0
- package/dist/test-e2e.js +266 -0
- package/dist/test-e2e.js.map +1 -0
- package/dist/workers/research-worker.d.ts +19 -0
- package/dist/workers/research-worker.d.ts.map +1 -0
- package/dist/workers/research-worker.js +141 -0
- package/dist/workers/research-worker.js.map +1 -0
- package/package.json +110 -0
|
@@ -0,0 +1,426 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Society Protocol — Demand-Driven Agent Spawner
|
|
3
|
+
*
|
|
4
|
+
* Inspired by:
|
|
5
|
+
* - AutoAgents (arXiv:2309.17288): Dynamic role generation per task
|
|
6
|
+
* - MaAS (arXiv:2502.04180): Per-query architecture sampling from supernet
|
|
7
|
+
* - IoA (arXiv:2505.07176): Ephemeral team assembly + dissolution
|
|
8
|
+
* - DyLAN (arXiv:2310.02170): Agent importance scoring for selection
|
|
9
|
+
*
|
|
10
|
+
* Given a request, the DemandSpawner:
|
|
11
|
+
* 1. Uses CapabilityRouter to determine roles needed
|
|
12
|
+
* 2. Tries to select existing agents from the SwarmController pool
|
|
13
|
+
* 3. Spawns ephemeral agents (Ollama, HTTP, Docker) for missing roles
|
|
14
|
+
* 4. Opens a Chain of Collaboration for the team
|
|
15
|
+
* 5. Monitors execution and collects results
|
|
16
|
+
* 6. Dissolves ephemeral agents when done
|
|
17
|
+
*/
|
|
18
|
+
import { EventEmitter } from 'events';
|
|
19
|
+
import { ulid } from 'ulid';
|
|
20
|
+
import { SwarmController } from '../proactive/swarm-controller.js';
|
|
21
|
+
import { CapabilityRouter } from './capability-router.js';
|
|
22
|
+
export const DEFAULT_SPAWN_CONFIG = {
|
|
23
|
+
defaultRuntime: 'ollama',
|
|
24
|
+
ollamaUrl: process.env.OLLAMA_URL || 'http://localhost:11434',
|
|
25
|
+
ollamaModel: process.env.OLLAMA_MODEL || 'qwen3:1.7b',
|
|
26
|
+
maxSpawnedAgents: 8,
|
|
27
|
+
taskTimeoutMs: 120_000,
|
|
28
|
+
autoDissolvе: true,
|
|
29
|
+
defaultRoom: 'swarm-lobby',
|
|
30
|
+
};
|
|
31
|
+
// ─── Demand Spawner ──────────────────────────────────────────────
|
|
32
|
+
export class DemandSpawner extends EventEmitter {
|
|
33
|
+
storage;
|
|
34
|
+
rooms;
|
|
35
|
+
coc;
|
|
36
|
+
identity;
|
|
37
|
+
config;
|
|
38
|
+
router;
|
|
39
|
+
swarm;
|
|
40
|
+
teams = new Map();
|
|
41
|
+
spawnedAgents = new Map();
|
|
42
|
+
constructor(storage, rooms, coc, registry, config = {}, identity) {
|
|
43
|
+
super();
|
|
44
|
+
this.storage = storage;
|
|
45
|
+
this.rooms = rooms;
|
|
46
|
+
this.coc = coc;
|
|
47
|
+
this.identity = identity;
|
|
48
|
+
this.config = { ...DEFAULT_SPAWN_CONFIG, ...config };
|
|
49
|
+
this.router = new CapabilityRouter();
|
|
50
|
+
this.swarm = new SwarmController(storage, rooms, registry);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Handle an incoming request end-to-end:
|
|
54
|
+
* Route → Select/Spawn → Execute → Collect → Dissolve
|
|
55
|
+
*/
|
|
56
|
+
async handleRequest(request) {
|
|
57
|
+
const teamId = `team_${ulid()}`;
|
|
58
|
+
const routing = this.router.route(request);
|
|
59
|
+
const roomId = request.roomId || this.config.defaultRoom;
|
|
60
|
+
this.emit('request:routed', { teamId, routing });
|
|
61
|
+
// Ensure room exists — use identity DID to satisfy FK constraints
|
|
62
|
+
const creatorDid = request.callerDid || this.identity?.did || 'system';
|
|
63
|
+
this.storage.createRoom(roomId, roomId, creatorDid);
|
|
64
|
+
const team = {
|
|
65
|
+
teamId,
|
|
66
|
+
request,
|
|
67
|
+
routing,
|
|
68
|
+
agents: [],
|
|
69
|
+
roomId,
|
|
70
|
+
status: 'assembling',
|
|
71
|
+
results: new Map(),
|
|
72
|
+
createdAt: Date.now(),
|
|
73
|
+
};
|
|
74
|
+
this.teams.set(teamId, team);
|
|
75
|
+
try {
|
|
76
|
+
// 1. Resolve or spawn agents for each role
|
|
77
|
+
const agents = await this.assembleTeam(team, routing);
|
|
78
|
+
team.agents = agents;
|
|
79
|
+
this.emit('team:assembled', {
|
|
80
|
+
teamId,
|
|
81
|
+
agentCount: agents.length,
|
|
82
|
+
roles: agents.map(a => a.role.role),
|
|
83
|
+
});
|
|
84
|
+
// 2. Open Chain of Collaboration
|
|
85
|
+
const chainId = await this.openChain(team, routing);
|
|
86
|
+
team.chainId = chainId;
|
|
87
|
+
team.status = 'working';
|
|
88
|
+
// 3. Execute tasks via agents
|
|
89
|
+
const results = await this.executeTeam(team);
|
|
90
|
+
team.results = results;
|
|
91
|
+
team.status = 'completed';
|
|
92
|
+
team.completedAt = Date.now();
|
|
93
|
+
this.emit('team:completed', { teamId, chainId });
|
|
94
|
+
// 4. Dissolve ephemeral agents
|
|
95
|
+
await this.dissolveTeam(team);
|
|
96
|
+
return {
|
|
97
|
+
teamId,
|
|
98
|
+
chainId,
|
|
99
|
+
status: 'completed',
|
|
100
|
+
results: Object.fromEntries(results),
|
|
101
|
+
agents: agents.map(a => ({
|
|
102
|
+
id: a.id,
|
|
103
|
+
role: a.role.role,
|
|
104
|
+
runtime: a.runtime,
|
|
105
|
+
status: a.status,
|
|
106
|
+
})),
|
|
107
|
+
durationMs: Date.now() - team.createdAt,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
catch (error) {
|
|
111
|
+
team.status = 'failed';
|
|
112
|
+
team.completedAt = Date.now();
|
|
113
|
+
await this.dissolveTeam(team);
|
|
114
|
+
this.emit('team:failed', {
|
|
115
|
+
teamId,
|
|
116
|
+
error: error instanceof Error ? error.message : String(error),
|
|
117
|
+
});
|
|
118
|
+
return {
|
|
119
|
+
teamId,
|
|
120
|
+
chainId: team.chainId || '',
|
|
121
|
+
status: 'failed',
|
|
122
|
+
results: { error: error instanceof Error ? error.message : String(error) },
|
|
123
|
+
agents: team.agents.map(a => ({
|
|
124
|
+
id: a.id,
|
|
125
|
+
role: a.role.role,
|
|
126
|
+
runtime: a.runtime,
|
|
127
|
+
status: a.status,
|
|
128
|
+
})),
|
|
129
|
+
durationMs: Date.now() - team.createdAt,
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Assemble a team by selecting existing agents or spawning new ones.
|
|
135
|
+
*/
|
|
136
|
+
async assembleTeam(team, routing) {
|
|
137
|
+
const agents = [];
|
|
138
|
+
for (const role of routing.roles) {
|
|
139
|
+
// Try to find existing agent in swarm
|
|
140
|
+
const existing = this.swarm.selectAgent(role.taskType, {
|
|
141
|
+
capabilities: role.capabilities,
|
|
142
|
+
});
|
|
143
|
+
if (existing) {
|
|
144
|
+
agents.push(this.wrapExistingAgent(existing, role));
|
|
145
|
+
this.emit('agent:selected', {
|
|
146
|
+
teamId: team.teamId,
|
|
147
|
+
did: existing.did,
|
|
148
|
+
role: role.role,
|
|
149
|
+
source: 'pool',
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
// Spawn ephemeral agent
|
|
154
|
+
const spawned = await this.spawnAgent(team, role);
|
|
155
|
+
agents.push(spawned);
|
|
156
|
+
this.emit('agent:spawned', {
|
|
157
|
+
teamId: team.teamId,
|
|
158
|
+
agentId: spawned.id,
|
|
159
|
+
role: role.role,
|
|
160
|
+
runtime: spawned.runtime,
|
|
161
|
+
source: 'spawned',
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
if (agents.length >= routing.maxAgents)
|
|
165
|
+
break;
|
|
166
|
+
}
|
|
167
|
+
return agents;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Wrap an existing swarm agent as a SpawnedAgent.
|
|
171
|
+
*/
|
|
172
|
+
wrapExistingAgent(agent, role) {
|
|
173
|
+
return {
|
|
174
|
+
id: `agent_${ulid()}`,
|
|
175
|
+
role,
|
|
176
|
+
runtime: 'http', // Existing agents are accessed via protocol
|
|
177
|
+
did: agent.did,
|
|
178
|
+
status: 'ready',
|
|
179
|
+
createdAt: Date.now(),
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Spawn an ephemeral agent for a role.
|
|
184
|
+
*/
|
|
185
|
+
async spawnAgent(team, role) {
|
|
186
|
+
if (this.spawnedAgents.size >= this.config.maxSpawnedAgents) {
|
|
187
|
+
throw new Error(`Max spawned agents (${this.config.maxSpawnedAgents}) reached`);
|
|
188
|
+
}
|
|
189
|
+
const agentId = `agent_${ulid()}`;
|
|
190
|
+
const did = `did:key:spawned-${agentId}`;
|
|
191
|
+
const agent = {
|
|
192
|
+
id: agentId,
|
|
193
|
+
role,
|
|
194
|
+
runtime: this.config.defaultRuntime,
|
|
195
|
+
did,
|
|
196
|
+
status: 'spawning',
|
|
197
|
+
createdAt: Date.now(),
|
|
198
|
+
};
|
|
199
|
+
// Register with swarm
|
|
200
|
+
const profile = {
|
|
201
|
+
did,
|
|
202
|
+
hostId: `host_${agentId}`,
|
|
203
|
+
roomId: team.roomId,
|
|
204
|
+
runtime: this.config.defaultRuntime === 'process' ? 'custom' : this.config.defaultRuntime,
|
|
205
|
+
specialties: role.specialties,
|
|
206
|
+
capabilities: role.capabilities,
|
|
207
|
+
kinds: [role.kind],
|
|
208
|
+
maxConcurrency: 1,
|
|
209
|
+
load: 0,
|
|
210
|
+
health: 'healthy',
|
|
211
|
+
displayName: `${role.role}-${agentId.slice(-6)}`,
|
|
212
|
+
lastSeen: Date.now(),
|
|
213
|
+
};
|
|
214
|
+
this.swarm.registerAgent(profile);
|
|
215
|
+
agent.status = 'ready';
|
|
216
|
+
this.spawnedAgents.set(agentId, agent);
|
|
217
|
+
return agent;
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Open a Chain of Collaboration for the team.
|
|
221
|
+
*/
|
|
222
|
+
async openChain(team, routing) {
|
|
223
|
+
const chainId = `coc_${ulid()}`;
|
|
224
|
+
this.storage.createChain(chainId, team.roomId, team.request.goal, null, team.request.callerDid || 'system', team.request.priority || 'normal');
|
|
225
|
+
// Create steps for each role
|
|
226
|
+
for (let i = 0; i < team.agents.length; i++) {
|
|
227
|
+
const agent = team.agents[i];
|
|
228
|
+
const stepId = `step_${ulid()}`;
|
|
229
|
+
this.storage.createStep(stepId, chainId, agent.role.kind, agent.role.role, `${agent.role.taskType} task for ${agent.role.role}`, i > 0 ? [`step_${team.agents[i - 1].id}`] : []);
|
|
230
|
+
}
|
|
231
|
+
return chainId;
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Execute the team's tasks using Ollama or other runtimes.
|
|
235
|
+
*/
|
|
236
|
+
async executeTeam(team) {
|
|
237
|
+
const results = new Map();
|
|
238
|
+
// Get steps for the chain
|
|
239
|
+
const chain = this.storage.getChain(team.chainId);
|
|
240
|
+
if (!chain)
|
|
241
|
+
throw new Error(`Chain ${team.chainId} not found`);
|
|
242
|
+
const steps = this.storage.getChainSteps(team.chainId);
|
|
243
|
+
// Execute steps - sequentially for now (parallel for independent steps later)
|
|
244
|
+
let previousResult = '';
|
|
245
|
+
for (let i = 0; i < steps.length; i++) {
|
|
246
|
+
const step = steps[i];
|
|
247
|
+
const agent = team.agents[i];
|
|
248
|
+
if (!agent)
|
|
249
|
+
continue;
|
|
250
|
+
agent.status = 'working';
|
|
251
|
+
this.emit('agent:working', {
|
|
252
|
+
teamId: team.teamId,
|
|
253
|
+
agentId: agent.id,
|
|
254
|
+
stepId: step.step_id,
|
|
255
|
+
});
|
|
256
|
+
try {
|
|
257
|
+
const result = await this.executeAgentTask(agent, team.request.goal, step, previousResult);
|
|
258
|
+
results.set(agent.role.role, result);
|
|
259
|
+
previousResult = typeof result === 'string' ? result : JSON.stringify(result);
|
|
260
|
+
agent.status = 'done';
|
|
261
|
+
// Record success in swarm
|
|
262
|
+
this.swarm.recordTaskOutcome(agent.did, agent.role.taskType, true);
|
|
263
|
+
this.emit('agent:done', {
|
|
264
|
+
teamId: team.teamId,
|
|
265
|
+
agentId: agent.id,
|
|
266
|
+
role: agent.role.role,
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
catch (error) {
|
|
270
|
+
agent.status = 'failed';
|
|
271
|
+
this.swarm.recordTaskOutcome(agent.did, agent.role.taskType, false);
|
|
272
|
+
results.set(agent.role.role, {
|
|
273
|
+
error: error instanceof Error ? error.message : String(error),
|
|
274
|
+
});
|
|
275
|
+
this.emit('agent:failed', {
|
|
276
|
+
teamId: team.teamId,
|
|
277
|
+
agentId: agent.id,
|
|
278
|
+
error: error instanceof Error ? error.message : String(error),
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
return results;
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Execute a single agent's task against Ollama or other runtime.
|
|
286
|
+
*/
|
|
287
|
+
async executeAgentTask(agent, goal, step, previousContext) {
|
|
288
|
+
const prompt = this.buildAgentPrompt(agent, goal, step, previousContext);
|
|
289
|
+
switch (agent.runtime) {
|
|
290
|
+
case 'ollama':
|
|
291
|
+
return this.callOllama(prompt);
|
|
292
|
+
case 'http':
|
|
293
|
+
return this.callHttp(agent, prompt);
|
|
294
|
+
default:
|
|
295
|
+
return this.callOllama(prompt);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* Build a prompt for an agent based on its role and context.
|
|
300
|
+
*/
|
|
301
|
+
buildAgentPrompt(agent, goal, step, previousContext) {
|
|
302
|
+
const parts = [
|
|
303
|
+
`You are a specialized AI agent with the role: ${agent.role.role}`,
|
|
304
|
+
`Your task type: ${agent.role.taskType}`,
|
|
305
|
+
`Your capabilities: ${agent.role.capabilities.join(', ')}`,
|
|
306
|
+
'',
|
|
307
|
+
`## Goal`,
|
|
308
|
+
goal,
|
|
309
|
+
'',
|
|
310
|
+
`## Your Step`,
|
|
311
|
+
`Title: ${step.title || agent.role.role}`,
|
|
312
|
+
`Kind: ${step.kind || agent.role.kind}`,
|
|
313
|
+
];
|
|
314
|
+
if (previousContext) {
|
|
315
|
+
parts.push('', '## Previous Context (from other agents)', previousContext);
|
|
316
|
+
}
|
|
317
|
+
parts.push('', '## Instructions', `Complete your part of the task. Be specific and concise.`, `Focus on your role as ${agent.role.role}.`, `Respond with your findings/results directly.`);
|
|
318
|
+
return parts.join('\n');
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* Call Ollama API to execute a task.
|
|
322
|
+
*/
|
|
323
|
+
async callOllama(prompt) {
|
|
324
|
+
const response = await fetch(`${this.config.ollamaUrl}/api/generate`, {
|
|
325
|
+
method: 'POST',
|
|
326
|
+
headers: { 'Content-Type': 'application/json' },
|
|
327
|
+
body: JSON.stringify({
|
|
328
|
+
model: this.config.ollamaModel,
|
|
329
|
+
prompt,
|
|
330
|
+
stream: false,
|
|
331
|
+
}),
|
|
332
|
+
signal: AbortSignal.timeout(this.config.taskTimeoutMs),
|
|
333
|
+
});
|
|
334
|
+
if (!response.ok) {
|
|
335
|
+
throw new Error(`Ollama error: ${response.status} ${response.statusText}`);
|
|
336
|
+
}
|
|
337
|
+
const data = await response.json();
|
|
338
|
+
return data?.response || '';
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Call an HTTP endpoint for existing agents.
|
|
342
|
+
*/
|
|
343
|
+
async callHttp(agent, prompt) {
|
|
344
|
+
if (!agent.endpoint) {
|
|
345
|
+
// Fallback to Ollama for agents without endpoints
|
|
346
|
+
return this.callOllama(prompt);
|
|
347
|
+
}
|
|
348
|
+
const response = await fetch(agent.endpoint, {
|
|
349
|
+
method: 'POST',
|
|
350
|
+
headers: { 'Content-Type': 'application/json' },
|
|
351
|
+
body: JSON.stringify({ prompt, role: agent.role.role }),
|
|
352
|
+
signal: AbortSignal.timeout(this.config.taskTimeoutMs),
|
|
353
|
+
});
|
|
354
|
+
if (!response.ok) {
|
|
355
|
+
throw new Error(`HTTP agent error: ${response.status}`);
|
|
356
|
+
}
|
|
357
|
+
const data = await response.json();
|
|
358
|
+
return data?.result || data?.response || JSON.stringify(data);
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* Dissolve ephemeral agents after task completion.
|
|
362
|
+
* IoA-inspired: ephemeral teams are assembled and dissolved per request.
|
|
363
|
+
*/
|
|
364
|
+
async dissolveTeam(team) {
|
|
365
|
+
for (const agent of team.agents) {
|
|
366
|
+
if (this.spawnedAgents.has(agent.id)) {
|
|
367
|
+
agent.status = 'dissolved';
|
|
368
|
+
agent.dissolvedAt = Date.now();
|
|
369
|
+
// Kill process if any
|
|
370
|
+
if (agent.process) {
|
|
371
|
+
agent.process.kill('SIGTERM');
|
|
372
|
+
}
|
|
373
|
+
this.spawnedAgents.delete(agent.id);
|
|
374
|
+
this.emit('agent:dissolved', {
|
|
375
|
+
teamId: team.teamId,
|
|
376
|
+
agentId: agent.id,
|
|
377
|
+
role: agent.role.role,
|
|
378
|
+
lifespan: Date.now() - agent.createdAt,
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
team.status = 'dissolved';
|
|
383
|
+
}
|
|
384
|
+
// ─── Public API ──────────────────────────────────────────────
|
|
385
|
+
/** Get the capability router instance */
|
|
386
|
+
getRouter() {
|
|
387
|
+
return this.router;
|
|
388
|
+
}
|
|
389
|
+
/** Get the swarm controller instance */
|
|
390
|
+
getSwarm() {
|
|
391
|
+
return this.swarm;
|
|
392
|
+
}
|
|
393
|
+
/** Get active teams */
|
|
394
|
+
getActiveTeams() {
|
|
395
|
+
return [...this.teams.values()].filter(t => t.status === 'assembling' || t.status === 'working');
|
|
396
|
+
}
|
|
397
|
+
/** Get team by ID */
|
|
398
|
+
getTeam(teamId) {
|
|
399
|
+
return this.teams.get(teamId);
|
|
400
|
+
}
|
|
401
|
+
/** Get all spawned agents */
|
|
402
|
+
getSpawnedAgents() {
|
|
403
|
+
return [...this.spawnedAgents.values()];
|
|
404
|
+
}
|
|
405
|
+
/** Get spawn config */
|
|
406
|
+
getConfig() {
|
|
407
|
+
return { ...this.config };
|
|
408
|
+
}
|
|
409
|
+
/** Update spawn config */
|
|
410
|
+
updateConfig(updates) {
|
|
411
|
+
Object.assign(this.config, updates);
|
|
412
|
+
}
|
|
413
|
+
/** Clean up */
|
|
414
|
+
destroy() {
|
|
415
|
+
for (const agent of this.spawnedAgents.values()) {
|
|
416
|
+
if (agent.process) {
|
|
417
|
+
agent.process.kill('SIGTERM');
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
this.spawnedAgents.clear();
|
|
421
|
+
this.teams.clear();
|
|
422
|
+
this.swarm.destroy();
|
|
423
|
+
this.removeAllListeners();
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
//# sourceMappingURL=demand-spawner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"demand-spawner.js","sourceRoot":"","sources":["../../src/gateway/demand-spawner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Society Protocol — Identity Module
|
|
3
|
+
*
|
|
4
|
+
* Ed25519 keypair generation, did:key derivation, message signing/verification.
|
|
5
|
+
* Uses @noble/ed25519 for cryptography.
|
|
6
|
+
*/
|
|
7
|
+
export interface Identity {
|
|
8
|
+
privateKey: Uint8Array;
|
|
9
|
+
publicKey: Uint8Array;
|
|
10
|
+
did: string;
|
|
11
|
+
displayName: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Generate a new Ed25519 identity with a did:key identifier.
|
|
15
|
+
*
|
|
16
|
+
* did:key format: did:key:z6Mk<base58btc(0xed01 + pubkey)>
|
|
17
|
+
* The 0xed01 prefix is the multicodec for Ed25519 public keys.
|
|
18
|
+
*/
|
|
19
|
+
export declare function generateIdentity(displayName: string): Identity;
|
|
20
|
+
/**
|
|
21
|
+
* Restore an identity from stored keys.
|
|
22
|
+
*/
|
|
23
|
+
export declare function restoreIdentity(privateKeyHex: string, displayName: string): Identity;
|
|
24
|
+
/**
|
|
25
|
+
* Canonical JSON serialization (sorted keys, no whitespace).
|
|
26
|
+
* This ensures deterministic serialization for signing.
|
|
27
|
+
*/
|
|
28
|
+
export declare function canonicalJson(obj: unknown): string;
|
|
29
|
+
/**
|
|
30
|
+
* Deep canonical JSON serialization (recursively sorts all nested objects).
|
|
31
|
+
*/
|
|
32
|
+
export declare function deepCanonicalJson(obj: unknown): string;
|
|
33
|
+
/**
|
|
34
|
+
* Sign a message (canonical JSON bytes) with the identity's private key.
|
|
35
|
+
* Returns base64-encoded signature.
|
|
36
|
+
*/
|
|
37
|
+
export declare function sign(identity: Identity, message: string): string;
|
|
38
|
+
/**
|
|
39
|
+
* Verify a signature against a message and public key.
|
|
40
|
+
*/
|
|
41
|
+
export declare function verify(publicKey: Uint8Array, message: string, signatureBase64: string): boolean;
|
|
42
|
+
/**
|
|
43
|
+
* Extract public key bytes from a did:key string.
|
|
44
|
+
*/
|
|
45
|
+
export declare function publicKeyFromDid(did: string): Uint8Array;
|
|
46
|
+
//# sourceMappingURL=identity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../src/identity.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAcH,MAAM,WAAW,QAAQ;IACrB,UAAU,EAAE,UAAU,CAAC;IACvB,SAAS,EAAE,UAAU,CAAC;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;CACvB;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,QAAQ,CAa9D;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC3B,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,GACpB,QAAQ,CAYV;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAElD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAWtD;AAED;;;GAGG;AACH,wBAAgB,IAAI,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAIhE;AAED;;GAEG;AACH,wBAAgB,MAAM,CAClB,SAAS,EAAE,UAAU,EACrB,OAAO,EAAE,MAAM,EACf,eAAe,EAAE,MAAM,GACxB,OAAO,CAIT;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAWxD"}
|
package/dist/identity.js
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Society Protocol — Identity Module
|
|
3
|
+
*
|
|
4
|
+
* Ed25519 keypair generation, did:key derivation, message signing/verification.
|
|
5
|
+
* Uses @noble/ed25519 for cryptography.
|
|
6
|
+
*/
|
|
7
|
+
import * as ed from '@noble/ed25519';
|
|
8
|
+
import { sha512 } from '@noble/hashes/sha512';
|
|
9
|
+
import { base58btc } from 'multiformats/bases/base58';
|
|
10
|
+
import { toString as uint8ToString, fromString as uint8FromString } from 'uint8arrays';
|
|
11
|
+
// Configure ed25519 to use sha512
|
|
12
|
+
ed.etc.sha512Sync = (...m) => {
|
|
13
|
+
const h = sha512.create();
|
|
14
|
+
for (const msg of m)
|
|
15
|
+
h.update(msg);
|
|
16
|
+
return h.digest();
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Generate a new Ed25519 identity with a did:key identifier.
|
|
20
|
+
*
|
|
21
|
+
* did:key format: did:key:z6Mk<base58btc(0xed01 + pubkey)>
|
|
22
|
+
* The 0xed01 prefix is the multicodec for Ed25519 public keys.
|
|
23
|
+
*/
|
|
24
|
+
export function generateIdentity(displayName) {
|
|
25
|
+
const privateKey = ed.utils.randomPrivateKey();
|
|
26
|
+
const publicKey = ed.getPublicKey(privateKey);
|
|
27
|
+
// Build did:key: multicodec prefix 0xed01 + public key
|
|
28
|
+
const multicodecPrefixed = new Uint8Array(2 + publicKey.length);
|
|
29
|
+
multicodecPrefixed[0] = 0xed;
|
|
30
|
+
multicodecPrefixed[1] = 0x01;
|
|
31
|
+
multicodecPrefixed.set(publicKey, 2);
|
|
32
|
+
const did = `did:key:${base58btc.encode(multicodecPrefixed)}`;
|
|
33
|
+
return { privateKey, publicKey, did, displayName };
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Restore an identity from stored keys.
|
|
37
|
+
*/
|
|
38
|
+
export function restoreIdentity(privateKeyHex, displayName) {
|
|
39
|
+
const privateKey = uint8FromString(privateKeyHex, 'base16');
|
|
40
|
+
const publicKey = ed.getPublicKey(privateKey);
|
|
41
|
+
const multicodecPrefixed = new Uint8Array(2 + publicKey.length);
|
|
42
|
+
multicodecPrefixed[0] = 0xed;
|
|
43
|
+
multicodecPrefixed[1] = 0x01;
|
|
44
|
+
multicodecPrefixed.set(publicKey, 2);
|
|
45
|
+
const did = `did:key:${base58btc.encode(multicodecPrefixed)}`;
|
|
46
|
+
return { privateKey, publicKey, did, displayName };
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Canonical JSON serialization (sorted keys, no whitespace).
|
|
50
|
+
* This ensures deterministic serialization for signing.
|
|
51
|
+
*/
|
|
52
|
+
export function canonicalJson(obj) {
|
|
53
|
+
return JSON.stringify(obj, Object.keys(obj).sort());
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Deep canonical JSON serialization (recursively sorts all nested objects).
|
|
57
|
+
*/
|
|
58
|
+
export function deepCanonicalJson(obj) {
|
|
59
|
+
if (obj === null || obj === undefined)
|
|
60
|
+
return JSON.stringify(obj);
|
|
61
|
+
if (typeof obj !== 'object')
|
|
62
|
+
return JSON.stringify(obj);
|
|
63
|
+
if (Array.isArray(obj)) {
|
|
64
|
+
return '[' + obj.map(deepCanonicalJson).join(',') + ']';
|
|
65
|
+
}
|
|
66
|
+
const sorted = Object.keys(obj).sort();
|
|
67
|
+
const pairs = sorted.map((k) => `${JSON.stringify(k)}:${deepCanonicalJson(obj[k])}`);
|
|
68
|
+
return '{' + pairs.join(',') + '}';
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Sign a message (canonical JSON bytes) with the identity's private key.
|
|
72
|
+
* Returns base64-encoded signature.
|
|
73
|
+
*/
|
|
74
|
+
export function sign(identity, message) {
|
|
75
|
+
const msgBytes = new TextEncoder().encode(message);
|
|
76
|
+
const sig = ed.sign(msgBytes, identity.privateKey);
|
|
77
|
+
return uint8ToString(sig, 'base64');
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Verify a signature against a message and public key.
|
|
81
|
+
*/
|
|
82
|
+
export function verify(publicKey, message, signatureBase64) {
|
|
83
|
+
const msgBytes = new TextEncoder().encode(message);
|
|
84
|
+
const sig = uint8FromString(signatureBase64, 'base64');
|
|
85
|
+
return ed.verify(sig, msgBytes, publicKey);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Extract public key bytes from a did:key string.
|
|
89
|
+
*/
|
|
90
|
+
export function publicKeyFromDid(did) {
|
|
91
|
+
if (!did.startsWith('did:key:z')) {
|
|
92
|
+
throw new Error(`Invalid did:key format: ${did}`);
|
|
93
|
+
}
|
|
94
|
+
const multibase = did.slice('did:key:'.length);
|
|
95
|
+
const decoded = base58btc.decode(multibase);
|
|
96
|
+
// Skip 2-byte multicodec prefix (0xed 0x01)
|
|
97
|
+
if (decoded[0] !== 0xed || decoded[1] !== 0x01) {
|
|
98
|
+
throw new Error('Not an Ed25519 did:key');
|
|
99
|
+
}
|
|
100
|
+
return decoded.slice(2);
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=identity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity.js","sourceRoot":"","sources":["../src/identity.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity.test.d.ts","sourceRoot":"","sources":["../src/identity.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { generateIdentity, sign, verify, publicKeyFromDid, canonicalJson } from './identity.js';
|
|
3
|
+
describe('Identity Module', () => {
|
|
4
|
+
it('generates a valid Ed25519 identity and did:key', () => {
|
|
5
|
+
const id = generateIdentity('Alice');
|
|
6
|
+
expect(id).toHaveProperty('privateKey');
|
|
7
|
+
expect(id).toHaveProperty('publicKey');
|
|
8
|
+
expect(id).toHaveProperty('did');
|
|
9
|
+
expect(id.displayName).toBe('Alice');
|
|
10
|
+
expect(id.did.startsWith('did:key:z6Mk')).toBe(true);
|
|
11
|
+
});
|
|
12
|
+
it('signs and verifies a string message successfully', () => {
|
|
13
|
+
const id = generateIdentity('Alice');
|
|
14
|
+
const message = "Hello World";
|
|
15
|
+
const signature = sign(id, message);
|
|
16
|
+
expect(typeof signature).toBe('string');
|
|
17
|
+
// Should verify correctly
|
|
18
|
+
const isValid = verify(id.publicKey, message, signature);
|
|
19
|
+
expect(isValid).toBe(true);
|
|
20
|
+
});
|
|
21
|
+
it('validates canonical JSON sorting', () => {
|
|
22
|
+
const payload1 = { b: 2, a: 1 };
|
|
23
|
+
const payload2 = { a: 1, b: 2 };
|
|
24
|
+
expect(canonicalJson(payload1)).toBe(canonicalJson(payload2));
|
|
25
|
+
});
|
|
26
|
+
it('rejects an invalid signature or tampered payload', () => {
|
|
27
|
+
const id = generateIdentity('Alice');
|
|
28
|
+
const message = "Original";
|
|
29
|
+
const signature = sign(id, message);
|
|
30
|
+
// Tamper with payload
|
|
31
|
+
const tamperedMessage = "Hacked";
|
|
32
|
+
const isValid = verify(id.publicKey, tamperedMessage, signature);
|
|
33
|
+
expect(isValid).toBe(false);
|
|
34
|
+
// Tamper with signature (middle modification keeps valid base64 padding)
|
|
35
|
+
const badSig = signature.slice(0, 10) + (signature[10] === 'A' ? 'B' : 'A') + signature.slice(11);
|
|
36
|
+
const isBadSigValid = verify(id.publicKey, message, badSig);
|
|
37
|
+
expect(isBadSigValid).toBe(false);
|
|
38
|
+
});
|
|
39
|
+
it('extracts public key bytes from a did:key', () => {
|
|
40
|
+
const id = generateIdentity('Alice');
|
|
41
|
+
const extracted = publicKeyFromDid(id.did);
|
|
42
|
+
expect(extracted).toEqual(id.publicKey);
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
//# sourceMappingURL=identity.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity.test.js","sourceRoot":"","sources":["../src/identity.test.ts"],"names":[],"mappings":"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"}
|