From b4ea4bdf107ec40ec24db1d0fb1d16a4e873a2f0 Mon Sep 17 00:00:00 2001 From: Craig Everett Date: Fri, 22 Aug 2025 15:24:32 +0900 Subject: [PATCH 1/5] Fix bad widget call --- src/gd_v_devman.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gd_v_devman.erl b/src/gd_v_devman.erl index a5dad28..65b3487 100644 --- a/src/gd_v_devman.erl +++ b/src/gd_v_devman.erl @@ -590,7 +590,7 @@ deploy(State = #s{code = {Codebook, Pages}}) -> State; Index -> #p{code = CodeTx} = lists:nth(Index + 1, Pages), - Source = wxTextCtrl:getValue(CodeTx), + Source = wxStyledTextCtrl:getText(CodeTx), deploy2(State, Source) end. From d8b8fee2329440def96f6cbb42c16e72fdcff447 Mon Sep 17 00:00:00 2001 From: Craig Everett Date: Sat, 25 Oct 2025 10:41:32 +0900 Subject: [PATCH 2/5] WIP: Adding binary signatures --- src/gd_con.erl | 81 +++++++++++++++++++++++++++++++++----------------- src/gd_gui.erl | 42 ++++++++++++++++++++++++++ 2 files changed, 96 insertions(+), 27 deletions(-) diff --git a/src/gd_con.erl b/src/gd_con.erl index 6bb2e63..f1d2992 100644 --- a/src/gd_con.erl +++ b/src/gd_con.erl @@ -679,38 +679,63 @@ do_grids_sig(JSON, URL) -> do_grids_sig2(Request = #{"grids" := 1, "type" := "message"}) -> gd_gui:grids_mess_sig(Request); +do_grids_sig2(Request = #{"grids" := 1, "type" := "binary"}) -> + gd_gui:grids_mess_sig(Request); do_grids_sig2(Request = #{"grids" := 1, "type" := "tx"}) -> gd_gui:grids_mess_sig(Request); do_grids_sig2(WTF) -> gd_gui:trouble({trash, WTF}). -do_sign_mess(Request = #{"public_id" := ID, "payload" := Message}, - #s{wallet = #wallet{keys = Keys}}) -> +do_sign_mess(Request = #{"public_id" := ID}, #s{wallet = #wallet{keys = Keys}}) -> case lists:keyfind(ID, #key.id, Keys) of #key{pair = #{secret := SecKey}} -> Sig = base64:encode(hz:sign_message(list_to_binary(Message), SecKey)), - do_sign_mess2(Request#{"signature" => Sig}); + SignedRequest = maps:put("signature", Sig, Request), + ResponseKeys = + ["grids", + "chain", + "network_id", + "type", + "public_id", + "payload", + "signature"], + post_grids_response(ResponseKeys, SignedRequest); false -> gd_gui:trouble({bad_key, ID}) end. -do_sign_mess2(Request = #{"url" := URL}) -> - ResponseKeys = - ["grids", - "chain", - "network_id", - "type", - "public_id", - "payload", - "signature"], - Response = zj:encode(maps:with(ResponseKeys, Request)), - case httpc:request(post, {URL, [], "application/json", Response}, [], []) of - {ok, {{_, 200, _}, _, JSON}} -> log(info, "Signature posted: ~p", [JSON]); - {error, socket_closed_remotely} -> tell("Yep, closed remotely."); - Error -> gd_gui:trouble(Error) + +do_sign_binary(Request = #{"public_id" := ID}, #s{wallet = #wallet{keys = Keys}}) -> + case lists:keyfind(ID, #key.id, Keys) of + #key{pair = #{secret := SecKey}} -> do_sign_binary2(Request, SecKey); + false -> gd_gui:trouble({bad_key, ID}) end. +do_sign_binary2(Request = #{"payload" := Payload}, SecKey) -> + case base64_decode(Payload) of + {ok, Binary} -> + Sig = base64:encode(hz_sign_binary(Binary, SecKey)), + SignedRequest = maps:put("signature", Sig, Request), + ResponseKeys = + ["grids", + "chain", + "network_id", + "type", + "public_id", + "payload", + "signature"], + post_grids_response(ResponseKeys, SignedRequest); + Error -> + gd_gui:trouble(Error) + end. + +hz_sign_binary(Binary, SecKey) -> + Prefix = <<"Gajumaru Signed Binary:">>, + Target = <>, + {ok, Hash} = eblake2:blake2b(32, Target), + ecu_eddsa:sign_detached(Hashed, SecKey). + do_sign_tx(Request = #{"public_id" := ID, "payload" := CallData, "network_id" := NID}, #s{wallet = #wallet{keys = Keys}}) -> @@ -719,20 +744,22 @@ do_sign_tx(Request = #{"public_id" := ID, "payload" := CallData, "network_id" := #key{pair = #{secret := SecKey}} -> BinaryTX = list_to_binary(CallData), SignedTX = hz:sign_tx(BinaryTX, SecKey, BinNID), - do_sign_tx2(Request#{"signed" => true, "payload" := SignedTX}); + SignedRequest = Request#{"signed" => true, "payload" := SignedTX}, + ResponseKeys = + ["grids", + "chain", + "network_id", + "type", + "public_id", + "payload", + "signed"], + post_grids_response(ResponseKeys, SignedRequest); false -> gd_gui:trouble({bad_key, ID}) end. -do_sign_tx2(Request = #{"url" := URL}) -> - ResponseKeys = - ["grids", - "chain", - "network_id", - "type", - "public_id", - "payload", - "signed"], + +post_grids_response(ResponseKeys, Request = #{"url" := URL}) -> Response = zj:encode(maps:with(ResponseKeys, Request)), case httpc:request(post, {URL, [], "application/json", Response}, [], []) of {ok, {{_, 200, _}, _, JSON}} -> log(info, "Signed TX posted: ~p", [JSON]); diff --git a/src/gd_gui.erl b/src/gd_gui.erl index 3b583aa..a5e7b65 100644 --- a/src/gd_gui.erl +++ b/src/gd_gui.erl @@ -1060,6 +1060,48 @@ do_grids_mess_sig2(Request = #{"grids" := 1, ?wxID_CANCEL -> ok end, wxDialog:destroy(Dialog); +do_grids_mess_sig2(Request = #{"grids" := 1, + "type" := "binary", + "url" := URL, + "public_id" := ID, + "payload" := Base64}, + #s{frame = Frame, j = J}) -> + Dialog = wxDialog:new(Frame, ?wxID_ANY, J("Binary Data Signature Request")), + Sizer = wxBoxSizer:new(?wxVERTICAL), + Instruction = + J("The server at the URL below is requesting you sign the following binary data."), + InstTx = wxStaticText:new(Dialog, ?wxID_ANY, Instruction), + AcctSz = wxStaticBoxSizer:new(?wxVERTICAL, Dialog, [{label, J("Signature Account")}]), + AcctTx = wxStaticText:new(Dialog, ?wxID_ANY, ID), + _ = wxStaticBoxSizer:add(AcctSz, AcctTx, zxw:flags(wide)), + URL_Label = J("Originating URL"), + URL_Sz = wxStaticBoxSizer:new(?wxVERTICAL, Dialog, [{label, URL_Label}]), + URL_Tx = wxStaticText:new(Dialog, ?wxID_ANY, URL), + _ = wxStaticBoxSizer:add(URL_Sz, URL_Tx, zxw:flags(wide)), + MessSz = wxStaticBoxSizer:new(?wxVERTICAL, Dialog, [{label, J("Base-64 Data")}]), + MessStyle = ?wxTE_MULTILINE bor ?wxTE_READONLY, + MessTx = wxTextCtrl:new(Dialog, ?wxID_ANY, [{value, Base64}, {style, MessStyle}]), + _ = wxStaticBoxSizer:add(MessSz, MessTx, zxw:flags(wide)), + ButtSz = wxBoxSizer:new(?wxHORIZONTAL), + Affirm = wxButton:new(Dialog, ?wxID_OK), + Cancel = wxButton:new(Dialog, ?wxID_CANCEL), + _ = wxBoxSizer:add(ButtSz, Affirm, zxw:flags(wide)), + _ = wxBoxSizer:add(ButtSz, Cancel, zxw:flags(wide)), + _ = wxBoxSizer:add(Sizer, InstTx, zxw:flags(wide)), + _ = wxBoxSizer:add(Sizer, AcctSz, zxw:flags(wide)), + _ = wxBoxSizer:add(Sizer, URL_Sz, zxw:flags(wide)), + _ = wxBoxSizer:add(Sizer, MessSz, zxw:flags(wide)), + _ = wxBoxSizer:add(Sizer, ButtSz, zxw:flags(base)), + ok = wxDialog:setSizer(Dialog, Sizer), + ok = wxDialog:setSize(Dialog, {500, 500}), + ok = wxBoxSizer:layout(Sizer), + ok = wxFrame:center(Dialog), + ok = + case wxDialog:showModal(Dialog) of + ?wxID_OK -> gd_con:sign_binary(Request); + ?wxID_CANCEL -> ok + end, + wxDialog:destroy(Dialog); do_grids_mess_sig2(Request = #{"grids" := 1, "type" := "tx", "url" := URL, From 44463574372e113fd213f746bb8bb36b680d2c5c Mon Sep 17 00:00:00 2001 From: Craig Everett Date: Sat, 25 Oct 2025 12:11:03 +0900 Subject: [PATCH 3/5] Add interface functions --- src/gd_con.erl | 50 ++++++++++++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/src/gd_con.erl b/src/gd_con.erl index f1d2992..e229b80 100644 --- a/src/gd_con.erl +++ b/src/gd_con.erl @@ -14,7 +14,8 @@ selected/1, network/0, password/2, refresh/0, - nonce/1, spend/1, chain/1, grids/1, sign_mess/1, sign_tx/1, sign_call/3, dry_run/2, + nonce/1, spend/1, chain/1, grids/1, + sign_mess/1, sign_binary/1, sign_tx/1, sign_call/3, dry_run/2, deploy/3, make_key/6, recover_key/1, mnemonic/1, rename_key/2, drop_key/1, list_keys/0, add_node/1, set_sole_node/1]). @@ -172,6 +173,13 @@ sign_mess(Request) -> gen_server:cast(?MODULE, {sign_mess, Request}). +-spec sign_binary(Request) -> ok + when Request :: map(). + +sign_binary(Request) -> + gen_server:cast(?MODULE, {sign_binary, Request}). + + -spec sign_tx(Request) -> ok when Request :: map(). @@ -431,6 +439,9 @@ handle_cast({grids, String}, State) -> handle_cast({sign_mess, Request}, State) -> ok = do_sign_mess(Request, State), {noreply, State}; +handle_cast({sign_binary, Request}, State) -> + ok = do_sign_binary(Request, State), + {noreply, State}; handle_cast({sign_tx, Request}, State) -> ok = do_sign_tx(Request, State), {noreply, State}; @@ -689,22 +700,23 @@ do_grids_sig2(WTF) -> do_sign_mess(Request = #{"public_id" := ID}, #s{wallet = #wallet{keys = Keys}}) -> case lists:keyfind(ID, #key.id, Keys) of - #key{pair = #{secret := SecKey}} -> - Sig = base64:encode(hz:sign_message(list_to_binary(Message), SecKey)), - SignedRequest = maps:put("signature", Sig, Request), - ResponseKeys = - ["grids", - "chain", - "network_id", - "type", - "public_id", - "payload", - "signature"], - post_grids_response(ResponseKeys, SignedRequest); - false -> - gd_gui:trouble({bad_key, ID}) + #key{pair = #{secret := SecKey}} -> do_sign_mess2(Request, SecKey); + false -> gd_gui:trouble({bad_key, ID}) end. +do_sign_mess2(Request = #{"payload" := Message}, SecKey) -> + Sig = base64:encode(hz:sign_message(list_to_binary(Message), SecKey)), + SignedRequest = maps:put("signature", Sig, Request), + ResponseKeys = + ["grids", + "chain", + "network_id", + "type", + "public_id", + "payload", + "signature"], + post_grids_response(ResponseKeys, SignedRequest). + do_sign_binary(Request = #{"public_id" := ID}, #s{wallet = #wallet{keys = Keys}}) -> case lists:keyfind(ID, #key.id, Keys) of @@ -715,7 +727,7 @@ do_sign_binary(Request = #{"public_id" := ID}, #s{wallet = #wallet{keys = Keys}} do_sign_binary2(Request = #{"payload" := Payload}, SecKey) -> case base64_decode(Payload) of {ok, Binary} -> - Sig = base64:encode(hz_sign_binary(Binary, SecKey)), + Sig = base64:encode(hz:sign_binary(Binary, SecKey)), SignedRequest = maps:put("signature", Sig, Request), ResponseKeys = ["grids", @@ -730,12 +742,6 @@ do_sign_binary2(Request = #{"payload" := Payload}, SecKey) -> gd_gui:trouble(Error) end. -hz_sign_binary(Binary, SecKey) -> - Prefix = <<"Gajumaru Signed Binary:">>, - Target = <>, - {ok, Hash} = eblake2:blake2b(32, Target), - ecu_eddsa:sign_detached(Hashed, SecKey). - do_sign_tx(Request = #{"public_id" := ID, "payload" := CallData, "network_id" := NID}, #s{wallet = #wallet{keys = Keys}}) -> From 25550cca328280a29c186d06552a32c14704e88a Mon Sep 17 00:00:00 2001 From: Craig Everett Date: Wed, 29 Oct 2025 16:15:29 +0900 Subject: [PATCH 4/5] Verup --- ebin/gajudesk.app | 2 +- src/gajudesk.erl | 2 +- src/gd_con.erl | 2 +- src/gd_grids.erl | 2 +- src/gd_gui.erl | 2 +- src/gd_jt.erl | 2 +- src/gd_sophia_editor.erl | 2 +- src/gd_sup.erl | 2 +- src/gd_v.erl | 2 +- src/gd_v_devman.erl | 2 +- src/gd_v_netman.erl | 2 +- src/gd_v_wallman.erl | 2 +- zomp.meta | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/ebin/gajudesk.app b/ebin/gajudesk.app index 676fc99..34d0b60 100644 --- a/ebin/gajudesk.app +++ b/ebin/gajudesk.app @@ -3,7 +3,7 @@ {registered,[]}, {included_applications,[]}, {applications,[stdlib,kernel,sasl,ssl]}, - {vsn,"0.7.0"}, + {vsn,"0.8.0"}, {modules,[gajudesk,gd_con,gd_grids,gd_gui,gd_jt, gd_sophia_editor,gd_sup,gd_v,gd_v_devman,gd_v_netman, gd_v_wallman]}, diff --git a/src/gajudesk.erl b/src/gajudesk.erl index 6ae95a4..bc0eb86 100644 --- a/src/gajudesk.erl +++ b/src/gajudesk.erl @@ -3,7 +3,7 @@ %%% @end -module(gajudesk). --vsn("0.7.0"). +-vsn("0.8.0"). -behavior(application). -author("Craig Everett "). -copyright("QPQ AG "). diff --git a/src/gd_con.erl b/src/gd_con.erl index e229b80..3f8f64e 100644 --- a/src/gd_con.erl +++ b/src/gd_con.erl @@ -3,7 +3,7 @@ %%% @end -module(gd_con). --vsn("0.7.0"). +-vsn("0.8.0"). -author("Craig Everett "). -copyright("QPQ AG "). -license("GPL-3.0-or-later"). diff --git a/src/gd_grids.erl b/src/gd_grids.erl index a639e30..3bf8bda 100644 --- a/src/gd_grids.erl +++ b/src/gd_grids.erl @@ -37,7 +37,7 @@ %%% @end -module(gd_grids). --vsn("0.7.0"). +-vsn("0.8.0"). -author("Craig Everett "). -copyright("QPQ AG "). -license("GPL-3.0-or-later"). diff --git a/src/gd_gui.erl b/src/gd_gui.erl index a5e7b65..df5137d 100644 --- a/src/gd_gui.erl +++ b/src/gd_gui.erl @@ -3,7 +3,7 @@ %%% @end -module(gd_gui). --vsn("0.7.0"). +-vsn("0.8.0"). -author("Craig Everett "). -copyright("QPQ AG "). -license("GPL-3.0-or-later"). diff --git a/src/gd_jt.erl b/src/gd_jt.erl index 6293b29..2ce39d5 100644 --- a/src/gd_jt.erl +++ b/src/gd_jt.erl @@ -15,7 +15,7 @@ %%% translation library is retained). -module(gd_jt). --vsn("0.7.0"). +-vsn("0.8.0"). -export([read_translations/1, j/2, oneshot_j/2]). diff --git a/src/gd_sophia_editor.erl b/src/gd_sophia_editor.erl index 448bb7c..1455ac7 100644 --- a/src/gd_sophia_editor.erl +++ b/src/gd_sophia_editor.erl @@ -1,5 +1,5 @@ -module(gd_sophia_editor). --vsn("0.7.0"). +-vsn("0.8.0"). -export([new/1, update/2, get_text/1, set_text/2]). diff --git a/src/gd_sup.erl b/src/gd_sup.erl index 5f92335..92d872d 100644 --- a/src/gd_sup.erl +++ b/src/gd_sup.erl @@ -12,7 +12,7 @@ %%% @end -module(gd_sup). --vsn("0.7.0"). +-vsn("0.8.0"). -behaviour(supervisor). -author("Craig Everett "). -copyright("QPQ AG "). diff --git a/src/gd_v.erl b/src/gd_v.erl index c93be9b..7f76601 100644 --- a/src/gd_v.erl +++ b/src/gd_v.erl @@ -1,5 +1,5 @@ -module(gd_v). --vsn("0.7.0"). +-vsn("0.8.0"). -author("Craig Everett "). -copyright("QPQ AG "). -license("GPL-3.0-or-later"). diff --git a/src/gd_v_devman.erl b/src/gd_v_devman.erl index 65b3487..610491f 100644 --- a/src/gd_v_devman.erl +++ b/src/gd_v_devman.erl @@ -1,5 +1,5 @@ -module(gd_v_devman). --vsn("0.7.0"). +-vsn("0.8.0"). -author("Craig Everett "). -copyright("QPQ AG "). -license("GPL-3.0-or-later"). diff --git a/src/gd_v_netman.erl b/src/gd_v_netman.erl index 000688a..6b99188 100644 --- a/src/gd_v_netman.erl +++ b/src/gd_v_netman.erl @@ -1,5 +1,5 @@ -module(gd_v_netman). --vsn("0.7.0"). +-vsn("0.8.0"). -author("Craig Everett "). -copyright("QPQ AG "). -license("GPL-3.0-or-later"). diff --git a/src/gd_v_wallman.erl b/src/gd_v_wallman.erl index cdf8514..1237005 100644 --- a/src/gd_v_wallman.erl +++ b/src/gd_v_wallman.erl @@ -13,7 +13,7 @@ -module(gd_v_wallman). --vsn("0.7.0"). +-vsn("0.8.0"). -author("Craig Everett "). -copyright("QPQ AG "). -license("GPL-3.0-or-later"). diff --git a/zomp.meta b/zomp.meta index 7e49fef..f79634e 100644 --- a/zomp.meta +++ b/zomp.meta @@ -4,7 +4,7 @@ {prefix,"gd"}. {author,"Craig Everett"}. {desc,"A desktop client for the Gajumaru network of blockchain networks"}. -{package_id,{"otpr","gajudesk",{0,7,0}}}. +{package_id,{"otpr","gajudesk",{0,8,0}}}. {deps,[{"otpr","hakuzaru",{0,6,1}}, {"otpr","eblake2",{1,0,1}}, {"otpr","base58",{0,1,1}}, From 363dfaf271a6546ac89876b17cf6abb9435b36b5 Mon Sep 17 00:00:00 2001 From: Craig Everett Date: Wed, 29 Oct 2025 16:16:23 +0900 Subject: [PATCH 5/5] Update hz dep --- zomp.meta | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/zomp.meta b/zomp.meta index f79634e..7f20576 100644 --- a/zomp.meta +++ b/zomp.meta @@ -2,10 +2,10 @@ {type,gui}. {modules,[]}. {prefix,"gd"}. -{author,"Craig Everett"}. {desc,"A desktop client for the Gajumaru network of blockchain networks"}. +{author,"Craig Everett"}. {package_id,{"otpr","gajudesk",{0,8,0}}}. -{deps,[{"otpr","hakuzaru",{0,6,1}}, +{deps,[{"otpr","hakuzaru",{0,7,0}}, {"otpr","eblake2",{1,0,1}}, {"otpr","base58",{0,1,1}}, {"otpr","gmserialization",{0,1,3}},