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