Blockchain explorer for Ethereum based network and a tool for inspecting and analyzing EVM based blockchains.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
blockscout/apps/block_scout_web/lib/block_scout_web/schema.ex

124 lines
3.6 KiB

defmodule BlockScoutWeb.Schema do
@moduledoc false
use Absinthe.Schema
use Absinthe.Relay.Schema, :modern
alias Absinthe.Middleware.Dataloader, as: AbsintheMiddlewareDataloader
alias Absinthe.Plugin, as: AbsinthePlugin
alias BlockScoutWeb.Resolvers.{
Address,
Block,
InternalTransaction,
TokenTransfer,
Transaction
}
alias Explorer.Chain
alias Explorer.Chain.InternalTransaction, as: ExplorerChainInternalTransaction
alias Explorer.Chain.TokenTransfer, as: ExplorerChainTokenTransfer
alias Explorer.Chain.Transaction, as: ExplorerChainTransaction
import_types(BlockScoutWeb.Schema.Types)
node interface do
resolve_type(fn
%ExplorerChainInternalTransaction{}, _ ->
:internal_transaction
%ExplorerChainTokenTransfer{}, _ ->
:token_transfer
%ExplorerChainTransaction{}, _ ->
:transaction
_, _ ->
nil
end)
end
query do
node field do
resolve(fn
%{type: :internal_transaction, id: id}, _ ->
%{"transaction_hash" => transaction_hash_string, "index" => index} = Jason.decode!(id)
{:ok, transaction_hash} = Chain.string_to_transaction_hash(transaction_hash_string)
InternalTransaction.get_by(%{transaction_hash: transaction_hash, index: index})
%{type: :token_transfer, id: id}, _ ->
%{"transaction_hash" => transaction_hash_string, "log_index" => log_index} = Jason.decode!(id)
{:ok, transaction_hash} = Chain.string_to_transaction_hash(transaction_hash_string)
TokenTransfer.get_by(%{transaction_hash: transaction_hash, log_index: log_index})
%{type: :transaction, id: transaction_hash_string}, _ ->
{:ok, hash} = Chain.string_to_transaction_hash(transaction_hash_string)
Transaction.get_by(%{}, %{hash: hash}, %{})
_, _ ->
{:error, "Unknown node"}
end)
end
@desc "Gets an address by hash."
field :address, :address do
arg(:hash, non_null(:address_hash))
resolve(&Address.get_by/3)
end
@desc "Gets addresses by address hash."
field :addresses, list_of(:address) do
arg(:hashes, non_null(list_of(non_null(:address_hash))))
resolve(&Address.get_by/3)
complexity(fn %{hashes: hashes}, child_complexity -> length(hashes) * child_complexity end)
end
@desc "Gets a block by number."
field :block, :block do
arg(:number, non_null(:integer))
resolve(&Block.get_by/3)
end
@desc "Gets token transfers by token contract address hash."
connection field(:token_transfers, node_type: :token_transfer) do
arg(:token_contract_address_hash, non_null(:address_hash))
arg(:count, :integer)
resolve(&TokenTransfer.get_by/3)
complexity(fn
%{first: first}, child_complexity ->
first * child_complexity
%{last: last}, child_complexity ->
last * child_complexity
end)
end
@desc "Gets a transaction by hash."
field :transaction, :transaction do
arg(:hash, non_null(:full_hash))
resolve(&Transaction.get_by/3)
end
end
subscription do
field :token_transfers, list_of(:token_transfer) do
arg(:token_contract_address_hash, non_null(:address_hash))
config(fn args, _info ->
{:ok, topic: to_string(args.token_contract_address_hash)}
end)
end
end
def context(context) do
loader = Dataloader.add_source(Dataloader.new(), :db, Chain.data())
Map.put(context, :loader, loader)
end
def plugins do
[AbsintheMiddlewareDataloader] ++ AbsinthePlugin.defaults()
end
end