From 8edfa59e3afa05f16703e5881bcea6d742082c46 Mon Sep 17 00:00:00 2001 From: Dominic Letz Date: Wed, 15 Jul 2026 16:20:22 +0200 Subject: [PATCH 1/3] Add Base L2 remote chain support and refresh chain metadata. Register Chains.Base in RemoteChain, derive NodeRegistry chain_id from diode_client Shell metadata, and bump diode_client for Shell.Base support. --- lib/chains/chains.ex | 35 ++++++++++++++------------------ lib/contract/node_registry.ex | 7 ++++++- lib/remote_chain/remote_chain.ex | 3 ++- mix.lock | 2 +- test/chains/base_test.exs | 26 ++++++++++++++++++++++++ 5 files changed, 50 insertions(+), 23 deletions(-) create mode 100644 test/chains/base_test.exs diff --git a/lib/chains/chains.ex b/lib/chains/chains.ex index efffbd2..0f30b24 100644 --- a/lib/chains/chains.ex +++ b/lib/chains/chains.ex @@ -168,41 +168,36 @@ defmodule Chains.Moonbeam do end end -defmodule Chains.Moonriver do +defmodule Chains.OasisSapphire do alias DiodeClient.{Base16, Hash} - def chain_id(), do: 1285 + def chain_id(), do: 23294 def expected_block_intervall(), do: 6 def epoch(n), do: Chains.epoch(__MODULE__, n) def epoch_progress(n), do: Chains.epoch_progress(__MODULE__, n) - def epoch_block(block), do: Chains.epoch_block(__MODULE__, block) + def epoch_block(epoch), do: Chains.epoch_block(__MODULE__, epoch) def epoch_duration(), do: 2_592_000 - def chain_prefix(), do: "movr" - - def additional_endpoints(), - do: - ~w(https://moonriver-rpc.dwellir.com https://moonriver.api.onfinality.io/public https://moonriver.unitedbloc.com https://moonriver.public.curie.radiumblock.co/http https://moonriver.rpc.grove.city/v1/01fdb492) - - def rpc_endpoints(), do: RemoteChain.ChainList.rpc_endpoints(__MODULE__, additional_endpoints()) - def ws_endpoints(), do: RemoteChain.ChainList.ws_endpoints(__MODULE__, additional_endpoints()) - def registry_address(), do: Base16.decode("0xEb0aDCd736Ae9341DFb635759C5D7D6c2D51B673") - def developer_fleet_address(), do: Base16.decode("0x6000000000000000000000000000000000000000") + def chain_prefix(), do: "sapphire" + def rpc_endpoints(), do: RemoteChain.ChainList.rpc_endpoints(__MODULE__) + def ws_endpoints(), do: RemoteChain.ChainList.ws_endpoints(__MODULE__) + def registry_address(), do: raise("not implemented") + def developer_fleet_address(), do: raise("not implemented") def transaction_hash(), do: &Hash.keccak_256/1 end -defmodule Chains.OasisSapphire do - alias DiodeClient.{Base16, Hash} +defmodule Chains.Base do + alias DiodeClient.{Base16, Hash, Shell.Base} - def chain_id(), do: 23294 - def expected_block_intervall(), do: 6 + def chain_id(), do: Base.chain_id() + def expected_block_intervall(), do: Base.block_time() def epoch(n), do: Chains.epoch(__MODULE__, n) def epoch_progress(n), do: Chains.epoch_progress(__MODULE__, n) def epoch_block(epoch), do: Chains.epoch_block(__MODULE__, epoch) def epoch_duration(), do: 2_592_000 - def chain_prefix(), do: "sapphire" + def chain_prefix(), do: "base" def rpc_endpoints(), do: RemoteChain.ChainList.rpc_endpoints(__MODULE__) def ws_endpoints(), do: RemoteChain.ChainList.ws_endpoints(__MODULE__) - def registry_address(), do: raise("not implemented") - def developer_fleet_address(), do: raise("not implemented") + def registry_address(), do: Base16.decode("0xfbfAF5BfF947869490C05d949c1BA5e260D6bd6E") + def developer_fleet_address(), do: Base16.decode("0x5c6ED819886b77017baAf81ef0E7abEAcb17bD1D") def transaction_hash(), do: &Hash.keccak_256/1 end diff --git a/lib/contract/node_registry.ex b/lib/contract/node_registry.ex index 6cde097..c789c4d 100644 --- a/lib/contract/node_registry.ex +++ b/lib/contract/node_registry.ex @@ -9,9 +9,14 @@ defmodule Contract.NodeRegistry do alias DiodeClient.{ABI, Base16} @address "0xc4b466f63c0A31302Bc8A688A7c90e1199Bb6f84" |> Base16.decode() @token "0x434116a99619f2B465A137199C38c1Aab0353913" |> Base16.decode() - @chain_id 1284 + @chain_id DiodeClient.Shell.Moonbeam.chain_id() @max_uint256 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_935 + # Do post-freeze block + # @address "0xBC7a66a80E760dD0D84f6e39Df6cfD937C6c94F6" |> Base16.decode() + # @token "0x2bDC3e3441Dd5540eA50920C158405Ccd5727De2" |> Base16.decode() + # @chain_id Shell.Base.chain_id() + def address(), do: @address def token(), do: @token def chain_id(), do: @chain_id diff --git a/lib/remote_chain/remote_chain.ex b/lib/remote_chain/remote_chain.ex index 7f7a05b..51b9eda 100644 --- a/lib/remote_chain/remote_chain.ex +++ b/lib/remote_chain/remote_chain.ex @@ -34,7 +34,8 @@ defmodule RemoteChain do @chains [ Chains.Diode, Chains.Moonbeam, - Chains.OasisSapphire + Chains.OasisSapphire, + Chains.Base ] end diff --git a/mix.lock b/mix.lock index f462d72..43569c0 100644 --- a/mix.lock +++ b/mix.lock @@ -16,7 +16,7 @@ "deoxysii": {:hex, :deoxysii, "1.0.4", "6514fc898fef5a24287770d6c2e2ffeb7ff332bd2ff2d7018b099dc1fc057b95", [:mix], [], "hexpm", "5c4ab28b0d81e552d504b28dc55cda5cf9f89405daa1a3c8f896557627ba5cac"}, "dets_plus": {:hex, :dets_plus, "2.4.4", "35ecb72d079bb8423e6bc849b45705ac4dec5a1e0fca6a2d746e0a60e8b04ae4", [:mix], [{:paged_file, "~> 1.1", [hex: :paged_file, repo: "hexpm", optional: false]}], "hexpm", "b79782f150750f5686f47fc064bbe19bc43f6b2d56fbcc9267ec813aa8d07285"}, "dialyxir": {:hex, :dialyxir, "1.4.7", "dda948fcee52962e4b6c5b4b16b2d8fa7d50d8645bbae8b8685c3f9ecb7f5f4d", [:mix], [{:erlex, ">= 0.2.8", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "b34527202e6eb8cee198efec110996c25c5898f43a4094df157f8d28f27d9efe"}, - "diode_client": {:git, "https://github.com/diodechain/diode_client_ex.git", "51b2e98cb3418dd70dc6fe2221294ed2b61d760f", []}, + "diode_client": {:git, "https://github.com/diodechain/diode_client_ex.git", "c8674be20c5535cbd2802f827df46100ba6d04ca", []}, "earmark_parser": {:hex, :earmark_parser, "1.4.44", "f20830dd6b5c77afe2b063777ddbbff09f9759396500cdbe7523efd58d7a339c", [:mix], [], "hexpm", "4778ac752b4701a5599215f7030989c989ffdc4f6df457c5f36938cc2d2a2750"}, "eblake2": {:hex, :eblake2, "1.0.0", "ec8ad20e438aab3f2e8d5d118c366a0754219195f8a0f536587440f8f9bcf2ef", [:rebar3], [], "hexpm", "3c4d300a91845b25d501929a26ac2e6f7157480846fab2347a4c11ae52e08a99"}, "elixir_make": {:hex, :elixir_make, "0.9.0", "6484b3cd8c0cee58f09f05ecaf1a140a8c97670671a6a0e7ab4dc326c3109726", [:mix], [], "hexpm", "db23d4fd8b757462ad02f8aa73431a426fe6671c80b200d9710caf3d1dd0ffdb"}, diff --git a/test/chains/base_test.exs b/test/chains/base_test.exs new file mode 100644 index 0000000..de26db7 --- /dev/null +++ b/test/chains/base_test.exs @@ -0,0 +1,26 @@ +# Diode Server +# Copyright 2021-2025 Diode +# Licensed under the Diode License, Version 1.1 +defmodule Chains.BaseTest do + use ExUnit.Case, async: true + + alias DiodeClient.{Base16, Shell.Base, Shell.Moonbeam} + + test "Chains.Base uses Base L2 chain metadata" do + assert Chains.Base.chain_id() == Base.chain_id() + assert Chains.Base.expected_block_intervall() == Base.block_time() + assert Chains.Base.chain_prefix() == "base" + end + + test "Chains.Base exposes registry and developer fleet addresses" do + assert Chains.Base.registry_address() == + Base16.decode("0xfbfAF5BfF947869490C05d949c1BA5e260D6bd6E") + + assert Chains.Base.developer_fleet_address() == + Base16.decode("0x5c6ED819886b77017baAf81ef0E7abEAcb17bD1D") + end + + test "Contract.NodeRegistry targets Moonbeam" do + assert Contract.NodeRegistry.chain_id() == Moonbeam.chain_id() + end +end From 78f47ec6016a7195134565472b95ee1439e6dbc6 Mon Sep 17 00:00:00 2001 From: Dominic Letz Date: Wed, 15 Jul 2026 16:37:26 +0200 Subject: [PATCH 2/3] Address review feedback on Base chain metadata and NodeRegistry. Restore Moonriver for movr_balance, fix Base block interval units, align NodeRegistry chain_id with Chains.Moonbeam, and simplify Base tests. --- lib/chains/chains.ex | 24 +++++++++++++++++++++++- lib/contract/node_registry.ex | 7 ++----- test/chains/base_test.exs | 22 +++++++--------------- 3 files changed, 32 insertions(+), 21 deletions(-) diff --git a/lib/chains/chains.ex b/lib/chains/chains.ex index 0f30b24..c554459 100644 --- a/lib/chains/chains.ex +++ b/lib/chains/chains.ex @@ -168,6 +168,28 @@ defmodule Chains.Moonbeam do end end +defmodule Chains.Moonriver do + alias DiodeClient.{Base16, Hash} + + def chain_id(), do: 1285 + def expected_block_intervall(), do: 6 + def epoch(n), do: Chains.epoch(__MODULE__, n) + def epoch_progress(n), do: Chains.epoch_progress(__MODULE__, n) + def epoch_block(epoch), do: Chains.epoch_block(__MODULE__, epoch) + def epoch_duration(), do: 2_592_000 + def chain_prefix(), do: "movr" + + def additional_endpoints(), + do: + ~w(https://moonriver-rpc.dwellir.com https://moonriver.api.onfinality.io/public https://moonriver.unitedbloc.com https://moonriver.public.curie.radiumblock.co/http https://moonriver.rpc.grove.city/v1/01fdb492) + + def rpc_endpoints(), do: RemoteChain.ChainList.rpc_endpoints(__MODULE__, additional_endpoints()) + def ws_endpoints(), do: RemoteChain.ChainList.ws_endpoints(__MODULE__, additional_endpoints()) + def registry_address(), do: Base16.decode("0xEb0aDCd736Ae9341DFb635759C5D7D6c2D51B673") + def developer_fleet_address(), do: Base16.decode("0x6000000000000000000000000000000000000000") + def transaction_hash(), do: &Hash.keccak_256/1 +end + defmodule Chains.OasisSapphire do alias DiodeClient.{Base16, Hash} @@ -189,7 +211,7 @@ defmodule Chains.Base do alias DiodeClient.{Base16, Hash, Shell.Base} def chain_id(), do: Base.chain_id() - def expected_block_intervall(), do: Base.block_time() + def expected_block_intervall(), do: 2 def epoch(n), do: Chains.epoch(__MODULE__, n) def epoch_progress(n), do: Chains.epoch_progress(__MODULE__, n) def epoch_block(epoch), do: Chains.epoch_block(__MODULE__, epoch) diff --git a/lib/contract/node_registry.ex b/lib/contract/node_registry.ex index c789c4d..44dd8ed 100644 --- a/lib/contract/node_registry.ex +++ b/lib/contract/node_registry.ex @@ -9,13 +9,10 @@ defmodule Contract.NodeRegistry do alias DiodeClient.{ABI, Base16} @address "0xc4b466f63c0A31302Bc8A688A7c90e1199Bb6f84" |> Base16.decode() @token "0x434116a99619f2B465A137199C38c1Aab0353913" |> Base16.decode() - @chain_id DiodeClient.Shell.Moonbeam.chain_id() + @chain_id Chains.Moonbeam.chain_id() @max_uint256 115_792_089_237_316_195_423_570_985_008_687_907_853_269_984_665_640_564_039_457_584_007_913_129_639_935 - # Do post-freeze block - # @address "0xBC7a66a80E760dD0D84f6e39Df6cfD937C6c94F6" |> Base16.decode() - # @token "0x2bDC3e3441Dd5540eA50920C158405Ccd5727De2" |> Base16.decode() - # @chain_id Shell.Base.chain_id() + # Post-freeze: point @address, @token, and @chain_id at the Base NodeRegistry deployment. def address(), do: @address def token(), do: @token diff --git a/test/chains/base_test.exs b/test/chains/base_test.exs index de26db7..201d1e4 100644 --- a/test/chains/base_test.exs +++ b/test/chains/base_test.exs @@ -4,23 +4,15 @@ defmodule Chains.BaseTest do use ExUnit.Case, async: true - alias DiodeClient.{Base16, Shell.Base, Shell.Moonbeam} - - test "Chains.Base uses Base L2 chain metadata" do - assert Chains.Base.chain_id() == Base.chain_id() - assert Chains.Base.expected_block_intervall() == Base.block_time() + test "Chains.Base chain metadata" do + assert Chains.Base.chain_id() == 8453 + assert Chains.Base.expected_block_intervall() == 2 assert Chains.Base.chain_prefix() == "base" + assert RemoteChain.chainimpl(Chains.Base) == Chains.Base end - test "Chains.Base exposes registry and developer fleet addresses" do - assert Chains.Base.registry_address() == - Base16.decode("0xfbfAF5BfF947869490C05d949c1BA5e260D6bd6E") - - assert Chains.Base.developer_fleet_address() == - Base16.decode("0x5c6ED819886b77017baAf81ef0E7abEAcb17bD1D") - end - - test "Contract.NodeRegistry targets Moonbeam" do - assert Contract.NodeRegistry.chain_id() == Moonbeam.chain_id() + test "Chains.Base exposes contract addresses" do + assert byte_size(Chains.Base.registry_address()) == 20 + assert byte_size(Chains.Base.developer_fleet_address()) == 20 end end From 985d6eaeb8d4ab3cdcee6d5c32bec14a6f70edbc Mon Sep 17 00:00:00 2001 From: Dominic Letz Date: Wed, 15 Jul 2026 17:25:12 +0200 Subject: [PATCH 3/3] Reduce balance limit for gas payment --- lib/remote_chain/call_permit_adapter.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/remote_chain/call_permit_adapter.ex b/lib/remote_chain/call_permit_adapter.ex index bfd677a..2445bc7 100644 --- a/lib/remote_chain/call_permit_adapter.ex +++ b/lib/remote_chain/call_permit_adapter.ex @@ -3,7 +3,7 @@ defmodule CallPermitAdapter do def should_forward_metatransaction?(chain) do chain not in [Chains.Diode, Chains.DiodeStaging, Chains.DiodeDev] and - Shell.get_balance(chain, Diode.address()) / Shell.ether(1) < 1 + Shell.get_balance(chain, Diode.address()) / Shell.ether(1) < 0.000001 end # RLP encoded MetaTransaction