Ir para o conteúdo principal
INTEGRAÇÃO LANGGRAPH

Integração de pagamento LangGraph.

Nenhum pacote LangGraph necessário. Um nó simples chama o cliente blockchain0x real, interrupt() suspende até que o webhook de pagamento chegue, e o gráfico retoma - durável entre execuções.

RESPOSTA CURTA

Não existe um pacote específico para LangGraph, e você não precisa de um. Um node simples no seu chama o cliente real , um suspende o grafo até o webhook de pagamento chegar, e o handler o retoma com os próprios + do LangGraph. Os pagamentos são liquidados na Base.

POR QUE A LANGGRAPH SE ADEQUA A ESTE PATRÃO

A execução durável torna o padrão de retomar após o pagamento natural.

A parte difícil dos pagamentos impulsionados por agentes é a lacuna assíncrona: você solicita o pagamento, o comprador paga minutos depois (ou nunca), e você precisa retomar o trabalho sem perder o estado de onde estava. A maioria dos frameworks de agentes depende de uma fila de trabalho + armazenamento de estado manual para preencher essa lacuna. O LangGraph já possui o primitivo embutido: interrupt() suspende um gráfico em um nó e um checkpointer persiste o estado no disco. Retomar é uma chamada.

A receita aproveita isso sem nenhuma maquinaria especial. Um node pay simples chama blockchain0x.payments.create. Um node await_settlement chama interrupt() para suspender, e o checkpointer persiste o estado. O handler de webhook verifica a assinatura, define settled na thread correspondente com graph.updateState e chama graph.invoke para continuar a partir do interrupt. O graph retoma exatamente de onde parou, incluindo qualquer contexto de LLM dos nodes anteriores - tudo usando as próprias APIs do LangGraph.

INSTALAÇÃO

Instale LangGraph e o SDK principal. Nenhum pacote extra.

Node 18+ e @langchain/langgraph 0.2+ mais o cliente real @blockchain0x/node. Não há adapter de LangGraph para adicionar em nenhuma das linguagens - usuários de LangGraph em Python instalam langgraph e o cliente Python do blockchain0x e escrevem a mesma receita, com interrupt() e Command(resume=...) no lado Python.

INSTALAR
npm install @langchain/langgraph @blockchain0x/node
VARIÁVEIS DE AMBIENTE
export BLOCKCHAIN0X_API_KEY=sk_test_...        # sk_test_ = Base Sepolia, sk_live_ = Base mainnet
export BLOCKCHAIN0X_WEBHOOK_SECRET=...          # for the webhook handler

BLOCKCHAIN0X_API_KEY é uma chave sk_test_ de testnet ou sk_live_ de mainnet do seu painel; o cliente a lê do ambiente. BLOCKCHAIN0X_WEBHOOK_SECRET (retornado uma única vez quando você cria ou rota um webhook) é necessário no processo que trata webhooks. Se o seu grafo roda em um processo e o handler em outro, ambos precisam do mesmo checkpointer (por exemplo, um Postgres compartilhado) para que o handler possa localizar a thread suspensa.

EXEMPLO COMPLETO DE GRÁFICO

Um gráfico de três nós: pagar, suspender, entregar.

Abaixo está um workflow completo de LangGraph com um State tipado, um nó pay que chama o blockchain0x.payments.create real, um nó await_settlement baseado em interrupt e um nó deliver que executa o trabalho dependente assim que a chain confirma que o pagamento foi movimentado.

GRAPH.TS
import { StateGraph, START, END, MemorySaver, interrupt, Annotation } from "@langchain/langgraph";
import { createClient } from "@blockchain0x/node";

const blockchain0x = createClient({ apiKey: process.env.BLOCKCHAIN0X_API_KEY! });

const State = Annotation.Root({
  agentId: Annotation<string>(),
  to: Annotation<string>(),
  amountWei: Annotation<string>(), // USDC base units: "10000" = 0.01 USDC
  settled: Annotation<boolean>(),
});

// A plain node that calls the real SDK. No dedicated package needed.
async function pay(state: typeof State.State) {
  await blockchain0x.payments.create({
    agentId: state.agentId,
    to: state.to,
    amountWei: state.amountWei,
  });
  return {};
}

// Suspend the graph until the payment.sent webhook resumes this thread.
function awaitSettlement() {
  interrupt("awaiting on-chain settlement");
  return {};
}

async function deliver() {
  // Funds have moved - do the work that depended on the payment.
  return {};
}

const graph = new StateGraph(State)
  .addNode("pay", pay)
  .addNode("await_settlement", awaitSettlement)
  .addNode("deliver", deliver)
  .addEdge(START, "pay")
  .addEdge("pay", "await_settlement")
  .addConditionalEdges("await_settlement", (s) => (s.settled ? "deliver" : END))
  .addEdge("deliver", END)
  .compile({ checkpointer: new MemorySaver() });

When the graph runs, the pay node submits the USDC transfer through the SDK. The await_settlement node calls interrupt(), which suspends the graph and persists state via the checkpointer. The conditional edge waits to be told settled=true before routing to deliver; if settlement never lands, a timeout sweep routes it to END. amountWei is base units, so 0.01 USDC is "10000".

MANUSEIO DE WEBHOOK

Verifique o webhook, depois retome o thread.

O manipulador verifica a assinatura com webhooks.verify do SDK Node, procura a thread LangGraph suspensa em seu próprio mapeamento, define settled com graph.updateState e chama graph.invoke(null, config) para continuar a partir da interrupção. Nenhum helper especial - essas são as próprias APIs do LangGraph.

WEBHOOK.TS
import express from "express";
import { webhooks } from "@blockchain0x/node";
import { graph } from "./graph";

const app = express();
// Capture the RAW body. The HMAC is over the exact bytes on the wire.
app.use(express.raw({ type: "application/json" }));

app.post("/webhooks/payment", async (req, res) => {
  const result = webhooks.verify({
    headers: req.headers,
    rawBody: req.body, // Buffer, raw bytes
    secret: process.env.BLOCKCHAIN0X_WEBHOOK_SECRET!,
  });
  if (!result.ok) return res.status(400).json({ code: result.code });

  if (result.eventType === "payment.sent") {
    // You map the event to the suspended graph thread (your own store).
    const config = { configurable: { thread_id: threadFor(result.eventId) } };
    await graph.updateState(config, { settled: true });
    await graph.invoke(null, config); // resume from the interrupt
  }
  res.status(200).send("ok");
});

webhooks.verify faz HMAC-SHA256 em tempo constante sobre o corpo raw e retorna uma união discriminada - ramifique em result.ok, sem try/catch. Mapeie result.eventId para a thread que você suspendeu, então graph.updateState + graph.invoke(null, config) retoma do ponto de verificação persistido e a execução do gráfico entrega. Os eventos enviados são payment.received, payment.sent, wallet.deployed e webhook.test.

FONTE E DOCUMENTOS

O cliente que você está envolvendo é aberto. Leia-o.

Não existe um starter package do LangGraph para clonar - a receita acima é a integração. Os SDKs da blockchain0x são open source no GitHub; esta receita encapsula o Python SDK (blockchain0x-python), com a superfície completa de métodos na documentação. Leia como referência para os corpos dos nodes e a verificação do webhook.

github.com/tosh-labs/blockchain0x-python

A superfície completa de métodos do SDK e o esquema de assinatura do webhook estão documentados em the docs. Comece com uma chave sk_test_ na Base Sepolia e depois mude para sk_live_ quando o graph retomar da forma que você espera.

ARMADILHAS COMUNS

Cinco armadilhas específicas do LangGraph a evitar.

O modelo de execução durável do LangGraph é poderoso, mas tem suas próprias armadilhas em torno de pontos de verificação, interrupções e atualizações de estado.

PITFALL 1

Não há pacote LangGraph - um nó simples chama o SDK

Blockchain0x envia adaptadores para LangChain e CrewAI, além do servidor MCP; não há um pacote dedicado do LangGraph, no npm ou pip. A receita acima é o caminho: um nó gráfico comum chama o cliente real @blockchain0x/node, e você retoma com o próprio graph.updateState + graph.invoke do LangGraph. Não há uma classe especial de nó de pagamento e nenhum helper de retomar para importar - esses nunca existiram.

PITFALL 2

Checkpointer ausente

O interrupt() do LangGraph só funciona se o gráfico tiver um checkpointer. Sem um, o estado evapora quando seu processo sai e o manipulador de webhook não tem nenhuma thread para retomar. Use MemorySaver para desenvolvimento e SqliteSaver ou PostgresSaver em produção. Se seu gráfico e manipulador de webhook forem executados em processos diferentes, eles devem compartilhar o mesmo checkpointer (por exemplo, um Postgres) para que o manipulador possa encontrar a thread suspensa.

PITFALL 3

Mapear o webhook para a thread certa é seu trabalho.

O webhook informa que um pagamento foi liquidado; ele não conhece seu thread_id do LangGraph. Mantenha seu próprio mapeamento - quando você inicia um gráfico, armazene thread_id indexado pelo agente, o destinatário ou uma chave de idempotência que você definir, e então procure-a no manipulador. A chamada threadFor() acima é essa busca. Se você errar isso, graph.invoke retoma a thread errada ou nenhuma.

PITFALL 4

Gerencie o caminho sem liquidação, ou suspenda para sempre

A borda condicional de await_settlement roteia para entregar somente quando settled é verdadeiro. Se um pagamento nunca chega, a thread permanece suspensa indefinidamente. Adicione um tempo limite: uma varredura agendada que retoma threads obsoletas com settled=false para que a borda roteie para END, ou uma verificação de payment.sent-versus-deadline. Uma thread suspensa não custa nada, mas também nunca termina por conta própria.

PITFALL 5

Os valores são unidades base de USDC, como strings

payments.create takes amountWei: a string of USDC base units (6 decimals), so 0.01 USDC is "10000" and 5 USDC is "5000000". It also does not retry by default and can answer 503 until the chain adapter is wired for your network. Handle that in the pay node - route to END or a retry node on error rather than letting the graph wedge.

PERGUNTAS FREQUENTES

Três perguntas específicas sobre LangGraph.

Há um pacote LangGraph, no npm ou pip?

Não. O LangGraph já te dá tudo: um nó é apenas uma função, interrupt() suspende, um checkpointer persiste, e graph.updateState + graph.invoke retomam. Portanto, o caminho honesto é um nó simples que chama o cliente real @blockchain0x/node (ou o cliente blockchain0x Python), como mostrado acima. Os únicos pacotes de framework enviados são blockchain0x-langchain e blockchain0x-crewai (ambos Python) além do servidor @blockchain0x/mcp.

Posso fazer isso no Python LangGraph também?

Sim, a mesma receita. Python LangGraph tem as mesmas primitivas - um function node, interrupt(), um checkpointer e Command(resume=...) ou update_state + invoke para continuar. Seu nó chama o cliente Python de blockchain0x (blockchain0x.payments.create(...)), e seu handler de webhook verifica a assinatura e retoma a thread. Não há pacote pip adicional para instalar além de langgraph e blockchain0x; a definição do grafo é praticamente idêntica à versão em TypeScript.

Isso funciona com a Plataforma LangGraph e nós com humanos no loop?

Sim. A receita é LangGraph simples, então ela funciona da mesma forma na LangGraph Platform - aponte seu webhook Blockchain0x para a implantação e retome a thread lá. interrupt() também suporta vários pontos de interrupção em um gráfico: uma interrupção de pagamento retomada pelo webhook e uma interrupção de revisão humana retomada por uma ação da interface do usuário podem coexistir, desde que cada retome atualize seu próprio campo no estado. O gráfico roteia através deles em ordem.

Adicione pagamentos duráveis ao seu gráfico.

Pausar no pagamento, retomar no webhook, tudo com as próprias APIs do LangGraph. Livre para começar.