BlockRun

LangChain Integration

Use BlockRun as an LLM provider in LangChain — either through the OpenAI-compatible LiteLLM adapter (full chat model: tools, streaming, async) or a custom LLM class over the Python SDK. Both handle x402 payments automatically across chains, agents, and RAG.

LangChain is the most popular framework for building LLM applications. BlockRun's /v1/chat/completions is already OpenAI-compatible at the protocol level; the only thing that differs is authentication — a per-request wallet signature instead of a Bearer key — and the two paths below bridge exactly that gap.

Community integration

No official langchain-blockrun package yet; use the two paths below or the BlockRun SDK directly. BlockRun's primary paths are Franklin, the MCP, and the SDKs.

Path 1 — ChatOpenAI via the BlockRun LiteLLM sidecar (recommended)

blockrun-litellm (v0.9.1) ships a local OpenAI-compatible proxy that signs x402 payments with your wallet. Any LangChain chat model that speaks the OpenAI protocol — ChatOpenAI — then works unchanged, including tool calling, streaming and async, which the string-in/string-out custom class in Path 2 cannot offer.

1
Install
pip install 'blockrun-litellm[proxy]' langchain langchain-openai
2
Start the sidecar
export BLOCKRUN_WALLET_KEY=0x...        # Base wallet; never leaves your machine
blockrun-litellm-proxy --port 4001      # → http://127.0.0.1:4001/v1

Add --api-url https://sol.blockrun.ai/api with a SOLANA_WALLET_KEY to pay on Solana. Keep the bind on loopback unless you also set BLOCKRUN_PROXY_TOKEN.

3
Point ChatOpenAI at it
from langchain_openai import ChatOpenAI

llm = ChatOpenAI(
    model="openai/gpt-5.4",                 # any BlockRun chat model id
    base_url="http://127.0.0.1:4001/v1",
    api_key="dummy",                        # ignored unless BLOCKRUN_PROXY_TOKEN is set
)

print(llm.invoke("Explain x402 in one sentence").content)

Prefer to stay in-process? pip install blockrun-litellm langchain-litellm, call from blockrun_litellm import register; register() once, and use ChatLiteLLM(model="blockrun/openai/gpt-5.4").

Path 2 — Custom LLM class over the Python SDK

No sidecar, no LiteLLM: a minimal LLM subclass over blockrun_llm.LLMClient. Text in, text out — fine for chains and RAG, not for tool-calling agents.

1
Install LangChain and the BlockRun SDK
pip install langchain langchain-core blockrun-llm
2
Define a custom LLM provider
from typing import Any, List, Optional
from langchain_core.language_models.llms import LLM
from blockrun_llm import LLMClient

class BlockRunLLM(LLM):
    """BlockRun LLM provider for LangChain."""

    model: str = "openai/gpt-5.4"
    client: Any = None

    def __init__(self, model: str = "openai/gpt-5.4", **kwargs):
        super().__init__(**kwargs)
        self.model = model
        self.client = LLMClient()   # BLOCKRUN_WALLET_KEY or ~/.blockrun/.session

    @property
    def _llm_type(self) -> str:
        return "blockrun"

    def _call(
        self,
        prompt: str,
        stop: Optional[List[str]] = None,
        **kwargs
    ) -> str:
        return self.client.chat(self.model, prompt, stop=stop)

# Usage
llm = BlockRunLLM(model="openai/gpt-5.4")

langchain_core.language_models.llms.LLM is the import that works on both LangChain 0.3 and 1.x; the old langchain.llms.base path was removed in 1.0.

Usage Examples

Basic Chain (LCEL)

Works with either path — swap llm for the ChatOpenAI instance above if you are using the sidecar.

from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser

llm = BlockRunLLM(model="anthropic/claude-sonnet-4.6")

prompt = ChatPromptTemplate.from_template("Write a brief explanation of {topic}")
chain = prompt | llm | StrOutputParser()

result = chain.invoke({"topic": "x402 micropayments"})
print(result)

Agent with Tools

Tool calling needs a chat model, so this uses Path 1. create_agent is LangChain 1.x; the sidecar forwards tools / tool_choice verbatim to the gateway.

from langchain.agents import create_agent
from langchain_openai import ChatOpenAI
from langchain_community.tools import DuckDuckGoSearchRun

llm = ChatOpenAI(model="openai/gpt-5.4", base_url="http://127.0.0.1:4001/v1", api_key="dummy")

agent = create_agent(
    model=llm,
    tools=[DuckDuckGoSearchRun()],
    system_prompt="You are a helpful assistant.",
)

result = agent.invoke({"messages": [("human", "What's the current price of ETH?")]})
print(result["messages"][-1].content)

RAG Pipeline

from langchain_chroma import Chroma
from langchain_huggingface import HuggingFaceEmbeddings
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough

llm = BlockRunLLM(model="anthropic/claude-sonnet-4.6")
embeddings = HuggingFaceEmbeddings()

vectorstore = Chroma(embedding_function=embeddings, persist_directory="./db")
retriever = vectorstore.as_retriever()

prompt = ChatPromptTemplate.from_template(
    "Answer based on context:\n{context}\n\nQuestion: {input}"
)

def format_docs(docs):
    return "\n\n".join(d.page_content for d in docs)

rag_chain = (
    {"context": retriever | format_docs, "input": RunnablePassthrough()}
    | prompt
    | llm
    | StrOutputParser()
)

print(rag_chain.invoke("How does x402 payment work?"))

Multi-Model Chains

Use different models for different tasks:

from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser

summarizer = BlockRunLLM(model="deepseek/deepseek-chat")
analyzer = BlockRunLLM(model="openai/gpt-5.4")

summary_prompt = ChatPromptTemplate.from_template("Summarize: {document}")
analysis_prompt = ChatPromptTemplate.from_template("Analyze this summary: {text}")

summary_chain = summary_prompt | summarizer | StrOutputParser()
analysis_chain = analysis_prompt | analyzer | StrOutputParser()

summary = summary_chain.invoke({"document": "..."})
analysis = analysis_chain.invoke({"text": summary})

Cost Optimization

# Use model routing based on task complexity
def get_model_for_task(task_type: str) -> str:
    if task_type == "simple":
        return "deepseek/deepseek-chat"  # $0.14/M input tokens
    elif task_type == "complex":
        return "openai/gpt-5.4"  # $2.50/M input tokens
    elif task_type == "reasoning":
        return "openai/o1"  # $15/M input tokens
    return "openai/gpt-5.4"

# Dynamic model selection
llm = BlockRunLLM(model=get_model_for_task("simple"))

Or let the SDK decide: the Python SDK's smart_chat() (bundled Router Core V3) picks the cheapest capable model per request — see Smart Routing — and the sidecar accepts blockrun/auto, blockrun/eco and blockrun/premium as model ids.

Async Support

The Python SDK ships an AsyncLLMClient with the same chat() signature:

import asyncio
from blockrun_llm import AsyncLLMClient

class AsyncBlockRunLLM(BlockRunLLM):
    aclient: Any = None

    def __init__(self, model: str = "openai/gpt-5.4", **kwargs):
        super().__init__(model=model, **kwargs)
        self.aclient = AsyncLLMClient()

    async def _acall(self, prompt: str, stop: Optional[List[str]] = None, **kwargs) -> str:
        return await self.aclient.chat(self.model, prompt, stop=stop)

# Usage
async def main():
    llm = AsyncBlockRunLLM()
    result = await llm.ainvoke("Hello!")
    print(result)

asyncio.run(main())

With Path 1, ChatOpenAI already supports ainvoke / astream.

Wallet Setup

BlockRun LLM uses your configured wallet:

export BLOCKRUN_WALLET_KEY=0x...

Or create programmatically:

from blockrun_llm import setup_agent_wallet

client = setup_agent_wallet()  # Creates ~/.blockrun/.session if none exists
print(f"Fund this address: {client.get_wallet_address()}")

See Wallet Setup.

Pricing

Same as the BlockRun API — no markup on top of the gateway price. Live prices come from https://blockrun.ai/api/v1/models; a few examples (per 1M tokens, input/output):

ModelCost
openai/gpt-4o$2.50 / $10.00
deepseek/deepseek-chat$0.14 / $0.28
anthropic/claude-sonnet-4.6$3.00 / $15.00

See Intelligence Pricing.

Links

What's next?