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