static bool TryGetDeploymentSigner(ConfigProps config, ExpressChain?chain, byte version, [MaybeNullWhen(false)] out Signer signer)
            {
                if (config.TryGetValue("deploy-signer", out var deploySignerToken))
                {
                    return(TryParseSigner(deploySignerToken, chain, version, out signer));
                }

                signer = default;
                return(false);
            }
        static async Task <IApplicationEngine> CreateEngineAsync(ConfigProps config)
        {
            if (!config.TryGetValue("invocation", out var jsonInvocation))
            {
                throw new JsonException("missing invocation property");
            }

            if (jsonInvocation.Type == JTokenType.Object && jsonInvocation["trace-file"] != null)
            {
                var traceFile      = jsonInvocation.Value <string>("trace-file") ?? throw new JsonException("invalid trace-file property");
                var program        = ParseProgram(config);
                var launchContract = LoadNefFile(program);
                var contracts      = new List <NefFile> {
                    launchContract
                };

                // TODO: load other contracts?

                return(new TraceApplicationEngine(traceFile, contracts));
            }

            return(await CreateDebugEngineAsync(config, jsonInvocation).ConfigureAwait(false));
        }