# Helius Transaction Render ```elixir Mix.install([ {:req, "~> 0.3.4"}, {:jason, "~> 1.4.0"}, {:kino, "~> 0.12.3"} ]) ``` ## Code Setup This section includes all the Elixir code to fetch and render the given transaction You don't need to edit any of it ```elixir # Define transaction fetching logic defmodule HeliusFetch do def fetch_transaction(signature, api_key) do transactions_url = "https://api.helius.xyz/v0/transactions" response = Req.post!( transactions_url, params: ["api-key": api_key], json: %{transactions: [signature]} ) case response do %Req.Response{status: 200, body: body} -> {:ok, List.first(body)} %Req.Response{body: body} -> {:error, body} end end end ``` ```elixir import Kino.Shorts ``` ````elixir # Define transaction rendering logic defmodule TransactionRender do defp truncate(string, length) do start = String.slice(string, 0, length) last = String.slice(string, 0 - length, length) start <> "..." <> last end defp render_summary(transaction) do source = transaction["source"] type = transaction["type"] description = transaction["description"] fee_payer = transaction["feePayer"] markdown(""" **Source**: #{source} **Type**: #{type} **Description**: #{description} **Fee Payer**: [#{truncate(fee_payer, 8)}](https://explorer.solana.com/address/#{fee_payer}) """) end defp render_event(name, event) do markdown(""" ### #{name} ```json #{Jason.encode!(event, pretty: true)} ``` """) end defp render_events(transaction) do events = transaction["events"] case events do %{} -> text("No events") _ -> events |> Enum.map(fn {name, event} -> render_event(name, event) end) |> Kino.Layout.grid() end end defp native_transfer_diagram_line(transfer) do from = case transfer["fromUserAccount"] do "" -> "none" address -> truncate(address, 4) end to = case transfer["toUserAccount"] do "" -> "none" address -> truncate(address, 4) end amount = (transfer["amount"] / 1_000_000_000) |> Float.round(4) label = "#{amount} SOL" # Mermaid diagram line starting with 2 spaces " #{from}-...->|#{label}|#{to}" end defp render_native_transfers(transaction) do native_transfers = transaction["nativeTransfers"] case native_transfers do [] -> text("No native transfers") _ -> diagram_lines = native_transfers |> Enum.filter(fn transfer -> transfer["amount"] > 0 end) |> Enum.map(fn transfer -> native_transfer_diagram_line(transfer) end) |> Enum.join("\n") diagram = """ flowchart LR #{diagram_lines} """ mermaid(diagram) end end defp token_transfer_diagram_line(transfer) do from = case transfer["fromUserAccount"] do "" -> "none" address -> truncate(address, 4) end to = case transfer["toUserAccount"] do "" -> "none" address -> truncate(address, 4) end token_amount = transfer["tokenAmount"] mint = truncate(transfer["mint"], 4) label = "#{token_amount} #{mint}" " #{from}-...->|#{label}|#{to}" end defp render_token_transfers(transaction) do token_transfers = transaction["tokenTransfers"] case token_transfers do [] -> text("No token transfers") _ -> diagram_lines = token_transfers |> Enum.map(fn transfer -> token_transfer_diagram_line(transfer) end) |> Enum.join("\n") diagram = """ flowchart LR #{diagram_lines} """ mermaid(diagram) end end def render(transaction) do Kino.Layout.tabs( Summary: render_summary(transaction), Tree: tree(transaction), Events: render_events(transaction), "Native Transfers": render_native_transfers(transaction), "Token Transfers": render_token_transfers(transaction) ) end end ```` ## Fetch a transaction ```elixir form = Kino.Control.form( [ signature: Kino.Input.text("Transaction Signature", default: "5r4xyeKUJkagGvNGpzKd7rE2LuxPJfhZfiub7JrqS28gFHY2Z18H557srUCPbiJQErW2XA4xBoZGQpLjDE8wyFs4" ), api_key: Kino.Input.password("Helius API Key") ], submit: "Fetch" ) form |> Kino.render() frame = frame() ``` This next code block does all the magic You just need to evaluate it :) ```elixir Kino.listen(form, fn event -> signature_length = byte_size(event.data.signature) api_key_length = byte_size(event.data.api_key) origin = event.origin case {signature_length, api_key_length} do {0, _} -> Kino.Frame.render( frame, Kino.Markdown.new("**No transaction signature given**"), to: origin ) {_, 0} -> Kino.Frame.render( frame, Kino.Markdown.new("**No Helius API key given**"), to: origin ) _ -> case HeliusFetch.fetch_transaction(event.data.signature, event.data.api_key) do {:ok, transaction} -> Kino.Frame.render(frame, TransactionRender.render(transaction), to: origin) {:error, error} -> Kino.Frame.render(frame, markdown("*Error*: #{inspect(error)}"), to: origin) end end end) ```