About
Simple implementation of ERC20 token-gating GitHub repositories.
Fueled by Mike's tweet.
Implementation
- Users login with GitHub OAuth, we store their
access token
to take actions on their behalf.
- Users can create new Gates for their repositories, specifying contract address, number of tokens needed, and number of invites to open. In the back-end, token name + decimals, and current latest block number is stored.
- Users can share links to Gates.
- Upon accessing a Gate invitation, users can sign-in with GitHub (again giving us their
access token
). Then, they connect their wallet and sign a message to verify ownership for our back-end.
- Finally, in
/api/gates/access
we run a multi-step process:
- Check that requesting user is authenticated
- Check that all parameters have been posted (address, signature, gated repo ID)
- Verify address ownership by matching address to signature
- Check if gated repo by ID exists
- Check if gated repo has available open invitations
- Check if address held necessary balance at block number
- Check if we have access token for requesting user
- Check if requesting user is not already a collaborator on private repo
- Check if we have access token for private repo owner
- Send invite from owner to requesting user to join private repo
- Accept invite from owner via requesting user to join private repo
- Increment number of used invites (decreasing available slots)
Build and run locally
# Collect repo
git clone https://github.com/anish-agnihotri/GateRepo
cd GateRepo
# Install dependencies
npm install
# Update environment variables
cp .env.sample .env
vim .env
# Run application
npm run dev
Environment variables
-
NEXTAUTH_URL
: Site link, http://localhost:3000
if developing locally, https://gaterepo.com
for this deployed instance
-
NEXTAUTH_SECRET
: Any randomly generated string as a secret, e.g.: NpUFdWakhCjbuIIogCvj
-
GITHUB_CLIENT_ID
and GITHUB_CLIENT_SECRET
: Follow the instructions here for spinning up a new GitHub OAuth application. When asked, the authorization callback URL is http://localhost:3000/api/auth/callback/github
(local) or https://your_domain.com/api/auth/callback/github
(deployed). Once setup, your OAuth applications Client ID
is your GITHUB_CLIENT_ID
and your Client Secret
is your GITHUB_CLIENT_SECRET
-
DATABASE_URL
: Postgres database connection URL
-
RPC_API
: Any Ethereum Mainnet JSON-RPC endpoint
Limitations
- GitHub API has a rate-limit of sending a maximum of 50 invitations for a repository per 24 hour period.
- Application does not run a scheduled job to check continuing token ownership (to remove users who transfer their tokens). This is deferred to the user if desired functionality.
- Application currently only supports ERC20 tokens but is easily extensible to other token formats by updating the snapshot strategy in
/pages/api/gates/access.ts
.
- Allows a single address to verify token ownership on behalf of multiple GitHub users (not a one-to-one between GitHub users and addresses). Easily changeable should user require uniqueness by tracking address-to-gateId in database in
/pages/api/gates/access.ts
.
- GitHub OAuth scopes are fairly invasive (
repo,read:user,user:email
). If you are privacy-aware, I'd recommended running your own fork or migrating to an app-based system?
License
GNU Affero GPL v3.0