Add GRIDS parser
This commit is contained in:
parent
50f1ea1b8d
commit
d77ee6d8f5
@ -13,7 +13,7 @@
|
|||||||
-behavior(gen_server).
|
-behavior(gen_server).
|
||||||
-export([show_ui/1,
|
-export([show_ui/1,
|
||||||
open_wallet/2, close_wallet/0, password/2,
|
open_wallet/2, close_wallet/0, password/2,
|
||||||
nonce/1, spend/2, chain/1,
|
nonce/1, spend/2, chain/1, grids/1,
|
||||||
make_key/6, recover_key/1, mnemonic/1, rename_key/2, drop_key/1]).
|
make_key/6, recover_key/1, mnemonic/1, rename_key/2, drop_key/1]).
|
||||||
-export([encrypt/2, decrypt/2]).
|
-export([encrypt/2, decrypt/2]).
|
||||||
-export([start_link/0, stop/0, save/1, save/2]).
|
-export([start_link/0, stop/0, save/1, save/2]).
|
||||||
@ -103,6 +103,12 @@ chain(ID) ->
|
|||||||
gen_server:cast(?MODULE, {chain, ID}).
|
gen_server:cast(?MODULE, {chain, ID}).
|
||||||
|
|
||||||
|
|
||||||
|
-spec grids(string()) -> ok.
|
||||||
|
|
||||||
|
grids(String) ->
|
||||||
|
gen_server:cast(?MODULE, {grids, String}).
|
||||||
|
|
||||||
|
|
||||||
-spec make_key(Type, Size, Name, Seed, Encoding, Transform) -> ok
|
-spec make_key(Type, Size, Name, Seed, Encoding, Transform) -> ok
|
||||||
when Type :: {eddsa, ed25519},
|
when Type :: {eddsa, ed25519},
|
||||||
Size :: 256,
|
Size :: 256,
|
||||||
@ -268,6 +274,9 @@ handle_cast({spend, KeyID, TX}, State) ->
|
|||||||
handle_cast({chain, ID}, State) ->
|
handle_cast({chain, ID}, State) ->
|
||||||
NewState = do_chain(ID, State),
|
NewState = do_chain(ID, State),
|
||||||
{noreply, NewState};
|
{noreply, NewState};
|
||||||
|
handle_cast({grids, String}, State) ->
|
||||||
|
ok = do_grids(String),
|
||||||
|
{noreply, State};
|
||||||
handle_cast({make_key, Name, Seed, Encoding, Transform}, State) ->
|
handle_cast({make_key, Name, Seed, Encoding, Transform}, State) ->
|
||||||
NewState = do_make_key(Name, Seed, Encoding, Transform, State),
|
NewState = do_make_key(Name, Seed, Encoding, Transform, State),
|
||||||
{noreply, NewState};
|
{noreply, NewState};
|
||||||
@ -355,6 +364,16 @@ do_chain(ID, State = #s{prefs = Prefs}) ->
|
|||||||
State.
|
State.
|
||||||
|
|
||||||
|
|
||||||
|
do_grids(String) ->
|
||||||
|
case gmc_grids:parse(String) of
|
||||||
|
{ok, Instruction} -> do_grids2(Instruction);
|
||||||
|
Error -> gmc_gui:trouble(Error)
|
||||||
|
end.
|
||||||
|
|
||||||
|
do_grids2(Instruction) ->
|
||||||
|
tell("GRIDS: ~tp", [Instruction]).
|
||||||
|
|
||||||
|
|
||||||
do_make_key(Name, <<>>, _, Transform, State) ->
|
do_make_key(Name, <<>>, _, Transform, State) ->
|
||||||
Bin = crypto:strong_rand_bytes(32),
|
Bin = crypto:strong_rand_bytes(32),
|
||||||
do_make_key2(Name, Bin, Transform, State);
|
do_make_key2(Name, Bin, Transform, State);
|
||||||
|
71
src/gmc_grids.erl
Normal file
71
src/gmc_grids.erl
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
-module(gmc_grids).
|
||||||
|
-vsn("0.1.0").
|
||||||
|
-author("Craig Everett <craigeverett@qpq.swiss>").
|
||||||
|
-copyright("QPQ AG <info@qpq.swiss>").
|
||||||
|
-license("GPL-3.0-or-later").
|
||||||
|
|
||||||
|
-export([parse/1]).
|
||||||
|
-include("$zx_include/zx_logger.hrl").
|
||||||
|
|
||||||
|
|
||||||
|
-spec parse(URL) -> {ok, Instruction} | {error, Reason}
|
||||||
|
when URL :: string(),
|
||||||
|
Instruction :: {{spend, chain | node}, {Location, Recipient, Amount, Payload}}
|
||||||
|
| {{sign, http | https}, URL},
|
||||||
|
Location :: Node :: {inet:ip_address() | inet:hostname(), inet:port_number()}
|
||||||
|
| Chain :: binary(),
|
||||||
|
Recipient :: clutch:id(),
|
||||||
|
Amount :: non_neg_integer(),
|
||||||
|
Payload :: binary(),
|
||||||
|
URL :: string(),
|
||||||
|
Reason :: bad_url.
|
||||||
|
|
||||||
|
parse(URL) ->
|
||||||
|
case uri_string:parse(URL) of
|
||||||
|
#{path := "/1/s/" ++ R, host := H, query := Q, scheme := "grids"} ->
|
||||||
|
spend(R, chain, list_to_binary(H), Q);
|
||||||
|
#{path := "/1/s/" ++ R, host := H, query := Q, scheme := "grid"} ->
|
||||||
|
spend(R, chain, list_to_binary(H), Q);
|
||||||
|
#{path := "/1/t/" ++ R, host := H, port := P, query := Q, scheme := "grids"} ->
|
||||||
|
spend(R, node, {H, P}, Q);
|
||||||
|
#{path := "/1/t/" ++ R, host := H, port := P, query := Q, scheme := "grid"} ->
|
||||||
|
spend(R, node, {H, P}, Q);
|
||||||
|
#{path := "/1/t/" ++ R, host := H, query := Q, scheme := "grids"} ->
|
||||||
|
spend(R, node, {H, 3013}, Q);
|
||||||
|
#{path := "/1/t/" ++ R, host := H, query := Q, scheme := "grid"} ->
|
||||||
|
spend(R, node, {H, 3013}, Q);
|
||||||
|
U = #{path := "/1/d/" ++ L, scheme := "grids"} ->
|
||||||
|
NewURL = uri_string:recompose(U#{scheme := "https", path := L}),
|
||||||
|
{ok ,{{sign, https}, NewURL}};
|
||||||
|
U = #{path := "/1/d/" ++ L, scheme := "grid"} ->
|
||||||
|
NewURL = uri_string:recompose(U#{scheme := "http", path := L}),
|
||||||
|
{ok, {{sign, http}, NewURL}};
|
||||||
|
{error, Reason, Info} ->
|
||||||
|
ok = tell("URL parsing failed with ~w: ~p", [Reason, Info]),
|
||||||
|
{error, bad_url};
|
||||||
|
U ->
|
||||||
|
ok = tell("GRIDS cannot proceed with this result: ~p", [U]),
|
||||||
|
{error, bad_url}
|
||||||
|
end.
|
||||||
|
|
||||||
|
spend(Recipient, Context, Location, Qwargs) ->
|
||||||
|
case dissect_query(Qwargs) of
|
||||||
|
{ok, Amount, Payload} ->
|
||||||
|
|
||||||
|
{ok, {{spend, Context}, {Location, Recipient, Amount, Payload}}};
|
||||||
|
Error ->
|
||||||
|
Error
|
||||||
|
end.
|
||||||
|
|
||||||
|
|
||||||
|
dissect_query(Qwargs) ->
|
||||||
|
case uri_string:dissect_query(Qwargs) of
|
||||||
|
{error, Reason, Info} ->
|
||||||
|
ok = tell("URL parsing failed with ~w: ~p", [Reason, Info]),
|
||||||
|
{error, bad_url};
|
||||||
|
ArgList ->
|
||||||
|
Amount = proplists:get_value("a", ArgList, 0),
|
||||||
|
Payload = proplists:get_value("p", ArgList, <<>>),
|
||||||
|
{ok, Amount, Payload}
|
||||||
|
end.
|
||||||
|
|
@ -741,14 +741,32 @@ is_int(S) ->
|
|||||||
lists:all(fun(C) -> $0 =< C andalso C =< $9 end, S).
|
lists:all(fun(C) -> $0 =< C andalso C =< $9 end, S).
|
||||||
|
|
||||||
|
|
||||||
grids_dialogue(State) ->
|
grids_dialogue(State = #s{frame = Frame, j = J}) ->
|
||||||
%grids_dialogue(State = #s{frame = Frame, j = J}) ->
|
Dialog = wxDialog:new(Frame, ?wxID_ANY, J("Password")),
|
||||||
tell("Handle GRIDS URL"),
|
Sizer = wxBoxSizer:new(?wxVERTICAL),
|
||||||
% ok =
|
Label = J("GRIDS URL"),
|
||||||
% case zxw:modal_text_input(Frame, J("GRIDS"), J("ZA GRIDS"), [J("URL")]) of
|
URL_Sz = wxStaticBoxSizer:new(?wxVERTICAL, Dialog, [{label, J(Label)}]),
|
||||||
% {ok, [URL]} -> tell("Received URL: ~p", [URL]);
|
URL_Tx = wxTextCtrl:new(Dialog, ?wxID_ANY),
|
||||||
% cancel -> tell("User cancelled GRIDS action.")
|
_ = wxStaticBoxSizer:add(URL_Sz, URL_Tx, zxw:flags(wide)),
|
||||||
% end,
|
ButtSz = wxBoxSizer:new(?wxHORIZONTAL),
|
||||||
|
Affirm = wxButton:new(Dialog, ?wxID_OK),
|
||||||
|
_ = wxBoxSizer:add(ButtSz, Affirm, zxw:flags(wide)),
|
||||||
|
_ = wxBoxSizer:add(Sizer, URL_Sz, zxw:flags(base)),
|
||||||
|
_ = wxBoxSizer:add(Sizer, ButtSz, zxw:flags(base)),
|
||||||
|
ok = wxDialog:setSizer(Dialog, Sizer),
|
||||||
|
ok = wxBoxSizer:layout(Sizer),
|
||||||
|
ok = wxFrame:center(Dialog),
|
||||||
|
ok = wxStyledTextCtrl:setFocus(URL_Tx),
|
||||||
|
ok =
|
||||||
|
case wxDialog:showModal(Dialog) of
|
||||||
|
?wxID_OK ->
|
||||||
|
case wxTextCtrl:getValue(URL_Tx) of
|
||||||
|
"" -> ok;
|
||||||
|
String -> gmc_con:grids(String)
|
||||||
|
end;
|
||||||
|
?wxID_CANCEL ->
|
||||||
|
ok
|
||||||
|
end,
|
||||||
State.
|
State.
|
||||||
|
|
||||||
|
|
||||||
@ -802,7 +820,7 @@ do_chain(ChainID, #node{ip = IP}, #s{buttons = Buttons}) ->
|
|||||||
do_ask_password(#s{frame = Frame, prefs = Prefs, j = J}) ->
|
do_ask_password(#s{frame = Frame, prefs = Prefs, j = J}) ->
|
||||||
Dialog = wxDialog:new(Frame, ?wxID_ANY, J("Password")),
|
Dialog = wxDialog:new(Frame, ?wxID_ANY, J("Password")),
|
||||||
Sizer = wxBoxSizer:new(?wxVERTICAL),
|
Sizer = wxBoxSizer:new(?wxVERTICAL),
|
||||||
Label = "Password (leave blank for no password)",
|
Label = J("Password (leave blank for no password)"),
|
||||||
PassSz = wxStaticBoxSizer:new(?wxVERTICAL, Dialog, [{label, J(Label)}]),
|
PassSz = wxStaticBoxSizer:new(?wxVERTICAL, Dialog, [{label, J(Label)}]),
|
||||||
PassTx = wxTextCtrl:new(Dialog, ?wxID_ANY),
|
PassTx = wxTextCtrl:new(Dialog, ?wxID_ANY),
|
||||||
_ = wxStaticBoxSizer:add(PassSz, PassTx, zxw:flags(wide)),
|
_ = wxStaticBoxSizer:add(PassSz, PassTx, zxw:flags(wide)),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user