Build an Onchain Agent-Earning Workflow with BNB Agent Studio v2 & LangGraph
BNB Agent Studio v2 lets agents get hired and paid onchain; wrap the ERC-8183 hire-to-settlement flow in a LangGraph state machine with a human approval gate and Altana wallet limits.
Deepak Bagada
CEO, SaaSNext
- BNB Agent Studio v2 closes the earn gap: agents expose an ERC-8183 payments receiving interface and settle x402 payments straight into their own wallet.
- Altana self-custodial wallets enforce spending limits, allowlists, and time bounds onchain, revocable instantly with no key rotation.
- The LangGraph human approval gate between work execution and settlement is what keeps autonomous earning from becoming ungoverned spending.
- BSC Testnet plus the v2 Paymaster makes the full hire-to-settlement loop free to validate before mainnet.
By Deepak Bagada, CEO at SaaSNext & Principal AI Architect.
When BNB Agent Studio launched in July 2026, it solved the hardest onboarding problem in web3 agents: describe an agent in plain English and it ships to BNB Smart Chain with an identity, a wallet, an LLM connection, and a cloud runtime. But the agent's relationship with money was one-way. It could spend — pay for LLM calls, buy data, settle tool fees — yet it could not earn. BNB Agent Studio v2, live since August 19, 2026, closes that gap. Agents can now be hired, complete work, and get paid onchain, with funds settling directly into their own wallet through the ERC-8183 commerce flow, end to end.
This dispatch builds the complete earning pipeline: an agent deployed through BNB Agent Studio v2, orchestrated by LangGraph with explicit human approval gates, registered under an ERC-8004 agent identity, exposed through the ERC-8183 task interface, and paid through the ERC-8183 payments receiving interface into an Altana self-custodial wallet with onchain spending limits and allowlists. Development runs on BSC Testnet where the Paymaster covers gas, so you can validate the whole hire-to-settlement loop before pointing the same agent at mainnet. TypeScript is the implementation language here because that is the other headline of v2, but every pattern maps one-to-one onto the Python SDK.
What Changed in BNB Agent Studio v2
The jump from v1 to v2 is a permission expansion: from "agents that spend" to "agents that earn and operate inside verifiable bounds." Four changes matter for anyone building agent commerce:
- Earning surfaces. A seller agent exposes a standard x402 receiving interface. A buyer pays, x402 settles, and the seller receives — no invoicing or billing infrastructure on the agent side, completing ERC-8183 from work to wallet settlement.
- Altana self-custodial wallets. Agents act through scoped session keys with spending limits, allowlists, and time bounds set before the agent does anything. Permissions are registered onchain rather than in a config file, so anyone can verify what an agent may do, and authority is revocable instantly without key rotation or downtime.
- TypeScript support. v2 ships an npm SDK and
bag initscaffolding, so TypeScript developers get the full stack without touching Python. - Paymaster on BSC Testnet. Gas is covered during development, removing the faucet trip and manual wallet funding step that previously stalled testnet work.
That combination turns "autonomous agent" from a demo that talks to a model into a machine that takes on work, does it, and gets paid for it — with money movements enforced by the chain rather than by trust in the operator. For the surrounding pattern catalog, the Daily AI World workflows library tracks these commerce and automation reference architectures as they stabilize.
Architecture: Hire-to-Settlement Graph
The workflow is a single LangGraph state machine with a human-in-the-loop gate in the middle. A hire request is matched to the agent's ERC-8004 identity, a task contract is written onchain via the ERC-8183 task interface, LangGraph executes the work through bounded tool calls, a human approves the payable outcome, and x402 settles payment into the Altana wallet before the graph tops up LLM credits and closes the ledger.
┌──────────────────────────────┐
│ Hire Request Received │
└──────────────┬───────────────┘
│ match ERC-8004 identity
▼
┌──────────────────────────────┐
│ ERC-8183 Task Contract │
│ scope · price · deadline │
└──────────────┬───────────────┘
│
┌──────────────▼───────────────┐
│ LangGraph Orchestrator │
│ plan → tool calls → verify │
└──────────────┬───────────────┘
│
┌──────────────▼───────────────┐
│ Human Approval Gate │── no ──► abort/refund
│ (payable actions) │
└──────────────┬───────────────┘
yes │
▼
┌──────────────────────────────┐
│ Execute Work + Evidence │
│ (tool calls, artifact hash) │
└──────────────┬───────────────┘
│
┌──────────────▼───────────────┐
│ ERC-8183 Invoice / Receipt │
└──────────────┬───────────────┘
│ x402 settlement
▼
┌──────────────────────────────┐
│ x402 Payment + LLM Top-up │
│ ledger write · final report │
└──────────────────────────────┘
Every edge is checkpointable. If the runtime restarts mid-task, LangGraph resumes from the last completed node, and because the task contract is onchain, the graph can re-derive truth from chain state instead of trusting local memory.
Prerequisites and Project Layout
Install the CLI, scaffold the agent, and confirm it is registered before writing orchestration code:
npm i -g @bnb-chain/bag-cli
bag init onchain-earner
cd onchain-earner
bag agent create --name research-bot --wallet altana --testnet
bag agent deploy --runtime aws-agentcore --testnet
Then scaffold the orchestration project:
onchain-earner/
├── .env # keys, limits, provider config
├── types.ts # ERC-8183/8004 types + Altana policy + graph state
├── tools.ts # LangChain tool wrappers over the onchain contract
├── graph.ts # LangGraph orchestrator with approval gate
└── main.ts # entrypoint with checkpointer
Environment Configuration
.env keeps keys and limits out of the code and mirrors the Altana policy you set when creating the agent:
# .env
BAG_TESTNET=true
BAG_RPC_URL=https://bsc-testnet-rpc.publicnode.com
AGENT_OWNER_KEY=0x... # builder keeps the key; agent never holds it
ALTANA_SPENDING_LIMIT_BNB=0.05 # per-transaction cap, enforced onchain
ALTANA_ALLOWLIST=0x1111...,0x2222... # only these addresses can receive funds
ALTANA_TIME_BOUND_SECONDS=3600 # session keys expire
LLM_PROVIDER=pieverse
LLM_API_KEY=pv_live_...
AWS_AGENTCORE_ROLE=arn:aws:iam::...:role/agentcore-agent
Never commit this file. The Altana policy is also re-registered onchain, so these .env values are the development mirror of what anyone can verify on-chain — the graph reads them, the chain enforces them.
TypeScript Types
types.ts defines the ERC-8004 identity, the ERC-8183 task contract, and the graph state with its approval flag:
// types.ts
import { Annotation } from "@langchain/langgraph";
export interface AgentIdentity {
agentId: string; // ERC-8004 onchain agent identity
owner: string;
registry: string; // where the identity is registered
}
export type TaskStatus = "created" | "approved" | "in_progress" | "delivered";
export interface TaskContract {
taskId: string; // ERC-8183 task interface id
scope: string; // description of the deliverable
priceWei: string; // agreed payout
deadlineEpoch: number;
status: TaskStatus;
}
export interface AltanaPolicy {
spendingLimitWei: string;
allowlist: string[]; // allowed recipient addresses
timeBoundSeconds: number;
}
export const AgentState = Annotation.Root({
hire: Annotation<string>,
identity: Annotation<AgentIdentity>,
task: Annotation<TaskContract>,
approved: Annotation<boolean>,
receipts: Annotation<string[]>,
llmCreditsAfter: Annotation<string>,
});
Tool Wrappers
tools.ts wraps the contract calls the agent is allowed to make. The wrapper layer is also where the allowlist is double-checked client-side, even though Altana enforces it onchain:
// tools.ts
import { tool } from "@langchain/core/tools";
import { z } from "zod";
const POST = { method: "POST", headers: { "Content-Type": "application/json" } };
export const createTask = tool(
async ({ scope, priceWei, deadlineEpoch }) => {
const res = await fetch("https://api.bnb-agent-studio.dev/tasks", {
...POST,
body: JSON.stringify({ scope, priceWei, deadlineEpoch }),
});
if (!res.ok) throw new Error(`task create failed: ${res.status}`);
return (await res.json()).taskId;
},
{
name: "erc8183_create_task",
description: "Create an ERC-8183 task contract for a hire request.",
schema: z.object({ scope: z.string(), priceWei: z.string(), deadlineEpoch: z.number() }),
}
);
export const settlePayment = tool(
async ({ taskId, recipient }) => {
// x402 flow: quote -> authorize -> settle into the Altana wallet.
const res = await fetch("https://api.bnb-agent-studio.dev/x402/settle", {
...POST,
body: JSON.stringify({ taskId, recipient }),
});
if (!res.ok) throw new Error(`settlement failed: ${res.status}`);
return (await res.json()).txHash;
},
{
name: "erc8183_settle_payment",
description: "Complete x402 settlement for a delivered ERC-8183 task.",
schema: z.object({ taskId: z.string(), recipient: z.string() }),
}
);
export const topUpLLM = tool(
async ({ amountWei }) => {
// Pay the LLM provider via the x402 protocol so the agent stays funded.
const res = await fetch("https://api.bnb-agent-studio.dev/x402/topup", {
...POST,
body: JSON.stringify({ amountWei }),
});
if (!res.ok) throw new Error(`top-up failed: ${res.status}`);
return (await res.json()).balanceAfter;
},
{
name: "x402_topup_llm_credits",
description: "Top up LLM credits through the x402 payment protocol.",
schema: z.object({ amountWei: z.string() }),
}
);
The LangGraph Orchestrator
graph.ts wires the nodes and inserts the human approval gate between work execution and settlement:
// graph.ts
import { END, START, StateGraph } from "@langchain/langgraph";
import { AgentState, type TaskContract } from "./types.ts";
import { createTask, settlePayment, topUpLLM } from "./tools.ts";
async function planWork(state) {
const identity = await registry.lookup(state.hire); // ERC-8004
return { identity };
}
async function createTaskContract(state) {
const taskId = await createTask.invoke({
scope: state.hire,
priceWei: process.env.HIRE_PRICE_WEI!,
deadlineEpoch: Math.floor(Date.now() / 1000) + 3600,
});
const task: TaskContract = {
taskId, scope: state.hire, priceWei: process.env.HIRE_PRICE_WEI!,
deadlineEpoch: 0, status: "created",
};
return { task };
}
async function executeWork(state) {
// Bounded tool loop for the actual deliverable; failures route to retry.
return { task: { ...state.task, status: "delivered" } };
}
async function requireApproval(state) {
if (!state.approved) {
// Human gate: pause here, resume only after explicit approval.
throw new ApprovalRequired(state.task.taskId);
}
return {};
}
async function settleAndTopUp(state) {
const txHash = await settlePayment.invoke({
taskId: state.task.taskId,
recipient: state.identity.agentId,
});
const balance = await topUpLLM.invoke({ amountWei: "100000000000000" });
return { receipts: [...state.receipts, txHash], llmCreditsAfter: balance };
}
export const graph = new StateGraph(AgentState)
.addNode("plan", planWork)
.addNode("contract", createTaskContract)
.addNode("work", executeWork)
.addNode("approval", requireApproval)
.addNode("settle", settleAndTopUp)
.addEdge(START, "plan")
.addEdge("plan", "contract")
.addEdge("contract", "work")
.addEdge("work", "approval")
.addEdge("approval", "settle")
.addEdge("settle", END)
.compile();
Entry Point
main.ts compiles the graph with a checkpointer so threads resume across restarts:
// main.ts
import "dotenv/config";
import { InMemorySaver } from "@langchain/langgraph";
import { graph } from "./graph.ts";
const config = { configurable: { thread_id: "hire-0001" } };
const result = await graph.invoke(
{ hire: "Compile a competitive teardown of BSC lending protocols" },
config
);
console.log("=== SETTLEMENT ===");
console.log(JSON.stringify(result.receipts, null, 2));
Run it with npm run dev, and approve the payable action when the graph pauses at the human gate.
Retry Rules
Every layer of the workflow has an explicit, bounded policy:
| Layer | Trigger | Action | Cap |
|---|---|---|---|
| RPC/transport | HTTP 429 or 5xx | Exponential backoff with jitter, 2**attempt s |
4 attempts |
| Graph | Tool throws or empty result | Re-queue node at Work | MAX_ATTEMPTS = 3 |
| Onchain | Gas estimate failure or reverted tx | Re-simulate with bumped gas, then re-submit | 2 submissions |
| x402 | Payment quote stale | Re-quote, re-authorize, settle | 3 attempts |
| Settlement | Receipt not confirmed in 5 blocks | Poll with 2 s backoff, then re-queue | 6 polls |
Deliberately not auto-retried: anything with side effects after partial success. A delivered task with an unconfirmed receipt must be reconciled by a human before re-submitting, because double-settlement on ERC-8183 is the worst failure mode in this class of workflow.
TWAK vs Altana: Which Wallet?
| TWAK (Trust Wallet AgentKit) | Altana (Smart Agentic Wallet) | |
|---|---|---|
| Custody | Self-custodial, keys never in plaintext | Self-custodial, builder holds the keys |
| Permissions | Continuous autonomous signing | Scoped session keys: limits, allowlists, time bounds |
| Verifiability | Not registered onchain | Permissions onchain, auditable by anyone |
| Revocation | Key rotation | Instant, no rotation or downtime |
| Best for | 24/7 autonomous operators | Agents that must prove their authority |
For an earning agent, Altana is the default: the same chain that pays you can also prove what you are allowed to do with the money.
Operating Notes
Three things break in production. First, gas estimation on a busy testnet: re-simulate before every payable tool and treat a reverted estimate as a retry class, not a crash. Second, the approval gate is the control surface: bind it to a real review queue — a webhook, a Slack approve/deny, or a CLI prompt — and log the actor. Auto-publishing payable actions is the top incident class in agent commerce. Third, cost accounting: the agent both earns and spends, so log every receipt against both the task id and the LLM top-up balance to keep chargebacks honest.
Start by proving the loop with the Paymaster on testnet and a single deliverable. Then widen the allowlist, raise the spending limit, and point the agent at mainnet with a real hire. If you standardize the tool layer as MCP servers before wiring external clients, our MCP directory shows the registration pattern. And because BSC moves fast — more registered AI agents than any other network, per BNB Chain — track the platform on the latest AI news page before committing to version-locked features.
The pattern — onchain identity, a task contract, a human approval gate, and x402 settlement — is the shape of most earning agents in 2026. LangGraph gives you the state; ERC-8183 gives you the money path.
FAQ
What exactly is ERC-8183?
ERC-8183 is the onchain commerce and escrow standard behind BNB Agent Studio v2. It defines a task interface an agent advertises for work and a payments receiving interface that completes the flow from hire to settlement. A buyer pays via x402 and funds land in the agent's wallet without any billing infrastructure on the seller side.
Is the Altana wallet really controlled by me?
Yes. The builder keeps the keys and the agent never holds them. The agent acts through scoped session keys with spending limits, allowlists, and time bounds that are registered onchain, so anyone can verify the agent's authority, and you can revoke it instantly with no key rotation.
Do I need Python for BNB Agent Studio v2?
No. v2 ships a TypeScript SDK installed from npm with bag init scaffolding. The Python packages and CLI work exactly as before, so you can pick either stack.
How do I test without spending real BNB?
Build on BSC Testnet. The v2 Paymaster covers gas, so there is no faucet trip and no manual wallet funding step. Run the full hire-to-settlement loop for free, then re-point the same agent at mainnet.
Where does the human approval gate go?
Between work execution and settlement. The graph pauses at the approval node with the task id and price in context; a human approves or denies before any x402 payment is authorized. That single gate keeps autonomous earning from becoming ungoverned spending.
Enjoyed this breakdown? Get our morning dispatch in your inbox.
Curated breakdowns of frontier model architectures and compute markets delivered every weekday. Zero fluff.
Deepak Bagada
CEO, SaaSNext
Deepak Bagada is the CEO of SaaSNext and founder of Daily AI World. He covers AI workflows, agentic automation, LLM architectures, and founder growth strategies.
Build an OpenClaw Multi-Agent Platform Workflow with LangGraph
Next Story →Build an MCP-Connected Test Automation Workflow with QF-Test 11.0.1 & Claude Code
Related Intelligence Analysis
The Step-by-Step Guide to Automating Meeting Tasks with Whisper
You're spending 45 minutes after every client meeting typing up notes and manually assigning tasks in Jira. This guide shows you how to wire OpenAI Whisper and Claude to automatically convert meeting recordings into assi...
Lovable AI UI-to-Code Pipeline: 2026 Tutorial
Lovable AI UI-to-code automation pipeline uses Lovable AI on Lovable Cloud to convert visual UI designs and natural language specs into production-grade web applications. UI/UX designers and frontend developers bridging...
Claude Code's New Browser: 5 Workflows That Save Hours Daily
Claude Code's built-in browser is a sandboxed tabbed browser inside the Claude Code desktop app (Week 28, July 2026) accessible via Cmd+Shift+B (macOS) or Ctrl+Shift+B (Windows). It lets Claude open websites, read docume...