@haven_ai/signer 0.2.1-alpha.0 → 0.3.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.d.cts CHANGED
@@ -282,18 +282,8 @@ declare function signerInstructions(): string;
282
282
  interface SignerCredentials {
283
283
  delegateKey: string;
284
284
  agentId?: string;
285
- /**
286
- * The Haven account (smart account) the agent spends from — #2908, the
287
- * account-vocabulary name. Same value as `safeAddress`.
288
- */
285
+ /** The Haven account (smart account) the agent spends from. */
289
286
  accountAddress?: string;
290
- /**
291
- * @deprecated #2908 — same value as {@link SignerCredentials.accountAddress}.
292
- * Removed from this shape in the release after the one carrying #2908
293
- * (#2914). The credential-FILE keys it was read from are a different
294
- * matter — see `readAccountAddressField`.
295
- */
296
- safeAddress?: string;
297
287
  chainId?: number;
298
288
  network?: string;
299
289
  x402BindingSigner?: string;
@@ -305,11 +295,11 @@ interface RawCredentialFile {
305
295
  delegateKey?: unknown;
306
296
  agent_id?: unknown;
307
297
  agentId?: unknown;
308
- /** #2908: what `@haven_ai/connect` writes from this release on. */
298
+ /** What `@haven_ai/connect` writes. */
309
299
  account_address?: unknown;
310
- /** Pre-#2908 spelling — read PERMANENTLY, see `readAccountAddressField`. */
300
+ /** Pre-#2908 spelling — read PERMANENTLY (a credential file never rewrites itself), see `readAccountAddressField`. */
311
301
  safe_address?: unknown;
312
- /** Pre-#2908 spelling — read PERMANENTLY, see `readAccountAddressField`. */
302
+ /** Pre-#2908 spelling — read PERMANENTLY (a credential file never rewrites itself), see `readAccountAddressField`. */
313
303
  safeAddress?: unknown;
314
304
  chain_id?: unknown;
315
305
  chainId?: unknown;
@@ -346,11 +336,11 @@ declare function loadSignerCredentials(path?: string | undefined): Promise<Signe
346
336
  */
347
337
  declare function readAccountAddressField(raw: Pick<RawCredentialFile, 'account_address' | 'safe_address' | 'safeAddress'>): string | undefined;
348
338
  /**
349
- * The account address off the process environment, new name first:
350
- * `HAVEN_ACCOUNT_ADDRESS` (the survivor, decided on #2906) then the two
351
- * names the dashboard handoff emitted before #2908 — `HAVEN_WALLET_ADDRESS`
352
- * and `HAVEN_SAFE_ADDRESS`. Unlike the file fallbacks these two ARE
353
- * window-scoped: they are dropped at #2914, one release after this one.
339
+ * The account address off the process environment: `HAVEN_ACCOUNT_ADDRESS`
340
+ * (the survivor, decided on #2906). The two names the dashboard handoff
341
+ * emitted before #2908 — `HAVEN_WALLET_ADDRESS` and `HAVEN_SAFE_ADDRESS` —
342
+ * were window-scoped (unlike the credential-FILE fallbacks) and are retired
343
+ * as of #2914.
354
344
  */
355
345
  declare function readAccountAddressEnv(env: NodeJS.ProcessEnv): string | undefined;
356
346
  /**
@@ -368,12 +358,20 @@ interface SigningAuditEntry {
368
358
  tool: SignerToolName;
369
359
  payload_hash: string;
370
360
  delegate_address: string;
361
+ /**
362
+ * Serialized key kept as `safe_address` deliberately (#2914 review): this
363
+ * is a persisted JSONL field, and an audit log written by an earlier
364
+ * release never rewrites itself — renaming the key here would fork the
365
+ * format mid-file. `SigningAuditContext.accountAddress` (the in-memory
366
+ * field this is built from) carries the account-vocabulary name; only the
367
+ * on-disk spelling stays put.
368
+ */
371
369
  safe_address?: string;
372
370
  chain_id?: number;
373
371
  }
374
372
  interface SigningAuditContext {
375
373
  delegateAddress: string;
376
- safeAddress?: string;
374
+ accountAddress?: string;
377
375
  chainId?: number;
378
376
  auditPath?: string;
379
377
  }
@@ -451,7 +449,7 @@ declare function createToolHandlers(signer: EdgeSigner, options?: ToolHandlerOpt
451
449
 
452
450
  interface SignerConsentInput {
453
451
  delegateAddress: string;
454
- safeAddress?: string;
452
+ accountAddress?: string;
455
453
  agentId?: string;
456
454
  chainId?: number;
457
455
  network?: string;
@@ -476,7 +474,7 @@ declare function renderSignerConsentBlock(input: SignerConsentInput, hash: strin
476
474
  declare function ensureSignerConsent(input: SignerConsentInput, options?: SignerConsentOptions): Promise<SignerConsentDecision>;
477
475
 
478
476
  declare const SIGNER_NAME = "@haven_ai/signer";
479
- declare const SIGNER_VERSION = "0.2.1-alpha.0";
477
+ declare const SIGNER_VERSION = "0.3.0-alpha.0";
480
478
  interface SignerOptions {
481
479
  /** Path to a Haven credential JSON file (delegate_key is read from it). */
482
480
  credentialsPath?: string;
package/dist/index.d.ts CHANGED
@@ -282,18 +282,8 @@ declare function signerInstructions(): string;
282
282
  interface SignerCredentials {
283
283
  delegateKey: string;
284
284
  agentId?: string;
285
- /**
286
- * The Haven account (smart account) the agent spends from — #2908, the
287
- * account-vocabulary name. Same value as `safeAddress`.
288
- */
285
+ /** The Haven account (smart account) the agent spends from. */
289
286
  accountAddress?: string;
290
- /**
291
- * @deprecated #2908 — same value as {@link SignerCredentials.accountAddress}.
292
- * Removed from this shape in the release after the one carrying #2908
293
- * (#2914). The credential-FILE keys it was read from are a different
294
- * matter — see `readAccountAddressField`.
295
- */
296
- safeAddress?: string;
297
287
  chainId?: number;
298
288
  network?: string;
299
289
  x402BindingSigner?: string;
@@ -305,11 +295,11 @@ interface RawCredentialFile {
305
295
  delegateKey?: unknown;
306
296
  agent_id?: unknown;
307
297
  agentId?: unknown;
308
- /** #2908: what `@haven_ai/connect` writes from this release on. */
298
+ /** What `@haven_ai/connect` writes. */
309
299
  account_address?: unknown;
310
- /** Pre-#2908 spelling — read PERMANENTLY, see `readAccountAddressField`. */
300
+ /** Pre-#2908 spelling — read PERMANENTLY (a credential file never rewrites itself), see `readAccountAddressField`. */
311
301
  safe_address?: unknown;
312
- /** Pre-#2908 spelling — read PERMANENTLY, see `readAccountAddressField`. */
302
+ /** Pre-#2908 spelling — read PERMANENTLY (a credential file never rewrites itself), see `readAccountAddressField`. */
313
303
  safeAddress?: unknown;
314
304
  chain_id?: unknown;
315
305
  chainId?: unknown;
@@ -346,11 +336,11 @@ declare function loadSignerCredentials(path?: string | undefined): Promise<Signe
346
336
  */
347
337
  declare function readAccountAddressField(raw: Pick<RawCredentialFile, 'account_address' | 'safe_address' | 'safeAddress'>): string | undefined;
348
338
  /**
349
- * The account address off the process environment, new name first:
350
- * `HAVEN_ACCOUNT_ADDRESS` (the survivor, decided on #2906) then the two
351
- * names the dashboard handoff emitted before #2908 — `HAVEN_WALLET_ADDRESS`
352
- * and `HAVEN_SAFE_ADDRESS`. Unlike the file fallbacks these two ARE
353
- * window-scoped: they are dropped at #2914, one release after this one.
339
+ * The account address off the process environment: `HAVEN_ACCOUNT_ADDRESS`
340
+ * (the survivor, decided on #2906). The two names the dashboard handoff
341
+ * emitted before #2908 — `HAVEN_WALLET_ADDRESS` and `HAVEN_SAFE_ADDRESS` —
342
+ * were window-scoped (unlike the credential-FILE fallbacks) and are retired
343
+ * as of #2914.
354
344
  */
355
345
  declare function readAccountAddressEnv(env: NodeJS.ProcessEnv): string | undefined;
356
346
  /**
@@ -368,12 +358,20 @@ interface SigningAuditEntry {
368
358
  tool: SignerToolName;
369
359
  payload_hash: string;
370
360
  delegate_address: string;
361
+ /**
362
+ * Serialized key kept as `safe_address` deliberately (#2914 review): this
363
+ * is a persisted JSONL field, and an audit log written by an earlier
364
+ * release never rewrites itself — renaming the key here would fork the
365
+ * format mid-file. `SigningAuditContext.accountAddress` (the in-memory
366
+ * field this is built from) carries the account-vocabulary name; only the
367
+ * on-disk spelling stays put.
368
+ */
371
369
  safe_address?: string;
372
370
  chain_id?: number;
373
371
  }
374
372
  interface SigningAuditContext {
375
373
  delegateAddress: string;
376
- safeAddress?: string;
374
+ accountAddress?: string;
377
375
  chainId?: number;
378
376
  auditPath?: string;
379
377
  }
@@ -451,7 +449,7 @@ declare function createToolHandlers(signer: EdgeSigner, options?: ToolHandlerOpt
451
449
 
452
450
  interface SignerConsentInput {
453
451
  delegateAddress: string;
454
- safeAddress?: string;
452
+ accountAddress?: string;
455
453
  agentId?: string;
456
454
  chainId?: number;
457
455
  network?: string;
@@ -476,7 +474,7 @@ declare function renderSignerConsentBlock(input: SignerConsentInput, hash: strin
476
474
  declare function ensureSignerConsent(input: SignerConsentInput, options?: SignerConsentOptions): Promise<SignerConsentDecision>;
477
475
 
478
476
  declare const SIGNER_NAME = "@haven_ai/signer";
479
- declare const SIGNER_VERSION = "0.2.1-alpha.0";
477
+ declare const SIGNER_VERSION = "0.3.0-alpha.0";
480
478
  interface SignerOptions {
481
479
  /** Path to a Haven credential JSON file (delegate_key is read from it). */
482
480
  credentialsPath?: string;
package/dist/index.js CHANGED
@@ -506,7 +506,6 @@ async function loadSignerCredentials(path = process.env.HAVEN_CREDENTIALS) {
506
506
  delegateKey: envKey,
507
507
  agentId: stringField(process.env.HAVEN_AGENT_ID),
508
508
  accountAddress,
509
- safeAddress: accountAddress,
510
509
  chainId: chainIdField(process.env.HAVEN_CHAIN_ID, "HAVEN_CHAIN_ID"),
511
510
  network: stringField(process.env.HAVEN_NETWORK),
512
511
  x402BindingSigner: stringField(process.env.HAVEN_X402_BINDING_SIGNER)
@@ -541,7 +540,6 @@ async function loadFromFile(path) {
541
540
  delegateKey,
542
541
  agentId: stringField(raw.agent_id ?? raw.agentId),
543
542
  accountAddress,
544
- safeAddress: accountAddress,
545
543
  chainId: chainIdField(raw.chain_id ?? raw.chainId, "chain_id"),
546
544
  network: stringField(raw.network),
547
545
  x402BindingSigner: stringField(
@@ -554,7 +552,22 @@ function readAccountAddressField(raw) {
554
552
  return stringField(raw.account_address ?? raw.safe_address ?? raw.safeAddress);
555
553
  }
556
554
  function readAccountAddressEnv(env) {
557
- return stringField(env.HAVEN_ACCOUNT_ADDRESS ?? env.HAVEN_WALLET_ADDRESS ?? env.HAVEN_SAFE_ADDRESS);
555
+ const current = stringField(env.HAVEN_ACCOUNT_ADDRESS);
556
+ for (const name of ["HAVEN_WALLET_ADDRESS", "HAVEN_SAFE_ADDRESS"]) {
557
+ const retired = stringField(env[name]);
558
+ if (!retired) continue;
559
+ if (!current) {
560
+ throw new Error(
561
+ `${name} is retired (#2906) \u2014 Haven accounts are addressed as accounts, not Safes. Set HAVEN_ACCOUNT_ADDRESS to the same value. Refusing rather than ignoring it, because an unset account address silently skips the sweep-destination check.`
562
+ );
563
+ }
564
+ if (retired.toLowerCase() !== current.toLowerCase()) {
565
+ throw new Error(
566
+ `${name} and HAVEN_ACCOUNT_ADDRESS were both set to different addresses. Remove the retired name, or make them match \u2014 picking one silently would hide the mismatch.`
567
+ );
568
+ }
569
+ }
570
+ return current;
558
571
  }
559
572
  function stringField(value) {
560
573
  return typeof value === "string" && value.trim() ? value.trim() : void 0;
@@ -611,7 +624,7 @@ function createSigningAuditEntry(tool, payloadHash, context, now = /* @__PURE__
611
624
  payload_hash: payloadHash,
612
625
  delegate_address: context.delegateAddress
613
626
  };
614
- if (context.safeAddress) entry.safe_address = context.safeAddress;
627
+ if (context.accountAddress) entry.safe_address = context.accountAddress;
615
628
  if (typeof context.chainId === "number") entry.chain_id = context.chainId;
616
629
  return entry;
617
630
  }
@@ -1078,7 +1091,7 @@ function createToolHandlers(signer, options = {}) {
1078
1091
  authorization: args.authorization,
1079
1092
  expectedAuth: args.expected_auth,
1080
1093
  // Cross-check `to` against the Safe in the local credential when present.
1081
- expectedSafe: options.audit?.safeAddress
1094
+ expectedSafe: options.audit?.accountAddress
1082
1095
  });
1083
1096
  await auditSigning(
1084
1097
  "haven_sign_sweep_delegate",
@@ -1203,7 +1216,7 @@ var SIGNER_CONSENT_SURFACE_VERSION = 2;
1203
1216
  function computeSignerConsentHash(input) {
1204
1217
  const identity = [
1205
1218
  input.delegateAddress.toLowerCase(),
1206
- (input.safeAddress ?? "").toLowerCase(),
1219
+ (input.accountAddress ?? "").toLowerCase(),
1207
1220
  input.agentId ?? "",
1208
1221
  input.chainId ?? "",
1209
1222
  input.network ?? ""
@@ -1222,7 +1235,7 @@ function renderSignerConsentBlock(input, hash) {
1222
1235
  "",
1223
1236
  `Delegate address: ${input.delegateAddress}`
1224
1237
  ];
1225
- lines.push(`Haven wallet: ${input.safeAddress ?? "not provided to this signer"}`);
1238
+ lines.push(`Haven wallet: ${input.accountAddress ?? "not provided to this signer"}`);
1226
1239
  if (input.agentId) lines.push(`Agent ID: ${input.agentId}`);
1227
1240
  if (typeof input.chainId === "number") lines.push(`Chain ID: ${input.chainId}`);
1228
1241
  if (input.network) lines.push(`Network: ${input.network}`);
@@ -1316,7 +1329,7 @@ async function writeAckFile(path, hash) {
1316
1329
  );
1317
1330
  }
1318
1331
  var SIGNER_NAME = "@haven_ai/signer";
1319
- var SIGNER_VERSION = "0.2.1-alpha.0";
1332
+ var SIGNER_VERSION = "0.3.0-alpha.0";
1320
1333
  async function resolveEdgeSigner(options = {}) {
1321
1334
  const { signer } = await resolveSignerRuntime(options);
1322
1335
  return signer;
@@ -1355,7 +1368,7 @@ function buildSignerMcpServer(signer, options = {}) {
1355
1368
  audit: {
1356
1369
  auditPath: options.auditPath ?? defaultSigningAuditPath(credentialsPath),
1357
1370
  delegateAddress: signer.delegateAddress,
1358
- safeAddress: options.credentials?.accountAddress ?? options.credentials?.safeAddress,
1371
+ accountAddress: options.credentials?.accountAddress,
1359
1372
  chainId: options.credentials?.chainId
1360
1373
  },
1361
1374
  // #1263: the payment_id signing path — the ONLY network call this server
@@ -1405,7 +1418,7 @@ async function runSignerConsentGate(signer, credentials, options) {
1405
1418
  return ensureSignerConsent(
1406
1419
  {
1407
1420
  delegateAddress: signer.delegateAddress,
1408
- safeAddress: credentials?.accountAddress ?? credentials?.safeAddress,
1421
+ accountAddress: credentials?.accountAddress,
1409
1422
  agentId: credentials?.agentId,
1410
1423
  chainId: credentials?.chainId,
1411
1424
  network: credentials?.network,