@conto_finance/sdk 0.3.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +309 -3
- package/dist/browserbase.d.mts +139 -0
- package/dist/browserbase.d.ts +139 -0
- package/dist/browserbase.js +1980 -0
- package/dist/browserbase.mjs +604 -0
- package/dist/checkout-verifier.d.mts +95 -0
- package/dist/checkout-verifier.d.ts +95 -0
- package/dist/checkout-verifier.js +400 -0
- package/dist/checkout-verifier.mjs +372 -0
- package/dist/chunk-B7F5QLE5.mjs +34 -0
- package/dist/chunk-HM4EG5MH.mjs +1256 -0
- package/dist/chunk-O5RAAB2U.mjs +123 -0
- package/dist/index.d.mts +975 -4
- package/dist/index.d.ts +975 -4
- package/dist/index.js +777 -51
- package/dist/index.mjs +661 -77
- package/dist/playwright.d.mts +255 -0
- package/dist/playwright.d.ts +255 -0
- package/dist/playwright.js +1394 -0
- package/dist/playwright.mjs +22 -0
- package/package.json +31 -6
package/README.md
CHANGED
|
@@ -19,6 +19,11 @@ npm install @conto_finance/sdk
|
|
|
19
19
|
An admin SDK key is still an agent SDK key. It keeps the `conto_agent_...` prefix, so it is not a
|
|
20
20
|
drop-in replacement for `ContoAdmin`.
|
|
21
21
|
|
|
22
|
+
## Verify the connection
|
|
23
|
+
|
|
24
|
+
Requires Node.js 20.19+. Call `await conto.setup()` to inspect your agent, linked wallets,
|
|
25
|
+
effective policies, and scopes without creating a payment.
|
|
26
|
+
|
|
22
27
|
## Agent SDK Quick Start
|
|
23
28
|
|
|
24
29
|
```typescript
|
|
@@ -113,7 +118,9 @@ const cardAccess = new ContoCardAccess({
|
|
|
113
118
|
Card Access claims each approved request exactly once before the executor can run. A
|
|
114
119
|
duplicate or uncertain claim cannot invoke the executor again. It remains
|
|
115
120
|
bypassable if another person or tool can access the card, and results are
|
|
116
|
-
self-reported rather than issuer-verified. The
|
|
121
|
+
self-reported rather than issuer-verified. The executor receives the normalized
|
|
122
|
+
purchase `idempotencyKey`; pass it to the payment processor so ambiguous
|
|
123
|
+
processor responses cannot create duplicate charges. The legacy `conto.cards.controlled()`
|
|
117
124
|
helper remains available for compatibility, but new customer-hosted enforcement
|
|
118
125
|
should use the standalone Card Access package. Use
|
|
119
126
|
`admin.cards.listRequests({ status: 'EXECUTING' })` for reconciliation and
|
|
@@ -160,6 +167,273 @@ const budget = await conto.x402.budget();
|
|
|
160
167
|
The MPP client mirrors the same shape with `conto.mpp.preAuthorize`, `conto.mpp.record`,
|
|
161
168
|
`conto.mpp.budget`, and `conto.mpp.services`.
|
|
162
169
|
|
|
170
|
+
## Stripe Link Checkout Commerce
|
|
171
|
+
|
|
172
|
+
For a merchant Conto controls, `LINK_CHECKOUT` evaluates policy before creating an ordinary
|
|
173
|
+
Stripe-hosted Checkout Session with card and Link enabled. It needs no private Link SDK permission,
|
|
174
|
+
Link connection, saved payment-method ID, SPT, or LPT.
|
|
175
|
+
|
|
176
|
+
Commerce execution responses separate the provider-neutral `executionChannel`, optional
|
|
177
|
+
`checkoutMethod`, and optional `settlementRail` from the legacy provider and adapter identifiers.
|
|
178
|
+
For dynamic hosted Checkout, `checkoutMethod` remains absent until settlement observes Link or the
|
|
179
|
+
card fallback; callers must not treat the adapter name as proof that Link was selected.
|
|
180
|
+
|
|
181
|
+
```typescript
|
|
182
|
+
let { execution } = await conto.beginCommerceExecution({
|
|
183
|
+
executionMethod: 'LINK_CHECKOUT',
|
|
184
|
+
idempotencyKey: crypto.randomUUID(),
|
|
185
|
+
amountMinor: 6400,
|
|
186
|
+
currency: 'USD',
|
|
187
|
+
category: 'OFFICE_SUPPLIES',
|
|
188
|
+
purpose: 'Office supplies',
|
|
189
|
+
counterparty: {
|
|
190
|
+
canonicalId: 'conto-demo-office-supply',
|
|
191
|
+
},
|
|
192
|
+
cart: {
|
|
193
|
+
lineItems: [{ name: 'Office supplies', quantity: 1, unitAmountMinor: 6400 }],
|
|
194
|
+
totals: [{ type: 'total', label: 'Total', amountMinor: 6400 }],
|
|
195
|
+
},
|
|
196
|
+
providerPresentation: {
|
|
197
|
+
approvalSummary: 'Buy office supplies from the configured merchant',
|
|
198
|
+
lineItemLabels: ['Office supplies'],
|
|
199
|
+
},
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
if (execution.status !== 'ACTION_REQUIRED' || !execution.approvalUrl) {
|
|
203
|
+
throw new Error('Stripe Checkout was not created safely');
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
if (execution.executionAdapter !== 'LINK_CHECKOUT') {
|
|
207
|
+
throw new Error('Unexpected commerce execution adapter');
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// Hand the temporary capability to a trusted interactive browser/UI. Do not log it.
|
|
211
|
+
await presentCheckoutActionSecurely(execution.approvalUrl);
|
|
212
|
+
|
|
213
|
+
while (execution.status === 'ACTION_REQUIRED' || execution.status === 'PROCESSING') {
|
|
214
|
+
({ execution } = await conto.refreshCommerceExecution(execution.id));
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
if (execution.status !== 'SETTLED' || execution.evidence.actualPaymentMethod !== 'LINK') {
|
|
218
|
+
throw new Error('This execution did not settle with Link');
|
|
219
|
+
}
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
Stripe decides whether Link appears and whether the customer chooses it. Card is an explicit
|
|
223
|
+
fallback, surfaced as `actualPaymentMethod: 'CARD'`; it is a valid payment but not Link evidence.
|
|
224
|
+
The read-only `getCommerceExecution` projection redacts action URLs; use the initial begin result or
|
|
225
|
+
the `payments:confirm` refresh path while action remains required.
|
|
226
|
+
The server resolves the exact merchant name, Stripe account, and return URLs from configuration, so
|
|
227
|
+
the caller cannot redirect the approved purchase. This path controls only that merchant's Conto
|
|
228
|
+
channel, not unrelated Checkout pages or the consumer's Link wallet. See
|
|
229
|
+
`docs/STRIPE_LINK_CHECKOUT_ADAPTER.md` for configuration, webhook, drill, and reconciliation
|
|
230
|
+
requirements.
|
|
231
|
+
|
|
232
|
+
## Agent checkout guard
|
|
233
|
+
|
|
234
|
+
For arbitrary third-party merchants, use `runGuardedCheckout` with
|
|
235
|
+
`executionMethod: 'BROWSER_CHECKOUT'`. It binds and atomically authorizes one exact Link, card,
|
|
236
|
+
Shop Pay, or PayPal browser action without requiring merchant or private provider integration. The
|
|
237
|
+
privileged browser executor must be available only through this wrapper; an unrestricted click or
|
|
238
|
+
payment tool would bypass the control. Persist its stable dispatch attempt before calling the helper; it owns authorization,
|
|
239
|
+
one-use claim, the privileged callback, and finalization. See `docs/AGENT_CHECKOUT_GUARD.md` for the
|
|
240
|
+
runtime boundary and example.
|
|
241
|
+
|
|
242
|
+
Isolated browser processes can implement `PrivilegedBrowserCheckoutDriver` and use
|
|
243
|
+
`runGuardedCheckoutWithDriver`; the agent model must receive only that guarded wrapper, never the
|
|
244
|
+
driver's `dispatch` primitive. Generate `action.targetFingerprint` with
|
|
245
|
+
`fingerprintBrowserCheckoutTarget` during inspection, then wrap the privileged target resolver with
|
|
246
|
+
`createVerifiedBrowserCheckoutDriver`. The wrapper re-hashes the current page, locator, accessible
|
|
247
|
+
name, destination, form action, and disabled state immediately before dispatch and refuses any
|
|
248
|
+
changed target without clicking it. Observed link and form destinations must be explicitly bound as
|
|
249
|
+
the action's `targetUrl`, allowing Conto's origin trust policy to evaluate them before the claim.
|
|
250
|
+
|
|
251
|
+
For Browserbase, use the first-class provider host. Its binding store must reject duplicate session
|
|
252
|
+
IDs and atomically revoke only an active record matching the supplied organization, agent, and
|
|
253
|
+
project. Store the credential-free binding durably; never add the provider `connectUrl` to it.
|
|
254
|
+
|
|
255
|
+
```typescript
|
|
256
|
+
import {
|
|
257
|
+
createBrowserbaseGuardedPlaywrightCheckoutRuntimeHost,
|
|
258
|
+
createBrowserbaseSessionHandoffAssertion,
|
|
259
|
+
} from '@conto_finance/sdk/browserbase';
|
|
260
|
+
import { chromium } from 'playwright-core';
|
|
261
|
+
|
|
262
|
+
const host = createBrowserbaseGuardedPlaywrightCheckoutRuntimeHost({
|
|
263
|
+
conto,
|
|
264
|
+
browserbase: {
|
|
265
|
+
apiKey: process.env.BROWSERBASE_API_KEY!,
|
|
266
|
+
projectId: process.env.BROWSERBASE_PROJECT_ID!,
|
|
267
|
+
organizationId,
|
|
268
|
+
agentId,
|
|
269
|
+
bindingStore: browserbaseSessionBindings,
|
|
270
|
+
contextId: process.env.BROWSERBASE_CONTEXT_ID,
|
|
271
|
+
handoffKey: Buffer.from(process.env.CONTO_BROWSER_HANDOFF_KEY!, 'base64'),
|
|
272
|
+
},
|
|
273
|
+
connectOverCDP: (connectUrl) => chromium.connectOverCDP(connectUrl),
|
|
274
|
+
targetStore: {
|
|
275
|
+
encryptionKey: Buffer.from(process.env.CONTO_BROWSER_TARGET_KEY!, 'base64'),
|
|
276
|
+
blobStore: durableTargetBlobs,
|
|
277
|
+
},
|
|
278
|
+
dispatchAttemptFor: ({ idempotencyKey }) => attempts.loadOrCreate(idempotencyKey),
|
|
279
|
+
token: process.env.CONTO_BROWSER_RUNTIME_TOKEN!,
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
const browser = await host.createSession();
|
|
283
|
+
// Give browser.browserSessionId, never a provider connection URL, to the guarded agent runtime.
|
|
284
|
+
|
|
285
|
+
// Or attach a session created by the customer's trusted Browserbase backend.
|
|
286
|
+
const browserSessionId = customerBrowserbaseSession.id;
|
|
287
|
+
const expiresAt = new Date(Date.now() + 60_000).toISOString();
|
|
288
|
+
const handoffAssertion = createBrowserbaseSessionHandoffAssertion(
|
|
289
|
+
{
|
|
290
|
+
browserSessionId,
|
|
291
|
+
projectId: process.env.BROWSERBASE_PROJECT_ID!,
|
|
292
|
+
organizationId,
|
|
293
|
+
agentId,
|
|
294
|
+
expiresAt,
|
|
295
|
+
},
|
|
296
|
+
Buffer.from(process.env.CONTO_BROWSER_HANDOFF_KEY!, 'base64')
|
|
297
|
+
);
|
|
298
|
+
await host.attachSession({ browserSessionId, handoffAssertion });
|
|
299
|
+
export const POST = host.handler;
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
The Browserbase host exposes `handler`, `createSession`, `attachSession`, `observeSession`,
|
|
303
|
+
`liveViewForSession`, `releaseSession`, `detachSession`, and `close`. `observeSession` returns only a
|
|
304
|
+
bounded page origin/title and visible
|
|
305
|
+
link/button outline; it excludes full page text, DOM, form values, URL paths and queries,
|
|
306
|
+
screenshots, cookies, storage, and provider capabilities. It rechecks ownership and page identity
|
|
307
|
+
after observing.
|
|
308
|
+
`createSession` returns a session ID, active status, and expiry without a connection URL.
|
|
309
|
+
`liveViewForSession` is a privileged operator capability: expose it only behind separate human
|
|
310
|
+
authentication, never as an agent tool. A configured Context persists login state but must remain
|
|
311
|
+
server-side; its durable binding store should prevent concurrent sessions from sharing one Context.
|
|
312
|
+
`releaseSession` atomically revokes Conto ownership before closing the local connection and asking
|
|
313
|
+
Browserbase to release the keep-alive session. Call it when the agent session ends; `close` only
|
|
314
|
+
closes local Playwright connections. `attachSession` accepts only a five-minute HMAC assertion
|
|
315
|
+
binding the exact provider project, Conto organization, agent, session, and expiry. Its matching
|
|
316
|
+
`detachSession` revokes Conto access and closes the local connection without releasing the
|
|
317
|
+
agent-host-owned provider session. Keep the independent 32-byte handoff key and assertions outside
|
|
318
|
+
the model and browser page.
|
|
319
|
+
|
|
320
|
+
For another Playwright or secure CDP provider, use
|
|
321
|
+
`createGuardedPlaywrightCheckoutRuntimeHost` from `@conto_finance/sdk/playwright`. The generic host
|
|
322
|
+
exposes only `handler`, `observeSession`, `closeSession`, and `close`, keeping discovery, mutation
|
|
323
|
+
primitives, the target store, the Playwright page, and raw dispatch private.
|
|
324
|
+
Lower-level integrations can still compose `createGuardedPlaywrightCheckoutRuntime`, whose façade
|
|
325
|
+
exposes only `discover` and `run`; the raw driver is not returned. Target
|
|
326
|
+
registrations expire after ten minutes by default. The encrypted store persists only ciphertext
|
|
327
|
+
through a small durable blob port, so a runtime restart does not lose an approved
|
|
328
|
+
target or disclose its locator. `dispatchAttemptFor` must atomically return the same persisted ID for
|
|
329
|
+
the same checkout intent. The dispatch result classifies the browser outcome as `NEW_PAGE`,
|
|
330
|
+
`PAGE_NAVIGATION`, or `SAME_PAGE`, but always reports settlement as `UNVERIFIED`; only merchant or
|
|
331
|
+
provider evidence can prove payment. Never expose the page, target store, persisted registrations,
|
|
332
|
+
or provider-derived locator state to the model. The inert positional reference returned by
|
|
333
|
+
`observeSession` is the only locator intended for the model.
|
|
334
|
+
|
|
335
|
+
The generic CDP registry accepts connection URLs only from exact secure origins and rechecks
|
|
336
|
+
`connectUrlForSession` ownership on every lookup. Revocation closes a cached connection. It caches
|
|
337
|
+
one connection per owned session and requires exactly one open page unless the runtime supplies
|
|
338
|
+
an exact `selectPage` callback. Keep Browserbase API keys and `connectUrl` values in the privileged process.
|
|
339
|
+
Call `closeSession` only when the agent session is finished because closing the Playwright browser
|
|
340
|
+
may end the provider session.
|
|
341
|
+
|
|
342
|
+
### Verify the exclusive checkout path
|
|
343
|
+
|
|
344
|
+
Use `@conto_finance/sdk/checkout-verifier` during agent-host onboarding and whenever its tool
|
|
345
|
+
registry changes. The manifest inventories every capability exposed to the model, identifies the
|
|
346
|
+
session ownership boundary, and names the supported checkout methods. The verifier reports
|
|
347
|
+
`ADVISORY` when an unrestricted payment-capable browser tool remains available and `UNVERIFIED`
|
|
348
|
+
when active probes have not run. It reports `ENFORCEABLE` and `canBypass: false` only after the
|
|
349
|
+
complete inventory is isolated and all denial, replay, tamper, alternate-path, and
|
|
350
|
+
ambiguous-dispatch probes pass.
|
|
351
|
+
|
|
352
|
+
The probe runner belongs to the trusted integration host and must execute against an isolated
|
|
353
|
+
fixture session. A report does not remotely attest an untrusted host or discover tools omitted from
|
|
354
|
+
its inventory. See `docs/CHECKOUT_INTEGRATION_VERIFIER.md` for the manifest, probe, and status
|
|
355
|
+
contract.
|
|
356
|
+
|
|
357
|
+
The HTTP handler implements the authenticated endpoint consumed by the optional
|
|
358
|
+
`guarded_browser_checkout` MCP tool. It accepts Web `Request` objects, so it can be mounted directly
|
|
359
|
+
in a compatible route or adapted to a Node server. It authenticates before reading the body,
|
|
360
|
+
rejects unknown fields and mismatched cart totals, performs discovery and guarded execution in one
|
|
361
|
+
request, and returns only minimized browser evidence. Use a dedicated random token of at least 32
|
|
362
|
+
characters; the handler rejects Conto API keys.
|
|
363
|
+
|
|
364
|
+
Organization-specific proposal facts can be sent through the typed normalization call after an
|
|
365
|
+
owner or administrator registers the namespace schema:
|
|
366
|
+
|
|
367
|
+
```typescript
|
|
368
|
+
const proposal = await conto.normalizeCommerceProposal({
|
|
369
|
+
proposalKey: 'office-toner-2026-09-02',
|
|
370
|
+
purpose: 'Purchase toner for operations',
|
|
371
|
+
extensions: [
|
|
372
|
+
{
|
|
373
|
+
namespace: 'acme.procurement.v1',
|
|
374
|
+
value: { costCenter: 'OPS', project: 'AP_AUTOMATION' },
|
|
375
|
+
},
|
|
376
|
+
],
|
|
377
|
+
});
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
Conto rejects unregistered namespaces and schema-invalid values before policy evaluation. Accepted
|
|
381
|
+
facts are bound to the schema revision and fingerprint returned on the normalized proposal.
|
|
382
|
+
|
|
383
|
+
## Stripe Link Sandbox Commerce
|
|
384
|
+
|
|
385
|
+
The gated Stripe Link sandbox surface uses the agent key for policy evaluation and execution. A
|
|
386
|
+
Link connection must first be created by its user and explicitly bound to the agent through the
|
|
387
|
+
authenticated session API. The agent SDK never receives the Link access token or payment artifact.
|
|
388
|
+
|
|
389
|
+
```typescript
|
|
390
|
+
const linkContext = await conto.listStripeLinkPaymentMethods(connectionId);
|
|
391
|
+
if (linkContext.organizationId !== expectedOrganizationId) {
|
|
392
|
+
throw new Error('Agent key belongs to the wrong Conto organization');
|
|
393
|
+
}
|
|
394
|
+
const { paymentMethods } = linkContext;
|
|
395
|
+
|
|
396
|
+
let { execution } = await conto.beginCommerceExecution({
|
|
397
|
+
connectionId,
|
|
398
|
+
paymentMethodId: paymentMethods[0].id,
|
|
399
|
+
executionMethod: 'STRIPE_PAYMENT_INTENT',
|
|
400
|
+
idempotencyKey: crypto.randomUUID(),
|
|
401
|
+
amountMinor: 6400,
|
|
402
|
+
currency: 'USD',
|
|
403
|
+
purpose: 'Office supplies',
|
|
404
|
+
counterparty: {
|
|
405
|
+
canonicalId: 'conto-demo-office-supply',
|
|
406
|
+
displayName: 'Conto Demo Office Supply',
|
|
407
|
+
},
|
|
408
|
+
cart: {
|
|
409
|
+
lineItems: [{ name: 'Office supplies', quantity: 1, unitAmountMinor: 6400 }],
|
|
410
|
+
totals: [{ type: 'total', label: 'Total', amountMinor: 6400 }],
|
|
411
|
+
},
|
|
412
|
+
providerPresentation: {
|
|
413
|
+
approvalSummary: 'Buy office supplies from Conto Demo Office Supply',
|
|
414
|
+
lineItemLabels: ['Office supplies'],
|
|
415
|
+
},
|
|
416
|
+
});
|
|
417
|
+
|
|
418
|
+
if (execution.status === 'AWAITING_APPROVAL') {
|
|
419
|
+
// Present execution.approvalUrl to the Link user, then poll with refresh.
|
|
420
|
+
({ execution } = await conto.refreshCommerceExecution(execution.id));
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
if (execution.status === 'READY') {
|
|
424
|
+
const result = await conto.executeCommerceExecution(execution.id);
|
|
425
|
+
console.log(result.execution.evidence, result.execution.evidenceFingerprint);
|
|
426
|
+
}
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
Use `getCommerceExecution(id)` for read-only reconciliation and
|
|
430
|
+
`cancelCommerceExecution(id)` to cancel a nonterminal execution. `beginCommerceExecution` safely
|
|
431
|
+
retries with its stable idempotency key, and `refreshCommerceExecution` safely retries observation.
|
|
432
|
+
Checkout execution and cancellation are not transport-retried.
|
|
433
|
+
The Stripe account and Link business-network profile are resolved from server-owned configuration;
|
|
434
|
+
an agent cannot supply or replace them. Use `executionMethod: 'MPP'` only for the optional,
|
|
435
|
+
configured MPP compatibility transport.
|
|
436
|
+
|
|
163
437
|
## Admin SDK Quick Start
|
|
164
438
|
|
|
165
439
|
`ContoAdmin` uses an organization API key (`conto_xxx...`), not an agent SDK key.
|
|
@@ -194,6 +468,27 @@ if (frozen) {
|
|
|
194
468
|
}
|
|
195
469
|
```
|
|
196
470
|
|
|
471
|
+
### Stripe Link Checkout readiness
|
|
472
|
+
|
|
473
|
+
Organization administrators can inspect the configured merchant Checkout adapter without calling
|
|
474
|
+
Stripe, then explicitly verify that Conto's configured credential resolves to its configured
|
|
475
|
+
merchant account:
|
|
476
|
+
|
|
477
|
+
```typescript
|
|
478
|
+
const { readiness } = await admin.paymentRails.getStripeLinkCheckoutReadiness();
|
|
479
|
+
|
|
480
|
+
if (readiness.canVerify && !readiness.checks.accountVerified) {
|
|
481
|
+
const verified = await admin.paymentRails.verifyStripeLinkCheckoutAccount();
|
|
482
|
+
console.log(verified.readiness.status, verified.readiness.verification);
|
|
483
|
+
}
|
|
484
|
+
```
|
|
485
|
+
|
|
486
|
+
The result contains only mode, booleans, safe status codes, timestamps, and scope statements. It
|
|
487
|
+
never contains merchant/account identifiers, URLs, credentials, hashes, Stripe objects, or raw
|
|
488
|
+
provider errors. Verification proves the configured account match only; Stripe still decides
|
|
489
|
+
whether Link is eligible, displayed, and selected at Checkout. The static GET is retry-safe; the
|
|
490
|
+
active POST verification is not automatically retried.
|
|
491
|
+
|
|
197
492
|
## What This Package Covers
|
|
198
493
|
|
|
199
494
|
- `Conto` for agent-scoped payment flows
|
|
@@ -235,8 +530,7 @@ try {
|
|
|
235
530
|
|
|
236
531
|
## What To Use Instead
|
|
237
532
|
|
|
238
|
-
- Use
|
|
239
|
-
external-wallet `approve -> transfer -> confirm` flows.
|
|
533
|
+
- Use `conto.payments.approve()` and `conto.payments.confirm()` for external wallets. Your own signer sends the transfer between those calls. Neither write retries automatically.
|
|
240
534
|
- Use the MCP server if a tool-calling assistant should operate Conto directly.
|
|
241
535
|
|
|
242
536
|
## Docs
|
|
@@ -250,3 +544,15 @@ try {
|
|
|
250
544
|
## License
|
|
251
545
|
|
|
252
546
|
MIT
|
|
547
|
+
|
|
548
|
+
Developer support: [support@conto.finance](mailto:support@conto.finance). Include the package version and request ID; never include API keys.
|
|
549
|
+
|
|
550
|
+
### Connected-card delivery
|
|
551
|
+
|
|
552
|
+
For an organization with connected cards enabled, `conto.connectedCards.draw()` returns a disposable
|
|
553
|
+
credential exactly once. Keep it in memory and use it at the mandate's merchant before
|
|
554
|
+
`credentialExpiresAt`. Never log or persist it. After receipt, call
|
|
555
|
+
`conto.connectedCards.acknowledgeDelivery(draw.requestId)`. Acknowledgement is idempotent and records
|
|
556
|
+
delivery only, not payment settlement. Replaying the original draw key cannot recover a lost
|
|
557
|
+
credential; check the original outcome before requesting a replacement. Issued capacity stays
|
|
558
|
+
consumed even when checkout fails.
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { Browser } from 'playwright-core';
|
|
2
|
+
import { GuardedPlaywrightCheckoutHttpHandler, PlaywrightSessionObservation, GuardedPlaywrightCheckoutClient, PlaywrightCdpSessionRegistryConfig, EncryptedPlaywrightCheckoutTargetStoreConfig, GuardedPlaywrightCheckoutRuntimeConfig } from './playwright.mjs';
|
|
3
|
+
import './index.mjs';
|
|
4
|
+
|
|
5
|
+
type BrowserbaseSessionStatus = 'PENDING' | 'RUNNING' | 'ERROR' | 'TIMED_OUT' | 'COMPLETED';
|
|
6
|
+
type BrowserbaseSessionBindingState = 'ACTIVE' | 'REVOKED';
|
|
7
|
+
type BrowserbaseSessionLifecycleOwner = 'CONTO_RUNTIME' | 'AGENT_HOST';
|
|
8
|
+
/** Credential-free durable record. Never persist Browserbase connect URLs or API keys here. */
|
|
9
|
+
interface BrowserbaseSessionBinding {
|
|
10
|
+
browserSessionId: string;
|
|
11
|
+
organizationId: string;
|
|
12
|
+
agentId: string;
|
|
13
|
+
projectId: string;
|
|
14
|
+
/** Missing legacy values are treated as CONTO_RUNTIME. */
|
|
15
|
+
lifecycleOwner?: BrowserbaseSessionLifecycleOwner;
|
|
16
|
+
state: BrowserbaseSessionBindingState;
|
|
17
|
+
createdAt: string;
|
|
18
|
+
expiresAt: string;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Durable ownership port for remote sessions. `create` must reject duplicate IDs and `revoke`
|
|
22
|
+
* must atomically transition only an ACTIVE record matching every supplied ownership field.
|
|
23
|
+
*/
|
|
24
|
+
interface BrowserbaseSessionBindingStore {
|
|
25
|
+
create(binding: BrowserbaseSessionBinding): Promise<boolean>;
|
|
26
|
+
get(browserSessionId: string): Promise<BrowserbaseSessionBinding | null>;
|
|
27
|
+
revoke(input: {
|
|
28
|
+
browserSessionId: string;
|
|
29
|
+
organizationId: string;
|
|
30
|
+
agentId: string;
|
|
31
|
+
projectId: string;
|
|
32
|
+
revokedAt: string;
|
|
33
|
+
}): Promise<boolean>;
|
|
34
|
+
/** Required with contextId. Release only after Browserbase confirms the provider session closed. */
|
|
35
|
+
releaseContextLease?(input: {
|
|
36
|
+
browserSessionId: string;
|
|
37
|
+
organizationId: string;
|
|
38
|
+
agentId: string;
|
|
39
|
+
projectId: string;
|
|
40
|
+
}): Promise<boolean>;
|
|
41
|
+
}
|
|
42
|
+
interface BrowserbaseSessionConfig {
|
|
43
|
+
/** Browserbase credential retained by the privileged runtime. Conto credentials are rejected. */
|
|
44
|
+
apiKey: string;
|
|
45
|
+
projectId: string;
|
|
46
|
+
organizationId: string;
|
|
47
|
+
agentId: string;
|
|
48
|
+
bindingStore: BrowserbaseSessionBindingStore;
|
|
49
|
+
/** Optional 32-byte server-only key required to attach sessions created by an agent host. */
|
|
50
|
+
handoffKey?: Uint8Array;
|
|
51
|
+
/** Optional server-only Browserbase Context used to persist Link or merchant authentication. */
|
|
52
|
+
contextId?: string;
|
|
53
|
+
/** Browserbase session timeout. Defaults to 900 seconds. */
|
|
54
|
+
timeoutSeconds?: number;
|
|
55
|
+
/** Browserbase API request timeout. Defaults to 10 seconds and may not exceed 60 seconds. */
|
|
56
|
+
requestTimeoutMs?: number;
|
|
57
|
+
/** Injected for tests or runtimes with an instrumented fetch implementation. */
|
|
58
|
+
fetch?: typeof fetch;
|
|
59
|
+
now?: () => Date;
|
|
60
|
+
}
|
|
61
|
+
interface BrowserbaseGuardedPlaywrightCheckoutRuntimeHostConfig {
|
|
62
|
+
conto: GuardedPlaywrightCheckoutClient;
|
|
63
|
+
browserbase: BrowserbaseSessionConfig;
|
|
64
|
+
/** Usually `(url) => chromium.connectOverCDP(url)`. */
|
|
65
|
+
connectOverCDP(connectUrl: string): Promise<Browser>;
|
|
66
|
+
selectPage?: PlaywrightCdpSessionRegistryConfig['selectPage'];
|
|
67
|
+
maxSessions?: number;
|
|
68
|
+
targetStore: EncryptedPlaywrightCheckoutTargetStoreConfig;
|
|
69
|
+
dispatchAttemptFor: GuardedPlaywrightCheckoutRuntimeConfig['dispatchAttemptFor'];
|
|
70
|
+
/** Dedicated service credential. Conto and Browserbase API keys are rejected. */
|
|
71
|
+
token: string;
|
|
72
|
+
maxBodyBytes?: number;
|
|
73
|
+
clickTimeoutMs?: number;
|
|
74
|
+
popupTimeoutMs?: number;
|
|
75
|
+
targetTtlMs?: number;
|
|
76
|
+
now?: () => Date;
|
|
77
|
+
}
|
|
78
|
+
/** Safe session projection for the agent-facing browser launcher. */
|
|
79
|
+
interface BrowserbaseOwnedSession {
|
|
80
|
+
browserSessionId: string;
|
|
81
|
+
status: Extract<BrowserbaseSessionStatus, 'PENDING' | 'RUNNING'>;
|
|
82
|
+
expiresAt: string;
|
|
83
|
+
}
|
|
84
|
+
/** Proof-carrying request from a trusted agent host for an existing Browserbase session. */
|
|
85
|
+
interface BrowserbaseSessionHandoff {
|
|
86
|
+
browserSessionId: string;
|
|
87
|
+
handoffAssertion: string;
|
|
88
|
+
}
|
|
89
|
+
/** Safe projection for a session whose provider lifecycle remains owned by the agent host. */
|
|
90
|
+
interface BrowserbaseAttachedSession extends BrowserbaseOwnedSession {
|
|
91
|
+
lifecycleOwner: 'AGENT_HOST';
|
|
92
|
+
}
|
|
93
|
+
interface BrowserbaseSessionHandoffAssertionInput {
|
|
94
|
+
browserSessionId: string;
|
|
95
|
+
projectId: string;
|
|
96
|
+
organizationId: string;
|
|
97
|
+
agentId: string;
|
|
98
|
+
expiresAt: string;
|
|
99
|
+
}
|
|
100
|
+
/** Operator-only capability for a human authentication or challenge handoff. */
|
|
101
|
+
interface BrowserbaseOwnedLiveView {
|
|
102
|
+
browserSessionId: string;
|
|
103
|
+
liveViewUrl: string;
|
|
104
|
+
expiresAt: string;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Closed Browserbase lifecycle plus guarded checkout façade. It never exposes the provider API
|
|
108
|
+
* key, CDP connection URL, Playwright page, target store, discovery primitive, or raw dispatch.
|
|
109
|
+
*/
|
|
110
|
+
interface BrowserbaseGuardedPlaywrightCheckoutRuntimeHost {
|
|
111
|
+
handler: GuardedPlaywrightCheckoutHttpHandler;
|
|
112
|
+
createSession(): Promise<BrowserbaseOwnedSession>;
|
|
113
|
+
/** Attaches an existing agent-host session after verifying a short-lived server assertion. */
|
|
114
|
+
attachSession(input: BrowserbaseSessionHandoff): Promise<BrowserbaseAttachedSession>;
|
|
115
|
+
/** Read-only, bounded projection of the exact runtime-owned page. */
|
|
116
|
+
observeSession(browserSessionId: string): Promise<PlaywrightSessionObservation>;
|
|
117
|
+
/** Returns a short-lived provider capability only to a separately authenticated operator path. */
|
|
118
|
+
liveViewForSession(browserSessionId: string): Promise<BrowserbaseOwnedLiveView>;
|
|
119
|
+
/** Revokes Conto ownership first, closes the local connection, then releases Browserbase. */
|
|
120
|
+
releaseSession(browserSessionId: string): Promise<void>;
|
|
121
|
+
/** Revokes the Conto binding without ending the externally owned Browserbase session. */
|
|
122
|
+
detachSession(browserSessionId: string): Promise<void>;
|
|
123
|
+
/** Closes local Playwright connections. Call releaseSession for each keep-alive provider session. */
|
|
124
|
+
close(): Promise<void>;
|
|
125
|
+
}
|
|
126
|
+
type BrowserbaseSessionErrorCode = 'BROWSERBASE_CONFIG_INVALID' | 'BROWSERBASE_PROVIDER_UNAVAILABLE' | 'BROWSERBASE_PROVIDER_RESPONSE_INVALID' | 'BROWSERBASE_SESSION_BINDING_FAILED' | 'BROWSERBASE_SESSION_HANDOFF_DISABLED' | 'BROWSERBASE_SESSION_HANDOFF_INVALID' | 'BROWSERBASE_LIVE_VIEW_UNAVAILABLE' | 'BROWSERBASE_SESSION_NOT_OWNED' | 'BROWSERBASE_SESSION_RELEASE_FAILED';
|
|
127
|
+
declare class BrowserbaseSessionError extends Error {
|
|
128
|
+
readonly code: BrowserbaseSessionErrorCode;
|
|
129
|
+
constructor(code: BrowserbaseSessionErrorCode, message: string);
|
|
130
|
+
}
|
|
131
|
+
/** Creates a short-lived assertion after the trusted agent host creates its Browserbase session. */
|
|
132
|
+
declare function createBrowserbaseSessionHandoffAssertion(input: BrowserbaseSessionHandoffAssertionInput, keyValue: Uint8Array): string;
|
|
133
|
+
/**
|
|
134
|
+
* Creates the recommended Browserbase deployment boundary. Provider lifecycle, ownership checks,
|
|
135
|
+
* remote connection resolution, guarded execution, and cleanup remain in one privileged object.
|
|
136
|
+
*/
|
|
137
|
+
declare function createBrowserbaseGuardedPlaywrightCheckoutRuntimeHost(config: BrowserbaseGuardedPlaywrightCheckoutRuntimeHostConfig): BrowserbaseGuardedPlaywrightCheckoutRuntimeHost;
|
|
138
|
+
|
|
139
|
+
export { type BrowserbaseAttachedSession, type BrowserbaseGuardedPlaywrightCheckoutRuntimeHost, type BrowserbaseGuardedPlaywrightCheckoutRuntimeHostConfig, type BrowserbaseOwnedLiveView, type BrowserbaseOwnedSession, type BrowserbaseSessionBinding, type BrowserbaseSessionBindingState, type BrowserbaseSessionBindingStore, type BrowserbaseSessionConfig, BrowserbaseSessionError, type BrowserbaseSessionErrorCode, type BrowserbaseSessionHandoff, type BrowserbaseSessionHandoffAssertionInput, type BrowserbaseSessionLifecycleOwner, type BrowserbaseSessionStatus, createBrowserbaseGuardedPlaywrightCheckoutRuntimeHost, createBrowserbaseSessionHandoffAssertion };
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { Browser } from 'playwright-core';
|
|
2
|
+
import { GuardedPlaywrightCheckoutHttpHandler, PlaywrightSessionObservation, GuardedPlaywrightCheckoutClient, PlaywrightCdpSessionRegistryConfig, EncryptedPlaywrightCheckoutTargetStoreConfig, GuardedPlaywrightCheckoutRuntimeConfig } from './playwright.js';
|
|
3
|
+
import './index.js';
|
|
4
|
+
|
|
5
|
+
type BrowserbaseSessionStatus = 'PENDING' | 'RUNNING' | 'ERROR' | 'TIMED_OUT' | 'COMPLETED';
|
|
6
|
+
type BrowserbaseSessionBindingState = 'ACTIVE' | 'REVOKED';
|
|
7
|
+
type BrowserbaseSessionLifecycleOwner = 'CONTO_RUNTIME' | 'AGENT_HOST';
|
|
8
|
+
/** Credential-free durable record. Never persist Browserbase connect URLs or API keys here. */
|
|
9
|
+
interface BrowserbaseSessionBinding {
|
|
10
|
+
browserSessionId: string;
|
|
11
|
+
organizationId: string;
|
|
12
|
+
agentId: string;
|
|
13
|
+
projectId: string;
|
|
14
|
+
/** Missing legacy values are treated as CONTO_RUNTIME. */
|
|
15
|
+
lifecycleOwner?: BrowserbaseSessionLifecycleOwner;
|
|
16
|
+
state: BrowserbaseSessionBindingState;
|
|
17
|
+
createdAt: string;
|
|
18
|
+
expiresAt: string;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Durable ownership port for remote sessions. `create` must reject duplicate IDs and `revoke`
|
|
22
|
+
* must atomically transition only an ACTIVE record matching every supplied ownership field.
|
|
23
|
+
*/
|
|
24
|
+
interface BrowserbaseSessionBindingStore {
|
|
25
|
+
create(binding: BrowserbaseSessionBinding): Promise<boolean>;
|
|
26
|
+
get(browserSessionId: string): Promise<BrowserbaseSessionBinding | null>;
|
|
27
|
+
revoke(input: {
|
|
28
|
+
browserSessionId: string;
|
|
29
|
+
organizationId: string;
|
|
30
|
+
agentId: string;
|
|
31
|
+
projectId: string;
|
|
32
|
+
revokedAt: string;
|
|
33
|
+
}): Promise<boolean>;
|
|
34
|
+
/** Required with contextId. Release only after Browserbase confirms the provider session closed. */
|
|
35
|
+
releaseContextLease?(input: {
|
|
36
|
+
browserSessionId: string;
|
|
37
|
+
organizationId: string;
|
|
38
|
+
agentId: string;
|
|
39
|
+
projectId: string;
|
|
40
|
+
}): Promise<boolean>;
|
|
41
|
+
}
|
|
42
|
+
interface BrowserbaseSessionConfig {
|
|
43
|
+
/** Browserbase credential retained by the privileged runtime. Conto credentials are rejected. */
|
|
44
|
+
apiKey: string;
|
|
45
|
+
projectId: string;
|
|
46
|
+
organizationId: string;
|
|
47
|
+
agentId: string;
|
|
48
|
+
bindingStore: BrowserbaseSessionBindingStore;
|
|
49
|
+
/** Optional 32-byte server-only key required to attach sessions created by an agent host. */
|
|
50
|
+
handoffKey?: Uint8Array;
|
|
51
|
+
/** Optional server-only Browserbase Context used to persist Link or merchant authentication. */
|
|
52
|
+
contextId?: string;
|
|
53
|
+
/** Browserbase session timeout. Defaults to 900 seconds. */
|
|
54
|
+
timeoutSeconds?: number;
|
|
55
|
+
/** Browserbase API request timeout. Defaults to 10 seconds and may not exceed 60 seconds. */
|
|
56
|
+
requestTimeoutMs?: number;
|
|
57
|
+
/** Injected for tests or runtimes with an instrumented fetch implementation. */
|
|
58
|
+
fetch?: typeof fetch;
|
|
59
|
+
now?: () => Date;
|
|
60
|
+
}
|
|
61
|
+
interface BrowserbaseGuardedPlaywrightCheckoutRuntimeHostConfig {
|
|
62
|
+
conto: GuardedPlaywrightCheckoutClient;
|
|
63
|
+
browserbase: BrowserbaseSessionConfig;
|
|
64
|
+
/** Usually `(url) => chromium.connectOverCDP(url)`. */
|
|
65
|
+
connectOverCDP(connectUrl: string): Promise<Browser>;
|
|
66
|
+
selectPage?: PlaywrightCdpSessionRegistryConfig['selectPage'];
|
|
67
|
+
maxSessions?: number;
|
|
68
|
+
targetStore: EncryptedPlaywrightCheckoutTargetStoreConfig;
|
|
69
|
+
dispatchAttemptFor: GuardedPlaywrightCheckoutRuntimeConfig['dispatchAttemptFor'];
|
|
70
|
+
/** Dedicated service credential. Conto and Browserbase API keys are rejected. */
|
|
71
|
+
token: string;
|
|
72
|
+
maxBodyBytes?: number;
|
|
73
|
+
clickTimeoutMs?: number;
|
|
74
|
+
popupTimeoutMs?: number;
|
|
75
|
+
targetTtlMs?: number;
|
|
76
|
+
now?: () => Date;
|
|
77
|
+
}
|
|
78
|
+
/** Safe session projection for the agent-facing browser launcher. */
|
|
79
|
+
interface BrowserbaseOwnedSession {
|
|
80
|
+
browserSessionId: string;
|
|
81
|
+
status: Extract<BrowserbaseSessionStatus, 'PENDING' | 'RUNNING'>;
|
|
82
|
+
expiresAt: string;
|
|
83
|
+
}
|
|
84
|
+
/** Proof-carrying request from a trusted agent host for an existing Browserbase session. */
|
|
85
|
+
interface BrowserbaseSessionHandoff {
|
|
86
|
+
browserSessionId: string;
|
|
87
|
+
handoffAssertion: string;
|
|
88
|
+
}
|
|
89
|
+
/** Safe projection for a session whose provider lifecycle remains owned by the agent host. */
|
|
90
|
+
interface BrowserbaseAttachedSession extends BrowserbaseOwnedSession {
|
|
91
|
+
lifecycleOwner: 'AGENT_HOST';
|
|
92
|
+
}
|
|
93
|
+
interface BrowserbaseSessionHandoffAssertionInput {
|
|
94
|
+
browserSessionId: string;
|
|
95
|
+
projectId: string;
|
|
96
|
+
organizationId: string;
|
|
97
|
+
agentId: string;
|
|
98
|
+
expiresAt: string;
|
|
99
|
+
}
|
|
100
|
+
/** Operator-only capability for a human authentication or challenge handoff. */
|
|
101
|
+
interface BrowserbaseOwnedLiveView {
|
|
102
|
+
browserSessionId: string;
|
|
103
|
+
liveViewUrl: string;
|
|
104
|
+
expiresAt: string;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Closed Browserbase lifecycle plus guarded checkout façade. It never exposes the provider API
|
|
108
|
+
* key, CDP connection URL, Playwright page, target store, discovery primitive, or raw dispatch.
|
|
109
|
+
*/
|
|
110
|
+
interface BrowserbaseGuardedPlaywrightCheckoutRuntimeHost {
|
|
111
|
+
handler: GuardedPlaywrightCheckoutHttpHandler;
|
|
112
|
+
createSession(): Promise<BrowserbaseOwnedSession>;
|
|
113
|
+
/** Attaches an existing agent-host session after verifying a short-lived server assertion. */
|
|
114
|
+
attachSession(input: BrowserbaseSessionHandoff): Promise<BrowserbaseAttachedSession>;
|
|
115
|
+
/** Read-only, bounded projection of the exact runtime-owned page. */
|
|
116
|
+
observeSession(browserSessionId: string): Promise<PlaywrightSessionObservation>;
|
|
117
|
+
/** Returns a short-lived provider capability only to a separately authenticated operator path. */
|
|
118
|
+
liveViewForSession(browserSessionId: string): Promise<BrowserbaseOwnedLiveView>;
|
|
119
|
+
/** Revokes Conto ownership first, closes the local connection, then releases Browserbase. */
|
|
120
|
+
releaseSession(browserSessionId: string): Promise<void>;
|
|
121
|
+
/** Revokes the Conto binding without ending the externally owned Browserbase session. */
|
|
122
|
+
detachSession(browserSessionId: string): Promise<void>;
|
|
123
|
+
/** Closes local Playwright connections. Call releaseSession for each keep-alive provider session. */
|
|
124
|
+
close(): Promise<void>;
|
|
125
|
+
}
|
|
126
|
+
type BrowserbaseSessionErrorCode = 'BROWSERBASE_CONFIG_INVALID' | 'BROWSERBASE_PROVIDER_UNAVAILABLE' | 'BROWSERBASE_PROVIDER_RESPONSE_INVALID' | 'BROWSERBASE_SESSION_BINDING_FAILED' | 'BROWSERBASE_SESSION_HANDOFF_DISABLED' | 'BROWSERBASE_SESSION_HANDOFF_INVALID' | 'BROWSERBASE_LIVE_VIEW_UNAVAILABLE' | 'BROWSERBASE_SESSION_NOT_OWNED' | 'BROWSERBASE_SESSION_RELEASE_FAILED';
|
|
127
|
+
declare class BrowserbaseSessionError extends Error {
|
|
128
|
+
readonly code: BrowserbaseSessionErrorCode;
|
|
129
|
+
constructor(code: BrowserbaseSessionErrorCode, message: string);
|
|
130
|
+
}
|
|
131
|
+
/** Creates a short-lived assertion after the trusted agent host creates its Browserbase session. */
|
|
132
|
+
declare function createBrowserbaseSessionHandoffAssertion(input: BrowserbaseSessionHandoffAssertionInput, keyValue: Uint8Array): string;
|
|
133
|
+
/**
|
|
134
|
+
* Creates the recommended Browserbase deployment boundary. Provider lifecycle, ownership checks,
|
|
135
|
+
* remote connection resolution, guarded execution, and cleanup remain in one privileged object.
|
|
136
|
+
*/
|
|
137
|
+
declare function createBrowserbaseGuardedPlaywrightCheckoutRuntimeHost(config: BrowserbaseGuardedPlaywrightCheckoutRuntimeHostConfig): BrowserbaseGuardedPlaywrightCheckoutRuntimeHost;
|
|
138
|
+
|
|
139
|
+
export { type BrowserbaseAttachedSession, type BrowserbaseGuardedPlaywrightCheckoutRuntimeHost, type BrowserbaseGuardedPlaywrightCheckoutRuntimeHostConfig, type BrowserbaseOwnedLiveView, type BrowserbaseOwnedSession, type BrowserbaseSessionBinding, type BrowserbaseSessionBindingState, type BrowserbaseSessionBindingStore, type BrowserbaseSessionConfig, BrowserbaseSessionError, type BrowserbaseSessionErrorCode, type BrowserbaseSessionHandoff, type BrowserbaseSessionHandoffAssertionInput, type BrowserbaseSessionLifecycleOwner, type BrowserbaseSessionStatus, createBrowserbaseGuardedPlaywrightCheckoutRuntimeHost, createBrowserbaseSessionHandoffAssertion };
|