Lalabase
티켓·문서·근무시간·고객대화를 한 곳에 모아 KI로 검색, 소프트웨어 기업 고객 프로젝트용, 오픈소스로 자체 서버·독일 클라우드에 배포
Contribo는 Monad 위에서 창업자를 개발자와 연결해 협업을 돕습니다
Contribo connects founders building on Monad with developers who want to help. Reward terms are published up front, pull requests are verified on GitHub, and accepted work is paid onchain.
비즈니스TypeScript · HTMLGitHub @sniperchief온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
Build together, get recognized, and share in the success of what you help build.
A rewards platform for open-source contributors in the Monad ecosystem. Founders lock real funds behind clear reward terms before work starts. Contributors ship pull requests, and accepted work is paid out from those funds on Monad.
1. Why Contribo
2. Live deployment
3. How it works
4. Architecture
5. Security and trust
6. The smart contract
7. Tech stack
8. Run it locally
9. Deploy your own copy
10. Testing
11. Project structure
12. Known limitations
13. Notes for contributorsREADME 전문 보기 ↗Build together, get recognized, and share in the success of what you help build.
A rewards platform for open-source contributors in the Monad ecosystem. Founders lock real funds behind clear reward terms before work starts. Contributors ship pull requests, and accepted work is paid out from those funds on Monad.
Open the app · Guide for judges · Explore projects · Smart contract · Source code
Open-source work often goes unrewarded, and when rewards are offered, they are easy to change after the work is done:
Contribo fixes this with three simple rules:
| Web app | https://trycontribo.vercel.app |
| Network | Monad Testnet (chain ID 10143) |
Rewards contract (ContriboRewards) | 0xf2080fC3CDBeFa5577b5c185794dBfAB348DD5D3 |
| Deployment transaction | 0x61d56882…e7f96e67 |
| Deployed | 10 October 2026, block 69,808,471 |
| Platform admin (can pause new activity, cannot move funds) | 0x0c2c06e426F09f33c64d45Fa62782C9FF9FB9fa4 |
| Deployer | 0x44d826e1d9a51239c8717fe7bc785985ec0d6ca1 |
| Source code verification | Exact ("perfect") match on Sourcify: check status |
| Compiler | Solidity 0.8.30, optimizer on (200 runs), EVM version prague |
You don't have to trust this README. Each of these checks takes a minute:
"status": "perfect". The source lives in contracts/src/ContriboRewards.sol.RPC=https://testnet-rpc.monad.xyz
ADDR=0xf2080fC3CDBeFa5577b5c185794dBfAB348DD5D3
cast call $ADDR "owner()(address)" --rpc-url $RPC # platform admin
cast call $ADDR "projectCount()(uint256)" --rpc-url $RPC # projects registered so far
cast call $ADDR "paused()(bool)" --rpc-url $RPC # false while operating normally
Contribo runs on testnet. Testnet MON has no real value; get some from the Monad faucet. The contract has not been independently audited yet. See Known limitations.
From Manage → + Create a project:
Repository. Paste a GitHub link or start typing to search your own repositories. If the repository belongs to your GitHub account, it is verified instantly. For an organization repository, Contribo gives you a small file to add to it, which proves you can manage it.
Rewards. Choose one reward type:
Pay in MON or any token on Monad. Contribo writes clear reward terms for you, and you can edit them.
Review and launch. One button runs a checklist and asks your wallet to approve each step:
If anything stops halfway, Continue launch picks up exactly where it left off and never repeats a payment.
Your progress is saved after every step. Unfinished projects show In setup · step X of 3 on Manage.
After launch, the project page is where you review contributions, add more bounties or funds, and manage approvers (trusted wallets that can approve rewards with you). Projects show Live while open and Ended once you close them.
| Stage | What it means | Where it's recorded |
|---|---|---|
| Detected | A merged pull request by you in a verified repository, found on GitHub | GitHub (not saved) |
| Verified | Contribo checked on GitHub that it's yours, merged, and in the right repository | Contribo database |
| Accepted | The founder chose a reward for it (a bounty or a pool amount) | Contribo database |
| Approved onchain | The reward is reserved for your wallet in the smart contract | Monad |
| Claimable | Approved, and you're connected with the receiving wallet | Monad + your wallet |
| Paid | You claimed it | Monad |
| Rejected | Not eligible for a reward | Contribo database |
A verified pull request is evidence, not payment. Nothing is paid until a person approves it and the approval is confirmed onchain.
Contribo notifies people in the app (no email or push) when a contribution moves to a new stage:
| Who | When |
|---|---|
| Contributor | Verified · Accepted · Rejected · Approved onchain (it can be claimed from then on; the contract has no separate "ready to claim" state) · Paid |
| Project owner | A pull request was verified and is waiting for review |
Notifications are written by a database trigger in the same transaction as the stage change, and only the server can change a contribution's stage, after checking GitHub or the contract. "Approved onchain" and "Paid" are set only after the server reads the approval or claim back from the contract. Each event has a unique key per recipient, so reloads and retries never create a second notification.
Each project page shows figures read from ContriboRewards at a single block:
| Figure | Contract field | Meaning |
|---|---|---|
| Available for new rewards | available | Unallocated funds; the only part the owner can put into new bounties or approvals, or withdraw |
| Locked in active bounties | escrowed | Funds in open bounties; leaves only when a bounty is awarded or cancelled after its deadline |
| Approved, awaiting claim | committed | Reserved for contributors; nobody else can move it |
| Total paid out | totalPaid | All-time claims: a history total, not a balance |
These buckets never overlap: an awarded bounty moves from escrowed to committed, and a claim from committed to paid out. Each project uses one token, and totals across projects (on Explore) are kept per token. Payouts are listed only when the contract reports the contribution as claimed; transaction links come from receipts that emitted RewardClaimed. If the network can't be read, the page says so and shows the time of the last verified reading instead of presenting old figures as current.
flowchart LR
U["Founders and contributors<br/>(browser + wallet)"] --> W["Contribo web app<br/>Next.js on Vercel"]
W -->|"sign-in, profiles,<br/>projects, terms, reviews"| S[("Supabase<br/>accounts + database")]
W -->|"check repos and<br/>pull requests"| G["GitHub API"]
U -->|"sign transactions"| C["ContriboRewards<br/>smart contract on Monad"]
W -->|"read balances, bounties,<br/>confirm transactions"| C
Contribo has four parts. Each one is the source of truth for something different:
| Part | What it does | Source of truth for |
|---|---|---|
| Web app (Next.js, hosted on Vercel) | The pages people use, plus server code that checks GitHub, confirms transactions and enforces the rules | Nothing stored; it coordinates the other parts |
| Supabase (accounts and PostgreSQL database) | GitHub sign-in, profiles, projects, reward terms, contribution reviews | Who people are, what was promised, what was reviewed |
| GitHub | Repositories and pull requests | Who wrote and merged what |
| ContriboRewards (smart contract on Monad) | Holds the money, reserves approved rewards, pays claims | Where every token is |
| Page | Who | What it's for |
|---|---|---|
/ | Everyone | Landing page with live total paid out |
/projects (Explore) | Everyone | Browse live projects; search and sort |
/projects/[slug] | Everyone | Reward terms, verified repositories and reward transparency (balances, active bounties and confirmed payouts read from the contract at one block); contributors submit pull requests here |
/login | Everyone | Sign in or sign up with GitHub |
/welcome | New users | Choose contributor or founder, link a wallet (optional) |
/dashboard (Contributions) | Contributors | Your pull requests by stage, and claims |
/founder (Manage) | Founders | Your projects, and their setup progress |
/founder/new | Founders | The three-step project setup |
/founder/[id] | Project owner and approvers | Manage details, repositories, terms, funding, bounties and approvers; review contributions |
/profile | Signed-in users | GitHub details, payout wallet, social links and skills |
One contract, ContriboRewards, does everything onchain: it is the project registry, the vault that holds funds, and the reward ledger. Keeping it in one contract means one set of balance books. Its types, events and errors are in IContriboRewards.
Each project's funds sit in one of these buckets:
deposited ──► available ──► escrowed (a bounty) ──► committed (approved for a contributor) ──► paid
│ │
└─► withdrawn └─► back to available if the bounty expires unawarded
| Step | Function | Who |
|---|---|---|
| Register a project, fixing its payment token and terms fingerprint | registerProject | Anyone (they become the owner) |
| Add funds | deposit | Anyone |
| Lock funds in a bounty with a deadline | createBounty | Owner |
| Approve a reward from the pool | approveContribution | Owner or approver |
| Award a bounty | awardBounty | Owner or approver |
| Claim an approved reward to any address | claim | The contributor |
| Take back unused funds | withdraw (available funds only) | Owner |
| Release an expired, unawarded bounty | cancelBounty (after deadline) | Owner |
| Update the terms fingerprint, add or remove approvers, hand over ownership | setPolicyHash, setApprover, transferProjectOwnership / acceptProjectOwnership | Owner |
| Pause new activity in an emergency | pause / unpause | Platform admin |
The books always balance, and the tests check this after thousands of random operations:
total deposited = available + escrowed + committed + paid + withdrawn
| Area | Choice |
|---|---|
| Web framework | Next.js 16 (App Router) and React 19, written in TypeScript |
| Styling | Tailwind CSS v4 with Contribo's design tokens (design/style-reference.md); Manrope and Instrument Serif fonts |
| Accounts and database | Supabase: GitHub sign-in and PostgreSQL with Row Level Security |
| Wallet connection | RainbowKit 2 on wagmi v2 and viem |
| Smart contract | Solidity 0.8.30, Foundry 1.8+, OpenZeppelin Contracts 5.7 |
| Blockchain | Monad Testnet |
| Hosting | Vercel |
| Tests | Vitest for the app, Foundry for the contract |
The app keeps its dependencies deliberately few: @supabase/ssr, @supabase/supabase-js, @rainbow-me/rainbowkit, wagmi, viem, @tanstack/react-query (needed by wagmi), server-only and tailwind-merge.
You need Node.js 20.9 or later and npm.
git clone https://github.com/sniperchief/Contribo.git
cd Contribo
npm install
cp .env.example .env.local
npm run dev
Open http://localhost:3000. The app runs without any configuration: pages that need a missing service show a friendly "not configured" message instead of breaking.
All variables are listed in .env.example with placeholder values. Put your real values in .env.local, which is never committed.
| Variable | Who sees it | Needed for | What it is |
|---|---|---|---|
NEXT_PUBLIC_SITE_URL | Public | Sign-in redirects | The app's address, e.g. http://localhost:3000 or https://trycontribo.vercel.app (no trailing slash) |
NEXT_PUBLIC_SUPABASE_URL | Public | Accounts and data | Your Supabase project URL |
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY | Public | Accounts and data | Supabase publishable (or "anon") key. Safe to expose; database rules protect the data |
SUPABASE_SECRET_KEY | Server only | Verification, publishing, wallet linking | Supabase secret (or "service role") key. Never prefix it with NEXT_PUBLIC_ |
GITHUB_TOKEN | Server only | Recommended | A GitHub token with no extra permissions. Without it, GitHub allows only about 60 requests per hour |
NEXT_PUBLIC_MONAD_NETWORK | Public | Optional | testnet (default) or mainnet |
NEXT_PUBLIC_MONAD_RPC_URL | Public | Optional | A dedicated Monad connection endpoint; defaults to the public one |
NEXT_PUBLIC_CONTRIBO_REWARDS_ADDRESS | Public | Onchain features | The contract address. Testnet: 0xf2080fC3CDBeFa5577b5c185794dBfAB348DD5D3 |
NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID | Public | Optional | Free ID from cloud.reown.com; enables phone wallets via QR code |
SUPABASE_AUTH_EXTERNAL_GITHUB_CLIENT_ID / _SECRET | Supabase CLI | Local Supabase only | Only used when running Supabase on your own machine |
Values starting with NEXT_PUBLIC_ are built into the app, so restart the dev server (or redeploy) after changing them.
Create a project at supabase.com.
Run the migrations in supabase/migrations/ in order, either by pasting each file into the Supabase SQL editor, or with npx supabase link --project-ref <ref> and then npx supabase db push:
| # | File | Adds |
|---|---|---|
| 1 | 20261010000000_initial_schema.sql | Profiles, projects, repositories, reward terms, contributions, and the access rules |
| 2 | 20261011000000_github_and_onchain_integration.sql | Wallet and repository verification, terms fingerprints, onchain links, approvers |
| 3 | 20261012000000_profile_socials_and_skills.sql | Social links and skills on profiles |
| 4 | 20261013000000_onboarding.sql | Contributor or founder role, and onboarding |
| 5 | 20261014000000_guided_project_setup.sql | Saved setup progress, bounty titles, server-only "go live" |
| 6 | 20261020000000_notifications_and_chain_snapshots.sql | In-app notifications (created by a database trigger), and the last verified onchain reading per project |
| Table | Holds |
|---|---|
profiles | One per user: name, avatar, bio, skills, social links, role, and the payout wallet (set only after a signature check) |
github_identities | The linked GitHub account, by its permanent numeric ID |
projects | Founder projects, their setup progress and their link to the onchain project. Status is draft, published (Live) or archived (Ended) |
project_repositories | Repositories under a project, with how they were verified |
reward_policies | Versioned reward terms. Published versions can never be edited; changes become a new version |
contributions | Pull requests submitted to a project, the reward chosen, and the onchain approval and claim |
project_approvers | Approver wallets, saved only after the contract confirms them |
bounty_details | A readable title for each onchain bounty |
notifications | One row per event and recipient: type, project and contribution, message, read time. Created only by a trigger on contributions; a unique dedupe key per recipient makes retries harmless. Recipients can read theirs and mark them read, nothing else |
project_chain_snapshots | The last successful, consistent read of each project's contract balances, written by the server from its own reads. Shown only as a labelled fallback when a live read fails |
Contributions record the terms that were in force when the pull request was merged, so later changes to the terms never affect earlier work.
http://localhost:3000 (or your live URL)https://<your-project-ref>.supabase.co/auth/v1/callback. Copy the exact value from Supabase → Authentication → Sign In / Providers → GitHub.http://localhost:3000http://localhost:3000/auth/callbackRequires Docker.
npx supabase init # creates supabase/config.toml, keeps the migrations folder
npx supabase start # starts the database and sign-in services, applies the migrations
For GitHub sign-in locally, set [auth.external.github] enabled = true in supabase/config.toml and put the two SUPABASE_AUTH_EXTERNAL_GITHUB_* values in supabase/.env. The OAuth App callback is then http://127.0.0.1:54321/auth/v1/callback.
| Command | What it does |
|---|---|
npm run dev | Start the app in development mode |
npm run build | Build for production (also checks types) |
npm run start | Serve the production build |
npm run typecheck | Check TypeScript types |
npm run lint | Check code style |
npm test | Run the app's tests |
npm run contracts:abi | Refresh the contract interface used by the app (run forge build in contracts/ first) |
The live app runs on Vercel at trycontribo.vercel.app. To deploy your own:
NEXT_PUBLIC_SITE_URL to your Vercel address, and mark SUPABASE_SECRET_KEY and GITHUB_TOKEN as sensitive.https://trycontribo.vercel.apphttps://trycontribo.vercel.app/auth/callback to Redirect URLsNEXT_PUBLIC_ values take effect.To test, open the site in a private window and sign in with GitHub. If you land on localhost, the Supabase Site URL still points there.
npm test # app tests
npm run typecheck && npm run lint && npm run build
cd contracts && forge test # contract tests
App tests (tests/, 143 tests) cover:
Contract tests (contracts/test/) cover:
Requires Foundry 1.8 or later.
git submodule update --init --recursive # forge-std and OpenZeppelin
cd contracts
forge build # compile
forge build --sizes # check size against Monad's limit
forge test # unit, fuzz and invariant tests
FOUNDRY_PROFILE=ci forge test # heavier random testing
forge fmt --check && forge lint
The deployment script is DeployContriboRewards.s.sol. The live deployment was made with:
CONTRIBO_ADMIN=<admin address> forge script script/DeployContriboRewards.s.sol \
--rpc-url monad_testnet --account <keystore account> --broadcast
Use an encrypted Foundry keystore (cast wallet import). Never put a private key in a file or command.
src/
app/
page.tsx Landing page
login/ GitHub sign-in (full-screen)
welcome/ Onboarding: role choice and wallet
projects/ Explore and public project pages; pull-request submission
dashboard/ Contributions: your pull requests, rewards and claims
founder/ Manage: your projects
new/ Three-step project setup (repository, rewards, launch)
[id]/ Project management: terms, repositories, funding, bounties, review
profile/ Profile, wallet, socials and skills
notifications/ Notification list and mark-as-read actions (shown in the header bell panel)
contributions/ Server actions for submissions, wallet linking and onchain sync
auth/ Sign-in callback and sign-out
components/ Shared interface pieces (header, buttons, badges, wallet, transactions)
lib/
project-setup.ts Rules for the setup flow (plans, totals, default terms)
rules.ts Who may manage, review and approve
policy.ts Terms fingerprinting
transparency.ts Reward accounting from contract state (per token)
notifications.ts Notification labels and in-app links
github/ GitHub verification rules
contracts/ Contract interface (generated), address and transaction states
server/ Server-only code: GitHub client, chain reads, access checks
supabase/ Database clients
monad/ Monad network selection
proxy.ts Keeps the sign-in session fresh on each request
types/database.ts Database types
supabase/migrations/ Database migrations (run in order)
contracts/ Smart contract project (Foundry)
src/ ContriboRewards and its interface
test/ Unit, fuzz and invariant tests
script/ Deployment script
tests/ App tests
design/ Approved designs and the style reference
withdraw function, but not from the app.middleware.ts is now proxy.ts, and any component that reads the session must be wrapped in <Suspense>. Version-matched docs are in node_modules/next/dist/docs/ (see AGENTS.md).rounded-control (8px), rounded-badge (16px), rounded-card (24px).npm run contracts:abi, so the app always calls the contract's real functions. Don't edit it by hand.Copy the project URL, publishable key and secret key into .env.local.