Introducing Towns Academy ๐ซ
Discover a dynamic hub where anyone can dive into creating bots with Towns Protocol. Start with a intro course or use AI to vibe-code whatever you can imagine.
Let's explore whatโs new ๐จ๐ปโ๐ป
Build a Space list for the current user with Towns React SDK.
List: useUserSpaces() returns spaceIds.
Resolve: Pass each ID to useSpace(spaceId).
Render: Read the Space name from its metadata.
$TOWNS
Two ways to connect a Sync Agent to Towns.
Signer: connect(signer, config).
Token: connectUsingBearerToken(token, config).
Hook: useAgentConnection() exposes both methods, plus disconnect().
$TOWNS
Large media does not have to ride inside one message.
Stream: Towns supports media as a separate stream.
Chunks: Nodes store indexed byte chunks for client pagination.
Context: The current schema can link media to a channel, Space or user.
$TOWNS
Towns uses two registries for two different coordination jobs.
Node Registry: Manages node onboarding and monitoring on Base.
Stream Registry: Records stream locations and state on Towns Chain.
Together: They coordinate node assignments for streams.
$TOWNS
A Towns bot can ask for structured input inside a channel.
Form: sendInteractionRequest() supports buttons and text inputs.
Audience: Target one user or leave the form public.
Response: onInteractionResponse() handles the submitted values.
$TOWNS
Towns governance has a public proposal process.
Discuss: Ideas can develop before a vote.
Vote: Token voting makes decisions publicly verifiable.
Track: Towns Lodge exposes proposals, discussions and voters.
$TOWNS
Towns gives client builders one resolver across four room types.
Input: getRoom(sync, streamId).
Output: Space, channel, DM or group DM.
Boundary: An unsupported stream ID returns an invalid room type error.
$TOWNS
A Towns bot can request a transaction. The userโs wallet signs it.
Request: The bot supplies chain, target, value and call data.
Wallet: It can require one signer or leave wallet choice to the user.
Response: The bot receives a transaction hash or an error.
$TOWNS
A Towns miniblock header gives clients a compact proof path.
Link: It references the previous header and block events.
Proof: It carries a vote proof and leader signature.
Check: A matching header hash on Towns Chain lets the client treat it as final.
$TOWNS
A Towns Space can opt out of protocol upgrades.
Proxy: A Diamond proxy keeps state and routes calls.
Facets: Modular contracts hold specific functions.
Choice: Facets can be added, replaced or removed, while Spaces retain an opt-out.
$TOWNS
A Towns bot can execute a batch of onchain calls atomically.
Account: The bot app address is a SimpleAccount.
Bundle: ERC-7821 execute() accepts a calls array.
Outcome: Every operation succeeds, or all fail.
$TOWNS
One Towns access rule can check assets across supported EVM chains.
Check: Ethereum, Optimism, Arbitrum and Polygon are documented.
Use: Checks can gate Read, Write or Mint.
Boundary: Channel creation and role assignment rely on Base assets.
$TOWNS
A Towns Mini App can open inside a conversation and write back to it.
Context: It receives the channel ID and optional Space ID.
Compose: actions.composeCast supports text and embeds.
Wallet: It can access the connected Towns Smart Wallet provider.
$TOWNS
A Towns Space can change hands.
Create: A Space on Base mints an ERC-721 owner token to its creator.
Control: The Space contract recognizes the token holder as owner.
Transfer: Move the token to another wallet, a multisig or a DAO.
$TOWNS
Every Towns event is signed.
Identity: The creator address identifies the user or Stream Node.
Delegate: An optional delegate signature links a separate device key to the primary wallet.
Validate: Stream Nodes check the signature before processing the event.
$TOWNS
A webhook can become a channel message.
Route: Add a custom endpoint beside the reserved Towns webhook.
Call: Use sendMessage() outside a Towns event handler.
Schedule: Intervals or cron jobs can push periodic updates.
$TOWNS
Start building on Towns with one command.
Run: bun create towns-protocol-app my-app
Scaffold: The recommended starter creates a React project with Towns dependencies and configuration.
Build: Connect, create a Space and send a message with the React SDK.
$TOWNS
Access control has two parts.
Roles: Bundle permissions such as read, write, react or modify channels.
Entitlements: Determine who is eligible for a role at Space or channel level.
Checks: Addresses, ENS names and onchain assets can qualify.
$TOWNS
After encryption, what happens to a message?
Validate: Stream Nodes check encrypted messages against protocol rules.
Assemble: Messages are grouped into linked mini-blocks.
Coordinate: Nodes sequence and distribute the stream.
$TOWNS
Onchain does not mean public conversation.
In Towns, memberships and permissions are verifiable onchain. Message content stays end-to-end encrypted between senders and entitled recipients.
Public rules. Private conversation.
$TOWNS