メインコンテンツにスキップ
LANGGRAPH統合

LangGraph支払い統合。

LangGraphパッケージは必要ありません。プレーンノードが実際のblockchain0xクライアントを呼び出し、interrupt()が支払いWebhookが到着するまで停止し、グラフが再開します - 実行を通じて耐久性があります。

短い回答

LangGraph 専用パッケージはありませんし、必要もありません。 内の通常の node が実際の client を呼び出し、 が payment webhook 到着まで graph を一時停止し、handler が LangGraph 独自の + で再開します。支払いは Base で決済されます。

LANGGRAPHがこのパターンに適している理由

耐久性のある実行により、支払い後の再開パターンが自然になります。

エージェント駆動の支払いの難しい部分は非同期のギャップです:支払いをリクエストし、購入者が数分後に支払う(または支払わない)と、あなたはどこにいたかの状態を失うことなく作業を再開しなければなりません。ほとんどのエージェントフレームワークは、このギャップを埋めるためにジョブキュー + 手動の状態ストアに依存しています。LangGraphには、すでに組み込まれたプリミティブがあります:interrupt()はノードでグラフをサスペンドし、チェックポインタは状態をディスクに保持します。再開は1回の呼び出しです。

このレシピは特別な仕組みなしでそれを活かします。通常の pay ノードが blockchain0x.payments.create を呼びます。await_settlement ノードは interrupt() を呼んで停止し、checkpointer が state を保持します。webhook handler は署名を検証し、graph.updateState で一致する thread を settled に設定し、graph.invoke を呼んで interrupt から続行します。graph は、前のノードの LLM context を含め、停止した位置から正確に再開します - すべて LangGraph の API だけで実現しています。

インストール

LangGraphとコアSDKをインストールします。追加のパッケージはありません。

Node 18+と@langchain/langgraph 0.2+、および実際の@blockchain0x/nodeクライアント。どちらの言語にも追加するLangGraphアダプターはありません - Python LangGraphユーザーはlanggraphとblockchain0x Pythonクライアントをインストールし、同じレシピを書きます。Python側ではinterrupt()とCommand(resume=...)を使用します。

インストール
npm install @langchain/langgraph @blockchain0x/node
環境変数
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 は dashboard の sk_test_ testnet または sk_live_ mainnet キーで、client は環境変数から読み込みます。BLOCKCHAIN0X_WEBHOOK_SECRET (webhook を作成またはローテーションしたときに 1 回だけ返されます) は webhook を処理するプロセスで必要です。graph が 1 つのプロセスで動作し、handler が別のプロセスで動作する場合は、handler が中断された thread を見つけられるように、両者で同じ checkpointer (例: shared Postgres) が必要です。

完全なグラフの例

3ノードのグラフ:支払い、一時停止、配信。

以下は完全な LangGraph workflow です。typed State、実際の blockchain0x.payments.create を呼び出す pay node、interrupt ベースの await_settlement node、そして chain が payment の移動を確認したら依存処理を実行する deliver node を含みます。

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".

ウェブフック処理

Webhookを確認し、その後スレッドを再開します。

ハンドラーはNode SDKのwebhooks.verifyを使用して署名を検証し、あなた自身のマッピングからサスペンドされたLangGraphスレッドを検索し、graph.updateStateでsettledを設定し、interruptから続けるためにgraph.invoke(null, config)を呼び出します。特別なヘルパーはありません - それらはLangGraphの独自のAPIです。

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はRAWボディに対して定数時間でHMAC-SHA256を行い、識別されたユニオンを返します - result.okで分岐し、try/catchはありません。result.eventIdを一時停止したスレッドにマッピングし、次にgraph.updateState + graph.invoke(null, config)が永続化されたチェックポイントから再開し、グラフが配信を実行します。出荷されたイベントはpayment.received、payment.sent、wallet.deployed、webhook.testです。

ソースとドキュメント

ラップしているクライアントはオープンです。読んでください。

クローンする LangGraph の starter package はありません - 上の recipe がそのまま integration です。blockchain0x の SDK は GitHub で open source です。この recipe は Python SDK (blockchain0x-python) をラップしており、完全なメソッド一覧は docs にあります。node body と webhook verify の参考として読んでください。

github.com/tosh-labs/blockchain0x-python

SDK のメソッド一覧と webhook の署名方式は the docs に記載されています。まずは Base Sepolia で sk_test_ key を使い、graph が想定どおり再開したら sk_live_ に切り替えてください。

一般的な落とし穴

LangGraphに特有の避けるべき5つの罠。

LangGraphの耐久実行モデルは強力ですが、チェックポイント、中断、および状態更新に関する独自のリスクがあります。

PITFALL 1

LangGraphパッケージはありません - プレーンノードがSDKを呼び出します。

Blockchain0xは、LangChainとCrewAI用のアダプタとMCPサーバーを出荷します。npmやpipには専用のLangGraphパッケージはありません。上記のレシピはパスです:通常のグラフノードが実際の@blockchain0x/nodeクライアントを呼び出し、LangGraphの独自のgraph.updateState + graph.invokeで再開します。特別なペイメントノードクラスやインポートするための再開ヘルパーはありません - それらは存在しませんでした。

PITFALL 2

チェックポインターがありません

LangGraphのinterrupt()は、グラフにチェックポインタがある場合にのみ機能します。チェックポインタがない場合、プロセスが終了すると状態が消失し、Webhookハンドラには再開するスレッドがありません。開発にはMemorySaverを使用し、本番ではSqliteSaverまたはPostgresSaverを使用します。グラフとWebhookハンドラが異なるプロセスで実行される場合、同じチェックポインタ(例: 1つのPostgres)を共有する必要がありますので、ハンドラがサスペンドされたスレッドを見つけることができます。

PITFALL 3

Webhookを正しいスレッドにマッピングするのはあなたの仕事です

Webhookは、支払いが決済されたことを知らせます; あなたのLangGraph thread_idは知りません。自分のマッピングを保持してください - グラフを開始するとき、エージェント、受取人、または設定したアイデンポテンシーキーによってキー付けされたthread_idを保存し、ハンドラーでそれを検索します。上記のthreadFor()呼び出しがその検索です。これを間違えると、graph.invokeは間違ったスレッドを再開するか、まったく再開しません。

PITFALL 4

決済なしのパスを処理するか、永遠に保留します

await_settlementからの条件付きエッジは、settledがtrueのときのみ配信するようにルーティングされます。支払いが決済されない場合、スレッドは無期限にサスペンドされたままになります。タイムアウトを追加します:settled=falseで古いスレッドを再開するスケジュールされたスイープを追加し、エッジがENDにルーティングされるか、payment.sentと締切のチェックを行います。サスペンドされたスレッドは何もコストがかかりませんが、自分自身で終了することもありません。

PITFALL 5

金額はUSDCの基本単位であり、文字列として表されます

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.

よくある質問

LangGraphに特有の質問が3つ。

npmまたはpipにLangGraphパッケージはありますか?

いいえ。LangGraphはすでにすべてを提供します:ノードは単なる関数で、interrupt()が停止し、チェックポインタが持続し、graph.updateState + graph.invokeが再開します。したがって、正直な道は、実際の@blockchain0x/nodeクライアント(またはPython blockchain0xクライアント)を呼び出すプレーンノードです。出荷されたフレームワークパッケージはblockchain0x-langchainとblockchain0x-crewai(両方ともPython)および@blockchain0x/mcpサーバーのみです。

Python LangGraphでもこれを行えますか?

はい、同じ recipe です。Python LangGraph には同じ primitive があります - function node, interrupt(), checkpointer、そして続行用の Command(resume=...) または update_state + invoke です。node は Python の blockchain0x client (blockchain0x.payments.create(...)) を呼び、webhook handler は署名を検証して thread を再開します。langgraph と blockchain0x 以外にインストールする pip package はありません。graph definition は TypeScript 版とほぼ同じです。

これはLangGraphプラットフォームおよびヒューマンインザループノードで動作しますか?

はい。レシピはプレーンLangGraphであるため、LangGraphプラットフォームで同じように実行されます - あなたのBlockchain0x webhookをデプロイメントに向けて、そこでスレッドを再開します。interrupt()は、1つのグラフ内で複数の中断ポイントをサポートします:Webhookによって再開された支払い中断とUIアクションによって再開されたhuman_review中断は、各再開が状態の独自のフィールドを更新する限り、並行して存在できます。グラフはそれらを順番にルーティングします。

グラフに耐久性のある支払いを追加します。

支払い時に一時停止し、Webhookで再開します。すべてLangGraphの独自のAPIで。無料で開始できます。