{
  "schema_version": 9,
  "status": "WARNING_DELTA",
  "aggregate_solvency_ratio": 1.001064,
  "aggregate_solvency_ratio_basis": "psm_usdc_reserve / outstanding_kusd (kUSD stablecoin backing). The pre-v4 vault-share basis is published unchanged in legacy_vault_share_solvency_ratio; see known_issue_vault_v1.",
  "aggregate_solvency_usd_ratio": 1.025195,
  "aggregate_collateral_usd": 1137.67,
  "aggregate_liabilities_usd": 1109.71,
  "psm_solvent": true,
  "psm_solvency_ratio": 1.001064,
  "is_solvent": true,
  "delta_neutral": false,
  "delta_neutral_state": "measured",
  "hedge_base_eth": 0,
  "hedge_base_basis": "net_delta = abs(1 - offchain.short_position_eth / hedge_base_eth), where hedge_base_eth is hedge_base_vault_exposed_eth ALONE: the ETH-price-exposed leg of the attested vault, which is protocol collateral backing kUSD. Nothing else is in this denominator. The disclosed founder-custodied float is NOT, and the signed field hedge_base_watch_only_in_canonical_base states so on every cycle. It is 0.0 today, because the attested vault v2 holds no user deposits, so an open short over it is scored as fully directional and this attestation publishes WARNING_DELTA. That is deliberate. The warning stays until the hedge runs against collateral that actually backs kUSD. SCHEMA 6 DID THE OPPOSITE AND IT WAS A MISTAKE: from 2026-07-24 00:16:36 UTC until schema 8, this denominator also included the founder float, which backs no kUSD, and it was added 57 minutes after Kerne publicly wrote that it would not be. It also made the measurement flap, because most of that float is a spendable gas balance: it fell 0.00792155 to 0.00562139 ETH against an unchanged 0.0079 short, and the signed status moved on that alone. The float is still read and still published, as disclosed_float_eth with its own delta, its own state, and a native/WETH split so a reader can tell a gas payment from a hedge change. It drives no status. See por_schema_changelog.py schema 6 and 8, and https://kerne.fi/api/por/schema-changelog. LEGACY FIELD NOTE: the vault leg is the ETH-price-exposed slice of the attested vault (totalAssets minus offChainAssets, l1Assets and hedgingReserve); it is 0.0 while the attested vault holds no user deposits. The watch-only leg is the disclosed, founder-custodied float the hedge engine sizes its Hyperliquid short against (bot WATCH_ONLY_ADDRESSES with HEDGE_INCLUDE_WATCH_ONLY, a read-only balance feed of native ETH plus WETH on Base). That float is NOT protocol collateral: it backs no kUSD, is excluded from every solvency ratio in this payload, and is published in advance under the Seed TVL policy at kerne.fi/api/por under reserves.protocolOwnedReserves.components.founderWatchOnlyFloat. It enters this attestation as disclosed_float_eth and its own delta ONLY, and is not part of hedge_base_eth. KNOWN AND ACCEPTED CONSEQUENCE: the engine sizes against the float while this attestation measures against protocol collateral, so disclosed_float_delta and offchain_net_delta legitimately differ and both are published. They are two different books and they are now named as two different books, which is the part schema 6 got wrong by summing them into one number. Anyone can reproduce either denominator: the float addresses are listed in hedge_base_watch_only_addresses and the balances are public reads, and the vault leg is chains[].eth_exposed_eth.",
  "status_explanation": "This is a hedge-tracking flag, NOT a solvency failure and NOT a backing shortfall. It fires when the measured hedge book deviates from its declared base by more than the published tolerance of 5 percent. Backing is reported independently in the same payload: read psm_solvent, psm_solvency_ratio and aggregate_solvency_usd_ratio, and note that aggregate collateral can exceed liabilities while this flag is set. SINCE SCHEMA 8 THIS IS THE EXPECTED STEADY STATE, not an incident: the delta denominator is protocol collateral that backs kUSD, the attested vault holds none of it yet, and an open short over an empty protocol base is scored as fully directional by design. It clears when the hedge runs against collateral that actually backs kUSD, and not before. Kerne did once clear this flag the other way, by widening the denominator to include a founder wallet 57 minutes after publicly committing not to. That was schema 6, it stood from 2026-07-24 to 2026-07-28, and it is recorded at kerne.fi/api/por/schema-changelog rather than quietly reverted. Read that entry before trusting this one.",
  "kusd_total_supply": 1144.707154,
  "outstanding_kusd": 1109.707154,
  "psm_usdc_reserve": 1110.888006,
  "psm_kusd_held": 35,
  "generated_at": "2026-08-16T17:49:29.000Z",
  "unix_timestamp": 1786902569,
  "block_heights": {
    "base": 50056611
  },
  "offchain_venue": "Hyperliquid",
  "offchain_equity_usd": 26.667966,
  "offchain_equity_eth_equiv": 0.014155347010270972,
  "offchain_net_delta": 1,
  "offchain_short_position_eth": 0.0079,
  "attestation_hash": "0x0c3384bf0255a183594d1c6e8ab3e51e549546bddd4deefa3e8d7d279996f904",
  "signature": "0x1ce220380fa33fdf1dba6f54de552672e4a2d03f6f2bc3414515a2ec354a152935aa74cd58df3dffb7a0453e0cda12b25de50f977e30bd49f930c36c505f2f6e1b",
  "signer": "0x09a2780ac8Be6D5d2d1F85A8D92b09D40C9CA37e",
  "signed_payload_canonical": "{\"account_registry_digest\":\"0x489712f75a593c2b36b56f1771b2e1b8dda5766fd4afd7cd45784fd4089f720a\",\"account_registry_state\":\"bound\",\"account_registry_url\":\"https://kerne.fi/api/por/accounts\",\"account_registry_version\":5,\"account_set_digest\":\"0x7cab3570d7a8d142e44560a350765bf29e86a0b1ce6eb4c2747c8ec8975592e7\",\"aggregate_collateral_usd\":1137.67,\"aggregate_liabilities_usd\":1109.71,\"aggregate_solvency_ratio\":1.001064,\"aggregate_solvency_ratio_basis\":\"psm_usdc_reserve / outstanding_kusd (kUSD stablecoin backing). The pre-v4 vault-share basis is published unchanged in legacy_vault_share_solvency_ratio; see known_issue_vault_v1.\",\"aggregate_solvency_usd_ratio\":1.025195,\"attestation_signer\":\"0x09a2780ac8Be6D5d2d1F85A8D92b09D40C9CA37e\",\"chains\":[{\"chain_id\":8453,\"chain_name\":\"Base Mainnet\",\"eth_exposed_complete\":true,\"eth_exposed_eth\":0.0,\"rpc_healthy\":true,\"solvency_ratio\":1.0,\"timestamp\":1786902569,\"total_assets_eth\":0.01421401920876899,\"total_assets_wei\":14214019208768990,\"total_supply_eth\":0.0,\"total_supply_wei\":0,\"vault_address\":\"0x8ccc56B5624e2FDB592F6609d81F4c3798e3292B\"}],\"delta_neutral\":false,\"delta_neutral_state\":\"measured\",\"disclosed_float_delta\":0.53394,\"disclosed_float_delta_state\":\"measured\",\"disclosed_float_eth\":0.00515014,\"disclosed_float_native_eth\":0.00437723,\"disclosed_float_weth_eth\":0.00077291,\"eth_price_usd\":1883.95,\"hedge_base_basis\":\"net_delta = abs(1 - offchain.short_position_eth / hedge_base_eth), where hedge_base_eth is hedge_base_vault_exposed_eth ALONE: the ETH-price-exposed leg of the attested vault, which is protocol collateral backing kUSD. Nothing else is in this denominator. The disclosed founder-custodied float is NOT, and the signed field hedge_base_watch_only_in_canonical_base states so on every cycle. It is 0.0 today, because the attested vault v2 holds no user deposits, so an open short over it is scored as fully directional and this attestation publishes WARNING_DELTA. That is deliberate. The warning stays until the hedge runs against collateral that actually backs kUSD. SCHEMA 6 DID THE OPPOSITE AND IT WAS A MISTAKE: from 2026-07-24 00:16:36 UTC until schema 8, this denominator also included the founder float, which backs no kUSD, and it was added 57 minutes after Kerne publicly wrote that it would not be. It also made the measurement flap, because most of that float is a spendable gas balance: it fell 0.00792155 to 0.00562139 ETH against an unchanged 0.0079 short, and the signed status moved on that alone. The float is still read and still published, as disclosed_float_eth with its own delta, its own state, and a native/WETH split so a reader can tell a gas payment from a hedge change. It drives no status. See por_schema_changelog.py schema 6 and 8, and https://kerne.fi/api/por/schema-changelog. LEGACY FIELD NOTE: the vault leg is the ETH-price-exposed slice of the attested vault (totalAssets minus offChainAssets, l1Assets and hedgingReserve); it is 0.0 while the attested vault holds no user deposits. The watch-only leg is the disclosed, founder-custodied float the hedge engine sizes its Hyperliquid short against (bot WATCH_ONLY_ADDRESSES with HEDGE_INCLUDE_WATCH_ONLY, a read-only balance feed of native ETH plus WETH on Base). That float is NOT protocol collateral: it backs no kUSD, is excluded from every solvency ratio in this payload, and is published in advance under the Seed TVL policy at kerne.fi/api/por under reserves.protocolOwnedReserves.components.founderWatchOnlyFloat. It enters this attestation as disclosed_float_eth and its own delta ONLY, and is not part of hedge_base_eth. KNOWN AND ACCEPTED CONSEQUENCE: the engine sizes against the float while this attestation measures against protocol collateral, so disclosed_float_delta and offchain_net_delta legitimately differ and both are published. They are two different books and they are now named as two different books, which is the part schema 6 got wrong by summing them into one number. Anyone can reproduce either denominator: the float addresses are listed in hedge_base_watch_only_addresses and the balances are public reads, and the vault leg is chains[].eth_exposed_eth.\",\"hedge_base_eth\":0.0,\"hedge_base_vault_exposed_eth\":0.0,\"hedge_base_verified\":true,\"hedge_base_watch_only_addresses\":[\"0x14f04cE02f35B29Af564A98544dD7e2393993946\"],\"hedge_base_watch_only_eth\":0.00515014,\"hedge_base_watch_only_in_canonical_base\":false,\"hedge_base_watch_only_included\":true,\"insurance_fund_usd\":0.0,\"insurance_fund_usdc\":0.0,\"insurance_fund_weth\":0.0,\"is_solvent_resolved\":true,\"kusd_total_supply\":1144.707154,\"legacy_vault_share_solvency_ratio\":999999.0,\"offchain\":{\"available\":true,\"equity_eth_equiv\":0.014155347010270972,\"equity_usd\":26.667966,\"net_delta\":1.0,\"position_stale\":false,\"short_position_eth\":0.0079,\"venue\":\"Hyperliquid\"},\"outstanding_kusd\":1109.707154,\"psm_kusd_held\":35.0,\"psm_reads_available\":true,\"psm_solvency_ratio\":1.001064,\"psm_solvent\":true,\"psm_usdc_reserve\":1110.888006,\"retired_vault_v1\":{\"address\":\"0x8005bc7A86AD904C20fd62788ABED7546c1cF2AC\",\"attested_in_this_payload\":false,\"explanation\":\"KerneVault v1 is retired and carries a phantom totalSupply on the order of 4.87e36 kLP from the bucket-transition asymmetry documented in ADVERSARIAL_AUDIT_2026-05-08 section 1.3. It holds no user deposits and backs no kUSD. It is NOT the vault attested above: this attestation reads the live KerneVault v2 at the address in chains[].vault_address. v1 is named here because kerne.fi/api/stats still publishes it as vaultAddress with state 'live-vault-degraded' and vaultDegraded true. That endpoint and this one are consistent and describe different vaults: the app deliberately still points at v1 with deposits hard-closed until the final audit report publishes, while this attestation covers v2. Neither field is a backing signal. kUSD backing is the PSM ratio published above as psm_solvency_ratio.\",\"public_deposits\":\"closed\",\"reconciles_with\":\"https://kerne.fi/api/stats\",\"state\":\"degraded_phantom_total_supply\"},\"safe_usd\":333.43,\"safe_usdc\":333.43,\"safe_weth\":0.0,\"schema_changelog_digest\":\"0x0fc2f7a6752f085436d84f7bb1e9611d98ce31fcd79e3f2c24c3bbc223342412\",\"schema_changelog_url\":\"https://kerne.fi/api/por/schema-changelog\",\"schema_version\":9,\"signer_binding\":null,\"signer_binding_state\":\"mismatch\",\"signer_registry_digest\":\"0x12f1ba6dea8f4c255f37c303be374a36a03849310b8b8fca288d56c5cc92be82\",\"signer_registry_url\":\"https://kerne.fi/api/por/signer-registry\",\"signer_registry_version\":2,\"solvency_ratio\":999999.0,\"status\":\"WARNING_DELTA\",\"status_explanation\":\"This is a hedge-tracking flag, NOT a solvency failure and NOT a backing shortfall. It fires when the measured hedge book deviates from its declared base by more than the published tolerance of 5 percent. Backing is reported independently in the same payload: read psm_solvent, psm_solvency_ratio and aggregate_solvency_usd_ratio, and note that aggregate collateral can exceed liabilities while this flag is set. SINCE SCHEMA 8 THIS IS THE EXPECTED STEADY STATE, not an incident: the delta denominator is protocol collateral that backs kUSD, the attested vault holds none of it yet, and an open short over an empty protocol base is scored as fully directional by design. It clears when the hedge runs against collateral that actually backs kUSD, and not before. Kerne did once clear this flag the other way, by widening the denominator to include a founder wallet 57 minutes after publicly committing not to. That was schema 6, it stood from 2026-07-24 to 2026-07-28, and it is recorded at kerne.fi/api/por/schema-changelog rather than quietly reverted. Read that entry before trusting this one.\",\"timestamp\":1786902569,\"total_assets_eth\":0.01421402,\"total_liabilities_eth\":0.0,\"treasury_usd\":0.0,\"treasury_usdc\":0.0,\"treasury_weth\":0.0,\"vault_v1_degraded_known\":false,\"vault_v1_degraded_known_basis\":\"Computed ONLY over the vault or vaults attested in chains[] above, by testing their combined share totalSupply against a phantom-supply threshold. It reads false here because the attested vault is KerneVault v2, which has a clean zero share supply. It is NOT a claim that the retired v1 vault is healthy. v1 IS degraded, is not attested in this payload, and is disclosed under retired_vault_v1.\",\"venue_account\":\"0x09a2780ac8Be6D5d2d1F85A8D92b09D40C9CA37e\"}",
  "vault_v1_degraded_known": false,
  "psm_reads_available": true,
  "insurance_fund_usdc": 0,
  "insurance_fund_weth": 0,
  "insurance_fund_usd": 0,
  "treasury_usdc": 0,
  "treasury_weth": 0,
  "treasury_usd": 0,
  "safe_usdc": 333.43,
  "safe_weth": 0,
  "safe_usd": 333.43,
  "eth_price_usd": 1883.95,
  "hedge_base_vault_exposed_eth": 0,
  "hedge_base_watch_only_eth": 0.00515014,
  "hedge_base_watch_only_addresses": [
    "0x14f04cE02f35B29Af564A98544dD7e2393993946"
  ],
  "hedge_base_watch_only_included": true,
  "hedge_base_verified": true,
  "hedge_base_watch_only_in_canonical_base": false,
  "disclosed_float_eth": 0.00515014,
  "disclosed_float_native_eth": 0.00437723,
  "disclosed_float_weth_eth": 0.00077291,
  "disclosed_float_delta": 0.53394,
  "disclosed_float_delta_state": "measured",
  "vault_v1_degraded_known_basis": "Computed ONLY over the vault or vaults attested in chains[] above, by testing their combined share totalSupply against a phantom-supply threshold. It reads false here because the attested vault is KerneVault v2, which has a clean zero share supply. It is NOT a claim that the retired v1 vault is healthy. v1 IS degraded, is not attested in this payload, and is disclosed under retired_vault_v1.",
  "retired_vault_v1": {
    "address": "0x8005bc7A86AD904C20fd62788ABED7546c1cF2AC",
    "attested_in_this_payload": false,
    "explanation": "KerneVault v1 is retired and carries a phantom totalSupply on the order of 4.87e36 kLP from the bucket-transition asymmetry documented in ADVERSARIAL_AUDIT_2026-05-08 section 1.3. It holds no user deposits and backs no kUSD. It is NOT the vault attested above: this attestation reads the live KerneVault v2 at the address in chains[].vault_address. v1 is named here because kerne.fi/api/stats still publishes it as vaultAddress with state 'live-vault-degraded' and vaultDegraded true. That endpoint and this one are consistent and describe different vaults: the app deliberately still points at v1 with deposits hard-closed until the final audit report publishes, while this attestation covers v2. Neither field is a backing signal. kUSD backing is the PSM ratio published above as psm_solvency_ratio.",
    "public_deposits": "closed",
    "reconciles_with": "https://kerne.fi/api/stats",
    "state": "degraded_phantom_total_supply"
  },
  "attestation_signer": "0x09a2780ac8Be6D5d2d1F85A8D92b09D40C9CA37e",
  "venue_account": "0x09a2780ac8Be6D5d2d1F85A8D92b09D40C9CA37e",
  "signer_binding_state": "mismatch",
  "signer_binding": null,
  "signer_registry_version": 2,
  "signer_registry_digest": "0x12f1ba6dea8f4c255f37c303be374a36a03849310b8b8fca288d56c5cc92be82",
  "signer_registry_url": "https://kerne.fi/api/por/signer-registry",
  "notes": [],
  "account_registry_state": "bound",
  "account_registry_version": 5,
  "account_registry_digest": "0x489712f75a593c2b36b56f1771b2e1b8dda5766fd4afd7cd45784fd4089f720a",
  "account_set_digest": "0x7cab3570d7a8d142e44560a350765bf29e86a0b1ce6eb4c2747c8ec8975592e7",
  "account_registry_url": "https://kerne.fi/api/por/accounts",
  "schema_changelog_digest": "0x0fc2f7a6752f085436d84f7bb1e9611d98ce31fcd79e3f2c24c3bbc223342412",
  "schema_changelog_url": "https://kerne.fi/api/por/schema-changelog",
  "known_issue_vault_v1": {},
  "chains": [
    {
      "chain_id": 8453,
      "chain_name": "Base Mainnet",
      "vault_address": "0x8ccc56B5624e2FDB592F6609d81F4c3798e3292B",
      "total_assets_wei": 14214019208768990,
      "total_assets_eth": 0.01421401920876899,
      "total_supply_wei": 0,
      "total_supply_eth": 0,
      "solvency_ratio": 1,
      "rpc_healthy": true,
      "timestamp": 1786902569,
      "eth_exposed_eth": 0,
      "eth_exposed_complete": true
    }
  ],
  "total_onchain_assets_eth": 0.01421402,
  "total_onchain_liabilities_eth": 0,
  "total_assets_eth": 0.01421402,
  "total_liabilities_eth": 0,
  "legacy_vault_share_solvency_ratio": 999999,
  "_meta": {
    "served_by": "kerne.fi /api/por/signed",
    "source": {
      "path": "/opt/kerne/bot/docs/reports/por/latest.json",
      "producer": "bot/por_automated.py (AutomatedPoRBot.run)",
      "cadence_seconds": 3600,
      "publisher": "kerne-por-public.service (systemd, port 8788)"
    },
    "staleness_seconds": 949,
    "is_fresh": true,
    "stale_threshold_seconds": 7800,
    "freshness": {
      "signed_timestamp": 1786902569,
      "signed_at": "2026-08-16T17:49:29.000Z",
      "expires_at": "2026-08-16T19:59:29.000Z",
      "computed_at": "2026-08-16T18:05:18.864Z",
      "remaining_seconds_at_render": 6851,
      "stale_threshold_seconds": 7800,
      "how_to_check": "Do not trust is_fresh from a cached response. Compare _meta.freshness.expires_at to your own clock: if it is in the past, this attestation is stale regardless of what is_fresh says. The signed timestamp is also inside signed_payload_canonical, so you can rebuild this check from the cryptographically bound bytes alone: JSON.parse(signed_payload_canonical).timestamp + _meta.freshness.stale_threshold_seconds."
    },
    "verified": true,
    "signature_valid": true,
    "recovered_signer": "0x09a2780ac8be6d5d2d1f85a8d92b09d40c9ca37e",
    "signer_matches_expected": true,
    "hash_matches": true,
    "expected_signer": "0x09a2780ac8Be6D5d2d1F85A8D92b09D40C9CA37e",
    "signer_chain": {
      "mode": "direct",
      "chain_ok": true,
      "recovered_signer": "0x09a2780ac8be6d5d2d1f85a8d92b09d40c9ca37e",
      "authorized_signer": null,
      "venue_account": "0x09a2780ac8Be6D5d2d1F85A8D92b09D40C9CA37e",
      "binding_authority": null,
      "binding_digest_matches": false,
      "binding_authority_is_trust_root": false,
      "signer_proof_ok": false,
      "crypto_ok": false,
      "started": false,
      "in_window": false,
      "role_matches": false,
      "custody_present": false,
      "custody_signature_valid": null,
      "registry_version": null,
      "venue_account_read": null,
      "warning": null
    },
    "integrity_warning": null,
    "v2_summary": {
      "schema_version": 9,
      "headline": "PSM is 1:1 USDC-backed. Aggregate collateral exceeds liabilities in USD.",
      "vault_v1_degraded_known": false,
      "psm_solvent": true,
      "aggregate_solvency_ratio": 1.001064,
      "legacy_vault_share_solvency_ratio": 999999,
      "psm_usdc_reserve": 1110.888006,
      "psm_kusd_held": 35,
      "outstanding_kusd": 1109.707154,
      "kusd_total_supply": 1144.707154,
      "psm_solvency_ratio": 1.001064,
      "aggregate_collateral_usd": 1137.67,
      "aggregate_liabilities_usd": 1109.71,
      "aggregate_solvency_usd_ratio": 1.025195,
      "eth_price_usd": 1883.95,
      "psm_reads_available": true
    },
    "degraded_state_explanation": null,
    "cross_links": {
      "live_risk_status": "https://kerne.fi/api/risk-status",
      "unsigned_live_por": "https://kerne.fi/api/por",
      "funnel_stats": "https://kerne.fi/api/stats",
      "signer_registry": "https://kerne.fi/api/por/signer-registry",
      "docs": "https://kerne.fi/transparency"
    },
    "verify": {
      "algorithm": "EIP-191 personal_sign (eth_account.messages.encode_defunct)",
      "message_hash_field": "attestation_hash",
      "signature_field": "signature",
      "signer_field": "signer",
      "canonical_field": "signed_payload_canonical",
      "js_bind_signer": "const json = await (await fetch(\"https://kerne.fi/api/por/signed\")).json();\nimport { sha256 } from \"@noble/hashes/sha2\";\nimport { bytesToHex } from \"@noble/hashes/utils\";\nimport { verifyMessage, getBytes } from \"ethers\";\nconst signed = JSON.parse(json.signed_payload_canonical);\nconst b = signed.signer_binding;\nif (b === null) { /* pre-v9: the signer must BE the venue account */ }\nelse {\n  const d = \"0x\" + bytesToHex(sha256(new TextEncoder().encode(b.statement_canonical)));\n  console.assert(d === b.statement_digest, \"binding bytes do not match its digest\");\n  const st = JSON.parse(b.statement_canonical);\n  const authority = verifyMessage(getBytes(d), b.venue_signature);\n  console.assert(authority.toLowerCase() === st.venue_account.toLowerCase(), \"not authorized by the venue account\");\n  const holder = verifyMessage(getBytes(d), b.signer_signature);\n  console.assert(holder.toLowerCase() === st.attestation_signer.toLowerCase(), \"named signer did not countersign\");\n  const actual = verifyMessage(getBytes(json.attestation_hash), json.signature);\n  console.assert(actual.toLowerCase() === st.attestation_signer.toLowerCase(), \"signed by an unauthorized key\");\n  // then confirm st.venue_account is the account you were shown:\n  // curl -s -X POST https://api.hyperliquid.xyz/info -H \"Content-Type: application/json\" \\\n  //   -d \"{\\\"type\\\":\\\"clearinghouseState\\\",\\\"user\\\":\\\"\" + st.venue_account + \"\\\"}\"\n}",
      "note": "Gate on _meta.verified. It is true only when the signature recovers to the expected signer (signer_matches_expected), the numbers+timestamp rehash to attestation_hash (hash_matches), and the bound attestation is fresh (is_fresh). To reproduce the number-binding yourself: assert \"0x\"+sha256(signed_payload_canonical) === attestation_hash, then read figures from JSON.parse(signed_payload_canonical).",
      "js_bind_numbers": "const json = await (await fetch(\"https://kerne.fi/api/por/signed\")).json();\nimport { sha256 } from \"@noble/hashes/sha2\";\nimport { bytesToHex } from \"@noble/hashes/utils\";\nconst recomputed = \"0x\" + bytesToHex(sha256(new TextEncoder().encode(json.signed_payload_canonical)));\nconsole.assert(recomputed === json.attestation_hash, \"numbers do not match the signed hash\");\nconst signed = JSON.parse(json.signed_payload_canonical); // bound figures + signed timestamp",
      "js_ethers": "const json = await (await fetch(\"https://kerne.fi/api/por/signed\")).json();\nimport { verifyMessage, getBytes } from \"ethers\";\nconst recovered = verifyMessage(getBytes(json.attestation_hash), json.signature);\nconsole.assert(recovered.toLowerCase() === json.signer.toLowerCase(), \"signature mismatch\");",
      "python_eth_account": "import requests\nfrom eth_account import Account\nfrom eth_account.messages import encode_defunct\nj = requests.get(\"https://kerne.fi/api/por/signed\").json()\nmsg = encode_defunct(hexstr=j[\"attestation_hash\"])\nrecovered = Account.recover_message(msg, signature=j[\"signature\"])\nassert recovered.lower() == j[\"signer\"].lower(), \"signature mismatch\"",
      "cli_cast": "curl -s https://kerne.fi/api/por/signed > por.json\nHASH=$(jq -r .attestation_hash por.json)\nSIG=$(jq -r .signature por.json)\nSIGNER=$(jq -r .signer por.json)\ncast wallet verify --address $SIGNER $HASH $SIG"
    }
  }
}