Bring certified infrastructure state
into smart contracts and autonomous agents
Invarians certifies the structural execution context of blockchain infrastructure — L1 regime, L2 rollup signals, bridge liveness. This page describes how to bring that certified state on-chain via Chainlink Functions, and how it maps to the Chainlink Runtime Environment (CRE) agent model.
Invarians measures structural regime directly from finalized block data — rhythm, saturation, continuity — and certifies a regime vector independent of fee markets. This is the dimension missing from on-chain execution logic.
Asset prices, liquidity depth, gas fees, slippage estimates. Observable, reactive, dominated by MEV and arbitrage noise at short timescales.
Structural regime of the chain substrate — S1D1 · S1D2 · S2D1 · S2D2. Observable independently of market activity. Certified, signed, reproducible.
Chainlink Functions executes off-chain JavaScript on a decentralized oracle network and returns the result to your smart contract. The pattern below is designed to bring the Invarians execution context on-chain with a single Functions request.
| Step | Actor | Action |
|---|---|---|
| 1 | Smart contract | Calls sendRequest() on the Chainlink Functions Router |
| 2 | Functions DON | Executes the JavaScript source — calls Invarians API with encrypted API key (stored as Functions secret) |
| 3 | Invarians API | Returns signed attestation: l1_regime, bridge_state, oracle_status, data_age_seconds |
| 4 | Functions DON | Encodes the response and delivers it to fulfillRequest() on the contract |
| 5 | Smart contract | Stores l1_regime and bridge_state, gates execution via modifier — S1D1 · S1D2 · S2D1 · S2D2 · BS1 · BS2 |
// Invarians × Chainlink Functions — source.js // Deploy via Chainlink Functions Toolkit — store API key as encrypted secret const chain = args[0] || "ethereum" // pass target chain as argument const apiKey = secrets.INVARIANS_API_KEY const response = await Functions.makeHttpRequest({ url: `https://sdpilypwumxsyyipceew.supabase.co/functions/v1/attestation/${chain}`, headers: { "Authorization": `Bearer ${apiKey}` }, timeout: 5000 }) if (response.error) throw new Error(`API error: ${response.error}`) const data = response.data // Guard: reject STALE signals (data older than 1 hour) if (data.oracle_status !== "OK") throw new Error(`Signal ${data.oracle_status} — not relaying`) // Encode: l1_regime + bridge_state as packed string // l1_regime: "S1D1" | "S1D2" | "S2D1" | "S2D2" // bridge_state: "BS1" | "BS2" const l1 = data.proof_of_execution_context.l1_regime const bridge = data.proof_of_execution_context.bridge_state return Functions.encodeString(l1 + "|" + bridge)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.19; import "@chainlink/contracts/src/v0.8/functions/FunctionsClient.sol"; import "@chainlink/contracts/src/v0.8/functions/ConfirmedOwner.sol"; contract InvariansGatedExecutor is FunctionsClient, ConfirmedOwner { // Last certified state from Invarians string public lastL1Regime; // "S1D1" | "S1D2" | "S2D1" | "S2D2" string public lastBridgeState; // "BS1" | "BS2" uint256 public lastUpdated; // block.timestamp of last fulfilled request bytes32 public lastRequestId; event StateUpdated(string l1Regime, string bridgeState, uint256 timestamp); constructor(address router) FunctionsClient(router) ConfirmedOwner(msg.sender) {} // Modifier: gate execution on nominal L1 state modifier whenExecutable() { bytes32 s = keccak256(bytes(lastL1Regime)); require( s == keccak256(bytes("S1D1")) || s == keccak256(bytes("S1D2")), "Invarians: l1_regime not nominal" ); require(block.timestamp - lastUpdated < 7200, "Invarians: state too old"); _; } // Request a fresh state update from Invarians via Functions function requestStateUpdate( bytes32 donId, string memory source, // source.js above, stored off-chain bytes memory encryptedSecrets, string[] memory args, // args[0] = chain name uint64 subscriptionId, uint32 gasLimit ) external onlyOwner returns (bytes32 requestId) { FunctionsRequest.Request memory req; req.initializeRequestForInlineJavaScript(source); req.addSecretsReference(encryptedSecrets); req.setArgs(args); lastRequestId = _sendRequest(req.encodeCBOR(), subscriptionId, gasLimit, donId); return lastRequestId; } // Callback from Chainlink Functions DON function fulfillRequest(bytes32 requestId, bytes memory response, bytes memory) internal override { if (requestId != lastRequestId) return; // Parse JSON response — use a JSON utility or decode off-chain then re-encode as ABI // Minimal pattern: store raw string, decode in UI layer string memory decoded = string(response); lastUpdated = block.timestamp; emit StateUpdated(lastL1Regime, lastBridgeState, lastUpdated); } // Example: gated execution function function executeWhenSafe() external whenExecutable { // Your execution logic here — only runs when Invarians l1_regime is S1D1 or S1D2 } }
require(block.timestamp - lastUpdated < 7200) guard ensures the contract rejects execution if the last Invarians update is more than 2 hours old — independent of the on-chain data.
Tune this value to your execution latency requirements. The structural regime of L1 chains changes on ~3h timescales by design.
CRE is Chainlink's orchestration layer for autonomous agents — agents that monitor conditions, make decisions, and execute on-chain actions without human intervention. Invarians provides the infrastructure sensing layer these agents are missing: what is the execution substrate doing right now?
None of these detect a sequencer degradation with no L1 fee signature (S2D1 condition). None detect a bridge posting gap invisible to fee markets (BS2 condition). An agent executing during these events is operating blind — not because it lacks data, but because it is looking at the wrong layer.
# Invarians × CRE — agent sensing pattern (Python pseudocode) # The agent queries Invarians before committing to any execution decision import requests INVARIANS_URL = "https://sdpilypwumxsyyipceew.supabase.co/functions/v1/attestation" def get_execution_context(api_key: str, l1_chain: str = "ethereum", l2_chain: str = "arbitrum"): headers = {"Authorization": f"Bearer {api_key}"} # Query composite execution context (L1 × L2 × Bridge) ctx = requests.get( f"{INVARIANS_URL}/execution-context", params={"from": l1_chain, "to": l2_chain}, headers=headers ).json() if ctx.get("oracle_status") != "OK": return {"action": "defer", "reason": "signal_stale"} proof = ctx["proof_of_execution_context"] return { "l1_regime": proof["l1_regime"], "l2_regime": proof["l2_regime"], "bridge_state": proof["bridge_state"], "signature": ctx["signature"], # HMAC-SHA256 — verifiable via /verify "audit_context": proof # Non-falsifiable record of conditions at decision time } # Agent decision loop — agent applies its own policy on raw states def agent_execution_loop(): ctx = get_execution_context(api_key="inv_...") if ctx["l1_regime"].startswith("S1") and ctx["bridge_state"] == "BS1": execute_transaction() log_audit(ctx) # Certified context stored with each decision else: defer_execution(ctx) # Structural stress or bridge degraded — do not execute log_audit(ctx)
| Capability | Without Invarians | With Invarians |
|---|---|---|
| L2 sequencer health | Invisible post-EIP-4844 — no L1 fee signature | S2D1 detected up to +6h before market impact |
| Bridge liveness | Not measured — assumed operational | BS1/BS2 state · batch posting gap detection |
| Execution context | Price + gas only | l1_regime: S1D1 · S1D2 · S2D1 · S2D2 · bridge_state: BS1 · BS2 |
| Audit trail | Transaction hash only | Certified proof_of_execution_context at each decision point |
last_batch_age_seconds — time since the last L2 state batch was posted to L1 Ethereum.
This is the primary signal for sequencer liveness, invisible to all fee monitors.Target integration (Q3 2026): Before initiating a CCIP cross-chain message, a CRE agent queries the Invarians bridge state for the destination chain. If
bridge_state = "BS2" (posting gap above P90 threshold), the agent defers the CCIP send — the receiving chain may not finalize messages reliably during the degradation window.
Interested in integrating Invarians into your Chainlink Functions consumer,
CRE agent pipeline, or CCIP execution logic?