shadowkey-agent-sdk 1.1.0 → 1.2.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.
Files changed (2) hide show
  1. package/README.md +136 -95
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,15 +1,18 @@
1
1
  # ShadowKey Agent SDK
2
2
 
3
- Official SDK for integrating AI agents with ShadowKey's privacy-preserving data vault.
3
+ Official SDK for integrating AI agents with [ShadowKey](https://shadowkey-ai.vercel.app)'s privacy-preserving data vault on Base.
4
+
5
+ [![npm](https://img.shields.io/npm/v/shadowkey-agent-sdk?style=flat-square&logo=npm&color=CB3837)](https://www.npmjs.com/package/shadowkey-agent-sdk) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow?style=flat-square)](LICENSE) [![Node](https://img.shields.io/badge/Node-%3E%3D18-339933?style=flat-square&logo=node.js)](https://nodejs.org) [![TypeScript](https://img.shields.io/badge/TypeScript-First-3178C6?style=flat-square&logo=typescript)](https://www.typescriptlang.org)
4
6
 
5
7
  ## Features
6
8
 
7
- - 🔐 Secure API key authentication with request signing
8
- - 🔄 Automatic retry logic with exponential backoff
9
- - ⏱ïļ Configurable timeouts and polling
10
- - ðŸŽŊ TypeScript-first with full type definitions
11
- - ðŸŠķ Zero dependencies for minimal bundle size
12
- - 🔍 Debug mode for development
9
+ - **HMAC-SHA256 Request Signing** — Every request is cryptographically signed to prevent replay attacks
10
+ - **Automatic Retry** — Exponential backoff on server errors (skips retries on 4xx client errors)
11
+ - **Approval Polling** — Built-in `waitForApproval()` with configurable timeout and interval
12
+ - **Node.js 18+ & Browser** — Works in both environments using `globalThis.crypto`
13
+ - **TypeScript-First** — Full type definitions included (CJS + ESM + `.d.ts`)
14
+ - **Zero Dependencies** — No external deps, minimal bundle size (4.8 KB ESM)
15
+ - **Debug Mode** — Logs requests/responses with automatic redaction of sensitive fields
13
16
 
14
17
  ## Installation
15
18
 
@@ -24,31 +27,55 @@ import { ShadowKeyClient } from 'shadowkey-agent-sdk';
24
27
 
25
28
  const client = new ShadowKeyClient({
26
29
  apiUrl: 'https://your-project.supabase.co/functions/v1',
27
- apiKey: 'your-api-key',
28
- debug: true // Enable logging during development
30
+ apiKey: 'sk_your_api_key_here',
31
+ debug: true,
29
32
  });
30
33
 
31
- // Request access to user data
34
+ // 1. Request access to user's vault data
32
35
  const response = await client.requestAccess({
33
- agentId: 'shopping-assistant-001',
36
+ agentId: 'shopping-bot-001',
34
37
  agentName: 'Smart Shopping Assistant',
35
- requestedFields: ['creditCard', 'shippingAddress'],
36
- purpose: 'Complete your purchase of wireless headphones',
37
- category: 'shopping'
38
+ requestedFields: ['shipping_address', 'billing_name', 'card_last4'],
39
+ purpose: 'Complete purchase of wireless headphones ($89.99)',
40
+ category: 'payment',
38
41
  });
39
42
 
40
43
  console.log('Request ID:', response.requestId);
44
+ // → User receives notification in their ShadowKey dashboard
41
45
 
42
- // Wait for user approval (with timeout)
43
- const result = await client.waitForApproval(response.requestId, 300000);
46
+ // 2. Wait for user to approve/deny (polls every 2s, max 5 min)
47
+ const result = await client.waitForApproval(response.requestId);
44
48
 
45
49
  if (result.status === 'approved') {
46
- console.log('Access granted!', result.grantedData);
50
+ console.log('Scoped access granted:', result.grantedFields);
51
+ console.log('Data:', result.grantedData);
52
+ // → Only the fields the user approved — nothing more
47
53
  } else {
48
54
  console.log('Access denied:', result.message);
49
55
  }
50
56
  ```
51
57
 
58
+ ## How It Works
59
+
60
+ ```
61
+ Your Agent ShadowKey SDK User's Vault
62
+ | | |
63
+ |-- requestAccess() ---------> | |
64
+ | |-- POST /sdk-access-request ->|
65
+ | | (HMAC-signed) |
66
+ | |<---- requestId, pending -----|
67
+ |<---- requestId --------------| |
68
+ | | |
69
+ |-- waitForApproval() -------> | |
70
+ | |-- GET /sdk-access-status --> |
71
+ | | (polls every 2s) |
72
+ | | User approves fields
73
+ | |<---- approved, grantedData --|
74
+ |<---- grantedData ------------| |
75
+ | | |
76
+ | Only approved fields received. Denied fields never leave the vault.
77
+ ```
78
+
52
79
  ## API Reference
53
80
 
54
81
  ### Constructor
@@ -57,121 +84,135 @@ if (result.status === 'approved') {
57
84
  new ShadowKeyClient(config: ShadowKeyConfig)
58
85
  ```
59
86
 
60
- **Config Options:**
61
- - `apiUrl` (required): Your Supabase project URL + `/functions/v1`
62
- - `apiKey` (required): API key generated from ShadowKey settings
63
- - `timeout` (optional): Request timeout in ms (default: 30000)
64
- - `retryAttempts` (optional): Number of retry attempts (default: 3)
65
- - `debug` (optional): Enable debug logging (default: false)
87
+ | Option | Type | Default | Description |
88
+ |--------|------|---------|-------------|
89
+ | `apiUrl` | `string` | *required* | Supabase project URL + `/functions/v1` |
90
+ | `apiKey` | `string` | *required* | API key from ShadowKey Settings page |
91
+ | `timeout` | `number` | `30000` | Request timeout in ms |
92
+ | `retryAttempts` | `number` | `3` | Max retries on server errors |
93
+ | `debug` | `boolean` | `false` | Enable debug logging (redacts sensitive fields) |
66
94
 
67
- ### Methods
95
+ ### `requestAccess(request): Promise<AccessResponse>`
96
+
97
+ Request scoped access to a user's vault data. Creates a pending disclosure request that the vault owner must approve.
98
+
99
+ ```typescript
100
+ const response = await client.requestAccess({
101
+ agentId: 'my-agent-001', // Your agent's unique ID
102
+ agentName: 'My AI Assistant', // Human-readable name (shown to user)
103
+ requestedFields: ['email', 'phone'], // Fields you need
104
+ purpose: 'Send order confirmation', // Why (shown to user)
105
+ category: 'identity', // Optional: payment, identity, health, etc.
106
+ expiresIn: 300, // Optional: seconds until request expires (default 300)
107
+ });
108
+ ```
68
109
 
69
- #### `requestAccess(request: AccessRequest): Promise<AccessResponse>`
110
+ ### `checkStatus(requestId): Promise<DisclosureStatus>`
70
111
 
71
- Request access to user's vault data.
112
+ Check the current status of an access request.
72
113
 
73
- **Parameters:**
74
114
  ```typescript
75
- {
76
- agentId: string; // Unique identifier for your agent
77
- agentName: string; // Human-readable agent name
78
- requestedFields: string[]; // Array of field names to request
79
- purpose: string; // Clear explanation of why you need access
80
- category?: string; // Optional category (shopping, travel, etc)
81
- expiresIn?: number; // Optional expiration time in seconds
82
- }
115
+ const status = await client.checkStatus(response.requestId);
116
+ // status.status → 'pending' | 'approved' | 'denied' | 'expired'
83
117
  ```
84
118
 
85
- **Returns:**
119
+ ### `waitForApproval(requestId, maxWaitMs?, pollIntervalMs?): Promise<AccessResponse>`
120
+
121
+ Poll for user approval with automatic timeout.
122
+
123
+ | Param | Default | Description |
124
+ |-------|---------|-------------|
125
+ | `requestId` | *required* | From `requestAccess()` |
126
+ | `maxWaitMs` | `300000` (5 min) | Max time to wait |
127
+ | `pollIntervalMs` | `2000` (2s) | Time between polls |
128
+
86
129
  ```typescript
87
- {
88
- requestId: string; // Use this to check status
89
- status: 'pending' | 'approved' | 'denied' | 'expired';
90
- grantedData?: Record<string, any>; // Present if approved
91
- expiresAt?: string; // ISO timestamp
92
- message?: string;
93
- }
130
+ const result = await client.waitForApproval(response.requestId, 120000, 3000);
94
131
  ```
95
132
 
96
- #### `checkStatus(requestId: string): Promise<DisclosureStatus>`
133
+ ### `submitReverseDisclosure(request): Promise<ReverseDisclosureResponse>`
97
134
 
98
- Check the current status of an access request.
135
+ Submit data to a user's vault (reverse data flow — services sending data to users).
99
136
 
100
- #### `waitForApproval(requestId: string, maxWaitMs?: number, pollIntervalMs?: number): Promise<AccessResponse>`
137
+ ```typescript
138
+ const receipt = await client.submitReverseDisclosure({
139
+ serviceId: 'acme-corp',
140
+ serviceName: 'Acme Corporation',
141
+ dataOffered: [
142
+ { field: 'loyalty_points', value: '4,250', category: 'preferences' },
143
+ { field: 'member_since', value: '2024-01-15', category: 'identity' },
144
+ ],
145
+ purpose: 'Share your loyalty program data',
146
+ });
147
+ ```
101
148
 
102
- Poll for approval with automatic retries.
149
+ ## Integration Examples
103
150
 
104
- **Parameters:**
105
- - `requestId`: The ID returned from `requestAccess()`
106
- - `maxWaitMs`: Maximum time to wait (default: 300000 = 5 minutes)
107
- - `pollIntervalMs`: Time between polls (default: 2000 = 2 seconds)
151
+ Both examples import directly from `shadowkey-agent-sdk`:
108
152
 
109
- #### `submitReverseDisclosure(request: ReverseDisclosureRequest): Promise<ReverseDisclosureResponse>`
153
+ ### OpenRouter AI Agent (`/examples/openrouter/`)
110
154
 
111
- Submit data to user's vault (reverse data flow).
155
+ An AI shopping agent that uses OpenRouter's free models with 4-model automatic failover:
112
156
 
113
- **Parameters:**
114
- ```typescript
115
- {
116
- serviceId: string;
117
- serviceName: string;
118
- dataOffered: Array<{
119
- field: string;
120
- value: string;
121
- category: string;
122
- }>;
123
- purpose: string;
124
- }
157
+ ```javascript
158
+ import { ShadowKeyClient } from 'shadowkey-agent-sdk';
159
+
160
+ const shadowKey = new ShadowKeyClient({
161
+ apiUrl: `${process.env.SUPABASE_URL}/functions/v1`,
162
+ apiKey: process.env.SHADOWKEY_API_KEY,
163
+ });
164
+
165
+ // AI determines needed fields → SDK requests access → user approves → AI completes task
125
166
  ```
126
167
 
127
- ## Examples
168
+ ### Express.js Server (`/examples/node-express/`)
128
169
 
129
- See the `/examples` directory for complete integration examples:
170
+ A REST API backend that wraps the SDK for multi-agent architectures:
130
171
 
131
- - `openrouter/` - AI agent using OpenRouter free models
132
- - `node-express/` - Express.js server with webhook handling
133
- - `langchain/` - LangChain tool integration
134
- - `python/` - Python SDK wrapper
172
+ ```javascript
173
+ import { ShadowKeyClient } from 'shadowkey-agent-sdk';
174
+
175
+ const shadowKey = new ShadowKeyClient({ ... });
176
+
177
+ app.post('/api/request-data', async (req, res) => {
178
+ const response = await shadowKey.requestAccess({ ... });
179
+ res.json(response);
180
+ });
181
+ ```
135
182
 
136
183
  ## Error Handling
137
184
 
138
185
  ```typescript
139
186
  try {
140
- const response = await client.requestAccess({...});
187
+ const response = await client.requestAccess({ ... });
141
188
  } catch (error) {
142
189
  if (error.message.includes('timeout')) {
143
- console.error('Request timed out');
190
+ // Request timed out — check network or increase timeout
144
191
  } else if (error.message.includes('401')) {
145
- console.error('Invalid API key');
192
+ // Invalid or expired API key
193
+ } else if (error.message.includes('404')) {
194
+ // No vault found for this API key's user
146
195
  } else {
147
- console.error('Request failed:', error.message);
196
+ // Server error — SDK auto-retried and all attempts failed
148
197
  }
149
198
  }
150
199
  ```
151
200
 
152
- ## Security Best Practices
153
-
154
- 1. **Never expose your API key** in client-side code
155
- 2. **Use environment variables** to store credentials
156
- 3. **Rotate keys regularly** using the ShadowKey dashboard
157
- 4. **Set appropriate rate limits** for your use case
158
- 5. **Validate all data** received from the vault
159
- 6. **Use HTTPS** for all requests (enforced by default)
160
-
161
- ## Rate Limits
162
-
163
- Default rate limits per API key:
164
- - 100 requests per minute
165
- - 1000 requests per hour
166
- - 10000 requests per day
201
+ ## Security
167
202
 
168
- Contact support for enterprise limits.
203
+ - **HMAC-SHA256 signing** — Every request includes timestamp, nonce, and signature headers
204
+ - **5-minute timestamp window** — Rejects requests with stale timestamps (prevents replay attacks)
205
+ - **Sensitive field redaction** — Debug logs automatically redact `grantedData`, `grantedFields`, and `response_data`
206
+ - **No secrets in transit** — SDK receives only the fields the user approved, never the full vault
169
207
 
170
- ## Support
208
+ ## Links
171
209
 
172
- - Documentation: https://shadowkey.dev/docs
173
- - Issues: https://github.com/shadowkey/agent-sdk/issues
174
- - Discord: https://discord.gg/shadowkey
210
+ - **npm:** [shadowkey-agent-sdk](https://www.npmjs.com/package/shadowkey-agent-sdk)
211
+ - **Live Demo:** [shadowkey-ai.vercel.app/agent-demo](https://shadowkey-ai.vercel.app/agent-demo)
212
+ - **Dashboard:** [shadowkey-ai.vercel.app](https://shadowkey-ai.vercel.app)
213
+ - **Smart Contract:** [Basescan (Verified)](https://basescan.org/address/0xC739f98B438620A9326Ddb7548201Bcd78a3DBAd#code)
214
+ - **GitHub:** [kimboltpro3-create/shadowkey](https://github.com/kimboltpro3-create/shadowkey)
215
+ - **Issues:** [GitHub Issues](https://github.com/kimboltpro3-create/shadowkey/issues)
175
216
 
176
217
  ## License
177
218
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shadowkey-agent-sdk",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "Official SDK for integrating AI agents with ShadowKey privacy vault",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",