Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion lib/twetch/transaction.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ defmodule Twetch.Transaction do
@moduledoc """
A module for building valid Twetch transactions.
"""
alias BSV.Script
alias BSV.{UTXO, Script}
alias Twetch.{BProtocol, MAPProtocol, AIPProtocol}

def build_op_return_args(content) do
Expand All @@ -17,6 +17,10 @@ defmodule Twetch.Transaction do
script.chunks
end

# def build(content, utxo_params, outputs) do
# UTXO.from_params!() |> IO.inspect()
# end

def build_op_return(content, privkey, address) do
%Script{}
|> Script.push(:OP_FALSE)
Expand Down
33 changes: 25 additions & 8 deletions lib/twetch/utxo.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@ defmodule Twetch.UTXO do
@moduledoc """
A module for getting your Twetch UTXOs.
"""
alias BSV.{ExtKey, PubKey}
alias BSV.{Address, Contract, ExtKey, PubKey, Script, UTXO}

@twetch_utxo_url "https://metasync.twetch.app/wallet/utxo"

@doc """
Get Twetch account UTXOs.
"""
@spec fetch() :: {:ok, list(UTXO.t())} | {:error, any()}
def fetch() do
with {:ok, pubkey} <- get_pubkey(),
{:ok, utxos} <- get_utxos(pubkey) do
Expand All @@ -26,7 +27,7 @@ defmodule Twetch.UTXO do
{:ok, key} ->
%{pubkey: pubkey} = ExtKey.derive(key, "m/0/0")

{:ok, PubKey.to_binary(pubkey, encoding: :hex)}
{:ok, pubkey}

{:error, _error} ->
{:error, "Unable to decode seed; Expecting base64 format"}
Expand All @@ -36,21 +37,37 @@ defmodule Twetch.UTXO do
defp get_utxos(pubkey) do
headers = [{"content-type", "application/json"}]

body = JSON.encode!(%{pubkey: pubkey, amount: 1})
body = JSON.encode!(%{pubkey: PubKey.to_binary(pubkey, encoding: :hex), amount: 1})

case HTTPoison.post(@twetch_utxo_url, body, headers) do
{:ok, response} ->
address = Address.from_pubkey(pubkey)

response.body
|> JSON.decode()
|> parse_utxos()
|> parse_utxos(address)

{:error, error} ->
{:error, error}
end
end

defp parse_utxos({:ok, %{"utxos" => []}}), do: {:error, "No UTXOs found"}
defp parse_utxos({:ok, %{"utxos" => utxos}}), do: {:ok, utxos}
defp parse_utxos({:ok, %{"error" => error}}), do: {:error, error}
defp parse_utxos(_), do: {:error, "Unable to parse Twetch utxos response"}
defp parse_utxos({:ok, %{"utxos" => []}}, _address), do: {:error, "No UTXOs found"}

defp parse_utxos({:ok, %{"utxos" => utxos}}, address) do
{:ok, Enum.map(utxos, &to_utxo(&1, address))}
end

defp parse_utxos({:ok, %{"error" => error}}, _address), do: {:error, error}
defp parse_utxos(_garbage, _address), do: {:error, "Unable to parse Twetch utxos response"}

defp to_utxo(%{"txid" => txid, "vout" => vout, "satoshis" => sats}, address) do
script =
sats
|> Contract.P2PKH.lock(%{address: address})
|> Contract.to_script()
|> Script.to_binary(encoding: :hex)

UTXO.from_params!(%{"txid" => txid, "vout" => vout, "satoshis" => sats, "script" => script})
end
end
27 changes: 16 additions & 11 deletions test/twetch/utxo_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,27 @@ defmodule Twetch.UTXOTest do
end

test "successfully gets utxos" do
utxos = [
%{
"path" => "1",
"satoshis" => "1830713",
"txid" => "1621958979c3f2bd1c51648f9f5ca2527450bd7fc083b36aba7d5f81ffc9f516",
"vout" => 4
}
]

utxo_body = JSON.encode!(%{"utxos" => utxos})
sats = "1830713"
vout = 4

utxo_body =
JSON.encode!(%{
"utxos" => [
%{
"path" => "1",
"satoshis" => sats,
"txid" => "1621958979c3f2bd1c51648f9f5ca2527450bd7fc083b36aba7d5f81ffc9f516",
"vout" => vout
}
]
})

Mimic.expect(HTTPoison, :post, fn _url, _body, _headers ->
{:ok, %HTTPoison.Response{body: utxo_body}}
end)

assert {:ok, ^utxos} = UTXO.fetch()
assert {:ok, [utxo]} = UTXO.fetch()
assert %BSV.UTXO{outpoint: %{vout: ^vout}, txout: %{satoshis: ^sats}} = utxo
end

test "handles no utxos result" do
Expand Down