Make Contract Calls Great Again #35
+18
-24
@@ -16,7 +16,7 @@
|
|||||||
refresh/0,
|
refresh/0,
|
||||||
nonce/1, spend/1, chain_id/0, grids/1,
|
nonce/1, spend/1, chain_id/0, grids/1,
|
||||||
sign_mess/1, sign_binary/1, sign_tx/1, sign_call/3,
|
sign_mess/1, sign_binary/1, sign_tx/1, sign_call/3,
|
||||||
prompt_call/3,
|
deploy/1, prompt_call/3,
|
||||||
make_key/6, recover_key/1, mnemonic/1, rename_key/2, drop_key/1, list_keys/0,
|
make_key/6, recover_key/1, mnemonic/1, rename_key/2, drop_key/1, list_keys/0,
|
||||||
add_node/1, set_sole_node/1]).
|
add_node/1, set_sole_node/1]).
|
||||||
-export([tic/1, update_balance/2]).
|
-export([tic/1, update_balance/2]).
|
||||||
@@ -158,7 +158,7 @@ spend(TX) ->
|
|||||||
when ID :: binary().
|
when ID :: binary().
|
||||||
|
|
||||||
chain_id() ->
|
chain_id() ->
|
||||||
gen_server:cast(?MODULE, {chain_id, ID}).
|
gen_server:cast(?MODULE, chain_id).
|
||||||
|
|
||||||
|
|
||||||
-spec grids(string()) -> ok.
|
-spec grids(string()) -> ok.
|
||||||
@@ -192,28 +192,18 @@ sign_tx(Request) ->
|
|||||||
when ChainID :: binary(),
|
when ChainID :: binary(),
|
||||||
PubKey :: gajudesk:id(),
|
PubKey :: gajudesk:id(),
|
||||||
TX :: binary(),
|
TX :: binary(),
|
||||||
Result :: {ok, SignedTX :: binary()},
|
Result :: {ok, SignedTX :: binary()}
|
||||||
| {error, Reason :: term()}.
|
| {error, Reason :: term()}.
|
||||||
|
|
||||||
sign_call(ChainID, PubKey, TX) ->
|
sign_call(ChainID, PubKey, TX) ->
|
||||||
gen_server:call(?MODULE, {sign_call, ChainID, PubKey, TX}).
|
gen_server:call(?MODULE, {sign_call, ChainID, PubKey, TX}).
|
||||||
|
|
||||||
|
|
||||||
-spec deploy(Build, Params, InitArgs) -> Result
|
-spec deploy(Build) -> ok
|
||||||
when Build :: map(),
|
when Build :: map().
|
||||||
Params :: {PK :: gajudesk:id(),
|
|
||||||
Nonce :: non_neg_integer(),
|
|
||||||
TTL :: pos_integer(),
|
|
||||||
GasP :: pos_integer(),
|
|
||||||
Gas :: pos_integer(),
|
|
||||||
Amount :: pos_integer()},
|
|
||||||
InitArgs :: [Arg :: string()],
|
|
||||||
Result :: {ok, TX_Hash :: gajudesk:id()}
|
|
||||||
| {error, Reason},
|
|
||||||
Reason :: term(). % FIXME
|
|
||||||
|
|
||||||
deploy(Build, Params, InitArgs) ->
|
deploy(Build) ->
|
||||||
gen_server:cast(?MODULE, {deploy, Build, Params, InitArgs}).
|
gen_server:cast(?MODULE, {deploy, Build}).
|
||||||
|
|
||||||
|
|
||||||
-spec prompt_call(FunDef, ConID, Build) -> ok
|
-spec prompt_call(FunDef, ConID, Build) -> ok
|
||||||
@@ -406,9 +396,9 @@ handle_call(list_keys, _, State) ->
|
|||||||
handle_call({nonce, ID}, _, State) ->
|
handle_call({nonce, ID}, _, State) ->
|
||||||
Response = do_nonce(ID),
|
Response = do_nonce(ID),
|
||||||
{reply, Response, State};
|
{reply, Response, State};
|
||||||
handle_call({chain_id, State) ->
|
handle_call(chain_id, _, State) ->
|
||||||
Response = do_chain_id(State),
|
Response = do_chain_id(State),
|
||||||
{reply, Response, NewState};
|
{reply, Response, State};
|
||||||
handle_call({sign_call, ChainID, PubKey, TX}, _, State) ->
|
handle_call({sign_call, ChainID, PubKey, TX}, _, State) ->
|
||||||
Response = do_sign_call(State, ChainID, PubKey, TX),
|
Response = do_sign_call(State, ChainID, PubKey, TX),
|
||||||
{reply, Response, State};
|
{reply, Response, State};
|
||||||
@@ -479,10 +469,10 @@ handle_cast({sign_binary, Request}, State) ->
|
|||||||
handle_cast({sign_tx, Request}, State) ->
|
handle_cast({sign_tx, Request}, State) ->
|
||||||
ok = do_sign_tx(Request, State),
|
ok = do_sign_tx(Request, State),
|
||||||
{noreply, State};
|
{noreply, State};
|
||||||
handle_cast({deploy, Build, Params, InitArgs}, State) ->
|
handle_cast({deploy, Build}, State) ->
|
||||||
ok = do_deploy(Build, Params, InitArgs, State),
|
ok = do_deploy(Build, State),
|
||||||
{noreply, State};
|
{noreply, State};
|
||||||
handle_cast({prompt_call, FunDef, ConID, Build}) ->
|
handle_cast({prompt_call, FunDef, ConID, Build}, State) ->
|
||||||
NewState = do_prompt_call(FunDef, ConID, Build, State),
|
NewState = do_prompt_call(FunDef, ConID, Build, State),
|
||||||
{noreply, NewState};
|
{noreply, NewState};
|
||||||
handle_cast({make_key, Name, Seed, Encoding, Transform}, State) ->
|
handle_cast({make_key, Name, Seed, Encoding, Transform}, State) ->
|
||||||
@@ -594,7 +584,7 @@ task_data(gd_v_devman, #s{}) ->
|
|||||||
%%% Network operations
|
%%% Network operations
|
||||||
|
|
||||||
% NOTE: This is temporary. As GD becomes more chain aware this will move.
|
% NOTE: This is temporary. As GD becomes more chain aware this will move.
|
||||||
do_chain_id(#s{wallet = #wallet{chain_id = ChainID}) ->
|
do_chain_id(#s{wallet = #wallet{chain_id = ChainID}}) ->
|
||||||
{ok, ChainID};
|
{ok, ChainID};
|
||||||
do_chain_id(_) ->
|
do_chain_id(_) ->
|
||||||
{error, no_chain}.
|
{error, no_chain}.
|
||||||
@@ -862,6 +852,10 @@ do_network(#s{wallet = #wallet{chain_id = ChainID}}) ->
|
|||||||
{ok, ChainID}.
|
{ok, ChainID}.
|
||||||
|
|
||||||
|
|
||||||
|
do_deploy(Build, State) ->
|
||||||
|
do_prompt_call({"init", init}, none, Build, State).
|
||||||
|
|
||||||
|
|
||||||
do_prompt_call(FunDef, ConID, Build, State = #s{tasks = Tasks, prefs = Prefs}) ->
|
do_prompt_call(FunDef, ConID, Build, State = #s{tasks = Tasks, prefs = Prefs}) ->
|
||||||
Name = {ConID, FunDef},
|
Name = {ConID, FunDef},
|
||||||
case do_list_keys(State) of
|
case do_list_keys(State) of
|
||||||
@@ -872,7 +866,7 @@ do_prompt_call(FunDef, ConID, Build, State = #s{tasks = Tasks, prefs = Prefs}) -
|
|||||||
State;
|
State;
|
||||||
false ->
|
false ->
|
||||||
CallPrefs = maps:get(gd_v_call, Prefs, #{}),
|
CallPrefs = maps:get(gd_v_call, Prefs, #{}),
|
||||||
Win = gd_v_call:start_link({CallPrefs, FunDef, ConID, Build, Selected, Keys}),
|
Win = gd_v_call:start_link({CallPrefs, FunDef, ConID, Build, Selected, KeyIDs}),
|
||||||
PID = wx_object:get_pid(Win),
|
PID = wx_object:get_pid(Win),
|
||||||
Mon = monitor(process, PID),
|
Mon = monitor(process, PID),
|
||||||
UI = #ui{name = Name, pid = PID, wx = Win, mon = Mon},
|
UI = #ui{name = Name, pid = PID, wx = Win, mon = Mon},
|
||||||
|
|||||||
+4
-3
@@ -5,6 +5,7 @@
|
|||||||
-module(gd_lib).
|
-module(gd_lib).
|
||||||
-vsn("0.8.1").
|
-vsn("0.8.1").
|
||||||
|
|
||||||
|
-include_lib("wx/include/wx.hrl").
|
||||||
-export([is_int/1,
|
-export([is_int/1,
|
||||||
mono_text/2, mono_text/3,
|
mono_text/2, mono_text/3,
|
||||||
button/2, button/3,
|
button/2, button/3,
|
||||||
@@ -42,7 +43,7 @@ mono_text(Parent, Name) ->
|
|||||||
Name :: term(),
|
Name :: term(),
|
||||||
Value :: string(),
|
Value :: string(),
|
||||||
StaticText :: #w{}.
|
StaticText :: #w{}.
|
||||||
@doc
|
%% @doc
|
||||||
%% Creats a monospace font static text field with the given value.
|
%% Creats a monospace font static text field with the given value.
|
||||||
%% This exists so that I don't have to remember the difference between how to create a styled
|
%% This exists so that I don't have to remember the difference between how to create a styled
|
||||||
%% wxStaticText vs wxTextCtrl (which has to do it in a weird way because it has a much richer
|
%% wxStaticText vs wxTextCtrl (which has to do it in a weird way because it has a much richer
|
||||||
@@ -50,11 +51,11 @@ mono_text(Parent, Name) ->
|
|||||||
|
|
||||||
mono_text(Parent, Name, Value) ->
|
mono_text(Parent, Name, Value) ->
|
||||||
Text = wxStaticText:new(Parent, ?wxID_ANY, Value),
|
Text = wxStaticText:new(Parent, ?wxID_ANY, Value),
|
||||||
Font = wxFont:new(10, ?wxFONTFAMILY_TELETYPE, ?wxFONT_STYLE_NORMAL, ?wxFONT_WEIGHT_NORMAL),
|
Font = wxFont:new(10, ?wxFONTFAMILY_TELETYPE, ?wxFONTSTYLE_NORMAL, ?wxFONTWEIGHT_NORMAL),
|
||||||
ok =
|
ok =
|
||||||
case wxStaticText:setFont(Text, Font) of
|
case wxStaticText:setFont(Text, Font) of
|
||||||
true -> ok;
|
true -> ok;
|
||||||
false -> tell(info, "wxStaticText ~p is already monospace.", [Text)
|
false -> tell(info, "wxStaticText ~p is already monospace.", [Text])
|
||||||
end,
|
end,
|
||||||
#w{name = Name, id = wxStaticText:getId(Text), wx = Text}.
|
#w{name = Name, id = wxStaticText:getId(Text), wx = Text}.
|
||||||
|
|
||||||
|
|||||||
+12
-41
@@ -100,14 +100,17 @@ init({Prefs, {FunName, FunType}, ConID, Build, Selected, Keys}) ->
|
|||||||
Action = #w{wx = ActionBn} = gd_lib:button(Frame, ActionLabel),
|
Action = #w{wx = ActionBn} = gd_lib:button(Frame, ActionLabel),
|
||||||
|
|
||||||
TX_Sz = wxStaticBoxSizer:new(?wxVERTICAL, Frame, [{label, J("Transaction Info")}]),
|
TX_Sz = wxStaticBoxSizer:new(?wxVERTICAL, Frame, [{label, J("Transaction Info")}]),
|
||||||
TX_Data = #w{wx = HashT} = gd_lib:mono_text(TX_Sz, tx_hash),
|
TX_Sz_Box = wxStaticBoxSizer:getStaticBox(TX_Sz),
|
||||||
TX_Hash = #w{wx = HashT} = gd_lib:mono_text(TX_Sz, tx_hash),
|
TX_Data = #w{wx = DataT} = gd_lib:mono_text(TX_Sz_Box, tx_hash),
|
||||||
TX_Info = #w{wx = HashT} = gd_lib:mono_text(TX_Sz, tx_hash),
|
TX_Hash = #w{wx = HashT} = gd_lib:mono_text(TX_Sz_Box, tx_hash),
|
||||||
|
TX_Info = #w{wx = InfoT} = gd_lib:mono_text(TX_Sz_Box, tx_hash),
|
||||||
Line = wxStaticLine:new(TX_Sz, [{style, ?wxLI_HORIZONTAL}]),
|
Line = wxStaticLine:new(TX_Sz, [{style, ?wxLI_HORIZONTAL}]),
|
||||||
Out = #w{wx = OutTxt} = gd_lib:mono_text(TX_Sz, out),
|
Out = #w{wx = OutTxt} = gd_lib:mono_text(TX_Sz_Box, out),
|
||||||
Copy = #w{wx = CopyBn} = gd_lib:button(Frame, J("Copy")),
|
Copy = #w{wx = CopyBn} = gd_lib:button(Frame, J("Copy")),
|
||||||
|
|
||||||
|
_ = wxStaticBoxSizer:add(TX_Sz, DataT, zxw:flags({wide, 5})),
|
||||||
_ = wxStaticBoxSizer:add(TX_Sz, HashT, zxw:flags({wide, 5})),
|
_ = wxStaticBoxSizer:add(TX_Sz, HashT, zxw:flags({wide, 5})),
|
||||||
|
_ = wxStaticBoxSizer:add(TX_Sz, InfoT, zxw:flags({wide, 5})),
|
||||||
_ = wxStaticBoxSizer:add(TX_Sz, Line, zxw:flags({wide, 5})),
|
_ = wxStaticBoxSizer:add(TX_Sz, Line, zxw:flags({wide, 5})),
|
||||||
_ = wxStaticBoxSizer:add(TX_Sz, OutTxt, zxw:flags({wide, 5})),
|
_ = wxStaticBoxSizer:add(TX_Sz, OutTxt, zxw:flags({wide, 5})),
|
||||||
_ = wxStaticBoxSizer:add(TX_Sz, CopyBn, zxw:flags({wide, 5})),
|
_ = wxStaticBoxSizer:add(TX_Sz, CopyBn, zxw:flags({wide, 5})),
|
||||||
@@ -282,7 +285,7 @@ engage4(State = #s{fundef = {"init", init}, build = Build}, ChainID, Params, Arg
|
|||||||
{ok, CreateTX} -> deploy(State, ChainID, CallerID, CreateTX);
|
{ok, CreateTX} -> deploy(State, ChainID, CallerID, CreateTX);
|
||||||
Error -> handle_troubling(State, Error)
|
Error -> handle_troubling(State, Error)
|
||||||
end;
|
end;
|
||||||
engage4(State = #s{con_id = ConID, build = Build, fundef = {Name, Type}}, ChainID, Params, Args) ->
|
engage4(State = #s{fundef = {Name, Type}, con_id = ConID, build = Build}, ChainID, Params, Args) ->
|
||||||
{CallerID, Nonce, TTL, GP, Gas, Amount} = Params,
|
{CallerID, Nonce, TTL, GP, Gas, Amount} = Params,
|
||||||
AACI = maps:get(aaci, Build),
|
AACI = maps:get(aaci, Build),
|
||||||
case hz:contract_call(CallerID, Nonce, Gas, GP, Amount, TTL, AACI, ConID, Name, Args) of
|
case hz:contract_call(CallerID, Nonce, Gas, GP, Amount, TTL, AACI, ConID, Name, Args) of
|
||||||
@@ -333,7 +336,7 @@ deploy(State, ChainID, CallerID, CreateTX) ->
|
|||||||
deploy2(State, SignedTX) ->
|
deploy2(State, SignedTX) ->
|
||||||
case hz:post_tx(SignedTX) of
|
case hz:post_tx(SignedTX) of
|
||||||
{ok, Data} -> check_tx(State#s{tx_data = Data});
|
{ok, Data} -> check_tx(State#s{tx_data = Data});
|
||||||
{ok, WTF} -> handle_troubling(State, {error, WTF});
|
% {ok, WTF} -> handle_troubling(State, {error, WTF});
|
||||||
Error -> handle_troubling(State, Error)
|
Error -> handle_troubling(State, Error)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
@@ -346,7 +349,7 @@ do_call(State, ChainID, CallerID, UnsignedTX) ->
|
|||||||
|
|
||||||
do_call2(State, SignedTX) ->
|
do_call2(State, SignedTX) ->
|
||||||
case hz:post_tx(SignedTX) of
|
case hz:post_tx(SignedTX) of
|
||||||
{ok, Data} -> check_tx(SDtate = #s{tx_data = Data});
|
{ok, Data} -> check_tx(State = #s{tx_data = Data});
|
||||||
Error -> handle_troubling(State, Error)
|
Error -> handle_troubling(State, Error)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
@@ -382,9 +385,9 @@ update_info(State = #s{tx_info = TXInfo, out = #w{wx = Out}}) ->
|
|||||||
State.
|
State.
|
||||||
|
|
||||||
|
|
||||||
copy(State = #s{tx_info = none}) ->
|
copy(#s{tx_info = none}) ->
|
||||||
ok;
|
ok;
|
||||||
copy(State = #s{out = #w{wx = Out}}) ->
|
copy(#s{out = #w{wx = Out}}) ->
|
||||||
Output = wxStaticText:getLabel(Out),
|
Output = wxStaticText:getLabel(Out),
|
||||||
gd_lib:copy_to_clipboard(Output).
|
gd_lib:copy_to_clipboard(Output).
|
||||||
|
|
||||||
@@ -399,38 +402,6 @@ textify({T, _, _}) when is_list(T) -> T;
|
|||||||
textify({T, _, _}) -> io_lib:format("~tp", [T]).
|
textify({T, _, _}) -> io_lib:format("~tp", [T]).
|
||||||
|
|
||||||
|
|
||||||
extract_args(Controls) ->
|
|
||||||
extract_args(Controls, []).
|
|
||||||
|
|
||||||
extract_args([], Acc) ->
|
|
||||||
pack_args(Acc);
|
|
||||||
extract_args([{Name, Control} | T], Acc) ->
|
|
||||||
String = wxTextCtrl:getValue(Control),
|
|
||||||
extract_args(T, [{Name, String} | Acc]).
|
|
||||||
|
|
||||||
pack_args(Args) ->
|
|
||||||
pack_args(Args, [], []).
|
|
||||||
|
|
||||||
pack_args([], M, A) ->
|
|
||||||
Message = unicode:characters_to_list(["Call Args:\n", M]),
|
|
||||||
{Message, A};
|
|
||||||
pack_args([{N, S} | T], M, A) ->
|
|
||||||
pack_args(T, [[N, ": ", S, "\n"] | M], [S | A]).
|
|
||||||
|
|
||||||
call_params(Controls) ->
|
|
||||||
call_params(Controls, {[], []}).
|
|
||||||
|
|
||||||
call_params([], {Acc, []}) ->
|
|
||||||
{ok, lists:reverse(Acc)};
|
|
||||||
call_params([], {_, Errors}) ->
|
|
||||||
{error, lists:reverse(Errors)};
|
|
||||||
call_params([{{Label, Validate}, Control} | T], {Acc, Errors}) ->
|
|
||||||
String = wxTextCtrl:getValue(Control),
|
|
||||||
case Validate(String) of
|
|
||||||
{ok, Value} -> call_params(T, {[Value | Acc], Errors});
|
|
||||||
{error, Reason} -> call_params(T, {Acc, [{Label, Reason} | Errors]})
|
|
||||||
end.
|
|
||||||
|
|
||||||
gt_0(S) ->
|
gt_0(S) ->
|
||||||
C = "Must be an integer greater than 0",
|
C = "Must be an integer greater than 0",
|
||||||
R =
|
R =
|
||||||
|
|||||||
Reference in New Issue
Block a user