LangGraph पेमेंट इंटिग्रेशन.
LangGraph पॅकेजची आवश्यकता नाही. एक साधा नोड वास्तविक blockchain0x क्लायंटला कॉल करतो, interrupt() पेमेंट वेबहुक लँड होईपर्यंत निलंबित राहतो, आणि ग्राफ पुन्हा सुरू होतो - चालवण्याच्या दरम्यान टिकाऊ.
LangGraph साठी कोणताही package नाही, आणि त्याची गरजही नाही. तुमच्या मधील एक साधा node खऱ्या client ला call करतो, payment webhook येईपर्यंत graph थांबवते, आणि handler LangGraph च्या स्वतःच्या + ने ते पुन्हा सुरू करतो. Payments Base वर settle होतात.
टिकाऊ कार्यान्वयन पेमेंटनंतर पुन्हा सुरू होण्याच्या पॅटर्नला नैसर्गिक बनवते.
एजंट-चालित पेमेंटचा कठीण भाग असिंक्रोनस गॅप आहे: तुम्ही पेमेंटची विनंती करता, खरेदीदार काही मिनिटांनी (किंवा कधीच नाही) पैसे देतो, आणि तुम्हाला तुमच्या स्थितीला गमावले बिना काम सुरू करावे लागते. बहुतेक एजंट फ्रेमवर्क या गॅपला भरून काढण्यासाठी जॉब क्यू + मॅन्युअल स्टेट-स्टोरवर अवलंबून असतात. LangGraph मध्ये आधीच प्राथमिकता आहे: interrupt() एक नोडवर ग्राफ निलंबित करते आणि एक चेकपॉइंटर स्थिती डिस्कवर टिकवून ठेवतो. पुन्हा सुरू करणे एक कॉल आहे.
हा recipe कोणतेही विशेष machinery न वापरता याचा फायदा घेतो. साधा pay node blockchain0x.payments.create कॉल करतो. await_settlement node suspend करण्यासाठी interrupt() कॉल करतो, आणि checkpointer state कायम ठेवतो. webhook handler signature verify करतो, graph.updateState ने जुळणाऱ्या thread वर settled सेट करतो, आणि interrupt पासून पुढे सुरू करण्यासाठी graph.invoke कॉल करतो. Graph अगदी जिथे थांबला होता तिथूनच पुढे सुरू होतो, पूर्वीच्या nodes मधील कोणताही LLM context सुद्धा तसाच राहतो - आणि हे सर्व LangGraph च्या स्वतःच्या APIs वापरून.
LangGraph आणि मुख्य SDK स्थापित करा. अतिरिक्त पॅकेज नाही.
Node 18+ आणि @langchain/langgraph 0.2+ आणि वास्तविक @blockchain0x/node क्लायंट. दोन्ही भाषेत जोडण्यासाठी LangGraph अडॅप्टर नाही - Python LangGraph वापरकर्ते langgraph आणि blockchain0x Python क्लायंट स्थापित करतात आणि त्याच रेसिपीची लेखन करतात, interrupt() आणि Command(resume=...) सह Python बाजूवर.
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 ती environment मधून वाचतो. BLOCKCHAIN0X_WEBHOOK_SECRET (webhook तयार करताना किंवा rotate करताना एकदाच परत दिलेला) webhook हाताळणाऱ्या process ला लागतो. तुमचा graph एका process मध्ये आणि handler दुसऱ्या process मध्ये चालत असेल, तर दोघांनाही तोच checkpointer (उदा. shared Postgres) लागतो, जेणेकरून handler suspended thread शोधू शकेल.
एक तीन-नोड ग्राफ: पैसे द्या, निलंबित करा, वितरित करा.
खाली typed State सह एक पूर्ण LangGraph workflow आहे, ज्यात वास्तविक blockchain0x.payments.create कॉल करणारा pay node, interrupt-आधारित await_settlement node, आणि chain ने payment move झाल्याची पुष्टी केल्यानंतर dependent work चालवणारा deliver node आहे.
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".
वेबहुक सत्यापित करा, नंतर थ्रेड पुन्हा सुरू करा.
हँडलर Node SDK मधून webhooks.verify सह स्वाक्षरीची पडताळणी करतो, तुमच्या स्वतःच्या मॅपिंगमधून निलंबित LangGraph धागा शोधतो, graph.updateState सह सेट केलेले ठरवतो, आणि व्यत्ययापासून पुढे जाण्यासाठी graph.invoke(null, config) कॉल करतो. कोणताही विशेष सहाय्यक नाही - ते LangGraph च्या स्वतःच्या APIs आहेत.
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 वर शाखा करा, कोणतीही प्रयत्न/पकड नाही. result.eventId तुम्ही निलंबित केलेल्या थ्रेडवर मॅप करा, नंतर graph.updateState + graph.invoke(null, config) कायम ठेवलेल्या चेकपॉइंटवरून पुन्हा सुरू होते आणि ग्राफ चालवतो. पाठवलेले इव्हेंट आहेत payment.received, payment.sent, wallet.deployed, आणि webhook.test.
तुम्ही लपवलेला क्लायंट ओपन आहे. त्याला वाचा.
Clone करण्यासाठी LangGraph starter package नाही - वरचा recipe हीच integration आहे. blockchain0x SDKs GitHub वर open source आहेत; हा recipe Python SDK (blockchain0x-python) wrap करतो, आणि पूर्ण method surface docs मध्ये आहे. node bodies आणि webhook verify साठी reference म्हणून ते वाचा.
github.com/tosh-labs/blockchain0x-pythonपूर्ण SDK method surface आणि webhook signature scheme यांचे दस्तऐवजीकरण the docs येथे आहे. Base Sepolia वर sk_test_ key ने सुरुवात करा, आणि graph अपेक्षेप्रमाणे पुन्हा सुरू झाल्यावर sk_live_ वर स्विच करा.
पाच LangGraph-विशिष्ट जाळे टाळा.
LangGraph चा टिकाऊ-कार्यप्रवृत्ती मॉडेल शक्तिशाली आहे परंतु त्याच्या चेकपॉइंट्स, इंटरप्ट्स, आणि स्थिती अद्यतनांभोवती स्वतःचे फूटगन्स आहेत.
LangGraph पॅकेज नाही - एक साधा नोड SDK ला कॉल करतो.
Blockchain0x LangChain आणि CrewAI साठी अडॅप्टर्स आणि MCP सर्व्हर पाठवते; येथे npm किंवा pip मध्ये कोणतीही समर्पित LangGraph पॅकेज नाही. वरील रेसिपी हा मार्ग आहे: एक सामान्य ग्राफ नोड वास्तविक @blockchain0x/node क्लायंटला कॉल करतो, आणि तुम्ही LangGraph च्या स्वतःच्या graph.updateState + graph.invoke सह पुढे जाता. येथे कोणतीही विशेष पेमेंट-नोड वर्ग नाही आणि आयात करण्यासाठी कोणतीही रिझ्युम सहाय्यक नाही - ती कधीच अस्तित्वात नव्हती.
चेकपॉइंटर गहाळ आहे
LangGraph चा interrupt() फक्त तेव्हा कार्य करतो जेव्हा ग्राफमध्ये चेकपॉइंटर असतो. त्याशिवाय, तुमची प्रक्रिया बाहेर पडताच स्थिती अदृश्य होते आणि वेबहुक हँडलरकडे पुनरारंभ करण्यासाठी कोणतीही थ्रेड नसते. विकासासाठी MemorySaver वापरा आणि उत्पादनात SqliteSaver किंवा PostgresSaver वापरा. जर तुमचा ग्राफ आणि वेबहुक हँडलर वेगवेगळ्या प्रक्रियांमध्ये चालत असतील, तर त्यांना समान चेकपॉइंटर सामायिक करावा लागेल (उदाहरणार्थ, एक Postgres) जेणेकरून हँडलर निलंबित थ्रेड शोधू शकेल.
वेबहुक योग्य थ्रेडशी मॅप करणे तुमचे काम आहे
वेबहुक तुम्हाला एक देयक निपटले आहे असे सांगते; ते तुमच्या LangGraph thread_id ला माहित नाही. तुमचे स्वतःचे मॅपिंग ठेवा - जेव्हा तुम्ही एक ग्राफ प्रारंभ करता, तेव्हा एजंट, प्राप्तकर्ता, किंवा तुम्ही सेट केलेल्या idempotency कीद्वारे की केलेले thread_id संग्रहित करा, नंतर हँडलरमध्ये ते शोधा. वरच्या threadFor() कॉल हे शोध आहे. हे चुकीचे मिळाल्यास ग्राफ.invoke चुकीच्या धाग्यावर किंवा एकदम नाहीत.
निपटारा न होणारा मार्ग हाताळा, किंवा कायमचे निलंबित करा
await_settlement कडून अटींचा कडा फक्त तेव्हा वितरित करतो जेव्हा सेट केलेले खरे आहे. जर एक देयक कधीच पोहोचत नसेल, तर धागा अनिश्चित काळासाठी निलंबित राहतो. एक टाइमआउट जोडा: एक नियोजित स्वेप जो निलंबित धाग्यांना settled=false सह पुन्हा सुरू करतो त्यामुळे कडा END कडे मार्गक्रमण करतो, किंवा एक payment.sent-versus-deadline तपासणी. एक निलंबित धागा काहीही खर्च करत नाही, परंतु तो स्वतःच कधीही संपत नाही.
रक्कम 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.