This commit is contained in:
Craig Everett 2025-01-05 13:34:56 +09:00
parent e7670411b0
commit 95015eb50c
3 changed files with 86 additions and 17 deletions

View File

@ -13,9 +13,11 @@
-behavior(gen_server). -behavior(gen_server).
-export([show_ui/1, -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/3, import_wallet/3, drop_wallet/2,
selected/1,
password/2, password/2,
refresh/0, refresh/0,
nonce/1, spend/2, chain/1, grids/1, sign_mess/1, sign_tx/1, nonce/1, spend/2, chain/1, grids/1, sign_mess/1, sign_tx/1,
deploy/2,
make_key/6, recover_key/1, mnemonic/1, rename_key/2, drop_key/1, make_key/6, recover_key/1, mnemonic/1, rename_key/2, drop_key/1,
add_node/1, set_sole_node/1]). add_node/1, set_sole_node/1]).
-export([encrypt/2, decrypt/2]). -export([encrypt/2, decrypt/2]).
@ -41,6 +43,7 @@
{version = 1 :: integer(), {version = 1 :: integer(),
window = none :: none | wx:wx_object(), window = none :: none | wx:wx_object(),
tasks = [] :: [#ui{}], tasks = [] :: [#ui{}],
picked = 0 :: non_neg_integer(),
wallet = none :: none | #wallet{}, wallet = none :: none | #wallet{},
pass = none :: none | binary(), pass = none :: none | binary(),
prefs = #{} :: #{module() := term()}, prefs = #{} :: #{module() := term()},
@ -104,6 +107,13 @@ drop_wallet(Path, Delete) ->
gen_server:cast(?MODULE, {drop_wallet, Path, Delete}). gen_server:cast(?MODULE, {drop_wallet, Path, Delete}).
-spec selected(Index) -> ok
when Index :: pos_integer() | none.
selected(Index) ->
gen_server:cast(?MODULE, {selected, Index}).
-spec password(Old, New) -> ok -spec password(Old, New) -> ok
when Old :: none | string(), when Old :: none | string(),
New :: none | string(). New :: none | string().
@ -162,6 +172,17 @@ sign_tx(Request) ->
gen_server:cast(?MODULE, {sign_tx, Request}). gen_server:cast(?MODULE, {sign_tx, Request}).
-spec deploy(Build, InitArgs) -> Result
when Build :: map(),
InitArgs :: [Arg :: string()],
Result :: {ok, TX_Hash :: clutch:id()}
| {error, Reason},
Reason :: term(). % FIXME
deploy(Build, InitArgs) ->
gen_server:call(?MODULE, {deploy, Build, InitArgs}).
-spec make_key(Type, Size, Name, Seed, Encoding, Transform) -> ok -spec make_key(Type, Size, Name, Seed, Encoding, Transform) -> ok
when Type :: {eddsa, ed25519}, when Type :: {eddsa, ed25519},
Size :: 256, Size :: 256,
@ -262,6 +283,7 @@ start_link() ->
init(none) -> init(none) ->
ok = log(info, "Starting"), ok = log(info, "Starting"),
process_flag(sensitive, true),
Prefs = read_prefs(), Prefs = read_prefs(),
GUI_Prefs = maps:get(gmc_gui, Prefs, #{}), GUI_Prefs = maps:get(gmc_gui, Prefs, #{}),
Window = gmc_gui:start_link(GUI_Prefs), Window = gmc_gui:start_link(GUI_Prefs),
@ -304,6 +326,9 @@ handle_call({save, Module, Prefs}, _, State) ->
handle_call({mnemonic, ID}, _, State) -> handle_call({mnemonic, ID}, _, State) ->
Response = do_mnemonic(ID, State), Response = do_mnemonic(ID, State),
{reply, Response, State}; {reply, Response, State};
handle_call({deploy, Build, InitArgs}, _, State) ->
Result = do_deploy(Build, InitArgs, State),
{reply, Result, 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}.
@ -337,6 +362,9 @@ handle_cast({import_wallet, Name, Path, Password}, State) ->
handle_cast({drop_wallet, Path, Delete}, State) -> handle_cast({drop_wallet, Path, Delete}, State) ->
NewState = do_drop_wallet(Path, Delete, State), NewState = do_drop_wallet(Path, Delete, State),
{noreply, NewState}; {noreply, NewState};
handle_cast({selected, Index}, State) ->
NewState = State#s{selected = Index},
{noreply, NewState};
handle_cast({password, Old, New}, State) -> handle_cast({password, Old, New}, State) ->
NewState = do_password(Old, New, State), NewState = do_password(Old, New, State),
{noreply, NewState}; {noreply, NewState};
@ -870,6 +898,43 @@ do_mnemonic(ID, #s{wallet = #wallet{keys = Keys}}) ->
end. end.
do_deploy(Build, InitArgs, #s{selected = Index, wallet = #wallet{keys = Keys}}) ->
#key{pair = #s{public = PubKey, secret := SecKey}} = lists:nth(Index, Keys),
case hz:contract_create_built(PubKey, Build, InitArgs) of
{ok, CreateTX} -> do_deploy2(SecKey, CreateTX);
Error -> Error
end.
do_deploy2(SecKey, CreateTX) ->
case gmc_con:sign(Request) of
{ok, SignedTX} -> do_deploy3(SignedTX);
Error -> Error
end.
do_deploy3(SignedTX) ->
case hz:post_tx(SignedTX) of
{ok, Data = #{"tx_hash" := TXHash}} ->
ok = tell("Contract deploy TX succeded with: ~p", [TXHash]),
do_deploy4(Data);
{ok, WTF} ->
{error, WTF};
Error ->
Error
end.
do_deploy4(#{"tx_hash" := TXHash}) ->
case hz:tx_info(TZHash) of
{ok, {"call_info" := #{"return_type" := "ok", "contract_id" := ConID}}} ->
{contract_id, ConID};
{error, "Tx not mined"} ->
{tx_hash, TXHash};
{ok, Reason = {"call_info" := #{"return_type" := "revert"}}} ->
{error, Reason};
Error ->
Error
end.
do_rename_key(ID, NewName, State = #s{wallet = W}) -> do_rename_key(ID, NewName, State = #s{wallet = W}) ->
#wallet{poas = POAs, keys = Keys} = W, #wallet{poas = POAs, keys = Keys} = W,
A = lists:keyfind(ID, #poa.id, POAs), A = lists:keyfind(ID, #poa.id, POAs),

View File

@ -863,10 +863,12 @@ do_selection(Selected,
State = #s{prefs = Prefs, accounts = Accounts, State = #s{prefs = Prefs, accounts = Accounts,
balance = {_, #w{wx = B}}, id = {_, #w{wx = I}}}) balance = {_, #w{wx = B}}, id = {_, #w{wx = I}}})
when Selected < length(Accounts) -> when Selected < length(Accounts) ->
#poa{id = ID, balances = Balances} = lists:nth(Selected + 1, Accounts), OneBasedIndex = Selected + 1,
#poa{id = ID, balances = Balances} = lists:nth(OneBasedIndex, Accounts),
[#balance{total = Pucks}] = Balances, [#balance{total = Pucks}] = Balances,
ok = wxStaticText:setLabel(I, ID), ok = wxStaticText:setLabel(I, ID),
ok = wxStaticText:setLabel(B, price_to_string(Pucks)), ok = wxStaticText:setLabel(B, price_to_string(Pucks)),
ok = gmc_con:selected(OneBasedIndex),
NewPrefs = maps:put(selected, Selected, Prefs), NewPrefs = maps:put(selected, Selected, Prefs),
State#s{prefs = NewPrefs}; State#s{prefs = NewPrefs};
do_selection(_, State) -> do_selection(_, State) ->

View File

@ -242,7 +242,7 @@ handle_event(E = #wx{event = #wxCommand{type = command_button_clicked},
#w{name = open} -> open_file(State); #w{name = open} -> open_file(State);
#w{name = close} -> close_file(State); #w{name = close} -> close_file(State);
#w{name = compile} -> compile(State); #w{name = compile} -> compile(State);
#w{name = Name} -> clicked(State, Name); #w{name = Name, wx = Button} -> clicked(State, Name, Button);
undefined -> undefined ->
tell("Received message: ~w", [E]), tell("Received message: ~w", [E]),
State State
@ -279,30 +279,32 @@ terminate(Reason, State) ->
%%% Doers %%% Doers
clicked(State = #s{book = {Notebook, Pages}}, Name) -> clicked(State = #s{book = {Notebook, Pages}}, Name, Button) ->
case wxNotebook:getSelection(Notebook) of case wxNotebook:getSelection(Notebook) of
?wxNOT_FOUND -> ?wxNOT_FOUND ->
ok = tell("Inconcievable! No notebook page is selected!"),
State; State;
Index -> Index ->
Page = lists:nth(Index + 1, Pages), Page = lists:nth(Index + 1, Pages),
clicked(State, Page, Name) clicked(State, Page, Name, Button)
end. end.
clicked(State, #p{instances = Is, funs = {_, Funs}, builds = Builds}, {<<"init">>, call}) -> clicked(State, #p{instances = Is, funs = {_, Funs}, builds = Builds}, {<<"init">>, call}) ->
BuildLabel = wxChoice:getStringSelection(Is), Label = wxChoice:getStringSelection(Is),
Build = maps:get(BuildLabel, Builds), Build = maps:get(Label, Builds),
#f{args = Args} = lists:keyfind(<<"init">>, #f.name, Funs), #f{args = Args} = lists:keyfind(<<"init">>, #f.name, Funs),
InitArgs = lists:map(fun get_arg/1, Args), InitArgs = lists:map(fun get_arg/1, Args),
ok = tell("BuildLabel: ~p~nArgs: ~p~nInitArgs: ~p", [BuildLabel, Args, InitArgs]), ok = tell("Label: ~p~nArgs: ~p~nInitArgs: ~p", [Label, Args, InitArgs]),
% contract_create_built( case gmc_con:deploy(Build, InitArgs) of
State; {contract_id, ConID} ->
{tx_hash, TX_Hash} ->
{error, Reason} ->
ok = tell("Deploy failed with: ~p", [Reason])
State
clicked(State, Page, Name) -> clicked(State, Page, Name) ->
ok = tell("Button: ~p~nPage: ~p", [Name, Page]), ok = tell("Button: ~p~nPage: ~p", [Name, Page]),
State. State.
get_arg({_, InputField, _}) ->
wxTextCtrl:getValue(InputField).
new_file(State = #s{frame = Frame, j = J, prefs = Prefs}) -> new_file(State = #s{frame = Frame, j = J, prefs = Prefs}) ->
DefaultDir = DefaultDir =