Current section
Files
Jump to
Current section
Files
src/gleeth@crypto@wallet.erl
-module(gleeth@crypto@wallet).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/gleeth/crypto/wallet.gleam").
-export([from_private_key_hex/1, from_private_key_bytes/1, generate/0, get_address/1, get_private_key_hex/1, get_public_key_hex/1, get_private_key_bytes/1, get_public_key_bytes/1, is_valid/1, sign_hash/2, sign_message/2, sign_personal_message/2, to_string/1, to_summary/1, equals/2, error_to_string/1, is_recoverable_error/1]).
-export_type([wallet/0, wallet_error/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() :: {wallet,
gleeth@crypto@secp256k1:private_key(),
gleeth@crypto@secp256k1:public_key(),
gleeth@crypto@secp256k1:ethereum_address()}.
-type wallet_error() :: {invalid_private_key, binary()} |
{invalid_hex, binary()} |
{key_generation_failed, binary()} |
{signing_failed, binary()}.
-file("src/gleeth/crypto/wallet.gleam", 28).
?DOC(
" Create a wallet from a private key hex string\n"
" Supports both with and without 0x prefix\n"
).
-spec from_private_key_hex(binary()) -> {ok, wallet()} | {error, wallet_error()}.
from_private_key_hex(Hex_string) ->
gleam@result:'try'(
begin
_pipe = gleeth@crypto@secp256k1:private_key_from_hex(Hex_string),
gleam@result:map_error(
_pipe,
fun(Field@0) -> {invalid_private_key, Field@0} end
)
end,
fun(Private_key) ->
gleam@result:'try'(
begin
_pipe@1 = gleeth@crypto@secp256k1:create_public_key(
Private_key
),
gleam@result:map_error(
_pipe@1,
fun(Field@0) -> {key_generation_failed, Field@0} end
)
end,
fun(Public_key) ->
gleam@result:'try'(
begin
_pipe@2 = gleeth@crypto@secp256k1:public_key_to_address(
Public_key
),
gleam@result:map_error(
_pipe@2,
fun(Field@0) -> {key_generation_failed, Field@0} end
)
end,
fun(Address) ->
{ok, {wallet, Private_key, Public_key, Address}}
end
)
end
)
end
).
-file("src/gleeth/crypto/wallet.gleam", 48).
?DOC(" Create a wallet from raw private key bytes\n").
-spec from_private_key_bytes(bitstring()) -> {ok, wallet()} |
{error, wallet_error()}.
from_private_key_bytes(Bytes) ->
gleam@result:'try'(
begin
_pipe = gleeth@crypto@secp256k1:private_key_from_bytes(Bytes),
gleam@result:map_error(
_pipe,
fun(Field@0) -> {invalid_private_key, Field@0} end
)
end,
fun(Private_key) ->
gleam@result:'try'(
begin
_pipe@1 = gleeth@crypto@secp256k1:create_public_key(
Private_key
),
gleam@result:map_error(
_pipe@1,
fun(Field@0) -> {key_generation_failed, Field@0} end
)
end,
fun(Public_key) ->
gleam@result:'try'(
begin
_pipe@2 = gleeth@crypto@secp256k1:public_key_to_address(
Public_key
),
gleam@result:map_error(
_pipe@2,
fun(Field@0) -> {key_generation_failed, Field@0} end
)
end,
fun(Address) ->
{ok, {wallet, Private_key, Public_key, Address}}
end
)
end
)
end
).
-file("src/gleeth/crypto/wallet.gleam", 68).
?DOC(" Generate a new random wallet using cryptographically secure randomness\n").
-spec generate() -> {ok, wallet()} | {error, wallet_error()}.
generate() ->
gleam@result:'try'(
begin
_pipe = gleeth@crypto@random:generate_private_key(),
gleam@result:map_error(
_pipe,
fun(Err) ->
{key_generation_failed,
<<"Failed to generate secure private key: "/utf8,
(gleeth@crypto@random:error_to_string(Err))/binary>>}
end
)
end,
fun(Private_key) ->
gleam@result:'try'(
begin
_pipe@1 = gleeth@crypto@secp256k1:create_public_key(
Private_key
),
gleam@result:map_error(
_pipe@1,
fun(Field@0) -> {key_generation_failed, Field@0} end
)
end,
fun(Public_key) ->
gleam@result:'try'(
begin
_pipe@2 = gleeth@crypto@secp256k1:public_key_to_address(
Public_key
),
gleam@result:map_error(
_pipe@2,
fun(Field@0) -> {key_generation_failed, Field@0} end
)
end,
fun(Address) ->
{ok, {wallet, Private_key, Public_key, Address}}
end
)
end
)
end
).
-file("src/gleeth/crypto/wallet.gleam", 96).
?DOC(" Get the wallet's Ethereum address as a string\n").
-spec get_address(wallet()) -> binary().
get_address(Wallet) ->
gleeth@crypto@secp256k1:address_to_string(erlang:element(4, Wallet)).
-file("src/gleeth/crypto/wallet.gleam", 101).
?DOC(" Get the wallet's private key as a hex string\n").
-spec get_private_key_hex(wallet()) -> binary().
get_private_key_hex(Wallet) ->
gleeth@crypto@secp256k1:private_key_to_hex(erlang:element(2, Wallet)).
-file("src/gleeth/crypto/wallet.gleam", 106).
?DOC(" Get the wallet's public key as a hex string\n").
-spec get_public_key_hex(wallet()) -> binary().
get_public_key_hex(Wallet) ->
gleeth@crypto@secp256k1:public_key_to_hex(erlang:element(3, Wallet)).
-file("src/gleeth/crypto/wallet.gleam", 111).
?DOC(" Get the wallet's private key as raw bytes\n").
-spec get_private_key_bytes(wallet()) -> bitstring().
get_private_key_bytes(Wallet) ->
gleeth@crypto@secp256k1:private_key_to_bytes(erlang:element(2, Wallet)).
-file("src/gleeth/crypto/wallet.gleam", 116).
?DOC(" Get the wallet's public key as raw bytes\n").
-spec get_public_key_bytes(wallet()) -> bitstring().
get_public_key_bytes(Wallet) ->
gleeth@crypto@secp256k1:public_key_to_bytes(erlang:element(3, Wallet)).
-file("src/gleeth/crypto/wallet.gleam", 121).
?DOC(" Check if the wallet has a valid private key\n").
-spec is_valid(wallet()) -> boolean().
is_valid(Wallet) ->
gleeth@crypto@secp256k1:is_valid_private_key(erlang:element(2, Wallet)).
-file("src/gleeth/crypto/wallet.gleam", 130).
?DOC(" Sign a message hash with the wallet's private key\n").
-spec sign_hash(wallet(), bitstring()) -> {ok,
gleeth@crypto@secp256k1:signature()} |
{error, wallet_error()}.
sign_hash(Wallet, Message_hash) ->
_pipe = gleeth@crypto@secp256k1:sign_message_hash(
Message_hash,
erlang:element(2, Wallet)
),
gleam@result:map_error(_pipe, fun(Field@0) -> {signing_failed, Field@0} end).
-file("src/gleeth/crypto/wallet.gleam", 139).
?DOC(" Sign raw message bytes (will be hashed with keccak256)\n").
-spec sign_message(wallet(), bitstring()) -> {ok,
gleeth@crypto@secp256k1:signature()} |
{error, wallet_error()}.
sign_message(Wallet, Message) ->
_pipe = gleeth@crypto@secp256k1:sign_message(
Message,
erlang:element(2, Wallet)
),
gleam@result:map_error(_pipe, fun(Field@0) -> {signing_failed, Field@0} end).
-file("src/gleeth/crypto/wallet.gleam", 148).
?DOC(" Sign an Ethereum personal message\n").
-spec sign_personal_message(wallet(), binary()) -> {ok,
gleeth@crypto@secp256k1:signature()} |
{error, wallet_error()}.
sign_personal_message(Wallet, Message) ->
_pipe = gleeth@crypto@secp256k1:sign_personal_message(
Message,
erlang:element(2, Wallet)
),
gleam@result:map_error(_pipe, fun(Field@0) -> {signing_failed, Field@0} end).
-file("src/gleeth/crypto/wallet.gleam", 161).
?DOC(" Convert a wallet to a summary string for display\n").
-spec to_string(wallet()) -> binary().
to_string(Wallet) ->
Address = get_address(Wallet),
Private_key = get_private_key_hex(Wallet),
<<<<<<<<<<<<<<"Wallet {\n"/utf8, " address: "/utf8>>/binary,
Address/binary>>/binary,
"\n"/utf8>>/binary,
" private_key: "/utf8>>/binary,
Private_key/binary>>/binary,
"\n"/utf8>>/binary,
"}"/utf8>>.
-file("src/gleeth/crypto/wallet.gleam", 176).
?DOC(" Convert a wallet to a compact summary for logging\n").
-spec to_summary(wallet()) -> binary().
to_summary(Wallet) ->
Address = get_address(Wallet),
<<<<"Wallet("/utf8, Address/binary>>/binary, ")"/utf8>>.
-file("src/gleeth/crypto/wallet.gleam", 182).
?DOC(" Check if two wallets are the same (have same private key)\n").
-spec equals(wallet(), wallet()) -> boolean().
equals(Wallet1, Wallet2) ->
get_private_key_hex(Wallet1) =:= get_private_key_hex(Wallet2).
-file("src/gleeth/crypto/wallet.gleam", 191).
?DOC(" Convert WalletError to string for display\n").
-spec error_to_string(wallet_error()) -> binary().
error_to_string(Error) ->
case Error of
{invalid_private_key, Msg} ->
<<"Invalid private key: "/utf8, Msg/binary>>;
{invalid_hex, Msg@1} ->
<<"Invalid hex format: "/utf8, Msg@1/binary>>;
{key_generation_failed, Msg@2} ->
<<"Key generation failed: "/utf8, Msg@2/binary>>;
{signing_failed, Msg@3} ->
<<"Signing failed: "/utf8, Msg@3/binary>>
end.
-file("src/gleeth/crypto/wallet.gleam", 201).
?DOC(" Check if an error is recoverable\n").
-spec is_recoverable_error(wallet_error()) -> boolean().
is_recoverable_error(Error) ->
case Error of
{invalid_private_key, _} ->
false;
{invalid_hex, _} ->
false;
{key_generation_failed, _} ->
true;
{signing_failed, _} ->
true
end.