@conto_finance/sdk 0.5.0 → 0.5.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.
- package/README.md +6 -31
- package/dist/browserbase.d.mts +12 -1
- package/dist/browserbase.d.ts +12 -1
- package/dist/browserbase.js +14 -8
- package/dist/browserbase.mjs +12 -7
- package/dist/index.d.mts +21 -6
- package/dist/index.d.ts +21 -6
- package/dist/index.js +44 -16
- package/dist/index.mjs +44 -16
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# @conto_finance/sdk
|
|
2
2
|
|
|
3
3
|
Conto is a buyer-side control layer. Integrate it in the agent owner's runtime or payment tools;
|
|
4
|
-
the owner or budget holder sets policy before the agent pays.
|
|
4
|
+
the owner or budget holder sets policy before the agent pays.
|
|
5
5
|
See [buyer-side control](https://conto.finance/docs/guides/buyer-side-control) for the authorization
|
|
6
6
|
and execution boundary.
|
|
7
7
|
|
|
@@ -99,35 +99,10 @@ await admin.cards.resumeForAgent('agent_id', card.id);
|
|
|
99
99
|
await admin.cards.revokeFromAgent('agent_id', card.id);
|
|
100
100
|
```
|
|
101
101
|
|
|
102
|
-
The policy overlay stops at approval, claiming, and reconciliation. For
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
package.
|
|
107
|
-
|
|
108
|
-
```typescript
|
|
109
|
-
import { ContoCardAccess } from '@conto_finance/card-access';
|
|
110
|
-
|
|
111
|
-
const cardAccess = new ContoCardAccess({
|
|
112
|
-
policy: conto.cards,
|
|
113
|
-
integrationId: 'procurement-agent-production',
|
|
114
|
-
deployment: {
|
|
115
|
-
credentialCustody: 'CUSTOMER',
|
|
116
|
-
agentHasRawCredentialAccess: false,
|
|
117
|
-
uncontrolledAgentPaymentPath: false,
|
|
118
|
-
},
|
|
119
|
-
executor: customerHostedExecutor,
|
|
120
|
-
});
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
Card Access claims each approved request exactly once before the executor can run. A
|
|
124
|
-
duplicate or uncertain claim cannot invoke the executor again. It remains
|
|
125
|
-
bypassable if another person or tool can access the card, and results are
|
|
126
|
-
self-reported rather than issuer-verified. The executor receives the normalized
|
|
127
|
-
purchase `idempotencyKey`; pass it to the payment processor so ambiguous
|
|
128
|
-
processor responses cannot create duplicate charges. The legacy `conto.cards.controlled()`
|
|
129
|
-
helper remains available for compatibility, but new customer-hosted enforcement
|
|
130
|
-
should use the standalone Card Access package. Use
|
|
102
|
+
The policy overlay stops at approval, claiming, and reconciliation. For
|
|
103
|
+
connected cards, see
|
|
104
|
+
[Connected cards](https://conto.finance/docs/guides/connected-cards).
|
|
105
|
+
The legacy `conto.cards.controlled()` helper remains available for compatibility. Use
|
|
131
106
|
`admin.cards.listRequests({ status: 'EXECUTING' })` for reconciliation and
|
|
132
107
|
`admin.cards.pause(card.id)` to revoke unclaimed grants and stop new approvals
|
|
133
108
|
in the Conto-controlled path.
|
|
@@ -276,7 +251,7 @@ requirements.
|
|
|
276
251
|
For browser checkouts on supported rails (Link, card, Shop Pay, or PayPal), use
|
|
277
252
|
`runGuardedCheckout` with `executionMethod: 'BROWSER_CHECKOUT'`. Other rails and checkout flows are
|
|
278
253
|
not covered. It binds and atomically authorizes one exact Link, card,
|
|
279
|
-
Shop Pay, or PayPal browser action without requiring
|
|
254
|
+
Shop Pay, or PayPal browser action without requiring private provider integration. The
|
|
280
255
|
privileged browser executor must be available only through this wrapper; an unrestricted click or
|
|
281
256
|
payment tool would bypass the control. Persist its stable dispatch attempt before calling the helper; it owns authorization,
|
|
282
257
|
one-use claim, the privileged callback, and finalization. See `docs/AGENT_CHECKOUT_GUARD.md` for the
|
package/dist/browserbase.d.mts
CHANGED
|
@@ -130,12 +130,23 @@ declare class BrowserbaseSessionError extends Error {
|
|
|
130
130
|
readonly code: BrowserbaseSessionErrorCode;
|
|
131
131
|
constructor(code: BrowserbaseSessionErrorCode, message: string);
|
|
132
132
|
}
|
|
133
|
+
interface BrowserbaseSessionManager {
|
|
134
|
+
createSession(): Promise<BrowserbaseOwnedSession>;
|
|
135
|
+
attachSession(input: BrowserbaseSessionHandoff): Promise<BrowserbaseAttachedSession>;
|
|
136
|
+
connectUrlForSession(browserSessionId: string): Promise<string | null>;
|
|
137
|
+
liveViewForSession(browserSessionId: string): Promise<BrowserbaseOwnedLiveView>;
|
|
138
|
+
revokeSession(browserSessionId: string, lifecycleOwner: BrowserbaseSessionLifecycleOwner): Promise<boolean>;
|
|
139
|
+
releaseProviderSession(browserSessionId: string): Promise<void>;
|
|
140
|
+
releaseContextLease(browserSessionId: string): Promise<boolean>;
|
|
141
|
+
}
|
|
133
142
|
/** Creates a short-lived assertion after the trusted agent host creates its Browserbase session. */
|
|
134
143
|
declare function createBrowserbaseSessionHandoffAssertion(input: BrowserbaseSessionHandoffAssertionInput, keyValue: Uint8Array): string;
|
|
144
|
+
/** Server-only capability. Never expose connect URLs or this manager as agent tools. */
|
|
145
|
+
declare function createBrowserbaseSessionManager(config: BrowserbaseSessionConfig): BrowserbaseSessionManager;
|
|
135
146
|
/**
|
|
136
147
|
* Creates the recommended Browserbase deployment boundary. Provider lifecycle, ownership checks,
|
|
137
148
|
* remote connection resolution, guarded execution, and cleanup remain in one privileged object.
|
|
138
149
|
*/
|
|
139
150
|
declare function createBrowserbaseGuardedPlaywrightCheckoutRuntimeHost(config: BrowserbaseGuardedPlaywrightCheckoutRuntimeHostConfig): BrowserbaseGuardedPlaywrightCheckoutRuntimeHost;
|
|
140
151
|
|
|
141
|
-
export { BROWSERBASE_CONNECT_ORIGINS, 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 };
|
|
152
|
+
export { BROWSERBASE_CONNECT_ORIGINS, 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 BrowserbaseSessionManager, type BrowserbaseSessionStatus, createBrowserbaseGuardedPlaywrightCheckoutRuntimeHost, createBrowserbaseSessionHandoffAssertion, createBrowserbaseSessionManager };
|
package/dist/browserbase.d.ts
CHANGED
|
@@ -130,12 +130,23 @@ declare class BrowserbaseSessionError extends Error {
|
|
|
130
130
|
readonly code: BrowserbaseSessionErrorCode;
|
|
131
131
|
constructor(code: BrowserbaseSessionErrorCode, message: string);
|
|
132
132
|
}
|
|
133
|
+
interface BrowserbaseSessionManager {
|
|
134
|
+
createSession(): Promise<BrowserbaseOwnedSession>;
|
|
135
|
+
attachSession(input: BrowserbaseSessionHandoff): Promise<BrowserbaseAttachedSession>;
|
|
136
|
+
connectUrlForSession(browserSessionId: string): Promise<string | null>;
|
|
137
|
+
liveViewForSession(browserSessionId: string): Promise<BrowserbaseOwnedLiveView>;
|
|
138
|
+
revokeSession(browserSessionId: string, lifecycleOwner: BrowserbaseSessionLifecycleOwner): Promise<boolean>;
|
|
139
|
+
releaseProviderSession(browserSessionId: string): Promise<void>;
|
|
140
|
+
releaseContextLease(browserSessionId: string): Promise<boolean>;
|
|
141
|
+
}
|
|
133
142
|
/** Creates a short-lived assertion after the trusted agent host creates its Browserbase session. */
|
|
134
143
|
declare function createBrowserbaseSessionHandoffAssertion(input: BrowserbaseSessionHandoffAssertionInput, keyValue: Uint8Array): string;
|
|
144
|
+
/** Server-only capability. Never expose connect URLs or this manager as agent tools. */
|
|
145
|
+
declare function createBrowserbaseSessionManager(config: BrowserbaseSessionConfig): BrowserbaseSessionManager;
|
|
135
146
|
/**
|
|
136
147
|
* Creates the recommended Browserbase deployment boundary. Provider lifecycle, ownership checks,
|
|
137
148
|
* remote connection resolution, guarded execution, and cleanup remain in one privileged object.
|
|
138
149
|
*/
|
|
139
150
|
declare function createBrowserbaseGuardedPlaywrightCheckoutRuntimeHost(config: BrowserbaseGuardedPlaywrightCheckoutRuntimeHostConfig): BrowserbaseGuardedPlaywrightCheckoutRuntimeHost;
|
|
140
151
|
|
|
141
|
-
export { BROWSERBASE_CONNECT_ORIGINS, 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 };
|
|
152
|
+
export { BROWSERBASE_CONNECT_ORIGINS, 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 BrowserbaseSessionManager, type BrowserbaseSessionStatus, createBrowserbaseGuardedPlaywrightCheckoutRuntimeHost, createBrowserbaseSessionHandoffAssertion, createBrowserbaseSessionManager };
|
package/dist/browserbase.js
CHANGED
|
@@ -23,7 +23,8 @@ __export(browserbase_exports, {
|
|
|
23
23
|
BROWSERBASE_CONNECT_ORIGINS: () => BROWSERBASE_CONNECT_ORIGINS,
|
|
24
24
|
BrowserbaseSessionError: () => BrowserbaseSessionError,
|
|
25
25
|
createBrowserbaseGuardedPlaywrightCheckoutRuntimeHost: () => createBrowserbaseGuardedPlaywrightCheckoutRuntimeHost,
|
|
26
|
-
createBrowserbaseSessionHandoffAssertion: () => createBrowserbaseSessionHandoffAssertion
|
|
26
|
+
createBrowserbaseSessionHandoffAssertion: () => createBrowserbaseSessionHandoffAssertion,
|
|
27
|
+
createBrowserbaseSessionManager: () => createBrowserbaseSessionManager
|
|
27
28
|
});
|
|
28
29
|
module.exports = __toCommonJS(browserbase_exports);
|
|
29
30
|
var import_node_crypto3 = require("crypto");
|
|
@@ -1572,7 +1573,9 @@ function parseProviderSession(value, expectedProjectId, expectedSessionId) {
|
|
|
1572
1573
|
status,
|
|
1573
1574
|
createdAt,
|
|
1574
1575
|
expiresAt,
|
|
1575
|
-
|
|
1576
|
+
// Completed sessions need not retain a connection capability. Validate it
|
|
1577
|
+
// only for active states; identity and timestamps above still must match.
|
|
1578
|
+
connectUrl: status === "PENDING" || status === "RUNNING" ? secureConnectUrl(record.connectUrl) : null
|
|
1576
1579
|
});
|
|
1577
1580
|
}
|
|
1578
1581
|
async function readProviderJson(response) {
|
|
@@ -1668,11 +1671,13 @@ function createBrowserbaseSessionManager(config) {
|
|
|
1668
1671
|
projectId,
|
|
1669
1672
|
timeout: durationSeconds,
|
|
1670
1673
|
keepAlive: true,
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1674
|
+
proxies: false,
|
|
1675
|
+
browserSettings: {
|
|
1676
|
+
recordSession: false,
|
|
1677
|
+
logSession: false,
|
|
1678
|
+
solveCaptchas: false,
|
|
1679
|
+
...contextId ? { context: { id: contextId, persist: true } } : {}
|
|
1680
|
+
}
|
|
1676
1681
|
})
|
|
1677
1682
|
});
|
|
1678
1683
|
if (response.status !== 201) {
|
|
@@ -1981,5 +1986,6 @@ function createBrowserbaseGuardedPlaywrightCheckoutRuntimeHost(config) {
|
|
|
1981
1986
|
BROWSERBASE_CONNECT_ORIGINS,
|
|
1982
1987
|
BrowserbaseSessionError,
|
|
1983
1988
|
createBrowserbaseGuardedPlaywrightCheckoutRuntimeHost,
|
|
1984
|
-
createBrowserbaseSessionHandoffAssertion
|
|
1989
|
+
createBrowserbaseSessionHandoffAssertion,
|
|
1990
|
+
createBrowserbaseSessionManager
|
|
1985
1991
|
});
|
package/dist/browserbase.mjs
CHANGED
|
@@ -196,7 +196,9 @@ function parseProviderSession(value, expectedProjectId, expectedSessionId) {
|
|
|
196
196
|
status,
|
|
197
197
|
createdAt,
|
|
198
198
|
expiresAt,
|
|
199
|
-
|
|
199
|
+
// Completed sessions need not retain a connection capability. Validate it
|
|
200
|
+
// only for active states; identity and timestamps above still must match.
|
|
201
|
+
connectUrl: status === "PENDING" || status === "RUNNING" ? secureConnectUrl(record.connectUrl) : null
|
|
200
202
|
});
|
|
201
203
|
}
|
|
202
204
|
async function readProviderJson(response) {
|
|
@@ -292,11 +294,13 @@ function createBrowserbaseSessionManager(config) {
|
|
|
292
294
|
projectId,
|
|
293
295
|
timeout: durationSeconds,
|
|
294
296
|
keepAlive: true,
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
297
|
+
proxies: false,
|
|
298
|
+
browserSettings: {
|
|
299
|
+
recordSession: false,
|
|
300
|
+
logSession: false,
|
|
301
|
+
solveCaptchas: false,
|
|
302
|
+
...contextId ? { context: { id: contextId, persist: true } } : {}
|
|
303
|
+
}
|
|
300
304
|
})
|
|
301
305
|
});
|
|
302
306
|
if (response.status !== 201) {
|
|
@@ -604,5 +608,6 @@ export {
|
|
|
604
608
|
BROWSERBASE_CONNECT_ORIGINS,
|
|
605
609
|
BrowserbaseSessionError,
|
|
606
610
|
createBrowserbaseGuardedPlaywrightCheckoutRuntimeHost,
|
|
607
|
-
createBrowserbaseSessionHandoffAssertion
|
|
611
|
+
createBrowserbaseSessionHandoffAssertion,
|
|
612
|
+
createBrowserbaseSessionManager
|
|
608
613
|
};
|
package/dist/index.d.mts
CHANGED
|
@@ -65,7 +65,7 @@ interface PaginatedResponse<T> {
|
|
|
65
65
|
limit: number;
|
|
66
66
|
offset: number;
|
|
67
67
|
}
|
|
68
|
-
type AgentType = 'OPENAI_ASSISTANT' | 'ANTHROPIC_CLAUDE' | '
|
|
68
|
+
type AgentType = 'OPENAI_ASSISTANT' | 'ANTHROPIC_CLAUDE' | 'AUTOGPT' | 'CUSTOM';
|
|
69
69
|
type AgentStatus = 'ACTIVE' | 'PAUSED' | 'SUSPENDED' | 'REVOKED' | 'FROZEN' | 'DELETED';
|
|
70
70
|
type AgentEnvironment = 'DEV' | 'STAGING' | 'PROD';
|
|
71
71
|
type AgentRiskTier = 'LOW' | 'MEDIUM' | 'HIGH' | 'CRITICAL';
|
|
@@ -1164,6 +1164,11 @@ interface PaymentRequestResult {
|
|
|
1164
1164
|
interface PaymentExecuteResult {
|
|
1165
1165
|
/** Payment request ID */
|
|
1166
1166
|
requestId: string;
|
|
1167
|
+
/**
|
|
1168
|
+
* True when the payment had already been executed, for example by an
|
|
1169
|
+
* approver in Conto. The receipt is the existing one; nothing was sent again.
|
|
1170
|
+
*/
|
|
1171
|
+
alreadyExecuted?: boolean;
|
|
1167
1172
|
/** Customer-facing execution state */
|
|
1168
1173
|
status: 'processing' | 'completed';
|
|
1169
1174
|
/** Amount sent */
|
|
@@ -1196,6 +1201,8 @@ interface PaymentStatusResult {
|
|
|
1196
1201
|
category: string | null;
|
|
1197
1202
|
expiresAt: string | null;
|
|
1198
1203
|
createdAt: string;
|
|
1204
|
+
/** Customer-facing reasons for a declined payment or a pending review. */
|
|
1205
|
+
reasons?: string[];
|
|
1199
1206
|
action: null;
|
|
1200
1207
|
transaction: {
|
|
1201
1208
|
/** Stable Conto transaction ID */
|
|
@@ -1855,11 +1862,17 @@ interface ProtocolPreAuthorizeResult {
|
|
|
1855
1862
|
authorized: boolean;
|
|
1856
1863
|
decision: 'approved' | 'declined' | 'review_required';
|
|
1857
1864
|
message: string;
|
|
1865
|
+
/**
|
|
1866
|
+
* Present when not authorized. Fixed reasons the agent can act on, such as a
|
|
1867
|
+
* spending limit or a service that is not allowed. Never includes rule values.
|
|
1868
|
+
*/
|
|
1869
|
+
reasons?: string[];
|
|
1870
|
+
/** Present when not authorized. Codes for `reasons`, for example `SPENDING_LIMIT`. */
|
|
1871
|
+
reasonCodes?: string[];
|
|
1858
1872
|
/**
|
|
1859
1873
|
* Present when authorized. Pass grantId and grantSignature to record(). A
|
|
1860
1874
|
* record without a valid, unexpired grant is accepted but treated as a policy
|
|
1861
|
-
* bypass: the payment is flagged and the owner is alerted.
|
|
1862
|
-
* can also have the agent frozen automatically.
|
|
1875
|
+
* bypass: the payment is flagged and the owner is alerted.
|
|
1863
1876
|
*/
|
|
1864
1877
|
grantId?: string;
|
|
1865
1878
|
grantSignature?: string;
|
|
@@ -2265,7 +2278,7 @@ declare class ControlledExternalCardPaymentTool<TReceipt = unknown> {
|
|
|
2265
2278
|
pay(input: ExternalCardApprovalInput): Promise<ControlledExternalCardPaymentResult<TReceipt>>;
|
|
2266
2279
|
}
|
|
2267
2280
|
/**
|
|
2268
|
-
* Agent client for connected cards (
|
|
2281
|
+
* Agent client for connected cards (Builder and Enterprise plans).
|
|
2269
2282
|
*
|
|
2270
2283
|
* A connected card is a customer card enrolled through the provider and
|
|
2271
2284
|
* delegated to this agent. `draw` mints one single-use credential against a
|
|
@@ -2273,7 +2286,7 @@ declare class ControlledExternalCardPaymentTool<TReceipt = unknown> {
|
|
|
2273
2286
|
* draw against. This is a separate rail from {@link CardsClient}: it does not
|
|
2274
2287
|
* share endpoints, scopes, or types with the external-card policy overlay.
|
|
2275
2288
|
*
|
|
2276
|
-
*
|
|
2289
|
+
* On plans without connected cards, these methods return an upgrade error.
|
|
2277
2290
|
*/
|
|
2278
2291
|
declare class ConnectedCardsClient {
|
|
2279
2292
|
private client;
|
|
@@ -2368,7 +2381,9 @@ declare class PaymentsClient {
|
|
|
2368
2381
|
* Execute an approved payment.
|
|
2369
2382
|
*
|
|
2370
2383
|
* This sends the onchain transaction. Only works for payments
|
|
2371
|
-
* with status 'APPROVED'.
|
|
2384
|
+
* with status 'APPROVED'. If an approver already executed the payment by
|
|
2385
|
+
* approving it in Conto, this returns the existing receipt with
|
|
2386
|
+
* `alreadyExecuted: true` and sends nothing.
|
|
2372
2387
|
*
|
|
2373
2388
|
* @param requestId - The requestId from a successful payment request
|
|
2374
2389
|
*
|
package/dist/index.d.ts
CHANGED
|
@@ -65,7 +65,7 @@ interface PaginatedResponse<T> {
|
|
|
65
65
|
limit: number;
|
|
66
66
|
offset: number;
|
|
67
67
|
}
|
|
68
|
-
type AgentType = 'OPENAI_ASSISTANT' | 'ANTHROPIC_CLAUDE' | '
|
|
68
|
+
type AgentType = 'OPENAI_ASSISTANT' | 'ANTHROPIC_CLAUDE' | 'AUTOGPT' | 'CUSTOM';
|
|
69
69
|
type AgentStatus = 'ACTIVE' | 'PAUSED' | 'SUSPENDED' | 'REVOKED' | 'FROZEN' | 'DELETED';
|
|
70
70
|
type AgentEnvironment = 'DEV' | 'STAGING' | 'PROD';
|
|
71
71
|
type AgentRiskTier = 'LOW' | 'MEDIUM' | 'HIGH' | 'CRITICAL';
|
|
@@ -1164,6 +1164,11 @@ interface PaymentRequestResult {
|
|
|
1164
1164
|
interface PaymentExecuteResult {
|
|
1165
1165
|
/** Payment request ID */
|
|
1166
1166
|
requestId: string;
|
|
1167
|
+
/**
|
|
1168
|
+
* True when the payment had already been executed, for example by an
|
|
1169
|
+
* approver in Conto. The receipt is the existing one; nothing was sent again.
|
|
1170
|
+
*/
|
|
1171
|
+
alreadyExecuted?: boolean;
|
|
1167
1172
|
/** Customer-facing execution state */
|
|
1168
1173
|
status: 'processing' | 'completed';
|
|
1169
1174
|
/** Amount sent */
|
|
@@ -1196,6 +1201,8 @@ interface PaymentStatusResult {
|
|
|
1196
1201
|
category: string | null;
|
|
1197
1202
|
expiresAt: string | null;
|
|
1198
1203
|
createdAt: string;
|
|
1204
|
+
/** Customer-facing reasons for a declined payment or a pending review. */
|
|
1205
|
+
reasons?: string[];
|
|
1199
1206
|
action: null;
|
|
1200
1207
|
transaction: {
|
|
1201
1208
|
/** Stable Conto transaction ID */
|
|
@@ -1855,11 +1862,17 @@ interface ProtocolPreAuthorizeResult {
|
|
|
1855
1862
|
authorized: boolean;
|
|
1856
1863
|
decision: 'approved' | 'declined' | 'review_required';
|
|
1857
1864
|
message: string;
|
|
1865
|
+
/**
|
|
1866
|
+
* Present when not authorized. Fixed reasons the agent can act on, such as a
|
|
1867
|
+
* spending limit or a service that is not allowed. Never includes rule values.
|
|
1868
|
+
*/
|
|
1869
|
+
reasons?: string[];
|
|
1870
|
+
/** Present when not authorized. Codes for `reasons`, for example `SPENDING_LIMIT`. */
|
|
1871
|
+
reasonCodes?: string[];
|
|
1858
1872
|
/**
|
|
1859
1873
|
* Present when authorized. Pass grantId and grantSignature to record(). A
|
|
1860
1874
|
* record without a valid, unexpired grant is accepted but treated as a policy
|
|
1861
|
-
* bypass: the payment is flagged and the owner is alerted.
|
|
1862
|
-
* can also have the agent frozen automatically.
|
|
1875
|
+
* bypass: the payment is flagged and the owner is alerted.
|
|
1863
1876
|
*/
|
|
1864
1877
|
grantId?: string;
|
|
1865
1878
|
grantSignature?: string;
|
|
@@ -2265,7 +2278,7 @@ declare class ControlledExternalCardPaymentTool<TReceipt = unknown> {
|
|
|
2265
2278
|
pay(input: ExternalCardApprovalInput): Promise<ControlledExternalCardPaymentResult<TReceipt>>;
|
|
2266
2279
|
}
|
|
2267
2280
|
/**
|
|
2268
|
-
* Agent client for connected cards (
|
|
2281
|
+
* Agent client for connected cards (Builder and Enterprise plans).
|
|
2269
2282
|
*
|
|
2270
2283
|
* A connected card is a customer card enrolled through the provider and
|
|
2271
2284
|
* delegated to this agent. `draw` mints one single-use credential against a
|
|
@@ -2273,7 +2286,7 @@ declare class ControlledExternalCardPaymentTool<TReceipt = unknown> {
|
|
|
2273
2286
|
* draw against. This is a separate rail from {@link CardsClient}: it does not
|
|
2274
2287
|
* share endpoints, scopes, or types with the external-card policy overlay.
|
|
2275
2288
|
*
|
|
2276
|
-
*
|
|
2289
|
+
* On plans without connected cards, these methods return an upgrade error.
|
|
2277
2290
|
*/
|
|
2278
2291
|
declare class ConnectedCardsClient {
|
|
2279
2292
|
private client;
|
|
@@ -2368,7 +2381,9 @@ declare class PaymentsClient {
|
|
|
2368
2381
|
* Execute an approved payment.
|
|
2369
2382
|
*
|
|
2370
2383
|
* This sends the onchain transaction. Only works for payments
|
|
2371
|
-
* with status 'APPROVED'.
|
|
2384
|
+
* with status 'APPROVED'. If an approver already executed the payment by
|
|
2385
|
+
* approving it in Conto, this returns the existing receipt with
|
|
2386
|
+
* `alreadyExecuted: true` and sends nothing.
|
|
2372
2387
|
*
|
|
2373
2388
|
* @param requestId - The requestId from a successful payment request
|
|
2374
2389
|
*
|
package/dist/index.js
CHANGED
|
@@ -39,7 +39,7 @@ var require_package = __commonJS({
|
|
|
39
39
|
"package.json"(exports2, module2) {
|
|
40
40
|
module2.exports = {
|
|
41
41
|
name: "@conto_finance/sdk",
|
|
42
|
-
version: "0.5.
|
|
42
|
+
version: "0.5.2",
|
|
43
43
|
description: "Conto SDK for AI agent payment authorization",
|
|
44
44
|
main: "./dist/index.js",
|
|
45
45
|
module: "./dist/index.mjs",
|
|
@@ -172,7 +172,10 @@ var PUBLIC_PAYMENT_REASONS = /* @__PURE__ */ new Set([
|
|
|
172
172
|
"This payment is outside the permitted schedule.",
|
|
173
173
|
"The available payment budget is insufficient.",
|
|
174
174
|
"This payment does not meet the current payment controls.",
|
|
175
|
-
"This payment requires approval before it can proceed."
|
|
175
|
+
"This payment requires approval before it can proceed.",
|
|
176
|
+
"No usable wallet is linked to this agent.",
|
|
177
|
+
"This payee needs review before payments to it can proceed automatically.",
|
|
178
|
+
"A reviewer declined this payment."
|
|
176
179
|
]);
|
|
177
180
|
function customerPaymentReasons(value) {
|
|
178
181
|
return Array.isArray(value) ? [
|
|
@@ -352,9 +355,11 @@ function responseErrorMetadata(response, data) {
|
|
|
352
355
|
const body = record(data);
|
|
353
356
|
const code = safeErrorCode(body.code, response.status);
|
|
354
357
|
const bodyRetryAfter = typeof body.retryAfter === "number" || typeof body.retryAfter === "string" ? parseRetryAfter(String(body.retryAfter)) : void 0;
|
|
358
|
+
const reasons = customerPaymentReasons(body.reasons);
|
|
355
359
|
return {
|
|
356
360
|
code,
|
|
357
361
|
status: response.status,
|
|
362
|
+
...reasons.length > 0 ? { reasons } : {},
|
|
358
363
|
fieldErrors: customerFieldErrors(body, response.status),
|
|
359
364
|
requestId: safeRequestId(
|
|
360
365
|
response.headers.get("x-request-id"),
|
|
@@ -1705,6 +1710,27 @@ var ConnectedCardsClient = class {
|
|
|
1705
1710
|
return this.client.request("GET", "/api/sdk/connected-cards");
|
|
1706
1711
|
}
|
|
1707
1712
|
};
|
|
1713
|
+
function approvalRetryGuidance(requestId) {
|
|
1714
|
+
const id = JSON.stringify(requestId);
|
|
1715
|
+
return `An approver in Conto executes the payment when they approve it. After approval, call payments.execute(${id}) or payments.status(${id}) to get the receipt. Do not request the payment again.`;
|
|
1716
|
+
}
|
|
1717
|
+
function executeRetryGuidance(code, requestId) {
|
|
1718
|
+
const id = JSON.stringify(requestId);
|
|
1719
|
+
switch (code) {
|
|
1720
|
+
case "APPROVAL_PENDING":
|
|
1721
|
+
return approvalRetryGuidance(requestId);
|
|
1722
|
+
case "POLICY_DENIED_AT_EXECUTION":
|
|
1723
|
+
case "PAYMENT_DENIED":
|
|
1724
|
+
return "This payment was declined and will not execute. Do not retry it; review the reasons before requesting a new payment.";
|
|
1725
|
+
case "POLICY_REAPPROVAL_REQUIRED":
|
|
1726
|
+
return "This payment now needs approval and will not execute. Request a new payment and wait for approval.";
|
|
1727
|
+
case "PAYMENT_PROCESSING":
|
|
1728
|
+
case "NEEDS_RECONCILIATION":
|
|
1729
|
+
return `Do not execute again. Check payments.status(${id}) for the outcome.`;
|
|
1730
|
+
default:
|
|
1731
|
+
return void 0;
|
|
1732
|
+
}
|
|
1733
|
+
}
|
|
1708
1734
|
var PaymentsClient = class {
|
|
1709
1735
|
constructor(client) {
|
|
1710
1736
|
this.client = client;
|
|
@@ -1778,7 +1804,9 @@ var PaymentsClient = class {
|
|
|
1778
1804
|
* Execute an approved payment.
|
|
1779
1805
|
*
|
|
1780
1806
|
* This sends the onchain transaction. Only works for payments
|
|
1781
|
-
* with status 'APPROVED'.
|
|
1807
|
+
* with status 'APPROVED'. If an approver already executed the payment by
|
|
1808
|
+
* approving it in Conto, this returns the existing receipt with
|
|
1809
|
+
* `alreadyExecuted: true` and sends nothing.
|
|
1782
1810
|
*
|
|
1783
1811
|
* @param requestId - The requestId from a successful payment request
|
|
1784
1812
|
*
|
|
@@ -1800,18 +1828,17 @@ var PaymentsClient = class {
|
|
|
1800
1828
|
{}
|
|
1801
1829
|
);
|
|
1802
1830
|
} catch (error) {
|
|
1803
|
-
if (error instanceof ContoError
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
}
|
|
1814
|
-
throw error;
|
|
1831
|
+
if (!(error instanceof ContoError)) throw error;
|
|
1832
|
+
const retryGuidance = error.status === 0 ? `Check payments.status(${JSON.stringify(requestId)}) before attempting execution again.` : executeRetryGuidance(error.code, requestId);
|
|
1833
|
+
if (!retryGuidance) throw error;
|
|
1834
|
+
throw new ContoError(error.message, {
|
|
1835
|
+
code: error.code,
|
|
1836
|
+
status: error.status,
|
|
1837
|
+
requestId: error.requestId,
|
|
1838
|
+
retryAfter: error.retryAfter,
|
|
1839
|
+
reasons: error.reasons,
|
|
1840
|
+
retryGuidance
|
|
1841
|
+
});
|
|
1815
1842
|
}
|
|
1816
1843
|
}
|
|
1817
1844
|
/**
|
|
@@ -1876,8 +1903,9 @@ var PaymentsClient = class {
|
|
|
1876
1903
|
throw new ContoError("Payment requires manual approval", {
|
|
1877
1904
|
code: "REQUIRES_APPROVAL",
|
|
1878
1905
|
status: 202,
|
|
1906
|
+
reasons: customerPaymentReasons(request.reasons),
|
|
1879
1907
|
requestId: request.requestId,
|
|
1880
|
-
retryGuidance:
|
|
1908
|
+
retryGuidance: approvalRetryGuidance(request.requestId)
|
|
1881
1909
|
});
|
|
1882
1910
|
}
|
|
1883
1911
|
if (request.status === "PROCESSING") {
|
package/dist/index.mjs
CHANGED
|
@@ -14,7 +14,7 @@ var require_package = __commonJS({
|
|
|
14
14
|
"package.json"(exports, module) {
|
|
15
15
|
module.exports = {
|
|
16
16
|
name: "@conto_finance/sdk",
|
|
17
|
-
version: "0.5.
|
|
17
|
+
version: "0.5.2",
|
|
18
18
|
description: "Conto SDK for AI agent payment authorization",
|
|
19
19
|
main: "./dist/index.js",
|
|
20
20
|
module: "./dist/index.mjs",
|
|
@@ -128,7 +128,10 @@ var PUBLIC_PAYMENT_REASONS = /* @__PURE__ */ new Set([
|
|
|
128
128
|
"This payment is outside the permitted schedule.",
|
|
129
129
|
"The available payment budget is insufficient.",
|
|
130
130
|
"This payment does not meet the current payment controls.",
|
|
131
|
-
"This payment requires approval before it can proceed."
|
|
131
|
+
"This payment requires approval before it can proceed.",
|
|
132
|
+
"No usable wallet is linked to this agent.",
|
|
133
|
+
"This payee needs review before payments to it can proceed automatically.",
|
|
134
|
+
"A reviewer declined this payment."
|
|
132
135
|
]);
|
|
133
136
|
function customerPaymentReasons(value) {
|
|
134
137
|
return Array.isArray(value) ? [
|
|
@@ -308,9 +311,11 @@ function responseErrorMetadata(response, data) {
|
|
|
308
311
|
const body = record(data);
|
|
309
312
|
const code = safeErrorCode(body.code, response.status);
|
|
310
313
|
const bodyRetryAfter = typeof body.retryAfter === "number" || typeof body.retryAfter === "string" ? parseRetryAfter(String(body.retryAfter)) : void 0;
|
|
314
|
+
const reasons = customerPaymentReasons(body.reasons);
|
|
311
315
|
return {
|
|
312
316
|
code,
|
|
313
317
|
status: response.status,
|
|
318
|
+
...reasons.length > 0 ? { reasons } : {},
|
|
314
319
|
fieldErrors: customerFieldErrors(body, response.status),
|
|
315
320
|
requestId: safeRequestId(
|
|
316
321
|
response.headers.get("x-request-id"),
|
|
@@ -1544,6 +1549,27 @@ var ConnectedCardsClient = class {
|
|
|
1544
1549
|
return this.client.request("GET", "/api/sdk/connected-cards");
|
|
1545
1550
|
}
|
|
1546
1551
|
};
|
|
1552
|
+
function approvalRetryGuidance(requestId) {
|
|
1553
|
+
const id = JSON.stringify(requestId);
|
|
1554
|
+
return `An approver in Conto executes the payment when they approve it. After approval, call payments.execute(${id}) or payments.status(${id}) to get the receipt. Do not request the payment again.`;
|
|
1555
|
+
}
|
|
1556
|
+
function executeRetryGuidance(code, requestId) {
|
|
1557
|
+
const id = JSON.stringify(requestId);
|
|
1558
|
+
switch (code) {
|
|
1559
|
+
case "APPROVAL_PENDING":
|
|
1560
|
+
return approvalRetryGuidance(requestId);
|
|
1561
|
+
case "POLICY_DENIED_AT_EXECUTION":
|
|
1562
|
+
case "PAYMENT_DENIED":
|
|
1563
|
+
return "This payment was declined and will not execute. Do not retry it; review the reasons before requesting a new payment.";
|
|
1564
|
+
case "POLICY_REAPPROVAL_REQUIRED":
|
|
1565
|
+
return "This payment now needs approval and will not execute. Request a new payment and wait for approval.";
|
|
1566
|
+
case "PAYMENT_PROCESSING":
|
|
1567
|
+
case "NEEDS_RECONCILIATION":
|
|
1568
|
+
return `Do not execute again. Check payments.status(${id}) for the outcome.`;
|
|
1569
|
+
default:
|
|
1570
|
+
return void 0;
|
|
1571
|
+
}
|
|
1572
|
+
}
|
|
1547
1573
|
var PaymentsClient = class {
|
|
1548
1574
|
constructor(client) {
|
|
1549
1575
|
this.client = client;
|
|
@@ -1617,7 +1643,9 @@ var PaymentsClient = class {
|
|
|
1617
1643
|
* Execute an approved payment.
|
|
1618
1644
|
*
|
|
1619
1645
|
* This sends the onchain transaction. Only works for payments
|
|
1620
|
-
* with status 'APPROVED'.
|
|
1646
|
+
* with status 'APPROVED'. If an approver already executed the payment by
|
|
1647
|
+
* approving it in Conto, this returns the existing receipt with
|
|
1648
|
+
* `alreadyExecuted: true` and sends nothing.
|
|
1621
1649
|
*
|
|
1622
1650
|
* @param requestId - The requestId from a successful payment request
|
|
1623
1651
|
*
|
|
@@ -1639,18 +1667,17 @@ var PaymentsClient = class {
|
|
|
1639
1667
|
{}
|
|
1640
1668
|
);
|
|
1641
1669
|
} catch (error) {
|
|
1642
|
-
if (error instanceof ContoError
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
}
|
|
1653
|
-
throw error;
|
|
1670
|
+
if (!(error instanceof ContoError)) throw error;
|
|
1671
|
+
const retryGuidance = error.status === 0 ? `Check payments.status(${JSON.stringify(requestId)}) before attempting execution again.` : executeRetryGuidance(error.code, requestId);
|
|
1672
|
+
if (!retryGuidance) throw error;
|
|
1673
|
+
throw new ContoError(error.message, {
|
|
1674
|
+
code: error.code,
|
|
1675
|
+
status: error.status,
|
|
1676
|
+
requestId: error.requestId,
|
|
1677
|
+
retryAfter: error.retryAfter,
|
|
1678
|
+
reasons: error.reasons,
|
|
1679
|
+
retryGuidance
|
|
1680
|
+
});
|
|
1654
1681
|
}
|
|
1655
1682
|
}
|
|
1656
1683
|
/**
|
|
@@ -1715,8 +1742,9 @@ var PaymentsClient = class {
|
|
|
1715
1742
|
throw new ContoError("Payment requires manual approval", {
|
|
1716
1743
|
code: "REQUIRES_APPROVAL",
|
|
1717
1744
|
status: 202,
|
|
1745
|
+
reasons: customerPaymentReasons(request.reasons),
|
|
1718
1746
|
requestId: request.requestId,
|
|
1719
|
-
retryGuidance:
|
|
1747
|
+
retryGuidance: approvalRetryGuidance(request.requestId)
|
|
1720
1748
|
});
|
|
1721
1749
|
}
|
|
1722
1750
|
if (request.status === "PROCESSING") {
|