nautechsystems/nautilus_trader · error

no Lighter L2 credentials in env

Error message

no Lighter L2 credentials in env

What it means

submit_integrator_revocation needs Lighter L2 (signer) credentials to authenticate the revocation request. Credential::resolve returned None, meaning no API key/private key/account material for the selected environment was found in the environment variables or explicit arguments, so the call aborts with this error.

Source

Thrown at crates/adapters/lighter/src/python/mod.rs:115

    }
}

#[expect(clippy::needless_pass_by_value)]
fn extract_lighter_exec_config(
    py: Python<'_>,
    config: Py<PyAny>,
) -> PyResult<Box<dyn ClientConfig>> {
    match config.extract::<LighterExecutionClientConfig>(py) {
        Ok(c) => Ok(Box::new(c)),
        Err(e) => Err(to_pyvalue_err(format!(
            "Failed to extract LighterExecutionClientConfig: {e}"
        ))),
    }
}

async fn submit_integrator_revocation(environment: LighterEnvironment) -> anyhow::Result<String> {
    let credential = Credential::resolve(None, None, None, environment)?
        .ok_or_else(|| anyhow::anyhow!("no Lighter L2 credentials in env"))?;
    let chain_id = lighter_chain_id(environment);

    let raw = LighterRawHttpClient::new(environment, None, 30, None)?;
    let http = LighterHttpClient::from_raw(raw);
    let next_nonce = http
        .get_next_nonce(credential.account_index(), credential.api_key_index())
        .await?
        .nonce;

    let now_ms = SystemTime::now().duration_since(UNIX_EPOCH)?.as_millis() as i64;

    let tx = ApproveIntegratorTxInfo {
        context: TxContext {
            account_index: credential.account_index(),
            api_key_index: credential.api_key_index(),
            nonce: next_nonce,
            expired_at: now_ms.saturating_add(TX_EXPIRY_MS),
        },

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Export the Lighter L2 credential environment variables expected by Credential::resolve for the target environment (account index, API key index, private key).
  2. Check you selected the correct LighterEnvironment (mainnet vs testnet) matching where your credentials are registered.
  3. Pass the credential values explicitly instead of relying on env resolution.
  4. Verify with `env | grep -i lighter` that the variables are visible to the process.

Example fix

// before
submit_integrator_revocation(LighterEnvironment::Mainnet).await?; // no creds in env
// after
export LIGHTER_MAINNET_PRIVATE_KEY=...;
export LIGHTER_MAINNET_ACCOUNT_INDEX=...;
export LIGHTER_MAINNET_API_KEY_INDEX=...;
// then run again
Defensive patterns

Strategy: validation

Validate before calling

// Check credentials exist before invoking revocation
std::env::var("LIGHTER_L2_PRIVATE_KEY")
    .or_else(|_| std::env::var("LIGHTER_PRIVATE_KEY"))
    .expect("set LIGHTER L2 credentials in env before revocation");

Try / catch

match revoke_lighter_integrator(env).await {
    Ok(tx) => println!("revoked: {tx}"),
    Err(e) if e.to_string().contains("no Lighter L2 credentials") => {
        eprintln!("export LIGHTER_* credentials for {env:?} first");
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling py_revoke_lighter_integrator (or the underlying submit_integrator_revocation) with explicit credential args None while no Lighter L2 env vars for the chosen environment (e.g. mainnet vs testnet) are set.

Common situations: Running the revocation script in a shell/CI where LIGHTER_* env vars are not exported; passing the wrong environment so credentials stored for testnet are not found; key stored in a secrets manager but not exported to env.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/ae89c41c48bf5acd. Report an issue: GitHub.