@conto_finance/sdk 0.1.0 → 0.3.1

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 CHANGED
@@ -34,14 +34,92 @@ const request = await conto.payments.request({
34
34
  recipientName: 'OpenAI',
35
35
  purpose: 'API credits',
36
36
  category: 'API_PROVIDER',
37
+ // Optional for a single attempt. Supply and reuse your own key when retrying
38
+ // across process restarts or independent job attempts.
39
+ idempotencyKey: crypto.randomUUID(),
37
40
  });
38
41
 
39
42
  if (request.status === 'APPROVED') {
40
43
  const result = await conto.payments.execute(request.requestId);
41
- console.log(result.txHash);
44
+ console.log(result.status);
45
+ console.log(result.receipt.transactionId, result.receipt.settlementMode);
46
+ console.log(result.receipt.txHash);
42
47
  }
43
48
  ```
44
49
 
50
+ ## External-card Policy Overlay
51
+
52
+ The admin client registers only a masked card alias and assigns cooperative
53
+ controls. Never pass PAN, CVC, expiry, or another usable credential to these
54
+ methods.
55
+
56
+ ```typescript
57
+ import { ContoAdmin } from '@conto_finance/sdk';
58
+
59
+ const admin = new ContoAdmin({
60
+ orgApiKey: process.env.CONTO_ORG_API_KEY!,
61
+ });
62
+
63
+ const { card } = await admin.cards.register({
64
+ name: 'Agent purchasing card',
65
+ last4: '4242',
66
+ brand: 'VISA',
67
+ fundingType: 'CREDIT',
68
+ spendLimitDaily: 500,
69
+ spendLimitPerTx: 200,
70
+ });
71
+
72
+ await admin.cards.assignToAgent('agent_id', {
73
+ cardId: card.id,
74
+ timezone: 'America/Los_Angeles',
75
+ spendLimitDaily: 250,
76
+ spendLimitPerTx: 100,
77
+ allowedMerchants: ['Example Software'],
78
+ });
79
+
80
+ await admin.cards.updateAgentAssignment('agent_id', card.id, {
81
+ timezone: 'America/Los_Angeles',
82
+ spendLimitDaily: 250,
83
+ spendLimitPerTx: 100,
84
+ activeUntil: '2026-09-01T00:00:00.000Z',
85
+ });
86
+
87
+ await admin.cards.pauseForAgent('agent_id', card.id);
88
+ await admin.cards.resumeForAgent('agent_id', card.id);
89
+ await admin.cards.revokeFromAgent('agent_id', card.id);
90
+ ```
91
+
92
+ The policy overlay stops at approval, claiming, and reconciliation. For a
93
+ customer-hosted payment tool that gates access to customer payment code, use the
94
+ separate
95
+ [`@conto_finance/card-access`](https://conto.finance/docs/card-access/overview) product
96
+ package.
97
+
98
+ ```typescript
99
+ import { ContoCardAccess } from '@conto_finance/card-access';
100
+
101
+ const cardAccess = new ContoCardAccess({
102
+ policy: conto.cards,
103
+ integrationId: 'procurement-agent-production',
104
+ deployment: {
105
+ credentialCustody: 'CUSTOMER',
106
+ agentHasRawCredentialAccess: false,
107
+ uncontrolledAgentPaymentPath: false,
108
+ },
109
+ executor: customerHostedExecutor,
110
+ });
111
+ ```
112
+
113
+ Card Access claims each approved request exactly once before the executor can run. A
114
+ duplicate or uncertain claim cannot invoke the executor again. It remains
115
+ bypassable if another person or tool can access the card, and results are
116
+ self-reported rather than issuer-verified. The legacy `conto.cards.controlled()`
117
+ helper remains available for compatibility, but new customer-hosted enforcement
118
+ should use the standalone Card Access package. Use
119
+ `admin.cards.listRequests({ status: 'EXECUTING' })` for reconciliation and
120
+ `admin.cards.pause(card.id)` to revoke unclaimed grants and stop new approvals
121
+ in the Conto-controlled path.
122
+
45
123
  For a single-call managed-wallet flow, use:
46
124
 
47
125
  ```typescript
@@ -52,6 +130,36 @@ const result = await conto.payments.pay({
52
130
  });
53
131
  ```
54
132
 
133
+ ## Protocol Clients
134
+
135
+ `Conto` also exposes typed helpers for x402 and MPP service payments:
136
+
137
+ ```typescript
138
+ const paymentId = crypto.randomUUID();
139
+
140
+ await conto.x402.preAuthorize({
141
+ amount: 0.01,
142
+ recipientAddress: '0x...',
143
+ resourceUrl: 'https://api.example.com/v1/search',
144
+ paymentId,
145
+ sessionId: 'session_123',
146
+ });
147
+
148
+ await conto.x402.record({
149
+ amount: 0.01,
150
+ recipientAddress: '0x...',
151
+ resourceUrl: 'https://api.example.com/v1/search',
152
+ paymentId,
153
+ txHash: '0x...',
154
+ sessionId: 'session_123',
155
+ });
156
+
157
+ const budget = await conto.x402.budget();
158
+ ```
159
+
160
+ The MPP client mirrors the same shape with `conto.mpp.preAuthorize`, `conto.mpp.record`,
161
+ `conto.mpp.budget`, and `conto.mpp.services`.
162
+
55
163
  ## Admin SDK Quick Start
56
164
 
57
165
  `ContoAdmin` uses an organization API key (`conto_xxx...`), not an agent SDK key.
@@ -79,15 +187,52 @@ const agent = await admin.agents.create({
79
187
  const wallet = await admin.wallets.create({
80
188
  name: 'Operations Wallet',
81
189
  });
190
+
191
+ const { frozen } = await admin.agents.freeze(agent.id, { freezeWallets: true });
192
+ if (frozen) {
193
+ await admin.agents.unfreeze(agent.id, { unfreezeWallets: true });
194
+ }
82
195
  ```
83
196
 
84
197
  ## What This Package Covers
85
198
 
86
199
  - `Conto` for agent-scoped payment flows
87
200
  - `ContoAdmin` for organization-scoped provisioning and management
88
- - Built-in retries for `429` and `5xx` responses
201
+ - Built-in retries for reads and idempotency-protected payment authorization requests
89
202
  - Typed request and response shapes for the public SDK surface
90
203
 
204
+ ## Retry and Error Safety
205
+
206
+ The SDK automatically adds an idempotency key to wallet payment authorization
207
+ requests. Provide your own stable `idempotencyKey` when a retry may happen in
208
+ another process or job attempt. External-card approvals always require a stable
209
+ caller-supplied `idempotencyKey`; card approval and confirmation are safe to
210
+ retry. x402 and MPP pre-authorization calls are non-mutating policy checks.
211
+ Record calls require an explicit stable `paymentId` or `credentialId` so an
212
+ ambiguous failure can be reconciled safely.
213
+
214
+ Read-only calls retry transient network failures, `429`, and `5xx` responses. Financial execution
215
+ and other non-idempotent mutations are never retried automatically. If execution times out, call
216
+ `conto.payments.status(requestId)` before attempting it again. A
217
+ `reconciliation_required` status means the execution outcome is ambiguous; do not resend the
218
+ payment until an operator has resolved it.
219
+
220
+ `ContoError` and `ContoAdminError` expose a stable error contract: `code`, `status`, `requestId`,
221
+ `retryAfter`, and locally generated `retryGuidance` where applicable. Arbitrary server details,
222
+ context, hints, and workflow steps are not forwarded through SDK errors:
223
+
224
+ ```typescript
225
+ import { ContoError } from '@conto_finance/sdk';
226
+
227
+ try {
228
+ await conto.payments.status('req_123');
229
+ } catch (error) {
230
+ if (error instanceof ContoError) {
231
+ console.error(error.code, error.requestId, error.retryGuidance);
232
+ }
233
+ }
234
+ ```
235
+
91
236
  ## What To Use Instead
92
237
 
93
238
  - Use the REST API docs if you need endpoints that are not wrapped by this package yet, especially