# 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" Req.post!( transactions_url, params: ["api-key": api_key], json: %{transactions: [signature]} ).body |> List.first() end end Kino.nothing() ``` ````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"] Kino.Markdown.new(""" **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 Kino.Markdown.new(""" ### #{name} ```json #{Jason.encode!(event, pretty: true)} ``` """) end defp render_events(transaction) do events = transaction["events"] case events do %{} -> Kino.Text.new("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 [] -> Kino.Text.new("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} """ Kino.Mermaid.new(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 [] -> Kino.Text.new("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} """ Kino.Mermaid.new(diagram) end end def render(transaction) do Kino.Layout.tabs( Summary: render_summary(transaction), Tree: Kino.Tree.new(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"), api_key: Kino.Input.password("Helius API Key") ], submit: "Fetch" ) form |> Kino.render() frame = Kino.Frame.new() ``` 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) case {signature_length, api_key_length} do {0, _} -> Kino.Frame.render( frame, Kino.Markdown.new("**No transaction signature given**") ) {_, 0} -> Kino.Frame.render( frame, Kino.Markdown.new("**No Helius API key given**") ) _ -> transaction = HeliusFetch.fetch_transaction(event.data.signature, event.data.api_key) Kino.Frame.render(frame, TransactionRender.render(transaction)) end end) ```