Packages
kujira
0.1.8
0.1.80
0.1.79
0.1.78
0.1.77
0.1.76
0.1.75
0.1.74
0.1.73
0.1.72
0.1.71
0.1.70
0.1.69
0.1.68
0.1.67
0.1.66
0.1.65
0.1.64
0.1.63
0.1.62
0.1.61
0.1.60
0.1.59
0.1.58
0.1.57
0.1.56
0.1.55
0.1.54
0.1.53
0.1.52
0.1.51
0.1.50
0.1.49
0.1.48
0.1.47
0.1.46
0.1.45
0.1.44
0.1.43
0.1.42
0.1.41
0.1.40
0.1.39
0.1.38
0.1.37
0.1.36
0.1.35
0.1.34
0.1.33
0.1.32
0.1.31
0.1.30
0.1.29
0.1.28
0.1.27
0.1.25
0.1.24
0.1.23
0.1.22
0.1.21
0.1.20
0.1.19
0.1.18
0.1.17
0.1.16
0.1.15
0.1.14
0.1.13
0.1.12
0.1.10
0.1.9
0.1.8
0.1.7
0.1.6
0.1.5
0.1.4
0.1.3
0.1.2
0.1.1
0.1.0
Elixir interfaces to Kujira dApps, for building indexers, APIs and bots
Current section
Files
Jump to
Current section
Files
lib/kujira/contract.ex
defmodule Kujira.Contract do
@moduledoc """
Convenience methods for querying CosmWasm smart contracts on Kujira
"""
@doc """
Queries the full, raw contract state at an address. It's highly recommended to memoize any calls to this function,
and invalidate them in response to external events e.g. a matching tx in a node websocket subscription
## Examples
iex> Kujira.hello()
:world
"""
alias Cosmwasm.Wasm.V1.Query.Stub
alias Cosmwasm.Wasm.V1.QuerySmartContractStateRequest
alias Cosmwasm.Wasm.V1.QueryContractsByCodeRequest
def query_state_all do
:world
end
@spec by_code(GRPC.Channel.t(), integer()) ::
{:ok, list(String.t())} | {:error, GRPC.RPCError.t()}
def by_code(channel, code_id) do
with {:ok, %{contracts: contracts}} <-
Stub.contracts_by_code(
channel,
QueryContractsByCodeRequest.new(code_id: code_id)
) do
{:ok, contracts}
end
end
@spec by_codes(GRPC.Channel.t(), list(integer())) ::
{:ok, list(String.t())} | {:error, GRPC.RPCError.t()}
def by_codes(channel, code_ids) do
Enum.reduce(code_ids, {:ok, []}, fn
el, {:ok, agg} ->
case by_code(channel, el) do
{:ok, contracts} -> {:ok, agg ++ contracts}
err -> err
end
_, err ->
err
end)
end
@spec get(Channel.t(), {module(), String.t()}) :: {:ok, struct()} | {:error, :not_found}
def get(channel, {module, address}) do
Memoize.Cache.get_or_run({__MODULE__, :resolve, [address]}, fn ->
with {:ok, config} <- query_state_smart(channel, address, %{config: %{}}),
{:ok, struct} <- module.from_config(address, config) do
{:ok, struct}
else
_ ->
{:error, :not_found}
end
end)
end
@spec list(GRPC.Channel.t(), module(), list(integer())) :: {:ok, list(struct())} | :error
def list(channel, module, code_ids) when is_list(code_ids) do
Memoize.Cache.get_or_run(
{__MODULE__, :resolve, [code_ids]},
fn ->
with {:ok, contracts} <- by_codes(channel, code_ids),
{:ok, struct} <-
contracts
|> Task.async_stream(&get(channel, {module, &1}))
|> Enum.reduce({:ok, []}, fn
{:ok, {:ok, x}}, {:ok, xs} ->
{:ok, [x | xs]}
_, err ->
err
end) do
{:ok, struct}
else
_ ->
:error
end
end,
expires_in: 24 * 60 * 1000
)
end
@spec query_state_smart(GRPC.Channel.t(), String.t(), map()) ::
{:ok, map()} | {:error, GRPC.RPCError.t()}
def query_state_smart(channel, address, query) do
with {:ok, %{data: data}} <-
Stub.smart_contract_state(
channel,
QuerySmartContractStateRequest.new(
address: address,
query_data: Jason.encode!(query)
)
),
{:ok, res} <- Jason.decode(data) do
{:ok, res}
end
end
end