Answers to the most common contributor and user questions about Stellar Goal Vault.
- How do I get testnet XLM for development and testing?
- How do I set up Freighter wallet for pledge transactions?
- How do I deploy the Soroban contract?
- How do I reset the local development database?
- How do I run the load test script?
- Why does my pledge fail?
- How do I configure environment variables?
- How do I run the full stack locally with Docker?
- How do I run the contract property tests?
- How do I contribute a new feature?
Stellar testnet XLM is free and available through the Stellar Laboratory Friendbot.
Steps:
- Create a Stellar testnet account using the Stellar Laboratory.
- Fund the account using the Friendbot button on the same page.
- Your account will receive 10,000 free testnet XLM.
Alternatively, use the Friendbot API directly:
curl -X POST "https://friendbot.stellar.org?addr=YOUR_TESTNET_PUBLIC_KEY"Expected output:
{
"_links": {
"transaction": { "href": "https://horizon-testnet.stellar.org/transactions/..." }
}
}Related: Stellar testnet docs
Freighter is the Stellar browser extension wallet used to sign pledge transactions.
Steps:
- Install the Freighter browser extension (Chrome or Firefox).
- Open Freighter and click Create a new wallet.
- Save your recovery phrase in a secure location.
- Click Settings → Network → switch to Testnet.
- Fund your wallet with testnet XLM (see FAQ #1).
- Verify connection by opening the app — the wallet widget in the header should show your public key.
Troubleshooting:
- If the widget shows "Connect Freighter", click it and approve the connection in the extension.
- Ensure both Freighter and the app are on the same network (Testnet).
- If transactions fail, check that your account has a non-zero XLM balance (minimum reserve is ~1 XLM).
Related:
frontend/src/services/freighter.ts— Freighter integration code
The contract lives in the contracts/ directory and is deployed via the provided shell script.
Prerequisites:
soroban-cliinstalled (see soroban.stellar.org)- Rust nightly with
wasm32v1-nonetarget:rustup target add wasm32v1-none - A funded Stellar testnet secret key
Steps:
# From the repository root
SECRET_KEY="S..." ./scripts/deploy.shWhat happens:
- The script builds the contract with
soroban contract build - Deploys it to the testnet with
soroban contract deploy - Saves the contract ID to
contracts/contract_id.txt - Prints the contract ID to the console
After deployment:
# Update the backend environment
CONTRACT_ID=$(cat contracts/contract_id.txt)
sed -i "s/^CONTRACT_ID=.*/CONTRACT_ID=$CONTRACT_ID/" backend/.envSee also: RUNBOOK.md — Redeploy the Soroban Contract for redeployment and rollback procedures.
The SQLite database at backend/data/campaigns.db stores all campaigns, pledges, and event history.
Quick reset (deletes all data):
# Stop the backend first
docker compose stop backend
# Delete the database file
rm -f backend/data/campaigns.db
# Restart
docker compose start backendReset with deterministic seed data:
# After deleting the DB (steps above)
cd backend && npx ts-node src/services/seedDeterministic.tsThis seeds 3 campaigns (open, funded, claimed) and 2 pledges for reproducible testing.
See also: RUNBOOK.md — Reset the Dev Database and
backend/src/services/seedDeterministic.ts
The backend includes an Autocannon-based load test for simulating concurrent traffic.
Prerequisites:
- Backend running locally:
npm run dev:backend
Run the default test:
cd backend
npm run load:testCustom test parameters:
cd backend
npm run load:test -- \
--base-url http://127.0.0.1:3001 \
--connections 20 \
--duration 20 \
--campaigns 8 \
--read-weight 3 \
--pledge-weight 1Available flags:
| Flag | Default | Description |
|---|---|---|
--connections |
20 | Number of concurrent connections |
--duration |
20 | Test duration in seconds |
--campaigns |
8 | Seed campaigns created before the run |
--read-weight |
3 | Relative weight of GET requests |
--pledge-weight |
1 | Relative weight of POST pledge requests |
--pledge-amount |
5 | Amount per pledge request |
--asset-code |
USDC | Asset code used for seed campaigns |
Expected output:
Running 20s test @ http://127.0.0.1:3001
Stat Avg Stdev Max
Latency 12 ms 8 ms 45 ms
Req/Sec 450 35 520
Bytes/Sec 2.1 MB 180 kB 2.5 MB
Non-2xx: 0
Timeouts: 0
Related:
backend/scripts/load-test.js— full script with source
Pledge failures typically fall into one of these categories:
1. Campaign is not in "open" status
- Campaigns past their deadline or fully funded return an error.
- Check the campaign status:
curl http://localhost:3001/api/campaigns/:id
2. Contributor limit reached
- If the campaign has a
maxPerContributorset, your total contributions across all pledges cannot exceed that limit. - Check your current contributions:
curl http://localhost:3001/api/campaigns/:id/contributors
3. Invalid request body
contributormust be a valid Stellar public key (G...).amountmust be a positive number.- Ensure the request body is valid JSON.
4. Database locked (SQLite contention)
- SQLite can block under high concurrency. This is expected during load tests but rare under normal use.
- Retry the pledge after a brief wait.
5. Contract ID mismatch (Freighter flow)
- If using the Soroban-integrated pledge flow, the backend
CONTRACT_IDmust match the deployed contract. - Verify:
curl http://localhost:3001/api/config | grep contractId
Related: RUNBOOK.md — Clear the Soroban Event Cache if events appear out of sync
Backend environment (backend/.env):
# Required
CONTRACT_ID=your_deployed_contract_id
# Optional (defaults shown)
PORT=3001
DB_PATH=backend/data/campaigns.db
SOROBAN_RPC_URL=https://soroban-testnet.stellar.org:443
ALLOWED_ASSETS=USDC,XLM,ARS
LOG_LEVEL=infoStart by copying the example file:
cp backend/.env.example backend/.envFrontend environment (frontend/.env):
VITE_API_URL=http://localhost:3001/apiImportant: In production,
VITE_API_URLshould point to your deployed backend URL.
Contract deployment environment:
SECRET_KEY— Stellar account secret key (required for deploy)NETWORK_PASSPHRASE— defaults to testnetRPC_URL— defaults to testnet
See also:
backend/.env.exampleandfrontend/.env.example
Docker Compose runs both the backend and frontend with hot-reload for local development.
Start everything:
docker compose up --buildThis starts:
- Backend at
http://localhost:3001(withts-node-devfor hot reload) - Frontend at
http://localhost:3000(with Vite HMR)
Run in background:
docker compose up --build -dStop:
docker compose downView logs:
docker compose logs -f backend
docker compose logs -f frontendNote: The
docker-compose.override.ymlmounts source directories and enables hot-reload automatically. No extra flags needed.
The Soroban contract includes property-based tests using the proptest crate.
Prerequisites:
- Rust toolchain installed
wasm32v1-nonetarget:rustup target add wasm32v1-none
Run all contract tests:
cd contracts
cargo testRun property tests only:
cd contracts
cargo test property_testsRun with verbose output:
cd contracts
cargo test -- --nocaptureExpected output:
running X tests
test test_multi_token_campaign ... ok
test test_multi_token_refund ... ok
test test_claim_before_deadline ... ok
test test_claim_creator_mismatch ... ok
test test_claim_double_claim ... ok
test test_claim_success ... ok
Related:
contracts/src/test.rsand PROPERTY_TESTS_IMPLEMENTATION.md
Quick start:
- Fork the repository on GitHub.
- Clone your fork:
git clone https://github.com/YOUR_USERNAME/stellar-goal-vault.git - Install dependencies:
npm run install:all - Create a branch:
git checkout -b feature/my-feature - Make your changes and test them:
- Backend tests:
cd backend && npx vitest - Contract tests:
cd contracts && cargo test - E2E tests:
npm run test:e2e
- Backend tests:
- Commit using conventional commits (e.g.,
feat: add new endpoint). - Push and open a Pull Request against the
mainbranch.
Code style:
- TypeScript in
backend/andfrontend/with ESLint + Prettier - Rust in
contracts/withcargo fmt - Pre-commit hooks are configured via Husky + lint-staged
Where to start:
- Check the open issues labelled
good first issue. - Browse
OPEN_SOURCE_ISSUES.mdfor curated contribution ideas. - Read the Contributing Guide for detailed setup instructions.
Last updated: 2026-06-01