First off — thank you for considering a contribution. Mova Store is an open-source, reference-architecture storefront on the Stellar network, and the project lives or dies by community contributions like yours.
This project is actively tracked for milestones and bounties on the GrantFox platform. That means your work can be scoped, reviewed, and rewarded through GrantFox's native issue and milestone tracking — not just merged silently.
Please take a minute to read this guide. It keeps contributions fast to review, easy to test, and consistent across the frontend and the Rust contract.
- How Milestones & Issues Work on GrantFox
- The 5-Step Contribution Pipeline
- Code Formatting
- Testing Guidelines
- Commit Message Style
- Pull Request Checklist
- Code of Conduct
We track the roadmap, open issues, and funded bounties natively on the GrantFox platform:
- Issues — scoped, actionable work items (bugs, improvements, new features).
- Milestones / Bounties — funded deliverables tied to one or more issues, with defined acceptance criteria and reward amounts.
- Proposals — larger architectural ideas. Post one in the discussions if you want to shape the roadmap before writing code.
A common misconception: bounty work is not "first to merge wins." It is reviewed on quality, so a well-tested, well-documented PR that satisfies the acceptance criteria wins over a faster, sloppier one.
Browse the open issues on GitHub (and cross-referenced GrantFox milestones).
Good first issues are usually labeled good first issue. If an issue is already
assigned, respect the assignee — ask before picking it up.
If the issue belongs to a funded milestone or bounty, apply for it on GrantFox first. Applying signals intent, links your identity to the work, and unlocks reward tracking. Don't start the implementation before your application is acknowledged for funded work.
Branch from the latest main. Use a short, descriptive name that matches the
work:
git checkout main
git pull origin main
git checkout -b feat/payment-retry # a new feature
# or
git checkout -b fix/order-already-paid-race # a bug fix
# or
git checkout -b docs/stellar-contract-readme # documentationBranch naming conventions:
| Prefix | Use for | Example |
|---|---|---|
feat/ |
New features | feat/payment-retry |
fix/ |
Bug fixes | fix/wrong-total-on-mobile |
docs/ |
Documentation only | docs/soroban-deploy-guide |
refactor/ |
Code changes with no behavior change | refactor/stellar-lib-modules |
test/ |
Adding or updating tests | test/pay-dup-order-cases |
- Follow the style and structure of the surrounding code.
- Add tests that cover the behavior you changed — see Testing Guidelines.
- Run the local checks below before committing. If they pass, commit.
- Never commit secrets,
.envfiles, ornode_modules.
git push -u origin feat/payment-retryThen open a PR against main:
- Title: a short summary using a Conventional Commit prefix, e.g.
feat: add payment success alert. - Description: link the issue/bounty, summarize the change, list how it was tested, and note any acceptance criteria you satisfied.
- Reference the GrantFox milestone/bounty id in the description so reviewers can tie the PR back to the funded work.
Once reviewers approve, maintainers merge. For funded milestones, completion is confirmed against the acceptance criteria on GrantFox.
Formatting is enforced to keep review diffs clean. Both frontend and contract code must be formatted before pushing.
- Prettier for formatting (
npx prettier --write "app/**/*.{js,jsx,ts,tsx}" "lib/**/*.ts" "components/**/*.{js,jsx}"). - ESLint via the Next.js lint script for correctness:
npm run lint- TypeScript must typecheck with zero errors:
npx tsc --noEmit- rustfmt for formatting:
cd contracts/checkout && cargo fmt -- --check- clippy for lints:
cd contracts/checkout && cargo clippy --all-targets -- -D warnings
-- -D warningspromotes every warning to an error — fix or justify each one.
The contract must be tested. The Rust contract ships with a mock-token test
suite in contracts/checkout/src/test.rs. Run it before every PR that touches
contracts/:
cd contracts/checkout && cargo test- Add a test for every new contract function and every new error path.
- When behavior changes, update existing tests — don't delete coverage.
- Tests run offline against a mock token; no network or funded account needed.
The frontend uses Vitest for unit and integration tests. Run tests before every PR:
# Run all tests once
npm run test
# Run tests in watch mode during development
npm run test:watch
# Run tests with coverage report
npm run test:coverage
# Run tests with interactive UI
npm run test:uiTest file locations:
- Unit tests:
tests/lib/for library functions - Component tests:
tests/components/for React components - Tests should be named
*.test.tsor*.test.tsx
What to test:
- Utility functions (validation, formatting, etc.)
- Custom hooks
- Component behavior (user interactions, state changes)
- Error handling paths
Example test:
import { describe, it, expect } from "vitest";
import { validateEmail } from "../../lib/validation";
describe("validateEmail", () => {
it("accepts valid emails", () => {
expect(validateEmail("test@example.com").isValid).toBe(true);
});
it("rejects invalid emails", () => {
expect(validateEmail("not-an-email").isValid).toBe(false);
});
});npm run type-check # TypeScript type checking
npm run lint # ESLint checks
npm run build # Production build must succeedIf your PR touches the Stellar payment flow, describe in the PR how you tested it against testnet (Freighter + USDC faucet account). Follow the flow in the root README.
Use Conventional Commits. This keeps the changelog readable and lets tooling detect releases automatically.
<type>(<optional scope>): <short summary>
| Type | Meaning |
|---|---|
feat |
A new user-facing feature |
fix |
A bug fix |
docs |
Documentation only |
refactor |
Code change with no behavior change |
test |
Adding or updating tests |
chore |
Build tooling, deps, config |
Examples:
feat: add payment success alert
fix(checkout): reject duplicate order ids before transfer
docs: add soroban contract deployment guide
test: cover invalid-amount rejection in pay
chore: bump @stellar/stellar-sdk to 16.2.0Rules:
- Imperative mood, lowercase after the type, no trailing period.
- Summary under ~72 characters. Add a body explaining why when it's not obvious.
- One logical change per commit. Prefer several focused commits over one large one.
Before opening a PR, verify:
- Linked to the GitHub issue and GrantFox milestone/bounty id.
- Branch name follows the naming convention.
- Code formatted (
npm run format/cargo fmt). - Lints pass (
npm run lint,cargo clippy -- -D warnings). - Typecheck passes (
npm run type-check). - Frontend tests pass (
npm run test). - Contract tests pass (
cd contracts/checkout && cargo test). - Build succeeds (
npm run build). - New behavior has tests; existing tests updated where needed.
- No secrets,
.envfiles, or build artifacts in the diff. - README/docs updated if behavior or config changed.
We are committed to providing a welcoming, collaborative environment for everyone — regardless of experience, background, or identity.
Our expectations:
- Be respectful. Disagreement on code is normal; keep it about the code.
- Be constructive. In reviews, explain why; in replies, be open to alternatives.
- Be patient. Maintainers and contributors volunteer their time; reviews may take a few days.
- Give credit. Acknowledge prior art and the work of others.
Unacceptable behavior includes harassment, personal attacks, trolling, doxxing, and any form of discrimination. Maintainers may remove comments, close PRs, or ban individuals who violate these standards.
Reporting: contact the maintainers via a GitHub issue (labeled
report/private) or through GrantFox. All reports are taken seriously and
reviewed confidentially.
Happy building — and see you on GrantFox.