After their (misunderstood) announcement to charge 2$ for every event RSVP, meetup faced a major meltdown in trust. Thousands of developers are working on dozens of "free alternatives" for now, as many build on their take on eventbrite or any other bloated, commercial, centralized, walled garden event management software (e.g. . Being event / meetup organizers ourselves we wanted to support that movement - not by building yet another blockchain driven Solidity-CRUD but by embracing current Web2 content as much as we can.

What it does

Every platform in the event space orbits around their "RSVP", "Join" or "buy ticket" buttons. Each event has its own canonical webpage and thankfully many platforms have added compatible microdata annotations to their contents. We "trust" that data to avoid building our own event management database / crud app. Instead we're hijacking their "RSVP" buttons: our browser plugin identifies pages that represent a event and offers an user another rsvp to that event on chain. The plugin extracts definitions, pushes them onto IPFS and redirects the user to a browser only app where she can put her RSVP on the ledger (since we cannot cross-communicate with Metamask). Event hosts can discover (future: claim) their event and avoid any boarding costs by the platforms. A dedicated "wallet" Đapp displays all events that an user has signed up for.

How we built it

browser plugin - lots of chrome internals, using a webpack template and libraries for ("node-less") ipfs, injecting JS code into the target pages, fetching and pushing it to IPFS.

event anchoring - using a solidity smart contract that persists minimal events' metadata (canonical url, cid for all details) and attendee lists / rsvp state on the Ropsten testnet

event discovery - using a TheGraph ( backend that listens for event creation and attendance events emitted by our smart contract. Generates a GraphQL backend that we use for our frontend / user facing Đapps.

frontend apps ("wallets" / signin pages): create react app /w Reach Router. Ethers.js on a Metamask provider.

Challenges we ran into

The initial event "anchoring" on chain is not that simple from an user experience perspective: an event host might not be aware that we exist. Some user might be, though. If she got the plugin installed and adds the event to IPFS for the first time, it's unclear who's the "real" event owner. Anchoring the event will cost some gas to the user - who might not even have an account for Eth yet.

The original "meetup meltdown" cost critics (2$/rsvp or some higher funding on the organizer's side) is actually mirrored in our apps: users either have to pay gas to RSVP for the event or the host must use Gas Station Networks to fund initial gas supplies to make it free for everyone else.

One cannot simply access the metamask plugin and its ethereum provider / signer / wallet from within a chrome plugin. That's why we are redirecting the user to a dedicated "sign up" page that's containing a metamask context that's injected with the user's account

Event discovery cannot happen on-chain. IPFS data isn't searchable either. So we've built a integration that listens to our contract's created and rsvp'd events to generate a queryable GraphQL api.

Accomplishments that we're proud of

being completely independent from a dedicated ipfs node - our injected page script uses ipfs-js (alpha) to push data to IPFS without knowing any centralized node.

A browser plugin built on a webpack stack

Making the Graph/QL integration work

Monorepo / trunk based development without many conflicts.

What we learned

you don't need to know / run an IPFS node to push content

Metamask isn't available to plugins

Metamask plugins aren't easy to provide

What's next for Team Meeting

prior art

the idea foundation of this project has been that Stefan and 3 other team members built during EthBerlinZwei. They concentrated on the "getting into the event" part, though (which could easily be connected or added here). At Diffusion we've concentrated on the "create" and "signup" part.

Built With

Share this project: