Dekajigger spend encoding from string inputs

This commit is contained in:
Craig Everett 2024-10-10 15:05:28 +09:00
parent b41e3ed1fd
commit 3afc3cfa02
2 changed files with 95 additions and 13 deletions

View File

@ -12,6 +12,7 @@
-behavior(gen_server).
-export([open_wallet/2, close_wallet/0, password/2,
nonce/1, spend/2,
make_key/6, recover_key/1, mnemonic/1, rename_key/2, drop_key/1]).
-export([encrypt/2, decrypt/2]).
-export([start_link/0, stop/0, save/1]).
@ -61,6 +62,23 @@ password(Old, New) ->
gen_server:cast(?MODULE, {password, Old, New}).
-spec nonce(ID) -> {ok, Nonce} | {error, Reason}
when ID :: clutch:id(),
Nonce :: integer(),
Reason :: term(). % FIXME
% FIXME
nonce(_) -> {ok, 42}.
-spec spend(KeyID, TX) -> ok
when KeyID :: clutch:id(),
TX :: #spend_tx{}.
spend(KeyID, TX) ->
gen_server:cast(?MODULE, {spend, KeyID, TX}).
-spec make_key(Type, Size, Name, Seed, Encoding, Transform) -> ok
when Type :: {eddsa, ed25519},
Size :: 256,
@ -200,6 +218,15 @@ handle_call(Unexpected, From, State) ->
%% The gen_server:handle_cast/2 callback.
%% See: http://erlang.org/doc/man/gen_server.html#Module:handle_cast-2
handle_cast({open_wallet, Path, Phrase}, State) ->
NewState = do_open_wallet(Path, Phrase, State),
{noreply, NewState};
handle_cast({password, Old, New}, State) ->
NewState = do_password(Old, New, State),
{noreply, NewState};
handle_cast({spend, KeyID, TX}, State) ->
ok = do_spend(KeyID, TX, State),
{noreply, State};
handle_cast({make_key, Name, Seed, Encoding, Transform}, State) ->
NewState = do_make_key(Name, Seed, Encoding, Transform, State),
{noreply, NewState};
@ -212,12 +239,6 @@ handle_cast({rename_key, ID, NewName}, State) ->
handle_cast({drop_key, ID}, State) ->
NewState = do_drop_key(ID, State),
{noreply, NewState};
handle_cast({open_wallet, Path, Phrase}, State) ->
NewState = do_open_wallet(Path, Phrase, State),
{noreply, NewState};
handle_cast({password, Old, New}, State) ->
NewState = do_password(Old, New, State),
{noreply, NewState};
handle_cast(stop, State) ->
ok = zx:stop(),
{noreply, State};
@ -443,7 +464,7 @@ do_spend(KeyID, TX, State = #s{wallet = #wallet{keys = Keys}}) ->
do_spend2(PrivKey,
#spend_tx{sender_id = SenderID,
recipient_id = RecipientId,
recipient_id = RecipientID,
amount = Amount,
gas_price = GasPrice,
gas = Gas,
@ -455,7 +476,7 @@ do_spend2(PrivKey,
Vsn = 1,
Fields =
[{sender_id, SenderID},
{recipient_id, RecipientId},
{recipient_id, RecipientID},
{amount, Amount},
{gas_price, GasPrice},
{gas, Gas},

View File

@ -589,8 +589,17 @@ spend(State = #s{picker = Picker}) ->
Selected -> spend(Selected + 1, State)
end.
spend(Selected, State = #s{frame = Frame, j = J, accounts = Accounts}) ->
#poa{id = ID, name = Name} = lists:nth(Selected, Accounts),
spend(Selected, State = #s{accounts = Accounts}) ->
POA = #poa{id = ID} = lists:nth(Selected, Accounts),
case gmc_con:nonce(ID) of
{ok, Nonce} ->
spend2(POA, Nonce, State);
{error, Reason} ->
tell("spend/2 failed to get nonce with ~tp", [Reason]),
State
end.
spend2(#poa{id = ID, name = Name}, Nonce, State = #s{frame = Frame, j = J}) ->
Dialog = wxDialog:new(Frame, ?wxID_ANY, J("Transfer"), [{size, {500, 400}}]),
Sizer = wxBoxSizer:new(?wxVERTICAL),
@ -636,12 +645,64 @@ spend(Selected, State = #s{frame = Frame, j = J, accounts = Accounts}) ->
ok = wxFrame:center(Dialog),
ok =
case wxDialog:showModal(Dialog) of
?wxID_OK -> gmc_con:drop_key(ID);
?wxID_CANCEL -> ok
?wxID_OK ->
{ok, PK} = decode_account_id(ID),
TX =
#spend_tx{sender_id = aeser_id:create(account, PK),
recipient_id = wxTextCtrl:getValue(ToTx),
amount = wxTextCtrl:getValue(AmtTx),
gas_price = wxSlider:getValue(GasSl),
gas = 20000,
ttl = 175320,
nonce = Nonce,
payload = wxTextCtrl:getValue(DataTx)},
clean_spend(ID, TX);
?wxID_CANCEL ->
ok
end,
ok = wxDialog:destroy(Dialog),
State.
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 = aeser_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) ->
case string_to_price(S) of
{ok, Amount} -> clean_spend(ID, TX#spend_tx{amount = Amount});
{error, _} -> ok
end;
clean_spend(ID, 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)});
false -> ok
end;
clean_spend(ID, 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)});
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) ->
gmc_con:spend(ID, TX).
decode_account_id(S) when is_list(S) ->
decode_account_id(list_to_binary(S));
decode_account_id(B) ->
try
{account_pubkey, PK} = aeser_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).
grids_dialogue(State) ->
%grids_dialogue(State = #s{frame = Frame, j = J}) ->