@attesso/sdk 1.0.0 → 1.0.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.
Files changed (2) hide show
  1. package/README.md +72 -241
  2. package/package.json +5 -7
package/README.md CHANGED
@@ -1,305 +1,136 @@
1
1
  # @attesso/sdk
2
2
 
3
- The official TypeScript SDK for Attesso. Hardware-backed identity for autonomous commerce.
3
+ API client for executing payments against FIDO2-signed mandates.
4
4
 
5
5
  ```bash
6
6
  npm install @attesso/sdk
7
7
  ```
8
8
 
9
- ## What This Is
10
-
11
- AI agents need to spend money. Attesso gives them a wallet with hardware-backed security and user-controlled spending limits.
12
-
13
- This SDK lets agents:
14
- - Execute payments within pre-authorized limits
15
- - Prove their identity to merchants
16
- - Check available spending power
17
-
18
- **No mobile app required.** Users authorize spending with WebAuthn passkeys (FaceID/TouchID) directly in the browser.
19
-
20
- ## Quick Start
9
+ ## AttessoClient
21
10
 
22
11
  ```typescript
23
12
  import { AttessoClient } from '@attesso/sdk';
24
13
 
25
14
  const client = new AttessoClient({
26
15
  apiKey: process.env.ATTESSO_API_KEY,
16
+ baseUrl: process.env.ATTESSO_BASE_URL, // optional
27
17
  });
18
+ ```
19
+
20
+ ### Methods
28
21
 
29
- // Check mandate limits
22
+ #### getMandate(mandateId)
23
+ ```typescript
30
24
  const mandate = await client.getMandate('mandate_xyz');
31
- console.log(`Available: $${mandate.maxAmount / 100}`);
25
+ // { id, botId, maxAmount, currency, merchant?, status, expiresAt?, createdAt }
26
+ ```
32
27
 
33
- // Execute payment
28
+ #### executePayment(options)
29
+ ```typescript
34
30
  const payment = await client.executePayment({
35
31
  mandateId: 'mandate_xyz',
36
- amount: 34700, // $347.00
37
- merchant: 'United Airlines',
32
+ amount: 34700, // cents
33
+ merchant: 'Acme Corp',
38
34
  });
39
-
40
- // Get identity token for merchant verification
41
- const passport = await client.getPassport('mandate_xyz');
35
+ // { id, mandateId, amount, merchant, status, createdAt }
42
36
  ```
43
37
 
44
- ## How Users Create Mandates
45
-
46
- Users create spending mandates in your web dashboard using WebAuthn passkeys:
47
-
38
+ #### getPayment(paymentId)
48
39
  ```typescript
49
- // Frontend: User creates mandate with passkey
50
- import { startAuthentication } from '@simplewebauthn/browser';
51
-
52
- // 1. Get authentication options from your backend
53
- const authOptions = await fetch('/api/auth/webauthn/authenticate/options', {
54
- method: 'POST',
55
- }).then(r => r.json());
56
-
57
- // 2. User authenticates with FaceID/TouchID (or QR code on desktop)
58
- const assertion = await startAuthentication(authOptions);
59
-
60
- // 3. Create mandate with the assertion
61
- const mandate = await fetch('/api/mandates', {
62
- method: 'POST',
63
- headers: { 'Content-Type': 'application/json' },
64
- body: JSON.stringify({
65
- botId: 'bot_travel_agent',
66
- maxAmount: 50000, // $500.00
67
- currency: 'usd',
68
- merchant: 'United Airlines',
69
- webAuthnAssertion: assertion,
70
- }),
71
- }).then(r => r.json());
72
-
73
- // 4. Pass mandateId to your AI agent
40
+ const payment = await client.getPayment('payment_abc');
74
41
  ```
75
42
 
76
- ### Cross-Device Authentication
77
-
78
- On desktops without biometrics (TouchID), WebAuthn automatically shows a QR code. Users scan it with their phone and authenticate using the phone's FaceID/TouchID. The signature still comes from hardware (phone's Secure Enclave).
79
-
80
- ## Vercel AI SDK Integration
81
-
82
- One line gives your AI agent a wallet:
83
-
43
+ #### getPassport(mandateId)
84
44
  ```typescript
85
- import { generateText } from 'ai';
86
- import { attesso } from '@attesso/sdk/vercel';
87
-
88
- const result = await generateText({
89
- model: openai('gpt-4o'),
90
- tools: attesso.tools(),
91
- prompt: 'Book me a flight to NYC under $500',
92
- });
45
+ const passport = await client.getPassport('mandate_xyz');
46
+ // { token, expiresAt }
93
47
  ```
94
48
 
95
- ### Available Tools
96
-
97
- | Tool | Description |
98
- |------|-------------|
99
- | `attesso_pay` | Execute payment against mandate |
100
- | `attesso_get_mandate` | Check spending limits |
101
- | `attesso_get_passport` | Get identity token |
102
- | `attesso_capture` | Capture authorized payment |
103
- | `attesso_cancel` | Cancel and release funds |
104
- | `attesso_check_balance` | Quick balance check |
105
-
106
- ### Configuration
107
-
49
+ #### capture(paymentId, options)
108
50
  ```typescript
109
- const tools = attesso.tools({
110
- mandateId: 'mandate_xyz', // Pre-select mandate
111
- merchant: 'United Airlines', // Lock to merchant
112
- maxAmountPerTransaction: 50000, // $500 cap
51
+ const result = await client.capture('payment_abc', {
52
+ amount: 34700,
53
+ metadata: { orderId: '123' },
113
54
  });
55
+ // { id, authorizedAmount, capturedAmount, status: 'completed' }
114
56
  ```
115
57
 
116
- ## Direct API Access
117
-
58
+ #### cancel(paymentId)
118
59
  ```typescript
119
- import { AttessoClient } from '@attesso/sdk';
120
-
121
- const client = new AttessoClient({ apiKey: '...' });
122
-
123
- // Get mandate details
124
- const mandate = await client.getMandate(mandateId);
125
-
126
- // Execute payment
127
- const payment = await client.executePayment({
128
- mandateId,
129
- amount: 10000,
130
- merchant: 'Acme Corp',
131
- });
132
-
133
- // Check payment status
134
- const status = await client.getPayment(payment.id);
135
-
136
- // Auth/Capture flow
137
- const auth = await client.executePayment({
138
- mandateId,
139
- amount: 50000,
140
- merchant: 'Hotel',
141
- });
142
- await client.capture(auth.id, { amount: 45000 }); // Final price
143
-
144
- // Cancel authorization
145
- await client.cancel(auth.id);
146
-
147
- // Get passport token
148
- const passport = await client.getPassport(mandateId);
149
- ```
150
-
151
- ## How It Works
152
-
153
- ```
154
- User creates mandate → WebAuthn passkey signs authorization
155
- ↓ (FaceID/TouchID or phone QR)
156
- Mandate stored → Hardware attestation verified
157
-
158
- AI Agent calls SDK → SDK checks mandate limits
159
-
160
- Payment executed → Funds transferred via Stripe
161
-
162
- Merchant verifies → Passport proves authorized spending
60
+ const result = await client.cancel('payment_abc');
61
+ // { id, authorizedAmount, status: 'cancelled' }
163
62
  ```
164
63
 
165
- ### Security Model
166
-
167
- - **WebAuthn Passkeys**: Mandates signed by device Secure Enclave
168
- - **Cross-Device Support**: QR-based authentication for desktops
169
- - **User Control**: Instant revocation, spending limits
170
- - **Cryptographic Identity**: JWT passports verifiable offline
171
-
172
- ## Infrastructure Security
173
-
174
- ### Idempotency
175
- - Idempotency keys required on all payment operations
176
- - Concurrent duplicates return `409 Conflict`
177
- - Request payloads hashed to detect tampering
178
-
179
- ### WebAuthn
180
- - Origin-bound credentials (phishing-resistant)
181
- - Single-use challenges with TTL
182
- - Hardware counter validation
183
-
184
- ### Rate Limiting
185
- | Endpoint | Limit |
186
- |----------|-------|
187
- | Auth | 5/min |
188
- | Payments | 30/min |
189
- | General | 100/min |
190
-
191
- ### Webhook Processing
192
- - Stripe event deduplication via `WebhookEvent` table
193
- - Row-level locking (`SELECT ... FOR UPDATE`)
194
- - Serializable transaction isolation
195
-
196
- ### Hardware Security by Device
197
-
198
- | Device | Security | Auth Method |
199
- |--------|----------|-------------|
200
- | iPhone/iPad | Secure Enclave | FaceID/TouchID |
201
- | Mac (Touch ID) | Secure Enclave | TouchID |
202
- | Mac (no Touch ID) | Phone via QR | Phone's Secure Enclave |
203
- | Windows (Hello) | TPM 2.0 | Windows Hello |
204
- | Windows (no Hello) | Phone via QR | Requires Bluetooth + manual selection |
205
- | Android | TEE/StrongBox | Fingerprint/Face |
206
-
207
- **Windows Note:** Without Windows Hello, users see a USB security key prompt first. They must click Cancel and select "iPhone/Android" for QR code. Bluetooth must be enabled.
208
-
209
- ## Application Fee Routing (Optional)
210
-
211
- Configure application fees per transaction. The protocol uses an additive settlement model, calculating charges on top of the base amount. This ensures merchant principal preservation while automating fee routing to the connected Stripe account.
212
-
213
- ### Configuration
64
+ ## Vercel AI SDK
214
65
 
215
66
  ```typescript
216
- // Principal is $100, total authorization is $106
217
- const payment = await rails.processPayment({
218
- amount: 10000, // $100.00 principal amount
219
- currency: 'usd',
220
- merchant: 'Acme Corp',
221
- mandateId: 'mandate_xyz',
222
- paymentId: 'payment_abc',
223
- userId: 'user_123',
224
- applicationFee: {
225
- destinationAccountId: 'acct_your_stripe_connect_id',
226
- feePercent: 5, // percentage of principal
227
- // OR
228
- feeFixed: 100, // fixed amount (cents)
229
- // OR both combined
230
- },
231
- });
232
- ```
233
-
234
- ### Fee Routing Options
235
-
236
- | Parameter | Example | On $100 principal |
237
- |-----------|---------|-------------------|
238
- | `feePercent` | `5` | +$5.00 |
239
- | `feeFixed` | `100` | +$1.00 |
240
- | Hybrid | `{ percent: 2, fixed: 30 }` | +$2.30 |
241
-
242
- ### Settlement Model
243
-
244
- $100 principal with 1% protocol fee + 5% application fee:
245
-
246
- | Settlement | Amount |
247
- |------------|--------|
248
- | Net Settlement (Merchant) | $100.00 |
249
- | Protocol Fee (Attesso) | $1.00 |
250
- | Application Fee | $5.00 |
251
- | **Total Authorization** | **$106.00** |
67
+ import { generateText } from 'ai';
68
+ import { attesso } from '@attesso/sdk/vercel';
252
69
 
253
- ```typescript
254
- const settlement = rails.calculateFees(10000, 5, 0);
255
- // { netSettlement: 10000, protocolFee: 100, applicationFee: 500, totalAuthorization: 10600 }
70
+ const result = await generateText({
71
+ model: openai('gpt-4o'),
72
+ tools: attesso.tools({
73
+ mandateId: 'mandate_xyz', // optional: pre-select mandate
74
+ merchant: 'Acme Corp', // optional: lock to merchant
75
+ maxAmountPerTransaction: 50000, // optional: per-tx cap
76
+ }),
77
+ prompt: 'Book a flight under $500',
78
+ });
256
79
  ```
257
80
 
258
- ### Requirements
259
-
260
- - Stripe Connect account (`acct_...` ID)
261
- - Application fee routing is optional—omit to disable
81
+ ### Tools
262
82
 
263
- ## Origin Restrictions (Optional)
83
+ | Tool | Parameters | Returns |
84
+ |------|------------|---------|
85
+ | `attesso_pay` | `{ mandateId?, amount, merchant? }` | PaymentResponse |
86
+ | `attesso_get_mandate` | `{ mandateId? }` | MandateResponse |
87
+ | `attesso_get_payment` | `{ paymentId }` | PaymentResponse |
88
+ | `attesso_get_passport` | `{ mandateId? }` | PassportToken |
89
+ | `attesso_capture` | `{ paymentId, amount, metadata? }` | CaptureResponse |
90
+ | `attesso_cancel` | `{ paymentId }` | CancelResponse |
91
+ | `attesso_check_balance` | `{ mandateId? }` | `{ available, currency, status }` |
264
92
 
265
- Restrict SDK usage to specific domains:
93
+ ## Origin Restrictions
266
94
 
267
95
  ```typescript
268
96
  const client = new AttessoClient({
269
- apiKey: 'sk_bot_xyz',
270
- allowedOrigins: [
271
- 'https://myapp.com',
272
- 'https://*.trusted-partner.com', // Wildcard subdomains
273
- ],
97
+ apiKey: '...',
98
+ allowedOrigins: ['https://myapp.com', 'https://*.trusted.com'],
274
99
  });
275
100
  ```
276
101
 
277
- Requests from non-allowed origins throw `OriginNotAllowedError`.
278
-
279
- ## Environment Variables
280
-
281
- ```bash
282
- ATTESSO_API_KEY=your_api_key
283
- ATTESSO_BASE_URL=https://api.attesso.dev # optional
284
- ```
102
+ Throws `OriginNotAllowedError` if called from unlisted origin.
285
103
 
286
- ## TypeScript
287
-
288
- Full type safety included:
104
+ ## Types
289
105
 
290
106
  ```typescript
291
107
  import type {
292
108
  MandateResponse,
293
109
  PaymentResponse,
294
110
  PassportToken,
295
- WebAuthnAssertion,
111
+ CapturePaymentResponse,
112
+ CancelAuthorizationResponse,
296
113
  } from '@attesso/sdk';
297
114
  ```
298
115
 
116
+ ## Errors
117
+
118
+ ```typescript
119
+ import { AttessoError, OriginNotAllowedError } from '@attesso/sdk';
120
+
121
+ try {
122
+ await client.executePayment({ ... });
123
+ } catch (e) {
124
+ if (e instanceof AttessoError) {
125
+ console.log(e.code); // MANDATE_NOT_FOUND, AMOUNT_EXCEEDS_LIMIT, etc.
126
+ }
127
+ }
128
+ ```
129
+
299
130
  ## Requirements
300
131
 
301
132
  - Node.js 18+
302
- - For Vercel AI SDK integration: `ai` >= 3.0, `zod` >= 3.0
133
+ - For Vercel AI SDK: `ai` >= 3.0, `zod` >= 3.0
303
134
 
304
135
  ## License
305
136
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@attesso/sdk",
3
- "version": "1.0.0",
4
- "description": "Attesso SDK for autonomous commerce - enable AI agents to make purchases",
3
+ "version": "1.0.2",
4
+ "description": "API client for executing payments against FIDO2-signed mandates. Includes Vercel AI SDK tools.",
5
5
  "author": "Attesso",
6
6
  "license": "MIT",
7
7
  "repository": {
@@ -41,11 +41,9 @@
41
41
  "keywords": [
42
42
  "attesso",
43
43
  "payments",
44
- "ai-agents",
45
- "autonomous-commerce",
46
- "open-banking",
47
- "vercel-ai-sdk",
48
- "ai-tools"
44
+ "mandates",
45
+ "fido2",
46
+ "vercel-ai-sdk"
49
47
  ],
50
48
  "dependencies": {
51
49
  "@attesso/gatekeeper": "workspace:*",