Compare commits
7 Commits
4b6f761ec4
...
9ec748d469
Author | SHA1 | Date | |
---|---|---|---|
9ec748d469 | |||
3a15466901 | |||
4fd4ab3f54 | |||
970eb1680f | |||
b6bdfc8095 | |||
f4a9dbcaf8 | |||
80691524df |
@ -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,[]}}]}.
|
||||
|
@ -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>").
|
||||
|
104
src/gd_con.erl
104
src/gd_con.erl
@ -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,16 +773,7 @@ do_dry_run(ConID, TX) ->
|
||||
end.
|
||||
|
||||
|
||||
do_spend(KeyID, TX, State = #s{wallet = #wallet{keys = Keys}}) ->
|
||||
case lists:keyfind(KeyID, #key.id, Keys) of
|
||||
#key{pair = #{secret := SecKey}} ->
|
||||
do_spend2(SecKey, TX, State);
|
||||
false ->
|
||||
log(warning, "Tried do_spend with a bad key: ~p", [KeyID])
|
||||
end.
|
||||
|
||||
do_spend2(SecKey,
|
||||
#spend_tx{sender_id = SenderID,
|
||||
do_spend(#spend_tx{sender_id = SenderID,
|
||||
recipient_id = RecipientID,
|
||||
amount = Amount,
|
||||
gas_price = GasPrice,
|
||||
@ -808,42 +781,23 @@ do_spend2(SecKey,
|
||||
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]).
|
||||
#s{wallet = #wallet{keys = Keys, chain_id = NetworkID}}) ->
|
||||
case lists:keyfind(SenderID, #key.id, Keys) of
|
||||
#key{pair = #{secret := SecKey}} ->
|
||||
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", [SenderID])
|
||||
end.
|
||||
|
||||
|
||||
do_list_keys(#s{selected = Selected, wallet = #wallet{poas = 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}} ->
|
||||
|
@ -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").
|
||||
|
@ -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).
|
||||
|
@ -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]).
|
||||
|
||||
|
||||
|
@ -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]).
|
||||
|
@ -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>").
|
||||
|
@ -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").
|
||||
|
@ -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").
|
||||
|
@ -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").
|
||||
|
@ -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").
|
||||
|
@ -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}},
|
||||
|
Loading…
x
Reference in New Issue
Block a user