@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.
- package/README.md +120 -5
- package/dist/{client-zCskUJag.d.ts → client-BhNz0ZAA.d.ts} +9 -3
- package/dist/{client-C0HgAugK.d.cts → client-GP-mTEI7.d.cts} +9 -3
- package/dist/device.d.cts +1 -1
- package/dist/device.d.ts +1 -1
- package/dist/env.cjs +40 -3
- package/dist/env.cjs.map +1 -1
- package/dist/env.d.cts +2 -2
- package/dist/env.d.ts +2 -2
- package/dist/env.js +40 -3
- package/dist/env.js.map +1 -1
- package/dist/errors-C9-V_zSi.d.cts +13 -0
- package/dist/errors-C9-V_zSi.d.ts +13 -0
- package/dist/{index-D5wdxNYy.d.cts → index-M0tsyotJ.d.cts} +2 -2
- package/dist/{index-DFJ6qcK0.d.ts → index-rC8smShg.d.ts} +2 -2
- package/dist/index.cjs +40 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -17
- package/dist/index.d.ts +6 -17
- package/dist/index.js +40 -3
- package/dist/index.js.map +1 -1
- package/dist/{proxy-KrA1vEmh.d.ts → proxy-CZLY0IfL.d.cts} +5 -2
- package/dist/{proxy-0wa8QZIU.d.cts → proxy-D36SpZ6k.d.ts} +5 -2
- package/dist/signer/gateway.cjs +542 -0
- package/dist/signer/gateway.cjs.map +1 -0
- package/dist/signer/gateway.d.cts +81 -0
- package/dist/signer/gateway.d.ts +81 -0
- package/dist/signer/gateway.js +538 -0
- package/dist/signer/gateway.js.map +1 -0
- package/dist/signer/server.cjs +225 -0
- package/dist/signer/server.cjs.map +1 -1
- package/dist/signer/server.d.cts +35 -4
- package/dist/signer/server.d.ts +35 -4
- package/dist/signer/server.js +219 -1
- package/dist/signer/server.js.map +1 -1
- package/dist/signer/webhook/adapters/api-key.d.cts +1 -1
- package/dist/signer/webhook/adapters/api-key.d.ts +1 -1
- package/dist/signer/webhook/adapters/composite.d.cts +1 -1
- package/dist/signer/webhook/adapters/composite.d.ts +1 -1
- package/dist/signer/webhook/adapters/oidc.cjs.map +1 -1
- package/dist/signer/webhook/adapters/oidc.d.cts +3 -3
- package/dist/signer/webhook/adapters/oidc.d.ts +3 -3
- package/dist/signer/webhook/adapters/oidc.js.map +1 -1
- package/dist/signer/webhook/adapters/trusted-headers.d.cts +1 -1
- package/dist/signer/webhook/adapters/trusted-headers.d.ts +1 -1
- package/dist/signer/webhook.cjs +40 -6
- package/dist/signer/webhook.cjs.map +1 -1
- package/dist/signer/webhook.d.cts +23 -6
- package/dist/signer/webhook.d.ts +23 -6
- package/dist/signer/webhook.js +37 -7
- package/dist/signer/webhook.js.map +1 -1
- package/dist/tokens.d.cts +1 -1
- package/dist/tokens.d.ts +1 -1
- package/dist/{types-BORaHW_x.d.cts → types-CcP67AZm.d.cts} +2 -0
- package/dist/{types-BORaHW_x.d.ts → types-CcP67AZm.d.ts} +2 -0
- package/dist/{verifier-Be9WAjFF.d.cts → verifier-D8z3spC0.d.cts} +2 -0
- package/dist/{verifier-Be9WAjFF.d.ts → verifier-D8z3spC0.d.ts} +2 -0
- package/dist/verify.d.cts +1 -1
- package/dist/verify.d.ts +1 -1
- package/package.json +6 -1
package/README.md
CHANGED
|
@@ -70,20 +70,78 @@ For advanced flows that already have a user JWT, call
|
|
|
70
70
|
|
|
71
71
|
### Dashboard API keys (long-lived `pmth_*`)
|
|
72
72
|
|
|
73
|
-
Create a key in the Dashboard **API keys** page, then exchange it for a
|
|
74
|
-
|
|
73
|
+
Create a key in the Dashboard **API keys** page, then exchange it for a short-lived
|
|
74
|
+
signer JWT without repeating device login. The facade mints credentials only;
|
|
75
|
+
signing RPCs go **directly to the remote signer DMZ** returned as `signerUrl`.
|
|
76
|
+
|
|
77
|
+
```ts
|
|
78
|
+
import {
|
|
79
|
+
DIRECT_SIGNER_PATHS,
|
|
80
|
+
exchangeApiKeyForSigner,
|
|
81
|
+
signerEndpointUrl,
|
|
82
|
+
} from "@pymthouse/builder-sdk/signer/server";
|
|
83
|
+
|
|
84
|
+
const session = await exchangeApiKeyForSigner({
|
|
85
|
+
facadeUrl: process.env.DASHBOARD_ORIGIN!, // exchange only
|
|
86
|
+
apiKey: process.env.PMTH_API_KEY!,
|
|
87
|
+
scope: "sign:job",
|
|
88
|
+
clientId: process.env.PYMTHOUSE_PUBLIC_CLIENT_ID!,
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
const signerBase = session.signerUrl!; // remote signer DMZ from exchange
|
|
92
|
+
const orchInfo = await fetch(
|
|
93
|
+
signerEndpointUrl(signerBase, DIRECT_SIGNER_PATHS.signOrchestratorInfo),
|
|
94
|
+
{
|
|
95
|
+
method: "POST",
|
|
96
|
+
headers: {
|
|
97
|
+
Authorization: `Bearer ${session.access_token}`,
|
|
98
|
+
"Content-Type": "application/json",
|
|
99
|
+
},
|
|
100
|
+
body: JSON.stringify({ /* ... */ }),
|
|
101
|
+
},
|
|
102
|
+
);
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Or via `PmtHouseClient` (returns `signerUrl` when using `facadeUrl`):
|
|
75
106
|
|
|
76
107
|
```ts
|
|
77
108
|
const session = await client.exchangeApiKeyForSignerSession({
|
|
78
109
|
apiKey: process.env.PMTH_API_KEY!,
|
|
79
|
-
facadeUrl: process.env.DASHBOARD_ORIGIN!,
|
|
110
|
+
facadeUrl: process.env.DASHBOARD_ORIGIN!,
|
|
80
111
|
scope: "sign:job",
|
|
81
112
|
});
|
|
82
|
-
// session.access_token —
|
|
113
|
+
// session.access_token — short-lived signer JWT
|
|
114
|
+
// session.signerUrl — remote signer DMZ base (call signer RPCs here directly)
|
|
83
115
|
```
|
|
84
116
|
|
|
85
117
|
See `examples/stream-with-api-key.mjs` for a minimal Node script.
|
|
86
118
|
|
|
119
|
+
### Exchange then direct signer (architecture)
|
|
120
|
+
|
|
121
|
+
```mermaid
|
|
122
|
+
sequenceDiagram
|
|
123
|
+
participant Client
|
|
124
|
+
participant Facade as PlatformFacade
|
|
125
|
+
participant Issuer as PymtHouseIssuer
|
|
126
|
+
participant Signer as RemoteSignerDMZ
|
|
127
|
+
|
|
128
|
+
Client->>Facade: POST /api/pymthouse/keys/exchange (pmth_*)
|
|
129
|
+
Facade->>Issuer: api-key token + M2M token exchange
|
|
130
|
+
Issuer-->>Facade: short-lived signer JWT + signerUrl
|
|
131
|
+
Facade-->>Client: access_token + signerUrl
|
|
132
|
+
Client->>Signer: POST {signerUrl}/sign-orchestrator-info (Bearer JWT)
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
**Do not** point `signerUrl` or gateway `--token signer` at dashboard
|
|
136
|
+
`/api/signer/*` proxy routes. Those proxies are removed; use the remote signer
|
|
137
|
+
DMZ URL from the exchange response (or `getSignerRouting().remoteDmzUrl`).
|
|
138
|
+
|
|
139
|
+
**Migration:** if you previously configured
|
|
140
|
+
`signer: https://dashboard.example.com/api/signer`, change to the remote signer
|
|
141
|
+
base returned by exchange (`signerUrl`) or routing (`remoteDmzUrl`). Keep
|
|
142
|
+
`facadeUrl` / `billing` pointed at the dashboard/platform origin for exchange
|
|
143
|
+
only (`/api/pymthouse/keys/exchange` or `/api/signer/device/exchange`).
|
|
144
|
+
|
|
87
145
|
Integrators can use the higher-level workflow helpers:
|
|
88
146
|
|
|
89
147
|
```ts
|
|
@@ -170,11 +228,64 @@ const customConfig = {
|
|
|
170
228
|
Env vars align with `auth0-livepeer` bootstrap output (`.env.livepeer`). For Auth0,
|
|
171
229
|
set `CLAIM_CLIENT_ID=azp` and `USAGE_SUBJECT_TYPE=auth0_user_id`.
|
|
172
230
|
|
|
231
|
+
## Gateway `--token` helper
|
|
232
|
+
|
|
233
|
+
The [livepeer-python-gateway](https://github.com/livepeer/livepeer-python-gateway)
|
|
234
|
+
`--token` is a **base64-encoded JSON** bundle (not a JWT). `buildGatewayToken`
|
|
235
|
+
assembles one client-side from values you already have, and `mintGatewayToken`
|
|
236
|
+
mints a signer JWT first as a convenience.
|
|
237
|
+
|
|
238
|
+
Two gateway auth modes:
|
|
239
|
+
|
|
240
|
+
- **`signerJwt`** — you mint a signer JWT and forward it as
|
|
241
|
+
`signer_headers.Authorization = "Bearer <jwt>"`. The gateway only reads the
|
|
242
|
+
JWT `exp`; it cannot refresh on its own (pre-mint or refresh externally).
|
|
243
|
+
- **`pmthApiKey`** — the gateway holds a `pmth_*` API key + the billing URL and
|
|
244
|
+
performs the exchange + auto-refresh itself (`api_key` + `billing` top-level).
|
|
245
|
+
|
|
246
|
+
```ts
|
|
247
|
+
import {
|
|
248
|
+
buildGatewayToken,
|
|
249
|
+
mintGatewayToken,
|
|
250
|
+
} from "@pymthouse/builder-sdk/signer/gateway";
|
|
251
|
+
|
|
252
|
+
// Pure assembly: pre-minted signer JWT mode
|
|
253
|
+
const token = buildGatewayToken({
|
|
254
|
+
signer: "https://signer.example/generate-live-payment",
|
|
255
|
+
auth: { kind: "signerJwt", accessToken: userSignerJwt },
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
// Pure assembly: gateway self-refreshes via platform exchange, signs directly to signer
|
|
259
|
+
const apiKeyToken = buildGatewayToken({
|
|
260
|
+
signer: "https://signer.example",
|
|
261
|
+
auth: {
|
|
262
|
+
kind: "pmthApiKey",
|
|
263
|
+
apiKey: process.env.PMTH_API_KEY!,
|
|
264
|
+
billing: "https://dashboard.example.com",
|
|
265
|
+
},
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
// Convenience: mint a signer JWT (M2M client_credentials) then assemble
|
|
269
|
+
const minted = await mintGatewayToken({
|
|
270
|
+
source: "m2m",
|
|
271
|
+
signer: "https://signer.example/generate-live-payment",
|
|
272
|
+
issuerUrl: process.env.PYMTHOUSE_ISSUER_URL!,
|
|
273
|
+
m2mClientId: process.env.PYMTHOUSE_M2M_CLIENT_ID!,
|
|
274
|
+
m2mClientSecret: process.env.PYMTHOUSE_M2M_CLIENT_SECRET!,
|
|
275
|
+
externalUserId: "naap-user-123",
|
|
276
|
+
});
|
|
277
|
+
// Pass `token` straight to the gateway: `--token <token>`
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
Use `decodeGatewayToken(token)` to inspect a bundle in tests/debugging.
|
|
281
|
+
|
|
173
282
|
## Subpath exports
|
|
174
283
|
|
|
175
284
|
| Import | Purpose |
|
|
176
285
|
|--------|---------|
|
|
177
286
|
| `@pymthouse/builder-sdk` | `PmtHouseClient`, usage helpers, manifest parsers, token helpers |
|
|
287
|
+
| `@pymthouse/builder-sdk/signer/server` | Exchange handlers, direct signer URL helpers, minting, `buildGatewayToken`/`mintGatewayToken` |
|
|
288
|
+
| `@pymthouse/builder-sdk/signer/gateway` | Gateway `--token` assembler (`buildGatewayToken`, `mintGatewayToken`, `decodeGatewayToken`) |
|
|
178
289
|
| `@pymthouse/builder-sdk/signer/webhook` | Identity webhook for `-remoteSignerWebhookUrl` |
|
|
179
290
|
| `@pymthouse/builder-sdk/config` | `isPymthouseConfigured`, `readPymthouseEnv` (Edge/middleware-safe) |
|
|
180
291
|
| `@pymthouse/builder-sdk/tokens` | Signer session TTL, JWT shape helpers, `parseSignerSessionExchange` |
|
|
@@ -204,7 +315,11 @@ const summary = summarizeUsageForExternalUser(usage, externalUserId);
|
|
|
204
315
|
|
|
205
316
|
**Retail estimates:** `getUsage({ includeRetail: true, groupBy: "pipeline_model" })` adds `endUserBillableUsdMicros` / fiat rows when the active plan has retail rates.
|
|
206
317
|
|
|
207
|
-
**Metering:** sign directly against the remote signer DMZ with
|
|
318
|
+
**Metering:** after exchange, sign directly against the remote signer DMZ with
|
|
319
|
+
`forwardToSigner`, `forwardDirectSignerRequest`, or plain `fetch` to
|
|
320
|
+
`{signerUrl}/{path}`. Usage is emitted asynchronously by go-livepeer to Kafka
|
|
321
|
+
and ingested by the OpenMeter collector. Dashboard `/api/signer/*` HTTP proxy
|
|
322
|
+
routes and synchronous HTTP signed-ticket ingest are removed.
|
|
208
323
|
|
|
209
324
|
**Routing:** `getSignerRouting()` returns the remote DMZ URL, webhook URL, and migration hints (`directDmz` / `deprecatedHostedFacade`).
|
|
210
325
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { SignerSessionToken } from './tokens.js';
|
|
2
|
-
import { P as PmtHouseClientOptions, G as GetDiscoveryOptions, O as OidcDiscoveryDocument, a as ParsedDeviceApprovalRedirect, A as AppUserRecord, U as UpsertAppUserInput, M as MintUserAccessTokenInput, b as MintUserAccessTokenResponse, T as TokenExchangeResponse, D as DeviceApprovalInput, C as ClientCredentialsTokenResponse, c as MintUserSignerSessionTokenInput, d as UsageQueryInput, e as UsageApiResponse, S as SignedTicketIngestInput, f as SignedTicketIngestResult, g as SignerRoutingResponse, L as ListBillingProductsResult, h as PlanSyncResult, i as UsageBalanceResponse, j as UserAllowancesResponse, k as UserAllowanceGrantInput, l as GrantSource, m as UserSubscriptionResponse, n as MeScopeUsagePayload, o as GetAppManifestResult, p as MintSignerSessionForExternalUserInput, q as ApproveDeviceLoginInput } from './types-
|
|
2
|
+
import { P as PmtHouseClientOptions, G as GetDiscoveryOptions, O as OidcDiscoveryDocument, a as ParsedDeviceApprovalRedirect, A as AppUserRecord, U as UpsertAppUserInput, M as MintUserAccessTokenInput, b as MintUserAccessTokenResponse, T as TokenExchangeResponse, D as DeviceApprovalInput, C as ClientCredentialsTokenResponse, c as MintUserSignerSessionTokenInput, d as UsageQueryInput, e as UsageApiResponse, S as SignedTicketIngestInput, f as SignedTicketIngestResult, g as SignerRoutingResponse, L as ListBillingProductsResult, h as PlanSyncResult, i as UsageBalanceResponse, j as UserAllowancesResponse, k as UserAllowanceGrantInput, l as GrantSource, m as UserSubscriptionResponse, n as MeScopeUsagePayload, o as GetAppManifestResult, p as MintSignerSessionForExternalUserInput, q as ApproveDeviceLoginInput } from './types-CcP67AZm.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Normalize RFC 8628 user codes for comparison and resource URIs (uppercase, strip separators).
|
|
@@ -39,8 +39,14 @@ declare class PmtHouseClient {
|
|
|
39
39
|
scope?: string;
|
|
40
40
|
}): Promise<MintUserAccessTokenResponse>;
|
|
41
41
|
/**
|
|
42
|
-
* Exchange a dashboard API key for a signer
|
|
43
|
-
*
|
|
42
|
+
* Exchange a dashboard API key for a short-lived signer JWT via a trusted facade.
|
|
43
|
+
*
|
|
44
|
+
* `facadeUrl` is used only for `POST {facadeUrl}/api/pymthouse/keys/exchange`.
|
|
45
|
+
* After exchange, call signer RPCs directly at `signerUrl` from the response
|
|
46
|
+
* (e.g. `{signerUrl}/sign-orchestrator-info`), not via dashboard `/api/signer/*`.
|
|
47
|
+
*
|
|
48
|
+
* When M2M credentials are available on this client, omit `facadeUrl` to exchange
|
|
49
|
+
* directly against the PymtHouse issuer.
|
|
44
50
|
*/
|
|
45
51
|
exchangeApiKeyForSignerSession(input: {
|
|
46
52
|
apiKey: string;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { SignerSessionToken } from './tokens.cjs';
|
|
2
|
-
import { P as PmtHouseClientOptions, G as GetDiscoveryOptions, O as OidcDiscoveryDocument, a as ParsedDeviceApprovalRedirect, A as AppUserRecord, U as UpsertAppUserInput, M as MintUserAccessTokenInput, b as MintUserAccessTokenResponse, T as TokenExchangeResponse, D as DeviceApprovalInput, C as ClientCredentialsTokenResponse, c as MintUserSignerSessionTokenInput, d as UsageQueryInput, e as UsageApiResponse, S as SignedTicketIngestInput, f as SignedTicketIngestResult, g as SignerRoutingResponse, L as ListBillingProductsResult, h as PlanSyncResult, i as UsageBalanceResponse, j as UserAllowancesResponse, k as UserAllowanceGrantInput, l as GrantSource, m as UserSubscriptionResponse, n as MeScopeUsagePayload, o as GetAppManifestResult, p as MintSignerSessionForExternalUserInput, q as ApproveDeviceLoginInput } from './types-
|
|
2
|
+
import { P as PmtHouseClientOptions, G as GetDiscoveryOptions, O as OidcDiscoveryDocument, a as ParsedDeviceApprovalRedirect, A as AppUserRecord, U as UpsertAppUserInput, M as MintUserAccessTokenInput, b as MintUserAccessTokenResponse, T as TokenExchangeResponse, D as DeviceApprovalInput, C as ClientCredentialsTokenResponse, c as MintUserSignerSessionTokenInput, d as UsageQueryInput, e as UsageApiResponse, S as SignedTicketIngestInput, f as SignedTicketIngestResult, g as SignerRoutingResponse, L as ListBillingProductsResult, h as PlanSyncResult, i as UsageBalanceResponse, j as UserAllowancesResponse, k as UserAllowanceGrantInput, l as GrantSource, m as UserSubscriptionResponse, n as MeScopeUsagePayload, o as GetAppManifestResult, p as MintSignerSessionForExternalUserInput, q as ApproveDeviceLoginInput } from './types-CcP67AZm.cjs';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Normalize RFC 8628 user codes for comparison and resource URIs (uppercase, strip separators).
|
|
@@ -39,8 +39,14 @@ declare class PmtHouseClient {
|
|
|
39
39
|
scope?: string;
|
|
40
40
|
}): Promise<MintUserAccessTokenResponse>;
|
|
41
41
|
/**
|
|
42
|
-
* Exchange a dashboard API key for a signer
|
|
43
|
-
*
|
|
42
|
+
* Exchange a dashboard API key for a short-lived signer JWT via a trusted facade.
|
|
43
|
+
*
|
|
44
|
+
* `facadeUrl` is used only for `POST {facadeUrl}/api/pymthouse/keys/exchange`.
|
|
45
|
+
* After exchange, call signer RPCs directly at `signerUrl` from the response
|
|
46
|
+
* (e.g. `{signerUrl}/sign-orchestrator-info`), not via dashboard `/api/signer/*`.
|
|
47
|
+
*
|
|
48
|
+
* When M2M credentials are available on this client, omit `facadeUrl` to exchange
|
|
49
|
+
* directly against the PymtHouse issuer.
|
|
44
50
|
*/
|
|
45
51
|
exchangeApiKeyForSignerSession(input: {
|
|
46
52
|
apiKey: string;
|
package/dist/device.d.cts
CHANGED
package/dist/device.d.ts
CHANGED
package/dist/env.cjs
CHANGED
|
@@ -307,6 +307,32 @@ var init_mint_token = __esm({
|
|
|
307
307
|
}
|
|
308
308
|
});
|
|
309
309
|
|
|
310
|
+
// src/signer/direct-signer.ts
|
|
311
|
+
function assertDirectSignerBaseUrl(signerBaseUrl) {
|
|
312
|
+
let parsed;
|
|
313
|
+
try {
|
|
314
|
+
parsed = new URL(signerBaseUrl.trim());
|
|
315
|
+
} catch {
|
|
316
|
+
throw new PmtHouseError("signer URL must be an absolute http(s) URL", {
|
|
317
|
+
status: 400,
|
|
318
|
+
code: "invalid_signer_url"
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
const pathname = stripTrailingSlashes(parsed.pathname);
|
|
322
|
+
if (pathname === "/api/signer" || pathname.startsWith("/api/signer/")) {
|
|
323
|
+
throw new PmtHouseError(
|
|
324
|
+
"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.",
|
|
325
|
+
{ status: 400, code: "invalid_signer_url" }
|
|
326
|
+
);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
var init_direct_signer = __esm({
|
|
330
|
+
"src/signer/direct-signer.ts"() {
|
|
331
|
+
init_string_utils();
|
|
332
|
+
init_errors();
|
|
333
|
+
}
|
|
334
|
+
});
|
|
335
|
+
|
|
310
336
|
// src/signer/device-exchange.ts
|
|
311
337
|
function extractSignerAccessTokenFromExchangeBody(body) {
|
|
312
338
|
const tokenObj = body.token;
|
|
@@ -539,6 +565,9 @@ async function exchangeApiKeyForSigner(options) {
|
|
|
539
565
|
const accessToken = extractSignerAccessTokenFromExchangeBody(parsed);
|
|
540
566
|
const signerUrlRaw = parsed.signerUrl ?? parsed.signer_url;
|
|
541
567
|
const signerUrl = typeof signerUrlRaw === "string" && signerUrlRaw.trim() ? signerUrlRaw.trim() : void 0;
|
|
568
|
+
if (signerUrl) {
|
|
569
|
+
assertDirectSignerBaseUrl(signerUrl);
|
|
570
|
+
}
|
|
542
571
|
return normalizeDeviceExchangeResponse(
|
|
543
572
|
{
|
|
544
573
|
access_token: accessToken,
|
|
@@ -601,6 +630,7 @@ var init_api_key_exchange = __esm({
|
|
|
601
630
|
init_fetch_json();
|
|
602
631
|
init_handler_errors();
|
|
603
632
|
init_device_exchange();
|
|
633
|
+
init_direct_signer();
|
|
604
634
|
EXCHANGE_RESPONSE_ERROR2 = "invalid_exchange_response";
|
|
605
635
|
}
|
|
606
636
|
});
|
|
@@ -1097,8 +1127,14 @@ var PmtHouseClient = class {
|
|
|
1097
1127
|
});
|
|
1098
1128
|
}
|
|
1099
1129
|
/**
|
|
1100
|
-
* Exchange a dashboard API key for a signer
|
|
1101
|
-
*
|
|
1130
|
+
* Exchange a dashboard API key for a short-lived signer JWT via a trusted facade.
|
|
1131
|
+
*
|
|
1132
|
+
* `facadeUrl` is used only for `POST {facadeUrl}/api/pymthouse/keys/exchange`.
|
|
1133
|
+
* After exchange, call signer RPCs directly at `signerUrl` from the response
|
|
1134
|
+
* (e.g. `{signerUrl}/sign-orchestrator-info`), not via dashboard `/api/signer/*`.
|
|
1135
|
+
*
|
|
1136
|
+
* When M2M credentials are available on this client, omit `facadeUrl` to exchange
|
|
1137
|
+
* directly against the PymtHouse issuer.
|
|
1102
1138
|
*/
|
|
1103
1139
|
async exchangeApiKeyForSignerSession(input) {
|
|
1104
1140
|
if (input.facadeUrl?.trim()) {
|
|
@@ -1115,7 +1151,8 @@ var PmtHouseClient = class {
|
|
|
1115
1151
|
token_type: exchanged.token_type,
|
|
1116
1152
|
expires_in: exchanged.expires_in,
|
|
1117
1153
|
scope: exchanged.scope,
|
|
1118
|
-
issued_token_type: "urn:ietf:params:oauth:token-type:access_token"
|
|
1154
|
+
issued_token_type: "urn:ietf:params:oauth:token-type:access_token",
|
|
1155
|
+
signerUrl: exchanged.signerUrl
|
|
1119
1156
|
};
|
|
1120
1157
|
}
|
|
1121
1158
|
const userToken = await this.exchangeApiKeyForUserAccessToken({
|