CLI-first, non-custodial Lightning Network wallet for autonomous AI agents
Project description
A CLI-first, non-custodial Lightning Network wallet built for autonomous AI agents.
Ultra-lightweight. Self-sovereign. No full Bitcoin node required.
# One-click install (uv) — installs 'sz' and 'sz-mcp' globally
uv tool install saturnzap --find-links https://github.com/lqwdtech/SaturnZap/releases/latest/download/
export SZ_PASSPHRASE="your-secure-passphrase"
sz setup --auto # Generate seed + start node + pick LQWD peer
sz service install # Keep the node running across reboots
sz connect-info --check # Share the URI with peers/LSPs
sz pay --invoice lnbc1... --max-sats 500
sz fetch https://api.example.com/data --max-sats 100
What is SaturnZap?
SaturnZap is an open-source Lightning wallet designed from the ground up for AI agents operating without human supervision. The agent installs SaturnZap, initializes its own Lightning node, opens channels to any peer on the network, sends and receives Bitcoin payments, and autonomously pays for L402-gated APIs.
SaturnZap is a CLI tool. It is not a hosted wallet, not a custodial service, and not a web application. Keys live on the agent's machine. The agent IS the Lightning node.
Two ways to integrate:
- CLI — call
szcommands from any language, parse JSON from stdout - MCP Server — connect AI agents directly via Model Context Protocol (stdio)
Documentation: See the docs/ folder for detailed guides on getting started, configuration, MCP server integration, architecture, and JSON API reference.
Business Model
SaturnZap has two layers:
CLI — Open Source (MIT)
The sz command-line tool is free and open source under the MIT license. Anyone can
install it, fork it, audit it, and build on it. There is no licensing fee, no API key
required to use the software itself, and no telemetry.
LQWD (LSP)
SaturnZap ships pre-configured to use LQWD Technologies as its default Lightning Service Provider (LSP). LQWD operates 18 Lightning nodes across 18 countries with deep global channel liquidity.
When an agent uses LQWD's infrastructure, LQWD earns through:
- Routing fees — sats earned as payments route through LQWD nodes
- Channel leasing — fees for opening and providing inbound liquidity to agents
- Managed connectivity — premium peering and reliability for agents that need it
LQWD is the default, not a requirement. Agents can open channels to any node on the Lightning Network. SaturnZap never enforces LQWD usage. LQWD competes on quality — 18-country coverage, deep liquidity, fast channel opens — not on lock-in.
This model mirrors how open-source software with cloud backends works: the tool is free, the infrastructure is the business.
Key Properties
- Non-custodial — BIP39 seed lives encrypted on the agent's machine. SaturnZap never holds, transmits, or has access to private keys.
- No full Bitcoin node — Esplora REST API provides chain data with automatic fallback (LQWD → blockstream.info → mempool.space). No bitcoind required.
- Peer-agnostic — Open channels to any Lightning node. LQWD is a smart default with global reach, but the agent controls its own peer relationships entirely.
- JSON-first — Every command writes structured JSON to stdout. Errors go to stderr. Designed for machine consumption from day one.
- MCP-native — Built-in MCP server exposes 25 tools over stdio. Connect Claude, Cursor, VS Code, or any MCP-compatible agent with a single config block.
- Autonomous — No interactive prompts in normal operation. Designed to run
inside agent runtimes, shell scripts, and orchestration pipelines. (Mainnet
spending commands prompt for confirmation unless
--yesis passed.)
Architecture
Full architecture details: docs/architecture.md
Component Map
┌─────────────────────────────────────────────────────────┐
│ Integration Layer │
│ │
│ sz CLI MCP Server OpenClaw Skill │
│ (typer) (FastMCP/stdio) (gateway) │
│ │ │ │ │
│ └───────────────┼──────────────────┘ │
│ │ │
│ ┌───────▼───────┐ │
│ │ IPC Client │ (auto-detect daemon) │
│ └───────┬───────┘ │
└──────────────────────┼──────────────────────────────────┘
│ Unix Domain Socket (sz.sock)
┌──────────────────────▼──────────────────────────────────┐
│ Daemon (sz start --daemon) │
│ │
│ IPC Server (asyncio) ─── Wallet Core │
│ 23 JSON methods node.py, payments.py, l402.py │
│ threading.Lock liquidity.py, keystore.py │
│ 0600 socket perms lqwd.py, config.py, output.py │
│ ipc.py │
└──────────────────────┬──────────────────────────────────┘
│
┌──────────────────────▼──────────────────────────────────┐
│ LDK Node │
│ - Full Lightning protocol implementation │
│ - Esplora chain sync (LQWD → blockstream → mempool) │
│ - BIP39 key management │
│ - Peer connections and channel state machine │
└──────────────┬────────────────────────┬─────────────────┘
│ │
┌──────────────▼──────────┐ ┌──────────▼──────────────────┐
│ LQWD Global Nodes │ │ Any Lightning Node │
│ (default — 18 nodes, │ │ (agent can peer with │
│ 18 countries, deep │ │ any public node on the │
│ liquidity, LSPS) │ │ Lightning Network) │
└─────────────────────────┘ └─────────────────────────────┘
Key Design Decisions
Unix Domain Socket IPC
The daemon (sz start) owns the LDK node and exposes 23 methods over a Unix
Domain Socket at ~/.local/share/saturnzap/<network>/sz.sock. CLI commands, the MCP
server, and OpenClaw automatically detect the daemon and route through IPC — no port
conflicts, no database locks. If no daemon is running, commands fall back to starting
an ephemeral node.
Esplora chain sync with fallback
LDK Node syncs chain data via Esplora (block explorer REST API). No external Bitcoin node is needed. SaturnZap ships with a fallback chain — if the primary Esplora server is unreachable, it automatically probes alternatives (LQWD, blockstream.info, mempool.space) and connects to the first healthy endpoint. First sync takes a few minutes on a fresh install; subsequent starts are near-instant.
LQWD as default LSP
All 18 LQWD node pubkeys and connection strings are embedded in SaturnZap's default
config. On sz init, the wallet automatically peers with the nearest LQWD node based
on the system's timezone offset — each node has a UTC offset, and sz picks the
one closest to yours. A server in UTC gets LQWD-England, one in EST gets LQWD-Canada,
one in JST gets LQWD-Japan. Override with SZ_REGION=CA or --region CA to force a
specific node. A fresh agent install goes from zero to channel-ready in under five
minutes.
Peer-agnostic after init
After the initial channel, agents use standard Lightning channel open flows to peer with anyone. SaturnZap has no routing logic that artificially prefers LQWD — Lightning pathfinding selects the best route. LQWD nodes appear as attractive routes naturally because of their connectivity and capacity across 18 countries.
JSON-first, no interactive prompts
All commands are designed for non-interactive execution. No [y/N] confirmations. No
spinners that break pipe parsing. Pass --pretty for human-readable output in a TTY.
Default is always clean JSON.
Autonomous channel management
SaturnZap monitors channel health. When configured, it automatically opens new channels when outbound liquidity drops below a threshold, and requests inbound liquidity from the configured LSP when needed. Agents can run indefinitely without manual intervention.
Technology Stack
| Component | Library | Notes |
|---|---|---|
| Language | Python 3.12 | Type hints throughout |
| Lightning node | ldk-node 0.7.0 | LDK Node Python bindings, Neutrino built-in |
| CLI framework | typer | Clean API, auto-generated help |
| HTTP client | httpx | Used for L402 interceptor |
| Config storage | platformdirs + TOML | OS-appropriate config paths |
| Key encryption | cryptography | Fernet encryption for seed file |
| BIP39 | mnemonic | Seed phrase generation |
| Package manager | uv | Fast, modern Python tooling |
| MCP server | mcp ≥1.26 | Model Context Protocol for AI agent integration |
| Testing | pytest | Unit + integration, 395+ tests |
| Linting | ruff | Fast Python linter and formatter |
LQWD Node Directory
Embedded in SaturnZap as trusted default peers. On sz init or sz channels open --lsp lqwd,
the nearest node is auto-selected by comparing the system's UTC offset against each
node's timezone — smallest offset difference wins. Override with SZ_REGION env var or
--region flag. Full pubkeys and connection strings are in src/saturnzap/lqwd.py.
| Alias | Region |
|---|---|
| LQWD-Canada | CA |
| LQWD-Sweden | SE |
| LQWD-France | FR |
| LQWD-England | GB |
| LQWD-Japan | JP |
| LQWD-Australia | AU |
| LQWD-Brazil | BR |
| LQWD-Bahrain | BH |
| LQWD-Singapore | SG |
| LQWD-SouthAfrica | ZA |
| LQWD-HongKong | HK |
| LQWD-SouthKorea | KR |
| LQWD-Indonesia | ID |
| LQWD-Ireland | IE |
| LQWD-Italy | IT |
| LQWD-Germany | DE |
| LQWD-India | IN |
| LQWD-US-West | US |
Full pubkeys and host:port connection strings are in src/saturnzap/lqwd.py.
Signet/testnet node details maintained separately for development.
CLI Reference
Full JSON API reference: docs/json-api-reference.md
Binary: sz
All commands output JSON to stdout. Errors exit with code 1, written to stderr.
Global options:
sz --network bitcoin|signet|testnet <command> # Select Bitcoin network (default: bitcoin)
sz --pretty <command> # Pretty-print JSON output
Node
sz init # Generate seed, start node, peer with nearest LQWD node
sz init --for-lqwd-faucet # Mainnet preset: sets a readable alias for LQWDClaw
sz setup # Guided first-run: init + address (idempotent)
sz setup --auto # Non-interactive: init + address + request inbound from LQWD
sz start # Foreground daemon — blocks until SIGTERM/SIGINT (systemd-friendly)
sz start --foreground # Legacy: print status and exit (non-persistent)
sz stop # Stop the node daemon
sz stop --close-all # Cooperatively close all channels, then stop
sz status # Node pubkey, sync state, peer/channel counts
sz connect-info --check # Connection URI + external reachability probe
Wallet
sz address # New on-chain receiving address
sz send <address> # Send all on-chain sats to address
sz send <address> -a 50000 # Send specific amount on-chain
sz send <address> --yes # Skip mainnet confirmation prompt
sz balance # Onchain + lightning balances, per-channel breakdown
sz transactions --limit 20 # Payment history
Peers
sz peers list
sz peers add <pubkey>@<host>:<port>
sz peers remove <pubkey>
# Anchor-reserve waiver / 0-conf — applied on next node start.
# The LQWD fleet is trusted by default on mainnet.
sz peers trust <pubkey>
sz peers untrust <pubkey>
sz peers trusted-list
Config
sz config list # Show current config + known keys
sz config get node.alias
sz config set node.alias "my-agent" # Persists to ~/.config/saturnzap/config.toml
sz config set node.listen_port 9735
sz config unset esplora_url
Channels
sz channels list
# Open to any node
sz channels open --peer <pubkey>@<host>:<port> --amount-sats 100000
# Open via LQWD — nearest node automatically selected
sz channels open --lsp lqwd --amount-sats 100000
# Open via LQWD in a specific region
sz channels open --lsp lqwd --region JP --amount-sats 100000
# Skip mainnet confirmation (for automation)
sz channels open --lsp lqwd --amount-sats 100000 --yes
sz channels close --channel-id <id>
sz channels close --channel-id <id> --force
# Wait for a channel to become usable (blocks until ready or timeout)
sz channels wait --channel-id <id> --timeout 300
Payments
sz invoice --amount-sats 1000 --memo "for data"
sz invoice --amount-sats 1000 --wait # Block until paid or expired
sz pay --invoice lnbc1...
sz pay --invoice lnbc1... --max-sats 500 # spending cap for agent safety
sz pay --invoice lnbc1... --yes # skip mainnet confirmation
sz keysend --pubkey <pubkey> --amount-sats 100
sz keysend --pubkey <pubkey> --amount-sats 100 --yes
L402 — Autonomous API Payments
# Auto-detects HTTP 402, pays invoice, retries request, returns body
sz fetch https://api.example.com/data
# With per-request spending cap
sz fetch https://api.example.com/data --max-sats 100
# With custom headers
sz fetch https://api.example.com/data --header "X-Custom: value"
Liquidity
sz liquidity status
sz liquidity request-inbound --amount-sats 500000
Service Management
sz service install # Install + start systemd unit (recommended for persistence)
sz service status # Check service status
sz service uninstall # Stop and remove systemd service
Once installed, the LDK node stays up across reboots and every sz command routes
through the daemon's IPC socket — no per-command startup overhead.
MCP Server
sz mcp # Start MCP server on stdio (for AI agent integration)
Or use the standalone entry point:
sz-mcp # Same as sz mcp
Agent configuration (Claude Desktop, Cursor, VS Code, etc.):
{
"mcpServers": {
"saturnzap": {
"command": "sz",
"args": ["mcp"],
"env": {
"SZ_PASSPHRASE": "your-passphrase"
}
}
}
}
The MCP server exposes 25 tools covering node lifecycle, wallet, peers, channels,
payments, L402 fetch, and liquidity management. Set SZ_MCP_MAX_SPEND_SATS to
enforce a global per-request spending cap on L402 payments.
JSON Output Format
sz balance
{
"status": "ok",
"network": "signet",
"onchain_sats": 0,
"lightning_sats": 45000,
"channels": [
{
"channel_id": "abc123",
"peer_pubkey": "036491...",
"peer_alias": "LQWD-Canada",
"capacity_sats": 100000,
"outbound_sats": 45000,
"inbound_sats": 55000,
"state": "open"
}
]
}
sz pay
{
"status": "ok",
"network": "signet",
"payment_hash": "def456...",
"amount_sats": 1000,
"fee_sats": 1,
"duration_ms": 342
}
sz fetch (L402 flow)
{
"status": "ok",
"network": "signet",
"url": "https://api.example.com/data",
"payment_hash": "ghi789...",
"amount_sats": 10,
"fee_sats": 1,
"http_status": 200,
"body": {}
}
Error (any command)
{
"status": "error",
"code": "INSUFFICIENT_OUTBOUND_LIQUIDITY",
"message": "Not enough outbound liquidity. Available: 200 sats, required: 1000 sats."
}
Exit Codes
| Code | Meaning |
|---|---|
| 0 | Success |
| 1 | General error |
| 2 | Node not running — run sz start |
| 3 | Insufficient funds |
| 4 | Channel not found |
| 5 | Peer unreachable |
| 6 | Invoice expired or invalid |
| 7 | LSP request failed |
Project Structure
/
├── README.md
├── LICENSE # MIT
├── pyproject.toml # Package definition, sz entry point
├── uv.lock
├── .env.example # Environment variable template
│
├── docs/
│ ├── getting-started.md # Installation and first-run guide
│ ├── configuration.md # Config file and env var reference
│ ├── mcp-server.md # MCP server setup and tool reference
│ ├── architecture.md # Design decisions and component map
│ └── json-api-reference.md # Full JSON shapes for all commands
│
├── src/
│ └── saturnzap/
│ ├── __init__.py
│ ├── cli.py # Typer app — all sz commands
│ ├── node.py # LDK Node lifecycle + channels + peers
│ ├── payments.py # Send / receive / invoice / keysend
│ ├── l402.py # L402 HTTP interceptor
│ ├── liquidity.py # Channel health scoring + recommendations
│ ├── keystore.py # BIP39 seed, Fernet encryption
│ ├── lqwd.py # LQWD node directory (18 regions)
│ ├── config.py # Config paths, Esplora fallback, TOML loader
│ ├── mcp_server.py # MCP server — 25 tools for AI agents
│ ├── service.py # Systemd service generator
│ └── output.py # JSON output, TTY detection, --pretty
│
├── tests/
│ ├── test_cli.py # CLI smoke tests
│ ├── test_keystore.py # Seed encryption
│ ├── test_node.py # Node lifecycle + channel rejection
│ ├── test_ipc.py # IPC layer
│ ├── test_payments.py # Payment helpers
│ ├── test_l402.py # L402 parsing
│ ├── test_liquidity.py # Health scoring
│ ├── test_config.py # Config + env vars
│ ├── test_mcp_server.py # MCP server
│ ├── test_backup.py # Backup/restore
│ ├── test_service.py # Systemd service
│ ├── test_lqwd.py # LQWD directory
│ ├── test_output.py # JSON output
│ ├── integration/ # Multi-command flows
│ ├── security/ # Input validation, spending guards
│ ├── reliability/ # Edge cases, concurrency
│ ├── ux/ # Agent workflow scenarios
│ └── live/ # Droplet tests (@live marker)
│
├── skills/
│ └── saturnzap/
│ ├── SKILL.md # OpenClaw skill definition
│ └── references/
│ └── json-contracts.md # Full JSON output reference
│
├── vendor/
│ └── ldk_node-0.7.0-py3-none-any.whl # LDK Node Python bindings (Linux x86_64)
│
├── security/
│ ├── security_scan.py
│ └── profiles/
│ └── saturnzap.yaml
│
├── hooks/
│ ├── pre-commit
│ └── pre-push
│
└── .github/
└── workflows/
├── ci.yml # Lint + test on push/PR
└── publish.yml # PyPI publish on version tags
Development Environment
| OS | Ubuntu 24.04 (DigitalOcean Droplet, 2GB RAM / 2 vCPU) |
| Editor | VS Code via Remote SSH |
| Python | 3.12 |
| Network | Bitcoin mainnet (default) / signet / testnet — selectable via --network |
| Chain source | Esplora REST API with automatic fallback chain |
| LQWD nodes | 18 regions, pubkeys embedded in src/saturnzap/lqwd.py |
Droplet Setup
# Install uv
curl -LsSf https://astral.sh/uv/install.sh | sh
source $HOME/.local/bin/env
# Clone and install
git clone https://github.com/lqwdtech/SaturnZap
cd saturnzap
uv venv
source .venv/bin/activate
uv sync
# Run
sz --help
Install from PyPI
# ldk-node is not yet on PyPI — use --find-links to pull it from GitHub Releases
pip install saturnzap --find-links https://github.com/lqwdtech/SaturnZap/releases/latest/download/
# Or with uv
uv pip install saturnzap --find-links https://github.com/lqwdtech/SaturnZap/releases/latest/download/
Development Phases
Phase 1 — Node Foundation ✅
sz init, sz start, sz stop, sz status
BIP39 seed generation, encrypted storage, LDK Node startup, Esplora chain sync, auto-peer with nearest LQWD node, JSON output infrastructure.
Phase 2 — Channel Management ✅
sz channels, sz peers, sz address, sz balance
Open channels to any node. LQWD LSP-assisted channel opens. LQWD node directory embedded (18 regions, timezone-based auto-selection). Channel list and close.
Phase 3 — Payments ✅
sz invoice, sz pay, sz keysend, sz transactions
Full BOLT11 send and receive. Variable-amount invoices. Keysend. Transaction history with sorting and pagination.
Phase 4 — L402 ✅
sz fetch
HTTP client with 402 detection, invoice extraction, auto-pay, request retry. Per-request spending caps. Token caching to avoid re-paying the same resource.
Phase 5 — Liquidity Intelligence ✅
sz liquidity
Channel health monitoring with 0-100 scoring. Actionable recommendations. Inbound liquidity requests via LQWD. Geography-aware peer selection across 18 regions.
Phase 6 — Packaging and Integration ✅
pip install saturnzap / uv add saturnzap / sz mcp
MCP server with 25 tools. Esplora fallback chain. GitHub Actions CI/CD. PyPI packaging. OpenClaw skill definition. Security scanner (Grade A+).
Phase 7 — Mainnet Support ✅
sz --network bitcoin
Network selection via CLI flag (--network signet|testnet|bitcoin), config.toml, or
default. Network-namespaced data directories isolate wallets per network. Real LQWD
mainnet node directory (18 nodes). Mainnet safety confirmation prompt on spending
commands, skippable with --yes flag or SZ_MAINNET_CONFIRM=yes. Network field
included in all JSON responses.
Upcoming
- PyPI publish (trusted publisher workflow ready)
- Docker image
- OpenClaw ClawHub listing
Responsible Use
SaturnZap is non-custodial software. You hold your own keys, and you are solely responsible for your funds. It is provided under the MIT license on an "as is" basis — the usual open-source terms apply. A few practical suggestions:
- Start with small amounts on mainnet while you get comfortable with the tooling.
- Back up your seed phrase somewhere safe and offline. Without it, there is no recovery path.
- Use
--network signetfor development and integration testing — signet coins are free and isolated from your mainnet wallet. - Set spending caps (
--max-sats,SZ_CLI_MAX_SPEND_SATS,SZ_MCP_MAX_SPEND_SATS) when running autonomous agents.
See SECURITY.md for the threat model and disclosure policy.
License
MIT License. See LICENSE.
The SaturnZap CLI is free and open source. LQWD infrastructure services are commercial. Using SaturnZap with non-LQWD peers requires no agreement with LQWD Technologies.
About LQWD
LQWD Technologies Corp (TSXV: LQWD | OTCQX: LQWDF) is a publicly traded Lightning Network infrastructure company. LQWD operates 18 Lightning nodes across 18 countries, providing routing infrastructure, liquidity services, and LSP connectivity for agents and developers building on Bitcoin's Lightning Network.
- Corporate: https://lqwdtech.com
- Agent endpoint: https://lqwd.ai
- Network: 18 nodes, 18 countries, 1,600+ channels
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file saturnzap-1.1.0.tar.gz.
File metadata
- Download URL: saturnzap-1.1.0.tar.gz
- Upload date:
- Size: 157.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f6d2682123ce3c766f4563c7f8cabc63846dc21fd3aead99de5caf6ba66cea54
|
|
| MD5 |
d90aac770cbfae9cf14735fc0a22b86d
|
|
| BLAKE2b-256 |
761b5922150e5e8015cd86e009c52153ca1e67ad1a43e979592f5e86330238ab
|
Provenance
The following attestation bundles were made for saturnzap-1.1.0.tar.gz:
Publisher:
publish.yml on lqwdtech/SaturnZap
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
saturnzap-1.1.0.tar.gz -
Subject digest:
f6d2682123ce3c766f4563c7f8cabc63846dc21fd3aead99de5caf6ba66cea54 - Sigstore transparency entry: 1358452129
- Sigstore integration time:
-
Permalink:
lqwdtech/SaturnZap@7fe3f183ea0cfcd36511f7978e95999cfc781ad9 -
Branch / Tag:
refs/tags/v1.1.0 - Owner: https://github.com/lqwdtech
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@7fe3f183ea0cfcd36511f7978e95999cfc781ad9 -
Trigger Event:
push
-
Statement type:
File details
Details for the file saturnzap-1.1.0-py3-none-any.whl.
File metadata
- Download URL: saturnzap-1.1.0-py3-none-any.whl
- Upload date:
- Size: 58.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
887cb00edda42fa4e3646147e0d96484d08757f2f0cb25552dbfb84c0ee9b09f
|
|
| MD5 |
a001553e1470e77a765acbddb6e840de
|
|
| BLAKE2b-256 |
af5802bccee4c875314da8248f88eb8af3ab85a1753f90b3fe00cf9950e413ce
|
Provenance
The following attestation bundles were made for saturnzap-1.1.0-py3-none-any.whl:
Publisher:
publish.yml on lqwdtech/SaturnZap
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
saturnzap-1.1.0-py3-none-any.whl -
Subject digest:
887cb00edda42fa4e3646147e0d96484d08757f2f0cb25552dbfb84c0ee9b09f - Sigstore transparency entry: 1358452145
- Sigstore integration time:
-
Permalink:
lqwdtech/SaturnZap@7fe3f183ea0cfcd36511f7978e95999cfc781ad9 -
Branch / Tag:
refs/tags/v1.1.0 - Owner: https://github.com/lqwdtech
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@7fe3f183ea0cfcd36511f7978e95999cfc781ad9 -
Trigger Event:
push
-
Statement type: