@xpr-agents/sdk 0.1.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.
@@ -0,0 +1,83 @@
1
+ import { Feedback, FeedbackConfig, AgentScore, Dispute, FeedbackListOptions, SubmitFeedbackData, TransactionResult, JsonRpc, ProtonSession } from './types';
2
+ export declare class FeedbackRegistry {
3
+ private rpc;
4
+ private session;
5
+ private contract;
6
+ constructor(rpc: JsonRpc, session?: ProtonSession, contract?: string);
7
+ /**
8
+ * Get feedback by ID
9
+ */
10
+ getFeedback(id: number): Promise<Feedback | null>;
11
+ /**
12
+ * List feedback for an agent
13
+ */
14
+ listFeedbackForAgent(agent: string, options?: FeedbackListOptions): Promise<Feedback[]>;
15
+ /**
16
+ * List feedback submitted by a reviewer
17
+ */
18
+ listFeedbackByReviewer(reviewer: string, options?: FeedbackListOptions): Promise<Feedback[]>;
19
+ /**
20
+ * Get aggregated score for an agent
21
+ */
22
+ getAgentScore(agent: string): Promise<AgentScore | null>;
23
+ /**
24
+ * Get dispute by ID
25
+ */
26
+ getDispute(id: number): Promise<Dispute | null>;
27
+ /**
28
+ * Get disputes for a feedback
29
+ */
30
+ getDisputesForFeedback(feedbackId: number): Promise<Dispute[]>;
31
+ /**
32
+ * Submit feedback for an agent
33
+ */
34
+ submit(data: SubmitFeedbackData): Promise<TransactionResult>;
35
+ /**
36
+ * Dispute feedback
37
+ */
38
+ dispute(feedbackId: number, reason: string, evidenceUri?: string): Promise<TransactionResult>;
39
+ /**
40
+ * Recalculate agent score (paginated).
41
+ *
42
+ * Recalculation is done in batches to avoid CPU exhaustion.
43
+ * - First call: offset=0, processes first `limit` feedbacks
44
+ * - Subsequent calls: use the next_offset from RecalcState
45
+ * - Recalculation expires after 1 hour if not completed
46
+ *
47
+ * @param agent - Agent account to recalculate
48
+ * @param offset - Must be 0 to start, or match next_offset to continue
49
+ * @param limit - Feedbacks to process per call (max 100)
50
+ */
51
+ recalculate(agent: string, offset?: number, limit?: number): Promise<TransactionResult>;
52
+ /**
53
+ * Resolve a feedback dispute (owner only)
54
+ */
55
+ resolve(disputeId: number, upheld: boolean, resolutionNotes: string): Promise<TransactionResult>;
56
+ /**
57
+ * Cancel an in-progress recalculation
58
+ */
59
+ cancelRecalculation(agent: string): Promise<TransactionResult>;
60
+ /**
61
+ * Submit feedback with fee in one transaction.
62
+ *
63
+ * @param data - Feedback data
64
+ * @param amount - The feedback fee (e.g., "1.0000 XPR")
65
+ */
66
+ submitWithFee(data: SubmitFeedbackData, amount: string): Promise<TransactionResult>;
67
+ /**
68
+ * Clean up old feedback entries (permissionless)
69
+ */
70
+ cleanFeedback(agent: string, maxAge: number, maxDelete: number): Promise<TransactionResult>;
71
+ /**
72
+ * Clean up resolved disputes (permissionless)
73
+ */
74
+ cleanDisputes(maxAge: number, maxDelete: number): Promise<TransactionResult>;
75
+ /**
76
+ * Get feedback contract configuration
77
+ */
78
+ getConfig(): Promise<FeedbackConfig>;
79
+ private requireSession;
80
+ private parseFeedback;
81
+ private parseAgentScore;
82
+ private parseDispute;
83
+ }
@@ -0,0 +1,424 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FeedbackRegistry = void 0;
4
+ const utils_1 = require("./utils");
5
+ const DEFAULT_CONTRACT = 'agentfeed';
6
+ class FeedbackRegistry {
7
+ constructor(rpc, session, contract) {
8
+ this.rpc = rpc;
9
+ this.session = session || null;
10
+ this.contract = contract || DEFAULT_CONTRACT;
11
+ }
12
+ // ============== READ OPERATIONS ==============
13
+ /**
14
+ * Get feedback by ID
15
+ */
16
+ async getFeedback(id) {
17
+ const result = await this.rpc.get_table_rows({
18
+ json: true,
19
+ code: this.contract,
20
+ scope: this.contract,
21
+ table: 'feedback',
22
+ lower_bound: String(id),
23
+ upper_bound: String(id),
24
+ limit: 1,
25
+ });
26
+ if (result.rows.length === 0)
27
+ return null;
28
+ return this.parseFeedback(result.rows[0]);
29
+ }
30
+ /**
31
+ * List feedback for an agent
32
+ */
33
+ async listFeedbackForAgent(agent, options = {}) {
34
+ const { limit = 100 } = options;
35
+ const result = await this.rpc.get_table_rows({
36
+ json: true,
37
+ code: this.contract,
38
+ scope: this.contract,
39
+ table: 'feedback',
40
+ index_position: 2,
41
+ key_type: 'i64',
42
+ limit,
43
+ });
44
+ let feedbacks = result.rows
45
+ .filter((row) => row.agent === agent)
46
+ .map((row) => this.parseFeedback(row));
47
+ if (options.min_score !== undefined) {
48
+ feedbacks = feedbacks.filter((f) => f.score >= options.min_score);
49
+ }
50
+ if (options.max_score !== undefined) {
51
+ feedbacks = feedbacks.filter((f) => f.score <= options.max_score);
52
+ }
53
+ return feedbacks;
54
+ }
55
+ /**
56
+ * List feedback submitted by a reviewer
57
+ */
58
+ async listFeedbackByReviewer(reviewer, options = {}) {
59
+ const { limit = 100 } = options;
60
+ const result = await this.rpc.get_table_rows({
61
+ json: true,
62
+ code: this.contract,
63
+ scope: this.contract,
64
+ table: 'feedback',
65
+ index_position: 3,
66
+ key_type: 'i64',
67
+ limit,
68
+ });
69
+ return result.rows
70
+ .filter((row) => row.reviewer === reviewer)
71
+ .map((row) => this.parseFeedback(row));
72
+ }
73
+ /**
74
+ * Get aggregated score for an agent
75
+ */
76
+ async getAgentScore(agent) {
77
+ const result = await this.rpc.get_table_rows({
78
+ json: true,
79
+ code: this.contract,
80
+ scope: this.contract,
81
+ table: 'agentscores',
82
+ lower_bound: agent,
83
+ upper_bound: agent,
84
+ limit: 1,
85
+ });
86
+ if (result.rows.length === 0)
87
+ return null;
88
+ return this.parseAgentScore(result.rows[0]);
89
+ }
90
+ /**
91
+ * Get dispute by ID
92
+ */
93
+ async getDispute(id) {
94
+ const result = await this.rpc.get_table_rows({
95
+ json: true,
96
+ code: this.contract,
97
+ scope: this.contract,
98
+ table: 'disputes',
99
+ lower_bound: String(id),
100
+ upper_bound: String(id),
101
+ limit: 1,
102
+ });
103
+ if (result.rows.length === 0)
104
+ return null;
105
+ return this.parseDispute(result.rows[0]);
106
+ }
107
+ /**
108
+ * Get disputes for a feedback
109
+ */
110
+ async getDisputesForFeedback(feedbackId) {
111
+ const result = await this.rpc.get_table_rows({
112
+ json: true,
113
+ code: this.contract,
114
+ scope: this.contract,
115
+ table: 'disputes',
116
+ index_position: 2,
117
+ key_type: 'i64',
118
+ limit: 100,
119
+ });
120
+ return result.rows
121
+ .filter((row) => row.feedback_id === String(feedbackId))
122
+ .map((row) => this.parseDispute(row));
123
+ }
124
+ // ============== WRITE OPERATIONS ==============
125
+ /**
126
+ * Submit feedback for an agent
127
+ */
128
+ async submit(data) {
129
+ this.requireSession();
130
+ return this.session.link.transact({
131
+ actions: [
132
+ {
133
+ account: this.contract,
134
+ name: 'submit',
135
+ authorization: [
136
+ {
137
+ actor: this.session.auth.actor,
138
+ permission: this.session.auth.permission,
139
+ },
140
+ ],
141
+ data: {
142
+ reviewer: this.session.auth.actor,
143
+ agent: data.agent,
144
+ score: data.score,
145
+ tags: (data.tags || []).join(','),
146
+ job_hash: data.job_hash || '',
147
+ evidence_uri: data.evidence_uri || '',
148
+ amount_paid: data.amount_paid || 0,
149
+ },
150
+ },
151
+ ],
152
+ });
153
+ }
154
+ /**
155
+ * Dispute feedback
156
+ */
157
+ async dispute(feedbackId, reason, evidenceUri) {
158
+ this.requireSession();
159
+ return this.session.link.transact({
160
+ actions: [
161
+ {
162
+ account: this.contract,
163
+ name: 'dispute',
164
+ authorization: [
165
+ {
166
+ actor: this.session.auth.actor,
167
+ permission: this.session.auth.permission,
168
+ },
169
+ ],
170
+ data: {
171
+ disputer: this.session.auth.actor,
172
+ feedback_id: feedbackId,
173
+ reason,
174
+ evidence_uri: evidenceUri || '',
175
+ },
176
+ },
177
+ ],
178
+ });
179
+ }
180
+ /**
181
+ * Recalculate agent score (paginated).
182
+ *
183
+ * Recalculation is done in batches to avoid CPU exhaustion.
184
+ * - First call: offset=0, processes first `limit` feedbacks
185
+ * - Subsequent calls: use the next_offset from RecalcState
186
+ * - Recalculation expires after 1 hour if not completed
187
+ *
188
+ * @param agent - Agent account to recalculate
189
+ * @param offset - Must be 0 to start, or match next_offset to continue
190
+ * @param limit - Feedbacks to process per call (max 100)
191
+ */
192
+ async recalculate(agent, offset = 0, limit = 100) {
193
+ this.requireSession();
194
+ return this.session.link.transact({
195
+ actions: [
196
+ {
197
+ account: this.contract,
198
+ name: 'recalc',
199
+ authorization: [
200
+ {
201
+ actor: this.session.auth.actor,
202
+ permission: this.session.auth.permission,
203
+ },
204
+ ],
205
+ data: {
206
+ agent,
207
+ offset,
208
+ limit,
209
+ },
210
+ },
211
+ ],
212
+ });
213
+ }
214
+ /**
215
+ * Resolve a feedback dispute (owner only)
216
+ */
217
+ async resolve(disputeId, upheld, resolutionNotes) {
218
+ this.requireSession();
219
+ return this.session.link.transact({
220
+ actions: [
221
+ {
222
+ account: this.contract,
223
+ name: 'resolve',
224
+ authorization: [
225
+ {
226
+ actor: this.session.auth.actor,
227
+ permission: this.session.auth.permission,
228
+ },
229
+ ],
230
+ data: {
231
+ resolver: this.session.auth.actor,
232
+ dispute_id: disputeId,
233
+ upheld,
234
+ resolution_notes: resolutionNotes,
235
+ },
236
+ },
237
+ ],
238
+ });
239
+ }
240
+ /**
241
+ * Cancel an in-progress recalculation
242
+ */
243
+ async cancelRecalculation(agent) {
244
+ this.requireSession();
245
+ return this.session.link.transact({
246
+ actions: [
247
+ {
248
+ account: this.contract,
249
+ name: 'cancelrecalc',
250
+ authorization: [
251
+ {
252
+ actor: this.session.auth.actor,
253
+ permission: this.session.auth.permission,
254
+ },
255
+ ],
256
+ data: {
257
+ agent,
258
+ },
259
+ },
260
+ ],
261
+ });
262
+ }
263
+ /**
264
+ * Submit feedback with fee in one transaction.
265
+ *
266
+ * @param data - Feedback data
267
+ * @param amount - The feedback fee (e.g., "1.0000 XPR")
268
+ */
269
+ async submitWithFee(data, amount) {
270
+ this.requireSession();
271
+ const actor = this.session.auth.actor;
272
+ return this.session.link.transact({
273
+ actions: [
274
+ {
275
+ account: 'eosio.token',
276
+ name: 'transfer',
277
+ authorization: [{
278
+ actor,
279
+ permission: this.session.auth.permission,
280
+ }],
281
+ data: {
282
+ from: actor,
283
+ to: this.contract,
284
+ quantity: amount,
285
+ memo: `feedfee:${actor}`,
286
+ },
287
+ },
288
+ {
289
+ account: this.contract,
290
+ name: 'submit',
291
+ authorization: [{
292
+ actor,
293
+ permission: this.session.auth.permission,
294
+ }],
295
+ data: {
296
+ reviewer: actor,
297
+ agent: data.agent,
298
+ score: data.score,
299
+ tags: (data.tags || []).join(','),
300
+ job_hash: data.job_hash || '',
301
+ evidence_uri: data.evidence_uri || '',
302
+ amount_paid: data.amount_paid || 0,
303
+ },
304
+ },
305
+ ],
306
+ });
307
+ }
308
+ /**
309
+ * Clean up old feedback entries (permissionless)
310
+ */
311
+ async cleanFeedback(agent, maxAge, maxDelete) {
312
+ this.requireSession();
313
+ return this.session.link.transact({
314
+ actions: [{
315
+ account: this.contract,
316
+ name: 'cleanfback',
317
+ authorization: [{
318
+ actor: this.session.auth.actor,
319
+ permission: this.session.auth.permission,
320
+ }],
321
+ data: {
322
+ agent,
323
+ max_age: maxAge,
324
+ max_delete: maxDelete,
325
+ },
326
+ }],
327
+ });
328
+ }
329
+ /**
330
+ * Clean up resolved disputes (permissionless)
331
+ */
332
+ async cleanDisputes(maxAge, maxDelete) {
333
+ this.requireSession();
334
+ return this.session.link.transact({
335
+ actions: [{
336
+ account: this.contract,
337
+ name: 'cleandisps',
338
+ authorization: [{
339
+ actor: this.session.auth.actor,
340
+ permission: this.session.auth.permission,
341
+ }],
342
+ data: {
343
+ max_age: maxAge,
344
+ max_delete: maxDelete,
345
+ },
346
+ }],
347
+ });
348
+ }
349
+ /**
350
+ * Get feedback contract configuration
351
+ */
352
+ async getConfig() {
353
+ const result = await this.rpc.get_table_rows({
354
+ json: true,
355
+ code: this.contract,
356
+ scope: this.contract,
357
+ table: 'config',
358
+ limit: 1,
359
+ });
360
+ if (result.rows.length === 0) {
361
+ throw new Error('Contract not initialized');
362
+ }
363
+ const row = result.rows[0];
364
+ return {
365
+ owner: row.owner,
366
+ core_contract: row.core_contract,
367
+ min_score: row.min_score,
368
+ max_score: row.max_score,
369
+ dispute_window: (0, utils_1.safeParseInt)(row.dispute_window),
370
+ decay_period: (0, utils_1.safeParseInt)(row.decay_period),
371
+ decay_floor: (0, utils_1.safeParseInt)(row.decay_floor),
372
+ paused: row.paused === 1,
373
+ feedback_fee: (0, utils_1.safeParseInt)(row.feedback_fee),
374
+ };
375
+ }
376
+ // ============== HELPERS ==============
377
+ requireSession() {
378
+ if (!this.session) {
379
+ throw new Error('Session required for write operations');
380
+ }
381
+ }
382
+ parseFeedback(raw) {
383
+ return {
384
+ id: (0, utils_1.safeParseInt)(raw.id),
385
+ agent: raw.agent,
386
+ reviewer: raw.reviewer,
387
+ reviewer_kyc_level: raw.reviewer_kyc_level,
388
+ score: raw.score,
389
+ tags: (0, utils_1.parseTags)(raw.tags),
390
+ job_hash: raw.job_hash,
391
+ evidence_uri: raw.evidence_uri,
392
+ amount_paid: (0, utils_1.safeParseInt)(raw.amount_paid),
393
+ timestamp: (0, utils_1.safeParseInt)(raw.timestamp),
394
+ disputed: raw.disputed === 1,
395
+ resolved: raw.resolved === 1,
396
+ };
397
+ }
398
+ parseAgentScore(raw) {
399
+ return {
400
+ agent: raw.agent,
401
+ total_score: (0, utils_1.safeParseInt)(raw.total_score),
402
+ total_weight: (0, utils_1.safeParseInt)(raw.total_weight),
403
+ feedback_count: (0, utils_1.safeParseInt)(raw.feedback_count),
404
+ avg_score: (0, utils_1.safeParseInt)(raw.avg_score),
405
+ last_updated: (0, utils_1.safeParseInt)(raw.last_updated),
406
+ };
407
+ }
408
+ parseDispute(raw) {
409
+ return {
410
+ id: (0, utils_1.safeParseInt)(raw.id),
411
+ feedback_id: (0, utils_1.safeParseInt)(raw.feedback_id),
412
+ disputer: raw.disputer,
413
+ reason: raw.reason,
414
+ evidence_uri: raw.evidence_uri,
415
+ status: (0, utils_1.disputeStatusFromNumber)(raw.status),
416
+ resolver: raw.resolver,
417
+ resolution_notes: raw.resolution_notes,
418
+ created_at: (0, utils_1.safeParseInt)(raw.created_at),
419
+ resolved_at: (0, utils_1.safeParseInt)(raw.resolved_at),
420
+ };
421
+ }
422
+ }
423
+ exports.FeedbackRegistry = FeedbackRegistry;
424
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRmVlZGJhY2tSZWdpc3RyeS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9GZWVkYmFja1JlZ2lzdHJ5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQWFBLG1DQUEyRTtBQUUzRSxNQUFNLGdCQUFnQixHQUFHLFdBQVcsQ0FBQztBQUVyQyxNQUFhLGdCQUFnQjtJQUszQixZQUFZLEdBQVksRUFBRSxPQUF1QixFQUFFLFFBQWlCO1FBQ2xFLElBQUksQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDO1FBQ2YsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLElBQUksSUFBSSxDQUFDO1FBQy9CLElBQUksQ0FBQyxRQUFRLEdBQUcsUUFBUSxJQUFJLGdCQUFnQixDQUFDO0lBQy9DLENBQUM7SUFFRCxnREFBZ0Q7SUFFaEQ7O09BRUc7SUFDSCxLQUFLLENBQUMsV0FBVyxDQUFDLEVBQVU7UUFDMUIsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsR0FBRyxDQUFDLGNBQWMsQ0FBYztZQUN4RCxJQUFJLEVBQUUsSUFBSTtZQUNWLElBQUksRUFBRSxJQUFJLENBQUMsUUFBUTtZQUNuQixLQUFLLEVBQUUsSUFBSSxDQUFDLFFBQVE7WUFDcEIsS0FBSyxFQUFFLFVBQVU7WUFDakIsV0FBVyxFQUFFLE1BQU0sQ0FBQyxFQUFFLENBQUM7WUFDdkIsV0FBVyxFQUFFLE1BQU0sQ0FBQyxFQUFFLENBQUM7WUFDdkIsS0FBSyxFQUFFLENBQUM7U0FDVCxDQUFDLENBQUM7UUFFSCxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsTUFBTSxLQUFLLENBQUM7WUFBRSxPQUFPLElBQUksQ0FBQztRQUMxQyxPQUFPLElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzVDLENBQUM7SUFFRDs7T0FFRztJQUNILEtBQUssQ0FBQyxvQkFBb0IsQ0FDeEIsS0FBYSxFQUNiLFVBQStCLEVBQUU7UUFFakMs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LFlBQVksRUFBRSxJQUFBLG9CQUFZLEVBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQztTQUM3QyxDQUFDO0lBQ0osQ0FBQztJQUVPLFlBQVksQ0FBQyxHQVdwQjtRQUNDLE9BQU87WUFDTCxFQUFFLEVBQUUsSUFBQSxvQkFBWSxFQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDeEIsV0FBVyxFQUFFLElBQUEsb0JBQVksRUFBQyxHQUFHLENBQUMsV0FBVyxDQUFDO1lBQzFDLFFBQVEsRUFBRSxHQUFHLENBQUMsUUFBUTtZQUN0QixNQUFNLEVBQUUsR0FBRyxDQUFDLE1BQU07WUFDbEIsWUFBWSxFQUFFLEdBQUcsQ0FBQyxZQUFZO1lBQzlCLE1BQU0sRUFBRSxJQUFBLCtCQUF1QixFQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUM7WUFDM0MsUUFBUSxFQUFFLEdBQUcsQ0FBQyxRQUFRO1lBQ3RCLGdCQUFnQixFQUFFLEdBQUcsQ0FBQyxnQkFBZ0I7WUFDdEMsVUFBVSxFQUFFLElBQUEsb0JBQVksRUFBQyxHQUFHLENBQUMsVUFBVSxDQUFDO1lBQ3hDLFdBQVcsRUFBRSxJQUFBLG9CQUFZLEVBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQztTQUMzQyxDQUFDO0lBQ0osQ0FBQztDQUNGO0FBdGdCRCw0Q0FzZ0JDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgRmVlZGJhY2ssXG4gIEZlZWRiYWNrUmF3LFxuICBGZWVkYmFja0NvbmZpZyxcbiAgQWdlbnRTY29yZSxcbiAgQWdlbnRTY29yZVJhdyxcbiAgRGlzcHV0ZSxcbiAgRmVlZGJhY2tMaXN0T3B0aW9ucyxcbiAgU3VibWl0RmVlZGJhY2tEYXRhLFxuICBUcmFuc2FjdGlvblJlc3VsdCxcbiAgSnNvblJwYyxcbiAgUHJvdG9uU2Vzc2lvbixcbn0gZnJvbSAnLi90eXBlcyc7XG5pbXBvcnQgeyBwYXJzZVRhZ3MsIGRpc3B1dGVTdGF0dXNGcm9tTnVtYmVyLCBzYWZlUGFyc2VJbnQgfSBmcm9tICcuL3V0aWxzJztcblxuY29uc3QgREVGQVVMVF9DT05UUkFDVCA9ICdhZ2VudGZlZWQnO1xuXG5leHBvcnQgY2xhc3MgRmVlZGJhY2tSZWdpc3RyeSB7XG4gIHByaXZhdGUgcnBjOiBKc29uUnBjO1xuICBwcml2YXRlIHNlc3Npb246IFByb3RvblNlc3Npb24gfCBudWxsO1xuICBwcml2YXRlIGNvbnRyYWN0OiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3IocnBjOiBKc29uUnBjLCBzZXNzaW9uPzogUHJvdG9uU2Vzc2lvbiwgY29udHJhY3Q/OiBzdHJpbmcpIHtcbiAgICB0aGlzLnJwYyA9IHJwYztcbiAgICB0aGlzLnNlc3Npb24gPSBzZXNzaW9uIHx8IG51bGw7XG4gICAgdGhpcy5jb250cmFjdCA9IGNvbnRyYWN0IHx8IERFRkFVTFRfQ09OVFJBQ1Q7XG4gIH1cblxuICAvLyA9PT09PT09PT09PT09PSBSRUFEIE9QRVJBVElPTlMgPT09PT09PT09PT09PT1cblxuICAvKipcbiAgICogR2V0IGZlZWRiYWNrIGJ5IElEXG4gICAqL1xuICBhc3luYyBnZXRGZWVkYmFjayhpZDogbnVtYmVyKTogUHJvbWlzZTxGZWVkYmFjayB8IG51bGw+IHtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLnJwYy5nZXRfdGFibGVfcm93czxGZWVkYmFja1Jhdz4oe1xuICAgICAganNvbjogdHJ1ZSxcbiAgICAgIGNvZGU6IHRoaXMuY29udHJhY3QsXG4gICAgICBzY29wZTogdGhpcy5jb250cmFjdCxcbiAgICAgIHRhYmxlOiAnZmVlZGJhY2snLFxuICAgICAgbG93ZXJfYm91bmQ6IFN0cmluZyhpZCksXG4gICAgICB1cHBlcl9ib3VuZDogU3RyaW5nKGlkKSxcbiAgICAgIGxpbWl0OiAxLFxuICAgIH0pO1xuXG4gICAgaWYgKHJlc3VsdC5yb3dzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIG51bGw7XG4gICAgcmV0dXJuIHRoaXMucGFyc2VGZWVkYmFjayhyZXN1bHQucm93c1swXSk7XG4gIH1cblxuICAvKipcbiAgICogTGlzdCBmZWVkYmFjayBmb3IgYW4gYWdlbnRcbiAgICovXG4gIGFzeW5jIGxpc3RGZWVkYmFja0ZvckFnZW50KFxuICAgIGFnZW50OiBzdHJpbmcsXG4gICAgb3B0aW9uczogRmVlZGJhY2tMaXN0T3B0aW9ucyA9IHt9XG4gICk6IFByb21pc2U8RmVlZGJhY2tbXT4ge1xuICAgIGNvbnN0IHsgbGltaXQgPSAxMDAgfSA9IG9wdGlvbnM7XG5cbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLnJwYy5nZXRfdGFibGVfcm93czxGZWVkYmFja1Jhdz4oe1xuICAgICAganNvbjogdHJ1ZSxcbiAgICAgIGNvZGU6IHRoaXMuY29udHJhY3QsXG4gICAgICBzY29wZTogdGhpcy5jb250cmFjdCxcbiAgICAgIHRhYmxlOiAnZmVlZGJhY2snLFxuICAgICAgaW5kZXhfcG9zaXRpb246IDIsXG4gICAgICBrZXlfdHlwZTogJ2k2NCcsXG4gICAgICBsaW1pdCxcbiAgICB9KTtcblxuICAgIGxldCBmZWVkYmFja3MgPSByZXN1bHQucm93c1xuICAgICAgLmZpbHRlcigocm93KSA9PiByb3cuYWdlbnQgPT09IGFnZW50KVxuICAgICAgLm1hcCgocm93KSA9PiB0aGlzLnBhcnNlRmVlZGJhY2socm93KSk7XG5cbiAgICBpZiAob3B0aW9ucy5taW5fc2NvcmUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgZmVlZGJhY2tzID0gZmVlZGJhY2tzLmZpbHRlcigoZikgPT4gZi5zY29yZSA+PSBvcHRpb25zLm1pbl9zY29yZSEpO1xuICAgIH1cblxuICAgIGlmIChvcHRpb25zLm1heF9zY29yZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBmZWVkYmFja3MgPSBmZWVkYmFja3MuZmlsdGVyKChmKSA9PiBmLnNjb3JlIDw9IG9wdGlvbnMubWF4X3Njb3JlISk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGZlZWRiYWNrcztcbiAgfVxuXG4gIC8qKlxuICAgKiBMaXN0IGZlZWRiYWNrIHN1Ym1pdHRlZCBieSBhIHJldmlld2VyXG4gICAqL1xuICBhc3luYyBsaXN0RmVlZGJhY2tCeVJldmlld2VyKFxuICAgIHJldmlld2VyOiBzdHJpbmcsXG4gICAgb3B0aW9uczogRmVlZGJhY2tMaXN0T3B0aW9ucyA9IHt9XG4gICk6IFByb21pc2U8RmVlZGJhY2tbXT4ge1xuICAgIGNvbnN0IHsgbGltaXQgPSAxMDAgfSA9IG9wdGlvbnM7XG5cbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLnJwYy5nZXRfdGFibGVfcm93czxGZWVkYmFja1Jhdz4oe1xuICAgICAganNvbjogdHJ1ZSxcbiAgICAgIGNvZGU6IHRoaXMuY29udHJhY3QsXG4gICAgICBzY29wZTogdGhpcy5jb250cmFjdCxcbiAgICAgIHRhYmxlOiAnZmVlZGJhY2snLFxuICAgICAgaW5kZXhfcG9zaXRpb246IDMsXG4gICAgICBrZXlfdHlwZTogJ2k2NCcsXG4gICAgICBsaW1pdCxcbiAgICB9KTtcblxuICAgIHJldHVybiByZXN1bHQucm93c1xuICAgICAgLmZpbHRlcigocm93KSA9PiByb3cucmV2aWV3ZXIgPT09IHJldmlld2VyKVxuICAgICAgLm1hcCgocm93KSA9PiB0aGlzLnBhcnNlRmVlZGJhY2socm93KSk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IGFnZ3JlZ2F0ZWQgc2NvcmUgZm9yIGFuIGFnZW50XG4gICAqL1xuICBhc3luYyBnZXRBZ2VudFNjb3JlKGFnZW50OiBzdHJpbmcpOiBQcm9taXNlPEFnZW50U2NvcmUgfCBudWxsPiB7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5ycGMuZ2V0X3RhYmxlX3Jvd3M8QWdlbnRTY29yZVJhdz4oe1xuICAgICAganNvbjogdHJ1ZSxcbiAgICAgIGNvZGU6IHRoaXMuY29udHJhY3QsXG4gICAgICBzY29wZTogdGhpcy5jb250cmFjdCxcbiAgICAgIHRhYmxlOiAnYWdlbnRzY29yZXMnLFxuICAgICAgbG93ZXJfYm91bmQ6IGFnZW50LFxuICAgICAgdXBwZXJfYm91bmQ6IGFnZW50LFxuICAgICAgbGltaXQ6IDEsXG4gICAgfSk7XG5cbiAgICBpZiAocmVzdWx0LnJvd3MubGVuZ3RoID09PSAwKSByZXR1cm4gbnVsbDtcbiAgICByZXR1cm4gdGhpcy5wYXJzZUFnZW50U2NvcmUocmVzdWx0LnJvd3NbMF0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBkaXNwdXRlIGJ5IElEXG4gICAqL1xuICBhc3luYyBnZXREaXNwdXRlKGlkOiBudW1iZXIpOiBQcm9taXNlPERpc3B1dGUgfCBudWxsPiB7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5ycGMuZ2V0X3RhYmxlX3Jvd3M8e1xuICAgICAgaWQ6IHN0cmluZztcbiAgICAgIGZlZWRiYWNrX2lkOiBzdHJpbmc7XG4gICAgICBkaXNwdXRlcjogc3RyaW5nO1xuICAgICAgcmVhc29uOiBzdHJpbmc7XG4gICAgICBldmlkZW5jZV91cmk6IHN0cmluZztcbiAgICAgIHN0YXR1czogbnVtYmVyO1xuICAgICAgcmVzb2x2ZXI6IHN0cmluZztcbiAgICAgIHJlc29sdXRpb25fbm90ZXM6IHN0cmluZztcbiAgICAgIGNyZWF0ZWRfYXQ6IHN0cmluZztcbiAgICAgIHJlc29sdmVkX2F0OiBzdHJpbmc7XG4gICAgfT4oe1xuICAgICAganNvbjogdHJ1ZSxcbiAgICAgIGNvZGU6IHRoaXMuY29udHJhY3QsXG4gICAgICBzY29wZTogdGhpcy5jb250cmFjdCxcbiAgICAgIHRhYmxlOiAnZGlzcHV0ZXMnLFxuICAgICAgbG93ZXJfYm91bmQ6IFN0cmluZyhpZCksXG4gICAgICB1cHBlcl9ib3VuZDogU3RyaW5nKGlkKSxcbiAgICAgIGxpbWl0OiAxLFxuICAgIH0pO1xuXG4gICAgaWYgKHJlc3VsdC5yb3dzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIG51bGw7XG4gICAgcmV0dXJuIHRoaXMucGFyc2VEaXNwdXRlKHJlc3VsdC5yb3dzWzBdKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgZGlzcHV0ZXMgZm9yIGEgZmVlZGJhY2tcbiAgICovXG4gIGFzeW5jIGdldERpc3B1dGVzRm9yRmVlZGJhY2soZmVlZGJhY2tJZDogbnVtYmVyKTogUHJvbWlzZTxEaXNwdXRlW10+IHtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLnJwYy5nZXRfdGFibGVfcm93czx7XG4gICAgICBpZDogc3RyaW5nO1xuICAgICAgZmVlZGJhY2tfaWQ6IHN0cmluZztcbiAgICAgIGRpc3B1dGVyOiBzdHJpbmc7XG4gICAgICByZWFzb246IHN0cmluZztcbiAgICAgIGV2aWRlbmNlX3VyaTogc3RyaW5nO1xuICAgICAgc3RhdHVzOiBudW1iZXI7XG4gICAgICByZXNvbHZlcjogc3RyaW5nO1xuICAgICAgcmVzb2x1dGlvbl9ub3Rlczogc3RyaW5nO1xuICAgICAgY3JlYXRlZF9hdDogc3RyaW5nO1xuICAgICAgcmVzb2x2ZWRfYXQ6IHN0cmluZztcbiAgICB9Pih7XG4gICAgICBqc29uOiB0cnVlLFxuICAgICAgY29kZTogdGhpcy5jb250cmFjdCxcbiAgICAgIHNjb3BlOiB0aGlzLmNvbnRyYWN0LFxuICAgICAgdGFibGU6ICdkaXNwdXRlcycsXG4gICAgICBpbmRleF9wb3NpdGlvbjogMixcbiAgICAgIGtleV90eXBlOiAnaTY0JyxcbiAgICAgIGxpbWl0OiAxMDAsXG4gICAgfSk7XG5cbiAgICByZXR1cm4gcmVzdWx0LnJvd3NcbiAgICAgIC5maWx0ZXIoKHJvdykgPT4gcm93LmZlZWRiYWNrX2lkID09PSBTdHJpbmcoZmVlZGJhY2tJZCkpXG4gICAgICAubWFwKChyb3cpID0+IHRoaXMucGFyc2VEaXNwdXRlKHJvdykpO1xuICB9XG5cbiAgLy8gPT09PT09PT09PT09PT0gV1JJVEUgT1BFUkFUSU9OUyA9PT09PT09PT09PT09PVxuXG4gIC8qKlxuICAgKiBTdWJtaXQgZmVlZGJhY2sgZm9yIGFuIGFnZW50XG4gICAqL1xuICBhc3luYyBzdWJtaXQoZGF0YTogU3VibWl0RmVlZGJhY2tEYXRhKTogUHJvbWlzZTxUcmFuc2FjdGlvblJlc3VsdD4ge1xuICAgIHRoaXMucmVxdWlyZVNlc3Npb24oKTtcblxuICAgIHJldHVybiB0aGlzLnNlc3Npb24hLmxpbmsudHJhbnNhY3Qoe1xuICAgICAgYWN0aW9uczogW1xuICAgICAgICB7XG4gICAgICAgICAgYWNjb3VudDogdGhpcy5jb250cmFjdCxcbiAgICAgICAgICBuYW1lOiAnc3VibWl0JyxcbiAgICAgICAgICBhdXRob3JpemF0aW9uOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGFjdG9yOiB0aGlzLnNlc3Npb24hLmF1dGguYWN0b3IsXG4gICAgICAgICAgICAgIHBlcm1pc3Npb246IHRoaXMuc2Vzc2lvbiEuYXV0aC5wZXJtaXNzaW9uLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIGRhdGE6IHtcbiAgICAgICAgICAgIHJldmlld2VyOiB0aGlzLnNlc3Npb24hLmF1dGguYWN0b3IsXG4gICAgICAgICAgICBhZ2VudDogZGF0YS5hZ2VudCxcbiAgICAgICAgICAgIHNjb3JlOiBkYXRhLnNjb3JlLFxuICAgICAgICAgICAgdGFnczogKGRhdGEudGFncyB8fCBbXSkuam9pbignLCcpLFxuICAgICAgICAgICAgam9iX2hhc2g6IGRhdGEuam9iX2hhc2ggfHwgJycsXG4gICAgICAgICAgICBldmlkZW5jZV91cmk6IGRhdGEuZXZpZGVuY2VfdXJpIHx8ICcnLFxuICAgICAgICAgICAgYW1vdW50X3BhaWQ6IGRhdGEuYW1vdW50X3BhaWQgfHwgMCxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEaXNwdXRlIGZlZWRiYWNrXG4gICAqL1xuICBhc3luYyBkaXNwdXRlKFxuICAgIGZlZWRiYWNrSWQ6IG51bWJlcixcbiAgICByZWFzb246IHN0cmluZyxcbiAgICBldmlkZW5jZVVyaT86IHN0cmluZ1xuICApOiBQcm9taXNlPFRyYW5zYWN0aW9uUmVzdWx0PiB7XG4gICAgdGhpcy5yZXF1aXJlU2Vzc2lvbigpO1xuXG4gICAgcmV0dXJuIHRoaXMuc2Vzc2lvbiEubGluay50cmFuc2FjdCh7XG4gICAgICBhY3Rpb25zOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBhY2NvdW50OiB0aGlzLmNvbnRyYWN0LFxuICAgICAgICAgIG5hbWU6ICdkaXNwdXRlJyxcbiAgICAgICAgICBhdXRob3JpemF0aW9uOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGFjdG9yOiB0aGlzLnNlc3Npb24hLmF1dGguYWN0b3IsXG4gICAgICAgICAgICAgIHBlcm1pc3Npb246IHRoaXMuc2Vzc2lvbiEuYXV0aC5wZXJtaXNzaW9uLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIGRhdGE6IHtcbiAgICAgICAgICAgIGRpc3B1dGVyOiB0aGlzLnNlc3Npb24hLmF1dGguYWN0b3IsXG4gICAgICAgICAgICBmZWVkYmFja19pZDogZmVlZGJhY2tJZCxcbiAgICAgICAgICAgIHJlYXNvbixcbiAgICAgICAgICAgIGV2aWRlbmNlX3VyaTogZXZpZGVuY2VVcmkgfHwgJycsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogUmVjYWxjdWxhdGUgYWdlbnQgc2NvcmUgKHBhZ2luYXRlZCkuXG4gICAqXG4gICAqIFJlY2FsY3VsYXRpb24gaXMgZG9uZSBpbiBiYXRjaGVzIHRvIGF2b2lkIENQVSBleGhhdXN0aW9uLlxuICAgKiAtIEZpcnN0IGNhbGw6IG9mZnNldD0wLCBwcm9jZXNzZXMgZmlyc3QgYGxpbWl0YCBmZWVkYmFja3NcbiAgICogLSBTdWJzZXF1ZW50IGNhbGxzOiB1c2UgdGhlIG5leHRfb2Zmc2V0IGZyb20gUmVjYWxjU3RhdGVcbiAgICogLSBSZWNhbGN1bGF0aW9uIGV4cGlyZXMgYWZ0ZXIgMSBob3VyIGlmIG5vdCBjb21wbGV0ZWRcbiAgICpcbiAgICogQHBhcmFtIGFnZW50IC0gQWdlbnQgYWNjb3VudCB0byByZWNhbGN1bGF0ZVxuICAgKiBAcGFyYW0gb2Zmc2V0IC0gTXVzdCBiZSAwIHRvIHN0YXJ0LCBvciBtYXRjaCBuZXh0X29mZnNldCB0byBjb250aW51ZVxuICAgKiBAcGFyYW0gbGltaXQgLSBGZWVkYmFja3MgdG8gcHJvY2VzcyBwZXIgY2FsbCAobWF4IDEwMClcbiAgICovXG4gIGFzeW5jIHJlY2FsY3VsYXRlKGFnZW50OiBzdHJpbmcsIG9mZnNldDogbnVtYmVyID0gMCwgbGltaXQ6IG51bWJlciA9IDEwMCk6IFByb21pc2U8VHJhbnNhY3Rpb25SZXN1bHQ+IHtcbiAgICB0aGlzLnJlcXVpcmVTZXNzaW9uKCk7XG5cbiAgICByZXR1cm4gdGhpcy5zZXNzaW9uIS5saW5rLnRyYW5zYWN0KHtcbiAgICAgIGFjdGlvbnM6IFtcbiAgICAgICAge1xuICAgICAgICAgIGFjY291bnQ6IHRoaXMuY29udHJhY3QsXG4gICAgICAgICAgbmFtZTogJ3JlY2FsYycsXG4gICAgICAgICAgYXV0aG9yaXphdGlvbjogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBhY3RvcjogdGhpcy5zZXNzaW9uIS5hdXRoLmFjdG9yLFxuICAgICAgICAgICAgICBwZXJtaXNzaW9uOiB0aGlzLnNlc3Npb24hLmF1dGgucGVybWlzc2lvbixcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgICBkYXRhOiB7XG4gICAgICAgICAgICBhZ2VudCxcbiAgICAgICAgICAgIG9mZnNldCxcbiAgICAgICAgICAgIGxpbWl0LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlc29sdmUgYSBmZWVkYmFjayBkaXNwdXRlIChvd25lciBvbmx5KVxuICAgKi9cbiAgYXN5bmMgcmVzb2x2ZShcbiAgICBkaXNwdXRlSWQ6IG51bWJlcixcbiAgICB1cGhlbGQ6IGJvb2xlYW4sXG4gICAgcmVzb2x1dGlvbk5vdGVzOiBzdHJpbmdcbiAgKTogUHJvbWlzZTxUcmFuc2FjdGlvblJlc3VsdD4ge1xuICAgIHRoaXMucmVxdWlyZVNlc3Npb24oKTtcblxuICAgIHJldHVybiB0aGlzLnNlc3Npb24hLmxpbmsudHJhbnNhY3Qoe1xuICAgICAgYWN0aW9uczogW1xuICAgICAgICB7XG4gICAgICAgICAgYWNjb3VudDogdGhpcy5jb250cmFjdCxcbiAgICAgICAgICBuYW1lOiAncmVzb2x2ZScsXG4gICAgICAgICAgYXV0aG9yaXphdGlvbjogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBhY3RvcjogdGhpcy5zZXNzaW9uIS5hdXRoLmFjdG9yLFxuICAgICAgICAgICAgICBwZXJtaXNzaW9uOiB0aGlzLnNlc3Npb24hLmF1dGgucGVybWlzc2lvbixcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgICBkYXRhOiB7XG4gICAgICAgICAgICByZXNvbHZlcjogdGhpcy5zZXNzaW9uIS5hdXRoLmFjdG9yLFxuICAgICAgICAgICAgZGlzcHV0ZV9pZDogZGlzcHV0ZUlkLFxuICAgICAgICAgICAgdXBoZWxkLFxuICAgICAgICAgICAgcmVzb2x1dGlvbl9ub3RlczogcmVzb2x1dGlvbk5vdGVzLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIENhbmNlbCBhbiBpbi1wcm9ncmVzcyByZWNhbGN1bGF0aW9uXG4gICAqL1xuICBhc3luYyBjYW5jZWxSZWNhbGN1bGF0aW9uKGFnZW50OiBzdHJpbmcpOiBQcm9taXNlPFRyYW5zYWN0aW9uUmVzdWx0PiB7XG4gICAgdGhpcy5yZXF1aXJlU2Vzc2lvbigpO1xuXG4gICAgcmV0dXJuIHRoaXMuc2Vzc2lvbiEubGluay50cmFuc2FjdCh7XG4gICAgICBhY3Rpb25zOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBhY2NvdW50OiB0aGlzLmNvbnRyYWN0LFxuICAgICAgICAgIG5hbWU6ICdjYW5jZWxyZWNhbGMnLFxuICAgICAgICAgIGF1dGhvcml6YXRpb246IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgYWN0b3I6IHRoaXMuc2Vzc2lvbiEuYXV0aC5hY3RvcixcbiAgICAgICAgICAgICAgcGVybWlzc2lvbjogdGhpcy5zZXNzaW9uIS5hdXRoLnBlcm1pc3Npb24sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0sXG4gICAgICAgICAgZGF0YToge1xuICAgICAgICAgICAgYWdlbnQsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogU3VibWl0IGZlZWRiYWNrIHdpdGggZmVlIGluIG9uZSB0cmFuc2FjdGlvbi5cbiAgICpcbiAgICogQHBhcmFtIGRhdGEgLSBGZWVkYmFjayBkYXRhXG4gICAqIEBwYXJhbSBhbW91bnQgLSBUaGUgZmVlZGJhY2sgZmVlIChlLmcuLCBcIjEuMDAwMCBYUFJcIilcbiAgICovXG4gIGFzeW5jIHN1Ym1pdFdpdGhGZWUoZGF0YTogU3VibWl0RmVlZGJhY2tEYXRhLCBhbW91bnQ6IHN0cmluZyk6IFByb21pc2U8VHJhbnNhY3Rpb25SZXN1bHQ+IHtcbiAgICB0aGlzLnJlcXVpcmVTZXNzaW9uKCk7XG5cbiAgICBjb25zdCBhY3RvciA9IHRoaXMuc2Vzc2lvbiEuYXV0aC5hY3RvcjtcblxuICAgIHJldHVybiB0aGlzLnNlc3Npb24hLmxpbmsudHJhbnNhY3Qoe1xuICAgICAgYWN0aW9uczogW1xuICAgICAgICB7XG4gICAgICAgICAgYWNjb3VudDogJ2Vvc2lvLnRva2VuJyxcbiAgICAgICAgICBuYW1lOiAndHJhbnNmZXInLFxuICAgICAgICAgIGF1dGhvcml6YXRpb246IFt7XG4gICAgICAgICAgICBhY3RvcixcbiAgICAgICAgICAgIHBlcm1pc3Npb246IHRoaXMuc2Vzc2lvbiEuYXV0aC5wZXJtaXNzaW9uLFxuICAgICAgICAgIH1dLFxuICAgICAgICAgIGRhdGE6IHtcbiAgICAgICAgICAgIGZyb206IGFjdG9yLFxuICAgICAgICAgICAgdG86IHRoaXMuY29udHJhY3QsXG4gICAgICAgICAgICBxdWFudGl0eTogYW1vdW50LFxuICAgICAgICAgICAgbWVtbzogYGZlZWRmZWU6JHthY3Rvcn1gLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBhY2NvdW50OiB0aGlzLmNvbnRyYWN0LFxuICAgICAgICAgIG5hbWU6ICdzdWJtaXQnLFxuICAgICAgICAgIGF1dGhvcml6YXRpb246IFt7XG4gICAgICAgICAgICBhY3RvcixcbiAgICAgICAgICAgIHBlcm1pc3Npb246IHRoaXMuc2Vzc2lvbiEuYXV0aC5wZXJtaXNzaW9uLFxuICAgICAgICAgIH1dLFxuICAgICAgICAgIGRhdGE6IHtcbiAgICAgICAgICAgIHJldmlld2VyOiBhY3RvcixcbiAgICAgICAgICAgIGFnZW50OiBkYXRhLmFnZW50LFxuICAgICAgICAgICAgc2NvcmU6IGRhdGEuc2NvcmUsXG4gICAgICAgICAgICB0YWdzOiAoZGF0YS50YWdzIHx8IFtdKS5qb2luKCcsJyksXG4gICAgICAgICAgICBqb2JfaGFzaDogZGF0YS5qb2JfaGFzaCB8fCAnJyxcbiAgICAgICAgICAgIGV2aWRlbmNlX3VyaTogZGF0YS5ldmlkZW5jZV91cmkgfHwgJycsXG4gICAgICAgICAgICBhbW91bnRfcGFpZDogZGF0YS5hbW91bnRfcGFpZCB8fCAwLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIENsZWFuIHVwIG9sZCBmZWVkYmFjayBlbnRyaWVzIChwZXJtaXNzaW9ubGVzcylcbiAgICovXG4gIGFzeW5jIGNsZWFuRmVlZGJhY2soYWdlbnQ6IHN0cmluZywgbWF4QWdlOiBudW1iZXIsIG1heERlbGV0ZTogbnVtYmVyKTogUHJvbWlzZTxUcmFuc2FjdGlvblJlc3VsdD4ge1xuICAgIHRoaXMucmVxdWlyZVNlc3Npb24oKTtcblxuICAgIHJldHVybiB0aGlzLnNlc3Npb24hLmxpbmsudHJhbnNhY3Qoe1xuICAgICAgYWN0aW9uczogW3tcbiAgICAgICAgYWNjb3VudDogdGhpcy5jb250cmFjdCxcbiAgICAgICAgbmFtZTogJ2NsZWFuZmJhY2snLFxuICAgICAgICBhdXRob3JpemF0aW9uOiBbe1xuICAgICAgICAgIGFjdG9yOiB0aGlzLnNlc3Npb24hLmF1dGguYWN0b3IsXG4gICAgICAgICAgcGVybWlzc2lvbjogdGhpcy5zZXNzaW9uIS5hdXRoLnBlcm1pc3Npb24sXG4gICAgICAgIH1dLFxuICAgICAgICBkYXRhOiB7XG4gICAgICAgICAgYWdlbnQsXG4gICAgICAgICAgbWF4X2FnZTogbWF4QWdlLFxuICAgICAgICAgIG1heF9kZWxldGU6IG1heERlbGV0ZSxcbiAgICAgICAgfSxcbiAgICAgIH1dLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIENsZWFuIHVwIHJlc29sdmVkIGRpc3B1dGVzIChwZXJtaXNzaW9ubGVzcylcbiAgICovXG4gIGFzeW5jIGNsZWFuRGlzcHV0ZXMobWF4QWdlOiBudW1iZXIsIG1heERlbGV0ZTogbnVtYmVyKTogUHJvbWlzZTxUcmFuc2FjdGlvblJlc3VsdD4ge1xuICAgIHRoaXMucmVxdWlyZVNlc3Npb24oKTtcblxuICAgIHJldHVybiB0aGlzLnNlc3Npb24hLmxpbmsudHJhbnNhY3Qoe1xuICAgICAgYWN0aW9uczogW3tcbiAgICAgICAgYWNjb3VudDogdGhpcy5jb250cmFjdCxcbiAgICAgICAgbmFtZTogJ2NsZWFuZGlzcHMnLFxuICAgICAgICBhdXRob3JpemF0aW9uOiBbe1xuICAgICAgICAgIGFjdG9yOiB0aGlzLnNlc3Npb24hLmF1dGguYWN0b3IsXG4gICAgICAgICAgcGVybWlzc2lvbjogdGhpcy5zZXNzaW9uIS5hdXRoLnBlcm1pc3Npb24sXG4gICAgICAgIH1dLFxuICAgICAgICBkYXRhOiB7XG4gICAgICAgICAgbWF4X2FnZTogbWF4QWdlLFxuICAgICAgICAgIG1heF9kZWxldGU6IG1heERlbGV0ZSxcbiAgICAgICAgfSxcbiAgICAgIH1dLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBmZWVkYmFjayBjb250cmFjdCBjb25maWd1cmF0aW9uXG4gICAqL1xuICBhc3luYyBnZXRDb25maWcoKTogUHJvbWlzZTxGZWVkYmFja0NvbmZpZz4ge1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMucnBjLmdldF90YWJsZV9yb3dzPHtcbiAgICAgIG93bmVyOiBzdHJpbmc7XG4gICAgICBjb3JlX2NvbnRyYWN0OiBzdHJpbmc7XG4gICAgICBtaW5fc2NvcmU6IG51bWJlcjtcbiAgICAgIG1heF9zY29yZTogbnVtYmVyO1xuICAgICAgZGlzcHV0ZV93aW5kb3c6IHN0cmluZztcbiAgICAgIGRlY2F5X3BlcmlvZDogc3RyaW5nO1xuICAgICAgZGVjYXlfZmxvb3I6IHN0cmluZztcbiAgICAgIHBhdXNlZDogbnVtYmVyO1xuICAgICAgZmVlZGJhY2tfZmVlOiBzdHJpbmc7XG4gICAgfT4oe1xuICAgICAganNvbjogdHJ1ZSxcbiAgICAgIGNvZGU6IHRoaXMuY29udHJhY3QsXG4gICAgICBzY29wZTogdGhpcy5jb250cmFjdCxcbiAgICAgIHRhYmxlOiAnY29uZmlnJyxcbiAgICAgIGxpbWl0OiAxLFxuICAgIH0pO1xuXG4gICAgaWYgKHJlc3VsdC5yb3dzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDb250cmFjdCBub3QgaW5pdGlhbGl6ZWQnKTtcbiAgICB9XG5cbiAgICBjb25zdCByb3cgPSByZXN1bHQucm93c1swXTtcbiAgICByZXR1cm4ge1xuICAgICAgb3duZXI6IHJvdy5vd25lcixcbiAgICAgIGNvcmVfY29udHJhY3Q6IHJvdy5jb3JlX2NvbnRyYWN0LFxuICAgICAgbWluX3Njb3JlOiByb3cubWluX3Njb3JlLFxuICAgICAgbWF4X3Njb3JlOiByb3cubWF4X3Njb3JlLFxuICAgICAgZGlzcHV0ZV93aW5kb3c6IHNhZmVQYXJzZUludChyb3cuZGlzcHV0ZV93aW5kb3cpLFxuICAgICAgZGVjYXlfcGVyaW9kOiBzYWZlUGFyc2VJbnQocm93LmRlY2F5X3BlcmlvZCksXG4gICAgICBkZWNheV9mbG9vcjogc2FmZVBhcnNlSW50KHJvdy5kZWNheV9mbG9vciksXG4gICAgICBwYXVzZWQ6IHJvdy5wYXVzZWQgPT09IDEsXG4gICAgICBmZWVkYmFja19mZWU6IHNhZmVQYXJzZUludChyb3cuZmVlZGJhY2tfZmVlKSxcbiAgICB9O1xuICB9XG5cbiAgLy8gPT09PT09PT09PT09PT0gSEVMUEVSUyA9PT09PT09PT09PT09PVxuXG4gIHByaXZhdGUgcmVxdWlyZVNlc3Npb24oKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLnNlc3Npb24pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignU2Vzc2lvbiByZXF1aXJlZCBmb3Igd3JpdGUgb3BlcmF0aW9ucycpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgcGFyc2VGZWVkYmFjayhyYXc6IEZlZWRiYWNrUmF3KTogRmVlZGJhY2sge1xuICAgIHJldHVybiB7XG4gICAgICBpZDogc2FmZVBhcnNlSW50KHJhdy5pZCksXG4gICAgICBhZ2VudDogcmF3LmFnZW50LFxuICAgICAgcmV2aWV3ZXI6IHJhdy5yZXZpZXdlcixcbiAgICAgIHJldmlld2VyX2t5Y19sZXZlbDogcmF3LnJldmlld2VyX2t5Y19sZXZlbCxcbiAgICAgIHNjb3JlOiByYXcuc2NvcmUsXG4gICAgICB0YWdzOiBwYXJzZVRhZ3MocmF3LnRhZ3MpLFxuICAgICAgam9iX2hhc2g6IHJhdy5qb2JfaGFzaCxcbiAgICAgIGV2aWRlbmNlX3VyaTogcmF3LmV2aWRlbmNlX3VyaSxcbiAgICAgIGFtb3VudF9wYWlkOiBzYWZlUGFyc2VJbnQocmF3LmFtb3VudF9wYWlkKSxcbiAgICAgIHRpbWVzdGFtcDogc2FmZVBhcnNlSW50KHJhdy50aW1lc3RhbXApLFxuICAgICAgZGlzcHV0ZWQ6IHJhdy5kaXNwdXRlZCA9PT0gMSxcbiAgICAgIHJlc29sdmVkOiByYXcucmVzb2x2ZWQgPT09IDEsXG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgcGFyc2VBZ2VudFNjb3JlKHJhdzogQWdlbnRTY29yZVJhdyk6IEFnZW50U2NvcmUge1xuICAgIHJldHVybiB7XG4gICAgICBhZ2VudDogcmF3LmFnZW50LFxuICAgICAgdG90YWxfc2NvcmU6IHNhZmVQYXJzZUludChyYXcudG90YWxfc2NvcmUpLFxuICAgICAgdG90YWxfd2VpZ2h0OiBzYWZlUGFyc2VJbnQocmF3LnRvdGFsX3dlaWdodCksXG4gICAgICBmZWVkYmFja19jb3VudDogc2FmZVBhcnNlSW50KHJhdy5mZWVkYmFja19jb3VudCksXG4gICAgICBhdmdfc2NvcmU6IHNhZmVQYXJzZUludChyYXcuYXZnX3Njb3JlKSxcbiAgICAgIGxhc3RfdXBkYXRlZDogc2FmZVBhcnNlSW50KHJhdy5sYXN0X3VwZGF0ZWQpLFxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIHBhcnNlRGlzcHV0ZShyYXc6IHtcbiAgICBpZDogc3RyaW5nO1xuICAgIGZlZWRiYWNrX2lkOiBzdHJpbmc7XG4gICAgZGlzcHV0ZXI6IHN0cmluZztcbiAgICByZWFzb246IHN0cmluZztcbiAgICBldmlkZW5jZV91cmk6IHN0cmluZztcbiAgICBzdGF0dXM6IG51bWJlcjtcbiAgICByZXNvbHZlcjogc3RyaW5nO1xuICAgIHJlc29sdXRpb25fbm90ZXM6IHN0cmluZztcbiAgICBjcmVhdGVkX2F0OiBzdHJpbmc7XG4gICAgcmVzb2x2ZWRfYXQ6IHN0cmluZztcbiAgfSk6IERpc3B1dGUge1xuICAgIHJldHVybiB7XG4gICAgICBpZDogc2FmZVBhcnNlSW50KHJhdy5pZCksXG4gICAgICBmZWVkYmFja19pZDogc2FmZVBhcnNlSW50KHJhdy5mZWVkYmFja19pZCksXG4gICAgICBkaXNwdXRlcjogcmF3LmRpc3B1dGVyLFxuICAgICAgcmVhc29uOiByYXcucmVhc29uLFxuICAgICAgZXZpZGVuY2VfdXJpOiByYXcuZXZpZGVuY2VfdXJpLFxuICAgICAgc3RhdHVzOiBkaXNwdXRlU3RhdHVzRnJvbU51bWJlcihyYXcuc3RhdHVzKSxcbiAgICAgIHJlc29sdmVyOiByYXcucmVzb2x2ZXIsXG4gICAgICByZXNvbHV0aW9uX25vdGVzOiByYXcucmVzb2x1dGlvbl9ub3RlcyxcbiAgICAgIGNyZWF0ZWRfYXQ6IHNhZmVQYXJzZUludChyYXcuY3JlYXRlZF9hdCksXG4gICAgICByZXNvbHZlZF9hdDogc2FmZVBhcnNlSW50KHJhdy5yZXNvbHZlZF9hdCksXG4gICAgfTtcbiAgfVxufVxuIl19
@@ -0,0 +1,115 @@
1
+ import { Validator, Validation, ValidationConfig, Challenge, ValidatorListOptions, SubmitValidationData, TransactionResult, JsonRpc, ProtonSession } from './types';
2
+ export declare class ValidationRegistry {
3
+ private rpc;
4
+ private session;
5
+ private contract;
6
+ constructor(rpc: JsonRpc, session?: ProtonSession, contract?: string);
7
+ /**
8
+ * Get a validator by account
9
+ */
10
+ getValidator(account: string): Promise<Validator | null>;
11
+ /**
12
+ * List all validators
13
+ */
14
+ listValidators(options?: ValidatorListOptions): Promise<Validator[]>;
15
+ /**
16
+ * Get validation by ID
17
+ */
18
+ getValidation(id: number): Promise<Validation | null>;
19
+ /**
20
+ * List validations for an agent
21
+ */
22
+ listValidationsForAgent(agent: string, limit?: number): Promise<Validation[]>;
23
+ /**
24
+ * List validations by a validator
25
+ */
26
+ listValidationsByValidator(validator: string, limit?: number): Promise<Validation[]>;
27
+ /**
28
+ * Get challenge by ID
29
+ */
30
+ getChallenge(id: number): Promise<Challenge | null>;
31
+ /**
32
+ * Get challenges for a validation
33
+ */
34
+ getChallengesForValidation(validationId: number): Promise<Challenge[]>;
35
+ /**
36
+ * Register as a validator
37
+ */
38
+ registerValidator(method: string, specializations: string[]): Promise<TransactionResult>;
39
+ /**
40
+ * Update validator info
41
+ */
42
+ updateValidator(method: string, specializations: string[]): Promise<TransactionResult>;
43
+ /**
44
+ * Stake XPR as validator
45
+ */
46
+ stake(amount: string): Promise<TransactionResult>;
47
+ /**
48
+ * Submit validation
49
+ */
50
+ validate(data: SubmitValidationData): Promise<TransactionResult>;
51
+ /**
52
+ * Challenge a validation
53
+ */
54
+ challenge(validationId: number, reason: string, evidenceUri?: string): Promise<TransactionResult>;
55
+ /**
56
+ * Stake for a challenge
57
+ */
58
+ stakeChallengeDeposit(challengeId: number, amount: string): Promise<TransactionResult>;
59
+ /**
60
+ * Set validator active status
61
+ */
62
+ setValidatorStatus(active: boolean): Promise<TransactionResult>;
63
+ /**
64
+ * Request to unstake validator funds (time-delayed).
65
+ * Must be deactivated and have no pending challenges first.
66
+ *
67
+ * @param amount - Amount to unstake in smallest units
68
+ */
69
+ unstake(amount: number): Promise<TransactionResult>;
70
+ /**
71
+ * Withdraw unstaked validator funds (after delay period)
72
+ *
73
+ * @param unstakeId - The ID of the unstake request to withdraw
74
+ */
75
+ withdraw(unstakeId: number): Promise<TransactionResult>;
76
+ /**
77
+ * Cancel an unfunded challenge (within grace period or after deadline)
78
+ */
79
+ cancelChallenge(challengeId: number): Promise<TransactionResult>;
80
+ /**
81
+ * Resolve a validation challenge (owner only)
82
+ */
83
+ resolve(challengeId: number, upheld: boolean, resolutionNotes: string): Promise<TransactionResult>;
84
+ /**
85
+ * Expire an unfunded challenge (permissionless cleanup)
86
+ */
87
+ expireUnfundedChallenge(challengeId: number): Promise<TransactionResult>;
88
+ /**
89
+ * Expire a funded challenge that was not resolved within timeout (permissionless cleanup)
90
+ */
91
+ expireFundedChallenge(challengeId: number): Promise<TransactionResult>;
92
+ /**
93
+ * Submit validation with fee in one transaction.
94
+ *
95
+ * @param data - Validation data
96
+ * @param amount - The validation fee (e.g., "1.0000 XPR")
97
+ */
98
+ validateWithFee(data: SubmitValidationData, amount: string): Promise<TransactionResult>;
99
+ /**
100
+ * Clean up old validations (permissionless)
101
+ */
102
+ cleanValidations(agent: string, maxAge: number, maxDelete: number): Promise<TransactionResult>;
103
+ /**
104
+ * Clean up resolved challenges (permissionless)
105
+ */
106
+ cleanChallenges(maxAge: number, maxDelete: number): Promise<TransactionResult>;
107
+ /**
108
+ * Get validation contract configuration
109
+ */
110
+ getConfig(): Promise<ValidationConfig>;
111
+ private requireSession;
112
+ private parseValidator;
113
+ private parseValidation;
114
+ private parseChallenge;
115
+ }