Quickstart Guide

Get started with Blocky402 in minutes. This guide walks you through making your first payment using the facilitator API. The wire format is x402 v2.

Prerequisites

  • Node.js 18+ or Python 3.8+
  • A wallet with testnet tokens (for testnet)
  • Basic understanding of HTTP APIs

Step 1: Choose Your Environment

Blocky402 currently supports testnet with open access (no API key required). Mainnet support is coming soon.

Testnet Base URL: http://localhost:3002 (local) or https://api.testnet.blocky402.com (hosted)

Step 2: Check Supported Networks

# Using cURL
curl http://localhost:3002/supported
// Using Node.js
const response = await fetch('http://localhost:3002/supported');
const data = await response.json();
console.log('Supported networks:', data.kinds);
# Using Python
import requests
 
networks = requests.get('http://localhost:3002/supported').json()
print('Supported networks:', networks['kinds'])

Response:

{
  "kinds": [
    { "scheme": "exact", "network": "eip155:80002", "x402Version": 2 },
    {
      "scheme": "exact",
      "network": "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1",
      "x402Version": 2,
      "extra": { "feePayer": "7B6Q2MvcJvNcy1A13wHmAzmmdo3L8DVriaXML7bvkojm" }
    },
    {
      "scheme": "exact",
      "network": "hedera:testnet",
      "x402Version": 2,
      "extra": { "feePayer": "0.0.7162784" }
    }
  ],
  "extensions": [],
  "signers": {
    "eip155:*": ["0xDCF7D72C2eE049DE4269ac6AAf925F33efdA18de"],
    "solana:*": ["7B6Q2MvcJvNcy1A13wHmAzmmdo3L8DVriaXML7bvkojm"],
    "hedera:*": ["0.0.7162784"]
  }
}

Step 3: Install the x402 Hedera client SDK

npm install @x402/hedera

Other families have their own SDKs: @x402/evm for any eip155:* chain and @x402/svm for Solana. This guide uses Hedera throughout.

Step 4: Sign a v2 PaymentPayload

The Hedera client builds and partially signs a TransferTransaction for the payer. The facilitator co-signs as fee-payer at settlement time, so requirements.extra.feePayer is required and must match the fee-payer the facilitator advertises in GET /supported (signers["hedera:*"][0]).

// Node.js example (Hedera, exact scheme)
import { ExactHederaScheme } from '@x402/hedera/exact/client';
import { createClientHederaSigner, PrivateKey } from '@x402/hedera';
 
const paymentRequirements = {
  scheme: 'exact',
  network: 'hedera:testnet',
  amount: '100000',              // 100,000 tinybars = 0.001 HBAR
  payTo: '0.0.8011510',
  maxTimeoutSeconds: 300,
  asset: '0.0.0',                // HBAR (use a token id for HTS payments)
  extra: { feePayer: '0.0.7162784' },
};
 
const signer = createClientHederaSigner(
  '0.0.7326075',                                       // payer account id
  PrivateKey.fromStringECDSA('0xYourHederaPrivateKey'),
  { network: 'hedera:testnet' },
);
 
const scheme = new ExactHederaScheme(signer);
const signed = await scheme.createPaymentPayload(2, paymentRequirements);
 
const paymentPayload = {
  x402Version: 2,
  scheme: 'exact',
  network: 'hedera:testnet',
  accepted: paymentRequirements,
  payload: signed.payload,       // { transaction: 'base64-encoded-TransferTransaction' }
};

Step 5: Verify the Payment

// Node.js
const verifyResponse = await fetch('http://localhost:3002/verify', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    x402Version: 2,
    paymentPayload,
    paymentRequirements,
  }),
});
 
const verification = await verifyResponse.json();
console.log('Valid:', verification.isValid, '| Payer:', verification.payer);

Step 6: Settle the Payment

// Node.js
const settleResponse = await fetch('http://localhost:3002/settle', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    x402Version: 2,
    paymentPayload,
    paymentRequirements,
  }),
});
 
const settlement = await settleResponse.json();
console.log('Transaction:', settlement.transaction, '| Network:', settlement.network);

Step 7: Use the Payment Proof

Once settled, present the paymentPayload as the X-PAYMENT header (base64-encoded JSON, per the x402 transport spec):

const xPayment = Buffer.from(JSON.stringify(paymentPayload)).toString('base64');
 
const apiResponse = await fetch('https://api.example.com/data', {
  headers: { 'X-PAYMENT': xPayment },
});
 
const data = await apiResponse.json();
console.log('Data:', data);

Complete Example

import { ExactHederaScheme } from '@x402/hedera/exact/client';
import { createClientHederaSigner, PrivateKey } from '@x402/hedera';
 
const API_BASE = 'http://localhost:3002';
 
async function makePaidRequest() {
  // 1. Discover supported networks + the facilitator's Hedera fee-payer
  const supported = await fetch(`${API_BASE}/supported`).then((r) => r.json());
  const hederaKind = supported.kinds.find((k) => k.network === 'hedera:testnet');
  if (!hederaKind) throw new Error('Facilitator does not advertise hedera:testnet');
  const feePayer = hederaKind.extra?.feePayer ?? supported.signers?.['hedera:*']?.[0];
 
  // 2. Build requirements + sign payload
  const paymentRequirements = {
    scheme: 'exact',
    network: 'hedera:testnet',
    amount: '100000',
    payTo: '0.0.8011510',
    maxTimeoutSeconds: 300,
    asset: '0.0.0',
    extra: { feePayer },
  };
 
  const signer = createClientHederaSigner(
    '0.0.7326075',
    PrivateKey.fromStringECDSA('0xYourHederaPrivateKey'),
    { network: 'hedera:testnet' },
  );
  const scheme = new ExactHederaScheme(signer);
  const signed = await scheme.createPaymentPayload(2, paymentRequirements);
 
  const paymentPayload = {
    x402Version: 2,
    scheme: 'exact',
    network: 'hedera:testnet',
    accepted: paymentRequirements,
    payload: signed.payload,
  };
 
  const body = { x402Version: 2, paymentPayload, paymentRequirements };
 
  // 3. Verify
  const verify = await fetch(`${API_BASE}/verify`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(body),
  }).then((r) => r.json());
  if (!verify.isValid) {
    throw new Error(`Payment verification failed: ${verify.invalidMessage ?? verify.invalidReason}`);
  }
 
  // 4. Settle
  const settle = await fetch(`${API_BASE}/settle`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(body),
  }).then((r) => r.json());
  if (!settle.success) {
    throw new Error(`Settlement failed: ${settle.errorMessage ?? settle.errorReason}`);
  }
  console.log('Settled:', settle.transaction);
 
  // 5. Use payment proof on the resource server
  const xPayment = Buffer.from(JSON.stringify(paymentPayload)).toString('base64');
  return fetch('https://api.example.com/data', {
    headers: { 'X-PAYMENT': xPayment },
  }).then((r) => r.json());
}

Next Steps

Need Help?