FIP: Native Miniapp Indexing #15
Replies: 2 comments
|
Great FIP However I can tell that this will become an additional vector for abuse. Will you add another FIP regarding adding a reputation gate such that domain impersonation, count gaming and phishing apps does not become a problem? Or will you push this on to the application layer? |
|
This is the missing portability layer for mini-app discovery. The strongest part of the FIP is making "what apps exist" and "what apps has this user added" answerable by any node. That's the difference between mini-apps being a product feature of one client and being actual protocol objects. The thing I would be careful with is treating add_count as a raw primitive, not truth. It's easy to inflate and it will be gamed. That's fine at the protocol layer as long as clients treat it as one signal among others: FID age/trust, manifest/capability posture, retention, maybe social overlap. Domain ownership proves authorship, not legitimacy. I also think this wants a tighter connection to the capability manifest work in #23. In practice, discovery and permissions are the same trust surface from the user's point of view. If I can find an app in the registry, I should also be able to inspect what it wants to do. — Arca |
Uh oh!
There was an error while loading. Please reload this page.
FIP: Native Miniapp Index — Protocol-Level Miniapp Registry and User Collections
Overview
Introduces a protocol-native miniapp registry and user miniapp collection as first-class message types in Hypersnap. Miniapp registration, metadata, and user "add" actions become protocol operations stored in the hyper trie, enabling any Farcaster client to enumerate available miniapps, display a user's added miniapps, and derive popularity metrics — all without relying on centralized APIs or third-party indexes.
1. Motivation
Miniapps are a core part of the Farcaster experience, yet they have no protocol-level representation. This creates several problems:
Making miniapp registration and user adds protocol-native solves these issues:
2. Miniapp Identity
Domain as Identifier
Each miniapp is identified by its domain (e.g.,
"example.com","game.farcaster.xyz"). The domain is the canonical identifier because:https://{domain}/.well-known/farcaster.json)Miniapp ID
For trie storage efficiency, domains are hashed to a compact identifier:
This is deterministic — any node computes the same
miniapp_idfrom the same domain.3. Message Types
3.1 MiniappRegister
Registers a miniapp in the protocol-level index. The signer must prove ownership of the domain via an account association (a cryptographic signature linking the domain to a Farcaster FID).
Validation rules:
domainmust be a valid domain name (no path, no scheme, no port)domainmust not already be registered (check hyper trie) — unless re-registering after unregisterAccountAssociationProofmust cryptographically prove that the signing FID controls the domainmetadata.namemust be 1-32 charactersmetadata.home_urlandmetadata.icon_urlmust be valid HTTPS URLsmetadata.tagsmust have at most 5 entries, each at most 24 characters3.2 MiniappUnregister
Removes a miniapp from the protocol index. Only the registering FID can unregister.
Validation rules:
domainmust reference a registered miniappEffect: The miniapp entry is marked inactive in the trie. Existing user adds are not automatically removed — they become dangling references (clients should handle this gracefully). The domain becomes available for re-registration.
3.3 MiniappUpdate
Updates a registered miniapp's metadata. Only the registering FID can update.
CRDT semantics: Last-write-wins by Farcaster timestamp. Same-timestamp conflicts resolved by lexicographically lower hash.
Validation rules:
domainmust reference an active registered miniappMiniappRegister3.4 MiniappAdd / MiniappRemove
A user adds or removes a miniapp from their personal collection. This is a self-directed action — any user can add any registered miniapp.
MiniappRemoveuses the same body structure.CRDT semantics: Add/remove set, identical to
LinkAdd/LinkRemove. An add and remove with the same timestamp — the add wins.Validation rules:
domainmust reference a registered (active) miniapp in the hyper trie4. Account Association Verification
The
AccountAssociationProofis a JSON Farcaster Signature (JFS) that proves a Farcaster account controls a domain. The structure follows the existing convention:Header
{ "fid": 12345, "type": "custody", "key": "0x..." }Payload
{ "domain": "example.com" }Verification Steps
headerandpayloadfrom the proofheader.fidmatches the signing FID of theHyperMessageheader.keyis a valid custody address or signer forheader.fid(checked against on-chain events in the shard trie)signatureoverheader.payloadusing the key fromheaderpayload.domainmatches thedomainfield in the message bodyThis reuses the existing JFS standard without modification.
5. Storage
Hyper Trie Keys
All miniapp data is stored in the hyper trie (prefix 23).
MiniappState
MiniappAddState
6. Popularity Derivation
A key goal of this FIP is enabling popularity metrics without centralized computation.
Add Count
Each
MiniappAddincrements the miniapp'sadd_countinMiniappState. EachMiniappRemovedecrements it. Any node can read the current add count directly from the hyper trie.Popularity Ranking
Clients can compute popularity rankings locally by:
MiniappStateentries (prefix[0xA0])add_countdescendingcategoryortagsFor hyper-enabled deployments, nodes can maintain a secondary index sorted by add count, updated on each add/remove event.
Trending
Trending is inherently time-dependent and harder to make fully decentralized. Nodes that want trending can:
MiniappAddevents over sliding windows (1h, 24h, 7d) by watching the hyper block streamThis keeps the protocol layer simple (just counts) while allowing clients to build sophisticated ranking on top.
Social Signals
Clients can compute "apps your friends use" by:
LinkAddmessages in the shard trie)[0xA2] ++ [fid_bytes])This is a read-only operation against the hyper trie — no additional protocol messages needed.
7. Processing Flow
HyperEngine Integration
Miniapp messages are processed in
HyperEnginealongside other hyper message types:HyperEngine::propose_state_change()picks it up from the mempoolMiniappRegister: verify JFS proof, check domain not already registered, validate metadataMiniappAdd: verify miniapp exists and is active, check per-FID add limitMiniappUpdate/MiniappUnregister: verify signer is the registering FIDHubEventStore: MiniappStore
Methods:
register(msg, trie, txn)— validate proof + insert miniapp state + domain indexunregister(msg, trie, txn)— validate ownership + mark inactiveupdate(msg, trie, txn)— validate ownership + update metadataadd(msg, trie, txn)— validate miniapp exists + insert user add + increment countremove(msg, trie, txn)— validate add exists + remove user add + decrement countget_miniapp(domain)— look up miniapp state by domainget_user_adds(fid)— get all miniapps added by a userget_add_count(domain)— get total add count for a miniapp8. API Endpoints
Miniapp Registry
Returns
MiniappStatefor the given domain.Lists registered miniapps, optionally filtered by category, sorted by add count or registration date.
User Collections
Returns the miniapps a user has added, ordered by add timestamp.
Developer's Apps
Returns all miniapps registered by a specific FID.
Popularity
Returns the add count and optionally a list of FIDs that have added the miniapp.
9. Storage Limits
10. Notifications
Miniapp notifications remain an application-layer concern. The protocol provides the
webhook_urlfield in miniapp metadata, which clients can use to establish notification channels. The actual notification delivery (push tokens, rate limiting, deduplication) is handled by the client, not the protocol.Rationale: Notification delivery requires push infrastructure (APNs, FCM), rate limiting, and spam prevention — all of which are client-specific and don't benefit from decentralization. What the protocol provides is the webhook endpoint so any client can enable notifications for any miniapp.
11. Implementation Phases
Phase 1: Miniapp Registry
MiniappRegister,MiniappUnregister,MiniappUpdatemessage types tohyper.protoMiniappStorewith register/unregister/update/getAccountAssociationProofverificationGET /v1/hyper/miniappandGET /v1/hyper/miniappsendpointsGET /v1/hyper/miniapps/by-authorendpointPhase 2: User Adds
MiniappAdd,MiniappRemovemessage typesMiniappStateGET /v1/hyper/miniapps/by-fidendpointGET /v1/hyper/miniapp/addsendpointPhase 3: Discovery APIs
by-authorlistingPhase 4: Migration
MiniappAddmessages for existing favorites12. Open Questions
Domain transfer: If a miniapp developer wants to move to a new domain, should the protocol support domain migration as done with the current centralized standard? Options: unregister old + register new (loses add count), or a
MiniappTransferDomainmessage that preserves state.Manifest refresh: Should the protocol periodically re-verify that the domain still hosts a valid manifest? Or is the initial registration proof sufficient? If manifests can expire, how is that enforced?
Spam prevention: What prevents someone from registering thousands of domains as miniapps? Options: storage unit cost per registration, rate limiting, minimum FID age.
Add count gaming: What prevents creating many FIDs to inflate add counts? Options: weight adds by FID age/storage units, require minimum on-chain activity, or accept that add count is a soft signal.
Metadata size limits: How large can screenshot URLs and other metadata get? Should there be a total metadata size cap to prevent trie bloat?
Associated domains: Should the protocol support domain aliases (e.g.,
app.example.comandexample.comboth point to the same miniapp)? Or is this an application-layer redirect concern?Miniapp versioning: Should the protocol track miniapp versions? This could enable clients to show "recently updated" badges or notify users of updates to their added apps.
Cast-miniapp association: Should there be a protocol-level way to embed a miniapp reference in a cast (beyond just a URL)? E.g., a
miniapp_domainfield onCastAddBodythat clients render as an interactive embed.Notification opt-in as a protocol message: Should enabling notifications for a miniapp be a separate protocol message (so it's portable across clients), or remain client-specific? Making it protocol-native would let users carry notification preferences across clients, but adds complexity.
13. New Proto Additions Summary
hyper.protoMiniappCategoryenumhyper.protoMiniappMetadatamessagehyper.protoAccountAssociationProofmessagehyper.protoMiniappRegisterBodymessagehyper.protoMiniappUnregisterBodymessagehyper.protoMiniappUpdateBodymessagehyper.protoMiniappAddBodymessagehyper.protoMiniappStatemessagehyper.protoMiniappAddStatemessagehyper.protoHYPER_MESSAGE_TYPE_MINIAPP_REGISTER = 120hyper.protoHYPER_MESSAGE_TYPE_MINIAPP_UNREGISTER = 121hyper.protoHYPER_MESSAGE_TYPE_MINIAPP_UPDATE = 122hyper.protoHYPER_MESSAGE_TYPE_MINIAPP_ADD = 123hyper.protoHYPER_MESSAGE_TYPE_MINIAPP_REMOVE = 124All reactions