spaps-sdk 0.1.0 โ†’ 1.0.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
@@ -1,164 +1,640 @@
1
- # @spaps/sdk
1
+ # Sweet Potato SDK
2
2
 
3
- > Sweet Potato Authentication & Payment Service SDK
3
+ [![npm version](https://badge.fury.io/js/%40sweet-potato%2Fsdk.svg)](https://www.npmjs.com/package/@sweet-potato/sdk)
4
+ [![TypeScript](https://img.shields.io/badge/TypeScript-4.5%2B-blue)](https://www.typescriptlang.org/)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
4
6
 
5
- Zero-config client for SPAPS authentication and payments. Works automatically with local development mode.
7
+ A comprehensive TypeScript SDK for integrating with the Sweet Potato Authentication and Payment Service (SPAPS). This SDK provides complete functionality for user authentication, Stripe payment processing, subscription management, and more.
8
+
9
+ **[๐Ÿ“š Full API Documentation](../API_INTEGRATION_GUIDE.md) | [๐Ÿ› ๏ธ Stripe Admin Guide](../STRIPE_ADMIN_GUIDE.md)**
10
+
11
+ ## Features
12
+
13
+ ### Authentication
14
+ - ๐Ÿ” **Multi-wallet Authentication**: Support for Solana, Ethereum, Bitcoin, and Base wallets
15
+ - ๐Ÿ”‘ **Traditional Authentication**: Email/password and magic link authentication
16
+ - ๐Ÿ”„ **Token Management**: Automatic token refresh and secure storage utilities
17
+ - ๐Ÿงฐ **Wallet Utilities**: Address validation, chain detection
18
+
19
+ ### Payments & Subscriptions
20
+ - ๐Ÿ’ณ **Stripe Checkout Sessions**: One-time payments and subscriptions
21
+ - ๐Ÿ“ฆ **Product Management**: List, create, update products and prices
22
+ - ๐Ÿ”„ **Subscription Management**: Create, update, cancel subscriptions
23
+ - ๐Ÿช **Customer Portal**: Self-service billing management
24
+ - ๐ŸŽฃ **Webhook Handling**: Secure event processing
25
+
26
+ ### Developer Experience
27
+ - ๐ŸŽฏ **TypeScript First**: Full TypeScript support with comprehensive type definitions
28
+ - ๐Ÿ›ก๏ธ **Error Handling**: Robust error handling with custom error types
29
+ - ๐Ÿ” **Retry Logic**: Built-in retry mechanism with exponential backoff
30
+ - โš›๏ธ **React Integration**: Ready-to-use hooks and components
31
+ - ๐Ÿ“š **Extensive Examples**: Real-world usage patterns
32
+ - ๐Ÿงช **Well Tested**: Comprehensive test suite with high coverage
6
33
 
7
34
  ## Installation
8
35
 
9
36
  ```bash
10
- npm install @spaps/sdk
37
+ npm install @sweet-potato/sdk
11
38
  # or
12
- yarn add @spaps/sdk
39
+ yarn add @sweet-potato/sdk
40
+ # or
41
+ pnpm add @sweet-potato/sdk
13
42
  ```
14
43
 
44
+ ### Requirements
45
+
46
+ - Node.js 14+ or modern browser
47
+ - TypeScript 4.5+ (optional, for TypeScript projects)
48
+
15
49
  ## Quick Start
16
50
 
17
- ```javascript
18
- import { SPAPSClient } from '@spaps/sdk';
19
- // or
20
- const { SPAPSClient } = require('@spaps/sdk');
51
+ ### Basic Setup
21
52
 
22
- // Auto-detects local mode - no API key needed for localhost!
23
- const spaps = new SPAPSClient({
24
- apiUrl: 'http://localhost:3300' // Optional, auto-detected
25
- });
53
+ ```typescript
54
+ import { SweetPotatoSDK, TokenManager } from '@sweet-potato/sdk';
26
55
 
27
- // Login
28
- const { data } = await spaps.login('user@example.com', 'password');
29
- console.log('User:', data.user);
56
+ // Initialize the SDK
57
+ const sdk = new SweetPotatoSDK({
58
+ apiUrl: 'http://localhost:3456', // Development
59
+ // apiUrl: 'https://api.sweetpotato.dev', // Production
60
+ apiKey: 'your-api-key',
61
+ timeout: 30000, // Optional: 30 second timeout
62
+ retries: 3 // Optional: 3 retry attempts
63
+ });
30
64
 
31
- // Check authentication
32
- if (spaps.isAuthenticated()) {
33
- const user = await spaps.getUser();
34
- console.log('Current user:', user.data);
35
- }
65
+ // Auto-restore authentication state (browser only)
66
+ await TokenManager.autoRefreshToken(sdk);
36
67
  ```
37
68
 
38
- ## Features
69
+ ## Authentication Examples
70
+
71
+ ### Wallet Authentication (Complete Flow)
72
+
73
+ ```typescript
74
+ // Auto-detect chain and authenticate
75
+ const authResponse = await sdk.auth.authenticateWallet(
76
+ '0x742d35CC6354C7Cb24b5d2C2C7f9Ff5Ef8B4d5f6',
77
+ async (message) => {
78
+ // Use your wallet provider to sign the message
79
+ // Example with MetaMask:
80
+ return await window.ethereum.request({
81
+ method: 'personal_sign',
82
+ params: [message, walletAddress]
83
+ });
84
+ },
85
+ 'ethereum', // Optional: specify chain type
86
+ 'username123' // Optional: username for new users
87
+ );
88
+
89
+ // Store tokens for future use
90
+ TokenManager.storeTokens(authResponse);
91
+ console.log('User:', authResponse.user);
92
+ ```
39
93
 
40
- ### ๐Ÿš€ Zero Configuration
41
- - **Auto-detects local mode** - No API key needed for localhost
42
- - **Auto-refreshes tokens** - Handles expired tokens automatically
43
- - **TypeScript support** - Full type definitions included
94
+ ### Email/Password Authentication
44
95
 
45
- ### ๐Ÿ” Authentication Methods
46
- ```javascript
47
- // Email/Password
48
- await spaps.login(email, password);
49
- await spaps.register(email, password);
96
+ ```typescript
97
+ const authResponse = await sdk.auth.signInWithPassword({
98
+ email: 'user@example.com',
99
+ password: 'securePassword123!'
100
+ });
50
101
 
51
- // Wallet Authentication
52
- await spaps.walletSignIn(walletAddress, signature, message, 'solana');
102
+ TokenManager.storeTokens(authResponse);
103
+ ```
53
104
 
54
- // Token Management
55
- await spaps.refresh();
56
- await spaps.logout();
105
+ ### Magic Link Authentication
57
106
 
58
- // Get User
59
- const user = await spaps.getUser();
107
+ ```typescript
108
+ await sdk.auth.requestMagicLink({
109
+ email: 'user@example.com',
110
+ redirect_url: 'https://myapp.com/auth/callback'
111
+ });
112
+ // User will receive email with authentication link
60
113
  ```
61
114
 
62
- ### ๐Ÿ’ณ Stripe Integration
63
- ```javascript
64
- // Create checkout session
65
- const session = await spaps.createCheckoutSession(priceId, successUrl);
66
- window.location.href = session.data.url;
115
+ ## Payment Examples
116
+
117
+ ### One-Time Payment
67
118
 
68
- // Manage subscription
69
- const subscription = await spaps.getSubscription();
70
- await spaps.cancelSubscription();
119
+ ```typescript
120
+ // Using existing price
121
+ const checkoutSession = await sdk.payments.createPaymentCheckout({
122
+ price_id: 'price_1234567890',
123
+ success_url: 'https://myapp.com/success',
124
+ cancel_url: 'https://myapp.com/cancel',
125
+ metadata: {
126
+ order_id: 'order_123',
127
+ user_type: 'premium'
128
+ }
129
+ });
130
+
131
+ // Redirect to Stripe Checkout
132
+ window.location.href = checkoutSession.url!;
71
133
  ```
72
134
 
73
- ### ๐Ÿ“Š Usage Tracking
74
- ```javascript
75
- // Check balance
76
- const balance = await spaps.getUsageBalance();
77
- console.log(`Credits: ${balance.data.balance}`);
135
+ ### Dynamic Pricing
136
+
137
+ ```typescript
138
+ // Create payment with custom price
139
+ const checkoutSession = await sdk.payments.createPaymentCheckout({
140
+ product_name: 'Premium Feature Access',
141
+ amount: 2999, // $29.99 in cents
142
+ currency: 'usd',
143
+ quantity: 1,
144
+ success_url: 'https://myapp.com/success',
145
+ cancel_url: 'https://myapp.com/cancel'
146
+ });
147
+ ```
78
148
 
79
- // Record usage
80
- await spaps.recordUsage('api-call', 1);
149
+ ### Subscription Creation
150
+
151
+ ```typescript
152
+ const subscriptionCheckout = await sdk.payments.createSubscriptionCheckout({
153
+ price_id: 'price_monthly_subscription',
154
+ success_url: 'https://myapp.com/subscription-success',
155
+ cancel_url: 'https://myapp.com/subscription-cancel',
156
+ trial_period_days: 14,
157
+ metadata: {
158
+ subscription_type: 'pro',
159
+ source: 'website'
160
+ }
161
+ });
81
162
  ```
82
163
 
83
- ## Configuration
164
+ ### Product Management
84
165
 
85
- ### Production Mode
86
- ```javascript
87
- const spaps = new SPAPSClient({
88
- apiUrl: 'https://api.sweetpotato.com',
89
- apiKey: 'spaps_your_api_key_here',
90
- timeout: 10000 // Optional timeout in ms
166
+ ```typescript
167
+ // List all products
168
+ const products = await sdk.payments.listProducts({
169
+ category: 'subscription',
170
+ active: true,
171
+ limit: 20
172
+ });
173
+
174
+ // Get specific product with prices
175
+ const product = await sdk.payments.getProduct('prod_123');
176
+
177
+ // Create new product (admin only)
178
+ const newProduct = await sdk.payments.createProduct({
179
+ name: 'New Premium Plan',
180
+ description: 'Enhanced features for power users',
181
+ category: 'subscription',
182
+ metadata: {
183
+ tier: 'premium',
184
+ features: 'advanced-analytics,priority-support'
185
+ }
91
186
  });
92
187
  ```
93
188
 
94
- ### Local Development Mode (Auto-detected)
95
- ```javascript
96
- const spaps = new SPAPSClient();
97
- // Automatically uses http://localhost:3300 with no API key
189
+ ### Subscription Management
190
+
191
+ ```typescript
192
+ // List user subscriptions
193
+ const subscriptions = await sdk.payments.listSubscriptions({
194
+ status: 'active'
195
+ });
196
+
197
+ // Update subscription
198
+ await sdk.payments.updateSubscription('sub_123', {
199
+ price_id: 'price_new_plan',
200
+ metadata: { upgrade_reason: 'user_requested' }
201
+ });
202
+
203
+ // Cancel subscription at period end
204
+ await sdk.payments.updateSubscription('sub_123', {
205
+ cancel_at_period_end: true
206
+ });
207
+
208
+ // Create customer portal session
209
+ const portalSession = await sdk.payments.createCustomerPortalSession({
210
+ return_url: 'https://myapp.com/account'
211
+ });
212
+ window.location.href = portalSession.url;
98
213
  ```
99
214
 
100
- ### Environment Variables
101
- ```bash
102
- # .env
103
- SPAPS_API_URL=https://api.sweetpotato.com
104
- SPAPS_API_KEY=spaps_your_api_key_here
215
+ ## Token Management
105
216
 
106
- # Next.js
107
- NEXT_PUBLIC_SPAPS_API_URL=https://api.sweetpotato.com
217
+ ### Automatic Token Refresh
218
+
219
+ ```typescript
220
+ // Set up automatic token refresh
221
+ async function setupAutoRefresh() {
222
+ const refreshSuccess = await TokenManager.autoRefreshToken(sdk);
223
+
224
+ if (refreshSuccess) {
225
+ console.log('Authentication restored from stored tokens');
226
+ } else {
227
+ console.log('No valid tokens found, user needs to authenticate');
228
+ }
229
+ }
230
+
231
+ // Manual token refresh
232
+ async function refreshTokens() {
233
+ try {
234
+ const refreshToken = TokenManager.getRefreshToken();
235
+ if (refreshToken) {
236
+ const newTokens = await sdk.auth.refreshToken(refreshToken);
237
+ TokenManager.storeTokens(newTokens);
238
+ }
239
+ } catch (error) {
240
+ console.error('Token refresh failed:', error);
241
+ // Redirect to login
242
+ }
243
+ }
108
244
  ```
109
245
 
110
- ## Helper Methods
246
+ ### Logout
111
247
 
112
- ```javascript
113
- // Check if authenticated
114
- spaps.isAuthenticated() // boolean
248
+ ```typescript
249
+ async function logout() {
250
+ try {
251
+ await sdk.auth.logout();
252
+ TokenManager.clearTokens();
253
+ console.log('Successfully logged out');
254
+ } catch (error) {
255
+ console.error('Logout failed:', error);
256
+ }
257
+ }
258
+ ```
259
+
260
+ ## User Management
115
261
 
116
- // Get current access token
117
- spaps.getAccessToken() // string | undefined
262
+ ### Get Current User
118
263
 
119
- // Set access token manually
120
- spaps.setAccessToken(token)
264
+ ```typescript
265
+ async function getCurrentUser() {
266
+ try {
267
+ const user = await sdk.auth.getCurrentUser();
268
+ console.log('Current user:', user);
269
+ return user;
270
+ } catch (error) {
271
+ console.error('Failed to get user:', error);
272
+ // User might not be authenticated
273
+ }
274
+ }
275
+ ```
121
276
 
122
- // Check if in local mode
123
- spaps.isLocalMode() // boolean
277
+ ### Check Authentication Status
124
278
 
125
- // Health check
126
- await spaps.health()
279
+ ```typescript
280
+ function checkAuthStatus() {
281
+ if (sdk.auth.isAuthenticated()) {
282
+ console.log('User is authenticated');
283
+ } else {
284
+ console.log('User needs to log in');
285
+ }
286
+ }
127
287
  ```
128
288
 
129
- ## Import Styles
289
+ ## Utility Functions
290
+
291
+ ### Wallet Address Validation
292
+
293
+ ```typescript
294
+ import { WalletUtils } from '@sweet-potato/auth-sdk';
295
+
296
+ // Detect chain type
297
+ const chainType = WalletUtils.detectChainType('0x742d35Cc6634C0532925a3b8D6Ac6d8F49c3589F');
298
+ console.log(chainType); // 'ethereum'
130
299
 
131
- All these work:
132
- ```javascript
133
- // ES6 Import
134
- import { SPAPSClient } from '@spaps/sdk';
135
- import SPAPSClient from '@spaps/sdk';
300
+ // Validate address format
301
+ const isValid = WalletUtils.isValidAddress('0x742d35Cc6634C0532925a3b8D6Ac6d8F49c3589F', 'ethereum');
302
+ console.log(isValid); // true
136
303
 
137
- // CommonJS
138
- const { SPAPSClient } = require('@spaps/sdk');
139
- const SPAPSClient = require('@spaps/sdk');
304
+ // Auto-detect and validate
305
+ const isValidAuto = WalletUtils.isValidAddress('0x742d35Cc6634C0532925a3b8D6Ac6d8F49c3589F');
306
+ console.log(isValidAuto); // true
307
+ ```
308
+
309
+ ### Token Utilities
140
310
 
141
- // Alternative names
142
- import { SPAPS } from '@spaps/sdk';
143
- import { SweetPotatoSDK } from '@spaps/sdk';
311
+ ```typescript
312
+ // Check if token is expired
313
+ const token = TokenManager.getAccessToken();
314
+ if (token && TokenManager.isTokenExpired(token)) {
315
+ console.log('Token is expired, refreshing...');
316
+ await refreshTokens();
317
+ }
144
318
  ```
145
319
 
146
320
  ## Error Handling
147
321
 
148
- ```javascript
322
+ ```typescript
323
+ import { SweetPotatoAPIError } from '@sweet-potato/auth-sdk';
324
+
149
325
  try {
150
- await spaps.login(email, password);
326
+ await sdk.auth.signInWithPassword({
327
+ email: 'invalid@example.com',
328
+ password: 'wrongpassword'
329
+ });
151
330
  } catch (error) {
152
- if (error.response?.status === 401) {
153
- console.error('Invalid credentials');
154
- } else if (error.response?.status === 429) {
155
- console.error('Rate limited');
331
+ if (error instanceof SweetPotatoAPIError) {
332
+ console.error('API Error:', {
333
+ message: error.message,
334
+ code: error.code,
335
+ status: error.status,
336
+ details: error.details
337
+ });
338
+
339
+ // Handle specific error codes
340
+ switch (error.code) {
341
+ case 'INVALID_CREDENTIALS':
342
+ console.log('Please check your email and password');
343
+ break;
344
+ case 'RATE_LIMITED':
345
+ console.log('Too many attempts, please wait');
346
+ break;
347
+ default:
348
+ console.log('An unexpected error occurred');
349
+ }
350
+ }
351
+ }
352
+ ```
353
+
354
+ ## Advanced Usage
355
+
356
+ ### Custom Requests
357
+
358
+ ```typescript
359
+ // Make custom authenticated requests
360
+ async function makeCustomRequest() {
361
+ try {
362
+ const response = await sdk.request(
363
+ 'GET',
364
+ '/api/custom-endpoint',
365
+ null,
366
+ true // requires authentication
367
+ );
368
+
369
+ console.log('Custom response:', response.data);
370
+ } catch (error) {
371
+ console.error('Custom request failed:', error);
372
+ }
373
+ }
374
+ ```
375
+
376
+ ### Health Check
377
+
378
+ ```typescript
379
+ async function checkAPIHealth() {
380
+ const isHealthy = await sdk.healthCheck();
381
+ if (isHealthy) {
382
+ console.log('API is healthy');
156
383
  } else {
157
- console.error('Error:', error.message);
384
+ console.log('API is down or unreachable');
158
385
  }
159
386
  }
160
387
  ```
161
388
 
389
+ ## React Integration Example
390
+
391
+ ```typescript
392
+ import React, { useEffect, useState } from 'react';
393
+ import { createSweetPotatoSDK, TokenManager, User } from '@sweet-potato/auth-sdk';
394
+
395
+ const sdk = createSweetPotatoSDK({
396
+ apiUrl: process.env.REACT_APP_API_URL!,
397
+ apiKey: process.env.REACT_APP_API_KEY!
398
+ });
399
+
400
+ export function useAuth() {
401
+ const [user, setUser] = useState<User | null>(null);
402
+ const [loading, setLoading] = useState(true);
403
+
404
+ useEffect(() => {
405
+ async function restoreAuth() {
406
+ try {
407
+ const restored = await TokenManager.autoRefreshToken(sdk);
408
+ if (restored) {
409
+ const currentUser = await sdk.auth.getCurrentUser();
410
+ setUser(currentUser);
411
+ }
412
+ } catch (error) {
413
+ console.error('Failed to restore authentication:', error);
414
+ } finally {
415
+ setLoading(false);
416
+ }
417
+ }
418
+
419
+ restoreAuth();
420
+ }, []);
421
+
422
+ const login = async (email: string, password: string) => {
423
+ const result = await sdk.auth.signInWithPassword({ email, password });
424
+ TokenManager.storeTokens(result);
425
+ setUser(result.user);
426
+ return result;
427
+ };
428
+
429
+ const logout = async () => {
430
+ await sdk.auth.logout();
431
+ TokenManager.clearTokens();
432
+ setUser(null);
433
+ };
434
+
435
+ return {
436
+ user,
437
+ loading,
438
+ login,
439
+ logout,
440
+ isAuthenticated: !!user
441
+ };
442
+ }
443
+ ```
444
+
445
+ ## Configuration Options
446
+
447
+ ```typescript
448
+ interface SweetPotatoConfig {
449
+ apiUrl: string; // Required: Your API base URL
450
+ apiKey: string; // Required: Your application API key
451
+ timeout?: number; // Optional: Request timeout in ms (default: 30000)
452
+ retries?: number; // Optional: Number of retries (default: 3)
453
+ }
454
+ ```
455
+
456
+ ## TypeScript Types
457
+
458
+ The SDK exports comprehensive TypeScript types for all API responses and request payloads:
459
+
460
+ ```typescript
461
+ import type {
462
+ User,
463
+ UserWallet,
464
+ AuthResponse,
465
+ NonceResponse,
466
+ WalletSignInRequest,
467
+ TraditionalLoginRequest,
468
+ ApiResponse,
469
+ SweetPotatoAPIError
470
+ } from '@sweet-potato/auth-sdk';
471
+ ```
472
+
473
+ ## Browser Compatibility
474
+
475
+ The SDK supports all modern browsers with ES2018+ support. For older browsers, you may need to include polyfills for:
476
+
477
+ - `fetch` API
478
+ - `Promise`
479
+ - `async/await`
480
+
481
+ ## Error Codes
482
+
483
+ Common error codes you might encounter:
484
+
485
+ - `INVALID_CREDENTIALS`: Invalid email/password or wallet signature
486
+ - `MISSING_REQUIRED_FIELDS`: Required fields are missing from request
487
+ - `INVALID_SIGNATURE`: Wallet signature verification failed
488
+ - `RATE_LIMITED`: Too many requests, rate limit exceeded
489
+ - `UNAUTHORIZED`: Invalid or expired tokens
490
+ - `INVALID_APPLICATION`: Invalid API key or application configuration
491
+ - `INTERNAL_SERVER_ERROR`: Server-side error occurred
492
+
493
+ ## API Reference
494
+
495
+ ### SDK Classes
496
+
497
+ #### `SweetPotatoSDK`
498
+ Main SDK class that provides access to all services.
499
+
500
+ #### `AuthService`
501
+ - `authenticateWallet()` - Complete wallet authentication flow
502
+ - `signInWithPassword()` - Email/password login
503
+ - `signUp()` - Create new account
504
+ - `requestMagicLink()` - Send magic link email
505
+ - `verifyMagicLink()` - Verify magic link token
506
+ - `refreshToken()` - Refresh access token
507
+ - `logout()` - Sign out and invalidate tokens
508
+ - `getCurrentUser()` - Get authenticated user
509
+ - `isAuthenticated()` - Check auth status
510
+
511
+ #### `PaymentsService`
512
+ - `createCheckoutSession()` - Create Stripe checkout
513
+ - `createPaymentCheckout()` - Simplified one-time payment
514
+ - `createSubscriptionCheckout()` - Simplified subscription
515
+ - `listProducts()` - Get available products
516
+ - `getProduct()` - Get product details
517
+ - `createProduct()` - Create product (admin)
518
+ - `updateProduct()` - Update product (admin)
519
+ - `syncProducts()` - Sync from Stripe (admin)
520
+ - `listSubscriptions()` - User's subscriptions
521
+ - `updateSubscription()` - Modify subscription
522
+ - `cancelSubscription()` - Cancel subscription
523
+ - `createCustomerPortalSession()` - Billing portal
524
+
525
+ #### `TokenManager`
526
+ Static utility class for browser token management.
527
+ - `storeTokens()` - Save tokens to localStorage
528
+ - `getAccessToken()` - Retrieve access token
529
+ - `getRefreshToken()` - Retrieve refresh token
530
+ - `clearTokens()` - Remove all tokens
531
+ - `isTokenExpired()` - Check token expiration
532
+ - `autoRefreshToken()` - Auto-refresh if needed
533
+
534
+ #### `WalletUtils`
535
+ Static utility class for wallet operations.
536
+ - `detectChainType()` - Identify blockchain from address
537
+ - `isValidAddress()` - Validate wallet address format
538
+
539
+ ## What's NOT in the SDK
540
+
541
+ ### Whitelist Management
542
+ Whitelist operations require admin JWT authentication and must be done via direct API calls:
543
+
544
+ ```typescript
545
+ // Authenticate as admin first
546
+ const adminAuth = await sdk.auth.signInWithPassword({
547
+ email: 'admin@example.com',
548
+ password: 'admin_password'
549
+ });
550
+
551
+ // Use JWT for admin API calls
552
+ const response = await fetch(`${apiUrl}/api/v1/whitelist`, {
553
+ method: 'POST',
554
+ headers: {
555
+ 'Authorization': `Bearer ${adminAuth.access_token}`,
556
+ 'X-API-Key': apiKey,
557
+ 'Content-Type': 'application/json'
558
+ },
559
+ body: JSON.stringify({
560
+ email: 'vip@example.com',
561
+ tier: 'premium',
562
+ bypass_payment: true
563
+ })
564
+ });
565
+ ```
566
+
567
+ ### Admin Operations
568
+ - Application management (create/rotate API keys)
569
+ - User management (admin dashboard)
570
+ - Direct database operations
571
+
572
+ See [Stripe Admin Guide](../STRIPE_ADMIN_GUIDE.md) for product management instructions.
573
+
574
+ ## Troubleshooting
575
+
576
+ ### Common Issues
577
+
578
+ **CORS Errors**
579
+ ```typescript
580
+ // Ensure your API URL is whitelisted in SPAPS config
581
+ // Contact support to add your domain
582
+ ```
583
+
584
+ **Token Expired**
585
+ ```typescript
586
+ // Use TokenManager for automatic refresh
587
+ await TokenManager.autoRefreshToken(sdk);
588
+ ```
589
+
590
+ **Rate Limiting**
591
+ ```typescript
592
+ // SDK automatically retries with exponential backoff
593
+ // Configure retries in SDK initialization
594
+ const sdk = new SweetPotatoSDK({
595
+ apiUrl: '...',
596
+ apiKey: '...',
597
+ retries: 5 // Increase retry count
598
+ });
599
+ ```
600
+
601
+ ## Migration Guide
602
+
603
+ ### From v0.x to v1.0
604
+
605
+ ```typescript
606
+ // Old (v0.x)
607
+ const sdk = new SweetPotatoSDK(apiUrl, apiKey);
608
+
609
+ // New (v1.0)
610
+ const sdk = new SweetPotatoSDK({
611
+ apiUrl,
612
+ apiKey,
613
+ timeout: 30000,
614
+ retries: 3
615
+ });
616
+ ```
617
+
618
+ ## Contributing
619
+
620
+ We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.
621
+
622
+ ## Security
623
+
624
+ - **Never expose API keys in client-side code**
625
+ - **Use environment variables for sensitive data**
626
+ - **Enable HTTPS in production**
627
+ - **Implement proper CORS policies**
628
+
629
+ Report security vulnerabilities to security@sweetpotato.dev
630
+
631
+ ## Support
632
+
633
+ - ๐Ÿ“– [Full Documentation](../API_INTEGRATION_GUIDE.md)
634
+ - ๐Ÿ’ฌ Discord: [discord.gg/sweetpotato](https://discord.gg/sweetpotato)
635
+ - ๐Ÿ“ง Email: support@sweetpotato.dev
636
+ - ๐Ÿ› Issues: [GitHub Issues](https://github.com/sweet-potato/sdk/issues)
637
+
162
638
  ## License
163
639
 
164
- MIT
640
+ MIT ยฉ Sweet Potato Team