@haven_ai/signer 0.7.0-alpha.0 → 0.8.0-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/dist/index.cjs CHANGED
@@ -350,7 +350,14 @@ function sameAddress(a, b) {
350
350
  return a.toLowerCase() === b.toLowerCase();
351
351
  }
352
352
  var SIGNER_HOSTED_HANDOFF_SHAPES = {
353
- haven_get_payment_status: { payment_id: zod.z.string().min(1) }
353
+ haven_get_payment_status: { payment_id: zod.z.string().min(1) },
354
+ // #3506: `haven_sign` hands a signed budget row to the hosted `haven_submit`
355
+ // (`signTaskBudget` / `signSubBudget` in tools.ts emit exactly these
356
+ // `next_arguments`). One hosted tool, two argument shapes, so each shape is
357
+ // its own entry keyed `<hosted tool>#<variant>`; the parity test reads the
358
+ // part before `#` as the hosted tool it checks the entry against.
359
+ "haven_submit#task_budget": { task_budget_id: zod.z.string().min(1), signature: zod.z.string().regex(/^0x[0-9a-fA-F]+$/) },
360
+ "haven_submit#sub_budget": { sub_budget_id: zod.z.string().min(1), signature: zod.z.string().regex(/^0x[0-9a-fA-F]+$/) }
354
361
  };
355
362
  function target(shape) {
356
363
  const schema = zod.z.object(shape).strict();
@@ -381,7 +388,8 @@ function nextStepWireFields(step) {
381
388
  }
382
389
 
383
390
  // src/sign-context.ts
384
- var DIRECT_RELAY_FALLBACK = "call haven_sign with payload_hash and typed_data_b64 from the haven_send / haven_pay result, passed through unchanged";
391
+ 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";
392
+ 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";
385
393
  var HavenSignContextError = class extends edge.HavenSigningError {
386
394
  /**
387
395
  * #3001 / #3010 review: the recovery path, when signing OTHER bytes is
@@ -459,7 +467,7 @@ var HavenSignContextError = class extends edge.HavenSigningError {
459
467
  step = signerRefusalStep({
460
468
  nextAction: edge.AgentPaymentNextAction.StopAndTellUser,
461
469
  nextTool: null,
462
- nextToolOmittedReason: DIRECT_RELAY_FALLBACK
470
+ nextToolOmittedReason: DIRECT_404_FALLBACK
463
471
  });
464
472
  } else if (flow === "direct" && refusal?.errorCode === "expired") {
465
473
  this.next_action = edge.AgentPaymentNextAction.PaymentWindowExpired;
@@ -614,7 +622,7 @@ async function fetchDirectSignContext(identity, paymentId, fetchImpl = fetch, ti
614
622
  } catch (err) {
615
623
  const timedOut = err instanceof Error && (err.name === "TimeoutError" || err.name === "AbortError");
616
624
  throw new HavenSignContextError(
617
- timedOut ? `Haven did not answer the direct-payment signing-context fetch for ${paymentId} within ${timeoutMs} ms. Retry, or pass typed_data_b64 from the payment result instead.` : `Could not reach Haven to fetch the direct-payment signing context for ${paymentId}: ${err instanceof Error ? err.message : String(err)}. Retry, or pass typed_data_b64 from the payment result instead.`,
625
+ 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.`,
618
626
  timedOut ? "SIGN_CONTEXT_TIMEOUT" : "SIGN_CONTEXT_UNREACHABLE",
619
627
  void 0,
620
628
  paymentId,
@@ -627,7 +635,7 @@ async function fetchDirectSignContext(identity, paymentId, fetchImpl = fetch, ti
627
635
  } catch (err) {
628
636
  if (err instanceof Error && (err.name === "TimeoutError" || err.name === "AbortError")) {
629
637
  throw new HavenSignContextError(
630
- `Haven did not finish sending the direct-payment signing context for ${paymentId} within ${timeoutMs} ms. Retry, or pass typed_data_b64 from the payment result instead.`,
638
+ `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.`,
631
639
  "SIGN_CONTEXT_TIMEOUT",
632
640
  void 0,
633
641
  paymentId,
@@ -639,7 +647,7 @@ async function fetchDirectSignContext(identity, paymentId, fetchImpl = fetch, ti
639
647
  if (!response.ok) {
640
648
  const detail = typeof body.error === "string" ? body.error : `HTTP ${response.status}`;
641
649
  throw new HavenSignContextError(
642
- `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 haven_send / haven_pay result, unchanged, instead." : body.error_code === "expired" ? " The payment window has expired; call haven_send / haven_pay again with the same idempotency_key." : ""),
650
+ `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." : ""),
643
651
  "SIGN_CONTEXT_REFUSED",
644
652
  refusalOf(response.status, body),
645
653
  paymentId,
@@ -650,7 +658,7 @@ async function fetchDirectSignContext(identity, paymentId, fetchImpl = fetch, ti
650
658
  const version = body.direct_sign_context_version;
651
659
  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)) {
652
660
  throw new HavenSignContextError(
653
- 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. Pass typed_data_b64 from the payment result instead.",
661
+ 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.",
654
662
  "SIGN_CONTEXT_MALFORMED",
655
663
  void 0,
656
664
  paymentId,
@@ -897,7 +905,8 @@ function signerCompatibility() {
897
905
  x402_expected_context_versions: [...SUPPORTED_X402_EXPECTED_VERSIONS],
898
906
  sweep_binding_versions: [...SUPPORTED_SWEEP_BINDING_VERSIONS],
899
907
  direct_sign_context_versions: [...SUPPORTED_DIRECT_SIGN_CONTEXT_VERSIONS],
900
- task_sign_context_versions: [...SUPPORTED_TASK_SIGN_CONTEXT_VERSIONS]
908
+ task_sign_context_versions: [...SUPPORTED_TASK_SIGN_CONTEXT_VERSIONS],
909
+ sub_budget_sign_context_versions: [...SUPPORTED_SUB_BUDGET_SIGN_CONTEXT_VERSIONS]
901
910
  };
902
911
  }
903
912
  function signerCapabilityAdvertisement() {
@@ -917,6 +926,7 @@ function signerInstructions() {
917
926
  `- sweep authorization binding versions supported: ${compatibility.sweep_binding_versions.join(", ")}`,
918
927
  `- 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`,
919
928
  `- 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`,
929
+ `- 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)`,
920
930
  "",
921
931
  "Haven quote and prepare results report the expected-context version they will emit",
922
932
  "(signer_compatibility.x402_expected_context_version). If that version is not in the list",
@@ -1156,7 +1166,7 @@ var HavenBareHashRefusedError = class extends edge.HavenSigningError {
1156
1166
 
1157
1167
  // src/tools.ts
1158
1168
  var SIGNER_NAME = "@haven_ai/signer";
1159
- var SIGNER_VERSION = "0.7.0-alpha.0";
1169
+ var SIGNER_VERSION = "0.8.0-alpha.0";
1160
1170
  var UNSUPPORTED_ARGUMENT_MARKER = "HavenSignerUnsupportedArgument:";
1161
1171
  var USEROP_BINDING_MISMATCH = "USEROP_BINDING_MISMATCH";
1162
1172
  var HavenUserOpBindingRefusedError = class extends edge.HavenSigningError {
@@ -1170,7 +1180,7 @@ var HavenUserOpBindingRefusedError = class extends edge.HavenSigningError {
1170
1180
  this.step = signerRefusalStep({
1171
1181
  nextAction: edge.AgentPaymentNextAction.StopAndTellUser,
1172
1182
  nextTool: null,
1173
- nextToolOmittedReason: "call haven_sign again with payment_id alone (preferred), or with typed_data copied unchanged from the payment result"
1183
+ 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)"
1174
1184
  });
1175
1185
  }
1176
1186
  };
@@ -1976,7 +1986,7 @@ function normalizeError(err) {
1976
1986
 
1977
1987
  // src/consent.ts
1978
1988
  var toolSummaries = {
1979
- haven_sign: "signs a Haven-prepared payment, task-budget open, or task-budget close (a UserOp from your own account whose only call redeems a delegation made to it, directly or through a self-delegated task-budget child, or an x402 funding intent against a Haven-signed context)",
1989
+ 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)",
1980
1990
  haven_x402_sign_header: "builds and signs the EIP-3009 merchant payment header for an x402 payment",
1981
1991
  haven_sign_x402: "the two above in one call: funding payload + merchant header",
1982
1992
  haven_sign_sweep_delegate: "signs a Haven-prepared gasless sweep of stranded funds back to your own account"