protected String resolveOffchain(
            String lookupData, OffchainResolverContract resolver, int lookupCounter)
            throws Exception {
        if (EnsUtils.isEIP3668(lookupData)) {

            OffchainLookup offchainLookup =
                    OffchainLookup.build(Numeric.hexStringToByteArray(lookupData.substring(10)));

            if (!resolver.getContractAddress().equals(offchainLookup.getSender())) {
                throw new EnsResolutionException(
                        "Cannot handle OffchainLookup raised inside nested call");
            }

            String gatewayResult =
                    ccipReadFetch(
                            offchainLookup.getUrls(),
                            offchainLookup.getSender(),
                            Numeric.toHexString(offchainLookup.getCallData()));

            if (gatewayResult == null) {
                throw new EnsResolutionException("CCIP Read disabled or provided no URLs.");
            }

            ObjectMapper objectMapper = ObjectMapperFactory.getObjectMapper();
            EnsGatewayResponseDTO gatewayResponseDTO =
                    objectMapper.readValue(gatewayResult, EnsGatewayResponseDTO.class);

            String resolvedNameHex =
                    resolver.resolveWithProof(
                                    Numeric.hexStringToByteArray(gatewayResponseDTO.getData()),
                                    offchainLookup.getExtraData())
                            .send();

            // This protocol can result in multiple lookups being requested by the same contract.
            if (EnsUtils.isEIP3668(resolvedNameHex)) {
                if (lookupCounter <= 0) {
                    throw new EnsResolutionException("Lookup calls is out of limit.");
                }

                return resolveOffchain(lookupData, resolver, --lookupCounter);
            } else {
                byte[] resolvedNameBytes =
                        DefaultFunctionReturnDecoder.decodeDynamicBytes(resolvedNameHex);

                return DefaultFunctionReturnDecoder.decodeAddress(
                        Numeric.toHexString(resolvedNameBytes));
            }
        }

        return lookupData;
    }
@Test
    void resolveOffchainWhenContractAddressNotEq() {
        OffchainResolverContract resolver = mock(OffchainResolverContract.class);

        when(resolver.getContractAddress()).thenReturn("0x123456");

        assertThrows(
                EnsResolutionException.class,
                () -> ensResolver.resolveOffchain(LOOKUP_HEX, resolver, 4));
    }