LangGraph পেমেন্ট ইন্টিগ্রেশন।
কোনও LangGraph প্যাকেজের প্রয়োজন নেই। একটি সাধারণ নোড বাস্তব blockchain0x ক্লায়েন্টকে কল করে, interrupt() অর্থপ্রদান ওয়েবহুক আসা পর্যন্ত স্থগিত থাকে, এবং গ্রাফ পুনরায় শুরু হয় - চালনার মধ্যে টেকসই।
LangGraph-এর জন্য আলাদা কোনো package নেই, এবং আপনারও তা দরকার নেই। আপনার -এর একটি plain node real client call করে, একটি payment webhook পৌঁছানো পর্যন্ত graph suspend করে, এবং handler LangGraph-এর নিজস্ব + দিয়ে তা resume করে। Payment Base-এ settle হয়।
টেকসই কার্যকরীতা পেমেন্টের পরে পুনরায় শুরু করার প্যাটার্নকে স্বাভাবিক করে তোলে।
এজেন্ট-চালিত পেমেন্টের কঠিন অংশ হল অ্যাসিঙ্ক গ্যাপ: আপনি পেমেন্টের জন্য অনুরোধ করেন, ক্রেতা কয়েক মিনিট পরে (অথবা কখনও নয়) পেমেন্ট করে, এবং আপনাকে যেখানে ছিলেন সেখানে অবস্থান হারিয়ে না কাজ পুনরায় শুরু করতে হবে। বেশিরভাগ এজেন্ট ফ্রেমওয়ার্ক এই গ্যাপটি পূরণ করতে একটি কাজের কিউ + ম্যানুয়াল স্টেট-স্টোরের উপর নির্ভর করে। LangGraph ইতিমধ্যে প্রাথমিকভাবে তৈরি করা হয়েছে: interrupt() একটি নোডে একটি গ্রাফ স্থগিত করে এবং একটি চেকপয়েন্টার অবস্থানটি ডিস্কে সংরক্ষণ করে। পুনরায় শুরু করা একটি কল।
রেসিপিটি বিশেষ যন্ত্রপাতি ছাড়াই এটির দিকে ঝুঁকে পড়ে। একটি সাধারণ পে নোড blockchain0x.payments.create কল করে। একটি await_settlement নোড interrupt() কল করে স্থগিত করতে, এবং চেকপয়েন্টার রাষ্ট্রটিকে স্থায়ী করে। ওয়েবহুক হ্যান্ডলার স্বাক্ষরটি যাচাই করে, গ্রাফ.updateState সহ মেলানো থ্রেডে সেটল করে, এবং ইন্টারাপ্ট থেকে চালিয়ে যেতে গ্রাফ.invoke কল করে। গ্রাফটি ঠিক যেখানে থেমেছিল সেখান থেকে শুরু করে, পূর্ববর্তী নোডগুলির যেকোন LLM প্রসঙ্গ সহ - সবই LangGraph এর নিজস্ব APIs ব্যবহার করে।
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 আপনার ড্যাশবোর্ড থেকে একটি sk_test_ testnet বা sk_live_ mainnet কী; ক্লায়েন্ট এটি পরিবেশ থেকে পড়ে। BLOCKCHAIN0X_WEBHOOK_SECRET (যা আপনি একটি ওয়েবহুক তৈরি বা রোটেট করার সময় একবার ফেরত দেয়) ওয়েবহুক পরিচালনার প্রক্রিয়ায় প্রয়োজন। যদি আপনার গ্রাফ একটি প্রক্রিয়ায় চলে এবং হ্যান্ডলার অন্য একটি প্রক্রিয়ায় চলে, তবে উভয়কেই একই চেকপয়েন্টার (যেমন শেয়ার করা Postgres) প্রয়োজন যাতে হ্যান্ডলার সাসপেন্ডেড থ্রেডটি খুঁজে পায়।
একটি তিন-নোড গ্রাফ: অর্থ প্রদান করুন, স্থগিত করুন, বিতরণ করুন।
নিচে একটি সম্পূর্ণ LangGraph ওয়ার্কফ্লো রয়েছে যার মধ্যে একটি টাইপ করা স্টেট, একটি পে নোড যা আসল blockchain0x.payments.create কল করে, একটি ইন্টারাপ্ট-ভিত্তিক await_settlement নোড, এবং একটি ডেলিভার নোড যা চেইন নিশ্চিত করার পরে নির্ভরশীল কাজ চালায় যে অর্থ স্থানান্তরিত হয়েছে।
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 দিয়ে সেটেল করে, এবং interrupt থেকে অব্যাহত রাখতে graph.invoke(null, config) কল করে। কোনো বিশেষ সহায়ক নেই - সেগুলি LangGraph-এর নিজস্ব API।
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।
আপনি যেটি মোড়াচ্ছেন ক্লায়েন্টটি খোলা। এটি পড়ুন।
এখন ক্লোন করার জন্য কোন LangGraph স্টার্টার প্যাকেজ নেই - উপরের রেসিপিটি ইন্টিগ্রেশন। blockchain0x SDK গুলি GitHub এ ওপেন সোর্স; এই রেসিপিটি Python SDK (blockchain0x-python) মোড়ানো, ডকসে সম্পূর্ণ পদ্ধতি পৃষ্ঠ সহ। নোড বডি এবং ওয়েবহুক যাচাইয়ের জন্য একটি রেফারেন্স হিসাবে এটি পড়ুন।
github.com/tosh-labs/blockchain0x-pythonপূর্ণ SDK পদ্ধতি পৃষ্ঠ এবং ওয়েবহুক স্বাক্ষর স্কিম ডকস এ নথিভুক্ত। Base Sepolia এর বিরুদ্ধে একটি sk_test_ কী দিয়ে শুরু করুন, তারপর যখন গ্রাফ আপনার প্রত্যাশা অনুযায়ী পুনরায় শুরু হয় তখন 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 জানে না। আপনার নিজস্ব ম্যাপিং রাখুন - যখন আপনি একটি গ্রাফ শুরু করেন, তখন এজেন্ট, প্রাপক, বা আপনি সেট করা একটি আইডেম্পোটেন্সি কী দ্বারা কী করা thread_id সংরক্ষণ করুন, তারপর এটি হ্যান্ডলারে খুঁজে বের করুন। উপরে threadFor() কলটি সেই অনুসন্ধান। এটি ভুল পেলে এবং graph.invoke ভুল থ্রেডে বা একটিও না ফিরে আসে।
কোন নিষ্পত্তি পথ পরিচালনা করুন, অথবা চিরকাল স্থগিত করুন।
await_settlement থেকে শর্তাধীন প্রান্ত কেবল তখনই বিতরণ করতে রাউট করে যখন সেটলড সত্য। যদি একটি পেমেন্ট কখনও না আসে, থ্রেডটি অসীম সময়ের জন্য স্থগিত থাকে। একটি টাইমআউট যোগ করুন: একটি নির্ধারিত সাফাই যা স্থির=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.