diff --git a/packages/eventindexer/AssignmentHook.json b/packages/eventindexer/AssignmentHook.json
new file mode 100644
index 00000000000..b7b29927cb6
--- /dev/null
+++ b/packages/eventindexer/AssignmentHook.json
@@ -0,0 +1,860 @@
+[
+  {
+    "type": "function",
+    "name": "MAX_GAS_PAYING_PROVER",
+    "inputs": [],
+    "outputs": [
+      {
+        "name": "",
+        "type": "uint256",
+        "internalType": "uint256"
+      }
+    ],
+    "stateMutability": "view"
+  },
+  {
+    "type": "function",
+    "name": "acceptOwnership",
+    "inputs": [],
+    "outputs": [],
+    "stateMutability": "nonpayable"
+  },
+  {
+    "type": "function",
+    "name": "addressManager",
+    "inputs": [],
+    "outputs": [
+      {
+        "name": "",
+        "type": "address",
+        "internalType": "address"
+      }
+    ],
+    "stateMutability": "view"
+  },
+  {
+    "type": "function",
+    "name": "hashAssignment",
+    "inputs": [
+      {
+        "name": "_assignment",
+        "type": "tuple",
+        "internalType": "struct AssignmentHook.ProverAssignment",
+        "components": [
+          {
+            "name": "feeToken",
+            "type": "address",
+            "internalType": "address"
+          },
+          {
+            "name": "expiry",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "maxBlockId",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "maxProposedIn",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "metaHash",
+            "type": "bytes32",
+            "internalType": "bytes32"
+          },
+          {
+            "name": "parentMetaHash",
+            "type": "bytes32",
+            "internalType": "bytes32"
+          },
+          {
+            "name": "tierFees",
+            "type": "tuple[]",
+            "internalType": "struct TaikoData.TierFee[]",
+            "components": [
+              {
+                "name": "tier",
+                "type": "uint16",
+                "internalType": "uint16"
+              },
+              {
+                "name": "fee",
+                "type": "uint128",
+                "internalType": "uint128"
+              }
+            ]
+          },
+          {
+            "name": "signature",
+            "type": "bytes",
+            "internalType": "bytes"
+          }
+        ]
+      },
+      {
+        "name": "_taikoL1Address",
+        "type": "address",
+        "internalType": "address"
+      },
+      {
+        "name": "_blockProposer",
+        "type": "address",
+        "internalType": "address"
+      },
+      {
+        "name": "_assignedProver",
+        "type": "address",
+        "internalType": "address"
+      },
+      {
+        "name": "_blobHash",
+        "type": "bytes32",
+        "internalType": "bytes32"
+      }
+    ],
+    "outputs": [
+      {
+        "name": "",
+        "type": "bytes32",
+        "internalType": "bytes32"
+      }
+    ],
+    "stateMutability": "view"
+  },
+  {
+    "type": "function",
+    "name": "impl",
+    "inputs": [],
+    "outputs": [
+      {
+        "name": "",
+        "type": "address",
+        "internalType": "address"
+      }
+    ],
+    "stateMutability": "view"
+  },
+  {
+    "type": "function",
+    "name": "inNonReentrant",
+    "inputs": [],
+    "outputs": [
+      {
+        "name": "",
+        "type": "bool",
+        "internalType": "bool"
+      }
+    ],
+    "stateMutability": "view"
+  },
+  {
+    "type": "function",
+    "name": "init",
+    "inputs": [
+      {
+        "name": "_owner",
+        "type": "address",
+        "internalType": "address"
+      },
+      {
+        "name": "_addressManager",
+        "type": "address",
+        "internalType": "address"
+      }
+    ],
+    "outputs": [],
+    "stateMutability": "nonpayable"
+  },
+  {
+    "type": "function",
+    "name": "lastUnpausedAt",
+    "inputs": [],
+    "outputs": [
+      {
+        "name": "",
+        "type": "uint64",
+        "internalType": "uint64"
+      }
+    ],
+    "stateMutability": "view"
+  },
+  {
+    "type": "function",
+    "name": "onBlockProposed",
+    "inputs": [
+      {
+        "name": "_blk",
+        "type": "tuple",
+        "internalType": "struct TaikoData.Block",
+        "components": [
+          {
+            "name": "metaHash",
+            "type": "bytes32",
+            "internalType": "bytes32"
+          },
+          {
+            "name": "assignedProver",
+            "type": "address",
+            "internalType": "address"
+          },
+          {
+            "name": "livenessBond",
+            "type": "uint96",
+            "internalType": "uint96"
+          },
+          {
+            "name": "blockId",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "proposedAt",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "proposedIn",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "nextTransitionId",
+            "type": "uint32",
+            "internalType": "uint32"
+          },
+          {
+            "name": "verifiedTransitionId",
+            "type": "uint32",
+            "internalType": "uint32"
+          }
+        ]
+      },
+      {
+        "name": "_meta",
+        "type": "tuple",
+        "internalType": "struct TaikoData.BlockMetadata",
+        "components": [
+          {
+            "name": "l1Hash",
+            "type": "bytes32",
+            "internalType": "bytes32"
+          },
+          {
+            "name": "difficulty",
+            "type": "bytes32",
+            "internalType": "bytes32"
+          },
+          {
+            "name": "blobHash",
+            "type": "bytes32",
+            "internalType": "bytes32"
+          },
+          {
+            "name": "extraData",
+            "type": "bytes32",
+            "internalType": "bytes32"
+          },
+          {
+            "name": "depositsHash",
+            "type": "bytes32",
+            "internalType": "bytes32"
+          },
+          {
+            "name": "coinbase",
+            "type": "address",
+            "internalType": "address"
+          },
+          {
+            "name": "id",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "gasLimit",
+            "type": "uint32",
+            "internalType": "uint32"
+          },
+          {
+            "name": "timestamp",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "l1Height",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "minTier",
+            "type": "uint16",
+            "internalType": "uint16"
+          },
+          {
+            "name": "blobUsed",
+            "type": "bool",
+            "internalType": "bool"
+          },
+          {
+            "name": "parentMetaHash",
+            "type": "bytes32",
+            "internalType": "bytes32"
+          },
+          {
+            "name": "sender",
+            "type": "address",
+            "internalType": "address"
+          }
+        ]
+      },
+      {
+        "name": "_data",
+        "type": "bytes",
+        "internalType": "bytes"
+      }
+    ],
+    "outputs": [],
+    "stateMutability": "payable"
+  },
+  {
+    "type": "function",
+    "name": "owner",
+    "inputs": [],
+    "outputs": [
+      {
+        "name": "",
+        "type": "address",
+        "internalType": "address"
+      }
+    ],
+    "stateMutability": "view"
+  },
+  {
+    "type": "function",
+    "name": "pause",
+    "inputs": [],
+    "outputs": [],
+    "stateMutability": "nonpayable"
+  },
+  {
+    "type": "function",
+    "name": "paused",
+    "inputs": [],
+    "outputs": [
+      {
+        "name": "",
+        "type": "bool",
+        "internalType": "bool"
+      }
+    ],
+    "stateMutability": "view"
+  },
+  {
+    "type": "function",
+    "name": "pendingOwner",
+    "inputs": [],
+    "outputs": [
+      {
+        "name": "",
+        "type": "address",
+        "internalType": "address"
+      }
+    ],
+    "stateMutability": "view"
+  },
+  {
+    "type": "function",
+    "name": "proxiableUUID",
+    "inputs": [],
+    "outputs": [
+      {
+        "name": "",
+        "type": "bytes32",
+        "internalType": "bytes32"
+      }
+    ],
+    "stateMutability": "view"
+  },
+  {
+    "type": "function",
+    "name": "renounceOwnership",
+    "inputs": [],
+    "outputs": [],
+    "stateMutability": "nonpayable"
+  },
+  {
+    "type": "function",
+    "name": "resolve",
+    "inputs": [
+      {
+        "name": "_chainId",
+        "type": "uint64",
+        "internalType": "uint64"
+      },
+      {
+        "name": "_name",
+        "type": "bytes32",
+        "internalType": "bytes32"
+      },
+      {
+        "name": "_allowZeroAddress",
+        "type": "bool",
+        "internalType": "bool"
+      }
+    ],
+    "outputs": [
+      {
+        "name": "",
+        "type": "address",
+        "internalType": "address payable"
+      }
+    ],
+    "stateMutability": "view"
+  },
+  {
+    "type": "function",
+    "name": "resolve",
+    "inputs": [
+      {
+        "name": "_name",
+        "type": "bytes32",
+        "internalType": "bytes32"
+      },
+      {
+        "name": "_allowZeroAddress",
+        "type": "bool",
+        "internalType": "bool"
+      }
+    ],
+    "outputs": [
+      {
+        "name": "",
+        "type": "address",
+        "internalType": "address payable"
+      }
+    ],
+    "stateMutability": "view"
+  },
+  {
+    "type": "function",
+    "name": "transferOwnership",
+    "inputs": [
+      {
+        "name": "newOwner",
+        "type": "address",
+        "internalType": "address"
+      }
+    ],
+    "outputs": [],
+    "stateMutability": "nonpayable"
+  },
+  {
+    "type": "function",
+    "name": "unpause",
+    "inputs": [],
+    "outputs": [],
+    "stateMutability": "nonpayable"
+  },
+  {
+    "type": "function",
+    "name": "upgradeTo",
+    "inputs": [
+      {
+        "name": "newImplementation",
+        "type": "address",
+        "internalType": "address"
+      }
+    ],
+    "outputs": [],
+    "stateMutability": "nonpayable"
+  },
+  {
+    "type": "function",
+    "name": "upgradeToAndCall",
+    "inputs": [
+      {
+        "name": "newImplementation",
+        "type": "address",
+        "internalType": "address"
+      },
+      {
+        "name": "data",
+        "type": "bytes",
+        "internalType": "bytes"
+      }
+    ],
+    "outputs": [],
+    "stateMutability": "payable"
+  },
+  {
+    "type": "event",
+    "name": "AdminChanged",
+    "inputs": [
+      {
+        "name": "previousAdmin",
+        "type": "address",
+        "indexed": false,
+        "internalType": "address"
+      },
+      {
+        "name": "newAdmin",
+        "type": "address",
+        "indexed": false,
+        "internalType": "address"
+      }
+    ],
+    "anonymous": false
+  },
+  {
+    "type": "event",
+    "name": "BeaconUpgraded",
+    "inputs": [
+      {
+        "name": "beacon",
+        "type": "address",
+        "indexed": true,
+        "internalType": "address"
+      }
+    ],
+    "anonymous": false
+  },
+  {
+    "type": "event",
+    "name": "BlockAssigned",
+    "inputs": [
+      {
+        "name": "assignedProver",
+        "type": "address",
+        "indexed": true,
+        "internalType": "address"
+      },
+      {
+        "name": "meta",
+        "type": "tuple",
+        "indexed": false,
+        "internalType": "struct TaikoData.BlockMetadata",
+        "components": [
+          {
+            "name": "l1Hash",
+            "type": "bytes32",
+            "internalType": "bytes32"
+          },
+          {
+            "name": "difficulty",
+            "type": "bytes32",
+            "internalType": "bytes32"
+          },
+          {
+            "name": "blobHash",
+            "type": "bytes32",
+            "internalType": "bytes32"
+          },
+          {
+            "name": "extraData",
+            "type": "bytes32",
+            "internalType": "bytes32"
+          },
+          {
+            "name": "depositsHash",
+            "type": "bytes32",
+            "internalType": "bytes32"
+          },
+          {
+            "name": "coinbase",
+            "type": "address",
+            "internalType": "address"
+          },
+          {
+            "name": "id",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "gasLimit",
+            "type": "uint32",
+            "internalType": "uint32"
+          },
+          {
+            "name": "timestamp",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "l1Height",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "minTier",
+            "type": "uint16",
+            "internalType": "uint16"
+          },
+          {
+            "name": "blobUsed",
+            "type": "bool",
+            "internalType": "bool"
+          },
+          {
+            "name": "parentMetaHash",
+            "type": "bytes32",
+            "internalType": "bytes32"
+          },
+          {
+            "name": "sender",
+            "type": "address",
+            "internalType": "address"
+          }
+        ]
+      },
+      {
+        "name": "assignment",
+        "type": "tuple",
+        "indexed": false,
+        "internalType": "struct AssignmentHook.ProverAssignment",
+        "components": [
+          {
+            "name": "feeToken",
+            "type": "address",
+            "internalType": "address"
+          },
+          {
+            "name": "expiry",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "maxBlockId",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "maxProposedIn",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "metaHash",
+            "type": "bytes32",
+            "internalType": "bytes32"
+          },
+          {
+            "name": "parentMetaHash",
+            "type": "bytes32",
+            "internalType": "bytes32"
+          },
+          {
+            "name": "tierFees",
+            "type": "tuple[]",
+            "internalType": "struct TaikoData.TierFee[]",
+            "components": [
+              {
+                "name": "tier",
+                "type": "uint16",
+                "internalType": "uint16"
+              },
+              {
+                "name": "fee",
+                "type": "uint128",
+                "internalType": "uint128"
+              }
+            ]
+          },
+          {
+            "name": "signature",
+            "type": "bytes",
+            "internalType": "bytes"
+          }
+        ]
+      }
+    ],
+    "anonymous": false
+  },
+  {
+    "type": "event",
+    "name": "EtherPaymentFailed",
+    "inputs": [
+      {
+        "name": "to",
+        "type": "address",
+        "indexed": false,
+        "internalType": "address"
+      },
+      {
+        "name": "maxGas",
+        "type": "uint256",
+        "indexed": false,
+        "internalType": "uint256"
+      }
+    ],
+    "anonymous": false
+  },
+  {
+    "type": "event",
+    "name": "Initialized",
+    "inputs": [
+      {
+        "name": "version",
+        "type": "uint8",
+        "indexed": false,
+        "internalType": "uint8"
+      }
+    ],
+    "anonymous": false
+  },
+  {
+    "type": "event",
+    "name": "OwnershipTransferStarted",
+    "inputs": [
+      {
+        "name": "previousOwner",
+        "type": "address",
+        "indexed": true,
+        "internalType": "address"
+      },
+      {
+        "name": "newOwner",
+        "type": "address",
+        "indexed": true,
+        "internalType": "address"
+      }
+    ],
+    "anonymous": false
+  },
+  {
+    "type": "event",
+    "name": "OwnershipTransferred",
+    "inputs": [
+      {
+        "name": "previousOwner",
+        "type": "address",
+        "indexed": true,
+        "internalType": "address"
+      },
+      {
+        "name": "newOwner",
+        "type": "address",
+        "indexed": true,
+        "internalType": "address"
+      }
+    ],
+    "anonymous": false
+  },
+  {
+    "type": "event",
+    "name": "Paused",
+    "inputs": [
+      {
+        "name": "account",
+        "type": "address",
+        "indexed": false,
+        "internalType": "address"
+      }
+    ],
+    "anonymous": false
+  },
+  {
+    "type": "event",
+    "name": "Unpaused",
+    "inputs": [
+      {
+        "name": "account",
+        "type": "address",
+        "indexed": false,
+        "internalType": "address"
+      }
+    ],
+    "anonymous": false
+  },
+  {
+    "type": "event",
+    "name": "Upgraded",
+    "inputs": [
+      {
+        "name": "implementation",
+        "type": "address",
+        "indexed": true,
+        "internalType": "address"
+      }
+    ],
+    "anonymous": false
+  },
+  {
+    "type": "error",
+    "name": "ETH_TRANSFER_FAILED",
+    "inputs": []
+  },
+  {
+    "type": "error",
+    "name": "FUNC_NOT_IMPLEMENTED",
+    "inputs": []
+  },
+  {
+    "type": "error",
+    "name": "HOOK_ASSIGNMENT_EXPIRED",
+    "inputs": []
+  },
+  {
+    "type": "error",
+    "name": "HOOK_ASSIGNMENT_INVALID_SIG",
+    "inputs": []
+  },
+  {
+    "type": "error",
+    "name": "HOOK_TIER_NOT_FOUND",
+    "inputs": []
+  },
+  {
+    "type": "error",
+    "name": "INVALID_PAUSE_STATUS",
+    "inputs": []
+  },
+  {
+    "type": "error",
+    "name": "REENTRANT_CALL",
+    "inputs": []
+  },
+  {
+    "type": "error",
+    "name": "RESOLVER_DENIED",
+    "inputs": []
+  },
+  {
+    "type": "error",
+    "name": "RESOLVER_INVALID_MANAGER",
+    "inputs": []
+  },
+  {
+    "type": "error",
+    "name": "RESOLVER_UNEXPECTED_CHAINID",
+    "inputs": []
+  },
+  {
+    "type": "error",
+    "name": "RESOLVER_ZERO_ADDR",
+    "inputs": [
+      {
+        "name": "chainId",
+        "type": "uint64",
+        "internalType": "uint64"
+      },
+      {
+        "name": "name",
+        "type": "bytes32",
+        "internalType": "bytes32"
+      }
+    ]
+  },
+  {
+    "type": "error",
+    "name": "ZERO_ADDRESS",
+    "inputs": []
+  },
+  {
+    "type": "error",
+    "name": "ZERO_VALUE",
+    "inputs": []
+  }
+]
diff --git a/packages/eventindexer/Bridge.json b/packages/eventindexer/Bridge.json
new file mode 100644
index 00000000000..3b85df5ac36
--- /dev/null
+++ b/packages/eventindexer/Bridge.json
@@ -0,0 +1,1637 @@
+[
+  {
+    "type": "function",
+    "name": "GAS_OVERHEAD",
+    "inputs": [],
+    "outputs": [
+      {
+        "name": "",
+        "type": "uint32",
+        "internalType": "uint32"
+      }
+    ],
+    "stateMutability": "view"
+  },
+  {
+    "type": "function",
+    "name": "GAS_RESERVE",
+    "inputs": [],
+    "outputs": [
+      {
+        "name": "",
+        "type": "uint32",
+        "internalType": "uint32"
+      }
+    ],
+    "stateMutability": "view"
+  },
+  {
+    "type": "function",
+    "name": "RELAYER_MAX_PROOF_BYTES",
+    "inputs": [],
+    "outputs": [
+      {
+        "name": "",
+        "type": "uint256",
+        "internalType": "uint256"
+      }
+    ],
+    "stateMutability": "view"
+  },
+  {
+    "type": "function",
+    "name": "acceptOwnership",
+    "inputs": [],
+    "outputs": [],
+    "stateMutability": "nonpayable"
+  },
+  {
+    "type": "function",
+    "name": "addressManager",
+    "inputs": [],
+    "outputs": [
+      {
+        "name": "",
+        "type": "address",
+        "internalType": "address"
+      }
+    ],
+    "stateMutability": "view"
+  },
+  {
+    "type": "function",
+    "name": "context",
+    "inputs": [],
+    "outputs": [
+      {
+        "name": "ctx_",
+        "type": "tuple",
+        "internalType": "struct IBridge.Context",
+        "components": [
+          {
+            "name": "msgHash",
+            "type": "bytes32",
+            "internalType": "bytes32"
+          },
+          {
+            "name": "from",
+            "type": "address",
+            "internalType": "address"
+          },
+          {
+            "name": "srcChainId",
+            "type": "uint64",
+            "internalType": "uint64"
+          }
+        ]
+      }
+    ],
+    "stateMutability": "view"
+  },
+  {
+    "type": "function",
+    "name": "failMessage",
+    "inputs": [
+      {
+        "name": "_message",
+        "type": "tuple",
+        "internalType": "struct IBridge.Message",
+        "components": [
+          {
+            "name": "id",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "fee",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "gasLimit",
+            "type": "uint32",
+            "internalType": "uint32"
+          },
+          {
+            "name": "from",
+            "type": "address",
+            "internalType": "address"
+          },
+          {
+            "name": "srcChainId",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "srcOwner",
+            "type": "address",
+            "internalType": "address"
+          },
+          {
+            "name": "destChainId",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "destOwner",
+            "type": "address",
+            "internalType": "address"
+          },
+          {
+            "name": "to",
+            "type": "address",
+            "internalType": "address"
+          },
+          {
+            "name": "value",
+            "type": "uint256",
+            "internalType": "uint256"
+          },
+          {
+            "name": "data",
+            "type": "bytes",
+            "internalType": "bytes"
+          }
+        ]
+      }
+    ],
+    "outputs": [],
+    "stateMutability": "nonpayable"
+  },
+  {
+    "type": "function",
+    "name": "getMessageMinGasLimit",
+    "inputs": [
+      {
+        "name": "dataLength",
+        "type": "uint256",
+        "internalType": "uint256"
+      }
+    ],
+    "outputs": [
+      {
+        "name": "",
+        "type": "uint32",
+        "internalType": "uint32"
+      }
+    ],
+    "stateMutability": "pure"
+  },
+  {
+    "type": "function",
+    "name": "hashMessage",
+    "inputs": [
+      {
+        "name": "_message",
+        "type": "tuple",
+        "internalType": "struct IBridge.Message",
+        "components": [
+          {
+            "name": "id",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "fee",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "gasLimit",
+            "type": "uint32",
+            "internalType": "uint32"
+          },
+          {
+            "name": "from",
+            "type": "address",
+            "internalType": "address"
+          },
+          {
+            "name": "srcChainId",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "srcOwner",
+            "type": "address",
+            "internalType": "address"
+          },
+          {
+            "name": "destChainId",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "destOwner",
+            "type": "address",
+            "internalType": "address"
+          },
+          {
+            "name": "to",
+            "type": "address",
+            "internalType": "address"
+          },
+          {
+            "name": "value",
+            "type": "uint256",
+            "internalType": "uint256"
+          },
+          {
+            "name": "data",
+            "type": "bytes",
+            "internalType": "bytes"
+          }
+        ]
+      }
+    ],
+    "outputs": [
+      {
+        "name": "",
+        "type": "bytes32",
+        "internalType": "bytes32"
+      }
+    ],
+    "stateMutability": "pure"
+  },
+  {
+    "type": "function",
+    "name": "impl",
+    "inputs": [],
+    "outputs": [
+      {
+        "name": "",
+        "type": "address",
+        "internalType": "address"
+      }
+    ],
+    "stateMutability": "view"
+  },
+  {
+    "type": "function",
+    "name": "inNonReentrant",
+    "inputs": [],
+    "outputs": [
+      {
+        "name": "",
+        "type": "bool",
+        "internalType": "bool"
+      }
+    ],
+    "stateMutability": "view"
+  },
+  {
+    "type": "function",
+    "name": "init",
+    "inputs": [
+      {
+        "name": "_owner",
+        "type": "address",
+        "internalType": "address"
+      },
+      {
+        "name": "_addressManager",
+        "type": "address",
+        "internalType": "address"
+      }
+    ],
+    "outputs": [],
+    "stateMutability": "nonpayable"
+  },
+  {
+    "type": "function",
+    "name": "init2",
+    "inputs": [],
+    "outputs": [],
+    "stateMutability": "nonpayable"
+  },
+  {
+    "type": "function",
+    "name": "isDestChainEnabled",
+    "inputs": [
+      {
+        "name": "_chainId",
+        "type": "uint64",
+        "internalType": "uint64"
+      }
+    ],
+    "outputs": [
+      {
+        "name": "enabled_",
+        "type": "bool",
+        "internalType": "bool"
+      },
+      {
+        "name": "destBridge_",
+        "type": "address",
+        "internalType": "address"
+      }
+    ],
+    "stateMutability": "view"
+  },
+  {
+    "type": "function",
+    "name": "isMessageFailed",
+    "inputs": [
+      {
+        "name": "_message",
+        "type": "tuple",
+        "internalType": "struct IBridge.Message",
+        "components": [
+          {
+            "name": "id",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "fee",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "gasLimit",
+            "type": "uint32",
+            "internalType": "uint32"
+          },
+          {
+            "name": "from",
+            "type": "address",
+            "internalType": "address"
+          },
+          {
+            "name": "srcChainId",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "srcOwner",
+            "type": "address",
+            "internalType": "address"
+          },
+          {
+            "name": "destChainId",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "destOwner",
+            "type": "address",
+            "internalType": "address"
+          },
+          {
+            "name": "to",
+            "type": "address",
+            "internalType": "address"
+          },
+          {
+            "name": "value",
+            "type": "uint256",
+            "internalType": "uint256"
+          },
+          {
+            "name": "data",
+            "type": "bytes",
+            "internalType": "bytes"
+          }
+        ]
+      },
+      {
+        "name": "_proof",
+        "type": "bytes",
+        "internalType": "bytes"
+      }
+    ],
+    "outputs": [
+      {
+        "name": "",
+        "type": "bool",
+        "internalType": "bool"
+      }
+    ],
+    "stateMutability": "view"
+  },
+  {
+    "type": "function",
+    "name": "isMessageReceived",
+    "inputs": [
+      {
+        "name": "_message",
+        "type": "tuple",
+        "internalType": "struct IBridge.Message",
+        "components": [
+          {
+            "name": "id",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "fee",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "gasLimit",
+            "type": "uint32",
+            "internalType": "uint32"
+          },
+          {
+            "name": "from",
+            "type": "address",
+            "internalType": "address"
+          },
+          {
+            "name": "srcChainId",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "srcOwner",
+            "type": "address",
+            "internalType": "address"
+          },
+          {
+            "name": "destChainId",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "destOwner",
+            "type": "address",
+            "internalType": "address"
+          },
+          {
+            "name": "to",
+            "type": "address",
+            "internalType": "address"
+          },
+          {
+            "name": "value",
+            "type": "uint256",
+            "internalType": "uint256"
+          },
+          {
+            "name": "data",
+            "type": "bytes",
+            "internalType": "bytes"
+          }
+        ]
+      },
+      {
+        "name": "_proof",
+        "type": "bytes",
+        "internalType": "bytes"
+      }
+    ],
+    "outputs": [
+      {
+        "name": "",
+        "type": "bool",
+        "internalType": "bool"
+      }
+    ],
+    "stateMutability": "view"
+  },
+  {
+    "type": "function",
+    "name": "isMessageSent",
+    "inputs": [
+      {
+        "name": "_message",
+        "type": "tuple",
+        "internalType": "struct IBridge.Message",
+        "components": [
+          {
+            "name": "id",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "fee",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "gasLimit",
+            "type": "uint32",
+            "internalType": "uint32"
+          },
+          {
+            "name": "from",
+            "type": "address",
+            "internalType": "address"
+          },
+          {
+            "name": "srcChainId",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "srcOwner",
+            "type": "address",
+            "internalType": "address"
+          },
+          {
+            "name": "destChainId",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "destOwner",
+            "type": "address",
+            "internalType": "address"
+          },
+          {
+            "name": "to",
+            "type": "address",
+            "internalType": "address"
+          },
+          {
+            "name": "value",
+            "type": "uint256",
+            "internalType": "uint256"
+          },
+          {
+            "name": "data",
+            "type": "bytes",
+            "internalType": "bytes"
+          }
+        ]
+      }
+    ],
+    "outputs": [
+      {
+        "name": "",
+        "type": "bool",
+        "internalType": "bool"
+      }
+    ],
+    "stateMutability": "view"
+  },
+  {
+    "type": "function",
+    "name": "lastUnpausedAt",
+    "inputs": [],
+    "outputs": [
+      {
+        "name": "",
+        "type": "uint64",
+        "internalType": "uint64"
+      }
+    ],
+    "stateMutability": "view"
+  },
+  {
+    "type": "function",
+    "name": "messageStatus",
+    "inputs": [
+      {
+        "name": "msgHash",
+        "type": "bytes32",
+        "internalType": "bytes32"
+      }
+    ],
+    "outputs": [
+      {
+        "name": "status",
+        "type": "uint8",
+        "internalType": "enum IBridge.Status"
+      }
+    ],
+    "stateMutability": "view"
+  },
+  {
+    "type": "function",
+    "name": "nextMessageId",
+    "inputs": [],
+    "outputs": [
+      {
+        "name": "",
+        "type": "uint64",
+        "internalType": "uint64"
+      }
+    ],
+    "stateMutability": "view"
+  },
+  {
+    "type": "function",
+    "name": "owner",
+    "inputs": [],
+    "outputs": [
+      {
+        "name": "",
+        "type": "address",
+        "internalType": "address"
+      }
+    ],
+    "stateMutability": "view"
+  },
+  {
+    "type": "function",
+    "name": "pause",
+    "inputs": [],
+    "outputs": [],
+    "stateMutability": "nonpayable"
+  },
+  {
+    "type": "function",
+    "name": "paused",
+    "inputs": [],
+    "outputs": [
+      {
+        "name": "",
+        "type": "bool",
+        "internalType": "bool"
+      }
+    ],
+    "stateMutability": "view"
+  },
+  {
+    "type": "function",
+    "name": "pendingOwner",
+    "inputs": [],
+    "outputs": [
+      {
+        "name": "",
+        "type": "address",
+        "internalType": "address"
+      }
+    ],
+    "stateMutability": "view"
+  },
+  {
+    "type": "function",
+    "name": "processMessage",
+    "inputs": [
+      {
+        "name": "_message",
+        "type": "tuple",
+        "internalType": "struct IBridge.Message",
+        "components": [
+          {
+            "name": "id",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "fee",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "gasLimit",
+            "type": "uint32",
+            "internalType": "uint32"
+          },
+          {
+            "name": "from",
+            "type": "address",
+            "internalType": "address"
+          },
+          {
+            "name": "srcChainId",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "srcOwner",
+            "type": "address",
+            "internalType": "address"
+          },
+          {
+            "name": "destChainId",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "destOwner",
+            "type": "address",
+            "internalType": "address"
+          },
+          {
+            "name": "to",
+            "type": "address",
+            "internalType": "address"
+          },
+          {
+            "name": "value",
+            "type": "uint256",
+            "internalType": "uint256"
+          },
+          {
+            "name": "data",
+            "type": "bytes",
+            "internalType": "bytes"
+          }
+        ]
+      },
+      {
+        "name": "_proof",
+        "type": "bytes",
+        "internalType": "bytes"
+      }
+    ],
+    "outputs": [
+      {
+        "name": "status_",
+        "type": "uint8",
+        "internalType": "enum IBridge.Status"
+      },
+      {
+        "name": "reason_",
+        "type": "uint8",
+        "internalType": "enum IBridge.StatusReason"
+      }
+    ],
+    "stateMutability": "nonpayable"
+  },
+  {
+    "type": "function",
+    "name": "proxiableUUID",
+    "inputs": [],
+    "outputs": [
+      {
+        "name": "",
+        "type": "bytes32",
+        "internalType": "bytes32"
+      }
+    ],
+    "stateMutability": "view"
+  },
+  {
+    "type": "function",
+    "name": "recallMessage",
+    "inputs": [
+      {
+        "name": "_message",
+        "type": "tuple",
+        "internalType": "struct IBridge.Message",
+        "components": [
+          {
+            "name": "id",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "fee",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "gasLimit",
+            "type": "uint32",
+            "internalType": "uint32"
+          },
+          {
+            "name": "from",
+            "type": "address",
+            "internalType": "address"
+          },
+          {
+            "name": "srcChainId",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "srcOwner",
+            "type": "address",
+            "internalType": "address"
+          },
+          {
+            "name": "destChainId",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "destOwner",
+            "type": "address",
+            "internalType": "address"
+          },
+          {
+            "name": "to",
+            "type": "address",
+            "internalType": "address"
+          },
+          {
+            "name": "value",
+            "type": "uint256",
+            "internalType": "uint256"
+          },
+          {
+            "name": "data",
+            "type": "bytes",
+            "internalType": "bytes"
+          }
+        ]
+      },
+      {
+        "name": "_proof",
+        "type": "bytes",
+        "internalType": "bytes"
+      }
+    ],
+    "outputs": [],
+    "stateMutability": "nonpayable"
+  },
+  {
+    "type": "function",
+    "name": "renounceOwnership",
+    "inputs": [],
+    "outputs": [],
+    "stateMutability": "nonpayable"
+  },
+  {
+    "type": "function",
+    "name": "resolve",
+    "inputs": [
+      {
+        "name": "_chainId",
+        "type": "uint64",
+        "internalType": "uint64"
+      },
+      {
+        "name": "_name",
+        "type": "bytes32",
+        "internalType": "bytes32"
+      },
+      {
+        "name": "_allowZeroAddress",
+        "type": "bool",
+        "internalType": "bool"
+      }
+    ],
+    "outputs": [
+      {
+        "name": "",
+        "type": "address",
+        "internalType": "address payable"
+      }
+    ],
+    "stateMutability": "view"
+  },
+  {
+    "type": "function",
+    "name": "resolve",
+    "inputs": [
+      {
+        "name": "_name",
+        "type": "bytes32",
+        "internalType": "bytes32"
+      },
+      {
+        "name": "_allowZeroAddress",
+        "type": "bool",
+        "internalType": "bool"
+      }
+    ],
+    "outputs": [
+      {
+        "name": "",
+        "type": "address",
+        "internalType": "address payable"
+      }
+    ],
+    "stateMutability": "view"
+  },
+  {
+    "type": "function",
+    "name": "retryMessage",
+    "inputs": [
+      {
+        "name": "_message",
+        "type": "tuple",
+        "internalType": "struct IBridge.Message",
+        "components": [
+          {
+            "name": "id",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "fee",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "gasLimit",
+            "type": "uint32",
+            "internalType": "uint32"
+          },
+          {
+            "name": "from",
+            "type": "address",
+            "internalType": "address"
+          },
+          {
+            "name": "srcChainId",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "srcOwner",
+            "type": "address",
+            "internalType": "address"
+          },
+          {
+            "name": "destChainId",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "destOwner",
+            "type": "address",
+            "internalType": "address"
+          },
+          {
+            "name": "to",
+            "type": "address",
+            "internalType": "address"
+          },
+          {
+            "name": "value",
+            "type": "uint256",
+            "internalType": "uint256"
+          },
+          {
+            "name": "data",
+            "type": "bytes",
+            "internalType": "bytes"
+          }
+        ]
+      },
+      {
+        "name": "_isLastAttempt",
+        "type": "bool",
+        "internalType": "bool"
+      }
+    ],
+    "outputs": [],
+    "stateMutability": "nonpayable"
+  },
+  {
+    "type": "function",
+    "name": "selfDelegate",
+    "inputs": [
+      {
+        "name": "_anyToken",
+        "type": "address",
+        "internalType": "address"
+      }
+    ],
+    "outputs": [],
+    "stateMutability": "nonpayable"
+  },
+  {
+    "type": "function",
+    "name": "sendMessage",
+    "inputs": [
+      {
+        "name": "_message",
+        "type": "tuple",
+        "internalType": "struct IBridge.Message",
+        "components": [
+          {
+            "name": "id",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "fee",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "gasLimit",
+            "type": "uint32",
+            "internalType": "uint32"
+          },
+          {
+            "name": "from",
+            "type": "address",
+            "internalType": "address"
+          },
+          {
+            "name": "srcChainId",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "srcOwner",
+            "type": "address",
+            "internalType": "address"
+          },
+          {
+            "name": "destChainId",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "destOwner",
+            "type": "address",
+            "internalType": "address"
+          },
+          {
+            "name": "to",
+            "type": "address",
+            "internalType": "address"
+          },
+          {
+            "name": "value",
+            "type": "uint256",
+            "internalType": "uint256"
+          },
+          {
+            "name": "data",
+            "type": "bytes",
+            "internalType": "bytes"
+          }
+        ]
+      }
+    ],
+    "outputs": [
+      {
+        "name": "msgHash_",
+        "type": "bytes32",
+        "internalType": "bytes32"
+      },
+      {
+        "name": "message_",
+        "type": "tuple",
+        "internalType": "struct IBridge.Message",
+        "components": [
+          {
+            "name": "id",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "fee",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "gasLimit",
+            "type": "uint32",
+            "internalType": "uint32"
+          },
+          {
+            "name": "from",
+            "type": "address",
+            "internalType": "address"
+          },
+          {
+            "name": "srcChainId",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "srcOwner",
+            "type": "address",
+            "internalType": "address"
+          },
+          {
+            "name": "destChainId",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "destOwner",
+            "type": "address",
+            "internalType": "address"
+          },
+          {
+            "name": "to",
+            "type": "address",
+            "internalType": "address"
+          },
+          {
+            "name": "value",
+            "type": "uint256",
+            "internalType": "uint256"
+          },
+          {
+            "name": "data",
+            "type": "bytes",
+            "internalType": "bytes"
+          }
+        ]
+      }
+    ],
+    "stateMutability": "payable"
+  },
+  {
+    "type": "function",
+    "name": "signalForFailedMessage",
+    "inputs": [
+      {
+        "name": "_msgHash",
+        "type": "bytes32",
+        "internalType": "bytes32"
+      }
+    ],
+    "outputs": [
+      {
+        "name": "",
+        "type": "bytes32",
+        "internalType": "bytes32"
+      }
+    ],
+    "stateMutability": "pure"
+  },
+  {
+    "type": "function",
+    "name": "transferOwnership",
+    "inputs": [
+      {
+        "name": "newOwner",
+        "type": "address",
+        "internalType": "address"
+      }
+    ],
+    "outputs": [],
+    "stateMutability": "nonpayable"
+  },
+  {
+    "type": "function",
+    "name": "unpause",
+    "inputs": [],
+    "outputs": [],
+    "stateMutability": "nonpayable"
+  },
+  {
+    "type": "function",
+    "name": "upgradeTo",
+    "inputs": [
+      {
+        "name": "newImplementation",
+        "type": "address",
+        "internalType": "address"
+      }
+    ],
+    "outputs": [],
+    "stateMutability": "nonpayable"
+  },
+  {
+    "type": "function",
+    "name": "upgradeToAndCall",
+    "inputs": [
+      {
+        "name": "newImplementation",
+        "type": "address",
+        "internalType": "address"
+      },
+      {
+        "name": "data",
+        "type": "bytes",
+        "internalType": "bytes"
+      }
+    ],
+    "outputs": [],
+    "stateMutability": "payable"
+  },
+  {
+    "type": "event",
+    "name": "AdminChanged",
+    "inputs": [
+      {
+        "name": "previousAdmin",
+        "type": "address",
+        "indexed": false,
+        "internalType": "address"
+      },
+      {
+        "name": "newAdmin",
+        "type": "address",
+        "indexed": false,
+        "internalType": "address"
+      }
+    ],
+    "anonymous": false
+  },
+  {
+    "type": "event",
+    "name": "BeaconUpgraded",
+    "inputs": [
+      {
+        "name": "beacon",
+        "type": "address",
+        "indexed": true,
+        "internalType": "address"
+      }
+    ],
+    "anonymous": false
+  },
+  {
+    "type": "event",
+    "name": "Initialized",
+    "inputs": [
+      {
+        "name": "version",
+        "type": "uint8",
+        "indexed": false,
+        "internalType": "uint8"
+      }
+    ],
+    "anonymous": false
+  },
+  {
+    "type": "event",
+    "name": "MessageProcessed",
+    "inputs": [
+      {
+        "name": "msgHash",
+        "type": "bytes32",
+        "indexed": true,
+        "internalType": "bytes32"
+      },
+      {
+        "name": "message",
+        "type": "tuple",
+        "indexed": false,
+        "internalType": "struct IBridge.Message",
+        "components": [
+          {
+            "name": "id",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "fee",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "gasLimit",
+            "type": "uint32",
+            "internalType": "uint32"
+          },
+          {
+            "name": "from",
+            "type": "address",
+            "internalType": "address"
+          },
+          {
+            "name": "srcChainId",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "srcOwner",
+            "type": "address",
+            "internalType": "address"
+          },
+          {
+            "name": "destChainId",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "destOwner",
+            "type": "address",
+            "internalType": "address"
+          },
+          {
+            "name": "to",
+            "type": "address",
+            "internalType": "address"
+          },
+          {
+            "name": "value",
+            "type": "uint256",
+            "internalType": "uint256"
+          },
+          {
+            "name": "data",
+            "type": "bytes",
+            "internalType": "bytes"
+          }
+        ]
+      },
+      {
+        "name": "stats",
+        "type": "tuple",
+        "indexed": false,
+        "internalType": "struct Bridge.ProcessingStats",
+        "components": [
+          {
+            "name": "gasUsedInFeeCalc",
+            "type": "uint32",
+            "internalType": "uint32"
+          },
+          {
+            "name": "proofSize",
+            "type": "uint32",
+            "internalType": "uint32"
+          },
+          {
+            "name": "numCacheOps",
+            "type": "uint32",
+            "internalType": "uint32"
+          },
+          {
+            "name": "processedByRelayer",
+            "type": "bool",
+            "internalType": "bool"
+          }
+        ]
+      }
+    ],
+    "anonymous": false
+  },
+  {
+    "type": "event",
+    "name": "MessageSent",
+    "inputs": [
+      {
+        "name": "msgHash",
+        "type": "bytes32",
+        "indexed": true,
+        "internalType": "bytes32"
+      },
+      {
+        "name": "message",
+        "type": "tuple",
+        "indexed": false,
+        "internalType": "struct IBridge.Message",
+        "components": [
+          {
+            "name": "id",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "fee",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "gasLimit",
+            "type": "uint32",
+            "internalType": "uint32"
+          },
+          {
+            "name": "from",
+            "type": "address",
+            "internalType": "address"
+          },
+          {
+            "name": "srcChainId",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "srcOwner",
+            "type": "address",
+            "internalType": "address"
+          },
+          {
+            "name": "destChainId",
+            "type": "uint64",
+            "internalType": "uint64"
+          },
+          {
+            "name": "destOwner",
+            "type": "address",
+            "internalType": "address"
+          },
+          {
+            "name": "to",
+            "type": "address",
+            "internalType": "address"
+          },
+          {
+            "name": "value",
+            "type": "uint256",
+            "internalType": "uint256"
+          },
+          {
+            "name": "data",
+            "type": "bytes",
+            "internalType": "bytes"
+          }
+        ]
+      }
+    ],
+    "anonymous": false
+  },
+  {
+    "type": "event",
+    "name": "MessageStatusChanged",
+    "inputs": [
+      {
+        "name": "msgHash",
+        "type": "bytes32",
+        "indexed": true,
+        "internalType": "bytes32"
+      },
+      {
+        "name": "status",
+        "type": "uint8",
+        "indexed": false,
+        "internalType": "enum IBridge.Status"
+      }
+    ],
+    "anonymous": false
+  },
+  {
+    "type": "event",
+    "name": "OwnershipTransferStarted",
+    "inputs": [
+      {
+        "name": "previousOwner",
+        "type": "address",
+        "indexed": true,
+        "internalType": "address"
+      },
+      {
+        "name": "newOwner",
+        "type": "address",
+        "indexed": true,
+        "internalType": "address"
+      }
+    ],
+    "anonymous": false
+  },
+  {
+    "type": "event",
+    "name": "OwnershipTransferred",
+    "inputs": [
+      {
+        "name": "previousOwner",
+        "type": "address",
+        "indexed": true,
+        "internalType": "address"
+      },
+      {
+        "name": "newOwner",
+        "type": "address",
+        "indexed": true,
+        "internalType": "address"
+      }
+    ],
+    "anonymous": false
+  },
+  {
+    "type": "event",
+    "name": "Paused",
+    "inputs": [
+      {
+        "name": "account",
+        "type": "address",
+        "indexed": false,
+        "internalType": "address"
+      }
+    ],
+    "anonymous": false
+  },
+  {
+    "type": "event",
+    "name": "Unpaused",
+    "inputs": [
+      {
+        "name": "account",
+        "type": "address",
+        "indexed": false,
+        "internalType": "address"
+      }
+    ],
+    "anonymous": false
+  },
+  {
+    "type": "event",
+    "name": "Upgraded",
+    "inputs": [
+      {
+        "name": "implementation",
+        "type": "address",
+        "indexed": true,
+        "internalType": "address"
+      }
+    ],
+    "anonymous": false
+  },
+  {
+    "type": "error",
+    "name": "B_INSUFFICIENT_GAS",
+    "inputs": []
+  },
+  {
+    "type": "error",
+    "name": "B_INVALID_CHAINID",
+    "inputs": []
+  },
+  {
+    "type": "error",
+    "name": "B_INVALID_CONTEXT",
+    "inputs": []
+  },
+  {
+    "type": "error",
+    "name": "B_INVALID_FEE",
+    "inputs": []
+  },
+  {
+    "type": "error",
+    "name": "B_INVALID_GAS_LIMIT",
+    "inputs": []
+  },
+  {
+    "type": "error",
+    "name": "B_INVALID_STATUS",
+    "inputs": []
+  },
+  {
+    "type": "error",
+    "name": "B_INVALID_VALUE",
+    "inputs": []
+  },
+  {
+    "type": "error",
+    "name": "B_MESSAGE_NOT_SENT",
+    "inputs": []
+  },
+  {
+    "type": "error",
+    "name": "B_OUT_OF_ETH_QUOTA",
+    "inputs": []
+  },
+  {
+    "type": "error",
+    "name": "B_PERMISSION_DENIED",
+    "inputs": []
+  },
+  {
+    "type": "error",
+    "name": "B_PROOF_TOO_LARGE",
+    "inputs": []
+  },
+  {
+    "type": "error",
+    "name": "B_RETRY_FAILED",
+    "inputs": []
+  },
+  {
+    "type": "error",
+    "name": "B_SIGNAL_NOT_RECEIVED",
+    "inputs": []
+  },
+  {
+    "type": "error",
+    "name": "ETH_TRANSFER_FAILED",
+    "inputs": []
+  },
+  {
+    "type": "error",
+    "name": "FUNC_NOT_IMPLEMENTED",
+    "inputs": []
+  },
+  {
+    "type": "error",
+    "name": "INVALID_PAUSE_STATUS",
+    "inputs": []
+  },
+  {
+    "type": "error",
+    "name": "REENTRANT_CALL",
+    "inputs": []
+  },
+  {
+    "type": "error",
+    "name": "RESOLVER_DENIED",
+    "inputs": []
+  },
+  {
+    "type": "error",
+    "name": "RESOLVER_INVALID_MANAGER",
+    "inputs": []
+  },
+  {
+    "type": "error",
+    "name": "RESOLVER_UNEXPECTED_CHAINID",
+    "inputs": []
+  },
+  {
+    "type": "error",
+    "name": "RESOLVER_ZERO_ADDR",
+    "inputs": [
+      {
+        "name": "chainId",
+        "type": "uint64",
+        "internalType": "uint64"
+      },
+      {
+        "name": "name",
+        "type": "bytes32",
+        "internalType": "bytes32"
+      }
+    ]
+  },
+  {
+    "type": "error",
+    "name": "ZERO_ADDRESS",
+    "inputs": []
+  },
+  {
+    "type": "error",
+    "name": "ZERO_VALUE",
+    "inputs": []
+  }
+]
diff --git a/packages/eventindexer/indexer/fetch_nft_metadata.go b/packages/eventindexer/indexer/fetch_nft_metadata.go
index 63dfa96d527..b53f558f856 100644
--- a/packages/eventindexer/indexer/fetch_nft_metadata.go
+++ b/packages/eventindexer/indexer/fetch_nft_metadata.go
@@ -2,13 +2,13 @@ package indexer
 
 import (
 	"context"
+	"encoding/base64"
 	"encoding/json"
 	"fmt"
-	"log/slog"
 	"math/big"
 	"net/http"
+	"net/url"
 	"strings"
-	"time"
 
 	"github.com/ethereum/go-ethereum"
 	"github.com/ethereum/go-ethereum/accounts/abi"
@@ -54,29 +54,25 @@ func (i *Indexer) fetchNFTMetadata(
 		return nil, errors.Wrap(err, "contractABI.UnpackIntoInterface")
 	}
 
-	url, err := resolveMetadataURL(ctx, tokenURI)
-	if err != nil {
-		if errors.Is(err, eventindexer.ErrInvalidURL) {
-			slog.Warn("Invalid metadata URI",
-				"contractAddress", contractAddress,
-				"tokenID", tokenID.Int64(),
-				"chainID", chainID.String())
-
-			return nil, nil
-		}
+	mdURL := resolveMetadataURL(tokenURI)
 
-		return nil, errors.Wrap(err, "resolveMetadataURL")
+	if !isValidURL(mdURL) {
+		return nil, nil
 	}
 
+	var metadata *eventindexer.NFTMetadata
+
 	//nolint
-	resp, err := http.Get(url)
+	resp, err := http.Get(mdURL)
 	if err != nil {
 		return nil, err
 	}
 
 	defer resp.Body.Close()
 
-	var metadata eventindexer.NFTMetadata
+	if resp.StatusCode != http.StatusOK {
+		return nil, nil
+	}
 
 	err = json.NewDecoder(resp.Body).Decode(&metadata)
 	if err != nil {
@@ -84,7 +80,7 @@ func (i *Indexer) fetchNFTMetadata(
 	}
 
 	if methodName == "tokenURI" {
-		if err := i.fetchSymbol(ctx, contractABI, &metadata, contractAddressCommon); err != nil {
+		if err := i.fetchSymbol(ctx, contractABI, metadata, contractAddressCommon); err != nil {
 			return nil, err
 		}
 	}
@@ -93,39 +89,52 @@ func (i *Indexer) fetchNFTMetadata(
 	metadata.TokenID = tokenID.Int64()
 	metadata.ChainID = chainID.Int64()
 
-	return &metadata, nil
+	return metadata, nil
 }
 
-func resolveMetadataURL(ctx context.Context, tokenURI string) (string, error) {
-	if strings.HasPrefix(tokenURI, "ipfs://") {
-		ipfsHash := strings.TrimPrefix(tokenURI, "ipfs://")
-		resolvedURL := fmt.Sprintf("https://ipfs.io/ipfs/%s", ipfsHash)
+// isValidURL checks if the given string is a valid URL
+func isValidURL(str string) bool {
+	u, err := url.Parse(str)
+	if err != nil || u.Scheme == "" || u.Host == "" {
+		return false
+	}
 
-		if isValidURL(ctx, resolvedURL) {
-			return resolvedURL, nil
-		}
+	return true
+}
 
-		return "", eventindexer.ErrInvalidURL
+// isBase64 checks if the given string is a valid base64 encoded string
+func isBase64(str string) bool {
+	if !strings.Contains(str, "base64,") {
+		return false
 	}
 
-	if isValidURL(ctx, tokenURI) {
-		return tokenURI, nil
+	parts := strings.Split(str, "base64,")
+	if len(parts) != 2 {
+		return false
 	}
 
-	return "", eventindexer.ErrInvalidURL
+	_, err := base64.StdEncoding.DecodeString(parts[1])
+
+	return err == nil
 }
 
-func isValidURL(ctx context.Context, rawURL string) bool {
-	client := &http.Client{
-		Timeout: 3 * time.Second,
+func resolveMetadataURL(tokenURI string) string {
+	if strings.HasPrefix(tokenURI, "ipfs://") {
+		ipfsHash := strings.TrimPrefix(tokenURI, "ipfs://")
+		resolvedURL := fmt.Sprintf("https://ipfs.io/ipfs/%s", ipfsHash)
+
+		return resolvedURL
 	}
 
-	resp, err := client.Head(rawURL)
-	if err != nil || resp.StatusCode != http.StatusOK {
-		return false
+	if isBase64(tokenURI) {
+		parts := strings.Split(tokenURI, "base64,")
+
+		decodedTokenURI, _ := base64.StdEncoding.DecodeString(parts[1])
+
+		return string(decodedTokenURI)
 	}
 
-	return true
+	return tokenURI
 }
 
 func (i *Indexer) fetchSymbol(ctx context.Context, contractABI abi.ABI, metadata *eventindexer.NFTMetadata, contractAddress common.Address) error {
diff --git a/packages/eventindexer/indexer/index_erc20_transfers.go b/packages/eventindexer/indexer/index_erc20_transfers.go
index d958bdfc7cc..2d5da493d10 100644
--- a/packages/eventindexer/indexer/index_erc20_transfers.go
+++ b/packages/eventindexer/indexer/index_erc20_transfers.go
@@ -157,10 +157,6 @@ func (i *Indexer) saveERC20Transfer(ctx context.Context, chainID *big.Int, vLog
 		if err != nil {
 			return errors.Wrap(err, "i.erc20BalanceRepo.CreateMetadata")
 		}
-
-		slog.Info("metadata created", "pk", pk, "symbol", symbol, "decimals", decimals, "contractAddress", vLog.Address.Hex())
-	} else {
-		slog.Info("metadata found", "pk", pk, "symbol", md.Symbol, "decimals", md.Decimals, "contractAddress", vLog.Address.Hex())
 	}
 
 	// increment To address's balance
diff --git a/packages/eventindexer/indexer/index_nft_transfers.go b/packages/eventindexer/indexer/index_nft_transfers.go
index 72d1d1de9c6..624f7c46e36 100644
--- a/packages/eventindexer/indexer/index_nft_transfers.go
+++ b/packages/eventindexer/indexer/index_nft_transfers.go
@@ -60,7 +60,7 @@ func (i *Indexer) indexNFTTransfers(
 }
 
 // isERC1155Transfer determines whether a given log is a valid ERC1155 transfer event
-func (i *Indexer) isERC1155Transfer(ctx context.Context, vLog types.Log) bool {
+func (i *Indexer) isERC1155Transfer(_ context.Context, vLog types.Log) bool {
 	// malformed event
 	if len(vLog.Topics) == 0 {
 		return false
@@ -152,20 +152,23 @@ func (i *Indexer) saveERC721Transfer(ctx context.Context, chainID *big.Int, vLog
 				TokenID:         tokenID,
 				Name:            "invalid_metadata",
 			}
-		}
 
-		metadata, err = i.nftMetadataRepo.SaveNFTMetadata(ctx, metadata)
-		if err != nil {
-			return errors.Wrap(err, "i.nftMetadataRepo.SaveNFTMetadata")
+			metadata, err = i.nftMetadataRepo.SaveNFTMetadata(ctx, metadata)
+			if err != nil {
+				return errors.Wrap(err, "i.nftMetadataRepo.SaveNFTMetadata")
+			}
 		}
 
 		pk = metadata.ID
+	}
 
-		slog.Info("metadata created", "contractAddress", vLog.Address.Hex(), "tokenId", metadata.TokenID)
-	} else {
-		slog.Info("metadata found", "contractAddress", vLog.Address.Hex(), "tokenId", metadata.TokenID)
+	if pk == 0 {
+		slog.Warn("unable to create or fetch md", "contractAddress", vLog.Address.Hex())
+		return nil
 	}
 
+	slog.Info("metadata pk", "pk", pk)
+
 	// increment To address's balance
 	// decrement From address's balance
 	increaseOpts := eventindexer.UpdateNFTBalanceOpts{
@@ -257,18 +260,14 @@ func (i *Indexer) saveERC1155Transfer(ctx context.Context, chainID *big.Int, vLo
 					TokenID:         t.Id.Int64(),
 					Name:            "invalid_metadata",
 				}
-			}
 
-			metadata, err = i.nftMetadataRepo.SaveNFTMetadata(ctx, metadata)
-			if err != nil {
-				return errors.Wrap(err, "i.nftMetadataRepo.SaveNFTMetadata")
+				metadata, err = i.nftMetadataRepo.SaveNFTMetadata(ctx, metadata)
+				if err != nil {
+					return errors.Wrap(err, "i.nftMetadataRepo.SaveNFTMetadata")
+				}
 			}
 
 			pk = metadata.ID
-
-			slog.Info("metadata created", "contractAddress", vLog.Address.Hex(), "tokenId", metadata.TokenID)
-		} else {
-			slog.Info("metadata found", "contractAddress", vLog.Address.Hex(), "tokenId", metadata.TokenID)
 		}
 
 		increaseOpts := eventindexer.UpdateNFTBalanceOpts{
@@ -300,8 +299,6 @@ func (i *Indexer) saveERC1155Transfer(ctx context.Context, chainID *big.Int, vLo
 			return err
 		}
 	} else if vLog.Topics[0].Hex() == transferBatchSignatureHash.Hex() {
-		slog.Info("erc1155 transfer batch")
-
 		type TransferBatchEvent struct {
 			Operator common.Address
 			From     common.Address
@@ -320,7 +317,6 @@ func (i *Indexer) saveERC1155Transfer(ctx context.Context, chainID *big.Int, vLo
 		for idx, id := range t.Ids {
 			var pk int = 0
 
-			slog.Info("ERC1155 BATCH:", "", pk)
 			// Check if metadata already exists in db, if not fetch and store
 			metadata, err := i.nftMetadataRepo.GetNFTMetadata(ctx, vLog.Address.Hex(), id.Int64(), chainID.Int64())
 			if err != nil {
@@ -344,18 +340,14 @@ func (i *Indexer) saveERC1155Transfer(ctx context.Context, chainID *big.Int, vLo
 						TokenID:         id.Int64(),
 						Name:            "invalid_metadata",
 					}
-				}
 
-				metadata, err = i.nftMetadataRepo.SaveNFTMetadata(ctx, metadata)
-				if err != nil {
-					return errors.Wrap(err, "i.nftMetadataRepo.SaveNFTMetadata")
+					metadata, err = i.nftMetadataRepo.SaveNFTMetadata(ctx, metadata)
+					if err != nil {
+						return errors.Wrap(err, "i.nftMetadataRepo.SaveNFTMetadata")
+					}
 				}
 
 				pk = metadata.ID
-
-				slog.Info("metadata created", "contractAddress", vLog.Address.Hex(), "tokenId", metadata.TokenID)
-			} else {
-				slog.Info("metadata found", "contractAddress", vLog.Address.Hex(), "tokenId", metadata.TokenID)
 			}
 
 			increaseOpts := eventindexer.UpdateNFTBalanceOpts{
diff --git a/packages/eventindexer/migrations/20270906208850_alter_nft_metadata_addtl_indexes.sql b/packages/eventindexer/migrations/20270906208850_alter_nft_metadata_addtl_indexes.sql
new file mode 100644
index 00000000000..8e9e3bfd923
--- /dev/null
+++ b/packages/eventindexer/migrations/20270906208850_alter_nft_metadata_addtl_indexes.sql
@@ -0,0 +1,12 @@
+-- +goose Up
+-- +goose StatementBegin
+ALTER TABLE `nft_metadata` ADD INDEX `nft_metadata_contract_address_token_id_chain_id_index` (`contract_address`, `token_id`, `chain_id`),
+ADD INDEX `nft_metadata_contract_address_index` (`contract_address`)
+;
+
+-- +goose StatementEnd
+-- +goose Down
+-- +goose StatementBegin
+ALTER TABLE nft_metadata DROP INDEX nft_metadata_contract_address_token_id_chain_id_index,
+  DROP INDEX nft_metadata_contract_address;
+-- +goose StatementEnd
diff --git a/packages/eventindexer/migrations/20270906208851_alter_nft_balances_addtl_indexes.sql b/packages/eventindexer/migrations/20270906208851_alter_nft_balances_addtl_indexes.sql
new file mode 100644
index 00000000000..e641c74a96b
--- /dev/null
+++ b/packages/eventindexer/migrations/20270906208851_alter_nft_balances_addtl_indexes.sql
@@ -0,0 +1,10 @@
+-- +goose Up
+-- +goose StatementBegin
+ALTER TABLE `nft_balances` ADD INDEX `nft_balances_address_chain_id_amount_index` (`address`, `chain_id`, `amount`);
+
+-- +goose StatementEnd
+-- +goose Down
+-- +goose StatementBegin
+ALTER TABLE nft_balances
+  DROP INDEX nft_balances_address_chain_id_amount_index
+-- +goose StatementEnd
diff --git a/packages/eventindexer/migrations/20270906208852_alter_erc20_balances_addtl_indexes.sql b/packages/eventindexer/migrations/20270906208852_alter_erc20_balances_addtl_indexes.sql
new file mode 100644
index 00000000000..b1de320be73
--- /dev/null
+++ b/packages/eventindexer/migrations/20270906208852_alter_erc20_balances_addtl_indexes.sql
@@ -0,0 +1,10 @@
+-- +goose Up
+-- +goose StatementBegin
+ALTER TABLE `erc20_balances` ADD INDEX `erc20_balances_contract_address_address_chain_id_index` (`contract_address`, `address`, `chain_id`);
+
+-- +goose StatementEnd
+-- +goose Down
+-- +goose StatementBegin
+ALTER TABLE erc20_balances DROP INDEX erc20_balances_contract_address_address_chain_id_index,
+  DROP INDEX erc20_balances_contract_address-- +goose StatementEnd
+-- +goose StatementEnd
\ No newline at end of file
diff --git a/packages/eventindexer/pkg/repo/nft_balance.go b/packages/eventindexer/pkg/repo/nft_balance.go
index 35e07bdd3c0..318a8a28b89 100644
--- a/packages/eventindexer/pkg/repo/nft_balance.go
+++ b/packages/eventindexer/pkg/repo/nft_balance.go
@@ -2,11 +2,13 @@ package repo
 
 import (
 	"context"
-	"github.com/taikoxyz/taiko-mono/packages/eventindexer/pkg/db"
 	"net/http"
 	"strings"
 	"time"
 
+	"github.com/taikoxyz/taiko-mono/packages/eventindexer/pkg/db"
+	"golang.org/x/exp/slog"
+
 	"github.com/morkid/paginate"
 	"github.com/pkg/errors"
 	"github.com/taikoxyz/taiko-mono/packages/eventindexer"
@@ -137,6 +139,8 @@ func (r *NFTBalanceRepository) IncreaseAndDecreaseBalancesInTx(
 		}
 
 		if strings.Contains(err.Error(), "Deadlock") {
+			slog.Warn("database deadlock")
+
 			retries--
 
 			time.Sleep(100 * time.Millisecond) // backoff before retrying