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

# Send a transaction

> Execute target-chain calls with funds sourced from one or more chains.

export const CSS = ".rhinestone-1auth-demo .demo-mint-banner {\n  background-color: light-dark(#fef3c7, #422006);\n  border-color: light-dark(#fde68a, #713f12);\n}\n.rhinestone-1auth-demo .oa-demo {\n  margin: 1.5rem 0;\n  border: 1px solid #202127;\n  border-radius: 16px;\n  background: #0b0c0e;\n  overflow: hidden;\n}\n.rhinestone-1auth-demo .oa-demo-head {\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  gap: 0.75rem;\n  min-height: 39px;\n  padding: 0.625rem 1rem;\n  border-bottom: 1px solid #191a1e;\n}\n.rhinestone-1auth-demo .oa-demo-title {\n  font-size: 0.8125rem;\n  font-weight: 500;\n  letter-spacing: -0.01em;\n  color: #e4e4e9;\n}\n.rhinestone-1auth-demo .oa-demo-status {\n  display: flex;\n  align-items: center;\n  gap: 0.4375rem;\n  flex: 0 0 auto;\n  font-size: 0.75rem;\n  color: #5e5e68;\n}\n.rhinestone-1auth-demo .oa-demo-dot {\n  width: 6px;\n  height: 6px;\n  border-radius: 999px;\n  background: #3f3f48;\n}\n.rhinestone-1auth-demo .oa-demo-dot[data-state=\"on\"] {\n  background: #22c55e;\n  box-shadow: 0 0 8px rgba(34, 197, 94, 0.5);\n}\n.rhinestone-1auth-demo .oa-demo-body {\n  display: flex;\n  flex-direction: column;\n  gap: 0.75rem;\n  padding: 1rem;\n}\n.rhinestone-1auth-demo .demo-preview {\n  display: contents;\n}\n.rhinestone-1auth-demo .demo-preview-header {\n  display: none;\n}\n.rhinestone-1auth-demo .demo-preview-content {\n  display: flex;\n  flex-wrap: wrap;\n  align-items: center;\n  gap: 0.75rem;\n}\n.rhinestone-1auth-demo .oa-demo-body > * > [style] {\n  margin: 0 !important;\n}\n.rhinestone-1auth-demo .oa-demo-body > * > div[style]:not([class]) {\n  padding: 0 !important;\n}\n.rhinestone-1auth-demo .oa-demo-body [style] {\n  text-align: left !important;\n}\n.rhinestone-1auth-demo .oa-demo-body [style*=\"justify-content: center\"] {\n  justify-content: flex-start !important;\n}\n.rhinestone-1auth-demo .demo-preview-content > div[style]:not([class]) {\n  padding: 0.75rem 0.875rem !important;\n  border-radius: 10px !important;\n  background: #14151a !important;\n  color: #8a8a94 !important;\n  font-size: 0.8125rem !important;\n}\n.rhinestone-1auth-demo .demo-button, .rhinestone-1auth-demo .demo-preview-button {\n  display: inline-flex;\n  align-items: center;\n  justify-content: center;\n  gap: 0.375rem;\n  height: 2.25rem;\n  padding: 0 0.875rem;\n  border: none;\n  border-radius: 10px;\n  background: #4f41ef;\n  color: #ffffff;\n  font-size: 0.875rem;\n  font-weight: 500;\n  cursor: pointer;\n  transition:\n    background 0.15s ease,\n    opacity 0.15s ease;\n}\n.rhinestone-1auth-demo .demo-button:hover:not(:disabled), .rhinestone-1auth-demo .demo-preview-button:hover:not(:disabled) {\n  background: #6355f5;\n}\n.rhinestone-1auth-demo .demo-button:disabled, .rhinestone-1auth-demo .demo-preview-button:disabled {\n  opacity: 0.6;\n  cursor: default;\n}\n.rhinestone-1auth-demo .demo-button-secondary {\n  display: inline-flex;\n  align-items: center;\n  justify-content: center;\n  height: 2.25rem;\n  padding: 0 0.875rem;\n  border: 1px solid #2e2e36;\n  border-radius: 10px;\n  background: transparent;\n  color: #c8c8d0;\n  font-size: 0.875rem;\n  font-weight: 500;\n  cursor: pointer;\n  transition:\n    border-color 0.15s ease,\n    color 0.15s ease;\n}\n.rhinestone-1auth-demo .demo-button-secondary:hover:not(:disabled) {\n  border-color: #45454f;\n  color: #f2f2f5;\n}\n.rhinestone-1auth-demo .oa-demo-body > * > .demo-button, .rhinestone-1auth-demo .oa-demo-body > * > .demo-button-secondary {\n  align-self: flex-start;\n}\n.rhinestone-1auth-demo .oa-demo-body input[type=\"checkbox\"] {\n  accent-color: #4f41ef;\n}\n.rhinestone-1auth-demo .demo-result {\n  padding: 0.75rem 0.875rem;\n  border-radius: 10px;\n  background: #14151a;\n}\n.rhinestone-1auth-demo .demo-result-label {\n  font-size: 0.6875rem;\n  font-weight: 500;\n  letter-spacing: 0.08em;\n  text-transform: uppercase;\n  color: #6e6e78;\n}\n.rhinestone-1auth-demo .demo-result-value {\n  margin-top: 0.1875rem;\n  font-family: paperMono, ui-monospace, SFMono-Regular, Menlo, monospace;\n  font-size: 0.8125rem;\n  line-height: 1.5;\n  color: #e4e4e9;\n  overflow-wrap: anywhere;\n}\n.rhinestone-1auth-demo .demo-result-success .demo-result-label {\n  color: #4ade80;\n}\n.rhinestone-1auth-demo .demo-result-error .demo-result-label {\n  color: #f87171;\n}\n.rhinestone-1auth-demo .demo-result-error .demo-result-value {\n  color: #fca5a5;\n}\n.rhinestone-1auth-demo .demo-error {\n  margin: 0;\n  font-size: 0.8125rem;\n  color: #f87171;\n  overflow-wrap: anywhere;\n}\n.rhinestone-1auth-demo .oa-demo-skeleton {\n  display: block;\n  width: 7rem;\n  height: 2.25rem;\n  border-radius: 10px;\n  background: #16171c;\n  animation: rhinestone-1auth-demo-pulse 1.6s ease-in-out infinite;\n}\n@keyframes rhinestone-1auth-demo-pulse {\n  50% {\n    opacity: 0.45;\n  }\n}";

export const SOURCE_COMMIT = "e06ebe8add704e95f679eaddc38fd7ea88cb3de8";

export const SDK_VERSION = "0.10.1";

export const VIEM_VERSION = "2.55.0";

export const STORAGE_KEY = "rhinestone-docs-1auth-account";

export const PROD_BACKENDS = {
  auth: "https://passkey.1auth.app",
  sponsorship: "https://docs.1auth.app/api/sponsorship"
};

export const DEV_BACKENDS = {
  auth: "https://passkey.passkey-test.app",
  sponsorship: "https://docs.passkey-test.app/api/sponsorship"
};

export const PROD_DOCS_HOST = "docs.rhinestone.dev";

export const backends = () => {
  const host = typeof window === "undefined" ? "" : window.location.hostname;
  return host === PROD_DOCS_HOST ? PROD_BACKENDS : DEV_BACKENDS;
};

export const BACKEND_NOTE = "Only the production docs host talks to the production Rhinestone deployment. " + "Every other host — a Mintlify preview, a tunnel, localhost — uses dev, so " + "an unrecognised preview pattern fails towards dev rather than creating " + "passkey state against production.";

export const CDN = spec => "https://esm.sh/" + spec + (spec.startsWith("@rhinestone/1auth@") ? "?deps=viem@" + VIEM_VERSION + "&external=react" : "");

export const shareReact = () => {
  if (window.__OA_SHARED_REACT__) return;
  if (typeof HTMLScriptElement.supports !== "function" || !HTMLScriptElement.supports("importmap")) {
    throw new Error("This demo requires a browser with import-map support.");
  }
  window.__OA_REACT__ = React;
  const reserved = ["default", "import", "export", "class", "function", "const", "let", "var", "new", "delete", "typeof", "void", "in", "of", "do", "if", "else", "for", "while", "switch", "case", "break", "continue", "return", "this", "super", "throw", "try", "catch", "finally", "yield", "await", "enum", "null", "true", "false", "with", "debugger", "instanceof", "extends", "static"];
  const names = Object.keys(React).filter(name => (/^[A-Za-z_$][A-Za-z0-9_$]*$/).test(name) && !reserved.includes(name));
  const source = ["const R = globalThis.__OA_REACT__; export default R;", ...names.map(name => "export const " + name + " = R." + name + ";")].join(" ");
  const jsx = ["const R = globalThis.__OA_REACT__; export const Fragment = R.Fragment;", "export const jsx = (type, props, key) => R.createElement(type, key == null ? props : { ...props, key });", "export const jsxs = jsx; export const jsxDEV = jsx;"].join(" ");
  const dataUrl = value => "data:text/javascript," + encodeURIComponent(value);
  const script = document.createElement("script");
  script.type = "importmap";
  script.textContent = JSON.stringify({
    imports: {
      react: dataUrl(source),
      "react/jsx-runtime": dataUrl(jsx),
      "react/jsx-dev-runtime": dataUrl(jsx)
    }
  });
  document.head.appendChild(script);
  window.__OA_SHARED_REACT__ = true;
};

export const MODULE_SPECS = {
  sdk: () => CDN("@rhinestone/1auth@" + SDK_VERSION),
  viem: () => CDN("viem@" + VIEM_VERSION)
};

export const importModule = url => new Promise((resolve, reject) => {
  const key = "__oa_" + Math.random().toString(36).slice(2);
  window[key] = {
    resolve,
    reject
  };
  const script = document.createElement("script");
  script.type = "module";
  script.textContent = "import(" + JSON.stringify(url) + ").then(m => window[" + JSON.stringify(key) + "].resolve(m))" + ".catch(e => window[" + JSON.stringify(key) + "].reject(new Error(String(e))));";
  script.onerror = () => reject(new Error("failed to load " + url));
  document.head.appendChild(script);
  script.remove();
});

export const importModuleWithRetry = async url => {
  try {
    return await importModule(url);
  } catch (first) {
    await new Promise(r => setTimeout(r, 500));
    return importModule(url);
  }
};

export const loadDeps = async () => {
  shareReact();
  const specs = Object.entries(MODULE_SPECS).map(([name, spec]) => [name, spec()]);
  const cacheKey = "__OA_DEPS__" + specs.map(([, url]) => url).join("|");
  if (window[cacheKey]) return window[cacheKey];
  const loaded = await Promise.all(specs.map(([, url]) => importModuleWithRetry(url)));
  const deps = {
    React
  };
  specs.forEach(([name], i) => {
    deps[name] = loaded[i];
  });
  deps.motion = motionShim();
  window[cacheKey] = deps;
  return deps;
};

export const unreachable = call => "Sponsorship " + call + " never reached " + backends().sponsorship + ". The browser hides why: a rejected origin, a failed preflight and a network" + " error all look identical here. The failing request is in the console.";

export const sponsorship = {
  accessToken: async () => {
    let res;
    try {
      res = await fetch(backends().sponsorship + "/access-token", {
        method: "GET",
        credentials: "include"
      });
    } catch (e) {
      throw new Error(unreachable("access token"));
    }
    if (!res.ok) throw new Error("Sponsorship access token failed (" + res.status + ")");
    return (await res.json()).token;
  },
  getExtensionToken: async intentOp => {
    let res;
    try {
      res = await fetch(backends().sponsorship + "/extension-token", {
        method: "POST",
        credentials: "include",
        headers: {
          "Content-Type": "application/json"
        },
        body: JSON.stringify({
          intentOp
        })
      });
    } catch (e) {
      throw new Error(unreachable("extension token"));
    }
    if (!res.ok) throw new Error("Sponsorship extension token failed (" + res.status + ")");
    return (await res.json()).token;
  }
};

export const motionShim = () => {
  const passthrough = Tag => React.forwardRef((props, ref) => {
    const rest = Object.fromEntries(Object.entries(props).filter(([k]) => !["initial", "animate", "exit", "transition", "variants", "whileHover", "whileTap", "layout", "layoutId"].includes(k)));
    return React.createElement(Tag, {
      ...rest,
      ref
    });
  });
  const cache = {};
  return {
    motion: new Proxy({}, {
      get: (_, tag) => {
        if (!cache[tag]) cache[tag] = passthrough(tag);
        return cache[tag];
      }
    }),
    AnimatePresence: ({children}) => React.createElement(React.Fragment, null, children),
    useReducedMotion: () => true
  };
};

export const AuthContext = React.createContext(null);

export const useAuthContext = () => React.useContext(AuthContext);

export const buildModules = deps => {
  const mods = {};
  mods.authctx = (() => {
    const DOCS_APP_ORIGIN_STORAGE_KEY = STORAGE_KEY;
    const useAuth = () => useAuthContext();
    return {
      DOCS_APP_ORIGIN_STORAGE_KEY,
      useAuth,
      clearDocsSession: () => {}
    };
  })();
  mods.constants = (() => {
    const DOCS_APP_ORIGIN_CLIENT_ID = "docs-app-origin";
    function docsAppOriginWebAuthn() {
      if (typeof window === "undefined" || window.location.protocol !== "https:") {
        return {
          mode: "app_origin"
        };
      }
      return {
        mode: "app_origin",
        rpId: window.location.hostname
      };
    }
    const DOCS_EXPERIMENTAL_CLEAR_SIGNING = true;
    const APP_ORIGIN_DEMO_CAPABILITIES = {
      payButton: true,
      eip1193Transactions: true,
      sendCalls: true,
      batchCalls: true,
      messageSigning: true,
      typedDataSigning: true,
      batchIntents: true,
      smartSessions: true,
      walletConnection: true,
      recovery: true
    };
    const DOCS_DIALOG_THEME = {
      mode: "dark",
      accent: "#ffffff",
      backdrop: {
        color: "#52525c",
        opacity: 0.5,
        blur: 12
      }
    };
    const MOCK_USD_ADDRESS = "0x2f6fdE5E2AeAB6335d8f978B4d8B2a9c1129AcFb";
    const RECIPIENT_ADDRESS = "0x180b791BD181DF1773E4e33cb0374b258936d186";
    const MOCK_RWA_ADDRESS = "0x5948C7E284174f6Df0f2505fb3CBFbd685154323";
    const MOCK_SWAP_ADDRESS = "0xf2DFDC35d46e62F6D026afa36Cc6e941174B67f1";
    const MOCK_NFT_V2_ADDRESS = "0x99CCb273351Cf13713F7Bf5A0716d7C2a3DD4712";
    const MOCK_NFT_LUIGI_ID = 1n;
    const NVDA_ICON_SVG = `<svg width="250" height="250" viewBox="0 0 250 250" fill="none" xmlns="http://www.w3.org/2000/svg"><rect width="250" height="250" fill="#76B900"/><path d="M99.5748 98.4439V86.5224C100.752 86.4488 101.93 86.3752 103.107 86.3752C135.781 85.345 157.195 114.486 157.195 114.486C157.195 114.486 134.088 146.571 109.289 146.571C105.977 146.571 102.739 146.056 99.6484 145.026V108.82C112.379 110.365 114.955 115.958 122.535 128.689L139.534 114.413C139.534 114.413 127.097 98.1495 106.198 98.1495C103.99 98.0759 101.782 98.2231 99.5748 98.4439ZM99.5748 59V76.8086L103.107 76.5878C148.512 75.0425 178.168 113.824 178.168 113.824C178.168 113.824 144.17 155.181 108.773 155.181C105.683 155.181 102.666 154.887 99.6484 154.372V165.41C102.15 165.705 104.726 165.925 107.228 165.925C140.196 165.925 164.039 149.073 187.146 129.204C190.973 132.295 206.647 139.727 209.885 142.965C187.956 161.363 136.811 176.154 107.817 176.154C105.02 176.154 102.371 176.007 99.722 175.713V191.24H224.971V59L99.5748 59ZM99.5748 145.026V154.445C69.1088 149 60.646 117.283 60.646 117.283C60.646 117.283 75.2903 101.093 99.5748 98.4439V108.746H99.5012C86.7702 107.201 76.7621 119.122 76.7621 119.122C76.7621 119.122 82.4285 139.212 99.5748 145.026ZM45.4866 115.958C45.4866 115.958 63.516 89.3188 99.6484 86.5224V76.8086C59.6158 80.0465 25.0288 113.898 25.0288 113.898C25.0288 113.898 44.6036 170.561 99.5748 175.713V165.41C59.2478 160.406 45.4866 115.958 45.4866 115.958Z" fill="white"/></svg>`;
    const NVDA_ICON_DATA_URL = `data:image/svg+xml;utf8,${encodeURIComponent(NVDA_ICON_SVG)}`;
    const LUIGI_ICON_SVG = `<svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" fill="none" viewBox="0 0 28 28"><rect width="28" height="28" fill="#32a742" rx="4"/><path fill="#101110" d="M13 5.4h.9a7 7 0 0 1 4 1.1q1.3 1 2 2.4l.3.5.5-.6L22 7.5q1-.9 2.2-1.3h.5l.4.3v.8a9 9 0 0 1-2.5 4.4l-.6.6q.6.7.2 1.7t-1.4 1.6l.2.8q.4 2-.5 3.6l-.4.5a8 8 0 0 1-5.7 2.1h-1l-1.8-.3-.5-.2-.9-.3q-1-.4-1.8-1.2-.6-.6-1-1.4a5 5 0 0 1 0-3.6q-.9-.3-1.3-.9-.5-.9-.1-2v-.1L3.8 10q-.9-1.3-1-2.8 0-.5.3-.6C4 6.6 6 8 6.8 8.8l.9.9q.4-1 1.1-2c1.2-1.5 2.3-2 4.2-2.3"/><path fill="#f7c30f" d="M8.5 14q1.1.7 2.4.5c1-.2 2.3-1 3.3-.9l1.6.4.3.1.6.2q1.6.4 2.8-.5l.2.2c.8 1.3 1.5 3.3 1 4.8l-.5 1c0 .2-.7.8-.9.9l-.3.2-.3.2q-.6.5-1.3.6a9 9 0 0 1-7.6-.4l-.5-.4-.6-.4-.6-.7-.4-.7c-.5-.8-.4-2.4-.1-3.2q.1-.8.6-1.4l.1-.2z"/><path fill="#fb9410" d="M17.7 20.8q0 .3.4.3h.6q-.6.5-1.3.6a9 9 0 0 1-7.6-.4q.5 0 .9-.3 3.4.9 6.7 0z"/><path fill="#e0051c" d="M17.6 20.2c.2-1.5 2.6-3 2.8-1.5h.3l-.5 1.1c0 .2-.7.8-.9.9l-.3.2-.3.2H18q-.3 0-.4-.3z"/><path fill="#870c0d" d="M17.6 20.2c.2-1.5 2.6-3 2.8-1.5h.3l-.5 1.1c0 .2-.7.8-.9.9l.4-.5q.6-.7.6-1.5l-.3-.1h-.8q-.6.4-1 1l-.4.4h-.1z"/><path fill="#fb99a0" d="m17.8 20 .3-.7c.4-.6 1.3-1.4 2-1l.2.4-.3-.1h-.8q-.6.4-1 1z"/><path fill="#fac550" d="M20.4 18.7h.3l-.5 1.1v-.2q.3-.5.2-.9"/><path fill="#870c0d" d="m17.6 20.2.1-.1q-.1.6.4.9h.6l.3-.1-.3.2H18q-.3 0-.4-.3z"/><path fill="#e0051c" d="M7.9 19q0-.7.7-.7c1 0 2.5 1.7 2 2.7q-.2.4-.8.3l-.5-.4-.6-.4-.6-.7-.4-.7z"/><path fill="#870c0d" d="M7.9 19q0-.7.7-.7c1 0 2.5 1.7 2 2.7q-.2.4-.8.3l-.5-.4c.4 0 .4.3 1 .2l.3-.3q0-.5-.2-.9l-.5-.6Q9 18.4 8 19l.2.9-.1-.2v.2l-.4-.7z"/><path fill="#fb99a0" d="M8 18.9q.2-.6.8-.5a3 3 0 0 1 1.7 1.5l-.6-.6Q9 18.4 8 19"/><path fill="#fac550" d="M7.7 19h.2q0 .4.2.6v.2z"/><path fill="#831218" d="m8 19.6.2.2q.4.3.5.7l-.6-.7z"/><path fill="#101110" d="M17.4 14.9h.7q1.2.8.6 2v.1q-.4.5-1 .6-.8-.2-1-.8-.3-.6 0-1.2t.7-.7"/><path fill="#f2f0ee" d="M17.3 15.2q.3 0 .5.2v.3q0 .3-.3.3-.4 0-.5-.2-.2-.5.3-.6"/><path fill="#fb9410" d="M8.5 14q1.1.7 2.4.5c1-.2 2.3-1 3.3-.9l1.6.4.3.1.6.2q1.6.4 2.8-.5l.2.2-.6.5-.7.3H18v.1h-.6c0-.2-.8-.2-1-.2q-1.3-.4-2.7-.6l-1.3.3c-1.8.5-2.3.7-4 0l-.1-.1z"/><path fill="#fac550" d="m8.3 14.3-.1.2h-.1z"/><path fill="#101110" d="m14.1 17.6.3.1a5 5 0 0 0 2.8.3l.6-.1.1.2c.1 1.7-1.6 2.1-3 1.8l-.8-.3-.4.1-.7.3-1.2-.1c-.7-.2-1.6-.9-1.3-1.7q0-.2.3 0 1.7.4 3.3-.6M10.2 15c1.6-.2 1.9 2.3.4 2.7l-.6-.1c-1.1-.5-1-2.4.2-2.6"/><path fill="#f2f0ee" d="M10.6 15.3q.3 0 .5.2v.4q0 .2-.3.2h-.2l-.3-.2q-.2-.5.3-.6"/><path fill="#101110" d="m14 17.2.3.1v.2q-.5 0-.4-.3"/><path fill="#008a4d" d="M8.4 10.7 8 10c-.1-.2.3-.9.4-1A6 6 0 0 1 11 6.3c1.5-.7 3.5-.8 5-.2q2.2.7 3.3 2.6.4.4.6 1l-.2.3-.5.8-.7 1.2-.7-.4 1 1.2-.6-.5a7 7 0 0 0-2.3-1q.7-1 .5-2t-1-1.5a3 3 0 0 0-4 .7c-.4.8-.4 2 .2 2.7l.2.2-1.5.6-.8.5v-.2l.3-.4.1-.3-.2.1-.4.4V12z"/><path fill="#80c491" d="M8.4 10.7 8 10c-.1-.2.3-.9.4-1A6 6 0 0 1 11 6.3c1.5-.7 3.5-.8 5-.2q2.2.7 3.3 2.6.4.4.6 1l-.2.3v-.2l-.7-.9q-.7-1-1.7-2a6 6 0 0 0-2.8-1 6 6 0 0 0-4.6 2c-.5.5-1.3 2-1.6 2.8"/><path fill="#064634" d="m19.7 9.8.1.2-.5.8-.7 1.2q-.4-.4-.7-.4l1 1.2-.6-.5-1-.5.1-.4q.3-.3 1-.4.9-.3 1.3-1.2"/><path fill="#80c491" d="M10 11.6h.3l-.4.3zm-.7.4.5-.3z"/><path fill="#008a4d" d="M9.6 12.9a7 7 0 0 1 6.8-1.2l1 .4a7 7 0 0 1 2 1.5c-.8.7-2 .5-2.8.3q-.6 0-1-.3c-1.4-.4-1.7-.5-3 0l-1.8.6a3 3 0 0 1-2.2-.5z"/><path fill="#064634" d="M17.3 12.1a7 7 0 0 1 2 1.5c-.7.7-1.8.5-2.7.3.8-.6 1-.7.7-1.8"/><path fill="#80c491" d="M9.6 12.9c.1.5-.1.5.4 1s2.3-.4 2.5-.3q-.8.4-1.7.6a3 3 0 0 1-2.2-.5z"/><path fill="#f2f0ee" d="M13.8 7.6q1 0 1.8.6 1.5 1.4.1 3a9 9 0 0 0-3.6.1q-.6-.5-.7-1.3.1-2.3 2.4-2.4"/><path fill="#008a4d" d="m13.6 8-.1 2h1.6v.8h-2.3V8z"/><path fill="#fb9410" d="m18.8 12.3.3-.7q1-1.7 2.4-3.2l.7-.7.2.3 1 2.4-3 2.9-.6.4-.8-1.3z"/><path fill="#f7c30f" d="m18.8 12.3.3-.7q1-1.7 2.4-3.2l.7-.7.2.3.3.8-.8.5-.7.5-1 1-.9.8z"/><path fill="#fbeca3" d="m18.8 12.3.3-.7q1-1.7 2.4-3.2l.7-.7.2.3-.3.3a14 14 0 0 0-2.5 2.9l-.3.4z"/><path fill="#fb9410" d="M5.4 8.1q2 1.5 3.3 3.6l.5.7-.1.2q-.6.5-.8 1.2l-.8-.5q-1.6-1.1-3-2.7l.7-2.1z"/><path fill="#f7c30f" d="M5.4 8.1q2 1.5 3.3 3.6l.5.7-.1.2H9l-.6-.8-1.5-1.6-.7-.5-1-.7H5z"/><path fill="#fbeca3" d="M5.4 8.1a14 14 0 0 1 3.4 3.7h-.1C8.2 11 6 8.9 5.3 8.5z"/><path fill="#fac550" d="m8.7 11.7.5.7-.1.2v-.3z"/><path fill="#064634" d="M21.7 12.5c.7 1.1 0 2.2-1 2.8l-.2-.3-.5-1zm-15.4.3 1.2.9.6.4-.5.9-.2.3q-.8-.3-1.2-1.1-.2-.8 0-1.4"/><path fill="#f2f0ee" d="M24.3 6.5h.4l-.5.4-1.5.9h-.2l-.1-.2a5 5 0 0 1 1.9-1.1M3.2 7a6 6 0 0 1 2 1v.2H5l-.8-.4L3 7.3z"/><path fill="#1f5e4c" d="m9.3 12.7.3-.4v.1z"/></svg>`;
    const LUIGI_ICON_DATA_URL = `data:image/svg+xml;utf8,${encodeURIComponent(LUIGI_ICON_SVG)}`;
    const MUSD_ICON_SVG = `<svg width="250" height="250" viewBox="0 0 250 250" fill="none" xmlns="http://www.w3.org/2000/svg"><g clip-path="url(#clip0_4758_159829)"><g filter="url(#filter0_i_4758_159829)"><path d="M124.999 249.149C193.565 249.149 249.149 193.565 249.149 124.999C249.149 56.4325 193.565 0.848633 124.999 0.848633C56.4325 0.848633 0.848633 56.4325 0.848633 124.999C0.848633 193.565 56.4325 249.149 124.999 249.149Z" fill="white"/></g><path d="M101.7 211.35C101.7 214.25 99.3499 215.9 96.6499 215.05C59.0499 203 31.8999 167.85 31.8999 126.25C31.8999 84.7497 59.0499 49.5497 96.6999 37.4997C99.4999 36.6497 101.75 38.2997 101.75 41.1997V48.4497C101.75 50.3997 100.3 52.5997 98.4499 53.2997C68.6499 64.2497 47.4499 92.8497 47.4499 126.25C47.4499 159.7 68.6999 188.25 98.4499 199.1C100.3 199.8 101.75 202 101.75 203.95V211.35H101.7Z" fill="black"/><path d="M132.752 184.451C132.752 186.601 131.002 188.351 128.852 188.351H121.102C118.952 188.351 117.202 186.601 117.202 184.451V172.251C100.252 169.901 92.0016 160.501 89.7516 147.501C89.3516 145.251 91.1016 143.351 93.3516 143.351H102.202C104.052 143.351 105.602 144.701 106.002 146.451C107.652 154.101 112.102 160.051 125.702 160.051C135.702 160.051 142.852 154.401 142.852 146.101C142.852 137.751 138.702 134.551 123.952 132.151C102.202 129.251 91.9516 122.651 91.9516 105.651C91.9516 92.5512 101.952 82.2512 117.252 80.1512V68.1012C117.252 65.9512 119.002 64.2012 121.152 64.2012H128.902C131.052 64.2012 132.802 65.9512 132.802 68.1012V80.4012C145.302 82.6512 153.252 89.7012 155.902 101.551C156.402 103.801 154.652 105.801 152.302 105.801H144.152C142.402 105.801 140.952 104.651 140.452 103.001C138.202 95.5512 132.902 92.2512 123.552 92.2512C113.252 92.2512 107.952 97.2012 107.952 104.201C107.952 111.551 110.952 115.251 126.752 117.501C148.102 120.401 159.152 126.501 159.152 144.651C159.152 158.401 148.852 169.601 132.852 172.101V184.501H132.752V184.451Z" fill="black"/><path d="M153.3 214.997C150.5 215.847 148.25 214.197 148.25 211.297V204.047C148.25 201.897 149.5 199.897 151.55 199.197C181.25 188.347 202.55 159.697 202.55 126.347C202.55 92.897 181.3 64.347 151.55 53.497C149.7 52.797 148.25 50.597 148.25 48.647V41.397C148.25 38.497 150.6 36.847 153.3 37.697C190.95 49.547 218.1 84.747 218.1 126.247C218.1 167.847 190.95 202.997 153.3 214.997Z" fill="black"/></g><defs><filter id="filter0_i_4758_159829" x="0.848633" y="0.848633" width="248.3" height="248.3" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB"><feFlood flood-opacity="0" result="BackgroundImageFix"/><feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/><feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/><feOffset/><feGaussianBlur stdDeviation="41.5"/><feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/><feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/><feBlend mode="normal" in2="shape" result="effect1_innerShadow_4758_159829"/></filter><clipPath id="clip0_4758_159829"><rect width="250" height="250" fill="white"/></clipPath></defs></svg>`;
    const MUSD_ICON_DATA_URL = `data:image/svg+xml;utf8,${encodeURIComponent(MUSD_ICON_SVG)}`;
    const USDC_BASE_ADDRESS = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
    const USDC_BASE_SEPOLIA_ADDRESS = "0x036CbD53842c5426634e7929541eC2318f3dCF7e";
    const USDC_ARB_SEPOLIA_ADDRESS = "0x75faf114eafb1BDbe2F0316DF893fd58CE46AA4d";
    const BASE_SEPOLIA_CHAIN_ID = 84532;
    const ARB_SEPOLIA_CHAIN_ID = 421614;
    const erc20Abi = [{
      name: "transfer",
      type: "function",
      stateMutability: "nonpayable",
      inputs: [{
        name: "to",
        type: "address"
      }, {
        name: "amount",
        type: "uint256"
      }],
      outputs: [{
        name: "",
        type: "bool"
      }]
    }, {
      name: "approve",
      type: "function",
      stateMutability: "nonpayable",
      inputs: [{
        name: "spender",
        type: "address"
      }, {
        name: "amount",
        type: "uint256"
      }],
      outputs: [{
        name: "",
        type: "bool"
      }]
    }, {
      name: "mint",
      type: "function",
      stateMutability: "nonpayable",
      inputs: [{
        name: "to",
        type: "address"
      }, {
        name: "amount",
        type: "uint256"
      }],
      outputs: []
    }, {
      name: "balanceOf",
      type: "function",
      inputs: [{
        name: "account",
        type: "address"
      }],
      outputs: [{
        name: "",
        type: "uint256"
      }],
      stateMutability: "view"
    }];
    const mockSwapAbi = [{
      name: "swap",
      type: "function",
      stateMutability: "nonpayable",
      inputs: [{
        name: "usdcIn",
        type: "uint256"
      }, {
        name: "minRwaOut",
        type: "uint256"
      }, {
        name: "recipient",
        type: "address"
      }],
      outputs: [{
        name: "rwaOut",
        type: "uint256"
      }]
    }, {
      name: "quote",
      type: "function",
      stateMutability: "view",
      inputs: [{
        name: "usdcIn",
        type: "uint256"
      }],
      outputs: [{
        name: "rwaOut",
        type: "uint256"
      }]
    }, {
      name: "getPrice",
      type: "function",
      stateMutability: "view",
      inputs: [],
      outputs: [{
        name: "price",
        type: "uint256"
      }]
    }, {
      name: "pricePerShare",
      type: "function",
      stateMutability: "view",
      inputs: [],
      outputs: [{
        name: "",
        type: "uint256"
      }]
    }, {
      name: "jitterRange",
      type: "function",
      stateMutability: "view",
      inputs: [],
      outputs: [{
        name: "",
        type: "uint256"
      }]
    }];
    const mockNftV2Abi = [{
      name: "buy",
      type: "function",
      stateMutability: "nonpayable",
      inputs: [{
        name: "id",
        type: "uint256"
      }, {
        name: "amount",
        type: "uint256"
      }, {
        name: "recipient",
        type: "address"
      }],
      outputs: [{
        name: "totalPrice",
        type: "uint256"
      }]
    }, {
      name: "priceOf",
      type: "function",
      stateMutability: "view",
      inputs: [{
        name: "id",
        type: "uint256"
      }],
      outputs: [{
        name: "",
        type: "uint256"
      }]
    }];
    return {
      docsAppOriginWebAuthn,
      DOCS_APP_ORIGIN_CLIENT_ID,
      DOCS_EXPERIMENTAL_CLEAR_SIGNING,
      APP_ORIGIN_DEMO_CAPABILITIES,
      DOCS_DIALOG_THEME,
      MOCK_USD_ADDRESS,
      RECIPIENT_ADDRESS,
      MOCK_RWA_ADDRESS,
      MOCK_SWAP_ADDRESS,
      MOCK_NFT_V2_ADDRESS,
      MOCK_NFT_LUIGI_ID,
      NVDA_ICON_DATA_URL,
      LUIGI_ICON_DATA_URL,
      MUSD_ICON_DATA_URL,
      USDC_BASE_ADDRESS,
      USDC_BASE_SEPOLIA_ADDRESS,
      USDC_ARB_SEPOLIA_ADDRESS,
      BASE_SEPOLIA_CHAIN_ID,
      ARB_SEPOLIA_CHAIN_ID,
      erc20Abi,
      mockSwapAbi,
      mockNftV2Abi
    };
  })();
  mods.mintBanner = (() => {
    const {useState, useCallback, useMemo, useEffect} = deps.React;
    const {createOneAuthProvider} = deps.sdk;
    const {encodeFunctionData, parseUnits} = deps.viem;
    const {DOCS_APP_ORIGIN_STORAGE_KEY, useAuth} = mods.authctx;
    const {MOCK_USD_ADDRESS, BASE_SEPOLIA_CHAIN_ID, erc20Abi} = mods.constants;
    const BASE_SEPOLIA_RPC = "https://sepolia.base.org";
    const callsOutcome = function callsOutcome2(result) {
      const intentStatus = String(result?.intentStatus ?? "").toLowerCase();
      if (intentStatus === "completed") return "success";
      if (intentStatus === "failed" || intentStatus === "expired") return "failed";
      if (!result || String(result.status).toUpperCase() !== "CONFIRMED") {
        return "pending";
      }
      const receipts = Array.isArray(result.receipts) ? result.receipts : [];
      if (receipts.length === 0) return "pending";
      const statuses = receipts.map(receipt => String(receipt?.status ?? "").toLowerCase());
      if (statuses.includes("0x0")) return "failed";
      return statuses.every(status => status === "0x1") ? "success" : "pending";
    };
    const isIntentLookupFailure = function isIntentLookupFailure2(result) {
      const code = String(result?.error?.code ?? "").toUpperCase();
      return code === "STATUS_FAILED" || code === "NETWORK_ERROR";
    };
    const readCallsStatus = async function readCallsStatus2(provider, client, id) {
      const result = await provider.request({
        method: "wallet_getCallsStatus",
        params: [id]
      });
      const receipts = Array.isArray(result?.receipts) ? result.receipts : null;
      if (String(result?.status).toUpperCase() !== "CONFIRMED" || !receipts || receipts.length > 0) {
        return result;
      }
      const intent = await client.getIntentStatus(id);
      if (isIntentLookupFailure(intent)) {
        throw new Error(intent.error?.message ?? "Status check failed");
      }
      return {
        ...result,
        intentStatus: intent?.status,
        transactionHash: result?.transactionHash ?? intent?.transactionHash
      };
    };
    function getStoredUser() {
      try {
        const saved = localStorage.getItem(DOCS_APP_ORIGIN_STORAGE_KEY);
        if (saved) return JSON.parse(saved);
      } catch {}
      return {};
    }
    function resolveAddress() {
      const stored = getStoredUser();
      return stored.address ?? null;
    }
    async function checkOnChainBalance(address) {
      const data = encodeFunctionData({
        abi: erc20Abi,
        functionName: "balanceOf",
        args: [address]
      });
      const res = await fetch(BASE_SEPOLIA_RPC, {
        method: "POST",
        headers: {
          "Content-Type": "application/json"
        },
        body: JSON.stringify({
          jsonrpc: "2.0",
          method: "eth_call",
          params: [{
            to: MOCK_USD_ADDRESS,
            data
          }, "latest"],
          id: 1
        })
      });
      const json = await res.json();
      return json.result ? BigInt(json.result) : 0n;
    }
    function MintBanner() {
      const {client, isAuthenticated} = useAuth();
      const [state, setState] = useState("idle");
      const [error, setError] = useState(null);
      const [callsId, setCallsId] = useState(null);
      const requiredBalance = useMemo(() => parseUnits("1", 6), []);
      const provider = useMemo(() => createOneAuthProvider({
        client,
        chainId: BASE_SEPOLIA_CHAIN_ID,
        storageKey: DOCS_APP_ORIGIN_STORAGE_KEY,
        waitForHash: false
      }), [client]);
      const checkBalance = useCallback(async () => {
        setState("checking");
        try {
          const address = resolveAddress();
          if (!address) {
            setState("insufficient");
            return;
          }
          const balance = await checkOnChainBalance(address);
          setState(balance >= requiredBalance ? "sufficient" : "insufficient");
        } catch {
          setState("insufficient");
        }
      }, [requiredBalance]);
      useEffect(() => {
        if (!isAuthenticated || !client) {
          setState("idle");
          return;
        }
        checkBalance();
      }, [isAuthenticated, client, checkBalance]);
      const handleMint = useCallback(async () => {
        setState("minting");
        setError(null);
        let submittedId = null;
        try {
          const accounts = await provider.request({
            method: "eth_requestAccounts"
          });
          const address = accounts[0];
          const mintData = encodeFunctionData({
            abi: erc20Abi,
            functionName: "mint",
            args: [address, parseUnits("1", 6)]
          });
          const mockUsdIcon = "https://s3.rhinestone.dev/tokens/musd.svg";
          const id = await provider.request({
            method: "wallet_sendCalls",
            params: [{
              chainId: BASE_SEPOLIA_CHAIN_ID,
              sourceChainId: BASE_SEPOLIA_CHAIN_ID,
              calls: [{
                to: MOCK_USD_ADDRESS,
                data: mintData,
                label: "Mint",
                sublabel: "1 mUSD",
                icon: mockUsdIcon
              }]
            }]
          });
          submittedId = id;
          setCallsId(id);
          const latest = await readCallsStatus(provider, client, id);
          const outcome = callsOutcome(latest);
          if (outcome === "success") {
            setState("success");
          } else if (outcome === "failed") {
            setError("Mint transaction failed onchain");
            setState("insufficient");
          } else {
            setState("pending");
          }
        } catch (err) {
          setError(err instanceof Error ? err.message : "Mint failed");
          setState(submittedId ? "pending" : "insufficient");
        }
      }, [provider, client]);
      const handleCheckMint = useCallback(async () => {
        if (!callsId) return;
        setError(null);
        try {
          const latest = await readCallsStatus(provider, client, callsId);
          const outcome = callsOutcome(latest);
          if (outcome === "success") setState("success"); else if (outcome === "failed") {
            setError("Mint transaction failed onchain");
            setState("insufficient");
          } else setState("pending");
        } catch (err) {
          setError(err instanceof Error ? err.message : "Status check failed");
        }
      }, [provider, client, callsId]);
      if (state === "idle" || state === "checking") return null;
      return React.createElement("div", {
        className: "demo-result demo-mint-banner",
        style: {
          marginTop: 0,
          marginBottom: "0.75rem"
        }
      }, state === "insufficient" && React.createElement(React.Fragment, null, React.createElement("p", {
        className: "demo-result-label"
      }, "No mUSD Balance"), React.createElement("p", {
        className: "demo-result-value",
        style: {
          fontSize: "0.8rem"
        }
      }, "This demo requires mUSD on Base Sepolia. Mint some to get started."), React.createElement("button", {
        onClick: handleMint,
        className: "demo-button",
        style: {
          marginTop: "0.5rem"
        }
      }, "Mint 1 mUSD")), state === "minting" && React.createElement("p", {
        className: "demo-result-value",
        style: {
          fontSize: "0.8rem"
        }
      }, "Minting mUSD..."), state === "pending" && React.createElement(React.Fragment, null, React.createElement("p", {
        className: "demo-result-label"
      }, "Mint submitted"), React.createElement("p", {
        className: "demo-result-value",
        style: {
          fontSize: "0.75rem"
        }
      }, callsId), React.createElement("button", {
        onClick: handleCheckMint,
        className: "demo-button",
        style: {
          marginTop: "0.5rem"
        }
      }, "Check status")), state === "success" && React.createElement(React.Fragment, null, React.createElement("p", {
        className: "demo-result-value",
        style: {
          fontSize: "0.8rem",
          color: "#22c55e"
        }
      }, "1 mUSD mint confirmed."), React.createElement("button", {
        onClick: checkBalance,
        className: "demo-button-secondary",
        style: {
          marginTop: "0.5rem"
        }
      }, "Refresh balance")), state === "sufficient" && React.createElement(React.Fragment, null, React.createElement("p", {
        className: "demo-result-value",
        style: {
          fontSize: "0.8rem"
        }
      }, "Funding available (last checked)."), React.createElement("button", {
        onClick: checkBalance,
        className: "demo-button-secondary",
        style: {
          marginTop: "0.5rem"
        }
      }, "Refresh balance")), error && React.createElement("p", {
        style: {
          fontSize: "0.75rem",
          color: "#ef4444",
          marginTop: "0.25rem"
        }
      }, error));
    }
    return {
      MintBanner
    };
  })();
  mods.batchQueueDemo = (() => {
    const {useCallback, useEffect, useState} = deps.React;
    const {BatchQueueProvider, useBatchQueue, BatchQueueWidget} = deps.sdk;
    const {useAuth} = mods.authctx;
    const {encodeFunctionData, parseUnits} = deps.viem;
    const {MOCK_USD_ADDRESS, BASE_SEPOLIA_CHAIN_ID, erc20Abi} = mods.constants;
    const {MintBanner} = mods.mintBanner;
    function BatchQueueDemoInner({address, pendingAdd, onAuthenticateForAdd, onPendingAddConsumed}) {
      const {client} = useAuth();
      const {queue, addToBatch, clearBatch, signAll, isSigning} = useBatchQueue();
      const [message, setMessage] = useState(null);
      const [submittedResults, setSubmittedResults] = useState(null);
      const [isChecking, setIsChecking] = useState(false);
      const intentOutcome = function intentOutcome2(result) {
        const code = String(result?.error?.code ?? "").toUpperCase();
        if (result?.intentId && (code === "STATUS_TIMEOUT" || code === "HASH_TIMEOUT")) {
          return "pending";
        }
        const status = String(result?.status ?? "").toLowerCase();
        if (status === "completed") return "success";
        if (status === "failed" || status === "expired") return "failed";
        return "pending";
      };
      const isIntentLookupFailure = function isIntentLookupFailure2(result) {
        const code = String(result?.error?.code ?? "").toUpperCase();
        return code === "STATUS_FAILED" || code === "NETWORK_ERROR";
      };
      const addCallForAddress = useCallback(addr => {
        const data = encodeFunctionData({
          abi: erc20Abi,
          functionName: "mint",
          args: [addr, parseUnits("0.00001", 6)]
        });
        const result = addToBatch({
          to: MOCK_USD_ADDRESS,
          data,
          label: "Mint 0.00001 mUSD",
          sublabel: "To your account on Base Sepolia"
        }, BASE_SEPOLIA_CHAIN_ID);
        setMessage(result.success ? null : result.error || "Failed to add");
      }, [addToBatch]);
      useEffect(() => {
        if (!pendingAdd || !address) return;
        addCallForAddress(address);
        onPendingAddConsumed();
      }, [addCallForAddress, address, onPendingAddConsumed, pendingAdd]);
      const handleAddCall = async () => {
        if (isSigning || submittedResults) return;
        if (!address) {
          try {
            const authenticated = await onAuthenticateForAdd();
            if (!authenticated) setMessage("Authentication cancelled");
          } catch (err) {
            setMessage(err instanceof Error ? err.message : "Authentication failed");
          }
          return;
        }
        addCallForAddress(address);
      };
      const handleSignAll = async () => {
        if (isSigning || submittedResults) {
          setMessage("Clear the submitted queue before starting another batch");
          return;
        }
        if (!address) {
          setMessage("Authentication required");
          return;
        }
        setMessage(null);
        try {
          const result = await signAll({
            accountAddress: address
          });
          if (result.results.length > 0) {
            setSubmittedResults(result.results);
            setMessage(`${result.results.length} result${result.results.length === 1 ? "" : "s"} returned`);
          } else if (["CANCELLED", "USER_CANCELLED", "USER_REJECTED"].includes(result.errorCode ?? "")) {
            setMessage("Signing cancelled");
          } else {
            setMessage(result.error || "Signing failed before submission");
          }
        } catch (err) {
          setMessage(err instanceof Error ? err.message : "Signing cancelled");
        }
      };
      const handleCheckStatuses = async () => {
        if (!submittedResults || isChecking) return;
        setIsChecking(true);
        try {
          const checked = await Promise.all(submittedResults.map(async result => {
            if (!result.intentId) return result;
            try {
              const latest = await client.getIntentStatus(result.intentId);
              if (isIntentLookupFailure(latest)) return {
                ...result,
                error: latest.error
              };
              return {
                ...result,
                status: latest.status ?? result.status,
                transactionHash: latest.transactionHash ?? result.transactionHash,
                error: latest.error
              };
            } catch (err) {
              return {
                ...result,
                error: {
                  message: err instanceof Error ? err.message : "Status check failed"
                }
              };
            }
          }));
          setSubmittedResults(current => current ? checked : null);
        } finally {
          setIsChecking(false);
        }
      };
      const handleClear = () => {
        if (isChecking) return;
        clearBatch();
        setSubmittedResults(null);
        setMessage(null);
      };
      return React.createElement("div", {
        className: "demo-preview",
        "data-testid": "batch-queue-demo"
      }, React.createElement("div", {
        className: "demo-preview-header"
      }, "Queue transactions"), React.createElement(MintBanner, null), React.createElement("div", {
        className: "demo-preview-content",
        style: {
          flexDirection: "column",
          alignItems: "stretch",
          gap: "0.75rem"
        }
      }, !address && React.createElement("div", {
        style: {
          padding: "0.5rem",
          backgroundColor: "#fef3c7",
          borderRadius: "0.375rem",
          textAlign: "center",
          fontSize: "0.875rem",
          color: "#92400e"
        }
      }, "Connect your wallet to authorize multi-intent signing"), React.createElement("div", {
        style: {
          display: "flex",
          gap: "0.75rem",
          justifyContent: "center"
        }
      }, React.createElement("button", {
        onClick: handleAddCall,
        disabled: isSigning || Boolean(submittedResults),
        className: "demo-preview-button",
        "data-testid": "batch-queue-add"
      }, "Add transaction"), React.createElement("button", {
        onClick: handleClear,
        disabled: isSigning || isChecking || queue.length === 0 && !submittedResults,
        className: "demo-preview-button",
        "data-testid": "batch-queue-clear",
        style: {
          opacity: isSigning || isChecking || queue.length === 0 && !submittedResults ? 0.5 : 1
        }
      }, "Clear")), React.createElement("div", {
        "data-testid": "batch-queue-count",
        style: {
          textAlign: "center",
          fontSize: "0.75rem",
          color: "#71717a"
        }
      }, queue.length === 0 ? "Click 'Add transaction' to queue intents" : `${queue.length} intent${queue.length !== 1 ? "s" : ""} queued`), message && React.createElement("div", {
        "data-testid": "batch-queue-result",
        style: {
          textAlign: "center",
          fontSize: "0.75rem",
          color: "#71717a"
        }
      }, message), submittedResults && React.createElement("button", {
        onClick: handleCheckStatuses,
        disabled: isChecking,
        className: "demo-button-secondary"
      }, isChecking ? "Checking..." : "Check statuses"), submittedResults?.map(result => {
        const outcome = intentOutcome(result);
        return React.createElement("div", {
          key: result.index,
          className: `demo-result ${outcome === "success" ? "demo-result-success" : outcome === "failed" ? "demo-result-error" : ""}`
        }, React.createElement("p", {
          className: "demo-result-label"
        }, "Transaction ", result.index + 1, ": ", result.intentId ? result.status ?? "submitted" : "not submitted"), result.intentId && React.createElement("p", {
          className: "demo-result-value"
        }, result.intentId), result.transactionHash && React.createElement("p", {
          className: "demo-result-value"
        }, result.transactionHash), result.error?.message && React.createElement("p", {
          className: "demo-result-value"
        }, result.error.message));
      })), !submittedResults && !isSigning && React.createElement("div", null, React.createElement(BatchQueueWidget, {
        onSignAll: handleSignAll
      })), React.createElement("div", {
        style: {
          padding: "0 1rem 1rem",
          fontSize: "0.75rem",
          color: "#71717a",
          textAlign: "center"
        }
      }, "One ceremony authorizes separate transactions. They are not atomic and each has its own outcome."));
    }
    function BatchQueueDemo() {
      const {client, address, login} = useAuth();
      const [effectiveAddress, setEffectiveAddress] = useState(address);
      const [pendingAdd, setPendingAdd] = useState(false);
      useEffect(() => {
        setEffectiveAddress(address);
      }, [address]);
      const authenticateForAdd = useCallback(async () => {
        const authenticatedAddress = await login();
        if (!authenticatedAddress) return false;
        setEffectiveAddress(authenticatedAddress);
        setPendingAdd(true);
        return true;
      }, [login]);
      return React.createElement(BatchQueueProvider, {
        key: effectiveAddress ?? "anonymous",
        client,
        accountAddress: effectiveAddress ?? void 0
      }, React.createElement(BatchQueueDemoInner, {
        address: effectiveAddress,
        pendingAdd,
        onAuthenticateForAdd: authenticateForAdd,
        onPendingAddConsumed: () => setPendingAdd(false)
      }));
    }
    return {
      BatchQueueDemo
    };
  })();
  return mods;
};

export const ADDRESS_RE = /^0x[0-9a-fA-F]{40}$/;

export const readStoredAddressFromJsonEnvelope = () => {
  try {
    const raw = window.localStorage.getItem(STORAGE_KEY);
    if (!raw) return null;
    const parsed = JSON.parse(raw);
    const address = parsed && typeof parsed === "object" ? parsed.address : null;
    return typeof address === "string" && ADDRESS_RE.test(address) ? address : null;
  } catch {
    return null;
  }
};

export const writeStoredAddressAsJsonEnvelope = address => {
  window.localStorage.setItem(STORAGE_KEY, JSON.stringify({
    address
  }));
};

export const useOneAuth = deps => {
  const [address, setAddress] = React.useState(null);
  const [client, setClient] = React.useState(null);
  const mounted = React.useRef(false);
  const sessionGeneration = React.useRef(0);
  React.useEffect(() => {
    if (!deps) return;
    mounted.current = true;
    const restoreGeneration = ++sessionGeneration.current;
    const {OneAuthClient} = deps.sdk;
    const nextClient = new OneAuthClient({
      providerUrl: backends().auth,
      clientId: "docs-app-origin",
      webauthn: {
        mode: "app_origin",
        rpId: window.location.hostname
      },
      theme: {
        mode: "dark",
        accent: "#ffffff",
        backdrop: {
          color: "#52525c",
          opacity: 0.5,
          blur: 12
        }
      },
      experimental_clear_signing: true,
      recovery: {
        fallback: {
          type: "verified-identity"
        }
      },
      testnets: true,
      prewarm: true,
      sponsorship,
      onDisconnect: () => {
        if (!mounted.current) return;
        sessionGeneration.current += 1;
        window.localStorage.removeItem(STORAGE_KEY);
        setAddress(null);
      }
    });
    setClient(nextClient);
    const stored = readStoredAddressFromJsonEnvelope();
    if (stored) {
      nextClient.getSession().then(result => {
        if (!mounted.current || sessionGeneration.current !== restoreGeneration) return;
        const account = result.success ? result.session.accountAddress : null;
        if (account && ADDRESS_RE.test(account)) {
          writeStoredAddressAsJsonEnvelope(account);
          setAddress(account);
        } else {
          window.localStorage.removeItem(STORAGE_KEY);
          setAddress(null);
        }
      }).catch(() => {
        if (!mounted.current || sessionGeneration.current !== restoreGeneration) return;
        window.localStorage.removeItem(STORAGE_KEY);
        setAddress(null);
      });
    }
    return () => {
      mounted.current = false;
      sessionGeneration.current += 1;
    };
  }, [deps]);
  const login = React.useCallback(async () => {
    if (!client) return null;
    const generation = ++sessionGeneration.current;
    const result = await client.authenticate({
      oauthEnabled: false
    });
    if (!result.success) {
      if (result.error?.code === "USER_CANCELLED") return null;
      throw new Error(result.error?.message ?? "Authentication failed");
    }
    const account = result.session.accountAddress;
    if (!ADDRESS_RE.test(account)) throw new Error("Authentication returned an invalid account address");
    if (!mounted.current || sessionGeneration.current !== generation) return null;
    writeStoredAddressAsJsonEnvelope(account);
    setAddress(account);
    return account;
  }, [client]);
  const logout = React.useCallback(() => {
    sessionGeneration.current += 1;
    window.localStorage.removeItem(STORAGE_KEY);
    if (mounted.current) setAddress(null);
    if (client?.disconnect) client.disconnect();
  }, [client]);
  return React.useMemo(() => ({
    address,
    isAuthenticated: !!address,
    client,
    sponsorship,
    login,
    logout
  }), [address, client, login, logout]);
};

export const Frame = ({children, connected}) => <div className="oa-demo">
    <div className="oa-demo-head">
      <span className="oa-demo-title">Queue non-atomic transactions</span>
      <span className="oa-demo-status">
        <span className="oa-demo-dot" data-state={connected ? "on" : "off"} />
        {connected ? "Signed in" : "Not connected"}
      </span>
    </div>
    <div className="oa-demo-body">{children}</div>
  </div>;

export const GuideDemo = () => {
  const [deps, setDeps] = React.useState(null);
  const [loadError, setLoadError] = React.useState("");
  const [connecting, setConnecting] = React.useState(false);
  React.useEffect(() => {
    let cancelled = false;
    loadDeps().then(d => !cancelled && setDeps(d)).catch(e => !cancelled && setLoadError(String(e.message ?? e)));
    return () => {
      cancelled = true;
    };
  }, []);
  const mods = React.useMemo(() => deps ? buildModules(deps) : null, [deps]);
  const auth = useOneAuth(deps);
  return <div className="not-prose rhinestone-1auth-demo" data-demo="send-a-transaction">
      <style dangerouslySetInnerHTML={{
    __html: CSS
  }} />
      <AuthContext.Provider value={auth}>
        <Frame connected={auth.isAuthenticated}>
          {mods && auth.client && true && !auth.isAuthenticated ? <div>
              <button className="demo-button" disabled={connecting} onClick={async () => {
    setConnecting(true);
    setLoadError("");
    try {
      await auth.login();
    } catch (error) {
      setLoadError(String(error.message ?? error));
    } finally {
      setConnecting(false);
    }
  }}>{connecting ? "Signing in..." : "Sign in to try it"}</button>
              {loadError ? <p className="demo-error">{loadError}</p> : null}
            </div> : mods && (auth.client || false) ? React.createElement(mods.batchQueueDemo.BatchQueueDemo, {
    key: auth.address
  }) : loadError ? <p className="demo-error">{loadError}</p> : <span className="oa-demo-skeleton" />}
        </Frame>
      </AuthContext.Provider>
    </div>;
};

A multichain transaction combines target-chain calls with the assets needed to execute them. Rhinestone selects a funding route, moves or swaps assets when required, and executes the calls as one intent.

## Describe the outcome

Keep funding and execution separate in the request:

| Field                    | Purpose                                                                                               |
| ------------------------ | ----------------------------------------------------------------------------------------------------- |
| Target chain             | The chain where every destination call executes.                                                      |
| `tokenRequests`          | Tokens and amounts needed on the target chain before calls execute. Use target-chain token addresses. |
| Calls                    | Real target-chain calldata. The calls execute in order and revert together if one fails.              |
| Source chains and assets | Constraints on balances that the orchestrator may spend. The fields differ by client.                 |

`tokenRequests` are not calldata. Add them when a call needs tokens delivered to the target chain. Omit them for a gas-only call that does not need assets delivered. For a token-only swap with no calls, see [Make a swap](/transactions/trading/make-a-swap). Do not add dummy calldata or a self-transfer to a request that does not need a call.

## Define the calls

This example sends 100 USDC to a recipient on Arbitrum, funded with USDC from the account on Base. Both wallet types use the same calldata:

```ts theme={null}
import { encodeFunctionData, erc20Abi, parseUnits } from "viem";
import { arbitrum, base } from "viem/chains";

const usdcOnBase = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
const usdcOnArbitrum = "0xaf88d065e77c8cC2239327C5EDb3A432268e5831";
const recipient = "0xd8da6bf26964af9d7eed9e03e53415d37aa96045";
const amount = parseUnits("100", 6);

const calls = [
  {
    to: usdcOnArbitrum,
    value: 0n,
    data: encodeFunctionData({
      abi: erc20Abi,
      functionName: "transfer",
      args: [recipient, amount],
    }),
  },
] as const;
```

## Send the transaction

<Tabs>
  <Tab title="Embedded wallet">
    Use the initialized `oneAuth` client and authenticated `accountAddress` from [Accounts](/wallets/embedded-wallets/accounts). `sendIntent()` prepares the quote, requests passkey approval, and submits the intent:

    ```ts {6-7} theme={null}
    const result = await oneAuth.sendIntent({
      accountAddress,
      targetChain: arbitrum.id,
      sourceChainId: base.id,
      sourceAssets: [usdcOnBase],
      tokenRequests: [{ token: usdcOnArbitrum, amount }],
      calls: [...calls],
    });

    if (!result.success) throw new Error(result.error?.message);
    ```

    Keep `result.intentId` for status checks.

    Embedded wallets use numeric chain IDs and `tokenRequests[].token`. `sourceChainId` restricts funding to Base; `sourceAssets` restricts the input token to USDC. To let the wallet choose across available mainnet balances, omit both source constraints and keep `tokenRequests`. A call with neither `tokenRequests` nor `sourceAssets` defaults to target-chain funding unless you set `sourceChainId`.

    The default is `sponsorshipMode: "required"`. See [Sponsor fees](/transactions/sponsorship/sponsor-fees) for user-paid quotes and fallback behavior. Set `experimental_clear_signing: true` for [prepared-action review](/wallets/embedded-wallets/clear-signing). The [end-to-end flow](/transactions/multichain/end-to-end-transaction-flow) covers `closeOn: "completed"` and `waitForHash: true` without repeating them in every request.

    Embedded wallets have no separate `recipient` field for this flow. Encode the payment recipient in the `transfer` call, as shown above.

    ### Batch calls

    Pass multiple calls to `sendIntent()` for an **atomic destination batch**. They target one chain, execute in order, and all revert when any call fails. Use this for dependent actions such as approve then deposit.

    `sendBatchIntent()` instead authorizes several separate intents with one passkey ceremony. Each intent has its own submission and outcome, so they can succeed or fail independently. Do not use it when the operations must be atomic.

    ### Try a non-atomic queue

    Add several small mUSD mint transactions on Base Sepolia, then authorize them with one passkey ceremony. This embedded-wallet demo shows **separate intents**, not an atomic batch or a crosschain funding route. For dependent calls that must revert together, try the [atomic relay demo](/transactions/relaying/relay-a-transaction#try-atomic-calls).

    Review each result independently. A submitted intent is not necessarily completed; retain its ID and [check its status](/transactions/multichain/end-to-end-transaction-flow#follow-the-flow) before retrying. Clear the queue deliberately after reviewing partial results rather than resubmitting successful entries.

    <GuideDemo />
  </Tab>

  <Tab title="Custom signer">
    Use `account` from the [Custom signer quickstart](/wallets/custom-signer/quickstart):

    ```ts {9,13,15} theme={null}
    const prepared = await account.prepareTransaction({
      sourceChains: [base],
      sourceAssets: [usdcOnBase],
      targetChain: arbitrum,
      tokenRequests: [{ address: usdcOnArbitrum, amount }],
      calls: [...calls],
    });

    const quote = prepared.quotes.best;
    console.log(quote.cost.input, quote.cost.output, quote.cost.fees);

    const signed = await account.signTransaction(prepared, {
      intentId: quote.intentId,
    });
    const submitted = await account.submitTransaction(signed);
    const result = await account.waitForExecution(submitted);

    console.log(result.status, result.operations);
    ```

    The SDK uses chain objects and `tokenRequests[].address`. `sourceChains` restricts funding to Base, while `sourceAssets` restricts the input token to USDC. Omit `sourceAssets` to allow other assets on Base, or omit both fields to allow routing across available balances. Review the selected quote's inputs, outputs, and fees before signing.

    To spend a fixed input amount instead of requesting a fixed output, pass amounts in `sourceAssets` and drop the amount from the token request; see [Spend an exact input amount](/transactions/trading/make-a-swap#spend-an-exact-input-amount).

    The example is user-paid. Set `sponsored: true` during preparation if your application pays the fees; see [Sponsor fees](/transactions/sponsorship/sponsor-fees).

    ### Deliver to another address

    To move assets to someone else on the target chain, request the token and set `recipient` — no calls needed. This delivers 100 USDC on Arbitrum, funded from the account's USDC on Base:

    ```ts theme={null}
    const prepared = await account.prepareTransaction({
      sourceChains: [base],
      sourceAssets: [usdcOnBase],
      targetChain: arbitrum,
      tokenRequests: [{ address: usdcOnArbitrum, amount }],
      calls: [],
      recipient,
    });
    ```

    The delivered token is the one in `tokenRequests`, so the same request also swaps when the source asset differs; see [Make a swap](/transactions/trading/make-a-swap).

    `recipient` changes the destination account for delivered assets and execution. A plain address selects an EOA destination. For another smart account, pass its `RhinestoneAccountConfig`. It does not rewrite addresses encoded in calldata: in the `transfer` example above, the payment recipient comes from the call itself and `recipient` stays unset.

    ### Choose a different route

    `prepareTransaction` returns every candidate route in `prepared.quotes.all`, ranked with the orchestrator's recommendation in `prepared.quotes.best`. Pick another one by passing its `intentId` to `signTransaction`:

    ```ts theme={null}
    const cheapestFastEnough =
      prepared.quotes.all
        .filter((candidate) => candidate.estimatedFillTime.seconds <= 60)
        .sort((a, b) => a.cost.fees.total.usd - b.cost.fees.total.usd)[0] ??
      prepared.quotes.best;

    const signed = await account.signTransaction(prepared, {
      intentId: cheapestFastEnough.intentId,
    });
    ```

    Each quote carries its own signing payload. Never sign one quote and submit another; always pass the `intentId` of the quote you reviewed.

    To constrain the routes before they are quoted, filter the settlement layers. Pass an allow-list to pin the route, or a deny-list to avoid one layer and let the orchestrator choose among the rest:

    ```ts {6} theme={null}
    const prepared = await account.prepareTransaction({
      sourceChains: [base],
      targetChain: arbitrum,
      tokenRequests: [{ address: usdcOnArbitrum, amount }],
      calls: [...calls],
      settlementLayers: { include: ["ACROSS"] },
    });
    ```

    Available layers are `ACROSS`, `ECO`, `RELAY`, `OFT`, `NEAR`, `RHINO`, `CCTP`, and `LZ`. An empty allow-list fails closed rather than falling back to an unconstrained route. Omit the field to let the orchestrator pick.

    ### Set the destination gas limit

    `gasLimit` is the gas the destination calls are quoted against. Without it, the quote assumes a conservative default of 1,000,000 units, so a small call is over-quoted:

    ```ts theme={null}
    const prepared = await account.prepareTransaction({
      sourceChains: [base],
      targetChain: arbitrum,
      tokenRequests: [{ address: usdcOnArbitrum, amount }],
      calls: [...calls],
      gasLimit: 200_000n,
    });
    ```

    Estimate the destination calls and add headroom. A limit below actual usage makes the destination execution run out of gas.

    ### Quote against incoming funds

    `auxiliaryFunds` declares balances the orchestrator cannot see yet but that arrive before the intent settles — a pending exchange withdrawal, an unstake, a vault exit. Routing treats them as spendable:

    ```ts theme={null}
    const prepared = await account.prepareTransaction({
      targetChain: arbitrum,
      tokenRequests: [{ address: usdcOnArbitrum, amount }],
      calls: [...calls],
      auxiliaryFunds: {
        [base.id]: { [usdcOnBase]: parseUnits("100", 6) },
      },
    });
    ```

    <Warning>
      Do not declare funds the account already holds. The orchestrator reads those
      balances itself, and declaring them again double-counts them and inflates the
      quoted input amount.
    </Warning>

    ### Run calls on the source chain first

    `sourceCalls` executes on the source side before the claim, covered by the same signature. Use it for an approval, a wrap, or a withdrawal that releases the funds the intent spends. Declare tokens that a call frees up with `provides` so routing counts them:

    ```ts {9-10,26} theme={null}
    const wethOnBase = "0x4200000000000000000000000000000000000006";
    const wrapAmount = parseUnits("0.05", 18);

    const prepared = await account.prepareTransaction({
      sourceChains: [base],
      targetChain: arbitrum,
      tokenRequests: [{ address: usdcOnArbitrum, amount }],
      calls: [...calls],
      sourceCalls: {
        [base.id]: [
          {
            to: wethOnBase,
            value: wrapAmount,
            data: encodeFunctionData({
              abi: [
                {
                  type: "function",
                  name: "deposit",
                  stateMutability: "payable",
                  inputs: [],
                  outputs: [],
                },
              ] as const,
              functionName: "deposit",
            }),
            provides: [{ token: wethOnBase, amount: wrapAmount }],
          },
        ],
      },
    });
    ```

    Each key must be a chain in `sourceChains`. Source calls only run when the route actually moves funds from that chain: a sponsored or no-op fill with no source movement skips the source element, and the calls keyed on that chain are dropped.

    ### Plain EOA requirements

    This example uses a smart account, which handles approvals and wrapping as preclaim operations. If you use a plain EOA instead, inspect the selected quote's `tokenRequirements` before signing and submitting. For the recommended route, read `prepared.quotes.best.tokenRequirements`.

    The SDK does not execute these requirements for an EOA. Complete each approval or native-token wrap on the specified chain and wait for confirmation. Follow [Complete token requirements](/transactions/multichain/end-to-end-transaction-flow#complete-token-requirements) for the onchain operations.

    ### Batch calls

    Pass multiple calls to `prepareTransaction()` for an **atomic destination batch**. They target one chain, execute in order, and all revert when any call fails. Use this for dependent actions such as approve then deposit.
  </Tab>
</Tabs>

Continue to the [end-to-end transaction flow](/transactions/multichain/end-to-end-transaction-flow) for the route lifecycle and failure recovery.
