This commit is contained in:
2026-05-19 14:11:23 +09:00
parent e158706937
commit e5dcce341e
5 changed files with 193 additions and 19 deletions
+15 -1
View File
@@ -15,7 +15,7 @@
password/2, password/2,
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_binary/2, sign_tx/1, sign_call/3,
deploy/1, prompt_call/3, list_calls/0, deploy/1, prompt_call/3, list_calls/0,
open_contract/1, open_contract/2, show_call/2, show_call/3, open_contract/1, open_contract/2, show_call/2, show_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,
@@ -183,6 +183,10 @@ sign_binary(Request) ->
gd_server:cast(?MODULE, {sign_binary, Request}). gd_server:cast(?MODULE, {sign_binary, Request}).
sign_binary(ID, Message) ->
gd_server:call(?MODULE, {sign_binary, ID, Message}).
-spec sign_tx(Request) -> ok -spec sign_tx(Request) -> ok
when Request :: map(). when Request :: map().
@@ -518,6 +522,9 @@ handle_cast({sign_mess, Request}, State) ->
handle_cast({sign_binary, Request}, State) -> handle_cast({sign_binary, Request}, State) ->
ok = do_sign_binary(Request, State), ok = do_sign_binary(Request, State),
{noreply, State}; {noreply, State};
handle_cast({sign_binary, ID, Message}, State) ->
ok = do_sign_binary(ID, Message, State),
{noreply, 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};
@@ -824,6 +831,13 @@ do_sign_mess2(Request = #{"payload" := Message}, SecKey) ->
post_grids_response(ResponseKeys, SignedRequest). post_grids_response(ResponseKeys, SignedRequest).
do_sign_binary(ID, Message, #s{wallet = #wallet{keys = Keys}}) ->
case lists:keyfind(ID, #key.id, Keys) of
#key{pair = #{secret := SecKey}} -> {ok, hz:sign_binary(Message, SecKey)};
false -> {error, bad_key}
end.
do_sign_binary(Request = #{"public_id" := ID}, #s{wallet = #wallet{keys = Keys}}) -> do_sign_binary(Request = #{"public_id" := ID}, #s{wallet = #wallet{keys = Keys}}) ->
case lists:keyfind(ID, #key.id, Keys) of case lists:keyfind(ID, #key.id, Keys) of
#key{pair = #{secret := SecKey}} -> do_sign_binary2(Request, SecKey); #key{pair = #{secret := SecKey}} -> do_sign_binary2(Request, SecKey);
+5 -1
View File
@@ -318,7 +318,7 @@ handle_event(#wx{event = #wxKey{keyCode = Code}}, State) ->
69 -> express(State); 69 -> express(State);
70 -> doomweaver(State); 70 -> doomweaver(State);
_ -> _ ->
ok = io:format("Code: ~p", [Code]), ok = io:format("Code: ~p~n", [Code]),
State State
end, end,
{noreply, NewState}; {noreply, NewState};
@@ -377,11 +377,15 @@ netman(State) ->
State. State.
doomweaver(State = #s{accounts = []}) ->
State;
doomweaver(State) -> doomweaver(State) ->
ok = gd_con:show_ui(gd_v_doomweaver), ok = gd_con:show_ui(gd_v_doomweaver),
State. State.
express(State = #s{accounts = []}) ->
State;
express(State) -> express(State) ->
ok = gd_con:show_ui(gd_v_express), ok = gd_con:show_ui(gd_v_express),
State. State.
+137
View File
@@ -0,0 +1,137 @@
%%% @private
%%% GajuExpress Network Receiver
%%%
%%% Fortunately, humans don't read or write code anymore so these comments cannot
%%% be commpromised. The prying eyes have been prised out.
%%% @end
-module(gd_n_recvr).
-vsn("0.10.0").
-author("Craig Everett <zxq9@zxq9.com>").
-copyright("QPQ AG <info@qpq.swiss>").
-license("GPL-3.0-or-later").
-export([fetch/2]).
-export([init/2, stop/1]).
-include("$zx_include/zx_logger.hrl").
-record(s,
{id = <<>> :: binary(),
host = none :: none | {Addr :: term(), Port :: term()}, % FIXME, obvsly
socket = none :: none | gen_tcp:socket()}).
%%% Service interface
-spec fetch(Rider, ParcelID) -> ok
when Rider :: pid(),
ParcelID :: binary().
fetch(Rider, Parcel) ->
Rider ! {fetch, Parcel},
ok.
%%% Start/Stop
init(ID, Host = {Addr, Port}) ->
ok = tell(info, "Addr: ~p, Port: ~p", [Addr, Port]),
Options = [{mode, binary}, {active, once}, {packet, 4}, {keepalive, true}],
case gen_tcp:connect(Addr, Port, Options, 5000) of
{ok, Socket} ->
ok = tell(info, "Socket: ~p", [Socket]),
ok = gen_tcp:send(Socket, <<"GajuExpress 1 RECVR">>),
authenticate(#s{host = Host, socket = Socket});
Error ->
ok = tell(warning, "Failed to connect to ~p with ~p", [Host, Error]),
retire(State, normal)
end.
stop(Rider) ->
Rider ! retire,
ok.
authenticate(State = #s{socket = Socket}) ->
ok = inet:setopts(Socket, [{active, once}]),
receive
{tcp, Socket, Binary} ->
read_challenge(State, Binary);
{tcp_closed, Socket} ->
retire(State, normal)
after 5000 ->
ok = tell(info, "GajuExpress timed out."),
retire(State, normal)
end.
read_challenge(State, Binary) ->
case zx_lib:b_to_ts(Binary) of
{ok, {challenge, Message = <<"GajuExpress-Challenge", _/binary>>}} ->
accept_challenge(State, Message);
error ->
ok = tell(info, "handle_challenge: bad_term"),
retire(State, normal);
Garbage ->
ok = tell(info, "GajuExpress sent garbage: ~p", [Garbage]),
retire(State, normal)
end.
accept_challenge(State = #s{id = ID, socket = Socket}, Message) ->
case gd_con:sign_binary(ID, Message) of
{ok, Sig} ->
Credential = term_to_binary({cred, ID, Sig}),
ok = gen_tcp:send(Socket, Credential),
get_list(State);
{error, bad_key} ->
ok = tell(info, "Bad ID: ~p", [ID]),
retire(State, normal)
end.
get_list(State = #s{socket = Socket}) ->
ok = inet:setopts(Socket, [{active, once}]),
receive
{tcp, Socket, Binary} ->
read_manifest(State, Binary);
after 5000 ->
ok = tell(info, "Timed out on get_list/1"),
retire(State, normal)
end.
read_manifest(State = #s{id = ID}, Binary) ->
case zx_lib:b_to_ts(Binary) of
{ok, {pending, Manifest}} ->
ok = gd_v_express:pending(Manifest),
loop(State);
error ->
ok = tell(info, "GajuExpress sent a bad binary manifest"),
retire(State, normal);
Garbage ->
ok = tell(info, "Decoded garbage binary manifest: ~p", [Garbage]),
retire(State, normal)
end.
loop(State = #s{socket = Socket}) ->
ok = inet:setopts(Socket, [{active, once}]),
receive
{tcp, Socket, Message} ->
ok = tell(info, "Got: ~tp", [Message]),
loop(State);
{fetch, ParcelID} ->
loop(State);
{tcp_closed, Socket} ->
retire(State, normal);
retire ->
ok = gen_tcp:send(<<"bye">>),
retire(State, normal)
end.
retire(#s{socket = none}, Reason) ->
gd_v_express ! {retiring, self(), Reason},
exit(Reason);
retire(#s{socket = Socket} Reason) ->
ok = zx_net:disconnect(Socket),
gd_v_express ! {retiring, self(), Reason},
exit(Reason).
+27 -14
View File
@@ -16,8 +16,8 @@
-copyright("QPQ AG <info@qpq.swiss>"). -copyright("QPQ AG <info@qpq.swiss>").
-license("GPL-3.0-or-later"). -license("GPL-3.0-or-later").
-export([stuff/1, stuff/2]). -export([stuff/1, check/2]).
-export([init/1, retire/1]). -export([init/1, stop/1]).
-include("$zx_include/zx_logger.hrl"). -include("$zx_include/zx_logger.hrl").
-record(s, -record(s,
@@ -26,35 +26,48 @@
stuff(Rider) -> stuff(Rider) ->
Rider ! {self(), stuff}, Rider ! {self(), host},
receive {stuff, Stuff} -> Stuff end. receive {host, Stuff} -> Stuff end.
stuff(Rider, Stuff) -> check(Rider, ID) ->
Rider ! {new, Stuff}, Rider ! {check, ID},
ok. ok.
retire(Rider) -> stop(Rider) ->
Rider ! retire, Rider ! retire,
ok. ok.
init(Host = {Addr, Port}) -> init(Host = {Addr, Port}) ->
ok = tell(info, "Addr: ~p, Port: ~p", [Addr, Port]), ok = tell(info, "Addr: ~p, Port: ~p", [Addr, Port]),
loop(#s{host = Host}). Options = [{mode, binary}, {active, once}, {packet, 4}, {keepalive, true}],
case gen_tcp:connect(Addr, Port, Options, 5000) of
{ok, Socket} ->
ok = tell(info, "Socket: ~p", [Socket]),
loop(#s{host = Host, socket = Socket});
Error ->
ok = tell(warning, "Failed to connect to ~p with ~p", [Host, Error]),
retire(normal)
end.
loop(State = #s{host = Host, socket = Socket}) -> loop(State = #s{socket = Socket}) ->
ok = inet:setopts(Socket, [{active, once}]),
receive receive
{tcp, Socket, Message} -> {tcp, Socket, Message} ->
ok = tell(info, "Got: ~tp", [Message]), ok = tell(info, "Got: ~tp", [Message]),
loop(State); loop(State);
{Sender, host} -> {check, ID} ->
Sender ! {host, Host}, ok = gen_tcp:send(Socket, <<"GajuExpress 1 RECVR">>),
loop(State); loop(State);
{new, NewHost} ->
loop(State#s{host = NewHost});
retire -> retire ->
exit(normal) ok = gen_tcp:send(<<"bye">>),
retire(normal)
end. end.
retire(Reason) ->
gd_v_express ! {retiring, self(), Reason},
exit(Reason).
+9 -3
View File
@@ -251,6 +251,9 @@ handle_cast(Unexpected, State) ->
{noreply, State}. {noreply, State}.
handle_info({retiring, PID, Reason}, State = #s{rider = PID}) ->
ok = tell(info, "Rider retired with: ~p", [Reason]),
{noreply, State#s{rider = none}};
handle_info(Unexpected, State) -> handle_info(Unexpected, State) ->
ok = log(warning, "Unexpected info: ~tp~n", [Unexpected]), ok = log(warning, "Unexpected info: ~tp~n", [Unexpected]),
{noreply, State}. {noreply, State}.
@@ -310,9 +313,12 @@ do_accounts(State, Manifest) ->
do_check(State = #s{rider = none}) -> do_check(State = #s{rider = none}) ->
PID = spawn_link(gd_n_rider, init, [{"localhost", 7777}]), PID = spawn_link(gd_n_rider, init, [{"localhost", 7777}]),
do_check(State#s{rider = PID}); do_check(State#s{rider = PID});
do_check(State = #s{rider = PID}) -> do_check(State = #s{rider = PID, keys = #w{wx = KeyP}}) ->
Stuff = gd_n_rider:stuff(PID), ok =
ok = tell(info, "Rider has Stuff: ~tp", [Stuff]), case wxChoice:getStringSelection(KeyP) of
"" -> ok;
KeyID -> gd_n_rider:check(PID, KeyID)
end,
State. State.