@pymthouse/builder-sdk 0.4.3 → 0.4.5

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 (60) hide show
  1. package/README.md +120 -5
  2. package/dist/{client-zCskUJag.d.ts → client-BhNz0ZAA.d.ts} +9 -3
  3. package/dist/{client-C0HgAugK.d.cts → client-GP-mTEI7.d.cts} +9 -3
  4. package/dist/device.d.cts +1 -1
  5. package/dist/device.d.ts +1 -1
  6. package/dist/env.cjs +40 -3
  7. package/dist/env.cjs.map +1 -1
  8. package/dist/env.d.cts +2 -2
  9. package/dist/env.d.ts +2 -2
  10. package/dist/env.js +40 -3
  11. package/dist/env.js.map +1 -1
  12. package/dist/errors-C9-V_zSi.d.cts +13 -0
  13. package/dist/errors-C9-V_zSi.d.ts +13 -0
  14. package/dist/{index-D5wdxNYy.d.cts → index-M0tsyotJ.d.cts} +2 -2
  15. package/dist/{index-DFJ6qcK0.d.ts → index-rC8smShg.d.ts} +2 -2
  16. package/dist/index.cjs +40 -3
  17. package/dist/index.cjs.map +1 -1
  18. package/dist/index.d.cts +6 -17
  19. package/dist/index.d.ts +6 -17
  20. package/dist/index.js +40 -3
  21. package/dist/index.js.map +1 -1
  22. package/dist/{proxy-KrA1vEmh.d.ts → proxy-CZLY0IfL.d.cts} +5 -2
  23. package/dist/{proxy-0wa8QZIU.d.cts → proxy-D36SpZ6k.d.ts} +5 -2
  24. package/dist/signer/gateway.cjs +542 -0
  25. package/dist/signer/gateway.cjs.map +1 -0
  26. package/dist/signer/gateway.d.cts +81 -0
  27. package/dist/signer/gateway.d.ts +81 -0
  28. package/dist/signer/gateway.js +538 -0
  29. package/dist/signer/gateway.js.map +1 -0
  30. package/dist/signer/server.cjs +225 -0
  31. package/dist/signer/server.cjs.map +1 -1
  32. package/dist/signer/server.d.cts +35 -4
  33. package/dist/signer/server.d.ts +35 -4
  34. package/dist/signer/server.js +219 -1
  35. package/dist/signer/server.js.map +1 -1
  36. package/dist/signer/webhook/adapters/api-key.d.cts +1 -1
  37. package/dist/signer/webhook/adapters/api-key.d.ts +1 -1
  38. package/dist/signer/webhook/adapters/composite.d.cts +1 -1
  39. package/dist/signer/webhook/adapters/composite.d.ts +1 -1
  40. package/dist/signer/webhook/adapters/oidc.cjs.map +1 -1
  41. package/dist/signer/webhook/adapters/oidc.d.cts +3 -3
  42. package/dist/signer/webhook/adapters/oidc.d.ts +3 -3
  43. package/dist/signer/webhook/adapters/oidc.js.map +1 -1
  44. package/dist/signer/webhook/adapters/trusted-headers.d.cts +1 -1
  45. package/dist/signer/webhook/adapters/trusted-headers.d.ts +1 -1
  46. package/dist/signer/webhook.cjs +40 -6
  47. package/dist/signer/webhook.cjs.map +1 -1
  48. package/dist/signer/webhook.d.cts +23 -6
  49. package/dist/signer/webhook.d.ts +23 -6
  50. package/dist/signer/webhook.js +37 -7
  51. package/dist/signer/webhook.js.map +1 -1
  52. package/dist/tokens.d.cts +1 -1
  53. package/dist/tokens.d.ts +1 -1
  54. package/dist/{types-BORaHW_x.d.cts → types-CcP67AZm.d.cts} +2 -0
  55. package/dist/{types-BORaHW_x.d.ts → types-CcP67AZm.d.ts} +2 -0
  56. package/dist/{verifier-Be9WAjFF.d.cts → verifier-D8z3spC0.d.cts} +2 -0
  57. package/dist/{verifier-Be9WAjFF.d.ts → verifier-D8z3spC0.d.ts} +2 -0
  58. package/dist/verify.d.cts +1 -1
  59. package/dist/verify.d.ts +1 -1
  60. package/package.json +6 -1
@@ -1,6 +1,7 @@
1
- import { C as CachedSignerToken, a as SignerTokenManagerOptions, F as ForwardDirectSignerRequestOptions, b as SignerJwtIdentity, M as MintUserSignerTokenOptions, D as DeviceExchangeHandlerConfig, c as DeviceExchangeHandlerConfigRemote, E as ExchangeDeviceTokenForSignerOptions, d as DeviceExchangeResponse, e as MintSignerTokenFromDeviceTokenOptions, f as DeviceExchangeMintResult, g as DeviceExchangeRequestBody, A as ApiKeyExchangeHandlerConfig, h as ExchangeApiKeyForSignerOptions, i as ApiKeyExchangeMintResult, j as ApiKeyExchangeRequestBody, k as DirectSignerProxyConfig } from '../proxy-0wa8QZIU.cjs';
2
- export { l as DeviceExchangeMintContext, m as DirectSignerBeforeSignContext, n as DirectSignerBeforeSignResult, o as ForwardToSignerOptions, p as ForwardToSignerResult, q as M2MClientCredentials, r as MintUserSignerTokenResponse, P as ProbeSignerHttpReachabilityOptions, s as SignerDmzGate, S as SignerUsageSnapshot, t as forwardToSigner, u as getCachedDmzBearerToken, v as normalizeSignerBaseUrl, w as parseSignerUsageSnapshot, x as pickConflictingNumberAliases, y as pickConflictingStringAliases, z as probeSignerHttpReachability, B as readSignerUpstreamBody, G as resolveSignerBaseUrl, H as stripSignerUsageFromResponse } from '../proxy-0wa8QZIU.cjs';
3
- import '../types-BORaHW_x.cjs';
1
+ import { C as CachedSignerToken, a as SignerTokenManagerOptions, F as ForwardDirectSignerRequestOptions, b as SignerJwtIdentity, M as MintUserSignerTokenOptions, D as DeviceExchangeHandlerConfig, c as DeviceExchangeHandlerConfigRemote, E as ExchangeDeviceTokenForSignerOptions, d as DeviceExchangeResponse, e as MintSignerTokenFromDeviceTokenOptions, f as DeviceExchangeMintResult, g as DeviceExchangeRequestBody, A as ApiKeyExchangeHandlerConfig, h as ExchangeApiKeyForSignerOptions, i as ApiKeyExchangeMintResult, j as ApiKeyExchangeRequestBody, k as DirectSignerProxyConfig } from '../proxy-CZLY0IfL.cjs';
2
+ export { l as DeviceExchangeMintContext, m as DirectSignerBeforeSignContext, n as DirectSignerBeforeSignResult, o as ForwardToSignerOptions, p as ForwardToSignerResult, q as M2MClientCredentials, r as MintUserSignerTokenResponse, P as ProbeSignerHttpReachabilityOptions, s as SignerDmzGate, S as SignerUsageSnapshot, t as forwardToSigner, u as getCachedDmzBearerToken, v as normalizeSignerBaseUrl, w as parseSignerUsageSnapshot, x as pickConflictingNumberAliases, y as pickConflictingStringAliases, z as probeSignerHttpReachability, B as readSignerUpstreamBody, G as resolveSignerBaseUrl, H as stripSignerUsageFromResponse } from '../proxy-CZLY0IfL.cjs';
3
+ export { GatewayTokenAuth, GatewayTokenBundle, GatewayTokenInput, MintGatewayTokenOptions, buildGatewayToken, decodeGatewayToken, mintGatewayToken } from './gateway.cjs';
4
+ import '../types-CcP67AZm.cjs';
4
5
 
5
6
  interface SignerTokenManager {
6
7
  getToken(publicClientId: string, externalUserId: string, options?: {
@@ -59,6 +60,36 @@ declare function mintSignerSessionFromApiKey(input: {
59
60
  declare function exchangeApiKeyForSigner(options: ExchangeApiKeyForSignerOptions): Promise<DeviceExchangeResponse>;
60
61
  declare function createApiKeyExchangeHandler(config: ApiKeyExchangeHandlerConfig): (request: Request) => Promise<Response>;
61
62
 
63
+ /** Remote signer paths clients call directly after exchange (never via dashboard proxy). */
64
+ declare const DIRECT_SIGNER_PATHS: {
65
+ readonly signOrchestratorInfo: "sign-orchestrator-info";
66
+ readonly generateLivePayment: "generate-live-payment";
67
+ readonly discoverOrchestrators: "discover-orchestrators";
68
+ };
69
+ type DirectSignerPath = (typeof DIRECT_SIGNER_PATHS)[keyof typeof DIRECT_SIGNER_PATHS];
70
+ /**
71
+ * Build a direct remote-signer URL from a DMZ base returned by exchange handlers.
72
+ * The base must be the signer service origin (e.g. `https://signer.example`), not a
73
+ * dashboard `/api/signer/*` proxy route.
74
+ */
75
+ declare function signerEndpointUrl(signerBaseUrl: string, path: DirectSignerPath | (string & {})): string;
76
+ /** Read `signerUrl` from an exchange response envelope. */
77
+ declare function signerUrlFromExchangeResponse(response: Pick<DeviceExchangeResponse, "signerUrl">): string | undefined;
78
+ /**
79
+ * Reject dashboard-style signer proxy bases. Exchange facades mint JWTs only;
80
+ * signing RPCs must target the remote signer DMZ directly.
81
+ *
82
+ * Parses the URL and inspects its pathname rather than running a regex over the
83
+ * raw string, which both avoids super-linear backtracking on adversarial input
84
+ * and rejects every `/api/signer` and `/api/signer/*` route (not just the three
85
+ * known endpoint suffixes).
86
+ *
87
+ * @param signerBaseUrl - Absolute signer base URL to validate.
88
+ * @throws {PmtHouseError} When the URL is not absolute or points at a dashboard
89
+ * `/api/signer` proxy path.
90
+ */
91
+ declare function assertDirectSignerBaseUrl(signerBaseUrl: string): void;
92
+
62
93
  interface DirectSignerProxyHandler {
63
94
  (request: Request): Promise<Response>;
64
95
  getCachedUsage(publicClientId: string, externalUserId: string): CachedSignerToken | undefined;
@@ -66,4 +97,4 @@ interface DirectSignerProxyHandler {
66
97
  }
67
98
  declare function createDirectSignerProxyHandler(config: DirectSignerProxyConfig): DirectSignerProxyHandler;
68
99
 
69
- export { ApiKeyExchangeHandlerConfig, ApiKeyExchangeMintResult, ApiKeyExchangeRequestBody, CachedSignerToken, DeviceExchangeHandlerConfig, DeviceExchangeHandlerConfigRemote, DeviceExchangeMintResult, DeviceExchangeRequestBody, DeviceExchangeResponse, DirectSignerProxyConfig, type DirectSignerProxyHandler, ExchangeApiKeyForSignerOptions, ExchangeDeviceTokenForSignerOptions, ForwardDirectSignerRequestOptions, LIVEPEER_REMOTE_SIGNER_AUDIENCE, MintSignerTokenFromDeviceTokenOptions, MintUserSignerTokenOptions, SIGN_MINT_USER_TOKEN_SCOPE, SignerJwtIdentity, type SignerTokenManager, SignerTokenManagerOptions, createApiKeyExchangeHandler, createDeviceExchangeHandler, createDirectSignerProxyHandler, createSignerTokenManager, decodeJwtPayload, exchangeApiKeyForSigner, exchangeDeviceTokenForSigner, extractSignerAccessTokenFromExchangeBody, forwardDirectSignerRequest, identityFromJwtPayload, livepeerIdentityHeaders, mintSignerSessionFromApiKey, mintSignerTokenFromDeviceToken, mintUserAccessTokenFromApiKey, mintUserSignerToken, normalizeDeviceExchangeResponse, parseApiKeyExchangeRequestBody, parseDeviceExchangeRequestBody, parseMintUserSignerTokenResponse, signerJwtAudience };
100
+ export { ApiKeyExchangeHandlerConfig, ApiKeyExchangeMintResult, ApiKeyExchangeRequestBody, CachedSignerToken, DIRECT_SIGNER_PATHS, DeviceExchangeHandlerConfig, DeviceExchangeHandlerConfigRemote, DeviceExchangeMintResult, DeviceExchangeRequestBody, DeviceExchangeResponse, type DirectSignerPath, DirectSignerProxyConfig, type DirectSignerProxyHandler, ExchangeApiKeyForSignerOptions, ExchangeDeviceTokenForSignerOptions, ForwardDirectSignerRequestOptions, LIVEPEER_REMOTE_SIGNER_AUDIENCE, MintSignerTokenFromDeviceTokenOptions, MintUserSignerTokenOptions, SIGN_MINT_USER_TOKEN_SCOPE, SignerJwtIdentity, type SignerTokenManager, SignerTokenManagerOptions, assertDirectSignerBaseUrl, createApiKeyExchangeHandler, createDeviceExchangeHandler, createDirectSignerProxyHandler, createSignerTokenManager, decodeJwtPayload, exchangeApiKeyForSigner, exchangeDeviceTokenForSigner, extractSignerAccessTokenFromExchangeBody, forwardDirectSignerRequest, identityFromJwtPayload, livepeerIdentityHeaders, mintSignerSessionFromApiKey, mintSignerTokenFromDeviceToken, mintUserAccessTokenFromApiKey, mintUserSignerToken, normalizeDeviceExchangeResponse, parseApiKeyExchangeRequestBody, parseDeviceExchangeRequestBody, parseMintUserSignerTokenResponse, signerEndpointUrl, signerJwtAudience, signerUrlFromExchangeResponse };
@@ -1,6 +1,7 @@
1
- import { C as CachedSignerToken, a as SignerTokenManagerOptions, F as ForwardDirectSignerRequestOptions, b as SignerJwtIdentity, M as MintUserSignerTokenOptions, D as DeviceExchangeHandlerConfig, c as DeviceExchangeHandlerConfigRemote, E as ExchangeDeviceTokenForSignerOptions, d as DeviceExchangeResponse, e as MintSignerTokenFromDeviceTokenOptions, f as DeviceExchangeMintResult, g as DeviceExchangeRequestBody, A as ApiKeyExchangeHandlerConfig, h as ExchangeApiKeyForSignerOptions, i as ApiKeyExchangeMintResult, j as ApiKeyExchangeRequestBody, k as DirectSignerProxyConfig } from '../proxy-KrA1vEmh.js';
2
- export { l as DeviceExchangeMintContext, m as DirectSignerBeforeSignContext, n as DirectSignerBeforeSignResult, o as ForwardToSignerOptions, p as ForwardToSignerResult, q as M2MClientCredentials, r as MintUserSignerTokenResponse, P as ProbeSignerHttpReachabilityOptions, s as SignerDmzGate, S as SignerUsageSnapshot, t as forwardToSigner, u as getCachedDmzBearerToken, v as normalizeSignerBaseUrl, w as parseSignerUsageSnapshot, x as pickConflictingNumberAliases, y as pickConflictingStringAliases, z as probeSignerHttpReachability, B as readSignerUpstreamBody, G as resolveSignerBaseUrl, H as stripSignerUsageFromResponse } from '../proxy-KrA1vEmh.js';
3
- import '../types-BORaHW_x.js';
1
+ import { C as CachedSignerToken, a as SignerTokenManagerOptions, F as ForwardDirectSignerRequestOptions, b as SignerJwtIdentity, M as MintUserSignerTokenOptions, D as DeviceExchangeHandlerConfig, c as DeviceExchangeHandlerConfigRemote, E as ExchangeDeviceTokenForSignerOptions, d as DeviceExchangeResponse, e as MintSignerTokenFromDeviceTokenOptions, f as DeviceExchangeMintResult, g as DeviceExchangeRequestBody, A as ApiKeyExchangeHandlerConfig, h as ExchangeApiKeyForSignerOptions, i as ApiKeyExchangeMintResult, j as ApiKeyExchangeRequestBody, k as DirectSignerProxyConfig } from '../proxy-D36SpZ6k.js';
2
+ export { l as DeviceExchangeMintContext, m as DirectSignerBeforeSignContext, n as DirectSignerBeforeSignResult, o as ForwardToSignerOptions, p as ForwardToSignerResult, q as M2MClientCredentials, r as MintUserSignerTokenResponse, P as ProbeSignerHttpReachabilityOptions, s as SignerDmzGate, S as SignerUsageSnapshot, t as forwardToSigner, u as getCachedDmzBearerToken, v as normalizeSignerBaseUrl, w as parseSignerUsageSnapshot, x as pickConflictingNumberAliases, y as pickConflictingStringAliases, z as probeSignerHttpReachability, B as readSignerUpstreamBody, G as resolveSignerBaseUrl, H as stripSignerUsageFromResponse } from '../proxy-D36SpZ6k.js';
3
+ export { GatewayTokenAuth, GatewayTokenBundle, GatewayTokenInput, MintGatewayTokenOptions, buildGatewayToken, decodeGatewayToken, mintGatewayToken } from './gateway.js';
4
+ import '../types-CcP67AZm.js';
4
5
 
5
6
  interface SignerTokenManager {
6
7
  getToken(publicClientId: string, externalUserId: string, options?: {
@@ -59,6 +60,36 @@ declare function mintSignerSessionFromApiKey(input: {
59
60
  declare function exchangeApiKeyForSigner(options: ExchangeApiKeyForSignerOptions): Promise<DeviceExchangeResponse>;
60
61
  declare function createApiKeyExchangeHandler(config: ApiKeyExchangeHandlerConfig): (request: Request) => Promise<Response>;
61
62
 
63
+ /** Remote signer paths clients call directly after exchange (never via dashboard proxy). */
64
+ declare const DIRECT_SIGNER_PATHS: {
65
+ readonly signOrchestratorInfo: "sign-orchestrator-info";
66
+ readonly generateLivePayment: "generate-live-payment";
67
+ readonly discoverOrchestrators: "discover-orchestrators";
68
+ };
69
+ type DirectSignerPath = (typeof DIRECT_SIGNER_PATHS)[keyof typeof DIRECT_SIGNER_PATHS];
70
+ /**
71
+ * Build a direct remote-signer URL from a DMZ base returned by exchange handlers.
72
+ * The base must be the signer service origin (e.g. `https://signer.example`), not a
73
+ * dashboard `/api/signer/*` proxy route.
74
+ */
75
+ declare function signerEndpointUrl(signerBaseUrl: string, path: DirectSignerPath | (string & {})): string;
76
+ /** Read `signerUrl` from an exchange response envelope. */
77
+ declare function signerUrlFromExchangeResponse(response: Pick<DeviceExchangeResponse, "signerUrl">): string | undefined;
78
+ /**
79
+ * Reject dashboard-style signer proxy bases. Exchange facades mint JWTs only;
80
+ * signing RPCs must target the remote signer DMZ directly.
81
+ *
82
+ * Parses the URL and inspects its pathname rather than running a regex over the
83
+ * raw string, which both avoids super-linear backtracking on adversarial input
84
+ * and rejects every `/api/signer` and `/api/signer/*` route (not just the three
85
+ * known endpoint suffixes).
86
+ *
87
+ * @param signerBaseUrl - Absolute signer base URL to validate.
88
+ * @throws {PmtHouseError} When the URL is not absolute or points at a dashboard
89
+ * `/api/signer` proxy path.
90
+ */
91
+ declare function assertDirectSignerBaseUrl(signerBaseUrl: string): void;
92
+
62
93
  interface DirectSignerProxyHandler {
63
94
  (request: Request): Promise<Response>;
64
95
  getCachedUsage(publicClientId: string, externalUserId: string): CachedSignerToken | undefined;
@@ -66,4 +97,4 @@ interface DirectSignerProxyHandler {
66
97
  }
67
98
  declare function createDirectSignerProxyHandler(config: DirectSignerProxyConfig): DirectSignerProxyHandler;
68
99
 
69
- export { ApiKeyExchangeHandlerConfig, ApiKeyExchangeMintResult, ApiKeyExchangeRequestBody, CachedSignerToken, DeviceExchangeHandlerConfig, DeviceExchangeHandlerConfigRemote, DeviceExchangeMintResult, DeviceExchangeRequestBody, DeviceExchangeResponse, DirectSignerProxyConfig, type DirectSignerProxyHandler, ExchangeApiKeyForSignerOptions, ExchangeDeviceTokenForSignerOptions, ForwardDirectSignerRequestOptions, LIVEPEER_REMOTE_SIGNER_AUDIENCE, MintSignerTokenFromDeviceTokenOptions, MintUserSignerTokenOptions, SIGN_MINT_USER_TOKEN_SCOPE, SignerJwtIdentity, type SignerTokenManager, SignerTokenManagerOptions, createApiKeyExchangeHandler, createDeviceExchangeHandler, createDirectSignerProxyHandler, createSignerTokenManager, decodeJwtPayload, exchangeApiKeyForSigner, exchangeDeviceTokenForSigner, extractSignerAccessTokenFromExchangeBody, forwardDirectSignerRequest, identityFromJwtPayload, livepeerIdentityHeaders, mintSignerSessionFromApiKey, mintSignerTokenFromDeviceToken, mintUserAccessTokenFromApiKey, mintUserSignerToken, normalizeDeviceExchangeResponse, parseApiKeyExchangeRequestBody, parseDeviceExchangeRequestBody, parseMintUserSignerTokenResponse, signerJwtAudience };
100
+ export { ApiKeyExchangeHandlerConfig, ApiKeyExchangeMintResult, ApiKeyExchangeRequestBody, CachedSignerToken, DIRECT_SIGNER_PATHS, DeviceExchangeHandlerConfig, DeviceExchangeHandlerConfigRemote, DeviceExchangeMintResult, DeviceExchangeRequestBody, DeviceExchangeResponse, type DirectSignerPath, DirectSignerProxyConfig, type DirectSignerProxyHandler, ExchangeApiKeyForSignerOptions, ExchangeDeviceTokenForSignerOptions, ForwardDirectSignerRequestOptions, LIVEPEER_REMOTE_SIGNER_AUDIENCE, MintSignerTokenFromDeviceTokenOptions, MintUserSignerTokenOptions, SIGN_MINT_USER_TOKEN_SCOPE, SignerJwtIdentity, type SignerTokenManager, SignerTokenManagerOptions, assertDirectSignerBaseUrl, createApiKeyExchangeHandler, createDeviceExchangeHandler, createDirectSignerProxyHandler, createSignerTokenManager, decodeJwtPayload, exchangeApiKeyForSigner, exchangeDeviceTokenForSigner, extractSignerAccessTokenFromExchangeBody, forwardDirectSignerRequest, identityFromJwtPayload, livepeerIdentityHeaders, mintSignerSessionFromApiKey, mintSignerTokenFromDeviceToken, mintUserAccessTokenFromApiKey, mintUserSignerToken, normalizeDeviceExchangeResponse, parseApiKeyExchangeRequestBody, parseDeviceExchangeRequestBody, parseMintUserSignerTokenResponse, signerEndpointUrl, signerJwtAudience, signerUrlFromExchangeResponse };
@@ -450,6 +450,46 @@ async function mintUserSignerToken(options) {
450
450
  return parseMintUserSignerTokenResponse(parsed);
451
451
  }
452
452
 
453
+ // src/signer/direct-signer.ts
454
+ var DIRECT_SIGNER_PATHS = {
455
+ signOrchestratorInfo: "sign-orchestrator-info",
456
+ generateLivePayment: "generate-live-payment",
457
+ discoverOrchestrators: "discover-orchestrators"
458
+ };
459
+ function signerEndpointUrl(signerBaseUrl, path) {
460
+ const base = stripTrailingSlashes(signerBaseUrl.trim());
461
+ if (!base) {
462
+ throw new PmtHouseError("signerBaseUrl is required", {
463
+ status: 400,
464
+ code: "invalid_signer_url"
465
+ });
466
+ }
467
+ const suffix = path.replace(/^\/+/, "");
468
+ return `${base}/${suffix}`;
469
+ }
470
+ function signerUrlFromExchangeResponse(response) {
471
+ const url = response.signerUrl?.trim();
472
+ return url || void 0;
473
+ }
474
+ function assertDirectSignerBaseUrl(signerBaseUrl) {
475
+ let parsed;
476
+ try {
477
+ parsed = new URL(signerBaseUrl.trim());
478
+ } catch {
479
+ throw new PmtHouseError("signer URL must be an absolute http(s) URL", {
480
+ status: 400,
481
+ code: "invalid_signer_url"
482
+ });
483
+ }
484
+ const pathname = stripTrailingSlashes(parsed.pathname);
485
+ if (pathname === "/api/signer" || pathname.startsWith("/api/signer/")) {
486
+ throw new PmtHouseError(
487
+ "signer URL must be the remote signer DMZ base, not a dashboard /api/signer/* proxy path. Exchange at the platform facade, then call signer endpoints directly using signerUrl from the exchange response.",
488
+ { status: 400, code: "invalid_signer_url" }
489
+ );
490
+ }
491
+ }
492
+
453
493
  // src/signer/device-exchange.ts
454
494
  var TOKEN_EXCHANGE_GRANT = "urn:ietf:params:oauth:grant-type:token-exchange";
455
495
  var SUBJECT_ACCESS_TOKEN_TYPE = "urn:ietf:params:oauth:token-type:access_token";
@@ -607,6 +647,9 @@ async function exchangeDeviceTokenForSigner(options) {
607
647
  const accessToken = extractSignerAccessTokenFromExchangeBody(parsed);
608
648
  const signerUrlRaw = parsed.signerUrl ?? parsed.signer_url;
609
649
  const signerUrl = typeof signerUrlRaw === "string" && signerUrlRaw.trim() ? signerUrlRaw.trim() : void 0;
650
+ if (signerUrl) {
651
+ assertDirectSignerBaseUrl(signerUrl);
652
+ }
610
653
  return normalizeDeviceExchangeResponse(
611
654
  {
612
655
  access_token: accessToken,
@@ -786,6 +829,9 @@ async function exchangeApiKeyForSigner(options) {
786
829
  const accessToken = extractSignerAccessTokenFromExchangeBody(parsed);
787
830
  const signerUrlRaw = parsed.signerUrl ?? parsed.signer_url;
788
831
  const signerUrl = typeof signerUrlRaw === "string" && signerUrlRaw.trim() ? signerUrlRaw.trim() : void 0;
832
+ if (signerUrl) {
833
+ assertDirectSignerBaseUrl(signerUrl);
834
+ }
789
835
  return normalizeDeviceExchangeResponse(
790
836
  {
791
837
  access_token: accessToken,
@@ -841,6 +887,178 @@ function createApiKeyExchangeHandler(config) {
841
887
  };
842
888
  }
843
889
 
890
+ // src/signer/gateway-token.ts
891
+ function requireString(value, label) {
892
+ if (typeof value !== "string") {
893
+ throw new PmtHouseError(`${label} must be a string`, {
894
+ status: 400,
895
+ code: "invalid_gateway_token"
896
+ });
897
+ }
898
+ return value.trim();
899
+ }
900
+ function optionalString(value, label) {
901
+ if (value === void 0 || value === null) {
902
+ return void 0;
903
+ }
904
+ return requireString(value, label) || void 0;
905
+ }
906
+ function encodeBase64Json(value) {
907
+ const json = JSON.stringify(value);
908
+ if (typeof Buffer === "undefined") {
909
+ const binary = Array.from(
910
+ new TextEncoder().encode(json),
911
+ (c) => String.fromCodePoint(c)
912
+ ).join("");
913
+ return btoa(binary);
914
+ }
915
+ return Buffer.from(json, "utf8").toString("base64");
916
+ }
917
+ function decodeBase64Json(token) {
918
+ const trimmed = requireString(token, "gateway token");
919
+ let json;
920
+ try {
921
+ if (typeof Buffer === "undefined") {
922
+ json = new TextDecoder().decode(
923
+ Uint8Array.from(atob(trimmed), (c) => c.codePointAt(0) ?? 0)
924
+ );
925
+ } else {
926
+ json = Buffer.from(trimmed, "base64").toString("utf8");
927
+ }
928
+ } catch {
929
+ throw new PmtHouseError("Invalid gateway token: expected base64-encoded JSON", {
930
+ status: 400,
931
+ code: "invalid_gateway_token"
932
+ });
933
+ }
934
+ try {
935
+ return JSON.parse(json);
936
+ } catch {
937
+ throw new PmtHouseError("Invalid gateway token: expected UTF-8 JSON payload", {
938
+ status: 400,
939
+ code: "invalid_gateway_token"
940
+ });
941
+ }
942
+ }
943
+ function normalizeStringMap(map) {
944
+ if (!map) {
945
+ return void 0;
946
+ }
947
+ const entries = Object.entries(map).filter(
948
+ ([key, value]) => key.trim() && typeof value === "string"
949
+ );
950
+ return entries.length > 0 ? Object.fromEntries(entries) : void 0;
951
+ }
952
+ function buildGatewayToken(input) {
953
+ if (input === null || typeof input !== "object") {
954
+ throw new PmtHouseError("buildGatewayToken requires an input object", {
955
+ status: 400,
956
+ code: "invalid_gateway_token"
957
+ });
958
+ }
959
+ const signer = requireString(input.signer, "signer URL");
960
+ if (!signer) {
961
+ throw new PmtHouseError("buildGatewayToken requires a non-empty signer URL", {
962
+ status: 400,
963
+ code: "invalid_gateway_token"
964
+ });
965
+ }
966
+ const signerHeaders = { ...input.signerHeaders };
967
+ const bundle = { signer };
968
+ const discovery = optionalString(input.discovery, "discovery URL");
969
+ if (discovery) {
970
+ bundle.discovery = discovery;
971
+ }
972
+ const rawOrchestrators = input.orchestrators ?? [];
973
+ if (!Array.isArray(rawOrchestrators)) {
974
+ throw new PmtHouseError("orchestrators must be an array of strings", {
975
+ status: 400,
976
+ code: "invalid_gateway_token"
977
+ });
978
+ }
979
+ const orchestrators = rawOrchestrators.map((entry) => requireString(entry, "orchestrator entry")).filter((entry) => entry.length > 0);
980
+ if (orchestrators.length > 0) {
981
+ bundle.orchestrators = orchestrators;
982
+ }
983
+ if (input.auth?.kind === "signerJwt") {
984
+ const accessToken = requireString(input.auth.accessToken, "signerJwt accessToken");
985
+ if (!accessToken) {
986
+ throw new PmtHouseError("signerJwt auth requires a non-empty accessToken", {
987
+ status: 400,
988
+ code: "invalid_gateway_token"
989
+ });
990
+ }
991
+ signerHeaders.Authorization = `Bearer ${accessToken}`;
992
+ } else if (input.auth?.kind === "pmthApiKey") {
993
+ const apiKey = requireString(input.auth.apiKey, "pmthApiKey apiKey");
994
+ if (!apiKey) {
995
+ throw new PmtHouseError("pmthApiKey auth requires a non-empty apiKey", {
996
+ status: 400,
997
+ code: "invalid_gateway_token"
998
+ });
999
+ }
1000
+ bundle.api_key = apiKey;
1001
+ const billing = optionalString(input.auth.billing, "pmthApiKey billing URL");
1002
+ if (billing) {
1003
+ bundle.billing = billing;
1004
+ }
1005
+ }
1006
+ const normalizedSignerHeaders = normalizeStringMap(signerHeaders);
1007
+ if (normalizedSignerHeaders) {
1008
+ bundle.signer_headers = normalizedSignerHeaders;
1009
+ }
1010
+ const normalizedDiscoveryHeaders = normalizeStringMap(input.discoveryHeaders);
1011
+ if (normalizedDiscoveryHeaders) {
1012
+ bundle.discovery_headers = normalizedDiscoveryHeaders;
1013
+ }
1014
+ return encodeBase64Json(bundle);
1015
+ }
1016
+ function decodeGatewayToken(token) {
1017
+ const payload = decodeBase64Json(token);
1018
+ if (payload === null || typeof payload !== "object" || Array.isArray(payload)) {
1019
+ throw new PmtHouseError("Invalid gateway token: payload must be a JSON object", {
1020
+ status: 400,
1021
+ code: "invalid_gateway_token"
1022
+ });
1023
+ }
1024
+ return payload;
1025
+ }
1026
+ async function mintGatewayToken(options) {
1027
+ let accessToken;
1028
+ if (options.source === "m2m") {
1029
+ const minted = await mintUserSignerToken({
1030
+ issuerUrl: options.issuerUrl,
1031
+ m2mClientId: options.m2mClientId,
1032
+ m2mClientSecret: options.m2mClientSecret,
1033
+ externalUserId: options.externalUserId,
1034
+ fetch: options.fetch,
1035
+ allowInsecureHttp: options.allowInsecureHttp
1036
+ });
1037
+ accessToken = minted.jwt;
1038
+ } else {
1039
+ const minted = await mintSignerSessionFromApiKey({
1040
+ issuerUrl: options.issuerUrl,
1041
+ publicClientId: options.publicClientId,
1042
+ m2mClientId: options.m2mClientId,
1043
+ m2mClientSecret: options.m2mClientSecret,
1044
+ apiKey: options.apiKey,
1045
+ scope: options.scope,
1046
+ audience: options.audience,
1047
+ fetch: options.fetch,
1048
+ allowInsecureHttp: options.allowInsecureHttp
1049
+ });
1050
+ accessToken = minted.access_token;
1051
+ }
1052
+ return buildGatewayToken({
1053
+ signer: options.signer,
1054
+ discovery: options.discovery,
1055
+ orchestrators: options.orchestrators,
1056
+ signerHeaders: options.signerHeaders,
1057
+ discoveryHeaders: options.discoveryHeaders,
1058
+ auth: { kind: "signerJwt", accessToken }
1059
+ });
1060
+ }
1061
+
844
1062
  // src/signer/proxy.ts
845
1063
  var HTTP_DMZ_TOKEN_MAX_ENTRIES = 100;
846
1064
  var HTTP_DMZ_TOKEN_TTL_MS = 3.5 * 60 * 1e3;
@@ -1249,6 +1467,6 @@ function createDirectSignerProxyHandler(config) {
1249
1467
  return handler;
1250
1468
  }
1251
1469
 
1252
- export { LIVEPEER_REMOTE_SIGNER_AUDIENCE, SIGN_MINT_USER_TOKEN_SCOPE, createApiKeyExchangeHandler, createDeviceExchangeHandler, createDirectSignerProxyHandler, createSignerTokenManager, decodeJwtPayload, exchangeApiKeyForSigner, exchangeDeviceTokenForSigner, extractSignerAccessTokenFromExchangeBody, forwardDirectSignerRequest, forwardToSigner, getCachedDmzBearerToken, identityFromJwtPayload, livepeerIdentityHeaders, mintSignerSessionFromApiKey, mintSignerTokenFromDeviceToken, mintUserAccessTokenFromApiKey, mintUserSignerToken, normalizeDeviceExchangeResponse, normalizeSignerBaseUrl, parseApiKeyExchangeRequestBody, parseDeviceExchangeRequestBody, parseMintUserSignerTokenResponse, parseSignerUsageSnapshot, pickConflictingNumberAliases, pickConflictingStringAliases, probeSignerHttpReachability, readSignerUpstreamBody, resolveSignerBaseUrl, signerJwtAudience, stripSignerUsageFromResponse };
1470
+ export { DIRECT_SIGNER_PATHS, LIVEPEER_REMOTE_SIGNER_AUDIENCE, SIGN_MINT_USER_TOKEN_SCOPE, assertDirectSignerBaseUrl, buildGatewayToken, createApiKeyExchangeHandler, createDeviceExchangeHandler, createDirectSignerProxyHandler, createSignerTokenManager, decodeGatewayToken, decodeJwtPayload, exchangeApiKeyForSigner, exchangeDeviceTokenForSigner, extractSignerAccessTokenFromExchangeBody, forwardDirectSignerRequest, forwardToSigner, getCachedDmzBearerToken, identityFromJwtPayload, livepeerIdentityHeaders, mintGatewayToken, mintSignerSessionFromApiKey, mintSignerTokenFromDeviceToken, mintUserAccessTokenFromApiKey, mintUserSignerToken, normalizeDeviceExchangeResponse, normalizeSignerBaseUrl, parseApiKeyExchangeRequestBody, parseDeviceExchangeRequestBody, parseMintUserSignerTokenResponse, parseSignerUsageSnapshot, pickConflictingNumberAliases, pickConflictingStringAliases, probeSignerHttpReachability, readSignerUpstreamBody, resolveSignerBaseUrl, signerEndpointUrl, signerJwtAudience, signerUrlFromExchangeResponse, stripSignerUsageFromResponse };
1253
1471
  //# sourceMappingURL=server.js.map
1254
1472
  //# sourceMappingURL=server.js.map