@paybond/kit 0.11.10 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/completion-presets/catalog.json +374 -3
- package/completion-presets/catalog.sha256 +1 -1
- package/dist/agent/facade.js +13 -0
- package/dist/agent/guarded-agent.d.ts +1 -1
- package/dist/agent/guarded-agent.js +19 -0
- package/dist/agent/index.d.ts +2 -1
- package/dist/agent/index.js +1 -0
- package/dist/agent/instrument.d.ts +6 -0
- package/dist/agent/instrument.js +6 -0
- package/dist/agent/interceptor.d.ts +9 -0
- package/dist/agent/interceptor.js +177 -1
- package/dist/agent/receipt-client.d.ts +49 -0
- package/dist/agent/receipt-client.js +45 -0
- package/dist/agent/registry.js +1 -0
- package/dist/agent/run.d.ts +2 -0
- package/dist/agent/run.js +52 -0
- package/dist/agent/types.d.ts +70 -0
- package/dist/agent-receipt-external-attestations.d.ts +29 -0
- package/dist/agent-receipt-external-attestations.js +124 -0
- package/dist/agent-receipt.d.ts +134 -0
- package/dist/agent-receipt.js +580 -0
- package/dist/agent-recognition.d.ts +25 -0
- package/dist/agent-recognition.js +36 -0
- package/dist/audit/exports.d.ts +72 -0
- package/dist/audit/exports.js +185 -0
- package/dist/audit/index.d.ts +3 -0
- package/dist/audit/index.js +3 -0
- package/dist/audit/verify.d.ts +8 -0
- package/dist/audit/verify.js +113 -0
- package/dist/audit/wire.d.ts +54 -0
- package/dist/audit/wire.js +80 -0
- package/dist/cli/agent/demo-loaders.d.ts +2 -0
- package/dist/cli/agent/demo-loaders.js +24 -0
- package/dist/cli/agent/production-evidence.d.ts +11 -0
- package/dist/cli/agent/production-evidence.js +17 -0
- package/dist/cli/audit-export.d.ts +2 -7
- package/dist/cli/audit-export.js +2 -120
- package/dist/cli/command-spec.js +43 -10
- package/dist/cli/commands/agent.d.ts +3 -0
- package/dist/cli/commands/agent.js +143 -1
- package/dist/cli/commands/discovery.js +39 -36
- package/dist/cli/commands/workflows.js +116 -18
- package/dist/cli/help.d.ts +1 -1
- package/dist/cli/help.js +12 -8
- package/dist/cli/intents-harbor-mutation.d.ts +18 -0
- package/dist/cli/intents-harbor-mutation.js +33 -0
- package/dist/cli/paybond.d.ts +9 -0
- package/dist/cli/paybond.js +23 -0
- package/dist/cli/redact.js +3 -0
- package/dist/cloudflare-agents/config.d.ts +24 -0
- package/dist/cloudflare-agents/config.js +23 -0
- package/dist/cloudflare-agents/index.d.ts +3 -0
- package/dist/cloudflare-agents/index.js +3 -0
- package/dist/cloudflare-agents/peer.d.ts +9 -0
- package/dist/cloudflare-agents/peer.js +20 -0
- package/dist/cloudflare-agents/sandbox-demo.d.ts +36 -0
- package/dist/cloudflare-agents/sandbox-demo.js +89 -0
- package/dist/completion-catalog-digest.d.ts +1 -1
- package/dist/completion-catalog-digest.js +1 -1
- package/dist/completion-init.js +8 -3
- package/dist/dev/offline-gateway.d.ts +2 -1
- package/dist/dev/offline-gateway.js +34 -3
- package/dist/dev/x402-fund-mock.d.ts +28 -0
- package/dist/dev/x402-fund-mock.js +124 -0
- package/dist/index.d.ts +125 -9
- package/dist/index.js +264 -17
- package/dist/init.js +113 -2
- package/dist/mastra/config.d.ts +30 -0
- package/dist/mastra/config.js +58 -0
- package/dist/mastra/index.d.ts +2 -0
- package/dist/mastra/index.js +2 -0
- package/dist/mastra/peer.d.ts +11 -0
- package/dist/mastra/peer.js +24 -0
- package/dist/mastra/sandbox-demo.d.ts +36 -0
- package/dist/mastra/sandbox-demo.js +87 -0
- package/dist/mcp/index.d.ts +1 -0
- package/dist/mcp/index.js +1 -0
- package/dist/mcp/sandbox-demo.d.ts +38 -0
- package/dist/mcp/sandbox-demo.js +112 -0
- package/dist/mcp-receipt-resource.d.ts +10 -0
- package/dist/mcp-receipt-resource.js +32 -0
- package/dist/mcp-server.d.ts +6 -0
- package/dist/mcp-server.js +124 -1
- package/dist/mpp-commercial.d.ts +19 -0
- package/dist/mpp-commercial.js +34 -0
- package/dist/mpp-funding.d.ts +71 -0
- package/dist/mpp-funding.js +192 -0
- package/dist/payment-transport.d.ts +30 -0
- package/dist/payment-transport.js +56 -0
- package/dist/policy/init.js +2 -0
- package/dist/policy/intent-spec.js +2 -0
- package/dist/principal-intent.d.ts +1 -1
- package/dist/principal-intent.js +4 -1
- package/dist/project-init.js +8 -0
- package/dist/template-init.d.ts +2 -2
- package/dist/template-init.js +6 -2
- package/dist/x402-funding.d.ts +52 -0
- package/dist/x402-funding.js +124 -0
- package/package.json +20 -2
- package/templates/manifest.json +28 -9
- package/templates/openai-shopping-agent/package-lock.json +16 -8
- package/templates/openai-shopping-agent/package.json +1 -1
- package/templates/paybond-aws-operator/package-lock.json +13 -5
- package/templates/paybond-aws-operator/package.json +1 -1
- package/templates/paybond-claude-agents-demo/package-lock.json +16 -8
- package/templates/paybond-claude-agents-demo/package.json +1 -1
- package/templates/paybond-invoice-agent/requirements.txt +1 -1
- package/templates/paybond-mastra-travel-agent/.env.example +3 -0
- package/templates/paybond-mastra-travel-agent/.github/workflows/smoke.yml +20 -0
- package/templates/paybond-mastra-travel-agent/LICENSE +201 -0
- package/templates/paybond-mastra-travel-agent/README.md +29 -0
- package/templates/paybond-mastra-travel-agent/package-lock.json +3377 -0
- package/templates/paybond-mastra-travel-agent/package.json +22 -0
- package/templates/paybond-mastra-travel-agent/paybond.policy.yaml +22 -0
- package/templates/paybond-mastra-travel-agent/src/index.ts +22 -0
- package/templates/paybond-mastra-travel-agent/src/paybond.config.ts +51 -0
- package/templates/paybond-mastra-travel-agent/tsconfig.json +13 -0
- package/templates/paybond-mcp-coding-agent/package-lock.json +13 -5
- package/templates/paybond-mcp-coding-agent/package.json +1 -1
- package/templates/paybond-openai-agents-demo/package-lock.json +16 -8
- package/templates/paybond-openai-agents-demo/package.json +1 -1
- package/templates/paybond-procurement-agent/package-lock.json +13 -5
- package/templates/paybond-procurement-agent/package.json +1 -1
- package/templates/paybond-travel-agent/package-lock.json +16 -8
- package/templates/paybond-travel-agent/package.json +1 -1
- package/templates/paybond-vercel-shopping-agent/package-lock.json +13 -5
- package/templates/paybond-vercel-shopping-agent/package.json +1 -1
|
@@ -0,0 +1,580 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { verify } from "@noble/ed25519";
|
|
3
|
+
import { ensureEd25519Sha512Sync } from "./ed25519-sync.js";
|
|
4
|
+
export const AGENT_RECEIPT_SCHEMA_VERSION = 1;
|
|
5
|
+
export const AGENT_RECEIPT_KIND_V1 = "paybond.agent_receipt_v1";
|
|
6
|
+
export const AGENT_RECEIPT_VERSION_V1 = "1";
|
|
7
|
+
export const AGENT_RECEIPT_SIGNING_ALGORITHM_ED25519 = "ed25519-sha256-json-v1";
|
|
8
|
+
export const AGENT_RECEIPT_SCOPE_ACTION = "action";
|
|
9
|
+
export const AGENT_RECEIPT_SCOPE_INTENT_TERMINAL = "intent_terminal";
|
|
10
|
+
export const AGENT_RECEIPT_WELL_KNOWN_PATH = "/.well-known/agent-receipt-v1.json";
|
|
11
|
+
const SCOPE_TOKEN_RE = /^[a-z0-9][a-z0-9._:/-]{0,127}$/;
|
|
12
|
+
const HEX64_RE = /^[0-9a-f]{64}$/;
|
|
13
|
+
const CURRENCY_RE = /^[a-z]{3}$/;
|
|
14
|
+
const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
|
|
15
|
+
function sha256Hex(data) {
|
|
16
|
+
return createHash("sha256").update(data).digest("hex");
|
|
17
|
+
}
|
|
18
|
+
function formatRfc3339Seconds(iso) {
|
|
19
|
+
const date = new Date(iso);
|
|
20
|
+
if (Number.isNaN(date.getTime())) {
|
|
21
|
+
throw new Error("agent receipt: timestamp is invalid");
|
|
22
|
+
}
|
|
23
|
+
return date.toISOString().replace(/\.\d{3}Z$/, "Z");
|
|
24
|
+
}
|
|
25
|
+
function canonicalizeJson(value) {
|
|
26
|
+
if (Array.isArray(value)) {
|
|
27
|
+
return value.map((item) => canonicalizeJson(item));
|
|
28
|
+
}
|
|
29
|
+
if (value && typeof value === "object") {
|
|
30
|
+
const record = value;
|
|
31
|
+
const keys = Object.keys(record).sort();
|
|
32
|
+
const out = {};
|
|
33
|
+
for (const key of keys) {
|
|
34
|
+
out[key] = canonicalizeJson(record[key]);
|
|
35
|
+
}
|
|
36
|
+
return out;
|
|
37
|
+
}
|
|
38
|
+
return value;
|
|
39
|
+
}
|
|
40
|
+
function jcsBytes(value) {
|
|
41
|
+
return new TextEncoder().encode(JSON.stringify(canonicalizeJson(value)));
|
|
42
|
+
}
|
|
43
|
+
/** Returns sha256(JCS({ system_prompt, tools_manifest, policy_snapshot_id })). */
|
|
44
|
+
export function configHashSha256Hex(input) {
|
|
45
|
+
return sha256Hex(jcsBytes(input));
|
|
46
|
+
}
|
|
47
|
+
/** Returns sha256(normalized_user_prompt). */
|
|
48
|
+
export function promptHashSha256Hex(normalizedUserPrompt) {
|
|
49
|
+
return sha256Hex(normalizedUserPrompt);
|
|
50
|
+
}
|
|
51
|
+
/** Returns sha256(JCS(value)). */
|
|
52
|
+
export function valueDigestSha256Hex(value) {
|
|
53
|
+
return sha256Hex(jcsBytes(value));
|
|
54
|
+
}
|
|
55
|
+
/** Returns sha256(intent_id + "\\x00" + tool_call_id) as lowercase hex. */
|
|
56
|
+
export function actionReceiptId(intentId, toolCallId) {
|
|
57
|
+
return sha256Hex(`${intentId}\u0000${toolCallId}`);
|
|
58
|
+
}
|
|
59
|
+
function normalizeScopeToken(value, field) {
|
|
60
|
+
const normalized = value.trim().toLowerCase();
|
|
61
|
+
if (!normalized) {
|
|
62
|
+
throw new Error(`agent receipt: ${field} is required`);
|
|
63
|
+
}
|
|
64
|
+
if (!SCOPE_TOKEN_RE.test(normalized)) {
|
|
65
|
+
throw new Error(`agent receipt: ${field} ${JSON.stringify(normalized)} is not canonical`);
|
|
66
|
+
}
|
|
67
|
+
return normalized;
|
|
68
|
+
}
|
|
69
|
+
function requireHex64(value, field) {
|
|
70
|
+
if (!HEX64_RE.test(value)) {
|
|
71
|
+
throw new Error(`agent receipt: ${field} must be a lowercase 64-byte hex SHA-256 digest`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
function parseUuid(value, field) {
|
|
75
|
+
const normalized = value.trim().toLowerCase();
|
|
76
|
+
if (!UUID_RE.test(normalized)) {
|
|
77
|
+
throw new Error(`agent receipt: ${field} must be a canonical UUID`);
|
|
78
|
+
}
|
|
79
|
+
return normalized;
|
|
80
|
+
}
|
|
81
|
+
function normalizeScopeSet(values, field) {
|
|
82
|
+
if (!values?.length) {
|
|
83
|
+
return [];
|
|
84
|
+
}
|
|
85
|
+
const seen = new Set();
|
|
86
|
+
const out = [];
|
|
87
|
+
for (const value of values) {
|
|
88
|
+
const normalized = normalizeScopeToken(value, field);
|
|
89
|
+
if (!seen.has(normalized)) {
|
|
90
|
+
seen.add(normalized);
|
|
91
|
+
out.push(normalized);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return out;
|
|
95
|
+
}
|
|
96
|
+
function normalizeReceipt(receipt) {
|
|
97
|
+
const schemaVersion = receipt.schema_version === 0 ? AGENT_RECEIPT_SCHEMA_VERSION : receipt.schema_version;
|
|
98
|
+
if (schemaVersion !== AGENT_RECEIPT_SCHEMA_VERSION) {
|
|
99
|
+
throw new Error(`agent receipt: unsupported schema_version ${schemaVersion}`);
|
|
100
|
+
}
|
|
101
|
+
const kind = receipt.kind.trim() || AGENT_RECEIPT_KIND_V1;
|
|
102
|
+
if (kind !== AGENT_RECEIPT_KIND_V1) {
|
|
103
|
+
throw new Error(`agent receipt: unsupported kind ${JSON.stringify(kind)}`);
|
|
104
|
+
}
|
|
105
|
+
const receiptVersion = receipt.receipt_version.trim() || AGENT_RECEIPT_VERSION_V1;
|
|
106
|
+
if (receiptVersion !== AGENT_RECEIPT_VERSION_V1) {
|
|
107
|
+
throw new Error(`agent receipt: unsupported receipt_version ${JSON.stringify(receiptVersion)}`);
|
|
108
|
+
}
|
|
109
|
+
const scope = receipt.scope.trim().toLowerCase();
|
|
110
|
+
if (scope !== AGENT_RECEIPT_SCOPE_ACTION && scope !== AGENT_RECEIPT_SCOPE_INTENT_TERMINAL) {
|
|
111
|
+
throw new Error(`agent receipt: scope must be ${AGENT_RECEIPT_SCOPE_ACTION} or ${AGENT_RECEIPT_SCOPE_INTENT_TERMINAL}`);
|
|
112
|
+
}
|
|
113
|
+
const receiptId = receipt.receipt_id.trim().toLowerCase();
|
|
114
|
+
if (!receiptId) {
|
|
115
|
+
throw new Error("agent receipt: receipt_id is required");
|
|
116
|
+
}
|
|
117
|
+
const tenantId = receipt.tenant_id.trim();
|
|
118
|
+
if (!tenantId) {
|
|
119
|
+
throw new Error("agent receipt: tenant_id is required");
|
|
120
|
+
}
|
|
121
|
+
const authorization = normalizeAuthorization(receipt.authorization);
|
|
122
|
+
const outcome = normalizeOutcome(receipt.outcome);
|
|
123
|
+
const references = normalizeReferences(receipt.references);
|
|
124
|
+
const externalAttestations = normalizeExternalAttestations(receipt.external_attestations ?? []);
|
|
125
|
+
let execution;
|
|
126
|
+
if (scope === AGENT_RECEIPT_SCOPE_ACTION) {
|
|
127
|
+
if (!receipt.execution) {
|
|
128
|
+
throw new Error("agent receipt: execution is required for action scope");
|
|
129
|
+
}
|
|
130
|
+
execution = normalizeExecution(receipt.execution);
|
|
131
|
+
}
|
|
132
|
+
const normalized = {
|
|
133
|
+
schema_version: AGENT_RECEIPT_SCHEMA_VERSION,
|
|
134
|
+
kind: AGENT_RECEIPT_KIND_V1,
|
|
135
|
+
receipt_version: AGENT_RECEIPT_VERSION_V1,
|
|
136
|
+
scope: scope,
|
|
137
|
+
receipt_id: receiptId,
|
|
138
|
+
issued_at: formatRfc3339Seconds(receipt.issued_at),
|
|
139
|
+
tenant_id: tenantId,
|
|
140
|
+
authorization,
|
|
141
|
+
execution,
|
|
142
|
+
merchant: receipt.merchant ? normalizeMerchant(receipt.merchant) : undefined,
|
|
143
|
+
evidence: receipt.evidence ? normalizeEvidence(receipt.evidence) : undefined,
|
|
144
|
+
payment: receipt.payment ? normalizePayment(receipt.payment) : undefined,
|
|
145
|
+
outcome,
|
|
146
|
+
references,
|
|
147
|
+
external_attestations: externalAttestations,
|
|
148
|
+
signing_algorithm: receipt.signing_algorithm.trim().toLowerCase() || AGENT_RECEIPT_SIGNING_ALGORITHM_ED25519,
|
|
149
|
+
message_digest_sha256_hex: receipt.message_digest_sha256_hex.trim().toLowerCase(),
|
|
150
|
+
signing_public_key_ed25519_hex: receipt.signing_public_key_ed25519_hex.trim().toLowerCase(),
|
|
151
|
+
ed25519_signature_hex: receipt.ed25519_signature_hex.trim().toLowerCase(),
|
|
152
|
+
};
|
|
153
|
+
verifyReceiptId(normalized);
|
|
154
|
+
return normalized;
|
|
155
|
+
}
|
|
156
|
+
function normalizeAuthorization(authorization) {
|
|
157
|
+
const principalDid = authorization.principal_did.trim();
|
|
158
|
+
const actorSubject = authorization.actor_subject.trim();
|
|
159
|
+
if (!principalDid) {
|
|
160
|
+
throw new Error("agent receipt: principal_did is required");
|
|
161
|
+
}
|
|
162
|
+
if (!actorSubject) {
|
|
163
|
+
throw new Error("agent receipt: actor_subject is required");
|
|
164
|
+
}
|
|
165
|
+
const currency = authorization.currency.trim().toLowerCase();
|
|
166
|
+
if (!CURRENCY_RE.test(currency)) {
|
|
167
|
+
throw new Error(`agent receipt: currency ${JSON.stringify(currency)} is not canonical`);
|
|
168
|
+
}
|
|
169
|
+
if (authorization.requested_spend_cents < 0) {
|
|
170
|
+
throw new Error("agent receipt: requested_spend_cents must be non-negative");
|
|
171
|
+
}
|
|
172
|
+
return {
|
|
173
|
+
principal_did: principalDid,
|
|
174
|
+
actor_subject: actorSubject,
|
|
175
|
+
agent: normalizeAgent(authorization.agent),
|
|
176
|
+
decision_id: parseUuid(authorization.decision_id, "decision_id"),
|
|
177
|
+
audit_id: authorization.audit_id ? parseUuid(authorization.audit_id, "audit_id") : undefined,
|
|
178
|
+
policy: normalizePolicy(authorization.policy),
|
|
179
|
+
authorized_at: formatRfc3339Seconds(authorization.authorized_at),
|
|
180
|
+
requested_spend_cents: authorization.requested_spend_cents,
|
|
181
|
+
currency,
|
|
182
|
+
reason_codes: normalizeScopeSet(authorization.reason_codes, "reason_codes"),
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
function normalizeAgent(agent) {
|
|
186
|
+
const modelFamily = normalizeScopeToken(agent.model_family, "agent.model_family");
|
|
187
|
+
const configHash = agent.config_hash_sha256_hex.trim().toLowerCase();
|
|
188
|
+
const promptHash = agent.prompt_hash_sha256_hex.trim().toLowerCase();
|
|
189
|
+
requireHex64(configHash, "agent.config_hash_sha256_hex");
|
|
190
|
+
requireHex64(promptHash, "agent.prompt_hash_sha256_hex");
|
|
191
|
+
const operatorDid = agent.operator_did.trim();
|
|
192
|
+
if (!operatorDid) {
|
|
193
|
+
throw new Error("agent receipt: agent.operator_did is required");
|
|
194
|
+
}
|
|
195
|
+
return {
|
|
196
|
+
operator_did: operatorDid,
|
|
197
|
+
model_family: modelFamily,
|
|
198
|
+
model_instance_id: agent.model_instance_id?.trim() || undefined,
|
|
199
|
+
config_hash_sha256_hex: configHash,
|
|
200
|
+
prompt_hash_sha256_hex: promptHash,
|
|
201
|
+
deployment_epoch: agent.deployment_epoch,
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
function normalizePolicy(policy) {
|
|
205
|
+
const templateId = policy.template_id.trim();
|
|
206
|
+
const digest = policy.content_digest_sha256_hex.trim().toLowerCase();
|
|
207
|
+
if (!templateId) {
|
|
208
|
+
throw new Error("agent receipt: policy.template_id is required");
|
|
209
|
+
}
|
|
210
|
+
requireHex64(digest, "policy.content_digest_sha256_hex");
|
|
211
|
+
return {
|
|
212
|
+
template_id: templateId,
|
|
213
|
+
version_seq: policy.version_seq,
|
|
214
|
+
content_digest_sha256_hex: digest,
|
|
215
|
+
spend_policy_version: policy.spend_policy_version,
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
function normalizeExecution(execution) {
|
|
219
|
+
const toolCallId = execution.tool_call_id.trim();
|
|
220
|
+
if (!toolCallId) {
|
|
221
|
+
throw new Error("agent receipt: tool_call_id is required");
|
|
222
|
+
}
|
|
223
|
+
const argumentsDigest = execution.arguments_digest_sha256_hex.trim().toLowerCase();
|
|
224
|
+
requireHex64(argumentsDigest, "arguments_digest_sha256_hex");
|
|
225
|
+
let resultDigest;
|
|
226
|
+
if (execution.result_digest_sha256_hex) {
|
|
227
|
+
resultDigest = execution.result_digest_sha256_hex.trim().toLowerCase();
|
|
228
|
+
requireHex64(resultDigest, "result_digest_sha256_hex");
|
|
229
|
+
}
|
|
230
|
+
const outcome = execution.outcome.trim().toLowerCase();
|
|
231
|
+
if (!["executed", "denied", "skipped", "failed"].includes(outcome)) {
|
|
232
|
+
throw new Error("agent receipt: outcome must be executed, denied, skipped, or failed");
|
|
233
|
+
}
|
|
234
|
+
if ((execution.duration_ms ?? 0) < 0) {
|
|
235
|
+
throw new Error("agent receipt: duration_ms must be non-negative");
|
|
236
|
+
}
|
|
237
|
+
return {
|
|
238
|
+
run_id: parseUuid(execution.run_id, "run_id"),
|
|
239
|
+
tool_call_id: toolCallId,
|
|
240
|
+
tool_name: normalizeScopeToken(execution.tool_name, "tool_name"),
|
|
241
|
+
operation: normalizeScopeToken(execution.operation, "operation"),
|
|
242
|
+
arguments_digest_sha256_hex: argumentsDigest,
|
|
243
|
+
result_digest_sha256_hex: resultDigest,
|
|
244
|
+
outcome: outcome,
|
|
245
|
+
started_at: formatRfc3339Seconds(execution.started_at),
|
|
246
|
+
completed_at: formatRfc3339Seconds(execution.completed_at),
|
|
247
|
+
duration_ms: execution.duration_ms,
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
function normalizeMerchant(merchant) {
|
|
251
|
+
const payeeDid = merchant.payee_did.trim();
|
|
252
|
+
if (!payeeDid) {
|
|
253
|
+
throw new Error("agent receipt: payee_did is required");
|
|
254
|
+
}
|
|
255
|
+
return {
|
|
256
|
+
payee_did: payeeDid,
|
|
257
|
+
vendor_id: merchant.vendor_id ? normalizeScopeToken(merchant.vendor_id, "vendor_id") : undefined,
|
|
258
|
+
vendor_ref_id: merchant.vendor_ref_id?.trim() || undefined,
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
function normalizeEvidence(evidence) {
|
|
262
|
+
const payloadDigest = evidence.payload_digest_sha256_hex.trim().toLowerCase();
|
|
263
|
+
requireHex64(payloadDigest, "payload_digest_sha256_hex");
|
|
264
|
+
let artifactsDigest;
|
|
265
|
+
if (evidence.artifacts_digest_sha256_hex) {
|
|
266
|
+
artifactsDigest = evidence.artifacts_digest_sha256_hex.trim().toLowerCase();
|
|
267
|
+
requireHex64(artifactsDigest, "artifacts_digest_sha256_hex");
|
|
268
|
+
}
|
|
269
|
+
let payeeSignatureDigest;
|
|
270
|
+
if (evidence.payee_signature_digest_sha256_hex) {
|
|
271
|
+
payeeSignatureDigest = evidence.payee_signature_digest_sha256_hex.trim().toLowerCase();
|
|
272
|
+
requireHex64(payeeSignatureDigest, "payee_signature_digest_sha256_hex");
|
|
273
|
+
}
|
|
274
|
+
const payeeDid = evidence.payee_did.trim();
|
|
275
|
+
if (!payeeDid) {
|
|
276
|
+
throw new Error("agent receipt: payee_did is required");
|
|
277
|
+
}
|
|
278
|
+
return {
|
|
279
|
+
completion_preset_id: normalizeScopeToken(evidence.completion_preset_id, "completion_preset_id"),
|
|
280
|
+
payload_digest_sha256_hex: payloadDigest,
|
|
281
|
+
artifacts_digest_sha256_hex: artifactsDigest,
|
|
282
|
+
predicate_passed: evidence.predicate_passed,
|
|
283
|
+
payee_did: payeeDid,
|
|
284
|
+
payee_signature_digest_sha256_hex: payeeSignatureDigest,
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
function normalizePayment(payment) {
|
|
288
|
+
let fundingDigest;
|
|
289
|
+
if (payment.funding_receipt_digest_sha256_hex) {
|
|
290
|
+
fundingDigest = payment.funding_receipt_digest_sha256_hex.trim().toLowerCase();
|
|
291
|
+
requireHex64(fundingDigest, "funding_receipt_digest_sha256_hex");
|
|
292
|
+
}
|
|
293
|
+
return {
|
|
294
|
+
intent_id: parseUuid(payment.intent_id, "intent_id"),
|
|
295
|
+
settlement_rail: normalizeScopeToken(payment.settlement_rail, "settlement_rail"),
|
|
296
|
+
funding_method: payment.funding_method
|
|
297
|
+
? normalizeScopeToken(payment.funding_method, "funding_method")
|
|
298
|
+
: undefined,
|
|
299
|
+
funding_reference: payment.funding_reference?.trim() || undefined,
|
|
300
|
+
funding_receipt_digest_sha256_hex: fundingDigest,
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
function normalizeOutcome(outcome) {
|
|
304
|
+
const harborState = normalizeScopeToken(outcome.harbor_state, "harbor_state");
|
|
305
|
+
let spendReservationOutcome;
|
|
306
|
+
if (outcome.spend_reservation_outcome) {
|
|
307
|
+
const normalized = outcome.spend_reservation_outcome.trim().toLowerCase();
|
|
308
|
+
if (!["consumed", "released", "pending", "none"].includes(normalized)) {
|
|
309
|
+
throw new Error("agent receipt: spend_reservation_outcome must be consumed, released, pending, or none");
|
|
310
|
+
}
|
|
311
|
+
spendReservationOutcome = normalized;
|
|
312
|
+
}
|
|
313
|
+
return {
|
|
314
|
+
harbor_state: harborState,
|
|
315
|
+
spend_reservation_outcome: spendReservationOutcome,
|
|
316
|
+
predicate_passed: outcome.predicate_passed,
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
function normalizeReferences(references) {
|
|
320
|
+
if ((references.ledger_seq ?? 0) < 0) {
|
|
321
|
+
throw new Error("agent receipt: ledger_seq must be non-negative");
|
|
322
|
+
}
|
|
323
|
+
let settlementReceiptId = references.settlement_receipt_id;
|
|
324
|
+
if (settlementReceiptId) {
|
|
325
|
+
const trimmed = settlementReceiptId.trim().toLowerCase();
|
|
326
|
+
if (!trimmed) {
|
|
327
|
+
settlementReceiptId = null;
|
|
328
|
+
}
|
|
329
|
+
else if (!UUID_RE.test(trimmed) && !HEX64_RE.test(trimmed)) {
|
|
330
|
+
throw new Error("agent receipt: settlement_receipt_id must be a canonical UUID or lowercase 64-byte hex digest");
|
|
331
|
+
}
|
|
332
|
+
else {
|
|
333
|
+
settlementReceiptId = trimmed;
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
return {
|
|
337
|
+
intent_id: parseUuid(references.intent_id, "intent_id"),
|
|
338
|
+
ledger_seq: references.ledger_seq,
|
|
339
|
+
settlement_receipt_id: settlementReceiptId ?? null,
|
|
340
|
+
};
|
|
341
|
+
}
|
|
342
|
+
function normalizeExternalAttestations(values) {
|
|
343
|
+
return values.map((value) => {
|
|
344
|
+
const digest = value.digest_sha256_hex.trim().toLowerCase();
|
|
345
|
+
requireHex64(digest, "digest_sha256_hex");
|
|
346
|
+
if (!value.kind.trim()) {
|
|
347
|
+
throw new Error("agent receipt: kind is required");
|
|
348
|
+
}
|
|
349
|
+
return {
|
|
350
|
+
source: normalizeScopeToken(value.source, "source"),
|
|
351
|
+
kind: value.kind.trim(),
|
|
352
|
+
digest_sha256_hex: digest,
|
|
353
|
+
reference_id: value.reference_id?.trim() || undefined,
|
|
354
|
+
};
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
function verifyReceiptId(receipt) {
|
|
358
|
+
if (receipt.scope === AGENT_RECEIPT_SCOPE_ACTION) {
|
|
359
|
+
if (!receipt.execution) {
|
|
360
|
+
throw new Error("agent receipt: execution is required to verify action receipt_id");
|
|
361
|
+
}
|
|
362
|
+
const expected = actionReceiptId(receipt.references.intent_id, receipt.execution.tool_call_id);
|
|
363
|
+
if (receipt.receipt_id !== expected) {
|
|
364
|
+
throw new Error("agent receipt: receipt_id does not match action scope derivation");
|
|
365
|
+
}
|
|
366
|
+
requireHex64(receipt.receipt_id, "receipt_id");
|
|
367
|
+
return;
|
|
368
|
+
}
|
|
369
|
+
if (receipt.receipt_id !== receipt.references.intent_id) {
|
|
370
|
+
throw new Error("agent receipt: receipt_id must equal intent_id for intent_terminal scope");
|
|
371
|
+
}
|
|
372
|
+
parseUuid(receipt.receipt_id, "receipt_id");
|
|
373
|
+
}
|
|
374
|
+
function marshalCanonicalAgentReceipt(receipt) {
|
|
375
|
+
const authorization = {
|
|
376
|
+
principal_did: receipt.authorization.principal_did,
|
|
377
|
+
actor_subject: receipt.authorization.actor_subject,
|
|
378
|
+
agent: {
|
|
379
|
+
operator_did: receipt.authorization.agent.operator_did,
|
|
380
|
+
model_family: receipt.authorization.agent.model_family,
|
|
381
|
+
...(receipt.authorization.agent.model_instance_id
|
|
382
|
+
? { model_instance_id: receipt.authorization.agent.model_instance_id }
|
|
383
|
+
: {}),
|
|
384
|
+
config_hash_sha256_hex: receipt.authorization.agent.config_hash_sha256_hex,
|
|
385
|
+
prompt_hash_sha256_hex: receipt.authorization.agent.prompt_hash_sha256_hex,
|
|
386
|
+
...(receipt.authorization.agent.deployment_epoch
|
|
387
|
+
? { deployment_epoch: receipt.authorization.agent.deployment_epoch }
|
|
388
|
+
: {}),
|
|
389
|
+
},
|
|
390
|
+
decision_id: receipt.authorization.decision_id,
|
|
391
|
+
...(receipt.authorization.audit_id ? { audit_id: receipt.authorization.audit_id } : {}),
|
|
392
|
+
policy: {
|
|
393
|
+
template_id: receipt.authorization.policy.template_id,
|
|
394
|
+
...(receipt.authorization.policy.version_seq
|
|
395
|
+
? { version_seq: receipt.authorization.policy.version_seq }
|
|
396
|
+
: {}),
|
|
397
|
+
content_digest_sha256_hex: receipt.authorization.policy.content_digest_sha256_hex,
|
|
398
|
+
...(receipt.authorization.policy.spend_policy_version
|
|
399
|
+
? { spend_policy_version: receipt.authorization.policy.spend_policy_version }
|
|
400
|
+
: {}),
|
|
401
|
+
},
|
|
402
|
+
authorized_at: receipt.authorization.authorized_at,
|
|
403
|
+
requested_spend_cents: receipt.authorization.requested_spend_cents,
|
|
404
|
+
currency: receipt.authorization.currency,
|
|
405
|
+
...(receipt.authorization.reason_codes?.length
|
|
406
|
+
? { reason_codes: receipt.authorization.reason_codes }
|
|
407
|
+
: {}),
|
|
408
|
+
};
|
|
409
|
+
const payload = {
|
|
410
|
+
schema_version: receipt.schema_version,
|
|
411
|
+
kind: receipt.kind,
|
|
412
|
+
receipt_version: receipt.receipt_version,
|
|
413
|
+
scope: receipt.scope,
|
|
414
|
+
receipt_id: receipt.receipt_id,
|
|
415
|
+
issued_at: receipt.issued_at,
|
|
416
|
+
tenant_id: receipt.tenant_id,
|
|
417
|
+
authorization,
|
|
418
|
+
};
|
|
419
|
+
if (receipt.execution) {
|
|
420
|
+
payload.execution = {
|
|
421
|
+
run_id: receipt.execution.run_id,
|
|
422
|
+
tool_call_id: receipt.execution.tool_call_id,
|
|
423
|
+
tool_name: receipt.execution.tool_name,
|
|
424
|
+
operation: receipt.execution.operation,
|
|
425
|
+
arguments_digest_sha256_hex: receipt.execution.arguments_digest_sha256_hex,
|
|
426
|
+
...(receipt.execution.result_digest_sha256_hex
|
|
427
|
+
? { result_digest_sha256_hex: receipt.execution.result_digest_sha256_hex }
|
|
428
|
+
: {}),
|
|
429
|
+
outcome: receipt.execution.outcome,
|
|
430
|
+
started_at: receipt.execution.started_at,
|
|
431
|
+
completed_at: receipt.execution.completed_at,
|
|
432
|
+
...(receipt.execution.duration_ms ? { duration_ms: receipt.execution.duration_ms } : {}),
|
|
433
|
+
};
|
|
434
|
+
}
|
|
435
|
+
if (receipt.merchant) {
|
|
436
|
+
payload.merchant = {
|
|
437
|
+
payee_did: receipt.merchant.payee_did,
|
|
438
|
+
...(receipt.merchant.vendor_id ? { vendor_id: receipt.merchant.vendor_id } : {}),
|
|
439
|
+
...(receipt.merchant.vendor_ref_id ? { vendor_ref_id: receipt.merchant.vendor_ref_id } : {}),
|
|
440
|
+
};
|
|
441
|
+
}
|
|
442
|
+
if (receipt.evidence) {
|
|
443
|
+
payload.evidence = {
|
|
444
|
+
completion_preset_id: receipt.evidence.completion_preset_id,
|
|
445
|
+
payload_digest_sha256_hex: receipt.evidence.payload_digest_sha256_hex,
|
|
446
|
+
...(receipt.evidence.artifacts_digest_sha256_hex
|
|
447
|
+
? { artifacts_digest_sha256_hex: receipt.evidence.artifacts_digest_sha256_hex }
|
|
448
|
+
: {}),
|
|
449
|
+
predicate_passed: receipt.evidence.predicate_passed,
|
|
450
|
+
payee_did: receipt.evidence.payee_did,
|
|
451
|
+
...(receipt.evidence.payee_signature_digest_sha256_hex
|
|
452
|
+
? { payee_signature_digest_sha256_hex: receipt.evidence.payee_signature_digest_sha256_hex }
|
|
453
|
+
: {}),
|
|
454
|
+
};
|
|
455
|
+
}
|
|
456
|
+
if (receipt.payment) {
|
|
457
|
+
payload.payment = {
|
|
458
|
+
intent_id: receipt.payment.intent_id,
|
|
459
|
+
settlement_rail: receipt.payment.settlement_rail,
|
|
460
|
+
...(receipt.payment.funding_method ? { funding_method: receipt.payment.funding_method } : {}),
|
|
461
|
+
...(receipt.payment.funding_reference
|
|
462
|
+
? { funding_reference: receipt.payment.funding_reference }
|
|
463
|
+
: {}),
|
|
464
|
+
...(receipt.payment.funding_receipt_digest_sha256_hex
|
|
465
|
+
? { funding_receipt_digest_sha256_hex: receipt.payment.funding_receipt_digest_sha256_hex }
|
|
466
|
+
: {}),
|
|
467
|
+
};
|
|
468
|
+
}
|
|
469
|
+
payload.outcome = {
|
|
470
|
+
harbor_state: receipt.outcome.harbor_state,
|
|
471
|
+
...(receipt.outcome.spend_reservation_outcome
|
|
472
|
+
? { spend_reservation_outcome: receipt.outcome.spend_reservation_outcome }
|
|
473
|
+
: {}),
|
|
474
|
+
...(receipt.outcome.predicate_passed !== undefined
|
|
475
|
+
? { predicate_passed: receipt.outcome.predicate_passed }
|
|
476
|
+
: {}),
|
|
477
|
+
};
|
|
478
|
+
payload.references = {
|
|
479
|
+
intent_id: receipt.references.intent_id,
|
|
480
|
+
...(receipt.references.ledger_seq ? { ledger_seq: receipt.references.ledger_seq } : {}),
|
|
481
|
+
settlement_receipt_id: receipt.references.settlement_receipt_id ?? null,
|
|
482
|
+
};
|
|
483
|
+
payload.external_attestations =
|
|
484
|
+
receipt.external_attestations.length > 0 ? receipt.external_attestations : null;
|
|
485
|
+
return new TextEncoder().encode(JSON.stringify(payload));
|
|
486
|
+
}
|
|
487
|
+
/** Returns canonical signing bytes for a normalized receipt body. */
|
|
488
|
+
export function canonicalAgentReceiptBytes(receipt) {
|
|
489
|
+
return marshalCanonicalAgentReceipt(normalizeReceipt(receipt));
|
|
490
|
+
}
|
|
491
|
+
/**
|
|
492
|
+
* Returns sha256(canonical receipt bytes) as lowercase hex, ignoring any existing
|
|
493
|
+
* `message_digest_sha256_hex` on the input. Used to compose unsigned receipt drafts
|
|
494
|
+
* (Agent Receipt Standard Phase 1) and to compute the digest signers must sign over.
|
|
495
|
+
*/
|
|
496
|
+
export function agentReceiptMessageDigestSha256Hex(receipt) {
|
|
497
|
+
return sha256Hex(canonicalAgentReceiptBytes(receipt));
|
|
498
|
+
}
|
|
499
|
+
/** Validates structure, receipt_id derivation, digest, and detached Ed25519 signature. */
|
|
500
|
+
export async function verifyAgentReceiptV1(receipt) {
|
|
501
|
+
ensureEd25519Sha512Sync();
|
|
502
|
+
const normalized = normalizeReceipt(receipt);
|
|
503
|
+
const canonical = marshalCanonicalAgentReceipt(normalized);
|
|
504
|
+
const digest = createHash("sha256").update(canonical).digest();
|
|
505
|
+
const digestHex = sha256Hex(canonical);
|
|
506
|
+
if (normalized.signing_algorithm !== AGENT_RECEIPT_SIGNING_ALGORITHM_ED25519) {
|
|
507
|
+
throw new Error(`agent receipt: signing_algorithm must be ${AGENT_RECEIPT_SIGNING_ALGORITHM_ED25519}`);
|
|
508
|
+
}
|
|
509
|
+
requireHex64(normalized.message_digest_sha256_hex, "message_digest_sha256_hex");
|
|
510
|
+
if (normalized.message_digest_sha256_hex !== digestHex) {
|
|
511
|
+
throw new Error("agent receipt: message digest mismatch");
|
|
512
|
+
}
|
|
513
|
+
const publicKey = hexToBytes(normalized.signing_public_key_ed25519_hex);
|
|
514
|
+
const signature = hexToBytes(normalized.ed25519_signature_hex);
|
|
515
|
+
if (publicKey.length !== 32 || signature.length !== 64) {
|
|
516
|
+
throw new Error("agent receipt: invalid signing material");
|
|
517
|
+
}
|
|
518
|
+
const valid = await verify(signature, digest, publicKey);
|
|
519
|
+
if (!valid) {
|
|
520
|
+
throw new Error("agent receipt: ed25519 signature verification failed");
|
|
521
|
+
}
|
|
522
|
+
await verifyOperatorAttestation(normalized, digest);
|
|
523
|
+
return normalized;
|
|
524
|
+
}
|
|
525
|
+
async function verifyOperatorAttestation(receipt, gatewayDigest) {
|
|
526
|
+
const attestation = receipt.operator_attestation;
|
|
527
|
+
if (!attestation) {
|
|
528
|
+
return;
|
|
529
|
+
}
|
|
530
|
+
const operatorDid = attestation.operator_did?.trim();
|
|
531
|
+
if (!operatorDid) {
|
|
532
|
+
throw new Error("agent receipt: operator_attestation.operator_did is required");
|
|
533
|
+
}
|
|
534
|
+
requireHex64(attestation.message_digest_sha256_hex, "operator_attestation.message_digest_sha256_hex");
|
|
535
|
+
if (attestation.message_digest_sha256_hex !== receipt.message_digest_sha256_hex) {
|
|
536
|
+
throw new Error("agent receipt: operator_attestation message_digest_sha256_hex must match gateway digest");
|
|
537
|
+
}
|
|
538
|
+
const publicKey = hexToBytes(attestation.signing_public_key_ed25519_hex);
|
|
539
|
+
const signature = hexToBytes(attestation.ed25519_signature_hex);
|
|
540
|
+
if (publicKey.length !== 32 || signature.length !== 64) {
|
|
541
|
+
throw new Error("agent receipt: invalid operator attestation signing material");
|
|
542
|
+
}
|
|
543
|
+
const valid = await verify(signature, gatewayDigest, publicKey);
|
|
544
|
+
if (!valid) {
|
|
545
|
+
throw new Error("agent receipt: operator attestation ed25519 signature verification failed");
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
/** Attach an optional operator counter-signature over the Gateway message digest. */
|
|
549
|
+
export async function attachOperatorAttestationV1(receipt, operatorPrivateKeyHex, operatorDid) {
|
|
550
|
+
ensureEd25519Sha512Sync();
|
|
551
|
+
const verified = await verifyAgentReceiptV1(receipt);
|
|
552
|
+
const digest = hexToBytes(verified.message_digest_sha256_hex);
|
|
553
|
+
const privateKey = hexToBytes(operatorPrivateKeyHex);
|
|
554
|
+
if (privateKey.length !== 64 && privateKey.length !== 32) {
|
|
555
|
+
throw new Error("agent receipt: operator private key must be 32- or 64-byte ed25519 material");
|
|
556
|
+
}
|
|
557
|
+
const { sign } = await import("@noble/ed25519");
|
|
558
|
+
const signature = await sign(digest, privateKey.slice(0, 32));
|
|
559
|
+
const { getPublicKey } = await import("@noble/ed25519");
|
|
560
|
+
const publicKey = await getPublicKey(privateKey.slice(0, 32));
|
|
561
|
+
return {
|
|
562
|
+
...verified,
|
|
563
|
+
operator_attestation: {
|
|
564
|
+
operator_did: operatorDid.trim(),
|
|
565
|
+
signing_public_key_ed25519_hex: Buffer.from(publicKey).toString("hex"),
|
|
566
|
+
message_digest_sha256_hex: verified.message_digest_sha256_hex,
|
|
567
|
+
ed25519_signature_hex: Buffer.from(signature).toString("hex"),
|
|
568
|
+
},
|
|
569
|
+
};
|
|
570
|
+
}
|
|
571
|
+
function hexToBytes(value) {
|
|
572
|
+
if (value.length % 2 !== 0) {
|
|
573
|
+
return new Uint8Array();
|
|
574
|
+
}
|
|
575
|
+
const out = new Uint8Array(value.length / 2);
|
|
576
|
+
for (let index = 0; index < out.length; index += 1) {
|
|
577
|
+
out[index] = Number.parseInt(value.slice(index * 2, index * 2 + 2), 16);
|
|
578
|
+
}
|
|
579
|
+
return out;
|
|
580
|
+
}
|
|
@@ -24,7 +24,10 @@ export declare const AGENT_RECOGNITION_PROOF_SCHEMA_VERSION = 1;
|
|
|
24
24
|
export declare const AGENT_RECOGNITION_PROOF_KIND_V1 = "paybond.agent_recognition_proof_v1";
|
|
25
25
|
export declare const AGENT_RECOGNITION_SIGNATURE_ALGORITHM_ED25519 = "ed25519-sha256-json-v1";
|
|
26
26
|
export declare const AGENT_RECOGNITION_GATEWAY_VERIFIER_ID = "paybond-gateway";
|
|
27
|
+
export declare const AGENT_RECOGNITION_PURPOSE_CREATE = "harbor.intent.create";
|
|
28
|
+
export declare const AGENT_RECOGNITION_PURPOSE_FUND = "harbor.intent.fund";
|
|
27
29
|
export declare const AGENT_RECOGNITION_PURPOSE_EVIDENCE_SUBMIT = "harbor.intent.evidence.submit";
|
|
30
|
+
export declare const AGENT_RECOGNITION_PURPOSE_SETTLEMENT_CONFIRM = "harbor.intent.settlement.confirm";
|
|
28
31
|
export declare const AGENT_RECOGNITION_MAX_FRESHNESS_MS: number;
|
|
29
32
|
export type SignAgentRecognitionProofV1Params = {
|
|
30
33
|
keyId: string;
|
|
@@ -61,6 +64,20 @@ type CanonicalRecognitionProof = {
|
|
|
61
64
|
export declare function newAgentRecognitionRequestEnvelope(method: string, path: string, body: Uint8Array | Record<string, unknown>): CanonicalRecognitionProof["requestEnvelope"];
|
|
62
65
|
/** Validate, canonicalize, and sign a replay-safe `AgentRecognitionProofV1`. */
|
|
63
66
|
export declare function signAgentRecognitionProofV1(signingSeed: Uint8Array, params: SignAgentRecognitionProofV1Params): SignedAgentRecognitionProofV1;
|
|
67
|
+
/** Build a recognition proof for Gateway `POST /harbor/intents`. */
|
|
68
|
+
export declare function signHarborCreateRecognitionProof(input: {
|
|
69
|
+
tenantId: string;
|
|
70
|
+
intentBody: Record<string, unknown>;
|
|
71
|
+
keyId: string;
|
|
72
|
+
signingSeed: Uint8Array;
|
|
73
|
+
}): SignedAgentRecognitionProofV1;
|
|
74
|
+
/** Build a recognition proof for Gateway `POST /harbor/intents/{intentId}/fund`. */
|
|
75
|
+
export declare function signHarborFundRecognitionProof(input: {
|
|
76
|
+
tenantId: string;
|
|
77
|
+
intentId: string;
|
|
78
|
+
keyId: string;
|
|
79
|
+
signingSeed: Uint8Array;
|
|
80
|
+
}): SignedAgentRecognitionProofV1;
|
|
64
81
|
/** Build a recognition proof for Gateway `POST /harbor/intents/{intentId}/evidence`. */
|
|
65
82
|
export declare function signHarborEvidenceSubmitRecognitionProof(input: {
|
|
66
83
|
tenantId: string;
|
|
@@ -69,4 +86,12 @@ export declare function signHarborEvidenceSubmitRecognitionProof(input: {
|
|
|
69
86
|
keyId: string;
|
|
70
87
|
signingSeed: Uint8Array;
|
|
71
88
|
}): SignedAgentRecognitionProofV1;
|
|
89
|
+
/** Build a recognition proof for Gateway `POST /harbor/intents/{intentId}/settlement/confirm`. */
|
|
90
|
+
export declare function signHarborSettlementConfirmRecognitionProof(input: {
|
|
91
|
+
tenantId: string;
|
|
92
|
+
intentId: string;
|
|
93
|
+
body?: Record<string, unknown>;
|
|
94
|
+
keyId: string;
|
|
95
|
+
signingSeed: Uint8Array;
|
|
96
|
+
}): SignedAgentRecognitionProofV1;
|
|
72
97
|
export {};
|
|
@@ -5,7 +5,10 @@ export const AGENT_RECOGNITION_PROOF_SCHEMA_VERSION = 1;
|
|
|
5
5
|
export const AGENT_RECOGNITION_PROOF_KIND_V1 = "paybond.agent_recognition_proof_v1";
|
|
6
6
|
export const AGENT_RECOGNITION_SIGNATURE_ALGORITHM_ED25519 = "ed25519-sha256-json-v1";
|
|
7
7
|
export const AGENT_RECOGNITION_GATEWAY_VERIFIER_ID = "paybond-gateway";
|
|
8
|
+
export const AGENT_RECOGNITION_PURPOSE_CREATE = "harbor.intent.create";
|
|
9
|
+
export const AGENT_RECOGNITION_PURPOSE_FUND = "harbor.intent.fund";
|
|
8
10
|
export const AGENT_RECOGNITION_PURPOSE_EVIDENCE_SUBMIT = "harbor.intent.evidence.submit";
|
|
11
|
+
export const AGENT_RECOGNITION_PURPOSE_SETTLEMENT_CONFIRM = "harbor.intent.settlement.confirm";
|
|
9
12
|
export const AGENT_RECOGNITION_MAX_FRESHNESS_MS = 10 * 60 * 1000;
|
|
10
13
|
const SCOPE_TOKEN_RE = /^[a-z0-9][a-z0-9._:/-]{0,127}$/;
|
|
11
14
|
const HEX64_RE = /^[0-9a-f]{64}$/;
|
|
@@ -152,6 +155,28 @@ export function signAgentRecognitionProofV1(signingSeed, params) {
|
|
|
152
155
|
ed25519_signature_hex: bytesToHex(signature),
|
|
153
156
|
};
|
|
154
157
|
}
|
|
158
|
+
/** Build a recognition proof for Gateway `POST /harbor/intents`. */
|
|
159
|
+
export function signHarborCreateRecognitionProof(input) {
|
|
160
|
+
return signAgentRecognitionProofV1(input.signingSeed, {
|
|
161
|
+
keyId: input.keyId,
|
|
162
|
+
purpose: AGENT_RECOGNITION_PURPOSE_CREATE,
|
|
163
|
+
tenantId: input.tenantId,
|
|
164
|
+
method: "POST",
|
|
165
|
+
path: "/harbor/intents",
|
|
166
|
+
body: input.intentBody,
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
/** Build a recognition proof for Gateway `POST /harbor/intents/{intentId}/fund`. */
|
|
170
|
+
export function signHarborFundRecognitionProof(input) {
|
|
171
|
+
return signAgentRecognitionProofV1(input.signingSeed, {
|
|
172
|
+
keyId: input.keyId,
|
|
173
|
+
purpose: AGENT_RECOGNITION_PURPOSE_FUND,
|
|
174
|
+
tenantId: input.tenantId,
|
|
175
|
+
method: "POST",
|
|
176
|
+
path: `/harbor/intents/${input.intentId}/fund`,
|
|
177
|
+
body: {},
|
|
178
|
+
});
|
|
179
|
+
}
|
|
155
180
|
/** Build a recognition proof for Gateway `POST /harbor/intents/{intentId}/evidence`. */
|
|
156
181
|
export function signHarborEvidenceSubmitRecognitionProof(input) {
|
|
157
182
|
return signAgentRecognitionProofV1(input.signingSeed, {
|
|
@@ -163,3 +188,14 @@ export function signHarborEvidenceSubmitRecognitionProof(input) {
|
|
|
163
188
|
body: input.evidenceBody,
|
|
164
189
|
});
|
|
165
190
|
}
|
|
191
|
+
/** Build a recognition proof for Gateway `POST /harbor/intents/{intentId}/settlement/confirm`. */
|
|
192
|
+
export function signHarborSettlementConfirmRecognitionProof(input) {
|
|
193
|
+
return signAgentRecognitionProofV1(input.signingSeed, {
|
|
194
|
+
keyId: input.keyId,
|
|
195
|
+
purpose: AGENT_RECOGNITION_PURPOSE_SETTLEMENT_CONFIRM,
|
|
196
|
+
tenantId: input.tenantId,
|
|
197
|
+
method: "POST",
|
|
198
|
+
path: `/harbor/intents/${input.intentId}/settlement/confirm`,
|
|
199
|
+
body: input.body ?? {},
|
|
200
|
+
});
|
|
201
|
+
}
|