Starlane
April 13, 2026 · View on GitHub
Dual-rail payment infrastructure for AI agents on Stellar — x402 per-call charges and MPP payment channels, auto-selected by call frequency.
Overview
AI agents can reason and plan, but stall the moment they need to pay for a tool. Starlane solves this with a dual-rail MCP payment proxy: the first few calls to any service use x402 (one HTTP round-trip per payment, settled on Stellar), and after a repeat threshold the proxy automatically promotes high-frequency calls to a pre-funded MPP payment channel, eliminating per-call on-chain overhead. The service registry is an MCP-native catalog that any agent can query to discover, price-check, and invoke paid services — no wallet integration required in the agent itself.
Features
- Dual-rail auto-selection — x402 for first calls, MPP channel sessions for repeat high-frequency calls, switched automatically by
selectRail()with no agent-side logic. - MCP interface — 6 tools exposed over stdio and HTTP (
search_services,web_search,page_extract,market_snapshot, and more) so any MCP-compatible agent connects out of the box. - Live Stellar testnet payments — real USDC transfers signed with Ed25519 via
@x402/stellarand@stellar/mpp. - Service registry — HMAC-signed service manifests, live health probing, and keyword/tag search over a catalog of paid HTTP services.
- Deployed MPP channel — one-way payment channel contract live on Stellar testnet, pre-funded with USDC, handling off-chain commitment signing.
- Real-time dashboard — React control room polls the registry, proxy runtime, and workflow timeline every 3–5 seconds, with Stellar Expert links on every transaction.
Architecture
graph TD
Agent["AI Agent (MCP client)"] -->|MCP tools| Proxy
subgraph Starlane
Proxy["Proxy :4301\nselectRail() · session mgmt\nWorkflow event log"] -->|discover| Registry["Registry :4300\nHMAC-signed manifests\nHealth probing"]
Proxy -->|x402 payment| Providers["Providers :4302\nweb-search · page-extract\nmarket-snapshot"]
Proxy -->|MPP channel commitment| Providers
Registry -->|seed + health| Providers
Web["Dashboard :4303\nReact · live polling"] -->|reads| Registry
Web -->|reads| Proxy
end
Providers -->|x402 verify| Facilitator["x402.org Facilitator"]
Providers -->|channel verify| StellarRPC["Stellar Testnet RPC"]
Facilitator --> StellarRPC
Tech Stack
| Component | Technology |
|---|---|
| Runtime | Node.js 22+, TypeScript ESM |
| Monorepo | pnpm workspaces |
| Payment rails | @x402/stellar 2.9.0 · @stellar/mpp 0.4.0 · mppx 0.4.12 |
| MCP server | @modelcontextprotocol/sdk |
| HTTP services | Express · cors |
| Frontend | React 19 · Vite |
| Schema/validation | Zod |
| Blockchain | Stellar testnet · Soroban · USDC SAC |
Deployed Contracts
| Contract | Network | Address |
|---|---|---|
| MPP One-Way Payment Channel | Stellar Testnet | CCM4HLLCFEFPEOAJPWPXAZEW2FJMLAZFUIUIY7GJ55MXLOKK74LAJTC2 |
| USDC SAC (testnet) | Stellar Testnet | CBIELTK6YBZJU5UP2WWQEUCYKLPU6AUNZ2BQ4WWFEIE3USCIHMXQDAMA |
Quickstart
Prerequisites: Node.js 22+, pnpm 10+
git clone https://github.com/Cassxbt/Starlane.git
cd Starlane
pnpm install
Option A — Use your own Stellar testnet credentials
Generate a fresh keypair, fund it, and set up USDC:
cp .env.example .env
# Fill in STELLAR_SECRET_KEY with a funded testnet secret (S...)
# Fill in TESTNET_SERVER_STELLAR_ADDRESS with a receiver address (G...)
# Fill in BRAVE_SEARCH_API_KEY (free at https://brave.com/search/api/)
# Fill in REGISTRY_SIGNING_SECRET, REGISTRY_ADMIN_TOKEN, PROXY_SHARED_SECRET (any random strings)
node scripts/setup-testnet.mjs # creates USDC trustline and swaps XLM → USDC
pnpm dev:all # starts all 4 services
To generate a testnet keypair and fund it with XLM via Friendbot:
# Visit https://laboratory.stellar.org/#account-creator?network=test
# Or use the Stellar CLI:
stellar keys generate --network testnet my-key
stellar keys fund my-key --network testnet
Option B — MPP channel (full dual-rail demo)
The x402 rail works immediately with just a funded keypair. To also demonstrate MPP rail promotion (x402 → MPP after repeated calls), you need a deployed one-way payment channel contract. See mpp-channel-runbook.md for deployment steps, or use the existing channel at CCM4HLLCFEFPEOAJPWPXAZEW2FJMLAZFUIUIY7GJ55MXLOKK74LAJTC2 if the testnet hasn't reset.
Required additional .env variables for MPP:
MPP_SECRET_KEY=<hex app secret>
MPP_CHANNEL_CONTRACT_ID=CCM4HLLCFEFPEOAJPWPXAZEW2FJMLAZFUIUIY7GJ55MXLOKK74LAJTC2
MPP_COMMITMENT_SECRET=<S... keypair secret>
MPP_CHANNEL_SOURCE_ACCOUNT=<G... channel funder>
Run the demo
pnpm dev:all # starts registry :4300, proxy :4301, providers :4302, web :4303
Open http://localhost:4303 for the live dashboard, then in a second terminal:
pnpm demo:workflow
This chains three service calls — web search → page extraction → 4× market snapshots — triggering automatic rail promotion from x402 to MPP on the repeated market-snapshot calls. You will see:
- Transaction hashes printed in the terminal
- Stellar Expert explorer links for each payment
- The dashboard timeline updating in real time
Configuration
| Variable | Description | Required |
|---|---|---|
PAYMENT_MODE | Must be live | Yes |
STELLAR_SECRET_KEY | Payer keypair secret (S...) — signs x402 payments | Yes |
TESTNET_SERVER_STELLAR_ADDRESS | Provider receiving address (G...) | Yes |
TESTNET_STELLAR_RPC_URL | Soroban RPC endpoint (default: https://soroban-testnet.stellar.org) | Yes |
TESTNET_FACILITATOR_URL | x402 facilitator — use https://www.x402.org/facilitator | Yes |
BRAVE_SEARCH_API_KEY | Brave Search API key for live paid web search | Yes |
PROVIDERS_ENABLE_LIVE_X402 | true to activate real x402 payment middleware | Yes |
PROVIDERS_ENABLE_LIVE_MPP | true to activate live MPP channel payments | MPP only |
MPP_CHANNEL_CONTRACT_ID | Deployed one-way channel contract address (C...) | MPP only |
MPP_COMMITMENT_SECRET | Channel commitment keypair secret (S...) | MPP only |
MPP_CHANNEL_SOURCE_ACCOUNT | Channel funder public key (G...) | MPP only |
MPP_SECRET_KEY | MPP app secret (hex) | MPP only |
REGISTRY_SIGNING_SECRET | HMAC secret for manifest signatures | Yes |
REGISTRY_ADMIN_TOKEN | Required bearer token for POST /services/register | Yes |
PROXY_SHARED_SECRET | Shared secret header between proxy and providers | Yes |
Usage
Run the demo workflow (requires all 4 services running):
pnpm demo:workflow
Check MPP channel and session status:
pnpm mpp:status
Invoke a service directly via the proxy:
curl -X POST http://localhost:4301/invoke/web-search \
-H "Content-Type: application/json" \
-d '{"query": "stellar x402 agent payments"}'
Query the service catalog:
curl http://localhost:4300/services
Connect an MCP client (Claude Desktop, Claude Code, or any MCP host):
{
"mcpServers": {
"starlane": {
"command": "npx",
"args": ["tsx", "apps/proxy/src/index.ts"],
"cwd": "/absolute/path/to/Starlane",
"env": {
"PROXY_BASE_URL": "http://localhost:4301"
}
}
}
}
MCP tools available: search_services · get_service · get_service_health · web_search · page_extract · market_snapshot
Testing
pnpm test # 14 tests across 3 suites (rail selection, sessions, security)
pnpm typecheck # TypeScript strict mode on all 8 packages
Roadmap
- On-chain channel settlement — automate
close()calls and recipient signing so the full channel lifecycle runs without manual CLI intervention. - Authenticated service registry — bind manifest updates to ownership so third-party providers can register without overwrite risk.
- Live market news enrichment — pair the live price feed with sourced headlines instead of fallback commentary.
Contributing
Pull requests are welcome. For major changes, open an issue first to discuss what you'd like to change. Run pnpm test and pnpm typecheck before submitting.