Skip to content

Update SKILL.md

Update SKILL.md #128

Workflow file for this run

name: Build and Release
on:
push:
branches: [main]
tags: ['v*']
pull_request:
branches: [main]
env:
CARGO_TERM_COLOR: always
jobs:
build:
name: Build - ${{ matrix.platform }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
# Linux x86_64 - static musl build
- os: ubuntu-latest
target: x86_64-unknown-linux-musl
platform: linux-x86_64
artifact_name: payment-linux-x86_64
use_cross: true
# Linux aarch64 - static musl build
- os: ubuntu-latest
target: aarch64-unknown-linux-musl
platform: linux-aarch64
artifact_name: payment-linux-aarch64
use_cross: true
# macOS x86_64 (cross-compile from Apple Silicon)
- os: macos-14
target: x86_64-apple-darwin
platform: darwin-x86_64
artifact_name: payment-darwin-x86_64
# macOS aarch64 (Apple Silicon)
- os: macos-14
target: aarch64-apple-darwin
platform: darwin-aarch64
artifact_name: payment-darwin-aarch64
# Windows x86_64
- os: windows-latest
target: x86_64-pc-windows-msvc
platform: windows-x86_64
artifact_name: payment-windows-x86_64
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}
- name: Install cross (for Linux musl builds)
if: matrix.use_cross
run: cargo install cross --git https://github.com/cross-rs/cross
- name: Cache cargo registry
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ matrix.platform }}-cargo-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ matrix.platform }}-cargo-
- name: Build release binaries (cross)
if: matrix.use_cross
run: cross build --release --target ${{ matrix.target }}
- name: Build release binaries (native)
if: ${{ !matrix.use_cross }}
run: cargo build --release --target ${{ matrix.target }}
- name: Create artifact directory
shell: bash
run: mkdir -p artifacts
- name: Package binaries (Unix)
if: matrix.os != 'windows-latest'
shell: bash
run: |
cd target/${{ matrix.target }}/release
chmod +x create-wallet get-address pay payment-config
zip ../../../artifacts/${{ matrix.artifact_name }}.zip \
create-wallet get-address pay payment-config
- name: Package binaries (Windows)
if: matrix.os == 'windows-latest'
shell: pwsh
run: |
cd target/${{ matrix.target }}/release
Compress-Archive -Path create-wallet.exe,get-address.exe,pay.exe,payment-config.exe `
-DestinationPath ../../../artifacts/${{ matrix.artifact_name }}.zip
- name: Verify static linking (Linux)
if: matrix.use_cross
run: |
echo "=== Checking binary type ==="
file target/${{ matrix.target }}/release/create-wallet
echo "=== Verifying static linking ==="
# The binary should be "statically linked" or "static-pie linked" - fail if not
file target/${{ matrix.target }}/release/create-wallet | grep -qE "(statically linked|static-pie linked)" || {
echo "ERROR: Binary is not statically linked!"
exit 1
}
echo "=== Checking for dynamic dependencies ==="
# ldd should show "statically linked", "not a dynamic executable", or fail for cross-compiled binaries
LDD_OUTPUT=$(ldd target/${{ matrix.target }}/release/create-wallet 2>&1) || true
if echo "$LDD_OUTPUT" | grep -qE "(statically linked|not a dynamic executable)"; then
echo "SUCCESS: No dynamic dependencies"
echo "$LDD_OUTPUT"
elif echo "$LDD_OUTPUT" | grep -qE "(cannot execute|wrong ELF class|cannot open)"; then
echo "SUCCESS: Cross-compiled binary (ldd cannot analyze, but file confirmed static linking)"
echo "$LDD_OUTPUT"
else
echo "ERROR: Binary has dynamic dependencies:"
echo "$LDD_OUTPUT"
exit 1
fi
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.artifact_name }}
path: artifacts/${{ matrix.artifact_name }}.zip
retention-days: 7
# Collect all artifacts into single directory
collect-artifacts:
name: Collect Artifacts
needs: build
runs-on: ubuntu-latest
steps:
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
merge-multiple: true
- name: List artifacts
run: ls -la artifacts/
- name: Upload combined artifacts
uses: actions/upload-artifact@v4
with:
name: all-platforms
path: artifacts/
retention-days: 30
# Create GitHub Release on tag push
release:
name: Create Release
needs: build
if: startsWith(github.ref, 'refs/tags/v')
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
merge-multiple: true
- name: List artifacts
run: ls -la artifacts/
- name: Create Release
uses: softprops/action-gh-release@v2
with:
files: artifacts/*.zip
generate_release_notes: true
draft: false
prerelease: ${{ contains(github.ref, '-rc') || contains(github.ref, '-beta') || contains(github.ref, '-alpha') }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Run tests
test:
name: Test
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Cache cargo registry
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: test-cargo-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
test-cargo-
- name: Run tests
run: cargo test --all
- name: Run clippy
run: cargo clippy --all -- -D warnings
- name: Check formatting
run: cargo fmt --all -- --check
# Verify builds work
verify:
name: Verify - ${{ matrix.platform }}
needs: build
runs-on: ${{ matrix.os }}
strategy:
matrix:
include:
- os: ubuntu-latest
platform: linux-x86_64
artifact_name: payment-linux-x86_64
- os: macos-latest
platform: darwin-aarch64
artifact_name: payment-darwin-aarch64
- os: windows-latest
platform: windows-x86_64
artifact_name: payment-windows-x86_64
steps:
- name: Download artifact
uses: actions/download-artifact@v4
with:
name: ${{ matrix.artifact_name }}
path: .
- name: Extract and verify (Unix)
if: matrix.os != 'windows-latest'
run: |
unzip ${{ matrix.artifact_name }}.zip
chmod +x *
./get-address --help
./create-wallet --help
./pay --help
./payment-config --help
- name: Verify static linking (Linux)
if: matrix.os == 'ubuntu-latest'
run: |
echo "=== Checking binary type ==="
file ./create-wallet
echo "=== Verifying no libc dependency ==="
# The binary should be "statically linked" or "static-pie linked"
file ./create-wallet | grep -qE "(statically linked|static-pie linked)" || {
echo "ERROR: Binary is not statically linked!"
file ./create-wallet
exit 1
}
# Verify ldd shows no dynamic dependencies
LDD_OUTPUT=$(ldd ./create-wallet 2>&1)
if echo "$LDD_OUTPUT" | grep -qE "(statically linked|not a dynamic executable)"; then
echo "SUCCESS: Binary has no dynamic dependencies (including libc)"
echo "$LDD_OUTPUT"
else
echo "ERROR: Binary has dynamic dependencies:"
echo "$LDD_OUTPUT"
exit 1
fi
echo "=== All binaries verified as fully static ==="
- name: Extract and verify (Windows)
if: matrix.os == 'windows-latest'
shell: pwsh
run: |
Expand-Archive -Path ${{ matrix.artifact_name }}.zip -DestinationPath .
.\get-address.exe --help
.\create-wallet.exe --help
.\pay.exe --help
.\payment-config.exe --help
# Integration test: wallet creation, address retrieval, payment link
integration-test:
name: Integration Test
needs: build
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Download Linux x86_64 artifact
uses: actions/download-artifact@v4
with:
name: payment-linux-x86_64
path: .
- name: Set up skill directory
run: |
# Create the skill directory layout: binaries in scripts/, data files in parent
SKILL_DIR="${HOME}/.openclaw/skills/payment"
mkdir -p "${SKILL_DIR}/scripts"
# Extract binaries into scripts/
unzip payment-linux-x86_64.zip -d "${SKILL_DIR}/scripts"
chmod +x "${SKILL_DIR}/scripts/"*
# Copy default config
cp skills/payment/config-default.toml "${SKILL_DIR}/config.toml"
echo "SKILL_DIR=${SKILL_DIR}" >> "$GITHUB_ENV"
- name: Configure network (base-mainnet)
run: |
"${SKILL_DIR}/scripts/payment-config" show
echo "=== Config verified ==="
- name: Create wallet
run: |
ADDRESS=$("${SKILL_DIR}/scripts/create-wallet" 2>/dev/null)
echo "Created wallet with address: ${ADDRESS}"
# Verify address format (0x + 40 hex chars)
if [[ ! "${ADDRESS}" =~ ^0x[0-9a-fA-F]{40}$ ]]; then
echo "ERROR: Invalid address format: ${ADDRESS}"
exit 1
fi
echo "WALLET_ADDRESS=${ADDRESS}" >> "$GITHUB_ENV"
- name: Get address and verify
run: |
OUTPUT=$("${SKILL_DIR}/scripts/get-address" 2>/dev/null)
echo "get-address output: ${OUTPUT}"
# Verify JSON output contains the address
ADDR=$(echo "${OUTPUT}" | jq -r '.address')
if [[ -z "${ADDR}" || "${ADDR}" == "null" ]]; then
echo "ERROR: No address in get-address output"
exit 1
fi
echo "Verified address: ${ADDR}"
- name: Create payment link
run: |
ADDR=$(echo "$("${SKILL_DIR}/scripts/get-address" 2>/dev/null)" | jq -r '.address')
echo "Creating payment link for 0.01 USDC to ${ADDR}..."
RESPONSE=$(curl -s "https://link.x402labs.dev/create-payment-link?amount=0.01&receiver=${ADDR}")
echo "Response: ${RESPONSE}"
# Verify response contains payment_url
PAYMENT_URL=$(echo "${RESPONSE}" | jq -r '.payment_url')
if [[ -z "${PAYMENT_URL}" || "${PAYMENT_URL}" == "null" ]]; then
echo "ERROR: No payment_url in response"
exit 1
fi
echo "Payment link created: ${PAYMENT_URL}"
# Verify payment status (should be unpaid)
PAYMENT_ID=$(echo "${RESPONSE}" | jq -r '.payment_id')
STATUS=$(curl -s "https://link.x402labs.dev/status/${PAYMENT_ID}")
echo "Payment status: ${STATUS}"
PAID=$(echo "${STATUS}" | jq -r '.paid')
if [[ "${PAID}" != "false" ]]; then
echo "ERROR: Expected paid=false, got paid=${PAID}"
exit 1
fi
echo "=== Integration test passed ==="