@towns-labs/app-framework
v7.1.0
Published
An app framework for Towns.
Readme
@towns-labs/app-framework
An app framework for Towns.
Installing
We suggest users to quickstart a project using our cli.
$ bunx towns-agent initIf you prefer to install manually:
$ bun add @towns-labs/app-framework viem honoUsage
With Node:
import { makeTownsApp } from "@towns-labs/app-framework";
import { serve } from "@hono/node-server";
const app = new Hono();
const townsApp = await makeTownsApp("<app-private-data-base64>");
townsApp.onMessage((handler, { channelId, isMentioned }) => {
if (isMentioned) {
handler.sendMessage(channelId, "Hello, world!");
}
});
const { jwtMiddleware, handler } = townsApp.start();
app.post("/webhook", jwtMiddleware, handler);
serve({ fetch: app.fetch });With Bun:
import { makeTownsApp } from "@towns-labs/app-framework";
const app = new Hono();
const townsApp = await makeTownsApp("<app-private-data-base64>");
townsApp.onMessage((handler, { channelId, isMentioned }) => {
if (isMentioned) {
handler.sendMessage(channelId, "Hello, world!");
}
});
const { jwtMiddleware, handler } = townsApp.start();
app.post("/webhook", jwtMiddleware, handler);
export default app;Identity Metadata (ERC-8004)
Apps can optionally define ERC-8004 compliant identity metadata for discovery and trust.
Minimal Example
Create identity.ts:
import type { AppIdentityConfig } from "@towns-labs/app-framework";
const identity = {
name: "My App",
description: "A helpful app for Towns",
image: "https://example.com/app-logo.png",
domain: "myApp.example.com",
} as const satisfies AppIdentityConfig;
export default identity;Use in app setup:
import identity from "./identity";
const townsApp = await makeTownsApp(process.env.APP_PRIVATE_DATA!, {
commands,
identity,
});
// Get metadata for hosting at /.well-known/agent-metadata.json
const metadata = townsApp.getIdentityMetadata();
app.get("/.well-known/agent-metadata.json", metadata);Advanced Example
For full ERC-8004 compliance with endpoints and trust models:
import type { AppIdentityConfig } from "@towns-labs/app-framework";
const identity = {
name: "Advanced App",
description: "AI-powered app with multi-protocol support",
image: "https://example.com/app-logo.png",
motto: "Building the future of agent economies",
domain: "app.example.com",
endpoints: [
{
name: "A2A",
endpoint: "https://app.example.com/.well-known/agent-card.json",
version: "0.3.0",
},
{
name: "MCP",
endpoint: "https://mcp.app.example.com/",
version: "2025-06-18",
},
],
registrations: [],
supportedTrust: ["reputation", "crypto-economic"],
attributes: [
{ trait_type: "Category", value: "Gateway" },
{ trait_type: "Model", value: "GPT-4" },
],
} as const satisfies AppIdentityConfig;
export default identity;The app automatically adds agentWallet endpoint using the app's address and A2A endpoint if domain is configured.
Debug Logging
App framework uses debug package for logging.
You can enable by setting the DEBUG environment variable to csb:agent.
DEBUG=csb:agent node dist/agent.cjs