askill
x402-tip

x402-tipSafety 75Repository

Create non-custodial USDC tip claim pages using x402. Use when someone asks to tip a person, create a tip link, send money via a claim page, or build a tip jar. Generates a funded burner wallet, builds a claim page, and uploads it — all gasless via x402facilitator.dev.

0 stars
1.2k downloads
Updated 2/15/2026

Package Files

Loading files...
SKILL.md

x402 Tip Claim Page

Create a non-custodial USDC tip page: generate a burner wallet, fund it, build an HTML claim page, upload to agentupload.dev. The recipient claims gaslessly via x402facilitator.dev — no gas ETH needed, no backend, one static HTML file.

Prerequisites

  • @x402/core, @x402/evm, viem, ethers installed in /tmp/node_modules
  • A funded facilitator account on x402facilitator.dev (Craig's: cddea943-c042-4546-9111-8900b4968319)
  • Craig's x402 wallet (via mcporter) for funding the burner

Architecture

The x402 protocol uses EIP-3009 transferWithAuthorization for gasless USDC transfers. A facilitator submits the signed authorization on-chain and pays gas via Coinbase CDP. The tip page embeds a burner private key and signs the transfer in the browser.

[Burner Wallet] --signs transferWithAuthorization--> [Facilitator] --submits on-chain via CDP--> [Recipient gets USDC]

The facilitator settle endpoint has CORS enabled (PR #8 on x402facilitator), so browsers can call it directly.

Step-by-Step Flow

1. Generate a burner wallet

const { ethers } = require('ethers');
const wallet = ethers.Wallet.createRandom();
// Save: wallet.address and wallet.privateKey

2. Fund the burner via x402scan

NODE_OPTIONS="--max-old-space-size=128" mcporter call x402 fetch \
  url="https://www.x402scan.com/api/send?address=BURNER_ADDRESS&amount=AMOUNT&chain=base" \
  method=POST body='{}'

This uses Craig's x402 wallet to pay x402scan, which transfers USDC to the burner.

3. Build the claim page

The HTML page must:

  1. Import x402 libraries via esm.sh:

    import { x402Client, x402HTTPClient } from 'https://esm.sh/@x402/core@2.3.1/client';
    import { registerExactEvmScheme } from 'https://esm.sh/@x402/evm@2.3.1/exact/client';
    import { privateKeyToAccount } from 'https://esm.sh/viem@2.21.26/accounts';
    import { isAddress } from 'https://esm.sh/viem@2.21.26';
    
  2. Set up the x402 client with the burner PK as signer:

    const account = privateKeyToAccount(BURNER_PK);
    const client = new x402Client();
    registerExactEvmScheme(client, { signer: account });
    const httpClient = new x402HTTPClient(client);
    
  3. Claim flow (when user enters their address):

    // Step 1: Get 402 challenge from x402scan
    const res = await fetch(
      `https://www.x402scan.com/api/send?address=${recipientAddress}&amount=${amount}&chain=base`,
      { method: 'POST' }
    );
    // res.status === 402
    
    // Step 2: Parse and sign the x402 payment
    const paymentRequired = httpClient.getPaymentRequiredResponse(
      (name) => res.headers.get(name)
    );
    const paymentPayload = await httpClient.createPaymentPayload(paymentRequired);
    const requirements = paymentRequired.accepts[0]; // Select EVM/Base
    
    // Step 3: Settle via facilitator (gasless!)
    const settleRes = await fetch(`${FACILITATOR_URL}/settle`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        x402Version: paymentPayload.x402Version,
        paymentPayload,
        paymentRequirements: requirements,
      }),
    });
    const data = await settleRes.json();
    // data.success === true, data.transaction === "0x..."
    
  4. Check if already claimed on page load:

    // Read USDC balance of burner via viem
    const bal = await publicClient.readContract({
      address: USDC_ADDRESS, // 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913
      abi: [balanceOf ABI],
      functionName: 'balanceOf',
      args: [BURNER_ADDRESS],
    });
    if (bal === 0n) { /* show "already claimed" state */ }
    
  5. Offer two claim methods:

    • Connect Wallet (window.ethereum) — for users with browser wallets
    • Paste address — for anyone with a Base wallet address

4. Upload to agentupload.dev

NODE_OPTIONS="--max-old-space-size=128" mcporter call x402 fetch \
  url="https://agentupload.dev/api/x402/upload" method=POST \
  body='{"filename":"tip.html","contentType":"text/html","tier":"10mb"}'
# Returns uploadUrl and publicUrl
curl -X PUT "$uploadUrl" -H "Content-Type: text/html" --data-binary @/tmp/tip.html

5. Send the link to the recipient

Via x402email, Discord message, or any other channel.

Key Constants

ConstantValue
USDC on Base0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913
Base chain IDeip155:8453
x402scan sendhttps://www.x402scan.com/api/send
Facilitator URLhttps://x402facilitator.dev/api/facilitator/v2/cddea943-c042-4546-9111-8900b4968319
Facilitator settle cost$0.01 per claim
x402scan send costequal to amount sent

Cost Breakdown Per Tip

ItemCost
Fund burner (x402scan send)$TIP_AMOUNT (passed through)
Facilitator settle$0.01
agentupload hosting$0.01
Total overhead$0.02 + tip amount

Design Notes

  • Follow the frontend-design skill for page styling — NO generic AI aesthetics
  • Each tip page should feel unique and contextual (music tips get music emoji, food tips get food, etc.)
  • Include confetti or celebration animation on successful claim
  • Always show a BaseScan link after claim so the recipient can verify on-chain
  • Include a "What is this?" explainer for non-crypto users pointing to Coinbase Wallet

Testing

Test the flow from Node.js before deploying (simulates what the browser does):

// Same flow as above but in Node instead of browser
// Verify: 402 challenge → sign → settle → success === true

Always send a test claim to Craig's own wallet first (0x6B173bf632a7Ee9151e94E10585BdecCd47bDAAf) before giving the link to anyone.

Facilitator Management

Craig's facilitator account was created with a $2.50 deposit. Each settle costs $0.01, so that's 250 claims before needing a top-up. Check balance:

# SIWX-authenticated — use the siwx_poll.cjs pattern
# Or just count: facilitator started with $2.50, each settle is $0.01

To deposit more:

NODE_OPTIONS="--max-old-space-size=128" mcporter call x402 fetch \
  url="https://x402facilitator.dev/api/deposit?amount=5" method=POST \
  body='{"walletAddress":"0x6B173bf632a7Ee9151e94E10585BdecCd47bDAAf","notificationEmail":"craig@craig.x402email.com"}'

What NOT to Do

  • ❌ Don't try direct on-chain USDC transfer (burner has no ETH for gas)
  • ❌ Don't use x402scan /api/send from the browser (CORS blocked, and adding CORS there is a security risk)
  • ❌ Don't expose Craig's main wallet PK in any page — only burner PKs
  • ❌ Don't embed the facilitator API key in any non-tip context

Install

Download ZIP
Requires askill CLI v1.0+

AI Quality Score

82/100Analyzed 2/19/2026

High-quality technical skill for creating x402-based tip pages. Well-structured with clear steps, code examples, constants, and safety warnings. Contains specific personal references (Craig's accounts) and credentials which reduce reusability but are necessary for the specific use case. Bonus for dedicated skills folder and structured approach. Minor deduction for internal-only signals in content."

75
90
65
85
90

Metadata

Licenseunknown
Version-
Updated2/15/2026
PublisherMerit-Systems

Tags

apici-cdsecuritytesting