@tjamescouch/agentchat 0.22.1 → 0.23.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/Dockerfile +1 -1
- package/dist/bin/agentchat.d.ts +7 -0
- package/dist/bin/agentchat.d.ts.map +1 -0
- package/dist/bin/agentchat.js +1511 -0
- package/dist/bin/agentchat.js.map +1 -0
- package/dist/lib/allowlist.d.ts +77 -0
- package/dist/lib/allowlist.d.ts.map +1 -0
- package/dist/lib/allowlist.js +151 -0
- package/dist/lib/allowlist.js.map +1 -0
- package/dist/lib/client.d.ts +147 -0
- package/dist/lib/client.d.ts.map +1 -0
- package/dist/lib/client.js +704 -0
- package/dist/lib/client.js.map +1 -0
- package/dist/lib/daemon.d.ts +122 -0
- package/dist/lib/daemon.d.ts.map +1 -0
- package/dist/lib/daemon.js +523 -0
- package/dist/lib/daemon.js.map +1 -0
- package/dist/lib/deploy/akash.d.ts +271 -0
- package/dist/lib/deploy/akash.d.ts.map +1 -0
- package/dist/lib/deploy/akash.js +671 -0
- package/dist/lib/deploy/akash.js.map +1 -0
- package/dist/lib/deploy/config.d.ts +62 -0
- package/dist/lib/deploy/config.d.ts.map +1 -0
- package/dist/lib/deploy/config.js +116 -0
- package/dist/lib/deploy/config.js.map +1 -0
- package/dist/lib/deploy/docker.d.ts +37 -0
- package/dist/lib/deploy/docker.d.ts.map +1 -0
- package/dist/lib/deploy/docker.js +122 -0
- package/dist/lib/deploy/docker.js.map +1 -0
- package/dist/lib/deploy/index.d.ts +11 -0
- package/dist/lib/deploy/index.d.ts.map +1 -0
- package/dist/lib/deploy/index.js +11 -0
- package/dist/lib/deploy/index.js.map +1 -0
- package/dist/lib/escrow-hooks.d.ts +199 -0
- package/dist/lib/escrow-hooks.d.ts.map +1 -0
- package/dist/lib/escrow-hooks.js +221 -0
- package/dist/lib/escrow-hooks.js.map +1 -0
- package/dist/lib/identity.d.ts +134 -0
- package/dist/lib/identity.d.ts.map +1 -0
- package/dist/lib/identity.js +334 -0
- package/dist/lib/identity.js.map +1 -0
- package/dist/lib/jitter.d.ts +42 -0
- package/dist/lib/jitter.d.ts.map +1 -0
- package/{lib/jitter.ts → dist/lib/jitter.js} +10 -18
- package/dist/lib/jitter.js.map +1 -0
- package/dist/lib/proposals.d.ts +223 -0
- package/dist/lib/proposals.d.ts.map +1 -0
- package/dist/lib/proposals.js +379 -0
- package/dist/lib/proposals.js.map +1 -0
- package/dist/lib/protocol.d.ts +220 -0
- package/dist/lib/protocol.d.ts.map +1 -0
- package/dist/lib/protocol.js +507 -0
- package/dist/lib/protocol.js.map +1 -0
- package/dist/lib/receipts.d.ts +134 -0
- package/dist/lib/receipts.d.ts.map +1 -0
- package/dist/lib/receipts.js +270 -0
- package/dist/lib/receipts.js.map +1 -0
- package/dist/lib/reputation.d.ts +250 -0
- package/dist/lib/reputation.d.ts.map +1 -0
- package/dist/lib/reputation.js +586 -0
- package/dist/lib/reputation.js.map +1 -0
- package/dist/lib/security.d.ts +27 -0
- package/dist/lib/security.d.ts.map +1 -0
- package/dist/lib/security.js +150 -0
- package/dist/lib/security.js.map +1 -0
- package/dist/lib/server/handlers/admin.d.ts +26 -0
- package/dist/lib/server/handlers/admin.d.ts.map +1 -0
- package/dist/lib/server/handlers/admin.js +76 -0
- package/dist/lib/server/handlers/admin.js.map +1 -0
- package/dist/lib/server/handlers/identity.d.ts +36 -0
- package/dist/lib/server/handlers/identity.d.ts.map +1 -0
- package/dist/lib/server/handlers/identity.js +330 -0
- package/dist/lib/server/handlers/identity.js.map +1 -0
- package/dist/lib/server/handlers/index.d.ts +10 -0
- package/dist/lib/server/handlers/index.d.ts.map +1 -0
- package/dist/lib/server/handlers/index.js +15 -0
- package/dist/lib/server/handlers/index.js.map +1 -0
- package/dist/lib/server/handlers/message.d.ts +47 -0
- package/dist/lib/server/handlers/message.d.ts.map +1 -0
- package/dist/lib/server/handlers/message.js +265 -0
- package/dist/lib/server/handlers/message.js.map +1 -0
- package/dist/lib/server/handlers/presence.d.ts +18 -0
- package/dist/lib/server/handlers/presence.d.ts.map +1 -0
- package/dist/lib/server/handlers/presence.js +35 -0
- package/dist/lib/server/handlers/presence.js.map +1 -0
- package/dist/lib/server/handlers/proposal.d.ts +38 -0
- package/dist/lib/server/handlers/proposal.d.ts.map +1 -0
- package/dist/lib/server/handlers/proposal.js +273 -0
- package/dist/lib/server/handlers/proposal.js.map +1 -0
- package/dist/lib/server/handlers/skills.d.ts +22 -0
- package/dist/lib/server/handlers/skills.d.ts.map +1 -0
- package/dist/lib/server/handlers/skills.js +119 -0
- package/dist/lib/server/handlers/skills.js.map +1 -0
- package/dist/lib/server-directory.d.ts +85 -0
- package/dist/lib/server-directory.d.ts.map +1 -0
- package/dist/lib/server-directory.js +177 -0
- package/dist/lib/server-directory.js.map +1 -0
- package/dist/lib/server.d.ts +162 -0
- package/dist/lib/server.d.ts.map +1 -0
- package/dist/lib/server.js +602 -0
- package/dist/lib/server.js.map +1 -0
- package/dist/lib/types.d.ts +461 -0
- package/dist/lib/types.d.ts.map +1 -0
- package/dist/lib/types.js +98 -0
- package/dist/lib/types.js.map +1 -0
- package/package.json +22 -13
- package/bin/agentchat.js +0 -1617
- package/bin/agentchat.ts +0 -1812
- package/lib/allowlist.js +0 -162
- package/lib/chat.py +0 -241
- package/lib/client.js +0 -821
- package/lib/client.ts +0 -877
- package/lib/daemon.js +0 -562
- package/lib/daemon.ts +0 -662
- package/lib/deploy/akash.js +0 -811
- package/lib/deploy/config.js +0 -128
- package/lib/deploy/docker.js +0 -132
- package/lib/deploy/index.js +0 -24
- package/lib/elo_swarm.py +0 -569
- package/lib/escrow-hooks.js +0 -237
- package/lib/escrow-hooks.ts +0 -391
- package/lib/identity.js +0 -376
- package/lib/identity.ts +0 -412
- package/lib/jitter.js +0 -54
- package/lib/proposals.js +0 -426
- package/lib/proposals.ts +0 -612
- package/lib/protocol.js +0 -516
- package/lib/receipts.js +0 -294
- package/lib/receipts.ts +0 -359
- package/lib/reputation.js +0 -664
- package/lib/reputation.ts +0 -790
- package/lib/security.js +0 -183
- package/lib/server/handlers/admin.js +0 -94
- package/lib/server/handlers/identity.js +0 -258
- package/lib/server/handlers/index.js +0 -42
- package/lib/server/handlers/message.js +0 -319
- package/lib/server/handlers/presence.js +0 -45
- package/lib/server/handlers/proposal.js +0 -358
- package/lib/server/handlers/skills.js +0 -141
- package/lib/server-directory.js +0 -190
- package/lib/server-directory.ts +0 -232
- package/lib/server.js +0 -633
- package/lib/server.ts +0 -698
- package/lib/supervisor/USAGE.md +0 -110
- package/lib/supervisor/agent-health.sh +0 -107
- package/lib/supervisor/agent-monitor.sh +0 -123
- package/lib/supervisor/agent-supervisor.sh +0 -135
- package/lib/supervisor/agentctl.sh +0 -266
- package/lib/supervisor/god-backup.sh +0 -126
- package/lib/supervisor/god-watchdog.sh +0 -107
- package/lib/supervisor/killswitch.sh +0 -43
- package/lib/supervisor/notify.sh +0 -19
- package/lib/types.ts +0 -433
package/lib/escrow-hooks.js
DELETED
|
@@ -1,237 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* EscrowHooks - Event system for external escrow integration
|
|
3
|
-
*
|
|
4
|
-
* Allows external systems (blockchain, multi-sig, compliance) to hook into
|
|
5
|
-
* escrow lifecycle events without modifying core AgentChat code.
|
|
6
|
-
*
|
|
7
|
-
* Events:
|
|
8
|
-
* escrow:created - Escrow created when proposal accepted with stakes
|
|
9
|
-
* escrow:released - Escrow released (expired, cancelled)
|
|
10
|
-
* settlement:completion - Proposal completed, stakes returned
|
|
11
|
-
* settlement:dispute - Proposal disputed, stakes transferred/burned
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
export const EscrowEvent = {
|
|
15
|
-
CREATED: 'escrow:created',
|
|
16
|
-
RELEASED: 'escrow:released',
|
|
17
|
-
COMPLETION_SETTLED: 'settlement:completion',
|
|
18
|
-
DISPUTE_SETTLED: 'settlement:dispute'
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
export class EscrowHooks {
|
|
22
|
-
constructor(options = {}) {
|
|
23
|
-
this.handlers = new Map(); // event -> Set of handlers
|
|
24
|
-
this.logger = options.logger || console;
|
|
25
|
-
this.continueOnError = options.continueOnError !== false; // default true
|
|
26
|
-
|
|
27
|
-
// Initialize event handler sets
|
|
28
|
-
for (const event of Object.values(EscrowEvent)) {
|
|
29
|
-
this.handlers.set(event, new Set());
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Register a handler for an escrow event
|
|
35
|
-
* @param {string} event - Event name from EscrowEvent
|
|
36
|
-
* @param {Function} handler - Async function(payload) to call
|
|
37
|
-
* @returns {Function} Unsubscribe function
|
|
38
|
-
*/
|
|
39
|
-
on(event, handler) {
|
|
40
|
-
if (!this.handlers.has(event)) {
|
|
41
|
-
throw new Error(`Unknown escrow event: ${event}`);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
if (typeof handler !== 'function') {
|
|
45
|
-
throw new Error('Handler must be a function');
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
this.handlers.get(event).add(handler);
|
|
49
|
-
|
|
50
|
-
// Return unsubscribe function
|
|
51
|
-
return () => this.off(event, handler);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Remove a handler for an escrow event
|
|
56
|
-
* @param {string} event - Event name
|
|
57
|
-
* @param {Function} handler - Handler to remove
|
|
58
|
-
*/
|
|
59
|
-
off(event, handler) {
|
|
60
|
-
if (this.handlers.has(event)) {
|
|
61
|
-
this.handlers.get(event).delete(handler);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* Remove all handlers for an event (or all events)
|
|
67
|
-
* @param {string} [event] - Optional event name
|
|
68
|
-
*/
|
|
69
|
-
clear(event) {
|
|
70
|
-
if (event) {
|
|
71
|
-
if (this.handlers.has(event)) {
|
|
72
|
-
this.handlers.get(event).clear();
|
|
73
|
-
}
|
|
74
|
-
} else {
|
|
75
|
-
for (const handlers of this.handlers.values()) {
|
|
76
|
-
handlers.clear();
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* Emit an escrow event to all registered handlers
|
|
83
|
-
* @param {string} event - Event name
|
|
84
|
-
* @param {Object} payload - Event payload
|
|
85
|
-
* @returns {Promise<Object>} Results from all handlers
|
|
86
|
-
*/
|
|
87
|
-
async emit(event, payload) {
|
|
88
|
-
if (!this.handlers.has(event)) {
|
|
89
|
-
throw new Error(`Unknown escrow event: ${event}`);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
const handlers = this.handlers.get(event);
|
|
93
|
-
if (handlers.size === 0) {
|
|
94
|
-
return { event, handled: false, results: [] };
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
const results = [];
|
|
98
|
-
const errors = [];
|
|
99
|
-
|
|
100
|
-
for (const handler of handlers) {
|
|
101
|
-
try {
|
|
102
|
-
const result = await handler(payload);
|
|
103
|
-
results.push({ success: true, result });
|
|
104
|
-
} catch (err) {
|
|
105
|
-
const errorInfo = {
|
|
106
|
-
success: false,
|
|
107
|
-
error: err.message,
|
|
108
|
-
stack: err.stack
|
|
109
|
-
};
|
|
110
|
-
errors.push(errorInfo);
|
|
111
|
-
results.push(errorInfo);
|
|
112
|
-
|
|
113
|
-
this.logger.error?.(`[EscrowHooks] Error in ${event} handler:`, err.message);
|
|
114
|
-
|
|
115
|
-
if (!this.continueOnError) {
|
|
116
|
-
break;
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
return {
|
|
122
|
-
event,
|
|
123
|
-
handled: true,
|
|
124
|
-
results,
|
|
125
|
-
errors: errors.length > 0 ? errors : undefined
|
|
126
|
-
};
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
/**
|
|
130
|
-
* Check if any handlers are registered for an event
|
|
131
|
-
* @param {string} event - Event name
|
|
132
|
-
* @returns {boolean}
|
|
133
|
-
*/
|
|
134
|
-
hasHandlers(event) {
|
|
135
|
-
return this.handlers.has(event) && this.handlers.get(event).size > 0;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
/**
|
|
139
|
-
* Get count of handlers for an event
|
|
140
|
-
* @param {string} event - Event name
|
|
141
|
-
* @returns {number}
|
|
142
|
-
*/
|
|
143
|
-
handlerCount(event) {
|
|
144
|
-
return this.handlers.has(event) ? this.handlers.get(event).size : 0;
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
* Create payload for escrow:created event
|
|
150
|
-
*/
|
|
151
|
-
export function createEscrowCreatedPayload(proposal, escrowResult) {
|
|
152
|
-
return {
|
|
153
|
-
event: EscrowEvent.CREATED,
|
|
154
|
-
timestamp: Date.now(),
|
|
155
|
-
proposal_id: proposal.id,
|
|
156
|
-
from_agent: proposal.from,
|
|
157
|
-
to_agent: proposal.to,
|
|
158
|
-
proposer_stake: proposal.proposer_stake || 0,
|
|
159
|
-
acceptor_stake: proposal.acceptor_stake || 0,
|
|
160
|
-
total_stake: (proposal.proposer_stake || 0) + (proposal.acceptor_stake || 0),
|
|
161
|
-
task: proposal.task,
|
|
162
|
-
amount: proposal.amount,
|
|
163
|
-
currency: proposal.currency,
|
|
164
|
-
expires: proposal.expires,
|
|
165
|
-
escrow_id: escrowResult.escrow?.proposal_id || proposal.id
|
|
166
|
-
};
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
/**
|
|
170
|
-
* Create payload for settlement:completion event
|
|
171
|
-
*/
|
|
172
|
-
export function createCompletionPayload(proposal, ratingChanges) {
|
|
173
|
-
const escrowInfo = ratingChanges?._escrow || {};
|
|
174
|
-
return {
|
|
175
|
-
event: EscrowEvent.COMPLETION_SETTLED,
|
|
176
|
-
timestamp: Date.now(),
|
|
177
|
-
proposal_id: proposal.id,
|
|
178
|
-
from_agent: proposal.from,
|
|
179
|
-
to_agent: proposal.to,
|
|
180
|
-
completed_by: proposal.completed_by,
|
|
181
|
-
completion_proof: proposal.completion_proof,
|
|
182
|
-
settlement: 'returned',
|
|
183
|
-
stakes_returned: {
|
|
184
|
-
proposer: escrowInfo.proposer_stake || 0,
|
|
185
|
-
acceptor: escrowInfo.acceptor_stake || 0
|
|
186
|
-
},
|
|
187
|
-
rating_changes: {
|
|
188
|
-
[proposal.from]: ratingChanges?.[proposal.from],
|
|
189
|
-
[proposal.to]: ratingChanges?.[proposal.to]
|
|
190
|
-
}
|
|
191
|
-
};
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
/**
|
|
195
|
-
* Create payload for settlement:dispute event
|
|
196
|
-
*/
|
|
197
|
-
export function createDisputePayload(proposal, ratingChanges) {
|
|
198
|
-
const escrowInfo = ratingChanges?._escrow || {};
|
|
199
|
-
return {
|
|
200
|
-
event: EscrowEvent.DISPUTE_SETTLED,
|
|
201
|
-
timestamp: Date.now(),
|
|
202
|
-
proposal_id: proposal.id,
|
|
203
|
-
from_agent: proposal.from,
|
|
204
|
-
to_agent: proposal.to,
|
|
205
|
-
disputed_by: proposal.disputed_by,
|
|
206
|
-
dispute_reason: proposal.dispute_reason,
|
|
207
|
-
settlement: escrowInfo.settlement || 'settled',
|
|
208
|
-
settlement_reason: escrowInfo.settlement_reason,
|
|
209
|
-
fault_determination: escrowInfo.fault_party,
|
|
210
|
-
stakes_transferred: escrowInfo.transferred,
|
|
211
|
-
stakes_burned: escrowInfo.burned,
|
|
212
|
-
rating_changes: {
|
|
213
|
-
[proposal.from]: ratingChanges?.[proposal.from],
|
|
214
|
-
[proposal.to]: ratingChanges?.[proposal.to]
|
|
215
|
-
}
|
|
216
|
-
};
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
/**
|
|
220
|
-
* Create payload for escrow:released event
|
|
221
|
-
*/
|
|
222
|
-
export function createEscrowReleasedPayload(proposalId, escrow, reason) {
|
|
223
|
-
return {
|
|
224
|
-
event: EscrowEvent.RELEASED,
|
|
225
|
-
timestamp: Date.now(),
|
|
226
|
-
proposal_id: proposalId,
|
|
227
|
-
from_agent: escrow.from?.agent_id,
|
|
228
|
-
to_agent: escrow.to?.agent_id,
|
|
229
|
-
stakes_released: {
|
|
230
|
-
proposer: escrow.from?.stake || 0,
|
|
231
|
-
acceptor: escrow.to?.stake || 0
|
|
232
|
-
},
|
|
233
|
-
reason: reason || 'expired'
|
|
234
|
-
};
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
export default EscrowHooks;
|
package/lib/escrow-hooks.ts
DELETED
|
@@ -1,391 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* EscrowHooks - Event system for external escrow integration
|
|
3
|
-
*
|
|
4
|
-
* Allows external systems (blockchain, multi-sig, compliance) to hook into
|
|
5
|
-
* escrow lifecycle events without modifying core AgentChat code.
|
|
6
|
-
*
|
|
7
|
-
* Events:
|
|
8
|
-
* escrow:created - Escrow created when proposal accepted with stakes
|
|
9
|
-
* escrow:released - Escrow released (expired, cancelled)
|
|
10
|
-
* settlement:completion - Proposal completed, stakes returned
|
|
11
|
-
* settlement:dispute - Proposal disputed, stakes transferred/burned
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
import type { Proposal } from './types.js';
|
|
15
|
-
|
|
16
|
-
export const EscrowEvent = {
|
|
17
|
-
CREATED: 'escrow:created',
|
|
18
|
-
RELEASED: 'escrow:released',
|
|
19
|
-
COMPLETION_SETTLED: 'settlement:completion',
|
|
20
|
-
DISPUTE_SETTLED: 'settlement:dispute'
|
|
21
|
-
} as const;
|
|
22
|
-
|
|
23
|
-
export type EscrowEventType = typeof EscrowEvent[keyof typeof EscrowEvent];
|
|
24
|
-
|
|
25
|
-
export interface Logger {
|
|
26
|
-
error?: (message: string, ...args: unknown[]) => void;
|
|
27
|
-
warn?: (message: string, ...args: unknown[]) => void;
|
|
28
|
-
info?: (message: string, ...args: unknown[]) => void;
|
|
29
|
-
debug?: (message: string, ...args: unknown[]) => void;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export interface EscrowHooksOptions {
|
|
33
|
-
logger?: Logger;
|
|
34
|
-
continueOnError?: boolean;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export interface HandlerResult {
|
|
38
|
-
success: boolean;
|
|
39
|
-
result?: unknown;
|
|
40
|
-
error?: string;
|
|
41
|
-
stack?: string;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export interface EmitResult {
|
|
45
|
-
event: EscrowEventType;
|
|
46
|
-
handled: boolean;
|
|
47
|
-
results: HandlerResult[];
|
|
48
|
-
errors?: HandlerResult[];
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
export type EscrowEventHandler = (payload: unknown) => Promise<unknown> | unknown;
|
|
52
|
-
|
|
53
|
-
export interface EscrowStakeInfo {
|
|
54
|
-
agent_id?: string;
|
|
55
|
-
stake?: number;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
export interface EscrowInfo {
|
|
59
|
-
proposal_id?: string;
|
|
60
|
-
from?: EscrowStakeInfo;
|
|
61
|
-
to?: EscrowStakeInfo;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
export interface EscrowResult {
|
|
65
|
-
escrow?: {
|
|
66
|
-
proposal_id?: string;
|
|
67
|
-
};
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
export interface RatingChanges {
|
|
71
|
-
_escrow?: {
|
|
72
|
-
proposer_stake?: number;
|
|
73
|
-
acceptor_stake?: number;
|
|
74
|
-
settlement?: string;
|
|
75
|
-
settlement_reason?: string;
|
|
76
|
-
fault_party?: string;
|
|
77
|
-
transferred?: number;
|
|
78
|
-
burned?: number;
|
|
79
|
-
};
|
|
80
|
-
[key: string]: unknown;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
export interface EscrowCreatedPayload {
|
|
84
|
-
event: typeof EscrowEvent.CREATED;
|
|
85
|
-
timestamp: number;
|
|
86
|
-
proposal_id: string;
|
|
87
|
-
from_agent: string;
|
|
88
|
-
to_agent: string;
|
|
89
|
-
proposer_stake: number;
|
|
90
|
-
acceptor_stake: number;
|
|
91
|
-
total_stake: number;
|
|
92
|
-
task: string;
|
|
93
|
-
amount?: number;
|
|
94
|
-
currency?: string;
|
|
95
|
-
expires?: number;
|
|
96
|
-
escrow_id: string;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
export interface CompletionPayload {
|
|
100
|
-
event: typeof EscrowEvent.COMPLETION_SETTLED;
|
|
101
|
-
timestamp: number;
|
|
102
|
-
proposal_id: string;
|
|
103
|
-
from_agent: string;
|
|
104
|
-
to_agent: string;
|
|
105
|
-
completed_by?: string;
|
|
106
|
-
completion_proof?: string;
|
|
107
|
-
settlement: string;
|
|
108
|
-
stakes_returned: {
|
|
109
|
-
proposer: number;
|
|
110
|
-
acceptor: number;
|
|
111
|
-
};
|
|
112
|
-
rating_changes: {
|
|
113
|
-
[key: string]: unknown;
|
|
114
|
-
};
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
export interface DisputePayload {
|
|
118
|
-
event: typeof EscrowEvent.DISPUTE_SETTLED;
|
|
119
|
-
timestamp: number;
|
|
120
|
-
proposal_id: string;
|
|
121
|
-
from_agent: string;
|
|
122
|
-
to_agent: string;
|
|
123
|
-
disputed_by?: string;
|
|
124
|
-
dispute_reason?: string;
|
|
125
|
-
settlement: string;
|
|
126
|
-
settlement_reason?: string;
|
|
127
|
-
fault_determination?: string;
|
|
128
|
-
stakes_transferred?: number;
|
|
129
|
-
stakes_burned?: number;
|
|
130
|
-
rating_changes: {
|
|
131
|
-
[key: string]: unknown;
|
|
132
|
-
};
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
export interface EscrowReleasedPayload {
|
|
136
|
-
event: typeof EscrowEvent.RELEASED;
|
|
137
|
-
timestamp: number;
|
|
138
|
-
proposal_id: string;
|
|
139
|
-
from_agent?: string;
|
|
140
|
-
to_agent?: string;
|
|
141
|
-
stakes_released: {
|
|
142
|
-
proposer: number;
|
|
143
|
-
acceptor: number;
|
|
144
|
-
};
|
|
145
|
-
reason: string;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
export interface ExtendedProposal extends Proposal {
|
|
149
|
-
proposer_stake?: number;
|
|
150
|
-
acceptor_stake?: number;
|
|
151
|
-
completed_by?: string;
|
|
152
|
-
completion_proof?: string;
|
|
153
|
-
disputed_by?: string;
|
|
154
|
-
dispute_reason?: string;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
export class EscrowHooks {
|
|
158
|
-
private handlers: Map<EscrowEventType, Set<EscrowEventHandler>>;
|
|
159
|
-
private logger: Logger;
|
|
160
|
-
private continueOnError: boolean;
|
|
161
|
-
|
|
162
|
-
constructor(options: EscrowHooksOptions = {}) {
|
|
163
|
-
this.handlers = new Map();
|
|
164
|
-
this.logger = options.logger || console;
|
|
165
|
-
this.continueOnError = options.continueOnError !== false; // default true
|
|
166
|
-
|
|
167
|
-
// Initialize event handler sets
|
|
168
|
-
for (const event of Object.values(EscrowEvent)) {
|
|
169
|
-
this.handlers.set(event, new Set());
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
/**
|
|
174
|
-
* Register a handler for an escrow event
|
|
175
|
-
* @param event - Event name from EscrowEvent
|
|
176
|
-
* @param handler - Async function(payload) to call
|
|
177
|
-
* @returns Unsubscribe function
|
|
178
|
-
*/
|
|
179
|
-
on(event: EscrowEventType, handler: EscrowEventHandler): () => void {
|
|
180
|
-
if (!this.handlers.has(event)) {
|
|
181
|
-
throw new Error(`Unknown escrow event: ${event}`);
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
if (typeof handler !== 'function') {
|
|
185
|
-
throw new Error('Handler must be a function');
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
this.handlers.get(event)!.add(handler);
|
|
189
|
-
|
|
190
|
-
// Return unsubscribe function
|
|
191
|
-
return () => this.off(event, handler);
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
/**
|
|
195
|
-
* Remove a handler for an escrow event
|
|
196
|
-
* @param event - Event name
|
|
197
|
-
* @param handler - Handler to remove
|
|
198
|
-
*/
|
|
199
|
-
off(event: EscrowEventType, handler: EscrowEventHandler): void {
|
|
200
|
-
if (this.handlers.has(event)) {
|
|
201
|
-
this.handlers.get(event)!.delete(handler);
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
/**
|
|
206
|
-
* Remove all handlers for an event (or all events)
|
|
207
|
-
* @param event - Optional event name
|
|
208
|
-
*/
|
|
209
|
-
clear(event?: EscrowEventType): void {
|
|
210
|
-
if (event) {
|
|
211
|
-
if (this.handlers.has(event)) {
|
|
212
|
-
this.handlers.get(event)!.clear();
|
|
213
|
-
}
|
|
214
|
-
} else {
|
|
215
|
-
for (const handlers of this.handlers.values()) {
|
|
216
|
-
handlers.clear();
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
/**
|
|
222
|
-
* Emit an escrow event to all registered handlers
|
|
223
|
-
* @param event - Event name
|
|
224
|
-
* @param payload - Event payload
|
|
225
|
-
* @returns Results from all handlers
|
|
226
|
-
*/
|
|
227
|
-
async emit(event: EscrowEventType, payload: unknown): Promise<EmitResult> {
|
|
228
|
-
if (!this.handlers.has(event)) {
|
|
229
|
-
throw new Error(`Unknown escrow event: ${event}`);
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
const handlers = this.handlers.get(event)!;
|
|
233
|
-
if (handlers.size === 0) {
|
|
234
|
-
return { event, handled: false, results: [] };
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
const results: HandlerResult[] = [];
|
|
238
|
-
const errors: HandlerResult[] = [];
|
|
239
|
-
|
|
240
|
-
for (const handler of handlers) {
|
|
241
|
-
try {
|
|
242
|
-
const result = await handler(payload);
|
|
243
|
-
results.push({ success: true, result });
|
|
244
|
-
} catch (err) {
|
|
245
|
-
const error = err as Error;
|
|
246
|
-
const errorInfo: HandlerResult = {
|
|
247
|
-
success: false,
|
|
248
|
-
error: error.message,
|
|
249
|
-
stack: error.stack
|
|
250
|
-
};
|
|
251
|
-
errors.push(errorInfo);
|
|
252
|
-
results.push(errorInfo);
|
|
253
|
-
|
|
254
|
-
this.logger.error?.(`[EscrowHooks] Error in ${event} handler:`, error.message);
|
|
255
|
-
|
|
256
|
-
if (!this.continueOnError) {
|
|
257
|
-
break;
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
return {
|
|
263
|
-
event,
|
|
264
|
-
handled: true,
|
|
265
|
-
results,
|
|
266
|
-
errors: errors.length > 0 ? errors : undefined
|
|
267
|
-
};
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
/**
|
|
271
|
-
* Check if any handlers are registered for an event
|
|
272
|
-
* @param event - Event name
|
|
273
|
-
* @returns True if handlers exist
|
|
274
|
-
*/
|
|
275
|
-
hasHandlers(event: EscrowEventType): boolean {
|
|
276
|
-
return this.handlers.has(event) && this.handlers.get(event)!.size > 0;
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
/**
|
|
280
|
-
* Get count of handlers for an event
|
|
281
|
-
* @param event - Event name
|
|
282
|
-
* @returns Number of handlers
|
|
283
|
-
*/
|
|
284
|
-
handlerCount(event: EscrowEventType): number {
|
|
285
|
-
return this.handlers.has(event) ? this.handlers.get(event)!.size : 0;
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
/**
|
|
290
|
-
* Create payload for escrow:created event
|
|
291
|
-
*/
|
|
292
|
-
export function createEscrowCreatedPayload(
|
|
293
|
-
proposal: ExtendedProposal,
|
|
294
|
-
escrowResult: EscrowResult
|
|
295
|
-
): EscrowCreatedPayload {
|
|
296
|
-
return {
|
|
297
|
-
event: EscrowEvent.CREATED,
|
|
298
|
-
timestamp: Date.now(),
|
|
299
|
-
proposal_id: proposal.id,
|
|
300
|
-
from_agent: proposal.from,
|
|
301
|
-
to_agent: proposal.to,
|
|
302
|
-
proposer_stake: proposal.proposer_stake || 0,
|
|
303
|
-
acceptor_stake: proposal.acceptor_stake || 0,
|
|
304
|
-
total_stake: (proposal.proposer_stake || 0) + (proposal.acceptor_stake || 0),
|
|
305
|
-
task: proposal.task,
|
|
306
|
-
amount: proposal.amount,
|
|
307
|
-
currency: proposal.currency,
|
|
308
|
-
expires: proposal.expires,
|
|
309
|
-
escrow_id: escrowResult.escrow?.proposal_id || proposal.id
|
|
310
|
-
};
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
/**
|
|
314
|
-
* Create payload for settlement:completion event
|
|
315
|
-
*/
|
|
316
|
-
export function createCompletionPayload(
|
|
317
|
-
proposal: ExtendedProposal,
|
|
318
|
-
ratingChanges?: RatingChanges
|
|
319
|
-
): CompletionPayload {
|
|
320
|
-
const escrowInfo = ratingChanges?._escrow || {};
|
|
321
|
-
return {
|
|
322
|
-
event: EscrowEvent.COMPLETION_SETTLED,
|
|
323
|
-
timestamp: Date.now(),
|
|
324
|
-
proposal_id: proposal.id,
|
|
325
|
-
from_agent: proposal.from,
|
|
326
|
-
to_agent: proposal.to,
|
|
327
|
-
completed_by: proposal.completed_by,
|
|
328
|
-
completion_proof: proposal.completion_proof,
|
|
329
|
-
settlement: 'returned',
|
|
330
|
-
stakes_returned: {
|
|
331
|
-
proposer: escrowInfo.proposer_stake || 0,
|
|
332
|
-
acceptor: escrowInfo.acceptor_stake || 0
|
|
333
|
-
},
|
|
334
|
-
rating_changes: {
|
|
335
|
-
[proposal.from]: ratingChanges?.[proposal.from],
|
|
336
|
-
[proposal.to]: ratingChanges?.[proposal.to]
|
|
337
|
-
}
|
|
338
|
-
};
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
/**
|
|
342
|
-
* Create payload for settlement:dispute event
|
|
343
|
-
*/
|
|
344
|
-
export function createDisputePayload(
|
|
345
|
-
proposal: ExtendedProposal,
|
|
346
|
-
ratingChanges?: RatingChanges
|
|
347
|
-
): DisputePayload {
|
|
348
|
-
const escrowInfo = ratingChanges?._escrow || {};
|
|
349
|
-
return {
|
|
350
|
-
event: EscrowEvent.DISPUTE_SETTLED,
|
|
351
|
-
timestamp: Date.now(),
|
|
352
|
-
proposal_id: proposal.id,
|
|
353
|
-
from_agent: proposal.from,
|
|
354
|
-
to_agent: proposal.to,
|
|
355
|
-
disputed_by: proposal.disputed_by,
|
|
356
|
-
dispute_reason: proposal.dispute_reason,
|
|
357
|
-
settlement: escrowInfo.settlement || 'settled',
|
|
358
|
-
settlement_reason: escrowInfo.settlement_reason,
|
|
359
|
-
fault_determination: escrowInfo.fault_party,
|
|
360
|
-
stakes_transferred: escrowInfo.transferred,
|
|
361
|
-
stakes_burned: escrowInfo.burned,
|
|
362
|
-
rating_changes: {
|
|
363
|
-
[proposal.from]: ratingChanges?.[proposal.from],
|
|
364
|
-
[proposal.to]: ratingChanges?.[proposal.to]
|
|
365
|
-
}
|
|
366
|
-
};
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
/**
|
|
370
|
-
* Create payload for escrow:released event
|
|
371
|
-
*/
|
|
372
|
-
export function createEscrowReleasedPayload(
|
|
373
|
-
proposalId: string,
|
|
374
|
-
escrow: EscrowInfo,
|
|
375
|
-
reason?: string
|
|
376
|
-
): EscrowReleasedPayload {
|
|
377
|
-
return {
|
|
378
|
-
event: EscrowEvent.RELEASED,
|
|
379
|
-
timestamp: Date.now(),
|
|
380
|
-
proposal_id: proposalId,
|
|
381
|
-
from_agent: escrow.from?.agent_id,
|
|
382
|
-
to_agent: escrow.to?.agent_id,
|
|
383
|
-
stakes_released: {
|
|
384
|
-
proposer: escrow.from?.stake || 0,
|
|
385
|
-
acceptor: escrow.to?.stake || 0
|
|
386
|
-
},
|
|
387
|
-
reason: reason || 'expired'
|
|
388
|
-
};
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
export default EscrowHooks;
|