def METHOD_NAME(gateway_config=None):
    """
    Create a Web3 instance configured and ready-to-use gateway to the blockchain.
    :param gateway_config: Blockchain gateway configuration.
    :type gateway_config: dict
    :return: Configured Web3 instance.
    :rtype: :class:`web3.Web3`
    """
    if gateway_config is None or gateway_config['type'] == 'auto':
        w3 = web3.Web3()
    elif gateway_config['type'] == 'user':
        request_kwargs = gateway_config.get('http_options', {})
        w3 = web3.Web3(web3.Web3.HTTPProvider(gateway_config['http'], request_kwargs=request_kwargs))
    elif gateway_config['type'] == 'infura':
        request_kwargs = gateway_config.get('http_options', {})
        project_id = gateway_config['key']
        # project_secret = gateway_config['secret']
        http_url = 'https://{}.infura.io/v3/{}'.format(gateway_config['network'], project_id)
        w3 = web3.Web3(web3.Web3.HTTPProvider(http_url, request_kwargs=request_kwargs))
        # https://web3py.readthedocs.io/en/stable/middleware.html#geth-style-proof-of-authority
        if gateway_config.get('network', None) == 'rinkeby':
            # This middleware is required to connect to geth --dev or the Rinkeby public network.
            from web3.middleware import geth_poa_middleware
            # inject the poa compatibility middleware to the innermost layer
            w3.middleware_onion.inject(geth_poa_middleware, layer=0)
    # FIXME
    elif gateway_config['type'] == 'cloudflare':
        # https://developers.cloudflare.com/web3/ethereum-gateway/reference/supported-networks/
        raise NotImplementedError()
    # FIXME
    elif gateway_config['type'] == 'zksync':
        # https://v2-docs.zksync.io/dev/testnet/important-links.html
        raise NotImplementedError()
    else:
        raise RuntimeError('invalid blockchain gateway type "{}"'.format(gateway_config['type']))
    return w3