diff --git a/.env.example b/.env.example index af282507..08836e65 100644 --- a/.env.example +++ b/.env.example @@ -1,8 +1,10 @@ export DB_TYPE= # set to postgresql if you want to use postgresql, empty otherwise (sqlite). export DISABLE_MAINNET_SYNC=true # Set to true if you want to disable mainnet sync export DISABLE_TESTNET_SYNC=true # Set to true if you want to disable testnet sync +export DISABLE_SEPOLIA_SYNC=true # Set to true if you want to disable sepolia sync export RPC_API_HOST= # Set to your mainnet rpc api host, is will be used in the explorer as "Mainnet" export TESTNET_RPC_API_HOST= # Set to your testnet rpc api host, is will be used in the explorer as "Testnet" +export SEPOLIA_RPC_API_HOST= # Set to your sepolia rpc api host, is will be used in the explorer as "Sepolia" export DB_NAME= # set DB creds export DB_USER= export DB_PASS= diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3eb2da41..2c99187e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,6 +18,7 @@ jobs: env: RPC_API_HOST: ${{ secrets.RPC_API_HOST }} TESTNET_RPC_API_HOST: ${{ secrets.TESTNET_RPC_API_HOST }} + SEPOLIA_RPC_API_HOST: ${{ secrets.SEPOLIA_RPC_API_HOST }} name: Build and test runs-on: ubuntu-latest services: diff --git a/.github/workflows/deploy-production.yaml b/.github/workflows/deploy-production.yaml index 61e0b9c1..100d6aaf 100644 --- a/.github/workflows/deploy-production.yaml +++ b/.github/workflows/deploy-production.yaml @@ -52,6 +52,7 @@ jobs: PHX_SERVER: ${{ vars.PHX_SERVER }} RPC_API_HOST: ${{ secrets.RPC_API_HOST }} TESTNET_RPC_API_HOST: ${{ secrets.TESTNET_RPC_API_HOST }} + SEPOLIA_RPC_API_HOST: ${{ secrets.SEPOLIA_RPC_API_HOST }} AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} AWS_REGION: ${{ vars.AWS_REGION }} @@ -67,6 +68,7 @@ jobs: SENTRY_DSN: ${{ secrets.SENTRY_DSN }} ENABLE_MAINNET_SYNC: "true" ENABLE_TESTNET_SYNC: "true" + ENABLE_SEPOLIA_SYNC: "true" ENABLE_GATEWAY_DATA: "true" run: | ansible-playbook -i ansible/inventory.yaml ansible/playbooks/deployment.yaml diff --git a/.github/workflows/deploy-testing.yaml b/.github/workflows/deploy-testing.yaml index 7b8d8c84..f188d6ea 100644 --- a/.github/workflows/deploy-testing.yaml +++ b/.github/workflows/deploy-testing.yaml @@ -53,6 +53,7 @@ jobs: PHX_SERVER: ${{ vars.PHX_SERVER }} RPC_API_HOST: ${{ secrets.RPC_API_HOST }} TESTNET_RPC_API_HOST: ${{ secrets.TESTNET_RPC_API_HOST }} + SEPOLIA_RPC_API_HOST: ${{ secrets.SEPOLIA_RPC_API_HOST }} AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} AWS_REGION: ${{ vars.AWS_REGION }} @@ -64,6 +65,7 @@ jobs: ANSIBLE_STDOUT_CALLBACK: "yaml" ENABLE_MAINNET_SYNC: "true" ENABLE_TESTNET_SYNC: "true" + ENABLE_SEPOLIA_SYNC: "true" ENABLE_GATEWAY_DATA: "true" NEWRELIC_KEY: ${{ secrets.NEWRELIC_KEY }} NEWRELIC_APP_NAME: ${{ vars.NEWRELIC_APP_NAME }} diff --git a/README.md b/README.md index 599e1a72..dbc675fd 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,7 @@ Set the following environment variables: ```bash export RPC_API_HOST=your_rpc_hostname export TESTNET_RPC_API_HOST=testnet_rpc_hostname +export SEPOLIA_RPC_API_HOST=sepolia_rpc_hostname ``` ### RPC with Juno @@ -100,6 +101,7 @@ The synchronization process is activated by default, you can turn it off by conf ```bash export DISABLE_MAINNET_SYNC=true export DISABLE_TESTNET_SYNC=true +export DISABLE_SEPOLIA_SYNC=true ``` It's worth noting that you have the flexibility to select which networks you want to synchronize by adjusting these environment variables. diff --git a/ansible/playbooks/deployment.yaml b/ansible/playbooks/deployment.yaml index 4479563d..6d08fdb3 100644 --- a/ansible/playbooks/deployment.yaml +++ b/ansible/playbooks/deployment.yaml @@ -41,6 +41,7 @@ MIX_ENV: prod RPC_API_HOST: "{{ lookup('ansible.builtin.env', 'RPC_API_HOST') }}" TESTNET_RPC_API_HOST: "{{ lookup('ansible.builtin.env', 'TESTNET_RPC_API_HOST') }}" + SEPOLIA_RPC_API_HOST: "{{ lookup('ansible.builtin.env', 'SEPOLIA_RPC_API_HOST') }}" DB_TYPE: "{{ lookup('ansible.builtin.env', 'DB_TYPE') }}" DATABASE_URL: "{{ lookup('ansible.builtin.env', 'DATABASE_URL') }}" NEWRELIC_KEY: @@ -51,6 +52,7 @@ SENTRY_DSN: "{{ lookup('ansible.builtin.env', 'SENTRY_DSN') }}" ENABLE_MAINNET_SYNC: "{{ lookup('ansible.builtin.env', 'ENABLE_MAINNET_SYNC') }}" ENABLE_TESTNET_SYNC: "{{ lookup('ansible.builtin.env', 'ENABLE_TESTNET_SYNC') }}" + ENABLE_SEPOLIA_SYNC: "{{ lookup('ansible.builtin.env', 'ENABLE_SEPOLIA_SYNC') }}" ENABLE_GATEWAY_DATA: "{{ lookup('ansible.builtin.env', 'ENABLE_GATEWAY_DATA') }}" args: chdir: "/home/{{ lookup('ansible.builtin.env', 'TS_USER') }}/tmp/stark_compass_explorer" @@ -80,6 +82,7 @@ database_url: "{{ lookup('ansible.builtin.env', 'DATABASE_URL') }}" rpc_api_host: "{{ lookup('ansible.builtin.env', 'RPC_API_HOST') }}" testnet_rpc_api_host: "{{ lookup('ansible.builtin.env', 'TESTNET_RPC_API_HOST') }}" + sepolia_rpc_api_host: "{{ lookup('ansible.builtin.env', 'SEPOLIA_RPC_API_HOST') }}" aws_access_key_id: "{{ lookup('ansible.builtin.env', 'AWS_ACCESS_KEY_ID') }}" aws_secret_access_key: "{{ lookup('ansible.builtin.env', 'AWS_SECRET_ACCESS_KEY') }}" aws_region: "{{ lookup('ansible.builtin.env', 'AWS_REGION') }}" @@ -90,6 +93,7 @@ sentry_dsn: "{{ lookup('ansible.builtin.env', 'SENTRY_DSN') }}" enable_mainnet_sync: "{{ lookup('ansible.builtin.env', 'ENABLE_MAINNET_SYNC') }}" enable_testnet_sync: "{{ lookup('ansible.builtin.env', 'ENABLE_TESTNET_SYNC') }}" + enable_sepolia_sync: "{{ lookup('ansible.builtin.env', 'ENABLE_SEPOLIA_SYNC') }}" enable_gateway_data: "{{ lookup('ansible.builtin.env', 'ENABLE_GATEWAY_DATA') }}" - name: Create user systemd directory diff --git a/ansible/playbooks/templates/.env.j2 b/ansible/playbooks/templates/.env.j2 index 7b2ecc77..83566e67 100644 --- a/ansible/playbooks/templates/.env.j2 +++ b/ansible/playbooks/templates/.env.j2 @@ -5,6 +5,7 @@ DB_TYPE={{ db_type }} DATABASE_URL={{ database_url }} RPC_API_HOST={{ rpc_api_host }} TESTNET_RPC_API_HOST={{ testnet_rpc_api_host }} +SEPOLIA_RPC_API_HOST={{ sepolia_rpc_api_host }} AWS_ACCESS_KEY_ID={{ aws_access_key_id }} AWS_SECRET_ACCESS_KEY={{ aws_secret_access_key }} AWS_REGION={{ aws_region }} @@ -16,3 +17,4 @@ SENTRY_DSN={{ sentry_dsn }} SENTRY_ENV={{ sentry_env }} ENABLE_MAINNET_SYNC={{ enable_mainnet_sync }} ENABLE_TESTNET_SYNC={{ enable_testnet_sync }} +ENABLE_SEPOLIA_SYNC={{ enable_sepolia_sync }} diff --git a/config/config.exs b/config/config.exs index 3599a8b4..3f651376 100644 --- a/config/config.exs +++ b/config/config.exs @@ -62,7 +62,7 @@ config :esbuild, ] config :starknet_explorer, - allowed_networks: [:mainnet, :testnet] + allowed_networks: [:mainnet, :testnet, :sepolia] # Import environment specific config. This must remain at the bottom # of this file so it overrides the configuration defined above. diff --git a/config/runtime.exs b/config/runtime.exs index 9eba51b0..75cf6556 100644 --- a/config/runtime.exs +++ b/config/runtime.exs @@ -32,9 +32,16 @@ testnet_rpc_host = environment variable for testnet is missing. """ +sepolia_rpc_host = + System.get_env("SEPOLIA_RPC_API_HOST") || + raise """ + environment variable for sepolia is missing. + """ + config :starknet_explorer, rpc_host: rpc_host, - testnet_host: testnet_rpc_host + testnet_host: testnet_rpc_host, + sepolia_host: sepolia_rpc_host config :starknet_explorer, rpc_host: rpc_host diff --git a/lib/cache_request_warmer.ex b/lib/cache_request_warmer.ex index 20991496..2c2a7c63 100644 --- a/lib/cache_request_warmer.ex +++ b/lib/cache_request_warmer.ex @@ -6,7 +6,7 @@ defmodule StarknetExplorer.Cache.BlockWarmer do def interval, do: @interval def execute(%{network: network}) - when network in [:mainnet, :testnet] do + when network in [:mainnet, :testnet, :sepolia] do Logger.debug("Warming cache for #{network}") # Try/Rescue is not really an elixir/erlang thing to do, but # I think this is the most simple way to do this, since diff --git a/lib/starknet_explorer/application.ex b/lib/starknet_explorer/application.ex index 899be335..61527730 100644 --- a/lib/starknet_explorer/application.ex +++ b/lib/starknet_explorer/application.ex @@ -35,6 +35,20 @@ defmodule StarknetExplorer.Application do ] end + sepolia_state_sync = + if System.get_env("DISABLE_SEPOLIA_SYNC") == "true" do + [] + else + # Start the State Sync System server for sepolia. + [ + Supervisor.child_spec( + {StarknetExplorer.Blockchain.StateSyncSystem, + [network: :sepolia, name: :sepolia_state_sync]}, + id: :sepolia_state_sync + ) + ] + end + children = [ # Start the Telemetry supervisor @@ -50,7 +64,7 @@ defmodule StarknetExplorer.Application do # Start a worker by calling: StarknetExplorer.Worker.start_link(arg) # {StarknetExplorer.Worker, arg} StarknetExplorer.IndexCache - ] ++ testnet_state_sync ++ mainnet_state_sync + ] ++ sepolia_state_sync ++ testnet_state_sync ++ mainnet_state_sync # See https://hexdocs.pm/elixir/Supervisor.html # for other strategies and supported options diff --git a/lib/starknet_explorer/block/block.ex b/lib/starknet_explorer/block/block.ex index c501bd8e..5d29d1cd 100644 --- a/lib/starknet_explorer/block/block.ex +++ b/lib/starknet_explorer/block/block.ex @@ -8,7 +8,7 @@ defmodule StarknetExplorer.Block do alias StarknetExplorerWeb.Utils alias StarknetExplorer.TransactionReceipt, as: Receipt require Logger - @networks [:mainnet, :testnet] + @networks [:mainnet, :testnet, :sepolia] @cast_fields [ :number, :status, diff --git a/lib/starknet_explorer/cache.ex b/lib/starknet_explorer/cache.ex index 8a75bd29..d9818c49 100644 --- a/lib/starknet_explorer/cache.ex +++ b/lib/starknet_explorer/cache.ex @@ -5,12 +5,14 @@ defmodule StarknetExplorer.IndexCache do def start_link(_) do blocks_mainnet = StarknetExplorer.Data.many_blocks_with_txs("mainnet") blocks_testnet = StarknetExplorer.Data.many_blocks_with_txs("testnet") + blocks_sepolia = StarknetExplorer.Data.many_blocks_with_txs("sepolia") Agent.start_link( fn -> %{ "mainnet" => blocks_mainnet, - "testnet" => blocks_testnet + "testnet" => blocks_testnet, + "sepolia" => blocks_sepolia } end, name: __MODULE__ diff --git a/lib/starknet_explorer/class.ex b/lib/starknet_explorer/class.ex index 95c5b891..4843e22c 100644 --- a/lib/starknet_explorer/class.ex +++ b/lib/starknet_explorer/class.ex @@ -54,7 +54,7 @@ defmodule StarknetExplorer.Class do ] } - @networks [:mainnet, :testnet] + @networks [:mainnet, :testnet, :sepolia] @fields [ :declared_by_address, diff --git a/lib/starknet_explorer/contract.ex b/lib/starknet_explorer/contract.ex index bebb8403..2a3f01bd 100644 --- a/lib/starknet_explorer/contract.ex +++ b/lib/starknet_explorer/contract.ex @@ -4,7 +4,7 @@ defmodule StarknetExplorer.Contract do import Ecto.Query alias StarknetExplorer.Repo - @networks [:mainnet, :testnet] + @networks [:mainnet, :testnet, :sepolia] @fields [ :address, :deployed_by_address, diff --git a/lib/starknet_explorer/events.ex b/lib/starknet_explorer/events.ex index 278787bf..92398a25 100644 --- a/lib/starknet_explorer/events.ex +++ b/lib/starknet_explorer/events.ex @@ -77,7 +77,7 @@ defmodule StarknetExplorer.Events do field :data, {:array, :string} field :index_in_block, :integer field :transaction_hash, :string - field :network, Ecto.Enum, values: [:mainnet, :testnet] + field :network, Ecto.Enum, values: [:mainnet, :testnet, :sepolia] timestamps() end diff --git a/lib/starknet_explorer/message.ex b/lib/starknet_explorer/message.ex index f26c6edb..37081246 100644 --- a/lib/starknet_explorer/message.ex +++ b/lib/starknet_explorer/message.ex @@ -36,7 +36,7 @@ defmodule StarknetExplorer.Message do :l1_to_l2_cancelled_on_l1 ] - field :network, Ecto.Enum, values: [:mainnet, :testnet] + field :network, Ecto.Enum, values: [:mainnet, :testnet, :sepolia] # belongs_to :transaction, Transaction, foreign_key: :transaction_hash, references: :hash timestamps() end diff --git a/lib/starknet_explorer/transaction.ex b/lib/starknet_explorer/transaction.ex index 580380c4..ae00cab9 100644 --- a/lib/starknet_explorer/transaction.ex +++ b/lib/starknet_explorer/transaction.ex @@ -71,7 +71,7 @@ defmodule StarknetExplorer.Transaction do @deploy_account_tx_fields ++ [:network, :nonce] - @networks [:mainnet, :testnet] + @networks [:mainnet, :testnet, :sepolia] @primary_key {:hash, :string, []} schema "transactions" do diff --git a/lib/starknet_explorer/transaction_receipt.ex b/lib/starknet_explorer/transaction_receipt.ex index 4d8501d1..8292e574 100644 --- a/lib/starknet_explorer/transaction_receipt.ex +++ b/lib/starknet_explorer/transaction_receipt.ex @@ -84,7 +84,7 @@ defmodule StarknetExplorer.TransactionReceipt do # :contract_address # ] - @networks [:mainnet, :testnet] + @networks [:mainnet, :testnet, :sepolia] @fields @invoke_tx_receipt_fields ++ @l1_receipt_handler ++ diff --git a/lib/starknet_explorer_web/components/layouts/root.html.heex b/lib/starknet_explorer_web/components/layouts/root.html.heex index 29f74c35..f3df4393 100644 --- a/lib/starknet_explorer_web/components/layouts/root.html.heex +++ b/lib/starknet_explorer_web/components/layouts/root.html.heex @@ -152,6 +152,14 @@ Testnet + diff --git a/lib/starknet_explorer_web/live/common_assigns.ex b/lib/starknet_explorer_web/live/common_assigns.ex index 5ee6e420..eb154f9c 100644 --- a/lib/starknet_explorer_web/live/common_assigns.ex +++ b/lib/starknet_explorer_web/live/common_assigns.ex @@ -4,7 +4,7 @@ defmodule StarknetExplorerWeb.Live.CommonAssigns do def on_mount(:network, params, _session, socket) do socket = case Map.get(params, "network") do - network when network in ["testnet"] -> + network when network in ["testnet", "sepolia"] -> network = network |> String.to_existing_atom() diff --git a/lib/starknet_explorer_web/live/utils.ex b/lib/starknet_explorer_web/live/utils.ex index 8c23dd8b..1402ac5a 100644 --- a/lib/starknet_explorer_web/live/utils.ex +++ b/lib/starknet_explorer_web/live/utils.ex @@ -164,6 +164,7 @@ defmodule StarknetExplorerWeb.Utils do # This case is for mainnet def network_path(:mainnet), do: "/" def network_path(:testnet), do: "/testnet/" + def network_path(:sepolia), do: "/sepolia/" def network_path(:mainnet, remaining_path) do "/#{remaining_path}" @@ -173,6 +174,10 @@ defmodule StarknetExplorerWeb.Utils do "/testnet/#{remaining_path}" end + def network_path(:sepolia, remaining_path) do + "/sepolia/#{remaining_path}" + end + def format_version(<<"0x", hex_val::binary>>), do: "Cairo " <> hex_val def format_version(nil), do: "-" def format_version(version), do: version diff --git a/lib/starknet_rpc.ex b/lib/starknet_rpc.ex index 6e60a0aa..2570b2b3 100644 --- a/lib/starknet_rpc.ex +++ b/lib/starknet_rpc.ex @@ -81,7 +81,7 @@ defmodule StarknetExplorer.Rpc do network ) - defp send_request(method, args, network) when network in [:mainnet, :testnet] do + defp send_request(method, args, network) when network in [:mainnet, :testnet, :sepolia] do payload = build_payload(method, args) case cache_lookup(method, args, network) do @@ -107,7 +107,7 @@ defmodule StarknetExplorer.Rpc do end defp send_request_no_cache(method, args, network) - when network in [:mainnet, :testnet] do + when network in [:mainnet, :testnet, :sepolia] do payload = build_payload(method, args) host = fetch_rpc_host(network) {:ok, rsp} = post(host, payload) @@ -116,6 +116,7 @@ defmodule StarknetExplorer.Rpc do defp fetch_rpc_host(:mainnet), do: Application.fetch_env!(:starknet_explorer, :rpc_host) defp fetch_rpc_host(:testnet), do: Application.fetch_env!(:starknet_explorer, :testnet_host) + defp fetch_rpc_host(:sepolia), do: Application.fetch_env!(:starknet_explorer, :sepolia_host) defp build_payload(method, params) do %{ @@ -151,7 +152,7 @@ defmodule StarknetExplorer.Rpc do defp do_cache_lookup(cache_type, key, network) when cache_type in [:block_cache, :tx_cache, :request_cache] and - network in [:mainnet, :testnet] do + network in [:mainnet, :testnet, :sepolia] do cache_name = :"#{network}_#{cache_type}" case Cachex.get(cache_name, key) do