'; } // ---------------------------------------------------------------------------- // WALLET LANDING // ---------------------------------------------------------------------------- function g1wallet_render_landing($access) { // Wallet landing: shows unlock form or unlocked interface depending on JS session state. // At skeleton stage, always shows the unlock form. // Once g1wallet.js is wired, the JS will swap to the unlocked view on successful derivation. $out = '
'; $out .= '
'; $out .= '

Ğ1 Wallet

'; $out .= '

Your self-sovereign Ğ1 identity. Keys are derived in your browser and never leave your device.

'; $out .= '
'; // Optional participation notice. $out .= '

'; $out .= 'The Ğ1 Wallet is optional. '; $out .= 'Ğ1 is a libre currency independent of fiat, used for valuing and bartering surplus capacity among private individuals. '; $out .= 'The Civic Infrastructure implements it for participants who choose to engage in that economy. '; $out .= 'It is not required for participation in the diagnostic record system. '; $out .= 'Future addons such as Barter will require an active wallet — this page is where you manage it.'; $out .= '

'; // Locked view — shown by default. JS hides this and shows unlocked-view on successful derivation. $out .= '
'; $out .= g1wallet_render_unlock_form(); $out .= '
'; // Unlocked view — hidden by default. JS populates and shows this after derivation. $out .= ''; $out .= '
'; return $out; } // ---------------------------------------------------------------------------- // UNLOCK FORM // ---------------------------------------------------------------------------- function g1wallet_render_unlock_form() { // Renders the wallet unlock form. // The form is handled entirely by g1wallet.js — it does NOT POST to the server. // The mnemonic never leaves the browser. // // Per Duniter HD Wallet RFC 0015 (Dubp_HD_Wallet), the wallet's keypair is // derived from a 12-word BIP39 mnemonic (English wordlist), using its // entropy as input to a BIP32-Ed25519 derivation — not a raw PBKDF2 seed. $out = '
'; $out .= '

Unlock Your Wallet

'; $out .= '

Enter your 12-word Ğ1 mnemonic phrase. It is used only in your browser to derive your keypair. It is never sent to the server.

'; $out .= '
'; $out .= ''; $out .= ''; $out .= '
Your 12-word Ğ1 mnemonic — the recovery phrase generated when your Ğ1 account was created. Words are separated by single spaces, lowercase, English wordlist.
'; $out .= '
'; $out .= ''; $out .= '
'; $out .= ''; $out .= ''; $out .= '
'; $out .= '
'; return $out; } // ---------------------------------------------------------------------------- // UNLOCKED INTERFACE (PLACEHOLDER) // ---------------------------------------------------------------------------- function g1wallet_render_unlocked_placeholder($access) { // Placeholder for the unlocked wallet interface. // Populated by g1wallet.js once key derivation is implemented. $out = '
'; $out .= '
'; $out .= 'Wallet unlocked.'; $out .= ''; $out .= '
'; $out .= '
'; $out .= ''; $out .= '

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

Not yet loaded.

'; $out .= ''; $out .= '
'; // Hidden form to store pubkey in channel settings — posted once after first unlock. // g1wallet.js posts to this via fetch() after derivation, not via form submit. $out .= ''; if ($access === 'operator') { $out .= '
'; $out .= '

You are the operator. Your Ğ1 public key is stored in your channel settings, not in config.

'; $out .= '
'; } $out .= '
'; return $out; } // ---------------------------------------------------------------------------- // ERROR // ---------------------------------------------------------------------------- function g1wallet_render_error($message) { // Shows a plain-language error. Never shows a blank page or stack trace. return '
' . g1wallet_h($message) . '
'; }