diff --git a/.changeset/wild-redirects-validate.md b/.changeset/wild-redirects-validate.md new file mode 100644 index 000000000..bc91ee5a7 --- /dev/null +++ b/.changeset/wild-redirects-validate.md @@ -0,0 +1,6 @@ +--- +"@onflow/fcl-core": patch +"@onflow/fcl-react-native": patch +--- + +Remove the unused `DEEPLINK/RPC` strategy and its associated redirect handling. diff --git a/packages/fcl-core/src/wallet-utils/send-msg-to-fcl.ts b/packages/fcl-core/src/wallet-utils/send-msg-to-fcl.ts index 54bff0dee..0b279f56e 100644 --- a/packages/fcl-core/src/wallet-utils/send-msg-to-fcl.ts +++ b/packages/fcl-core/src/wallet-utils/send-msg-to-fcl.ts @@ -1,7 +1,3 @@ -import { - FCL_REDIRECT_URL_PARAM_NAME, - FCL_RESPONSE_PARAM_NAME, -} from "../utils/constants" import {onMessageFromFCL} from "./on-message-from-fcl" export interface PollingResponse { @@ -14,8 +10,8 @@ export interface PollingResponse { /** * @description Sends messages from a wallet or service back to the parent FCL application. This function - * handles communication between wallet UIs (running in iframes, popups, or redirects) and the main FCL - * application. It automatically detects the communication method (redirect, iframe, or popup) and sends + * handles communication between wallet UIs (running in iframes or popups) and the main FCL + * application. It automatically detects the communication method (iframe or popup) and sends * the message accordingly. * * @param type The message type identifier (e.g., "FCL:VIEW:RESPONSE", "FCL:VIEW:READY") @@ -41,15 +37,7 @@ export interface PollingResponse { * }) */ export const sendMsgToFCL = (type: string, msg?: PollingResponse): void => { - const data = {...msg, type} - - const urlParams = new URLSearchParams(window.location.search) - const redirectUrl = urlParams.get(FCL_REDIRECT_URL_PARAM_NAME) - if (redirectUrl) { - const url = new URL(redirectUrl) - url.searchParams.append(FCL_RESPONSE_PARAM_NAME, JSON.stringify(data)) - window.location.href = url.href - } else if (window.location !== window.parent.location) { + if (window.location !== window.parent.location) { window.parent.postMessage({...msg, type}, "*") } else if (window.opener) { window.opener.postMessage({...msg, type}, "*") diff --git a/packages/fcl-react-native/src/utils/react-native/ServiceDiscovery.js b/packages/fcl-react-native/src/utils/react-native/ServiceDiscovery.js index 8fd4f6aa0..2feecd7ad 100644 --- a/packages/fcl-react-native/src/utils/react-native/ServiceDiscovery.js +++ b/packages/fcl-react-native/src/utils/react-native/ServiceDiscovery.js @@ -26,7 +26,7 @@ export const useServiceDiscovery = ({fcl}) => { const requestBody = { fclVersion: VERSION, userAgent: "ReactNative", - supportedStrategies: ["WC/RPC", "DEEPLINK/RPC"], + supportedStrategies: ["WC/RPC"], } // Fetch wallets from Discovery API diff --git a/packages/fcl-react-native/src/utils/react-native/coreStrategies.js b/packages/fcl-react-native/src/utils/react-native/coreStrategies.js index bff40acb0..dc582b5f6 100644 --- a/packages/fcl-react-native/src/utils/react-native/coreStrategies.js +++ b/packages/fcl-react-native/src/utils/react-native/coreStrategies.js @@ -1,12 +1,10 @@ import {CORE_STRATEGIES, getExecHttpPost} from "@onflow/fcl-core" import {execLocal} from "./exec-local" -import {execDeeplinkRPC} from "./strategies/deeplink-rpc" import {execDiscoveryRN} from "./strategies/discovery-rn" import {DISCOVERY_RN_METHOD} from "./constants" export const coreStrategies = { [CORE_STRATEGIES["HTTP/RPC"]]: getExecHttpPost(execLocal), [CORE_STRATEGIES["HTTP/POST"]]: getExecHttpPost(execLocal), - [CORE_STRATEGIES["DEEPLINK/RPC"]]: execDeeplinkRPC, [DISCOVERY_RN_METHOD]: execDiscoveryRN, } diff --git a/packages/fcl-react-native/src/utils/react-native/render-browser.js b/packages/fcl-react-native/src/utils/react-native/render-browser.js index a6e0dda74..e1b97321a 100644 --- a/packages/fcl-react-native/src/utils/react-native/render-browser.js +++ b/packages/fcl-react-native/src/utils/react-native/render-browser.js @@ -1,6 +1,5 @@ -import {FCL_REDIRECT_URL_PARAM_NAME, URL} from "@onflow/fcl-core" +import {URL} from "@onflow/fcl-core" import * as WebBrowser from "expo-web-browser" -import * as Linking from "expo-linking" /** * @@ -9,12 +8,7 @@ import * as Linking from "expo-linking" * @returns {[object, () => void]} */ export async function renderBrowser(src, opts = {}) { - const redirectUrl = Linking.createURL("$$fcl_auth_callback$$", { - queryParams: {}, - }) - const url = new URL(src.toString()) - url.searchParams.append(FCL_REDIRECT_URL_PARAM_NAME, redirectUrl) const webbrowser = WebBrowser.openAuthSessionAsync(url.toString()) diff --git a/packages/fcl-react-native/src/utils/react-native/strategies/deeplink-rpc.js b/packages/fcl-react-native/src/utils/react-native/strategies/deeplink-rpc.js deleted file mode 100644 index 4994c4ec7..000000000 --- a/packages/fcl-react-native/src/utils/react-native/strategies/deeplink-rpc.js +++ /dev/null @@ -1,42 +0,0 @@ -import {normalizePollingResponse} from "@onflow/fcl-core" -import {browser} from "./utils/browser" - -export function execDeeplinkRPC({service, config, body}) { - return new Promise((resolve, reject) => { - browser(service, config, body, { - onResponse: (e, {close}) => { - try { - if (typeof e.data !== "object") return - const resp = normalizePollingResponse(e.data) - - switch (resp.status) { - case "APPROVED": - resolve(resp.data) - close() - break - - case "DECLINED": - reject(`Declined: ${resp.reason || "No reason supplied"}`) - close() - break - - case "REDIRECT": - resolve(resp) - close() - break - - default: - reject(`Declined: No reason supplied`) - close() - break - } - } catch (error) { - reject(error) - } - }, - onClose: () => { - reject(`Declined: Externally Halted`) - }, - }) - }) -} diff --git a/packages/fcl-react-native/src/utils/react-native/strategies/discovery-rn.js b/packages/fcl-react-native/src/utils/react-native/strategies/discovery-rn.js index ece034602..37495f737 100644 --- a/packages/fcl-react-native/src/utils/react-native/strategies/discovery-rn.js +++ b/packages/fcl-react-native/src/utils/react-native/strategies/discovery-rn.js @@ -18,7 +18,7 @@ import {config} from "@onflow/config" * 4. This function executes → shows ConnectModal with wallet list * 5. User selects wallet * 6. Returns {status: "REDIRECT", data: walletService} - * 7. FCL core executes the wallet service (WC/RPC or DEEPLINK/RPC) + * 7. FCL core executes the wallet service (WC/RPC) * * @param {object} params - Strategy execution parameters * @param {object} params.service - The discovery service to execute diff --git a/packages/fcl-react-native/src/utils/react-native/strategies/utils/browser.js b/packages/fcl-react-native/src/utils/react-native/strategies/utils/browser.js deleted file mode 100644 index e5b3668d2..000000000 --- a/packages/fcl-react-native/src/utils/react-native/strategies/utils/browser.js +++ /dev/null @@ -1,71 +0,0 @@ -import {renderBrowser} from "../../render-browser" -import {serviceEndpoint} from "./service-endpoint" -import {FCL_RESPONSE_PARAM_NAME, buildMessageHandler} from "@onflow/fcl-core" -import * as Linking from "expo-linking" - -const noop = () => {} - -export async function browser(service, config, body, opts = {}) { - if (service == null) return {send: noop, close: noop} - - const onClose = opts.onClose || noop - const onMessage = noop - const onReady = noop - const onResponse = opts.onResponse || noop - - const handler = buildMessageHandler({ - close, - send: noop, - onReady, - onResponse, - onMessage, - }) - const parseDeeplink = result => { - // Handle both deep link callback (with url) and browser result (with type) - const url = result?.url - if (!url) { - if (result?.type === "dismiss" || result?.type === "cancel") { - close() - } - return - } - - const {queryParams} = Linking.parse(url) - - const eventDataRaw = queryParams[FCL_RESPONSE_PARAM_NAME] - if (!eventDataRaw) { - return - } - - try { - const eventData = JSON.parse(eventDataRaw) - - handler({data: eventData}) - - // Auto-close browser after successful authentication - close() - } catch (error) { - // Ignore parse errors - } - } - - const [browser, unmount] = await renderBrowser( - serviceEndpoint(service, config, body) - ) - // Android deeplink parsing - Linking.addEventListener("url", parseDeeplink) - // iOS deeplink parsing - browser.then(parseDeeplink).catch(() => { - // Ignore errors - }) - return {send: noop, close} - - function close() { - try { - unmount() - onClose() - } catch (error) { - // Ignore close errors - } - } -}