WIP
This commit is contained in:
parent
56ca92a236
commit
54b65413d5
@ -9,7 +9,7 @@
|
|||||||
-copyright("Craig Everett <craigeverett@qpq.swiss>").
|
-copyright("Craig Everett <craigeverett@qpq.swiss>").
|
||||||
-license("GPL-3.0-or-later").
|
-license("GPL-3.0-or-later").
|
||||||
|
|
||||||
-export([start/2, stop/1]).
|
-export([start/2, stop/1, exec_bin_dir/0]).
|
||||||
|
|
||||||
-include("$zx_include/zx_logger.hrl").
|
-include("$zx_include/zx_logger.hrl").
|
||||||
|
|
||||||
@ -28,7 +28,6 @@ start(normal, _Args) ->
|
|||||||
end,
|
end,
|
||||||
ok = application:ensure_started(hakuzaru),
|
ok = application:ensure_started(hakuzaru),
|
||||||
ok = application:ensure_started(zxwidgets),
|
ok = application:ensure_started(zxwidgets),
|
||||||
ok = application:ensure_started(sophia),
|
|
||||||
gmc_sup:start_link().
|
gmc_sup:start_link().
|
||||||
|
|
||||||
|
|
||||||
@ -36,3 +35,9 @@ start(normal, _Args) ->
|
|||||||
|
|
||||||
stop(_State) ->
|
stop(_State) ->
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
|
|
||||||
|
-spec exec_bin_dir() -> file:filename().
|
||||||
|
|
||||||
|
exec_bin_dir() ->
|
||||||
|
gmc_con:bin_dir().
|
||||||
|
163
src/gmc_con.erl
163
src/gmc_con.erl
@ -9,7 +9,8 @@
|
|||||||
-license("GPL-3.0-or-later").
|
-license("GPL-3.0-or-later").
|
||||||
|
|
||||||
-behavior(gen_server).
|
-behavior(gen_server).
|
||||||
-export([unlock/1, make_key/1, load_key/2, end_setup/0]).
|
-export([start_stop/0]).
|
||||||
|
-export([unlock/1, make_key/2, load_key/3, end_setup/0, exec_bin_dir/0]).
|
||||||
-export([network/0]).
|
-export([network/0]).
|
||||||
-export([start_link/0, stop/0]).
|
-export([start_link/0, stop/0]).
|
||||||
-export([init/1, terminate/2, code_change/3,
|
-export([init/1, terminate/2, code_change/3,
|
||||||
@ -22,11 +23,12 @@
|
|||||||
|
|
||||||
|
|
||||||
-record(s,
|
-record(s,
|
||||||
{version = 1 :: integer(),
|
{version = 1 :: integer(),
|
||||||
window = none :: none | wx:wx_object(),
|
window = none :: none | wx:wx_object(),
|
||||||
network = none :: none | mainnet | testnet,
|
network = none :: none | mainnet | testnet,
|
||||||
key = none :: none | {blob, binary()} | #key{},
|
exec_dir = platform_dir() :: file:filename(),
|
||||||
pass = none :: none | binary()}).
|
key = none :: none | {blob, binary()} | #key{},
|
||||||
|
pass = none :: none | binary()}).
|
||||||
|
|
||||||
-type state() :: #s{}.
|
-type state() :: #s{}.
|
||||||
|
|
||||||
@ -34,6 +36,12 @@
|
|||||||
|
|
||||||
%% Interface
|
%% Interface
|
||||||
|
|
||||||
|
-spec start_stop() -> ok.
|
||||||
|
|
||||||
|
start_stop() ->
|
||||||
|
gen_server:cast(?MODULE, start_stop).
|
||||||
|
|
||||||
|
|
||||||
-spec unlock(Phrase) -> ok
|
-spec unlock(Phrase) -> ok
|
||||||
when Phrase :: string().
|
when Phrase :: string().
|
||||||
|
|
||||||
@ -41,19 +49,21 @@ unlock(Phrase) ->
|
|||||||
gen_server:cast(?MODULE, {unlock, Phrase}).
|
gen_server:cast(?MODULE, {unlock, Phrase}).
|
||||||
|
|
||||||
|
|
||||||
-spec make_key(Phrase) -> ok
|
-spec make_key(Phrase, Network) -> ok
|
||||||
when Phrase :: string().
|
when Phrase :: string(),
|
||||||
|
Network :: mainnet | testnet.
|
||||||
|
|
||||||
make_key(Phrase) ->
|
make_key(Phrase, Network) ->
|
||||||
gen_server:cast(?MODULE, {make_key, Phrase}).
|
gen_server:cast(?MODULE, {make_key, Phrase, Network}).
|
||||||
|
|
||||||
|
|
||||||
-spec load_key(Phrase, Mnemonic) -> ok
|
-spec load_key(Phrase, Mnemonic, Network) -> ok
|
||||||
when Phrase :: string(),
|
when Phrase :: string(),
|
||||||
Mnemonic :: string().
|
Mnemonic :: string(),
|
||||||
|
Network :: mainnet | testnet.
|
||||||
|
|
||||||
load_key(Phrase, Mnemonic) ->
|
load_key(Phrase, Mnemonic, Network) ->
|
||||||
gen_server:cast(?MODULE, {load_key, Phrase, Mnemonic}).
|
gen_server:cast(?MODULE, {load_key, Phrase, Mnemonic, Network}).
|
||||||
|
|
||||||
|
|
||||||
-spec end_setup() -> ok.
|
-spec end_setup() -> ok.
|
||||||
@ -62,6 +72,12 @@ end_setup() ->
|
|||||||
gen_server:call(?MODULE, end_setup).
|
gen_server:call(?MODULE, end_setup).
|
||||||
|
|
||||||
|
|
||||||
|
-spec bin_dir() -> file:filename().
|
||||||
|
|
||||||
|
bin_dir() ->
|
||||||
|
gen_server:call(?MODULE, bin_dir).
|
||||||
|
|
||||||
|
|
||||||
-spec network() -> mainnet | testnet | none.
|
-spec network() -> mainnet | testnet | none.
|
||||||
|
|
||||||
network() ->
|
network() ->
|
||||||
@ -134,6 +150,22 @@ open_wallet() ->
|
|||||||
error
|
error
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
platform_dir() ->
|
||||||
|
#{deps := Deps} = zx_daemon:meta(),
|
||||||
|
AppID = lists:keyfind("cuckoo_cpu", 2, Deps),
|
||||||
|
Priv = filename:join(zx_lib:ppath(lib, AppID), "priv"),
|
||||||
|
Dir =
|
||||||
|
case os:type() of
|
||||||
|
{unix, linux} ->
|
||||||
|
"linux_x86_64";
|
||||||
|
{unix, darwin} ->
|
||||||
|
% TODO: Check M2 vs x86
|
||||||
|
"mac_m2";
|
||||||
|
{win32, nt} ->
|
||||||
|
"win_x86_64"
|
||||||
|
end,
|
||||||
|
filename:join(Priv, Dir).
|
||||||
|
|
||||||
|
|
||||||
start_gui(State = #s{key = #key{id = ID}}) ->
|
start_gui(State = #s{key = #key{id = ID}}) ->
|
||||||
Window = gmc_gui:start_link(#{}),
|
Window = gmc_gui:start_link(#{}),
|
||||||
@ -152,6 +184,8 @@ handle_call(end_setup, _, State) ->
|
|||||||
{reply, ok, NewState};
|
{reply, ok, NewState};
|
||||||
handle_call(network, _, State = #s{network = Network}) ->
|
handle_call(network, _, State = #s{network = Network}) ->
|
||||||
{reply, Network, State};
|
{reply, Network, State};
|
||||||
|
handle_call(bin_dir, _, State = #s{exec = {BinDir, _}}) ->
|
||||||
|
{reply, BinDir, State};
|
||||||
handle_call(Unexpected, From, State) ->
|
handle_call(Unexpected, From, State) ->
|
||||||
ok = log(warning, "Unexpected call from ~tp: ~tp~n", [From, Unexpected]),
|
ok = log(warning, "Unexpected call from ~tp: ~tp~n", [From, Unexpected]),
|
||||||
{noreply, State}.
|
{noreply, State}.
|
||||||
@ -160,15 +194,19 @@ handle_call(Unexpected, From, State) ->
|
|||||||
handle_cast({unlock, Phrase}, State) ->
|
handle_cast({unlock, Phrase}, State) ->
|
||||||
NewState = unlock(Phrase, State),
|
NewState = unlock(Phrase, State),
|
||||||
{noreply, NewState};
|
{noreply, NewState};
|
||||||
handle_cast({make_key, Phrase}, State) ->
|
handle_cast({make_key, Phrase, Network}, State) ->
|
||||||
NewState = make_key(Phrase, State),
|
NewState = make_key(Phrase, Network, State),
|
||||||
{noreply, NewState};
|
{noreply, NewState};
|
||||||
handle_cast({load_key, Phrase, Mnemonic}, State) ->
|
handle_cast({load_key, Phrase, Mnemonic, Network}, State) ->
|
||||||
NewState = load_key(Phrase, Mnemonic, State),
|
NewState = load_key(Phrase, Mnemonic, Network, State),
|
||||||
{noreply, NewState};
|
{noreply, NewState};
|
||||||
|
handle_cast(start_stop, State) ->
|
||||||
|
ok = do_start_stop(State),
|
||||||
|
{noreply, State};
|
||||||
handle_cast(stop, State) ->
|
handle_cast(stop, State) ->
|
||||||
|
ok = do_stop(),
|
||||||
ok = log(info, "Received a 'stop' message."),
|
ok = log(info, "Received a 'stop' message."),
|
||||||
{stop, normal, State};
|
{noreply, State};
|
||||||
handle_cast(Unexpected, State) ->
|
handle_cast(Unexpected, State) ->
|
||||||
ok = log(warning, "Unexpected cast: ~tp~n", [Unexpected]),
|
ok = log(warning, "Unexpected cast: ~tp~n", [Unexpected]),
|
||||||
{noreply, State}.
|
{noreply, State}.
|
||||||
@ -194,6 +232,13 @@ terminate(Reason, _) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
|
do_stop() ->
|
||||||
|
case is_pid(whereis(gd_con)) of
|
||||||
|
false -> zx:stop();
|
||||||
|
true -> application:stop(gajumine)
|
||||||
|
end.
|
||||||
|
|
||||||
|
|
||||||
%%% Doers
|
%%% Doers
|
||||||
|
|
||||||
unlock(Phrase, State = #s{key = {blob, Cipher}}) ->
|
unlock(Phrase, State = #s{key = {blob, Cipher}}) ->
|
||||||
@ -213,32 +258,36 @@ unlock(Phrase, State = #s{key = {blob, Cipher}}) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
make_key(Phrase, State) ->
|
make_key(Phrase, Network, State) ->
|
||||||
{ID, Pair = #{secret := <<K:32/binary, _/binary>>}} = hz_key_master:make_key(<<>>),
|
{ID, Pair = #{secret := <<K:32/binary, _/binary>>}} = hz_key_master:make_key(<<>>),
|
||||||
Mnemonic = hz_key_master:encode(K),
|
Mnemonic = hz_key_master:encode(K),
|
||||||
ok = gmc_setup:done(Mnemonic),
|
ok = gmc_setup:done(Mnemonic),
|
||||||
finalize_key(Phrase, ID, Pair, State).
|
finalize_key(Phrase, ID, Pair, Network, State).
|
||||||
|
|
||||||
|
|
||||||
load_key(Phrase, Mnemonic, State) ->
|
load_key(Phrase, Mnemonic, Network, State) ->
|
||||||
case hz_key_master:decode(Mnemonic) of
|
case hz_key_master:decode(Mnemonic) of
|
||||||
{ok, Secret} ->
|
{ok, Secret} ->
|
||||||
{ID, Pair} = hz_key_master:make_key(Secret),
|
{ID, Pair} = hz_key_master:make_key(Secret),
|
||||||
finalize_key(Phrase, ID, Pair, State);
|
ok = gmc_setup:done(),
|
||||||
|
finalize_key(Phrase, ID, Pair, Network, State);
|
||||||
Error ->
|
Error ->
|
||||||
ok = gmc_gui:trouble(Error),
|
ok = gmc_setup:trouble(Error),
|
||||||
ok = gmc_gui:bad_mnemonic(),
|
|
||||||
State
|
State
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
finalize_key(Phrase, ID, Pair, State) ->
|
finalize_key(Phrase, ID, Pair, Network, State) ->
|
||||||
Pass = pass(unicode:characters_to_binary(Phrase)),
|
Pass =
|
||||||
Key = #key{id = ID} = add_wallet(Pass, ID, Pair),
|
case Phrase =:= "" of
|
||||||
State#s{key = Key, pass = Pass}.
|
false -> pass(unicode:characters_to_binary(Phrase));
|
||||||
|
true -> none
|
||||||
|
end,
|
||||||
|
Key = #key{id = ID} = add_wallet(Pass, ID, Pair, Network),
|
||||||
|
State#s{key = Key, pass = Pass, network = Network}.
|
||||||
|
|
||||||
|
|
||||||
add_wallet(Pass, ID, Pair = #{secret := Secret}) ->
|
add_wallet(Pass, ID, Pair = #{secret := Secret}, Network) ->
|
||||||
GDPrefsPath = gd_prefs_path(),
|
GDPrefsPath = gd_prefs_path(),
|
||||||
GDPrefs =
|
GDPrefs =
|
||||||
case file:consult(GDPrefsPath) of
|
case file:consult(GDPrefsPath) of
|
||||||
@ -247,21 +296,29 @@ add_wallet(Pass, ID, Pair = #{secret := Secret}) ->
|
|||||||
end,
|
end,
|
||||||
Wallets = gd_get_prefs(wallets, GDPrefs, []),
|
Wallets = gd_get_prefs(wallets, GDPrefs, []),
|
||||||
WalletPath = gajumining_wallet(),
|
WalletPath = gajumining_wallet(),
|
||||||
Entry = #wr{name = gm_name(), path = WalletPath, pass = true},
|
|
||||||
NewWallets = lists:keystore(gm_name(), #wr.name, Wallets, Entry),
|
|
||||||
NewGDPrefs = gd_put_prefs(wallets, NewWallets, GDPrefs),
|
|
||||||
Created = #key{name = gm_name(), id = ID, pair = Pair},
|
Created = #key{name = gm_name(), id = ID, pair = Pair},
|
||||||
|
{Net, ChainID, Node} =
|
||||||
|
case Network of
|
||||||
|
mainnet -> {#net{id = <<"mainnet">>}, <<"groot.mainnet">>, #node{ip = "groot.mainnet.gajumaru.io"}};
|
||||||
|
testnet -> {#net{id = <<"testnet">>}, <<"groot.testnet">>, #node{ip = "groot.testnet.gajumaru.io"}}
|
||||||
|
end,
|
||||||
New = #wallet{name = gm_name(),
|
New = #wallet{name = gm_name(),
|
||||||
poas = [#poa{name = gm_name(), id = ID}],
|
poas = [#poa{name = gm_name(), id = ID}],
|
||||||
keys = [Created],
|
keys = [Created],
|
||||||
chain_id = <<"groot.devnet">>,
|
chain_id = ChainID,
|
||||||
endpoint = #node{},
|
endpoint = Node,
|
||||||
nets = [#net{}]},
|
nets = [Net]},
|
||||||
Cipher = encrypt(Pass, term_to_binary(New)),
|
{WalletBin, KeyPair, HasPass} =
|
||||||
ok = file:write_file(WalletPath, Cipher),
|
case Pass =:= none of
|
||||||
|
false -> {encrypt(Pass, term_to_binary(New)), Pair#{secret => {cipher, encrypt(Pass, Secret)}}, true};
|
||||||
|
true -> {term_to_binary(New), Pair, false}
|
||||||
|
end,
|
||||||
|
Entry = #wr{name = gm_name(), path = WalletPath, pass = HasPass},
|
||||||
|
NewWallets = lists:keystore(gm_name(), #wr.name, Wallets, Entry),
|
||||||
|
NewGDPrefs = gd_put_prefs(wallets, NewWallets, GDPrefs),
|
||||||
|
ok = file:write_file(WalletPath, WalletBin),
|
||||||
ok = zx_lib:write_terms(GDPrefsPath, proplists:from_map(NewGDPrefs)),
|
ok = zx_lib:write_terms(GDPrefsPath, proplists:from_map(NewGDPrefs)),
|
||||||
Encrypted = Pair#{secret => encrypt(Pass, Secret)},
|
Created#key{pair = KeyPair}.
|
||||||
Created#key{pair = Encrypted}.
|
|
||||||
|
|
||||||
|
|
||||||
end_setup(State = #s{window = Window}) ->
|
end_setup(State = #s{window = Window}) ->
|
||||||
@ -270,6 +327,32 @@ end_setup(State = #s{window = Window}) ->
|
|||||||
start_gui(State#s{window = none}).
|
start_gui(State#s{window = none}).
|
||||||
|
|
||||||
|
|
||||||
|
do_start_stop(#s{key = #key{id = PubKey}, network = Network}) ->
|
||||||
|
% smrt guy stuff happens here
|
||||||
|
{Bits, Eureka} =
|
||||||
|
case Network of
|
||||||
|
mainnet -> {"29", <<"https://gajumining.com/api/workers/", PubKey/binary>>};
|
||||||
|
testnet -> {"15", <<"https://test.gajumining.com/api/workers/", PubKey/binary>>}
|
||||||
|
end,
|
||||||
|
{Fatness, Type} =
|
||||||
|
case {os:type(), Network} of
|
||||||
|
{unix, linux} ->
|
||||||
|
% Check memory. >7gb gets mean, <7gb gets lean
|
||||||
|
% Check avx2.
|
||||||
|
{unix, darwin} ->
|
||||||
|
% Check memory. >7gb gets mean, <7gb gets lean
|
||||||
|
{win32, nt} ->
|
||||||
|
% Check memory. >7gb gets mean, <7gb gets lean
|
||||||
|
% Check avx2.
|
||||||
|
% Both should be provided by the F# start program
|
||||||
|
end,
|
||||||
|
Miner = string:join([Fatness, Bits, "-", Type]),
|
||||||
|
Profile =
|
||||||
|
[{pubkey, PubKey},
|
||||||
|
{mining, #{executable => Miner, executable_group => <<"gajumine">>}},
|
||||||
|
{pool_admin_url, Eureka}],
|
||||||
|
gmmpc_app:start(Profile).
|
||||||
|
|
||||||
|
|
||||||
%%% Utils
|
%%% Utils
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
-behavior(wx_object).
|
-behavior(wx_object).
|
||||||
-include_lib("wx/include/wx.hrl").
|
-include_lib("wx/include/wx.hrl").
|
||||||
-export([ask_passphrase/0, set_account/1, show/1]).
|
-export([ask_passphrase/0, set_account/1, message/1]).
|
||||||
-export([start_link/1]).
|
-export([start_link/1]).
|
||||||
-export([init/1, terminate/2, code_change/3,
|
-export([init/1, terminate/2, code_change/3,
|
||||||
handle_call/3, handle_cast/2, handle_info/2, handle_event/2]).
|
handle_call/3, handle_cast/2, handle_info/2, handle_event/2]).
|
||||||
@ -47,8 +47,8 @@ ask_passphrase() ->
|
|||||||
wx_object:cast(?MODULE, ask_passphrase).
|
wx_object:cast(?MODULE, ask_passphrase).
|
||||||
|
|
||||||
|
|
||||||
show(Terms) ->
|
message(Terms) ->
|
||||||
wx_object:cast(?MODULE, {show, Terms}).
|
wx_object:cast(?MODULE, {message, Terms}).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -106,7 +106,7 @@ init(Prefs) ->
|
|||||||
|
|
||||||
ok = wxFrame:connect(Frame, command_button_clicked),
|
ok = wxFrame:connect(Frame, command_button_clicked),
|
||||||
ok = wxFrame:connect(Frame, close_window),
|
ok = wxFrame:connect(Frame, close_window),
|
||||||
ok = wxFrame:setSize(Frame, {650, 160}),
|
ok = wxFrame:setSize(Frame, {650, 200}),
|
||||||
ok = wxFrame:center(Frame),
|
ok = wxFrame:center(Frame),
|
||||||
true = wxFrame:show(Frame),
|
true = wxFrame:show(Frame),
|
||||||
State =
|
State =
|
||||||
@ -145,8 +145,8 @@ handle_cast(ask_passphrase, State) ->
|
|||||||
handle_cast({set_account, ID}, State) ->
|
handle_cast({set_account, ID}, State) ->
|
||||||
ok = set_account(ID, State),
|
ok = set_account(ID, State),
|
||||||
{noreply, State};
|
{noreply, State};
|
||||||
handle_cast({show, Terms}, State) ->
|
handle_cast({message, Terms}, State) ->
|
||||||
ok = do_show(Terms, State),
|
ok = do_message(Terms, State),
|
||||||
{noreply, State};
|
{noreply, State};
|
||||||
handle_cast(Unexpected, State) ->
|
handle_cast(Unexpected, State) ->
|
||||||
ok = log(warning, "Unexpected cast: ~tp~n", [Unexpected]),
|
ok = log(warning, "Unexpected cast: ~tp~n", [Unexpected]),
|
||||||
@ -218,7 +218,7 @@ set_account(ID, #s{id = Widget}) ->
|
|||||||
wxStaticText:setLabel(Widget, ID).
|
wxStaticText:setLabel(Widget, ID).
|
||||||
|
|
||||||
|
|
||||||
do_show(Terms, #s{mess = Mess}) ->
|
do_message(Terms, #s{mess = Mess}) ->
|
||||||
String = io_lib:format("Received args: ~tp", [Terms]),
|
String = io_lib:format("Received args: ~tp", [Terms]),
|
||||||
wxTextCtrl:changeValue(Mess, String).
|
wxTextCtrl:changeValue(Mess, String).
|
||||||
|
|
||||||
@ -257,22 +257,27 @@ eureka(State = #s{frame = Frame, j = J}) ->
|
|||||||
|
|
||||||
eureka_url() ->
|
eureka_url() ->
|
||||||
case gmc_con:network() of
|
case gmc_con:network() of
|
||||||
mainnet -> "https://eureka.gajumining.com";
|
mainnet -> "https://gajumining.com";
|
||||||
testnet -> "https://eureka.test.gajumarumining.com";
|
testnet -> "https://test.gajumining.com";
|
||||||
none -> "https://gajumarumining.com"
|
none -> "https://gajumining.com"
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
explorer(State = #s{frame = Frame, j = J}) ->
|
explorer(State = #s{frame = Frame, j = J, id = ID}) ->
|
||||||
ok = tell(info, "Opening Explorer"),
|
ok = tell(info, "Opening Explorer"),
|
||||||
ok = open_browser(Frame, J, explorer_url()),
|
URL =
|
||||||
|
case wxStaticText:getLabel(ID) of
|
||||||
|
"" -> explorer_url();
|
||||||
|
AccountID -> unicode:characters_to_list([explorer_url(), "/account/", AccountID])
|
||||||
|
end,
|
||||||
|
ok = open_browser(Frame, J, URL),
|
||||||
State.
|
State.
|
||||||
|
|
||||||
explorer_url() ->
|
explorer_url() ->
|
||||||
case gmc_con:network() of
|
case gmc_con:network() of
|
||||||
mainnet -> "https://groot.mainnet.gajumaru.io";
|
mainnet -> "https://groot.mainnet.gajumaru.io";
|
||||||
testnet -> "https://groot.testnet.gajumaru.io";
|
testnet -> "https://groot.testnet.gajumaru.io";
|
||||||
none -> "https://gajumaru.io"
|
none -> "https://groot.mainnet.gajumaru.io"
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
-behavior(wx_object).
|
-behavior(wx_object).
|
||||||
-include_lib("wx/include/wx.hrl").
|
-include_lib("wx/include/wx.hrl").
|
||||||
-export([trouble/1, done/1]).
|
-export([trouble/1, done/0, done/1]).
|
||||||
-export([start_link/1]).
|
-export([start_link/1]).
|
||||||
-export([init/1, terminate/2, code_change/3,
|
-export([init/1, terminate/2, code_change/3,
|
||||||
handle_call/3, handle_cast/2, handle_info/2, handle_event/2]).
|
handle_call/3, handle_cast/2, handle_info/2, handle_event/2]).
|
||||||
@ -46,6 +46,10 @@ trouble(Info) ->
|
|||||||
wx_object:cast(?MODULE, {trouble, Info}).
|
wx_object:cast(?MODULE, {trouble, Info}).
|
||||||
|
|
||||||
|
|
||||||
|
done() ->
|
||||||
|
wx_object:cast(?MODULE, done).
|
||||||
|
|
||||||
|
|
||||||
done(Mnemonic) ->
|
done(Mnemonic) ->
|
||||||
wx_object:cast(?MODULE, {done, Mnemonic}).
|
wx_object:cast(?MODULE, {done, Mnemonic}).
|
||||||
|
|
||||||
@ -105,6 +109,10 @@ handle_call(Unexpected, From, State) ->
|
|||||||
handle_cast({trouble, Info}, State) ->
|
handle_cast({trouble, Info}, State) ->
|
||||||
ok = handle_troubling(State, Info),
|
ok = handle_troubling(State, Info),
|
||||||
{noreply, State};
|
{noreply, State};
|
||||||
|
handle_cast(done, State = #s{frame = Frame}) ->
|
||||||
|
ok = gmc_con:end_setup(),
|
||||||
|
ok = wxWindow:destroy(Frame),
|
||||||
|
{noreply, State};
|
||||||
handle_cast({done, Mnemonic}, State) ->
|
handle_cast({done, Mnemonic}, State) ->
|
||||||
ok = done(Mnemonic, State),
|
ok = done(Mnemonic, State),
|
||||||
{noreply, State};
|
{noreply, State};
|
||||||
@ -150,9 +158,9 @@ terminate(Reason, State) ->
|
|||||||
|
|
||||||
|
|
||||||
new_key(State = #s{frame = Frame, j = J}) ->
|
new_key(State = #s{frame = Frame, j = J}) ->
|
||||||
case prompt_passphrase(Frame, J) of
|
case new_key(Frame, J) of
|
||||||
{ok, Phrase} ->
|
{ok, Phrase, Network} ->
|
||||||
gmc_con:make_key(Phrase);
|
gmc_con:make_key(Phrase, Network);
|
||||||
mismatch ->
|
mismatch ->
|
||||||
ok = zxw:show_message(Frame, J("Password entered incorrectly. Try again.")),
|
ok = zxw:show_message(Frame, J("Password entered incorrectly. Try again.")),
|
||||||
new_key(State);
|
new_key(State);
|
||||||
@ -161,10 +169,11 @@ new_key(State = #s{frame = Frame, j = J}) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
prompt_passphrase(Frame, J) ->
|
new_key(Frame, J) ->
|
||||||
Label = J("Generate New Account Key"),
|
Label = J("Generate New Account Key"),
|
||||||
Dialog = wxDialog:new(Frame, ?wxID_ANY, Label, [{size, {500, 180}}]),
|
Dialog = wxDialog:new(Frame, ?wxID_ANY, Label, [{size, {500, 180}}]),
|
||||||
Sizer = wxBoxSizer:new(?wxVERTICAL),
|
Sizer = wxBoxSizer:new(?wxVERTICAL),
|
||||||
|
Network = wxRadioBox:new(Dialog, ?wxID_ANY, J("Network"), {0, 0}, {50, 50}, [J("Mainnet"), J("Testnet")]),
|
||||||
PassSz1 = wxStaticBoxSizer:new(?wxVERTICAL, Dialog, [{label, J("Create Password")}]),
|
PassSz1 = wxStaticBoxSizer:new(?wxVERTICAL, Dialog, [{label, J("Create Password")}]),
|
||||||
PassTx1 = wxTextCtrl:new(Dialog, ?wxID_ANY, [{style, ?wxTE_PASSWORD}]),
|
PassTx1 = wxTextCtrl:new(Dialog, ?wxID_ANY, [{style, ?wxTE_PASSWORD}]),
|
||||||
_ = wxStaticBoxSizer:add(PassSz1, PassTx1, zxw:flags(wide)),
|
_ = wxStaticBoxSizer:add(PassSz1, PassTx1, zxw:flags(wide)),
|
||||||
@ -176,19 +185,27 @@ prompt_passphrase(Frame, J) ->
|
|||||||
Cancel = wxButton:new(Dialog, ?wxID_CANCEL),
|
Cancel = wxButton:new(Dialog, ?wxID_CANCEL),
|
||||||
_ = wxBoxSizer:add(ButtSz, Affirm, zxw:flags(wide)),
|
_ = wxBoxSizer:add(ButtSz, Affirm, zxw:flags(wide)),
|
||||||
_ = wxBoxSizer:add(ButtSz, Cancel, zxw:flags(wide)),
|
_ = wxBoxSizer:add(ButtSz, Cancel, zxw:flags(wide)),
|
||||||
|
_ = wxBoxSizer:add(Sizer, Network, zxw:flags(base)),
|
||||||
_ = wxBoxSizer:add(Sizer, PassSz1, zxw:flags(base)),
|
_ = wxBoxSizer:add(Sizer, PassSz1, zxw:flags(base)),
|
||||||
_ = wxBoxSizer:add(Sizer, PassSz2, zxw:flags(base)),
|
_ = wxBoxSizer:add(Sizer, PassSz2, zxw:flags(base)),
|
||||||
_ = wxBoxSizer:add(Sizer, ButtSz, zxw:flags(wide)),
|
_ = wxBoxSizer:add(Sizer, ButtSz, zxw:flags(wide)),
|
||||||
ok = wxDialog:setSizer(Dialog, Sizer),
|
ok = wxDialog:setSizer(Dialog, Sizer),
|
||||||
|
ok = wxDialog:setSize(Dialog, {400, 250}),
|
||||||
ok = wxBoxSizer:layout(Sizer),
|
ok = wxBoxSizer:layout(Sizer),
|
||||||
ok = wxFrame:center(Dialog),
|
ok = wxFrame:center(Dialog),
|
||||||
Outcome =
|
Outcome =
|
||||||
case wxDialog:showModal(Dialog) of
|
case wxDialog:showModal(Dialog) of
|
||||||
?wxID_OK ->
|
?wxID_OK ->
|
||||||
|
Net =
|
||||||
|
case wxRadioBox:getSelection(Network) of
|
||||||
|
0 -> mainnet;
|
||||||
|
1 -> testnet;
|
||||||
|
_ -> mainnet
|
||||||
|
end,
|
||||||
Pass1 = wxTextCtrl:getValue(PassTx1),
|
Pass1 = wxTextCtrl:getValue(PassTx1),
|
||||||
Pass2 = wxTextCtrl:getValue(PassTx2),
|
Pass2 = wxTextCtrl:getValue(PassTx2),
|
||||||
case Pass1 =:= Pass2 of
|
case Pass1 =:= Pass2 of
|
||||||
true -> {ok, Pass1};
|
true -> {ok, Pass1, Net};
|
||||||
false -> mismatch
|
false -> mismatch
|
||||||
end;
|
end;
|
||||||
?wxID_CANCEL ->
|
?wxID_CANCEL ->
|
||||||
@ -199,8 +216,20 @@ prompt_passphrase(Frame, J) ->
|
|||||||
|
|
||||||
|
|
||||||
recover(State = #s{frame = Frame, j = J}) ->
|
recover(State = #s{frame = Frame, j = J}) ->
|
||||||
|
case recover(Frame, J) of
|
||||||
|
{ok, Phrase, Mnemonic, Network} ->
|
||||||
|
gmc_con:load_key(Phrase, Mnemonic, Network);
|
||||||
|
mismatch ->
|
||||||
|
ok = zxw:show_message(Frame, J("Password entered incorrectly. Try again.")),
|
||||||
|
recover(State);
|
||||||
|
cancel ->
|
||||||
|
ok
|
||||||
|
end.
|
||||||
|
|
||||||
|
recover(Frame, J) ->
|
||||||
Dialog = wxDialog:new(Frame, ?wxID_ANY, J("Import Account Key")),
|
Dialog = wxDialog:new(Frame, ?wxID_ANY, J("Import Account Key")),
|
||||||
Sizer = wxBoxSizer:new(?wxVERTICAL),
|
Sizer = wxBoxSizer:new(?wxVERTICAL),
|
||||||
|
Network = wxRadioBox:new(Dialog, ?wxID_ANY, J("Network"), {0, 0}, {50, 50}, [J("Mainnet"), J("Testnet")]),
|
||||||
PassSz1 = wxStaticBoxSizer:new(?wxVERTICAL, Dialog, [{label, J("Create Password")}]),
|
PassSz1 = wxStaticBoxSizer:new(?wxVERTICAL, Dialog, [{label, J("Create Password")}]),
|
||||||
PassTx1 = wxTextCtrl:new(Dialog, ?wxID_ANY, [{style, ?wxTE_PASSWORD}]),
|
PassTx1 = wxTextCtrl:new(Dialog, ?wxID_ANY, [{style, ?wxTE_PASSWORD}]),
|
||||||
_ = wxStaticBoxSizer:add(PassSz1, PassTx1, zxw:flags(wide)),
|
_ = wxStaticBoxSizer:add(PassSz1, PassTx1, zxw:flags(wide)),
|
||||||
@ -215,11 +244,13 @@ recover(State = #s{frame = Frame, j = J}) ->
|
|||||||
Cancel = wxButton:new(Dialog, ?wxID_CANCEL),
|
Cancel = wxButton:new(Dialog, ?wxID_CANCEL),
|
||||||
_ = wxBoxSizer:add(ButtSz, Affirm, zxw:flags(wide)),
|
_ = wxBoxSizer:add(ButtSz, Affirm, zxw:flags(wide)),
|
||||||
_ = wxBoxSizer:add(ButtSz, Cancel, zxw:flags(wide)),
|
_ = wxBoxSizer:add(ButtSz, Cancel, zxw:flags(wide)),
|
||||||
|
_ = wxBoxSizer:add(Sizer, Network, zxw:flags(base)),
|
||||||
_ = wxBoxSizer:add(Sizer, PassSz1, zxw:flags(base)),
|
_ = wxBoxSizer:add(Sizer, PassSz1, zxw:flags(base)),
|
||||||
_ = wxBoxSizer:add(Sizer, PassSz2, zxw:flags(base)),
|
_ = wxBoxSizer:add(Sizer, PassSz2, zxw:flags(base)),
|
||||||
_ = wxBoxSizer:add(Sizer, MnemSz, zxw:flags(wide)),
|
_ = wxBoxSizer:add(Sizer, MnemSz, zxw:flags(wide)),
|
||||||
_ = wxBoxSizer:add(Sizer, ButtSz, zxw:flags(base)),
|
_ = wxBoxSizer:add(Sizer, ButtSz, zxw:flags(base)),
|
||||||
ok = wxDialog:setSizer(Dialog, Sizer),
|
ok = wxDialog:setSizer(Dialog, Sizer),
|
||||||
|
ok = wxDialog:setSize(Dialog, {400, 400}),
|
||||||
ok = wxBoxSizer:layout(Sizer),
|
ok = wxBoxSizer:layout(Sizer),
|
||||||
ok = wxFrame:center(Dialog),
|
ok = wxFrame:center(Dialog),
|
||||||
Outcome =
|
Outcome =
|
||||||
@ -229,8 +260,14 @@ recover(State = #s{frame = Frame, j = J}) ->
|
|||||||
Pass2 = wxTextCtrl:getValue(PassTx2),
|
Pass2 = wxTextCtrl:getValue(PassTx2),
|
||||||
case Pass1 =:= Pass2 of
|
case Pass1 =:= Pass2 of
|
||||||
true ->
|
true ->
|
||||||
|
Net =
|
||||||
|
case wxRadioBox:getSelection(Network) of
|
||||||
|
0 -> mainnet;
|
||||||
|
1 -> testnet;
|
||||||
|
_ -> mainnet
|
||||||
|
end,
|
||||||
Mnemonic = wxTextCtrl:getValue(MnemTx),
|
Mnemonic = wxTextCtrl:getValue(MnemTx),
|
||||||
gmc_con:load_key(Pass1, Mnemonic);
|
{ok, Pass1, Mnemonic, Net};
|
||||||
false ->
|
false ->
|
||||||
mismatch
|
mismatch
|
||||||
end;
|
end;
|
||||||
@ -238,15 +275,7 @@ recover(State = #s{frame = Frame, j = J}) ->
|
|||||||
cancel
|
cancel
|
||||||
end,
|
end,
|
||||||
ok = wxDialog:destroy(Dialog),
|
ok = wxDialog:destroy(Dialog),
|
||||||
case Outcome of
|
Outcome.
|
||||||
ok ->
|
|
||||||
ok;
|
|
||||||
mismatch ->
|
|
||||||
ok = zxw:show_message(Frame, J("Password entered incorrectly. Try again.")),
|
|
||||||
recover(State);
|
|
||||||
cancel ->
|
|
||||||
ok
|
|
||||||
end.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
12
zomp.meta
12
zomp.meta
@ -1,11 +1,19 @@
|
|||||||
{name,"GajuMine"}.
|
{name,"GajuMine"}.
|
||||||
{type,gui}.
|
{type,gui}.
|
||||||
{modules,[]}.
|
{modules,[]}.
|
||||||
{author,"Craig Everett"}.
|
|
||||||
{prefix,"gmc"}.
|
{prefix,"gmc"}.
|
||||||
|
{author,"Craig Everett"}.
|
||||||
{desc,"Mining client for the Gajumaru Root"}.
|
{desc,"Mining client for the Gajumaru Root"}.
|
||||||
{package_id,{"qpq","gajumine",{0,1,0}}}.
|
{package_id,{"qpq","gajumine",{0,1,0}}}.
|
||||||
{deps,[{"otpr","hakuzaru",{0,6,1}},
|
{deps,[{"uwiger","gm_mining_pool_protocol",{0,2,0}},
|
||||||
|
{"uwiger","gmmp_client",{0,3,0}},
|
||||||
|
{"uwiger","gproc",{1,0,0}},
|
||||||
|
{"uwiger","enoise",{1,3,0}},
|
||||||
|
{"uwiger","gmminer",{1,0,1}},
|
||||||
|
{"uwiger","gmcuckoo",{1,1,0}},
|
||||||
|
{"uwiger","setup",{2,2,4}},
|
||||||
|
{"uwiger","gmconfig",{0,1,1}},
|
||||||
|
{"otpr","hakuzaru",{0,6,1}},
|
||||||
{"otpr","gajudesk",{0,5,3}},
|
{"otpr","gajudesk",{0,5,3}},
|
||||||
{"otpr","zxwidgets",{1,0,1}},
|
{"otpr","zxwidgets",{1,0,1}},
|
||||||
{"otpr","ec_utils",{1,0,0}},
|
{"otpr","ec_utils",{1,0,0}},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user