Abstraxn ships two sample projects you can clone or mirror:
SampleStackRole
Sample backend APINestJS, PostgresYour server: users, DB, @abstraxn/agent-kit, MCP + LLM
Sample web appNext.jsYour UI: login, agents, chat, portfolio
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

LayerYour projectResponsibility
DashboardAbstraxn UIAPI key, MCP URL, monitor agents
Backend APISample backend API (NestJS)Users, DB, @abstraxn/agent-kit, MCP + LLM
Web appSample web app (Next.js)Login, pick agent, chat, portfolio
InfrastructureAgent Kit hostREST + MCP + x402

Prerequisites

  1. Dashboard setup — application API key and MCP URL.
  2. SDK quickstart — understand createAgent and accessKey.
  3. Postgres (or adapt persistence) for the sample service.

Part 1 — Sample backend API (NestJS)

Install and configure

cd <your-backend-project>   # NestJS sample API
npm install
cp .env.example .env
VariableExamplePurpose
AGENT_KIT_API_KEYFrom dashboard OverviewAgentKitClient + MCP auth
AGENT_KIT_BASE_URLhttps://dev-agent-kit.abstraxn.comREST base
MCP_SERVER_URLhttps://dev-agent-kit.abstraxn.com/mcpSame as dashboard MCP URL
MCP_SERVER_AUTH_TOKENSame as AGENT_KIT_API_KEYMCP Authorization header
ENCRYPTION_KEYLong random secretEncrypt wallet.accessKey at rest
LLM_API_KEY / LLM_BASE_URL / LLM_MODELOpenRouter, etc.Chat model
JWT_SECRETRandomEnd-user sessions
POSTGRES_*Local DBAgents + chat tables
npm run start:dev   # default port 3008

Create agent — SDK + server wallet

When the UI calls POST /agents, AgentsService.create:
  1. Calls agentKitClient.createAgent({ name, description, userIdentity: userId }).
  2. Receives agent (Kit id, per-agent apiKey) and wallet (evmAddress, organizationId, accessKey).
  3. Encrypts wallet.accessKey with ENCRYPTION_KEY and saves to Postgres.
  4. Never returns accessKey in API responses.
This matches SDK quickstart. After creation, the agent appears in dashboard All agents with EVM/Solana addresses. Your production checklist:
  • Map userIdentity to your stable user id (the sample uses userId).
  • Fund the agent EVM address with native gas before transfers or x402.
  • Store agentId (Kit UUID) for MCP agent_id in tool arguments.

REST surface (your API, JWT)

MethodPathBehavior
POST/agentscreateAgent via SDK
GET/agentsList agents for logged-in user
GET/agents/:idAgent detail (no accessKey)
PATCH/agents/:idUpdate name / prompt
POST/agents/:id/register-identityBody { "chainId": … }supported chain IDs (1, 11155111, 137, 80002, 8453, 84532, 56, 97, 42161, 43114)
GET/agents/:id/identity?chainId=Read registration for one supported chain
GET/agents/assetsMulti-chain balances (Tatum)
POST/chat/sessionsNew session for agentId
POST/chat/sessions/:id/messagesSSE stream; runs LLM + MCP tools
Swagger is available when enabled in your Nest build.

MCP + LLM chat loop

McpClientService (on module init when MCP_SERVER_URL is set):
  1. initialize + notifications/initialized
  2. tools/list → cache tool schemas
  3. Expose tools to the LLM as OpenAI functions
ChatService.sendMessageStreaming:
  1. Loads session messages.
  2. Calls LLM with tool definitions.
  3. On tool call → McpClientService.callTool(name, args, paymentPayload?).
  4. For application key, include agent_id: session.agentId in args (Kit UUID from DB).
  5. Streams assistant text to the client over SSE.
Relevant files:
  • src/chat/mcp-client.service.ts
  • src/chat/chat.service.ts
  • src/chat/llm.service.ts

Transfer auto-sign (unsigned MCP → broadcast)

When the LLM calls MCP transfer, the tool returns an unsigned transaction. The sample app:
  1. Detects transfer metadata in the stream (transfer_confirmation_ui / pending transfer flow).
  2. Asks the user to confirm in the UI.
  3. AgentSigningService loads decrypted accessKey, authenticates server signer, signs and sends via viem.
See 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):
  1. AgentSigningService.createX402PaymentPayloadForAgent builds paymentPayload using the agent’s access key.
  2. Chat layer retries tools/call with top-level paymentPayload.
See x402 payments and src/chat/mcp-x402.util.ts.

Part 2 — Sample web app (Next.js)

Install and configure

cd <your-frontend-project>   # Next.js sample app
npm install
Set backend URL in lib/constants.ts:
export const API_BASE_URL = "https://your-agent-api.example.com";
npm run dev   # default http://localhost:3000

Auth

  • Email OTP or Google OAuth → auth-store JWT.
  • lib/api.ts adds Authorization: Bearer on every request to your API only.

Agents UI

FileRole
components/providers/agents-provider.tsxLoad/create agents via /agents
app/dashboard/page.tsxAgent picker + chat entry
stores/agents-store.tsSelected agent persistence
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.
  1. UI posts to Next.js app/api/chat/route.ts with Bearer JWT.
  2. Route proxies to POST /chat/sessions/:sessionId/messages on the backend with SSE.
  3. lib/chat/create-chat-session.ts creates sessions via your API.
// app/api/chat/route.ts — pattern
const upstream = await fetch(
  `${API_BASE_URL}/chat/sessions/${sessionId}/messages`,
  {
    method: "POST",
    headers: { Authorization: auth, Accept: "text/event-stream" },
    body: JSON.stringify({ content }),
  },
);

Portfolio and ERC-8004 identity

  • components/portfolio/ — balances from /agents/assets
  • RegisterIdentityModal — user picks a supported chainId; your API posts { "chainId": … } to /agents/:id/register-identity (full list)
  • RegisterIdentityFundRequiredModal — prompts to fund the agent EVM wallet when gas is insufficient
  • AgentIdentityDetails — global id, on-chain agent id, registry, owner, explorer links
  • useAgentIdentity / lib/fetch-agent-identity.ts — load identity from your backend (proxies Agent Kit)
Your API must decrypt accessKey and call @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

Dashboard screenYour implementation
Overview API keyAGENT_KIT_API_KEY, MCP_SERVER_AUTH_TOKEN
Overview MCP URLMCP_SERVER_URL
All agents tableRows from your DB after createAgent
Identity tabmetadata.erc8004 after registerAgentIdentity
Activity log tabMCP tool call logs for that agent
Tools catalogSame tools McpClientService discovers

Security model

Application API key, MCP token, ENCRYPTION_KEY, and LLM keys live only in backend env. The web app holds the user JWT only.
Losing accessKey means you cannot sign transfers or x402 for that agent. Encrypt the DB column; never expose in GET /agents/:id.
Always proxy tool execution through your backend so keys and paymentPayload signing stay server-side.

Customize for production

Sample choiceAlternative
userIdentity: userIdEmail, external id
OpenRouterAzure OpenAI, Anthropic via compatible proxy
Tatum balancesYour indexer
Next.js /api/chat BFFSSE from API + CORS
Single AGENT_KIT_API_KEYPer-agent apiKey for MCP