Default walletses

This commit is contained in:
2025-05-20 17:31:09 +09:00
parent 09d31e74e5
commit 88b2e986b7
14 changed files with 129 additions and 68 deletions
+1 -1
View File
@@ -3,7 +3,7 @@
%%% @end
-module(gajudesk).
-vsn("0.6.2").
-vsn("0.6.3").
-behavior(application).
-author("Craig Everett <craigeverett@qpq.swiss>").
-copyright("QPQ AG <info@qpq.swiss>").
+51 -25
View File
@@ -3,14 +3,14 @@
%%% @end
-module(gd_con).
-vsn("0.6.2").
-vsn("0.6.3").
-author("Craig Everett <craigeverett@qpq.swiss>").
-copyright("QPQ AG <info@qpq.swiss>").
-license("GPL-3.0-or-later").
-behavior(gen_server).
-export([show_ui/1,
open_wallet/2, close_wallet/0, new_wallet/3, import_wallet/3, drop_wallet/2,
open_wallet/2, close_wallet/0, new_wallet/4, import_wallet/3, drop_wallet/2,
selected/1, network/0,
password/2,
refresh/0,
@@ -80,13 +80,14 @@ close_wallet() ->
gen_server:cast(?MODULE, close_wallet).
-spec new_wallet(Name, Path, Password) -> ok
when Name :: string(),
-spec new_wallet(Net, Name, Path, Password) -> ok
when Net :: mainnet | testnet | devnet,
Name :: string(),
Path :: string(),
Password :: string().
new_wallet(Name, Path, Password) ->
gen_server:cast(?MODULE, {new_wallet, Name, Path, Password}).
new_wallet(Net, Name, Path, Password) ->
gen_server:cast(?MODULE, {new_wallet, Net, Name, Path, Password}).
-spec import_wallet(Name, Path, Password) -> ok
@@ -332,10 +333,8 @@ init(none) ->
read_prefs() ->
case file:consult(prefs_path()) of
{ok, Prefs} ->
proplists:to_map(Prefs);
_ ->
#{gd_v_wallman => #{geometry => {582,335,500,300}}}
{ok, Prefs} -> proplists:to_map(Prefs);
_ -> #{}
end.
@@ -399,8 +398,8 @@ handle_cast(close_wallet, State) ->
ok = gd_gui:show([]),
NewState = do_show_ui(gd_v_wallman, NextState),
{noreply, NewState};
handle_cast({new_wallet, Name, Path, Password}, State) ->
NewState = do_new_wallet(Name, Path, Password, State),
handle_cast({new_wallet, Net, Name, Path, Password}, State) ->
NewState = do_new_wallet(Net, Name, Path, Password, State),
{noreply, NewState};
handle_cast({import_wallet, Name, Path, Password}, State) ->
NewState = do_import_wallet(Name, Path, Password, State),
@@ -532,6 +531,7 @@ do_show_ui(Name, State = #s{tasks = Tasks, prefs = Prefs}) ->
Win = Name:start_link({TaskPrefs, TaskData}),
PID = wx_object:get_pid(Win),
Mon = monitor(process, PID),
ok = Name:to_front(Win),
UI = #ui{name = Name, pid = PID, wx = Win, mon = Mon},
State#s{tasks = [UI | Tasks]}
end.
@@ -561,12 +561,15 @@ do_add_node(New, State) ->
do_set_sole_node(TOTN = #node{external = none}, State) ->
do_set_sole_node(TOTN#node{external = 3013}, State);
do_set_sole_node(New = #node{ip = IP, external = Port}, State = #s{wallet = W}) ->
do_set_sole_node(New = #node{ip = IP, external = Port}, State = #s{wallet = W, wallets = Ws, pass = Pass}) ->
ok = hz:chain_nodes([{IP, Port}]),
case ensure_hz_set(New) of
{ok, ChainID} ->
#wallet{name = Name} = W,
RW = lists:keyfind(Name, #wr.name, Ws),
Net = #net{id = ChainID, chains = [#chain{id = ChainID, nodes = [New]}]},
NewWallet = W#wallet{chain_id = ChainID, endpoint = New, nets = [Net]},
ok = save_wallet(RW, Pass, NewWallet),
NewState = State#s{wallet = NewWallet},
do_refresh(NewState);
Error ->
@@ -982,22 +985,26 @@ do_deploy3(#{"tx_hash" := TXHash}) ->
end.
do_rename_key(ID, NewName, State = #s{wallet = W}) ->
#wallet{poas = POAs, keys = Keys} = W,
do_rename_key(ID, NewName, State = #s{wallet = W, wallets = Wallets, pass = Pass}) ->
#wallet{name = Name, poas = POAs, keys = Keys} = W,
RW = lists:keyfind(Name, #wr.name, Wallets),
A = lists:keyfind(ID, #poa.id, POAs),
K = lists:keyfind(ID, #key.id, Keys),
NewPOAs = lists:keystore(ID, #poa.id, POAs, A#poa{name = NewName}),
NewKeys = lists:keystore(ID, #key.id, Keys, K#key{name = NewName}),
NewWallet = W#wallet{poas = NewPOAs, keys = NewKeys},
ok = save_wallet(RW, Pass, NewWallet),
ok = gd_gui:show(NewPOAs),
State#s{wallet = NewWallet}.
do_drop_key(ID, State = #s{wallet = W}) ->
#wallet{poas = POAs, keys = Keys} = W,
do_drop_key(ID, State = #s{wallet = W, wallets = Wallets, pass = Pass}) ->
#wallet{name = Name, poas = POAs, keys = Keys} = W,
RW = lists:keyfind(Name, #wr.name, Wallets),
NewPOAs = lists:keydelete(ID, #poa.id, POAs),
NewKeys = lists:keydelete(ID, #key.id, Keys),
NewWallet = W#wallet{poas = NewPOAs, keys = NewKeys},
ok = save_wallet(RW, Pass, NewWallet),
ok = gd_gui:show(NewPOAs),
State#s{wallet = NewWallet}.
@@ -1022,12 +1029,25 @@ do_open_wallet(Path, Phrase, State) ->
default_wallet() ->
DevNet = #net{id = <<"devnet">>, chains = [#chain{}]},
% TestChain1 = #chain{id = <<"groot.testnet">>,
% nodes = [#node{ip = {1,2,3,4}}, #node{ip = {5,6,7,8}}]},
% TestChain2 = #chain{id = <<"test_ac.testnet">>,
% nodes = [#node{ip = {11,12,13,14}}, #node{ip = {15,16,17,18}}]},
% TestNet = #net{id = <<"testnet">>, chains = [TestChain1, TestChain2]},
default_wallet(testnet).
default_wallet(mainnet) ->
Node = #node{ip = "groot.mainnet.gajumaru.io"},
Groot = #chain{id = <<"groot.mainnet">>,
nodes = [Node]},
MainNet = #net{id = <<"mainnet">>, chains = [Groot]},
#wallet{nets = [MainNet], endpoint = Node};
default_wallet(testnet) ->
Node = #node{ip = "groot.testnet.gajumaru.io"},
Groot = #chain{id = <<"groot.testnet">>,
nodes = [Node]},
TestNet = #net{id = <<"testnet">>, chains = [Groot]},
#wallet{nets = [TestNet], endpoint = Node};
default_wallet(devnet) ->
% TODO: This accounts for the nature of devnets by defining *no* chains.
% The GUI/CON will need to manage this properly when encountered and prompt.
DevNet = #net{id = <<"devnet">>,
chains = []},
#wallet{nets = [DevNet]}.
@@ -1071,17 +1091,23 @@ do_stop(State = #s{prefs = Prefs}) ->
NewState.
do_new_wallet(Name, Path, Password, State = #s{wallets = Wallets, prefs = Prefs}) ->
do_new_wallet(Net, Name, Path, Password, State = #s{wallets = Wallets, prefs = Prefs}) ->
case lists:keyfind(Name, #wr.name, Wallets) of
false ->
NextState = do_close_wallet(State),
Pass = pass(Password),
HasPass = Pass =/= none,
Entry = #wr{name = Name, path = Path, pass = HasPass},
New = #wallet{name = Name},
DW = #wallet{endpoint = Node} = default_wallet(Net),
New = DW#wallet{name = Name},
ok = save_wallet(Entry, Pass, New),
ok = gd_gui:show([]),
ok = gd_gui:wallet(Name),
ok =
case ensure_hz_set(Node) of
{ok, ChainID} -> gd_gui:chain(ChainID, Node);
Error -> gd_gui:trouble(Error)
end,
NewWallets = [Entry | Wallets],
NewPrefs = put_prefs(wallets, NewWallets, Prefs),
ok = persist(NewPrefs),
+1 -1
View File
@@ -37,7 +37,7 @@
%%% @end
-module(gd_grids).
-vsn("0.6.2").
-vsn("0.6.3").
-author("Craig Everett <craigeverett@qpq.swiss>").
-copyright("QPQ AG <info@qpq.swiss>").
-license("GPL-3.0-or-later").
+1 -1
View File
@@ -3,7 +3,7 @@
%%% @end
-module(gd_gui).
-vsn("0.6.2").
-vsn("0.6.3").
-author("Craig Everett <craigeverett@qpq.swiss>").
-copyright("QPQ AG <info@qpq.swiss>").
-license("GPL-3.0-or-later").
+1 -1
View File
@@ -15,7 +15,7 @@
%%% translation library is retained).
-module(gd_jt).
-vsn("0.6.2").
-vsn("0.6.3").
-export([read_translations/1, j/2, oneshot_j/2]).
+1 -1
View File
@@ -1,5 +1,5 @@
-module(gd_sophia_editor).
-vsn("0.6.2").
-vsn("0.6.3").
-export([new/1, update/2,
get_text/1, set_text/2]).
+1 -1
View File
@@ -12,7 +12,7 @@
%%% @end
-module(gd_sup).
-vsn("0.6.2").
-vsn("0.6.3").
-behaviour(supervisor).
-author("Craig Everett <craigeverett@qpq.swiss>").
-copyright("QPQ AG <info@qpq.swiss>").
+1 -1
View File
@@ -1,5 +1,5 @@
-module(gd_v).
-vsn("0.6.2").
-vsn("0.6.3").
-author("Craig Everett <craigeverett@qpq.swiss>").
-copyright("QPQ AG <info@qpq.swiss>").
-license("GPL-3.0-or-later").
+1 -1
View File
@@ -1,5 +1,5 @@
-module(gd_v_devman).
-vsn("0.6.2").
-vsn("0.6.3").
-author("Craig Everett <craigeverett@qpq.swiss>").
-copyright("QPQ AG <info@qpq.swiss>").
-license("GPL-3.0-or-later").
+1 -1
View File
@@ -1,5 +1,5 @@
-module(gd_v_netman).
-vsn("0.6.2").
-vsn("0.6.3").
-author("Craig Everett <zxq9@zxq9.com>").
-copyright("QPQ AG <info@qpq.swiss>").
-license("GPL-3.0-or-later").
+41 -6
View File
@@ -1,5 +1,5 @@
-module(gd_v_wallman).
-vsn("0.6.2").
-vsn("0.6.3").
-author("Craig Everett <zxq9@zxq9.com>").
-copyright("QPQ AG <info@qpq.swiss>").
-license("GPL-3.0-or-later").
@@ -89,12 +89,34 @@ init({Prefs, Manifest}) ->
ok = wxFrame:setSizer(Frame, MainSz),
ok = wxSizer:layout(MainSz),
ok = gd_v:safe_size(Frame, Prefs),
NewPrefs =
case maps:is_key(geometry, Prefs) of
true ->
Prefs;
false ->
Display = wxDisplay:new(),
{_, _, W, H} = wxDisplay:getGeometry(Display),
ok = wxDisplay:destroy(Display),
WW = 500,
WH = 350,
X = (W div 2) - (WW div 2),
Y = (H div 2) - (WH div 2),
Prefs#{geometry => {X, Y, WW, WH}}
end,
ok = gd_v:safe_size(Frame, NewPrefs),
ok = wxFrame:connect(Frame, command_button_clicked),
ok = wxFrame:connect(Frame, close_window),
true = wxFrame:show(Frame),
ok = wxListBox:connect(Picker, command_listbox_doubleclicked),
ok =
case length(Manifest) =:= 0 of
false ->
ok;
true ->
self() ! new,
ok
end,
State = #s{wx = Wx, frame = Frame, lang = Lang, j = J, prefs = Prefs,
wallets = Manifest,
picker = Picker,
@@ -121,6 +143,9 @@ handle_cast(Unexpected, State) ->
{noreply, State}.
handle_info(new, State) ->
NewState = do_new(State),
{noreply, NewState};
handle_info(Unexpected, State) ->
ok = log(warning, "Unexpected info: ~tp~n", [Unexpected]),
{noreply, State}.
@@ -252,6 +277,7 @@ do_new(State = #s{frame = Frame, j = J, prefs = Prefs}) ->
{defaultDir, DefaultDir},
{defaultFile, "default.gaju"},
{wildCard, "*.gaju"},
{sz, {300, 270}},
{style, ?wxFD_SAVE bor ?wxFD_OVERWRITE_PROMPT}],
Dialog = wxFileDialog:new(Frame, Options),
case wxFileDialog:showModal(Dialog) of
@@ -276,6 +302,7 @@ do_new2(Path, J, Frame) ->
Dialog = wxDialog:new(Frame, ?wxID_ANY, J("New Wallet"), [{size, {400, 250}}]),
Sizer = wxBoxSizer:new(?wxVERTICAL),
Network = wxRadioBox:new(Dialog, ?wxID_ANY, J("Network"), {0, 0}, {50, 50}, [J("Mainnet"), J("Testnet")]),
NameSz = wxStaticBoxSizer:new(?wxVERTICAL, Dialog, [{label, J("Name")}]),
NameTx = wxTextCtrl:new(Dialog, ?wxID_ANY),
_ = wxSizer:add(NameSz, NameTx, zxw:flags(wide)),
@@ -294,12 +321,14 @@ do_new2(Path, J, Frame) ->
_ = wxBoxSizer:add(ButtSz, Affirm, zxw:flags(wide)),
_ = wxBoxSizer:add(ButtSz, Cancel, zxw:flags(wide)),
_ = wxBoxSizer:add(Sizer, Network, zxw:flags(base)),
_ = wxSizer:add(Sizer, NameSz, zxw:flags(base)),
_ = wxSizer:add(Sizer, PassSz, zxw:flags(base)),
_ = wxSizer:add(Sizer, PassConSz, zxw:flags(base)),
_ = wxSizer:add(Sizer, ButtSz, zxw:flags(wide)),
ok = wxDialog:setSizer(Dialog, Sizer),
ok = wxDialog:setSize(Dialog, {300, 270}),
ok = wxBoxSizer:layout(Sizer),
ok = wxDialog:center(Dialog),
ok = wxStyledTextCtrl:setFocus(NameTx),
@@ -307,6 +336,12 @@ do_new2(Path, J, Frame) ->
Result =
case wxDialog:showModal(Dialog) of
?wxID_OK ->
Net =
case wxRadioBox:getSelection(Network) of
0 -> mainnet;
1 -> testnet;
_ -> mainnet
end,
Name =
case wxTextCtrl:getValue(NameTx) of
"" -> Path;
@@ -318,17 +353,17 @@ do_new2(Path, J, Frame) ->
{P, P} -> P;
{_, _} -> bad
end,
do_new3(Name, Path, Pass);
do_new3(Net, Name, Path, Pass);
?wxID_CANCEL ->
abort
end,
ok = wxDialog:destroy(Dialog),
Result.
do_new3(_, _, bad) ->
do_new3(_, _, _, bad) ->
abort;
do_new3(Name, Path, Pass) ->
gd_con:new_wallet(Name, Path, Pass).
do_new3(Net, Name, Path, Pass) ->
gd_con:new_wallet(Net, Name, Path, Pass).
do_import(State = #s{frame = Frame, j = J, prefs = Prefs}) ->