@adcp/sdk 16.0.0-beta.1 → 16.0.0-beta.2

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.
Files changed (97) hide show
  1. package/dist/lib/core/SingleAgentClient.d.mts +10 -1
  2. package/dist/lib/core/SingleAgentClient.d.ts +10 -1
  3. package/dist/lib/core/SingleAgentClient.js +29 -8
  4. package/dist/lib/core/SingleAgentClient.mjs +29 -8
  5. package/dist/lib/identity-3.3/generated-compat.d.mts +34 -0
  6. package/dist/lib/identity-3.3/generated-compat.d.ts +34 -0
  7. package/dist/lib/identity-3.3/generated-compat.js +16 -0
  8. package/dist/lib/identity-3.3/generated-compat.mjs +0 -0
  9. package/dist/lib/identity-3.3/index.d.mts +2 -2
  10. package/dist/lib/identity-3.3/index.d.ts +2 -2
  11. package/dist/lib/identity-3.3/index.js +4 -0
  12. package/dist/lib/identity-3.3/index.mjs +5 -1
  13. package/dist/lib/identity-3.3/lifecycle.d.mts +17 -5
  14. package/dist/lib/identity-3.3/lifecycle.d.ts +17 -5
  15. package/dist/lib/identity-3.3/lifecycle.js +32 -5
  16. package/dist/lib/identity-3.3/lifecycle.mjs +38 -6
  17. package/dist/lib/identity-3.3/revocation.d.mts +39 -3
  18. package/dist/lib/identity-3.3/revocation.d.ts +39 -3
  19. package/dist/lib/identity-3.3/revocation.js +88 -18
  20. package/dist/lib/identity-3.3/revocation.mjs +89 -19
  21. package/dist/lib/identity-3.3/server.d.mts +12 -0
  22. package/dist/lib/identity-3.3/server.d.ts +12 -0
  23. package/dist/lib/identity-3.3/server.js +103 -43
  24. package/dist/lib/identity-3.3/server.mjs +111 -45
  25. package/dist/lib/identity-3.3/trust.d.mts +62 -1
  26. package/dist/lib/identity-3.3/trust.d.ts +62 -1
  27. package/dist/lib/identity-3.3/trust.js +126 -21
  28. package/dist/lib/identity-3.3/trust.mjs +124 -21
  29. package/dist/lib/identity-3.3/types.d.mts +39 -11
  30. package/dist/lib/identity-3.3/types.d.ts +39 -11
  31. package/dist/lib/index.d.mts +1 -1
  32. package/dist/lib/index.d.ts +1 -1
  33. package/dist/lib/index.js +2 -0
  34. package/dist/lib/index.mjs +2 -0
  35. package/dist/lib/protocols/index.d.mts +1 -1
  36. package/dist/lib/protocols/index.d.ts +1 -1
  37. package/dist/lib/protocols/index.js +2 -2
  38. package/dist/lib/protocols/index.mjs +2 -2
  39. package/dist/lib/reporting/bigquery/index.js +8 -0
  40. package/dist/lib/reporting/bigquery/index.mjs +8 -0
  41. package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
  42. package/dist/lib/server/auth-signature.d.mts +6 -1
  43. package/dist/lib/server/auth-signature.d.ts +6 -1
  44. package/dist/lib/server/auth-signature.js +24 -13
  45. package/dist/lib/server/auth-signature.mjs +29 -13
  46. package/dist/lib/server/auth.d.mts +2 -2
  47. package/dist/lib/server/auth.d.ts +2 -2
  48. package/dist/lib/server/create-adcp-server.js +31 -10
  49. package/dist/lib/server/create-adcp-server.mjs +37 -11
  50. package/dist/lib/signing/crypto.js +8 -0
  51. package/dist/lib/signing/crypto.mjs +9 -1
  52. package/dist/lib/signing/fetch-async.js +1 -1
  53. package/dist/lib/signing/fetch-async.mjs +1 -1
  54. package/dist/lib/signing/fetch.js +1 -1
  55. package/dist/lib/signing/fetch.mjs +1 -1
  56. package/dist/lib/signing/middleware.js +9 -0
  57. package/dist/lib/signing/middleware.mjs +14 -0
  58. package/dist/lib/signing/parser.d.mts +8 -5
  59. package/dist/lib/signing/parser.d.ts +8 -5
  60. package/dist/lib/signing/parser.js +77 -61
  61. package/dist/lib/signing/parser.mjs +77 -61
  62. package/dist/lib/signing/revocation.js +3 -0
  63. package/dist/lib/signing/revocation.mjs +3 -0
  64. package/dist/lib/signing/verifier.js +1 -1
  65. package/dist/lib/signing/verifier.mjs +1 -1
  66. package/dist/lib/signing/web-bot-auth.d.mts +84 -10
  67. package/dist/lib/signing/web-bot-auth.d.ts +84 -10
  68. package/dist/lib/signing/web-bot-auth.js +259 -82
  69. package/dist/lib/signing/web-bot-auth.mjs +259 -87
  70. package/dist/lib/signing/webhook-verifier.js +1 -1
  71. package/dist/lib/signing/webhook-verifier.mjs +1 -1
  72. package/dist/lib/testing/storyboard/validations.d.mts +1 -1
  73. package/dist/lib/testing/storyboard/validations.d.ts +1 -1
  74. package/dist/lib/v2/projection/catalog-snapshot.js +3 -1
  75. package/dist/lib/v2/projection/catalog-snapshot.mjs +3 -1
  76. package/dist/lib/v2/projection/creative-delivery.d.mts +31 -9
  77. package/dist/lib/v2/projection/creative-delivery.d.ts +31 -9
  78. package/dist/lib/v2/projection/index.d.mts +1 -1
  79. package/dist/lib/v2/projection/index.d.ts +1 -1
  80. package/dist/lib/v2/projection/index.js +2 -0
  81. package/dist/lib/v2/projection/index.mjs +2 -0
  82. package/dist/lib/v2/projection/legacy-routes.d.mts +10 -0
  83. package/dist/lib/v2/projection/legacy-routes.d.ts +10 -0
  84. package/dist/lib/v2/projection/legacy-routes.js +7 -0
  85. package/dist/lib/v2/projection/legacy-routes.mjs +6 -0
  86. package/dist/lib/version.d.mts +3 -3
  87. package/dist/lib/version.d.ts +3 -3
  88. package/dist/lib/version.js +3 -3
  89. package/dist/lib/version.mjs +3 -3
  90. package/docs/TYPE-SUMMARY.md +2 -2
  91. package/docs/guides/REPORTING-LEDGER.md +15 -5
  92. package/docs/guides/REPORTING-OPERATIONS.md +17 -11
  93. package/docs/llms.txt +2 -2
  94. package/docs/migration-12-to-13.md +8 -0
  95. package/docs/migration-14.x-rc-worksheet.md +4 -4
  96. package/docs/migration-agent-identity-3.3.md +150 -11
  97. package/package.json +3 -1
@@ -98,7 +98,16 @@ export type WebhookParseErrorCode = WebhookSignatureErrorCode | 'webhook_signatu
98
98
  export interface WebhookVerificationConfig {
99
99
  webBotAuth?: {
100
100
  directory: import('../signing/web-bot-auth.mjs').SignatureDirectoryResolver;
101
- isRevoked: (origin: string, keyid: string) => Promise<boolean>;
101
+ /**
102
+ * Seller origin revocation, checked after verification. A revoked key is
103
+ * refused; unknown status is retryable; a seller that serves no list is
104
+ * accepted (webhooks do not spend). Usually an `OriginRevocationResolver`.
105
+ */
106
+ revocation?: {
107
+ status(origin: string, keyid: string): Promise<import('../identity-3.3/revocation.mjs').OriginRevocationStatus>;
108
+ };
109
+ /** @deprecated Use `revocation`. Conservative: a seller that serves no list is refused. */
110
+ isRevoked?: (origin: string, keyid: string) => Promise<boolean>;
102
111
  };
103
112
  /** Applicable pins from persisted media-buy records. Reuse refresh callbacks bound to the seller/publisher/tenant across deliveries to share their cooldown. Never use webhook payload fields. */
104
113
  publisherPins?: (registration: Readonly<WebhookRegistration>) => Promise<readonly import('../signing/publisher-pins.mjs').PublisherSigningKeyPin[]>;
@@ -98,7 +98,16 @@ export type WebhookParseErrorCode = WebhookSignatureErrorCode | 'webhook_signatu
98
98
  export interface WebhookVerificationConfig {
99
99
  webBotAuth?: {
100
100
  directory: import('../signing/web-bot-auth').SignatureDirectoryResolver;
101
- isRevoked: (origin: string, keyid: string) => Promise<boolean>;
101
+ /**
102
+ * Seller origin revocation, checked after verification. A revoked key is
103
+ * refused; unknown status is retryable; a seller that serves no list is
104
+ * accepted (webhooks do not spend). Usually an `OriginRevocationResolver`.
105
+ */
106
+ revocation?: {
107
+ status(origin: string, keyid: string): Promise<import('../identity-3.3/revocation').OriginRevocationStatus>;
108
+ };
109
+ /** @deprecated Use `revocation`. Conservative: a seller that serves no list is refused. */
110
+ isRevoked?: (origin: string, keyid: string) => Promise<boolean>;
102
111
  };
103
112
  /** Applicable pins from persisted media-buy records. Reuse refresh callbacks bound to the seller/publisher/tenant across deliveries to share their cooldown. Never use webhook payload fields. */
104
113
  publisherPins?: (registration: Readonly<WebhookRegistration>) => Promise<readonly import('../signing/publisher-pins').PublisherSigningKeyPin[]>;
@@ -2450,7 +2450,7 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
2450
2450
  }
2451
2451
  }
2452
2452
  if (registration?.mode === "rfc9421") {
2453
- const { verifyWebBotAuth, selectSignatureProfile, WebBotAuthError } = loadWebBotAuth();
2453
+ const { verifyWebBotAuth, selectSignatureProfile, WebBotAuthError, WebBotAuthUnavailableError } = loadWebBotAuth();
2454
2454
  const requestMethod = options.requestMethod;
2455
2455
  const requestUrl = options.requestUrl;
2456
2456
  if (rawBody === void 0 || !options.headers || !trustedOperationId || !requestMethod || !requestUrl) {
@@ -2474,17 +2474,30 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
2474
2474
  method: requestMethod,
2475
2475
  url: requestUrl,
2476
2476
  headers: normalizedHeaders.headers,
2477
- body: typeof rawBody === "string" ? rawBody : new TextDecoder("utf-8", { fatal: true }).decode(rawBody)
2477
+ body: typeof rawBody === "string" ? rawBody : (
2478
+ // ignoreBOM: Content-Digest covers the exact received bytes.
2479
+ new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(rawBody)
2480
+ )
2478
2481
  },
2479
2482
  {
2480
2483
  directory: config.directory,
2481
2484
  replayStore: this.webhookReplayStore,
2482
- isRevoked: config.isRevoked,
2485
+ ...config.isRevoked && !config.revocation && { isRevoked: config.isRevoked },
2483
2486
  now: this.config.webhookVerification?.now
2484
2487
  }
2485
2488
  );
2486
2489
  if (signers.length !== 1 || signers[0].origin !== (0, import_canonicalize.canonicalAgentOrigin)(registration.agentUrl))
2487
2490
  throw new WebBotAuthError(403, "webhook_signer_mismatch");
2491
+ if (config.revocation) {
2492
+ let status;
2493
+ try {
2494
+ status = await config.revocation.status(signers[0].origin, signers[0].keyid);
2495
+ } catch (error) {
2496
+ throw new WebBotAuthUnavailableError("revocation_persistence_failed", error);
2497
+ }
2498
+ if (status === "revoked") throw new WebBotAuthError(403, "key_revoked");
2499
+ if (status === "unknown") throw new WebBotAuthError(403, "identity_unverified");
2500
+ } else if (!config.isRevoked) throw new WebBotAuthError(403, "webhook_revocation_not_configured");
2488
2501
  } else {
2489
2502
  if (actualProfile === "web-bot-auth") throw new WebBotAuthError(403, "webhook_profile_mismatch");
2490
2503
  const delegatedOperatorAuthorization = this.delegatedOperatorAuthorizationForRegistration(registration);
@@ -2510,14 +2523,17 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
2510
2523
  );
2511
2524
  }
2512
2525
  } catch (cause) {
2526
+ if (cause instanceof WebBotAuthUnavailableError)
2527
+ return { ok: false, code: "webhook_verification_unavailable", message: cause.message, cause };
2513
2528
  if (cause instanceof WebBotAuthError)
2514
2529
  return {
2515
2530
  ok: false,
2516
2531
  code: [
2517
2532
  "directory_unavailable",
2518
- "revocation_unavailable",
2519
- "verification_unavailable",
2520
- "directory_fetch_limit"
2533
+ "directory_fetch_limit",
2534
+ "directory_expired",
2535
+ "identity_unverified",
2536
+ "verification_unavailable"
2521
2537
  ].includes(cause.reason) ? "webhook_verification_unavailable" : "webhook_signature_invalid",
2522
2538
  message: cause.message,
2523
2539
  cause
@@ -4854,6 +4870,11 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
4854
4870
  const defaultAuth = !signed33Webhooks && this.config.webhookSecret ? { schemes: ["HMAC-SHA256"], credentials: this.config.webhookSecret } : void 0;
4855
4871
  const resolvedAuth = consumerAuth !== void 0 ? consumerAuth : consumerUrl === void 0 ? defaultAuth : void 0;
4856
4872
  if (!signed33Webhooks && resolvedAuth === void 0 || resolvedAuth === null) {
4873
+ if (consumerReportingWebhook && consumerUrl !== void 0 && consumerAuth === void 0) {
4874
+ throw new Error(
4875
+ "reporting_webhook requires an `authentication` block without positively negotiated 3.3 signed webhooks: a caller-supplied `reporting_webhook.url` must bring its own `reporting_webhook.authentication` (the client never pairs `webhookSecret` with a caller-controlled URL). Omit `url` to use the client's webhookUrlTemplate callback, or remove `reporting_webhook` if you do not need automated delivery reports."
4876
+ );
4877
+ }
4857
4878
  if (consumerReportingWebhook) {
4858
4879
  throw new Error(
4859
4880
  "reporting_webhook requires an `authentication` block without positively negotiated 3.3 signed webhooks, and no credential is available: set `webhookSecret` on the client, or pass `reporting_webhook.authentication` explicitly. Remove `reporting_webhook` from the request if you do not need automated delivery reports \u2014 the media buy itself does not require it."
@@ -4876,12 +4897,12 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
4876
4897
  ...resolvedAuth === void 0 && this.selectedWebhookSigningProfile() && { signing_profile: this.selectedWebhookSigningProfile() }
4877
4898
  }
4878
4899
  };
4879
- if (signed33Webhooks && resolvedAuth === void 0) {
4900
+ if (signed33Webhooks && resolvedAuth === void 0 && consumerUrl === void 0) {
4880
4901
  await this.persistWebhookRegistration({
4881
4902
  agent: this.normalizedAgent,
4882
4903
  taskType: "media_buy_delivery",
4883
4904
  operationId,
4884
- callbackUrl: consumerUrl ?? deliveryWebhookUrl,
4905
+ callbackUrl: deliveryWebhookUrl,
4885
4906
  mode: "rfc9421",
4886
4907
  signingProfile: this.selectedWebhookSigningProfile()
4887
4908
  });
@@ -2541,7 +2541,7 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
2541
2541
  }
2542
2542
  }
2543
2543
  if (registration?.mode === "rfc9421") {
2544
- const { verifyWebBotAuth, selectSignatureProfile, WebBotAuthError } = loadWebBotAuth();
2544
+ const { verifyWebBotAuth, selectSignatureProfile, WebBotAuthError, WebBotAuthUnavailableError } = loadWebBotAuth();
2545
2545
  const requestMethod = options.requestMethod;
2546
2546
  const requestUrl = options.requestUrl;
2547
2547
  if (rawBody === void 0 || !options.headers || !trustedOperationId || !requestMethod || !requestUrl) {
@@ -2565,17 +2565,30 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
2565
2565
  method: requestMethod,
2566
2566
  url: requestUrl,
2567
2567
  headers: normalizedHeaders.headers,
2568
- body: typeof rawBody === "string" ? rawBody : new TextDecoder("utf-8", { fatal: true }).decode(rawBody)
2568
+ body: typeof rawBody === "string" ? rawBody : (
2569
+ // ignoreBOM: Content-Digest covers the exact received bytes.
2570
+ new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(rawBody)
2571
+ )
2569
2572
  },
2570
2573
  {
2571
2574
  directory: config.directory,
2572
2575
  replayStore: this.webhookReplayStore,
2573
- isRevoked: config.isRevoked,
2576
+ ...config.isRevoked && !config.revocation && { isRevoked: config.isRevoked },
2574
2577
  now: this.config.webhookVerification?.now
2575
2578
  }
2576
2579
  );
2577
2580
  if (signers.length !== 1 || signers[0].origin !== canonicalAgentOrigin(registration.agentUrl))
2578
2581
  throw new WebBotAuthError(403, "webhook_signer_mismatch");
2582
+ if (config.revocation) {
2583
+ let status;
2584
+ try {
2585
+ status = await config.revocation.status(signers[0].origin, signers[0].keyid);
2586
+ } catch (error) {
2587
+ throw new WebBotAuthUnavailableError("revocation_persistence_failed", error);
2588
+ }
2589
+ if (status === "revoked") throw new WebBotAuthError(403, "key_revoked");
2590
+ if (status === "unknown") throw new WebBotAuthError(403, "identity_unverified");
2591
+ } else if (!config.isRevoked) throw new WebBotAuthError(403, "webhook_revocation_not_configured");
2579
2592
  } else {
2580
2593
  if (actualProfile === "web-bot-auth") throw new WebBotAuthError(403, "webhook_profile_mismatch");
2581
2594
  const delegatedOperatorAuthorization = this.delegatedOperatorAuthorizationForRegistration(registration);
@@ -2601,14 +2614,17 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
2601
2614
  );
2602
2615
  }
2603
2616
  } catch (cause) {
2617
+ if (cause instanceof WebBotAuthUnavailableError)
2618
+ return { ok: false, code: "webhook_verification_unavailable", message: cause.message, cause };
2604
2619
  if (cause instanceof WebBotAuthError)
2605
2620
  return {
2606
2621
  ok: false,
2607
2622
  code: [
2608
2623
  "directory_unavailable",
2609
- "revocation_unavailable",
2610
- "verification_unavailable",
2611
- "directory_fetch_limit"
2624
+ "directory_fetch_limit",
2625
+ "directory_expired",
2626
+ "identity_unverified",
2627
+ "verification_unavailable"
2612
2628
  ].includes(cause.reason) ? "webhook_verification_unavailable" : "webhook_signature_invalid",
2613
2629
  message: cause.message,
2614
2630
  cause
@@ -4945,6 +4961,11 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
4945
4961
  const defaultAuth = !signed33Webhooks && this.config.webhookSecret ? { schemes: ["HMAC-SHA256"], credentials: this.config.webhookSecret } : void 0;
4946
4962
  const resolvedAuth = consumerAuth !== void 0 ? consumerAuth : consumerUrl === void 0 ? defaultAuth : void 0;
4947
4963
  if (!signed33Webhooks && resolvedAuth === void 0 || resolvedAuth === null) {
4964
+ if (consumerReportingWebhook && consumerUrl !== void 0 && consumerAuth === void 0) {
4965
+ throw new Error(
4966
+ "reporting_webhook requires an `authentication` block without positively negotiated 3.3 signed webhooks: a caller-supplied `reporting_webhook.url` must bring its own `reporting_webhook.authentication` (the client never pairs `webhookSecret` with a caller-controlled URL). Omit `url` to use the client's webhookUrlTemplate callback, or remove `reporting_webhook` if you do not need automated delivery reports."
4967
+ );
4968
+ }
4948
4969
  if (consumerReportingWebhook) {
4949
4970
  throw new Error(
4950
4971
  "reporting_webhook requires an `authentication` block without positively negotiated 3.3 signed webhooks, and no credential is available: set `webhookSecret` on the client, or pass `reporting_webhook.authentication` explicitly. Remove `reporting_webhook` from the request if you do not need automated delivery reports \u2014 the media buy itself does not require it."
@@ -4967,12 +4988,12 @@ Hint: this usually means agent_uri does not include the MCP endpoint path. The S
4967
4988
  ...resolvedAuth === void 0 && this.selectedWebhookSigningProfile() && { signing_profile: this.selectedWebhookSigningProfile() }
4968
4989
  }
4969
4990
  };
4970
- if (signed33Webhooks && resolvedAuth === void 0) {
4991
+ if (signed33Webhooks && resolvedAuth === void 0 && consumerUrl === void 0) {
4971
4992
  await this.persistWebhookRegistration({
4972
4993
  agent: this.normalizedAgent,
4973
4994
  taskType: "media_buy_delivery",
4974
4995
  operationId,
4975
- callbackUrl: consumerUrl ?? deliveryWebhookUrl,
4996
+ callbackUrl: deliveryWebhookUrl,
4976
4997
  mode: "rfc9421",
4977
4998
  signingProfile: this.selectedWebhookSigningProfile()
4978
4999
  });
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Bridges the experimental AdCP 3.3 preview types to the generated wire types.
3
+ *
4
+ * The released SDK pins an AdCP schema version that predates the 3.3 identity
5
+ * drafts, so the preview types in `./types` start from hand-written drafts. Once
6
+ * the pinned schemas (or a candidate spec bundle built by the spec repo's
7
+ * "Generate TypeScript SDK" check) define a shape, the generated type wins: the
8
+ * preview type becomes an alias of it, so the two cannot drift apart and a
9
+ * server that accepts the preview shape always emits a generated-valid payload.
10
+ *
11
+ * Internal: not re-exported from `@adcp/sdk/identity-3.3`.
12
+ */
13
+ import type { GetAdCPCapabilitiesResponse } from '../types/tools.generated.mjs';
14
+ /**
15
+ * The value type of an optional property `K` on `T`, or `unknown` when `T`
16
+ * does not declare it. An object type without `K` is assignable to
17
+ * `{ K?: V }`, so the absent case infers `unknown` rather than failing.
18
+ * Non-distributive, so a union `T` resolves to the property's union rather
19
+ * than silently falling back when one member lacks it.
20
+ */
21
+ export type OptionalPropertyOf<T, K extends PropertyKey> = [T] extends [{
22
+ [P in K]?: infer V;
23
+ }] ? V : unknown;
24
+ /** `Generated` when the pinned schemas define it, otherwise `Draft`. */
25
+ export type PreferGenerated<Generated, Draft> = unknown extends Generated ? Draft : [NonNullable<Generated>] extends [never] ? Draft : NonNullable<Generated>;
26
+ /**
27
+ * Resolves `account.agent_onboarding` from a `get_adcp_capabilities` account
28
+ * shape, falling back to the draft when that shape does not declare it.
29
+ * Parameterised so type tests can exercise it against fixtures of newer
30
+ * generated shapes without regenerating the SDK.
31
+ */
32
+ export type ResolveAgentOnboarding<Account, Draft> = PreferGenerated<OptionalPropertyOf<NonNullable<Account>, 'agent_onboarding'>, Draft>;
33
+ /** `account` in the pinned `get_adcp_capabilities` response. */
34
+ export type GeneratedAccountCapabilities = NonNullable<GetAdCPCapabilitiesResponse['account']>;
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Bridges the experimental AdCP 3.3 preview types to the generated wire types.
3
+ *
4
+ * The released SDK pins an AdCP schema version that predates the 3.3 identity
5
+ * drafts, so the preview types in `./types` start from hand-written drafts. Once
6
+ * the pinned schemas (or a candidate spec bundle built by the spec repo's
7
+ * "Generate TypeScript SDK" check) define a shape, the generated type wins: the
8
+ * preview type becomes an alias of it, so the two cannot drift apart and a
9
+ * server that accepts the preview shape always emits a generated-valid payload.
10
+ *
11
+ * Internal: not re-exported from `@adcp/sdk/identity-3.3`.
12
+ */
13
+ import type { GetAdCPCapabilitiesResponse } from '../types/tools.generated';
14
+ /**
15
+ * The value type of an optional property `K` on `T`, or `unknown` when `T`
16
+ * does not declare it. An object type without `K` is assignable to
17
+ * `{ K?: V }`, so the absent case infers `unknown` rather than failing.
18
+ * Non-distributive, so a union `T` resolves to the property's union rather
19
+ * than silently falling back when one member lacks it.
20
+ */
21
+ export type OptionalPropertyOf<T, K extends PropertyKey> = [T] extends [{
22
+ [P in K]?: infer V;
23
+ }] ? V : unknown;
24
+ /** `Generated` when the pinned schemas define it, otherwise `Draft`. */
25
+ export type PreferGenerated<Generated, Draft> = unknown extends Generated ? Draft : [NonNullable<Generated>] extends [never] ? Draft : NonNullable<Generated>;
26
+ /**
27
+ * Resolves `account.agent_onboarding` from a `get_adcp_capabilities` account
28
+ * shape, falling back to the draft when that shape does not declare it.
29
+ * Parameterised so type tests can exercise it against fixtures of newer
30
+ * generated shapes without regenerating the SDK.
31
+ */
32
+ export type ResolveAgentOnboarding<Account, Draft> = PreferGenerated<OptionalPropertyOf<NonNullable<Account>, 'agent_onboarding'>, Draft>;
33
+ /** `account` in the pinned `get_adcp_capabilities` response. */
34
+ export type GeneratedAccountCapabilities = NonNullable<GetAdCPCapabilitiesResponse['account']>;
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __copyProps = (to, from, except, desc) => {
7
+ if (from && typeof from === "object" || typeof from === "function") {
8
+ for (let key of __getOwnPropNames(from))
9
+ if (!__hasOwnProp.call(to, key) && key !== except)
10
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
11
+ }
12
+ return to;
13
+ };
14
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
15
+ var generated_compat_exports = {};
16
+ module.exports = __toCommonJS(generated_compat_exports);
File without changes
@@ -2,8 +2,8 @@ export * from './types.mjs';
2
2
  export * from './trust.mjs';
3
3
  export * from './lifecycle.mjs';
4
4
  export * from './revocation.mjs';
5
- export { WEB_BOT_AUTH_DRAFT_REVISION, verifyWebBotAuth, signWebBotAuth, createWebBotAuthFetch, createSignedSignatureDirectory, SignatureDirectoryResolver, verifySignatureDirectory, selectSignatureProfile, jwkThumbprint, WebBotAuthError, } from '../signing/web-bot-auth.mjs';
6
- export type { WebBotSigningKey, WebBotSigningOptions, VerifiedWebBotSigner, VerifyWebBotAuthOptions, } from '../signing/web-bot-auth.mjs';
5
+ export { WEB_BOT_AUTH_DRAFT_REVISION, verifyWebBotAuth, signWebBotAuth, createWebBotAuthFetch, createSignedSignatureDirectory, SignatureDirectoryResolver, verifySignatureDirectory, verifyKeyDirectory, selectSignatureProfile, jwkThumbprint, WebBotAuthError, WebBotAuthUnavailableError, } from '../signing/web-bot-auth.mjs';
6
+ export type { WebBotSigningKey, WebBotSigningOptions, VerifiedWebBotSigner, VerifyWebBotAuthOptions, VerifiedSignatureDirectory, SignatureDirectoryResolverOptions, } from '../signing/web-bot-auth.mjs';
7
7
  export { validateIdentity33Payload } from './validation.mjs';
8
8
  export { createIdentity33PrincipalResolver, createIdentity33PrincipalScopeResolver, createIdentity33Authorization, withIdentity33PrincipalHandlers, isIdentity33UnboundContext, } from './server.mjs';
9
9
  export { createIdentity33StateStores } from './store.mjs';
@@ -2,8 +2,8 @@ export * from './types';
2
2
  export * from './trust';
3
3
  export * from './lifecycle';
4
4
  export * from './revocation';
5
- export { WEB_BOT_AUTH_DRAFT_REVISION, verifyWebBotAuth, signWebBotAuth, createWebBotAuthFetch, createSignedSignatureDirectory, SignatureDirectoryResolver, verifySignatureDirectory, selectSignatureProfile, jwkThumbprint, WebBotAuthError, } from '../signing/web-bot-auth';
6
- export type { WebBotSigningKey, WebBotSigningOptions, VerifiedWebBotSigner, VerifyWebBotAuthOptions, } from '../signing/web-bot-auth';
5
+ export { WEB_BOT_AUTH_DRAFT_REVISION, verifyWebBotAuth, signWebBotAuth, createWebBotAuthFetch, createSignedSignatureDirectory, SignatureDirectoryResolver, verifySignatureDirectory, verifyKeyDirectory, selectSignatureProfile, jwkThumbprint, WebBotAuthError, WebBotAuthUnavailableError, } from '../signing/web-bot-auth';
6
+ export type { WebBotSigningKey, WebBotSigningOptions, VerifiedWebBotSigner, VerifyWebBotAuthOptions, VerifiedSignatureDirectory, SignatureDirectoryResolverOptions, } from '../signing/web-bot-auth';
7
7
  export { validateIdentity33Payload } from './validation';
8
8
  export { createIdentity33PrincipalResolver, createIdentity33PrincipalScopeResolver, createIdentity33Authorization, withIdentity33PrincipalHandlers, isIdentity33UnboundContext, } from './server';
9
9
  export { createIdentity33StateStores } from './store';
@@ -22,6 +22,7 @@ __export(identity_3_exports, {
22
22
  SignatureDirectoryResolver: () => import_web_bot_auth.SignatureDirectoryResolver,
23
23
  WEB_BOT_AUTH_DRAFT_REVISION: () => import_web_bot_auth.WEB_BOT_AUTH_DRAFT_REVISION,
24
24
  WebBotAuthError: () => import_web_bot_auth.WebBotAuthError,
25
+ WebBotAuthUnavailableError: () => import_web_bot_auth.WebBotAuthUnavailableError,
25
26
  createIdentity33Authorization: () => import_server.createIdentity33Authorization,
26
27
  createIdentity33PrincipalResolver: () => import_server.createIdentity33PrincipalResolver,
27
28
  createIdentity33PrincipalScopeResolver: () => import_server.createIdentity33PrincipalScopeResolver,
@@ -34,6 +35,7 @@ __export(identity_3_exports, {
34
35
  selectSignatureProfile: () => import_web_bot_auth.selectSignatureProfile,
35
36
  signWebBotAuth: () => import_web_bot_auth.signWebBotAuth,
36
37
  validateIdentity33Payload: () => import_validation.validateIdentity33Payload,
38
+ verifyKeyDirectory: () => import_web_bot_auth.verifyKeyDirectory,
37
39
  verifySignatureDirectory: () => import_web_bot_auth.verifySignatureDirectory,
38
40
  verifyWebBotAuth: () => import_web_bot_auth.verifyWebBotAuth,
39
41
  withIdentity33PrincipalHandlers: () => import_server.withIdentity33PrincipalHandlers
@@ -53,6 +55,7 @@ var import_webhook_registration = require('../core/webhook-registration.js');
53
55
  SignatureDirectoryResolver,
54
56
  WEB_BOT_AUTH_DRAFT_REVISION,
55
57
  WebBotAuthError,
58
+ WebBotAuthUnavailableError,
56
59
  createIdentity33Authorization,
57
60
  createIdentity33PrincipalResolver,
58
61
  createIdentity33PrincipalScopeResolver,
@@ -65,6 +68,7 @@ var import_webhook_registration = require('../core/webhook-registration.js');
65
68
  selectSignatureProfile,
66
69
  signWebBotAuth,
67
70
  validateIdentity33Payload,
71
+ verifyKeyDirectory,
68
72
  verifySignatureDirectory,
69
73
  verifyWebBotAuth,
70
74
  withIdentity33PrincipalHandlers,
@@ -10,9 +10,11 @@ import {
10
10
  createSignedSignatureDirectory,
11
11
  SignatureDirectoryResolver,
12
12
  verifySignatureDirectory,
13
+ verifyKeyDirectory,
13
14
  selectSignatureProfile,
14
15
  jwkThumbprint,
15
- WebBotAuthError
16
+ WebBotAuthError,
17
+ WebBotAuthUnavailableError
16
18
  } from "../signing/web-bot-auth.mjs";
17
19
  import { validateIdentity33Payload } from "./validation.mjs";
18
20
  import {
@@ -28,6 +30,7 @@ export {
28
30
  SignatureDirectoryResolver,
29
31
  WEB_BOT_AUTH_DRAFT_REVISION,
30
32
  WebBotAuthError,
33
+ WebBotAuthUnavailableError,
31
34
  createIdentity33Authorization,
32
35
  createIdentity33PrincipalResolver,
33
36
  createIdentity33PrincipalScopeResolver,
@@ -40,6 +43,7 @@ export {
40
43
  selectSignatureProfile,
41
44
  signWebBotAuth,
42
45
  validateIdentity33Payload,
46
+ verifyKeyDirectory,
43
47
  verifySignatureDirectory,
44
48
  verifyWebBotAuth,
45
49
  withIdentity33PrincipalHandlers
@@ -1,6 +1,6 @@
1
1
  import type { PrincipalKind } from '../server/principal/types.mjs';
2
2
  import { TrustEvaluator } from './trust.mjs';
3
- import type { AgentOnboarding, AgentOnboardingRequirement, BillingParty, PrincipalRelationship, IdentityPrincipalChangedReason } from './types.mjs';
3
+ import type { AgentOnboarding, AgentOnboardingRequirement, ObservedAgentOnboardingRequirement, BillingParty, PrincipalRelationship, IdentityPrincipalChangedReason } from './types.mjs';
4
4
  export interface OriginBinding {
5
5
  origin: string;
6
6
  operator: string;
@@ -47,10 +47,13 @@ export declare class InMemoryOriginIdentityStore implements OriginIdentityStore
47
47
  getApplication(origin: string): Promise<IdentityApplication | undefined>;
48
48
  compareAndSetApplication(origin: string, expectedRevision: number | undefined, application: IdentityApplication): Promise<boolean>;
49
49
  }
50
- /** Wrong-direction gates are ignored; unknown gates remain unsatisfied. */
51
- export declare function evaluateOnboardingRequirements(requirements: readonly AgentOnboardingRequirement[], direction: 'seller' | 'buyer', check: (requirement: AgentOnboardingRequirement) => Promise<boolean>): Promise<{
50
+ /**
51
+ * Wrong-direction gates are ignored; unknown gates remain unsatisfied. Accepts
52
+ * requirements read off the wire, whose `kind` may be one this SDK does not know.
53
+ */
54
+ export declare function evaluateOnboardingRequirements<R extends ObservedAgentOnboardingRequirement = AgentOnboardingRequirement>(requirements: readonly R[], direction: 'seller' | 'buyer', check: (requirement: R) => Promise<boolean>): Promise<{
52
55
  satisfied: boolean;
53
- unsatisfied: AgentOnboardingRequirement[];
56
+ unsatisfied: R[];
54
57
  }>;
55
58
  export declare function validateAgentOnboarding(posture: AgentOnboarding, account: {
56
59
  sandbox?: boolean;
@@ -93,7 +96,16 @@ export declare class OriginIdentityLifecycle {
93
96
  migrationApproved?: boolean;
94
97
  sharedOrigin?: boolean;
95
98
  }): Promise<OriginBinding>;
96
- /** Cryptographic verification does not call this. Authorization revalidates delisting. */
99
+ /**
100
+ * Cryptographic verification does not call this. Authorization revalidates
101
+ * delisting: the last record read does not list the origin (an empty
102
+ * `agents[]` retires it; a known delisting stays delisted through a failed
103
+ * refresh) and throws {@link TrustMembershipError}. An unreadable record
104
+ * (404/410 included) throws {@link TrustRecordUnavailableError} for spend;
105
+ * read-only and identity-configuration calls continue under the binding only
106
+ * while the last record read listed the origin and is within the evaluator's
107
+ * `maxOutageContinuationSeconds`.
108
+ */
97
109
  authorizeBound(originUrl: string, access?: {
98
110
  readOnly?: true;
99
111
  identityConfiguration?: true;
@@ -1,6 +1,6 @@
1
1
  import type { PrincipalKind } from '../server/principal/types';
2
2
  import { TrustEvaluator } from './trust';
3
- import type { AgentOnboarding, AgentOnboardingRequirement, BillingParty, PrincipalRelationship, IdentityPrincipalChangedReason } from './types';
3
+ import type { AgentOnboarding, AgentOnboardingRequirement, ObservedAgentOnboardingRequirement, BillingParty, PrincipalRelationship, IdentityPrincipalChangedReason } from './types';
4
4
  export interface OriginBinding {
5
5
  origin: string;
6
6
  operator: string;
@@ -47,10 +47,13 @@ export declare class InMemoryOriginIdentityStore implements OriginIdentityStore
47
47
  getApplication(origin: string): Promise<IdentityApplication | undefined>;
48
48
  compareAndSetApplication(origin: string, expectedRevision: number | undefined, application: IdentityApplication): Promise<boolean>;
49
49
  }
50
- /** Wrong-direction gates are ignored; unknown gates remain unsatisfied. */
51
- export declare function evaluateOnboardingRequirements(requirements: readonly AgentOnboardingRequirement[], direction: 'seller' | 'buyer', check: (requirement: AgentOnboardingRequirement) => Promise<boolean>): Promise<{
50
+ /**
51
+ * Wrong-direction gates are ignored; unknown gates remain unsatisfied. Accepts
52
+ * requirements read off the wire, whose `kind` may be one this SDK does not know.
53
+ */
54
+ export declare function evaluateOnboardingRequirements<R extends ObservedAgentOnboardingRequirement = AgentOnboardingRequirement>(requirements: readonly R[], direction: 'seller' | 'buyer', check: (requirement: R) => Promise<boolean>): Promise<{
52
55
  satisfied: boolean;
53
- unsatisfied: AgentOnboardingRequirement[];
56
+ unsatisfied: R[];
54
57
  }>;
55
58
  export declare function validateAgentOnboarding(posture: AgentOnboarding, account: {
56
59
  sandbox?: boolean;
@@ -93,7 +96,16 @@ export declare class OriginIdentityLifecycle {
93
96
  migrationApproved?: boolean;
94
97
  sharedOrigin?: boolean;
95
98
  }): Promise<OriginBinding>;
96
- /** Cryptographic verification does not call this. Authorization revalidates delisting. */
99
+ /**
100
+ * Cryptographic verification does not call this. Authorization revalidates
101
+ * delisting: the last record read does not list the origin (an empty
102
+ * `agents[]` retires it; a known delisting stays delisted through a failed
103
+ * refresh) and throws {@link TrustMembershipError}. An unreadable record
104
+ * (404/410 included) throws {@link TrustRecordUnavailableError} for spend;
105
+ * read-only and identity-configuration calls continue under the binding only
106
+ * while the last record read listed the origin and is within the evaluator's
107
+ * `maxOutageContinuationSeconds`.
108
+ */
97
109
  authorizeBound(originUrl: string, access?: {
98
110
  readOnly?: true;
99
111
  identityConfiguration?: true;
@@ -66,14 +66,20 @@ class InMemoryOriginIdentityStore {
66
66
  }
67
67
  }
68
68
  const BUYER_GATES = /* @__PURE__ */ new Set(["aao_verified", "storyboard", "sandbox", "experimental_feature"]);
69
- const SELLER_GATES = /* @__PURE__ */ new Set(["agent_identity", "grant", "billing_entity", "contract", "credit_application"]);
69
+ const SELLER_GATES = /* @__PURE__ */ new Set([
70
+ "agent_identity",
71
+ "grant",
72
+ "billing_entity",
73
+ "contract",
74
+ "credit_application"
75
+ ]);
70
76
  async function evaluateOnboardingRequirements(requirements, direction, check) {
71
77
  const relevant = direction === "seller" ? SELLER_GATES : BUYER_GATES;
72
78
  const wrong = direction === "seller" ? BUYER_GATES : SELLER_GATES;
73
79
  const unsatisfied = [];
74
80
  for (const requirement of requirements) {
75
81
  if (wrong.has(requirement.kind)) continue;
76
- const wellFormed = requirement.kind !== "aao_verified" || !!requirement.role && !!requirement.verification_modes?.length && !!requirement.specialisms?.length && !!requirement.adcp_version;
82
+ const wellFormed = requirement.kind !== "aao_verified" || !!requirement.role && !!requirement.verification_modes?.length && !!(requirement.verified_specialisms ?? requirement.specialisms)?.length && !!requirement.adcp_version;
77
83
  const hasId = !["storyboard", "experimental_feature"].includes(requirement.kind) || !!requirement.id;
78
84
  if (!relevant.has(requirement.kind) || !wellFormed || !hasId || !await check(requirement))
79
85
  unsatisfied.push(requirement);
@@ -126,13 +132,34 @@ class OriginIdentityLifecycle {
126
132
  await this.options.store.bind(binding);
127
133
  return binding;
128
134
  }
129
- /** Cryptographic verification does not call this. Authorization revalidates delisting. */
135
+ /**
136
+ * Cryptographic verification does not call this. Authorization revalidates
137
+ * delisting: the last record read does not list the origin (an empty
138
+ * `agents[]` retires it; a known delisting stays delisted through a failed
139
+ * refresh) and throws {@link TrustMembershipError}. An unreadable record
140
+ * (404/410 included) throws {@link TrustRecordUnavailableError} for spend;
141
+ * read-only and identity-configuration calls continue under the binding only
142
+ * while the last record read listed the origin and is within the evaluator's
143
+ * `maxOutageContinuationSeconds`.
144
+ */
130
145
  async authorizeBound(originUrl, access) {
131
146
  const origin = (0, import_canonicalize.canonicalAgentOrigin)(originUrl);
132
147
  const binding = await this.options.store.getBinding(origin);
133
148
  if (!binding) throw new import_trust.IdentityAuthorizationError();
134
- const trust = await this.options.trust.match(origin, "adcp:buying");
135
- if (binding.operator !== trust.operator) throw new import_trust.IdentityAuthorizationError();
149
+ try {
150
+ let trust;
151
+ try {
152
+ trust = await this.options.trust.match(origin, "adcp:buying");
153
+ } catch (error) {
154
+ if (error instanceof import_trust.TrustMembershipError && error.membership === "absent")
155
+ throw Object.assign(new import_trust.TrustRecordUnavailableError(), { cause: error });
156
+ throw error;
157
+ }
158
+ if (binding.operator !== trust.operator) throw new import_trust.TrustMembershipError();
159
+ } catch (error) {
160
+ if (!(error instanceof import_trust.TrustRecordUnavailableError) || !error.lastKnownListed || !(access?.readOnly || access?.identityConfiguration))
161
+ throw error;
162
+ }
136
163
  const relationship = (await this.options.store.getApplication(origin))?.relationship;
137
164
  if (!access?.readOnly && relationship && (relationship.status !== "active" || relationship.expires_at && Date.parse(relationship.expires_at) <= this.now() * 1e3))
138
165
  throw new import_trust.IdentityAuthorizationError();
@@ -2,7 +2,12 @@ import { randomUUID } from "crypto";
2
2
  import { parse as parseTld } from "tldts";
3
3
  import { canonicalAgentOrigin } from "../signing/agent-resolver/canonicalize.mjs";
4
4
  import { eTldPlusOne } from "../signing/agent-resolver/etld.mjs";
5
- import { IdentityAuthorizationError, validateIdentity33Schema } from "./trust.mjs";
5
+ import {
6
+ IdentityAuthorizationError,
7
+ TrustMembershipError,
8
+ TrustRecordUnavailableError,
9
+ validateIdentity33Schema
10
+ } from "./trust.mjs";
6
11
  class InMemoryOriginIdentityStore {
7
12
  durability = "process-local";
8
13
  bindings = /* @__PURE__ */ new Map();
@@ -40,14 +45,20 @@ class InMemoryOriginIdentityStore {
40
45
  }
41
46
  }
42
47
  const BUYER_GATES = /* @__PURE__ */ new Set(["aao_verified", "storyboard", "sandbox", "experimental_feature"]);
43
- const SELLER_GATES = /* @__PURE__ */ new Set(["agent_identity", "grant", "billing_entity", "contract", "credit_application"]);
48
+ const SELLER_GATES = /* @__PURE__ */ new Set([
49
+ "agent_identity",
50
+ "grant",
51
+ "billing_entity",
52
+ "contract",
53
+ "credit_application"
54
+ ]);
44
55
  async function evaluateOnboardingRequirements(requirements, direction, check) {
45
56
  const relevant = direction === "seller" ? SELLER_GATES : BUYER_GATES;
46
57
  const wrong = direction === "seller" ? BUYER_GATES : SELLER_GATES;
47
58
  const unsatisfied = [];
48
59
  for (const requirement of requirements) {
49
60
  if (wrong.has(requirement.kind)) continue;
50
- const wellFormed = requirement.kind !== "aao_verified" || !!requirement.role && !!requirement.verification_modes?.length && !!requirement.specialisms?.length && !!requirement.adcp_version;
61
+ const wellFormed = requirement.kind !== "aao_verified" || !!requirement.role && !!requirement.verification_modes?.length && !!(requirement.verified_specialisms ?? requirement.specialisms)?.length && !!requirement.adcp_version;
51
62
  const hasId = !["storyboard", "experimental_feature"].includes(requirement.kind) || !!requirement.id;
52
63
  if (!relevant.has(requirement.kind) || !wellFormed || !hasId || !await check(requirement))
53
64
  unsatisfied.push(requirement);
@@ -100,13 +111,34 @@ class OriginIdentityLifecycle {
100
111
  await this.options.store.bind(binding);
101
112
  return binding;
102
113
  }
103
- /** Cryptographic verification does not call this. Authorization revalidates delisting. */
114
+ /**
115
+ * Cryptographic verification does not call this. Authorization revalidates
116
+ * delisting: the last record read does not list the origin (an empty
117
+ * `agents[]` retires it; a known delisting stays delisted through a failed
118
+ * refresh) and throws {@link TrustMembershipError}. An unreadable record
119
+ * (404/410 included) throws {@link TrustRecordUnavailableError} for spend;
120
+ * read-only and identity-configuration calls continue under the binding only
121
+ * while the last record read listed the origin and is within the evaluator's
122
+ * `maxOutageContinuationSeconds`.
123
+ */
104
124
  async authorizeBound(originUrl, access) {
105
125
  const origin = canonicalAgentOrigin(originUrl);
106
126
  const binding = await this.options.store.getBinding(origin);
107
127
  if (!binding) throw new IdentityAuthorizationError();
108
- const trust = await this.options.trust.match(origin, "adcp:buying");
109
- if (binding.operator !== trust.operator) throw new IdentityAuthorizationError();
128
+ try {
129
+ let trust;
130
+ try {
131
+ trust = await this.options.trust.match(origin, "adcp:buying");
132
+ } catch (error) {
133
+ if (error instanceof TrustMembershipError && error.membership === "absent")
134
+ throw Object.assign(new TrustRecordUnavailableError(), { cause: error });
135
+ throw error;
136
+ }
137
+ if (binding.operator !== trust.operator) throw new TrustMembershipError();
138
+ } catch (error) {
139
+ if (!(error instanceof TrustRecordUnavailableError) || !error.lastKnownListed || !(access?.readOnly || access?.identityConfiguration))
140
+ throw error;
141
+ }
110
142
  const relationship = (await this.options.store.getApplication(origin))?.relationship;
111
143
  if (!access?.readOnly && relationship && (relationship.status !== "active" || relationship.expires_at && Date.parse(relationship.expires_at) <= this.now() * 1e3))
112
144
  throw new IdentityAuthorizationError();