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
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ members = [
"contracts/market",
"contracts/dispute",
"contracts/royalty_distribution",
"contracts/escrow",
]

[workspace.dependencies]
Expand Down
39 changes: 39 additions & 0 deletions apps/backend/src/test/seeds/basic.seed.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/**
* Basic seed entry point — seeds a small representative data set
* (10 users, 5 courses, enrollments, progress records).
*
* Invoked via: npm run seed:basic --workspace=apps/backend
* Which resolves to: ts-node -r tsconfig-paths/register src/test/seeds/basic.seed.ts
*/
import { NestFactory } from '@nestjs/core';
import { Logger } from '@nestjs/common';
import { AppModule } from '../../app.module';
import { SeedService } from '../../database/seed.service';
import { env } from '../../config/env';

async function bootstrap(): Promise<void> {
const logger = new Logger('BasicSeed');

if (env.isProduction) {
logger.error('❌ Refusing to seed in production. Set NODE_ENV to development or staging.');
process.exit(1);
}

const app = await NestFactory.createApplicationContext(AppModule, {
logger: ['error', 'warn'],
});
const seedService = app.get(SeedService);

try {
logger.log('🌱 Running basic seed (10 users, 5 courses) …');
await seedService.seed({ count: 10, includeReviews: false, includeTips: false });
logger.log('✅ Basic seed complete.');
} catch (err) {
logger.error('❌ Basic seed failed:', err);
process.exit(1);
} finally {
await app.close();
}
}

bootstrap();
57 changes: 57 additions & 0 deletions apps/backend/src/test/seeds/cleanup.seed.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/**
* Cleanup seed entry point — removes seeded test data from the database.
*
* Invoked via: npm run seed:cleanup --workspace=apps/backend
* Which resolves to: ts-node -r tsconfig-paths/register src/test/seeds/cleanup.seed.ts
*/
import { NestFactory } from '@nestjs/core';
import { Logger } from '@nestjs/common';
import { getDataSourceToken } from '@nestjs/typeorm';
import { DataSource } from 'typeorm';
import { AppModule } from '../../app.module';
import { env } from '../../config/env';

async function bootstrap(): Promise<void> {
const logger = new Logger('CleanupSeed');

if (env.isProduction) {
logger.error('❌ Refusing to truncate in production. Set NODE_ENV to development or staging.');
process.exit(1);
}

const app = await NestFactory.createApplicationContext(AppModule, {
logger: ['error', 'warn'],
});

const dataSource = app.get<DataSource>(getDataSourceToken());

try {
logger.log('🗑️ Truncating seeded tables …');

// Truncate in dependency order (children first, then parents)
const tables = [
'progress',
'enrollment',
'review',
'lesson',
'course_module',
'notification',
'course',
'user',
];

for (const table of tables) {
await dataSource.query(`TRUNCATE TABLE "${table}" CASCADE`);
logger.log(` ✓ ${table} cleared`);
}

logger.log('✅ Cleanup complete.');
} catch (err) {
logger.error('❌ Cleanup failed:', err);
process.exit(1);
} finally {
await app.close();
}
}

bootstrap();
39 changes: 39 additions & 0 deletions apps/backend/src/test/seeds/performance.seed.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/**
* Performance seed entry point — seeds a large data set intended for
* load / performance testing (500 users, 50 courses, full relations).
*
* Invoked via: npm run seed:performance --workspace=apps/backend
* Which resolves to: ts-node -r tsconfig-paths/register src/test/seeds/performance.seed.ts
*/
import { NestFactory } from '@nestjs/core';
import { Logger } from '@nestjs/common';
import { AppModule } from '../../app.module';
import { SeedService } from '../../database/seed.service';
import { env } from '../../config/env';

async function bootstrap(): Promise<void> {
const logger = new Logger('PerformanceSeed');

if (env.isProduction) {
logger.error('❌ Refusing to seed in production. Set NODE_ENV to development or staging.');
process.exit(1);
}

const app = await NestFactory.createApplicationContext(AppModule, {
logger: ['error', 'warn'],
});
const seedService = app.get(SeedService);

try {
logger.log('🌱 Running performance seed (500 users, 50 courses) …');
await seedService.seed({ count: 500, includeReviews: true, includeTips: true });
logger.log('✅ Performance seed complete.');
} catch (err) {
logger.error('❌ Performance seed failed:', err);
process.exit(1);
} finally {
await app.close();
}
}

bootstrap();
17 changes: 17 additions & 0 deletions contracts/escrow/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[package]
name = "brain-storm-escrow"
version = "0.1.0"
edition = "2021"

[lib]
crate-type = ["cdylib", "rlib"]

[dependencies]
soroban-sdk = { version = "21.0.0", features = ["alloc"] }
brain-storm-shared = { path = "../shared", default-features = false }

[dev-dependencies]
soroban-sdk = { version = "21.0.0", features = ["testutils"] }

[lints]
workspace = true
Empty file modified scripts/audit-eslint-disables.sh
100644 → 100755
Empty file.
Empty file modified scripts/audit-imports.sh
100644 → 100755
Empty file.
68 changes: 50 additions & 18 deletions scripts/build-wasm.sh
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,38 +1,70 @@
#!/bin/bash
# Build WASM contracts locally for development/testing
#!/usr/bin/env bash
# Build WASM contracts locally for development/testing.
# Builds every crate under contracts/ that contains a Cargo.toml.

set -e
set -euo pipefail

ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"

GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m'

echo -e "${YELLOW}🔨 Building WASM contracts...${NC}"

# Build all contracts
for contract in stellar-contract packages/contracts/contracts/market; do
if [ -d "$contract" ]; then
echo -e "${GREEN}Building $contract...${NC}"
cd "$contract"
cargo build --target wasm32-unknown-unknown --release
cd - > /dev/null
BUILT=0
FAILED=0

for contract_dir in "$ROOT_DIR"/contracts/*/; do
contract_name=$(basename "$contract_dir")

# Skip entries that are not Rust crates
if [ ! -f "$contract_dir/Cargo.toml" ]; then
continue
fi

echo -e "${GREEN}Building $contract_name...${NC}"
if cargo build \
--manifest-path "$contract_dir/Cargo.toml" \
--target wasm32-unknown-unknown \
--release; then
BUILT=$((BUILT + 1))
else
echo -e "${RED}❌ Failed to build $contract_name${NC}" >&2
FAILED=$((FAILED + 1))
fi
done

echo -e "${GREEN}✅ All WASM contracts built!${NC}"
if [ "$BUILT" -eq 0 ] && [ "$FAILED" -eq 0 ]; then
echo -e "${YELLOW}⚠️ No Rust contracts found under contracts/${NC}"
exit 0
fi

if [ "$FAILED" -gt 0 ]; then
echo -e "${RED}❌ $FAILED contract(s) failed to build.${NC}" >&2
exit 1
fi

echo -e "${GREEN}✅ All $BUILT WASM contract(s) built!${NC}"

# Compute hashes
# Compute checksums
echo -e "${YELLOW}📋 Computing checksums...${NC}"
echo "# WASM Contract Checksums" > CHECKSUMS.md
echo "" >> CHECKSUMS.md
echo "| Contract | Size | SHA256 |" >> CHECKSUMS.md
echo "|----------|------|--------|" >> CHECKSUMS.md
CHECKSUMS_FILE="$ROOT_DIR/CHECKSUMS.md"
{
echo "# WASM Contract Checksums"
echo ""
echo "| Contract | Size | SHA256 |"
echo "|----------|------|--------|"
} > "$CHECKSUMS_FILE"

find . -name "*.wasm" -type f | while read -r file; do
find "$ROOT_DIR/target/wasm32-unknown-unknown/release" \
-maxdepth 1 -name "*.wasm" -type f \
! -path "*/deps/*" 2>/dev/null | sort | while read -r file; do
NAME=$(basename "$file" .wasm)
SIZE=$(stat -c%s "$file" 2>/dev/null || stat -f%z "$file" 2>/dev/null)
HASH=$(sha256sum "$file" | cut -d' ' -f1)
echo "| $NAME | $SIZE bytes | \`$HASH\` |" >> CHECKSUMS.md
echo "| $NAME | $SIZE bytes | \`$HASH\` |" >> "$CHECKSUMS_FILE"
done

echo -e "${GREEN}✅ Checksums saved to CHECKSUMS.md${NC}"
Empty file modified scripts/ci-local.sh
100644 → 100755
Empty file.
Empty file modified scripts/consolidate-types.sh
100644 → 100755
Empty file.
Empty file modified scripts/find-duplicate-types.sh
100644 → 100755
Empty file.
Empty file modified scripts/find-unused-exports.sh
100644 → 100755
Empty file.
Empty file modified scripts/fix-imports.sh
100644 → 100755
Empty file.
Empty file modified scripts/generate-contract-errors.js
100644 → 100755
Empty file.
Empty file modified scripts/generate-trend-report.js
100644 → 100755
Empty file.
Empty file modified scripts/migrate-error-enums.sh
100644 → 100755
Empty file.
68 changes: 52 additions & 16 deletions scripts/publish-registry.sh
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,32 +1,68 @@
#!/bin/bash
# Publish contracts to Soroban registry
#!/usr/bin/env bash
# Publish compiled contracts to the Stellar/Soroban registry.
# Requires: DEPLOYER_SECRET env var, stellar CLI, and wasm files built by build-wasm.sh.

set -e
set -euo pipefail

ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
WASM_DIR="$ROOT_DIR/target/wasm32-unknown-unknown/release"
NETWORK="${NETWORK:-testnet}"

GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m'

# Check if deployer secret is set
if [ -z "$DEPLOYER_SECRET" ]; then
echo -e "${RED}❌ DEPLOYER_SECRET environment variable not set${NC}"
# Check required env var
if [ -z "${DEPLOYER_SECRET:-}" ]; then
echo -e "${RED}❌ DEPLOYER_SECRET environment variable not set${NC}" >&2
exit 1
fi

# Check stellar CLI is available
if ! command -v stellar &>/dev/null; then
echo -e "${RED}❌ 'stellar' CLI not found in PATH. Install from https://github.com/stellar/stellar-cli/releases${NC}" >&2
exit 1
fi

# Ensure wasm files are present
if [ ! -d "$WASM_DIR" ]; then
echo -e "${RED}❌ WASM output directory not found: $WASM_DIR${NC}" >&2
echo -e "${YELLOW} Run ./scripts/build-wasm.sh (or ./scripts/build.sh) first.${NC}" >&2
exit 1
fi

echo -e "${YELLOW}📦 Publishing contracts to Soroban registry...${NC}"
WASM_FILES=()
while IFS= read -r -d '' f; do
WASM_FILES+=("$f")
done < <(find "$WASM_DIR" -maxdepth 1 -name "*.wasm" -type f ! -path "*/deps/*" -print0 2>/dev/null)

# Find all WASM files
find . -name "*.wasm" -type f | while read -r file; do
if [ "${#WASM_FILES[@]}" -eq 0 ]; then
echo -e "${RED}❌ No .wasm files found in $WASM_DIR${NC}" >&2
echo -e "${YELLOW} Run ./scripts/build-wasm.sh (or ./scripts/build.sh) first.${NC}" >&2
exit 1
fi

echo -e "${YELLOW}📦 Publishing ${#WASM_FILES[@]} contract(s) to Stellar registry (network: $NETWORK)...${NC}"

PUBLISHED=0
FAILED=0

for file in "${WASM_FILES[@]}"; do
NAME=$(basename "$file" .wasm)
echo -e "${GREEN}Publishing $NAME...${NC}"

# Publish to testnet
soroban contract install \

if stellar contract install \
--wasm "$file" \
--network testnet \
--source-account "$DEPLOYER_SECRET" \
--output-json || echo -e "${RED}❌ Failed to publish $NAME${NC}"
--network "$NETWORK" \
--source-account "$DEPLOYER_SECRET"; then
PUBLISHED=$((PUBLISHED + 1))
else
echo -e "${RED}❌ Failed to publish $NAME${NC}" >&2
FAILED=$((FAILED + 1))
fi
done

echo -e "${GREEN}✅ All contracts published!${NC}"
echo ""
echo -e "${GREEN}✅ Published: $PUBLISHED | ${RED}Failed: $FAILED${NC}"
[ "$FAILED" -gt 0 ] && exit 1 || exit 0
Empty file modified scripts/remove-unused-exports.sh
100644 → 100755
Empty file.
Loading