@x402/extensions 2.1.0 → 2.3.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 (33) hide show
  1. package/README.md +324 -95
  2. package/dist/cjs/bazaar/index.d.ts +3 -547
  3. package/dist/cjs/bazaar/index.js +26 -3
  4. package/dist/cjs/bazaar/index.js.map +1 -1
  5. package/dist/cjs/index-DvDlinmy.d.ts +575 -0
  6. package/dist/cjs/index.d.ts +4 -1
  7. package/dist/cjs/index.js +1022 -5
  8. package/dist/cjs/index.js.map +1 -1
  9. package/dist/cjs/payment-identifier/index.d.ts +345 -0
  10. package/dist/cjs/payment-identifier/index.js +285 -0
  11. package/dist/cjs/payment-identifier/index.js.map +1 -0
  12. package/dist/cjs/sign-in-with-x/index.d.ts +1054 -1
  13. package/dist/cjs/sign-in-with-x/index.js +766 -0
  14. package/dist/cjs/sign-in-with-x/index.js.map +1 -1
  15. package/dist/esm/bazaar/index.d.mts +3 -547
  16. package/dist/esm/bazaar/index.mjs +1 -1
  17. package/dist/esm/chunk-73HCOE6N.mjs +233 -0
  18. package/dist/esm/chunk-73HCOE6N.mjs.map +1 -0
  19. package/dist/esm/{chunk-STXY3Q5R.mjs → chunk-DFJ4ZQFO.mjs} +27 -4
  20. package/dist/esm/chunk-DFJ4ZQFO.mjs.map +1 -0
  21. package/dist/esm/chunk-E3F2XHTI.mjs +719 -0
  22. package/dist/esm/chunk-E3F2XHTI.mjs.map +1 -0
  23. package/dist/esm/index-DvDlinmy.d.mts +575 -0
  24. package/dist/esm/index.d.mts +4 -1
  25. package/dist/esm/index.mjs +102 -3
  26. package/dist/esm/payment-identifier/index.d.mts +345 -0
  27. package/dist/esm/payment-identifier/index.mjs +39 -0
  28. package/dist/esm/sign-in-with-x/index.d.mts +1054 -1
  29. package/dist/esm/sign-in-with-x/index.mjs +66 -1
  30. package/package.json +16 -2
  31. package/dist/esm/chunk-MKFJ5AA3.mjs +0 -1
  32. package/dist/esm/chunk-STXY3Q5R.mjs.map +0 -1
  33. /package/dist/esm/{chunk-MKFJ5AA3.mjs.map → payment-identifier/index.mjs.map} +0 -0
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @x402/extensions
2
2
 
3
- x402 Payment Protocol Extensions. This package provides optional extensions that enhance the x402 payment protocol with additional functionality like resource discovery and cataloging.
3
+ x402 Payment Protocol Extensions. This package provides optional extensions that enhance the x402 payment protocol with additional functionality.
4
4
 
5
5
  ## Installation
6
6
 
@@ -10,10 +10,11 @@ pnpm install @x402/extensions
10
10
 
11
11
  ## Overview
12
12
 
13
- Extensions are optional features that can be added to x402 payment flows. They allow servers to provide additional metadata and enable facilitators to offer enhanced services like resource discovery and cataloging.
13
+ Extensions are optional features that can be added to x402 payment flows. They follow a standardized `{ info, schema }` structure and are included in `PaymentRequired.extensions` and `PaymentPayload.extensions`.
14
14
 
15
- Currently, this package includes:
16
- - **Bazaar Discovery Extension**: Enables automatic cataloging and indexing of x402-enabled resources
15
+ This package includes:
16
+ - **Bazaar Discovery**: Automatic cataloging and indexing of x402-enabled resources
17
+ - **Sign-In-With-X (SIWx)**: CAIP-122 wallet authentication for accessing previously purchased resources
17
18
 
18
19
  ## Bazaar Discovery Extension
19
20
 
@@ -39,29 +40,29 @@ import { declareDiscoveryExtension } from "@x402/extensions/bazaar";
39
40
 
40
41
  const resources = {
41
42
  "GET /weather": {
42
- accepts: {
43
- scheme: "exact",
44
- price: "$0.001",
45
- network: "eip155:84532",
46
- payTo: "0xYourAddress"
43
+ accepts: {
44
+ scheme: "exact",
45
+ price: "$0.001",
46
+ network: "eip155:84532",
47
+ payTo: "0xYourAddress"
47
48
  },
48
49
  extensions: {
49
50
  ...declareDiscoveryExtension({
50
51
  input: { city: "San Francisco" },
51
52
  inputSchema: {
52
- properties: {
53
+ properties: {
53
54
  city: { type: "string" },
54
55
  units: { type: "string", enum: ["celsius", "fahrenheit"] }
55
56
  },
56
57
  required: ["city"]
57
58
  },
58
- output: {
59
- example: {
60
- city: "San Francisco",
59
+ output: {
60
+ example: {
61
+ city: "San Francisco",
61
62
  weather: "foggy",
62
63
  temperature: 15,
63
64
  humidity: 85
64
- }
65
+ }
65
66
  },
66
67
  }),
67
68
  },
@@ -78,15 +79,15 @@ import { declareDiscoveryExtension } from "@x402/extensions/bazaar";
78
79
 
79
80
  const resources = {
80
81
  "POST /api/translate": {
81
- accepts: {
82
- scheme: "exact",
83
- price: "$0.01",
84
- network: "eip155:84532",
85
- payTo: "0xYourAddress"
82
+ accepts: {
83
+ scheme: "exact",
84
+ price: "$0.01",
85
+ network: "eip155:84532",
86
+ payTo: "0xYourAddress"
86
87
  },
87
88
  extensions: {
88
89
  ...declareDiscoveryExtension({
89
- input: {
90
+ input: {
90
91
  text: "Hello, world!",
91
92
  targetLanguage: "es"
92
93
  },
@@ -116,15 +117,15 @@ const resources = {
116
117
  ```typescript
117
118
  const resources = {
118
119
  "PUT /api/user/profile": {
119
- accepts: {
120
- scheme: "exact",
121
- price: "$0.05",
122
- network: "eip155:84532",
123
- payTo: "0xYourAddress"
120
+ accepts: {
121
+ scheme: "exact",
122
+ price: "$0.05",
123
+ network: "eip155:84532",
124
+ payTo: "0xYourAddress"
124
125
  },
125
126
  extensions: {
126
127
  ...declareDiscoveryExtension({
127
- input: {
128
+ input: {
128
129
  name: "John Doe",
129
130
  email: "john@example.com",
130
131
  bio: "Software developer"
@@ -156,11 +157,11 @@ const resources = {
156
157
  ```typescript
157
158
  const resources = {
158
159
  "DELETE /api/data/:id": {
159
- accepts: {
160
- scheme: "exact",
161
- price: "$0.001",
162
- network: "eip155:84532",
163
- payTo: "0xYourAddress"
160
+ accepts: {
161
+ scheme: "exact",
162
+ price: "$0.001",
163
+ network: "eip155:84532",
164
+ payTo: "0xYourAddress"
164
165
  },
165
166
  extensions: {
166
167
  ...declareDiscoveryExtension({
@@ -269,17 +270,17 @@ import { validateDiscoveryExtension, extractDiscoveryInfo } from "@x402/extensio
269
270
 
270
271
  function processPayment(paymentPayload: PaymentPayload, paymentRequirements: PaymentRequirements) {
271
272
  const discovered = extractDiscoveryInfo(paymentPayload, paymentRequirements);
272
-
273
+
273
274
  if (discovered && paymentPayload.extensions?.bazaar) {
274
275
  // Validate the extension schema
275
276
  const validation = validateDiscoveryExtension(paymentPayload.extensions.bazaar);
276
-
277
+
277
278
  if (!validation.valid) {
278
279
  console.warn("Invalid discovery extension:", validation.errors);
279
280
  // Handle invalid extension (log, reject, etc.)
280
281
  return;
281
282
  }
282
-
283
+
283
284
  // Extension is valid, proceed with cataloging
284
285
  catalogResource(discovered);
285
286
  }
@@ -297,19 +298,19 @@ import { x402ResourceServer } from "@x402/core/server";
297
298
  // The extension helper automatically extracts discovery info
298
299
  const resourceServer = new x402ResourceServer(facilitatorClient)
299
300
  .register("eip155:84532", new ExactEvmScheme())
300
- .useExtension(bazaarResourceServerExtension);
301
+ .registerExtension(bazaarResourceServerExtension);
301
302
  ```
302
303
 
303
- ## API Reference
304
+ ### Bazaar API Reference
304
305
 
305
- ### `declareDiscoveryExtension(config)`
306
+ #### `declareDiscoveryExtension(config)`
306
307
 
307
308
  Creates a discovery extension object for resource servers.
308
309
 
309
310
  **Parameters:**
310
311
  - `config.input` (optional): Example input values (query params for GET/HEAD/DELETE, body for POST/PUT/PATCH)
311
312
  - `config.inputSchema` (optional): JSON Schema for input validation
312
- - `config.bodyType` (optional): For POST/PUT/PATCH, specify `"json"`, `"form-data"`, or `"text"` (default: `"json"`)
313
+ - `config.bodyType` (required for body methods): For POST/PUT/PATCH, specify `"json"`, `"form-data"`, or `"text"`. This is how TypeScript discriminates between query methods (GET/HEAD/DELETE) and body methods.
313
314
  - `config.output` (optional): Output specification
314
315
  - `output.example`: Example output data
315
316
  - `output.schema`: JSON Schema for output validation
@@ -333,7 +334,7 @@ const extension = declareDiscoveryExtension({
333
334
  // Returns: { bazaar: { info: {...}, schema: {...} } }
334
335
  ```
335
336
 
336
- ### `extractDiscoveryInfo(paymentPayload, paymentRequirements, validate?)`
337
+ #### `extractDiscoveryInfo(paymentPayload, paymentRequirements, validate?)`
337
338
 
338
339
  Extracts discovery information from a payment request (for facilitators).
339
340
 
@@ -353,88 +354,314 @@ interface DiscoveredResource {
353
354
  }
354
355
  ```
355
356
 
356
- **Example:**
357
+ #### `validateDiscoveryExtension(extension)`
358
+
359
+ Validates a discovery extension's info against its schema.
360
+
361
+ **Returns:** `{ valid: boolean, errors?: string[] }`
362
+
363
+ #### `validateAndExtract(extension)`
364
+
365
+ Validates and extracts discovery info in one step.
366
+
367
+ **Returns:** `{ valid: boolean, info?: DiscoveryInfo, errors?: string[] }`
368
+
369
+ #### `bazaarResourceServerExtension`
370
+
371
+ A server extension that automatically enriches discovery extensions with HTTP method information from the request context.
372
+
373
+ **Usage:**
357
374
  ```typescript
358
- const info = extractDiscoveryInfo(paymentPayload, paymentRequirements);
359
- if (info) {
360
- console.log(info.resourceUrl); // "https://api.example.com/endpoint"
361
- console.log(info.method); // "GET"
362
- console.log(info.discoveryInfo); // { input: {...}, output: {...} }
363
- }
375
+ import { bazaarResourceServerExtension } from "@x402/extensions/bazaar";
376
+
377
+ const resourceServer = new x402ResourceServer(facilitatorClient)
378
+ .registerExtension(bazaarResourceServerExtension);
364
379
  ```
365
380
 
366
- ### `validateDiscoveryExtension(extension)`
381
+ ### `BAZAAR`
367
382
 
368
- Validates a discovery extension's info against its schema.
383
+ The extension identifier constant (`"bazaar"`).
369
384
 
370
- **Parameters:**
371
- - `extension`: A discovery extension object
385
+ ## Sign-In-With-X Extension
372
386
 
373
- **Returns:** `{ valid: boolean, errors?: string[] }`
387
+ The Sign-In-With-X extension implements [CAIP-122](https://chainagnostic.org/CAIPs/caip-122) for chain-agnostic wallet authentication. It allows clients to prove control of a wallet that previously paid for a resource, enabling access without repurchase.
388
+
389
+ ### How It Works
390
+
391
+ 1. Server returns 402 with `sign-in-with-x` extension containing challenge parameters
392
+ 2. Client signs the CAIP-122 message with their wallet
393
+ 3. Client sends signed proof in `SIGN-IN-WITH-X` header
394
+ 4. Server verifies signature and grants access if wallet has previous payment
395
+
396
+ ### Server Usage
397
+
398
+ #### Recommended: Hooks (Automatic)
374
399
 
375
- **Example:**
376
400
  ```typescript
377
- const result = validateDiscoveryExtension(extension);
378
- if (!result.valid) {
379
- console.error("Validation errors:", result.errors);
401
+ import {
402
+ declareSIWxExtension,
403
+ siwxResourceServerExtension,
404
+ createSIWxSettleHook,
405
+ createSIWxRequestHook,
406
+ InMemorySIWxStorage,
407
+ } from '@x402/extensions/sign-in-with-x';
408
+
409
+ // Storage for tracking paid addresses
410
+ const storage = new InMemorySIWxStorage();
411
+
412
+ // 1. Register extension for time-based field refreshment
413
+ const resourceServer = new x402ResourceServer(facilitatorClient)
414
+ .register(NETWORK, new ExactEvmScheme())
415
+ .registerExtension(siwxResourceServerExtension) // Refreshes nonce/timestamps per request
416
+ .onAfterSettle(createSIWxSettleHook({ storage })); // Records payments
417
+
418
+ // 2. Declare SIWX support in routes (network/domain/uri derived automatically)
419
+ const routes = {
420
+ "GET /data": {
421
+ accepts: [{scheme: "exact", price: "$0.01", network: "eip155:8453", payTo}],
422
+ extensions: declareSIWxExtension({
423
+ statement: 'Sign in to access your purchased content',
424
+ }),
425
+ },
426
+ };
427
+
428
+ // 3. Verify incoming SIWX proofs
429
+ const httpServer = new x402HTTPResourceServer(resourceServer, routes)
430
+ .onProtectedRequest(createSIWxRequestHook({ storage })); // Grants access if paid
431
+
432
+ // Optional: Enable smart wallet support (EIP-1271/EIP-6492)
433
+ import { createPublicClient, http } from 'viem';
434
+ import { base } from 'viem/chains';
435
+
436
+ const publicClient = createPublicClient({ chain: base, transport: http() });
437
+ const httpServerWithSmartWallets = new x402HTTPResourceServer(resourceServer, routes)
438
+ .onProtectedRequest(createSIWxRequestHook({
439
+ storage,
440
+ verifyOptions: { evmVerifier: publicClient.verifyMessage },
441
+ }));
442
+ ```
443
+
444
+ The hooks automatically:
445
+ - **siwxResourceServerExtension**: Derives `network` from `accepts`, `domain`/`uri` from request URL, refreshes `nonce`/`issuedAt`/`expirationTime` per request
446
+ - **createSIWxSettleHook**: Records payment when settlement succeeds
447
+ - **createSIWxRequestHook**: Validates and verifies SIWX proofs, grants access if wallet has paid
448
+
449
+ #### Manual Usage (Advanced)
450
+
451
+ ```typescript
452
+ import {
453
+ declareSIWxExtension,
454
+ parseSIWxHeader,
455
+ validateSIWxMessage,
456
+ verifySIWxSignature,
457
+ SIGN_IN_WITH_X,
458
+ } from '@x402/extensions/sign-in-with-x';
459
+
460
+ // 1. Declare in PaymentRequired response
461
+ const extensions = {
462
+ [SIGN_IN_WITH_X]: declareSIWxExtension({
463
+ domain: 'api.example.com',
464
+ resourceUri: 'https://api.example.com/data',
465
+ network: 'eip155:8453',
466
+ statement: 'Sign in to access your purchased content',
467
+ }),
468
+ };
469
+
470
+ // 2. Verify incoming proof
471
+ async function handleRequest(request: Request) {
472
+ const header = request.headers.get('SIGN-IN-WITH-X');
473
+ if (!header) return; // No auth provided
474
+
475
+ // Parse the header
476
+ const payload = parseSIWxHeader(header);
477
+
478
+ // Validate message fields (expiry, nonce, domain, etc.)
479
+ const validation = await validateSIWxMessage(
480
+ payload,
481
+ 'https://api.example.com/data'
482
+ );
483
+ if (!validation.valid) {
484
+ return { error: validation.error };
485
+ }
486
+
487
+ // Verify signature and recover address
488
+ const verification = await verifySIWxSignature(payload);
489
+ if (!verification.valid) {
490
+ return { error: verification.error };
491
+ }
492
+
493
+ // verification.address is the verified wallet
494
+ // Check if this wallet has paid before
495
+ const hasPaid = await checkPaymentHistory(verification.address);
496
+ if (hasPaid) {
497
+ // Grant access without payment
498
+ }
380
499
  }
381
500
  ```
382
501
 
383
- ### `validateAndExtract(extension)`
502
+ ### Client Usage
384
503
 
385
- Validates and extracts discovery info in one step.
504
+ #### Recommended: Client Hook (Automatic)
386
505
 
387
- **Parameters:**
388
- - `extension`: A discovery extension object
506
+ ```typescript
507
+ import { createSIWxClientHook } from '@x402/extensions/sign-in-with-x';
508
+ import { x402HTTPClient } from '@x402/fetch';
389
509
 
390
- **Returns:** `{ valid: boolean, info?: DiscoveryInfo, errors?: string[] }`
510
+ // Configure client with SIWX hook - automatically tries SIWX auth before payment
511
+ const httpClient = new x402HTTPClient(client)
512
+ .onPaymentRequired(createSIWxClientHook(signer));
513
+
514
+ // Requests automatically use SIWX auth when server supports it
515
+ const response = await httpClient.fetch(url);
516
+ ```
517
+
518
+ The client hook automatically:
519
+ - Detects SIWX support in 402 responses
520
+ - Matches your wallet's chain with server's `supportedChains`
521
+ - Signs and sends the authentication proof
522
+ - Falls back to payment if SIWX auth fails
523
+
524
+ #### Manual Usage (Advanced)
391
525
 
392
- **Example:**
393
526
  ```typescript
394
- const { valid, info, errors } = validateAndExtract(extension);
395
- if (valid && info) {
396
- // Use info
527
+ import {
528
+ createSIWxPayload,
529
+ encodeSIWxHeader,
530
+ } from '@x402/extensions/sign-in-with-x';
531
+
532
+ // 1. Get extension and network from 402 response
533
+ const paymentRequired = await response.json();
534
+ const extension = paymentRequired.extensions['sign-in-with-x'];
535
+ const paymentNetwork = paymentRequired.accepts[0].network; // e.g., "eip155:8453"
536
+
537
+ // 2. Find matching chain in supportedChains
538
+ const matchingChain = extension.supportedChains.find(
539
+ chain => chain.chainId === paymentNetwork
540
+ );
541
+
542
+ if (!matchingChain) {
543
+ // Payment network not supported for SIWX
544
+ throw new Error('Chain not supported');
397
545
  }
546
+
547
+ // 3. Build complete info with selected chain
548
+ const completeInfo = {
549
+ ...extension.info,
550
+ chainId: matchingChain.chainId,
551
+ type: matchingChain.type,
552
+ };
553
+
554
+ // 4. Create signed payload
555
+ const payload = await createSIWxPayload(completeInfo, signer);
556
+
557
+ // 5. Encode and send
558
+ const header = encodeSIWxHeader(payload);
559
+ const response = await fetch(url, {
560
+ headers: { 'SIGN-IN-WITH-X': header }
561
+ });
398
562
  ```
399
563
 
400
- ### `bazaarResourceServerExtension`
564
+ ### SIWx API Reference
401
565
 
402
- A server extension that automatically enriches discovery extensions with HTTP method information from the request context.
566
+ #### `declareSIWxExtension(options?)`
567
+
568
+ Creates the extension object for servers to include in PaymentRequired. Most fields are derived automatically from request context when using `siwxResourceServerExtension`.
403
569
 
404
- **Usage:**
405
570
  ```typescript
406
- import { bazaarResourceServerExtension } from "@x402/extensions/bazaar";
571
+ declareSIWxExtension({
572
+ // All fields optional - derived from context if omitted
573
+ domain?: string; // Server domain (derived from request URL)
574
+ resourceUri?: string; // Full resource URI (derived from request URL)
575
+ network?: string | string[]; // CAIP-2 network(s) (derived from accepts[].network)
576
+ statement?: string; // Human-readable purpose
577
+ version?: string; // CAIP-122 version (default: "1")
578
+ expirationSeconds?: number; // Challenge TTL in seconds
579
+ })
580
+ ```
407
581
 
408
- const resourceServer = new x402ResourceServer(facilitatorClient)
409
- .useExtension(bazaarResourceServerExtension);
582
+ **Automatic derivation:** When using `siwxResourceServerExtension`, omitted fields are derived:
583
+ - `network` → from `accepts[].network` in route config
584
+ - `resourceUri` → from request URL
585
+ - `domain` → parsed from resourceUri
586
+
587
+ **Multi-chain support:** When `network` is an array (or multiple networks in `accepts`), `supportedChains` will contain one entry per network.
588
+
589
+ #### `parseSIWxHeader(header)`
590
+
591
+ Parses a base64-encoded SIGN-IN-WITH-X header into a payload object.
592
+
593
+ #### `validateSIWxMessage(payload, resourceUri, options?)`
594
+
595
+ Validates message fields (expiry, domain binding, nonce, etc.).
596
+
597
+ ```typescript
598
+ validateSIWxMessage(payload, resourceUri, {
599
+ maxAge?: number; // Max age for issuedAt (default: 5 min)
600
+ checkNonce?: (nonce) => boolean; // Custom nonce validation
601
+ })
602
+ // Returns: { valid: boolean; error?: string }
410
603
  ```
411
604
 
412
- ### `BAZAAR`
605
+ #### `verifySIWxSignature(payload, options?)`
413
606
 
414
- The extension identifier constant (`"bazaar"`).
607
+ Verifies the cryptographic signature and recovers the signer address.
415
608
 
416
609
  ```typescript
417
- import { BAZAAR } from "@x402/extensions/bazaar";
418
- // BAZAAR === "bazaar"
610
+ verifySIWxSignature(payload, {
611
+ evmVerifier?: EVMMessageVerifier; // For smart wallet support
612
+ })
613
+ // Returns: { valid: boolean; address?: string; error?: string }
419
614
  ```
420
615
 
421
- ## Use Cases
616
+ **Smart Wallet Support (EIP-1271 / EIP-6492):**
617
+
618
+ By default, only EOA (Externally Owned Account) signatures are verified. To support smart contract wallets (like Coinbase Smart Wallet, Safe, etc.), pass `publicClient.verifyMessage` from viem:
619
+
620
+ ```typescript
621
+ import { createPublicClient, http } from 'viem';
622
+ import { base } from 'viem/chains';
623
+
624
+ const publicClient = createPublicClient({
625
+ chain: base,
626
+ transport: http()
627
+ });
628
+
629
+ // In your request hook
630
+ const result = await verifySIWxSignature(payload, {
631
+ evmVerifier: publicClient.verifyMessage,
632
+ });
633
+ ```
634
+
635
+ This enables:
636
+ - **EIP-1271**: Verification of deployed smart contract wallets
637
+ - **EIP-6492**: Verification of counterfactual (not-yet-deployed) wallets
638
+
639
+ Note: Smart wallet verification requires RPC calls, while EOA verification is purely local.
640
+
641
+ #### `createSIWxPayload(serverInfo, signer)`
642
+
643
+ Client helper that creates and signs a complete payload.
644
+
645
+ #### `encodeSIWxHeader(payload)`
646
+
647
+ Encodes a payload as base64 for the SIGN-IN-WITH-X header.
422
648
 
423
- ### 1. API Marketplace Discovery
424
- Enable users to discover paid APIs through facilitator catalogs. Servers declare their endpoints, and facilitators index them for easy discovery.
649
+ #### `SIGN_IN_WITH_X`
425
650
 
426
- ### 2. Developer Tools
427
- Build tools that automatically generate API documentation or client SDKs from discovery metadata.
651
+ Extension identifier constant (`"sign-in-with-x"`).
428
652
 
429
- ### 3. Resource Cataloging
430
- Facilitators can maintain catalogs of available paid resources, making it easier for users to find services.
653
+ ### Supported Signature Schemes
431
654
 
432
- ### 4. Testing and Validation
433
- Use discovery schemas to validate API requests and responses during development.
655
+ | Scheme | Description |
656
+ |--------|-------------|
657
+ | `eip191` | personal_sign (default for EVM EOAs) |
658
+ | `eip1271` | Smart contract wallet verification |
659
+ | `eip6492` | Counterfactual smart wallet verification |
660
+ | `siws` | Sign-In-With-Solana |
434
661
 
435
662
  ## Troubleshooting
436
663
 
437
- ### Extension Not Being Extracted
664
+ ### Bazaar Extension Not Being Extracted
438
665
 
439
666
  **Problem:** `extractDiscoveryInfo` returns `null`.
440
667
 
@@ -443,7 +670,7 @@ Use discovery schemas to validate API requests and responses during development.
443
670
  - Check that `paymentPayload.extensions.bazaar` exists
444
671
  - Verify you're using x402 v2 (v1 uses a different format in `outputSchema`)
445
672
 
446
- ### Schema Validation Fails
673
+ ### Bazaar Schema Validation Fails
447
674
 
448
675
  **Problem:** `validateDiscoveryExtension` returns `valid: false`.
449
676
 
@@ -452,27 +679,29 @@ Use discovery schemas to validate API requests and responses during development.
452
679
  - Check that required fields are marked in `inputSchema.required`
453
680
  - Verify JSON Schema syntax is correct
454
681
 
455
- ### Missing Discovery Info
682
+ ### SIWx Signature Verification Fails
456
683
 
457
- **Problem:** Discovery info is incomplete.
684
+ **Problem:** `verifySIWxSignature` returns `valid: false`.
458
685
 
459
686
  **Solutions:**
460
- - Ensure both `input` and `inputSchema` are provided
461
- - For POST/PUT/PATCH, include `bodyType` in the config
462
- - Check that `output.example` is provided if you want output documentation
687
+ - Ensure the message was signed with the correct wallet
688
+ - Check that the signature scheme matches the wallet type
689
+ - For smart wallets, enable `checkSmartWallet` option with a provider
463
690
 
464
- ### Method Not Being Detected
691
+ ### SIWx Message Validation Fails
465
692
 
466
- **Problem:** The HTTP method is missing from discovery info.
693
+ **Problem:** `validateSIWxMessage` returns `valid: false`.
467
694
 
468
695
  **Solutions:**
469
- - Use `bazaarResourceServerExtension` which automatically injects the method
470
- - Ensure the route key follows the format `"METHOD /path"` (e.g., `"GET /weather"`)
696
+ - Check that `issuedAt` is recent (within `maxAge`, default 5 minutes)
697
+ - Verify `expirationTime` hasn't passed
698
+ - Ensure `domain` matches the server's domain
699
+ - Confirm `uri` matches the resource URI
471
700
 
472
701
  ## Related Resources
473
702
 
474
703
  - [x402 Core Package](../core/README.md) - Core x402 protocol implementation
475
- - [x402 Specification](../../../specs/x402-specification.md) - Full protocol specification
704
+ - [CAIP-122 Specification](https://chainagnostic.org/CAIPs/caip-122) - Sign-In-With-X standard
476
705
 
477
706
  ## Version Support
478
707