@skillzmarket/sdk 0.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.
Files changed (59) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +313 -0
  3. package/dist/client.d.ts +18 -0
  4. package/dist/client.d.ts.map +1 -0
  5. package/dist/client.js +118 -0
  6. package/dist/client.js.map +1 -0
  7. package/dist/creator/auth.d.ts +50 -0
  8. package/dist/creator/auth.d.ts.map +1 -0
  9. package/dist/creator/auth.js +114 -0
  10. package/dist/creator/auth.js.map +1 -0
  11. package/dist/creator/index.d.ts +27 -0
  12. package/dist/creator/index.d.ts.map +1 -0
  13. package/dist/creator/index.js +26 -0
  14. package/dist/creator/index.js.map +1 -0
  15. package/dist/creator/payment.d.ts +20 -0
  16. package/dist/creator/payment.d.ts.map +1 -0
  17. package/dist/creator/payment.js +46 -0
  18. package/dist/creator/payment.js.map +1 -0
  19. package/dist/creator/register.d.ts +35 -0
  20. package/dist/creator/register.d.ts.map +1 -0
  21. package/dist/creator/register.js +165 -0
  22. package/dist/creator/register.js.map +1 -0
  23. package/dist/creator/serve.d.ts +19 -0
  24. package/dist/creator/serve.d.ts.map +1 -0
  25. package/dist/creator/serve.js +163 -0
  26. package/dist/creator/serve.js.map +1 -0
  27. package/dist/creator/skill.d.ts +20 -0
  28. package/dist/creator/skill.d.ts.map +1 -0
  29. package/dist/creator/skill.js +40 -0
  30. package/dist/creator/skill.js.map +1 -0
  31. package/dist/creator/types.d.ts +173 -0
  32. package/dist/creator/types.d.ts.map +1 -0
  33. package/dist/creator/types.js +2 -0
  34. package/dist/creator/types.js.map +1 -0
  35. package/dist/creator/utils/price.d.ts +19 -0
  36. package/dist/creator/utils/price.d.ts.map +1 -0
  37. package/dist/creator/utils/price.js +62 -0
  38. package/dist/creator/utils/price.js.map +1 -0
  39. package/dist/creator/utils/wallet.d.ts +22 -0
  40. package/dist/creator/utils/wallet.d.ts.map +1 -0
  41. package/dist/creator/utils/wallet.js +45 -0
  42. package/dist/creator/utils/wallet.js.map +1 -0
  43. package/dist/discovery.d.ts +10 -0
  44. package/dist/discovery.d.ts.map +1 -0
  45. package/dist/discovery.js +40 -0
  46. package/dist/discovery.js.map +1 -0
  47. package/dist/index.d.ts +6 -0
  48. package/dist/index.d.ts.map +1 -0
  49. package/dist/index.js +4 -0
  50. package/dist/index.js.map +1 -0
  51. package/dist/payment.d.ts +20 -0
  52. package/dist/payment.d.ts.map +1 -0
  53. package/dist/payment.js +34 -0
  54. package/dist/payment.js.map +1 -0
  55. package/dist/types.d.ts +62 -0
  56. package/dist/types.d.ts.map +1 -0
  57. package/dist/types.js +2 -0
  58. package/dist/types.js.map +1 -0
  59. package/package.json +81 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 SkillzMarket
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,313 @@
1
+ # @skillzmarket/sdk
2
+
3
+ [![npm version](https://img.shields.io/npm/v/@skillzmarket/sdk.svg)](https://www.npmjs.com/package/@skillzmarket/sdk)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+
6
+ SDK for discovering and calling paid AI skills with automatic x402 crypto payments.
7
+
8
+ ## Features
9
+
10
+ - **Discover skills** - Search and explore the Skillz Market registry
11
+ - **Automatic payments** - x402 protocol handles USDC payments seamlessly
12
+ - **Create skills** - Monetize your AI services with zero crypto knowledge
13
+ - **Type-safe** - Full TypeScript support with comprehensive types
14
+ - **Base network** - Fast, low-cost transactions on Base mainnet
15
+
16
+ ## Installation
17
+
18
+ ```bash
19
+ npm install @skillzmarket/sdk viem
20
+ # or
21
+ pnpm add @skillzmarket/sdk viem
22
+ ```
23
+
24
+ ## Quick Start
25
+
26
+ ### Consumer: Call Paid Skills
27
+
28
+ ```typescript
29
+ import { SkillzMarket } from '@skillzmarket/sdk';
30
+
31
+ const market = new SkillzMarket({ wallet: '0x...' });
32
+ const result = await market.call('text-to-image', { prompt: 'A sunset' });
33
+ ```
34
+
35
+ ### Creator: Monetize Your Skills
36
+
37
+ ```typescript
38
+ import { skill, serve } from '@skillzmarket/sdk/creator';
39
+
40
+ const echo = skill({ price: '$0.001' }, async (input) => ({ echo: input }));
41
+ serve({ echo }); // Run: SKILLZ_WALLET_KEY=0x... npx tsx index.ts
42
+ ```
43
+
44
+ ## Documentation
45
+
46
+ 📚 **[Full Documentation](https://docs.skillz.market)** - Complete guides, API reference, and examples.
47
+
48
+ ---
49
+
50
+ ## AI Assistant Integration
51
+
52
+ For AI assistants like Claude, use the MCP package:
53
+
54
+ ```json
55
+ {
56
+ "mcpServers": {
57
+ "skillzmarket": {
58
+ "command": "npx",
59
+ "args": ["@skillzmarket/mcp"],
60
+ "env": { "SKILLZ_PRIVATE_KEY": "0x..." }
61
+ }
62
+ }
63
+ }
64
+ ```
65
+
66
+ | Tool | Description |
67
+ |------|-------------|
68
+ | `skillz_search` | Search for skills |
69
+ | `skillz_info` | Get skill details |
70
+ | `skillz_call` | Call with payment |
71
+ | `skillz_reviews` | Get reviews |
72
+
73
+ See [@skillzmarket/mcp](../mcp) for details.
74
+
75
+ ---
76
+
77
+ ## Consumer API
78
+
79
+ The consumer API lets you discover and call paid skills.
80
+
81
+ ### Initialize
82
+
83
+ ```typescript
84
+ import { SkillzMarket } from '@skillzmarket/sdk';
85
+
86
+ // Without wallet (discovery only)
87
+ const market = new SkillzMarket();
88
+
89
+ // With wallet (can call paid skills)
90
+ const market = new SkillzMarket({
91
+ wallet: '0x...private-key',
92
+ apiUrl: 'https://api.skillz.market', // optional
93
+ network: 'eip155:8453', // Base mainnet (default)
94
+ });
95
+ ```
96
+
97
+ ### Methods
98
+
99
+ | Method | Description |
100
+ |--------|-------------|
101
+ | `search(query, filters?)` | Search for skills by keyword |
102
+ | `info(slug)` | Get detailed skill information |
103
+ | `call(slug, input)` | Call a skill with automatic payment |
104
+ | `getCreator(address)` | Get creator profile |
105
+ | `getReviews(slug)` | Get reviews for a skill |
106
+ | `authenticate()` | Auth with wallet signature |
107
+ | `feedback(slug, score, comment?)` | Submit a review |
108
+
109
+ ### Example
110
+
111
+ ```typescript
112
+ import { SkillzMarket } from '@skillzmarket/sdk';
113
+
114
+ const market = new SkillzMarket({
115
+ wallet: process.env.WALLET_KEY,
116
+ });
117
+
118
+ // Discover skills
119
+ const skills = await market.search('image generation');
120
+ const skill = await market.info('text-to-image');
121
+
122
+ // Call with automatic payment
123
+ const result = await market.call('text-to-image', {
124
+ prompt: 'A cyberpunk cityscape at night',
125
+ style: 'photorealistic',
126
+ });
127
+
128
+ // Submit feedback
129
+ await market.feedback('text-to-image', 90, 'Amazing results!');
130
+ ```
131
+
132
+ ### Payment Flow
133
+
134
+ Payments use the [x402 protocol](https://x402.org):
135
+
136
+ 1. Skill endpoint returns `402 Payment Required`
137
+ 2. SDK creates USDC transfer (consumer → creator)
138
+ 3. Payment settles on Base (instant)
139
+ 4. SDK retries request with payment proof
140
+ 5. Skill executes and returns result
141
+
142
+ ---
143
+
144
+ ## Creator API
145
+
146
+ The creator API lets you monetize your AI skills.
147
+
148
+ ### Functions
149
+
150
+ | Function | Description |
151
+ |----------|-------------|
152
+ | `skill(options, handler)` | Define a monetized skill |
153
+ | `serve(skills, options?)` | Start the skill server |
154
+ | `register(skills, options)` | Register skills with marketplace |
155
+
156
+ ### Example
157
+
158
+ ```typescript
159
+ import { skill, serve } from '@skillzmarket/sdk/creator';
160
+
161
+ // Define skills
162
+ const summarize = skill({
163
+ price: '$0.005',
164
+ description: 'Summarize text using AI',
165
+ inputSchema: {
166
+ type: 'object',
167
+ properties: { text: { type: 'string' } },
168
+ required: ['text'],
169
+ },
170
+ }, async ({ text }) => {
171
+ // Your AI logic here
172
+ return { summary: text.slice(0, 100) + '...' };
173
+ });
174
+
175
+ const translate = skill({
176
+ price: '$0.003',
177
+ description: 'Translate text between languages',
178
+ }, async ({ text, targetLang }) => {
179
+ return { translated: `[${targetLang}] ${text}` };
180
+ });
181
+
182
+ // Serve multiple skills
183
+ serve({ summarize, translate }, {
184
+ port: 3002,
185
+ register: {
186
+ endpoint: 'https://your-server.com',
187
+ enabled: true,
188
+ },
189
+ });
190
+ ```
191
+
192
+ ### Price Formats
193
+
194
+ Creators can specify prices in multiple formats:
195
+
196
+ | Format | Example | Result |
197
+ |--------|---------|--------|
198
+ | Dollar sign | `'$0.001'` | 0.001 USDC |
199
+ | With currency | `'0.005 USDC'` | 0.005 USDC |
200
+ | Plain number | `'0.01'` | 0.01 USDC |
201
+
202
+ ### Skill Options
203
+
204
+ ```typescript
205
+ interface SkillOptions {
206
+ price: string; // Required: price per call
207
+ description?: string; // What the skill does
208
+ timeout?: number; // Max execution time (ms, default: 60000)
209
+ inputSchema?: JsonSchema; // JSON Schema for input validation
210
+ outputSchema?: JsonSchema; // JSON Schema for output format
211
+ }
212
+ ```
213
+
214
+ ### Serve Options
215
+
216
+ ```typescript
217
+ interface ServeOptions {
218
+ port?: number; // Port to listen on (default: 3002)
219
+ wallet?: Hex; // Private key (or use SKILLZ_WALLET_KEY env)
220
+ network?: string; // Network (default: 'eip155:8453')
221
+ register?: {
222
+ endpoint: string; // Your public server URL
223
+ enabled?: boolean; // Enable auto-registration
224
+ onError?: 'throw' | 'warn' | 'silent';
225
+ };
226
+ onCall?: (name, input) => void; // Callback for skill calls
227
+ onError?: (name, error) => void; // Callback for errors
228
+ }
229
+ ```
230
+
231
+ ---
232
+
233
+ ## Environment Variables
234
+
235
+ | Variable | Description | Required |
236
+ |----------|-------------|----------|
237
+ | `SKILLZ_WALLET_KEY` | Private key for payments (Creator) | Yes* |
238
+
239
+ *Required for `serve()` if not passed in options.
240
+
241
+ ## Security Considerations
242
+
243
+ ### HTTPS Required
244
+
245
+ All API URLs must use HTTPS. The SDK rejects HTTP URLs (except localhost for development).
246
+
247
+ ### Wallet Security
248
+
249
+ - Never hardcode private keys in source code
250
+ - Use environment variables or secure key management
251
+ - Consider hardware wallets for production
252
+
253
+ ### Error Handling
254
+
255
+ In production (`NODE_ENV=production`), error messages are masked to prevent information disclosure.
256
+
257
+ ---
258
+
259
+ ## Types
260
+
261
+ ### Consumer Types
262
+
263
+ ```typescript
264
+ interface Skill {
265
+ id: string;
266
+ slug: string;
267
+ name: string;
268
+ description: string | null;
269
+ price: string;
270
+ currency: string;
271
+ endpoint: string;
272
+ inputSchema: Record<string, unknown> | null;
273
+ outputSchema: Record<string, unknown> | null;
274
+ paymentAddress: string;
275
+ isActive: boolean;
276
+ creatorId: string;
277
+ }
278
+
279
+ interface SearchFilters {
280
+ category?: string;
281
+ minPrice?: string;
282
+ maxPrice?: string;
283
+ creator?: string;
284
+ }
285
+
286
+ type WalletConfig = PrivateKeyAccount | Hex;
287
+ ```
288
+
289
+ ### Creator Types
290
+
291
+ ```typescript
292
+ interface SkillDefinition<TInput, TOutput> {
293
+ options: SkillOptions;
294
+ handler: SkillHandler<TInput, TOutput>;
295
+ parsedPrice: ParsedPrice;
296
+ }
297
+
298
+ interface ParsedPrice {
299
+ amount: string;
300
+ currency: 'USDC';
301
+ }
302
+ ```
303
+
304
+ ---
305
+
306
+ ## Requirements
307
+
308
+ - Node.js >= 18.0.0
309
+ - pnpm >= 8.0.0 (recommended)
310
+
311
+ ## License
312
+
313
+ MIT © [Skillz Market](https://skillz.market)
@@ -0,0 +1,18 @@
1
+ import type { Skill, SearchFilters, SkillzMarketOptions } from './types.js';
2
+ export declare class SkillzMarket {
3
+ private discovery;
4
+ private apiUrl;
5
+ private wallet?;
6
+ private walletAddress?;
7
+ private paymentFetch?;
8
+ private authToken?;
9
+ constructor(options?: SkillzMarketOptions);
10
+ search(query: string, filters?: SearchFilters): Promise<Skill[]>;
11
+ info(slug: string): Promise<Skill>;
12
+ getCreator(address: string): Promise<import("./types.js").Creator>;
13
+ getReviews(skillSlug: string): Promise<import("./types.js").Review[]>;
14
+ call<T = unknown>(slug: string, input: Record<string, unknown>): Promise<T>;
15
+ authenticate(): Promise<string>;
16
+ feedback(slug: string, score: number, comment?: string): Promise<void>;
17
+ }
18
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,mBAAmB,EAAgB,MAAM,YAAY,CAAC;AAgB1F,qBAAa,YAAY;IACvB,OAAO,CAAC,SAAS,CAAkB;IACnC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAC,CAAe;IAC9B,OAAO,CAAC,aAAa,CAAC,CAAS;IAC/B,OAAO,CAAC,YAAY,CAAC,CAAe;IACpC,OAAO,CAAC,SAAS,CAAC,CAAS;gBAEf,OAAO,GAAE,mBAAwB;IAmBvC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;IAIhE,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;IAIlC,UAAU,CAAC,OAAO,EAAE,MAAM;IAI1B,UAAU,CAAC,SAAS,EAAE,MAAM;IAK5B,IAAI,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAyB3E,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC;IA4C/B,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAkB7E"}
package/dist/client.js ADDED
@@ -0,0 +1,118 @@
1
+ import { DiscoveryClient } from './discovery.js';
2
+ import { createPaymentFetch, getWalletAddress, DEFAULT_NETWORK } from './payment.js';
3
+ const DEFAULT_API_URL = 'https://api.skillz.market';
4
+ /**
5
+ * Validate that a URL uses HTTPS protocol.
6
+ * Allows localhost for development purposes.
7
+ */
8
+ function validateHttpsUrl(url, paramName) {
9
+ const parsed = new URL(url);
10
+ const isLocalhost = parsed.hostname === 'localhost' || parsed.hostname === '127.0.0.1';
11
+ if (!isLocalhost && parsed.protocol !== 'https:') {
12
+ throw new Error(`${paramName} must use HTTPS protocol for security`);
13
+ }
14
+ }
15
+ export class SkillzMarket {
16
+ discovery;
17
+ apiUrl;
18
+ wallet;
19
+ walletAddress;
20
+ paymentFetch;
21
+ authToken;
22
+ constructor(options = {}) {
23
+ this.apiUrl = options.apiUrl || DEFAULT_API_URL;
24
+ // Validate HTTPS for API URL (allow localhost for development)
25
+ validateHttpsUrl(this.apiUrl, 'apiUrl');
26
+ this.discovery = new DiscoveryClient(this.apiUrl);
27
+ if (options.wallet) {
28
+ this.wallet = options.wallet;
29
+ this.walletAddress = getWalletAddress(options.wallet);
30
+ this.paymentFetch = createPaymentFetch(options.wallet, options.network || DEFAULT_NETWORK);
31
+ }
32
+ }
33
+ // Discovery methods
34
+ async search(query, filters) {
35
+ return this.discovery.search(query, filters);
36
+ }
37
+ async info(slug) {
38
+ return this.discovery.getSkill(slug);
39
+ }
40
+ async getCreator(address) {
41
+ return this.discovery.getCreator(address);
42
+ }
43
+ async getReviews(skillSlug) {
44
+ return this.discovery.getReviews(skillSlug);
45
+ }
46
+ // Execution (handles x402 payment automatically)
47
+ async call(slug, input) {
48
+ if (!this.paymentFetch || !this.wallet) {
49
+ throw new Error('Wallet required for calling paid skills');
50
+ }
51
+ const skill = await this.info(slug);
52
+ if (!skill.isActive) {
53
+ throw new Error(`Skill ${slug} is not active`);
54
+ }
55
+ const response = await this.paymentFetch(skill.endpoint, {
56
+ method: 'POST',
57
+ headers: { 'Content-Type': 'application/json' },
58
+ body: JSON.stringify(input),
59
+ });
60
+ if (!response.ok) {
61
+ throw new Error(`Skill call failed: ${response.statusText}`);
62
+ }
63
+ return response.json();
64
+ }
65
+ // Authentication
66
+ async authenticate() {
67
+ if (!this.wallet || !this.walletAddress) {
68
+ throw new Error('Wallet required for authentication');
69
+ }
70
+ const { resolveAccount } = await import('./payment.js');
71
+ const account = resolveAccount(this.wallet);
72
+ // Get challenge
73
+ const challengeRes = await fetch(`${this.apiUrl}/auth/challenge`, {
74
+ method: 'POST',
75
+ headers: { 'Content-Type': 'application/json' },
76
+ body: JSON.stringify({ address: this.walletAddress }),
77
+ });
78
+ if (!challengeRes.ok) {
79
+ throw new Error('Failed to get auth challenge');
80
+ }
81
+ const { message } = await challengeRes.json();
82
+ // Sign message using viem account
83
+ if (!account.signMessage) {
84
+ throw new Error('Account does not support message signing');
85
+ }
86
+ const signature = await account.signMessage({ message });
87
+ // Verify and get token
88
+ const verifyRes = await fetch(`${this.apiUrl}/auth/verify`, {
89
+ method: 'POST',
90
+ headers: { 'Content-Type': 'application/json' },
91
+ body: JSON.stringify({ address: this.walletAddress, signature }),
92
+ });
93
+ if (!verifyRes.ok) {
94
+ throw new Error('Authentication failed');
95
+ }
96
+ const { token } = await verifyRes.json();
97
+ this.authToken = token;
98
+ return token;
99
+ }
100
+ // Feedback
101
+ async feedback(slug, score, comment) {
102
+ if (!this.authToken) {
103
+ await this.authenticate();
104
+ }
105
+ const response = await fetch(`${this.apiUrl}/reviews`, {
106
+ method: 'POST',
107
+ headers: {
108
+ 'Content-Type': 'application/json',
109
+ 'Authorization': `Bearer ${this.authToken}`,
110
+ },
111
+ body: JSON.stringify({ skillSlug: slug, score, comment }),
112
+ });
113
+ if (!response.ok) {
114
+ throw new Error(`Failed to submit feedback: ${response.statusText}`);
115
+ }
116
+ }
117
+ }
118
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ import type { PrivateKeyAccount } from 'viem/accounts';
2
+ export interface AuthenticateOptions {
3
+ apiUrl?: string;
4
+ }
5
+ export interface AuthResult {
6
+ token: string;
7
+ refreshToken?: string;
8
+ expiresIn?: number;
9
+ }
10
+ /**
11
+ * Authenticate with the Skillz Market API using a wallet.
12
+ *
13
+ * This performs a challenge-response authentication flow:
14
+ * 1. Request a challenge message from the API
15
+ * 2. Sign the message with the wallet
16
+ * 3. Submit the signature to get a JWT token
17
+ *
18
+ * @param account - viem PrivateKeyAccount to sign with
19
+ * @param options - Authentication options
20
+ * @returns JWT token
21
+ */
22
+ export declare function authenticate(account: PrivateKeyAccount, options?: AuthenticateOptions): Promise<AuthResult>;
23
+ export interface RefreshOptions {
24
+ apiUrl?: string;
25
+ }
26
+ export interface RefreshResult {
27
+ token: string;
28
+ expiresIn: number;
29
+ }
30
+ /**
31
+ * Refresh an access token using a refresh token.
32
+ *
33
+ * Call this before the access token expires (typically 15 minutes).
34
+ * The refresh token is valid for 7 days.
35
+ *
36
+ * @param refreshToken - Refresh token from authenticate()
37
+ * @param options - Refresh options
38
+ * @returns New access token and expiration time
39
+ */
40
+ export declare function refreshAccessToken(refreshToken: string, options?: RefreshOptions): Promise<RefreshResult>;
41
+ /**
42
+ * Make an authenticated fetch request to the Skillz Market API.
43
+ *
44
+ * @param url - Full URL to fetch
45
+ * @param token - JWT token from authenticate()
46
+ * @param options - Fetch options
47
+ * @returns Fetch response
48
+ */
49
+ export declare function authenticatedFetch(url: string, token: string, options?: RequestInit): Promise<Response>;
50
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/creator/auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAIvD,MAAM,WAAW,mBAAmB;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAcD;;;;;;;;;;;GAWG;AACH,wBAAsB,YAAY,CAChC,OAAO,EAAE,iBAAiB,EAC1B,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,UAAU,CAAC,CA2DrB;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;GASG;AACH,wBAAsB,kBAAkB,CACtC,YAAY,EAAE,MAAM,EACpB,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,aAAa,CAAC,CAoBxB;AAED;;;;;;;GAOG;AACH,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,WAAgB,GACxB,OAAO,CAAC,QAAQ,CAAC,CASnB"}
@@ -0,0 +1,114 @@
1
+ const DEFAULT_API_URL = 'https://api.skillz.market';
2
+ /**
3
+ * Validate that a URL uses HTTPS protocol.
4
+ * Allows localhost for development purposes.
5
+ */
6
+ function validateHttpsUrl(url, paramName) {
7
+ const parsed = new URL(url);
8
+ const isLocalhost = parsed.hostname === 'localhost' || parsed.hostname === '127.0.0.1';
9
+ if (!isLocalhost && parsed.protocol !== 'https:') {
10
+ throw new Error(`${paramName} must use HTTPS protocol for security`);
11
+ }
12
+ }
13
+ /**
14
+ * Authenticate with the Skillz Market API using a wallet.
15
+ *
16
+ * This performs a challenge-response authentication flow:
17
+ * 1. Request a challenge message from the API
18
+ * 2. Sign the message with the wallet
19
+ * 3. Submit the signature to get a JWT token
20
+ *
21
+ * @param account - viem PrivateKeyAccount to sign with
22
+ * @param options - Authentication options
23
+ * @returns JWT token
24
+ */
25
+ export async function authenticate(account, options = {}) {
26
+ const apiUrl = options.apiUrl ?? DEFAULT_API_URL;
27
+ // Validate HTTPS for API URL (allow localhost for development)
28
+ validateHttpsUrl(apiUrl, 'apiUrl');
29
+ // Step 1: Request challenge message
30
+ const challengeResponse = await fetch(`${apiUrl}/auth/challenge`, {
31
+ method: 'POST',
32
+ headers: {
33
+ 'Content-Type': 'application/json',
34
+ },
35
+ body: JSON.stringify({
36
+ address: account.address,
37
+ }),
38
+ });
39
+ if (!challengeResponse.ok) {
40
+ const error = await challengeResponse.text();
41
+ throw new Error(`Failed to get auth challenge: ${error}`);
42
+ }
43
+ const { message } = (await challengeResponse.json());
44
+ // Step 2: Sign the message
45
+ const signature = await account.signMessage({
46
+ message,
47
+ });
48
+ // Step 3: Submit signature for JWT
49
+ const authResponse = await fetch(`${apiUrl}/auth/verify`, {
50
+ method: 'POST',
51
+ headers: {
52
+ 'Content-Type': 'application/json',
53
+ },
54
+ body: JSON.stringify({
55
+ address: account.address,
56
+ signature,
57
+ }),
58
+ });
59
+ if (!authResponse.ok) {
60
+ const error = await authResponse.text();
61
+ throw new Error(`Failed to authenticate: ${error}`);
62
+ }
63
+ const authResult = (await authResponse.json());
64
+ return {
65
+ token: authResult.token,
66
+ refreshToken: authResult.refreshToken,
67
+ expiresIn: authResult.expiresIn,
68
+ };
69
+ }
70
+ /**
71
+ * Refresh an access token using a refresh token.
72
+ *
73
+ * Call this before the access token expires (typically 15 minutes).
74
+ * The refresh token is valid for 7 days.
75
+ *
76
+ * @param refreshToken - Refresh token from authenticate()
77
+ * @param options - Refresh options
78
+ * @returns New access token and expiration time
79
+ */
80
+ export async function refreshAccessToken(refreshToken, options = {}) {
81
+ const apiUrl = options.apiUrl ?? DEFAULT_API_URL;
82
+ validateHttpsUrl(apiUrl, 'apiUrl');
83
+ const response = await fetch(`${apiUrl}/auth/refresh`, {
84
+ method: 'POST',
85
+ headers: {
86
+ 'Content-Type': 'application/json',
87
+ },
88
+ body: JSON.stringify({ refreshToken }),
89
+ });
90
+ if (!response.ok) {
91
+ const error = await response.text();
92
+ throw new Error(`Failed to refresh token: ${error}`);
93
+ }
94
+ const result = (await response.json());
95
+ return result;
96
+ }
97
+ /**
98
+ * Make an authenticated fetch request to the Skillz Market API.
99
+ *
100
+ * @param url - Full URL to fetch
101
+ * @param token - JWT token from authenticate()
102
+ * @param options - Fetch options
103
+ * @returns Fetch response
104
+ */
105
+ export async function authenticatedFetch(url, token, options = {}) {
106
+ const headers = new Headers(options.headers);
107
+ headers.set('Authorization', `Bearer ${token}`);
108
+ headers.set('Content-Type', 'application/json');
109
+ return fetch(url, {
110
+ ...options,
111
+ headers,
112
+ });
113
+ }
114
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/creator/auth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * @skillzmarket/sdk/creator - Create monetized skills with zero x402 knowledge
3
+ *
4
+ * @example
5
+ * ```typescript
6
+ * import { skill, serve } from '@skillzmarket/sdk/creator';
7
+ *
8
+ * const echo = skill({
9
+ * price: '$0.001',
10
+ * description: 'Echoes input back',
11
+ * }, async (input) => {
12
+ * return { echo: input };
13
+ * });
14
+ *
15
+ * serve({ echo });
16
+ * // Run: SKILLZ_WALLET_KEY=0x... npx tsx index.ts
17
+ * ```
18
+ */
19
+ export { skill } from './skill.js';
20
+ export { serve } from './serve.js';
21
+ export { register } from './register.js';
22
+ export { authenticate, refreshAccessToken } from './auth.js';
23
+ export type { AuthResult, RefreshResult } from './auth.js';
24
+ export type { SkillOptions, SkillHandler, SkillDefinition, SkillsMap, ServeOptions, ParsedPrice, JsonSchema, RegistrationOptions, RegistrationResult, } from './types.js';
25
+ export { parsePrice, formatPriceForX402 } from './utils/price.js';
26
+ export { resolveWallet, maskPrivateKey } from './utils/wallet.js';
27
+ //# sourceMappingURL=index.d.ts.map