> ## 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.

# Create offramp quote

> Create an exact-in, variable quote to a Cash App username or Lightning address. Returns the normal quote response and deposit instructions; paying creates the order. The recipient is resolved at delivery, so an unavailable account or an amount outside its limits can fail after funding. Completion confirms Lightning delivery. Cash App USD conversion depends on the recipient setting and is not guaranteed.

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/offramp" method="post" helpers={createApiHelpers()} RequestComponent={ApiRequest} CodeBlock={ApiCode} />
</div>


## OpenAPI

````yaml https://orchestration.flashnet.xyz/openapi.json POST /v1/orchestration/offramp
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/offramp:
    post:
      tags:
        - Orchestration
      summary: Create Lightning offramp quote
      description: >-
        Create an exact-in, variable quote to a Cash App username or Lightning
        address. Returns the normal quote response and deposit instructions;
        paying creates the order. The recipient is resolved at delivery, so an
        unavailable account or an amount outside its limits can fail after
        funding. Completion confirms Lightning delivery. Cash App USD conversion
        depends on the recipient setting and is not guaranteed.
      operationId: postV1OrchestrationOfframp
      parameters:
        - schema:
            type: string
            minLength: 1
          required: true
          name: X-Idempotency-Key
          in: header
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/OrchestrationOfframpRequest'
            example:
              sourceChain: solana
              sourceAsset: USDC
              amount: '50000000'
              recipientAddress: $username
              refundAddress: YOUR_SOURCE_CHAIN_REFUND_ADDRESS
      responses:
        '200':
          description: Quote created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrchestrationQuoteResponse'
              examples:
                success:
                  summary: Lightning offramp deposit quote
                  value:
                    amountMode: exact_in
                    estimatedOut: '49500'
                    feeAmount: '250000'
                    roundingFeeAmount: '0'
                    totalFeeAmount: '250000'
                    feeBps: 50
                    feeAsset: USDC
                    route:
                      - USDC
                      - USDB
                      - BTC
                    quoteId: q_7e450ab4-935b-4f8d-a6c4-4987a3cd2831
                    depositAddress: 7EcDhSYGxXyscszYEp35KHN8vvw3svAuLKTzXwCFLtV
                    amountIn: '50000000'
                    expiresAt: '2026-09-12T12:02:00.000Z'
        '400':
          description: Invalid request or unsupported route
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '409':
          description: Idempotency conflict
          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'
        '500':
          description: Internal error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      security:
        - bearerAuth: []
components:
  schemas:
    OrchestrationOfframpRequest:
      type: object
      properties:
        sourceChain:
          $ref: '#/components/schemas/Chain'
        sourceAsset:
          $ref: '#/components/schemas/AssetInput'
        amount:
          type: string
          pattern: ^[0-9]+$
          description: Amount in smallest units of the source asset.
        recipientAddress:
          type: string
          minLength: 1
          description: >-
            Cash App username (username or $username), or Lightning address
            (username@domain). Cash App usernames resolve to username@cash.app.
            BOLT11 invoices and URLs are not accepted.
        refundChain:
          $ref: '#/components/schemas/Chain'
        refundAddress:
          type: string
          minLength: 1
          description: >-
            Required refund address on the source chain, or the supplied
            refundChain.
        slippageBps:
          type: integer
          minimum: 0
          maximum: 1000
          description: Slippage tolerance in basis points, subject to the route minimum.
        appFees:
          type: array
          items:
            $ref: '#/components/schemas/OrchestrationAppFeeRequest'
          minItems: 1
          maxItems: 16
          description: Inline app fees, requiring a server key or dashboard session.
        affiliateId:
          type: string
          description: >-
            Registered affiliate ID for accrued fees, also accepted from client
            keys.
        affiliateIds:
          type: array
          items:
            $ref: '#/components/schemas/OrchestrationAffiliateIdEntry'
          minItems: 1
          maxItems: 16
          description: >-
            Registered affiliate IDs or fee overrides; mutually exclusive with
            appFees, with overrides requiring a server key or dashboard session.
      required:
        - sourceChain
        - sourceAsset
        - amount
        - recipientAddress
        - refundAddress
      additionalProperties: false
      description: Exact-in variable Lightning payout. Unknown fields are rejected.
      allOf:
        - not:
            allOf:
              - properties:
                  sourceAsset:
                    const: TON
                required:
                  - sourceAsset
              - properties:
                  sourceChain:
                    not:
                      const: ton
                required:
                  - sourceChain
    OrchestrationQuoteResponse:
      type: object
      properties:
        quoteId:
          type: string
        reviewedAssets:
          type: array
          items:
            $ref: '#/components/schemas/ReviewedAssetIdentity'
          minItems: 1
          maxItems: 32
          description: >-
            Exact immutable reviewed token identities frozen by the native
            quote. Omitted for legacy or invalid snapshots; caller metadata
            cannot set these pins.
        depositAddress:
          type: string
        depositMemo:
          type: string
          description: Memo or tag required with the deposit when present.
        lightningReceiveRequestId:
          type: string
        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
        priceLockMode:
          type: string
          enum:
            - strict_requote
            - approval_required
          description: Action required when the locked price can no longer be honored.
        lockedMinAmountOut:
          type: string
          description: Minimum locked destination amount in smallest units.
        amountIn:
          type: string
        estimatedOut:
          type: string
        feeAmount:
          type: string
        roundingFeeAmount:
          type: string
        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.
        sweepFeeAmount:
          type: string
        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
        feeBps:
          type: integer
        route:
          type: array
          items:
            type: string
        expiresAt:
          type: string
        readToken:
          type: string
          description: >-
            Client-key read token for this quote and its order, including
            private ZeroConf outcomes.
      required:
        - quoteId
        - depositAddress
        - amountIn
        - estimatedOut
        - feeAmount
        - totalFeeAmount
        - feeAsset
        - feeBps
        - route
        - expiresAt
      additionalProperties: false
    ErrorResponse:
      type: object
      properties:
        error:
          $ref: '#/components/schemas/ErrorDetail'
      required:
        - error
      additionalProperties: false
    Chain:
      type: string
      enum:
        - arbitrum
        - arc
        - 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
        - $ref: '#/components/schemas/RegistryAssetKey'
      description: >-
        A canonical public asset symbol or a registry asset routing key. TON is
        a legacy input alias for ton:GRAM only; responses use GRAM.
    OrchestrationAppFeeRequest:
      type: object
      properties:
        recipient:
          type: string
          minLength: 1
          description: Fee recipient address; sanctioned addresses are rejected.
        fee:
          type: integer
          minimum: 1
          maximum: 9999
      required:
        - recipient
        - fee
      description: Unknown top-level fields are ignored rather than rejected.
    OrchestrationAffiliateIdEntry:
      anyOf:
        - type: string
          minLength: 1
          description: Registered affiliate id. Uses the profile's static feeBps.
        - type: object
          properties:
            affiliateId:
              type: string
              minLength: 1
            feeBps:
              type: integer
              minimum: 1
              maximum: 9999
              description: >-
                Fee override for this quote only; the stored affiliate profile
                is unchanged.
          required:
            - affiliateId
            - feeBps
          additionalProperties: false
      description: Registered affiliate ID or { affiliateId, feeBps } override.
    ReviewedAssetIdentity:
      type: object
      properties:
        version:
          type: number
          enum:
            - 1
        catalogVersion:
          type: string
          pattern: ^sha256:[0-9a-f]{64}$
        chain:
          type: string
          enum:
            - solana
            - ethereum
            - bsc
        asset:
          type: string
          minLength: 1
          maxLength: 32
        address:
          type: string
          minLength: 32
          maxLength: 44
        decimals:
          type: integer
          minimum: 0
          maximum: 255
        tokenProgram:
          type: string
          enum:
            - erc20
            - spl
            - token-2022
        mechanic:
          type: string
          enum:
            - standard
            - scaled-ui
            - rebasing
            - accumulating
        mechanicHash:
          type: string
          pattern: ^sha256:[0-9a-f]{64}$
      required:
        - version
        - catalogVersion
        - chain
        - asset
        - address
        - decimals
        - tokenProgram
        - mechanic
        - mechanicHash
      additionalProperties: false
    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
        tokenProgram:
          type: string
          enum:
            - erc20
            - spl
            - token-2022
        reviewedIdentity:
          $ref: '#/components/schemas/ReviewedAssetIdentity'
        chainId:
          type:
            - string
            - 'null'
        chainDisplayName:
          type: string
        chainIcon:
          type:
            - string
            - 'null'
        assetIcon:
          type: string
          format: uri
          description: >-
            Absolute https logo URL served from the asset registry. Absent when
            the asset has no registry logo; clients keep their bundled artwork.
      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
    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
    RegistryAssetKey:
      type: string
      minLength: 1
      maxLength: 96
      pattern: ^[A-Za-z0-9][A-Za-z0-9._-]*$
      description: >-
        Routing key of an asset served from the shared asset registry, as
        advertised by GET /v2/orchestration/routes (for example asset_<sha256>).
        Accepted only while the registry serves the asset; any other value fails
        validation.
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: 'Partner API key in the form `Authorization: Bearer fn_...`.'

````