Proxy for Account abstraction microservice (#9145)

* Proxy for Account abstraction microservice

* Process reviewer comments

* Fix reviewer comment

* Fix response for endpoints with the list

* Fix reviewer comment
pull/9198/head
Victor Baranov 10 months ago committed by GitHub
parent 9f23f398f6
commit 9c41c6abb6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 26
      .github/workflows/config.yml
  2. 1
      CHANGELOG.md
  3. 14
      apps/block_scout_web/lib/block_scout_web/api_router.ex
  4. 176
      apps/block_scout_web/lib/block_scout_web/controllers/api/v2/proxy/account_abstraction_controller.ex
  5. 14
      apps/block_scout_web/lib/block_scout_web/views/api/v2/helper.ex
  6. 203
      apps/explorer/lib/explorer/microservice_interfaces/account_abstraction.ex
  7. 12
      config/runtime.exs
  8. 2
      docker-compose/envs/common-blockscout.env

@ -75,7 +75,7 @@ jobs:
path: |
deps
_build
key: ${{ runner.os }}-${{ env.ELIXIR_VERSION }}-${{ env.OTP_VERSION }}-${{ env.MIX_ENV }}-deps-mixlockhash_34-${{ hashFiles('mix.lock') }}
key: ${{ runner.os }}-${{ env.ELIXIR_VERSION }}-${{ env.OTP_VERSION }}-${{ env.MIX_ENV }}-deps-mixlockhash_35-${{ hashFiles('mix.lock') }}
restore-keys: |
${{ runner.os }}-${{ env.ELIXIR_VERSION }}-${{ env.OTP_VERSION }}-${{ env.MIX_ENV }}-deps-
@ -133,7 +133,7 @@ jobs:
path: |
deps
_build
key: ${{ runner.os }}-${{ env.ELIXIR_VERSION }}-${{ env.OTP_VERSION }}-${{ env.MIX_ENV }}-deps-mixlockhash_34-${{ hashFiles('mix.lock') }}
key: ${{ runner.os }}-${{ env.ELIXIR_VERSION }}-${{ env.OTP_VERSION }}-${{ env.MIX_ENV }}-deps-mixlockhash_35-${{ hashFiles('mix.lock') }}
restore-keys: |
${{ runner.os }}-${{ env.ELIXIR_VERSION }}-${{ env.OTP_VERSION }}-${{ env.MIX_ENV }}-deps-"
@ -157,7 +157,7 @@ jobs:
path: |
deps
_build
key: ${{ runner.os }}-${{ env.ELIXIR_VERSION }}-${{ env.OTP_VERSION }}-${{ env.MIX_ENV }}-deps-mixlockhash_34-${{ hashFiles('mix.lock') }}
key: ${{ runner.os }}-${{ env.ELIXIR_VERSION }}-${{ env.OTP_VERSION }}-${{ env.MIX_ENV }}-deps-mixlockhash_35-${{ hashFiles('mix.lock') }}
restore-keys: |
${{ runner.os }}-${{ env.ELIXIR_VERSION }}-${{ env.OTP_VERSION }}-${{ env.MIX_ENV }}-deps-"
@ -186,7 +186,7 @@ jobs:
path: |
deps
_build
key: ${{ runner.os }}-${{ env.ELIXIR_VERSION }}-${{ env.OTP_VERSION }}-${{ env.MIX_ENV }}-deps-mixlockhash_34-${{ hashFiles('mix.lock') }}
key: ${{ runner.os }}-${{ env.ELIXIR_VERSION }}-${{ env.OTP_VERSION }}-${{ env.MIX_ENV }}-deps-mixlockhash_35-${{ hashFiles('mix.lock') }}
restore-keys: |
${{ runner.os }}-${{ env.ELIXIR_VERSION }}-${{ env.OTP_VERSION }}-${{ env.MIX_ENV }}-deps-"
@ -230,7 +230,7 @@ jobs:
path: |
deps
_build
key: ${{ runner.os }}-${{ env.ELIXIR_VERSION }}-${{ env.OTP_VERSION }}-${{ env.MIX_ENV }}-deps-mixlockhash_34-${{ hashFiles('mix.lock') }}
key: ${{ runner.os }}-${{ env.ELIXIR_VERSION }}-${{ env.OTP_VERSION }}-${{ env.MIX_ENV }}-deps-mixlockhash_35-${{ hashFiles('mix.lock') }}
restore-keys: |
${{ runner.os }}-${{ env.ELIXIR_VERSION }}-${{ env.OTP_VERSION }}-${{ env.MIX_ENV }}-deps-"
@ -256,7 +256,7 @@ jobs:
path: |
deps
_build
key: ${{ runner.os }}-${{ env.ELIXIR_VERSION }}-${{ env.OTP_VERSION }}-${{ env.MIX_ENV }}-deps-mixlockhash_34-${{ hashFiles('mix.lock') }}
key: ${{ runner.os }}-${{ env.ELIXIR_VERSION }}-${{ env.OTP_VERSION }}-${{ env.MIX_ENV }}-deps-mixlockhash_35-${{ hashFiles('mix.lock') }}
restore-keys: |
${{ runner.os }}-${{ env.ELIXIR_VERSION }}-${{ env.OTP_VERSION }}-${{ env.MIX_ENV }}-deps-"
@ -285,7 +285,7 @@ jobs:
path: |
deps
_build
key: ${{ runner.os }}-${{ env.ELIXIR_VERSION }}-${{ env.OTP_VERSION }}-${{ env.MIX_ENV }}-deps-mixlockhash_34-${{ hashFiles('mix.lock') }}
key: ${{ runner.os }}-${{ env.ELIXIR_VERSION }}-${{ env.OTP_VERSION }}-${{ env.MIX_ENV }}-deps-mixlockhash_35-${{ hashFiles('mix.lock') }}
restore-keys: |
${{ runner.os }}-${{ env.ELIXIR_VERSION }}-${{ env.OTP_VERSION }}-${{ env.MIX_ENV }}-deps-"
@ -333,7 +333,7 @@ jobs:
path: |
deps
_build
key: ${{ runner.os }}-${{ env.ELIXIR_VERSION }}-${{ env.OTP_VERSION }}-${{ env.MIX_ENV }}-deps-mixlockhash_34-${{ hashFiles('mix.lock') }}
key: ${{ runner.os }}-${{ env.ELIXIR_VERSION }}-${{ env.OTP_VERSION }}-${{ env.MIX_ENV }}-deps-mixlockhash_35-${{ hashFiles('mix.lock') }}
restore-keys: |
${{ runner.os }}-${{ env.ELIXIR_VERSION }}-${{ env.OTP_VERSION }}-${{ env.MIX_ENV }}-deps-"
@ -379,7 +379,7 @@ jobs:
path: |
deps
_build
key: ${{ runner.os }}-${{ env.ELIXIR_VERSION }}-${{ env.OTP_VERSION }}-${{ env.MIX_ENV }}-deps-mixlockhash_34-${{ hashFiles('mix.lock') }}
key: ${{ runner.os }}-${{ env.ELIXIR_VERSION }}-${{ env.OTP_VERSION }}-${{ env.MIX_ENV }}-deps-mixlockhash_35-${{ hashFiles('mix.lock') }}
restore-keys: |
${{ runner.os }}-${{ env.ELIXIR_VERSION }}-${{ env.OTP_VERSION }}-${{ env.MIX_ENV }}-deps-"
@ -441,7 +441,7 @@ jobs:
path: |
deps
_build
key: ${{ runner.os }}-${{ env.ELIXIR_VERSION }}-${{ env.OTP_VERSION }}-${{ env.MIX_ENV }}-deps-mixlockhash_34-${{ hashFiles('mix.lock') }}
key: ${{ runner.os }}-${{ env.ELIXIR_VERSION }}-${{ env.OTP_VERSION }}-${{ env.MIX_ENV }}-deps-mixlockhash_35-${{ hashFiles('mix.lock') }}
restore-keys: |
${{ runner.os }}-${{ env.ELIXIR_VERSION }}-${{ env.OTP_VERSION }}-${{ env.MIX_ENV }}-deps-"
@ -501,7 +501,7 @@ jobs:
path: |
deps
_build
key: ${{ runner.os }}-${{ env.ELIXIR_VERSION }}-${{ env.OTP_VERSION }}-${{ env.MIX_ENV }}-deps-mixlockhash_34-${{ hashFiles('mix.lock') }}
key: ${{ runner.os }}-${{ env.ELIXIR_VERSION }}-${{ env.OTP_VERSION }}-${{ env.MIX_ENV }}-deps-mixlockhash_35-${{ hashFiles('mix.lock') }}
restore-keys: |
${{ runner.os }}-${{ env.ELIXIR_VERSION }}-${{ env.OTP_VERSION }}-${{ env.MIX_ENV }}-deps-"
@ -572,7 +572,7 @@ jobs:
path: |
deps
_build
key: ${{ runner.os }}-${{ env.ELIXIR_VERSION }}-${{ env.OTP_VERSION }}-${{ env.MIX_ENV }}-deps-mixlockhash_34-${{ hashFiles('mix.lock') }}
key: ${{ runner.os }}-${{ env.ELIXIR_VERSION }}-${{ env.OTP_VERSION }}-${{ env.MIX_ENV }}-deps-mixlockhash_35-${{ hashFiles('mix.lock') }}
restore-keys: |
${{ runner.os }}-${{ env.ELIXIR_VERSION }}-${{ env.OTP_VERSION }}-${{ env.MIX_ENV }}-deps-"
@ -640,7 +640,7 @@ jobs:
path: |
deps
_build
key: ${{ runner.os }}-${{ env.ELIXIR_VERSION }}-${{ env.OTP_VERSION }}-${{ env.MIX_ENV }}-deps-mixlockhash_34-${{ hashFiles('mix.lock') }}
key: ${{ runner.os }}-${{ env.ELIXIR_VERSION }}-${{ env.OTP_VERSION }}-${{ env.MIX_ENV }}-deps-mixlockhash_35-${{ hashFiles('mix.lock') }}
restore-keys: |
${{ runner.os }}-${{ env.ELIXIR_VERSION }}-${{ env.OTP_VERSION }}-${{ env.MIX_ENV }}-deps-"

@ -5,6 +5,7 @@
### Features
- [#9155](https://github.com/blockscout/blockscout/pull/9155) - Allow bypassing avg block time in proxy implementation re-fetch ttl calculation
- [#9145](https://github.com/blockscout/blockscout/pull/9145) - Proxy for Account abstraction microservice
- [#9131](https://github.com/blockscout/blockscout/pull/9131) - Merge addresses stage with address referencing
- [#9072](https://github.com/blockscout/blockscout/pull/9072) - Add tracing by block logic for geth
- [#9056](https://github.com/blockscout/blockscout/pull/9056) - Noves.fi API proxy

@ -307,6 +307,20 @@ defmodule BlockScoutWeb.ApiRouter do
get("/transactions/:transaction_hash_param/describe", V2.Proxy.NovesFiController, :describe_transaction)
get("/addresses/:address_hash_param/transactions", V2.Proxy.NovesFiController, :address_transactions)
end
scope "/account-abstraction" do
get("/operations/:operation_hash_param", V2.Proxy.AccountAbstractionController, :operation)
get("/bundlers/:address_hash_param", V2.Proxy.AccountAbstractionController, :bundler)
get("/bundlers", V2.Proxy.AccountAbstractionController, :bundlers)
get("/factories/:address_hash_param", V2.Proxy.AccountAbstractionController, :factory)
get("/factories", V2.Proxy.AccountAbstractionController, :factories)
get("/paymasters/:address_hash_param", V2.Proxy.AccountAbstractionController, :paymaster)
get("/paymasters", V2.Proxy.AccountAbstractionController, :paymasters)
get("/accounts/:address_hash_param", V2.Proxy.AccountAbstractionController, :account)
get("/accounts", V2.Proxy.AccountAbstractionController, :accounts)
get("/bundles", V2.Proxy.AccountAbstractionController, :bundles)
get("/operations", V2.Proxy.AccountAbstractionController, :operations)
end
end
end

@ -0,0 +1,176 @@
defmodule BlockScoutWeb.API.V2.Proxy.AccountAbstractionController do
use BlockScoutWeb, :controller
alias BlockScoutWeb.API.V2.Helper
alias Explorer.Chain
alias Explorer.MicroserviceInterfaces.AccountAbstraction
@address_fields ["bundler", "entry_point", "sender", "address", "factory", "paymaster"]
action_fallback(BlockScoutWeb.API.V2.FallbackController)
@doc """
Function to handle GET requests to `/api/v2/proxy/account-abstraction/operations/:user_operation_hash_param` endpoint.
"""
@spec operation(Plug.Conn.t(), map()) :: Plug.Conn.t() | {atom(), any()}
def operation(conn, %{"operation_hash_param" => operation_hash_string}) do
operation_hash_string
|> AccountAbstraction.get_user_ops_by_hash()
|> process_response(conn)
end
@doc """
Function to handle GET requests to `/api/v2/proxy/account-abstraction/bundlers/:address_hash_param` endpoint.
"""
@spec bundler(Plug.Conn.t(), map()) :: Plug.Conn.t() | {atom(), any()}
def bundler(conn, %{"address_hash_param" => address_hash_string}) do
address_hash_string
|> AccountAbstraction.get_bundler_by_hash()
|> process_response(conn)
end
@doc """
Function to handle GET requests to `/api/v2/proxy/account-abstraction/bundlers` endpoint.
"""
@spec bundlers(Plug.Conn.t(), map()) :: Plug.Conn.t() | {atom(), any()}
def bundlers(conn, query_string) do
query_string
|> AccountAbstraction.get_bundlers()
|> process_response(conn)
end
@doc """
Function to handle GET requests to `/api/v2/proxy/account-abstraction/factories/:address_hash_param` endpoint.
"""
@spec factory(Plug.Conn.t(), map()) :: Plug.Conn.t() | {atom(), any()}
def factory(conn, %{"address_hash_param" => address_hash_string}) do
address_hash_string
|> AccountAbstraction.get_factory_by_hash()
|> process_response(conn)
end
@doc """
Function to handle GET requests to `/api/v2/proxy/account-abstraction/factories` endpoint.
"""
@spec factories(Plug.Conn.t(), map()) :: Plug.Conn.t() | {atom(), any()}
def factories(conn, query_string) do
query_string
|> AccountAbstraction.get_factories()
|> process_response(conn)
end
@doc """
Function to handle GET requests to `/api/v2/proxy/account-abstraction/paymasters/:address_hash_param` endpoint.
"""
@spec paymaster(Plug.Conn.t(), map()) :: Plug.Conn.t() | {atom(), any()}
def paymaster(conn, %{"address_hash_param" => address_hash_string}) do
address_hash_string
|> AccountAbstraction.get_paymaster_by_hash()
|> process_response(conn)
end
@doc """
Function to handle GET requests to `/api/v2/proxy/account-abstraction/paymasters` endpoint.
"""
@spec paymasters(Plug.Conn.t(), map()) :: Plug.Conn.t() | {atom(), any()}
def paymasters(conn, query_string) do
query_string
|> AccountAbstraction.get_paymasters()
|> process_response(conn)
end
@doc """
Function to handle GET requests to `/api/v2/proxy/account-abstraction/accounts/:address_hash_param` endpoint.
"""
@spec account(Plug.Conn.t(), map()) :: Plug.Conn.t() | {atom(), any()}
def account(conn, %{"address_hash_param" => address_hash_string}) do
address_hash_string
|> AccountAbstraction.get_account_by_hash()
|> process_response(conn)
end
@doc """
Function to handle GET requests to `/api/v2/proxy/account-abstraction/accounts` endpoint.
"""
@spec accounts(Plug.Conn.t(), map()) :: Plug.Conn.t() | {atom(), any()}
def accounts(conn, query_string) do
query_string
|> AccountAbstraction.get_accounts()
|> process_response(conn)
end
@doc """
Function to handle GET requests to `/api/v2/proxy/account-abstraction/bundles` endpoint.
"""
@spec bundles(Plug.Conn.t(), map()) :: Plug.Conn.t() | {atom(), any()}
def bundles(conn, query_string) do
query_string
|> AccountAbstraction.get_bundles()
|> process_response(conn)
end
@doc """
Function to handle GET requests to `/api/v2/proxy/account-abstraction/operations` endpoint.
"""
@spec operations(Plug.Conn.t(), map()) :: Plug.Conn.t() | {atom(), any()}
def operations(conn, query_string) do
query_string
|> AccountAbstraction.get_operations()
|> process_response(conn)
end
defp extended_info(response) do
case response do
%{"items" => items} ->
extended_items =
Enum.map(items, fn response_item ->
add_address_extended_info(response_item)
end)
response
|> Map.put("items", extended_items)
_ ->
add_address_extended_info(response)
end
end
defp add_address_extended_info(response) do
@address_fields
|> Enum.reduce(response, fn address_output_field, output_response ->
if Map.has_key?(output_response, address_output_field) do
output_response
|> Map.replace(
address_output_field,
address_info_from_hash_string(Map.get(output_response, address_output_field))
)
else
output_response
end
end)
end
defp address_info_from_hash_string(address_hash_string) do
with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string),
{:ok, address} <- Chain.hash_to_address(address_hash, [], false) do
Helper.address_with_info(address, address_hash_string)
else
_ -> address_hash_string
end
end
defp process_response(response, conn) do
case response do
{:error, :disabled} ->
conn
|> put_status(501)
|> json(extended_info(%{message: "Service is disabled"}))
{status_code, response} ->
conn
|> put_status(status_code)
|> json(extended_info(response))
end
end
end

@ -48,7 +48,11 @@ defmodule BlockScoutWeb.API.V2.Helper do
})
end
defp address_with_info(%Address{} = address, _address_hash) do
@doc """
Gets address with the additional info for api v2
"""
@spec address_with_info(any(), any()) :: nil | %{optional(<<_::32, _::_*8>>) => any()}
def address_with_info(%Address{} = address, _address_hash) do
%{
"hash" => Address.checksum(address),
"is_contract" => Address.is_smart_contract(address),
@ -59,21 +63,21 @@ defmodule BlockScoutWeb.API.V2.Helper do
}
end
defp address_with_info(%{ens_domain_name: name}, address_hash) do
def address_with_info(%{ens_domain_name: name}, address_hash) do
nil
|> address_with_info(address_hash)
|> Map.put("ens_domain_name", name)
end
defp address_with_info(%NotLoaded{}, address_hash) do
def address_with_info(%NotLoaded{}, address_hash) do
address_with_info(nil, address_hash)
end
defp address_with_info(nil, nil) do
def address_with_info(nil, nil) do
nil
end
defp address_with_info(_, address_hash) do
def address_with_info(_, address_hash) do
%{
"hash" => Address.checksum(address_hash),
"is_contract" => false,

@ -0,0 +1,203 @@
defmodule Explorer.MicroserviceInterfaces.AccountAbstraction do
@moduledoc """
Interface to interact with Blockscout Account Abstraction (EIP-4337) microservice
"""
alias Explorer.Utility.Microservice
alias HTTPoison.Response
require Logger
@doc """
Get user operation by hash via GET {{baseUrl}}/api/v1/userOps/:hash
"""
@spec get_user_ops_by_hash(binary()) :: {non_neg_integer(), map()} | {:error, :disabled}
def get_user_ops_by_hash(user_operation_hash_string) do
with :ok <- Microservice.check_enabled(__MODULE__) do
query_params = %{}
http_get_request(operation_by_hash_url(user_operation_hash_string), query_params)
end
end
@doc """
Get operations list via GET {{baseUrl}}/api/v1/operations
"""
@spec get_operations(map()) :: {non_neg_integer(), map()} | {:error, :disabled}
def get_operations(query_params) do
with :ok <- Microservice.check_enabled(__MODULE__) do
http_get_request(operations_url(), query_params)
end
end
@doc """
Get bundler by address hash via GET {{baseUrl}}/api/v1/bundlers/:address
"""
@spec get_bundler_by_hash(binary()) :: {non_neg_integer(), map()} | {:error, :disabled}
def get_bundler_by_hash(address_hash_string) do
with :ok <- Microservice.check_enabled(__MODULE__) do
query_params = %{}
http_get_request(bundler_by_hash_url(address_hash_string), query_params)
end
end
@doc """
Get bundlers list via GET {{baseUrl}}/api/v1/bundlers
"""
@spec get_bundlers(map()) :: {non_neg_integer(), map()} | {:error, :disabled}
def get_bundlers(query_params) do
with :ok <- Microservice.check_enabled(__MODULE__) do
http_get_request(bundlers_url(), query_params)
end
end
@doc """
Get factory by address hash via GET {{baseUrl}}/api/v1/factories/:address
"""
@spec get_factory_by_hash(binary()) :: {non_neg_integer(), map()} | {:error, :disabled}
def get_factory_by_hash(address_hash_string) do
with :ok <- Microservice.check_enabled(__MODULE__) do
query_params = %{}
http_get_request(factory_by_hash_url(address_hash_string), query_params)
end
end
@doc """
Get factories list via GET {{baseUrl}}/api/v1/factories
"""
@spec get_factories(map()) :: {non_neg_integer(), map()} | {:error, :disabled}
def get_factories(query_params) do
with :ok <- Microservice.check_enabled(__MODULE__) do
http_get_request(factories_url(), query_params)
end
end
@doc """
Get paymaster by address hash via GET {{baseUrl}}/api/v1/paymasters/:address
"""
@spec get_paymaster_by_hash(binary()) :: {non_neg_integer(), map()} | {:error, :disabled}
def get_paymaster_by_hash(address_hash_string) do
with :ok <- Microservice.check_enabled(__MODULE__) do
query_params = %{}
http_get_request(paymaster_by_hash_url(address_hash_string), query_params)
end
end
@doc """
Get paymasters list via GET {{baseUrl}}/api/v1/paymasters
"""
@spec get_paymasters(map()) :: {non_neg_integer(), map()} | {:error, :disabled}
def get_paymasters(query_params) do
with :ok <- Microservice.check_enabled(__MODULE__) do
http_get_request(paymasters_url(), query_params)
end
end
@doc """
Get account by address hash via GET {{baseUrl}}/api/v1/accounts/:address
"""
@spec get_account_by_hash(binary()) :: {non_neg_integer(), map()} | {:error, :disabled}
def get_account_by_hash(address_hash_string) do
with :ok <- Microservice.check_enabled(__MODULE__) do
query_params = %{}
http_get_request(account_by_hash_url(address_hash_string), query_params)
end
end
@doc """
Get accounts list via GET {{baseUrl}}/api/v1/accounts
"""
@spec get_accounts(map()) :: {non_neg_integer(), map()} | {:error, :disabled}
def get_accounts(query_params) do
with :ok <- Microservice.check_enabled(__MODULE__) do
http_get_request(accounts_url(), query_params)
end
end
@doc """
Get bundles list via GET {{baseUrl}}/api/v1/bundles
"""
@spec get_bundles(map()) :: {non_neg_integer(), map()} | {:error, :disabled}
def get_bundles(query_params) do
with :ok <- Microservice.check_enabled(__MODULE__) do
http_get_request(bundles_url(), query_params)
end
end
defp http_get_request(url, query_params) do
case HTTPoison.get(url, [], params: query_params) do
{:ok, %Response{body: body, status_code: 200}} ->
{:ok, response_json} = Jason.decode(body)
{200, response_json}
{_, %Response{body: body, status_code: status_code} = error} ->
old_truncate = Application.get_env(:logger, :truncate)
Logger.configure(truncate: :infinity)
Logger.error(fn ->
[
"Error while sending request to Account Abstraction microservice url: #{url}: ",
inspect(error, limit: :infinity, printable_limit: :infinity)
]
end)
Logger.configure(truncate: old_truncate)
{:ok, response_json} = Jason.decode(body)
{status_code, response_json}
end
end
@spec enabled?() :: boolean
def enabled?, do: Application.get_env(:explorer, __MODULE__)[:enabled]
defp operation_by_hash_url(user_op_hash) do
"#{base_url()}/userOps/#{user_op_hash}"
end
defp operations_url do
"#{base_url()}/userOps"
end
defp bundler_by_hash_url(address_hash) do
"#{base_url()}/bundlers/#{address_hash}"
end
defp bundlers_url do
"#{base_url()}/bundlers"
end
defp factory_by_hash_url(address_hash) do
"#{base_url()}/factories/#{address_hash}"
end
defp factories_url do
"#{base_url()}/factories"
end
defp paymaster_by_hash_url(address_hash) do
"#{base_url()}/paymasters/#{address_hash}"
end
defp paymasters_url do
"#{base_url()}/paymasters"
end
defp account_by_hash_url(address_hash) do
"#{base_url()}/accounts/#{address_hash}"
end
defp accounts_url do
"#{base_url()}/accounts"
end
defp bundles_url do
"#{base_url()}/bundles"
end
defp base_url do
"#{Microservice.base_url(__MODULE__)}/api/v1"
end
end

@ -405,6 +405,14 @@ config :explorer, Explorer.SmartContract.SigProviderInterface,
service_url: System.get_env("MICROSERVICE_SIG_PROVIDER_URL"),
enabled: ConfigHelper.parse_bool_env_var("MICROSERVICE_SIG_PROVIDER_ENABLED")
config :explorer, Explorer.MicroserviceInterfaces.BENS,
service_url: System.get_env("MICROSERVICE_BENS_URL"),
enabled: ConfigHelper.parse_bool_env_var("MICROSERVICE_BENS_ENABLED")
config :explorer, Explorer.MicroserviceInterfaces.AccountAbstraction,
service_url: System.get_env("MICROSERVICE_ACCOUNT_ABSTRACTION_URL"),
enabled: ConfigHelper.parse_bool_env_var("MICROSERVICE_ACCOUNT_ABSTRACTION_ENABLED")
config :explorer, Explorer.ThirdPartyIntegrations.AirTable,
table_url: System.get_env("ACCOUNT_PUBLIC_TAGS_AIRTABLE_URL"),
api_key: System.get_env("ACCOUNT_PUBLIC_TAGS_AIRTABLE_API_KEY")
@ -461,10 +469,6 @@ config :explorer, Explorer.Chain.Transaction,
config :explorer, Explorer.Chain.Cache.AddressesTabsCounters,
ttl: ConfigHelper.parse_time_env_var("ADDRESSES_TABS_COUNTERS_TTL", "10m")
config :explorer, Explorer.MicroserviceInterfaces.BENS,
service_url: System.get_env("MICROSERVICE_BENS_URL"),
enabled: ConfigHelper.parse_bool_env_var("MICROSERVICE_BENS_ENABLED")
config :explorer, Explorer.Migrator.TransactionsDenormalization,
batch_size: ConfigHelper.parse_integer_env_var("DENORMALIZATION_MIGRATION_BATCH_SIZE", 500),
concurrency: ConfigHelper.parse_integer_env_var("DENORMALIZATION_MIGRATION_CONCURRENCY", 10)

@ -238,6 +238,8 @@ MICROSERVICE_SIG_PROVIDER_ENABLED=true
MICROSERVICE_SIG_PROVIDER_URL=http://sig-provider:8050/
# MICROSERVICE_BENS_URL=
# MICROSERVICE_BENS_ENABLED=
#MICROSERVICE_ACCOUNT_ABSTRACTION_ENABLED=true
#MICROSERVICE_ACCOUNT_ABSTRACTION_URL=
DECODE_NOT_A_CONTRACT_CALLS=true
# DATABASE_READ_ONLY_API_URL=
# ACCOUNT_DATABASE_URL=

Loading…
Cancel
Save