@haven_ai/signer 0.7.0-alpha.0 → 0.8.1-alpha.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 +26 -12
- package/dist/cli.cjs +21 -11
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +21 -11
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +21 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +16 -1
- package/dist/index.d.ts +16 -1
- package/dist/index.js +21 -11
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.cts
CHANGED
|
@@ -258,6 +258,13 @@ interface SignerCompatibility {
|
|
|
258
258
|
* discipline as `direct_sign_context_versions`.
|
|
259
259
|
*/
|
|
260
260
|
task_sign_context_versions: number[];
|
|
261
|
+
/**
|
|
262
|
+
* #3506: `sub_budget_sign_context_version`s this signer will fetch and
|
|
263
|
+
* verify from `GET /sub-budgets/:id/sign-context` — derived from
|
|
264
|
+
* `SUPPORTED_SUB_BUDGET_SIGN_CONTEXT_VERSIONS`, never a second literal.
|
|
265
|
+
* Additive: 0.7.0 already signed sub-budgets but did not say so here.
|
|
266
|
+
*/
|
|
267
|
+
sub_budget_sign_context_versions: number[];
|
|
261
268
|
}
|
|
262
269
|
/** The supported sets this signer enforces, as a plain serialisable object. */
|
|
263
270
|
declare function signerCompatibility(): SignerCompatibility;
|
|
@@ -486,6 +493,14 @@ declare const SIGNER_HOSTED_HANDOFF_SHAPES: {
|
|
|
486
493
|
readonly haven_get_payment_status: {
|
|
487
494
|
readonly payment_id: z.ZodString;
|
|
488
495
|
};
|
|
496
|
+
readonly 'haven_submit#task_budget': {
|
|
497
|
+
readonly task_budget_id: z.ZodString;
|
|
498
|
+
readonly signature: z.ZodString;
|
|
499
|
+
};
|
|
500
|
+
readonly 'haven_submit#sub_budget': {
|
|
501
|
+
readonly sub_budget_id: z.ZodString;
|
|
502
|
+
readonly signature: z.ZodString;
|
|
503
|
+
};
|
|
489
504
|
};
|
|
490
505
|
|
|
491
506
|
/**
|
|
@@ -495,7 +510,7 @@ declare const SIGNER_HOSTED_HANDOFF_SHAPES: {
|
|
|
495
510
|
* `server.ts` re-exports them, so the package's public API is unchanged.
|
|
496
511
|
*/
|
|
497
512
|
declare const SIGNER_NAME = "@haven_ai/signer";
|
|
498
|
-
declare const SIGNER_VERSION = "0.
|
|
513
|
+
declare const SIGNER_VERSION = "0.8.1-alpha.0";
|
|
499
514
|
/**
|
|
500
515
|
* #3419: the marker the tool layer prefixes the undeclared-argument refusal
|
|
501
516
|
* with. The strict re-parse lives in THIS module (`parseStrictFor`, below) —
|
package/dist/index.d.ts
CHANGED
|
@@ -258,6 +258,13 @@ interface SignerCompatibility {
|
|
|
258
258
|
* discipline as `direct_sign_context_versions`.
|
|
259
259
|
*/
|
|
260
260
|
task_sign_context_versions: number[];
|
|
261
|
+
/**
|
|
262
|
+
* #3506: `sub_budget_sign_context_version`s this signer will fetch and
|
|
263
|
+
* verify from `GET /sub-budgets/:id/sign-context` — derived from
|
|
264
|
+
* `SUPPORTED_SUB_BUDGET_SIGN_CONTEXT_VERSIONS`, never a second literal.
|
|
265
|
+
* Additive: 0.7.0 already signed sub-budgets but did not say so here.
|
|
266
|
+
*/
|
|
267
|
+
sub_budget_sign_context_versions: number[];
|
|
261
268
|
}
|
|
262
269
|
/** The supported sets this signer enforces, as a plain serialisable object. */
|
|
263
270
|
declare function signerCompatibility(): SignerCompatibility;
|
|
@@ -486,6 +493,14 @@ declare const SIGNER_HOSTED_HANDOFF_SHAPES: {
|
|
|
486
493
|
readonly haven_get_payment_status: {
|
|
487
494
|
readonly payment_id: z.ZodString;
|
|
488
495
|
};
|
|
496
|
+
readonly 'haven_submit#task_budget': {
|
|
497
|
+
readonly task_budget_id: z.ZodString;
|
|
498
|
+
readonly signature: z.ZodString;
|
|
499
|
+
};
|
|
500
|
+
readonly 'haven_submit#sub_budget': {
|
|
501
|
+
readonly sub_budget_id: z.ZodString;
|
|
502
|
+
readonly signature: z.ZodString;
|
|
503
|
+
};
|
|
489
504
|
};
|
|
490
505
|
|
|
491
506
|
/**
|
|
@@ -495,7 +510,7 @@ declare const SIGNER_HOSTED_HANDOFF_SHAPES: {
|
|
|
495
510
|
* `server.ts` re-exports them, so the package's public API is unchanged.
|
|
496
511
|
*/
|
|
497
512
|
declare const SIGNER_NAME = "@haven_ai/signer";
|
|
498
|
-
declare const SIGNER_VERSION = "0.
|
|
513
|
+
declare const SIGNER_VERSION = "0.8.1-alpha.0";
|
|
499
514
|
/**
|
|
500
515
|
* #3419: the marker the tool layer prefixes the undeclared-argument refusal
|
|
501
516
|
* with. The strict re-parse lives in THIS module (`parseStrictFor`, below) —
|
package/dist/index.js
CHANGED
|
@@ -349,7 +349,14 @@ function sameAddress(a, b) {
|
|
|
349
349
|
return a.toLowerCase() === b.toLowerCase();
|
|
350
350
|
}
|
|
351
351
|
var SIGNER_HOSTED_HANDOFF_SHAPES = {
|
|
352
|
-
haven_get_payment_status: { payment_id: z.string().min(1) }
|
|
352
|
+
haven_get_payment_status: { payment_id: z.string().min(1) },
|
|
353
|
+
// #3506: `haven_sign` hands a signed budget row to the hosted `haven_submit`
|
|
354
|
+
// (`signTaskBudget` / `signSubBudget` in tools.ts emit exactly these
|
|
355
|
+
// `next_arguments`). One hosted tool, two argument shapes, so each shape is
|
|
356
|
+
// its own entry keyed `<hosted tool>#<variant>`; the parity test reads the
|
|
357
|
+
// part before `#` as the hosted tool it checks the entry against.
|
|
358
|
+
"haven_submit#task_budget": { task_budget_id: z.string().min(1), signature: z.string().regex(/^0x[0-9a-fA-F]+$/) },
|
|
359
|
+
"haven_submit#sub_budget": { sub_budget_id: z.string().min(1), signature: z.string().regex(/^0x[0-9a-fA-F]+$/) }
|
|
353
360
|
};
|
|
354
361
|
function target(shape) {
|
|
355
362
|
const schema = z.object(shape).strict();
|
|
@@ -380,7 +387,8 @@ function nextStepWireFields(step) {
|
|
|
380
387
|
}
|
|
381
388
|
|
|
382
389
|
// src/sign-context.ts
|
|
383
|
-
var DIRECT_RELAY_FALLBACK = "call haven_sign with payload_hash and typed_data_b64 from
|
|
390
|
+
var DIRECT_RELAY_FALLBACK = "re-run whichever of haven_send / haven_pay you called, with the SAME idempotency_key (echoed on its result) plus include_signing_payload: true, then call haven_sign with payload_hash and typed_data_b64 from THAT re-run's result, passed through unchanged";
|
|
391
|
+
var DIRECT_404_FALLBACK = "either the payment_id is not from this agent\u2019s own POST /payments call, or this Haven backend predates #3271 (which also predates #3495, so its result already carries payload_hash and typed_data_b64 unconditionally): pass those fields from the ORIGINAL haven_send / haven_pay result, unchanged, if it already carries them \u2014 or, on a newer server, re-run haven_send / haven_pay with the SAME idempotency_key plus include_signing_payload: true and pass them from THAT result instead";
|
|
384
392
|
var HavenSignContextError = class extends HavenSigningError {
|
|
385
393
|
/**
|
|
386
394
|
* #3001 / #3010 review: the recovery path, when signing OTHER bytes is
|
|
@@ -458,7 +466,7 @@ var HavenSignContextError = class extends HavenSigningError {
|
|
|
458
466
|
step = signerRefusalStep({
|
|
459
467
|
nextAction: AgentPaymentNextAction.StopAndTellUser,
|
|
460
468
|
nextTool: null,
|
|
461
|
-
nextToolOmittedReason:
|
|
469
|
+
nextToolOmittedReason: DIRECT_404_FALLBACK
|
|
462
470
|
});
|
|
463
471
|
} else if (flow === "direct" && refusal?.errorCode === "expired") {
|
|
464
472
|
this.next_action = AgentPaymentNextAction.PaymentWindowExpired;
|
|
@@ -613,7 +621,7 @@ async function fetchDirectSignContext(identity, paymentId, fetchImpl = fetch, ti
|
|
|
613
621
|
} catch (err) {
|
|
614
622
|
const timedOut = err instanceof Error && (err.name === "TimeoutError" || err.name === "AbortError");
|
|
615
623
|
throw new HavenSignContextError(
|
|
616
|
-
timedOut ? `Haven did not answer the direct-payment signing-context fetch for ${paymentId} within ${timeoutMs} ms. Retry, or pass typed_data_b64 from
|
|
624
|
+
timedOut ? `Haven did not answer the direct-payment signing-context fetch for ${paymentId} within ${timeoutMs} ms. Retry, or re-run haven_send / haven_pay with the same idempotency_key plus include_signing_payload: true and pass typed_data_b64 from that result instead.` : `Could not reach Haven to fetch the direct-payment signing context for ${paymentId}: ${err instanceof Error ? err.message : String(err)}. Retry, or re-run haven_send / haven_pay with the same idempotency_key plus include_signing_payload: true and pass typed_data_b64 from that result instead.`,
|
|
617
625
|
timedOut ? "SIGN_CONTEXT_TIMEOUT" : "SIGN_CONTEXT_UNREACHABLE",
|
|
618
626
|
void 0,
|
|
619
627
|
paymentId,
|
|
@@ -626,7 +634,7 @@ async function fetchDirectSignContext(identity, paymentId, fetchImpl = fetch, ti
|
|
|
626
634
|
} catch (err) {
|
|
627
635
|
if (err instanceof Error && (err.name === "TimeoutError" || err.name === "AbortError")) {
|
|
628
636
|
throw new HavenSignContextError(
|
|
629
|
-
`Haven did not finish sending the direct-payment signing context for ${paymentId} within ${timeoutMs} ms. Retry, or pass typed_data_b64 from
|
|
637
|
+
`Haven did not finish sending the direct-payment signing context for ${paymentId} within ${timeoutMs} ms. Retry, or re-run haven_send / haven_pay with the same idempotency_key plus include_signing_payload: true and pass typed_data_b64 from that result instead.`,
|
|
630
638
|
"SIGN_CONTEXT_TIMEOUT",
|
|
631
639
|
void 0,
|
|
632
640
|
paymentId,
|
|
@@ -638,7 +646,7 @@ async function fetchDirectSignContext(identity, paymentId, fetchImpl = fetch, ti
|
|
|
638
646
|
if (!response.ok) {
|
|
639
647
|
const detail = typeof body.error === "string" ? body.error : `HTTP ${response.status}`;
|
|
640
648
|
throw new HavenSignContextError(
|
|
641
|
-
`Haven refused the direct-payment signing-context fetch for ${paymentId}: ${detail}` + (response.status === 404 ? " \u2014 either the payment_id is not from this agent\u2019s own POST /payments call, or this Haven backend predates #3271. Pass payload_hash and typed_data_b64 from the
|
|
649
|
+
`Haven refused the direct-payment signing-context fetch for ${paymentId}: ${detail}` + (response.status === 404 ? " \u2014 either the payment_id is not from this agent\u2019s own POST /payments call, or this Haven backend predates #3271 (which also predates #3495, so its haven_send / haven_pay result already carries payload_hash and typed_data_b64 unconditionally). Pass payload_hash and typed_data_b64, unchanged, from the original result \u2014 or, on a newer server, from a same-key re-run with include_signing_payload: true." : body.error_code === "expired" ? " The payment window has expired; call haven_send / haven_pay again with the same idempotency_key." : ""),
|
|
642
650
|
"SIGN_CONTEXT_REFUSED",
|
|
643
651
|
refusalOf(response.status, body),
|
|
644
652
|
paymentId,
|
|
@@ -649,7 +657,7 @@ async function fetchDirectSignContext(identity, paymentId, fetchImpl = fetch, ti
|
|
|
649
657
|
const version = body.direct_sign_context_version;
|
|
650
658
|
if (!signData || typeof signData.hash !== "string" || !signData.typed_data || typeof signData.typed_data !== "object" || signData.signature_scheme !== "eip712_userop" || typeof version !== "number" || !SUPPORTED_DIRECT_SIGN_CONTEXT_VERSIONS.includes(version)) {
|
|
651
659
|
throw new HavenSignContextError(
|
|
652
|
-
typeof version === "number" && !SUPPORTED_DIRECT_SIGN_CONTEXT_VERSIONS.includes(version) ? `The Haven direct-payment sign-context response is version ${version}, which this signer does not support (supported: ${SUPPORTED_DIRECT_SIGN_CONTEXT_VERSIONS.join(", ")}). Update @haven_ai/signer.` : "The Haven direct-payment sign-context response is missing sign_data.typed_data, or its signature_scheme is not 'eip712_userop' \u2014 the backend may predate #3271.
|
|
660
|
+
typeof version === "number" && !SUPPORTED_DIRECT_SIGN_CONTEXT_VERSIONS.includes(version) ? `The Haven direct-payment sign-context response is version ${version}, which this signer does not support (supported: ${SUPPORTED_DIRECT_SIGN_CONTEXT_VERSIONS.join(", ")}). Update @haven_ai/signer.` : "The Haven direct-payment sign-context response is missing sign_data.typed_data, or its signature_scheme is not 'eip712_userop' \u2014 the backend may predate #3271. Re-run haven_send / haven_pay with the same idempotency_key plus include_signing_payload: true and pass typed_data_b64 from that result instead.",
|
|
653
661
|
"SIGN_CONTEXT_MALFORMED",
|
|
654
662
|
void 0,
|
|
655
663
|
paymentId,
|
|
@@ -896,7 +904,8 @@ function signerCompatibility() {
|
|
|
896
904
|
x402_expected_context_versions: [...SUPPORTED_X402_EXPECTED_VERSIONS],
|
|
897
905
|
sweep_binding_versions: [...SUPPORTED_SWEEP_BINDING_VERSIONS],
|
|
898
906
|
direct_sign_context_versions: [...SUPPORTED_DIRECT_SIGN_CONTEXT_VERSIONS],
|
|
899
|
-
task_sign_context_versions: [...SUPPORTED_TASK_SIGN_CONTEXT_VERSIONS]
|
|
907
|
+
task_sign_context_versions: [...SUPPORTED_TASK_SIGN_CONTEXT_VERSIONS],
|
|
908
|
+
sub_budget_sign_context_versions: [...SUPPORTED_SUB_BUDGET_SIGN_CONTEXT_VERSIONS]
|
|
900
909
|
};
|
|
901
910
|
}
|
|
902
911
|
function signerCapabilityAdvertisement() {
|
|
@@ -916,6 +925,7 @@ function signerInstructions() {
|
|
|
916
925
|
`- sweep authorization binding versions supported: ${compatibility.sweep_binding_versions.join(", ")}`,
|
|
917
926
|
`- direct-payment (haven_send / haven_pay) sign-context versions supported: ${compatibility.direct_sign_context_versions.join(", ")} \u2014 pass payment_id alone to haven_sign; this signer fetches the exact bytes`,
|
|
918
927
|
`- task-budget sign-context versions supported: ${compatibility.task_sign_context_versions.join(", ")} \u2014 pass task_budget_id alone to haven_sign; this signer fetches the exact bytes`,
|
|
928
|
+
`- sub-budget sign-context versions supported: ${compatibility.sub_budget_sign_context_versions.join(", ")} \u2014 pass sub_budget_id alone to haven_sign; this signer fetches the exact bytes (a sub-budget your owner issued narrows your own budget for another agent of your account)`,
|
|
919
929
|
"",
|
|
920
930
|
"Haven quote and prepare results report the expected-context version they will emit",
|
|
921
931
|
"(signer_compatibility.x402_expected_context_version). If that version is not in the list",
|
|
@@ -1155,7 +1165,7 @@ var HavenBareHashRefusedError = class extends HavenSigningError {
|
|
|
1155
1165
|
|
|
1156
1166
|
// src/tools.ts
|
|
1157
1167
|
var SIGNER_NAME = "@haven_ai/signer";
|
|
1158
|
-
var SIGNER_VERSION = "0.
|
|
1168
|
+
var SIGNER_VERSION = "0.8.1-alpha.0";
|
|
1159
1169
|
var UNSUPPORTED_ARGUMENT_MARKER = "HavenSignerUnsupportedArgument:";
|
|
1160
1170
|
var USEROP_BINDING_MISMATCH = "USEROP_BINDING_MISMATCH";
|
|
1161
1171
|
var HavenUserOpBindingRefusedError = class extends HavenSigningError {
|
|
@@ -1169,7 +1179,7 @@ var HavenUserOpBindingRefusedError = class extends HavenSigningError {
|
|
|
1169
1179
|
this.step = signerRefusalStep({
|
|
1170
1180
|
nextAction: AgentPaymentNextAction.StopAndTellUser,
|
|
1171
1181
|
nextTool: null,
|
|
1172
|
-
nextToolOmittedReason: "call haven_sign again with payment_id alone (preferred), or with typed_data copied unchanged from the payment result"
|
|
1182
|
+
nextToolOmittedReason: "call haven_sign again with payment_id alone (preferred), or with typed_data copied unchanged from the payment result (or, on a compact direct-payment result, from a same-key re-run with include_signing_payload: true)"
|
|
1173
1183
|
});
|
|
1174
1184
|
}
|
|
1175
1185
|
};
|
|
@@ -1975,7 +1985,7 @@ function normalizeError(err) {
|
|
|
1975
1985
|
|
|
1976
1986
|
// src/consent.ts
|
|
1977
1987
|
var toolSummaries = {
|
|
1978
|
-
haven_sign: "signs a Haven-prepared payment, task-budget
|
|
1988
|
+
haven_sign: "signs a Haven-prepared payment, task-budget or sub-budget open or close (a UserOp from your own account redeeming a delegation made to it, directly or via a task-budget child; a sub-budget child narrowing your budget for another agent of yours; or an x402 funding intent against a Haven-signed context)",
|
|
1979
1989
|
haven_x402_sign_header: "builds and signs the EIP-3009 merchant payment header for an x402 payment",
|
|
1980
1990
|
haven_sign_x402: "the two above in one call: funding payload + merchant header",
|
|
1981
1991
|
haven_sign_sweep_delegate: "signs a Haven-prepared gasless sweep of stranded funds back to your own account"
|