Skip to content

Commit

Permalink
feat: add Cardano.Transactions
Browse files Browse the repository at this point in the history
  • Loading branch information
v0idpwn committed Sep 23, 2021
1 parent 05de99d commit 42c75d0
Show file tree
Hide file tree
Showing 19 changed files with 1,182 additions and 50 deletions.
209 changes: 209 additions & 0 deletions lib/blockfrost/cardano/transactions.ex
@@ -1,3 +1,212 @@
defmodule Blockfrost.Cardano.Transactions do
@moduledoc "Functions for to the /transactions namespace in the Blockfrost API"

alias Blockfrost.HTTP
alias Blockfrost.Response
alias Blockfrost.Utils

alias Blockfrost.Response.{
SpecificTransactionResponse,
TransactionUTXOsResponse,
TransactionStakeAddressCertificatesResponse,
TransactionDelegationCertificatesResponse,
TransactionWithdrawalsResponse,
TransactionMIRsResponse,
TransactionStakePoolRegistrationAndUpdateCertificatesResponse,
TransactionStakePoolRetirementCertificatesResponse,
TransactionMetadataResponse,
TransactionMetadataCBORResponse,
TransactionRedeemersResponse,
SubmitTransactionResponse
}

@doc """
Return content of the requested transaction.
[API Docs](https://docs.blockfrost.io/#tag/Cardano-Transactions/paths/~1txs~1{hash}/get)
"""
@spec specific_transaction(Blockfrost.t(), hash :: String.t(), Keyword.t()) ::
{:ok, SpecificTransactionResponse.t()} | HTTP.error_response()
def specific_transaction(name, hash, opts \\ []) do
Utils.validate_cardano!(name)

name
|> HTTP.build_and_send(:get, "/txs/#{hash}", opts)
|> Response.deserialize(SpecificTransactionResponse)
end

@doc """
Return the inputs and UTXOs of the specific transaction.
[API Docs](https://docs.blockfrost.io/#tag/Cardano-Transactions/paths/~1txs~1{hash}~1utxos/get)
"""
@spec utxos(Blockfrost.t(), hash :: String.t(), Keyword.t()) ::
{:ok, TransactionUTXOsResponse.t()} | HTTP.error_response()
def utxos(name, hash, opts \\ []) do
Utils.validate_cardano!(name)

name
|> HTTP.build_and_send(:get, "/txs/#{hash}/utxos", opts)
|> Response.deserialize(TransactionUTXOsResponse)
end

@doc """
Obtain information about (de)registration of stake addresses within a transaction.
[API Docs](https://docs.blockfrost.io/#tag/Cardano-Transactions/paths/~1txs~1{hash}~1stakes/get)
"""
@spec stake_address_certificates(Blockfrost.t(), hash :: String.t(), Keyword.t()) ::
{:ok, TransactionStakeAddressCertificatesResponse.t()} | HTTP.error_response()
def stake_address_certificates(name, hash, opts \\ []) do
Utils.validate_cardano!(name)

name
|> HTTP.build_and_send(:get, "/txs/#{hash}/stakes", opts)
|> Response.deserialize(TransactionStakeAddressCertificatesResponse)
end

@doc """
Obtain information about delegation certificates of a specific transaction.
[API Docs](https://docs.blockfrost.io/#tag/Cardano-Transactions/paths/~1txs~1{hash}~1delegations/get)
"""
@spec delegation_certificates(Blockfrost.t(), hash :: String.t(), Keyword.t()) ::
{:ok, TransactionDelegationCertificatesResponse.t()} | HTTP.error_response()
def delegation_certificates(name, hash, opts \\ []) do
Utils.validate_cardano!(name)

name
|> HTTP.build_and_send(:get, "/txs/#{hash}/delegations", opts)
|> Response.deserialize(TransactionDelegationCertificatesResponse)
end

@doc """
Obtain information about withdrawals of a specific transaction.
[API Docs](https://docs.blockfrost.io/#tag/Cardano-Transactions/paths/~1txs~1{hash}~1delegations/get)
"""
@spec withdrawals(Blockfrost.t(), hash :: String.t(), Keyword.t()) ::
{:ok, TransactionWithdrawalsResponse.t()} | HTTP.error_response()
def withdrawals(name, hash, opts \\ []) do
Utils.validate_cardano!(name)

name
|> HTTP.build_and_send(:get, "/txs/#{hash}/withdrawals", opts)
|> Response.deserialize(TransactionWithdrawalsResponse)
end

@doc """
Obtain information about Move Instantaneous Rewards (MIRs) of a specific transaction.
[API Docs](https://docs.blockfrost.io/#tag/Cardano-Transactions/paths/~1txs~1{hash}~1withdrawals/get)
"""
@spec mirs(Blockfrost.t(), hash :: String.t(), Keyword.t()) ::
{:ok, TransactionMIRsResponse.t()} | HTTP.error_response()
def mirs(name, hash, opts \\ []) do
Utils.validate_cardano!(name)

name
|> HTTP.build_and_send(:get, "/txs/#{hash}/mirs", opts)
|> Response.deserialize(TransactionMIRsResponse)
end

@doc """
Obtain information about stake pool registration and update certificates of a specific transaction.
[API Docs](https://docs.blockfrost.io/#tag/Cardano-Transactions/paths/~1txs~1{hash}~1pool_updates/get)
"""
@spec stake_pool_registration_and_update_certificates(
Blockfrost.t(),
hash :: String.t(),
Keyword.t()
) ::
{:ok, TransactionMIRsResponse.t()} | HTTP.error_response()
def stake_pool_registration_and_update_certificates(name, hash, opts \\ []) do
Utils.validate_cardano!(name)

name
|> HTTP.build_and_send(:get, "/txs/#{hash}/updates", opts)
|> Response.deserialize(TransactionStakePoolRegistrationAndUpdateCertificatesResponse)
end

@doc """
Obtain information about stake pool retirements within a specific transaction.
[API Docs](https://docs.blockfrost.io/#tag/Cardano-Transactions/paths/~1txs~1{hash}~1pool_retires/get)
"""
@spec stake_pool_retirement_certificates(Blockfrost.t(), hash :: String.t(), Keyword.t()) ::
{:ok, TransactionStakePoolRetirementCertificatesResponse.t()} | HTTP.error_response()
def stake_pool_retirement_certificates(name, hash, opts \\ []) do
Utils.validate_cardano!(name)

name
|> HTTP.build_and_send(:get, "/txs/#{hash}/pool_retires", opts)
|> Response.deserialize(TransactionStakePoolRetirementCertificatesResponse)
end

@doc """
Obtain the transaction metadata.
[API Docs](https://docs.blockfrost.io/#tag/Cardano-Transactions/paths/~1txs~1{hash}~1metadata/get)
"""
@spec metadata(Blockfrost.t(), hash :: String.t(), Keyword.t()) ::
{:ok, TransactionMetadataResponse.t()} | HTTP.error_response()
def metadata(name, hash, opts \\ []) do
Utils.validate_cardano!(name)

name
|> HTTP.build_and_send(:get, "/txs/#{hash}/metadata", opts)
|> Response.deserialize(TransactionMetadataResponse)
end

@doc """
Obtain the transaction metadata in CBOR
[API Docs](https://docs.blockfrost.io/#tag/Cardano-Transactions/paths/~1txs~1{hash}~1metadata~1cbor/get)
"""
@spec metadata_cbor(Blockfrost.t(), hash :: String.t(), Keyword.t()) ::
{:ok, TransactionMetadataCBORResponse.t()} | HTTP.error_response()
def metadata_cbor(name, hash, opts \\ []) do
Utils.validate_cardano!(name)

name
|> HTTP.build_and_send(:get, "/txs/#{hash}/metadata_cbor", opts)
|> Response.deserialize(TransactionMetadataCBORResponse)
end

@doc """
Obtain the transaction redeemers.
[API Docs](https://docs.blockfrost.io/#tag/Cardano-Transactions/paths/~1txs~1{hash}~1redeemers/get)
"""
@spec redeemers(Blockfrost.t(), hash :: String.t(), Keyword.t()) ::
{:ok, TransactionRedeemersResponse.t()} | HTTP.error_response()
def redeemers(name, hash, opts \\ []) do
Utils.validate_cardano!(name)

name
|> HTTP.build_and_send(:get, "/txs/#{hash}/redeemers", opts)
|> Response.deserialize(TransactionRedeemersResponse)
end

@doc """
Submit an already serialized transaction to the network.
[API Docs](https://docs.blockfrost.io/#tag/Cardano-Transactions/paths/~1txs~1{hash}~1redeemers/get)
"""
@spec submit(Blockfrost.t(), hash :: String.t(), Keyword.t()) ::
{:ok, SubmitTransactionResponse.t()} | HTTP.error_response()
def submit(name, cbor, opts \\ []) do
Utils.validate_cardano!(name)

opts =
opts
|> Keyword.put(:content_type, "application/cbor")
|> Keyword.put(:body, cbor)

name
|> HTTP.build_and_send(:post, "/tx/submit", opts)
|> Response.deserialize(SubmitTransactionResponse)
end
end
@@ -1,27 +1,7 @@
defmodule Blockfrost.Response.StakePoolMetadataResponse do
use Blockfrost.Response.BaseSchema

@type t :: [
%__MODULE__{
pool_id: String.t(),
hex: String.t(),
url: String.t(),
hash: String.t(),
ticker: String.t(),
name: String.t(),
description: String.t(),
homepage: String.t()
}
]
@type t :: Blockfrost.Shared.StakePoolMetadata.t()

embedded_schema do
field(:pool_id, :string)
field(:hex, :string)
field(:url, :string)
field(:hash, :string)
field(:ticker, :string)
field(:name, :string)
field(:description, :string)
field(:homepage, :string)
end
defdelegate cast(data), to: Blockfrost.Shared.StakePoolMetadata
end
@@ -1,28 +1,6 @@
defmodule Blockfrost.Response.StakePoolRelaysResponse do
use Blockfrost.Response.BaseSchema

defmodule StakePoolRelay do
use Blockfrost.Response.BaseSchema

embedded_schema do
field(:ipv4, :string)
field(:ipv6, :string)
field(:dns, :string)
field(:dns_srv, :string)
field(:port, :integer)
end
end

@type t :: [
%StakePoolRelay{
ipv4: String.t(),
ipv6: String.t(),
dns: String.t(),
dns_srv: String.t(),
port: integer()
}
]
@type t :: [Blockfrost.Shared.StakePoolRelay.t()]

@doc false
def cast(body), do: Enum.map(body, &StakePoolRelay.cast/1)
def cast(body), do: Enum.map(body, &Blockfrost.Shared.StakePoolRelay.cast/1)
end
@@ -0,0 +1,49 @@
defmodule Blockfrost.Response.SpecificTransactionResponse do
use Blockfrost.Response.BaseSchema

@type t :: %__MODULE__{
hash: String.t(),
block: String.t(),
block_height: integer(),
slot: integer(),
index: integer(),
output_amount: list(Blockfrost.Shared.Amount.t()),
fees: String.t(),
deposit: String.t(),
size: integer(),
invalid_before: String.t() | nil,
invalid_hereafter: String.t() | nil,
utxo_count: integer(),
withdrawal_count: integer(),
mir_cert_count: integer(),
delegation_count: integer(),
stake_cert_count: integer(),
pool_update_count: integer(),
pool_retire_count: integer(),
asset_mint_or_burn_count: integer(),
redeemer_count: integer()
}

embedded_schema do
field(:hash, :string)
field(:block, :string)
field(:block_height, :integer)
field(:slot, :integer)
field(:index, :integer)
embeds_many(:output_amount, Blockfrost.Shared.Amount)
field(:fees, :string)
field(:deposit, :string)
field(:size, :integer)
field(:invalid_before, :string)
field(:invalid_hereafter, :string)
field(:utxo_count, :integer)
field(:withdrawal_count, :integer)
field(:mir_cert_count, :integer)
field(:delegation_count, :integer)
field(:stake_cert_count, :integer)
field(:pool_update_count, :integer)
field(:pool_retire_count, :integer)
field(:asset_mint_or_burn_count, :integer)
field(:redeemer_count, :integer)
end
end
@@ -0,0 +1,6 @@
defmodule Blockfrost.Response.SubmitTransactionResponse do
@type t :: String.t()

@doc false
def cast(body), do: body
end
@@ -0,0 +1,26 @@
defmodule Blockfrost.Response.TransactionDelegationCertificatesResponse do
defmodule DelegationCertificate do
use Blockfrost.Response.BaseSchema

embedded_schema do
field(:index, :integer)
field(:cert_index, :integer)
field(:address, :string)
field(:pool_id, :string)
field(:active_epoch, :integer)
end
end

@type t :: [
%DelegationCertificate{
index: integer(),
cert_index: integer(),
address: String.t(),
pool_id: String.t(),
active_epoch: integer()
}
]

@doc false
def cast(body), do: Enum.map(body, &DelegationCertificate.cast/1)
end
@@ -0,0 +1,22 @@
defmodule Blockfrost.Response.TransactionMetadataResponse do
defmodule Metadata do
use Blockfrost.Response.BaseSchema

embedded_schema do
field(:label, :string)
field(:json_metadata, :map)
end
end

@type t :: [
%Metadata{
label: String.t(),
json_metadata: term()
}
]

@doc false
def cast(body) do
Enum.map(body, &Metadata.cast/1)
end
end

0 comments on commit 42c75d0

Please sign in to comment.