> ## Documentation Index
> Fetch the complete documentation index at: https://armory.sh/llms.txt
> Use this file to discover all available pages before exploring further.

> x402 protocol extensions

# @armory-sh/extensions

Protocol extensions for the x402 payment standard.

## Installation

```bash theme={null}
# npm
npm install @armory-sh/extensions

# yarn
yarn add @armory-sh/extensions

# pnpm
pnpm add @armory-sh/extensions

# bun
bun add @armory-sh/extensions
```

## Available Extensions

| Extension          | Purpose                                 |
| ------------------ | --------------------------------------- |
| Sign-In-With-X     | Wallet authentication for repeat access |
| Payment Identifier | Idempotency for payment requests        |
| Bazaar             | Resource discovery                      |

## API Reference

### Hook Creators (Client-Side)

Hooks allow you to automatically handle server extension requirements.

#### createSIWxHook

Creates a hook that handles Sign-In-With-X authentication:

```typescript theme={null}
import { createSIWxHook } from '@armory-sh/extensions';

const hook = createSIWxHook({
  domain: 'example.com',
  statement: 'Sign in to access premium content',
  expirationSeconds: 3600
});
```

**Config Options:**

| Option              | Type     | Description               |
| ------------------- | -------- | ------------------------- |
| `domain`            | `string` | Domain requesting sign-in |
| `statement`         | `string` | Human-readable statement  |
| `expirationSeconds` | `number` | Seconds until expiration  |

#### createPaymentIdHook

Creates a hook that adds payment idempotency:

```typescript theme={null}
import { createPaymentIdHook } from '@armory-sh/extensions';

// Auto-generate payment ID
const hook = createPaymentIdHook();

// Or specify a custom ID
const hook = createPaymentIdHook({
  paymentId: 'my-custom-id-123'
});
```

**Config Options:**

| Option      | Type     | Description               |
| ----------- | -------- | ------------------------- |
| `paymentId` | `string` | Custom payment identifier |

#### createCustomHook

Create custom extension hooks:

```typescript theme={null}
import { createCustomHook } from '@armory-sh/extensions';

const customHook = createCustomHook({
  key: 'my-extension',
  handler: async (context) => {
    // Modify the payment payload
    if (context.payload) {
      context.payload.extensions = {
        ...(context.payload.extensions ?? {}),
        'my-extension': { data: 'value' }
      };
    }
  },
  priority: 75  // Higher priority runs first
});
```

### Server Extension Declaration

For server-side middleware, declare extensions that clients should provide:

#### declareSIWxExtension

```typescript theme={null}
import { declareSIWxExtension } from '@armory-sh/extensions';

const extension = declareSIWxExtension({
  domain: 'api.example.com',
  statement: 'Sign in to access this API',
  network: 'eip155:8453',
  expirationSeconds: 3600
});
```

#### declarePaymentIdentifierExtension

```typescript theme={null}
import { declarePaymentIdentifierExtension } from '@armory-sh/extensions';

// Require payment ID from clients
const extension = declarePaymentIdentifierExtension({
  required: true
});
```

#### declareDiscoveryExtension

```typescript theme={null}
import { declareDiscoveryExtension } from '@armory-sh/extensions';

const extension = declareDiscoveryExtension({
  required: true
});
```

### Verification

Verify client-provided extension data:

#### validateSIWxMessage

```typescript theme={null}
import { validateSIWxMessage, parseSIWxHeader } from '@armory-sh/extensions';

const payload = parseSIWxHeader(header);

const result = validateSIWxMessage(
  payload,
  'https://api.example.com/resource',
  { maxAge: 3600 }
);

if (result.valid) {
  console.log('Valid SIWX message');
} else {
  console.error('Invalid:', result.error);
}
```

#### verifySIWxSignature

```typescript theme={null}
import { verifySIWxSignature } from '@armory-sh/extensions';

const result = await verifySIWxSignature(payload, {
  evmVerifier: async (message, signature, address) => {
    // Custom signature verification
    return true;
  }
});
```

### Utilities

#### generatePaymentId

Generate a random payment identifier:

```typescript theme={null}
import { generatePaymentId } from '@armory-sh/extensions';

const id = generatePaymentId();
```

#### extractExtension

Extract extension data from a payload:

```typescript theme={null}
import { extractExtension } from '@armory-sh/extensions';

const siwxData = extractExtension(payload.extensions, 'siwx');
```

### Constants

```typescript theme={null}
import {
  SIGN_IN_WITH_X,
  PAYMENT_IDENTIFIER,
  BAZAAR,
} from '@armory-sh/extensions';
```

### Types

```typescript theme={null}
import type {
  SIWxHookConfig,
  PaymentIdHookConfig,
  CustomHookConfig,
  SIWxExtensionConfig,
  PaymentIdentifierConfig,
  BazaarDiscoveryConfig,
  SIWxPayload,
  SIWxExtensionInfo,
  PaymentIdentifierExtensionInfo,
  BazaarExtensionInfo,
  Extension,
} from '@armory-sh/extensions';
```

## Exports Summary

| Export                              | Description                            |
| ----------------------------------- | -------------------------------------- |
| `createSIWxHook`                    | Hook for Sign-In-With-X                |
| `createPaymentIdHook`               | Hook for payment idempotency           |
| `createCustomHook`                  | Create custom hooks                    |
| `declareSIWxExtension`              | Declare SIWX extension for server      |
| `declarePaymentIdentifierExtension` | Declare payment ID extension           |
| `declareDiscoveryExtension`         | Declare Bazaar discovery extension     |
| `validateSIWxMessage`               | Validate SIWX payload                  |
| `verifySIWxSignature`               | Verify SIWX signature                  |
| `parseSIWxHeader`                   | Parse SIWX header                      |
| `encodeSIWxHeader`                  | Encode SIWX header                     |
| `createSIWxMessage`                 | Create SIWX message                    |
| `createSIWxPayload`                 | Create SIWX payload                    |
| `generatePaymentId`                 | Generate random payment ID             |
| `extractExtension`                  | Extract extension data                 |
| `isSIWxExtension`                   | Check if extension is SIWX             |
| `isPaymentIdentifierExtension`      | Check if extension is Payment ID       |
| `isDiscoveryExtension`              | Check if extension is Bazaar discovery |
