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
24 changes: 17 additions & 7 deletions .github/workflows/templates.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ on:
- "src/utils/templates.rs"
- "src/commands/new.rs"
- "src/commands/add.rs"
- "src/manifest.rs"
- "src/utils/wasm_target.rs"
- "templates/components/**"
- "Cargo.toml"
- "Cargo.lock"
Expand All @@ -19,6 +21,8 @@ on:
- "src/utils/templates.rs"
- "src/commands/new.rs"
- "src/commands/add.rs"
- "src/manifest.rs"
- "src/utils/wasm_target.rs"
- "templates/components/**"
- "Cargo.toml"
- "Cargo.lock"
Expand Down Expand Up @@ -66,16 +70,22 @@ jobs:
fail-fast: false
matrix:
template: ${{ fromJSON(needs.discover.outputs.templates) }}
toolchain:
- version: 1.80.0
target: wasm32-unknown-unknown
- version: stable
target: wasm32v1-none
env:
CARGO_TERM_COLOR: always
STARFORGE_NON_INTERACTIVE: "1"
CARGO_TARGET_DIR: ${{ github.workspace }}/project/target
WASM_TARGET: ${{ matrix.toolchain.target }}
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
toolchain: stable
targets: wasm32-unknown-unknown
toolchain: ${{ matrix.toolchain.version }}
targets: ${{ matrix.toolchain.target }}
- uses: actions/download-artifact@v4
with:
name: starforge-cli
Expand All @@ -95,7 +105,7 @@ jobs:
run: cargo test
- name: Build template for WASM
working-directory: project
run: cargo build --target wasm32-unknown-unknown --release
run: cargo build --target "$WASM_TARGET" --release
- name: Record WASM size
id: wasm-size
working-directory: project
Expand All @@ -104,7 +114,7 @@ jobs:
run: |
python3 - <<'PY'
import glob, json, os
files = sorted(glob.glob('target/wasm32-unknown-unknown/release/*.wasm'))
files = sorted(glob.glob(f"target/{os.environ['WASM_TARGET']}/release/*.wasm"))
if not files:
raise SystemExit('No WASM files found in release target directory')
with open(f"../wasm-size-{os.environ['TEMPLATE_NAME']}.json", 'w', encoding='utf-8') as out:
Expand All @@ -117,7 +127,7 @@ jobs:
PY
- uses: actions/upload-artifact@v4
with:
name: wasm-size-${{ matrix.template }}
name: wasm-size-${{ matrix.template }}-${{ matrix.toolchain.version }}
path: wasm-size-${{ matrix.template }}.json
if-no-files-found: error
retention-days: 7
Expand Down Expand Up @@ -170,7 +180,7 @@ jobs:
- uses: dtolnay/rust-toolchain@stable
with:
toolchain: stable
targets: wasm32-unknown-unknown
targets: wasm32v1-none
- uses: actions/download-artifact@v4
with:
name: starforge-cli
Expand All @@ -192,7 +202,7 @@ jobs:
run: cargo test
- name: Build modified contract for WASM
working-directory: component-project
run: cargo build --target wasm32-unknown-unknown --release
run: cargo build --target wasm32v1-none --release

templates-ok:
name: templates-ok
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/verify.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ jobs:

- name: Run formal verification (if WASM artifact exists)
run: |
WASM="target/wasm32-unknown-unknown/release/contract.wasm"
WASM="target/wasm32v1-none/release/contract.wasm"
if [ -f "$WASM" ]; then
cargo run -- contract verify \
--wasm "$WASM" \
Expand Down
4 changes: 2 additions & 2 deletions docs/COMMAND_REFERENCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -494,10 +494,10 @@ Full reference: [SIMULATION_RESOURCES.md](SIMULATION_RESOURCES.md) and
| `advanced-perf generate-dashboard <CONTRACT>` | Show the recorded-metrics performance dashboard |

```bash norun
starforge contract profile profile ./target/wasm32-unknown-unknown/release/token.wasm \
starforge contract profile profile ./target/wasm32v1-none/release/token.wasm \
--label token --dashboard ./target/token-profile.html

starforge contract profile profile ./target/wasm32-unknown-unknown/release/token.wasm \
starforge contract profile profile ./target/wasm32v1-none/release/token.wasm \
--baseline ~/.starforge/contract_profiles/profile-abc123def456.json \
--output ./target/token-profile.json
```
Expand Down
2 changes: 1 addition & 1 deletion docs/DEPLOYMENT_CHECKPOINTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ StarForge automatically persists deployment progress to disk, enabling deploymen
When running deployment automation:

```bash norun
starforge deployment-automate run --wasm ./target/wasm32-unknown-unknown/release/my_contract.wasm --network testnet
starforge deployment-automate run --wasm ./target/wasm32v1-none/release/my_contract.wasm --network testnet
```

If the run is interrupted at step 3, simply re-run the exact same command. StarForge will output:
Expand Down
4 changes: 2 additions & 2 deletions docs/GAS_OPTIMIZATION_BEST_PRACTICES.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ A practical guide to writing cheaper, faster Soroban contracts, and to using

```bash norun
# Profile a single contract
starforge gas analyze ./target/wasm32-unknown-unknown/release/my_contract.wasm
starforge gas analyze ./target/wasm32v1-none/release/my_contract.wasm

# Export a shareable HTML report
starforge gas analyze ./my_contract.wasm --format html --output report.html
Expand All @@ -19,7 +19,7 @@ starforge gas analyze ./my_contract.wasm --format json --output report.json
starforge gas diff ./old.wasm ./new.wasm

# Benchmark every contract in a directory
starforge gas benchmark --dir ./target/wasm32-unknown-unknown/release
starforge gas benchmark --dir ./target/wasm32v1-none/release
```

## What drives cost
Expand Down
25 changes: 6 additions & 19 deletions docs/GAS_OPTIMIZATION_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ improvements.

```bash norun
# Profile a compiled contract
starforge gas profile ./target/wasm32-unknown-unknown/release/my_contract.wasm
starforge gas profile ./target/wasm32v1-none/release/my_contract.wasm

# Compare two builds
starforge gas compare baseline.wasm optimized.wasm
Expand Down Expand Up @@ -154,7 +154,7 @@ debug = []

Build for production without the `debug` feature:
```bash norun
cargo build --release --target wasm32-unknown-unknown
cargo build --release --target wasm32v1-none
```

---
Expand Down Expand Up @@ -247,23 +247,10 @@ impl MyContract {

### Continuous profiling in CI

```yaml
# .github/workflows/ci.yml
- name: Build contract
run: cargo build --release --target wasm32-unknown-unknown

- name: Gas profile
run: |
starforge gas profile \
target/wasm32-unknown-unknown/release/my_contract.wasm \
--fail-on-critical

- name: Gas comparison (on PRs)
if: github.event_name == 'pull_request'
run: |
starforge gas compare \
artifacts/baseline.wasm \
target/wasm32-unknown-unknown/release/my_contract.wasm
```bash
cargo build --release --target wasm32v1-none
starforge gas profile target/wasm32v1-none/release/my_contract.wasm --fail-on-critical
starforge gas compare artifacts/baseline.wasm target/wasm32v1-none/release/my_contract.wasm
```

### Reading the optimization score
Expand Down
3 changes: 1 addition & 2 deletions docs/MANIFEST_MIGRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,7 @@ Map your contracts and WASM build outputs under `[contracts]`:
```toml
[contracts.my_contract]
path = "contracts/my_contract"
wasm = "target/wasm32-unknown-unknown/release/my_contract.wasm"
build = "cargo build --target wasm32-unknown-unknown --release"
build = "starforge contract build"
```

### Step 3: Define Custom Networks and Deploy Targets
Expand Down
4 changes: 2 additions & 2 deletions docs/ROLLBACK_TESTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ Run the default rollback scenario:

```bash norun
starforge test \
--wasm target/wasm32-unknown-unknown/release/contract_v2.wasm \
--wasm target/wasm32v1-none/release/contract_v2.wasm \
--rollback \
--previous-wasm target/wasm32-unknown-unknown/release/contract_v1.wasm \
--previous-wasm target/wasm32v1-none/release/contract_v1.wasm \
--report json
```

Expand Down
2 changes: 1 addition & 1 deletion docs/TEMPLATE_CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ This document covers every step from writing your template to getting it accepte

Before opening a pull request, confirm each item:

- [ ] Template compiles with `cargo build` targeting `wasm32-unknown-unknown`
- [ ] Template compiles for `wasm32v1-none` on stable and `wasm32-unknown-unknown` on the Rust 1.80 MSRV
- [ ] Template passes its own test suite (`cargo test`)
- [ ] Template source uses `{{PROJECT_NAME_PASCAL}}` as the contract struct name
- [ ] A `README.md` is included describing the contract and its public functions
Expand Down
2 changes: 1 addition & 1 deletion docs/TEMPLATE_MARKETPLACE.md
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ twice and diffing the results — the output will be byte-identical.
```bash norun
cd my-dex
stellar contract build
starforge deploy --wasm target/wasm32-unknown-unknown/release/my_dex.wasm
starforge deploy --wasm target/wasm32v1-none/release/my_dex.wasm
```

### For Template Authors
Expand Down
7 changes: 4 additions & 3 deletions docs/manifest.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ Previously, StarForge settings were spread across command-line flags, global use
|---|---|---|
| `version` | `string` | **Required.** Manifest schema version. Must be `"1"`. |
| `package` | `table` | Optional project metadata. |
| `wasm_target` | `string` | Optional Soroban WASM target override. Defaults to the target supported by the active Rust toolchain. |
| `contracts` | `table` | Smart contract target specifications. |
| `networks` | `table` | Custom network endpoints and overrides. |
| `deploy` | `table` | Target deployment environments (`deploy.testnet`, `deploy.mainnet`, etc.). |
Expand All @@ -36,6 +37,7 @@ Previously, StarForge settings were spread across command-line flags, global use

```toml
version = "1"
wasm_target = "wasm32v1-none"

[package]
name = "my_soroban_project"
Expand All @@ -46,8 +48,7 @@ license = "MIT"

[contracts.my_contract]
path = "."
wasm = "target/wasm32-unknown-unknown/release/my_contract.wasm"
build = "cargo build --target wasm32-unknown-unknown --release"
build = "starforge contract build"

[networks.testnet]
horizon_url = "https://horizon-testnet.stellar.org"
Expand All @@ -62,7 +63,7 @@ fee = 100
source_wallet = "alice"

[scripts]
build = "cargo build --target wasm32-unknown-unknown --release"
build = "starforge contract build"
test = "cargo test"
deploy = "starforge deploy"
```
Expand Down
2 changes: 1 addition & 1 deletion docs/native-deploy.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ entirely over Soroban RPC:
5. `CreateContract` / `CreateContractV2` (with `--constructor-arg` when needed)

```bash
starforge deploy run --wasm target/wasm32-unknown-unknown/release/hello.wasm \
starforge deploy run --wasm target/wasm32v1-none/release/hello.wasm \
--wallet deployer --network testnet --execute

# Machine-readable contract id
Expand Down
2 changes: 1 addition & 1 deletion docs/plugins/cookbook.md
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ Security implications for authors:
summarises a compiled contract:

```bash norun
starforge wasm-inspect target/wasm32-unknown-unknown/release/my_contract.wasm
starforge wasm-inspect target/wasm32v1-none/release/my_contract.wasm
```

It reports the module size, WebAssembly version, every section, and whether
Expand Down
18 changes: 12 additions & 6 deletions src/commands/ai_deploy_docs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,8 @@ fn generate_deployment_guide(
let h1 = if markdown { "#" } else { "" };
let h2 = if markdown { "##" } else { "──" };
let h3 = if markdown { "###" } else { " >" };
let wasm_target = crate::utils::wasm_target::resolve_target(None)
.unwrap_or_else(|_| "<selected-target>".to_string());

format!(
r#"{h1} Deployment Guide — {contract}
Expand All @@ -239,23 +241,23 @@ Generated by starforge ai-deploy-docs · Network: {network}

{h2} Prerequisites

- Rust toolchain with `wasm32-unknown-unknown` target installed
- Rust toolchain with the selected Soroban WASM target installed
- Stellar CLI (`stellar`) ≥ 21.0 on your PATH
- A funded {network} account (create with `starforge wallet create deployer --fund`)
- The compiled contract WASM: `target/wasm32-unknown-unknown/release/{contract_snake}.wasm`
- The compiled contract WASM: `target/{wasm_target}/release/{contract_snake}.wasm`

{h2} Build

```bash
stellar contract build
# Output: target/wasm32-unknown-unknown/release/{contract_snake}.wasm
# Output: target/{wasm_target}/release/{contract_snake}.wasm
```

{h2} Pre-deployment Checks

1. Verify the WASM size is within Soroban limits (< 64 KB recommended):
```bash
wc -c target/wasm32-unknown-unknown/release/{contract_snake}.wasm
wc -c target/{wasm_target}/release/{contract_snake}.wasm
```
2. Check your deployer account balance:
```bash
Expand All @@ -271,7 +273,7 @@ stellar contract build

```bash
starforge deploy \
--wasm target/wasm32-unknown-unknown/release/{contract_snake}.wasm \
--wasm target/{wasm_target}/release/{contract_snake}.wasm \
--network {network} \
--wallet deployer
```
Expand Down Expand Up @@ -310,6 +312,7 @@ production deployer accounts and store the passphrase in a secrets manager.
contract_snake = contract.replace('-', "_"),
network = network,
fn_list = fn_list,
wasm_target = wasm_target,
)
}

Expand All @@ -327,6 +330,8 @@ fn generate_runbook(contract: &str, network: &str, source: &str, markdown: bool)

let h1 = if markdown { "#" } else { "" };
let h2 = if markdown { "##" } else { "──" };
let wasm_target = crate::utils::wasm_target::resolve_target(None)
.unwrap_or_else(|_| "<selected-target>".to_string());

format!(
r#"{h1} Operational Runbook — {contract}
Expand All @@ -351,7 +356,7 @@ Generated by starforge ai-deploy-docs · Network: {network}
2. **Deploy the contract**
```bash
starforge deploy \
--wasm target/wasm32-unknown-unknown/release/{contract_snake}.wasm \
--wasm target/{wasm_target}/release/{contract_snake}.wasm \
--network {network} \
--wallet deployer
```
Expand Down Expand Up @@ -404,6 +409,7 @@ starforge analytics show --contract <CONTRACT_ID>
contract_snake = contract.replace('-', "_"),
network = network,
fn_checks = fn_checks,
wasm_target = wasm_target,
)
}

Expand Down
15 changes: 8 additions & 7 deletions src/commands/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -873,15 +873,15 @@ fn handle_build(args: BuildArgs) -> Result<()> {
.map(Path::to_path_buf)
.unwrap_or_else(|| current_dir.clone());

let manifest_target = crate::manifest::discover_manifest(&project_dir)
.map(|path| crate::manifest::load_manifest(&path))
.transpose()?
.and_then(|manifest| manifest.wasm_target);
let wasm_target = crate::utils::wasm_target::resolve_target(manifest_target.as_deref())?;

let mut command = Command::new("stellar");
command.args(["contract", "build"]);

// For stellar-cli >= 22.0.0, `--workspace` can be used to build the workspace.
// Wait, does stellar contract build support --workspace? Actually, `cargo build --workspace` does.
// Wait, we can just pass `--workspace` or `--all` or maybe just do it. I'll just pass `--workspace` if `--all` is set or just let cargo handle it. Wait, the prompt says "Build and deploy commands understand workspaces". Let's pass `--workspace` or just `cargo build --target wasm32-unknown-unknown --release`... actually I'll pass `--workspace`.
// Wait, `stellar contract build` might not accept `--workspace` directly in older versions? Actually, it accepts `--all` or `--workspace`? Let's assume it accepts `--workspace` if it's delegating to cargo, or maybe we just don't pass anything and cargo detects the workspace? Let's check.
// Wait! StarForge wraps `stellar contract build`. I will pass `--workspace`.
// Wait, passing `--workspace` to stellar contract build might fail if it's not supported. I'll just skip it for a moment, wait, I'll pass `--workspace` if `args.all` is true. Wait, `cargo check` task logs might tell me. Let me just pass `--workspace`. Wait, I will just do it.
command.env("CARGO_BUILD_TARGET", &wasm_target);

if args.all {
command.arg("--workspace");
Expand Down Expand Up @@ -928,6 +928,7 @@ fn handle_build(args: BuildArgs) -> Result<()> {
} else {
p::info("Embedding StarForge build provenance metadata.");
}
p::info(&format!("Using Rust target {wasm_target}."));

p::separator();

Expand Down
Loading