Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"name": "StellarForge Development Container",
"image": "mcr.microsoft.com/devcontainers/rust:1-1-bookworm",
"features": {
"ghcr.io/devcontainers/features/node:1": {
"version": "22"
}
},
"containerEnv": {
"STELLAR_CLI_VERSION": "27.1.0",
"STELLAR_CLI_SHA256": "9915fe63753d7154c26bb9e6410cf1d1ff9727a9b378e663c2790ab7a266af94"
},
"postCreateCommand": "rustup toolchain install && rustup default \"$(sed -n 's/^channel = \"\\(.*\\)\"/\\1/p' rust-toolchain.toml)\" && curl -sSfL -o /tmp/stellar-cli.tar.gz \"https://github.com/stellar/stellar-cli/releases/download/v${STELLAR_CLI_VERSION}/stellar-cli-${STELLAR_CLI_VERSION}-x86_64-unknown-linux-gnu.tar.gz\" && echo \"${STELLAR_CLI_SHA256} /tmp/stellar-cli.tar.gz\" | sha256sum --check --strict && sudo tar xzf /tmp/stellar-cli.tar.gz -C /usr/local/bin stellar && rm /tmp/stellar-cli.tar.gz && cd sdk && npm ci",
"customizations": {
"vscode": {
"extensions": [
"rust-lang.rust-analyzer",
"tamasfe.even-better-toml",
"esbenp.prettier-vscode",
"dbaeumer.vscode-eslint",
"ms-vscode.vscode-typescript-next",
"GitHub.vscode-pull-request-github",
"usernamehw.errorlens"
]
}
}
}
46 changes: 46 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "make build",
"type": "shell",
"command": "make build",
"group": {
"kind": "build",
"isDefault": true
},
"problemMatcher": "$rustc",
"detail": "Build all Soroban WASM contracts"
},
{
"label": "make lint",
"type": "shell",
"command": "make lint",
"group": "build",
"problemMatcher": "$rustc",
"detail": "Run Clippy linter across the Rust workspace"
},
{
"label": "make test",
"type": "shell",
"command": "make test",
"group": {
"kind": "test",
"isDefault": true
},
"problemMatcher": "$rustc",
"detail": "Run all Rust contract tests"
},
{
"label": "npm test",
"type": "shell",
"command": "npm test",
"options": {
"cwd": "${workspaceFolder}/sdk"
},
"group": "test",
"problemMatcher": [],
"detail": "Run TypeScript SDK unit tests in sdk/"
}
]
}
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- `.devcontainer/devcontainer.json` with the pinned Rust toolchain (`rust-toolchain.toml`), `wasm32v1-none`, `stellar-cli` `27.1.0`, and Node.js 22 preinstalled, running `npm ci` in `sdk/` on creation (#81).
- `.vscode/tasks.json` defining `make build`, `make lint`, `make test`, and `npm test` grouped as build and test tasks (#82).
- `make doctor` target (`scripts/doctor.sh`) checking `rustc`, `wasm32v1-none`, `stellar-cli`, `node`, and `npm` versions against the repository's pinned expectations (#86).
- `ci`: Add `contracts/size-budget.json` establishing tracked byte thresholds for each contract, enforced in `.github/workflows/contracts-ci.yml` (#94).
- `ci`: Add `deny.toml` and `cargo-deny` check in `.github/workflows/security.yml` to enforce license compliance (Apache-2.0, MIT, BSD) and deny unknown registries (#91).
- Stage 1 developer-experience tooling:
Expand Down
21 changes: 20 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,9 @@ a weekly schedule.
git clone https://github.com/0xLizTech/stellarforge.git
cd stellarforge

# Verify required toolchain versions (rustc, wasm32v1-none, stellar-cli, node, npm)
make doctor

# Build everything
make build

Expand All @@ -137,6 +140,21 @@ make sdk-lint
make sdk-typecheck
```

### Devcontainer & Codespaces

If you use GitHub Codespaces or the VS Code Dev Containers extension, `.devcontainer/devcontainer.json` provisions a ready-to-use environment with the pinned Rust toolchain (`rust-toolchain.toml`), the `wasm32v1-none` target, `stellar-cli` (`27.1.0`, matching CI), and Node.js 22 preinstalled, and runs `npm ci` in `sdk/` automatically on container creation so `make test` and `npm test` work immediately without manual setup.

### VS Code Tasks

`.vscode/tasks.json` defines Command Palette tasks (**Terminal: Run Task**) grouped into build and test tasks:

| Task label | Group | Command | Description |
|---|---|---|---|
| `make build` | `build` (default) | `make build` | Build all Soroban WASM contracts |
| `make lint` | `build` | `make lint` | Run Clippy linter across the Rust workspace |
| `make test` | `test` (default) | `make test` | Run all Rust contract tests |
| `npm test` | `test` | `npm test` (in `sdk/`) | Run TypeScript SDK unit tests |

### Running a single contract's tests

```bash
Expand Down Expand Up @@ -173,7 +191,8 @@ stellarforge/
│ ├── registry/ # Global registry of deployed asset contracts
│ ├── compliance/ # KYC/AML record management
│ ├── governance/ # On-chain proposal & voting
│ └── oracle-adapter/ # SEP-40 NAV price feed (Phase 2)
│ ├── oracle-adapter/ # SEP-40 NAV price feed (Phase 2)
│ └── vault/ # Fractionalization vault & SEP-41 share token (Phase 2)
├── sdk/ # @stellarforge-protocol/sdk (TypeScript)
│ ├── src/
│ │ ├── client.ts # RwaAssetClient, ComplianceClient
Expand Down
5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.PHONY: all build test fmt lint clean sdk-install sdk-build sdk-test sdk-lint sdk-typecheck deploy-testnet udeps hooks help
.PHONY: all build test fmt lint clean sdk-install sdk-build sdk-test sdk-lint sdk-typecheck deploy-testnet udeps hooks doctor help

# ─── Variables ────────────────────────────────────────────────────────────────
NETWORK ?= testnet
Expand Down Expand Up @@ -61,6 +61,9 @@ hooks: ## Install the pre-commit Git hooks (install: pip install pre-commit)
pre-commit install --hook-type commit-msg
@echo "Pre-commit hooks installed. Run 'pre-commit run --all-files' to check the tree."

doctor: ## Check local Rust, stellar-cli, and Node toolchain against pinned versions
./scripts/doctor.sh

##@ Release
deploy-testnet: ## Deploy all four contracts to Stellar testnet
@echo "Deploying all four contracts to Stellar testnet..."
Expand Down
127 changes: 127 additions & 0 deletions scripts/doctor.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
#!/usr/bin/env bash
# doctor.sh — Verify that the local StellarForge development toolchain is
# installed and matches the versions pinned across the repository.
#
# Usage:
# make doctor
# ./scripts/doctor.sh
#
# Checks every required tool in one pass rather than stopping at the first
# failure, printing the expected version beside each result and exiting
# non-zero if anything is missing or mismatched.

set -uo pipefail

EXPECTED_RUSTC="1.98.1"
if [[ -f rust-toolchain.toml ]]; then
parsed_rustc=$(sed -n 's/^channel *= *"\([^"]*\)".*/\1/p' rust-toolchain.toml)
[[ -n "$parsed_rustc" ]] && EXPECTED_RUSTC="$parsed_rustc"
fi

EXPECTED_WASM_TARGET="wasm32v1-none"
EXPECTED_STELLAR_CLI="27.1.0"
if [[ -f .github/workflows/contracts-ci.yml ]]; then
parsed_stellar=$(sed -n 's/^ *STELLAR_CLI_VERSION: *"\([^"]*\)".*/\1/p' .github/workflows/contracts-ci.yml)
[[ -n "$parsed_stellar" ]] && EXPECTED_STELLAR_CLI="$parsed_stellar"
fi

EXPECTED_NODE_MIN="22.12.0"
EXPECTED_NPM_MIN="10.0.0"

failures=0

pass() {
printf " [OK] %-18s %-20s (expected: %s)\n" "$1" "$2" "$3"
}

fail() {
printf " [FAIL] %-18s %-20s (expected: %s)\n" "$1" "$2" "$3" >&2
failures=$((failures + 1))
}

version_ge() {
local actual="$1"
local required="$2"
local IFS=.
local i a=($actual) r=($required)
for ((i = 0; i < ${#r[@]}; i++)); do
local av="${a[i]:-0}"
local rv="${r[i]:-0}"
if ((10#$av > 10#$rv)); then
return 0
elif ((10#$av < 10#$rv)); then
return 1
fi
done
return 0
}

echo "Checking StellarForge toolchain..."

# 1. rustc
if command -v rustc >/dev/null 2>&1; then
rustc_ver=$(rustc --version 2>/dev/null | awk '{print $2}')
if [[ "$rustc_ver" == "$EXPECTED_RUSTC" ]]; then
pass "rustc" "$rustc_ver" "$EXPECTED_RUSTC"
else
fail "rustc" "${rustc_ver:-unknown}" "$EXPECTED_RUSTC"
fi
else
fail "rustc" "missing" "$EXPECTED_RUSTC"
fi

# 2. wasm32v1-none target
if command -v rustup >/dev/null 2>&1; then
if rustup target list --installed 2>/dev/null | grep -qx "$EXPECTED_WASM_TARGET"; then
pass "wasm target" "$EXPECTED_WASM_TARGET" "$EXPECTED_WASM_TARGET installed"
else
fail "wasm target" "not installed" "$EXPECTED_WASM_TARGET installed"
fi
else
fail "wasm target" "rustup missing" "$EXPECTED_WASM_TARGET installed"
fi

# 3. stellar-cli
if command -v stellar >/dev/null 2>&1; then
stellar_ver=$(stellar --version 2>/dev/null | head -n 1 | awk '{print $2}')
if [[ "$stellar_ver" == "$EXPECTED_STELLAR_CLI" ]]; then
pass "stellar-cli" "$stellar_ver" "$EXPECTED_STELLAR_CLI"
else
fail "stellar-cli" "${stellar_ver:-unknown}" "$EXPECTED_STELLAR_CLI"
fi
else
fail "stellar-cli" "missing" "$EXPECTED_STELLAR_CLI"
fi

# 4. node
if command -v node >/dev/null 2>&1; then
node_ver=$(node --version 2>/dev/null | sed 's/^v//')
if [[ -n "$node_ver" ]] && version_ge "$node_ver" "$EXPECTED_NODE_MIN"; then
pass "node" "$node_ver" ">= $EXPECTED_NODE_MIN"
else
fail "node" "${node_ver:-unknown}" ">= $EXPECTED_NODE_MIN"
fi
else
fail "node" "missing" ">= $EXPECTED_NODE_MIN"
fi

# 5. npm
if command -v npm >/dev/null 2>&1; then
npm_ver=$(npm --version 2>/dev/null | tr -d '[:space:]')
if [[ -n "$npm_ver" ]] && version_ge "$npm_ver" "$EXPECTED_NPM_MIN"; then
pass "npm" "$npm_ver" ">= $EXPECTED_NPM_MIN"
else
fail "npm" "${npm_ver:-unknown}" ">= $EXPECTED_NPM_MIN"
fi
else
fail "npm" "missing" ">= $EXPECTED_NPM_MIN"
fi

if ((failures > 0)); then
echo "" >&2
echo "doctor: $failures check(s) failed. See CONTRIBUTING.md for installation instructions." >&2
exit 1
fi

echo ""
echo "All toolchain checks passed."