Management API Reference

Wallets

Integrating with web3 libraries

Using web3 libraries to interact with accounts.

Openfort's accounts object is fully compatible with popular web3 libraries for interfacing wallets, including ethers, and wagmi.

Read below to learn how to best integrate Openfort alongside these libraries.

Ethers#

Ethers represents connected wallets as a provider, which can be used to take read-only actions with the wallet, and a signer, which can be used to take write actions (signatures and transactions).

Call the wallet's getEthereumProvider method to get a provider:

client.tsx
openfortConfig.ts

_10
import openfort from "./openfortConfig"
_10
_10
const provider = openfort.getEthereumProvider();
_10
_10
// This example assumes you have already checked that Openfort 'embeddedState' is
_10
// `ready` and the user is `authenticated`
_10
const web3Provider = new ethers.providers.Web3Provider(provider);

Then, call the provider's getSigner method to get the corresponding signer:


_10
const signer = web3Provider.getSigner();


Wagmi#

Wagmi is a set of React hooks for interfacing with Ethereum wallets, allowing you read wallet state, request signatures or transactions, and take read and write actions on the blockchain.

Openfort is fully compatible with wagmi, and you can use wagmi's React hooks to interface with external and embedded wallets from Openfort. Just follow the steps below!

1. Install dependencies#

Install the latest versions of wagmi, @tanstack/react-query and @openfort/openfort-js:


_10
npm i wagmi @tanstack/react-query @openfort/openfort-js

2. Setup TanStack Query#

To start, set up your app with the TanStack Query's React Provider. Wagmi uses TanStack Query under the hood to power its data fetching and caching of wallet and blockchain data.


_10
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';

Next, create a new instance of the QueryClient:


_10
const queryClient = new QueryClient();

Then, wrap your app's components with the QueryClientProvider. This must be rendered inside the WagmiProvider component.


_10
<WagmiProvider config={config}>
_10
<QueryClientProvider client={queryClient}>
_10
<Connect />
_10
</QueryClientProvider>
_10
</WagmiProvider>

For the client property of the QueryClientProvider, pass the queryClient instance you created.

3. Setup Wagmi#

To build your wagmi config, import the createConfig method. Next, import your app's required chains from viem/chains and the http transport from wagmi. Your app's required chains should match whatever you configure as supportedChains for Openfort.

wagmi.tsx

_11
import { createConfig, http } from 'wagmi';
_11
import { sepolia } from 'wagmi/chains';
_11
import { injected } from 'wagmi/connectors';
_11
_11
export const config = createConfig({
_11
chains: [sepolia],
_11
connectors: [injected()],
_11
transports: {
_11
[sepolia.id]: http(),
_11
},
_11
});

4. Create Openfort Connector#

You'll need to create a custom connector for Openfort. Create a new file openfortConnector.ts:

main.tsx

_25
import {QueryClient, QueryClientProvider} from '@tanstack/react-query';
_25
import {WagmiProvider} from 'wagmi';
_25
_25
import {Connect} from './components/Connect';
_25
import {config} from './wagmi';
_25
import {useEffect} from 'react';
_25
import {openfortInstance} from './main';
_25
_25
const queryClient = new QueryClient();
_25
_25
export default function App() {
_25
useEffect(() => {
_25
if (!openfortInstance) return;
_25
openfortInstance.getEmbeddedState();
_25
openfortInstance.getEthereumProvider(); // EIP-6963
_25
}, [openfortInstance]);
_25
_25
return (
_25
<WagmiProvider config={config}>
_25
<QueryClientProvider client={queryClient}>
_25
<Connect />
_25
</QueryClientProvider>
_25
</WagmiProvider>
_25
);
_25
}

5. Connector list#

Create a new file Connect.tsx to list the available connectors and handle the connection. When you press on Openfort, then you will be redirected to the authentication page that you should implement. You can find an example of the authentication page in the Openfort documentation.

Connect.tsx

_71
import * as React from 'react';
_71
import {useNavigate} from 'react-router-dom';
_71
import {Connector, useChainId, useConnect} from 'wagmi';
_71
_71
export function ConnectorsList() {
_71
const chainId = useChainId();
_71
const {connectors, connect, error} = useConnect();
_71
const navigate = useNavigate();
_71
const [activeConnector, setActiveConnector] =
_71
React.useState<Connector | null>(null);
_71
_71
React.useEffect(() => {
_71
if (
_71
error &&
_71
activeConnector?.name === 'Openfort' &&
_71
error.message ===
_71
'Unauthorized - must be authenticated and configured with a signer'
_71
) {
_71
navigate('/authentication');
_71
}
_71
}, [error, activeConnector, navigate]);
_71
_71
const handleConnect = (connector: Connector) => {
_71
setActiveConnector(connector);
_71
connect({connector, chainId});
_71
};
_71
_71
return (
_71
<div>
_71
<div className="buttons">
_71
{connectors
_71
.filter((connector) => !connector.name.includes('Injected'))
_71
.map((connector) => (
_71
<ConnectorButton
_71
key={connector.uid}
_71
connector={connector}
_71
onClick={() => handleConnect(connector)}
_71
/>
_71
))}
_71
</div>
_71
{error && <div className="error">Error: {error.message}</div>}
_71
</div>
_71
);
_71
}
_71
_71
function ConnectorButton({
_71
connector,
_71
onClick,
_71
}: {
_71
connector: Connector;
_71
onClick: () => void;
_71
}) {
_71
const [ready, setReady] = React.useState(false);
_71
React.useEffect(() => {
_71
(async () => {
_71
const provider = await connector.getProvider();
_71
setReady(!!provider);
_71
})();
_71
}, [connector, setReady]);
_71
_71
return (
_71
<button
_71
className="button"
_71
disabled={!ready}
_71
onClick={onClick}
_71
type="button"
_71
>
_71
{connector.name}
_71
</button>
_71
);
_71
}

6. Complete example#

Altogether, this should look like:

app.tsx
main.tsx
wagmi.tsx
Connect.tsx

_25
import {QueryClient, QueryClientProvider} from '@tanstack/react-query';
_25
import {WagmiProvider} from 'wagmi';
_25
_25
import {Connect} from './components/Connect';
_25
import {config} from './wagmi';
_25
import {useEffect} from 'react';
_25
import {openfortInstance} from './main';
_25
_25
const queryClient = new QueryClient();
_25
_25
export default function App() {
_25
useEffect(() => {
_25
if (!openfortInstance) return;
_25
openfortInstance.getEmbeddedState();
_25
openfortInstance.getEthereumProvider(); // EIP-6963
_25
}, [openfortInstance]);
_25
_25
return (
_25
<WagmiProvider config={config}>
_25
<QueryClientProvider client={queryClient}>
_25
<Connect />
_25
</QueryClientProvider>
_25
</WagmiProvider>
_25
);
_25
}

That's it! You've successfully integrated Openfort alongside wagmi in your app! 🎉

7. Use wagmi throughout your app#

Once you've completed the setup above, you can use wagmi's React hooks throughout your app to interface with wallets and take read and write actions on the blockchain.

To use wagmi hooks, like useAccount, in your components, import the hook directly from wagmi and call it as usual:


_10
import {useAccount} from 'wagmi';
_10
_10
export default const WalletAddress = () => {
_10
const {address} = useAccount();
_10
return <p>Wallet address: {address}</p>;
_10
}

Demo app#

Feel free to take a look at the app's source code to see an end-to-end implementation of Openfort with wagmi: