fix: tests/setup/stack.ts: contract addresses have no env var override path (#391)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
openhands 2026-03-02 22:34:44 +00:00
parent 0fe098ddc3
commit c9fe1ab178
3 changed files with 49 additions and 20 deletions

View file

@ -18,8 +18,12 @@ export interface HealthCheckResult {
* 1. Checking eth_chainId returns the expected chain
* 2. Making an eth_call to verify contract accessibility
* 3. Confirming deployed contracts are accessible
*
* @param kraikenAddress - Optional Kraiken contract address. When provided the
* deployments-local.json file is not read, which allows the check to succeed
* in containerised environments that supply addresses via env vars.
*/
export async function checkRpcFunctional(rpcUrl: string): Promise<HealthCheckResult> {
export async function checkRpcFunctional(rpcUrl: string, kraikenAddress?: string): Promise<HealthCheckResult> {
const service = 'RPC Proxy';
try {
@ -54,24 +58,27 @@ export async function checkRpcFunctional(rpcUrl: string): Promise<HealthCheckRes
};
}
// Step 2: Load deployed contracts and verify accessibility
const deploymentsPath = resolve(repoRoot, 'onchain', 'deployments-local.json');
let deployments: { contracts: { Kraiken: string } };
// Step 2: Resolve the Kraiken address for the eth_call probe.
// Use the address supplied by the caller; fall back to deployments-local.json.
let resolvedKraikenAddress = kraikenAddress;
try {
const deploymentsContent = await readFile(deploymentsPath, 'utf-8');
deployments = JSON.parse(deploymentsContent);
} catch (error) {
return {
success: false,
service,
message: 'Failed to load contract deployments',
details: `Could not read ${deploymentsPath}. Run stack setup first.`
};
if (!resolvedKraikenAddress) {
const deploymentsPath = resolve(repoRoot, 'onchain', 'deployments-local.json');
try {
const deploymentsContent = await readFile(deploymentsPath, 'utf-8');
const deployments: { contracts: { Kraiken: string } } = JSON.parse(deploymentsContent);
resolvedKraikenAddress = deployments.contracts.Kraiken;
} catch (error) {
return {
success: false,
service,
message: 'Failed to load contract deployments',
details: `Could not read ${deploymentsPath}. Run stack setup first or set STACK_KRAIKEN_ADDRESS.`
};
}
}
// Step 3: Verify we can make eth_call to deployed Kraiken contract
const kraikenAddress = deployments.contracts.Kraiken;
const totalSupplyCalldata = '0x18160ddd'; // totalSupply() selector
const callResponse = await fetch(rpcUrl, {
@ -82,7 +89,7 @@ export async function checkRpcFunctional(rpcUrl: string): Promise<HealthCheckRes
id: 2,
method: 'eth_call',
params: [{
to: kraikenAddress,
to: resolvedKraikenAddress,
data: totalSupplyCalldata
}, 'latest']
}),
@ -104,7 +111,7 @@ export async function checkRpcFunctional(rpcUrl: string): Promise<HealthCheckRes
success: false,
service,
message: 'Contract call returned RPC error',
details: `${callPayload.error.message}. Kraiken contract at ${kraikenAddress} may not be deployed.`
details: `${callPayload.error.message}. Kraiken contract at ${resolvedKraikenAddress} may not be deployed.`
};
}
@ -271,16 +278,20 @@ export async function checkWebAppAccessible(webAppUrl: string): Promise<HealthCh
}
/**
* Run all functional health checks and return detailed results
* Run all functional health checks and return detailed results.
* Accepts an optional `contracts` field so that the Kraiken address resolved
* by getStackConfig() (including any STACK_KRAIKEN_ADDRESS env var override)
* is reused here, avoiding a redundant file read.
*/
export async function runAllHealthChecks(options: {
rpcUrl: string;
webAppUrl: string;
graphqlUrl: string;
contracts?: { Kraiken: string };
}): Promise<HealthCheckResult[]> {
// Skip GraphQL check temporarily - Ponder crashed but staking still works
const results = await Promise.all([
checkRpcFunctional(options.rpcUrl),
checkRpcFunctional(options.rpcUrl, options.contracts?.Kraiken),
checkWebAppAccessible(options.webAppUrl),
// checkGraphqlIndexed(options.graphqlUrl),
]);

View file

@ -34,14 +34,16 @@ function loadContractAddresses(): ContractAddresses {
const envLm = process.env.STACK_LM_ADDRESS;
if (envKraiken && envStake && envLm) {
const envOptimizerProxy = process.env.STACK_OPTIMIZER_PROXY_ADDRESS;
return {
Kraiken: envKraiken,
Stake: envStake,
LiquidityManager: envLm,
...(envOptimizerProxy !== undefined ? { OptimizerProxy: envOptimizerProxy } : {}),
};
}
let fileContracts: ContractAddresses;
let fileContracts!: ContractAddresses;
try {
const deploymentsPath = join(process.cwd(), 'onchain', 'deployments-local.json');
const deploymentsJson = readFileSync(deploymentsPath, 'utf-8');