> ## Documentation Index
> Fetch the complete documentation index at: https://docs.flashnet.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# Estimate a swap

> Indicative price for a route, no state created. Public.

export const createApiHelpers = () => {
  function record(value) {
    return value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
  }
  function list(value) {
    return Array.isArray(value) ? value : [];
  }
  function text(value) {
    return typeof value === "string" ? value : "";
  }
  function owns(value, key) {
    return Object.prototype.hasOwnProperty.call(value, key);
  }
  function scalar(value) {
    return value === null || ["string", "number", "boolean"].includes(typeof value);
  }
  function pointer(spec, ref) {
    if (ref === "#") return spec;
    if (!ref.startsWith("#/")) throw new Error("Unsupported reference: " + ref);
    const parts = decodeURIComponent(ref.slice(2)).split("/");
    let value = spec;
    for (const part of parts) {
      if ((/~(?:[^01]|$)/).test(part)) throw new Error("Invalid JSON pointer: " + ref);
      const key = part.replace(/~1/g, "/").replace(/~0/g, "~");
      if (value === null || typeof value !== "object" || !Object.prototype.hasOwnProperty.call(value, key)) {
        throw new Error("Missing reference: " + ref);
      }
      value = value[key];
    }
    return value;
  }
  function referenceObject(spec, input, seen = new Set()) {
    const source = record(input);
    if (typeof source.$ref !== "string") return source;
    if (seen.has(source.$ref) || seen.size >= 32) throw new Error("Cyclic reference: " + source.$ref);
    const target = pointer(spec, source.$ref);
    if (target === null || typeof target !== "object" || Array.isArray(target)) {
      throw new Error("Expected object reference: " + source.$ref);
    }
    const {$ref, ...siblings} = source;
    return {
      ...referenceObject(spec, target, new Set([...seen, source.$ref])),
      ...siblings
    };
  }
  function indexAllOf(branches, base) {
    const objects = [...branches.map(record), base];
    const names = [...new Set(objects.flatMap(item => Object.keys(record(item.properties))))];
    const properties = Object.fromEntries(names.map(name => {
      const values = objects.filter(item => owns(record(item.properties), name)).map(item => record(item.properties)[name]);
      const unique = uniqueConstraints(values);
      return [name, unique.length === 1 ? unique[0] : {
        allOf: unique
      }];
    }));
    const required = [...new Set(objects.flatMap(item => list(item.required).filter(name => typeof name === "string")))];
    const result = {
      ...base
    };
    if (names.length) result.properties = properties;
    if (required.length) result.required = required;
    for (const key of ["description", "title", "example", "examples", "default"]) {
      if (!owns(result, key)) {
        const source = [...objects].reverse().find(item => owns(item, key));
        if (source) result[key] = source[key];
      }
    }
    for (const key of ["type", "items", "format", "enum", "const", "minimum", "maximum", "exclusiveMinimum", "exclusiveMaximum", "minLength", "maxLength", "minItems", "maxItems", "pattern", "multipleOf", "additionalProperties"]) {
      const values = objects.filter(item => owns(item, key)).map(item => item[key]);
      if (!owns(result, key) && values.length && values.every(value => JSON.stringify(value) === JSON.stringify(values[0]))) result[key] = values[0];
    }
    return result;
  }
  function uniqueConstraints(values) {
    const flattened = values.flatMap(value => {
      const item = record(value);
      return Object.keys(item).length === 1 && Array.isArray(item.allOf) ? uniqueConstraints(item.allOf) : [value];
    });
    return [...new Map(flattened.map(value => [JSON.stringify(value), value])).values()];
  }
  function resolveNode(spec, input, seen, depth) {
    if (typeof input === "boolean") return input;
    const source = record(input);
    if (depth >= 32) return {
      ...source,
      "x-resolution-error": "Schema resolution depth exceeded"
    };
    if (typeof source.$ref === "string") {
      try {
        if (seen.has(source.$ref)) throw new Error("Cyclic reference: " + source.$ref);
        const target = pointer(spec, source.$ref);
        if (typeof target !== "boolean" && (target === null || typeof target !== "object" || Array.isArray(target))) {
          throw new Error("Expected schema reference: " + source.$ref);
        }
        const resolved = resolveNode(spec, target, new Set([...seen, source.$ref]), depth + 1);
        const {$ref, ...siblings} = source;
        if (!Object.keys(siblings).length) return resolved;
        return resolveNode(spec, {
          ...siblings,
          allOf: [resolved, ...list(siblings.allOf)]
        }, seen, depth + 1);
      } catch (error) {
        return {
          ...source,
          "x-resolution-error": error instanceof Error ? error.message : String(error)
        };
      }
    }
    const result = {
      ...source
    };
    for (const key of ["allOf", "anyOf", "oneOf"]) {
      if (Array.isArray(source[key])) result[key] = list(source[key]).map(branch => resolveNode(spec, branch, seen, depth + 1));
    }
    return Array.isArray(result.allOf) ? indexAllOf(result.allOf, result) : result;
  }
  function resolveSchema(spec, schema) {
    return resolveNode(spec, schema, new Set(), 0);
  }
  function fields(spec, input, depth) {
    if (depth >= 16) return [];
    const schema = record(resolveSchema(spec, input));
    const required = new Set(list(schema.required));
    const result = new Map(Object.entries(record(schema.properties)).map(([name, value]) => {
      const resolved = resolveSchema(spec, value);
      return [name, {
        name,
        required: required.has(name),
        schema: resolved,
        description: text(record(resolved).description)
      }];
    }));
    for (const key of ["anyOf", "oneOf"]) {
      const branches = list(schema[key]).map(branch => fields(spec, branch, depth + 1));
      const names = [...new Set(branches.flatMap(branch => branch.map(field => field.name)))];
      for (const name of names) {
        const variants = branches.flatMap(branch => branch.filter(field => field.name === name));
        const alternative = variants.length === 1 ? variants[0].schema : {
          anyOf: variants.map(field => field.schema)
        };
        const existing = result.get(name);
        const merged = existing ? resolveSchema(spec, {
          allOf: [existing.schema, alternative]
        }) : alternative;
        result.set(name, {
          name,
          schema: merged,
          required: Boolean(existing?.required || required.has(name) || variants.length === branches.length && variants.every(field => field.required)),
          description: existing?.description ?? (variants.every(field => field.description === variants[0].description) ? variants[0].description : "")
        });
      }
    }
    for (const branch of list(schema.allOf)) {
      for (const field of fields(spec, branch, depth + 1)) {
        const existing = result.get(field.name);
        if (!existing) result.set(field.name, field); else if (field.required && !existing.required) result.set(field.name, {
          ...existing,
          required: true
        });
      }
    }
    return [...result.values()];
  }
  function schemaFields(spec, schema) {
    return fields(spec, schema, 0);
  }
  function typeLabel(spec, input, depth) {
    if (depth >= 16) return "recursive schema";
    const resolved = resolveSchema(spec, input);
    if (resolved === false) return "never";
    if (resolved === true) return "unknown";
    if (resolved.$ref) return "unresolved reference: " + text(resolved.$ref);
    if (resolved["x-resolution-error"]) return text(resolved["x-resolution-error"]);
    const parts = [];
    for (const key of ["anyOf", "oneOf", "allOf"]) {
      if (!Array.isArray(resolved[key])) continue;
      const labels = [...new Set(list(resolved[key]).map(branch => typeLabel(spec, branch, depth + 1)))];
      const useful = key === "allOf" ? labels.filter(label => label !== "unknown") : labels;
      if (useful.length === 1) parts.push(useful[0]); else if (useful.length) parts.push(key === "allOf" ? useful.map(label => `(${label})`).join(" & ") : `${key}(${useful.join(" | ")})`);
    }
    const types = typeof resolved.type === "string" ? [resolved.type] : list(resolved.type).filter(value => typeof value === "string");
    if (!types.length && resolved.properties && !parts.length) types.push("object");
    if (!types.length && resolved.items) types.push("array");
    const ownType = types.map(type => type === "array" ? `array<${typeLabel(spec, resolved.items, depth + 1)}>` : type !== "null" && typeof resolved.format === "string" ? `${type}<${resolved.format}>` : type).join(" | ");
    if (ownType && !parts.includes(ownType)) parts.push(ownType);
    let label = parts.join(" & ") || (owns(resolved, "const") ? resolved.const === null ? "null" : typeof resolved.const : "unknown");
    if (resolved.nullable === true && !types.includes("null")) label = `(${label}) | null`;
    return label;
  }
  function schemaType(spec, schema) {
    return typeLabel(spec, schema, 0);
  }
  function options(spec, input, depth) {
    if (input === false) return [];
    if (depth >= 16) return null;
    const schema = record(resolveSchema(spec, input));
    if (schema.$ref || schema["x-resolution-error"]) return null;
    let values = null;
    if (Array.isArray(schema.enum) && schema.enum.every(scalar)) values = schema.enum;
    if (owns(schema, "const") && scalar(schema.const)) values = [schema.const];
    if (schema.type === "null") values = [null];
    for (const key of ["anyOf", "oneOf"]) {
      if (!Array.isArray(schema[key])) continue;
      const branches = list(schema[key]).map(branch => options(spec, branch, depth + 1));
      if (values === null && branches.every(branch => branch !== null)) values = branches.flat();
    }
    for (const branch of list(schema.allOf)) {
      const bounded = options(spec, branch, depth + 1);
      if (values === null && bounded !== null) values = bounded;
    }
    if (values === null) return null;
    if (schema.nullable === true) values = [...values, null];
    return [...new Set(values)].filter(value => permitsScalar(spec, schema, value, depth));
  }
  function permitsScalar(spec, input, value, depth) {
    if (input === false) return false;
    if (depth >= 16) return true;
    const schema = record(resolveSchema(spec, input));
    if (value === null && schema.nullable === true) return true;
    if (Array.isArray(schema.enum) && !schema.enum.includes(value)) return false;
    if (owns(schema, "const") && schema.const !== value) return false;
    const types = typeof schema.type === "string" ? [schema.type] : list(schema.type);
    const type = value === null ? "null" : typeof value;
    if (types.length && !types.includes(type) && !(typeof value === "number" && Number.isInteger(value) && types.includes("integer"))) return false;
    if (!list(schema.allOf).every(branch => permitsScalar(spec, branch, value, depth + 1))) return false;
    if (Array.isArray(schema.anyOf) && !list(schema.anyOf).some(branch => permitsScalar(spec, branch, value, depth + 1))) return false;
    if (Array.isArray(schema.oneOf)) {
      const matching = list(schema.oneOf).filter(branch => permitsScalar(spec, branch, value, depth + 1));
      if (matching.length !== 1) return false;
    }
    return true;
  }
  function schemaOptions(spec, schema) {
    return options(spec, schema, 0) ?? [];
  }
  function explicitExample(spec, media) {
    if (owns(media, "example")) return {
      found: true,
      value: media.example
    };
    for (const example of Object.values(record(media.examples))) {
      const resolved = referenceObject(spec, example);
      if (owns(resolved, "value")) return {
        found: true,
        value: resolved.value
      };
    }
    return {
      found: false,
      value: undefined
    };
  }
  function generatedExample(spec, input, depth) {
    if (depth >= 6 || input === false) return undefined;
    const schema = record(resolveSchema(spec, input));
    if (owns(schema, "example")) return schema.example;
    if (Array.isArray(schema.examples) && schema.examples.length) return schema.examples[0];
    if (owns(schema, "const")) return schema.const;
    if (schema.$ref || schema["x-resolution-error"]) return undefined;
    if (!canGenerate(spec, schema, depth)) return undefined;
    if (list(schema.enum).length) return schemaOptions(spec, schema)[0];
    if (schema.properties || schema.type === "object") return objectExample(spec, schema, depth);
    if (schema.type === "array" || schema.items) return schema.minItems ? undefined : [];
    const type = typeof schema.type === "string" ? schema.type : list(schema.type).find(value => value !== "null");
    if (type === "string") return schema.pattern || schema.format || schema.minLength ? undefined : typeof schema.maxLength === "number" && schema.maxLength < 6 ? "" : "string";
    if (type === "boolean") return false;
    if (type === "null") return null;
    if (type === "integer" || type === "number") return numericExample(schema);
    const branches = list(schema.allOf);
    return branches.length === 1 ? generatedExample(spec, branches[0], depth + 1) : undefined;
  }
  function canGenerate(spec, input, depth) {
    if (input === false || depth >= 12) return false;
    const schema = record(resolveSchema(spec, input));
    if (["anyOf", "oneOf", "not", "if", "dependentRequired", "dependentSchemas", "contains", "minProperties", "unevaluatedProperties"].some(key => owns(schema, key))) return false;
    return list(schema.allOf).every(branch => {
      const item = record(branch);
      if (item.additionalProperties === false || !canGenerate(spec, branch, depth + 1)) return false;
      return ["minimum", "maximum", "minLength", "maxLength", "minItems", "maxItems", "pattern", "format", "multipleOf"].every(key => !owns(item, key) || JSON.stringify(item[key]) === JSON.stringify(schema[key]));
    });
  }
  function numericExample(schema) {
    let value = typeof schema.minimum === "number" ? Math.max(0, schema.minimum) : 0;
    if (schema.type === "integer") value = Math.ceil(value);
    if (schema.exclusiveMinimum !== undefined || schema.exclusiveMaximum !== undefined || schema.multipleOf !== undefined) return undefined;
    if (typeof schema.maximum === "number" && value > schema.maximum) return undefined;
    return value;
  }
  function objectExample(spec, schema, depth) {
    const entries = [];
    const known = schemaFields(spec, schema);
    if (list(schema.required).some(name => !known.some(field => field.name === name))) return undefined;
    for (const field of known.filter(item => item.required)) {
      const value = generatedExample(spec, field.schema, depth + 1);
      if (value === undefined) return undefined;
      entries.push([field.name, value]);
    }
    return Object.fromEntries(entries);
  }
  function contentModel(spec, container) {
    const content = record(container.content);
    const keys = Object.keys(content);
    const contentType = ((keys.find(key => key === "application/json") ?? keys.find(key => (/\+json(?:;|$)/i).test(key))) ?? keys[0]) ?? null;
    const media = contentType ? record(content[contentType]) : {};
    const schema = owns(media, "schema") ? resolveSchema(spec, media.schema) : null;
    const explicit = explicitExample(spec, media);
    return {
      contentType,
      schema,
      example: explicit.found ? explicit.value : schema === null ? undefined : generatedExample(spec, schema, 0)
    };
  }
  function parameterModels(spec, values) {
    const parameters = new Map();
    for (const value of values) {
      const item = referenceObject(spec, value);
      const schema = owns(item, "schema") ? resolveSchema(spec, item.schema) : contentModel(spec, item).schema ?? ({});
      const name = text(item.name);
      const location = text(item.in);
      parameters.set(JSON.stringify([name, location]), {
        name,
        location,
        required: location === "path" || item.required === true,
        schema,
        description: text(item.description ?? record(schema).description)
      });
    }
    return [...parameters.values()];
  }
  function serverUrl(servers) {
    const server = record(list(servers)[0]);
    return text(server.url).replace(/\{([^{}]+)\}/g, (match, name) => {
      const variable = record(record(server.variables)[name]);
      return owns(variable, "default") ? String(variable.default) : match;
    });
  }
  function requestBodyModel(spec, body) {
    const content = contentModel(spec, body);
    return {
      required: body.required === true,
      description: text(body.description ?? record(content.schema).description),
      ...content
    };
  }
  function createOperationModel(spec, path, method) {
    const verb = method.toLowerCase();
    const item = referenceObject(spec, record(spec.paths)[path]);
    if (!["get", "put", "post", "delete", "options", "head", "patch", "trace"].includes(verb) || !owns(item, verb)) {
      throw new Error(`Operation not found: ${method.toUpperCase()} ${path}`);
    }
    const operation = referenceObject(spec, item[verb]);
    const body = owns(operation, "requestBody") ? referenceObject(spec, operation.requestBody) : null;
    return {
      title: text(operation.summary) || text(operation.operationId) || `${verb.toUpperCase()} ${path}`,
      description: text(operation.description),
      method: verb.toUpperCase(),
      path,
      server: serverUrl((operation.servers ?? item.servers) ?? spec.servers),
      parameters: parameterModels(spec, [...list(item.parameters), ...list(operation.parameters)]),
      requestBody: body ? requestBodyModel(spec, body) : null,
      responses: Object.entries(record(operation.responses)).map(([status, value]) => {
        const response = referenceObject(spec, value);
        return {
          status,
          description: text(response.description),
          ...contentModel(spec, response)
        };
      }),
      security: list(operation.security ?? spec.security),
      securitySchemes: Object.fromEntries(Object.entries(record(record(spec.components).securitySchemes)).map(([name, value]) => [name, referenceObject(spec, value)]))
    };
  }
  return {
    createOperationModel,
    schemaFields,
    schemaType,
    schemaOptions,
    resolveSchema
  };
};

export const ApiCode = ({language, children}) => <CodeBlock language={language}>{children}</CodeBlock>;

export const ApiRequest = ({model, CodeBlock}) => {
  const origin = "https://orchestration.flashnet.xyz";
  const [language, setLanguage] = useState("curl");
  const method = model.method.toUpperCase();
  const security = selectSecurity();
  const authFields = security === null ? [] : Object.keys(security).map(authField);
  const parameters = (model.parameters || []).filter(parameter => ["path", "query", "header"].includes(parameter.location) && !(parameter.location === "header" && parameter.name.toLowerCase() === "authorization") && !authFields.some(field => field.location === parameter.location && (field.location === "header" ? field.name.toLowerCase() === parameter.name.toLowerCase() : field.name === parameter.name)));
  const example = codeExample();
  function initialBody() {
    const requestBody = model.requestBody;
    if (!requestBody) return "";
    const value = requestBody.example ?? requestBody.schema?.example;
    return value === undefined && !requestBody.required ? "" : JSON.stringify(value ?? ({}), null, 2);
  }
  function publishedServerSupported() {
    try {
      const server = new URL(model.server);
      return server.origin === origin && !server.username && !server.password;
    } catch {
      return false;
    }
  }
  function supportedSecurity(name) {
    const scheme = model.securitySchemes?.[name];
    if (!scheme) return false;
    if (["oauth2", "openIdConnect"].includes(scheme.type)) return true;
    if (scheme.type === "http") return ["bearer", "basic"].includes(scheme.scheme?.toLowerCase());
    return scheme.type === "apiKey" && ["header", "query"].includes(scheme.in) && Boolean(scheme.name);
  }
  function selectSecurity() {
    const requirements = model.security || [];
    if (!requirements.length || requirements.some(requirement => !Object.keys(requirement).length)) return {};
    return requirements.find(requirement => {
      const names = Object.keys(requirement);
      if (!names.every(supportedSecurity)) return false;
      const targets = names.map(name => {
        const field = authField(name);
        return field.location + ":" + (field.location === "header" ? field.name.toLowerCase() : field.name);
      });
      return new Set(targets).size === targets.length;
    }) ?? null;
  }
  function authField(key) {
    const scheme = model.securitySchemes[key];
    const apiKey = scheme.type === "apiKey";
    const basic = scheme.scheme?.toLowerCase() === "basic";
    return {
      key,
      name: apiKey ? scheme.name : "Authorization",
      location: apiKey ? scheme.in : "header",
      prefix: apiKey ? "" : basic ? "Basic " : "Bearer ",
      placeholder: basic ? "BASE64_USERNAME_PASSWORD" : "YOUR_" + key.toUpperCase().replace(/[^A-Z0-9]/g, "_")
    };
  }
  function parameterKey(parameter) {
    return parameter.location + ":" + parameter.name;
  }
  function placeholder(name) {
    return "YOUR_" + name.toUpperCase().replace(/[^A-Z0-9]/g, "_");
  }
  function requestUrl(inputs) {
    if (!publishedServerSupported()) throw new Error("Unsupported published server.");
    if (!(/^\/v\d+(?:\/|$)/).test(model.path) || (/[?#\\]/).test(model.path)) throw new Error("Invalid API path.");
    const segments = model.path.split("/").map(segment => {
      const resolved = segment.replace(/\{([^{}]+)\}/g, (_, name) => {
        const value = inputs["path:" + name];
        if (!value?.trim()) throw new Error("Enter " + name + ".");
        return value;
      });
      if ([".", ".."].includes(resolved)) throw new Error("Path values cannot be dot segments.");
      return encodeURIComponent(resolved);
    });
    const url = new URL(origin);
    url.pathname = segments.join("/");
    for (const parameter of parameters) {
      const value = inputs[parameterKey(parameter)];
      if (parameter.location === "query" && value?.trim()) url.searchParams.append(parameter.name, value);
    }
    return url;
  }
  function shellQuote(value) {
    return "'" + value.replace(/'/g, "'\"'\"'") + "'";
  }
  function applyExampleSecurity(url, headers) {
    if (security === null) throw new Error("Unsupported example authentication.");
    for (const field of authFields) {
      if (field.location === "query") {
        url.searchParams.set(field.name, field.placeholder);
      } else {
        headers.set(field.name, field.prefix + field.placeholder);
      }
    }
  }
  function exampleRequest() {
    if (!["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"].includes(method)) {
      throw new Error("Unsupported HTTP method.");
    }
    const inputs = Object.fromEntries(parameters.map(parameter => [parameterKey(parameter), placeholder(parameter.name)]));
    for (const match of model.path.matchAll(/\{([^{}]+)\}/g)) inputs["path:" + match[1]] = placeholder(match[1]);
    const url = requestUrl(inputs);
    const headers = new Headers({
      Accept: "application/json"
    });
    for (const parameter of parameters) {
      if (parameter.location === "header") headers.set(parameter.name, placeholder(parameter.name));
    }
    applyExampleSecurity(url, headers);
    const payload = model.requestBody && !["GET", "HEAD"].includes(method) ? initialBody() || "{}" : undefined;
    if (payload !== undefined) headers.set("Content-Type", model.requestBody.contentType || "application/json");
    const query = Array.from(url.searchParams.entries());
    url.search = "";
    return {
      url: url.toString(),
      query,
      headers: Object.fromEntries(headers.entries()),
      body: payload
    };
  }
  function curlExample(request) {
    const lines = [method === "GET" ? "curl --get" : "curl --request " + shellQuote(method)];
    lines.push("  --url " + shellQuote(request.url));
    const queryOption = method === "GET" ? "--data-urlencode" : "--url-query";
    for (const [name, value] of request.query) {
      lines.push("  " + queryOption + " " + shellQuote(encodeURIComponent(name) + "=" + value));
    }
    for (const [name, value] of Object.entries(request.headers)) lines.push("  --header " + shellQuote(name + ": " + value));
    if (request.body !== undefined) lines.push("  --data-raw " + shellQuote(request.body));
    return lines.join(" \\\n");
  }
  function javascriptExample(request) {
    const lines = ["const url = new URL(" + JSON.stringify(request.url) + ");"];
    for (const [name, value] of request.query) {
      lines.push("url.searchParams.append(" + JSON.stringify(name) + ", " + JSON.stringify(value) + ");");
    }
    const options = {
      method,
      headers: request.headers,
      credentials: "omit",
      redirect: "error"
    };
    lines.push("", "const response = await fetch(url, " + JSON.stringify(options, null, 2).slice(0, -2) + ",");
    if (request.body !== undefined) {
      lines.push("  body: [");
      for (const line of request.body.split("\n")) lines.push("    " + JSON.stringify(line) + ",");
      lines.push('  ].join("\\n"),');
    }
    return [...lines, "  signal: AbortSignal.timeout(30000)", "});", "console.log(response.status);", "console.log(await response.text());"].join("\n");
  }
  function pythonExample(request) {
    const lines = ["import requests", "", "response = requests.request(", "    " + JSON.stringify(method) + ",", "    " + JSON.stringify(request.url) + ","];
    if (request.query.length) {
      lines.push("    params={");
      for (const [name, value] of request.query) lines.push("        " + JSON.stringify(name) + ": " + JSON.stringify(value) + ",");
      lines.push("    },");
    }
    lines.push("    headers={");
    for (const [name, value] of Object.entries(request.headers)) lines.push("        " + JSON.stringify(name) + ": " + JSON.stringify(value) + ",");
    lines.push("    },");
    if (request.body !== undefined) {
      lines.push("    data=(");
      const bodyLines = request.body.split("\n");
      bodyLines.forEach((line, index) => lines.push("        " + JSON.stringify(line + (index < bodyLines.length - 1 ? "\n" : ""))));
      lines.push("    ),");
    }
    return [...lines, "    timeout=30,", "    allow_redirects=False,", ")", "print(response.status_code)", "print(response.text)"].join("\n");
  }
  function codeExample() {
    try {
      const request = exampleRequest();
      if (language === "curl") return curlExample(request);
      return language === "javascript" ? javascriptExample(request) : pythonExample(request);
    } catch (failure) {
      return "Example unavailable: " + (failure instanceof Error ? failure.message : "invalid endpoint model.");
    }
  }
  return <div className="api-reference-request">
      <div className="api-reference-code-toolbar">
        <div className="api-reference-language-tabs" role="group" aria-label="Request language">
          {["curl", "javascript", "python"].map(item => <button className="api-reference-language-tab" type="button" key={item} aria-pressed={language === item} onClick={() => setLanguage(item)}>
              {item === "javascript" ? "JavaScript" : item === "python" ? "Python" : "cURL"}
            </button>)}
        </div>
      </div>
      {CodeBlock ? <CodeBlock language={language === "curl" ? "bash" : language}>
          {example}
        </CodeBlock> : <pre className="api-reference-code" tabIndex={0}>
          <code className={"api-reference-code-" + language}>{example}</code>
        </pre>}
    </div>;
};

export const LiveApiPage = ({path, method, helpers, RequestComponent, CodeBlock}) => {
  const schemaDetails = ({schema, spec, helpers, depth = 0, placement = "all"}) => {
    const resolved = helpers.resolveSchema(spec, schema);
    const options = helpers.schemaOptions(spec, schema);
    const branches = resolved.oneOf || resolved.anyOf || resolved.allOf || [];
    const nested = resolved.items || resolved;
    const fields = helpers.schemaFields(spec, nested);
    const hasChildren = fields.length > 0 || branches.length > 0 && options.length === 0;
    if (placement === "nested" && !hasChildren) return null;
    return <>
        {placement !== "nested" && options.length > 0 && <details className="api-reference-disclosure">
            <summary>
              Allowed values <span>{options.length}</span>
            </summary>
            <div className="api-reference-values">
              {options.map((value, index) => <code key={index}>{JSON.stringify(value)}</code>)}
            </div>
          </details>}
        {placement !== "inline" && depth < 8 && fields.length > 0 && <details className="api-reference-disclosure api-reference-children">
            <summary>
              {resolved.items ? "Item fields" : "Fields"}{" "}
              <span>{fields.length}</span>
            </summary>
            {schemaTable({
      fields,
      spec,
      helpers,
      depth: depth + 1
    })}
          </details>}
        {placement !== "inline" && depth < 8 && branches.length > 0 && options.length === 0 && <details className="api-reference-disclosure api-reference-children">
              <summary>
                {resolved.oneOf ? "One of" : resolved.anyOf ? "Any of" : "All of"}{" "}
                <span>{branches.length} schemas</span>
              </summary>
              {branches.map((branch, index) => <div className="api-reference-variant" key={index}>
                  <code>{helpers.schemaType(spec, branch)}</code>
                  {description({
      text: branch.description
    })}
                  {schemaDetails({
      schema: branch,
      spec,
      helpers,
      depth: depth + 1
    })}
                </div>)}
            </details>}
        {placement !== "nested" && constraints({
      schema: resolved
    })}
        {placement !== "inline" && depth >= 8 && <a href="https://orchestration.flashnet.xyz/openapi.json">
            View full schema
          </a>}
      </>;
  };
  const description = ({text}) => text ? <div className="api-reference-description">
        {text.split(/(`[^`]+`)/g).map((part, index) => part.startsWith("`") && part.endsWith("`") ? <code key={index}>{part.slice(1, -1)}</code> : <span key={index}>{part}</span>)}
      </div> : null;
  const constraints = ({schema}) => {
    const labels = {
      minimum: "Minimum",
      maximum: "Maximum",
      exclusiveMinimum: "Greater than",
      exclusiveMaximum: "Less than",
      minLength: "Minimum length",
      maxLength: "Maximum length",
      minItems: "Minimum items",
      maxItems: "Maximum items",
      pattern: "Pattern",
      multipleOf: "Multiple of",
      default: "Default",
      const: "Value"
    };
    return Object.entries(labels).map(([key, label]) => schema[key] !== undefined ? <div className="api-reference-constraint" key={key}>
          {label}: <code>{JSON.stringify(schema[key])}</code>
        </div> : null);
  };
  const schemaTable = ({fields, spec, helpers, depth = 0}) => <div className="api-reference-fields" role="table" aria-label={depth ? "Nested fields" : "Schema fields"}>
      <div className="api-reference-field-head" role="row">
        <span role="columnheader">Property</span>
        <span role="columnheader">Type</span>
        <span role="columnheader">Description</span>
      </div>
      {fields.map((field, index) => {
    const children = schemaDetails({
      schema: field.schema,
      spec,
      helpers,
      depth,
      placement: "nested"
    });
    return <div className="api-reference-field-group" role="rowgroup" key={`${field.location || ""}:${field.name}:${index}`}>
            <div className="api-reference-field" role="row">
              <div role="cell">
                <code>{field.name}</code>
                {field.location && <span className="api-reference-location">
                    {field.location}
                  </span>}
              </div>
              <div role="cell" className="api-reference-type">
                <code>{helpers.schemaType(spec, field.schema)}</code>
                {field.required && <span className="api-reference-required">required</span>}
                {field.schema.deprecated && <span>deprecated</span>}
              </div>
              <div role="cell">
                {description({
      text: field.description || field.schema.description
    })}
                {schemaDetails({
      schema: field.schema,
      spec,
      helpers,
      depth,
      placement: "inline"
    })}
              </div>
            </div>
            {children && <div role="row" className="api-reference-child-row">
                <div role="cell" aria-colspan={3}>
                  {children}
                </div>
              </div>}
          </div>;
  })}
    </div>;
  const responseSection = ({model, spec, helpers}) => {
    const response = model.responses.find(item => item.status === selected) || model.responses[0];
    if (!response) return <p>No response schema is published for this operation.</p>;
    const fields = helpers.schemaFields(spec, response.schema || ({}));
    return <>
        <div className="api-reference-response-bar">
          <label>
            Status{" "}
            <select value={response.status} onChange={event => setSelected(event.target.value)}>
              {model.responses.map(item => <option key={item.status} value={item.status}>
                  {item.status}
                </option>)}
            </select>
          </label>
          <code>{response.contentType}</code>
        </div>
        {description({
      text: response.description
    })}
        {fields.length > 0 ? schemaTable({
      fields,
      spec,
      helpers
    }) : schemaDetails({
      schema: response.schema || ({}),
      spec,
      helpers
    })}
        {response.example !== undefined && <details className="api-reference-disclosure api-reference-response-example">
            <summary>JSON example</summary>
            <CodeBlock language="json">
              {JSON.stringify(response.example, null, 2)}
            </CodeBlock>
          </details>}
      </>;
  };
  const [state, setState] = useState({
    spec: null,
    error: ""
  });
  const [attempt, setAttempt] = useState(0);
  const [selected, setSelected] = useState("");
  const model = useMemo(() => state.spec ? helpers.createOperationModel(state.spec, path, method) : null, [state.spec, path, method]);
  useEffect(() => {
    const controller = new AbortController();
    let active = true;
    const timeout = setTimeout(() => controller.abort(), 15000);
    setState({
      spec: null,
      error: ""
    });
    fetch("https://orchestration.flashnet.xyz/openapi.json", {
      signal: controller.signal,
      credentials: "omit"
    }).then(response => {
      if (!response.ok) throw new Error("The API specification is unavailable.");
      return response.json();
    }).then(spec => {
      helpers.createOperationModel(spec, path, method);
      if (active) setState({
        spec,
        error: ""
      });
    }).catch(error => {
      console.error("Could not render the official OpenAPI operation", error);
      if (active) setState({
        spec: null,
        error: "Could not load this endpoint from the official API specification."
      });
    }).finally(() => clearTimeout(timeout));
    return () => {
      active = false;
      clearTimeout(timeout);
      controller.abort();
    };
  }, [path, method, attempt]);
  if (state.error) return <div className="api-reference" role="alert">
        <p>{state.error}</p>
        <button onClick={() => setAttempt(attempt + 1)}>Retry</button>{" "}
        <a href="https://orchestration.flashnet.xyz/docs">
          Open official reference
        </a>
      </div>;
  if (!state.spec) return <div className="api-reference" role="status" aria-live="polite">
        Loading endpoint...
      </div>;
  return <div className="api-reference api-reference-layout">
      <div className="api-reference-main">
        {description({
    text: model.description
  })}
        {model.security?.length > 0 && !model.security.some(requirement => Object.keys(requirement).length === 0) && <p className="api-reference-auth">
              <a href="/api/authentication">Authentication</a> required by the
              published specification.
            </p>}
        <section id="parameters">
          <h2>Parameters</h2>
          {model.parameters.length > 0 ? schemaTable({
    fields: model.parameters,
    spec: state.spec,
    helpers
  }) : <p>No path, query, or header parameters.</p>}
          {model.requestBody && <>
              <h3>Request body</h3>
              {description({
    text: model.requestBody.description
  })}
              {schemaDetails({
    schema: model.requestBody.schema,
    spec: state.spec,
    helpers
  })}
            </>}
        </section>
        <section id="request">
          <h2>Request</h2>
          <RequestComponent model={model} CodeBlock={CodeBlock} />
        </section>
        <section id="response">
          <h2>Response</h2>
          {responseSection({
    model,
    spec: state.spec,
    helpers
  })}
        </section>
        <p className="api-reference-source">
          <a href="https://orchestration.flashnet.xyz/openapi.json">
            Official OpenAPI specification
          </a>
        </p>
      </div>
      <aside className="api-reference-toc">
        <nav aria-label="On this page">
          <span>On this page</span>
          <a href="#parameters">Parameters</a>
          <a href="#request">Request</a>
          <a href="#response">Response</a>
        </nav>
      </aside>
    </div>;
};

<div className="api-reference-page">
  <LiveApiPage path="/v1/orchestration/estimate" method="get" helpers={createApiHelpers()} RequestComponent={ApiRequest} CodeBlock={ApiCode} />
</div>


## OpenAPI

````yaml https://orchestration.flashnet.xyz/openapi.json GET /v1/orchestration/estimate
openapi: 3.1.0
info:
  title: Flashnet Orchestrator API
  version: 0.1.0
  description: >-
    Partner API for quotes, orders, standing deposits, webhooks, and affiliates.
    Operations marked x-excluded are omitted from the documentation navigation;
    internal, pay-link, SSE, and provider-integration routes are outside this
    registry.
servers:
  - url: https://orchestration.flashnet.xyz
security: []
tags:
  - name: Orchestration
    description: >-
      Routes, limits, estimates, quotes, orders, onramp, and ZeroConf decisions
      for one-off swaps.
  - name: Standing Deposit Addresses
    description: >-
      Permanent per-customer deposit addresses bound to one immutable conversion
      instruction.
  - name: Webhooks
    description: >-
      Registration of HTTPS endpoints for order status events and recovery
      events.
  - name: Affiliates
    description: Registered fee recipients, their accrued balances, and claims.
  - name: Accumulation Addresses
    description: >-
      Legacy reusable addresses that convert one source asset into Spark BTC or
      USDB.
  - name: Liquidations
    description: >-
      Legacy Bitcoin L1 deposit addresses that convert each output to a
      configured destination.
  - name: System
  - name: Explorer
  - name: Dashboard
  - name: Affiliate Dashboard
paths:
  /v1/orchestration/estimate:
    get:
      tags:
        - Orchestration
      summary: Estimate a swap
      description: Indicative price for a route, no state created. Public.
      operationId: getV1OrchestrationEstimate
      parameters:
        - schema:
            $ref: '#/components/schemas/Chain'
          required: true
          name: sourceChain
          in: query
        - schema:
            $ref: '#/components/schemas/AssetInput'
          required: true
          description: TON is a legacy input alias for ton:GRAM only; responses use GRAM.
          name: sourceAsset
          in: query
        - schema:
            $ref: '#/components/schemas/Chain'
          required: true
          name: destinationChain
          in: query
        - schema:
            $ref: '#/components/schemas/AssetInput'
          required: true
          description: TON is a legacy input alias for ton:GRAM only; responses use GRAM.
          name: destinationAsset
          in: query
        - schema:
            type: string
            pattern: ^[0-9]+$
          required: true
          name: amount
          in: query
        - schema:
            type: string
            enum:
              - exact_in
              - exact_out
          required: false
          name: amountMode
          in: query
        - schema:
            type: string
            enum:
              - variable
              - fixed
            description: >-
              Delivery mode; read fixed-delivery destinations from
              /v2/orchestration/routes.
          required: false
          description: >-
            Delivery mode; read fixed-delivery destinations from
            /v2/orchestration/routes.
          name: deliveryMode
          in: query
        - schema:
            type: string
            minLength: 1
            description: >-
              Destination recipient for validation and network costs; use the
              owner address for Solana tokens.
          required: false
          description: >-
            Destination recipient for validation and network costs; use the
            owner address for Solana tokens.
          name: recipientAddress
          in: query
        - schema:
            type: integer
            minimum: 0
            maximum: 1000
          required: false
          name: slippageBps
          in: query
      responses:
        '200':
          description: Quote estimate
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrchestrationEstimateResponse'
              examples:
                success:
                  summary: Estimate for 100000 sats
                  value:
                    amountMode: exact_in
                    estimatedOut: '99000000'
                    feeAmount: '500000'
                    roundingFeeAmount: '0'
                    totalFeeAmount: '500000'
                    feeBps: 50
                    feeAsset: USDC
                    route:
                      - BTC
                      - USDB
                      - USDC
                    source:
                      chain: bitcoin
                      asset: BTC
                      assetDisplayName: Bitcoin
                      assetDisplaySymbol: BTC
                      contractAddress: null
                      decimals: 8
                      chainId: null
                      chainDisplayName: Bitcoin
                      chainIcon: /btc.svg
                    destination:
                      chain: solana
                      asset: USDC
                      assetDisplayName: USDC
                      assetDisplaySymbol: USDC
                      contractAddress: EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v
                      decimals: 6
                      chainId: solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp
                      chainDisplayName: Solana
                      chainIcon: /chain-solana.svg
        '400':
          description: Invalid request or unsupported route
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Sanctioned address or cached screening block
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: >-
            Rate limited (`rate_limited`); see the [rate-limits
            guide](/api/rate-limits). Retry after Retry-After seconds when
            present (per-key limiter only), otherwise at X-RateLimit-Reset, an
            absolute epoch timestamp in milliseconds; both limiters also return
            X-RateLimit-Limit and X-RateLimit-Remaining.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      security:
        - {}
        - bearerAuth: []
components:
  schemas:
    Chain:
      type: string
      enum:
        - arbitrum
        - avalanche
        - base
        - bitcoin
        - bsc
        - ethereum
        - hedera
        - hypercore
        - hyperevm
        - lightning
        - litecoin
        - monad
        - monero
        - optimism
        - plasma
        - polygon
        - robinhood
        - sei
        - solana
        - spark
        - tempo
        - ton
        - tron
        - xrp
        - zcash
    AssetInput:
      anyOf:
        - $ref: '#/components/schemas/Asset'
        - type: string
          enum:
            - TON
      description: TON is a legacy input alias for ton:GRAM only; responses use GRAM.
    OrchestrationEstimateResponse:
      type: object
      properties:
        amountMode:
          type: string
          enum:
            - exact_in
            - exact_out
        targetAmountOut:
          type: string
        requiredAmountIn:
          type: string
        maxAcceptedAmountIn:
          type: string
        inputBufferBps:
          type: integer
        deliveryMode:
          type: string
          enum:
            - fixed
        estimatedOut:
          type: string
        feeAmount:
          type: string
        roundingFeeAmount:
          type: string
        feeBps:
          type: integer
        totalFeeAmount:
          type: string
        networkCostAmount:
          type: string
          description: Quoted network cost in smallest units of networkCostAsset.
        networkCostAsset:
          type: string
          description: Asset used to pay the quoted network cost.
        networkCostRequired:
          type: boolean
          description: Whether the quoted network cost must be paid.
        networkCosts:
          type: array
          items:
            $ref: '#/components/schemas/OrchestrationNetworkCost'
          description: Itemized network costs and quote-time assumptions.
        appFeeAmount:
          type: string
        appFeePlatformCutAmount:
          type: string
        appFees:
          type: array
          items:
            $ref: '#/components/schemas/OrchestrationAppFeeQuote'
        feeAsset:
          type: string
        feeAssetDetails:
          $ref: '#/components/schemas/PublicAssetDetails'
        feeAmountUsd:
          type: string
        totalFeeAmountUsd:
          type: string
        route:
          type: array
          items:
            type: string
        source:
          type: object
          properties:
            chain:
              $ref: '#/components/schemas/Chain'
            asset:
              type: string
            assetDisplayName:
              type: string
            assetDisplaySymbol:
              type: string
            contractAddress:
              type:
                - string
                - 'null'
            decimals:
              type: integer
            chainId:
              type:
                - string
                - 'null'
            chainDisplayName:
              type: string
            chainIcon:
              type:
                - string
                - 'null'
          required:
            - chain
            - asset
            - assetDisplayName
            - assetDisplaySymbol
            - contractAddress
            - decimals
            - chainId
            - chainDisplayName
            - chainIcon
          additionalProperties: false
        destination:
          type: object
          properties:
            chain:
              $ref: '#/components/schemas/Chain'
            asset:
              type: string
            assetDisplayName:
              type: string
            assetDisplaySymbol:
              type: string
            contractAddress:
              type:
                - string
                - 'null'
            decimals:
              type: integer
            chainId:
              type:
                - string
                - 'null'
            chainDisplayName:
              type: string
            chainIcon:
              type:
                - string
                - 'null'
          required:
            - chain
            - asset
            - assetDisplayName
            - assetDisplaySymbol
            - contractAddress
            - decimals
            - chainId
            - chainDisplayName
            - chainIcon
          additionalProperties: false
      required:
        - estimatedOut
        - feeAmount
        - feeBps
        - feeAsset
        - route
        - source
        - destination
      additionalProperties: false
    ErrorResponse:
      type: object
      properties:
        error:
          $ref: '#/components/schemas/ErrorDetail'
      required:
        - error
      additionalProperties: false
    Asset:
      type: string
      enum:
        - AAPL
        - AI
        - AMD
        - AMZN
        - BNB
        - BONER
        - BTC
        - CASHCAT
        - COIN
        - COST
        - DAI
        - DELTA
        - DJT
        - ETH
        - GLD
        - GME
        - GOOGL
        - GRAM
        - HIMS
        - HSUSD
        - HYPE
        - IF
        - LTC
        - META
        - MON
        - MSFT
        - MSTR
        - MU
        - NVDA
        - PIPEDOG
        - PLTR
        - POL
        - PONS
        - PYUSD
        - PathUSD
        - QQQ
        - RDDT
        - SHX
        - SKHY
        - SLV
        - SNDK
        - SOL
        - SPCX
        - SPY
        - STONKBROKER
        - TENDIES
        - TRX
        - TSLA
        - TSM
        - UP
        - USDB
        - USDC
        - USDC.e
        - USDG
        - USDT
        - USDe
        - USD₮0
        - USO
        - WBNB
        - WBTC
        - WEN
        - XMR
        - XPL
        - XRP
        - ZEC
        - cbBTC
        - tBTC
    OrchestrationNetworkCost:
      oneOf:
        - type: object
          properties:
            type:
              type: string
              enum:
                - solana_associated_token_account
            nativeAmount:
              type: string
            nativeAsset:
              type: string
              enum:
                - SOL
            amount:
              type: string
            asset:
              type: string
            assumption:
              type: string
              enum:
                - assumed_missing
                - observed_missing
                - observed_exists
          required:
            - type
            - nativeAmount
            - nativeAsset
            - amount
            - asset
            - assumption
          additionalProperties: false
        - type: object
          properties:
            type:
              type: string
              enum:
                - solana_mayan_order_accounts
            nativeAmount:
              type: string
            nativeAsset:
              type: string
              enum:
                - SOL
            amount:
              type: string
            asset:
              type: string
              enum:
                - USDC
          required:
            - type
            - nativeAmount
            - nativeAsset
            - amount
            - asset
          additionalProperties: false
    OrchestrationAppFeeQuote:
      type: object
      properties:
        affiliateId:
          type: string
        recipient:
          type: string
          minLength: 1
        feeBps:
          type: integer
          minimum: 1
          maximum: 9999
        amount:
          type: string
        platformCutAmount:
          type: string
        recipientAmount:
          type: string
      required:
        - recipient
        - feeBps
        - amount
        - platformCutAmount
        - recipientAmount
      additionalProperties: false
    PublicAssetDetails:
      type: object
      properties:
        chain:
          $ref: '#/components/schemas/Chain'
        asset:
          type: string
        assetDisplayName:
          type: string
        assetDisplaySymbol:
          type: string
        contractAddress:
          type:
            - string
            - 'null'
        decimals:
          type: integer
        chainId:
          type:
            - string
            - 'null'
        chainDisplayName:
          type: string
        chainIcon:
          type:
            - string
            - 'null'
      required:
        - chain
        - asset
        - assetDisplayName
        - assetDisplaySymbol
        - contractAddress
        - decimals
        - chainId
        - chainDisplayName
        - chainIcon
      additionalProperties: false
    ErrorDetail:
      type: object
      properties:
        code:
          type: string
        message:
          type: string
      required:
        - code
        - message
      additionalProperties: false
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: 'Partner API key in the form `Authorization: Bearer fn_...`.'

````