Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve Rainbowkit adapter configuration #2191

Merged
merged 7 commits into from
Mar 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/shaggy-bats-wink.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@onflow/fcl-rainbowkit-adapter": minor
---

**BREAKING** Change configuration fields for `createFclConnector`
5 changes: 5 additions & 0 deletions .changeset/spicy-queens-shout.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@onflow/fcl-wagmi-adapter": minor
---

**BREAKING** Expose RDNS configuration field for `fclWagmiAdapter`
6 changes: 3 additions & 3 deletions packages/fcl-ethereum-provider/src/create-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,16 @@ export type FclProviderConfig = {
user: typeof fcl.currentUser
config: typeof fcl.config
service?: Service
gateway?: string
rpcUrls?: {[chainId: string]: number}
rpcUrls?: {[chainId: number]: string}
}

/**
* Create a new FCL Ethereum provider
* @param config - Configuration object
* @param config.user - The current user
* @param config.config - The FCL config
* @param config.service - The service
* @param config.gateway - The gateway
* @param config.rpcUrls - The RPC URLs
* @returns The provider
* @public
* @example
Expand Down
82 changes: 46 additions & 36 deletions packages/fcl-rainbowkit-adapter/src/create-connector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,18 @@ import {
import {createConnector, CreateConnectorFn} from "@wagmi/core"
import * as mipd from "mipd"
import {getWalletConnectConnector} from "./get-wc-connector"
import {Service} from "@onflow/typedefs"
import * as fcl from "@onflow/fcl"

const store = mipd.createStore()

type FclConnectorOptions = Parameters<typeof fclWagmiAdapter>[0] & {
supportsWc?: boolean
type FclConnectorOptions = {
user?: typeof fcl.currentUser
config?: typeof fcl.config
rpcUrls?: {[chainId: number]: string}
walletConnectParams?: RainbowKitWalletConnectParameters
walletDetails: Omit<Wallet, "createConnector">
services?: Service[]
}

type DefaultWalletOptions = {
Expand All @@ -23,22 +29,11 @@ const FALLBACK_ICON =
"https://assets.website-files.com/5f6294c0c7a8cdd643b1c820/5f6294c0c7a8cda55cb1c936_Flow_Wordmark.svg"

export const createFclConnector = (options: FclConnectorOptions) => {
const uid = options.service?.uid
const name = options.service?.provider?.name
const iconUrl = options.service?.provider?.icon ?? ""
const rdns = (options.service?.provider as any)?.rdns as string | undefined

return ({projectId}: DefaultWalletOptions): Wallet => {
const rdns = options.walletDetails.rdns

const obj: Wallet = {
id: uid ? `fcl-${uid}` : "fcl",
name: name || "Cadence Wallet",
iconUrl: iconUrl || FALLBACK_ICON,
iconBackground: "#FFFFFF",
downloadUrls: {
browserExtension:
"https://chrome.google.com/webstore/detail/flow-wallet/hpclkefagolihohboafpheddmmgdffjm",
mobile: "https://core.flow.com",
},
...options.walletDetails,
// Do not list RDNS here since Rainbowkit will discard the wallet
// when conflicting with an injected wallet
rdns: undefined,
Expand All @@ -49,23 +44,37 @@ export const createFclConnector = (options: FclConnectorOptions) => {
let currentDetails = walletDetails.rkDetails
let isInstalled = false

// Initialize the installed connector
let installedConnector = {
...fclWagmiAdapter(options)(config),
// Initialize the primary connector (e.g. anything other than WalletConnect)
const primaryService = options.services?.find(
service => service.method !== "WC/RPC"
)
let primaryConnector = {
...fclWagmiAdapter({
user: options.user || fcl.currentUser,
config: options.config || fcl.config,
service: primaryService,
rdns: rdns,
rpcUrls: options.rpcUrls,
})(config),
...walletDetails,
}
installedConnector.setup?.().catch(e => {
primaryConnector.setup?.().catch(e => {
console.error("Failed to setup installed connector", e)
})

// Initialize the WalletConnect connector
let walletConnectConnector = getWalletConnectConnector({
projectId,
walletConnectParameters: options.walletConnectParams,
})({
...walletDetails,
})(config)
walletConnectConnector.setup?.().catch(e => {
let supportsWc = options.services?.some(
service => service.method === "WC/RPC"
)
let walletConnectConnector = supportsWc
? getWalletConnectConnector({
projectId,
walletConnectParameters: options.walletConnectParams,
})({
...walletDetails,
})(config)
: null
walletConnectConnector?.setup?.().catch(e => {
console.error("Failed to setup installed connector", e)
})

Expand All @@ -85,7 +94,7 @@ export const createFclConnector = (options: FclConnectorOptions) => {
* (e.g. there's no teardown logic when switching between connectors)
*/
return {
...installedConnector,
...primaryConnector,
...walletDetails,
async getProvider(params) {
return currentHandler.getProvider(params)
Expand Down Expand Up @@ -124,22 +133,18 @@ export const createFclConnector = (options: FclConnectorOptions) => {
false

let rkDetails: WalletDetailsParams["rkDetails"]
if (isInstalled) {
if (isInstalled || !walletConnectConnector) {
rkDetails = {
...originalDetails,
groupIndex: -1,
groupName: "Installed",
qrCode: undefined,
mobile: undefined,
installed: true,
}
} else {
const getUri = (uri: string) => {
return uri
}

rkDetails = {
...originalDetails,
qrCode: {getUri},
mobile: {getUri},
installed: undefined,
}
}
Expand All @@ -152,8 +157,13 @@ export const createFclConnector = (options: FclConnectorOptions) => {

// Update the current handler (i.e. the proxied connector which is actually active)
const _currentHandler = isInstalled
? installedConnector
? primaryConnector
: walletConnectConnector

if (!_currentHandler) {
throw new Error("No handler found")
}

currentHandler = {
getProvider: _currentHandler.getProvider.bind(_currentHandler),
connect: _currentHandler.connect.bind(_currentHandler),
Expand Down
106 changes: 83 additions & 23 deletions packages/fcl-rainbowkit-adapter/src/wallets/flow-wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,30 +14,90 @@ export const flowWallet = (params: {
createFclConnector({
user: params.user || fcl.currentUser,
config: params.config || fcl.config,
service: {
f_type: "Service",
f_vsn: "1.0.0",
type: "authn",
uid: "fcw#authn",
endpoint:
"chrome-extension://hpclkefagolihohboafpheddmmgdffjm/popup.html",
method: "EXT/RPC",
id: "hpclkefagolihohboafpheddmmgdffjm",
identity: {
address: "0x33f75ff0b830dcec",
services: [
{
f_type: "Service",
f_vsn: "1.0.0",
type: "authn",
uid: "fcw#authn",
endpoint:
"chrome-extension://hpclkefagolihohboafpheddmmgdffjm/popup.html",
method: "EXT/RPC",
provider: {},
params: {},
},
provider: {
name: "Flow Wallet",
address: "0x33f75ff0b830dcec",
description: "A wallet created for everyone",
icon: "https://lilico.app/frw-logo.png",
color: "#41CC5D",
website: "https://core.flow.com",
requires_install: true,
is_installed: true,
install_link:
{
f_type: "Service",
f_vsn: "1.0.0",
type: "authn",
method: "WC/RPC",
uid: "https://fcw-link.lilico.app/wc",
endpoint: "flow_authn",
provider: {},
params: {},
},
],
walletDetails: {
id: "flow-wallet",
name: "Flow Wallet",
iconUrl: "https://lilico.app/logo_mobile.png",
iconBackground: "#FFFFFF",
downloadUrls: {
android:
"https://play.google.com/store/apps/details?id=com.flowfoundation.wallet",
ios: "https://apps.apple.com/ca/app/flow-wallet-nfts-and-crypto/id6478996750",
chrome:
"https://chromewebstore.google.com/detail/flow-wallet/hpclkefagolihohboafpheddmmgdffjm",
rdns: "com.flowfoundation.wallet",
qrCode: "https://link.lilico.app",
},
mobile: {
getUri: (uri: string) => `fcw://${uri}`,
},
qrCode: {
getUri: (uri: string) => uri,
instructions: {
learnMoreUrl: "https://wallet.flow.com",
steps: [
{
description:
"We recommend putting Flow Wallet on your home screen for faster access to your wallet.",
step: "install",
title: "Open the Flow Wallet app",
},
{
description:
"You can find the scan button on the home page. A connection prompt will appear, allowing you to connect your wallet.",
step: "scan",
title: "Tap the scan button",
},
],
},
},
extension: {
instructions: {
learnMoreUrl: "https://wallet.flow.com",
steps: [
{
description:
"We recommend pinning Flow Wallet to your taskbar for quicker access to your wallet.",
step: "install",
title: "Install the Flow Wallet extension",
},
{
description:
"Be sure to back up your wallet using a secure method. Never share your secret phrase with anyone.",
step: "create",
title: "Create or Import a Wallet",
},
{
description:
"Once you set up your wallet, click below to refresh the browser and load up the extension.",
step: "refresh",
title: "Refresh your browser",
},
],
},
},
} as unknown as Service,
rdns: "com.flowfoundation.wallet",
},
})
9 changes: 4 additions & 5 deletions packages/fcl-wagmi-adapter/src/fcl-connector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ import {
} from "viem"
import {createProvider} from "@onflow/fcl-ethereum-provider"

type FclWagmiAdapterParams = Parameters<typeof createProvider>[0]
type FclWagmiAdapterParams = Parameters<typeof createProvider>[0] & {
rdns?: string
}

export function fclWagmiAdapter(params: FclWagmiAdapterParams) {
type Provider = ReturnType<typeof createProvider>
Expand All @@ -32,14 +34,11 @@ export function fclWagmiAdapter(params: FclWagmiAdapterParams) {
const id = params.service?.uid || "fcl"
const name = params.service?.provider?.name || "Cadence Wallet"

// TODO: we need to surface this through FCL service configuration
const rdns = (params.service?.provider as any)?.rdns

return createConnector<Provider, Properties>(config => ({
id: id,
name: name,
type: "fcl-wagmi-adapter",
rdns: rdns,
rdns: params.rdns,
async setup() {
const provider = await this.getProvider()

Expand Down