npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@payxor/sdk

v0.1.2

Published

TypeScript SDK for PayXor payment and entitlement system

Downloads

8

Readme

@payxor/sdk

TypeScript SDK for integrating PayXor payments and entitlements into your application. Works with any wallet provider (wagmi, RainbowKit, web3-react, etc.) via viem.

Table of Contents

Installation

pnpm add @payxor/sdk
npm install @payxor/sdk
yarn add @payxor/sdk

Dependencies: viem Optional peer dependency: wagmi (for wallet client integration)

Quick Start

import { PayXorClient } from "@payxor/sdk";
import { maxUint256 } from "viem";

// Initialize client with wagmi wallet client
const client = new PayXorClient({
  apiUrl: "https://api.payxor.xyz",
  walletClient: yourWagmiWalletClient,
});

// 1. Get app's supported stablecoins
const stablecoins = await client.getAppSupportedStablecoins(appId, chainId);

// 2. Check balance and approval
const balance = await client.checkBalance(stablecoins[0].address, userAddress, chainId);
const needsApproval = !(await client.hasSufficientAllowance(
  stablecoins[0].address,
  userAddress,
  requiredAmount,
  chainId
));

// 3. Approve if needed
if (needsApproval) {
  await client.approveToken(stablecoins[0].address, maxUint256, userAddress, chainId);
}

// 4. Get quote and pay
const { quote, sigBackend } = await client.getQuote({
  appId,
  productId,
  chainId,
  payer: userAddress,
  tokenAddress: stablecoins[0].address,
});

const txHash = await client.pay(quote, sigBackend, userAddress, chainId);

// 5. Confirm transaction
await client.confirmTransaction(txHash, quote.quoteId);

PayXorClient

The main client class for interacting with PayXor.

Constructor

import { PayXorClient } from "@payxor/sdk";

const client = new PayXorClient({
  apiUrl: "https://api.payxor.xyz",
  walletClient: yourWagmiWalletClient,
});

Options:

| Option | Type | Default | Description | |--------|------|---------|-------------| | apiUrl | string | "http://localhost:3000" | PayXor API URL | | walletClient | WalletClient | — | Wagmi v2 wallet client (required for transactions) | | transport | Transport | — | Viem transport (alternative to walletClient) |

Note: To execute on-chain transactions (pay, approveToken), you must provide either walletClient or transport.


Core Methods

getProductInfo

Fetch public product information without creating a quote. Use for UI display and approval amount checks.

const product = await client.getProductInfo(appId, productId);

Parameters:

| Parameter | Type | Description | |-----------|------|-------------| | appId | string | App ID (hex string, e.g., "0x...") | | productId | string | Product ID (hex string) |

Returns: Promise<ProductInfo>

interface ProductInfo {
  appId: string;
  productId: string;
  name: string;
  mode: PaymentMode;
  price: string;           // Price in smallest unit (wei)
  duration: number | null; // Session duration in seconds
  entitlementId: string | null;
}

getQuote

Get a signed quote from the backend. Call this when the user is ready to purchase.

const { quote, sigBackend } = await client.getQuote({
  appId: "0x...",
  productId: "0x...",
  chainId: 8453,
  payer: "0x...",
  tokenAddress: "0x...", // Optional
});

Parameters:

| Parameter | Type | Description | |-----------|------|-------------| | appId | string | App ID (hex string) | | productId | string | Product ID (hex string) | | chainId | number | Target chain ID | | payer | string | User's wallet address | | tokenAddress | string | (Optional) Payment token address |

Returns: Promise<{ quote: Quote; sigBackend: string }>


pay

Execute the payment transaction on-chain.

const txHash = await client.pay(
  quote,
  sigBackend,
  account,
  chainId,
  contractAddress,    // Optional
  onTransactionHash   // Optional callback
);

Parameters:

| Parameter | Type | Description | |-----------|------|-------------| | quote | Quote | Quote from getQuote() | | sigBackend | string | Backend signature from getQuote() | | account | Address | User's wallet address | | chainId | number | Chain ID for the transaction | | contractAddress | Address | (Optional) PayXor contract address | | onTransactionHash | (hash: string) => void | (Optional) Callback when tx is submitted |

Returns: Promise<Hash> — Transaction hash


confirmTransaction

Confirm a transaction with the backend after payment. Updates quote status to "used".

await client.confirmTransaction(txHash, quoteId);

Parameters:

| Parameter | Type | Description | |-----------|------|-------------| | txHash | Hash | Transaction hash | | quoteId | string | Quote ID from the quote |

Returns: Promise<ConfirmTxResponse>


Entitlement Methods

isSessionActive

Check if a user has an active time-based session.

const isActive = await client.isSessionActive(
  payer,
  appId,
  productId,
  chainId,
  contractAddress, // Optional
  rpcUrl           // Optional
);

Parameters:

| Parameter | Type | Description | |-----------|------|-------------| | payer | Address | User's wallet address | | appId | string | App ID (hex string) | | productId | string | Product ID (hex string) | | chainId | number | Chain ID | | contractAddress | Address | (Optional) PayXor contract address | | rpcUrl | string | (Optional) Custom RPC URL |

Returns: Promise<boolean>


isFeatureUnlocked

Check if a user has permanently unlocked a feature.

const isUnlocked = await client.isFeatureUnlocked(
  payer,
  appId,
  entitlementId,
  chainId,
  contractAddress, // Optional
  rpcUrl           // Optional
);

Parameters:

| Parameter | Type | Description | |-----------|------|-------------| | payer | Address | User's wallet address | | appId | string | App ID (hex string) | | entitlementId | string | Entitlement ID (from product or custom) | | chainId | number | Chain ID | | contractAddress | Address | (Optional) PayXor contract address | | rpcUrl | string | (Optional) Custom RPC URL |

Returns: Promise<boolean>


hasPass

Check if a user holds a specific pass.

const hasUserPass = await client.hasPass(
  payer,
  appId,
  passId,
  chainId,
  contractAddress, // Optional
  rpcUrl           // Optional
);

Parameters:

| Parameter | Type | Description | |-----------|------|-------------| | payer | Address | User's wallet address | | appId | string | App ID (hex string) | | passId | string | Pass ID (hex string) | | chainId | number | Chain ID | | contractAddress | Address | (Optional) PayXor contract address | | rpcUrl | string | (Optional) Custom RPC URL |

Returns: Promise<boolean>


verifyReceipt

Verify a payment receipt by checking on-chain events.

const isValid = await client.verifyReceipt(
  txHash,
  expectedQuoteId,
  chainId,
  contractAddress, // Optional
  rpcUrl           // Optional
);

Returns: Promise<boolean>


Token Management

getAppSupportedStablecoins

Get the stablecoins configured for a specific app on a chain.

const stablecoins = await client.getAppSupportedStablecoins(appId, chainId);
// Returns app-specific tokens configured in the dashboard

Parameters:

| Parameter | Type | Description | |-----------|------|-------------| | appId | string | App ID (hex string) | | chainId | number | Chain ID |

Returns: Promise<StablecoinConfig[]>

interface StablecoinConfig {
  symbol: string;   // e.g., "USDC", "USDT", "DAI"
  name: string;     // e.g., "USD Coin"
  address: string;  // Token contract address
  decimals: number; // Usually 6 for USDC/USDT, 18 for DAI
}

getAvailableStablecoins

Get all PayXor-supported stablecoins for a chain (not app-specific).

const allStablecoins = client.getAvailableStablecoins(chainId);

Returns: StablecoinConfig[]


checkBalance

Check a user's token balance.

const balance = await client.checkBalance(
  tokenAddress,
  owner,
  chainId,
  rpcUrl // Optional
);

Parameters:

| Parameter | Type | Description | |-----------|------|-------------| | tokenAddress | Address | ERC20 token address | | owner | Address | Address to check | | chainId | number | Chain ID | | rpcUrl | string | (Optional) Custom RPC URL |

Returns: Promise<bigint> — Balance in smallest unit (wei)


checkAllowance

Check the current token allowance for the PayXor contract.

const allowance = await client.checkAllowance(
  tokenAddress,
  owner,
  chainId,
  contractAddress, // Optional
  rpcUrl           // Optional
);

Returns: Promise<bigint> — Allowance in smallest unit (wei)


hasSufficientAllowance

Check if allowance is sufficient for a payment amount.

const hasEnough = await client.hasSufficientAllowance(
  tokenAddress,
  owner,
  requiredAmount,
  chainId,
  contractAddress, // Optional
  rpcUrl           // Optional
);

Returns: Promise<boolean>


approveToken

Approve token spending for the PayXor contract.

import { maxUint256 } from "viem";

const txHash = await client.approveToken(
  tokenAddress,
  maxUint256,      // Or specific amount
  account,
  chainId,
  contractAddress  // Optional
);

Parameters:

| Parameter | Type | Description | |-----------|------|-------------| | tokenAddress | Address | ERC20 token address | | amount | bigint | Amount to approve (use maxUint256 for unlimited) | | account | Address | User's wallet address | | chainId | number | Chain ID | | contractAddress | Address | (Optional) PayXor contract address |

Returns: Promise<Hash> — Transaction hash

Note: Requires walletClient to be configured.


Utility Methods

formatTokenAmount

Format a token amount for display.

const displayAmount = client.formatTokenAmount(1000000n, 6);
// Returns: "1"

Parameters:

| Parameter | Type | Description | |-----------|------|-------------| | amount | bigint | Amount in smallest unit | | decimals | number | Token decimals |

Returns: string


parseTokenAmount

Parse a display amount to smallest unit.

const rawAmount = client.parseTokenAmount("100.50", 6);
// Returns: 100500000n

Parameters:

| Parameter | Type | Description | |-----------|------|-------------| | amount | string | Display amount | | decimals | number | Token decimals |

Returns: bigint


Types

The SDK exports all types from @payxor/types:

PaymentMode

enum PaymentMode {
  SESSION = 0,  // Time-based access
  FEATURE = 1,  // Permanent unlock
  RECEIPT = 2,  // One-time payment proof
  PASS = 3,     // Pass/membership
}

Quote

interface Quote {
  appId: string;         // bytes32 hex
  productId: string;     // bytes32 hex
  mode: PaymentMode;
  token: string;         // Token address
  amount: string;        // Payment amount (wei)
  payee: string;         // Recipient address
  entitlementId: string; // bytes32 hex
  duration: number;      // Session duration (seconds)
  expiresAt: number;     // Quote expiration timestamp
  quoteId: string;       // Unique quote identifier
  payer: string;         // Payer address
  deadline: number;      // Payment deadline timestamp
  chainId: number;       // Target chain ID
}

QuoteRequest

interface QuoteRequest {
  appId: string;
  productId: string;
  chainId: number;
  payer: string;
  tokenAddress?: string; // Optional token selection
}

ProductInfo

interface ProductInfo {
  appId: string;
  productId: string;
  name: string;
  mode: PaymentMode;
  price: string;
  duration: number | null;
  entitlementId: string | null;
}

StablecoinConfig

interface StablecoinConfig {
  symbol: string;   // "USDC", "USDT", "DAI", "USD1"
  name: string;     // Full name
  address: string;  // Contract address
  decimals: number; // Token decimals
}

ChainConfig

interface ChainConfig {
  chainId: number;
  name: string;
  rpcUrl?: string;
  usdcAddress: string;
  payxorContractAddress?: string;
}

Supported Chains

Mainnets

| Chain | Chain ID | Supported Stablecoins | |-------|----------|----------------------| | Ethereum | 1 | USDC, USDT, DAI, USD1 | | Arbitrum | 42161 | USDC, USDT, DAI | | Base | 8453 | USDC, USDT, DAI | | Polygon | 137 | USDC, USDC.e, USDT, DAI | | Avalanche | 43114 | USDC, USDT, DAI | | Optimism | 10 | USDC, USDT, DAI | | BNB Chain | 56 | USDC, USDT, DAI, USD1 | | zkSync | 324 | USDC, USDT, DAI |

Testnets

| Chain | Chain ID | |-------|----------| | Ethereum Sepolia | 11155111 | | Base Sepolia | 84532 | | Arbitrum Sepolia | 421614 | | Polygon Mumbai | 80001 | | Optimism Sepolia | 11155420 | | Avalanche Fuji | 43113 | | BNB Chain Testnet | 97 | | zkSync Sepolia | 300 |


Standalone Functions

The SDK also exports standalone functions for use without the client:

Chain Utilities

import {
  getViemChain,
  getPublicClient,
  getChainConfig,
} from "@payxor/sdk";

// Get viem chain configuration
const chain = getViemChain(8453); // Base

// Create a public client for reading
const publicClient = getPublicClient(8453, customRpcUrl);

// Get chain config with contract address
const config = getChainConfig(8453);

Token Utilities

import {
  getAvailableStablecoins,
  getStablecoinsForChain,
  getMockTokensForChain,
  getAllTokensForChain,
  checkBalance,
  checkAllowance,
  approveToken,
  formatTokenAmount,
  parseTokenAmount,
} from "@payxor/sdk";

Hex Utilities

import { normalizeBytes32 } from "@payxor/sdk";

// Normalize a bytes32 value (pads to 64 hex chars)
const normalized = normalizeBytes32("0x123");
// Returns: "0x0000...0123" (64 hex chars)

EIP-712 Utilities

import { getDomain, getQuoteTypedData } from "@payxor/sdk";

// Get EIP-712 domain for signing
const domain = getDomain(chainId, contractAddress);

// Get typed data for quote signing
const typedData = getQuoteTypedData(quote, chainId, contractAddress);

Chain Helper Functions

import {
  isTestnet,
  getTestnetChains,
  getMainnetChains,
  getFaucetAddress,
  getMockTokenAddress,
} from "@payxor/sdk";

isTestnet(11155111);       // true (Sepolia)
isTestnet(8453);           // false (Base mainnet)

const testnets = getTestnetChains();
const mainnets = getMainnetChains();

// For testnets with mock tokens
const faucetAddress = getFaucetAddress(11155111);
const mockUsdcAddress = getMockTokenAddress(11155111, "MockUSDC");

Examples

Complete Payment Flow with wagmi

import { PayXorClient } from "@payxor/sdk";
import { maxUint256, parseUnits } from "viem";
import { useWalletClient, useAccount, useChainId } from "wagmi";

function PaymentComponent({ appId, productId }: Props) {
  const { address } = useAccount();
  const chainId = useChainId();
  const { data: walletClient } = useWalletClient();

  const handlePayment = async () => {
    if (!walletClient || !address) return;

    const client = new PayXorClient({
      apiUrl: "https://api.payxor.xyz",
      walletClient,
    });

    // Get product info for price
    const product = await client.getProductInfo(appId, productId);

    // Get supported tokens
    const stablecoins = await client.getAppSupportedStablecoins(appId, chainId);
    const selectedToken = stablecoins[0];

    // Check balance
    const balance = await client.checkBalance(
      selectedToken.address,
      address,
      chainId
    );

    const requiredAmount = BigInt(product.price);
    if (balance < requiredAmount) {
      throw new Error("Insufficient balance");
    }

    // Check and handle approval
    const hasApproval = await client.hasSufficientAllowance(
      selectedToken.address,
      address,
      requiredAmount,
      chainId
    );

    if (!hasApproval) {
      const approveTx = await client.approveToken(
        selectedToken.address,
        maxUint256,
        address,
        chainId
      );
      // Wait for approval confirmation...
    }

    // Get quote and execute payment
    const { quote, sigBackend } = await client.getQuote({
      appId,
      productId,
      chainId,
      payer: address,
      tokenAddress: selectedToken.address,
    });

    const txHash = await client.pay(
      quote,
      sigBackend,
      address,
      chainId,
      undefined,
      (hash) => console.log("Transaction submitted:", hash)
    );

    // Confirm with backend
    await client.confirmTransaction(txHash, quote.quoteId);

    console.log("Payment complete:", txHash);
  };

  return <button onClick={handlePayment}>Pay</button>;
}

Checking Entitlements

import { PayXorClient } from "@payxor/sdk";

const client = new PayXorClient({
  apiUrl: "https://api.payxor.xyz",
});

// Check session-based access
const hasActiveSession = await client.isSessionActive(
  userAddress,
  appId,
  productId,
  chainId
);

if (hasActiveSession) {
  // Grant temporary access
}

// Check permanent feature unlock
const hasPremium = await client.isFeatureUnlocked(
  userAddress,
  appId,
  "premium-feature-id",
  chainId
);

if (hasPremium) {
  // Show premium content
}

// Check pass ownership
const hasVipPass = await client.hasPass(
  userAddress,
  appId,
  "vip-pass-id",
  chainId
);

Server-Side Receipt Verification

import { PayXorClient } from "@payxor/sdk";

const client = new PayXorClient({
  apiUrl: "https://api.payxor.xyz",
});

// Verify a payment receipt
const isValidReceipt = await client.verifyReceipt(
  txHash,
  expectedQuoteId,
  chainId
);

if (isValidReceipt) {
  // Fulfill the order
}

Multi-Chain Token Selection UI

import { PayXorClient, getMainnetChains } from "@payxor/sdk";

const client = new PayXorClient({
  apiUrl: "https://api.payxor.xyz",
  walletClient,
});

// Get all supported chains
const chains = getMainnetChains();

// For each chain, get app's supported tokens
const tokensByChain = await Promise.all(
  chains.map(async (chain) => ({
    chainId: chain.chainId,
    chainName: chain.name,
    tokens: await client.getAppSupportedStablecoins(appId, chain.chainId),
  }))
);

// Display token selector UI with chain/token options

Notes

  • Chain selection is configured during app creation in the PayXor dashboard. The SDK supports multi-chain apps by specifying chainId per method call.
  • All bytes32 values (appId, productId, entitlementId) should be hex strings. Use normalizeBytes32() to ensure proper formatting.
  • For React applications, consider using @payxor/react which provides hooks and components built on top of this SDK.