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

# Quickstart Guide

The quickest path to a working h402 integration is a thin gateway that sits in front of your HTTP service. This guide shows how to implement both client and server components using the `@bit-gpt/h402` package.

## Client and Server quickstart

<Steps>
  <Step title="Installation">
    ```bash theme={"system"}
    npm install @bit-gpt/h402
    ```
  </Step>

  <Step title="Server implementation (to h402 gate your resources)">
    <CardGroup cols={2}>
      <Card title="Express code" icon="js" href="https://github.com/bit-gpt/h402/blob/main/examples/typescript/servers/express/README.md" arrow="true">
        Explore the Express server implementation for h402 integration.
      </Card>

      <Card title="All examples" icon="github" href="https://github.com/bit-gpt/h402/blob/main/examples" arrow="true">
        Browse all h402 integration examples available in our repository.
      </Card>
    </CardGroup>

    <CodeGroup>
      ```typescript Server.ts expandable wrap focus={3,20-58} theme={"system"}
      import { config } from "dotenv";
      import express from "express";
      import { paymentMiddleware, Resource, createRouteConfigFromPrice, Network } from "h402-express";

      config();

      const facilitatorUrl = process.env.FACILITATOR_URL as Resource;
      const payTo = process.env.ADDRESS as `0x${string}`;
      const network = process.env.NETWORK as Network;

      if (!facilitatorUrl || !payTo || !network) {
        console.error("Missing required environment variables");
        process.exit(1);
      }

      const app = express();

      console.log("Server is running");

      app.use(
        paymentMiddleware(
          payTo,
          {
            // Use createRouteConfigFromPrice to construct the RouteConfig
            "/weather": createRouteConfigFromPrice("$0.001", network),
            // Example of advanced configuration with multiple payment options
            "/premium/*": {
              paymentRequirements: [
                {
                  scheme: "exact",
                  namespace: "evm",
                  tokenAddress: "0x55d398326f99059ff775485246999027b3197955", // USDT on BSC
                  amountRequired: 0.01,
                  amountRequiredFormat: "humanReadable",
                  networkId: "56",
                  payToAddress: payTo,
                  description: "Premium content access with USDT on BSC",
                  tokenDecimals: 18,
                },
                {
                  scheme: "exact",
                  namespace: "solana",
                  tokenAddress: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", // USDC on Solana
                  amountRequired: 0.01,
                  amountRequiredFormat: "humanReadable",
                  networkId: "mainnet",
                  payToAddress: "9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM", // Example Solana address
                  description: "Premium content access with USDC on Solana",
                  tokenDecimals: 6,
                },
              ],
            },
          },
          {
            url: facilitatorUrl,
          },
        ),
      );

      app.get("/weather", (req, res) => {
        res.send({
          report: {
            weather: "sunny",
            temperature: 70,
          },
        });
      });

      app.get("/premium/content", (req, res) => {
        res.send({
          content: "This is premium content accessible via multiple payment methods",
          supportedPayments: ["USDT on BSC", "USDC on Solana"],
        });
      });

      app.listen(4021, () => {
        console.log(`Server listening at http://localhost:${4021}`);
      });
      ```
    </CodeGroup>
  </Step>

  <Step title="Client implementation (to interact with h402-gated servers)">
    <CardGroup cols={2}>
      <Card title="Axios client code" icon="js" href="https://github.com/bit-gpt/h402/blob/main/examples/typescript/clients/axios/README.md" arrow="true">
        Discover how to implement the Axios client for h402 integration.
      </Card>

      <Card title="All examples" icon="github" href="https://github.com/bit-gpt/h402/blob/main/examples" arrow="true">
        Browse all h402 integration examples available in our repository.
      </Card>
    </CardGroup>

    ```typescript Client.ts expandable wrap theme={"system"}
    import axios from "axios";
    import { config } from "dotenv";
    import { createWalletClient, http, publicActions, type Hex } from "viem";
    import { withPaymentInterceptor, decodeXPaymentResponse } from "h402-axios";
    import { Keypair } from "@solana/web3.js";
    import bs58 from "bs58";
    import { createKeyPairSignerFromBytes } from "@solana/signers";
    import type { TransactionModifyingSigner } from "@solana/signers";
    import type { Transaction } from "@solana/transactions";
    import { privateKeyToAccount } from "viem/accounts";
    import { bsc } from "viem/chains";

    config();

    const evmPrivateKey = process.env.EVM_PRIVATE_KEY as Hex;
    const solanaPrivateKey = process.env.SOLANA_PRIVATE_KEY as Hex;
    const baseURL = process.env.RESOURCE_SERVER_URL as string; // e.g. http://localhost:3000
    const endpointPath = process.env.ENDPOINT_PATH as string; // e.g. /image

    if (!baseURL || !evmPrivateKey || !endpointPath) {
      console.error("Missing required environment variables");
      process.exit(1);
    }

    // EVM client
    const evmAccount = privateKeyToAccount(evmPrivateKey);
    const evmClient = createWalletClient({
      account: evmAccount,
      transport: http(),
      chain: bsc,
    }).extend(publicActions);

    // Solana client
    const solanaKeypair = Keypair.fromSecretKey(bs58.decode(solanaPrivateKey));
    const solanaClient = {
      publicKey: solanaKeypair.publicKey.toBase58(),
      signTransaction: async <T extends Transaction>(
        transactions: readonly T[],
      ): Promise<readonly T[]> => {
        const signer = await createKeyPairSignerFromBytes(solanaKeypair.secretKey);
        const signatures = await signer.signTransactions(transactions);
        const modifiedTransactions = transactions.map((transaction, index) => {
          const signature = signatures[index];
          if (!signature || Object.keys(signature).length === 0) {
            throw new Error(`Failed to sign transaction at index ${index}`);
          }
          return {
            ...transaction,
            signatures: {
              ...transaction.signatures,
              ...signature,
            },
          } as T;
        });
        return modifiedTransactions;
      },
    } satisfies {
      publicKey: string;
      signTransaction: TransactionModifyingSigner["modifyAndSignTransactions"];
    };

    // Create the API client with payment interceptor
    // If multiple clients are provided, the payment interceptor will use the first one that is available according to payment requirements
    // You can comment out the evmClient to test the solana client
    const api = withPaymentInterceptor(
      axios.create({
        baseURL,
      }),
      {
        evmClient,
        solanaClient,
      },
    );

    api
      .get(endpointPath)
      .then(response => {
        console.log(response.data);

        const paymentResponse = decodeXPaymentResponse(response.headers["x-payment-response"]);
        console.log(paymentResponse);
      })
      .catch(error => {
        console.error("example axios error", error);
      });
    ```
  </Step>
</Steps>

## Key Points

* The resource server remains completely stateless - all necessary information is encoded in the payment header
* No hidden session state or database required
* Payment verification is deterministic and based on cryptographic proofs
* The same pattern works for any HTTP service, from API endpoints to static files
* Support for multiple payment networks through the same interface

For production deployments, consider:

* Adding proper error handling
* Implementing retry logic
* Setting up monitoring and logging
* Using a production-grade facilitator (or use ours `https://facilitator.bitgpt.xyz/`)
