Skip to content

Commit

Permalink
Fix deep linking for in-app browsers (#1966)
Browse files Browse the repository at this point in the history
  • Loading branch information
jribbink authored Oct 18, 2024
1 parent b73ab41 commit f283110
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 74 deletions.
6 changes: 6 additions & 0 deletions .changeset/unlucky-melons-arrive.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@onflow/fcl-core": minor
"@onflow/fcl-wc": minor
---

Fix deep linking issues with mobile wallets
32 changes: 16 additions & 16 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 8 additions & 6 deletions packages/fcl-core/src/current-user/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,14 @@ const getResolvePreAuthz =
addr: az.identity.address,
keyId: az.identity.keyId,
signingFunction(signable) {
return execService({service: az, msg: signable, platform})
return execService({
service: az,
msg: signable,
platform,
opts: {
initiatedByPreAuthz: true,
},
})
},
role: {
proposer: role === "PROPOSER",
Expand Down Expand Up @@ -315,10 +322,6 @@ const getAuthorization =
})
)
if (authz) {
let windowRef
if (isMobile() && authz.method === "WC/RPC") {
windowRef = window.open("", "_blank")
}
return {
...account,
tempId: "CURRENT_USER",
Expand All @@ -334,7 +337,6 @@ const getAuthorization =
msg: signable,
opts: {
includeOlderJsonRpcCall: true,
windowRef,
},
platform,
})
Expand Down
61 changes: 9 additions & 52 deletions packages/fcl-wc/src/service.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {invariant} from "@onflow/util-invariant"
import {log, LEVELS} from "@onflow/util-logger"
import {isMobile, isIOS} from "./utils"
import {isMobile, openDeeplink} from "./utils"
import {FLOW_METHODS, REQUEST_TYPES} from "./constants"
import {SignClient} from "@walletconnect/sign-client/dist/types/client"
import {createSessionProposal, makeSessionData, request} from "./session"
Expand Down Expand Up @@ -60,7 +60,7 @@ const makeExec = (
const client = await clientPromise
invariant(!!client, "WalletConnect is not initialized")

let session: any, pairing: any, windowRef: any
let session: any, pairing: any
const method = service.endpoint
const appLink = validateAppLink(service)
const pairings = client.pairing.getAll({active: true})
Expand All @@ -74,14 +74,6 @@ const makeExec = (
session = client.session.get(client.session.keys.at(lastKeyIndex)!)
}

if (isMobile()) {
if (opts.windowRef) {
windowRef = opts.windowRef
} else {
windowRef = window.open("", "_blank")
}
}

if (session == null) {
session = await new Promise((resolve, reject) => {
function onClose() {
Expand All @@ -92,7 +84,6 @@ const makeExec = (
service,
onClose,
appLink,
windowRef,
client,
method,
pairing,
Expand All @@ -114,8 +105,12 @@ const makeExec = (
})
}

if (isMobile() && method !== FLOW_METHODS.FLOW_AUTHN) {
openDeepLink()
if (
isMobile() &&
method !== FLOW_METHODS.FLOW_AUTHN &&
!(method === FLOW_METHODS.FLOW_AUTHZ && opts.initiatedByPreAuthz)
) {
openDeeplink(appLink)
}

// Make request to the WalletConnect client and return the result
Expand All @@ -125,10 +120,6 @@ const makeExec = (
session,
client,
abortSignal,
}).finally(() => {
if (windowRef && !windowRef.closed) {
windowRef.close()
}
})

function validateAppLink({uid}: {uid: string}) {
Expand All @@ -141,35 +132,6 @@ const makeExec = (
}
return uid
}

function openDeepLink() {
if (windowRef) {
if (appLink.startsWith("http") && !isIOS()) {
// Workaround for https://github.com/rainbow-me/rainbowkit/issues/524.
// Using 'window.open' causes issues on iOS in non-Safari browsers and
// WebViews where a blank tab is left behind after connecting.
// This is especially bad in some WebView scenarios (e.g. following a
// link from Twitter) where the user doesn't have any mechanism for
// closing the blank tab.
// For whatever reason, links with a target of "_blank" don't suffer
// from this problem, and programmatically clicking a detached link
// element with the same attributes also avoids the issue.
const link = document.createElement("a")
link.href = appLink
link.target = "_blank"
link.rel = "noreferrer noopener"
link.click()
} else {
windowRef.location.href = appLink
}
} else {
log({
title: "Problem opening deep link in new window",
message: `Window failed to open (was it blocked by the browser?)`,
level: LEVELS.warn,
})
}
}
}
}

Expand All @@ -179,7 +141,6 @@ function connectWc(WalletConnectModal: Promise<WalletConnectModalType>) {
service,
onClose,
appLink,
windowRef,
client,
method,
pairing,
Expand All @@ -190,7 +151,6 @@ function connectWc(WalletConnectModal: Promise<WalletConnectModalType>) {
service: any
onClose: any
appLink: string
windowRef: any
client: SignClient
method: string
pairing: any
Expand Down Expand Up @@ -228,7 +188,7 @@ function connectWc(WalletConnectModal: Promise<WalletConnectModalType>) {
if (isMobile()) {
const queryString = new URLSearchParams({uri: uri}).toString()
let url = pairing == null ? appLink + "?" + queryString : appLink
windowRef.location.href = url
openDeeplink(url)
} else if (!pairing) {
if (!pairingModalOverride) {
walletConnectModal = new (await WalletConnectModal)({
Expand Down Expand Up @@ -267,9 +227,6 @@ function connectWc(WalletConnectModal: Promise<WalletConnectModalType>) {
onClose()
throw error
} finally {
if (windowRef && !windowRef.closed) {
windowRef.close()
}
walletConnectModal?.closeModal()
}
}
Expand Down
21 changes: 21 additions & 0 deletions packages/fcl-wc/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,24 @@ export function isIOS() {
export function isMobile() {
return isAndroid() || isIOS()
}

export function openDeeplink(url: string) {
if (url.startsWith("http")) {
// Workaround for https://github.com/rainbow-me/rainbowkit/issues/524.
// Using 'window.open' causes issues on iOS in non-Safari browsers and
// WebViews where a blank tab is left behind after connecting.
// This is especially bad in some WebView scenarios (e.g. following a
// link from Twitter) where the user doesn't have any mechanism for
// closing the blank tab.
// For whatever reason, links with a target of "_blank" don't suffer
// from this problem, and programmatically clicking a detached link
// element with the same attributes also avoids the issue.
const link = document.createElement("a")
link.href = url
link.target = "_blank"
link.rel = "noreferrer noopener"
link.click()
} else {
window.open(url, "_blank")
}
}

0 comments on commit f283110

Please sign in to comment.