{
  "schema_version": 9,
  "status": "SOLVENT_DELTA_NOT_ASSERTED",
  "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.017596,
  "aggregate_collateral_usd": 1129.78,
  "aggregate_liabilities_usd": 1110.24,
  "psm_solvent": true,
  "psm_solvency_ratio": 1.001064,
  "is_solvent": true,
  "delta_neutral": null,
  "delta_neutral_state": "no_hedge_book",
  "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 reads 0.0 while the attested vault holds no user deposits. Since 2026-10-05 the hedge engine sizes its short against this same base and nothing else (KRN-26-HEDGE-BASE-PARITY), so while it is 0.0 the engine's target short is 0.0 too, and any short left open over it is scored as fully directional and publishes WARNING_DELTA as a real deviation. 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 sized its Hyperliquid short against from 2026-07-21 to 2026-10-05 (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 not part of hedge_base_eth. When a deployment declares it, it enters this attestation as disclosed_float_eth and its own delta ONLY; when none is declared, disclosed_float_delta_state reads not_declared. WHY THE ENGINE MOVED: while the engine sized against the float and this attestation measured protocol collateral, the two were different books, and this attestation correctly scored the short as directional every cycle from schema 8 onward. Schema 6 tried to reconcile them by moving this denominator and was wrong to. KRN-26-HEDGE-BASE-PARITY reconciled them by moving the engine onto protocol collateral, so the engine and this attestation now measure one book. Anyone can reproduce the denominator: the vault leg is chains[].eth_exposed_eth, and the short is offchain.short_position_eth, readable at the venue account without our cooperation.",
  "status_explanation": "kUSD is fully backed by the PSM USDC reserves. No delta verdict is asserted this cycle because there was no hedge book to measure, the venue could not be read, or the hedge base itself could not be verified. Read delta_neutral_state for which of those applies. Solvency is unaffected: it is measured separately from the hedge.",
  "kusd_total_supply": 1145.243248,
  "outstanding_kusd": 1110.243248,
  "psm_usdc_reserve": 1111.424636,
  "psm_kusd_held": 35,
  "generated_at": "2026-10-08T19:14:46.000Z",
  "unix_timestamp": 1791486886,
  "block_heights": {
    "base": 52348769
  },
  "offchain_venue": "Hyperliquid",
  "offchain_equity_usd": 0,
  "offchain_equity_eth_equiv": 0,
  "offchain_net_delta": 0,
  "offchain_short_position_eth": 0,
  "attestation_hash": "0x4b7fc83b934f02cf464b78fe0b449df5b181c9645c6a9ca95fc6cb41fb16af0d",
  "signature": "0x313d733267b31f706c57005d69c7e93f1f0fed744bbe5dead46f47cd5105238d673e4ff8ad8b4d4eb8625170c3216e198acf246aa934cf5e8f45bb6258185e351b",
  "signer": "0x09a2780ac8Be6D5d2d1F85A8D92b09D40C9CA37e",
  "signed_payload_canonical": "{\"account_registry_digest\":\"0xc92df514e90bd1135b811fb1e99950f8bc4713edb3d6b9de35ae1a078cd3f663\",\"account_registry_state\":\"bound\",\"account_registry_url\":\"https://kerne.fi/api/por/accounts\",\"account_registry_version\":6,\"account_set_digest\":\"0xa660aa6303ebabaac77ec2c27cb5111e88b9ffcf406299d95f8b53119c0613f7\",\"aggregate_collateral_usd\":1129.78,\"aggregate_liabilities_usd\":1110.24,\"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.017596,\"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\":1791486887,\"total_assets_eth\":0.00751307682389995,\"total_assets_wei\":7513076823899950,\"total_supply_eth\":0.0,\"total_supply_wei\":0,\"vault_address\":\"0x8ccc56B5624e2FDB592F6609d81F4c3798e3292B\"}],\"delta_neutral\":null,\"delta_neutral_state\":\"no_hedge_book\",\"disclosed_float_delta\":0.0,\"disclosed_float_delta_state\":\"not_declared\",\"disclosed_float_eth\":0.0,\"disclosed_float_native_eth\":0.0,\"disclosed_float_weth_eth\":0.0,\"eth_price_usd\":2443.02,\"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 reads 0.0 while the attested vault holds no user deposits. Since 2026-10-05 the hedge engine sizes its short against this same base and nothing else (KRN-26-HEDGE-BASE-PARITY), so while it is 0.0 the engine's target short is 0.0 too, and any short left open over it is scored as fully directional and publishes WARNING_DELTA as a real deviation. 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 sized its Hyperliquid short against from 2026-07-21 to 2026-10-05 (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 not part of hedge_base_eth. When a deployment declares it, it enters this attestation as disclosed_float_eth and its own delta ONLY; when none is declared, disclosed_float_delta_state reads not_declared. WHY THE ENGINE MOVED: while the engine sized against the float and this attestation measured protocol collateral, the two were different books, and this attestation correctly scored the short as directional every cycle from schema 8 onward. Schema 6 tried to reconcile them by moving this denominator and was wrong to. KRN-26-HEDGE-BASE-PARITY reconciled them by moving the engine onto protocol collateral, so the engine and this attestation now measure one book. Anyone can reproduce the denominator: the vault leg is chains[].eth_exposed_eth, and the short is offchain.short_position_eth, readable at the venue account without our cooperation.\",\"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.0,\"hedge_base_watch_only_in_canonical_base\":false,\"hedge_base_watch_only_included\":false,\"insurance_fund_usd\":0.0,\"insurance_fund_usdc\":0.0,\"insurance_fund_weth\":0.0,\"is_solvent_resolved\":true,\"kusd_total_supply\":1145.243248,\"legacy_vault_share_solvency_ratio\":999999.0,\"offchain\":{\"available\":true,\"equity_eth_equiv\":0.0,\"equity_usd\":0.0,\"net_delta\":0.0,\"position_stale\":false,\"short_position_eth\":0.0,\"venue\":\"Hyperliquid\"},\"outstanding_kusd\":1110.243248,\"psm_kusd_held\":35.0,\"psm_reads_available\":true,\"psm_solvency_ratio\":1.001064,\"psm_solvent\":true,\"psm_usdc_reserve\":1111.424636,\"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\":\"SOLVENT_DELTA_NOT_ASSERTED\",\"status_explanation\":\"kUSD is fully backed by the PSM USDC reserves. No delta verdict is asserted this cycle because there was no hedge book to measure, the venue could not be read, or the hedge base itself could not be verified. Read delta_neutral_state for which of those applies. Solvency is unaffected: it is measured separately from the hedge.\",\"timestamp\":1791486886,\"total_assets_eth\":0.00751308,\"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": 2443.02,
  "hedge_base_vault_exposed_eth": 0,
  "hedge_base_watch_only_eth": 0,
  "hedge_base_watch_only_addresses": [
    "0x14f04cE02f35B29Af564A98544dD7e2393993946"
  ],
  "hedge_base_watch_only_included": false,
  "hedge_base_verified": true,
  "hedge_base_watch_only_in_canonical_base": false,
  "disclosed_float_eth": 0,
  "disclosed_float_native_eth": 0,
  "disclosed_float_weth_eth": 0,
  "disclosed_float_delta": 0,
  "disclosed_float_delta_state": "not_declared",
  "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": 6,
  "account_registry_digest": "0xc92df514e90bd1135b811fb1e99950f8bc4713edb3d6b9de35ae1a078cd3f663",
  "account_set_digest": "0xa660aa6303ebabaac77ec2c27cb5111e88b9ffcf406299d95f8b53119c0613f7",
  "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": 7513076823899950,
      "total_assets_eth": 0.00751307682389995,
      "total_supply_wei": 0,
      "total_supply_eth": 0,
      "solvency_ratio": 1,
      "rpc_healthy": true,
      "timestamp": 1791486887,
      "eth_exposed_eth": 0,
      "eth_exposed_complete": true
    }
  ],
  "total_onchain_assets_eth": 0.00751308,
  "total_onchain_liabilities_eth": 0,
  "total_assets_eth": 0.00751308,
  "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": 2719,
    "is_fresh": true,
    "stale_threshold_seconds": 7800,
    "freshness": {
      "signed_timestamp": 1791486886,
      "signed_at": "2026-10-08T19:14:46.000Z",
      "expires_at": "2026-10-08T21:24:46.000Z",
      "computed_at": "2026-10-08T20:00:05.317Z",
      "remaining_seconds_at_render": 5081,
      "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": 1111.424636,
      "psm_kusd_held": 35,
      "outstanding_kusd": 1110.243248,
      "kusd_total_supply": 1145.243248,
      "psm_solvency_ratio": 1.001064,
      "aggregate_collateral_usd": 1129.78,
      "aggregate_liabilities_usd": 1110.24,
      "aggregate_solvency_usd_ratio": 1.017596,
      "eth_price_usd": 2443.02,
      "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"
    }
  }
}