@haven_ai/signer 0.4.0-alpha.0 → 0.6.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/README.md +198 -35
- package/dist/cli.cjs +1516 -1055
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +1681 -1220
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +963 -520
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +216 -128
- package/dist/index.d.ts +216 -128
- package/dist/index.js +886 -451
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,21 +1,23 @@
|
|
|
1
|
-
import { X402ExpectedAuth, X402PaymentRequired, X402PaymentOption, SweepAuthorization, SweepExpectedAuth } from '@haven_ai/sdk';
|
|
1
|
+
import { X402ExpectedAuth, X402PaymentRequired, X402PaymentOption, SweepAuthorization, SweepExpectedAuth, HavenClientUpdate } from '@haven_ai/sdk/edge';
|
|
2
|
+
export { deriveDelegateAccountAddress } from '@haven_ai/sdk/edge';
|
|
2
3
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
3
|
-
import { z } from 'zod/v3';
|
|
4
|
-
import {
|
|
4
|
+
import { z as z$1 } from 'zod/v3';
|
|
5
|
+
import { Stats } from 'node:fs';
|
|
6
|
+
import { z } from 'zod';
|
|
5
7
|
|
|
6
8
|
/**
|
|
7
9
|
* The edge signer core.
|
|
8
10
|
*
|
|
9
|
-
* Holds the delegate key in this process and exposes the
|
|
10
|
-
*
|
|
11
|
+
* Holds the delegate key in this process and exposes the signing operations a
|
|
12
|
+
* hosted-MCP flow needs — five, none of them a raw-hash primitive (#3169): each
|
|
13
|
+
* takes a payload something can check — a Haven binding verified here, typed
|
|
14
|
+
* data the account validates on-chain, or a sweep authorization. It performs no network I/O and never
|
|
11
15
|
* returns the key — only signatures and the standard x402 header. See
|
|
12
16
|
* docs/architecture/07-edge-signer.md.
|
|
13
17
|
*/
|
|
14
18
|
interface EdgeSigner {
|
|
15
19
|
/** Address derived from the delegate key. */
|
|
16
20
|
readonly delegateAddress: string;
|
|
17
|
-
/** Sign an AllowanceModule funding/transfer hash (raw ECDSA, 65 bytes). */
|
|
18
|
-
signPaymentHash(hash: string): string;
|
|
19
21
|
/**
|
|
20
22
|
* Sign a DIRECT delegation-rail payment's EIP-712 typed data (#1254) — the
|
|
21
23
|
* non-x402 counterpart of `signX402FundingTypedData`. The Hybrid account
|
|
@@ -26,24 +28,27 @@ interface EdgeSigner {
|
|
|
26
28
|
* visible to this process's audit log.
|
|
27
29
|
*/
|
|
28
30
|
signDelegationTypedData(typedData: Record<string, unknown>): Promise<string>;
|
|
29
|
-
/** Sign an x402 funding hash and remember the funded merchant-header context. */
|
|
30
|
-
signX402FundingHash(hash: string, expected: X402ExpectedPayment): X402FundingSignatureResult;
|
|
31
31
|
/**
|
|
32
32
|
* Sign a delegation-rail x402 funding intent's EIP-712 typed data (#1138) and
|
|
33
|
-
* remember the funded merchant-header context
|
|
33
|
+
* remember the funded merchant-header context — every x402 funding intent
|
|
34
|
+
* now takes this path (#3272 criterion 8: the bare-hash v1 rail is
|
|
35
|
+
* retired).
|
|
34
36
|
*
|
|
35
|
-
* The account validates this typed data, NOT
|
|
36
|
-
*
|
|
37
|
-
* `assertExpectedBinding`.
|
|
37
|
+
* The account validates this typed data, NOT a bare hash, so the expected
|
|
38
|
+
* context must be v2/v3 and commit to its digest — see
|
|
39
|
+
* `assertExpectedBinding`. `typedData` is `undefined` when the caller had
|
|
40
|
+
* none to supply; that is itself refused (a v1 context that needed no typed
|
|
41
|
+
* data is refused earlier, by the version check).
|
|
38
42
|
*/
|
|
39
|
-
signX402FundingTypedData(typedData: X402FundingTypedData, expected: X402ExpectedPayment): Promise<X402FundingSignatureResult>;
|
|
43
|
+
signX402FundingTypedData(typedData: X402FundingTypedData | undefined, expected: X402ExpectedPayment): Promise<X402FundingSignatureResult>;
|
|
40
44
|
/** Build + sign the EIP-3009 X-PAYMENT header for the merchant leg of x402. */
|
|
41
45
|
buildX402PaymentHeader(paymentRequired: X402PaymentRequired, x402Binding: string): Promise<X402HeaderResult>;
|
|
42
46
|
/**
|
|
43
47
|
* Sign a Haven-prepared EIP-3009 sweep authorization (gasless USDC recovery
|
|
44
|
-
* delegate →
|
|
45
|
-
*
|
|
46
|
-
*
|
|
48
|
+
* delegate → the agent's account (Haven wallet)). Verifies the authorization
|
|
49
|
+
* came from Haven and pays out to the agent's account (Haven wallet) — the
|
|
50
|
+
* account belongs to the agent, not the delegate — before signing; the
|
|
51
|
+
* relayer broadcasts it and pays gas. Never broadcasts — pure signing.
|
|
47
52
|
*/
|
|
48
53
|
signSweepAuthorization(input: SweepSignatureInput): Promise<SweepSignatureResult>;
|
|
49
54
|
}
|
|
@@ -52,7 +57,7 @@ interface SweepSignatureInput {
|
|
|
52
57
|
authorization: SweepAuthorization;
|
|
53
58
|
/** Haven's signature over the authorization context (binding). */
|
|
54
59
|
expectedAuth: SweepExpectedAuth;
|
|
55
|
-
/** Optional
|
|
60
|
+
/** Optional account (Haven wallet) address from the local credential, cross-checked against `to` when present. */
|
|
56
61
|
expectedSafe?: string;
|
|
57
62
|
}
|
|
58
63
|
interface SweepSignatureResult {
|
|
@@ -121,7 +126,7 @@ interface X402HeaderResult {
|
|
|
121
126
|
accepted: X402PaymentOption;
|
|
122
127
|
}
|
|
123
128
|
interface X402FundingSignatureResult {
|
|
124
|
-
/**
|
|
129
|
+
/** EIP-712 signature over the Haven-committed funding typed data. */
|
|
125
130
|
signature: string;
|
|
126
131
|
/** Opaque process-local binding for the later merchant header signing step. */
|
|
127
132
|
x402Binding: string;
|
|
@@ -149,11 +154,12 @@ declare function assertX402MatchesExpected(paymentRequired: X402PaymentRequired,
|
|
|
149
154
|
* version arrives *here* instead of dying at the schema boundary with a raw
|
|
150
155
|
* validation string.
|
|
151
156
|
*
|
|
152
|
-
* **Adding a version here is not sufficient to support it.** The
|
|
157
|
+
* **Adding a version here is not sufficient to support it.** The rules in
|
|
153
158
|
* `assertExpectedBinding` derive the expected version from the context's
|
|
154
|
-
* *contents* (`
|
|
155
|
-
*
|
|
156
|
-
*
|
|
159
|
+
* *contents* (`payerDelegate` present ⇒ 3, else 2 — `typedDataHash` is
|
|
160
|
+
* required unconditionally, #3272), not from `auth.version`, so a v4 that
|
|
161
|
+
* carries anything new needs that derivation extended in the same change.
|
|
162
|
+
* Widening this array alone would admit a v4 context to the v2/v3 rule set:
|
|
157
163
|
* the array announces what this signer can evaluate, it does not define it.
|
|
158
164
|
*/
|
|
159
165
|
declare const SUPPORTED_X402_EXPECTED_VERSIONS: readonly number[];
|
|
@@ -182,7 +188,7 @@ declare const SUPPORTED_SWEEP_BINDING_VERSIONS: readonly number[];
|
|
|
182
188
|
*
|
|
183
189
|
* #2347: that word was "authorised" until this change, and the reading was
|
|
184
190
|
* always the correct one — Haven does sign this message. It is now "declared",
|
|
185
|
-
* the word `settlement-child.ts` already uses for this exact binding ("proves
|
|
191
|
+
* the word the settlement-child verifier (`@haven_ai/sdk`'s `settlement-child.ts`) already uses for this exact binding ("proves
|
|
186
192
|
* Haven *declared* a payload … it says nothing about what the payload MEANS"),
|
|
187
193
|
* because on an agent-facing refusal inside a payment flow the broader word
|
|
188
194
|
* invites the #2334 misreading that Haven is what authorises the spend. It is
|
|
@@ -207,9 +213,10 @@ declare function assertSupportedBindingVersion(received: number, supported: read
|
|
|
207
213
|
*
|
|
208
214
|
* **The check is necessarily agent-mediated.** The signer and the hosted Haven
|
|
209
215
|
* MCP are two separate servers connected to the same client; neither can
|
|
210
|
-
* introspect the other. The signer's
|
|
211
|
-
* `GET /x402/:payment_id/sign-context`
|
|
212
|
-
*
|
|
216
|
+
* introspect the other. The signer's Haven reads (#1263's read-only
|
|
217
|
+
* `GET /x402/:payment_id/sign-context` and #3271's direct-payment
|
|
218
|
+
* `GET /payments/:payment_id/sign-context`, both in `sign-context.ts`) do not help
|
|
219
|
+
* here: each fetches one payment's signing bytes, not the hosted server's
|
|
213
220
|
* handshake, and it happens at signing time — after the quote this module
|
|
214
221
|
* exists to get ahead of. So only the agent sees both handshakes, and what
|
|
215
222
|
* ships here is the *information* plus the prompt to compare it — never a
|
|
@@ -237,6 +244,20 @@ interface SignerCompatibility {
|
|
|
237
244
|
x402_expected_context_versions: number[];
|
|
238
245
|
/** Sweep-binding versions this signer will verify (`SUPPORTED_SWEEP_BINDING_VERSIONS`). */
|
|
239
246
|
sweep_binding_versions: number[];
|
|
247
|
+
/**
|
|
248
|
+
* #3271: `direct_sign_context_version`s this signer will fetch and verify
|
|
249
|
+
* from `GET /payments/:id/sign-context` — derived from the SDK's
|
|
250
|
+
* `DIRECT_SIGN_CONTEXT_VERSION` via `SUPPORTED_DIRECT_SIGN_CONTEXT_VERSIONS`,
|
|
251
|
+
* never a second literal.
|
|
252
|
+
*/
|
|
253
|
+
direct_sign_context_versions: number[];
|
|
254
|
+
/**
|
|
255
|
+
* #3329: `task_sign_context_version`s this signer will fetch and verify
|
|
256
|
+
* from `GET /task-budgets/:id/sign-context` — derived from
|
|
257
|
+
* `SUPPORTED_TASK_SIGN_CONTEXT_VERSIONS`, never a second literal, same
|
|
258
|
+
* discipline as `direct_sign_context_versions`.
|
|
259
|
+
*/
|
|
260
|
+
task_sign_context_versions: number[];
|
|
240
261
|
}
|
|
241
262
|
/** The supported sets this signer enforces, as a plain serialisable object. */
|
|
242
263
|
declare function signerCompatibility(): SignerCompatibility;
|
|
@@ -270,9 +291,11 @@ declare function signerInstructions(): string;
|
|
|
270
291
|
*
|
|
271
292
|
* That is a claim about this credential, not about the process, and the
|
|
272
293
|
* difference matters: the sentence that used to stand here ("it does not call
|
|
273
|
-
* the Haven API") was retired by #1263. The MCP server layer does make
|
|
274
|
-
* authenticated call — a read-only
|
|
275
|
-
* `sign-context
|
|
294
|
+
* the Haven API") was retired by #1263. The MCP server layer does make at
|
|
295
|
+
* most two authenticated reads per signing call — a read-only
|
|
296
|
+
* `GET /x402/:payment_id/sign-context` and, for a direct payment via
|
|
297
|
+
* `haven_sign` since #3271, then `GET /payments/:payment_id/sign-context`, see
|
|
298
|
+
* `sign-context.ts` — and it reads the `api_url` / `api_key` for them from a
|
|
276
299
|
* SEPARATE `identity.json` in the same directory as the credential file
|
|
277
300
|
* resolved here. That is why `sourcePath` below is load-bearing rather than
|
|
278
301
|
* diagnostic, and why a key supplied through `HAVEN_DELEGATE_KEY` alone (no
|
|
@@ -353,6 +376,65 @@ declare function readAccountAddressEnv(env: NodeJS.ProcessEnv): string | undefin
|
|
|
353
376
|
*/
|
|
354
377
|
declare function warnIfCredentialFilePermissive(path: string, log?: (message: string) => void, platform?: NodeJS.Platform): Promise<void>;
|
|
355
378
|
|
|
379
|
+
/** Owner-only: the mode every file this package writes beside a credential gets. */
|
|
380
|
+
declare const OWNER_ONLY_MODE = 384;
|
|
381
|
+
type PermissionLog = (message: string) => void;
|
|
382
|
+
interface PermissiveFile {
|
|
383
|
+
/** The offending mode, e.g. `0644`. */
|
|
384
|
+
octal: string;
|
|
385
|
+
/** False for a symlink, directory or device at that path — never chmod those. */
|
|
386
|
+
regular: boolean;
|
|
387
|
+
}
|
|
388
|
+
/**
|
|
389
|
+
* Is this path readable, writable or executable by anyone but its owner?
|
|
390
|
+
* Returns null when the path cannot be stat'ed or is owner-only, and on
|
|
391
|
+
* Windows where POSIX mode bits do not map cleanly (the same carve-out
|
|
392
|
+
* `@haven_ai/mcp` makes). Pass `stats` to reuse a stat the caller took
|
|
393
|
+
* IMMEDIATELY before — with `stats` the path is not touched, so a cached
|
|
394
|
+
* `Stats` would be trusted over the disk. `follow` decides what a symlink at the path means: a file the signer
|
|
395
|
+
* only READS (the credential) is judged by its target, which is what the
|
|
396
|
+
* content protection is about and what the pre-#3172 `stat` did; a file the
|
|
397
|
+
* signer is about to CHMOD (the audit sidecar) is judged as the link, so a
|
|
398
|
+
* planted symlink is never chmod-ed through (#3172 review).
|
|
399
|
+
*/
|
|
400
|
+
declare function permissiveMode(path: string, platform?: NodeJS.Platform, stats?: Stats, follow?: 'follow' | 'nofollow'): Promise<PermissiveFile | null>;
|
|
401
|
+
/**
|
|
402
|
+
* Warn (best-effort, POSIX only) when a file this signer READS is readable
|
|
403
|
+
* beyond its owner. The signer does not own the credential, so it tells the
|
|
404
|
+
* operator what to run rather than changing a file it was handed. Follows a
|
|
405
|
+
* symlink, as the pre-#3172 `stat` did: a link to a 0600 credential is fine.
|
|
406
|
+
*/
|
|
407
|
+
declare function warnIfFilePermissive(kind: string, path: string, log?: PermissionLog, platform?: NodeJS.Platform): Promise<void>;
|
|
408
|
+
type TightenOutcome = 'owner-only' | 'tightened' | 'warned' | 'skipped';
|
|
409
|
+
/**
|
|
410
|
+
* Tighten a file this signer WRITES to owner-only when it finds it
|
|
411
|
+
* permissive (#3172): the audit sidecar was created with the default mode
|
|
412
|
+
* (0644 under the usual umask 022) by every release before this one, so an
|
|
413
|
+
* existing sidecar is fixed in place rather than warned about. Judged with
|
|
414
|
+
* `lstat`. Falls back to the warning when the path is not a regular file (a
|
|
415
|
+
* symlink would make chmod hit whatever it points at) or when chmod is
|
|
416
|
+
* refused (a file owned by another user). Outcomes: `tightened` / `warned`
|
|
417
|
+
* as above; `owner-only` when there is nothing to tighten (owner-only file,
|
|
418
|
+
* or no file at that path); `skipped` on Windows only.
|
|
419
|
+
*/
|
|
420
|
+
declare function tightenIfFilePermissive(kind: string, path: string, log?: PermissionLog, platform?: NodeJS.Platform, stats?: Stats): Promise<TightenOutcome>;
|
|
421
|
+
|
|
422
|
+
/**
|
|
423
|
+
* #3172: the sidecar is bounded. When it reaches this size the current file is
|
|
424
|
+
* renamed to `<path>.1` (replacing the previous `.1`) and a fresh file starts,
|
|
425
|
+
* so at most two generations — the live file and one predecessor — ever exist.
|
|
426
|
+
* 8 MiB is roughly 30 000 entries at the ~270-byte row size; nothing in the
|
|
427
|
+
* signer reads the file back, so the bound protects the disk and the reader's
|
|
428
|
+
* patience, never a signing decision.
|
|
429
|
+
*/
|
|
430
|
+
declare const AUDIT_ROTATE_BYTES: number;
|
|
431
|
+
interface AppendAuditOptions {
|
|
432
|
+
/** Where permission notices go; defaults to stderr. */
|
|
433
|
+
log?: PermissionLog;
|
|
434
|
+
/** Rotation threshold in bytes; exported default `AUDIT_ROTATE_BYTES`. */
|
|
435
|
+
rotateAtBytes?: number;
|
|
436
|
+
platform?: NodeJS.Platform;
|
|
437
|
+
}
|
|
356
438
|
interface SigningAuditEntry {
|
|
357
439
|
version: 1;
|
|
358
440
|
timestamp: string;
|
|
@@ -377,7 +459,7 @@ interface SigningAuditContext {
|
|
|
377
459
|
auditPath?: string;
|
|
378
460
|
}
|
|
379
461
|
declare function defaultSigningAuditPath(credentialsPath?: string): string;
|
|
380
|
-
declare function appendSigningAuditEntry(entry: SigningAuditEntry, path: string): Promise<void>;
|
|
462
|
+
declare function appendSigningAuditEntry(entry: SigningAuditEntry, path: string, options?: AppendAuditOptions): Promise<void>;
|
|
381
463
|
declare function createSigningAuditEntry(tool: SignerToolName, payloadHash: string, context: SigningAuditContext, now?: Date): SigningAuditEntry;
|
|
382
464
|
declare function hashPayloadForAudit(payload: unknown): string;
|
|
383
465
|
|
|
@@ -386,6 +468,26 @@ interface HavenIdentity {
|
|
|
386
468
|
apiKey: string;
|
|
387
469
|
}
|
|
388
470
|
|
|
471
|
+
/**
|
|
472
|
+
* #3103 (epic #3105, slice 4/5): the signer's typed next step.
|
|
473
|
+
*
|
|
474
|
+
* The signer decides a `next_action` on its refusals and, until this module,
|
|
475
|
+
* never said which tool to call. It cannot know the client's server names
|
|
476
|
+
* (#2550), so the handoff is expressed through the role fields the SDK
|
|
477
|
+
* builder renders — `next_tool_server_role: hosted`, `next_tool_name` — from
|
|
478
|
+
* a bare tool name. The signer must not import the hosted server (it is an
|
|
479
|
+
* npm package installed on user machines; the hosted server is a Docker
|
|
480
|
+
* deployment), so the hosted tools it hands off to are DECLARED here as the
|
|
481
|
+
* argument shape the signer actually emits, and `next-step-signer-parity`
|
|
482
|
+
* in the hosted server's own suite pins them to the hosted schemas at test
|
|
483
|
+
* time — the mirror of how the hosted server declares the signer's shapes.
|
|
484
|
+
*/
|
|
485
|
+
declare const SIGNER_HOSTED_HANDOFF_SHAPES: {
|
|
486
|
+
readonly haven_get_payment_status: {
|
|
487
|
+
readonly payment_id: z.ZodString;
|
|
488
|
+
};
|
|
489
|
+
};
|
|
490
|
+
|
|
389
491
|
/**
|
|
390
492
|
* Local signer tool set. These run on the agent's machine, next to the key,
|
|
391
493
|
* and pair with the hosted server's construct/relay tools (#183). They sign;
|
|
@@ -394,16 +496,16 @@ interface HavenIdentity {
|
|
|
394
496
|
type SignerToolName = 'haven_sign' | 'haven_x402_sign_header' | 'haven_sign_x402' | 'haven_sign_sweep_delegate';
|
|
395
497
|
declare const toolSchemas: {
|
|
396
498
|
readonly haven_sign_sweep_delegate: {
|
|
397
|
-
readonly authorization: z.ZodObject<{
|
|
398
|
-
from: z.ZodString;
|
|
399
|
-
to: z.ZodString;
|
|
400
|
-
value: z.ZodString;
|
|
401
|
-
validAfter: z.ZodString;
|
|
402
|
-
validBefore: z.ZodString;
|
|
403
|
-
nonce: z.ZodString;
|
|
404
|
-
token: z.ZodString;
|
|
405
|
-
chainId: z.ZodNumber;
|
|
406
|
-
}, "strip", z.ZodTypeAny, {
|
|
499
|
+
readonly authorization: z$1.ZodObject<{
|
|
500
|
+
from: z$1.ZodString;
|
|
501
|
+
to: z$1.ZodString;
|
|
502
|
+
value: z$1.ZodString;
|
|
503
|
+
validAfter: z$1.ZodString;
|
|
504
|
+
validBefore: z$1.ZodString;
|
|
505
|
+
nonce: z$1.ZodString;
|
|
506
|
+
token: z$1.ZodString;
|
|
507
|
+
chainId: z$1.ZodNumber;
|
|
508
|
+
}, "strip", z$1.ZodTypeAny, {
|
|
407
509
|
chainId: number;
|
|
408
510
|
to: string;
|
|
409
511
|
from: string;
|
|
@@ -422,12 +524,12 @@ declare const toolSchemas: {
|
|
|
422
524
|
validAfter: string;
|
|
423
525
|
validBefore: string;
|
|
424
526
|
}>;
|
|
425
|
-
readonly expected_auth: z.ZodObject<{
|
|
426
|
-
version: z.ZodNumber;
|
|
427
|
-
message: z.ZodString;
|
|
428
|
-
signature: z.ZodString;
|
|
429
|
-
signer: z.ZodString;
|
|
430
|
-
}, "strip", z.ZodTypeAny, {
|
|
527
|
+
readonly expected_auth: z$1.ZodObject<{
|
|
528
|
+
version: z$1.ZodNumber;
|
|
529
|
+
message: z$1.ZodString;
|
|
530
|
+
signature: z$1.ZodString;
|
|
531
|
+
signer: z$1.ZodString;
|
|
532
|
+
}, "strip", z$1.ZodTypeAny, {
|
|
431
533
|
message: string;
|
|
432
534
|
version: number;
|
|
433
535
|
signature: string;
|
|
@@ -440,26 +542,26 @@ declare const toolSchemas: {
|
|
|
440
542
|
}>;
|
|
441
543
|
};
|
|
442
544
|
readonly haven_sign: {
|
|
443
|
-
readonly payment_id: z.ZodOptional<z.ZodString>;
|
|
444
|
-
readonly payload_hash: z.ZodOptional<z.ZodString>;
|
|
445
|
-
readonly x402_expected: z.ZodOptional<z.ZodObject<{
|
|
446
|
-
payment_id: z.ZodString;
|
|
447
|
-
payload_hash: z.ZodString;
|
|
448
|
-
resource_url: z.ZodString;
|
|
449
|
-
merchant_to: z.ZodString;
|
|
450
|
-
amount: z.ZodString;
|
|
451
|
-
asset: z.ZodString;
|
|
452
|
-
network: z.ZodString;
|
|
453
|
-
expires_at: z.ZodString;
|
|
454
|
-
typed_data_hash: z.ZodOptional<z.ZodString>;
|
|
455
|
-
payer_delegate: z.ZodOptional<z.ZodString>;
|
|
456
|
-
payer_agent_id: z.ZodOptional<z.ZodString>;
|
|
457
|
-
auth: z.ZodObject<{
|
|
458
|
-
version: z.ZodNumber;
|
|
459
|
-
message: z.ZodString;
|
|
460
|
-
signature: z.ZodString;
|
|
461
|
-
signer: z.ZodString;
|
|
462
|
-
}, "strip", z.ZodTypeAny, {
|
|
545
|
+
readonly payment_id: z$1.ZodOptional<z$1.ZodString>;
|
|
546
|
+
readonly payload_hash: z$1.ZodOptional<z$1.ZodString>;
|
|
547
|
+
readonly x402_expected: z$1.ZodOptional<z$1.ZodObject<{
|
|
548
|
+
payment_id: z$1.ZodString;
|
|
549
|
+
payload_hash: z$1.ZodString;
|
|
550
|
+
resource_url: z$1.ZodString;
|
|
551
|
+
merchant_to: z$1.ZodString;
|
|
552
|
+
amount: z$1.ZodString;
|
|
553
|
+
asset: z$1.ZodString;
|
|
554
|
+
network: z$1.ZodString;
|
|
555
|
+
expires_at: z$1.ZodString;
|
|
556
|
+
typed_data_hash: z$1.ZodOptional<z$1.ZodString>;
|
|
557
|
+
payer_delegate: z$1.ZodOptional<z$1.ZodString>;
|
|
558
|
+
payer_agent_id: z$1.ZodOptional<z$1.ZodString>;
|
|
559
|
+
auth: z$1.ZodObject<{
|
|
560
|
+
version: z$1.ZodNumber;
|
|
561
|
+
message: z$1.ZodString;
|
|
562
|
+
signature: z$1.ZodString;
|
|
563
|
+
signer: z$1.ZodString;
|
|
564
|
+
}, "strip", z$1.ZodTypeAny, {
|
|
463
565
|
message: string;
|
|
464
566
|
version: number;
|
|
465
567
|
signature: string;
|
|
@@ -470,15 +572,15 @@ declare const toolSchemas: {
|
|
|
470
572
|
signature: string;
|
|
471
573
|
signer: string;
|
|
472
574
|
}>;
|
|
473
|
-
}, "strip", z.ZodTypeAny, {
|
|
474
|
-
network: string;
|
|
575
|
+
}, "strip", z$1.ZodTypeAny, {
|
|
475
576
|
payment_id: string;
|
|
577
|
+
expires_at: string;
|
|
578
|
+
network: string;
|
|
476
579
|
payload_hash: string;
|
|
477
580
|
resource_url: string;
|
|
478
581
|
merchant_to: string;
|
|
479
582
|
amount: string;
|
|
480
583
|
asset: string;
|
|
481
|
-
expires_at: string;
|
|
482
584
|
auth: {
|
|
483
585
|
message: string;
|
|
484
586
|
version: number;
|
|
@@ -489,14 +591,14 @@ declare const toolSchemas: {
|
|
|
489
591
|
payer_delegate?: string | undefined;
|
|
490
592
|
payer_agent_id?: string | undefined;
|
|
491
593
|
}, {
|
|
492
|
-
network: string;
|
|
493
594
|
payment_id: string;
|
|
595
|
+
expires_at: string;
|
|
596
|
+
network: string;
|
|
494
597
|
payload_hash: string;
|
|
495
598
|
resource_url: string;
|
|
496
599
|
merchant_to: string;
|
|
497
600
|
amount: string;
|
|
498
601
|
asset: string;
|
|
499
|
-
expires_at: string;
|
|
500
602
|
auth: {
|
|
501
603
|
message: string;
|
|
502
604
|
version: number;
|
|
@@ -507,34 +609,35 @@ declare const toolSchemas: {
|
|
|
507
609
|
payer_delegate?: string | undefined;
|
|
508
610
|
payer_agent_id?: string | undefined;
|
|
509
611
|
}>>;
|
|
510
|
-
readonly typed_data: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
511
|
-
readonly typed_data_b64: z.ZodOptional<z.ZodString>;
|
|
612
|
+
readonly typed_data: z$1.ZodOptional<z$1.ZodRecord<z$1.ZodString, z$1.ZodUnknown>>;
|
|
613
|
+
readonly typed_data_b64: z$1.ZodOptional<z$1.ZodString>;
|
|
614
|
+
readonly task_budget_id: z$1.ZodOptional<z$1.ZodString>;
|
|
512
615
|
};
|
|
513
616
|
readonly haven_x402_sign_header: {
|
|
514
|
-
readonly payment_required: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
515
|
-
readonly x402_binding: z.ZodString;
|
|
617
|
+
readonly payment_required: z$1.ZodRecord<z$1.ZodString, z$1.ZodUnknown>;
|
|
618
|
+
readonly x402_binding: z$1.ZodString;
|
|
516
619
|
};
|
|
517
620
|
readonly haven_sign_x402: {
|
|
518
|
-
readonly payment_id: z.ZodOptional<z.ZodString>;
|
|
519
|
-
readonly payload_hash: z.ZodOptional<z.ZodString>;
|
|
520
|
-
readonly x402_expected: z.ZodOptional<z.ZodObject<{
|
|
521
|
-
payment_id: z.ZodString;
|
|
522
|
-
payload_hash: z.ZodString;
|
|
523
|
-
resource_url: z.ZodString;
|
|
524
|
-
merchant_to: z.ZodString;
|
|
525
|
-
amount: z.ZodString;
|
|
526
|
-
asset: z.ZodString;
|
|
527
|
-
network: z.ZodString;
|
|
528
|
-
expires_at: z.ZodString;
|
|
529
|
-
typed_data_hash: z.ZodOptional<z.ZodString>;
|
|
530
|
-
payer_delegate: z.ZodOptional<z.ZodString>;
|
|
531
|
-
payer_agent_id: z.ZodOptional<z.ZodString>;
|
|
532
|
-
auth: z.ZodObject<{
|
|
533
|
-
version: z.ZodNumber;
|
|
534
|
-
message: z.ZodString;
|
|
535
|
-
signature: z.ZodString;
|
|
536
|
-
signer: z.ZodString;
|
|
537
|
-
}, "strip", z.ZodTypeAny, {
|
|
621
|
+
readonly payment_id: z$1.ZodOptional<z$1.ZodString>;
|
|
622
|
+
readonly payload_hash: z$1.ZodOptional<z$1.ZodString>;
|
|
623
|
+
readonly x402_expected: z$1.ZodOptional<z$1.ZodObject<{
|
|
624
|
+
payment_id: z$1.ZodString;
|
|
625
|
+
payload_hash: z$1.ZodString;
|
|
626
|
+
resource_url: z$1.ZodString;
|
|
627
|
+
merchant_to: z$1.ZodString;
|
|
628
|
+
amount: z$1.ZodString;
|
|
629
|
+
asset: z$1.ZodString;
|
|
630
|
+
network: z$1.ZodString;
|
|
631
|
+
expires_at: z$1.ZodString;
|
|
632
|
+
typed_data_hash: z$1.ZodOptional<z$1.ZodString>;
|
|
633
|
+
payer_delegate: z$1.ZodOptional<z$1.ZodString>;
|
|
634
|
+
payer_agent_id: z$1.ZodOptional<z$1.ZodString>;
|
|
635
|
+
auth: z$1.ZodObject<{
|
|
636
|
+
version: z$1.ZodNumber;
|
|
637
|
+
message: z$1.ZodString;
|
|
638
|
+
signature: z$1.ZodString;
|
|
639
|
+
signer: z$1.ZodString;
|
|
640
|
+
}, "strip", z$1.ZodTypeAny, {
|
|
538
641
|
message: string;
|
|
539
642
|
version: number;
|
|
540
643
|
signature: string;
|
|
@@ -545,15 +648,15 @@ declare const toolSchemas: {
|
|
|
545
648
|
signature: string;
|
|
546
649
|
signer: string;
|
|
547
650
|
}>;
|
|
548
|
-
}, "strip", z.ZodTypeAny, {
|
|
549
|
-
network: string;
|
|
651
|
+
}, "strip", z$1.ZodTypeAny, {
|
|
550
652
|
payment_id: string;
|
|
653
|
+
expires_at: string;
|
|
654
|
+
network: string;
|
|
551
655
|
payload_hash: string;
|
|
552
656
|
resource_url: string;
|
|
553
657
|
merchant_to: string;
|
|
554
658
|
amount: string;
|
|
555
659
|
asset: string;
|
|
556
|
-
expires_at: string;
|
|
557
660
|
auth: {
|
|
558
661
|
message: string;
|
|
559
662
|
version: number;
|
|
@@ -564,14 +667,14 @@ declare const toolSchemas: {
|
|
|
564
667
|
payer_delegate?: string | undefined;
|
|
565
668
|
payer_agent_id?: string | undefined;
|
|
566
669
|
}, {
|
|
567
|
-
network: string;
|
|
568
670
|
payment_id: string;
|
|
671
|
+
expires_at: string;
|
|
672
|
+
network: string;
|
|
569
673
|
payload_hash: string;
|
|
570
674
|
resource_url: string;
|
|
571
675
|
merchant_to: string;
|
|
572
676
|
amount: string;
|
|
573
677
|
asset: string;
|
|
574
|
-
expires_at: string;
|
|
575
678
|
auth: {
|
|
576
679
|
message: string;
|
|
577
680
|
version: number;
|
|
@@ -582,9 +685,9 @@ declare const toolSchemas: {
|
|
|
582
685
|
payer_delegate?: string | undefined;
|
|
583
686
|
payer_agent_id?: string | undefined;
|
|
584
687
|
}>>;
|
|
585
|
-
readonly payment_required: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
586
|
-
readonly typed_data: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
587
|
-
readonly typed_data_b64: z.ZodOptional<z.ZodString>;
|
|
688
|
+
readonly payment_required: z$1.ZodOptional<z$1.ZodRecord<z$1.ZodString, z$1.ZodUnknown>>;
|
|
689
|
+
readonly typed_data: z$1.ZodOptional<z$1.ZodRecord<z$1.ZodString, z$1.ZodUnknown>>;
|
|
690
|
+
readonly typed_data_b64: z$1.ZodOptional<z$1.ZodString>;
|
|
588
691
|
};
|
|
589
692
|
};
|
|
590
693
|
declare const toolDescriptions: Record<SignerToolName, string>;
|
|
@@ -626,11 +729,14 @@ interface ToolFailure {
|
|
|
626
729
|
fallback?: string;
|
|
627
730
|
/**
|
|
628
731
|
* #3001: present on `SIGN_CONTEXT_REFUSED` — the HTTP status the backend
|
|
629
|
-
* answered the
|
|
732
|
+
* answered the sign-context fetch with (404, 410, …) — the x402 fetch, or
|
|
733
|
+
* the direct `/payments/:id/sign-context` fetch since #3271.
|
|
630
734
|
*/
|
|
631
735
|
http_status?: number;
|
|
632
|
-
/** #3001: the backend's own `error_code` on `SIGN_CONTEXT_REFUSED` (`expired`, `already_executed`, `not_signable`, `sign_context_unavailable`). */
|
|
736
|
+
/** #3001: the backend's own `error_code` on `SIGN_CONTEXT_REFUSED` (`expired`, `already_executed`, `not_signable`, `sign_context_unavailable`, and since #3303 `client_outdated`). */
|
|
633
737
|
backend_error_code?: string;
|
|
738
|
+
/** #3303: on `client_outdated`, the backend's update hint — `upgrade_command` is what updates this signer. */
|
|
739
|
+
client_update?: HavenClientUpdate;
|
|
634
740
|
}
|
|
635
741
|
type ToolPayload<T = unknown> = ToolSuccess<T> | ToolFailure;
|
|
636
742
|
interface ToolHandlerOptions {
|
|
@@ -645,6 +751,8 @@ interface ToolHandlerOptions {
|
|
|
645
751
|
signContext?: {
|
|
646
752
|
loadIdentity: () => Promise<HavenIdentity | null>;
|
|
647
753
|
fetchImpl?: typeof fetch;
|
|
754
|
+
/** #3303: `@haven_ai/signer/<version>`, sent as `X-Haven-Client` on every sign-context read. */
|
|
755
|
+
clientIdentity?: string;
|
|
648
756
|
};
|
|
649
757
|
}
|
|
650
758
|
declare function createToolHandlers(signer: EdgeSigner, options?: ToolHandlerOptions): Record<SignerToolName, (input: unknown) => Promise<ToolPayload>>;
|
|
@@ -676,7 +784,7 @@ declare function renderSignerConsentBlock(input: SignerConsentInput, hash: strin
|
|
|
676
784
|
declare function ensureSignerConsent(input: SignerConsentInput, options?: SignerConsentOptions): Promise<SignerConsentDecision>;
|
|
677
785
|
|
|
678
786
|
declare const SIGNER_NAME = "@haven_ai/signer";
|
|
679
|
-
declare const SIGNER_VERSION = "0.
|
|
787
|
+
declare const SIGNER_VERSION = "0.6.0-alpha.0";
|
|
680
788
|
interface SignerOptions {
|
|
681
789
|
/** Path to a Haven credential JSON file (delegate_key is read from it). */
|
|
682
790
|
credentialsPath?: string;
|
|
@@ -741,24 +849,4 @@ declare function assertSupportedNodeVersion(nodeVersion?: string): void;
|
|
|
741
849
|
declare function runSignerStdioServer(options?: SignerOptions): Promise<void>;
|
|
742
850
|
declare function runSignerConsentGate(signer: EdgeSigner, credentials: SignerCredentials | undefined, options: SignerOptions): Promise<SignerConsentDecision>;
|
|
743
851
|
|
|
744
|
-
|
|
745
|
-
* #3103 (epic #3105, slice 4/5): the signer's typed next step.
|
|
746
|
-
*
|
|
747
|
-
* The signer decides a `next_action` on its refusals and, until this module,
|
|
748
|
-
* never said which tool to call. It cannot know the client's server names
|
|
749
|
-
* (#2550), so the handoff is expressed through the role fields the SDK
|
|
750
|
-
* builder renders — `next_tool_server_role: hosted`, `next_tool_name` — from
|
|
751
|
-
* a bare tool name. The signer must not import the hosted server (it is an
|
|
752
|
-
* npm package installed on user machines; the hosted server is a Docker
|
|
753
|
-
* deployment), so the hosted tools it hands off to are DECLARED here as the
|
|
754
|
-
* argument shape the signer actually emits, and `next-step-signer-parity`
|
|
755
|
-
* in the hosted server's own suite pins them to the hosted schemas at test
|
|
756
|
-
* time — the mirror of how the hosted server declares the signer's shapes.
|
|
757
|
-
*/
|
|
758
|
-
declare const SIGNER_HOSTED_HANDOFF_SHAPES: {
|
|
759
|
-
readonly haven_get_payment_status: {
|
|
760
|
-
readonly payment_id: z$1.ZodString;
|
|
761
|
-
};
|
|
762
|
-
};
|
|
763
|
-
|
|
764
|
-
export { type EdgeSigner, type ResolvedSignerRuntime, SIGNER_ACK_ENV, SIGNER_CAPABILITY_KEY, SIGNER_HOSTED_HANDOFF_SHAPES, SIGNER_NAME, SIGNER_VERSION, SUPPORTED_SWEEP_BINDING_VERSIONS, SUPPORTED_X402_EXPECTED_VERSIONS, type SignerCompatibility, type SignerConsentDecision, type SignerConsentInput, type SignerConsentOptions, type SignerCredentials, type SignerOptions, type SignerToolName, type SigningAuditContext, type SigningAuditEntry, type ToolFailure, type ToolPayload, type ToolSuccess, type X402ExpectedPayment, type X402FundingSignatureResult, type X402HeaderResult, appendSigningAuditEntry, assertSupportedBindingVersion, assertSupportedNodeVersion, assertX402MatchesExpected, buildSignerMcpServer, computeSignerConsentHash, createEdgeSigner, createSigningAuditEntry, createToolHandlers, defaultSigningAuditPath, ensureSignerConsent, hashPayloadForAudit, loadSignerCredentials, readAccountAddressEnv, readAccountAddressField, renderSignerConsentBlock, resolveEdgeSigner, resolveSignerRuntime, runSignerConsentGate, runSignerStdioServer, signerCapabilityAdvertisement, signerCompatibility, signerInstructions, toolDescriptions, toolSchemas, warnIfCredentialFilePermissive };
|
|
852
|
+
export { AUDIT_ROTATE_BYTES, type AppendAuditOptions, type EdgeSigner, OWNER_ONLY_MODE, type PermissionLog, type PermissiveFile, type ResolvedSignerRuntime, SIGNER_ACK_ENV, SIGNER_CAPABILITY_KEY, SIGNER_HOSTED_HANDOFF_SHAPES, SIGNER_NAME, SIGNER_VERSION, SUPPORTED_SWEEP_BINDING_VERSIONS, SUPPORTED_X402_EXPECTED_VERSIONS, type SignerCompatibility, type SignerConsentDecision, type SignerConsentInput, type SignerConsentOptions, type SignerCredentials, type SignerOptions, type SignerToolName, type SigningAuditContext, type SigningAuditEntry, type TightenOutcome, type ToolFailure, type ToolPayload, type ToolSuccess, type X402ExpectedPayment, type X402FundingSignatureResult, type X402HeaderResult, appendSigningAuditEntry, assertSupportedBindingVersion, assertSupportedNodeVersion, assertX402MatchesExpected, buildSignerMcpServer, computeSignerConsentHash, createEdgeSigner, createSigningAuditEntry, createToolHandlers, defaultSigningAuditPath, ensureSignerConsent, hashPayloadForAudit, loadSignerCredentials, permissiveMode, readAccountAddressEnv, readAccountAddressField, renderSignerConsentBlock, resolveEdgeSigner, resolveSignerRuntime, runSignerConsentGate, runSignerStdioServer, signerCapabilityAdvertisement, signerCompatibility, signerInstructions, tightenIfFilePermissive, toolDescriptions, toolSchemas, warnIfCredentialFilePermissive, warnIfFilePermissive };
|