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

@qilinxlabs/a2a-cronos-x402

v0.1.0

Published

TypeScript SDK for x402 protocol contract interactions on Cronos networks

Readme

a2a-cronos-x402

TypeScript SDK for x402 protocol contract interactions on Cronos networks.

Overview

This library provides a clean implementation of the x402 protocol for contract-based services on Cronos. It enables:

  • Server developers to register x402 service contracts (NFT Mint, Reward Points, Transfer/Split)
  • Client applications to discover services and execute transactions via EIP-712 signed authorizations

Features

  • 🔐 EIP-712 typed data signing for secure transactions
  • 🔍 Service discovery via .well-known/agent.json
  • 📦 Three hook types: NFT Mint, Reward Points, Transfer/Split
  • ⛓️ Cronos mainnet and testnet support
  • 🛡️ Comprehensive error handling

Installation

pnpm add @qilinxlabs/a2a-cronos-x402
# or
npm install @qilinxlabs/a2a-cronos-x402

Quick Start

Server Setup

import express from 'express';
import { createX402Server, type X402ServiceConfig } from '@qilinxlabs/a2a-cronos-x402';

const server = createX402Server({
  name: 'My X402 Services',
  description: 'x402 protocol services on Cronos',
  url: 'http://localhost:8787',
  network: 'cronos-testnet',
});

// Register NFT Mint service
await server.addService({
  id: 'nft-mint',
  title: 'NFT Mint Service',
  description: 'Mint a random NFT by paying with USDC',
  hookType: 'nft-mint',
  hookAddress: '0xf2A8921EEAda2734FeAbB9EC1d73fC5771B4Ec5B',
  network: 'cronos-testnet',
  supportingContracts: {
    nftContract: '0xA8633f571c51ad0EA7b3c51EC930Ee51fF8F0551',
  },
  defaults: {
    paymentAmount: '0.1',
    facilitatorFee: '0',
    payTo: '0xYourMerchantAddress',
  },
});

// Register Reward Points service
await server.addService({
  id: 'reward-points',
  title: 'Reward Points Service',
  description: 'Earn reward points by making a payment',
  hookType: 'reward-points',
  hookAddress: '0xaF49Bd5164D530aC5127d364F6ce4e079741950b',
  network: 'cronos-testnet',
  supportingContracts: {
    rewardToken: '0xF7A17B7EA6EBB661A88B45035D58f0699C7b9d31',
  },
  defaults: {
    paymentAmount: '0.1',
    facilitatorFee: '0',
    payTo: '0xYourMerchantAddress',
  },
});

// Register Transfer/Split service
await server.addService({
  id: 'transfer-split',
  title: 'Transfer/Split Payment Service',
  description: 'Transfer or split payments between multiple recipients',
  hookType: 'transfer-split',
  hookAddress: '0xC94ebf218bb67d6FF5599B5a6457Ad5E70E0db8D',
  network: 'cronos-testnet',
  defaults: {
    paymentAmount: '0.1',
    facilitatorFee: '0',
    payTo: '0xYourMerchantAddress',
  },
});

// Mount Express middleware
const app = express();
app.use(express.json());
const router = express.Router();
server.expressMiddleware(router);
app.use(router);
app.listen(8787);

Client Usage

import { createX402Client } from '@qilinxlabs/a2a-cronos-x402';
import { ethers } from 'ethers';

const client = createX402Client({
  network: 'cronos-testnet',
});

// Discover services from server
const discovered = await client.discover('http://localhost:8787');
console.log('Services:', discovered.services);

// Select a service
const service = discovered.services.find(s => s.hookType === 'nft-mint');

// Prepare transaction
const prepared = await client.prepareTransaction({
  service,
  payerAddress: '0xPayerAddress',
  payTo: '0xMerchantAddress',
  paymentAmount: '0.1',
  hookDataParams: {
    type: 'nft-mint',
    nftContract: '0xA8633f571c51ad0EA7b3c51EC930Ee51fF8F0551',
  },
});

// Sign with ethers wallet
const wallet = new ethers.Wallet(privateKey);
const { domain, types, message } = prepared.typedData;
const signature = await wallet.signTypedData(
  { name: domain.name, version: domain.version, chainId: domain.chainId, verifyingContract: domain.verifyingContract },
  { TransferWithAuthorization: types.TransferWithAuthorization },
  message
);

// Submit transaction
const result = await client.submitTransaction(prepared, signature, facilitatorPrivateKey);
console.log('Transaction hash:', result.txHash);

Hook Types

| Hook Type | Description | hookData Format | |-----------|-------------|-----------------| | nft-mint | Mint NFT after payment | tuple(address nftContract) | | reward-points | Distribute loyalty points | tuple(address rewardToken) | | transfer-split | Split payment between recipients | tuple(address recipient, uint16 bips)[] |

Transfer/Split Hook Data

For simple transfers, use empty hookData (0x). For split payments:

// Split 50/50 between two recipients
const hookData = client.encodeHookData({
  type: 'transfer-split',
  splits: [
    { recipient: '0xRecipient1', bips: 5000 }, // 50%
    { recipient: '0xRecipient2', bips: 5000 }, // 50%
  ],
});

Note: bips (basis points) must sum to 10000 (100%).

API Reference

X402Server

import { createX402Server, X402Server } from '@qilinxlabs/a2a-cronos-x402';

interface X402ServerConfig {
  name: string;
  description?: string;
  url: string;
  network: 'cronos' | 'cronos-testnet';
  rpcUrl?: string;
}

// Methods
server.addService(config: X402ServiceConfig): Promise<void>
server.getService(id: string): X402Service | undefined
server.listServices(): X402Service[]
server.getAgentCard(): AgentCard
server.expressMiddleware(router: Router): Router

X402Client

import { createX402Client, X402Client } from '@qilinxlabs/a2a-cronos-x402';

interface X402ClientConfig {
  network: 'cronos' | 'cronos-testnet';
  rpcUrl?: string;
}

// Methods
client.discover(serverUrl: string): Promise<DiscoveredServices>
client.discoverAll(serverUrls: string[]): Promise<DiscoveredServices[]>
client.prepareTransaction(params: TransactionParams): Promise<PreparedTransaction>
client.submitTransaction(prepared, signature, signerPrivateKey): Promise<TransactionResult>
client.validateSignature(signature: string): boolean
client.encodeHookData(params: HookDataParams): string

Server Endpoints

| Endpoint | Description | |----------|-------------| | GET /.well-known/agent.json | Agent card with all services | | GET /api/x402/services | List all registered services | | GET /api/x402/services/:id | Get service details with hookData schema |

Deployed Contracts (Cronos Testnet)

const TESTNET_CONTRACTS = {
  // Infrastructure
  settlementRouter: '0x80e941858065dfD4875030A7a30DfbfeE8c7742a',
  devUSDC: '0xc01efAaF7C5C61bEbFAeb358E1161b537b8bC0e0',
  
  // NFT Mint Hook
  nftMintHook: '0xf2A8921EEAda2734FeAbB9EC1d73fC5771B4Ec5B',
  randomNFT: '0xA8633f571c51ad0EA7b3c51EC930Ee51fF8F0551',
  
  // Reward Points Hook
  rewardHook: '0xaF49Bd5164D530aC5127d364F6ce4e079741950b',
  rewardToken: '0xF7A17B7EA6EBB661A88B45035D58f0699C7b9d31',
  
  // Transfer/Split Hook
  transferHook: '0xC94ebf218bb67d6FF5599B5a6457Ad5E70E0db8D',
};

Error Handling

import {
  X402Error,
  ContractNotFoundError,
  SignatureError,
  TransactionError,
  NetworkError,
  ConfigurationError,
} from '@qilinxlabs/a2a-cronos-x402';

try {
  await server.addService(config);
} catch (error) {
  if (error instanceof ContractNotFoundError) {
    console.log('Hook contract not found:', error.address);
  } else if (error instanceof ConfigurationError) {
    console.log('Missing fields:', error.missingFields);
  } else if (error instanceof TransactionError) {
    console.log('Transaction failed:', error.revertReason);
  }
}

Network Configuration

The library automatically configures RPC URLs and contract addresses for each network:

| Network | Chain ID | USDC Address | |---------|----------|--------------| | cronos | 25 | 0xc21223249CA28397B4B6541dfFaEcC539BfF0c59 | | cronos-testnet | 338 | 0xc01efAaF7C5C61bEbFAeb358E1161b537b8bC0e0 |

You can override the RPC URL:

const server = createX402Server({
  network: 'cronos-testnet',
  rpcUrl: 'https://your-custom-rpc.com',
});

License

MIT