diff --git a/examples/nextjs-app/package.json b/examples/nextjs-app/package.json index c47230b50..2fd932aef 100644 --- a/examples/nextjs-app/package.json +++ b/examples/nextjs-app/package.json @@ -40,8 +40,8 @@ }, "dependencies": { "@creit.tech/stellar-wallets-kit": "^1.9.5", - "@rozoai/intent-common": "0.1.35", - "@rozoai/intent-pay": "0.1.45", + "@rozoai/intent-common": "0.1.36", + "@rozoai/intent-pay": "0.1.46-beta.2", "@stellar/stellar-sdk": "^14.6.1", "@tanstack/react-query": "^5.0.0", "@web3icons/react": "^4.1.19", diff --git a/packages/connectkit/README.md b/packages/connectkit/README.md index f20986d78..b00e75ec3 100644 --- a/packages/connectkit/README.md +++ b/packages/connectkit/README.md @@ -65,6 +65,10 @@ export function Providers({ children }: { children: React.ReactNode }) { ssr: true, // Optional: Base builder code attribution (https://docs.base.org/apps/builder-codes) // dataSuffix: Attribution.toDataSuffix({ codes: [process.env.NEXT_PUBLIC_BASE_BUILDER_CODE] }), + // Optional: your own WalletConnect Cloud project ID (https://cloud.reown.com). + // Desktop WalletConnect QR is available by default via Rozo's shared + // project ID — pass yours here to use a separate WalletConnect project. + // walletConnectProjectId: process.env.NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID, }))); const [qc] = useState(() => new QueryClient()); return ( @@ -95,7 +99,7 @@ Then drop a `` (snippet above) anywhere ### Supported Wallets -**EVM Wallets:** MetaMask, Coinbase Wallet, Trust Wallet, Rainbow Wallet, Family Wallet, Zerion, OKX, Bitget +**EVM Wallets:** MetaMask, Coinbase Wallet, Trust Wallet, Rainbow Wallet, Family Wallet, Zerion, OKX, Bitget, WalletConnect (desktop QR only) **Solana Wallets:** Phantom, Backpack, Solflare diff --git a/packages/connectkit/package.json b/packages/connectkit/package.json index f0f8f99b2..6913af810 100644 --- a/packages/connectkit/package.json +++ b/packages/connectkit/package.json @@ -1,6 +1,6 @@ { "name": "@rozoai/intent-pay", - "version": "0.1.46", + "version": "0.1.46-beta.2", "private": false, "description": "Seamless crypto payments. Onboard users from any chain, any coin into your app with one click.", "keywords": [ @@ -49,7 +49,7 @@ "@reown/appkit": "^1.7.0", "@rollup/plugin-image": "^3.0.3", "@rollup/plugin-typescript": "^12.1.2", - "@rozoai/intent-common": "0.1.35", + "@rozoai/intent-common": "0.1.36", "@solana/spl-memo": "^0.2.5", "@solana/spl-token": "^0.4.14", "@solana/wallet-adapter-base": "^0.9.27", diff --git a/packages/connectkit/src/components/Common/ConnectorList/index.tsx b/packages/connectkit/src/components/Common/ConnectorList/index.tsx index d0093264d..5b8b02e0c 100644 --- a/packages/connectkit/src/components/Common/ConnectorList/index.tsx +++ b/packages/connectkit/src/components/Common/ConnectorList/index.tsx @@ -7,7 +7,7 @@ import { useRozoPay } from "../../../hooks/useRozoPay"; import useIsMobile from "../../../hooks/useIsMobile"; import { useLastConnector } from "../../../hooks/useLastConnector"; import { usePayContext } from "../../../hooks/usePayContext"; -import { detectBrowser, isCoinbaseWalletConnector } from "../../../utils"; +import { detectBrowser, isCoinbaseWalletConnector, isWalletConnectConnector } from "../../../utils"; import { WALLET_ID_MOBILE_WALLETS, WALLET_ID_OTHER_WALLET, @@ -141,6 +141,24 @@ const ConnectorItem = ({ // Desktop multi-chain wallet flow: prompt for chain selection. if (!isMobile) { + if (isWalletConnectConnector(wallet.connector?.id)) { + context.setPendingConnectorId(wallet.id); + context.setRoute(ROUTES.CONNECT_WALLETCONNECT, meta); + return; + } + + // No-extension fallback tile: any WC wallet can scan the QR, so route + // to the shared WalletConnect page. pendingConnectorId keeps the stub + // wallet id so the QR page can brand itself ("Scan with MetaMask"). + // Only the no-connector fallback stub routes to QR. The real injected + // wallet inherits walletConnectFallback from its config but has a live + // connector, so it must connect directly (not show the WC QR). + if (wallet.walletConnectFallback && !wallet.connector) { + context.setPendingConnectorId(wallet.id); + context.setRoute(ROUTES.CONNECT_WALLETCONNECT, meta); + return; + } + if (wallet.solanaConnectorName) { const supportsEvm = wallet.connector?.name != null; diff --git a/packages/connectkit/src/components/Common/OrderHeader/index.tsx b/packages/connectkit/src/components/Common/OrderHeader/index.tsx index 67597443e..8bc83bb60 100644 --- a/packages/connectkit/src/components/Common/OrderHeader/index.tsx +++ b/packages/connectkit/src/components/Common/OrderHeader/index.tsx @@ -11,6 +11,8 @@ import { Solana, Stellar, } from "../../../assets/chains"; +import { WalletConnect } from "../../../assets/logos"; +import { isWalletConnectConnector } from "../../../utils"; import defaultTheme from "../../../constants/defaultTheme"; import { ROUTES } from "../../../constants/routes"; import { useRozoPay } from "../../../hooks/useRozoPay"; @@ -113,7 +115,13 @@ export const OrderHeader = ({ ); }; - const walletIcon = renderIcon(connector?.icon, undefined, 32); + // WalletConnect connectors have no icon payload — show WC branding instead. + const evmWalletIcon = isWalletConnectConnector(connector?.id) ? ( + + ) : ( + connector?.icon + ); + const walletIcon = renderIcon(evmWalletIcon, undefined, 32); const solanaIcon = renderIcon( solanaWallet?.adapter.icon || , solanaWallet?.adapter.name, diff --git a/packages/connectkit/src/components/Pages/Confirmation/index.tsx b/packages/connectkit/src/components/Pages/Confirmation/index.tsx index 547f02137..ce06fd64e 100644 --- a/packages/connectkit/src/components/Pages/Confirmation/index.tsx +++ b/packages/connectkit/src/components/Pages/Confirmation/index.tsx @@ -6,6 +6,7 @@ import { Link, ModalBody, ModalContent, ModalH1, PageContent } from "../../Commo import { assert, getAddressContraction, + isHydrated, getChainExplorerTxUrl, getOrderDestChainId, getPayment, @@ -23,6 +24,7 @@ import { ROZO_INVOICE_URL } from "../../../constants/rozoConfig"; import { usePayoutPolling } from "../../../hooks/usePayoutPolling"; import { usePusherPayout } from "../../../hooks/usePusherPayout"; import { useRozoPay } from "../../../hooks/useRozoPay"; +import { resolveConfirmedPayoutTxHash } from "../../../payment/resolveConfirmedPayoutTxHash"; import { beginRequestScope, cancelRequestScope, @@ -91,17 +93,19 @@ const Confirmation: React.FC = () => { // is known as soon as the pay-in txHash is confirmed. const isStellarDirectSameTx = useMemo(() => { if (!order) return false; - - const meta = (order as any).metadata as Record | undefined; + const meta = order.metadata as Record | undefined; if (meta?.settlementMode !== "stellar_direct") return false; + // txHash fields only exist on hydrated orders — narrow first. + const hydrated = isHydrated(order) ? order : null; const sourceTx = - (order as any).sourceStartTxHash ?? (meta?.payinTransactionHash as string | undefined); - + hydrated?.sourceStartTxHash ?? + (meta?.payinTransactionHash as string | undefined); const destTx = - (order as any).payoutTransactionHash ?? - (order as any).destFastFinishTxHash ?? - (order as any).destClaimTxHash; + (meta?.payoutTransactionHash as string | undefined) ?? + hydrated?.payoutTransactionHash ?? + hydrated?.destFastFinishTxHash ?? + hydrated?.destClaimTxHash; return !!sourceTx && !!destTx && sourceTx === destTx; }, [order]); @@ -123,7 +127,13 @@ const Confirmation: React.FC = () => { } } - if (payParams && (tokenMode === "stellar" || tokenMode === "solana" || tokenMode === "evm")) { + if ( + payParams && + (tokenMode === "stellar" || + tokenMode === "solana" || + tokenMode === "evm" || + tokenMode === "all") + ) { return payParams.showProcessingPayout; } @@ -140,6 +150,15 @@ const Confirmation: React.FC = () => { return undefined; }, [pusherPayoutTxHash, order]); + const confirmedPayoutTxHash = payinConfirmed?.payoutTxHash; + const confirmedPayoutTxHashUrl = useMemo(() => { + if (!confirmedPayoutTxHash || !order) return undefined; + return getChainExplorerTxUrl( + getOrderDestChainId(order), + confirmedPayoutTxHash, + ); + }, [confirmedPayoutTxHash, order]); + const rozoPaymentId = useMemo(() => { const id = order?.externalId || paymentStateContext.rozoPaymentId; return id; @@ -500,6 +519,7 @@ const Confirmation: React.FC = () => { // Payout is resolved when either Pusher or polling has found the destination txhash const payoutResolved = !!( + (confirmedPayoutTxHash && confirmedPayoutTxHashUrl) || (pusherPayoutTxHash && computedPusherPayoutTxHashUrl) || (payoutTxHash && payoutTxHashUrl) ); @@ -683,28 +703,28 @@ const Confirmation: React.FC = () => { }, [done, paymentStateContext, rawPayInHash, rozoPaymentId]); /** - * Payout that is settled by the payin itself, so there is nothing to wait - * for: stellar_direct with source txHash === destination txHash (known from - * the order, or from the confirmed API response), and deposit-address flows - * (which previously marked payout completed on payin detection). Separate - * from the completion effect so its dedupe cannot swallow this event. + * Complete payout immediately when the payin confirmation response already + * includes its destination hash. This covers payouts completed before the + * Confirmation page subscribed to Pusher, plus stellar_direct same-tx flows. */ useEffect(() => { if (!done || !rawPayInHash || !rozoPaymentId) return; const sameTx = isStellarDirectSameTx || !!payinConfirmed?.sameTxPayout; - // Deposit-address flow: only when the API already reports the destination - // tx. Otherwise leave payoutCompletedRef untouched so the normal Pusher / - // polling payout wait runs — never report the source tx as the payout. - const depositPayout = - !!paymentStateContext.selectedDepositAddressOption && !!payinConfirmed?.payoutTxHash; - if (!sameTx && !depositPayout) return; - const payoutHash = sameTx ? rawPayInHash : payinConfirmed!.payoutTxHash!; + const payoutHash = resolveConfirmedPayoutTxHash( + rawPayInHash, + payinConfirmed?.payoutTxHash, + sameTx, + ); + if (!payoutHash) return; const payoutKey = `${payoutHash}-${rozoPaymentId}`; if (payoutCompletedSent.current === payoutKey) return; payoutCompletedSent.current = payoutKey; payoutCompletedRef.current = true; setPaymentPayoutCompleted(payoutHash, rozoPaymentId); - context.log("[CONFIRMATION] payout completed directly:", { sameTx, depositPayout, payoutHash }); + context.log("[CONFIRMATION] payout completed from payin response:", { + sameTx, + payoutHash, + }); // eslint-disable-next-line react-hooks/exhaustive-deps }, [done, rawPayInHash, rozoPaymentId, isStellarDirectSameTx, payinConfirmed]); @@ -854,15 +874,26 @@ const Confirmation: React.FC = () => { {payoutLoading ? ( Processing payout... - ) : (computedPusherPayoutTxHashUrl && pusherPayoutTxHash) || + ) : (confirmedPayoutTxHashUrl && confirmedPayoutTxHash) || + (computedPusherPayoutTxHashUrl && pusherPayoutTxHash) || (payoutTxHashUrl && payoutTxHash) ? ( - {getAddressContraction(pusherPayoutTxHash || payoutTxHash || "")} + {getAddressContraction( + confirmedPayoutTxHash || + pusherPayoutTxHash || + payoutTxHash || + "", + )} ) : ( diff --git a/packages/connectkit/src/components/Pages/ConnectWalletConnect/index.tsx b/packages/connectkit/src/components/Pages/ConnectWalletConnect/index.tsx new file mode 100644 index 000000000..64e38e570 --- /dev/null +++ b/packages/connectkit/src/components/Pages/ConnectWalletConnect/index.tsx @@ -0,0 +1,128 @@ +import { useEffect, useState } from "react"; +import { useAccount } from "wagmi"; + +import { ROUTES } from "../../../constants/routes"; +import { useConnect } from "../../../hooks/useConnect"; +import { useConnectors } from "../../../hooks/useConnectors"; +import { usePayContext } from "../../../hooks/usePayContext"; +import { useWallet } from "../../../wallets/useWallets"; +import CopyToClipboard from "../../Common/CopyToClipboard"; +import CustomQRCode from "../../Common/CustomQRCode"; +import Alert from "../../Common/Alert"; +import Button from "../../Common/Button"; +import { + ModalBody, + ModalContent, + ModalH1, + PageContent, +} from "../../Common/Modal/styles"; + +/** + * Desktop-only WalletConnect connect flow: renders our own QR + copyable URI + * instead of WalletConnect's bundled modal. The desktop-only connector is + * configured with showQrModal: false in defaultConnectors.ts. + * + * pendingConnectorId may be either the real "walletConnect" connector id, or a + * no-extension fallback stub id ("wc-fallback-…"). The connector is always the + * shared walletConnect one; the stub only drives branding ("Scan with + * MetaMask" + its logo), since any WC wallet can scan the QR. + * + * The connector emits a "display_uri" message on its own `emitter` (wagmi + * gives every connector a dedicated Emitter, wired up in + * createConfig's setup()) once connect() kicks off the pairing handshake; + * we grab that URI and render it here. + */ +const ConnectWalletConnect: React.FC = () => { + const context = usePayContext(); + const { pendingConnectorId, setRoute } = context; + const brandingWallet = useWallet(pendingConnectorId ?? ""); + const { connect } = useConnect(); + const { isConnected } = useAccount(); + + // Resolve the real WC connector regardless of which tile the user clicked. + const connectors = useConnectors(); + const wcConnector = connectors.find((c) => c.id === "walletConnect"); + + const [uri, setUri] = useState(null); + const [error, setError] = useState(null); + const [attempt, setAttempt] = useState(0); + + useEffect(() => { + if (!wcConnector) return; + + setError(null); + setUri(null); + + const listener = (event: { type: string; data?: unknown }) => { + if (event.type === "display_uri" && typeof event.data === "string") { + setUri(event.data); + } + }; + wcConnector.emitter.on("message", listener); + + connect({ + connector: wcConnector, + mutation: { + onError: (err) => setError(err?.message ?? "Failed to connect"), + }, + }); + + return () => { + wcConnector.emitter.off("message", listener); + }; + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [wcConnector, attempt]); + + // Error Alert changes content height — poke the modal so it re-measures. + useEffect(() => { + if (error) setTimeout(context.triggerResize, 10); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [error]); + + useEffect(() => { + if (!isConnected) return; + setRoute(ROUTES.SELECT_TOKEN, { event: "walletconnect-connected" }); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [isConnected]); + + if (!wcConnector) return Connector not found; + + // Branding: fallback stubs carry the wallet's own name/logo; the generic + // walletConnect tile falls back to WalletConnect branding. + const title = brandingWallet?.name + ? `Scan with ${brandingWallet.name}` + : "Scan with WalletConnect"; + + return ( + + + {title} + + Scan this QR code with a WalletConnect-compatible wallet, or copy + the link below. + + + + + {error && ( + <> + {error} + setAttempt((n) => n + 1)} + style={{ margin: "0 auto" }} + > + Try again + + > + )} + + + Copy to clipboard + + + + + ); +}; + +export default ConnectWalletConnect; diff --git a/packages/connectkit/src/components/Pages/SelectMethod/index.tsx b/packages/connectkit/src/components/Pages/SelectMethod/index.tsx index 5b32dd57a..e92469167 100644 --- a/packages/connectkit/src/components/Pages/SelectMethod/index.tsx +++ b/packages/connectkit/src/components/Pages/SelectMethod/index.tsx @@ -24,9 +24,11 @@ import { MetaMask, Phantom, Rainbow, + WalletConnect, WalletIcon, } from "../../../assets/logos"; import { useAutoConnectGate } from "../../../hooks/useAutoConnectGate"; +import { isWalletConnectConnector } from "../../../utils"; import useIsMobile from "../../../hooks/useIsMobile"; import { useStellar } from "../../../provider/StellarContextProvider"; import { walletConfigs } from "../../../wallets/walletConfigs"; @@ -151,30 +153,35 @@ export default function SelectMethod() { // Prefer icon from walletConfigs if there's a name match, otherwise fall back // to the connector-provided icon, and finally to the generic WalletIcon. + // WalletConnect connectors have no name/icon payload — show WC branding. let walletIcon: JSX.Element; - const matchedConfig = Object.values(walletConfigs).find((cfg) => { - if (!cfg.name || !connector?.name) return false; - const cfgName = cfg.name.toLowerCase(); - const connName = connector.name.toLowerCase(); - return cfgName.includes(connName) || connName.includes(cfgName); - }); + if (isWalletConnectConnector(connector?.id)) { + walletIcon = ; + } else { + const matchedConfig = Object.values(walletConfigs).find((cfg) => { + if (!cfg.name || !connector?.name) return false; + const cfgName = cfg.name.toLowerCase(); + const connName = connector.name.toLowerCase(); + return cfgName.includes(connName) || connName.includes(cfgName); + }); - if (matchedConfig?.icon) { - walletIcon = - typeof matchedConfig.icon === "string" ? ( - - ) : ( - (matchedConfig.icon as JSX.Element) + if (matchedConfig?.icon) { + walletIcon = + typeof matchedConfig.icon === "string" ? ( + + ) : ( + (matchedConfig.icon as JSX.Element) + ); + } else if (connector?.icon) { + walletIcon = ( + + + ); - } else if (connector?.icon) { - walletIcon = ( - - - - ); - } else { - walletIcon = ; + } else { + walletIcon = ; + } } const connectedEthWalletOption = { diff --git a/packages/connectkit/src/components/RozoPayModal/index.tsx b/packages/connectkit/src/components/RozoPayModal/index.tsx index 36e19c217..0737ee798 100644 --- a/packages/connectkit/src/components/RozoPayModal/index.tsx +++ b/packages/connectkit/src/components/RozoPayModal/index.tsx @@ -51,6 +51,7 @@ import WaitingDepositAddress from "../Pages/WaitingDepositAddress"; import WaitingExternal from "../Pages/WaitingExternal"; import WaitingWallet from "../Pages/WaitingWallet"; import ConnectUsing from "./ConnectUsing"; +import ConnectWalletConnect from "../Pages/ConnectWalletConnect"; export const RozoPayModal: React.FC<{ mode: Mode; @@ -134,6 +135,8 @@ export const RozoPayModal: React.FC<{ context.setRoute(ROUTES.CONNECT, meta); } else if (context.route === ROUTES.CONNECTORS) { context.setRoute(ROUTES.SELECT_METHOD, meta); + } else if (context.route === ROUTES.CONNECT_WALLETCONNECT) { + context.setRoute(ROUTES.CONNECTORS, meta); } else if (context.route === ROUTES.SELECT_AMOUNT) { setSelectedTokenOption(undefined); context.setRoute(ROUTES.SELECT_TOKEN, meta); @@ -277,6 +280,7 @@ export const RozoPayModal: React.FC<{ [ROUTES.CONNECTORS]: , [ROUTES.MOBILECONNECTORS]: , [ROUTES.CONNECT]: , + [ROUTES.CONNECT_WALLETCONNECT]: , [ROUTES.SWITCHNETWORKS]: , }; diff --git a/packages/connectkit/src/constants/routes.ts b/packages/connectkit/src/constants/routes.ts index 6d0404569..0578a1f1a 100644 --- a/packages/connectkit/src/constants/routes.ts +++ b/packages/connectkit/src/constants/routes.ts @@ -29,6 +29,7 @@ export enum ROUTES { CONNECTORS = "connectors", MOBILECONNECTORS = "mobileConnectors", CONNECT = "connect", + CONNECT_WALLETCONNECT = "rozoPayConnectWalletConnect", DOWNLOAD = "download", SWITCHNETWORKS = "switchNetworks", } diff --git a/packages/connectkit/src/defaultConfig.ts b/packages/connectkit/src/defaultConfig.ts index 5d0fff09f..1f630c642 100644 --- a/packages/connectkit/src/defaultConfig.ts +++ b/packages/connectkit/src/defaultConfig.ts @@ -13,6 +13,11 @@ import { CoinbaseWalletParameters } from "wagmi/connectors"; import defaultConnectors from "./defaultConnectors"; +// Rozo's own WalletConnect Cloud project ID — same one used for Stellar's +// WalletConnectModule (utils/stellar/singleton-import.ts). Consumers can +// override via walletConnectProjectId if they want their own. +const ROZO_WALLETCONNECT_PROJECT_ID = "7440dd8acf85933ffcc775ec6675d4a9"; + // TODO: Move these to a provider rather than global variable let globalAppName: string; let globalAppIcon: string; @@ -32,6 +37,11 @@ type DefaultConfigProps = { // Additional connectors to use additionalConnectors?: CreateConnectorFn[]; + + // WalletConnect Cloud project ID (https://cloud.reown.com). Defaults to + // Rozo's shared project ID for the desktop QR flow. Pass your own to use a + // separate WalletConnect Cloud project. + walletConnectProjectId?: string; } & Partial; /** @@ -70,6 +80,7 @@ const defaultConfig = ({ coinbaseWalletPreference, dataSuffix, additionalConnectors, + walletConnectProjectId = ROZO_WALLETCONNECT_PROJECT_ID, chains = REQUIRED_CHAINS, client, ...props @@ -110,6 +121,7 @@ const defaultConfig = ({ coinbaseWalletPreference, dataSuffix, additionalConnectors, + walletConnectProjectId, }); const config: CreateConfigParameters = { diff --git a/packages/connectkit/src/defaultConnectors.ts b/packages/connectkit/src/defaultConnectors.ts index 666c38642..9c23844b8 100644 --- a/packages/connectkit/src/defaultConnectors.ts +++ b/packages/connectkit/src/defaultConnectors.ts @@ -2,18 +2,73 @@ import { CreateConnectorFn } from "wagmi"; import { coinbaseWallet, CoinbaseWalletParameters, + injected, safe, + walletConnect, } from "wagmi/connectors"; -// ponytail: lazy import walletConnect to avoid pulling pino → pino-pretty into webpack bundle. -// Only imported when walletConnectProjectId is provided. import type { Hex } from "viem"; +// Harden getProvider/connect/setup: WalletConnect's EthereumProvider +// touches indexedDB/localStorage during init and can resolve without a live +// provider in some environments (private browsing, storage quota, a stale +// session). wagmi's own connector code calls `provider.on(...)` right after +// `await getProvider()` with no null-check in the connect() path, so an +// undefined provider throws synchronously inside that async function — +// escapes as an uncaught error instead of a rejected/caught promise. Wrap +// each entry point in a try/catch that rethrows as a real Error, so it +// always surfaces as a normal promise rejection our onError handlers catch. +const hardenConnector = (connector: ReturnType) => { + const wrap = ( + fn: ((...args: A) => Promise) | undefined + ) => { + if (!fn) return fn; + return async (...args: A): Promise => { + try { + return await fn(...args); + } catch (err) { + throw err instanceof Error + ? err + : new Error("WalletConnect connector failed to initialize."); + } + }; + }; + return { + ...connector, + getProvider: wrap(connector.getProvider?.bind(connector)), + connect: wrap(connector.connect?.bind(connector)), + setup: connector.setup + ? async () => { + try { + await connector.setup!(); + } catch { + // setup() isn't awaited by callers expecting a rejection path + // (fire-and-forget in some wagmi versions) — swallow so it can't + // become an unhandled rejection; connect() will retry/fail loud. + } + } + : undefined, + } as ReturnType; +}; + +const hardenConnectorFactory = (fn: CreateConnectorFn): CreateConnectorFn => + ((config: Parameters[0]) => + hardenConnector(fn(config))) as CreateConnectorFn; + // ponytail: module singleton — last-write-wins, never reset, not SSR-safe. // Matches globalAppName/globalAppIcon pattern. Single-config assumption; if // multi-config or SSR is needed, carry dataSuffix on wagmi Config/context instead. let globalDataSuffix: Hex | undefined; export const getDataSuffix = () => globalDataSuffix; +// WalletConnect's Core is itself a module-level singleton inside +// @walletconnect/core — constructing walletConnect() connectors more than +// once per projectId logs "Core is already initialized" (harmless but noisy, +// happens on every dev HMR reload or if a consumer calls getDefaultConfig() +// without memoizing). Cache the factory by projectId so repeated +// defaultConnectors() calls reuse its provider closure. +let cachedWalletConnectProjectId: string | undefined; +let cachedWalletConnectConnector: CreateConnectorFn | undefined; + type DefaultConnectorsProps = { app: { name: string; @@ -79,15 +134,28 @@ const defaultConnectors = ({ }) ); - if (walletConnectProjectId) { - // ponytail: lazy require avoids pino → pino-pretty resolution error in Next.js builds. - // webpack evaluates the full wagmi/connectors barrel when walletConnect is a top-level import. - const wc = require("wagmi/connectors"); - connectors.push( - wc.walletConnect({ - projectId: walletConnectProjectId, - }) - ); + // EIP-6963 injected wallets (MetaMask, Rabby, etc.). With extension present, + // connector names itself after the wallet (e.g. "io.metamask") and connects + // directly. Without extension, generic "injected" name is filtered by useWallets. + connectors.push( + injected({ shimDisconnect: true }) + ); + + // WalletConnect's provider touches indexedDB/localStorage at construction + // time (WalletConnect Core, UniversalProvider) — building it during Next.js + // SSR throws "indexedDB is not defined". Skip on the server; the connector + // is only needed once the modal renders in the browser anyway. + if (walletConnectProjectId && typeof window !== "undefined") { + if (cachedWalletConnectProjectId !== walletConnectProjectId) { + cachedWalletConnectProjectId = walletConnectProjectId; + cachedWalletConnectConnector = hardenConnectorFactory( + walletConnect({ + projectId: walletConnectProjectId, + showQrModal: false, + }) + ); + } + connectors.push(cachedWalletConnectConnector!); } return connectors; diff --git a/packages/connectkit/src/hooks/usePaymentState.ts b/packages/connectkit/src/hooks/usePaymentState.ts index 008ecdb57..22d232fde 100644 --- a/packages/connectkit/src/hooks/usePaymentState.ts +++ b/packages/connectkit/src/hooks/usePaymentState.ts @@ -86,6 +86,7 @@ import { derivePayIdPreferredTokens, resolveDepositSourceAmount, } from "../payment/createPaymentPayload"; +import { waitForPaymentSourceTxHash } from "../payment/waitForPaymentSourceTxHash"; import { PaymentEvent, PayParams } from "../payment/paymentFsm"; import { useAnalytics } from "../provider/AnalyticsProvider"; import { useStellar } from "../provider/StellarContextProvider"; @@ -277,7 +278,7 @@ export function usePaymentState({ }, []); // Wallet state. - const { address: ethWalletAddress } = useAccount(); + const { address: ethWalletAddress, connector: ethConnector } = useAccount(); const senderEnsName = undefined; const { switchChainAsync } = useSwitchChain(); @@ -945,7 +946,8 @@ export function usePaymentState({ const destinationAddress = hydratedOrder.intentAddr; // Execute transaction with optimized error handling - const paymentTxHash = await (async () => { + let transactionRecoveredFromApi = false; + const transactionPromise = (async () => { try { if (isNativeToken) { // dataSuffix intentionally omitted — appending data to bare ETH transfers @@ -1008,7 +1010,7 @@ export function usePaymentState({ }); } } catch (e) { - if (hydratedOrder.externalId) { + if (hydratedOrder.externalId && !transactionRecoveredFromApi) { try { await pay.setPaymentUnpaid(hydratedOrder.externalId); } catch (resetErr) { @@ -1020,6 +1022,34 @@ export function usePaymentState({ } })(); + let paymentTxHash: Hex; + const activePaymentId = paymentId ?? hydratedOrder.externalId ?? undefined; + if (ethConnector?.id === "walletConnect" && activePaymentId) { + // MetaMask Mobile can submit a WalletConnect transaction without ever + // returning the eth_sendTransaction response to the browser. The backend + // still detects the deposit, so race the wallet response against that + // server-confirmed source hash instead of leaving the UI stuck forever. + const pollingController = new AbortController(); + try { + const result = await Promise.race([ + transactionPromise.then((txHash) => ({ txHash, recovered: false })), + waitForPaymentSourceTxHash(activePaymentId, { + signal: pollingController.signal, + ignoreTxHash: hydratedOrder.sourceStartTxHash, + }).then((txHash) => ({ txHash, recovered: true })), + ]); + paymentTxHash = result.txHash; + transactionRecoveredFromApi = result.recovered; + if (result.recovered) { + log?.(`[PAY TOKEN] Recovered WalletConnect tx hash from payment API: ${paymentTxHash}`); + } + } finally { + pollingController.abort(); + } + } else { + paymentTxHash = await transactionPromise; + } + // Set transaction hash and return result setTxHash(paymentTxHash); return { txHash: paymentTxHash, success: true }; diff --git a/packages/connectkit/src/hooks/useTokenOptions.tsx b/packages/connectkit/src/hooks/useTokenOptions.tsx index b0312651e..5f105f737 100644 --- a/packages/connectkit/src/hooks/useTokenOptions.tsx +++ b/packages/connectkit/src/hooks/useTokenOptions.tsx @@ -382,21 +382,43 @@ export function useTokenOptions(mode: "evm" | "solana" | "stellar" | "all"): { isDepositFlow, ]); + // Wallet-switch glitch: on address change, the new fetch is debounced + // (smartRefresh, 300ms) before it even starts, so sortedOptionsList still + // holds the PREVIOUS wallet's stale results (or an empty list) for a beat. + // "sortedOptionsList.length > 0 → never loading" below trusted that stale + // data, flashing "no tokens" before the real list for the new address pops + // in. Track which address the current options actually belong to so a + // mismatch (address changed, fetch not caught up yet) still shows loading. + const { ethWalletAddress, solanaPubKey, stellarPubKey } = paymentState; + const currentAddressKey = `${ethWalletAddress || ""}-${solanaPubKey || ""}-${stellarPubKey || ""}`; + // Tracks the address the most recently SETTLED (isLoading: false) fetch + // belongs to — regardless of whether it came back empty. Only gating on + // "got a non-empty list" (previous version) meant a wallet with zero + // tokens never flipped this, so shouldShowLoading stayed stuck true + // forever instead of settling into a legitimate "no tokens" state. + const settledAddressKey = useRef(""); + if (!isLoading) { + settledAddressKey.current = currentAddressKey; + } + const optionsAreForCurrentAddress = settledAddressKey.current === currentAddressKey; + const shouldShowLoading = useMemo( () => - // Once we have options, don't show loading/skeletons (avoids extra skeleton when - // e.g. EVM+Solana are done but Stellar is still loading in mode "all") - sortedOptionsList.length > 0 + // Once the fetch has settled for the CURRENT address, don't show + // loading/skeletons — regardless of whether it returned any options. + // Stale options (or staleness) from a previous address don't count. + optionsAreForCurrentAddress ? false : connectedWalletOnly && sortedOptionsList.length === 0 && !hasRelevantHooksWithValidParams ? false - : isLoading && (!hasAnyData || sortedOptionsList.length === 0), + : isLoading || !hasAnyData || sortedOptionsList.length === 0, [ connectedWalletOnly, sortedOptionsList, hasRelevantHooksWithValidParams, isLoading, hasAnyData, + optionsAreForCurrentAddress, ], ); diff --git a/packages/connectkit/src/payment/resolveConfirmedPayoutTxHash.ts b/packages/connectkit/src/payment/resolveConfirmedPayoutTxHash.ts new file mode 100644 index 000000000..f0e8dc53d --- /dev/null +++ b/packages/connectkit/src/payment/resolveConfirmedPayoutTxHash.ts @@ -0,0 +1,7 @@ +export function resolveConfirmedPayoutTxHash( + payinTxHash: string | undefined, + payoutTxHash: string | undefined, + sameTxPayout: boolean, +): string | undefined { + return sameTxPayout ? payinTxHash : payoutTxHash; +} diff --git a/packages/connectkit/src/payment/waitForPaymentSourceTxHash.ts b/packages/connectkit/src/payment/waitForPaymentSourceTxHash.ts new file mode 100644 index 000000000..1f924ee2a --- /dev/null +++ b/packages/connectkit/src/payment/waitForPaymentSourceTxHash.ts @@ -0,0 +1,74 @@ +import { getPayment } from "@rozoai/intent-common"; +import { type Hex, isHex } from "viem"; + +type Options = { + signal?: AbortSignal; + intervalMs?: number; + ignoreTxHash?: string | null; + fetchSourceTxHash?: ( + paymentId: string, + signal?: AbortSignal, + ) => Promise; +}; + +const fetchSourceTxHash = async ( + paymentId: string, + signal?: AbortSignal, +): Promise => { + const response = await getPayment(paymentId, "v2", { signal }); + return response.data?.source?.txHash ?? undefined; +}; + +const wait = (ms: number, signal?: AbortSignal) => + new Promise((resolve, reject) => { + let timeout: ReturnType | undefined; + const cleanup = () => signal?.removeEventListener("abort", onAbort); + const onAbort = () => { + if (timeout) clearTimeout(timeout); + cleanup(); + const error = new Error("Aborted"); + error.name = "AbortError"; + reject(error); + }; + + if (signal?.aborted) return onAbort(); + signal?.addEventListener("abort", onAbort, { once: true }); + timeout = setTimeout(() => { + cleanup(); + resolve(); + }, ms); + }); + +/** Recovers an EVM tx hash when a WalletConnect wallet submits but never returns the RPC response. */ +export async function waitForPaymentSourceTxHash( + paymentId: string, + options: Options = {}, +): Promise { + const { + signal, + intervalMs = 1_000, + ignoreTxHash, + fetchSourceTxHash: fetchHash = fetchSourceTxHash, + } = options; + + while (!signal?.aborted) { + try { + const txHash = await fetchHash(paymentId, signal); + if ( + typeof txHash === "string" && + txHash !== ignoreTxHash && + isHex(txHash) + ) { + return txHash; + } + } catch (error) { + if (signal?.aborted) throw error; + } + + await wait(intervalMs, signal); + } + + const error = new Error("Aborted"); + error.name = "AbortError"; + throw error; +} diff --git a/packages/connectkit/src/utils/index.ts b/packages/connectkit/src/utils/index.ts index 5342c5c1b..b1590795c 100644 --- a/packages/connectkit/src/utils/index.ts +++ b/packages/connectkit/src/utils/index.ts @@ -89,6 +89,9 @@ export const isSafeConnector = (connectorId?: string) => connectorId === "safe"; export const isInjectedConnector = (connectorId?: string) => connectorId === "injected"; +export const isWalletConnectConnector = (connectorId?: string) => + connectorId === "walletConnect"; + export function parseError(e: any) { return { code: e?.error?.code || e?.code || -1, diff --git a/packages/connectkit/src/wallets/useWallets.tsx b/packages/connectkit/src/wallets/useWallets.tsx index 94f894c38..7d1a77304 100644 --- a/packages/connectkit/src/wallets/useWallets.tsx +++ b/packages/connectkit/src/wallets/useWallets.tsx @@ -2,7 +2,7 @@ import { assertNotNull } from "@rozoai/intent-common"; import { Connector } from "wagmi"; import { useWallet as useSolanaWalletAdapter } from "@solana/wallet-adapter-react"; -import Logos, { SquircleIcon } from "../assets/logos"; +import Logos, { SquircleIcon, WalletConnect } from "../assets/logos"; import { useConnectors } from "../hooks/useConnectors"; import { usePayContext } from "../hooks/usePayContext"; import { SolanaWalletName } from "../provider/SolanaContextProvider"; @@ -10,6 +10,7 @@ import { isCoinbaseWalletConnector, isInjectedConnector, isPhantomConnector, + isWalletConnectConnector, } from "../utils"; import { WalletConfigProps, walletConfigs } from "./walletConfigs"; @@ -65,6 +66,9 @@ export const useWallets = (isMobile?: boolean): WalletProps[] => { } } + // WalletConnect is desktop-only. This mobile list includes injected + // connectors and direct wallet deeplinks, not the desktop QR connector. + // Add injected wallet (if any) first, unless disabled if (!disableMobileInjector) { connectors.forEach((connector) => { @@ -141,13 +145,11 @@ export const useWallets = (isMobile?: boolean): WalletProps[] => { } const filteredConnectors = connectors.filter((connector) => { - // Skip if id === "phantom" or "injected" and connector name does NOT include "walletconnect" if ( ["phantom"].includes(connector.id) || (connector.id === "injected" && connector.name?.toLowerCase().includes("injected") && - connector.type === "injected") || - connector.name?.toLowerCase().includes("walletconnect") + connector.type === "injected") ) { return false; } @@ -155,6 +157,19 @@ export const useWallets = (isMobile?: boolean): WalletProps[] => { }); const wallets = filteredConnectors.map((connector): WalletProps => { + // WalletConnect: dedicated tile, our own QR + copy page (see + // ConnectWalletConnect) instead of matching against walletConfigs. + if (isWalletConnectConnector(connector.id)) { + return { + id: connector.id, + name: "WalletConnect", + connector, + iconConnector: , + iconShape: "squircle", + isInstalled: true, + }; + } + // First, attempt to find a config by matching connector.id (existing logic). let walletConfigKey: string | undefined = Object.keys(walletConfigs).find( (id) => @@ -214,6 +229,40 @@ export const useWallets = (isMobile?: boolean): WalletProps[] => { return c; }); + // Desktop, no injected EVM provider (e.g. incognito / no extension): the + // only live connector is Coinbase's SDK, so the curated tiles vanish. + // Surface major wallets as stubs that route through the WalletConnect QR — + // any WC wallet can scan it, no extension needed. Desktop-only: this whole + // branch runs after the mobile early-return above. + // Check window.ethereum, not the connector list — defaultConnectors() never + // adds an injected() connector, so wagmi's list is empty even when a wallet + // extension IS installed (then it arrives via EIP-6963 / additionalConnectors). + const hasInjectedProvider = + typeof window !== "undefined" && window.ethereum != null; + const hasWalletConnect = wallets.some((w) => isWalletConnectConnector(w.id)); + // ponytail: name-fuzzy dedupe vs live injected wallets; exact-id matching if + // collisions ever show duplicates. + if (!hasInjectedProvider && hasWalletConnect) { + Object.entries(walletConfigs).forEach(([key, cfg]) => { + if (!cfg.walletConnectFallback) return; + const cfgName = (cfg.name ?? "").toLowerCase(); + if (wallets.some((w) => { + const n = (w.name ?? "").toLowerCase(); + return n && cfgName && (n.includes(cfgName) || cfgName.includes(n)); + })) return; + wallets.push({ + id: `wc-fallback-${key}`, + name: cfg.name, + shortName: cfg.shortName, + icon: cfg.icon, + iconConnector: cfg.iconConnector, + iconShape: cfg.iconShape, + iconShouldShrink: cfg.iconShouldShrink, + walletConnectFallback: true, + }); + }); + } + // wallets.push({ // id: WALLET_ID_MOBILE_WALLETS, // name: "Mobile Wallets", diff --git a/packages/connectkit/src/wallets/walletConfigs.tsx b/packages/connectkit/src/wallets/walletConfigs.tsx index 6cf148adc..47b9dc3ca 100644 --- a/packages/connectkit/src/wallets/walletConfigs.tsx +++ b/packages/connectkit/src/wallets/walletConfigs.tsx @@ -76,6 +76,9 @@ export type WalletConfigProps = { // Used to filter wallets that only support solana in mobile mode to not show in the connector options when the payID doesn't support solana isSolanaOnly?: boolean; // Used to filter wallets that only support stellar in mobile mode to not show in the connector options when the payID doesn't support stellar + // Desktop no-extension fallback: tile routes through the WalletConnect QR + // (any WC wallet can scan it) instead of requiring an injected connector. + walletConnectFallback?: boolean; isStellarOnly?: boolean; }; @@ -203,7 +206,7 @@ export const walletConfigs: { customDeeplink ?? getRozoPayUrl(payId, appId) }`; }, - showInMobileConnectors: true, + walletConnectFallback: true, }, "metaMask, metaMask-io, io.metamask, io.metamask.mobile, metaMaskSDK": { name: "MetaMask", @@ -242,6 +245,7 @@ export const walletConfigs: { "" )}`; }, + walletConnectFallback: true, }, "app.phantom": { name: "Phantom", @@ -313,8 +317,8 @@ export const walletConfigs: { ios: "https://apps.apple.com/app/rainbow-ethereum-wallet/id1457119021?pt=119997837&ct=rozopay&mt=8", chrome: "https://rainbow.me/extension?utm_source=rozopay", edge: "https://rainbow.me/extension?utm_source=rozopay", - brave: "https://rainbow.me/extension?utm_source=rozopay", }, + walletConnectFallback: true, showInMobileConnectors: true, deeplinkScheme: "rainbow://", getRozoPayDeeplink: ({ @@ -354,8 +358,8 @@ export const walletConfigs: { download: "https://connect.family.co/v0/download/trust", android: "https://play.google.com/store/apps/details?id=com.wallet.crypto.trustapp", - ios: "https://apps.apple.com/app/trust-crypto-bitcoin-wallet/id1288339409", }, + walletConnectFallback: true, showInMobileConnectors: true, deeplinkScheme: "trust://", getRozoPayDeeplink: ({ @@ -376,6 +380,7 @@ export const walletConfigs: { }, okx: { name: "OKX", + walletConnectFallback: true, icon: , showInMobileConnectors: true, deeplinkScheme: "okx://", diff --git a/packages/connectkit/test/resolveConfirmedPayoutTxHash.test.ts b/packages/connectkit/test/resolveConfirmedPayoutTxHash.test.ts new file mode 100644 index 000000000..b679c4ecb --- /dev/null +++ b/packages/connectkit/test/resolveConfirmedPayoutTxHash.test.ts @@ -0,0 +1,14 @@ +import { describe, expect, it } from "vitest"; +import { resolveConfirmedPayoutTxHash } from "../src/payment/resolveConfirmedPayoutTxHash.js"; + +describe("resolveConfirmedPayoutTxHash", () => { + it("uses destination hash for bridged payouts and payin hash for same-tx settlement", () => { + expect(resolveConfirmedPayoutTxHash("source", "destination", false)).toBe( + "destination", + ); + expect(resolveConfirmedPayoutTxHash("source", "destination", true)).toBe( + "source", + ); + expect(resolveConfirmedPayoutTxHash("source", undefined, false)).toBeUndefined(); + }); +}); diff --git a/packages/connectkit/test/waitForPaymentSourceTxHash.test.ts b/packages/connectkit/test/waitForPaymentSourceTxHash.test.ts new file mode 100644 index 000000000..d875e4995 --- /dev/null +++ b/packages/connectkit/test/waitForPaymentSourceTxHash.test.ts @@ -0,0 +1,21 @@ +import { describe, expect, it } from "vitest"; +import { waitForPaymentSourceTxHash } from "../src/payment/waitForPaymentSourceTxHash.js"; + +const oldHash = `0x${"1".repeat(64)}`; +const newHash = `0x${"2".repeat(64)}`; + +describe("waitForPaymentSourceTxHash", () => { + it("waits for a new backend-confirmed source transaction", async () => { + const hashes = [oldHash, undefined, newHash]; + let calls = 0; + + const result = await waitForPaymentSourceTxHash("payment-id", { + intervalMs: 0, + ignoreTxHash: oldHash, + fetchSourceTxHash: async () => hashes[calls++], + }); + + expect(result).toBe(newHash); + expect(calls).toBe(3); + }); +}); diff --git a/packages/pay-common/package.json b/packages/pay-common/package.json index 9711edc7c..f718e65c8 100644 --- a/packages/pay-common/package.json +++ b/packages/pay-common/package.json @@ -1,6 +1,6 @@ { "name": "@rozoai/intent-common", - "version": "0.1.35", + "version": "0.1.36", "description": "Intent Pay shared types and utilities", "homepage": "https://github.com/RozoAI/intent-pay", "license": "BSD-2-Clause", diff --git a/packages/pay-common/src/rozoPay.ts b/packages/pay-common/src/rozoPay.ts index 4e02b5019..c5e91d115 100644 --- a/packages/pay-common/src/rozoPay.ts +++ b/packages/pay-common/src/rozoPay.ts @@ -160,6 +160,11 @@ export const zRozoPayOrderMetadata = z.object({ // Source-side token symbol (e.g. "SOL", "ETH", "USDC"). Paired with // `sourceAmountUnits` above. sourceTokenSymbol: z.string().nullish(), + // Written by formatPaymentResponseToHydratedOrder for stellar_direct flows + // (see Confirmation isStellarDirectSameTx — skip payout wait when same tx). + settlementMode: z.string().optional(), + payinTransactionHash: z.string().nullish(), + payoutTransactionHash: z.string().nullish(), }); export type RozoPayOrderMetadata = z.infer; diff --git a/packages/pay-common/tsconfig.json b/packages/pay-common/tsconfig.json index 322475e28..8d09f815d 100644 --- a/packages/pay-common/tsconfig.json +++ b/packages/pay-common/tsconfig.json @@ -1,6 +1,10 @@ { "extends": "@tsconfig/node20/tsconfig.json", "compilerOptions": { + // ponytail: node16 resolution treats viem>=2.28 (_types is {"type":"module"}) as + // ESM-only, breaking CJS imports. Classic "node" resolution ignores it. + "module": "commonjs", + "moduleResolution": "node", "strict": true, "resolveJsonModule": true, "sourceMap": true, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7f4f54bc7..c43102a41 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -19,6 +19,15 @@ overrides: '@walletconnect/sign-client': 2.23.10 '@walletconnect/universal-provider': 2.23.10 '@walletconnect/ethereum-provider': 2.23.10 + '@reown/appkit': 1.8.23 + '@reown/appkit-common': 1.8.23 + '@reown/appkit-controllers': 1.8.23 + '@reown/appkit-pay': 1.8.23 + '@reown/appkit-polyfills': 1.8.23 + '@reown/appkit-scaffold-ui': 1.8.23 + '@reown/appkit-ui': 1.8.23 + '@reown/appkit-utils': 1.8.23 + '@reown/appkit-wallet': 1.8.23 importers: @@ -49,11 +58,11 @@ importers: specifier: ^1.9.5 version: 1.9.5(9cefe9a0cf1871d579912eca36ef5853) '@rozoai/intent-common': - specifier: 0.1.35 - version: 0.1.35(bufferutil@4.1.0)(typescript@5.5.2)(utf-8-validate@6.0.6)(viem@2.56.3(bufferutil@4.1.0)(typescript@5.5.2)(utf-8-validate@6.0.6)(zod@3.25.76)) + specifier: 0.1.36 + version: 0.1.36(bufferutil@4.1.0)(typescript@5.5.2)(utf-8-validate@6.0.6)(viem@2.56.3(bufferutil@4.1.0)(typescript@5.5.2)(utf-8-validate@6.0.6)(zod@3.25.76)) '@rozoai/intent-pay': - specifier: 0.1.45 - version: 0.1.45(ac1985f42b143b3498df95d95a007ae9) + specifier: 0.1.46-beta.2 + version: 0.1.46-beta.2(ac1985f42b143b3498df95d95a007ae9) '@stellar/stellar-sdk': specifier: ^14.4.3 version: 14.6.1 @@ -158,7 +167,7 @@ importers: specifier: ^1.9.5 version: 1.9.5(9cefe9a0cf1871d579912eca36ef5853) '@reown/appkit': - specifier: ^1.7.0 + specifier: 1.8.23 version: 1.8.23(@react-native-async-storage/async-storage@1.24.0(react-native@0.87.1(@babel/core@7.29.7)(@types/react@18.3.31)(bufferutil@4.1.0)(react@18.2.0)(utf-8-validate@6.0.6)))(@types/react@18.3.31)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react@18.2.0)(typescript@5.5.2)(use-sync-external-store@1.6.0(react@18.2.0))(utf-8-validate@6.0.6)(zod@4.5.4) '@rollup/plugin-image': specifier: ^3.0.3 @@ -167,8 +176,8 @@ importers: specifier: ^12.1.2 version: 12.3.0(rollup@4.63.1)(tslib@2.8.1)(typescript@5.5.2) '@rozoai/intent-common': - specifier: 0.1.35 - version: 0.1.35(bufferutil@4.1.0)(typescript@5.5.2)(utf-8-validate@6.0.6)(viem@2.56.3(bufferutil@4.1.0)(typescript@5.5.2)(utf-8-validate@6.0.6)(zod@4.5.4)) + specifier: 0.1.36 + version: 0.1.36(bufferutil@4.1.0)(typescript@5.5.2)(utf-8-validate@6.0.6)(viem@2.56.3(bufferutil@4.1.0)(typescript@5.5.2)(utf-8-validate@6.0.6)(zod@4.5.4)) '@solana/spl-memo': specifier: ^0.2.5 version: 0.2.5(@solana/web3.js@1.98.4(bufferutil@4.1.0)(typescript@5.5.2)(utf-8-validate@6.0.6)) @@ -2524,61 +2533,32 @@ packages: '@types/react': optional: true - '@reown/appkit-common@1.8.19': - resolution: {integrity: sha512-z5wDrYjUGY7YbM4b14NHVo54WKZ5++PQtGkcsXhiOP39yAVijubBQD8BfHs/Pu2fSFqnqLIFoCVvIEfNWWccRw==} - '@reown/appkit-common@1.8.23': resolution: {integrity: sha512-6rl19bQvgXTKsN99wza3AOjZyhKI/9tUo9Jfqg+5aV4TPn3fK9OV6jVuPAQKXtujbM6kkjb6TbVizWqXMLIo7Q==} - '@reown/appkit-controllers@1.8.19': - resolution: {integrity: sha512-JFNT8CfAVit9FJXh596Ye4U8A/oIapW+Y0KQqjB59DXyTCDZbxZDB32rULBQrSkZ6PufTEa239Dil4kABCQKtg==} - '@reown/appkit-controllers@1.8.23': resolution: {integrity: sha512-nNG7Xp9bjEhyBj7F7nuStXbg1k0Vv7gteqI2TyKD8Bbov1F7j/KyjC2WQoYqfvhOSZtX361FZdemqvrQjT7ytw==} - '@reown/appkit-pay@1.8.19': - resolution: {integrity: sha512-HO/tQT0TbTQO3eONxNNPJAOZAOzUiHvjM0Mty1rFFeRBH68auiqQxQi2YFNMs014gNkRN+cb84VYau7+MCC0fQ==} - '@reown/appkit-pay@1.8.23': resolution: {integrity: sha512-uYkCOeDzCE/rPWVl8qL2dj058RvzOaXSgnrkTGZ92tmEwr5Km23U3v2KeEhLhUw0JYTlVLyTrM44zYQr5j1Y0Q==} - '@reown/appkit-polyfills@1.8.19': - resolution: {integrity: sha512-PSoetRSuZg7f2YFPzdfs4BayQl51zcGqYr7frwOe6td0XEsspLrrVFn/zk5QFbFHZVsMdfRZ+TTunt84ozRdnQ==} - '@reown/appkit-polyfills@1.8.23': resolution: {integrity: sha512-4UtoYy9Nva0/iDwSqiX+EuD0Kpgy+TM2+nry+un/i0zbjshmiepBPyuc3ds52T8agjq2yQKJ9SapA9O+KT9PlA==} - '@reown/appkit-scaffold-ui@1.8.19': - resolution: {integrity: sha512-Ak767x0VzeDIXb0wbzkl19kx6udw7vkb1EU0SAweG3iKc9BunW87Rfcd48/YimzMZycJaYmlbtfmqQQDYs6Few==} - '@reown/appkit-scaffold-ui@1.8.23': resolution: {integrity: sha512-wR3g5bgojukamAdDCMs1PFEdpx69FLoFvMontSzRsV2MKYaUOqYycw6mJsMPmA4t+LCt5IU3otClTT+ONOp7UA==} - '@reown/appkit-ui@1.8.19': - resolution: {integrity: sha512-fCAwW8yyyC3JcgKLBPvCtYuDGC4H8anO7u4LTaAXGEzdcU5H+IrCgNFSPNK7NuTSmgXm1TnoYxPxRFKNiNwFdA==} - '@reown/appkit-ui@1.8.23': resolution: {integrity: sha512-wR1+CWh0hKM4jIW7fMOdXofIUwX3TaeyJyUQ6jxXc0S/iu80S/nEoa/i5VW0qvtBAcRmnzoAtd7zRG5e8b5c1w==} - '@reown/appkit-utils@1.8.19': - resolution: {integrity: sha512-VQPgUMTFqoh4UD3EDZSw9wyMkyZsmIVmu8CdQ2FUxIuqYW4fLd0VIpkDeO64MMhSv8b0X8Vd6m4+eGcqSwlUAg==} - peerDependencies: - valtio: 2.1.7 - '@reown/appkit-utils@1.8.23': resolution: {integrity: sha512-7M2pL5LqCgII1jpTqNLPtjC774yyUP8Mh2EHKYTLXW0NtSO+K8R5DfSfMygKcSiLiELe9LBVqpB4gBRML3R7zg==} peerDependencies: valtio: 2.1.7 - '@reown/appkit-wallet@1.8.19': - resolution: {integrity: sha512-NVdIKceUhkXYtsG32925ctmVn0QJFNyDlr+mWheMLCEZ/IUPn+6aA53vTVaSUquhyeFxUXtrCOh3ln6v1tup5w==} - '@reown/appkit-wallet@1.8.23': resolution: {integrity: sha512-IMcBTCN7jONQ3J2sjT2b3ZVAgzgn6RXh8kQf4/0cO6c0ukpQaka9/uW7BTApizRepSfAui9XuhXSZ5XOfJFnNg==} - '@reown/appkit@1.8.19': - resolution: {integrity: sha512-wB+xatkRbOy0AY1cZxxtcKzzPk3l3CTFulDbaISLVmZI6ZnQrOFuLnYc285zGsC6DB4d6bmwYUh89zcMLa4PvQ==} - '@reown/appkit@1.8.23': resolution: {integrity: sha512-oW97J0ZJ1tEsrdDz2fzilsP8m0+9q8CT0uxMOpZbz3ZTkpn4Vo7QCafAbTTYVO5XYjIWztoQtXCW/McGc0hWbg==} @@ -2760,13 +2740,13 @@ packages: cpu: [x64] os: [win32] - '@rozoai/intent-common@0.1.35': - resolution: {integrity: sha512-VPTOwTufryC33ZlbS5ktZ2IX0DGrtNKE3bINrAX+Y8Q+xzxhk4xhn1rD0p0LmqvlwWEiDRx12w9WQujj/FmOYw==} + '@rozoai/intent-common@0.1.36': + resolution: {integrity: sha512-0uUT2UsC+Ab33sPSMQ/m6PZjQwEHSWuYawB0ZOTrp3N00IkLQULSA/c5TpaY3orCS8TMOgSLW5XjL+C6eFeDSQ==} peerDependencies: viem: ^2.23.2 - '@rozoai/intent-pay@0.1.45': - resolution: {integrity: sha512-LuKFvpCs+SIVzE03DQxJ4JrZpj8ESb028HcRZ1yh0dPvsR3pubiGk9KSAOhS9Jvv1NClrNXN149t/tCK65SoKw==} + '@rozoai/intent-pay@0.1.46-beta.2': + resolution: {integrity: sha512-k/evRTKKEEeegavRW89XGBe2Mfmt01QdgGGG7EEiMY8SjtoN8bw3Gtp4EKUkYm2bWBqsKz15n9XJagGWueaSyw==} engines: {node: '>=12.4'} peerDependencies: '@creit.tech/stellar-wallets-kit': ^1.9.5 @@ -11400,28 +11380,6 @@ snapshots: optionalDependencies: '@types/react': 18.3.31 - '@reown/appkit-common@1.8.19(bufferutil@4.1.0)(typescript@5.5.2)(utf-8-validate@6.0.6)(zod@3.22.4)': - dependencies: - big.js: 6.2.2 - dayjs: 1.11.13 - viem: 2.56.3(bufferutil@4.1.0)(typescript@5.5.2)(utf-8-validate@6.0.6)(zod@3.22.4) - transitivePeerDependencies: - - bufferutil - - typescript - - utf-8-validate - - zod - - '@reown/appkit-common@1.8.19(bufferutil@4.1.0)(typescript@5.5.2)(utf-8-validate@6.0.6)(zod@4.5.4)': - dependencies: - big.js: 6.2.2 - dayjs: 1.11.13 - viem: 2.56.3(bufferutil@4.1.0)(typescript@5.5.2)(utf-8-validate@6.0.6)(zod@4.5.4) - transitivePeerDependencies: - - bufferutil - - typescript - - utf-8-validate - - zod - '@reown/appkit-common@1.8.23(bufferutil@4.1.0)(typescript@5.5.2)(utf-8-validate@6.0.6)(zod@3.22.4)': dependencies: big.js: 6.2.2 @@ -11444,41 +11402,6 @@ snapshots: - utf-8-validate - zod - '@reown/appkit-controllers@1.8.19(@react-native-async-storage/async-storage@1.24.0(react-native@0.87.1(@babel/core@7.29.7)(@types/react@18.3.31)(bufferutil@4.1.0)(react@18.2.0)(utf-8-validate@6.0.6)))(@types/react@18.3.31)(bufferutil@4.1.0)(react@18.2.0)(typescript@5.5.2)(utf-8-validate@6.0.6)(zod@4.5.4)': - dependencies: - '@reown/appkit-common': 1.8.19(bufferutil@4.1.0)(typescript@5.5.2)(utf-8-validate@6.0.6)(zod@4.5.4) - '@reown/appkit-wallet': 1.8.19(bufferutil@4.1.0)(typescript@5.5.2)(utf-8-validate@6.0.6) - '@walletconnect/universal-provider': 2.23.10(@react-native-async-storage/async-storage@1.24.0(react-native@0.87.1(@babel/core@7.29.7)(@types/react@18.3.31)(bufferutil@4.1.0)(react@18.2.0)(utf-8-validate@6.0.6)))(bufferutil@4.1.0)(typescript@5.5.2)(utf-8-validate@6.0.6)(zod@4.5.4) - valtio: 2.1.7(@types/react@18.3.31)(react@18.2.0) - viem: 2.56.3(bufferutil@4.1.0)(typescript@5.5.2)(utf-8-validate@6.0.6)(zod@4.5.4) - transitivePeerDependencies: - - '@azure/app-configuration' - - '@azure/cosmos' - - '@azure/data-tables' - - '@azure/identity' - - '@azure/keyvault-secrets' - - '@azure/storage-blob' - - '@capacitor/preferences' - - '@deno/kv' - - '@netlify/blobs' - - '@planetscale/database' - - '@react-native-async-storage/async-storage' - - '@types/react' - - '@upstash/redis' - - '@vercel/blob' - - '@vercel/functions' - - '@vercel/kv' - - aws4fetch - - bufferutil - - db0 - - encoding - - ioredis - - react - - typescript - - uploadthing - - utf-8-validate - - zod - '@reown/appkit-controllers@1.8.23(@react-native-async-storage/async-storage@1.24.0(react-native@0.87.1(@babel/core@7.29.7)(@types/react@18.3.31)(bufferutil@4.1.0)(react@18.2.0)(utf-8-validate@6.0.6)))(@types/react@18.3.31)(bufferutil@4.1.0)(react@18.2.0)(typescript@5.5.2)(utf-8-validate@6.0.6)(zod@4.5.4)': dependencies: '@reown/appkit-common': 1.8.23(bufferutil@4.1.0)(typescript@5.5.2)(utf-8-validate@6.0.6)(zod@4.5.4) @@ -11514,50 +11437,6 @@ snapshots: - utf-8-validate - zod - '@reown/appkit-pay@1.8.19(@react-native-async-storage/async-storage@1.24.0(react-native@0.87.1(@babel/core@7.29.7)(@types/react@18.3.31)(bufferutil@4.1.0)(react@18.2.0)(utf-8-validate@6.0.6)))(@types/react@18.3.31)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react@18.2.0)(typescript@5.5.2)(use-sync-external-store@1.4.0(react@18.2.0))(utf-8-validate@6.0.6)(zod@4.5.4)': - dependencies: - '@reown/appkit-common': 1.8.19(bufferutil@4.1.0)(typescript@5.5.2)(utf-8-validate@6.0.6)(zod@4.5.4) - '@reown/appkit-controllers': 1.8.19(@react-native-async-storage/async-storage@1.24.0(react-native@0.87.1(@babel/core@7.29.7)(@types/react@18.3.31)(bufferutil@4.1.0)(react@18.2.0)(utf-8-validate@6.0.6)))(@types/react@18.3.31)(bufferutil@4.1.0)(react@18.2.0)(typescript@5.5.2)(utf-8-validate@6.0.6)(zod@4.5.4) - '@reown/appkit-ui': 1.8.19(@react-native-async-storage/async-storage@1.24.0(react-native@0.87.1(@babel/core@7.29.7)(@types/react@18.3.31)(bufferutil@4.1.0)(react@18.2.0)(utf-8-validate@6.0.6)))(@types/react@18.3.31)(bufferutil@4.1.0)(react@18.2.0)(typescript@5.5.2)(utf-8-validate@6.0.6)(zod@4.5.4) - '@reown/appkit-utils': 1.8.19(@react-native-async-storage/async-storage@1.24.0(react-native@0.87.1(@babel/core@7.29.7)(@types/react@18.3.31)(bufferutil@4.1.0)(react@18.2.0)(utf-8-validate@6.0.6)))(@types/react@18.3.31)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react@18.2.0)(typescript@5.5.2)(use-sync-external-store@1.4.0(react@18.2.0))(utf-8-validate@6.0.6)(valtio@2.1.7(@types/react@18.3.31)(react@18.2.0))(zod@4.5.4) - lit: 3.3.0 - valtio: 2.1.7(@types/react@18.3.31)(react@18.2.0) - transitivePeerDependencies: - - '@azure/app-configuration' - - '@azure/cosmos' - - '@azure/data-tables' - - '@azure/identity' - - '@azure/keyvault-secrets' - - '@azure/storage-blob' - - '@capacitor/preferences' - - '@deno/kv' - - '@netlify/blobs' - - '@planetscale/database' - - '@react-native-async-storage/async-storage' - - '@types/react' - - '@upstash/redis' - - '@vercel/blob' - - '@vercel/functions' - - '@vercel/kv' - - '@x402/core' - - '@x402/evm' - - '@x402/extensions' - - '@x402/svm' - - aws4fetch - - bufferutil - - db0 - - debug - - encoding - - fastestsmallesttextencoderdecoder - - immer - - ioredis - - react - - typescript - - uploadthing - - use-sync-external-store - - utf-8-validate - - zod - '@reown/appkit-pay@1.8.23(@react-native-async-storage/async-storage@1.24.0(react-native@0.87.1(@babel/core@7.29.7)(@types/react@18.3.31)(bufferutil@4.1.0)(react@18.2.0)(utf-8-validate@6.0.6)))(@types/react@18.3.31)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react@18.2.0)(typescript@5.5.2)(use-sync-external-store@1.4.0(react@18.2.0))(utf-8-validate@6.0.6)(zod@4.5.4)': dependencies: '@reown/appkit-common': 1.8.23(bufferutil@4.1.0)(typescript@5.5.2)(utf-8-validate@6.0.6)(zod@4.5.4) @@ -11646,60 +11525,10 @@ snapshots: - utf-8-validate - zod - '@reown/appkit-polyfills@1.8.19': - dependencies: - buffer: 6.0.3 - '@reown/appkit-polyfills@1.8.23': dependencies: buffer: 6.0.3 - '@reown/appkit-scaffold-ui@1.8.19(@react-native-async-storage/async-storage@1.24.0(react-native@0.87.1(@babel/core@7.29.7)(@types/react@18.3.31)(bufferutil@4.1.0)(react@18.2.0)(utf-8-validate@6.0.6)))(@types/react@18.3.31)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react@18.2.0)(typescript@5.5.2)(use-sync-external-store@1.4.0(react@18.2.0))(utf-8-validate@6.0.6)(valtio@2.1.7(@types/react@18.3.31)(react@18.2.0))(zod@4.5.4)': - dependencies: - '@reown/appkit-common': 1.8.19(bufferutil@4.1.0)(typescript@5.5.2)(utf-8-validate@6.0.6)(zod@4.5.4) - '@reown/appkit-controllers': 1.8.19(@react-native-async-storage/async-storage@1.24.0(react-native@0.87.1(@babel/core@7.29.7)(@types/react@18.3.31)(bufferutil@4.1.0)(react@18.2.0)(utf-8-validate@6.0.6)))(@types/react@18.3.31)(bufferutil@4.1.0)(react@18.2.0)(typescript@5.5.2)(utf-8-validate@6.0.6)(zod@4.5.4) - '@reown/appkit-pay': 1.8.19(@react-native-async-storage/async-storage@1.24.0(react-native@0.87.1(@babel/core@7.29.7)(@types/react@18.3.31)(bufferutil@4.1.0)(react@18.2.0)(utf-8-validate@6.0.6)))(@types/react@18.3.31)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react@18.2.0)(typescript@5.5.2)(use-sync-external-store@1.4.0(react@18.2.0))(utf-8-validate@6.0.6)(zod@4.5.4) - '@reown/appkit-ui': 1.8.19(@react-native-async-storage/async-storage@1.24.0(react-native@0.87.1(@babel/core@7.29.7)(@types/react@18.3.31)(bufferutil@4.1.0)(react@18.2.0)(utf-8-validate@6.0.6)))(@types/react@18.3.31)(bufferutil@4.1.0)(react@18.2.0)(typescript@5.5.2)(utf-8-validate@6.0.6)(zod@4.5.4) - '@reown/appkit-utils': 1.8.19(@react-native-async-storage/async-storage@1.24.0(react-native@0.87.1(@babel/core@7.29.7)(@types/react@18.3.31)(bufferutil@4.1.0)(react@18.2.0)(utf-8-validate@6.0.6)))(@types/react@18.3.31)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react@18.2.0)(typescript@5.5.2)(use-sync-external-store@1.4.0(react@18.2.0))(utf-8-validate@6.0.6)(valtio@2.1.7(@types/react@18.3.31)(react@18.2.0))(zod@4.5.4) - '@reown/appkit-wallet': 1.8.19(bufferutil@4.1.0)(typescript@5.5.2)(utf-8-validate@6.0.6) - lit: 3.3.0 - transitivePeerDependencies: - - '@azure/app-configuration' - - '@azure/cosmos' - - '@azure/data-tables' - - '@azure/identity' - - '@azure/keyvault-secrets' - - '@azure/storage-blob' - - '@capacitor/preferences' - - '@deno/kv' - - '@netlify/blobs' - - '@planetscale/database' - - '@react-native-async-storage/async-storage' - - '@types/react' - - '@upstash/redis' - - '@vercel/blob' - - '@vercel/functions' - - '@vercel/kv' - - '@x402/core' - - '@x402/evm' - - '@x402/extensions' - - '@x402/svm' - - aws4fetch - - bufferutil - - db0 - - debug - - encoding - - fastestsmallesttextencoderdecoder - - immer - - ioredis - - react - - typescript - - uploadthing - - use-sync-external-store - - utf-8-validate - - valtio - - zod - '@reown/appkit-scaffold-ui@1.8.23(@react-native-async-storage/async-storage@1.24.0(react-native@0.87.1(@babel/core@7.29.7)(@types/react@18.3.31)(bufferutil@4.1.0)(react@18.2.0)(utf-8-validate@6.0.6)))(@types/react@18.3.31)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react@18.2.0)(typescript@5.5.2)(use-sync-external-store@1.4.0(react@18.2.0))(utf-8-validate@6.0.6)(valtio@2.1.7(@types/react@18.3.31)(react@18.2.0))(zod@4.5.4)': dependencies: '@reown/appkit-common': 1.8.23(bufferutil@4.1.0)(typescript@5.5.2)(utf-8-validate@6.0.6)(zod@4.5.4) @@ -11792,42 +11621,6 @@ snapshots: - valtio - zod - '@reown/appkit-ui@1.8.19(@react-native-async-storage/async-storage@1.24.0(react-native@0.87.1(@babel/core@7.29.7)(@types/react@18.3.31)(bufferutil@4.1.0)(react@18.2.0)(utf-8-validate@6.0.6)))(@types/react@18.3.31)(bufferutil@4.1.0)(react@18.2.0)(typescript@5.5.2)(utf-8-validate@6.0.6)(zod@4.5.4)': - dependencies: - '@phosphor-icons/webcomponents': 2.1.5 - '@reown/appkit-common': 1.8.19(bufferutil@4.1.0)(typescript@5.5.2)(utf-8-validate@6.0.6)(zod@4.5.4) - '@reown/appkit-controllers': 1.8.19(@react-native-async-storage/async-storage@1.24.0(react-native@0.87.1(@babel/core@7.29.7)(@types/react@18.3.31)(bufferutil@4.1.0)(react@18.2.0)(utf-8-validate@6.0.6)))(@types/react@18.3.31)(bufferutil@4.1.0)(react@18.2.0)(typescript@5.5.2)(utf-8-validate@6.0.6)(zod@4.5.4) - '@reown/appkit-wallet': 1.8.19(bufferutil@4.1.0)(typescript@5.5.2)(utf-8-validate@6.0.6) - lit: 3.3.0 - qrcode: 1.5.3 - transitivePeerDependencies: - - '@azure/app-configuration' - - '@azure/cosmos' - - '@azure/data-tables' - - '@azure/identity' - - '@azure/keyvault-secrets' - - '@azure/storage-blob' - - '@capacitor/preferences' - - '@deno/kv' - - '@netlify/blobs' - - '@planetscale/database' - - '@react-native-async-storage/async-storage' - - '@types/react' - - '@upstash/redis' - - '@vercel/blob' - - '@vercel/functions' - - '@vercel/kv' - - aws4fetch - - bufferutil - - db0 - - encoding - - ioredis - - react - - typescript - - uploadthing - - utf-8-validate - - zod - '@reown/appkit-ui@1.8.23(@react-native-async-storage/async-storage@1.24.0(react-native@0.87.1(@babel/core@7.29.7)(@types/react@18.3.31)(bufferutil@4.1.0)(react@18.2.0)(utf-8-validate@6.0.6)))(@types/react@18.3.31)(bufferutil@4.1.0)(react@18.2.0)(typescript@5.5.2)(utf-8-validate@6.0.6)(zod@4.5.4)': dependencies: '@phosphor-icons/webcomponents': 2.1.5 @@ -11864,57 +11657,6 @@ snapshots: - utf-8-validate - zod - '@reown/appkit-utils@1.8.19(@react-native-async-storage/async-storage@1.24.0(react-native@0.87.1(@babel/core@7.29.7)(@types/react@18.3.31)(bufferutil@4.1.0)(react@18.2.0)(utf-8-validate@6.0.6)))(@types/react@18.3.31)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react@18.2.0)(typescript@5.5.2)(use-sync-external-store@1.4.0(react@18.2.0))(utf-8-validate@6.0.6)(valtio@2.1.7(@types/react@18.3.31)(react@18.2.0))(zod@4.5.4)': - dependencies: - '@reown/appkit-common': 1.8.19(bufferutil@4.1.0)(typescript@5.5.2)(utf-8-validate@6.0.6)(zod@4.5.4) - '@reown/appkit-controllers': 1.8.19(@react-native-async-storage/async-storage@1.24.0(react-native@0.87.1(@babel/core@7.29.7)(@types/react@18.3.31)(bufferutil@4.1.0)(react@18.2.0)(utf-8-validate@6.0.6)))(@types/react@18.3.31)(bufferutil@4.1.0)(react@18.2.0)(typescript@5.5.2)(utf-8-validate@6.0.6)(zod@4.5.4) - '@reown/appkit-polyfills': 1.8.19 - '@reown/appkit-wallet': 1.8.19(bufferutil@4.1.0)(typescript@5.5.2)(utf-8-validate@6.0.6) - '@wallet-standard/wallet': 1.1.0 - '@walletconnect/logger': 3.0.2 - '@walletconnect/universal-provider': 2.23.10(@react-native-async-storage/async-storage@1.24.0(react-native@0.87.1(@babel/core@7.29.7)(@types/react@18.3.31)(bufferutil@4.1.0)(react@18.2.0)(utf-8-validate@6.0.6)))(bufferutil@4.1.0)(typescript@5.5.2)(utf-8-validate@6.0.6)(zod@4.5.4) - valtio: 2.1.7(@types/react@18.3.31)(react@18.2.0) - viem: 2.56.3(bufferutil@4.1.0)(typescript@5.5.2)(utf-8-validate@6.0.6)(zod@4.5.4) - optionalDependencies: - '@base-org/account': 2.4.0(@types/react@18.3.31)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react@18.2.0)(typescript@5.5.2)(use-sync-external-store@1.4.0(react@18.2.0))(utf-8-validate@6.0.6)(zod@4.5.4) - '@safe-global/safe-apps-provider': 0.18.6(bufferutil@4.1.0)(typescript@5.5.2)(utf-8-validate@6.0.6)(zod@4.5.4) - '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.1.0)(typescript@5.5.2)(utf-8-validate@6.0.6)(zod@4.5.4) - transitivePeerDependencies: - - '@azure/app-configuration' - - '@azure/cosmos' - - '@azure/data-tables' - - '@azure/identity' - - '@azure/keyvault-secrets' - - '@azure/storage-blob' - - '@capacitor/preferences' - - '@deno/kv' - - '@netlify/blobs' - - '@planetscale/database' - - '@react-native-async-storage/async-storage' - - '@types/react' - - '@upstash/redis' - - '@vercel/blob' - - '@vercel/functions' - - '@vercel/kv' - - '@x402/core' - - '@x402/evm' - - '@x402/extensions' - - '@x402/svm' - - aws4fetch - - bufferutil - - db0 - - debug - - encoding - - fastestsmallesttextencoderdecoder - - immer - - ioredis - - react - - typescript - - uploadthing - - use-sync-external-store - - utf-8-validate - - zod - '@reown/appkit-utils@1.8.23(@react-native-async-storage/async-storage@1.24.0(react-native@0.87.1(@babel/core@7.29.7)(@types/react@18.3.31)(bufferutil@4.1.0)(react@18.2.0)(utf-8-validate@6.0.6)))(@types/react@18.3.31)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react@18.2.0)(typescript@5.5.2)(use-sync-external-store@1.4.0(react@18.2.0))(utf-8-validate@6.0.6)(valtio@2.1.7(@types/react@18.3.31)(react@18.2.0))(zod@4.5.4)': dependencies: '@reown/appkit-common': 1.8.23(bufferutil@4.1.0)(typescript@5.5.2)(utf-8-validate@6.0.6)(zod@4.5.4) @@ -12019,17 +11761,6 @@ snapshots: - utf-8-validate - zod - '@reown/appkit-wallet@1.8.19(bufferutil@4.1.0)(typescript@5.5.2)(utf-8-validate@6.0.6)': - dependencies: - '@reown/appkit-common': 1.8.19(bufferutil@4.1.0)(typescript@5.5.2)(utf-8-validate@6.0.6)(zod@3.22.4) - '@reown/appkit-polyfills': 1.8.19 - '@walletconnect/logger': 3.0.2 - zod: 3.22.4 - transitivePeerDependencies: - - bufferutil - - typescript - - utf-8-validate - '@reown/appkit-wallet@1.8.23(bufferutil@4.1.0)(typescript@5.5.2)(utf-8-validate@6.0.6)': dependencies: '@reown/appkit-common': 1.8.23(bufferutil@4.1.0)(typescript@5.5.2)(utf-8-validate@6.0.6)(zod@3.22.4) @@ -12041,59 +11772,6 @@ snapshots: - typescript - utf-8-validate - '@reown/appkit@1.8.19(@react-native-async-storage/async-storage@1.24.0(react-native@0.87.1(@babel/core@7.29.7)(@types/react@18.3.31)(bufferutil@4.1.0)(react@18.2.0)(utf-8-validate@6.0.6)))(@types/react@18.3.31)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react@18.2.0)(typescript@5.5.2)(use-sync-external-store@1.4.0(react@18.2.0))(utf-8-validate@6.0.6)(zod@4.5.4)': - dependencies: - '@reown/appkit-common': 1.8.19(bufferutil@4.1.0)(typescript@5.5.2)(utf-8-validate@6.0.6)(zod@4.5.4) - '@reown/appkit-controllers': 1.8.19(@react-native-async-storage/async-storage@1.24.0(react-native@0.87.1(@babel/core@7.29.7)(@types/react@18.3.31)(bufferutil@4.1.0)(react@18.2.0)(utf-8-validate@6.0.6)))(@types/react@18.3.31)(bufferutil@4.1.0)(react@18.2.0)(typescript@5.5.2)(utf-8-validate@6.0.6)(zod@4.5.4) - '@reown/appkit-pay': 1.8.19(@react-native-async-storage/async-storage@1.24.0(react-native@0.87.1(@babel/core@7.29.7)(@types/react@18.3.31)(bufferutil@4.1.0)(react@18.2.0)(utf-8-validate@6.0.6)))(@types/react@18.3.31)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react@18.2.0)(typescript@5.5.2)(use-sync-external-store@1.4.0(react@18.2.0))(utf-8-validate@6.0.6)(zod@4.5.4) - '@reown/appkit-polyfills': 1.8.19 - '@reown/appkit-scaffold-ui': 1.8.19(@react-native-async-storage/async-storage@1.24.0(react-native@0.87.1(@babel/core@7.29.7)(@types/react@18.3.31)(bufferutil@4.1.0)(react@18.2.0)(utf-8-validate@6.0.6)))(@types/react@18.3.31)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react@18.2.0)(typescript@5.5.2)(use-sync-external-store@1.4.0(react@18.2.0))(utf-8-validate@6.0.6)(valtio@2.1.7(@types/react@18.3.31)(react@18.2.0))(zod@4.5.4) - '@reown/appkit-ui': 1.8.19(@react-native-async-storage/async-storage@1.24.0(react-native@0.87.1(@babel/core@7.29.7)(@types/react@18.3.31)(bufferutil@4.1.0)(react@18.2.0)(utf-8-validate@6.0.6)))(@types/react@18.3.31)(bufferutil@4.1.0)(react@18.2.0)(typescript@5.5.2)(utf-8-validate@6.0.6)(zod@4.5.4) - '@reown/appkit-utils': 1.8.19(@react-native-async-storage/async-storage@1.24.0(react-native@0.87.1(@babel/core@7.29.7)(@types/react@18.3.31)(bufferutil@4.1.0)(react@18.2.0)(utf-8-validate@6.0.6)))(@types/react@18.3.31)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react@18.2.0)(typescript@5.5.2)(use-sync-external-store@1.4.0(react@18.2.0))(utf-8-validate@6.0.6)(valtio@2.1.7(@types/react@18.3.31)(react@18.2.0))(zod@4.5.4) - '@reown/appkit-wallet': 1.8.19(bufferutil@4.1.0)(typescript@5.5.2)(utf-8-validate@6.0.6) - '@walletconnect/universal-provider': 2.23.10(@react-native-async-storage/async-storage@1.24.0(react-native@0.87.1(@babel/core@7.29.7)(@types/react@18.3.31)(bufferutil@4.1.0)(react@18.2.0)(utf-8-validate@6.0.6)))(bufferutil@4.1.0)(typescript@5.5.2)(utf-8-validate@6.0.6)(zod@4.5.4) - bs58: 6.0.0 - semver: 7.7.2 - valtio: 2.1.7(@types/react@18.3.31)(react@18.2.0) - viem: 2.56.3(bufferutil@4.1.0)(typescript@5.5.2)(utf-8-validate@6.0.6)(zod@4.5.4) - optionalDependencies: - '@lit/react': 1.0.8(@types/react@18.3.31) - transitivePeerDependencies: - - '@azure/app-configuration' - - '@azure/cosmos' - - '@azure/data-tables' - - '@azure/identity' - - '@azure/keyvault-secrets' - - '@azure/storage-blob' - - '@capacitor/preferences' - - '@deno/kv' - - '@netlify/blobs' - - '@planetscale/database' - - '@react-native-async-storage/async-storage' - - '@types/react' - - '@upstash/redis' - - '@vercel/blob' - - '@vercel/functions' - - '@vercel/kv' - - '@x402/core' - - '@x402/evm' - - '@x402/extensions' - - '@x402/svm' - - aws4fetch - - bufferutil - - db0 - - debug - - encoding - - fastestsmallesttextencoderdecoder - - immer - - ioredis - - react - - typescript - - uploadthing - - use-sync-external-store - - utf-8-validate - - zod - '@reown/appkit@1.8.23(@react-native-async-storage/async-storage@1.24.0(react-native@0.87.1(@babel/core@7.29.7)(@types/react@18.3.31)(bufferutil@4.1.0)(react@18.2.0)(utf-8-validate@6.0.6)))(@types/react@18.3.31)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react@18.2.0)(typescript@5.5.2)(use-sync-external-store@1.4.0(react@18.2.0))(utf-8-validate@6.0.6)(zod@4.5.4)': dependencies: '@reown/appkit-common': 1.8.23(bufferutil@4.1.0)(typescript@5.5.2)(utf-8-validate@6.0.6)(zod@4.5.4) @@ -12305,7 +11983,7 @@ snapshots: '@rollup/rollup-win32-x64-msvc@4.63.1': optional: true - '@rozoai/intent-common@0.1.35(bufferutil@4.1.0)(typescript@5.5.2)(utf-8-validate@6.0.6)(viem@2.56.3(bufferutil@4.1.0)(typescript@5.5.2)(utf-8-validate@6.0.6)(zod@3.25.76))': + '@rozoai/intent-common@0.1.36(bufferutil@4.1.0)(typescript@5.5.2)(utf-8-validate@6.0.6)(viem@2.56.3(bufferutil@4.1.0)(typescript@5.5.2)(utf-8-validate@6.0.6)(zod@3.25.76))': dependencies: '@scure/base': 1.2.6 '@solana/web3.js': 1.98.4(bufferutil@4.1.0)(typescript@5.5.2)(utf-8-validate@6.0.6) @@ -12320,7 +11998,7 @@ snapshots: - typescript - utf-8-validate - '@rozoai/intent-common@0.1.35(bufferutil@4.1.0)(typescript@5.5.2)(utf-8-validate@6.0.6)(viem@2.56.3(bufferutil@4.1.0)(typescript@5.5.2)(utf-8-validate@6.0.6)(zod@4.5.4))': + '@rozoai/intent-common@0.1.36(bufferutil@4.1.0)(typescript@5.5.2)(utf-8-validate@6.0.6)(viem@2.56.3(bufferutil@4.1.0)(typescript@5.5.2)(utf-8-validate@6.0.6)(zod@4.5.4))': dependencies: '@scure/base': 1.2.6 '@solana/web3.js': 1.98.4(bufferutil@4.1.0)(typescript@5.5.2)(utf-8-validate@6.0.6) @@ -12335,13 +12013,13 @@ snapshots: - typescript - utf-8-validate - '@rozoai/intent-pay@0.1.45(ac1985f42b143b3498df95d95a007ae9)': + '@rozoai/intent-pay@0.1.46-beta.2(ac1985f42b143b3498df95d95a007ae9)': dependencies: '@creit.tech/stellar-wallets-kit': 1.9.5(9cefe9a0cf1871d579912eca36ef5853) '@reown/appkit': 1.8.23(@react-native-async-storage/async-storage@1.24.0(react-native@0.87.1(@babel/core@7.29.7)(@types/react@18.3.31)(bufferutil@4.1.0)(react@18.2.0)(utf-8-validate@6.0.6)))(@types/react@18.3.31)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react@18.2.0)(typescript@5.5.2)(use-sync-external-store@1.4.0(react@18.2.0))(utf-8-validate@6.0.6)(zod@4.5.4) '@rollup/plugin-image': 3.0.3(rollup@4.63.1) '@rollup/plugin-typescript': 12.3.0(rollup@4.63.1)(tslib@2.8.1)(typescript@5.5.2) - '@rozoai/intent-common': 0.1.35(bufferutil@4.1.0)(typescript@5.5.2)(utf-8-validate@6.0.6)(viem@2.56.3(bufferutil@4.1.0)(typescript@5.5.2)(utf-8-validate@6.0.6)(zod@3.25.76)) + '@rozoai/intent-common': 0.1.36(bufferutil@4.1.0)(typescript@5.5.2)(utf-8-validate@6.0.6)(viem@2.56.3(bufferutil@4.1.0)(typescript@5.5.2)(utf-8-validate@6.0.6)(zod@3.25.76)) '@solana/spl-memo': 0.2.5(@solana/web3.js@1.98.4(bufferutil@4.1.0)(typescript@5.5.2)(utf-8-validate@6.0.6)) '@solana/spl-token': 0.4.15(@solana/web3.js@1.98.4(bufferutil@4.1.0)(typescript@5.5.2)(utf-8-validate@6.0.6))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.2)(utf-8-validate@6.0.6) '@solana/wallet-adapter-base': 0.9.27(@solana/web3.js@1.98.4(bufferutil@4.1.0)(typescript@5.5.2)(utf-8-validate@6.0.6)) @@ -14921,7 +14599,7 @@ snapshots: '@walletconnect/ethereum-provider@2.23.10(@react-native-async-storage/async-storage@1.24.0(react-native@0.87.1(@babel/core@7.29.7)(@types/react@18.3.31)(bufferutil@4.1.0)(react@18.2.0)(utf-8-validate@6.0.6)))(@types/react@18.3.31)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react@18.2.0)(typescript@5.5.2)(use-sync-external-store@1.4.0(react@18.2.0))(utf-8-validate@6.0.6)(zod@4.5.4)': dependencies: - '@reown/appkit': 1.8.19(@react-native-async-storage/async-storage@1.24.0(react-native@0.87.1(@babel/core@7.29.7)(@types/react@18.3.31)(bufferutil@4.1.0)(react@18.2.0)(utf-8-validate@6.0.6)))(@types/react@18.3.31)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react@18.2.0)(typescript@5.5.2)(use-sync-external-store@1.4.0(react@18.2.0))(utf-8-validate@6.0.6)(zod@4.5.4) + '@reown/appkit': 1.8.23(@react-native-async-storage/async-storage@1.24.0(react-native@0.87.1(@babel/core@7.29.7)(@types/react@18.3.31)(bufferutil@4.1.0)(react@18.2.0)(utf-8-validate@6.0.6)))(@types/react@18.3.31)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react@18.2.0)(typescript@5.5.2)(use-sync-external-store@1.4.0(react@18.2.0))(utf-8-validate@6.0.6)(zod@4.5.4) '@walletconnect/jsonrpc-provider': 1.0.14 '@walletconnect/jsonrpc-types': 1.0.4 '@walletconnect/jsonrpc-utils': 1.0.8 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 18403f71a..3292b53eb 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -35,6 +35,16 @@ overrides: "@walletconnect/sign-client": "2.23.10" "@walletconnect/universal-provider": "2.23.10" "@walletconnect/ethereum-provider": "2.23.10" + # Force single @reown/appkit version to avoid custom element collision + "@reown/appkit": "1.8.23" + "@reown/appkit-common": "1.8.23" + "@reown/appkit-controllers": "1.8.23" + "@reown/appkit-pay": "1.8.23" + "@reown/appkit-polyfills": "1.8.23" + "@reown/appkit-scaffold-ui": "1.8.23" + "@reown/appkit-ui": "1.8.23" + "@reown/appkit-utils": "1.8.23" + "@reown/appkit-wallet": "1.8.23" dedupePeerDependents: true