Cabin encourages coliving in nature for creators and remote workers.
The Census is Cabin’s membership directory.
Production environment: https://app.cabin.city Dev environment: https://cabin-census-dev.vercel.app/
Make sure you are using the right node version. We recommend using nvm
to manage node versions.
nvm use
Install dependencies:
npm install
Copy the .env.example
file to .env
and fill in the values.
cp .env.example .env
npm run dev
Open http://localhost:3000 with your browser to see the result.
Follow these instructions
to create an API key and set the NEXT_PUBLIC_GOOGLE_MAPS_API_KEY
env var.
Make sure foundry is updated: https://book.getfoundry.sh/getting-started/installation
You can install the lastest version with curl -L https://foundry.paradigm.xyz | bash
Helpful commands:
- format:
npm run lint:contracts:fix
(update .sol files to adhere to styling rules) - install:
forge install
install Solidity dependencies - test:
forge test
(optionally add-v
through-vvvv
for failure message verbosity)
This Smart Contract is used to manage the Unlock hooks for the Cabin app. See the Unlock Protocol documentation here for more information. You can run.
This Smart Contract is used to mock the Cabin Token contract. It is used for testing purposes only.
When working on a new feature, follow these steps:
- Create a new branch from
dev
- Make your changes
- Create a PR to
dev
- This will create a preview deployment on Vercel
- Once the PR is approved, merge it into
dev
- This will also run migrations, if any, so that the database is up to date
- The changes will be live on the dev environment: https://cabin-census-dev.vercel.app/
- Once the changes are tested and ready to be deployed to production, create a PR from
dev
tomain
- Make sure you double check all the changes previously merged to
dev
- Make sure you double check all the changes previously merged to
- Once the PR is approved, merge it into
main
and push it- Migrations will be run against the production database
The following custom events are being tracked:
- share: it tracks when a user shares a profile
- sign_in_click: when a user clicks the sign in button
- vote_modal_click: triggered when a user clicks the vote button
- contact_steward_click: tracked when a user clicks the contact caretaker button
- apply_to_event_click: tracked when a user clicks on the apply now button
- external_link_click: generic event to track external URLs such as discord, twitter, notion docs, etc.
- react_to_post: tracked when a user reacts to a post (like or unlike)
- mint_button: tracked when a user clicks on the citizenship mint button
- view_city_directory: tracked when a user clicks on the view city directory button. Optionally,
it can track an specific listing by passing the
listing_id
as a parameter. - view_events: tracked when a user clicks on the view events button. Optionally, it
can track an specific listing by passing the
event_id
as a parameter. - nav_bar_click: tracked when a user clicks on any of the nav bar links
- faqItemExpand: tracked when a user expands a FAQ item
- role_cards_slideshow: whenever a user clicks on the next or previous button on the role cards slideshow
- found_citizen_learn_more: tracked when a user clicks on the learn more button on the found citizen section
- signal_interest: tracked when a user clicks on the signal interest button
- citizenship_share_discord: tracked when a user clicks on the share on discord button
- subscribe_to_newsletter: tracked when a user subscribes to the newsletter
Removed for now. It's lazy-universal-dotenv dependency had an ancient dotenv version and broke our env var loading
Storybook is used to document and develop UI components. To run storybook:
npm run storybook
Since this app is dependent on data coming from outside sources, it is sometimes necessary to walk through some manual steps in a local or dev environment in order to set up a prod-like experience.
- Reset the database
bin/run_script reset-db.ts
- Create one or more profiles by going through onboarding
- To be able to test citizenship flows, you need to have one account that already has a citizenship NFT. You can do this via Airdrop via Unlock.
- To test the Citizenship/Unlock modal locally, run ngrok and update the
NEXT_PUBLIC_VERCEL_URL
environment variablengrok http 3000
The sync jobs that support this app are somewhat complicated so we're documenting some important notes about how they work and how to test them.
Each sync job is run periodically on its own cron schedule. See vercel.json
for cron
configuration.
A sync job is invoked by calling its respective endpoint, e.g. /api/sync/cabin-token
.
Sync attempts target a specific block range. Block ranges are used when synchronizing directly from on-chain data sources (cabin token) and also from subgraphs (hats, otterspace).
Sync attempts are locked via the Fauna database to prevent duplicate jobs from colliding with one another and to facilitate retries in the case of failures.
Synchronized data is expected to work at the Account
level, meaning a registered Profile
does
not need to exist in order for data to be imported. This allows synchronized data to be available to
end users immediately after their Profile
is created.
New Profile
for Account
with prior cabinTokenBalance
- Run the
/sync/cabin-token
job until an account is created that has acabinTokenBalance
greater than zero. - Create a new profile, either through onboarding or using the
createProfile
mutation. - Verify the
cabinTokenBalanceInt
on theProfile
is an accurate integer representation of the 18-decimal balance.
New Profile
for Account
with prior badges
- Run the
/sync/otterspace-badges
job until an account is created that has badges. - Create a new profile, either through onboarding or using the
createProfile
mutation. - Verify the
badgeCount
on theProfile
matches the number of badges owned by theAccount
.
Existing Profile
with updated cabinTokenBalance
- Create a new
Profile
that is associated with anAccount
that does not yet have acabinTokenBalance
or has a balance that has recently changed on-chain. - Run
/sync/cabin-token
until theAccount
has acabinTokenBalance
. - Verify the
cabinTokenBalanceInt
on theProfile
is an accurate integer representation of the 18-decimal balance.
Existing Profile
with updated badges
- Create a new
Profile
that is associated with anAccount
that does not yet havebadges
or hasbadges
that have recently been changed on-chain. - Run
/sync/otterspace-badges
until theAccount
has the updatedbadges
. - Verify the
badgeCount
on theProfile
matches the number of badges owned by theAccount
.
# Login if not already logged in
vercel login
# Deploy to dev
vercel
# Deploy to prod
vercel --prod
TODO
To generate GQL code for Hats and Otterspace synced data, run:
npm run codegen
To generate the smart contract types:
- get ABI file for the contract you want from Etherscan and put it in the
lib/abi
dir- eg go to https://etherscan.io/address/0x1934e252f840aa98dfce2b6205b3e45c41aef830#code, scroll down to Contract ABI and export in JSON format
- run
npm run contract:gen
, which puts generated files intogenerated/contract
dir