-module(gleeth@commands@wallet). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/gleeth/commands/wallet.gleam"). -export([parse_args/1, run/1, print_usage/0, print_help/0]). -export_type([wallet_operation/0]). -if(?OTP_RELEASE >= 27). -define(MODULEDOC(Str), -moduledoc(Str)). -define(DOC(Str), -doc(Str)). -else. -define(MODULEDOC(Str), -compile([])). -define(DOC(Str), -compile([])). -endif. -type wallet_operation() :: {create_from_key, binary()} | generate_new | {show_info, binary()} | {sign_message, binary(), binary()} | {verify_message, binary(), binary(), binary()}. -file("src/gleeth/commands/wallet.gleam", 29). ?DOC(" Parse wallet command arguments\n"). -spec parse_args(list(binary())) -> {ok, wallet_operation()} | {error, binary()}. parse_args(Args) -> case Args of [<<"create"/utf8>>, <<"--private-key"/utf8>>, Key] -> {ok, {create_from_key, Key}}; [<<"create"/utf8>>, <<"-k"/utf8>>, Key@1] -> {ok, {create_from_key, Key@1}}; [<<"generate"/utf8>>] -> {ok, generate_new}; [<<"info"/utf8>>, <<"--private-key"/utf8>>, Key@2] -> {ok, {show_info, Key@2}}; [<<"info"/utf8>>, <<"-k"/utf8>>, Key@3] -> {ok, {show_info, Key@3}}; [<<"sign"/utf8>>, <<"--private-key"/utf8>>, Key@4, <<"--message"/utf8>>, Message] -> {ok, {sign_message, Key@4, Message}}; [<<"sign"/utf8>>, <<"-k"/utf8>>, Key@5, <<"-m"/utf8>>, Message@1] -> {ok, {sign_message, Key@5, Message@1}}; [<<"verify"/utf8>>, <<"--public-key"/utf8>>, Pubkey, <<"--message"/utf8>>, Message@2, <<"--signature"/utf8>>, Sig] -> {ok, {verify_message, Pubkey, Message@2, Sig}}; [<<"verify"/utf8>>, <<"-p"/utf8>>, Pubkey@1, <<"-m"/utf8>>, Message@3, <<"-s"/utf8>>, Sig@1] -> {ok, {verify_message, Pubkey@1, Message@3, Sig@1}}; _ -> {error, <<"Invalid wallet command. Use: create|generate|info|sign|verify"/utf8>>} end. -file("src/gleeth/commands/wallet.gleam", 123). ?DOC(" Handle signing a message\n"). -spec handle_sign_message(binary(), binary()) -> {ok, nil} | {error, binary()}. handle_sign_message(Private_key_hex, Message) -> gleam@result:'try'( begin _pipe = gleeth@utils@validation:validate_private_key( Private_key_hex ), gleam@result:map_error(_pipe, fun(Err) -> case Err of {parse_error, Msg} -> Msg; _ -> <<"Invalid private key format"/utf8>> end end) end, fun(_) -> gleam@result:'try'( begin _pipe@1 = gleeth@crypto@wallet:from_private_key_hex( Private_key_hex ), gleam@result:map_error( _pipe@1, fun(Err@1) -> gleeth@crypto@wallet:error_to_string(Err@1) end ) end, fun(Wallet_result) -> gleam@result:'try'( begin _pipe@2 = gleeth@crypto@wallet:sign_personal_message( Wallet_result, Message ), gleam@result:map_error( _pipe@2, fun(Err@2) -> gleeth@crypto@wallet:error_to_string(Err@2) end ) end, fun(Signature) -> gleeth@ethereum@formatting:print_success( <<"Message signed successfully!"/utf8>> ), gleeth@ethereum@formatting:print_section( <<""/utf8>> ), gleeth@ethereum@formatting:print_labeled_value( <<"Message"/utf8>>, Message ), gleeth@ethereum@formatting:print_labeled_value( <<"Signature"/utf8>>, gleeth@crypto@secp256k1:signature_to_hex( Signature ) ), {V, R, S} = gleeth@crypto@secp256k1:signature_to_vrs( Signature ), gleeth@ethereum@formatting:print_section( <<"Signature components"/utf8>> ), gleeth@ethereum@formatting:print_labeled_value( <<"v"/utf8>>, gleam@string:inspect(V) ), gleeth@ethereum@formatting:print_labeled_value( <<"r"/utf8>>, R ), gleeth@ethereum@formatting:print_labeled_value( <<"s"/utf8>>, S ), {ok, nil} end ) end ) end ). -file("src/gleeth/commands/wallet.gleam", 239). ?DOC(" Parse signature from validated hex string\n"). -spec parse_signature_hex(binary()) -> {ok, gleeth@crypto@secp256k1:signature()} | {error, binary()}. parse_signature_hex(Signature_hex) -> Clean_hex = gleeth@utils@hex:strip_prefix(Signature_hex), R_hex = gleam@string:slice(Clean_hex, 0, 64), S_hex = gleam@string:slice(Clean_hex, 64, 64), V_hex = gleam@string:slice(Clean_hex, 128, 2), gleam@result:'try'( begin _pipe = gleeth@utils@hex:decode(<<"0x"/utf8, R_hex/binary>>), gleam@result:map_error( _pipe, fun(_) -> <<"Invalid r component in signature"/utf8>> end ) end, fun(R_bytes) -> gleam@result:'try'( begin _pipe@1 = gleeth@utils@hex:decode( <<"0x"/utf8, S_hex/binary>> ), gleam@result:map_error( _pipe@1, fun(_) -> <<"Invalid s component in signature"/utf8>> end ) end, fun(S_bytes) -> gleam@result:'try'(case gleam@int:base_parse(V_hex, 16) of {ok, V} -> {ok, V - 27}; {error, _} -> {error, <<"Invalid v component in signature"/utf8>>} end, fun(V_int) -> {ok, {signature, R_bytes, S_bytes, V_int}} end) end ) end ). -file("src/gleeth/commands/wallet.gleam", 165). ?DOC(" Handle verifying a message signature\n"). -spec handle_verify_message(binary(), binary(), binary()) -> {ok, nil} | {error, binary()}. handle_verify_message(Public_key_hex, Message, Signature_hex) -> gleam@result:'try'( begin _pipe = gleeth@utils@validation:validate_public_key(Public_key_hex), gleam@result:map_error(_pipe, fun(Err) -> case Err of {parse_error, Msg} -> Msg; _ -> <<"Invalid public key format"/utf8>> end end) end, fun(Validated_pubkey) -> gleam@result:'try'( begin _pipe@1 = gleeth@utils@hex:decode(Validated_pubkey), gleam@result:map_error( _pipe@1, fun(_) -> <<"Failed to decode public key"/utf8>> end ) end, fun(Public_key_bytes) -> Public_key = {public_key, Public_key_bytes}, gleam@result:'try'( begin _pipe@2 = gleeth@utils@validation:validate_signature( Signature_hex ), gleam@result:map_error( _pipe@2, fun(Err@1) -> case Err@1 of {parse_error, Msg@1} -> Msg@1; _ -> <<"Invalid signature format"/utf8>> end end ) end, fun(Validated_signature) -> gleam@result:'try'( parse_signature_hex(Validated_signature), fun(Signature) -> Message_bytes = gleam_stdlib:identity( Message ), Message_length = begin _pipe@3 = erlang:byte_size( Message_bytes ), gleam@string:inspect(_pipe@3) end, Prefix = <<"\\x19Ethereum Signed Message:\\n"/utf8, Message_length/binary>>, Prefix_bytes = gleam_stdlib:identity(Prefix), Full_message = gleam@bit_array:append( Prefix_bytes, Message_bytes ), Message_hash = gleeth@crypto@keccak:keccak256_binary( Full_message ), gleam@result:'try'( gleeth@crypto@secp256k1:verify_signature( Message_hash, Signature, Public_key ), fun(Is_valid) -> case Is_valid of true -> gleeth@ethereum@formatting:print_success( <<"Signature verification successful!"/utf8>> ), gleeth@ethereum@formatting:print_section( <<""/utf8>> ), gleeth@ethereum@formatting:print_labeled_value( <<"Message"/utf8>>, Message ), gleeth@ethereum@formatting:print_labeled_value( <<"Public Key"/utf8>>, Public_key_hex ), gleeth@ethereum@formatting:print_labeled_value( <<"Signature"/utf8>>, Signature_hex ), gleeth@ethereum@formatting:print_labeled_value( <<"Status"/utf8>>, <<"VALID ✓"/utf8>> ), {ok, nil}; false -> gleeth@ethereum@formatting:print_error( <<"Signature verification failed!"/utf8>> ), gleeth@ethereum@formatting:print_section( <<""/utf8>> ), gleeth@ethereum@formatting:print_labeled_value( <<"Message"/utf8>>, Message ), gleeth@ethereum@formatting:print_labeled_value( <<"Public Key"/utf8>>, Public_key_hex ), gleeth@ethereum@formatting:print_labeled_value( <<"Signature"/utf8>>, Signature_hex ), gleeth@ethereum@formatting:print_labeled_value( <<"Status"/utf8>>, <<"INVALID ✗"/utf8>> ), {error, <<"Signature is not valid for the given message and public key"/utf8>>} end end ) end ) end ) end ) end ). -file("src/gleeth/commands/wallet.gleam", 266). ?DOC(" Print formatted wallet information\n"). -spec print_wallet_info(gleeth@crypto@wallet:wallet()) -> nil. print_wallet_info(Wallet_obj) -> Address = gleeth@crypto@wallet:get_address(Wallet_obj), Private_key = gleeth@crypto@wallet:get_private_key_hex(Wallet_obj), Public_key = gleeth@crypto@wallet:get_public_key_hex(Wallet_obj), Is_valid = gleeth@crypto@wallet:is_valid(Wallet_obj), gleeth@ethereum@formatting:print_labeled_value( <<"Address"/utf8>>, gleeth@ethereum@formatting:display_address(Address) ), gleeth@ethereum@formatting:print_labeled_value( <<"Private Key"/utf8>>, gleeth@utils@hex:normalize(Private_key) ), gleeth@ethereum@formatting:print_labeled_value( <<"Public Key"/utf8>>, gleeth@utils@hex:normalize(Public_key) ), gleeth@ethereum@formatting:print_labeled_value( <<"Valid"/utf8>>, gleam@string:inspect(Is_valid) ). -file("src/gleeth/commands/wallet.gleam", 61). ?DOC(" Handle creating wallet from private key\n"). -spec handle_create_from_key(binary()) -> {ok, nil} | {error, binary()}. handle_create_from_key(Private_key_hex) -> gleam@result:'try'( begin _pipe = gleeth@utils@validation:validate_private_key( Private_key_hex ), gleam@result:map_error(_pipe, fun(Err) -> case Err of {parse_error, Msg} -> Msg; _ -> <<"Invalid private key format"/utf8>> end end) end, fun(_) -> gleam@result:'try'( begin _pipe@1 = gleeth@crypto@wallet:from_private_key_hex( Private_key_hex ), gleam@result:map_error( _pipe@1, fun(Err@1) -> gleeth@crypto@wallet:error_to_string(Err@1) end ) end, fun(Wallet_result) -> gleeth@ethereum@formatting:print_success( <<"Wallet created successfully!"/utf8>> ), gleeth@ethereum@formatting:print_section(<<""/utf8>>), print_wallet_info(Wallet_result), {ok, nil} end ) end ). -file("src/gleeth/commands/wallet.gleam", 84). ?DOC(" Handle generating new wallet\n"). -spec handle_generate_new() -> {ok, nil} | {error, binary()}. handle_generate_new() -> case gleeth@crypto@wallet:generate() of {ok, New_wallet} -> gleeth@ethereum@formatting:print_success( <<"New wallet generated!"/utf8>> ), gleeth@ethereum@formatting:print_warning( <<"WARNING: Save your private key securely!"/utf8>> ), gleeth@ethereum@formatting:print_section(<<""/utf8>>), print_wallet_info(New_wallet), {ok, nil}; {error, Err} -> {error, <<"Failed to generate wallet: "/utf8, (gleeth@crypto@wallet:error_to_string(Err))/binary>>} end. -file("src/gleeth/commands/wallet.gleam", 100). ?DOC(" Handle showing wallet info\n"). -spec handle_show_info(binary()) -> {ok, nil} | {error, binary()}. handle_show_info(Private_key_hex) -> gleam@result:'try'( begin _pipe = gleeth@utils@validation:validate_private_key( Private_key_hex ), gleam@result:map_error(_pipe, fun(Err) -> case Err of {parse_error, Msg} -> Msg; _ -> <<"Invalid private key format"/utf8>> end end) end, fun(_) -> gleam@result:'try'( begin _pipe@1 = gleeth@crypto@wallet:from_private_key_hex( Private_key_hex ), gleam@result:map_error( _pipe@1, fun(Err@1) -> gleeth@crypto@wallet:error_to_string(Err@1) end ) end, fun(Wallet_result) -> gleeth@ethereum@formatting:print_info( <<"Wallet Information:"/utf8>> ), gleeth@ethereum@formatting:print_section(<<""/utf8>>), print_wallet_info(Wallet_result), {ok, nil} end ) end ). -file("src/gleeth/commands/wallet.gleam", 48). ?DOC(" Execute wallet operation\n"). -spec run(wallet_operation()) -> {ok, nil} | {error, binary()}. run(Operation) -> case Operation of {create_from_key, Private_key} -> handle_create_from_key(Private_key); generate_new -> handle_generate_new(); {show_info, Private_key@1} -> handle_show_info(Private_key@1); {sign_message, Private_key@2, Message} -> handle_sign_message(Private_key@2, Message); {verify_message, Public_key, Message@1, Signature} -> handle_verify_message(Public_key, Message@1, Signature) end. -file("src/gleeth/commands/wallet.gleam", 279). ?DOC(" Print usage information\n"). -spec print_usage() -> nil. print_usage() -> gleam_stdlib:println(<<"Usage: gleeth wallet [options]"/utf8>>), gleam_stdlib:println(<<""/utf8>>), gleam_stdlib:println(<<"Commands:"/utf8>>), gleam_stdlib:println( <<" create --private-key Create wallet from private key"/utf8>> ), gleam_stdlib:println( <<" generate Generate new random wallet"/utf8>> ), gleam_stdlib:println( <<" info --private-key Show wallet information"/utf8>> ), gleam_stdlib:println( <<" sign --private-key --message Sign a message"/utf8>> ), gleam_stdlib:println( <<" verify --public-key --message --signature Verify a signature"/utf8>> ), gleam_stdlib:println(<<""/utf8>>), gleam_stdlib:println(<<"Options:"/utf8>>), gleam_stdlib:println( <<" --private-key, -k Private key (hex format)"/utf8>> ), gleam_stdlib:println( <<" --public-key, -p Public key (hex format)"/utf8>> ), gleam_stdlib:println( <<" --message, -m Message to sign/verify"/utf8>> ), gleam_stdlib:println( <<" --signature, -s Signature to verify (hex format)"/utf8>> ), gleam_stdlib:println(<<""/utf8>>), gleam_stdlib:println(<<"Examples:"/utf8>>), gleam_stdlib:println(<<" gleeth wallet create -k 0x1234..."/utf8>>), gleam_stdlib:println(<<" gleeth wallet generate"/utf8>>), gleam_stdlib:println(<<" gleeth wallet info -k 0x1234..."/utf8>>), gleam_stdlib:println( <<" gleeth wallet sign -k 0x1234... -m 'Hello World'"/utf8>> ), gleam_stdlib:println( <<" gleeth wallet verify -p 0x04abc... -m 'Hello World' -s 0xdef..."/utf8>> ). -file("src/gleeth/commands/wallet.gleam", 308). ?DOC(" Print help for wallet command\n"). -spec print_help() -> nil. print_help() -> gleam_stdlib:println(<<"Gleeth Wallet Management"/utf8>>), gleam_stdlib:println(<<"========================"/utf8>>), gleam_stdlib:println(<<""/utf8>>), gleam_stdlib:println(<<"Manage Ethereum wallets and sign messages."/utf8>>), gleam_stdlib:println(<<""/utf8>>), print_usage(), gleam_stdlib:println(<<""/utf8>>), gleam_stdlib:println(<<"Security Notes:"/utf8>>), gleam_stdlib:println(<<"- Never share your private key"/utf8>>), gleam_stdlib:println(<<"- Store private keys securely"/utf8>>), gleam_stdlib:println(<<"- Use hardware wallets for large amounts"/utf8>>), gleam_stdlib:println(<<"- Test on testnets before mainnet"/utf8>>).