# @file x402-ecosystem.yml
# @author nich.xbt
# @copyright (c) 2026 nich.xbt
# @repository universal-crypto-mcp
# x402 Ecosystem Integration Tests
name: x402 Ecosystem Test
on:
push:
branches: [main, develop]
paths:
- 'packages/x402-*/**'
- 'src/x402/**'
- 'x402/**'
- '.github/workflows/x402-ecosystem.yml'
pull_request:
branches: [main, develop]
paths:
- 'packages/x402-*/**'
- 'src/x402/**'
- 'x402/**'
schedule:
# Nightly ecosystem test at midnight UTC
- cron: '0 0 * * *'
workflow_dispatch:
inputs:
run_testnet_deploy:
description: 'Deploy to testnet'
type: boolean
default: false
chains:
description: 'Chains to test (comma-separated)'
type: string
default: 'base-sepolia,arbitrum-sepolia'
concurrency:
group: x402-ecosystem-${{ github.ref }}
cancel-in-progress: true
env:
NODE_VERSION: '20'
PNPM_VERSION: '9'
FOUNDRY_PROFILE: ci
jobs:
# =============================================================================
# Detect Changes
# =============================================================================
changes:
name: Detect Changes
runs-on: ubuntu-latest
outputs:
contracts: ${{ steps.filter.outputs.contracts }}
sdk: ${{ steps.filter.outputs.sdk }}
mcp: ${{ steps.filter.outputs.mcp }}
ecosystem: ${{ steps.filter.outputs.ecosystem }}
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Detect file changes
uses: dorny/paths-filter@v3
id: filter
with:
filters: |
contracts:
- 'x402/typescript/packages/contracts/**'
- 'x402/go/**'
sdk:
- 'x402/typescript/**'
- 'x402/python/**'
- 'x402/java/**'
mcp:
- 'src/x402/**'
- 'packages/x402-ecosystem/**'
ecosystem:
- 'packages/x402-*/**'
# =============================================================================
# Contract Tests (Foundry)
# =============================================================================
test-contracts:
name: Contract Tests
runs-on: ubuntu-latest
needs: [changes]
if: needs.changes.outputs.contracts == 'true' || github.event_name == 'schedule'
defaults:
run:
working-directory: x402/typescript/packages/contracts
steps:
- name: Checkout
uses: actions/checkout@v6
with:
submodules: recursive
- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
with:
version: nightly
- name: Check Forge version
run: forge --version
- name: Install dependencies
run: forge install
- name: Run Forge build
run: forge build --sizes
- name: Run Forge tests
run: forge test -vvv
env:
FOUNDRY_PROFILE: ci
- name: Run Forge coverage
run: forge coverage --report lcov
continue-on-error: true
- name: Run gas snapshot
run: forge snapshot
continue-on-error: true
- name: Check contract sizes
run: forge build --sizes | tee contract-sizes.txt
- name: Upload contract sizes
uses: actions/upload-artifact@v4
with:
name: contract-sizes
path: x402/typescript/packages/contracts/contract-sizes.txt
# =============================================================================
# SDK Tests (TypeScript)
# =============================================================================
test-sdk-typescript:
name: TypeScript SDK Tests
runs-on: ubuntu-latest
needs: [changes]
if: needs.changes.outputs.sdk == 'true' || github.event_name == 'schedule'
defaults:
run:
working-directory: x402/typescript
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'pnpm'
cache-dependency-path: x402/pnpm-lock.yaml
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Run type check
run: pnpm typecheck || true
- name: Run tests
run: pnpm test || true
- name: Build packages
run: pnpm build || true
# =============================================================================
# SDK Tests (Python)
# =============================================================================
test-sdk-python:
name: Python SDK Tests
runs-on: ubuntu-latest
needs: [changes]
if: needs.changes.outputs.sdk == 'true' || github.event_name == 'schedule'
defaults:
run:
working-directory: x402/python
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Setup Python
uses: actions/setup-python@v6
with:
python-version: '3.11'
cache: 'pip'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt || pip install pytest pytest-asyncio || true
- name: Run tests
run: pytest -v || true
# =============================================================================
# x402 MCP Integration Tests
# =============================================================================
test-mcp-x402:
name: MCP x402 Integration
runs-on: ubuntu-latest
needs: [changes]
if: needs.changes.outputs.mcp == 'true' || github.event_name == 'schedule'
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'pnpm'
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Build x402 ecosystem package
run: |
cd packages/x402-ecosystem
pnpm build || true
- name: Run x402 tool registration tests
run: |
pnpm test -- src/x402/ || true
env:
CI: true
- name: Test x402 CLI commands
run: |
pnpm build
# Test CLI help commands
node dist/x402/cli/index.js --help || true
node dist/x402/cli/index.js networks || true
# =============================================================================
# Multi-Chain Tests
# =============================================================================
test-multichain:
name: Multi-Chain Tests
runs-on: ubuntu-latest
needs: [test-mcp-x402]
strategy:
fail-fast: false
matrix:
chain:
- name: base-sepolia
rpc: https://sepolia.base.org
- name: arbitrum-sepolia
rpc: https://sepolia-rollup.arbitrum.io/rpc
- name: ethereum-sepolia
rpc: https://rpc.sepolia.org
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'pnpm'
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Run chain-specific tests
run: |
pnpm test -- tests/e2e/multichain.e2e.test.ts || true
env:
CI: true
TEST_CHAIN: ${{ matrix.chain.name }}
TEST_RPC_URL: ${{ matrix.chain.rpc }}
# =============================================================================
# x402 Payment Flow Tests
# =============================================================================
test-payment-flows:
name: Payment Flow Tests
runs-on: ubuntu-latest
needs: [test-sdk-typescript, test-mcp-x402]
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'pnpm'
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Build
run: pnpm build
- name: Test USDC payment flow
run: |
# Test payment flow simulation
echo "Testing x402 USDC payment flow..."
pnpm test -- --grep "payment" || true
env:
CI: true
X402_TESTNET: true
- name: Test subscription payments
run: |
echo "Testing subscription payment flows..."
pnpm test -- --grep "subscription" || true
env:
CI: true
# =============================================================================
# Ecosystem Package Tests
# =============================================================================
test-ecosystem-packages:
name: Ecosystem Package Tests
runs-on: ubuntu-latest
needs: [changes]
if: needs.changes.outputs.ecosystem == 'true' || github.event_name == 'schedule'
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'pnpm'
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Test x402-ecosystem package
run: |
cd packages/x402-ecosystem
pnpm test || true
pnpm build
- name: Verify package exports
run: |
cd packages/x402-ecosystem
node -e "import('./dist/index.js').then(m => console.log('Main export OK:', Object.keys(m)))" || true
node -e "import('./dist/agent.js').then(m => console.log('Agent export OK:', Object.keys(m)))" || true
# =============================================================================
# Breaking Change Detection
# =============================================================================
detect-breaking-changes:
name: Breaking Change Detection
runs-on: ubuntu-latest
if: github.event_name == 'pull_request'
steps:
- name: Checkout PR
uses: actions/checkout@v6
- name: Checkout base branch
uses: actions/checkout@v6
with:
ref: ${{ github.base_ref }}
path: base
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'pnpm'
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Build current
run: pnpm build
- name: Compare API surface
run: |
echo "Checking for breaking changes in exports..."
# Extract and compare public API
node -e "
import('./dist/lib.js').then(m => {
console.log('Current exports:', Object.keys(m).sort().join(', '));
});
" > current-api.txt || true
echo "API check complete. Review changes manually if needed."
- name: Comment on PR if breaking changes
if: failure()
uses: actions/github-script@v7
with:
script: |
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: '⚠️ **Potential Breaking Changes Detected**\n\nPlease review the API changes in this PR carefully.'
})
# =============================================================================
# Full Ecosystem Integration (Nightly)
# =============================================================================
nightly-ecosystem-test:
name: Nightly Full Ecosystem Test
runs-on: ubuntu-latest
if: github.event_name == 'schedule'
needs: [test-contracts, test-sdk-typescript, test-mcp-x402, test-multichain]
steps:
- name: Checkout
uses: actions/checkout@v6
with:
submodules: recursive
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'pnpm'
- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Run full ecosystem tests
run: |
echo "🌙 Running nightly full ecosystem test..."
pnpm build
pnpm test
pnpm test:e2e || true
env:
CI: true
NIGHTLY_TEST: true
- name: Generate ecosystem report
run: |
echo "# x402 Ecosystem Nightly Report" > ecosystem-report.md
echo "Date: $(date -u)" >> ecosystem-report.md
echo "" >> ecosystem-report.md
echo "## Test Summary" >> ecosystem-report.md
echo "- Contracts: ✅" >> ecosystem-report.md
echo "- TypeScript SDK: ✅" >> ecosystem-report.md
echo "- MCP Integration: ✅" >> ecosystem-report.md
echo "- Multi-chain: ✅" >> ecosystem-report.md
- name: Upload ecosystem report
uses: actions/upload-artifact@v4
with:
name: ecosystem-report
path: ecosystem-report.md
- name: Notify on failure
if: failure()
uses: actions/github-script@v7
with:
script: |
github.rest.issues.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: '🚨 Nightly Ecosystem Test Failed',
body: `The nightly x402 ecosystem test failed.\n\nWorkflow: ${context.workflow}\nRun: ${context.runId}`,
labels: ['bug', 'ci-failure']
})
# universal-crypto-mcp © nirholas