@svsprotocol/solana 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.
- package/LICENSE +158 -0
- package/README.md +365 -0
- package/dist/action-production-proof-evidence.js +553 -0
- package/dist/adapter-catalog.d.ts +29 -0
- package/dist/adapter-catalog.js +146 -0
- package/dist/adapter-core.d.ts +48 -0
- package/dist/adapter-core.js +249 -0
- package/dist/approval-signature.js +197 -0
- package/dist/base58.js +69 -0
- package/dist/bot-auth.js +50 -0
- package/dist/bot-certification-evidence.js +342 -0
- package/dist/bot-first-action-runbook.js +299 -0
- package/dist/bot-integration-contract.js +41 -0
- package/dist/certified-submit-status.js +176 -0
- package/dist/common.d.ts +1135 -0
- package/dist/elizaos.d.ts +43 -0
- package/dist/elizaos.js +227 -0
- package/dist/goat.d.ts +47 -0
- package/dist/goat.js +261 -0
- package/dist/index.d.ts +330 -0
- package/dist/index.js +128 -0
- package/dist/protocol.d.ts +205 -0
- package/dist/protocol.js +900 -0
- package/dist/receipt.js +51 -0
- package/dist/signed-proof-read-protection.js +495 -0
- package/dist/solana-agent-kit.d.ts +35 -0
- package/dist/solana-agent-kit.js +151 -0
- package/dist/svs-client.js +1232 -0
- package/dist/vercel-ai.d.ts +47 -0
- package/dist/vercel-ai.js +266 -0
- package/dist/verified-agent-adoption-kit.js +471 -0
- package/dist/verified-agent-profile.js +329 -0
- package/dist/verified-agent-registry-consumer.js +421 -0
- package/dist/verified-agent-registry.d.ts +36 -0
- package/dist/verified-agent-registry.js +826 -0
- package/dist/verified-agent-trust-score.js +335 -0
- package/dist/webhooks.js +834 -0
- package/package.json +72 -0
package/dist/protocol.js
ADDED
|
@@ -0,0 +1,900 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ACTION_PRODUCTION_PROOF_EVIDENCE_VERSION,
|
|
3
|
+
APPROVAL_MESSAGE_DOMAIN,
|
|
4
|
+
LEGACY_APPROVAL_MESSAGE_DOMAIN,
|
|
5
|
+
VERIFIED_AGENT_TRUST_SCORE_HIGH_TRUST_MIN,
|
|
6
|
+
productionCertificationIsReady,
|
|
7
|
+
summarizeApprovalDomain,
|
|
8
|
+
SolanaVerificationClient,
|
|
9
|
+
verifyActionProductionProofEvidence,
|
|
10
|
+
verifyVerifiedAgentRegistryUrl
|
|
11
|
+
} from "./index.js";
|
|
12
|
+
import { hashObject } from "./receipt.js";
|
|
13
|
+
|
|
14
|
+
export const VERIFIED_AGENT_REQUIREMENT_VERSION = "svs.verified-agent-requirement.v1";
|
|
15
|
+
export const CURRENT_APPROVAL_DOMAIN_REQUIREMENT_VERSION = "svs.current-approval-domain-requirement.v1";
|
|
16
|
+
export const HOSTED_VERIFIED_AGENT_REGISTRY_REQUIREMENT_VERSION = "svs.hosted-verified-agent-registry-requirement.v1";
|
|
17
|
+
export const VERIFIED_AGENT_STANDARD_CONFORMANCE_FIXTURES_VERSION = "svs.verified-agent-standard-conformance-fixtures.v1";
|
|
18
|
+
export const VERIFIED_AGENT_STANDARD_CONFORMANCE_VERSION = "svs.verified-agent-standard-conformance.v1";
|
|
19
|
+
export const HOSTED_VERIFIED_AGENT_TRUST_POLICY_STANDARD = "standard";
|
|
20
|
+
export const HOSTED_VERIFIED_AGENT_TRUST_POLICY_HIGH_TRUST = "high-trust";
|
|
21
|
+
export const HOSTED_VERIFIED_AGENT_TRUST_POLICY_CUSTOM = "custom";
|
|
22
|
+
export const HOSTED_VERIFIED_AGENT_TRUST_POLICY_VALUES = [
|
|
23
|
+
HOSTED_VERIFIED_AGENT_TRUST_POLICY_STANDARD,
|
|
24
|
+
HOSTED_VERIFIED_AGENT_TRUST_POLICY_HIGH_TRUST,
|
|
25
|
+
HOSTED_VERIFIED_AGENT_TRUST_POLICY_CUSTOM
|
|
26
|
+
];
|
|
27
|
+
|
|
28
|
+
export async function requireVerifiedAgent({
|
|
29
|
+
client = null,
|
|
30
|
+
baseUrl,
|
|
31
|
+
apiKey,
|
|
32
|
+
requestSigningSecret,
|
|
33
|
+
botId,
|
|
34
|
+
agentWallet = null,
|
|
35
|
+
action = null,
|
|
36
|
+
minCertification = "production_verified",
|
|
37
|
+
staleAfterMs = undefined,
|
|
38
|
+
requireCurrentIntegrationContract = true
|
|
39
|
+
} = {}) {
|
|
40
|
+
if (!botId) {
|
|
41
|
+
throw new Error("botId is required.");
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const svs = client ?? new SolanaVerificationClient({
|
|
45
|
+
baseUrl,
|
|
46
|
+
apiKey,
|
|
47
|
+
requestSigningSecret
|
|
48
|
+
});
|
|
49
|
+
const certification = await svs.requireProductionCertification({
|
|
50
|
+
botId,
|
|
51
|
+
staleAfterMs,
|
|
52
|
+
requireCurrentIntegrationContract
|
|
53
|
+
});
|
|
54
|
+
const ok = productionCertificationIsReady(certification);
|
|
55
|
+
|
|
56
|
+
if (!ok) {
|
|
57
|
+
throw new Error(`SVS verified agent requirement failed for ${botId}.`);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return {
|
|
61
|
+
version: VERIFIED_AGENT_REQUIREMENT_VERSION,
|
|
62
|
+
ok: true,
|
|
63
|
+
status: "verified",
|
|
64
|
+
minCertification,
|
|
65
|
+
botId,
|
|
66
|
+
agentWallet,
|
|
67
|
+
action,
|
|
68
|
+
certificationHash: certification.certification?.certificationHash ?? null,
|
|
69
|
+
recordId: certification.certification?.recordId ?? null,
|
|
70
|
+
qualityTarget: certification.qualityTarget ?? null,
|
|
71
|
+
integrationContract: certification.integrationContract ?? null,
|
|
72
|
+
proofs: certification.proofs ?? null,
|
|
73
|
+
nextAction: {
|
|
74
|
+
code: "none",
|
|
75
|
+
message: "Agent satisfies SVS production certification requirements."
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export function requireCurrentApprovalDomain(proofEvidenceOrHumanApproval, {
|
|
81
|
+
action = null
|
|
82
|
+
} = {}) {
|
|
83
|
+
const humanApproval = proofEvidenceOrHumanApproval?.humanApproval ?? proofEvidenceOrHumanApproval;
|
|
84
|
+
const domain = summarizeApprovalDomain(humanApproval);
|
|
85
|
+
const status = humanApproval?.domainStatus ?? domain.status;
|
|
86
|
+
const current = domain.domain === APPROVAL_MESSAGE_DOMAIN && status === "current";
|
|
87
|
+
|
|
88
|
+
if (!current) {
|
|
89
|
+
const error = new Error(`SVS approval domain is not current: ${status}.`);
|
|
90
|
+
error.name = "SvsCurrentApprovalDomainError";
|
|
91
|
+
error.details = {
|
|
92
|
+
version: CURRENT_APPROVAL_DOMAIN_REQUIREMENT_VERSION,
|
|
93
|
+
ok: false,
|
|
94
|
+
status,
|
|
95
|
+
domain: domain.domain,
|
|
96
|
+
expectedDomain: APPROVAL_MESSAGE_DOMAIN,
|
|
97
|
+
action,
|
|
98
|
+
nextAction: {
|
|
99
|
+
code: status === "legacy_compatible"
|
|
100
|
+
? "approval_domain_legacy_compatible"
|
|
101
|
+
: "approval_domain_not_current",
|
|
102
|
+
message: status === "legacy_compatible"
|
|
103
|
+
? "This proof uses the legacy approval domain. Keep it for historical audit compatibility, but require current-domain proofs for new production bot actions."
|
|
104
|
+
: "Require a current SVS approval-domain proof before accepting this bot action."
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
throw error;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return {
|
|
111
|
+
version: CURRENT_APPROVAL_DOMAIN_REQUIREMENT_VERSION,
|
|
112
|
+
ok: true,
|
|
113
|
+
status: "current",
|
|
114
|
+
domain: domain.domain,
|
|
115
|
+
expectedDomain: APPROVAL_MESSAGE_DOMAIN,
|
|
116
|
+
action,
|
|
117
|
+
nextAction: {
|
|
118
|
+
code: "none",
|
|
119
|
+
message: "SVS approval domain is current."
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export async function requireHostedVerifiedAgentRegistry({
|
|
125
|
+
registryUrl,
|
|
126
|
+
trustManifestUrl = null,
|
|
127
|
+
expectedRegistryHash,
|
|
128
|
+
botId,
|
|
129
|
+
requireVerified = true,
|
|
130
|
+
trustPolicy = null,
|
|
131
|
+
requireHighTrustScore = false,
|
|
132
|
+
minimumTrustScore = null,
|
|
133
|
+
requireTrustScoreEvidenceComplete = null,
|
|
134
|
+
maxTrustScoreBlockingSignals = null,
|
|
135
|
+
staleAfterMs = null,
|
|
136
|
+
now = new Date(),
|
|
137
|
+
fetchImpl = globalThis.fetch
|
|
138
|
+
} = {}) {
|
|
139
|
+
if (!botId) {
|
|
140
|
+
throw new Error("botId is required.");
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const resolvedTrustPolicy = resolveHostedTrustScorePolicyOptions({
|
|
144
|
+
trustPolicy,
|
|
145
|
+
requireHighTrustScore,
|
|
146
|
+
minimumTrustScore,
|
|
147
|
+
requireTrustScoreEvidenceComplete,
|
|
148
|
+
maxTrustScoreBlockingSignals
|
|
149
|
+
});
|
|
150
|
+
const verification = await verifyVerifiedAgentRegistryUrl({
|
|
151
|
+
registryUrl,
|
|
152
|
+
trustManifestUrl,
|
|
153
|
+
expectedRegistryHash,
|
|
154
|
+
requireVerified,
|
|
155
|
+
staleAfterMs,
|
|
156
|
+
now,
|
|
157
|
+
fetchImpl
|
|
158
|
+
});
|
|
159
|
+
const agent = verification.agents?.find((item) => item.botId === botId) ?? null;
|
|
160
|
+
const trustScorePolicy = evaluateHostedTrustScorePolicy(agent?.trustScore, resolvedTrustPolicy);
|
|
161
|
+
const ok = verification.ok === true && agent?.ok === true && trustScorePolicy.ok === true;
|
|
162
|
+
|
|
163
|
+
if (!ok) {
|
|
164
|
+
const firstFailure = trustScorePolicy.ok === false
|
|
165
|
+
? {
|
|
166
|
+
name: "Hosted registry trust score policy satisfied",
|
|
167
|
+
ok: false,
|
|
168
|
+
detail: trustScorePolicy.detail
|
|
169
|
+
}
|
|
170
|
+
: agent?.failedChecks?.[0] ?? verification.failedChecks?.[0];
|
|
171
|
+
const error = new Error(
|
|
172
|
+
`SVS hosted verified-agent registry requirement failed for ${botId}: ${firstFailure?.name ?? verification.status ?? "failed"}.`
|
|
173
|
+
);
|
|
174
|
+
error.name = "SvsHostedVerifiedAgentRegistryError";
|
|
175
|
+
error.details = {
|
|
176
|
+
version: HOSTED_VERIFIED_AGENT_REGISTRY_REQUIREMENT_VERSION,
|
|
177
|
+
ok: false,
|
|
178
|
+
status: trustScorePolicy.ok === false
|
|
179
|
+
? "trust_score_policy_failed"
|
|
180
|
+
: verification.status === "verified"
|
|
181
|
+
? "agent_not_verified"
|
|
182
|
+
: verification.status,
|
|
183
|
+
botId,
|
|
184
|
+
registryUrl,
|
|
185
|
+
trustManifestUrl: verification.trustManifestUrl ?? trustManifestUrl ?? null,
|
|
186
|
+
expectedRegistryHash,
|
|
187
|
+
registryHash: verification.registryHash ?? null,
|
|
188
|
+
trustManifest: verification.trustManifest ?? null,
|
|
189
|
+
trustScorePolicy,
|
|
190
|
+
failedCheckCount: verification.failedCheckCount ?? null,
|
|
191
|
+
firstFailure: firstFailure ?? null,
|
|
192
|
+
agent: agent ? summarizeRegistryAgentForRequirement(agent) : null,
|
|
193
|
+
nextAction: {
|
|
194
|
+
code: trustScorePolicy.ok === false
|
|
195
|
+
? "raise_hosted_verified_agent_trust_score"
|
|
196
|
+
: agent
|
|
197
|
+
? "fix_hosted_verified_agent_registry"
|
|
198
|
+
: "publish_verified_agent_to_registry",
|
|
199
|
+
message: trustScorePolicy.ok === false
|
|
200
|
+
? "Refresh or strengthen SVS proof evidence until the hosted registry trust-score policy passes."
|
|
201
|
+
: agent
|
|
202
|
+
? "Fix the hosted SVS registry, trust manifest, or linked profile before accepting this agent."
|
|
203
|
+
: "Publish this bot to the hosted SVS verified-agent registry before accepting it."
|
|
204
|
+
}
|
|
205
|
+
};
|
|
206
|
+
throw error;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
return {
|
|
210
|
+
version: HOSTED_VERIFIED_AGENT_REGISTRY_REQUIREMENT_VERSION,
|
|
211
|
+
ok: true,
|
|
212
|
+
status: "verified",
|
|
213
|
+
botId,
|
|
214
|
+
registryUrl,
|
|
215
|
+
trustManifestUrl: verification.trustManifestUrl ?? trustManifestUrl ?? null,
|
|
216
|
+
expectedRegistryHash,
|
|
217
|
+
registryHash: verification.registryHash ?? null,
|
|
218
|
+
trustManifest: verification.trustManifest ?? null,
|
|
219
|
+
trustScorePolicy,
|
|
220
|
+
agent: summarizeRegistryAgentForRequirement(agent),
|
|
221
|
+
profileCount: verification.profileCount ?? null,
|
|
222
|
+
verifiedAgentCount: verification.verifiedAgentCount ?? null,
|
|
223
|
+
nextAction: {
|
|
224
|
+
code: "none",
|
|
225
|
+
message: "Hosted SVS registry, trust manifest, and linked profile checks passed for this agent."
|
|
226
|
+
}
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
export function createHostedVerifiedAgentRegistryMiddleware({
|
|
231
|
+
registryUrl,
|
|
232
|
+
trustManifestUrl = null,
|
|
233
|
+
expectedRegistryHash,
|
|
234
|
+
requireVerified = true,
|
|
235
|
+
trustPolicy = null,
|
|
236
|
+
requireHighTrustScore = false,
|
|
237
|
+
minimumTrustScore = null,
|
|
238
|
+
requireTrustScoreEvidenceComplete = null,
|
|
239
|
+
maxTrustScoreBlockingSignals = null,
|
|
240
|
+
staleAfterMs = null,
|
|
241
|
+
now = new Date(),
|
|
242
|
+
fetchImpl = globalThis.fetch
|
|
243
|
+
} = {}) {
|
|
244
|
+
return async function svsHostedVerifiedAgentRegistryMiddleware(request = {}) {
|
|
245
|
+
const botId = request.botId ?? request.agent?.botId ?? request.body?.botId;
|
|
246
|
+
|
|
247
|
+
return requireHostedVerifiedAgentRegistry({
|
|
248
|
+
registryUrl,
|
|
249
|
+
trustManifestUrl,
|
|
250
|
+
expectedRegistryHash,
|
|
251
|
+
botId,
|
|
252
|
+
requireVerified,
|
|
253
|
+
trustPolicy,
|
|
254
|
+
requireHighTrustScore,
|
|
255
|
+
minimumTrustScore,
|
|
256
|
+
requireTrustScoreEvidenceComplete,
|
|
257
|
+
maxTrustScoreBlockingSignals,
|
|
258
|
+
staleAfterMs,
|
|
259
|
+
now,
|
|
260
|
+
fetchImpl
|
|
261
|
+
});
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
function summarizeRegistryAgentForRequirement(agent) {
|
|
266
|
+
return {
|
|
267
|
+
index: agent.index ?? null,
|
|
268
|
+
botId: agent.botId ?? null,
|
|
269
|
+
profilePath: agent.profilePath ?? null,
|
|
270
|
+
profileUrl: agent.profileUrl ?? null,
|
|
271
|
+
profileHash: agent.profileHash ?? null,
|
|
272
|
+
trustScore: agent.trustScore
|
|
273
|
+
? {
|
|
274
|
+
version: agent.trustScore.version ?? null,
|
|
275
|
+
status: agent.trustScore.status ?? null,
|
|
276
|
+
score: agent.trustScore.score ?? null,
|
|
277
|
+
maxScore: agent.trustScore.maxScore ?? null,
|
|
278
|
+
evidenceComplete: agent.trustScore.evidenceComplete === true,
|
|
279
|
+
blockingSignalCount: agent.trustScore.blockingSignalCount ?? null,
|
|
280
|
+
trustScoreHash: agent.trustScore.trustScoreHash ?? null,
|
|
281
|
+
computedTrustScoreHash: agent.trustScore.computedTrustScoreHash ?? null,
|
|
282
|
+
hashValid: agent.trustScore.hashValid === true,
|
|
283
|
+
highTrustMinimumScore: agent.trustScore.highTrustMinimumScore ?? null,
|
|
284
|
+
nextAction: agent.trustScore.nextAction ?? null
|
|
285
|
+
}
|
|
286
|
+
: null,
|
|
287
|
+
ok: agent.ok === true,
|
|
288
|
+
failedCheckCount: agent.failedCheckCount ?? 0
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
function evaluateHostedTrustScorePolicy(trustScore, {
|
|
293
|
+
trustPolicy = HOSTED_VERIFIED_AGENT_TRUST_POLICY_STANDARD,
|
|
294
|
+
requireHighTrustScore = false,
|
|
295
|
+
minimumTrustScore = null,
|
|
296
|
+
requireTrustScoreEvidenceComplete = null,
|
|
297
|
+
maxTrustScoreBlockingSignals = null
|
|
298
|
+
} = {}) {
|
|
299
|
+
const effectiveMinimum = normalizeOptionalNumber(minimumTrustScore);
|
|
300
|
+
const effectiveBlockingMax = normalizeOptionalNumber(maxTrustScoreBlockingSignals);
|
|
301
|
+
const policyEnabled = requireHighTrustScore ||
|
|
302
|
+
effectiveMinimum !== null ||
|
|
303
|
+
requireTrustScoreEvidenceComplete === true ||
|
|
304
|
+
effectiveBlockingMax !== null;
|
|
305
|
+
|
|
306
|
+
if (!policyEnabled) {
|
|
307
|
+
return {
|
|
308
|
+
ok: true,
|
|
309
|
+
status: "not_required",
|
|
310
|
+
required: false,
|
|
311
|
+
trustPolicy,
|
|
312
|
+
detail: "No hosted registry trust-score policy was requested."
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
const minScore = requireHighTrustScore
|
|
317
|
+
? effectiveMinimum ?? trustScore?.highTrustMinimumScore ?? VERIFIED_AGENT_TRUST_SCORE_HIGH_TRUST_MIN
|
|
318
|
+
: effectiveMinimum;
|
|
319
|
+
const mustComplete = requireHighTrustScore || requireTrustScoreEvidenceComplete === true;
|
|
320
|
+
const maxBlocking = requireHighTrustScore ? 0 : effectiveBlockingMax;
|
|
321
|
+
const failures = [];
|
|
322
|
+
|
|
323
|
+
if (!trustScore) {
|
|
324
|
+
failures.push("trust score missing");
|
|
325
|
+
} else {
|
|
326
|
+
if (trustScore.hashValid !== true) {
|
|
327
|
+
failures.push("trust score hash invalid");
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
if (minScore !== null && Number(trustScore.score ?? -1) < minScore) {
|
|
331
|
+
failures.push(`score ${trustScore.score ?? "missing"} below ${minScore}`);
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
if (mustComplete && trustScore.evidenceComplete !== true) {
|
|
335
|
+
failures.push("required evidence incomplete");
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
if (maxBlocking !== null && Number(trustScore.blockingSignalCount ?? Number.POSITIVE_INFINITY) > maxBlocking) {
|
|
339
|
+
failures.push(`blocking signals ${trustScore.blockingSignalCount ?? "missing"} above ${maxBlocking}`);
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
const ok = failures.length === 0;
|
|
344
|
+
|
|
345
|
+
return {
|
|
346
|
+
ok,
|
|
347
|
+
status: ok ? "passed" : "failed",
|
|
348
|
+
required: true,
|
|
349
|
+
trustPolicy,
|
|
350
|
+
requireHighTrustScore: Boolean(requireHighTrustScore),
|
|
351
|
+
minimumTrustScore: minScore,
|
|
352
|
+
requireTrustScoreEvidenceComplete: mustComplete,
|
|
353
|
+
maxTrustScoreBlockingSignals: maxBlocking,
|
|
354
|
+
detail: ok
|
|
355
|
+
? `score=${trustScore?.score ?? "missing"} min=${minScore ?? "not_required"} blocking=${trustScore?.blockingSignalCount ?? "missing"} maxBlocking=${maxBlocking ?? "not_required"}`
|
|
356
|
+
: failures.join("; ")
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
function resolveHostedTrustScorePolicyOptions({
|
|
361
|
+
trustPolicy = null,
|
|
362
|
+
requireHighTrustScore = false,
|
|
363
|
+
minimumTrustScore = null,
|
|
364
|
+
requireTrustScoreEvidenceComplete = null,
|
|
365
|
+
maxTrustScoreBlockingSignals = null
|
|
366
|
+
} = {}) {
|
|
367
|
+
const explicitPolicy = normalizeHostedTrustPolicy(trustPolicy);
|
|
368
|
+
const hasCustomScoreOptions = normalizeOptionalNumber(minimumTrustScore) !== null ||
|
|
369
|
+
requireTrustScoreEvidenceComplete === true ||
|
|
370
|
+
normalizeOptionalNumber(maxTrustScoreBlockingSignals) !== null;
|
|
371
|
+
|
|
372
|
+
if (explicitPolicy === HOSTED_VERIFIED_AGENT_TRUST_POLICY_CUSTOM && !hasCustomScoreOptions) {
|
|
373
|
+
throw new Error(
|
|
374
|
+
'trustPolicy "custom" requires minimumTrustScore, requireTrustScoreEvidenceComplete, or maxTrustScoreBlockingSignals.'
|
|
375
|
+
);
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
let resolvedPolicy = explicitPolicy ??
|
|
379
|
+
(requireHighTrustScore
|
|
380
|
+
? HOSTED_VERIFIED_AGENT_TRUST_POLICY_HIGH_TRUST
|
|
381
|
+
: hasCustomScoreOptions
|
|
382
|
+
? HOSTED_VERIFIED_AGENT_TRUST_POLICY_CUSTOM
|
|
383
|
+
: HOSTED_VERIFIED_AGENT_TRUST_POLICY_STANDARD);
|
|
384
|
+
|
|
385
|
+
if (resolvedPolicy === HOSTED_VERIFIED_AGENT_TRUST_POLICY_STANDARD && hasCustomScoreOptions) {
|
|
386
|
+
resolvedPolicy = HOSTED_VERIFIED_AGENT_TRUST_POLICY_CUSTOM;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
return {
|
|
390
|
+
trustPolicy: resolvedPolicy,
|
|
391
|
+
requireHighTrustScore: requireHighTrustScore ||
|
|
392
|
+
resolvedPolicy === HOSTED_VERIFIED_AGENT_TRUST_POLICY_HIGH_TRUST,
|
|
393
|
+
minimumTrustScore,
|
|
394
|
+
requireTrustScoreEvidenceComplete,
|
|
395
|
+
maxTrustScoreBlockingSignals
|
|
396
|
+
};
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
function normalizeHostedTrustPolicy(value) {
|
|
400
|
+
if (value === null || value === undefined || value === "") {
|
|
401
|
+
return null;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
const normalized = String(value).trim().toLowerCase().replaceAll("_", "-");
|
|
405
|
+
|
|
406
|
+
if (["standard", "baseline", "default"].includes(normalized)) {
|
|
407
|
+
return HOSTED_VERIFIED_AGENT_TRUST_POLICY_STANDARD;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
if (["high-trust", "hightrust", "strict"].includes(normalized)) {
|
|
411
|
+
return HOSTED_VERIFIED_AGENT_TRUST_POLICY_HIGH_TRUST;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
if (normalized === "custom") {
|
|
415
|
+
return HOSTED_VERIFIED_AGENT_TRUST_POLICY_CUSTOM;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
throw new Error(
|
|
419
|
+
`Unsupported hosted registry trustPolicy "${value}". Use one of: ${HOSTED_VERIFIED_AGENT_TRUST_POLICY_VALUES.join(", ")}.`
|
|
420
|
+
);
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
function normalizeOptionalNumber(value) {
|
|
424
|
+
if (value === null || value === undefined || value === "") {
|
|
425
|
+
return null;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
const number = Number(value);
|
|
429
|
+
|
|
430
|
+
return Number.isFinite(number) ? number : null;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
export function createVerifiedAgentStandardConformanceFixtures({
|
|
434
|
+
now = new Date(),
|
|
435
|
+
botId = "svs-conformance-agent",
|
|
436
|
+
agentWallet = "ConformanceController111111111111111111111111",
|
|
437
|
+
action = "treasury_transfer",
|
|
438
|
+
recordId = "svs-conformance-record-1"
|
|
439
|
+
} = {}) {
|
|
440
|
+
const generatedAt = normalizeDate(now).toISOString();
|
|
441
|
+
const baseCertification = createConformanceCertification({ recordId });
|
|
442
|
+
const baseEvidence = createConformanceActionProofEvidence({
|
|
443
|
+
generatedAt,
|
|
444
|
+
botId,
|
|
445
|
+
recordId,
|
|
446
|
+
approvalDomain: APPROVAL_MESSAGE_DOMAIN,
|
|
447
|
+
approvalDomainStatus: "current"
|
|
448
|
+
});
|
|
449
|
+
const scenarios = [
|
|
450
|
+
{
|
|
451
|
+
id: "accept_current_verified_agent_action",
|
|
452
|
+
label: "Accept current verified agent action",
|
|
453
|
+
expectedAccepted: true,
|
|
454
|
+
requirement: "Protocol accepts only when certification, action proof, current approval domain, signed bot request, human approval, broadcast, custom registry, and action-record verification pass.",
|
|
455
|
+
botId,
|
|
456
|
+
agentWallet,
|
|
457
|
+
action,
|
|
458
|
+
recordId,
|
|
459
|
+
certification: baseCertification,
|
|
460
|
+
actionProductionProofEvidence: baseEvidence
|
|
461
|
+
},
|
|
462
|
+
{
|
|
463
|
+
id: "reject_legacy_approval_domain",
|
|
464
|
+
label: "Reject legacy approval domain for new protocol acceptance",
|
|
465
|
+
expectedAccepted: false,
|
|
466
|
+
expectedFailureCode: "approval_domain_legacy_compatible",
|
|
467
|
+
requirement: "Protocol must fail closed when a new action proof uses the legacy approval domain.",
|
|
468
|
+
botId,
|
|
469
|
+
agentWallet,
|
|
470
|
+
action,
|
|
471
|
+
recordId,
|
|
472
|
+
certification: baseCertification,
|
|
473
|
+
actionProductionProofEvidence: createConformanceActionProofEvidence({
|
|
474
|
+
generatedAt,
|
|
475
|
+
botId,
|
|
476
|
+
recordId,
|
|
477
|
+
approvalDomain: LEGACY_APPROVAL_MESSAGE_DOMAIN,
|
|
478
|
+
approvalDomainStatus: "legacy_compatible"
|
|
479
|
+
})
|
|
480
|
+
},
|
|
481
|
+
{
|
|
482
|
+
id: "reject_stale_action_proof",
|
|
483
|
+
label: "Reject stale action production proof",
|
|
484
|
+
expectedAccepted: false,
|
|
485
|
+
expectedFailureCode: "action_proof_verification_failed",
|
|
486
|
+
requirement: "Protocol must fail closed when the action production proof is older than the configured freshness window.",
|
|
487
|
+
botId,
|
|
488
|
+
agentWallet,
|
|
489
|
+
action,
|
|
490
|
+
recordId,
|
|
491
|
+
certification: baseCertification,
|
|
492
|
+
actionProductionProofEvidence: createConformanceActionProofEvidence({
|
|
493
|
+
generatedAt: new Date(normalizeDate(now).getTime() - 3_600_000).toISOString(),
|
|
494
|
+
botId,
|
|
495
|
+
recordId,
|
|
496
|
+
approvalDomain: APPROVAL_MESSAGE_DOMAIN,
|
|
497
|
+
approvalDomainStatus: "current"
|
|
498
|
+
}),
|
|
499
|
+
staleAfterMs: 1_000
|
|
500
|
+
},
|
|
501
|
+
{
|
|
502
|
+
id: "reject_missing_custom_registry_proof",
|
|
503
|
+
label: "Reject missing custom receipt-registry proof",
|
|
504
|
+
expectedAccepted: false,
|
|
505
|
+
expectedFailureCode: "action_proof_verification_failed",
|
|
506
|
+
requirement: "Protocol must fail closed when production rules require the custom receipt registry and the proof does not show a confirmed registry write.",
|
|
507
|
+
botId,
|
|
508
|
+
agentWallet,
|
|
509
|
+
action,
|
|
510
|
+
recordId,
|
|
511
|
+
certification: baseCertification,
|
|
512
|
+
actionProductionProofEvidence: createConformanceActionProofEvidence({
|
|
513
|
+
generatedAt,
|
|
514
|
+
botId,
|
|
515
|
+
recordId,
|
|
516
|
+
receiptRegistryConfirmed: false,
|
|
517
|
+
approvalDomain: APPROVAL_MESSAGE_DOMAIN,
|
|
518
|
+
approvalDomainStatus: "current"
|
|
519
|
+
})
|
|
520
|
+
},
|
|
521
|
+
{
|
|
522
|
+
id: "reject_unauthenticated_bot_request",
|
|
523
|
+
label: "Reject unauthenticated bot request",
|
|
524
|
+
expectedAccepted: false,
|
|
525
|
+
expectedFailureCode: "action_proof_verification_failed",
|
|
526
|
+
requirement: "Protocol must fail closed when the action proof is not tied to an authenticated signed bot request.",
|
|
527
|
+
botId,
|
|
528
|
+
agentWallet,
|
|
529
|
+
action,
|
|
530
|
+
recordId,
|
|
531
|
+
certification: baseCertification,
|
|
532
|
+
actionProductionProofEvidence: createConformanceActionProofEvidence({
|
|
533
|
+
generatedAt,
|
|
534
|
+
botId,
|
|
535
|
+
recordId,
|
|
536
|
+
requestSignatureVerified: false,
|
|
537
|
+
approvalDomain: APPROVAL_MESSAGE_DOMAIN,
|
|
538
|
+
approvalDomainStatus: "current"
|
|
539
|
+
})
|
|
540
|
+
},
|
|
541
|
+
{
|
|
542
|
+
id: "reject_record_mismatch",
|
|
543
|
+
label: "Reject action proof for another record",
|
|
544
|
+
expectedAccepted: false,
|
|
545
|
+
expectedFailureCode: "action_proof_verification_failed",
|
|
546
|
+
requirement: "Protocol must fail closed when the action production proof does not match the record being accepted.",
|
|
547
|
+
botId,
|
|
548
|
+
agentWallet,
|
|
549
|
+
action,
|
|
550
|
+
recordId,
|
|
551
|
+
certification: baseCertification,
|
|
552
|
+
expectedRecordId: "svs-conformance-record-2",
|
|
553
|
+
actionProductionProofEvidence: baseEvidence
|
|
554
|
+
},
|
|
555
|
+
{
|
|
556
|
+
id: "reject_uncertified_agent",
|
|
557
|
+
label: "Reject uncertified agent",
|
|
558
|
+
expectedAccepted: false,
|
|
559
|
+
expectedFailureCode: "verified_agent_requirement_failed",
|
|
560
|
+
requirement: "Protocol must fail closed when SVS production certification is missing, stale, incomplete, or below policy.",
|
|
561
|
+
botId,
|
|
562
|
+
agentWallet,
|
|
563
|
+
action,
|
|
564
|
+
recordId,
|
|
565
|
+
certification: createConformanceCertification({
|
|
566
|
+
recordId,
|
|
567
|
+
ok: false,
|
|
568
|
+
qualityReady: false,
|
|
569
|
+
score: 70,
|
|
570
|
+
status: "incomplete"
|
|
571
|
+
}),
|
|
572
|
+
actionProductionProofEvidence: baseEvidence
|
|
573
|
+
}
|
|
574
|
+
];
|
|
575
|
+
|
|
576
|
+
return {
|
|
577
|
+
version: VERIFIED_AGENT_STANDARD_CONFORMANCE_FIXTURES_VERSION,
|
|
578
|
+
generatedAt,
|
|
579
|
+
standard: "Verified Agent Standard",
|
|
580
|
+
botId,
|
|
581
|
+
agentWallet,
|
|
582
|
+
action,
|
|
583
|
+
recordId,
|
|
584
|
+
scenarioCount: scenarios.length,
|
|
585
|
+
scenarios
|
|
586
|
+
};
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
export async function runVerifiedAgentStandardConformance({
|
|
590
|
+
fixtures = null,
|
|
591
|
+
now = new Date(),
|
|
592
|
+
staleAfterMs = 86_400_000
|
|
593
|
+
} = {}) {
|
|
594
|
+
const checkedAt = normalizeDate(now).toISOString();
|
|
595
|
+
const resolvedFixtures = fixtures ?? createVerifiedAgentStandardConformanceFixtures({ now });
|
|
596
|
+
const scenarios = [];
|
|
597
|
+
|
|
598
|
+
for (const fixture of resolvedFixtures.scenarios ?? []) {
|
|
599
|
+
scenarios.push(await evaluateVerifiedAgentStandardScenario(fixture, {
|
|
600
|
+
now: normalizeDate(now),
|
|
601
|
+
staleAfterMs
|
|
602
|
+
}));
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
const failedScenarios = scenarios.filter((scenario) => scenario.ok !== true);
|
|
606
|
+
const unsigned = {
|
|
607
|
+
version: VERIFIED_AGENT_STANDARD_CONFORMANCE_VERSION,
|
|
608
|
+
ok: failedScenarios.length === 0,
|
|
609
|
+
status: failedScenarios.length === 0 ? "verified" : "failed",
|
|
610
|
+
checkedAt,
|
|
611
|
+
fixtureVersion: resolvedFixtures.version ?? null,
|
|
612
|
+
scenarioCount: scenarios.length,
|
|
613
|
+
passedScenarioCount: scenarios.filter((scenario) => scenario.ok === true).length,
|
|
614
|
+
failedScenarioCount: failedScenarios.length,
|
|
615
|
+
scenarios,
|
|
616
|
+
nextAction: failedScenarios[0]
|
|
617
|
+
? {
|
|
618
|
+
code: failedScenarios[0].id,
|
|
619
|
+
message: `Fix Verified Agent Standard conformance scenario ${failedScenarios[0].id}: ${failedScenarios[0].detail}.`
|
|
620
|
+
}
|
|
621
|
+
: {
|
|
622
|
+
code: "none",
|
|
623
|
+
message: "Verified Agent Standard pass/fail conformance fixtures match SDK verifier behavior."
|
|
624
|
+
}
|
|
625
|
+
};
|
|
626
|
+
|
|
627
|
+
return {
|
|
628
|
+
...unsigned,
|
|
629
|
+
conformanceHash: hashObject(unsigned)
|
|
630
|
+
};
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
async function evaluateVerifiedAgentStandardScenario(fixture, {
|
|
634
|
+
now,
|
|
635
|
+
staleAfterMs
|
|
636
|
+
}) {
|
|
637
|
+
const expectedAccepted = fixture.expectedAccepted === true;
|
|
638
|
+
const expectedRecordId = fixture.expectedRecordId ?? fixture.recordId ?? null;
|
|
639
|
+
const scenarioStaleAfterMs = fixture.staleAfterMs ?? staleAfterMs;
|
|
640
|
+
|
|
641
|
+
try {
|
|
642
|
+
const verifiedAgent = await requireVerifiedAgent({
|
|
643
|
+
client: {
|
|
644
|
+
async requireProductionCertification(options) {
|
|
645
|
+
return {
|
|
646
|
+
...(fixture.certification ?? {}),
|
|
647
|
+
requestedOptions: options
|
|
648
|
+
};
|
|
649
|
+
}
|
|
650
|
+
},
|
|
651
|
+
botId: fixture.botId,
|
|
652
|
+
agentWallet: fixture.agentWallet ?? null,
|
|
653
|
+
action: fixture.action ?? null,
|
|
654
|
+
staleAfterMs: fixture.certificationStaleAfterMs,
|
|
655
|
+
requireCurrentIntegrationContract: true
|
|
656
|
+
});
|
|
657
|
+
const actionProof = verifyActionProductionProofEvidence(fixture.actionProductionProofEvidence, {
|
|
658
|
+
expectedRecordId,
|
|
659
|
+
staleAfterMs: scenarioStaleAfterMs,
|
|
660
|
+
now
|
|
661
|
+
});
|
|
662
|
+
|
|
663
|
+
if (actionProof.ok !== true) {
|
|
664
|
+
return createConformanceScenarioResult({
|
|
665
|
+
fixture,
|
|
666
|
+
expectedAccepted,
|
|
667
|
+
accepted: false,
|
|
668
|
+
failureCode: "action_proof_verification_failed",
|
|
669
|
+
detail: actionProof.failedChecks?.[0]?.name ?? actionProof.status,
|
|
670
|
+
verifiedAgent,
|
|
671
|
+
actionProof
|
|
672
|
+
});
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
const approvalDomain = requireCurrentApprovalDomain(fixture.actionProductionProofEvidence, {
|
|
676
|
+
action: fixture.action ?? null
|
|
677
|
+
});
|
|
678
|
+
|
|
679
|
+
return createConformanceScenarioResult({
|
|
680
|
+
fixture,
|
|
681
|
+
expectedAccepted,
|
|
682
|
+
accepted: true,
|
|
683
|
+
failureCode: null,
|
|
684
|
+
detail: "accepted",
|
|
685
|
+
verifiedAgent,
|
|
686
|
+
actionProof,
|
|
687
|
+
approvalDomain
|
|
688
|
+
});
|
|
689
|
+
} catch (error) {
|
|
690
|
+
return createConformanceScenarioResult({
|
|
691
|
+
fixture,
|
|
692
|
+
expectedAccepted,
|
|
693
|
+
accepted: false,
|
|
694
|
+
failureCode: classifyConformanceError(error),
|
|
695
|
+
detail: error.message,
|
|
696
|
+
errorName: error.name
|
|
697
|
+
});
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
function createConformanceScenarioResult({
|
|
702
|
+
fixture,
|
|
703
|
+
expectedAccepted,
|
|
704
|
+
accepted,
|
|
705
|
+
failureCode,
|
|
706
|
+
detail,
|
|
707
|
+
errorName = null,
|
|
708
|
+
verifiedAgent = null,
|
|
709
|
+
actionProof = null,
|
|
710
|
+
approvalDomain = null
|
|
711
|
+
}) {
|
|
712
|
+
const expectedFailureCode = expectedAccepted ? null : fixture.expectedFailureCode ?? null;
|
|
713
|
+
const ok = accepted === expectedAccepted &&
|
|
714
|
+
(expectedAccepted || !expectedFailureCode || failureCode === expectedFailureCode);
|
|
715
|
+
|
|
716
|
+
return {
|
|
717
|
+
id: fixture.id,
|
|
718
|
+
label: fixture.label,
|
|
719
|
+
ok,
|
|
720
|
+
expectedAccepted,
|
|
721
|
+
accepted,
|
|
722
|
+
expectedFailureCode,
|
|
723
|
+
failureCode,
|
|
724
|
+
errorName,
|
|
725
|
+
detail,
|
|
726
|
+
requirement: fixture.requirement,
|
|
727
|
+
verification: verifiedAgent
|
|
728
|
+
? {
|
|
729
|
+
ok: verifiedAgent.ok,
|
|
730
|
+
status: verifiedAgent.status,
|
|
731
|
+
certificationHash: verifiedAgent.certificationHash,
|
|
732
|
+
recordId: verifiedAgent.recordId
|
|
733
|
+
}
|
|
734
|
+
: null,
|
|
735
|
+
actionProductionProof: actionProof
|
|
736
|
+
? {
|
|
737
|
+
ok: actionProof.ok,
|
|
738
|
+
status: actionProof.status,
|
|
739
|
+
recordId: actionProof.recordId,
|
|
740
|
+
evidenceHash: actionProof.evidenceHash,
|
|
741
|
+
failedCheckCount: actionProof.failedCheckCount,
|
|
742
|
+
failedChecks: actionProof.failedChecks?.slice(0, 3) ?? []
|
|
743
|
+
}
|
|
744
|
+
: null,
|
|
745
|
+
approvalDomain: approvalDomain
|
|
746
|
+
? {
|
|
747
|
+
ok: approvalDomain.ok,
|
|
748
|
+
status: approvalDomain.status,
|
|
749
|
+
domain: approvalDomain.domain,
|
|
750
|
+
expectedDomain: approvalDomain.expectedDomain
|
|
751
|
+
}
|
|
752
|
+
: null
|
|
753
|
+
};
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
function classifyConformanceError(error) {
|
|
757
|
+
if (error?.name === "SvsCurrentApprovalDomainError") {
|
|
758
|
+
return error.details?.nextAction?.code ?? "approval_domain_not_current";
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
if (/SVS verified agent requirement failed/.test(error?.message ?? "")) {
|
|
762
|
+
return "verified_agent_requirement_failed";
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
return "unexpected_error";
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
function createConformanceCertification({
|
|
769
|
+
recordId,
|
|
770
|
+
ok = true,
|
|
771
|
+
qualityReady = true,
|
|
772
|
+
score = 100,
|
|
773
|
+
status = "excellent"
|
|
774
|
+
} = {}) {
|
|
775
|
+
return {
|
|
776
|
+
ok,
|
|
777
|
+
certification: {
|
|
778
|
+
certificationHash: ok ? "a".repeat(64) : null,
|
|
779
|
+
recordId
|
|
780
|
+
},
|
|
781
|
+
qualityTarget: {
|
|
782
|
+
ready: qualityReady,
|
|
783
|
+
score,
|
|
784
|
+
targetScore: 100,
|
|
785
|
+
status
|
|
786
|
+
},
|
|
787
|
+
integrationContract: {
|
|
788
|
+
ok,
|
|
789
|
+
status: ok ? "current" : "missing"
|
|
790
|
+
},
|
|
791
|
+
proofs: {
|
|
792
|
+
actionRecordVerificationOk: ok
|
|
793
|
+
},
|
|
794
|
+
nextAction: ok
|
|
795
|
+
? { code: "none", message: "Production certification is current." }
|
|
796
|
+
: { code: "complete_certification", message: "Complete SVS production certification before protocol acceptance." }
|
|
797
|
+
};
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
function createConformanceActionProofEvidence({
|
|
801
|
+
generatedAt,
|
|
802
|
+
botId,
|
|
803
|
+
recordId,
|
|
804
|
+
approvalDomain,
|
|
805
|
+
approvalDomainStatus,
|
|
806
|
+
requestSignatureVerified = true,
|
|
807
|
+
receiptRegistryConfirmed = true
|
|
808
|
+
} = {}) {
|
|
809
|
+
const unsigned = {
|
|
810
|
+
version: ACTION_PRODUCTION_PROOF_EVIDENCE_VERSION,
|
|
811
|
+
generatedAt,
|
|
812
|
+
source: {
|
|
813
|
+
recordPath: `data/actions/${recordId}.json`,
|
|
814
|
+
statusVersion: "svs.action-production-proof-status.v1"
|
|
815
|
+
},
|
|
816
|
+
productionProof: {
|
|
817
|
+
ready: true,
|
|
818
|
+
status: "ready",
|
|
819
|
+
recordId,
|
|
820
|
+
botId,
|
|
821
|
+
receiptId: "svs-conformance-receipt-1",
|
|
822
|
+
nextAction: { code: "none", message: "Production proof is ready." },
|
|
823
|
+
checks: []
|
|
824
|
+
},
|
|
825
|
+
request: {
|
|
826
|
+
authenticatedBotId: requestSignatureVerified ? botId : null,
|
|
827
|
+
requestSignatureVerified,
|
|
828
|
+
requestSignatureSlot: requestSignatureVerified ? "primary" : null,
|
|
829
|
+
requestSignatureVersion: requestSignatureVerified ? "v1" : null,
|
|
830
|
+
requestNonce: requestSignatureVerified ? "svs-conformance-nonce-1" : null,
|
|
831
|
+
requestId: "svs-conformance-request-1",
|
|
832
|
+
idempotencyKey: "svs-conformance-request-1",
|
|
833
|
+
requestTimestamp: generatedAt
|
|
834
|
+
},
|
|
835
|
+
humanApproval: {
|
|
836
|
+
approved: true,
|
|
837
|
+
reviewer: "operator",
|
|
838
|
+
signer: "ConformanceController111111111111111111111111",
|
|
839
|
+
verified: true,
|
|
840
|
+
messageHash: "c".repeat(64),
|
|
841
|
+
domain: approvalDomain,
|
|
842
|
+
domainStatus: approvalDomainStatus,
|
|
843
|
+
currentDomain: approvalDomainStatus === "current",
|
|
844
|
+
legacyDomainCompatible: approvalDomainStatus === "legacy_compatible"
|
|
845
|
+
},
|
|
846
|
+
broadcast: {
|
|
847
|
+
confirmed: true,
|
|
848
|
+
signature: "svs-conformance-broadcast-signature",
|
|
849
|
+
confirmationStatus: "confirmed",
|
|
850
|
+
slot: 100,
|
|
851
|
+
rpcUrl: "https://api.devnet.solana.com"
|
|
852
|
+
},
|
|
853
|
+
receiptRegistry: {
|
|
854
|
+
confirmed: receiptRegistryConfirmed,
|
|
855
|
+
signature: receiptRegistryConfirmed ? "svs-conformance-registry-signature" : null,
|
|
856
|
+
confirmationStatus: receiptRegistryConfirmed ? "confirmed" : null,
|
|
857
|
+
slot: receiptRegistryConfirmed ? 101 : null,
|
|
858
|
+
programId: "ReceiptRegistry111111111111111111111111111111",
|
|
859
|
+
receiptAccount: receiptRegistryConfirmed ? "ReceiptAccount111111111111111111111111111111" : null,
|
|
860
|
+
planHash: receiptRegistryConfirmed ? "d".repeat(64) : null,
|
|
861
|
+
transactionPlanHash: receiptRegistryConfirmed ? "e".repeat(64) : null
|
|
862
|
+
},
|
|
863
|
+
actionRecordVerification: {
|
|
864
|
+
ok: true,
|
|
865
|
+
version: "svs.action-record-verification.v1",
|
|
866
|
+
checkedAt: generatedAt,
|
|
867
|
+
receiptId: "svs-conformance-receipt-1",
|
|
868
|
+
receiptAccount: receiptRegistryConfirmed ? "ReceiptAccount111111111111111111111111111111" : null,
|
|
869
|
+
registryTransactionSignature: receiptRegistryConfirmed ? "svs-conformance-registry-signature" : null,
|
|
870
|
+
failedCheckCount: 0
|
|
871
|
+
},
|
|
872
|
+
policy: {
|
|
873
|
+
controllerWallet: "ConformanceController111111111111111111111111",
|
|
874
|
+
policyHash: "f".repeat(64),
|
|
875
|
+
intentHash: "1".repeat(64),
|
|
876
|
+
simulationHash: "2".repeat(64)
|
|
877
|
+
},
|
|
878
|
+
reportSafety: {
|
|
879
|
+
secretsIncluded: false,
|
|
880
|
+
redactedFields: [
|
|
881
|
+
"SVS_BOT_API_KEY",
|
|
882
|
+
"SVS_BOT_REQUEST_SIGNING_SECRET",
|
|
883
|
+
"SVS_BOT_PENDING_REQUEST_SIGNING_SECRET",
|
|
884
|
+
"apiKey",
|
|
885
|
+
"requestSigningSecret",
|
|
886
|
+
"pendingRequestSigningSecret",
|
|
887
|
+
"webhookSecret"
|
|
888
|
+
]
|
|
889
|
+
}
|
|
890
|
+
};
|
|
891
|
+
|
|
892
|
+
return {
|
|
893
|
+
...unsigned,
|
|
894
|
+
evidenceHash: hashObject(unsigned)
|
|
895
|
+
};
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
function normalizeDate(value) {
|
|
899
|
+
return value instanceof Date ? value : new Date(value);
|
|
900
|
+
}
|