Added support for VK

This commit is contained in:
Vamsi Krishna B 2021-08-16 08:11:58 +05:30
parent 3acb6de212
commit 5205fa2ba3
10 changed files with 230 additions and 15 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -34,7 +34,9 @@ config :zcash_explorer, Zcashex,
zcashd_hostname: "localhost",
zcashd_port: "38232",
zcashd_username: "zcashrpc",
zcashd_password: "changeme"
zcashd_password: "changeme",
vk_cpus: "0.2",
vk_mem: "2048M"
# ## SSL Support
#

View File

@ -1,5 +1,6 @@
defmodule ZcashExplorerWeb.PageController do
use ZcashExplorerWeb, :controller
alias Phoenix.PubSub
def index(conn, _params) do
render(conn, "index.html", page_title: "Zcash Explorer - Search the Zcash Blockchain")
@ -17,7 +18,6 @@ defmodule ZcashExplorerWeb.PageController do
case Zcashex.sendrawtransaction(tx_hex) do
{:ok, resp} ->
# IO.inspect(resp)
conn
|> put_flash(:info, resp)
|> render("broadcast.html",
@ -26,7 +26,6 @@ defmodule ZcashExplorerWeb.PageController do
)
{:error, reason} ->
# IO.inspect(reason)
conn
|> put_flash(:error, reason)
|> render("broadcast.html",
@ -80,6 +79,73 @@ defmodule ZcashExplorerWeb.PageController do
end
def vk(conn, _params) do
render(conn, "vk.html", csrf_token: get_csrf_token(), page_title: "Zcash Viewing Key")
height =
case Cachex.get(:app_cache, "metrics") do
{:ok, info} ->
info["blocks"] - 10000
{:error, _reason} ->
# hardcoded to canopy
1_046_400
end
render(conn, "vk.html",
csrf_token: get_csrf_token(),
height: height,
page_title: "Zcash Viewing Key"
)
end
def do_import_vk(conn, params) do
height = params["scan-height"]
vkey = params["vkey"]
with true <- String.starts_with?(vkey, "zxview"),
true <- is_integer(String.to_integer(height)),
true <- String.to_integer(height) >= 0 do
cmd =
MuonTrap.cmd("docker", [
"create",
"-t",
"-i",
"--rm",
"--cpus",
Application.get_env(:zcash_explorer, Zcashex)[:vk_cpus],
"-m",
Application.get_env(:zcash_explorer, Zcashex)[:vk_mem],
"nighthawkapps/vkrunner",
"zecwallet-cli",
"import",
vkey,
height
])
container_id = elem(cmd, 0) |> String.trim_trailing("\n") |> String.slice(0, 12)
task = Task.start(fn -> MuonTrap.cmd("docker", ["start", "-a", "-i", container_id]) end)
render(conn, "vk_txs.html",
csrf_token: get_csrf_token(),
height: height,
container_id: container_id,
page_title: "Zcash Viewing Key"
)
else
false ->
conn
|> put_flash(:error, "Invalid Input")
|> render("vk.html",
csrf_token: get_csrf_token(),
height: height,
page_title: "Zcash Viewing Key"
)
end
end
def vk_from_zecwalletcli(conn, params) do
container_id = Map.get(params, "hostname")
chan = "VK:" <> "#{container_id}"
txs = Map.get(params, "_json")
Phoenix.PubSub.broadcast(ZcashExplorer.PubSub, chan, {:received_txs, txs})
json(conn, %{status: "received"})
end
end

View File

@ -0,0 +1,95 @@
defmodule ZcashExplorerWeb.VkLive do
use Phoenix.LiveView
def render(assigns) do
~L"""
<div class="text-green-400 font-mono break-all ">
<%= @message["message"] %>
</div>
<%= if length(@message["txs"]) > 0 do %>
<div class="shadow overflow-hidden border-b border-gray-200 rounded-lg overflow-x-auto">
<table class="min-w-full divide-y divide-gray-200">
<thead class="bg-gray-50">
<tr>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-midnight-500 uppercase tracking-wider">Tx</th>
<th scope="col" class="px-4 py-3 text-left text-xs font-medium text-midnight-500 uppercase tracking-wider">Amount</th>
<th scope="col" class="px-4 py-3 text-left text-xs font-medium text-midnight-500 uppercase tracking-wider">Address</th>
<th scope="col" class="px-4 py-3 text-left text-xs font-medium text-midnight-500 uppercase tracking-wider">Date</th>
<th scope="col" class="px-4 py-3 text-left text-xs font-medium text-midnight-500 uppercase tracking-wider">Memo</th>
</tr>
</thead>
<tbody class="bg-white-500 divide-y divide-gray-200">
<%= for tx <- @message["txs"] do %>
<tr class="hover:bg-indigo-50">
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-indigo-600 hover:text-indigo-500">
<a href='/transactions/<%= tx["txid"] %>' target="_blank">
<%= tx["txid"] %>
</a>
</td>
<td class="px-4 py-4 whitespace-nowrap text-sm font-medium text-gray-500">
<%= ZcashExplorerWeb.AddressView.zatoshi_to_zec(tx["amount"]) %>
</td>
<td class="px-4 py-4 whitespace-nowrap text-sm font-medium text-gray-500">
<%= tx["address"] %>
</td>
<td class="px-4 py-4 whitespace-nowrap text-sm font-medium text-gray-500">
<%= ZcashExplorerWeb.BlockView.mined_time_rel(tx["datetime"]) %>
</td>
<td class="px-4 py-4 whitespace-nowrap text-sm font-medium text-gray-500 break-all">
<%= tx["memo"] %>
</td>
</tr>
<% end %>
</tbody>
</table>
<% end %>
"""
end
def mount(params, session, socket) do
if connected?(socket) do
container_id = Map.get(session, "container_id")
Process.send_after(self(), :update, 3000)
subscribed = Phoenix.PubSub.subscribe(ZcashExplorer.PubSub, "VK:" <> "#{container_id}")
end
{:ok,
assign(socket, :message, %{
"message" => "Starting to import the VK .",
"container_id" => Map.get(session, "container_id"),
"txs" => []
})}
end
def handle_info(:update, socket) do
if length(socket.assigns.message["txs"]) == 0 do
Process.send_after(self(), :update, 3000)
end
cmd = MuonTrap.cmd("docker", ["logs", socket.assigns.message["container_id"]])
logs = elem(cmd, 0) |> Phoenix.HTML.Format.text_to_html()
{:noreply,
assign(socket, :message, %{
"message" => logs,
"container_id" => socket.assigns.message["container_id"],
"txs" => socket.assigns.message["txs"]
})}
end
def handle_info({:received_txs, txs}, socket) do
{:noreply,
assign(socket, :message, %{
"message" => "Got list of txs",
"container_id" => socket.assigns.message["container_id"],
"txs" => txs
})}
end
end

View File

@ -31,6 +31,7 @@ defmodule ZcashExplorerWeb.Router do
live "/index/recent_transactions", RecentTransactionsLive
live "/live/raw_mempool", RawMempoolLive
live "/live/nodes", NodesLive
live "/vkdetails", VkLive
get "/broadcast", PageController, :broadcast
post "/broadcast", PageController, :do_broadcast
get "/payment-disclosure", PageController, :disclosure
@ -41,6 +42,13 @@ defmodule ZcashExplorerWeb.Router do
get "/mempool", PageController, :mempool
get "/nodes", PageController, :nodes
get "/vk", PageController, :vk
post "/vk", PageController, :do_import_vk
end
scope "/", ZcashExplorerWeb do
pipe_through :api
post "/api/vk/:hostname", PageController, :vk_from_zecwalletcli
end
# Other scopes may use custom stacks.

View File

@ -118,6 +118,7 @@ Heroicon name: outline/x" x-state:on="Menu open" x-state:off="Menu closed" class
<path fill-rule="evenodd" d="M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z" clip-rule="evenodd" />
</svg>
</a>
</div>
<div class="mt-8 md:mt-0 md:order-1">
<p class="text-center text-base text-gray-400">

View File

@ -3,21 +3,53 @@
<h3 class="text-lg leading-6 font-medium text-gray-500 py-2">
Zcash Viewing Key
</h3>
<form class="space-y-8" action="/do_import_vk" method="post">
<form class="space-y-8" action="/vk" method="post">
<div class="space-y-8 divide-y divide-gray-200 sm:space-y-5">
<div>
<%= if get_flash(@conn, :error) do %>
<div class="rounded-md bg-red-50 p-4">
<div class="flex">
<div class="flex-shrink-0">
<!-- Heroicon name: solid/x-circle -->
<svg class="h-5 w-5 text-red-400" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clip-rule="evenodd" />
</svg>
</div>
<div class="ml-3">
<h3 class="text-sm font-medium text-red-800">
There was an error when importing the VK.
</h3>
<div class="mt-2 text-sm text-red-700">
<ul class="list-disc pl-5 space-y-1">
<li>
<%= get_flash(@conn, :error) %>
</li>
</ul>
</div>
</div>
</div>
</div>
<% end %>
<p class="mt-1 mb-2 max-w-2xl text-sm text-gray-600">
Paste the viewing key, click on view transactions button and grab a coffee !
Paste the viewing key, click on the "start importing" button and grab a coffee !
</p>
<input type="hidden" value="<%= @csrf_token %>" name="_csrf_token"/>
<textarea id="broadcast" name="tx-hex" rows="22" class="w-full shadow-sm bg-indigo-400 bg-opacity-5 focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm border border-gray-300 rounded-md font-mono text-green-400 "></textarea>
<textarea id="broadcast" name="vkey" rows="4" class="w-full shadow-sm bg-indigo-400 bg-opacity-5 focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm border border-gray-300 rounded-md font-mono text-green-400 "></textarea>
<div>
<label for="height" class="block text-sm font-medium text-gray-700">Start Height</label>
<div class="mt-1">
<input type="text" name="scan-height" id="scan-height" class="shadow-sm focus:ring-indigo-500 bg-opacity-5 focus:border-indigo-500 block w-1/4 sm:text-sm border-gray-300 bg-indigo-400 rounded-md text-green-400 font-mono" placeholder="height" value="<%= @height %>">
</div>
</div>
<div class="pt-5 pb-5">
<div class="flex justify-center">
<button type="submit" class="flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
Start importing
</button>

View File

@ -0,0 +1,8 @@
<main class="py-4">
<div class="grid grid-cols-1 mx-8">
<h3 class="text-lg leading-6 font-medium text-gray-500 py-2">
Zcash Viewing Key
</h3>
<%= live_render(@conn, ZcashExplorerWeb.VkLive,session: %{"container_id" => @container_id}) %>
</div>
</main>

View File

@ -56,7 +56,8 @@ defmodule ZcashExplorer.MixProject do
{:timex, "~> 3.0"},
{:sizeable, "~> 1.0"},
{:eqrcode, "~> 0.1.8"},
{:contex, "~> 0.3.0"}
{:contex, "~> 0.3.0"},
{:muontrap, "~> 0.6.1"}
]
end

View File

@ -12,6 +12,7 @@
"ecto": {:hex, :ecto, "3.6.2", "efdf52acfc4ce29249bab5417415bd50abd62db7b0603b8bab0d7b996548c2bc", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "efad6dfb04e6f986b8a3047822b0f826d9affe8e4ebdd2aeedbfcb14fd48884e"},
"ecto_psql_extras": {:hex, :ecto_psql_extras, "0.6.5", "161a4343d2befafef79f7a9e73a85fe2543ab1933ea211838ad76c372d4b6da2", [:mix], [{:ecto_sql, "~> 3.4", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:postgrex, ">= 0.15.7", [hex: :postgrex, repo: "hexpm", optional: false]}, {:table_rex, "~> 3.1.1", [hex: :table_rex, repo: "hexpm", optional: false]}], "hexpm", "5dbe26a78110019d2192512201a17d15d691d1a7bc72e04484fce7ed4576582b"},
"ecto_sql": {:hex, :ecto_sql, "3.6.2", "9526b5f691701a5181427634c30655ac33d11e17e4069eff3ae1176c764e0ba3", [:mix], [{:db_connection, "~> 2.2", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.6.2", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.4.0 or ~> 0.5.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.15.0 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "5ec9d7e6f742ea39b63aceaea9ac1d1773d574ea40df5a53ef8afbd9242fdb6b"},
"elixir_make": {:hex, :elixir_make, "0.6.2", "7dffacd77dec4c37b39af867cedaabb0b59f6a871f89722c25b28fcd4bd70530", [:mix], [], "hexpm", "03e49eadda22526a7e5279d53321d1cced6552f344ba4e03e619063de75348d9"},
"eqrcode": {:hex, :eqrcode, "0.1.8", "5c97ce5626ad8712264eeb6cbb62f7300c3402d8de711c9159894c7b3db8af7b", [:mix], [], "hexpm", "cd15dda9e85b9e6bbd8ec536b373440d5268d1ef6200a9c0e367fd1f49b96e62"},
"eternal": {:hex, :eternal, "1.2.2", "d1641c86368de99375b98d183042dd6c2b234262b8d08dfd72b9eeaafc2a1abd", [:mix], [], "hexpm", "2c9fe32b9c3726703ba5e1d43a1d255a4f3f2d8f8f9bc19f094c7cb1a7a9e782"},
"file_system": {:hex, :file_system, "0.2.10", "fb082005a9cd1711c05b5248710f8826b02d7d1784e7c3451f9c1231d4fc162d", [:mix], [], "hexpm", "41195edbfb562a593726eda3b3e8b103a309b733ad25f3d642ba49696bf715dc"},
@ -26,21 +27,22 @@
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"},
"mime": {:hex, :mime, "1.6.0", "dabde576a497cef4bbdd60aceee8160e02a6c89250d6c0b29e56c0dfb00db3d2", [:mix], [], "hexpm", "31a1a8613f8321143dde1dafc36006a17d28d02bdfecb9e95a880fa7aabd19a7"},
"mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm", "f278585650aa581986264638ebf698f8bb19df297f66ad91b18910dfc6e19323"},
"muontrap": {:hex, :muontrap, "0.6.1", "fa11dc9152470c4d0ce5a5fcb6524d8c1edc9bf6d63b3f6a89096f1e751ae271", [:make, :mix], [{:elixir_make, "~> 0.6", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "86d1ef2fa0a30435a1d595e96f631ad4a24a931d8d855688e012fadd7147bd1d"},
"nimble_strftime": {:hex, :nimble_strftime, "0.1.1", "b988184d1bd945bc139b2c27dd00a6c0774ec94f6b0b580083abd62d5d07818b", [:mix], [], "hexpm", "89e599c9b8b4d1203b7bb5c79eb51ef7c6a28fbc6228230b312f8b796310d755"},
"observer_cli": {:hex, :observer_cli, "1.6.2", "016588e9a966247401bcbf02976d468f1e6f06891dde44f873c9259c6496cca1", [:mix, :rebar3], [{:recon, "~>2.5.1", [hex: :recon, repo: "hexpm", optional: false]}], "hexpm", "c23db9e4cca0e849adc42b0a099affb9e6267c5f23a871fc6f144348b249341f"},
"parse_trans": {:hex, :parse_trans, "3.3.1", "16328ab840cc09919bd10dab29e431da3af9e9e7e7e6f0089dd5a2d2820011d8", [:rebar3], [], "hexpm", "07cd9577885f56362d414e8c4c4e6bdf10d43a8767abb92d24cbe8b24c54888b"},
"phoenix": {:hex, :phoenix, "1.5.9", "a6368d36cfd59d917b37c44386e01315bc89f7609a10a45a22f47c007edf2597", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_html, "~> 2.13 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:plug, "~> 1.10", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 1.0 or ~> 2.2", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.1.2 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7e4bce20a67c012f1fbb0af90e5da49fa7bf0d34e3a067795703b74aef75427d"},
"phoenix": {:hex, :phoenix, "1.5.10", "3ee7d5c17ff9626d72d374d8fc8909bf00f4323fd15549fbe3abbbd38b5299c8", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_html, "~> 2.13 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:plug, "~> 1.10", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 1.0 or ~> 2.2", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.1.2 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "f9c2eaa5a8fe5a412610c6aa84ccdb6f3e92f333d4df7fbaeb0d5a157dbfb48d"},
"phoenix_ecto": {:hex, :phoenix_ecto, "4.3.0", "2c69a452c2e0ee8c93345ae1cdc1696ef4877ff9cbb15c305def41960c3c4ebf", [:mix], [{:ecto, "~> 3.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.14.2 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "0ac491924217550c8f42c81c1f390b5d81517d12ceaf9abf3e701156760a848e"},
"phoenix_html": {:hex, :phoenix_html, "2.14.3", "51f720d0d543e4e157ff06b65de38e13303d5778a7919bcc696599e5934271b8", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "efd697a7fff35a13eeeb6b43db884705cba353a1a41d127d118fda5f90c8e80f"},
"phoenix_live_dashboard": {:hex, :phoenix_live_dashboard, "0.4.0", "87990e68b60213d7487e65814046f9a2bed4a67886c943270125913499b3e5c3", [:mix], [{:ecto_psql_extras, "~> 0.4.1 or ~> 0.5", [hex: :ecto_psql_extras, repo: "hexpm", optional: true]}, {:phoenix_html, "~> 2.14.1 or ~> 2.15", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:phoenix_live_view, "~> 0.15.0", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}, {:telemetry_metrics, "~> 0.4.0 or ~> 0.5.0 or ~> 0.6.0", [hex: :telemetry_metrics, repo: "hexpm", optional: false]}], "hexpm", "8d52149e58188e9e4497cc0d8900ab94d9b66f96998ec38c47c7a4f8f4f50e57"},
"phoenix_live_reload": {:hex, :phoenix_live_reload, "1.3.3", "3a53772a6118d5679bf50fc1670505a290e32a1d195df9e069d8c53ab040c054", [:mix], [{:file_system, "~> 0.2.1 or ~> 0.3", [hex: :file_system, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}], "hexpm", "766796676e5f558dbae5d1bdb066849673e956005e3730dfd5affd7a6da4abac"},
"phoenix_live_view": {:hex, :phoenix_live_view, "0.15.7", "09720b8e5151b3ca8ef739cd7626d4feb987c69ba0b509c9bbdb861d5a365881", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.5.7", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.14", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.2 or ~> 0.5", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "3a756cf662420272d0f1b3b908cce5222163b5a95aa9bab404f9d29aff53276e"},
"phoenix_pubsub": {:hex, :phoenix_pubsub, "2.0.0", "a1ae76717bb168cdeb10ec9d92d1480fec99e3080f011402c0a2d68d47395ffb", [:mix], [], "hexpm", "c52d948c4f261577b9c6fa804be91884b381a7f8f18450c5045975435350f771"},
"plug": {:hex, :plug, "1.11.1", "f2992bac66fdae679453c9e86134a4201f6f43a687d8ff1cd1b2862d53c80259", [:mix], [{:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "23524e4fefbb587c11f0833b3910bfb414bf2e2534d61928e920f54e3a1b881f"},
"plug_cowboy": {:hex, :plug_cowboy, "2.5.0", "51c998f788c4e68fc9f947a5eba8c215fbb1d63a520f7604134cab0270ea6513", [:mix], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:cowboy_telemetry, "~> 0.3", [hex: :cowboy_telemetry, repo: "hexpm", optional: false]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "5b2c8925a5e2587446f33810a58c01e66b3c345652eeec809b76ba007acde71a"},
"plug": {:hex, :plug, "1.12.1", "645678c800601d8d9f27ad1aebba1fdb9ce5b2623ddb961a074da0b96c35187d", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "d57e799a777bc20494b784966dc5fbda91eb4a09f571f76545b72a634ce0d30b"},
"plug_cowboy": {:hex, :plug_cowboy, "2.5.1", "7cc96ff645158a94cf3ec9744464414f02287f832d6847079adfe0b58761cbd0", [:mix], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:cowboy_telemetry, "~> 0.3", [hex: :cowboy_telemetry, repo: "hexpm", optional: false]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "107d0a5865fa92bcb48e631cc0729ae9ccfa0a9f9a1bd8f01acb513abf1c2d64"},
"plug_crypto": {:hex, :plug_crypto, "1.2.2", "05654514ac717ff3a1843204b424477d9e60c143406aa94daf2274fdd280794d", [:mix], [], "hexpm", "87631c7ad914a5a445f0a3809f99b079113ae4ed4b867348dd9eec288cecb6db"},
"poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm", "fec8660eb7733ee4117b85f55799fd3833eb769a6df71ccf8903e8dc5447cfce"},
"postgrex": {:hex, :postgrex, "0.15.9", "46f8fe6f25711aeb861c4d0ae09780facfdf3adbd2fb5594ead61504dd489bda", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "610719103e4cb2223d4ab78f9f0f3e720320eeca6011415ab4137ddef730adee"},
"postgrex": {:hex, :postgrex, "0.15.10", "2809dee1b1d76f7cbabe570b2a9285c2e7b41be60cf792f5f2804a54b838a067", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "1560ca427542f6b213f8e281633ae1a3b31cdbcd84ebd7f50628765b8f6132be"},
"ranch": {:hex, :ranch, "1.8.0", "8c7a100a139fd57f17327b6413e4167ac559fbc04ca7448e9be9057311597a1d", [:make, :rebar3], [], "hexpm", "49fbcfd3682fab1f5d109351b61257676da1a2fdbe295904176d5e521a2ddfe5"},
"recon": {:hex, :recon, "2.5.2", "cba53fa8db83ad968c9a652e09c3ed7ddcc4da434f27c3eaa9ca47ffb2b1ff03", [:mix, :rebar3], [], "hexpm", "2c7523c8dee91dff41f6b3d63cba2bd49eb6d2fe5bf1eec0df7f87eb5e230e1c"},
"sizeable": {:hex, :sizeable, "1.0.2", "625fe06a5dad188b52121a140286f1a6ae1adf350a942cf419499ecd8a11ee29", [:mix], [], "hexpm", "4bab548e6dfba777b400ca50830a9e3a4128e73df77ab1582540cf5860601762"},
@ -50,7 +52,7 @@
"telemetry": {:hex, :telemetry, "0.4.3", "a06428a514bdbc63293cd9a6263aad00ddeb66f608163bdec7c8995784080818", [:rebar3], [], "hexpm", "eb72b8365ffda5bed68a620d1da88525e326cb82a75ee61354fc24b844768041"},
"telemetry_metrics": {:hex, :telemetry_metrics, "0.6.1", "315d9163a1d4660aedc3fee73f33f1d355dcc76c5c3ab3d59e76e3edf80eef1f", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7be9e0871c41732c233be71e4be11b96e56177bf15dde64a8ac9ce72ac9834c6"},
"telemetry_poller": {:hex, :telemetry_poller, "0.5.1", "21071cc2e536810bac5628b935521ff3e28f0303e770951158c73eaaa01e962a", [:rebar3], [{:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "4cab72069210bc6e7a080cec9afffad1b33370149ed5d379b81c7c5f0c663fd4"},
"timex": {:hex, :timex, "3.7.5", "3eca56e23bfa4e0848f0b0a29a92fa20af251a975116c6d504966e8a90516dfd", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:gettext, "~> 0.10", [hex: :gettext, repo: "hexpm", optional: false]}, {:tzdata, "~> 1.0", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm", "a15608dca680f2ef663d71c95842c67f0af08a0f3b1d00e17bbd22872e2874e4"},
"timex": {:hex, :timex, "3.7.6", "502d2347ec550e77fdf419bc12d15bdccd31266bb7d925b30bf478268098282f", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:gettext, "~> 0.10", [hex: :gettext, repo: "hexpm", optional: false]}, {:tzdata, "~> 1.0", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm", "a296327f79cb1ec795b896698c56e662ed7210cc9eb31f0ab365eb3a62e2c589"},
"tzdata": {:hex, :tzdata, "1.1.0", "72f5babaa9390d0f131465c8702fa76da0919e37ba32baa90d93c583301a8359", [:mix], [{:hackney, "~> 1.17", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "18f453739b48d3dc5bcf0e8906d2dc112bb40baafe2c707596d89f3c8dd14034"},
"unicode_util_compat": {:hex, :unicode_util_compat, "0.7.0", "bc84380c9ab48177092f43ac89e4dfa2c6d62b40b8bd132b1059ecc7232f9a78", [:rebar3], [], "hexpm", "25eee6d67df61960cf6a794239566599b09e17e668d3700247bc498638152521"},
"unsafe": {:hex, :unsafe, "1.0.1", "a27e1874f72ee49312e0a9ec2e0b27924214a05e3ddac90e91727bc76f8613d8", [:mix], [], "hexpm", "6c7729a2d214806450d29766abc2afaa7a2cbecf415be64f36a6691afebb50e5"},