Compare commits

...

7 Commits

13 changed files with 60 additions and 121 deletions

View File

@ -3,7 +3,7 @@
{registered,[]},
{included_applications,[]},
{applications,[stdlib,kernel,sasl,ssl]},
{vsn,"0.5.1"},
{vsn,"0.5.2"},
{modules,[gajudesk,gd_con,gd_grids,gd_gui,gd_jt,gd_key_master,
gd_sup,gd_v,gd_v_devman,gd_v_netman,gd_v_wallman]},
{mod,{gajudesk,[]}}]}.

View File

@ -3,7 +3,7 @@
%%% @end
-module(gajudesk).
-vsn("0.5.1").
-vsn("0.5.2").
-behavior(application).
-author("Craig Everett <craigeverett@qpq.swiss>").
-copyright("QPQ AG <info@qpq.swiss>").

View File

@ -3,7 +3,7 @@
%%% @end
-module(gd_con).
-vsn("0.5.1").
-vsn("0.5.2").
-author("Craig Everett <craigeverett@qpq.swiss>").
-copyright("QPQ AG <info@qpq.swiss>").
-license("GPL-3.0-or-later").
@ -14,7 +14,7 @@
selected/1,
password/2,
refresh/0,
nonce/1, spend/2, 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_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]).
@ -135,12 +135,11 @@ nonce(ID) ->
gen_server:call(?MODULE, {nonce, ID}).
-spec spend(KeyID, TX) -> ok
when KeyID :: gajudesk:id(),
TX :: #spend_tx{}.
-spec spend(TX) -> ok
when TX :: #spend_tx{}.
spend(KeyID, TX) ->
gen_server:cast(?MODULE, {spend, KeyID, TX}).
spend(TX) ->
gen_server:cast(?MODULE, {spend, TX}).
-spec chain(ID) -> ok
@ -400,8 +399,8 @@ handle_cast({password, Old, New}, State) ->
handle_cast(refresh, State) ->
NewState = do_refresh(State),
{noreply, NewState};
handle_cast({spend, KeyID, TX}, State) ->
ok = do_spend(KeyID, TX, State),
handle_cast({spend, TX}, State) ->
ok = do_spend(TX, State),
{noreply, State};
handle_cast({chain, ID}, State) ->
NewState = do_chain(ID, State),
@ -589,7 +588,6 @@ ensure_hz_set(Node = #node{ip = IP, external = Port}) ->
[{IP, Port}] ->
case hz:status() of
{ok, #{"network_id" := ChainID}} ->
ok = hz:network_id(ChainID),
ok = gd_gui:chain(ChainID, Node),
{ok, list_to_binary(ChainID)};
{error, no_nodes} ->
@ -714,7 +712,7 @@ do_sign_tx(Request = #{"public_id" := ID, "payload" := CallData, "network_id" :=
case lists:keyfind(ID, #key.id, Keys) of
#key{pair = #{secret := SecKey}} ->
BinaryTX = list_to_binary(CallData),
SignedTX = sign_tx_hash(BinaryTX, SecKey, BinNID),
SignedTX = hz:sign_tx(BinaryTX, SecKey, BinNID),
do_sign_tx2(Request#{"signed" => true, "payload" := SignedTX});
false ->
gd_gui:trouble({bad_key, ID})
@ -736,29 +734,13 @@ do_sign_tx2(Request = #{"url" := URL}) ->
Error -> gd_gui:trouble(Error)
end.
sign_tx_hash(Unsigned, SecKey, NetworkID) ->
{ok, TX_Data} = gmser_api_encoder:safe_decode(transaction, Unsigned),
{ok, Hash} = eblake2:blake2b(32, TX_Data),
NetworkHash = <<NetworkID/binary, Hash/binary>>,
Signature = ecu_eddsa:sign_detached(NetworkHash, SecKey),
SigTxType = signed_tx,
SigTxVsn = 1,
SigTemplate =
[{signatures, [binary]},
{transaction, binary}],
TX =
[{signatures, [Signature]},
{transaction, TX_Data}],
SignedTX = gmser_chain_objects:serialize(SigTxType, SigTxVsn, SigTemplate, TX),
gmser_api_encoder:encode(transaction, SignedTX).
do_sign_call(#s{wallet = #wallet{keys = Keys, chain_id = ChainID}},
ConID,
PubKey,
TX) ->
#key{pair = #{secret := SecKey}} = lists:keyfind(PubKey, #key.id, Keys),
SignedTX = sign_tx_hash(TX, SecKey, ChainID),
SignedTX = hz:sign_tx(TX, SecKey, ChainID),
case hz:post_tx(SignedTX) of
{ok, Data = #{"tx_hash" := TXHash}} ->
ok = tell("TX succeded with: ~p", [TXHash]),
@ -791,60 +773,32 @@ do_dry_run(ConID, TX) ->
end.
do_spend(KeyID, TX, State = #s{wallet = #wallet{keys = Keys}}) ->
case lists:keyfind(KeyID, #key.id, Keys) of
do_spend(#spend_tx{sender_id = SenderID,
recipient_id = RecipientID,
amount = Amount,
gas_price = GasPrice,
gas = Gas,
ttl = TTL,
nonce = Nonce,
payload = Payload},
#s{wallet = #wallet{keys = Keys, chain_id = NetworkID}}) ->
case lists:keyfind(SenderID, #key.id, Keys) of
#key{pair = #{secret := SecKey}} ->
do_spend2(SecKey, TX, State);
Outcome = hz:spend(SenderID,
SecKey,
RecipientID,
Amount,
GasPrice,
Gas,
TTL,
Nonce,
Payload,
NetworkID),
tell(info, "Outcome: ~p", [Outcome]);
false ->
log(warning, "Tried do_spend with a bad key: ~p", [KeyID])
log(warning, "Tried do_spend with a bad key: ~p", [SenderID])
end.
do_spend2(SecKey,
#spend_tx{sender_id = SenderID,
recipient_id = RecipientID,
amount = Amount,
gas_price = GasPrice,
gas = Gas,
ttl = TTL,
nonce = Nonce,
payload = Payload},
#s{wallet = #wallet{chain_id = ChainID}}) ->
Type = spend_tx,
Vsn = 1,
Fields =
[{sender_id, SenderID},
{recipient_id, RecipientID},
{amount, Amount},
{gas_price, GasPrice},
{gas, Gas},
{ttl, TTL},
{nonce, Nonce},
{payload, Payload}],
Template =
[{sender_id, id},
{recipient_id, id},
{amount, int},
{gas_price, int},
{gas, int},
{ttl, int},
{nonce, int},
{payload, binary}],
BinaryTX = gmser_chain_objects:serialize(Type, Vsn, Template, Fields),
NetworkTX = <<ChainID/binary, BinaryTX/binary>>,
Signature = ecu_eddsa:sign_detached(NetworkTX, SecKey),
SigTxType = signed_tx,
SigTxVsn = 1,
SigTemplate =
[{signatures, [binary]},
{transaction, binary}],
TX_Data =
[{signatures, [Signature]},
{transaction, BinaryTX}],
SignedTX = gmser_chain_objects:serialize(SigTxType, SigTxVsn, SigTemplate, TX_Data),
Encoded = gmser_api_encoder:encode(transaction, SignedTX),
Outcome = hz:post_tx(Encoded),
tell("Outcome: ~p", [Outcome]).
do_list_keys(#s{selected = Selected, wallet = #wallet{poas = POAs}}) ->
{ok, Selected, [ID || #poa{id = ID} <- POAs]};
@ -996,7 +950,7 @@ do_deploy(Build,
end.
do_deploy2(SecKey, CreateTX, ChainID) ->
SignedTX = sign_tx_hash(CreateTX, SecKey, ChainID),
SignedTX = hz:sign_tx(CreateTX, SecKey, ChainID),
tell(info, "SignedTX: ~p", [SignedTX]),
case hz:post_tx(SignedTX) of
{ok, Data = #{"tx_hash" := TXHash}} ->

View File

@ -37,7 +37,7 @@
%%% @end
-module(gd_grids).
-vsn("0.5.1").
-vsn("0.5.2").
-author("Craig Everett <craigeverett@qpq.swiss>").
-copyright("QPQ AG <info@qpq.swiss>").
-license("GPL-3.0-or-later").

View File

@ -3,7 +3,7 @@
%%% @end
-module(gd_gui).
-vsn("0.5.1").
-vsn("0.5.2").
-author("Craig Everett <craigeverett@qpq.swiss>").
-copyright("QPQ AG <info@qpq.swiss>").
-license("GPL-3.0-or-later").
@ -773,9 +773,8 @@ spend2(#poa{id = ID, name = Name}, Nonce, Height, State = #s{frame = Frame, j =
ok =
case wxDialog:showModal(Dialog) of
?wxID_OK ->
{ok, PK} = decode_account_id(ID),
TX =
#spend_tx{sender_id = gmser_id:create(account, PK),
#spend_tx{sender_id = ID,
recipient_id = wxTextCtrl:getValue(ToTx),
amount = wxTextCtrl:getValue(AmtTx),
gas_price = wxSlider:getValue(GasSl),
@ -783,49 +782,35 @@ spend2(#poa{id = ID, name = Name}, Nonce, Height, State = #s{frame = Frame, j =
ttl = Height + wxSlider:getValue(TTL_Sl),
nonce = Nonce,
payload = wxTextCtrl:getValue(DataTx)},
clean_spend(ID, TX);
clean_spend(TX);
?wxID_CANCEL ->
ok
end,
ok = wxDialog:destroy(Dialog),
State.
clean_spend(_, #spend_tx{recipient_id = ""}) ->
clean_spend(#spend_tx{recipient_id = ""}) ->
ok;
clean_spend(ID, TX = #spend_tx{recipient_id = S}) when is_list(S) ->
case decode_account_id(S) of
{ok, PK} -> clean_spend(ID, TX#spend_tx{recipient_id = gmser_id:create(account, PK)});
Error -> tell("Decode recipient_id failed with: ~tp", [Error])
end;
clean_spend(ID, TX = #spend_tx{amount = S}) when is_list(S) ->
clean_spend( TX = #spend_tx{amount = S}) when is_list(S) ->
case string_to_price(S) of
{ok, Amount} -> clean_spend(ID, TX#spend_tx{amount = Amount});
{ok, Amount} -> clean_spend(TX#spend_tx{amount = Amount});
{error, _} -> ok
end;
clean_spend(ID, TX = #spend_tx{gas_price = S}) when is_list(S) ->
clean_spend(TX = #spend_tx{gas_price = S}) when is_list(S) ->
case is_int(S) of
true -> clean_spend(ID, TX#spend_tx{gas_price = list_to_integer(S)});
true -> clean_spend(TX#spend_tx{gas_price = list_to_integer(S)});
false -> ok
end;
clean_spend(ID, TX = #spend_tx{gas = S}) when is_list(S) ->
clean_spend(TX = #spend_tx{gas = S}) when is_list(S) ->
case is_int(S) of
true -> clean_spend(ID, TX#spend_tx{gas = list_to_integer(S)});
true -> clean_spend(TX#spend_tx{gas = list_to_integer(S)});
false -> ok
end;
clean_spend(ID, TX = #spend_tx{payload = S}) when is_list(S) ->
clean_spend(ID, TX#spend_tx{payload = list_to_binary(S)});
clean_spend(ID, TX) ->
gd_con:spend(ID, TX).
clean_spend(TX = #spend_tx{payload = S}) when is_list(S) ->
clean_spend(TX#spend_tx{payload = list_to_binary(S)});
clean_spend(TX) ->
gd_con:spend(TX).
decode_account_id(S) when is_list(S) ->
decode_account_id(list_to_binary(S));
decode_account_id(B) ->
try
{account_pubkey, PK} = gmser_api_encoder:decode(B),
{ok, PK}
catch
E:R -> {E, R}
end.
is_int(S) ->
lists:all(fun(C) -> $0 =< C andalso C =< $9 end, S).

View File

@ -15,7 +15,7 @@
%%% translation library is retained).
-module(gd_jt).
-vsn("0.5.1").
-vsn("0.5.2").
-export([read_translations/1, j/2, oneshot_j/2]).

View File

@ -8,7 +8,7 @@
%%% @end
-module(gd_key_master).
-vsn("0.5.1").
-vsn("0.5.2").
-export([make_key/2, encode/1, decode/1]).

View File

@ -12,7 +12,7 @@
%%% @end
-module(gd_sup).
-vsn("0.5.1").
-vsn("0.5.2").
-behaviour(supervisor).
-author("Craig Everett <craigeverett@qpq.swiss>").
-copyright("QPQ AG <info@qpq.swiss>").

View File

@ -1,5 +1,5 @@
-module(gd_v).
-vsn("0.5.1").
-vsn("0.5.2").
-author("Craig Everett <craigeverett@qpq.swiss>").
-copyright("QPQ AG <info@qpq.swiss>").
-license("GPL-3.0-or-later").

View File

@ -1,5 +1,5 @@
-module(gd_v_devman).
-vsn("0.5.1").
-vsn("0.5.2").
-author("Craig Everett <craigeverett@qpq.swiss>").
-copyright("QPQ AG <info@qpq.swiss>").
-license("GPL-3.0-or-later").

View File

@ -1,5 +1,5 @@
-module(gd_v_netman).
-vsn("0.5.1").
-vsn("0.5.2").
-author("Craig Everett <zxq9@zxq9.com>").
-copyright("QPQ AG <info@qpq.swiss>").
-license("GPL-3.0-or-later").

View File

@ -1,5 +1,5 @@
-module(gd_v_wallman).
-vsn("0.5.1").
-vsn("0.5.2").
-author("Craig Everett <zxq9@zxq9.com>").
-copyright("QPQ AG <info@qpq.swiss>").
-license("GPL-3.0-or-later").

View File

@ -2,10 +2,10 @@
{type,gui}.
{modules,[]}.
{prefix,"gd"}.
{desc,"A desktop client for the Gajumaru network of blockchain networks"}.
{author,"Craig Everett"}.
{package_id,{"otpr","gajudesk",{0,5,1}}}.
{deps,[{"otpr","hakuzaru",{0,4,0}},
{desc,"A desktop client for the Gajumaru network of blockchain networks"}.
{package_id,{"otpr","gajudesk",{0,5,2}}}.
{deps,[{"otpr","hakuzaru",{0,5,0}},
{"otpr","gmserialization",{0,1,3}},
{"otpr","sophia",{9,0,0}},
{"otpr","gmbytecode",{3,4,1}},