Together they show the full path from dashboard credentials to a user-facing agent with chat, portfolio, and on-chain actions. Folder names in your monorepo may differ; the patterns below apply to any backend and frontend you build.
What you are building
Prerequisites
- Dashboard setup — application API key and MCP URL.
- SDK quickstart — understand
createAgentandaccessKey. - Postgres (or adapt persistence) for the sample service.
Part 1 — Sample backend API (NestJS)
Install and configure
Create agent — SDK + server wallet
When the UI callsPOST /agents, AgentsService.create:
- Calls
agentKitClient.createAgent({ name, description, userIdentity: userId }). - Receives
agent(Kit id, per-agentapiKey) andwallet(evmAddress,organizationId,accessKey). - Encrypts
wallet.accessKeywithENCRYPTION_KEYand saves to Postgres. - Never returns
accessKeyin API responses.
- Map
userIdentityto your stable user id (the sample usesuserId). - Fund the agent EVM address with native gas before transfers or x402.
- Store
agentId(Kit UUID) for MCPagent_idin tool arguments.
REST surface (your API, JWT)
Swagger is available when enabled in your Nest build.
MCP + LLM chat loop
McpClientService (on module init when MCP_SERVER_URL is set):
initialize+notifications/initializedtools/list→ cache tool schemas- Expose tools to the LLM as OpenAI functions
ChatService.sendMessageStreaming:
- Loads session messages.
- Calls LLM with tool definitions.
- On tool call →
McpClientService.callTool(name, args, paymentPayload?). - For application key, include
agent_id: session.agentIdin args (Kit UUID from DB). - Streams assistant text to the client over SSE.
src/chat/mcp-client.service.tssrc/chat/chat.service.tssrc/chat/llm.service.ts
Transfer auto-sign (unsigned MCP → broadcast)
When the LLM calls MCPtransfer, the tool returns an unsigned transaction. The sample app:
- Detects transfer metadata in the stream (
transfer_confirmation_ui/ pending transfer flow). - Asks the user to confirm in the UI.
AgentSigningServiceloads decryptedaccessKey, authenticates server signer, signs and sends via viem.
src/agents/agent-signing.service.ts and src/agents/pending-transfer.service.ts.
x402 in chat (paid_fetch, get_token_price)
When MCP returns payment required (-32402 or paymentRequired):
AgentSigningService.createX402PaymentPayloadForAgentbuildspaymentPayloadusing the agent’s access key.- Chat layer retries
tools/callwith top-levelpaymentPayload.
src/chat/mcp-x402.util.ts.
Part 2 — Sample web app (Next.js)
Install and configure
lib/constants.ts:
Auth
- Email OTP or Google OAuth →
auth-storeJWT. lib/api.tsaddsAuthorization: Beareron every request to your API only.
Agents UI
Creating an agent in the UI →
POST /agents on your backend → SDK createAgent → dashboard All agents updates on refresh.
Chat (BFF)
The browser never calls Agent Kit or the LLM directly.- UI posts to Next.js
app/api/chat/route.tswith Bearer JWT. - Route proxies to
POST /chat/sessions/:sessionId/messageson the backend with SSE. lib/chat/create-chat-session.tscreates sessions via your API.
Category specialist agents
The sample web app supports predefined specialist agents viaserviceAgent on chat requests (or the category picker in the UI). Each specialist filters MCP tools and injects focused system prompts.
Example: open chat as Portfolio & Price with
?serviceAgent=portfolio.
Portfolio and ERC-8004 identity
components/portfolio/— balances from/agents/assetsRegisterIdentityModal— user picks a supportedchainId; your API posts{ "chainId": … }to/agents/:id/register-identity(full list)RegisterIdentityFundRequiredModal— prompts to fund the agent EVM wallet when gas is insufficientAgentIdentityDetails— global id, on-chain agent id, registry, owner, explorer linksuseAgentIdentity/lib/fetch-agent-identity.ts— load identity from your backend (proxies Agent Kit)
@abstraxn/agent-kit registerAgentIdentity (or Kit REST prepare/confirm). The browser never signs registration transactions directly.
Full standard and dashboard parity: ERC-8004 agent identity.
Transaction history
hooks/use-agent-transactions.ts— on-chain transfer history helpers
Part 3 — Map dashboard UI to your code
Security model
Secrets stay on your backend API
Secrets stay on your backend API
Application API key, MCP token,
ENCRYPTION_KEY, and LLM keys live only in backend env. The web app holds the user JWT only.accessKey is the signing root
accessKey is the signing root
Losing
accessKey means you cannot sign transfers or x402 for that agent. Encrypt the DB column; never expose in GET /agents/:id.Do not call MCP from the browser
Do not call MCP from the browser
Always proxy tool execution through your backend so keys and
paymentPayload signing stay server-side.