Initial commit: add .gitignore and README
This commit is contained in:
156
scripts/check-env.ts
Normal file
156
scripts/check-env.ts
Normal file
@@ -0,0 +1,156 @@
|
||||
#!/usr/bin/env tsx
|
||||
|
||||
/**
|
||||
* Environment Variable Checker
|
||||
*
|
||||
* This script checks that all required environment variables are set
|
||||
* and validates RPC URLs are accessible.
|
||||
*
|
||||
* Usage:
|
||||
* tsx scripts/check-env.ts
|
||||
*/
|
||||
|
||||
// Load environment variables FIRST
|
||||
import dotenv from 'dotenv';
|
||||
dotenv.config();
|
||||
|
||||
import { createPublicClient, http } from 'viem';
|
||||
import { mainnet, base, arbitrum, optimism, polygon } from 'viem/chains';
|
||||
import chalk from 'chalk';
|
||||
|
||||
interface EnvCheck {
|
||||
name: string;
|
||||
value: string | undefined;
|
||||
required: boolean;
|
||||
valid: boolean;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
async function checkRpcUrl(name: string, url: string | undefined, chain: any): Promise<EnvCheck> {
|
||||
const check: EnvCheck = {
|
||||
name,
|
||||
value: url ? (url.length > 50 ? `${url.substring(0, 30)}...${url.substring(url.length - 10)}` : url) : undefined,
|
||||
required: false,
|
||||
valid: false,
|
||||
};
|
||||
|
||||
if (!url) {
|
||||
check.error = 'Not set (using default or will fail)';
|
||||
return check;
|
||||
}
|
||||
|
||||
if (url.includes('YOUR_KEY') || url.includes('YOUR_INFURA_KEY')) {
|
||||
check.error = 'Contains placeholder - please set a real RPC URL';
|
||||
return check;
|
||||
}
|
||||
|
||||
try {
|
||||
const client = createPublicClient({
|
||||
chain,
|
||||
transport: http(url, { timeout: 5000 }),
|
||||
});
|
||||
|
||||
const blockNumber = await client.getBlockNumber();
|
||||
check.valid = true;
|
||||
check.error = `✓ Connected (block: ${blockNumber})`;
|
||||
} catch (error: any) {
|
||||
check.error = `Connection failed: ${error.message}`;
|
||||
}
|
||||
|
||||
return check;
|
||||
}
|
||||
|
||||
async function main() {
|
||||
console.log(chalk.blue('='.repeat(60)));
|
||||
console.log(chalk.blue('Environment Variable Checker'));
|
||||
console.log(chalk.blue('='.repeat(60)));
|
||||
console.log('');
|
||||
|
||||
const checks: EnvCheck[] = [];
|
||||
|
||||
// Check RPC URLs
|
||||
console.log(chalk.yellow('Checking RPC URLs...'));
|
||||
console.log('');
|
||||
|
||||
checks.push(await checkRpcUrl('MAINNET_RPC_URL', process.env.MAINNET_RPC_URL, mainnet));
|
||||
checks.push(await checkRpcUrl('BASE_RPC_URL', process.env.BASE_RPC_URL, base));
|
||||
checks.push(await checkRpcUrl('ARBITRUM_RPC_URL', process.env.ARBITRUM_RPC_URL, arbitrum));
|
||||
checks.push(await checkRpcUrl('OPTIMISM_RPC_URL', process.env.OPTIMISM_RPC_URL, optimism));
|
||||
checks.push(await checkRpcUrl('POLYGON_RPC_URL', process.env.POLYGON_RPC_URL, polygon));
|
||||
|
||||
// Check other variables
|
||||
console.log(chalk.yellow('Checking other environment variables...'));
|
||||
console.log('');
|
||||
|
||||
const privateKey = process.env.PRIVATE_KEY;
|
||||
checks.push({
|
||||
name: 'PRIVATE_KEY',
|
||||
value: privateKey ? '***' + privateKey.slice(-4) : undefined,
|
||||
required: false,
|
||||
valid: !!privateKey,
|
||||
error: privateKey ? '✓ Set (not shown for security)' : 'Not set (optional, only needed for mainnet transactions)',
|
||||
});
|
||||
|
||||
// Print results
|
||||
console.log(chalk.blue('='.repeat(60)));
|
||||
console.log(chalk.blue('Results'));
|
||||
console.log(chalk.blue('='.repeat(60)));
|
||||
console.log('');
|
||||
|
||||
let hasErrors = false;
|
||||
let hasWarnings = false;
|
||||
|
||||
for (const check of checks) {
|
||||
const status = check.valid ? chalk.green('✓') : (check.required ? chalk.red('✗') : chalk.yellow('⚠'));
|
||||
const name = chalk.bold(check.name);
|
||||
const value = check.value ? chalk.gray(`(${check.value})`) : '';
|
||||
const error = check.error ? ` - ${check.error}` : '';
|
||||
|
||||
console.log(`${status} ${name} ${value}${error}`);
|
||||
|
||||
if (!check.valid) {
|
||||
if (check.required) {
|
||||
hasErrors = true;
|
||||
} else {
|
||||
hasWarnings = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for placeholder values
|
||||
if (check.value && (check.value.includes('YOUR_KEY') || check.value.includes('YOUR_INFURA_KEY'))) {
|
||||
hasWarnings = true;
|
||||
console.log(chalk.yellow(` ⚠ Contains placeholder - please set a real value`));
|
||||
}
|
||||
}
|
||||
|
||||
console.log('');
|
||||
console.log(chalk.blue('='.repeat(60)));
|
||||
|
||||
if (hasErrors) {
|
||||
console.log(chalk.red('✗ Some required checks failed'));
|
||||
console.log('');
|
||||
console.log('Please:');
|
||||
console.log(' 1. Copy .env.example to .env');
|
||||
console.log(' 2. Fill in your RPC URLs');
|
||||
console.log(' 3. Run this script again to verify');
|
||||
process.exit(1);
|
||||
} else if (hasWarnings) {
|
||||
console.log(chalk.yellow('⚠ Some checks have warnings'));
|
||||
console.log('');
|
||||
console.log('Recommendations:');
|
||||
console.log(' - Set RPC URLs in .env file for better performance');
|
||||
console.log(' - Replace placeholder values with real RPC URLs');
|
||||
console.log(' - Check RPC provider settings if connections fail');
|
||||
console.log('');
|
||||
console.log('You can still run tests, but they may fail if RPC URLs are not properly configured.');
|
||||
} else {
|
||||
console.log(chalk.green('✓ All checks passed!'));
|
||||
console.log('');
|
||||
console.log('You can now run:');
|
||||
console.log(' - pnpm run strat run scenarios/aave/leveraged-long.yml');
|
||||
console.log(' - pnpm run strat:test');
|
||||
}
|
||||
}
|
||||
|
||||
main().catch(console.error);
|
||||
|
||||
16
scripts/install-foundry-deps.sh
Executable file
16
scripts/install-foundry-deps.sh
Executable file
@@ -0,0 +1,16 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Install Foundry dependencies (OpenZeppelin, etc.)
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
echo "Installing Foundry dependencies..."
|
||||
|
||||
# Install forge-std
|
||||
forge install foundry-rs/forge-std --no-commit
|
||||
|
||||
# Install OpenZeppelin contracts
|
||||
forge install OpenZeppelin/openzeppelin-contracts --no-commit
|
||||
|
||||
echo "Foundry dependencies installed successfully!"
|
||||
|
||||
182
scripts/test-strategy.ts
Normal file
182
scripts/test-strategy.ts
Normal file
@@ -0,0 +1,182 @@
|
||||
#!/usr/bin/env tsx
|
||||
|
||||
/**
|
||||
* Test script for DeFi strategy testing
|
||||
*
|
||||
* This script can be used to test the strategy framework with a real fork
|
||||
*
|
||||
* Usage:
|
||||
* tsx scripts/test-strategy.ts
|
||||
*
|
||||
* Environment variables:
|
||||
* MAINNET_RPC_URL - RPC URL for mainnet fork (required)
|
||||
* TEST_SCENARIO - Path to scenario file (default: scenarios/aave/leveraged-long.yml)
|
||||
* TEST_NETWORK - Network name (default: mainnet)
|
||||
*/
|
||||
|
||||
// Load environment variables FIRST, before any other imports that might use them
|
||||
import dotenv from 'dotenv';
|
||||
dotenv.config();
|
||||
|
||||
import { readFileSync } from 'fs';
|
||||
import { join } from 'path';
|
||||
import { ForkOrchestrator } from '../src/strat/core/fork-orchestrator.js';
|
||||
import { ScenarioRunner } from '../src/strat/core/scenario-runner.js';
|
||||
import { loadScenario } from '../src/strat/dsl/scenario-loader.js';
|
||||
import { AaveV3Adapter } from '../src/strat/adapters/aave-v3-adapter.js';
|
||||
import { UniswapV3Adapter } from '../src/strat/adapters/uniswap-v3-adapter.js';
|
||||
import { CompoundV3Adapter } from '../src/strat/adapters/compound-v3-adapter.js';
|
||||
import { Erc20Adapter } from '../src/strat/adapters/erc20-adapter.js';
|
||||
import { FailureInjector } from '../src/strat/core/failure-injector.js';
|
||||
import { JsonReporter } from '../src/strat/reporters/json-reporter.js';
|
||||
import { HtmlReporter } from '../src/strat/reporters/html-reporter.js';
|
||||
import { getNetwork } from '../src/strat/config/networks.js';
|
||||
import type { ProtocolAdapter } from '../src/strat/types.js';
|
||||
|
||||
async function main() {
|
||||
const scenarioPath = process.env.TEST_SCENARIO || 'scenarios/aave/leveraged-long.yml';
|
||||
const networkName = process.env.TEST_NETWORK || 'mainnet';
|
||||
|
||||
// Get RPC URL from env - try network-specific first, then MAINNET_RPC_URL
|
||||
const networkEnvVar = `${networkName.toUpperCase()}_RPC_URL`;
|
||||
let rpcUrl = process.env[networkEnvVar] || process.env.MAINNET_RPC_URL;
|
||||
|
||||
if (!rpcUrl) {
|
||||
console.error('ERROR: RPC URL not found');
|
||||
console.error(` Please set ${networkEnvVar} or MAINNET_RPC_URL in your .env file`);
|
||||
console.error(' Or create .env from .env.example and fill in your RPC URLs');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (rpcUrl.includes('YOUR_KEY') || rpcUrl.includes('YOUR_INFURA_KEY')) {
|
||||
console.error('ERROR: RPC URL contains placeholder');
|
||||
console.error(' Please set a real RPC URL in your .env file');
|
||||
console.error(` Current: ${rpcUrl.substring(0, 50)}...`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log('='.repeat(60));
|
||||
console.log('DeFi Strategy Testing - Test Script');
|
||||
console.log('='.repeat(60));
|
||||
console.log(`Scenario: ${scenarioPath}`);
|
||||
console.log(`Network: ${networkName}`);
|
||||
console.log(`RPC: ${rpcUrl.substring(0, 30)}...`);
|
||||
console.log('');
|
||||
|
||||
try {
|
||||
// Load scenario
|
||||
console.log('Loading scenario...');
|
||||
const scenario = loadScenario(scenarioPath);
|
||||
console.log(`✓ Loaded scenario with ${scenario.steps.length} steps`);
|
||||
|
||||
// Setup network
|
||||
const network = getNetwork(networkName);
|
||||
network.rpcUrl = rpcUrl;
|
||||
|
||||
// Start fork
|
||||
console.log('Starting fork...');
|
||||
const fork = new ForkOrchestrator(network, rpcUrl);
|
||||
await fork.start();
|
||||
console.log('✓ Fork started');
|
||||
|
||||
// Register adapters
|
||||
console.log('Registering adapters...');
|
||||
const adapters = new Map<string, ProtocolAdapter>();
|
||||
adapters.set('erc20', new Erc20Adapter());
|
||||
adapters.set('aave-v3', new AaveV3Adapter());
|
||||
adapters.set('uniswap-v3', new UniswapV3Adapter());
|
||||
adapters.set('compound-v3', new CompoundV3Adapter());
|
||||
|
||||
// Register failure injector
|
||||
const failureInjector = new FailureInjector(fork);
|
||||
adapters.set('failure', {
|
||||
name: 'failure',
|
||||
discover: async () => ({}),
|
||||
actions: {
|
||||
oracleShock: (ctx, args) => failureInjector.oracleShock(ctx, args),
|
||||
timeTravel: (ctx, args) => failureInjector.timeTravel(ctx, args),
|
||||
setTimestamp: (ctx, args) => failureInjector.setTimestamp(ctx, args),
|
||||
liquidityShock: (ctx, args) => failureInjector.liquidityShock(ctx, args),
|
||||
setBaseFee: (ctx, args) => failureInjector.setBaseFee(ctx, args),
|
||||
pauseReserve: (ctx, args) => failureInjector.pauseReserve(ctx, args),
|
||||
capExhaustion: (ctx, args) => failureInjector.capExhaustion(ctx, args),
|
||||
},
|
||||
views: {},
|
||||
});
|
||||
console.log('✓ Adapters registered');
|
||||
|
||||
// Create snapshot
|
||||
console.log('Creating snapshot...');
|
||||
const snapshotId = await fork.snapshot('test_start');
|
||||
console.log(`✓ Snapshot created: ${snapshotId}`);
|
||||
|
||||
// Run scenario
|
||||
console.log('');
|
||||
console.log('Running scenario...');
|
||||
console.log('-'.repeat(60));
|
||||
const runner = new ScenarioRunner(fork, adapters, network);
|
||||
const report = await runner.run(scenario);
|
||||
console.log('-'.repeat(60));
|
||||
|
||||
// Print summary
|
||||
console.log('');
|
||||
console.log('='.repeat(60));
|
||||
console.log('Run Summary');
|
||||
console.log('='.repeat(60));
|
||||
console.log(`Status: ${report.passed ? '✓ PASSED' : '✗ FAILED'}`);
|
||||
console.log(`Steps: ${report.steps.length}`);
|
||||
console.log(`Duration: ${((report.endTime! - report.startTime) / 1000).toFixed(2)}s`);
|
||||
console.log(`Total Gas: ${report.metadata.totalGas.toString()}`);
|
||||
if (report.error) {
|
||||
console.log(`Error: ${report.error}`);
|
||||
}
|
||||
|
||||
// Generate reports
|
||||
const outputDir = 'out';
|
||||
const timestamp = Date.now();
|
||||
const jsonPath = join(outputDir, `test-run-${timestamp}.json`);
|
||||
const htmlPath = join(outputDir, `test-report-${timestamp}.html`);
|
||||
|
||||
console.log('');
|
||||
console.log('Generating reports...');
|
||||
JsonReporter.generate(report, jsonPath);
|
||||
HtmlReporter.generate(report, htmlPath);
|
||||
console.log(`✓ JSON report: ${jsonPath}`);
|
||||
console.log(`✓ HTML report: ${htmlPath}`);
|
||||
|
||||
// Print step details
|
||||
console.log('');
|
||||
console.log('Step Results:');
|
||||
for (const step of report.steps) {
|
||||
const status = step.result.success ? '✓' : '✗';
|
||||
const duration = (step.duration / 1000).toFixed(2);
|
||||
console.log(` ${status} ${step.stepName} (${duration}s)`);
|
||||
if (!step.result.success) {
|
||||
console.log(` Error: ${step.result.error}`);
|
||||
}
|
||||
if (step.assertions && step.assertions.length > 0) {
|
||||
const passed = step.assertions.filter(a => a.passed).length;
|
||||
const total = step.assertions.length;
|
||||
console.log(` Assertions: ${passed}/${total} passed`);
|
||||
}
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
await fork.revert(snapshotId);
|
||||
await fork.stop();
|
||||
|
||||
console.log('');
|
||||
console.log('='.repeat(60));
|
||||
console.log('Test completed');
|
||||
|
||||
process.exit(report.passed ? 0 : 1);
|
||||
} catch (error: any) {
|
||||
console.error('');
|
||||
console.error('ERROR:', error.message);
|
||||
console.error(error.stack);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
|
||||
72
scripts/verify-env.ts
Normal file
72
scripts/verify-env.ts
Normal file
@@ -0,0 +1,72 @@
|
||||
#!/usr/bin/env tsx
|
||||
|
||||
/**
|
||||
* Quick verification that environment variables are being loaded correctly
|
||||
*
|
||||
* Usage:
|
||||
* tsx scripts/verify-env.ts
|
||||
*/
|
||||
|
||||
// Load dotenv FIRST
|
||||
import dotenv from 'dotenv';
|
||||
dotenv.config();
|
||||
|
||||
console.log('Environment Variable Verification');
|
||||
console.log('='.repeat(50));
|
||||
|
||||
// Check if dotenv loaded the .env file
|
||||
const envFile = dotenv.config();
|
||||
if (envFile.error) {
|
||||
console.log('⚠ .env file not found (this is okay if using system env vars)');
|
||||
} else {
|
||||
console.log('✓ .env file loaded');
|
||||
}
|
||||
|
||||
console.log('');
|
||||
|
||||
// Check RPC URLs
|
||||
const rpcUrls = {
|
||||
'MAINNET_RPC_URL': process.env.MAINNET_RPC_URL,
|
||||
'BASE_RPC_URL': process.env.BASE_RPC_URL,
|
||||
'ARBITRUM_RPC_URL': process.env.ARBITRUM_RPC_URL,
|
||||
'OPTIMISM_RPC_URL': process.env.OPTIMISM_RPC_URL,
|
||||
'POLYGON_RPC_URL': process.env.POLYGON_RPC_URL,
|
||||
};
|
||||
|
||||
console.log('RPC URLs:');
|
||||
for (const [key, value] of Object.entries(rpcUrls)) {
|
||||
if (value) {
|
||||
const display = value.length > 50
|
||||
? `${value.substring(0, 30)}...${value.substring(value.length - 10)}`
|
||||
: value;
|
||||
const hasPlaceholder = value.includes('YOUR_KEY') || value.includes('YOUR_INFURA_KEY');
|
||||
console.log(` ${key}: ${hasPlaceholder ? '⚠ PLACEHOLDER' : '✓'} ${display}`);
|
||||
} else {
|
||||
console.log(` ${key}: ✗ Not set`);
|
||||
}
|
||||
}
|
||||
|
||||
console.log('');
|
||||
|
||||
// Check other vars
|
||||
if (process.env.PRIVATE_KEY) {
|
||||
console.log('PRIVATE_KEY: ✓ Set (not shown)');
|
||||
} else {
|
||||
console.log('PRIVATE_KEY: ✗ Not set (optional)');
|
||||
}
|
||||
|
||||
console.log('');
|
||||
console.log('='.repeat(50));
|
||||
|
||||
// Test network loading
|
||||
try {
|
||||
// This will import networks.ts which should use the env vars
|
||||
const { getNetwork } = await import('../src/strat/config/networks.js');
|
||||
const network = getNetwork('mainnet');
|
||||
console.log(`Network config test: ✓ Loaded (RPC: ${network.rpcUrl.substring(0, 30)}...)`);
|
||||
} catch (error: any) {
|
||||
console.log(`Network config test: ✗ Failed - ${error.message}`);
|
||||
}
|
||||
|
||||
console.log('');
|
||||
|
||||
169
scripts/verify-setup.ts
Normal file
169
scripts/verify-setup.ts
Normal file
@@ -0,0 +1,169 @@
|
||||
#!/usr/bin/env tsx
|
||||
|
||||
/**
|
||||
* Comprehensive Setup Verification Script
|
||||
*
|
||||
* Verifies that all scripts are properly configured with environment variables
|
||||
* and that connections work correctly.
|
||||
*
|
||||
* Usage:
|
||||
* tsx scripts/verify-setup.ts
|
||||
*/
|
||||
|
||||
// Load dotenv FIRST
|
||||
import dotenv from 'dotenv';
|
||||
dotenv.config();
|
||||
|
||||
import { existsSync } from 'fs';
|
||||
import { join } from 'path';
|
||||
import chalk from 'chalk';
|
||||
|
||||
async function main() {
|
||||
console.log(chalk.blue('='.repeat(70)));
|
||||
console.log(chalk.blue('DeFi Strategy Testing Framework - Setup Verification'));
|
||||
console.log(chalk.blue('='.repeat(70)));
|
||||
console.log('');
|
||||
|
||||
let allGood = true;
|
||||
|
||||
// Check .env file
|
||||
console.log(chalk.yellow('1. Checking .env file...'));
|
||||
if (existsSync('.env')) {
|
||||
console.log(chalk.green(' ✓ .env file exists'));
|
||||
} else {
|
||||
console.log(chalk.yellow(' ⚠ .env file not found'));
|
||||
console.log(chalk.yellow(' Create it from .env.example: cp .env.example .env'));
|
||||
allGood = false;
|
||||
}
|
||||
console.log('');
|
||||
|
||||
// Check .env.example
|
||||
console.log(chalk.yellow('2. Checking .env.example...'));
|
||||
if (existsSync('.env.example')) {
|
||||
console.log(chalk.green(' ✓ .env.example exists'));
|
||||
} else {
|
||||
console.log(chalk.red(' ✗ .env.example not found'));
|
||||
allGood = false;
|
||||
}
|
||||
console.log('');
|
||||
|
||||
// Check environment variables
|
||||
console.log(chalk.yellow('3. Checking environment variables...'));
|
||||
const requiredVars = ['MAINNET_RPC_URL'];
|
||||
const optionalVars = ['BASE_RPC_URL', 'ARBITRUM_RPC_URL', 'OPTIMISM_RPC_URL', 'POLYGON_RPC_URL', 'PRIVATE_KEY'];
|
||||
|
||||
for (const varName of requiredVars) {
|
||||
const value = process.env[varName];
|
||||
if (value && !value.includes('YOUR_KEY') && !value.includes('YOUR_INFURA_KEY')) {
|
||||
console.log(chalk.green(` ✓ ${varName} is set`));
|
||||
} else {
|
||||
console.log(chalk.red(` ✗ ${varName} is not properly configured`));
|
||||
allGood = false;
|
||||
}
|
||||
}
|
||||
|
||||
for (const varName of optionalVars) {
|
||||
const value = process.env[varName];
|
||||
if (value && !value.includes('YOUR_KEY') && !value.includes('YOUR_INFURA_KEY')) {
|
||||
console.log(chalk.green(` ✓ ${varName} is set`));
|
||||
} else if (value) {
|
||||
console.log(chalk.yellow(` ⚠ ${varName} contains placeholder`));
|
||||
} else {
|
||||
console.log(chalk.gray(` - ${varName} not set (optional)`));
|
||||
}
|
||||
}
|
||||
console.log('');
|
||||
|
||||
// Check scripts load dotenv
|
||||
console.log(chalk.yellow('4. Checking scripts load dotenv...'));
|
||||
const scripts = [
|
||||
'src/strat/cli.ts',
|
||||
'src/cli/cli.ts',
|
||||
'scripts/test-strategy.ts',
|
||||
];
|
||||
|
||||
for (const script of scripts) {
|
||||
if (existsSync(script)) {
|
||||
// Read first few lines to check for dotenv
|
||||
const fs = await import('fs');
|
||||
const content = fs.readFileSync(script, 'utf-8');
|
||||
const lines = content.split('\n').slice(0, 20);
|
||||
const hasDotenv = lines.some(line =>
|
||||
line.includes('dotenv') && (line.includes('import') || line.includes('require'))
|
||||
);
|
||||
const dotenvConfigLine = lines.findIndex(line => line.includes('dotenv.config()'));
|
||||
const firstNonDotenvImport = lines.findIndex(line =>
|
||||
line.includes('import') && !line.includes('dotenv') && !line.trim().startsWith('//')
|
||||
);
|
||||
const dotenvBeforeImports = dotenvConfigLine !== -1 &&
|
||||
(firstNonDotenvImport === -1 || dotenvConfigLine < firstNonDotenvImport);
|
||||
|
||||
if (hasDotenv && dotenvBeforeImports) {
|
||||
console.log(chalk.green(` ✓ ${script} loads dotenv correctly`));
|
||||
} else if (hasDotenv) {
|
||||
console.log(chalk.yellow(` ⚠ ${script} loads dotenv but may be after other imports`));
|
||||
} else {
|
||||
console.log(chalk.red(` ✗ ${script} does not load dotenv`));
|
||||
allGood = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
console.log('');
|
||||
|
||||
// Check network config
|
||||
console.log(chalk.yellow('5. Checking network configuration...'));
|
||||
try {
|
||||
const { getNetwork } = await import('../src/strat/config/networks.js');
|
||||
const network = getNetwork('mainnet');
|
||||
if (network.rpcUrl && !network.rpcUrl.includes('YOUR_KEY')) {
|
||||
console.log(chalk.green(` ✓ Network config loads correctly`));
|
||||
console.log(chalk.gray(` Mainnet RPC: ${network.rpcUrl.substring(0, 50)}...`));
|
||||
} else {
|
||||
console.log(chalk.yellow(` ⚠ Network config has placeholder RPC URL`));
|
||||
}
|
||||
} catch (error: any) {
|
||||
console.log(chalk.red(` ✗ Network config error: ${error.message}`));
|
||||
allGood = false;
|
||||
}
|
||||
console.log('');
|
||||
|
||||
// Check scenario files
|
||||
console.log(chalk.yellow('6. Checking scenario files...'));
|
||||
const scenarios = [
|
||||
'scenarios/aave/leveraged-long.yml',
|
||||
'scenarios/aave/liquidation-drill.yml',
|
||||
'scenarios/compound3/supply-borrow.yml',
|
||||
];
|
||||
|
||||
for (const scenario of scenarios) {
|
||||
if (existsSync(scenario)) {
|
||||
console.log(chalk.green(` ✓ ${scenario} exists`));
|
||||
} else {
|
||||
console.log(chalk.yellow(` ⚠ ${scenario} not found`));
|
||||
}
|
||||
}
|
||||
console.log('');
|
||||
|
||||
// Summary
|
||||
console.log(chalk.blue('='.repeat(70)));
|
||||
if (allGood) {
|
||||
console.log(chalk.green('✓ Setup verification passed!'));
|
||||
console.log('');
|
||||
console.log('Next steps:');
|
||||
console.log(' 1. Run environment check: pnpm run check:env');
|
||||
console.log(' 2. Test a scenario: pnpm run strat:test');
|
||||
console.log(' 3. Run a scenario: pnpm run strat run scenarios/aave/leveraged-long.yml');
|
||||
} else {
|
||||
console.log(chalk.yellow('⚠ Setup verification found some issues'));
|
||||
console.log('');
|
||||
console.log('Please:');
|
||||
console.log(' 1. Create .env file: cp .env.example .env');
|
||||
console.log(' 2. Fill in your RPC URLs in .env');
|
||||
console.log(' 3. Run: pnpm run check:env');
|
||||
process.exit(1);
|
||||
}
|
||||
console.log('');
|
||||
}
|
||||
|
||||
main().catch(console.error);
|
||||
|
||||
Reference in New Issue
Block a user