OtterFi

Developers

A high-level look at how Verify and Notify are built - useful context, not an implementation manual.

Coming Soon

A public API for programmatic access to your own community's data is on the roadmap but not available yet.

Two products, one platform

Verify and Notify are built and run independently, sharing only the top-level account a community belongs to. Neither one depends on the other's data or uptime - Verify reads chain state directly for its own needs rather than relying on Notify's own event pipeline, since the two products have different correctness requirements.

Notify architecture

Notify is a one-directional pipeline:

  1. Provider adapters watch OpenSea and on-chain activity for your tracked collection.
  2. Every real event is normalized into one common shape, regardless of source.
  3. Matching destinations (your Telegram group, your Discord channel) are resolved.
  4. Bursts of related activity are aggregated so you don't get flooded.
  5. The event is formatted for the destination's platform and chosen notification style.
  6. Delivery happens over that platform's own API.

Verify architecture

Verify's job is a single decision, made repeatedly: does this wallet still satisfy this community's Access Policy? The flow:

  1. A member proves control of a wallet (connect, or self-transfer).
  2. The Verification Engine independently re-confirms that proof.
  3. The wallet's real, current on-chain holdings are read directly.
  4. The Access Policy is evaluated against those holdings.
  5. A Grant Adapter applies the result - a Discord role, a Discord channel, or a Telegram invite.

Verification Engine

The Verification Engine is a small, pluggable registry of ownership-proof methods (today: connect-wallet and self-transfer). Whatever triggers a re-check - a schedule, a manual command, or an on-chain event via Live Membership - always funnels into the exact same evaluation logic. A trigger is only ever treated as a hint about when to check, never as the answer itself.

Event pipeline

Both products are built around domain events rather than direct calls between components - an event is persisted, and whatever needs to react to it (a notification formatter, a dirty-membership check) does so independently. This keeps the two products, and the pieces within each one, loosely coupled.

Platform adapters

Telegram and Discord are each implemented as an adapter behind a common interface, for both message delivery and access-granting. Adding a future platform means implementing that one interface, not changing how either product's core logic works.