'; } // ---------------------------------------------------------------------------- // CONTENT ROUTER // ---------------------------------------------------------------------------- function cry01_content() { if (function_exists('head_add_css')) { head_add_css('/addon/cry01/view/css/cry01.css'); } if (function_exists('head_add_js')) { head_add_js('/addon/cry01/view/js/cry01.js'); } $association_slug = argv(1) ?? ''; $sub_route = strtolower(argv(2) ?? ''); if (!$association_slug) { return cry01_render_index(); } $raw = @file_get_contents('addon/vs01/config.json'); if ($raw === false) return cry01_render_error('Configuration unavailable. Contact the operator.'); $cfg = json_decode($raw, true); if (!isset($cfg['associations'][$association_slug])) { return cry01_render_not_found(); } $access = cry01_access_state($association_slug); switch ($sub_route) { case 'signal': if ($_SERVER['REQUEST_METHOD'] === 'POST') { if ($access === 'public') return cry01_access_wall($association_slug); if (!cry01_verify_csrf()) { return cry01_render_error('Invalid form token. Please reload and try again.'); } return cry01_handle_signal_post($association_slug, $access); } if ($access === 'public') return cry01_access_wall($association_slug); return cry01_render_signal_form($association_slug, $access); case 'g1': if ($access !== 'operator') return cry01_access_wall($association_slug); return cry01_render_g1_candidates($association_slug); case 'manage': if ($access !== 'operator') return cry01_access_wall($association_slug); if ($_SERVER['REQUEST_METHOD'] === 'POST') { return cry01_handle_manage_post($association_slug); } return cry01_render_manage($association_slug); case 'lookup': // Public Ğ1 account lookup. No SASE gate, no wallet session, no // storage of any kind. Address in, full AccountInfo out. if ($_SERVER['REQUEST_METHOD'] === 'POST') { if (!cry01_verify_csrf()) { return cry01_render_error('Invalid form token. Please reload and try again.'); } return cry01_handle_lookup_post($association_slug, $access); } return cry01_render_landing($association_slug, $access); default: return cry01_render_landing($association_slug, $access); } } // ---------------------------------------------------------------------------- // LOOKUP HANDLER // ---------------------------------------------------------------------------- function cry01_handle_lookup_post($association_slug, $access) { // Public account lookup: decode the pasted Ğ1 address, query the chain // for the full AccountInfo struct, re-render the landing page with the // result (or an error) inline. No data is stored anywhere — this is a // pure read. $address = trim($_POST['g1_lookup_address'] ?? ''); if (!$address) { return cry01_render_landing($association_slug, $access, [ 'lookup_error' => 'Please enter a Ğ1 address.', ]); } $account_id = cry01_ss58_decode($address); if ($account_id === null) { return cry01_render_landing($association_slug, $access, [ 'lookup_error' => 'That doesn\'t look like a valid Ğ1 address. Check for typos and try again.', 'lookup_address' => $address, ]); } $info = cry01_get_account_info($account_id); if ($info === null) { return cry01_render_landing($association_slug, $access, [ 'lookup_error' => 'Could not reach the Ğ1 network right now. Please try again shortly.', 'lookup_address' => $address, ]); } return cry01_render_landing($association_slug, $access, [ 'lookup_address' => $address, 'lookup_balance' => cry01_format_g1_amount($info['free']), 'lookup_account_info' => $info, ]); } // ---------------------------------------------------------------------------- // RENDER — INDEX // ---------------------------------------------------------------------------- function cry01_render_index() { // Lists all registered associations with links to their value layer pages. $raw = @file_get_contents('addon/vs01/config.json'); $cfg = $raw ? json_decode($raw, true) : []; $list = $cfg['associations'] ?? []; if (empty($list)) { return '

No associations registered.

'; } $out = '
'; $out .= '

Value Layer

'; $out .= '
'; return $out; } // ---------------------------------------------------------------------------- // RENDER — NOT FOUND / ERROR // ---------------------------------------------------------------------------- function cry01_render_not_found() { return '
Association not found.
'; } function cry01_render_error($message) { // Shows a plain-language error message. Never shows a blank page or stack trace. return '
' . cry01_h($message) . '
'; } // ---------------------------------------------------------------------------- // CSRF // ---------------------------------------------------------------------------- function cry01_csrf_token() { // Generates and stores a CSRF token for the current session. if (empty($_SESSION['cry01_csrf'])) { $_SESSION['cry01_csrf'] = bin2hex(random_bytes(16)); } return ''; } function cry01_verify_csrf() { // Returns true if the CSRF token in POST matches the session token. return isset($_POST['cry01_csrf'], $_SESSION['cry01_csrf']) && hash_equals($_SESSION['cry01_csrf'], $_POST['cry01_csrf']); }