Skip to content
Back to skills

600 Reference 821d4a5b

ASecurity

The core package provides protocol-agnostic base classes and types.

  • 9 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added June 1, 2026
developmenttypescriptgonextjsnodeexpresstestinggitapidocumentation

Works with

  • cli
  • api

Security analysis

A100/100

Pro scans all 2 files and shows the line behind each finding

Scanned June 1, 2026

npx -y skills add tools-only/X-Skills --skill 600-reference_821d4a5b --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of 600 Reference 821d4a5b?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for 600 Reference 821d4a5b
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/tools-only-600-reference-821d4a5b/badge)](https://www.skillsdirectory.com/skills/tools-only-600-reference-821d4a5b)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
# x402-avm TypeScript Reference

## Package Ecosystem

### @x402-avm/core

The core package provides protocol-agnostic base classes and types.

**Key Exports:**

| Export | Path | Description |
|--------|------|-------------|
| `x402Client` | `@x402-avm/core/client` | Base client that handles 402 responses and payment |
| `x402ResourceServer` | `@x402-avm/core/server` | Transport-agnostic resource server |
| `x402HTTPResourceServer` | `@x402-avm/core/server` | HTTP-aware resource server with route configuration |
| `HTTPFacilitatorClient` | `@x402-avm/core/server` | HTTP client for communicating with a remote facilitator |
| `x402Facilitator` | `@x402-avm/core/facilitator` | Base facilitator for verifying and settling payments |
| `PaymentRequirements` | `@x402-avm/core/types` | Type: what payment a server accepts |
| `PaymentPayload` | `@x402-avm/core/types` | Type: what the client sends in X-PAYMENT header |
| `PaymentRequired` | `@x402-avm/core/types` | Type: 402 response body |
| `Network` | `@x402-avm/core/types` | Type: CAIP-2 network identifier string |
| `PaymentPolicy` | `@x402-avm/core/client` | Type: filter function for payment requirements |

### @x402-avm/avm

The AVM mechanism package provides Algorand-specific signer interfaces, constants, utilities, and scheme registration.

**Signer Interfaces:**

| Interface | Description |
|-----------|-------------|
| `ClientAvmSigner` | Client-side signer with `address` and `signTransactions()` |
| `FacilitatorAvmSigner` | Facilitator signer with `getAddresses()`, `signTransaction()`, `getAlgodClient()`, `simulateTransactions()`, `sendTransactions()`, `waitForConfirmation()` |

**Registration Functions (from subpaths):**

| Function | Import Path | Arguments |
|----------|-------------|-----------|
| `registerExactAvmScheme` | `@x402-avm/avm/exact/client` | `(client, { signer, algodConfig?, networks?, policies? })` |
| `registerExactAvmScheme` | `@x402-avm/avm/exact/server` | `(server, { networks? }?)` |
| `registerExactAvmScheme` | `@x402-avm/avm/exact/facilitator` | `(facilitator, { signer, networks })` |

**Constants:**

| Constant | Value | Description |
|----------|-------|-------------|
| `ALGORAND_TESTNET_CAIP2` | `"algorand:SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI="` | Testnet CAIP-2 |
| `ALGORAND_MAINNET_CAIP2` | `"algorand:wGHE2Pwdvd7S12BL5FaOP20EGYesN73ktiC1qzkkit8="` | Mainnet CAIP-2 |
| `CAIP2_NETWORKS` | Array of both | All supported CAIP-2 networks |
| `ALGORAND_TESTNET_GENESIS_HASH` | `"SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI="` | Testnet genesis hash |
| `ALGORAND_MAINNET_GENESIS_HASH` | `"wGHE2Pwdvd7S12BL5FaOP20EGYesN73ktiC1qzkkit8="` | Mainnet genesis hash |
| `V1_ALGORAND_TESTNET` | `"algorand-testnet"` | V1 testnet identifier |
| `V1_ALGORAND_MAINNET` | `"algorand-mainnet"` | V1 mainnet identifier |
| `V1_TO_CAIP2` | `Record<string, string>` | V1 to CAIP-2 mapping |
| `CAIP2_TO_V1` | `Record<string, string>` | CAIP-2 to V1 mapping |
| `USDC_TESTNET_ASA_ID` | `"10458941"` | USDC ASA ID on testnet |
| `USDC_MAINNET_ASA_ID` | `"31566704"` | USDC ASA ID on mainnet |
| `USDC_DECIMALS` | `6` | USDC decimal places |
| `USDC_CONFIG` | `Record<network, config>` | USDC config per network |
| `DEFAULT_ALGOD_TESTNET` | Env or `"https://testnet-api.algonode.cloud"` | Testnet Algod URL |
| `DEFAULT_ALGOD_MAINNET` | Env or `"https://mainnet-api.algonode.cloud"` | Mainnet Algod URL |
| `MIN_TXN_FEE` | `1000` | Minimum transaction fee (microAlgos) |
| `MAX_ATOMIC_GROUP_SIZE` | `16` | Maximum group size |
| `MAX_REASONABLE_FEE` | `10_000_000` | Fee safety cap (microAlgos) |
| `ALGORAND_ADDRESS_LENGTH` | `58` | Address character length |
| `ALGORAND_ADDRESS_REGEX` | `/^[A-Z2-7]{58}$/` | Address format regex |

**Utility Functions:**

| Function | Signature | Description |
|----------|-----------|-------------|
| `isValidAlgorandAddress` | `(addr: string) => boolean` | Full address validation (format + checksum) |
| `convertToTokenAmount` | `(amount: string, decimals: number) => string` | Decimal to atomic units |
| `convertFromTokenAmount` | `(amount: string, decimals: number) => string` | Atomic units to decimal |
| `encodeTransaction` | `(bytes: Uint8Array) => string` | Uint8Array to base64 |
| `decodeTransaction` | `(b64: string) => Uint8Array` | Base64 to Uint8Array |
| `decodeSignedTransaction` | `(b64: string) => SignedTransaction` | Decode signed txn from base64 |
| `decodeUnsignedTransaction` | `(b64: string) => Transaction` | Decode unsigned txn from base64 |
| `getNetworkFromCaip2` | `(caip2: string) => "testnet" \| "mainnet" \| null` | Extract network type |
| `isAlgorandNetwork` | `(network: string) => boolean` | Check if Algorand network |
| `isTestnetNetwork` | `(network: string) => boolean` | Check if testnet |
| `v1ToCaip2` | `(v1: string) => string` | Convert V1 to CAIP-2 |
| `caip2ToV1` | `(caip2: string) => string` | Convert CAIP-2 to V1 |
| `createAlgodClient` | `(network, url?, token?) => Algodv2` | Create Algod client |
| `getSenderFromTransaction` | `(bytes, isSigned) => string` | Extract sender address |
| `getTransactionId` | `(bytes) => string` | Get transaction ID |
| `hasSignature` | `(bytes) => boolean` | Check if transaction is signed |
| `validateGroupId` | `(txnBytes[]) => boolean` | Validate consistent group ID |
| `assignGroupId` | `(txns[]) => Transaction[]` | Assign group ID to transactions |
| `isAvmSignerWallet` | `(wallet: unknown) => wallet is ClientAvmSigner` | Type guard for ClientAvmSigner |

### @x402-avm/express

Express.js middleware for payment-gated routes.

| Export | Description |
|--------|-------------|
| `paymentMiddleware(routes, server, paywallConfig?, paywall?)` | Middleware with pre-configured x402ResourceServer |
| `paymentMiddlewareFromConfig(routes, facilitatorClient, schemes?, paywallConfig?, paywall?)` | Auto-creates server internally |
| `paymentMiddlewareFromHTTPServer(httpServer)` | Uses x402HTTPResourceServer with hooks |

### @x402-avm/hono

Hono middleware for payment-gated routes. Same API as Express but returns Hono `MiddlewareHandler`.

| Export | Description |
|--------|-------------|
| `paymentMiddleware(routes, server, paywallConfig?, paywall?)` | Middleware with pre-configured x402ResourceServer |
| `paymentMiddlewareFromConfig(routes, facilitatorClient, schemes?, paywallConfig?, paywall?, syncOnStart?)` | Auto-creates server internally |
| `paymentMiddlewareFromHTTPServer(httpServer)` | Uses x402HTTPResourceServer with hooks |

### @x402-avm/next

Next.js middleware for payment-gated routes.

### @x402-avm/fetch

Fetch API wrapper that automatically handles 402 responses.

| Export | Description |
|--------|-------------|
| `wrapFetch(client)` | Returns a fetch-like function with 402 handling |

### @x402-avm/axios

Axios interceptor that automatically handles 402 responses.

| Export | Description |
|--------|-------------|
| `wrapAxios(client)` | Returns an axios instance with 402 handling |

### @x402-avm/paywall

Browser paywall UI component shown when a user visits a protected route in a browser.

### @x402-avm/extensions

Protocol extensions (bazaar marketplace, custom schemes).

## ClientAvmSigner Interface (Detailed)

```typescript
interface ClientAvmSigner {
  /**
   * The 58-character Algorand address of the signer.
   * Used to identify which transactions belong to this signer.
   */
  address: string;

  /**
   * Sign one or more transactions from an atomic group.
   *
   * @param txns - Array of unsigned transactions as raw msgpack Uint8Array bytes.
   *               Each element is a complete unsigned transaction.
   * @param indexesToSign - Optional array of zero-based indexes indicating which
   *                        transactions this signer should sign. If not provided,
   *                        the signer should sign all transactions.
   * @returns Array of the same length as txns. Each element is either:
   *          - Uint8Array: the signed transaction bytes (for indexes that were signed)
   *          - null: for indexes that were not signed (e.g., fee payer txn)
   */
  signTransactions(
    txns: Uint8Array[],
    indexesToSign?: number[],
  ): Promise<(Uint8Array | null)[]>;
}
```

**Compatibility:** This interface matches `@txnlab/use-wallet`'s `signTransactions` function signature, allowing direct bridging from wallet to signer.

## FacilitatorAvmSigner Interface (Detailed)

```typescript
interface FacilitatorAvmSigner {
  /**
   * Get all Algorand addresses this facilitator manages.
   * These are the fee payer addresses used for fee abstraction.
   * Only transactions from these addresses will be signed by the facilitator.
   */
  getAddresses(): readonly string[];

  /**
   * Sign a single unsigned transaction.
   *
   * @param txn - Raw msgpack bytes of the unsigned transaction
   * @param senderAddress - The Algorand address of the transaction sender
   * @returns Raw msgpack bytes of the signed transaction
   */
  signTransaction(txn: Uint8Array, senderAddress: string): Promise<Uint8Array>;

  /**
   * Get an Algod client for the specified network.
   * Used for fetching transaction parameters and other on-chain queries.
   *
   * @param network - CAIP-2 network identifier
   * @returns algosdk.Algodv2 instance (typed as unknown to avoid algosdk dependency in types)
   */
  getAlgodClient(network: Network): unknown;

  /**
   * Simulate a transaction group before submission.
   * Must use allowEmptySignatures: true for unsigned fee payer transactions.
   *
   * @param txns - Array of transaction bytes (mix of signed and unsigned)
   * @param network - CAIP-2 network identifier
   * @returns Simulation result from the Algod API
   */
  simulateTransactions(txns: Uint8Array[], network: Network): Promise<unknown>;

  /**
   * Submit fully signed transactions to the Algorand network.
   * All transactions in the group must be signed at this point.
   *
   * @param signedTxns - Array of signed transaction bytes
   * @param network - CAIP-2 network identifier
   * @returns Transaction ID of the submitted group
   */
  sendTransactions(signedTxns: Uint8Array[], network: Network): Promise<string>;

  /**
   * Wait for a transaction to be confirmed on-chain.
   *
   * @param txId - Transaction ID to wait for
   * @param network - CAIP-2 network identifier
   * @param waitRounds - Number of rounds to wait (default: 4)
   * @returns Confirmation result
   */
  waitForConfirmation(
    txId: string,
    network: Network,
    waitRounds?: number,
  ): Promise<unknown>;
}
```

## Route Configuration Types

```typescript
// RoutesConfig: maps "METHOD /path" to RouteConfig
type RoutesConfig = Record<string, RouteConfig>;

interface RouteConfig {
  accepts: PaymentOption | PaymentOption[];
  resource?: string;
  description?: string;
  mimeType?: string;
  customPaywallHtml?: string;
  unpaidResponseBody?: (context: any) => { contentType: string; body: any };
  extensions?: Record<string, unknown>;
}

interface PaymentOption {
  scheme: string;          // "exact"
  payTo: string;           // Algorand address (58 chars)
  price: Price;            // "$0.01" or DynamicPrice function
  network: string;         // CAIP-2 identifier
  maxTimeoutSeconds?: number;
  extra?: Record<string, unknown>;
}
```

## Testing Notes

### Running a Local Stack

1. Start facilitator on port 4020 with `AVM_PRIVATE_KEY` env var
2. Start resource server on port 4021 with `FACILITATOR_URL=http://localhost:4020`
3. Run client with `AVM_PRIVATE_KEY` and `RESOURCE_SERVER_URL=http://localhost:4021`

### Using the Online Facilitator

Set `FACILITATOR_URL=https://facilitator.goplausible.xyz` in the resource server to avoid running a local facilitator.

### Algorand Testnet Resources

- Fund accounts: [Algorand Testnet Dispenser](https://bank.testnet.algorand.network/)
- Explorer: [Allo Explorer Testnet](https://testnet.explorer.perawallet.app/)
- Algod: `https://testnet-api.algonode.cloud`
- USDC ASA ID: `10458941`

## Design Considerations

### Why Signer Separation?

The SDK defines interfaces (`ClientAvmSigner`, `FacilitatorAvmSigner`) but never imports `algosdk`. This means:

- The SDK core has zero `algosdk` dependency
- Any wallet library can provide signers (Pera, Defly, Kibisis, etc.)
- Server-side code can use `algosdk` directly
- The `@txnlab/use-wallet` ecosystem works out of the box

### Why Raw Bytes?

The SDK passes `Uint8Array` between all methods. This:

- Matches `@txnlab/use-wallet`'s `signTransactions` signature
- Avoids double-encoding/decoding
- Keeps the protocol layer independent of `algosdk` types
- Base64 encoding only happens at the HTTP boundary (X-PAYMENT header)

### Why Unconditional Registration?

AVM scheme registration is never conditional on environment variables. This ensures:

- AVM is always available as a payment option
- No silent failures when env vars are missing
- Parity with EVM and SVM treatment

## External Resources

- [@x402-avm/core on npm](https://www.npmjs.com/package/@x402-avm/core)
- [@x402-avm/avm on npm](https://www.npmjs.com/package/@x402-avm/avm)
- [@x402-avm/express on npm](https://www.npmjs.com/package/@x402-avm/express)
- [@x402-avm/hono on npm](https://www.npmjs.com/package/@x402-avm/hono)
- [@x402-avm/next on npm](https://www.npmjs.com/package/@x402-avm/next)
- [@x402-avm/fetch on npm](https://www.npmjs.com/package/@x402-avm/fetch)
- [@x402-avm/axios on npm](https://www.npmjs.com/package/@x402-avm/axios)
- [@x402-avm/paywall on npm](https://www.npmjs.com/package/@x402-avm/paywall)
- [@x402-avm/extensions on npm](https://www.npmjs.com/package/@x402-avm/extensions)
- [GoPlausible x402-avm Examples](https://github.com/GoPlausible/x402-avm/tree/branch-v2-algorand-publish/examples/)
- [GoPlausible x402-avm Documentation](https://github.com/GoPlausible/.github/blob/main/profile/algorand-x402-documentation/)
- [@txnlab/use-wallet](https://github.com/TxnLab/use-wallet)
- [algosdk TypeScript](https://github.com/algorand/js-algorand-sdk)

Files in this skill

  • README.md959 B
  • skill.md13.7 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.