From 2a52516fd3c2ec27db7ca6ae417af8e6d8678393 Mon Sep 17 00:00:00 2001 From: Craig Everett Date: Tue, 5 May 2026 13:47:38 +0900 Subject: [PATCH] WIP --- src/gd_v_call.erl | 186 +++++++++++++++++++++++++++------------------- 1 file changed, 109 insertions(+), 77 deletions(-) diff --git a/src/gd_v_call.erl b/src/gd_v_call.erl index 1f8b4e0..206b5db 100644 --- a/src/gd_v_call.erl +++ b/src/gd_v_call.erl @@ -29,20 +29,15 @@ args = [] :: [#w{}], kp = #w{} :: #w{}, params = [] :: [param()], - ttl = #w{} :: #w{}, - gasprice = #w{} :: #w{}, - gas = #w{} :: #w{}, - amount = #w{} :: #w{}, + return = #w{} :: #w{}, % wxTextCtrl, single-line + copy = #w{} :: #w{}, status = none :: status(), action = #w{} :: #w{}, tx_data = none :: none | map(), tx_info = none :: none | map(), - hash = #w{} :: #w{}, % wxTextCtrl, single-line - info = #w{} :: #w{}, % wxTextCtrl, multi-line - out = #w{} :: #w{}, - copy = #w{} :: #w{}}). + hash = #w{} :: #w{}, % wxTextCtrl, single-line + info = #w{} :: #w{}}). % wxTextCtrl, multi-line -show_the_amount_value() -> -type fun_name() :: string(). -type fun_type() :: call | dryr | init. @@ -75,7 +70,7 @@ tx_hash(Win) -> when Win :: pid() | wx:wx_object(), Result :: none | map(). -tx_hash(Win) -> +tx_data(Win) -> wx_object:call(Win, tx_data). @@ -83,7 +78,7 @@ tx_hash(Win) -> when Win :: pid() | wx:wx_object(), Result :: none | map(). -tx_hash(Win) -> +tx_info(Win) -> wx_object:call(Win, tx_info). @@ -100,48 +95,40 @@ init({Prefs, FunDef = {FunName, FunType}, ConID, Build, Selected, Keys}) -> J = gd_jt:j(Lang, Trans), {aaci, ConName, FunSpecs, _} = maps:get(aaci, Build), FunSpec = maps:get(FunName, FunSpecs), - {CallType, ActionLabel} = + {CallTypeLabel, ActionLabel} = case FunType of call -> {J("Contract Call"), J("Submit Call")}; dryr -> {J("Dry Run"), J("Submit Dry Run")}; init -> {J("Deploy"), J("Deploy")} end, Arity = integer_to_list(length(element(1, FunSpec))), - Title = [CallType, ": ", ConName, ".", FunName, "/", Arity], + Title = [CallTypeLabel, ": ", ConName, ".", FunName, "/", Arity], Wx = wx:new(), Frame = wxFrame:new(Wx, ?wxID_ANY, Title), MainSz = wxBoxSizer:new(?wxVERTICAL), KeySz = wxStaticBoxSizer:new(?wxVERTICAL, Frame, [{label, J("Signature Key")}]), - KeyPicker = wxChoice:new(Frame, ?wxID_ANY, [{choices, Keys}]), + KeyBox = wxStaticBoxSizer:getStaticBox(KeySz), + KeyPicker = wxChoice:new(KeyBox, ?wxID_ANY, [{choices, Keys}]), KP = #w{name = key_picker, id = wxChoice:getId(KeyPicker), wx = KeyPicker}, ZeroBasedSelected = Selected - 1, ok = wxChoice:setSelection(KeyPicker, ZeroBasedSelected), _ = wxStaticBoxSizer:add(KeySz, KeyPicker, zxw:flags(wide)), - {ArgSz, Args, HasArgs} = call_arg_sizer(Frame, J, FunSpec), + {ArgSz, Args, Return, Copy, HasArgs} = call_arg_sizer(Frame, J, FunType, FunSpec), {ParamSz, Params} = call_param_sizer(Frame, J), Action = #w{wx = ActionBn} = gd_lib:button(Frame, ActionLabel), TX_Sz = wxStaticBoxSizer:new(?wxVERTICAL, Frame, [{label, J("Transaction Info")}]), TX_Sz_Box = wxStaticBoxSizer:getStaticBox(TX_Sz), - TxStyle = [{style, ?wxTE_READONLY}], - TX_Data = #w{wx = DataT} = gd_lib:mono_text(TX_Sz_Box, tx_data, "", TxStyle), - TX_Hash = #w{wx = HashT} = gd_lib:mono_text(TX_Sz_Box, tx_hash, "", TxStyle), - TX_Info = #w{wx = InfoT} = gd_lib:mono_text(TX_Sz_Box, tx_info, "", TxStyle), + Single = [{style, ?wxTE_READONLY}], + Multi = [{style, ?wxTE_MULTILINE bor ?wxTE_READONLY}], + TX_Hash = #w{wx = HashT} = gd_lib:mono_text(TX_Sz_Box, tx_hash, "", Single), + TX_Info = #w{wx = InfoT} = gd_lib:mono_text(TX_Sz_Box, tx_info, "", Multi), - Line = wxStaticLine:new(TX_Sz_Box, [{style, ?wxLI_HORIZONTAL}]), - OutStyle = [{style, ?wxTE_MULTILINE bor ?wxTE_READONLY}], - Out = #w{wx = OutTxt} = gd_lib:mono_text(TX_Sz_Box, out, "", OutStyle), - Copy = #w{wx = CopyBn} = gd_lib:button(TX_Sz_Box, J("Copy")), - - _ = wxStaticBoxSizer:add(TX_Sz, DataT, zxw:flags({base, 5})), - _ = wxStaticBoxSizer:add(TX_Sz, HashT, zxw:flags({base, 5})), - _ = wxStaticBoxSizer:add(TX_Sz, InfoT, zxw:flags({base, 5})), - _ = wxStaticBoxSizer:add(TX_Sz, Line, zxw:flags({base, 5})), - _ = wxStaticBoxSizer:add(TX_Sz, OutTxt, zxw:flags({wide, 5})), - _ = wxStaticBoxSizer:add(TX_Sz, CopyBn, zxw:flags({base, 5})), + _ = wxStaticBoxSizer:add(TX_Sz, HashT, zxw:flags({base, 5})), + _ = wxStaticBoxSizer:add(TX_Sz, InfoT, zxw:flags({base, 5})), ArgSzArgs = case HasArgs of @@ -152,7 +139,7 @@ init({Prefs, FunDef = {FunName, FunType}, ConID, Build, Selected, Keys}) -> _ = wxSizer:add(MainSz, KeySz, zxw:flags({base, 5})), _ = wxSizer:add(MainSz, ParamSz, zxw:flags({base, 5})), _ = wxSizer:add(MainSz, ActionBn, zxw:flags({base, 5})), - _ = wxSizer:add(MainSz, TX_Sz, zxw:flags({wide, 5})), + _ = wxSizer:add(MainSz, TX_Sz, zxw:flags({base, 5})), _ = wxFrame:setSizer(Frame, MainSz), _ = wxFrame:setSize(Frame, {900, 900}), @@ -161,34 +148,37 @@ init({Prefs, FunDef = {FunName, FunType}, ConID, Build, Selected, Keys}) -> ok = wxFrame:connect(Frame, command_button_clicked), true = wxFrame:show(Frame), State = - #s{wx = Wx, frame = Frame, j = J, prefs = Prefs, - fundef = FunDef, con_id = ConID, build = Build, - args = Args, kp = KP, params = Params, - action = Action, status = none, - tx_data = TX_Data, tx_hash = TX_Hash, tx_info = TX_Info, - out = Out, copy = Copy}, + #s{wx = Wx, frame = Frame, j = J, prefs = Prefs, + fundef = FunDef, con_id = ConID, build = Build, + args = Args, kp = KP, params = Params, + return = Return, copy = Copy, + action = Action, status = none, + hash = TX_Hash, info = TX_Info}, {Frame, State}. -call_arg_sizer(Frame, J, {CallArgs, ReturnType}) -> +call_arg_sizer(Frame, J, {CallArgs, FunType, ReturnType}) -> SpecSz = wxStaticBoxSizer:new(?wxVERTICAL, Frame, [{label, J("Function Spec")}]), - {CallSz, CallControls, HasArgs} = call_sizer(Frame, J, CallArgs), - ReturnSz = return_sizer(Frame, J, ReturnType), + SpecBox = wxStaticBoxSizer:getStaticBox(SpecSz), + {CallSz, CallControls, HasArgs} = call_sizer(SpecBox, J, CallArgs), + {ReturnSz, Return, Copy} = return_sizer(SpecBox, J, FunType, ReturnType), _ = wxStaticBoxSizer:add(SpecSz, CallSz, zxw:flags({wide, 5})), _ = wxStaticBoxSizer:add(SpecSz, ReturnSz, zxw:flags({base, 5})), - {SpecSz, CallControls, HasArgs}. + {SpecSz, CallControls, Return, Copy, HasArgs}. -call_sizer(Frame, J, []) -> - CallSz = wxStaticBoxSizer:new(?wxVERTICAL, Frame, [{label, J("Call Args")}]), - Args = wxStaticText:new(Frame, ?wxID_ANY, ["[", J("No Args"), "]"]), +call_sizer(Parent, J, []) -> + CallSz = wxStaticBoxSizer:new(?wxVERTICAL, Parent, [{label, J("Call Args")}]), + CallBox = wxStaticBoxSizer:getStaticBox(CallSz), + Args = wxStaticText:new(CallBox, ?wxID_ANY, ["[", J("No Args"), "]"]), _ = wxStaticBoxSizer:add(CallSz, Args, zxw:flags({wide, 5})), {CallSz, [], false}; -call_sizer(Frame, J, CallArgs) -> - ScrollWin = wxScrolledWindow:new(Frame), +call_sizer(Parent, J, CallArgs) -> + CallSz = wxStaticBoxSizer:new(?wxVERTICAL, Parent, [{label, J("Call Args")}]), + CallBox = wxStaticBoxSizer:getStaticBox(CallSz), + ScrollWin = wxScrolledWindow:new(CallBox), ScrollSz = wxBoxSizer:new(?wxVERTICAL), ok = wxScrolledWindow:setSizerAndFit(ScrollWin, ScrollSz), ok = wxScrolledWindow:setScrollRate(ScrollWin, 5, 5), - CallSz = wxStaticBoxSizer:new(?wxVERTICAL, Frame, [{label, J("Call Args")}]), GridSz = wxFlexGridSizer:new(2, [{gap, {4, 4}}]), ok = wxFlexGridSizer:setFlexibleDirection(GridSz, ?wxHORIZONTAL), ok = wxFlexGridSizer:addGrowableCol(GridSz, 1), @@ -197,20 +187,30 @@ call_sizer(Frame, J, CallArgs) -> AddArg = fun({Name, Type}) -> L = wxStaticText:new(ScrollWin, ?wxID_ANY, [Name, " : ", textify(Type)]), - C = wxTextCtrl:new(ScrollWin, ?wxID_ANY), + C = #w{wx = T} = gd_lib:mono_text(ScrollWin, Name), _ = wxFlexGridSizer:add(GridSz, L, zxw:flags({base, 5})), - _ = wxFlexGridSizer:add(GridSz, C, zxw:flags({wide, 5})), - #w{name = Name, id = wxTextCtrl:getId(C), wx = C} + _ = wxFlexGridSizer:add(GridSz, T, zxw:flags({wide, 5})), + C end, Controls = lists:map(AddArg, CallArgs), {CallSz, Controls, true}. -return_sizer(Frame, J, ReturnType) -> - ReturnSz = wxStaticBoxSizer:new(?wxVERTICAL, Frame, [{label, J("Return Type")}]), +return_sizer(Parent, J, FunType, ReturnType) -> + TypeLabel = + case FunType =:= init of + false -> textify(ReturnType); + true -> J("Contract Address") + end, + ReturnSz = wxStaticBoxSizer:new(?wxVERTICAL, Parent, [{label, J("Return Type")}]), ReturnSzBox = wxStaticBoxSizer:getStaticBox(ReturnSz), - Return = wxStaticText:new(ReturnSzBox, ?wxID_ANY, textify(ReturnType)), - _ = wxStaticBoxSizer:add(ReturnSz, Return, zxw:flags({wide, 5})), - ReturnSz. + ReturnLabel = wxStaticText:new(ReturnSzBox, ?wxID_ANY, TypeLabel), + Single = [{style, ?wxTE_READONLY}], + Return = #w{wx = ReturnTx} = gd_lib:mono_text(ReturnSzBox, return, "", Single), + Copy = #w{wx = CopyBn} = gd_lib:button(ReturnSzBox, J("Copy")), + _ = wxStaticBoxSizer:add(ReturnSz, ReturnLabel, zxw:flags({wide, 5})), + _ = wxStaticBoxSizer:add(ReturnSz, ReturnTx, zxw:flags({wide, 5})), + _ = wxStaticBoxSizer:add(ReturnSz, CopyBn, zxw:flags({wide, 5})), + {ReturnSz, Return, Copy}. call_param_sizer(Frame, J) -> @@ -220,20 +220,21 @@ call_param_sizer(Frame, J) -> DefGas = 5000000, DefAmount = 0, ParamSz = wxStaticBoxSizer:new(?wxVERTICAL, Frame, [{label, J("TX Parameters")}]), + ParamBox = wxStaticBoxSizer:getStaticBox(ParamSz), GridSz = wxFlexGridSizer:new(2, 4, 4), ok = wxFlexGridSizer:setFlexibleDirection(GridSz, ?wxHORIZONTAL), ok = wxFlexGridSizer:addGrowableCol(GridSz, 1), - TTL_L = wxStaticText:new(Frame, ?wxID_ANY, "TTL"), - TTL_T = wxTextCtrl:new(Frame, ?wxID_ANY), + TTL_L = wxStaticText:new(ParamBox, ?wxID_ANY, "TTL"), + TTL_T = wxTextCtrl:new(ParamBox, ?wxID_ANY), ok = wxTextCtrl:setValue(TTL_T, integer_to_list(DefTTL)), - Gas_L = wxStaticText:new(Frame, ?wxID_ANY, J("Gas")), - Gas_T = wxTextCtrl:new(Frame, ?wxID_ANY), + Gas_L = wxStaticText:new(ParamBox, ?wxID_ANY, J("Gas")), + Gas_T = wxTextCtrl:new(ParamBox, ?wxID_ANY), ok = wxTextCtrl:setValue(Gas_T, integer_to_list(DefGas)), - GasP_L = wxStaticText:new(Frame, ?wxID_ANY, J("Gas Price")), - GasP_T = wxTextCtrl:new(Frame, ?wxID_ANY), + GasP_L = wxStaticText:new(ParamBox, ?wxID_ANY, J("Gas Price")), + GasP_T = wxTextCtrl:new(ParamBox, ?wxID_ANY), ok = wxTextCtrl:setValue(GasP_T, integer_to_list(DefGasP)), - Amount_L = wxStaticText:new(Frame, ?wxID_ANY, J("TX Amount")), - Amount_T = wxTextCtrl:new(Frame, ?wxID_ANY), + Amount_L = wxStaticText:new(ParamBox, ?wxID_ANY, J("TX Amount")), + Amount_T = wxTextCtrl:new(ParamBox, ?wxID_ANY), ok = wxTextCtrl:setValue(Amount_T, integer_to_list(DefAmount)), _ = wxFlexGridSizer:add(GridSz, TTL_L, zxw:flags({base, 5})), _ = wxFlexGridSizer:add(GridSz, TTL_T, zxw:flags({wide, 5})), @@ -252,7 +253,8 @@ call_param_sizer(Frame, J) -> {ParamSz, Params}. -handle_call(tx_hash, _, State = #s{tx_hash = TXHash}) -> +handle_call(tx_hash, _, State) -> + TXHash = do_tx_hash(State), {reply, TXHash, State}; handle_call(tx_data, _, State = #s{tx_data = TXData}) -> {reply, TXData, State}; @@ -308,6 +310,12 @@ handle_troubling(State = #s{frame = Frame}, Info) -> State. +do_tx_hash(#s{tx_data = #{"tx_hash" := TXHash}}) -> + TXHash; +do_tx_hash(#s{tx_data = none}) -> + none. + + prep_call(State) -> case gd_con:chain_id() of {ok, ChainID} -> prep_call2(State, ChainID); @@ -315,14 +323,12 @@ prep_call(State) -> end. prep_call2(State, ChainID) -> - tell(info, "ChainID: ~p", [ChainID]), case params(State) of {ok, Params} -> prep_call3(State, ChainID, Params); Error -> handle_troubling(State, Error) end. prep_call3(State, ChainID, Params) -> - tell(info, "Params: ~p", [Params]), case args(State) of {ok, Args} -> prep_call4(State, ChainID, Params, {sophia, Args}); Error -> handle_troubling(State, Error) @@ -382,10 +388,13 @@ deploy(State, ChainID, CallerID, CreateTX) -> Error -> handle_troubling(State, Error) end. -deploy2(State, SignedTX) -> +deploy2(State = #s{hash = #w{wx = HashT}, action = #w{wx = ActionB}}, SignedTX) -> case hz:post_tx(SignedTX) of {ok, Data = #{"tx_hash" := TXHash}} -> + _ = wxButton:disable(ActionB), + ok = wxButton:setLabel(ActionB, J("Check Transaction Status")), ok = log(info, "Submitted transaction ~s", [TXHash]), + ok = wxTextCtrl:setValue(HashT, unicode:characters_to_list(TXHash)), check_tx(State#s{tx_data = Data, status = submitted}); {ok, #{"reason" := Reason}} -> handle_troubling(State, {error, Reason}); @@ -400,24 +409,47 @@ do_call(State, ChainID, CallerID, UnsignedTX) -> Error -> handle_troubling(State, Error) end. -do_call2(State, SignedTX) -> +do_call2(State = #s{action = #w{wx = ActionB}}, SignedTX) -> + _ = wxButton:disable(ActionB), + ok = wxButton:setLabel(ActionB, J("Check Transaction Status")), case hz:post_tx(SignedTX) of - {ok, Data} -> check_tx(State#s{tx_data = Data}); + {ok, Data} -> check_tx(State#s{tx_data = Data, status = submitted}); Error -> handle_troubling(State, Error) end. -do_dry_run(State, ConID, TX) -> +do_dry_run(State = #s{action = #w{wx = ActionB}}, ConID, TX) -> + _ = wxButton:disable(ActionB), case hz:dry_run(TX) of {ok, Result} -> update_info(State#s{tx_info = Result}); Other -> handle_troubling(State, {error, ConID, Other}) end. - -check_tx(State = #s{tx_data = #{"tx_hash" := TXHash} = TXData, tx_info = none}) -> - ok = tell("TXData: ~p", [TXData]), +check_tx(State = #s{fundef = {_, init}, + tx_data = #{"tx_hash" := TXHash}, + tx_info = none, + return = #w{wx = ReturnT}, + status = submitted, + action = #w{wx = ActionB}, + info = #w{wx = InfoT}}) -> case hz:tx_info(TXHash) of {ok, Info = #{"call_info" := #{"return_type" := "ok", "contract_id" := ConID}}} -> + ok = wxTextCtrl:setValue(ReturnT, ConID), + ok = gd_v_devman:open_contract(ConID), + FormattedInfo = io_lib:fomat("~tw", [Info]), + ok = wxTextCtrl:setValue(InfoT, FormattedInfo), + +check_tx(State = #s{tx_data = #{"tx_hash" := TXHash}, + tx_info = none, + status = submitted, + action = #w{wx = ActionB}, + info = #w{wx = InfoT}}) -> + case hz:tx_info(TXHash) of + {ok, Info = #{"call_info" := #{"return_type" := "ok", + "contract_id" := ConID, + "return_value" := Value}}} -> + FormattedInfo = io_lib:fomat("~tw", [Info]), + ok = wxTextCtrl:setValue(InfoT, FormattedInfo), ok = gd_v_devman:open_contract(ConID), update_info(State#s{tx_info = Info}); {error, "Tx not mined"} -> @@ -433,16 +465,16 @@ check_tx(State = #s{tx_data = TXData}) -> State. -update_info(State = #s{tx_info = TXInfo, out = #w{wx = Out}}) -> +update_info(State = #s{tx_info = TXInfo, return = #w{wx = Return}}) -> Formatted = io_lib:format("TXInfo: ~p~n", [TXInfo]), - ok = wxTextCtrl:setValue(Out, Formatted), + ok = wxTextCtrl:setValue(Return, Formatted), State. copy(#s{tx_info = none}) -> ok; -copy(#s{out = #w{wx = Out}}) -> - Output = wxTextCtrl:getValue(Out), +copy(#s{return = #w{wx = Return}}) -> + Output = wxTextCtrl:getValue(Return), gd_lib:copy_to_clipboard(Output).