Skip to main content

LangGraph integration for the 402fly payment protocol

Project description

402fly-langgraph

LangGraph integration for the X402 payment protocol - build workflows that include payment nodes for accessing paid APIs.

Overview

The 402fly-langgraph package provides LangGraph nodes and utilities for building AI workflows that can automatically handle payment requirements. Create workflows that seamlessly integrate payment processing for accessing premium APIs.

Features

  • Pre-built payment nodes for LangGraph workflows
  • Conditional routing based on payment requirements
  • Helper functions for quick workflow creation
  • Support for multi-step workflows with multiple API calls
  • Async and sync payment node support
  • State management utilities for payment workflows

Installation

pip install 402fly-langgraph

Quick Start

Simple Payment Workflow

The easiest way to create a payment-enabled workflow:

from 402fly_langgraph import create_simple_payment_workflow
from solders.keypair import Keypair
import json

# Load wallet
with open("wallet.json") as f:
    wallet_data = json.load(f)
    keypair = Keypair.from_bytes(bytes(wallet_data))

# Create simple workflow
workflow = create_simple_payment_workflow(
    wallet_keypair=keypair,
    api_url="http://localhost:8000/premium-data",
    max_payment="1.0",
)

# Run workflow
result = workflow()
print(f"Payment completed: {result.get('payment_completed')}")
print(f"Response: {result.get('api_response')}")

Usage Patterns

Pattern 1: Simple Workflow (Recommended)

Best for single API access with payment:

from 402fly_langgraph import create_simple_payment_workflow
from solders.keypair import Keypair

keypair = Keypair()  # Your wallet

workflow = create_simple_payment_workflow(
    wallet_keypair=keypair,
    api_url="https://api.example.com/premium-data",
    max_payment="1.0",
)

result = workflow()

Pattern 2: Custom Workflow with Payment Nodes

For more complex workflows with custom logic:

from typing import TypedDict, Optional
from langgraph.graph import StateGraph, END
from 402fly_langgraph import (
    payment_node,
    fetch_with_payment_node,
    check_payment_required,
)
from solders.keypair import Keypair

# Define state
class WorkflowState(TypedDict):
    api_url: str
    api_response: Optional[str]
    payment_required: bool
    payment_completed: bool
    payment_error: Optional[str]
    wallet_keypair: Keypair
    max_payment_amount: str

# Build workflow
workflow = StateGraph(WorkflowState)

# Add nodes
workflow.add_node("fetch", fetch_with_payment_node)
workflow.add_node("payment", payment_node)

# Set entry point
workflow.set_entry_point("fetch")

# Add conditional routing
workflow.add_conditional_edges(
    "fetch",
    check_payment_required,
    {
        "payment_required": "payment",
        "success": END,
        "error": END
    }
)

workflow.add_edge("payment", END)

app = workflow.compile()

# Run workflow
keypair = Keypair()
result = app.invoke({
    "api_url": "https://api.example.com/data",
    "wallet_keypair": keypair,
    "max_payment_amount": "5.0"
})

Pattern 3: Multi-Step Research Workflow

Build workflows that access multiple paid APIs:

from typing import TypedDict, Optional, List
from langgraph.graph import StateGraph, END
from 402fly_langgraph import fetch_with_payment_node
from solders.keypair import Keypair

# Define state with multiple APIs
class ResearchState(TypedDict):
    wallet_keypair: Keypair
    apis: List[str]
    current_api_index: int
    api_url: str
    api_response: Optional[str]
    payment_completed: bool
    results: List[dict]
    max_payment_amount: str

def plan_node(state: ResearchState) -> ResearchState:
    """Initialize research plan"""
    state["apis"] = [
        "http://localhost:8000/premium-data",
        "http://localhost:8000/tiered-data/premium",
    ]
    state["current_api_index"] = 0
    state["api_url"] = state["apis"][0]
    state["results"] = []
    return state

def collect_result_node(state: ResearchState) -> ResearchState:
    """Collect result and move to next API"""
    if state.get("api_response"):
        state["results"].append({
            "api": state["api_url"],
            "response": state["api_response"]
        })

    # Move to next API
    state["current_api_index"] += 1
    if state["current_api_index"] < len(state["apis"]):
        state["api_url"] = state["apis"][state["current_api_index"]]
        state["api_response"] = None
        state["payment_completed"] = False

    return state

def check_more_apis(state: ResearchState) -> str:
    """Check if there are more APIs to access"""
    if state["current_api_index"] < len(state["apis"]):
        return "fetch_next"
    return "complete"

# Build workflow
workflow = StateGraph(ResearchState)
workflow.add_node("plan", plan_node)
workflow.add_node("fetch", fetch_with_payment_node)
workflow.add_node("collect", collect_result_node)

workflow.set_entry_point("plan")
workflow.add_edge("plan", "fetch")
workflow.add_edge("fetch", "collect")
workflow.add_conditional_edges(
    "collect",
    check_more_apis,
    {"fetch_next": "fetch", "complete": END}
)

app = workflow.compile()

# Run multi-step workflow
keypair = Keypair()
result = app.invoke({
    "wallet_keypair": keypair,
    "max_payment_amount": "5.0"
})

print(f"APIs processed: {len(result.get('results', []))}")

Complete Example

from 402fly_langgraph import create_simple_payment_workflow
from solders.keypair import Keypair
import json

# Load wallet
with open("wallet.json") as f:
    wallet_data = json.load(f)
    keypair = Keypair.from_bytes(bytes(wallet_data))

# Create and run workflow
workflow = create_simple_payment_workflow(
    wallet_keypair=keypair,
    api_url="http://localhost:8000/premium-data",
    max_payment="1.0",
)

result = workflow()

if result.get("payment_completed"):
    print("✅ Payment completed successfully")
    print(f"Response: {result.get('api_response')[:100]}...")
else:
    print(f"❌ Error: {result.get('payment_error')}")

Available Nodes

Payment Processing Nodes

  • payment_node: Process payment for current API request
  • async_payment_node: Async version of payment node
  • fetch_with_payment_node: Fetch API with automatic payment handling
  • async_fetch_with_payment_node: Async version

Conditional Routing Functions

  • check_payment_required: Route based on payment requirement
  • check_payment_completed: Route based on payment status

State Utilities

  • PaymentState: TypedDict for payment-capable state
  • create_payment_capable_state: Create custom state with payment fields
  • add_payment_workflow: Add payment nodes to existing workflow

Configuration

Node Parameters (via State)

  • wallet_keypair: Your Solana wallet keypair (required)
  • api_url: URL to access (required)
  • max_payment_amount: Maximum payment limit (required)
  • payment_required: Payment requirement flag
  • payment_completed: Payment completion flag
  • payment_error: Error message if payment fails

Wallet Setup

import json
from solders.keypair import Keypair

# Create new wallet
keypair = Keypair()
wallet_data = list(bytes(keypair))
with open("wallet.json", "w") as f:
    json.dump(wallet_data, f)

print(f"Wallet address: {keypair.pubkey()}")
print("Fund this wallet with SOL and USDC on devnet!")

Documentation

For complete API reference and guides, see:

Testing

pytest tests/

License

MIT License - See LICENSE file for details.

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

fly402langgraph-0.1.1.tar.gz (7.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fly402langgraph-0.1.1-py3-none-any.whl (8.7 kB view details)

Uploaded Python 3

File details

Details for the file fly402langgraph-0.1.1.tar.gz.

File metadata

  • Download URL: fly402langgraph-0.1.1.tar.gz
  • Upload date:
  • Size: 7.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for fly402langgraph-0.1.1.tar.gz
Algorithm Hash digest
SHA256 4ff922f6423dcd676d5308e4292512119e320fe9beada864476a895dba2503ff
MD5 5d00ded70650269f71999dcf642c6948
BLAKE2b-256 2e1a5678afbb44d1d85bc395181c80dc9c0340fdf4978ed873628a039e9e8c14

See more details on using hashes here.

File details

Details for the file fly402langgraph-0.1.1-py3-none-any.whl.

File metadata

File hashes

Hashes for fly402langgraph-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 55c4511c4dafb5d3f51e35d290cebd45c640683e7c9ff5bc97495e93cf5fbf58
MD5 bf3d0b37690c34f5c500f06b7d8bea15
BLAKE2b-256 3eabd102fcb089317f31ffa5875263346da79f29088d21dfa08e82473bca3ab3

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page