Directory Structure:
└── ./
└── pages
├── guides
│ ├── dashboard
│ │ ├── custom-auth
│ │ │ ├── auth-token.mdx
│ │ │ ├── oidc-token.mdx
│ │ │ └── telegram-mini-app.mdx
│ │ ├── external-auth
│ │ │ ├── accelbyte.mdx
│ │ │ ├── firebase.mdx
│ │ │ ├── lootlocker.mdx
│ │ │ ├── playfab.mdx
│ │ │ └── supabase.mdx
│ │ ├── password
│ │ │ ├── custom-smtp.mdx
│ │ │ └── security.mdx
│ │ ├── social-login
│ │ │ ├── auth-discord.mdx
│ │ │ ├── auth-epic.mdx
│ │ │ ├── auth-facebook.mdx
│ │ │ ├── auth-google.mdx
│ │ │ ├── auth-line.mdx
│ │ │ ├── auth-telegram.mdx
│ │ │ └── auth-twitter.mdx
│ │ ├── dev.mdx
│ │ ├── ecosystem.mdx
│ │ ├── external-auth.mdx
│ │ ├── faqs.mdx
│ │ ├── gas-erc20.mdx
│ │ ├── gas-sponsorship.mdx
│ │ ├── keys.mdx
│ │ ├── notifications.mdx
│ │ ├── project-billing.mdx
│ │ ├── social-login.mdx
│ │ ├── sponsor-rules.mdx
│ │ ├── team.mdx
│ │ ├── users.mdx
│ │ └── webhooks.mdx
│ ├── ecosystem
│ │ ├── configuration
│ │ │ ├── branding.mdx
│ │ │ ├── ecosystem-id.mdx
│ │ │ ├── login-methods.mdx
│ │ │ ├── samples.mdx
│ │ │ └── wallet-ui.mdx
│ │ ├── batch-transactions.mdx
│ │ ├── create-wallet-button.mdx
│ │ ├── faqs.mdx
│ │ ├── gas-policies.mdx
│ │ ├── getting-started.mdx
│ │ ├── intro.mdx
│ │ ├── libraries.mdx
│ │ ├── react-native-integration.mdx
│ │ ├── signatures.mdx
│ │ └── web-app-wagmi.mdx
│ ├── javascript
│ │ ├── auth
│ │ │ ├── user-management
│ │ │ │ └── linking.mdx
│ │ │ ├── external-auth.mdx
│ │ │ ├── external-wallet.mdx
│ │ │ ├── guest.mdx
│ │ │ ├── oauth-login.mdx
│ │ │ ├── password.mdx
│ │ │ ├── user-management.mdx
│ │ │ └── user-sessions.mdx
│ │ ├── embedded-signer
│ │ │ ├── advanced
│ │ │ │ ├── iframe.mdx
│ │ │ │ └── shield.mdx
│ │ │ ├── advanced.mdx
│ │ │ ├── export-key.mdx
│ │ │ ├── recovery.mdx
│ │ │ ├── sign-messages.mdx
│ │ │ └── update-recovery.mdx
│ │ ├── resources
│ │ │ └── telegram-react.mdx
│ │ ├── smart-wallet
│ │ │ ├── advanced
│ │ │ │ ├── session-keys.mdx
│ │ │ │ ├── sign-custodial.mdx
│ │ │ │ ├── social-recovery.mdx
│ │ │ │ └── transfer-ownership.mdx
│ │ │ ├── guides
│ │ │ │ ├── bridge.mdx
│ │ │ │ └── exchange.mdx
│ │ │ ├── connected-wallets.mdx
│ │ │ ├── funding.mdx
│ │ │ ├── libraries.mdx
│ │ │ └── send.mdx
│ │ ├── auth.mdx
│ │ ├── faqs.mdx
│ │ ├── features.mdx
│ │ ├── react-native.mdx
│ │ ├── resources.mdx
│ │ ├── troubleshooting.mdx
│ │ ├── use-openfort.mdx
│ │ └── wallets.mdx
│ ├── server
│ │ ├── quickstarts
│ │ │ ├── api.mdx
│ │ │ └── sdk.mdx
│ │ ├── access-token.mdx
│ │ ├── architecture.mdx
│ │ ├── dev.mdx
│ │ ├── pregenerate-wallets.mdx
│ │ ├── setup.mdx
│ │ ├── usage.mdx
│ │ └── webhooks.mdx
│ ├── unity
│ │ ├── auth
│ │ │ ├── email.mdx
│ │ │ ├── external-wallet.mdx
│ │ │ ├── guest.mdx
│ │ │ ├── oauth.mdx
│ │ │ ├── third-party.mdx
│ │ │ └── user-sessions.mdx
│ │ ├── embedded-signer
│ │ │ ├── recovery.mdx
│ │ │ ├── sign-messages.mdx
│ │ │ └── state.mdx
│ │ ├── resources
│ │ │ ├── backend
│ │ │ │ ├── firebase-extension.mdx
│ │ │ │ ├── playfab.mdx
│ │ │ │ └── unity-gaming-services.mdx
│ │ │ ├── ads-unity.mdx
│ │ │ ├── android-iap-unity.mdx
│ │ │ ├── apple-iap-unity.mdx
│ │ │ ├── captcha-unity.mdx
│ │ │ ├── telegram-unity.mdx
│ │ │ └── token-bound-accounts.mdx
│ │ ├── smart-wallet
│ │ │ ├── advanced
│ │ │ │ └── session-keys.mdx
│ │ │ ├── connected-wallets.mdx
│ │ │ └── send.mdx
│ │ ├── quickstart.mdx
│ │ ├── resources.mdx
│ │ ├── troubleshooting.mdx
│ │ └── webgl.mdx
│ ├── dashboard.mdx
│ ├── ecosystem.mdx
│ ├── getting-started.mdx
│ ├── react-native.mdx
│ ├── server.mdx
│ ├── unity.mdx
│ └── unreal-engine.mdx
├── reference
│ └── api
│ └── [...slug].tsx
├── addresses.mdx
├── api-keys.mdx
├── chains.mdx
├── libraries.mdx
└── security.mdx
---
File: /pages/guides/dashboard/custom-auth/auth-token.mdx
---
import Layout from '@/layouts/DefaultGuideLayout'
export const meta = {
title: 'Custom Generic Auth Token',
description:
'Configure a custom auth token',
subtitle:
'Learn how to setup your custom auth token',
breadcrumb: 'Authentication',
}
Generic authentication serves as an alternative for those utilizing their own authentication server. This method accommodates various authentication types not currently supported, such as `Discord`, `Twitter`, `GitHub`, or bespoke systems.
Essential steps and requirements for generic authentication through an endpoint include:
- Post-login, generate a public identifier to recognize the user.
- Relay this identifier to the embedded signer to initiate wallet creation.
- An endpoint you provide will be contacted to confirm the user's identity, upon which we'll create a wallet if the information is valid.
You'll need to supply an endpoint for identity verification.
Additional headers for request authentication can be passed and will accompany every verification request to your endpoint.
## Authenticating Users with Generic Authentication
### Configure your server
Within the server that handles auhentication requests, you'll need to implement an endpoint responsible for verifying the user's identity. This endpoint should accept a `POST` request with a JSON body containing the `payload` field, which corresponds to the user's public identifier.
```json
{
"payload": "public_identifier" // you can put any data you want here (as long as it's a string)
}
```
After returning a JSON response, the SDK will create a wallet for the user if the response is valid. The response should contain the following fields:
```json
{
"userId": "unique_user_id", // A unique identifier for the user, used for wallet identification if no email is provided
"email": "user_email" // optional
}
```
### Set up your provider
To set up your Custom Authentication with Openfort, visit your [dashboard provider settings](https://dashboard.openfort.xyz/players/auth/providers).
export const Page = ({ children }) =>
export default Page
---
File: /pages/guides/dashboard/custom-auth/oidc-token.mdx
---
import Layout from '@/layouts/DefaultGuideLayout'
export const meta = {
title: 'Custom OIDC compatible Auth',
description:
'Configure a custom OIDC compatible auth',
subtitle:
'Learn how to setup your custom OIDC compatible auth',
breadcrumb: 'Authentication',
}
OIDC authentication setup is a viable choice when leveraging an external authentication provider such as `Auth0`, `Cognito`, etc., that offers JWK publication for token authenticity verification.
An OIDC authentication framework employs a public-private key pair, utilizing the private key to sign authentication tokens. The public key is made accessible via a public URL in JWKS format, typically found at `https://{domain}.com/.well-known/jwks.json`. When a user logs in, an idToken, a JWT, is produced and signed with the private key, following OIDC specifications for token field requirements. This JWT is then used within the embedded signer to create a user wallet.
The verification of the JWT against the public key confirms its authenticity, allowing wallet generation based on the subject (user identifier) within the idToken.
Input Requirements:
- JWKS File URL (public key): Validates the token's authentic signature.
- idToken's `aud` value: Confirms that the intended recipient of the token is correct.
## Authenticating Users with OIDC-Compatible Authentication
### Set up your provider
To set up your OIDC Authentication with Openfort, visit your [dashboard provider settings](https://dashboard.openfort.xyz/players/auth/providers).
export const Page = ({ children }) =>
export default Page
---
File: /pages/guides/dashboard/custom-auth/telegram-mini-app.mdx
---
import Layout from '@/layouts/DefaultGuideLayout'
export const meta = {
id: 'Integrate wallet in your Telegram mini-app',
title: 'Seamless login with Telegram mini-app',
description: 'Learn how you can integrate EVM wallet in your Telegam mini-app',
subtitle: 'Integrate wallet in your Telegram mini-app',
breadcrumb: 'Authentication',
}
You can integrate Openfort to enable login directly from within a Telegram bot or Telegram mini-app.
## Configuration
Follow [this guide](https://core.telegram.org/bots/tutorial#obtain-your-bot-token) to create a telegram bot. After creating a Telegram bot, you must set your domain using the `/setdomain` command in the `@BotFather` chat. You will need to provide the following to Openfort via the Openfort Dashboard upon completion:
- Bot token
The `telegramMiniApp`, uses the signed `initDataRaw` from the `telegramSDK` available in the mini app as third party authentication. It does not have any kind of refresh token since Telegram is in charge of issuing new authentications. This method can be used directly from the mini app without requiring interaction with the user as he is already authenticated with the mini app.
Since you need to set your bot's allowed domain you'll need to use a tunneling tool for local development such as [ngrok](https://ngrok.com/).
## Samples
{'Learn how integrate with our mini-app sample'}
export const Page = ({ children }) =>
export default Page
---
File: /pages/guides/dashboard/external-auth/accelbyte.mdx
---
import Layout from '@/layouts/DefaultGuideLayout'
export const meta = {
title: 'AccelByte Auth',
description:
'Integrate with AccelByte.',
subtitle:
'Learn how to interact with AccelByte',
breadcrumb: 'Authentication',
}
AccelByte offers robust backend services for building and operating online games, featuring scalable cloud infrastructure, matchmaking, and cross-platform player accounts.
Their solutions focus on enhancing multiplayer experiences while providing developers with the flexibility to customize game services.
## Set up your provider
To set up Accelbyte to authenticate players with Openfort, visit your [dashboard provider settings](https://dashboard.openfort.xyz/players/auth/providers).
export const Page = ({ children }) =>
export default Page
---
File: /pages/guides/dashboard/external-auth/firebase.mdx
---
import Layout from '@/layouts/DefaultGuideLayout'
export const meta = {
title: 'Firebase Auth',
description:
'Integrate with Firebase.',
subtitle:
'Learn how to interact with Firebase',
breadcrumb: 'Authentication',
}
Firebase is a development platform from Google that provides a variety of tools and services to help developers build, improve, and grow their apps, with features such as databases, analytics, messaging, and crash reporting.
It emphasizes easy integration and real-time updates, enabling developers to create rich, collaborative experiences.
## Prerequisites
Head to your Project Settings in the Firebase Console and grab your Firebase Project ID.
## Set up your provider
To set up Firebase to authenticate players with Openfort, visit your [dashboard provider settings](https://dashboard.openfort.xyz/players/auth/providers).
export const Page = ({ children }) =>
export default Page
---
File: /pages/guides/dashboard/external-auth/lootlocker.mdx
---
import Layout from '@/layouts/DefaultGuideLayout'
export const meta = {
title: 'LootLocker Auth',
description:
'Integrate with LootLocker.',
subtitle:
'Learn how to interact with LootLocker',
breadcrumb: 'Authentication',
}
LootLocker offers robust backend services for building and operating online games, featuring scalable cloud infrastructure, matchmaking, and cross-platform player accounts.
Their solutions focus on enhancing multiplayer experiences while providing developers with the flexibility to customize game services.
## Set up your provider
To set up LootLocker to authenticate players with Openfort, visit your [dashboard provider settings](https://dashboard.openfort.xyz/players/auth/providers).
export const Page = ({ children }) =>
export default Page
---
File: /pages/guides/dashboard/external-auth/playfab.mdx
---
import Layout from '@/layouts/DefaultGuideLayout'
export const meta = {
title: 'PlayFab Auth',
description:
'Integrate with PlayFab',
subtitle:
'Learn how to interact with PlayFab Auth',
breadcrumb: 'Authentication',
}
PlayFab provides a comprehensive suite of live game management services, including server hosting, data analytics, and liveOps utilities to streamline game development and monetization.
It is designed to empower developers with the tools needed to engage players and drive revenue, all while minimizing overhead and time to market.
## Prerequisites
To set up your PlayFab authentication with Openfort, you'll need to get the `Project ID`.
1. Visit the [PlayFab developer dashboard](https://developer.playfab.com/), select your title, and navigate to **_Settings wheel --> Title settings_**:
2. In the **_API Features_** section, copy your **_Title ID_**:
export const Page = ({ children }) =>
export default Page
---
File: /pages/guides/dashboard/external-auth/supabase.mdx
---
import Layout from '@/layouts/DefaultGuideLayout'
export const meta = {
title: 'Supabase Auth',
description:
'Integrate with Supabase.',
subtitle:
'Learn how to interact with Supabase',
breadcrumb: 'Authentication',
}
Supabase is an open-source alternative to Firebase. It provides a variety of tools and services to help with Postgres database, Authentication, instant APIs, Realtime, Functions, Storage and Vector embeddings.
## Prerequisites
Head to your Project Settings in the Supabase Console and grab your Project URL and anon API Key.
## Set up your provider
To set up Supabase to authenticate players with Openfort, visit your [dashboard provider settings](https://dashboard.openfort.xyz/players/auth/providers).
export const Page = ({ children }) =>
export default Page
---
File: /pages/guides/dashboard/password/custom-smtp.mdx
---
import Layout from '@/layouts/DefaultGuideLayout'
export const meta = {
id: 'auth',
title: 'Password Security',
description: 'How to work with passwords in Openfort Auth',
breadcrumb: 'Authentication',
}
## Custom SMTP
At present, you can trial the Openfort platform by sending up to **3** emails per hour via the built-in service. The default email service as a whole is offered on a best effort basis: we will do our best to maintain it and will review usage of the service on a regular basis to see if the email service should be continued.
As you progress toward production, you may find yourself wanting for a custom SMTP service in order to increase your limits. A custom SMTP server will allow you to set your own cap on the number of emails sent per hour.
Beyond rate limits, an SMTP server might also help with:
- Deliverability and Reputation Management
- Scalability
- Analytics and Tracking
- Compliance and Anti Spam measures
## How to set up SMTP
Head over to [Settings Page](https://dashboard.openfort.xyz/settings/configuration/auth) and hit "Enable Custom SMTP" under the SMTP Provider section.
Fill in fields below with the relevant details obtained from your custom SMTP provider:
### SMTP providers
You can use Openfort Auth with any major SMTP provider of your choosing. Some SMTP providers you could consider using are:
- [Twilio SendGrid](https://docs.sendgrid.com/for-developers/sending-email/integrating-with-the-smtp-api)
- [AWS SES](https://docs.aws.amazon.com/ses/latest/dg/send-email-smtp.html)
## Email templates
You can customize the email messages used for the authentication flows. You can edit the following email templates:
- Confirm signup
- Reset Password
## Terminology
The templating system provides the following variables for use:
| Name | Description |
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `{{ .state }}` | Contains a 6-digit One-Time-Password (OTP). |
| `{{ .email }}` | The user's email address. |
| `{{ .redirectUrl }}` | Contains the redirect URL to confirm the email address to a new account. |
## Editing email templates
Edit your email templates on the [Email Templates](https://dashboard.openfort.xyz/settings/configuration/templates) page. Below is an example for a verification of a sign up:
```
Subject: Confirm Reauthentication
Body:
Confirm reauthentication
Enter the code: {{ .state }}
```
export const Page = ({ children }) =>
export default Page
---
File: /pages/guides/dashboard/password/security.mdx
---
import Layout from '@/layouts/DefaultGuideLayout'
export const meta = {
id: 'auth',
title: 'Password-based Auth',
description: 'How to work with passwords in Openfort Auth',
breadcrumb: 'Authentication',
}
You only need to enable this togle if you're developing an ecosystem wallets.
## Password security
A password is more secure if it is harder to guess or brute-force. In theory, a password is harder to guess if it is longer. It is also harder to guess if it uses a larger set of characters (for example, digits, lowercase and uppercase letters, and symbols).
This table shows the _minimum_ number of guesses that need to be tried to access a user's account:
| Required characters | Length | Guesses |
| -------------------------------------------- | ------ | ---------------- |
| Digits only | 8 | ~ 227 |
| Digits and letters | 8 | ~ 241 |
| Digits, lower and uppercase letters | 8 | ~ 248 |
| Digits, lower and uppercase letters, symbols | 8 | ~ 252 |
In reality though, passwords are not always generated at random. They often contain variations of names, words, dates, and common phrases. Malicious actors can use these properties to guess a password in fewer attempts.
There are hundreds of millions (and growing!) known passwords out there. Malicious actors can use these lists of leaked passwords to automate login attempts (known as credential stuffing) and steal or access sensitive user data.
### Password strength and leaked password protection
To help protect your users, Openfort Auth sets strength constrains of the passwords used on your project.
- Set a large minimum password length. Anything less than 8 characters is not recommended.
- Set the required characters that must appear at least once in a user's password. Use the strongest option of requiring digits, lowercase and uppercase letters, and symbols.
- Prevent the use of leaked passwords. Openfort Auth uses the open-source [HaveIBeenPwned.org Pwned Passwords API](https://haveibeenpwned.com/Passwords) to reject passwords that have been leaked and are known by malicious actors.
export const Page = ({ children }) =>
export default Page
---
File: /pages/guides/dashboard/social-login/auth-discord.mdx
---
import Layout from '@/layouts/DefaultGuideLayout'
export const meta = {
id: 'auth',
title: 'Discord Login',
description: 'Integrate with Discord Login',
subtitle: 'Learn how to interact with Discord Login',
breadcrumb: 'Authentication',
}
To enable Discord Auth for your project, you need to set up a Discord OAuth application and add the application credentials in the Openfort Dashboard.
## Overview
Setting up Discord logins for your application consists of 3 parts:
- Create and configure a Discord Project and App on the [Discord Developer Dashboard](https://discord.com/developers).
- Add your Discord API Key and API Secret Key to your [Openfort Project](https://dashboard.openfort.xyz/players/auth/providers).
- Add the login code to your [Openfort JS Client App](https://github.com/openfort-xyz/openfort-js).
### Configuration
**Access your Discord account**
- Go to [discord.com](https://discord.com/).
- Click on `Login` at the top right to log in.
- Once logged in, go to [discord.com/developers](https://discord.com/developers).
- callback URL: `https://api.openfort.xyz/iam/v1/oauth/callback/discord`
**Create a Discord application**
- Click on `New Application` at the top right.
- Enter the name of your application and click `Create`.
- Click on `OAuth2` under `Settings` in the left side panel.
- Click `Add Redirect` under `Redirects`.
- Type or paste your `callback URL` into the `Redirects` box.
- Click `Save Changes` at the bottom.
- Copy your `Client ID` and `Client Secret` under `Client information`.
**Add your Discord credentials into your Supabase project**
export const Page = ({ children }) =>
export default Page
---
File: /pages/guides/dashboard/social-login/auth-epic.mdx
---
import Layout from '@/layouts/DefaultGuideLayout'
export const meta = {
id: 'auth',
title: 'Epic Games Login',
description: 'Integrate with Epic Games Login',
subtitle: 'Learn how to interact with Epic Games Login',
breadcrumb: 'Authentication',
}
To enable Epic Games Auth for your project, you need to set up a Epic Games OAuth application and add the application credentials in the Openfort Dashboard.
## Overview
Setting up Epic Games login for your application consists of 3 parts:
- Create and configure a Epic Project and App on the [Epic Developer Dashboard](https://dev.epicgames.com/portal/en-US/).
- Add your Epic API Key and API Secret Key to your [Openfort Project](https://dashboard.openfort.xyz/players/auth/providers).
- Add the login code to your [Openfort JS Client App](https://github.com/openfort-xyz/openfort-js).
### Configuration
1. Create an organization on Epic Games portal and create a new project.
2. Click on `Epic Account Services` and add a new applications:
- Verify your application website and privacy policy URL
- Save the API Key (client_id) and API Secret Key (client_secret) for later use.
3. Set up Epic Games in Openfort:
- Go to the [Openfort dashboard](https://dashboard.openfort.xyz/players/auth/providers).
- Click on Epic Enabled to turn it ON.
- Enter the Epic Client ID and Epic Client Secret.
export const Page = ({ children }) =>
export default Page
---
File: /pages/guides/dashboard/social-login/auth-facebook.mdx
---
import Layout from '@/layouts/DefaultGuideLayout'
export const meta = {
id: 'auth',
title: 'Facebook Login',
description: 'Integrate with Facebook Login',
subtitle: 'Learn how to interact with Facebook Login',
breadcrumb: 'Authentication',
}
To enable Facebook Auth for your project, you need to set up a Facebook OAuth application and add the application credentials to your Openfort Dashboard.
## Overview
Setting up Facebook logins for your application consists of 3 parts:
- Create and configure a Facebook Application on the [Facebook Developers Site](https://developers.facebook.com/).
- Add your Facebook keys to your [Openfort Project](https://dashboard.openfort.xyz/players/auth/providers).
- Add the login code to your [Openfort JS Client App](https://github.com/openfort-xyz/openfort-js).
### Configuration
- Go to [developers.facebook.com](https://developers.facebook.com).
- Click on `Log In` at the top right to log in.
**Create a Facebook app**
- Click on `My Apps` at the top right.
- Click `Create App` near the top right.
- Select your app type and click `Continue`.
- Fill in your app information, then click `Create App`.
- This should bring you to the screen: `Add Products to Your App`. (Alternatively you can click on `Add Product` in the left sidebar to get to this screen.)
**Set up Facebook login for your Facebook app**
From the `Add Products to your App` screen:
- Click `Setup` under `Facebook Login`
- Skip the Quickstart screen, instead, in the left sidebar, click `Settings` under `Facebook Login`
- Enter your callback URI (`https://api.openfort.xyz/iam/v1/oauth/callback/facebook`) under `Valid OAuth Redirect URIs` on the `Facebook Login Settings` page
- Enter this in the `Valid OAuth Redirect URIs` box
- Click `Save Changes` at the bottom right
Be aware that you have to set the right use case permissions to enable Third party applications to read the email address. To do so:
Under `Build Your App`, click on `Use Cases` screen. From there, do the following steps:
- Click the Edit button in `Authentication and Account Creation` on the right side. This action will lead to the other page.
- `public_profile` is set by default, so make sure it and `email` have status of **Ready for testing** in the redirected page.
- If not, click the **Add** button in email on right side.
**Copy your Facebook app ID and secret**
- Click `Settings / Basic` in the left sidebar
- Copy your App ID from the top of the `Basic Settings` page
- Under `App Secret` click `Show` then copy your secret
- Make sure all required fields are completed on this screen.
**Enter your Facebook app ID and secret into your Supabase project**
export const Page = ({ children }) =>
export default Page
---
File: /pages/guides/dashboard/social-login/auth-google.mdx
---
import Layout from '@/layouts/DefaultGuideLayout'
export const meta = {
id: 'auth',
title: 'Google Login',
description: 'Integrate with Google Login',
subtitle: 'Learn how to interact with Google Login',
breadcrumb: 'Authentication',
}
Openfort Auth supports Sign in with Google on the web, native Android applications and Chrome extensions.
## Overview
Setting up Twitter logins for your application consists of 3 parts:
- Create and configure a Google Project and App on the [Google Cloud Platform](https://console.cloud.google.com/home/dashboard).
- Add your Google API Key and API Secret Key to your [Openfort Project](https://dashboard.openfort.xyz/players/auth/providers).
- Add the login code to your [Openfort JS Client App](https://github.com/openfort-xyz/openfort-js).
### Configuration
1. Go to the [API Credentials page](https://console.cloud.google.com/apis/credentials).
2. Click `Create credentials` and choose `OAuth Client ID`.
3. For application type, choose `Web application`.
4. Under **Authorized redirect URLs**, enter the callback URL from the [Openfort dashboard](https://dashboard.openfort.xyz/players/auth/providers). Expand the Google Auth Provider section to display it.
5. When you finish configuring your credentials, you will be shown your client ID and secret. Add these to the Google Auth Provider section of the Openfort Dashboard.
export const Page = ({ children }) =>
export default Page
---
File: /pages/guides/dashboard/social-login/auth-line.mdx
---
import Layout from '@/layouts/DefaultGuideLayout'
export const meta = {
id: 'auth',
title: 'LINE Login',
description: 'Integrate with LINE Login',
subtitle: 'Learn how to interact with LINE Login',
breadcrumb: 'Authentication',
}
Integrate LINE Login into your web app (website) to make it easier for people to create an account and log in.
## Overview
Setting up LINE login for your application consists of 3 parts:
- Create and configure a LINE Project and App on the [LINE Dashboard](https://developers.line.biz/console/).
- Add your LINE `Channel ID` and `Channel Secret` to your [Openfort Project](https://dashboard.openfort.xyz/players/auth/providers).
- Add the login code to your [Openfort JS Client App](https://github.com/openfort-xyz/openfort-js).
export const Page = ({ children }) =>
export default Page
---
File: /pages/guides/dashboard/social-login/auth-telegram.mdx
---
import Layout from '@/layouts/DefaultGuideLayout'
export const meta = {
id: 'auth',
title: 'Telegram Login',
description: 'Integrate with Telegram Login',
subtitle: 'Learn how to interact with Telegram Login',
breadcrumb: 'Authentication',
}
Openfort enables developers to quickly integrate Login with Telegram into their applications.
## Overview
There are two methods of authentication with Telegram. Telegram Auth requires the botUsername as an OAuth2 authentication flow with telegram, similarly to how you login with Google with an access/refresh token returned. This method goes through the screen you have seen with the [Continue with Telegram](https://core.telegram.org/widgets/login) button.
Openfort also enables seamless Telegram login directly from within a Telegram bot or within Telegram Mini-Apps! [Refer to this guide](/docs/guides/dashboard/custom-auth/telegram-mini-app).
### Configuration
Start the conversation with [BotFather](https://t.me/botfather) and follow [this guide](https://core.telegram.org/bots/tutorial#obtain-your-bot-token) to create a telegram bot. You will need to provide the following to Openfort via the Openfort Dashboard upon completion:
- Bot token (Paste the token you recive from BotFather)
- Bot name (Paste the bot's username)
After creating a Telegram bot, you must set your domain using the `/setdomain` command in the `@BotFather` chat. Send this link 'https://oauth.openfort.xyz/telegram/callback'.
Telegram login requires developers to create a Telegram bot with a bot secret. This bot secret controls the Telegram bot and is also used as a symmetric key for authentication. Control over this key enables a developer to sign over authentication data, meaning compromise of this key puts your users (and their accounts) at risk.
**Securing this symmetric key is essential for the security of all of your app’s Telegram logins.**
export const Page = ({ children }) =>
export default Page
---
File: /pages/guides/dashboard/social-login/auth-twitter.mdx
---
import Layout from '@/layouts/DefaultGuideLayout'
export const meta = {
id: 'auth',
title: 'X (Twitter) Login',
description: 'Integrate with X Login',
subtitle: 'Learn how to interact with X Login',
breadcrumb: 'Authentication',
}
To enable Twitter Auth for your project, you need to set up a Twitter OAuth application and add the application credentials in the Openfort Dashboard.
## Overview
Setting up Twitter logins for your application consists of 3 parts:
- Create and configure a Twitter Project and App on the [Twitter Developer Dashboard](https://developer.twitter.com/en/portal/dashboard).
- Add your Twitter API Key and API Secret Key to your [Openfort Project](https://dashboard.openfort.xyz/players/auth/providers).
- Add the login code to your [Openfort JS Client App](https://github.com/openfort-xyz/openfort-js).
### Configuration
1. Create Project and App:
- Click "+ Create Project", enter project name, and select use case.
- Enter a project description and app name.
- Copy and save your API Key (client_id) and API Secret Key (client_secret).
2. Set Up App Settings:
- Click on "App settings".
- Go to "User authentication settings" and click "Set up".
3. Configure App Permissions:
- Turn ON "Request email from users".
- Select "Web App" as the Type of App.
- Enter Callback URL, Website URL, Terms of service URL, and Privacy policy URL.
4. Set up X in Openfort:
- Go to the [Openfort dashboard](https://dashboard.openfort.xyz/players/auth/providers).
- Click on Twitter Enabled to turn it ON.
- Enter the Twitter Client ID and Twitter Client Secret.
export const Page = ({ children }) =>
export default Page
---
File: /pages/guides/dashboard/dev.mdx
---
import Layout from '@/layouts/DefaultGuideLayout'
export const meta = {
title: 'Backend wallets',
breadcrumb: ({ route }) => {
const pathParts = route.split('/').filter(Boolean);
return pathParts.map(part => part.charAt(0).toUpperCase() + part.slice(1)).join(' > ');
},
}
Backend wallets serve as an internal account for games and developers to manage assets and flows. The accounts are EOAs (Externally Owned Account).
There are [several use cases](/docs/guides/server/dev) for this:
- **Treasury Account**: Transferring assets on demand.
- **Minting Account**: Minting assets on demand.
- **Escrow Account**: Hold assets or tokens in an escrow between players and transferring them afterwards.
## Requisites
Developer account pay for gas using either:
- **Support [ERC-2771](https://eips.ethereum.org/EIPS/eip-2771) transactions**: The assets you want to escrow need to support [ERC-2771](https://eips.ethereum.org/EIPS/eip-2771) transactions (i.e. gasless).
- **Funding a backend wallet**: You need to fund your developer account with the chain's native token.
## Create a backend wallet
Head to the [backend wallet](https://dashboard.openfort.xyz/accounts) page in your dashboard settings and click on `Add account`. By default, the backend wallets created with Openfort are custodial.
```ts server.ts
// Set your secret key. Remember to switch to your live secret key in production.
// See your keys here: https://dashboard.openfort.xyz/developers/api-keys
const Openfort = require('@openfort/openfort-node').default;
const openfort = new Openfort(YOUR_SECRET_KEY);
const settings = await openfort.settings.createDeveloperAccount({
name: 'Minting Account',
})
```
```bash command-line
curl https://api.openfort.xyz/v1/settings/developer_accounts \
-u "$YOUR_SECRET_KEY:" \
-d name= "Minting Account"
```
### Verify wallet ownership
If you're looking to **sponsor gas with your native tokens** for smart accounts, it's important to verify your deposited funds with the paymaster.
Head to [backend wallets](https://dashboard.openfort.xyz/accounts) in your dashboard and click on `Add account`.
1. Click on "Advanced Options" to start the process.
2. Sign the explorer message.
3. Add the wallet address used to deposit native tokens.
4. Add the signed message.
### Optional: Custom forwarder contract
By default you can use the [supported forwarder contracts](/docs/addresses) from Openfort if you need.
Alternatively, you can also use your forward contract in order to sponsor the transaction of your backend wallet. Go to your [Gas policy](https://dashboard.openfort.xyz/policies) section and create a policy by adding the address of your `Forwarder contract address`.
export const Page = ({ children }) =>
export default Page
---
File: /pages/guides/dashboard/ecosystem.mdx
---
import Layout from '@/layouts/DefaultGuideLayout'
export const meta = {
title: 'Ecosystem dashboard configuration',
breadcrumb: 'Dashboard',
}
Creating ecosystem wallets is an **enterprise feature**. To enable it, please [contact us](https://t.me/joalavedra).
Use the **customization** page of the dashboard to configure your ecosystem's brand settings, including name, logo, accent color, and legal policies.
## Customization options
| Customization | Description |
| ------------- |-------------|
| Domain | Choose where to host your dashboard |
| Name | Ecosystem name as you'd like to present it to users
| Logo | Ecosystem logo |
| Brand color | Accent color for your ecosystem |
| Legal | Used to set your own terms & conditions, and your privacy policy. |
| SDK links | Client SDKs |
| Example links | Template examples using the ecosystem SDKs |
export const Page = ({ children }) =>
export default Page
---
File: /pages/guides/dashboard/external-auth.mdx
---
import Layout from '@/layouts/DefaultGuideLayout'
import { IconCheck } from '@/components/ui'
export const meta = {
title: 'Using a third-party auth provider',
description: 'Integrate with existing auth providers and backends',
subtitle: 'Learn how to integrate with third-party auth provider.',
breadcrumb: 'Authentication',
}
Openfort's signer solution enables the user onboarding by integrating with established backend solutions and authentication providers that support JWT-based authentication. This strategy provides a trusted, scalable, and versatile framework that supports an extensive range of authentication options.
## Third-party auth platforms
With this approach, Openfort is in charge of creating **embedded signers** on the and follow the necessary security steps to make sure the smart wallet created remains non custodial.
## Custom Auth Methods
We offer two options to setup embedded signers with custom auth, one that is based on the OIDC ([Open ID Connect](https://openid.net/developers/how-connect-works/)) standard, and a generic option that lets you bring your own auth server.
export const Page = ({ children }) =>
export default Page
---
File: /pages/guides/dashboard/faqs.mdx
---
import Layout from '@/layouts/DefaultGuideLayout'
export const meta = {
id: 'faqs',
title: 'FAQs',
description: 'Most frequently asked questions about the Openfort platform.',
}
### Can players use ERC-20 tokens to pay for gas fees?
Yes, you can sponsor fully or partially with the network token or ERC-20.
### Do users need to fund the newly created accounts?
You don't need to. With Openfort you can use policies to sponsor gas fees on behalf of your users.
### How do I pay for the sponsored gas fees?
Openfort handles all the gas payments for you when using policies. While everything is free on `Testnets`, on `Mainnets` you'll need to top up your account.
### What smart contracts can I interact with?
Yes, you're free to use any smart contracts you wish. You will need add contracts using the assets page in your dashboard.
### Is Openfort ERC-4337 compatible?
Yes, Openfort is compatible with Account Abstraction (ERC-4337) among other standards and follows best practices and implementations across other ethereum standards.
### What blockchains do you support?
Checkout the comprehensive list of [supported chains](/docs/chains).
### Can users have the same smart account address on all EVM chains?
Yes, users can have the same address across all EVM chains because the addresses are deterministic. Each chain will have separate smart account.
### Has Openfort been audited?
The Smart Account implementation has been [audited by CertiK](https://drive.google.com/drive/u/0/folders/1aoPgJD_oz1qagWflnO91ASlQo-2upjRL) and the embedded signer is [audited by Cure+53](https://drive.google.com/drive/u/0/folders/1aoPgJD_oz1qagWflnO91ASlQo-2upjRL).
### Do you provide the ability to communicate with players through notifications?
Openfort can notify you of transactions succeeded or reverted with [webhooks](/docs/guides/dashboard/webhooks). You can use that to send push notifications.
### What's Openfort's business model?
At Openfort we work with any size business to connect your backend and product to the blockchain. Our business model adapts to your needs based on volume as well as the revenue and growth model your business has.
### How can I activate "Live Mode"?
Whenever you want to go live with your product, you need to make sure to complete the details on your billing settings. This is necessary on order to top up your Account Funds.
### What options are available for branding and white labeling?
Openfort offers headless smart accounts which means that you can customize your own UI and experience. You can decide to use any popular framework or completely integrate it within you game (zero popups).
## Security and Contingency Planning
### If Openfort were to shut down with a one-month notice, would there be scope to change the signer on the Smart Contract Wallet and use it in connection with a different provider that manages the private keys differently?
**TLDR:** With enough time, transitioning is fairly simple. You’d need to invoke the `transferOwnership` function for users to accept the new signer.
**Detailed Answer:** Yes, if Openfort shuts down with a one-month notice, it's possible to change the signer. Since Openfort wallets are non-custodial, users have control over their private keys. The key migration process would involve using the "recovery share" and "device share" from Shamir's Secret Sharing (SSS) to reconstruct the private key, allowing users to accept a new signer through the `transferOwnership` function. The new provider would need to support compatible key management systems.
### If Openfort were shut down with zero notice, would there be any scope to do a migration? Would that rely on a self-hosted Shield for the recovery share and the device share being intact?
**TLDR:** If there is no self-hosted option, users should rely on on-chain social recovery.
**Detailed Answer:** Migration is still possible, but it depends on the self-hosted Shield for the recovery share and the availability of the device share. If a self-hosted Shield is not in place, users can utilize on-chain social recovery. As long as the device share and recovery share are intact, users can reconstruct their private key and migrate to a new provider. On-chain social recovery can also help recover the wallet if the device share is lost.
### If Openfort's API were compromised, what is the risk there? Can that risk be mitigated? What’s the risk of the auth share on the private key being exposed?
**TLDR:** Both Openfort's server and Shield are encrypted. Even if an attacker obtains the auth share, they would need a secret to decrypt it.
**Detailed Answer:** If Openfort's API were compromised, the risk is limited because both the auth share and Shield service are encrypted. Even if an attacker gains access to the auth share, they would still need to decrypt it using a secret. Furthermore, since the private key is split using Shamir's Secret Sharing, the auth share alone is insufficient to reconstruct the full key without the device or recovery share.
export const Page = ({ children }) =>
export default Page
---
File: /pages/guides/dashboard/gas-erc20.mdx
---
import Layout from '@/layouts/DefaultGuideLayout'
import StepHikeCompact from '@/components/StepHikeCompact'
import { Accordion } from '@/components/ui'
export const meta = {
title: 'Charge Gas Fees with ERC20 Tokens',
description: 'Make your users pay transaction with ERC20.',
subtitle: 'A step-by-step guide to configure gas fee payments using ERC20 tokens.'
}
Gas fees can be a hurdle for many users in blockchain applications. This guide will help you configure gasless transactions where the gas is paid using an ERC20 token. Choose between dynamic or fixed-rate payment strategies. By the end of this guide, you’ll have a working implementation for charging gas fees with ERC20 tokens and executing transactions seamlessly.
Charge an ERC20 with dynamic price}
id="mint-nft"
>
{/* Step 1: Select Contract */}
Add your collectible’s smart contract.
Define the contract function you want to use (e.g., mint).
Note: You can make a transaction without a registered user or account deployed at the time of interaction. Once you make the transaction, a playerId and accountId will be created.
Note: You can make a transaction without a registered user or account deployed at the time of interaction. Once you make the transaction, a playerId and accountId will be created.
export const Page = ({ children }) => (
)
export default Page
---
File: /pages/guides/dashboard/gas-sponsorship.mdx
---
import Layout from '@/layouts/DefaultGuideLayout'
import { Accordion } from '@/components/ui'
export const meta = {
title: 'Gas sponsorship',
description: 'Gas sponsorship offers a flexible way to manage and control gas payments',
subtitle: 'Gas sponsorship offers a flexible way to manage and control gas payments',
breadcrumb: 'Dashboard',
}
Whether you're building a game, marketplace, or any web3 application, these policies give you the tools to create seamless user experiences by controlling how transaction fees are handled.
## What's a Gas Manager?
A gas manager is at the heart of how Openfort handles transaction fees. Think of it as your control center for managing how and when your application will sponsor user's gas fees. You might use it to make onboarding smoother by covering gas fees for new users, let players use in-game tokens for transactions, or encourage specific actions in your ecosystem.
## Getting started
Setting up gas sponsorship is straightforward. Start by visiting the [Gas Policy tab](https://dashboard.openfort.xyz/policies) in your dashboard and clicking `Add Policy`. From there, you'll be able to configure how you want to handle transaction fees.
## Sponsoring gas fees
When it comes to sponsoring gas fees, you have two main approaches available:
### Paying with credit card
The simplest way to get started is by adding [balance credit](https://dashboard.openfort.xyz/settings/project/billing) to your account. When you choose this method, gas costs are automatically deducted from your balance as transactions occur. This is particularly useful when you're ready to go live with your project, as it's required for `livemode` operations.
### Paying with native tokens
For more advanced use cases, you can use network native tokens (like ETH on Base). This method involves depositing tokens to Openfort's Paymaster contract. Here's how to set it up:
Check the [entity addresses](/docs/addresses) page to find the paymaster's address in your network.
Tokens deposited in this contract can always be withdrawn by the owner and you can control its balance at any time checking the its balance.
1. First, deposit your tokens using the `depositFor` function:
2. After depositing, head to the [backend wallets](https://dashboard.openfort.xyz/accounts) page to register your EOA wallet.
3. Sign and validate your signature by clicking on advanced configuration (see the video below).
4. Finally, configure your policy to use these deposits by selecting "Sponsor gas with your tokens" when editing or creating a policy:
When using a strategy that supports payment in ERC-20 tokens (i.e. `charge_custom_tokens` or `fixed_rate`), the backend wallet will receive the tokens users pay for gas fees.
## Optional: Using external paymasters
For those needing custom solutions, Openfort supports integration with external paymasters. This feature is particularly useful when you have specific requirements for gas sponsorship that go beyond the standard options. Note that when using external paymasters, you'll need to use the `pay_for_user` strategy.
When using an external paymaster, the only supported `strategy` is `pay_for_user`.
To set up an external paymaster, you can either use the dashboard:
Or configure it through the API:
```bash
# Create the paymaster object
curl https://api.openfort.xyz/v1/paymasters/ \
-H "Authorization: Bearer $YOUR_SECRET_KEY" \
-d address=80002 \
-d url="YOUR_PAYMASTER_URL"
# Link it to your policy
curl https://api.openfort.xyz/v1/policies/:id \
-H "Authorization: Bearer $YOUR_SECRET_KEY" \
-d paymaster=pay_...
```
With these fundamentals in place, you're ready to start managing gas fees for your users. The next section will dive deeper into the different types of policies and rules you can create.
export const Page = ({ children }) =>
export default Page
---
File: /pages/guides/dashboard/keys.mdx
---
import Layout from '@/layouts/DefaultGuideLayout'
export const meta = {
title: 'API Keys',
description: 'Use API keys to authenticate API requests.',
subtitle: 'Use API keys to authenticate API requests.',
breadcrumb: 'Dashboard',
}
## Regenerate API keys
Regenerating an API key will invalidate the current key and generate a new one. This action cannot be undone. If you have set up webhooks or registered a Shield project with the key, you will need to update them with the new key.
Openfort supports the ability to regenerate, delete and create API keys. You can do this at any time in the [API keys](https://dashboard.openfort.xyz/developers/api-keys) section of the dashboard.
- **Delete and regenerate API keys**:
- **Generate new API keys**: You can create multiple API keys when you're planning to generate a new one to avoid disruption to your integration.
### Limit API keys interaction by IP
Openfort supports limiting the IPs that can interact with Openfort services using specific APIn keys.
To enable this, [API keys](https://dashboard.openfort.xyz/developers/api-keys) section of the dashboard and press the three dots next to the **secret key**.
A new page will appear with an option `Whitelist IPs` like so:
You can then add multiple IPs per single secret key.
If you try to make a request from an unauthorized IP, you will receive a `Forbidden` error like so:
```json
{
"error": {
"type": "invalid_request_error",
"message": "Access is limited for this address"
}
}
```
export const Page = ({ children }) =>
export default Page
---
File: /pages/guides/dashboard/notifications.mdx
---
import Layout from '@/layouts/DefaultGuideLayout'
export const meta = {
title: 'Events',
description: 'Get notified about events happening in Openfort and onchain',
subtitle: 'Get notified about events happening in Openfort and onchain.',
breadcrumb: 'Dashboard',
}
## Why use events?
When building Openfort integrations, you might want your applications to receive events as they occur in your Openfort accounts, so that your backend systems can execute actions accordingly.
You can configure notifications via the API to be notified about events that happen in your Openfort account or on-chain.
By default, Openfort will send a notification to the specified subscriptions every 24 hours.
## Create an event
Notification objects are the core of the event system. They define the name of the event and encapsulate both the trigger and subscriptions.
```bash command-line
curl https://api.openfort.xyz/v1/notifications/ \
-H "Authorization: Bearer $YOUR_SECRET_KEY" \
-d "name=Low balance"
```
```ts server.ts
const Openfort = require('@openfort/openfort-node').default;
const openfort = new Openfort(YOUR_SECRET_KEY);
const notifications = await openfort.notifications.create({
name: "Low balance"
})
```
```csharp Program.cs
using Openfort.SDK;
using Openfort.SDK.Model;
const openfort = new OpenfortClient(YOUR_SECRET_KEY);
const notifications = await openfort.Notifications.Create(
new CreateNotificationRequest(
name: "Low balance"
)
);
```
You can also configure events directly from your **dashboard**.
## Create a trigger
Triggers define the condition that will trigger the notification.
There are 3 available triggers:
- **[Project balance trigger](https://dashboard.openfort.xyz/settings/project/notifications)**: Define a threshold balance of credits in your project. This is useful to control you can continue to sponsor gas fees for your users.
- **[Contract balance trigger](https://dashboard.openfort.xyz/developers/events)**: Check for the returned parameter of a contract call and compare it to a threshold. This is useful to control the deposited amount in a paymaster contract.
- **[Backend wallet balance trigger](https://dashboard.openfort.xyz/developers/events)**: Check for the balance of a backend wallet and compare it to a threshold. This is useful when you're using a backend wallet itself is paying for the gas fees of the transactions it puts onchain.
There can be more than one notification trigger per event.
```bash command-line
curl https://api.openfort.xyz/v1/notification_triggers \
-u "$YOUR_SECRET_KEY:" \
-d 'notification=not_e0b84653-1741-4a3d-9e91-2b0fd2942f60' \
-d 'type=project_balance_trigger' \
-d 'threshold=1000000000'
```
```ts server.ts
const Openfort = require('@openfort/openfort-node').default;
const openfort = new Openfort(YOUR_SECRET_KEY);
const notificationtriggers = await openfort.notificationTriggers.create({
notification: "not_e0b84653-1741-4a3d-9e91-2b0fd2942f60",
type: "project_balance_trigger",
threshold: "1000000000"
})
```
```csharp Program.cs
using Openfort.SDK;
using Openfort.SDK.Model;
const openfort = new OpenfortClient(YOUR_SECRET_KEY);
const notificationtriggers = await openfort.NotificationTriggers.Create(
new CreateNotificationTriggerRequest(
notification: "not_e0b84653-1741-4a3d-9e91-2b0fd2942f60",
type: "project_balance_trigger",
threshold: "1000000000"
)
);
```
## Create a subscription
Subscriptions define the method and target of the event.
There are 2 available subscription methods:
- **Email**: Send an email to the specified target.
- **Webhook**: Send a POST request to the specified target. To learn more about receiving webhooks, check out the [webhooks guide](/docs/guides/dashboard/webhooks) and the types `notification.developer_account.balance`, `notification.contract.balance` or `notification.project.balance`.
There can be more than one notification subscription per event.
```bash command-line
curl https://api.openfort.xyz/v1/notification_subscriptions \
-u "$YOUR_SECRET_KEY:" \
-d 'notification=not_e0b84653-1741-4a3d-9e91-2b0fd2942f60' \
-d 'method=Email' \
-d 'target=jaume@openfort.xyz'
```
```ts server.ts
const Openfort = require('@openfort/openfort-node').default;
const openfort = new Openfort(YOUR_SECRET_KEY);
const notificationsubscriptions = await openfort.notificationSubscriptions.create({
notification: "not_e0b84653-1741-4a3d-9e91-2b0fd2942f60",
method: "Email",
target: "jaume@openfort.xyz"
})
```
```csharp Program.cs
using Openfort.SDK;
using Openfort.SDK.Model;
const openfort = new OpenfortClient(YOUR_SECRET_KEY);
const notificationsubscriptions = await openfort.NotificationSubscriptions.Create(
new CreateNotificationSubscriptionRequest(
notification: "not_e0b84653-1741-4a3d-9e91-2b0fd2942f60",
method: "Email",
target: "jaume@openfort.xyz"
)
);
```
export const Page = ({ children }) =>
export default Page
---
File: /pages/guides/dashboard/project-billing.mdx
---
import Layout from '@/layouts/DefaultGuideLayout'
export const meta = {
id: 'project-based-billing',
title: 'How billing works',
description: 'Learn how project-based billing works in Openfort.',
subtitle: 'Learn how organzation-based billing works in Openfort.',
}
Our goal at Openfort is to provide a _predictable_ billing system that grows with your project.
## How billing is organized
The Openfort Platform has "projects". A user can be a member of multiple projects. For example:
- `User 1`
- `Project 1` (Smart Accounts, Auth, Payments)
- `Project 2` (Smart Accounts, Auth, Payments)
- `User 2`
- `Project 3` (Smart Accounts, Auth, Payments)
## Billing system
### Project-based Billing
Each project has an individual subscription, a plan and addons. For example, `Project 1` could be on the Pro plan and `Project 2` could be on the Free plan.
![Credit Balance](https://blog-cms.openfort.xyz/uploads/project_billing_4f33e2d7a9.png)
### Credit balance (Prepaid)
Each project has a credit balance. The credit balance is used to pay for the project's gas sponsorship.
Given that each proct supports all chains, the credit balance is shared across all chains.
You can monitor the gas report spending in by visiting the policy page.
![Policy Gas Reports](https://blog-cms.openfort.xyz/uploads/policy_report_de8f42695f.png)
### FAQ
Do you only support the prepaid option?
No, we also support the postpaid option. Please contact us for more information
at joan@openfort.xyx.
What happens if my balance reaches 0?
Gas sponsorship will be disabled for your project. You can top up your balance
to enable it again. If you want more flexible billing options, please contact us
at joan@openfort.xyz, where we can enable a buffer for your project.
export const Page = ({ children }) =>
export default Page
---
File: /pages/guides/dashboard/social-login.mdx
---
import Layout from '@/layouts/DefaultGuideLayout'
export const meta = {
id: 'auth',
title: 'Social Login',
description: 'Logging in with social accounts',
breadcrumb: 'Authentication',
}
OAuth is commonly used for things like logging in to a social media account from a third-party app. It is a secure and convenient way to authenticate users and share information between applications.
### Social Providers
## Provider Token
You can use the provider token and provider refresh token returned to make API calls to the OAuth provider. For example, you can use the Google provider token to access Google APIs on behalf of your user.
export const Page = ({ children }) =>
export default Page
---
File: /pages/guides/dashboard/sponsor-rules.mdx
---
import Layout from '@/layouts/DefaultGuideLayout'
import { Accordion } from '@/components/ui'
export const meta = {
id: 'rules',
title: 'Gas Policy Strategies & Rules',
description: 'This guide covers the detailed configuration of gas policies, including available strategies and rule types',
subtitle: 'Covers the detailed configuration of gas policies, including available strategies and rule types',
breadcrumb: 'Dashboard',
}
## Gas Policy Strategies
Gas policies offer three distinct strategies for handling transaction fees:
### 1. Sponsored Transactions
Developers cover all gas fees, removing the need for users to hold native tokens.
```bash
curl https://api.openfort.xyz/v1/policies/ \
-H "Authorization: Bearer $YOUR_SECRET_KEY" \
-d chainId=80002 \
-d name="Sponsored Policy" \
-d "strategy[sponsorSchema]=pay_for_user"
```
### 2. Dynamic ERC20 Payment
Users pay gas fees using ERC20 tokens at a dynamic exchange rate.
```bash
curl https://api.openfort.xyz/v1/policies/ \
-H "Authorization: Bearer $YOUR_SECRET_KEY" \
-d chainId=80002 \
-d name="Fixed ERC20" \
-d "strategy[sponsorSchema]=fixed_rate" \
-d "strategy[tokenContract]=con_..." \
-d "strategy[tokenContractAmount]=10000"
```
## Policy Rules
While strategies determine how gas fees are paid, rules define when and how your gas policy applies. Every policy needs at least one rule to function, and you can choose from three types:
| Rule Model | Description |
|----------------------|--------------------------------------------------------|
| **`contract_functions`** | Sponsor interactions with smart contracts. |
| **`account_functions`** | Sponsor interactions with the smart account. |
| **`limit_rules`** | Limit the amount of gas or number of transactions over an interval. |
### Contract functions
These rules let you specify which smart contract interactions your policy covers. You might want to sponsor all interactions with your game contracts but not with external marketplaces, for instance.
Wildcard policies allow you to sponsor any transaction for any contract without the need to add them in the policy. Enable "Catch-all sponsorship".
To create a policy rule, you need first to add a contract to Openfort:
Add a contract}
id={`add-contract`}
>
If the contract is not verified on the block explorer, you will need to enter the ABI manually. If the contract you want to interact with is a proxy contract, you will need to enter the ABI of the implementation contract.
Add a contract to Openfort to an API request:
```bash command-line
curl https://api.openfort.xyz/v1/contracts \
-H "Authorization: Bearer $YOUR_SECRET_KEY" \
-d name="SimpleNFT" \
-d address="0x416c...354D" \
-d chainId="80002"
```
Add a new contract by clicking the `Add contract` button in the [Asset contracts](https://dashboard.openfort.xyz/assets) section, then enter:
- The name of the contract (it can be any name you want; the name is only for identification purposes)
- The network (`chainId`) where the smart contract is located.
- The address of the contract.
- The Application Binary Interface (ABI) of the contract (if not verified in the block explorer of that network).
Once you've selected your contract, you can then choose what function you whish to enable sponsorship for. You can select `All functions` instead to allow sponsoring all functions in that specific contract.
```bash command-line
curl https://api.openfort.xyz/v1/policy_rules \
-H "Authorization: Bearer $YOUR_SECRET_KEY" \
-d type="contract_functions" \
-d functionName="mint" \
-d "contract=con_..."
```
### Account functions
These rules cover account-related operations, such as transferring ownership of accounts, managing session keys, or deploying smart accounts. They're essential for maintaining smooth account management operations within your application.
```bash command-line
curl https://api.openfort.xyz/v1/policy_rules \
-H "Authorization: Bearer $YOUR_SECRET_KEY" \
-d type="account_functions"
```
### Limit rule
Limit rules help you control usage of your gas policy. You can set limits based on:
| Rule Type | Description | Example Use Case |
|-----------|-------------|-----------------|
| Gas per Interval | Total gas limit in timeframe | 1000 WEI/minute |
| Gas per Transaction | Gas limit per transaction | 100 WEI/transaction |
| Count per Interval | Transaction count limit | 10 transactions/minute |
```bash command-line
curl https://api.openfort.xyz/v1/policy_rules \
-H "Authorization: Bearer $YOUR_SECRET_KEY" \
-d type="rate_limit" \
-d functionName="gas_per_transaction" \
-d gasLimit="1000000"
```
export const Page = ({ children }) =>
export default Page
---
File: /pages/guides/dashboard/team.mdx
---
import Layout from '@/layouts/DefaultGuideLayout'
import { IconCheck } from '@/components/ui'
export const meta = {
title: 'Manage teams',
breadcrumbs: 'Dashboard'
}
Openfort provides granular **access controls** to manage permissions across your organizations. For each project, a user can have one of the following roles:
- Owner
- Administrator
- Member
A default project is created when you first sign in and you'll be assigned the **Owner** role. Each member can access everything under the project. Create a separate project if you need to restrict access to certain parts.
## Manage team members
To invite others to collaborate, visit your project's team settings in the [Dashboard](https://dashboard.openfort.com/settings/project/members) to send an invite link to another user's email. The invite expires after 24 hours.
If you're creating an ecosystem, head to the [ecosystem guide](/docs/guides/ecosystem).
### Permissions across roles [#permission-across-roles]
The table below shows the corresponding permissions for each available role you can assign a team member in the Dashboard.
| Permissions | Owner | Administrator | Member |
| ----------------------- | ----------------------- | ----------------------- | ----------------------- |
| **Members** |
| Add an Administrator | | | |
| Remove an Administrator | | | |
| Add a Member | | | |
| Remove a Member | | | |
| Revoke an invite | | | |
| Resend an invite | | | |
| Accept an invite | | | |
| **Billing** |
| Read invoices | | | |
| Read billing email | | | |
| Read billing address | | | |
| Update billing address | | | |
| Read payment methods | | | |
| Update payment methods | | | |
| **Projects** |
| Create a project | | | |
## Organization Overview
The default organization structure at Openfort are split in different projects. Each project has their own API Keys, players, assets and billing configuration beign completely independent one another.
export const Page = ({ children }) =>
export default Page
---
File: /pages/guides/dashboard/users.mdx
---
import Layout from '@/layouts/DefaultGuideLayout'
import { IconCheck } from '@/components/ui'
export const meta = {
title: 'Players',
breadcrumbs: 'Dashboard'
}
Use the **Players** page of the dashboard to manage all registered players in your Openfort application.
## Player table
The **player table** displays all players that have been registered within Openfort for your selected application. This table only shows players who have been created through Openfort's systems, whether via direct authentication or through your application's integration. You can see important information including:
- Provider used for authentication
- API ID (unique identifier)
- Creation date
- Last sign-in timestamp
The **player table** is paginated to display 10 players at a time. You can navigate through the list using the "Previous" and "Next" buttons at the bottom. The current view range is displayed (e.g., "Viewing 1 to 10 of 838 results").
### Player details
Clicking on a player's API ID opens the **player details** page, where you can see comprehensive information about the selected player, including:
- Details
- API ID
- Description
- Creation timestamp
- Metadata
- External User ID
- Accounts
- Chain (e.g., Polygon)
- Wallet address
- Status (Active/Inactive)
- Creation date
- Transactions
View and manage player transactions, including asset transfers and NFT minting
- Sessions
Monitor and manage player authentication sessions for frictionless interactions
## Authentication
The drawer displays session data such as when the user first logged into your app, when they were last seen in your app. Please note that the "Last seen" field is a rough approximation on the order of an hour from when the user was precisely last active in your app.
If you're using a third-party authentication provider instead of Openfort's authentication solution, this section will remain empty, and you'll manage your authentication through your chosen provider's interface.
### Deleting users
From the user drawer, you can delete a user if necessary. This is an irreversible and destructive action; if the user logs into your app again, they will have a new user's ID (`playerID`), will have to relink any formerly linked accounts, and will get a new embedded wallet address. **Please take extreme care when deleting users.**
For security of user assets, Openfort does not delete the embedded wallet, and instead "soft deletes" it by disassociating it from the deleted user. If the user still has access to their login method and their wallet password, if they have set one, their wallet can be recovered after deletion.
export const Page = ({ children }) =>
export default Page
---
File: /pages/guides/dashboard/webhooks.mdx
---
import Layout from '@/layouts/DefaultGuideLayout'
export const meta = {
id: 'webhooks',
title: 'Webhooks',
description: 'Listen for events on your Openfort account.',
subtitle:
'Listen for events so your integration can automatically trigger reactions.',
breadcrumb: 'Dashboard',
}
## What is a webhook?
Openfort uses webhooks to push real-time notifications to you about your transactions. All webhooks use HTTPS and deliver a JSON payload that can be used by your application. You can use webhook feeds to do things like:
- Granting users a game item when a transaction is confirmed.
- Store all transaction events in your own database for custom reporting/retention
## Steps to receive webhooks
You can start receiving real-time events in your app using the steps:
1. Create a local endpoint to receive requests
2. Register your development webhook endpoint
3. Test that your webhook endpoint is working properly
4. Register your production webhook endpoint
## Webhook object
The webhook object contains the following fields:
```json
{
"data": {
"id": "tin_c502d628-5bb3-42f2-b8f5-62ba4d71df3a",
"createdAt": 1689869074,
"object": "transactionIntent",
"etc":"..."
},
"type": "transaction_intent.succeeded",
"date": 1689869074
}
```
Where the `type` will be one of the following:
- `transaction_intent.succeeded`: The transaction intent has arrived on-chain and is confirmed.
- `transaction_intent.failed`: The transaction intent has arrived on-chain and is reverted.
- `transaction_intent.cancelled`: The transaction intent parameters were not met.
- `transaction_intent.broadcast`: The transaction intent was broadcasted.
- `balance. project`: The project balance.
- `balance.contract`: The contract balance.
- `balance.dev_account`: The balance of your backend wallet.
And the `data` will be a [transaction intent object](https://www.openfort.xyz/docs/reference/api/get-a-transaction-intent-object).
### Register your development webhook endpoint
Register your publicly accessible HTTPS URL in the Openfort [dashboard](https://dashboard.openfort.xyz/webhooks). Then decide the type of webhook you want to receive.
You can create a tunnel to your localhost server using a tool like [ngrok](https://ngrok.com/download). For example: https://8733-191-204-177-89.sa.ngrok.io/webhooks
### Test that your webhook endpoint is working properly
Send a few test transactions to check that your webhook endpoint is receiving the events.
You can specify the number of block confirmations you want to wait before getting notified of a transaction making it on chain. The default is 0 (i.e. as soon as the transaction arrives on chain).
To do so, you need to include the `confirmationBlocks` body parameter when [creating the transaction intent](https://www.openfort.xyz/docs/reference/api/create-a-transaction-intent-object).
When instantiating the **Client SDK**, you can pass in the `appearance` object to customize the appearance of the wallet. For wallet discovery, it will use [EIP-6963](https://eips.ethereum.org/EIPS/eip-6963) to embedded your branding.
The `appearance` object has the following properties:
- **icon**: a data url schema, compliant with [RFC-2397](https://www.rfc-editor.org/rfc/rfc2397).
- **logo**: a [URI](https://www.rfc-editor.org/rfc/rfc3986) pointing to an image. The image SHOULD be a square with 96x96px minimum resolution.
- **name**: a human-readable local alias of the Wallet Provider to be displayed to the user on the DApp. (e.g. `Example Wallet Extension` or `Awesome Example Wallet`)
- **reverseDomainNameSystem**: the Wallet MUST supply the `rdns` property which is intended to be a domain name from the Domain Name System in reverse syntax ordering such as `com.example.subdomain`. It’s up to the Wallet to determine the domain name they wish to use, but it’s generally expected the identifier will remain the same throughout the development of the Wallet. It’s also worth noting that similar to a user agent string in browsers, there are times where the supplied value could be unknown, invalid, incorrect, or attempt to imitate a different Wallet. Therefore, the DApp SHOULD be able to handle these failure cases with minimal degradation to the functionality of the DApp.
When creating your **client SDK** you need to add the *ecosystem ID*. It can be found in their dashboard at the [settings section](https://dashboard.openfort.xyz/settings/project/overview).
The *ecosystemWalletDomain* is the domain where your wallet UI is hosted.
Therefore, when creating your wallet SDK, you can pass in the `appearance` object to customize the appearance of the wallet.
```ts index.ts
// Set your ecosystem id. Remember to switch to your live secret key in production.
// See your ecosystem id here: https://dashboard.openfort.xyz/settings/project/overview
import { AppMetadata, Client } from '@openfort/ecosystem-js/client'
class EcosystemWallet extends Client {
constructor(appMetadata?: AppMetadata) {
super({
appMetadata: appMetadata,
baseConfig: {
// URL where the UI wallet is hosted
ecosystemWalletDomain: 'https://wallet.ecosystem.com',
ecosystemId: 'YOUR_ECOSYSTEM_ID',
},
appearance: {
icon: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAFwF52RAAAACXBIWXMAAAsTAAALEwEAmpwYAAABpElEQVQ4jZ2Sv0vDUBTFf4f9Cg',
logo: 'https://www.example.com/logo.png',
name: 'Ecosystem Wallet',
reverseDomainNameSystem: 'com.example.ecosystem.wallet'
}
});
// Use a Proxy to allow for new method additions
return new Proxy(this, {
get: (target, prop) => {
if (prop in target) {
const value = target[prop as keyof EcosystemWallet];
return typeof value === 'function' ? value.bind(target) : value;
}
return undefined;
}
});
}
setPolicy(options?: { policy?: string; }): void {
return super.setPolicy(options);
}
}
export default EcosystemWallet;
```
You can check all the available components in the [Client SDK reference](/docs/reference/ecosystem-js/modules/client.html).
export const Page = ({ children }) =>
export default Page
---
File: /pages/guides/ecosystem/configuration/ecosystem-id.mdx
---
import Layout from '@/layouts/DefaultGuideLayout'
export const meta = {
title: 'Onboard your ecosystem partners',
breadcrumb: 'Ecosystem wallet',
}
After you've created your own ecosystem SDK and registered the npm package. You're now ready to onboard new projects and partners and let them use your new ecosystem wallet.
Through the dashboard, you're able to create `child_projects` under your ecosystem, given it a name, and head to the members section to invite their emails.
-----
Each child project will have their own API keys as well as capabilities to manage smart contracts, users, and gas policies. An ecosystem can decide to share multiple `contract_id` and `policy_id` with child projects in order to take advantage of gas policy campaigns or ecosystem assets like ERC20 tokens.
export const Page = ({ children }) =>
export default Page
---
File: /pages/guides/ecosystem/configuration/login-methods.mdx
---
import Layout from '@/layouts/DefaultGuideLayout'
export const meta = {
title: 'Configure login methods',
breadcrumb: 'Ecosystem wallet',
}
Openfort supports a variety of login methods for your app, including email, phone, wallet, Google, Apple, Twitter, Discord, Epic Games, Line, Telegram, and more coming.
Users can either use these account types as their upfront login method, or can link them to their profile after logging in via a different method.
### 1. Configure _upfront_ login methods in the SDK
The login methods you enable in the Openfort Dashboard should contain all of the account types that users are allowed to login with or link in your app. You can choose a subset (or all) of these account types as upfront login methods shown to users when they first login to your app.
Learn more about configuring your authentication methods in the [auth guide](/docs/guides/dashboard/social-login).
As soon as you enable each provider from your dashboard, it will automatically appear as an option in the authentication page.
## Using a custom auth provider
`
Openfort's ecosystem wallets are fully-compatible with any authentication provider that supports JWT-based, stateless authentication. If you're looking to add embedded wallets to your app, you can either:
- use Openfort as your authentication provider (easy to set up out-of-the-box).
- use a custom authentication provider (easy to integrate alongside your existing stack).
export const Page = ({ children }) =>
export default Page
---
File: /pages/guides/ecosystem/configuration/samples.mdx
---
import Layout from '@/layouts/DefaultGuideLayout'
import { IconCheck } from '@/components/ui'
export const meta = {
title: 'Sample to create an ecosystem wallet SDK',
breadcrumb: 'Ecosystem wallet',
tocVideo: 'FBMv3LuGoG4',
}
The following is a sample and video guide on how to create a wallet SDK.
## Samples
{'A quick start guide to create your own wallet SDK with the ecosystem SDK'}
### Guides
export const Page = ({ children }) =>
export default Page
---
File: /pages/guides/ecosystem/configuration/wallet-ui.mdx
---
import Layout from '@/layouts/DefaultGuideLayout'
export const meta = {
title: 'Craft and customize your wallet',
breadcrumb: 'Ecosystem wallet',
}
The Fort **ecosystem wallets** come with a default set of screens for authentication, session key confirmation, sign typed message, configuration, and transaction confirmation. These screens are designed to be customizable to fit your brand and user experience. Openfort provides helpers to the most popular frameworks to make it easier to integrate the ecosystem wallets.
The _default_ **Client SDK** expects the following routes to exist in your wallet UI:
| Route | Description |
|-----------------------|---------------------------|
| /sign/personal-sign | personal_sign |
| /sign/eth-sign-typed-data-v-4 | eth_signTypedData_v4 |
| /sign/eth-send-transaction | eth_signTransaction |
| /sign/eth-request-accounts | eth_requestAccounts |
| /sign/wallet-show-calls | wallet_showCallsStatus |
| /sign/wallet-send-calls | wallet_sendCalls |
| /sign/eth-grant-permissions | wallet_grantPermissions |
| / | Loading screen |
## React SDK
When adding the React components to your App, there are two places where the components can be customized. All but one of the theme customizations options are passed through to the Fort Tailwind plugin in your `tailwind.config.js` file.
In your **wallet UI project**, after installing the `@openfort/ecosystem-js` package to get started with the React SDK. It will be then available from `@openfort/ecosystem-js/react`.
You can check all the available components in the [React SDK reference](/docs/reference/ecosystem-js/modules/react.html).
Use the **live [ecosystem customization](https://build.openfort.xyz/)** tool to get your custom theme and components.
### Colors
The available colors are:
**Background colors**
- `bg000` - Lightest background color
- `bg100` - Light background color
- `bg200` - Medium background color
**Border colors**
- `border` - The color of borders
**Button colors**
- `btnPrimary` - The color of the primary button
- `btnPrimaryText` - The text color for the primary button
- `btnPrimaryHover` - The hover color for the primary button
- `btnSecondary` - The color of the secondary button
- `btnSecondaryText` - The text color for the secondary button
- `btnSecondaryHover` - The hover color for the secondary button
**Text colors**
- `title` - The color for title text
- `text` - The main text color
- `textSubtle` - The color for subtle or secondary text
**Status colors**
- `info` - The color for informational elements
- `success` - The color for success messages or indicators
- `warning` - The color for warning messages or indicators
- `error` - The color for error messages or indicators
- `critical` - The color for critical messages or indicators
These color variables can be used to customize various elements of the UI as shown in the image. For example, the main content area uses `bg200`, while the outer container uses `bg100`. Text elements use `title`, `text`, and `textSubtle` accordingly.
The button styles (`btnPrimary`, `btnSecondary`, etc.) are applied to the "Approve" and "Deny" buttons at the bottom of the UI.
## Core SDK
The **Core SDK** is the package that you will use to **receive and send** communication with the **Client SDK**. This package includes all the necessary functionality in order to onboard your users to blockchain with non-custodial wallets.
```ts main.ts
// Set your publishable key, shield publishable key and ecosystem id. Remember to switch to your live secret key in production.
// See your keys here: https://dashboard.openfort.xyz/developers/api-keys
// See your ecosystem ID here: https://dashboard.openfort.xyz/settings/project/overview
import { Core, MethodType } from "@openfort/ecosystem-js/core";
// Create a new instance of the Core SDK
const core = new Core({
baseConfig: {
publishableKey: "YOUR_PUBLISHABLE_KEY",
supportedChains: [80002],
ecosystemId: 'YOUR_ECOSYSTEM_ID',
},
shieldConfig: {
shieldPublishableKey: 'YOUR_SHIELD_PUBLISHABLE_KEY',
},
oidcConfig: {
redirectUri: "http://localhost:3000",
},
});
// instantiate the event listener
const evhl = core.eventsHandler;
evhl.subscribe(MethodType.ACCOUNTS_REQUEST, (data) => {
console.log("Event received", data);
})
evhl.listen();
```
This are the available **Method Types** that will be sent from the **Client SDK** and that you can subscribe to:
| Method | Type |
|-----------------------|---------------------------|
| ETH_SEND_TRANSACTION | 'eth_signTransaction' |
| ETH_TYPED_MESSAGE_V4 | 'eth_signTypedData_v4' |
| PERSONAL_MESSAGE | 'personal_sign' |
| WALLET_GRANT_PERMISSIONS | 'wallet_grantPermissions' |
| WALLET_SEND_CALLS | 'wallet_sendCalls' |
| WALLET_SHOW_CALLS_STATUS | 'wallet_showCallsStatus' |
| ETH_REQUEST_ACCOUNTS | 'eth_requestAccounts' |
You can check all the available components in the [Core SDK reference](/docs/reference/ecosystem-js/modules/core.html). You can react to receiving this events by subscribing to them and executing the necessary logic in your app, like rendering a confirmation screen or sending the transaction to the blockchain.
export const Page = ({ children }) =>
export default Page
---
File: /pages/guides/ecosystem/batch-transactions.mdx
---
import Layout from '@/layouts/DefaultGuideLayout'
import StepHikeCompact from '@/components/StepHikeCompact'
import { IconCheck } from '@/components/ui'
export const meta = {
title: 'Batch transactions',
breadcrumb: 'Ecosystem wallet',
hide_table_of_contents: true
}
Smart Wallet enables you to send multiple onchain calls in a single transaction, improving UX by reducing multi-step interactions to a single click. A common example is combining an ERC-20 `approve` with a swap operation.
You can submit batch transactions using the new `wallet_sendCalls` [RPC](https://eip5792.xyz/reference/sendCalls) method.
- First, verify if your app supports atomic batching (This step is crucial if your app supports multiple wallet types)
- Use the `useCapabilities` hook from Wagmi experimental features
- Implement fallback functionality for unsupported wallets
Note: The `useWriteContracts` and `useCapabilities` hooks rely on new wallet RPC and may not be supported in all wallets.
```typescript app.tsx
import { useCapabilities } from 'wagmi/experimental'
function App() {
const { data: capabilities } = useCapabilities()
// Returns capability object per chain:
// {
// 84532: {
// atomicBatch: {
// supported: true,
// },
// }
// }
// Check if atomic batching is supported in the chain we want to interact with
const isAtomicBatchSupported = capabilities?.[84532]?.atomicBatch?.supported
return (
{isAtomicBatchSupported ? (
) : (
)}
)
}
```
- Import required hooks: `useAccount` and `useWriteContracts` from Wagmi
- Define your smart contract ABI
- Initialize the `useWriteContracts` hook for batch transactions
- Create a transaction handling function that can process multiple contract calls
Important: Make sure your contract ABIs are correctly typed for better development experience.
```typescript app.tsx
import { useAccount } from 'wagmi'
import { useWriteContracts } from 'wagmi/experimental'
// Define your contract ABI
const abi = [
{
stateMutability: 'nonpayable',
type: 'function',
inputs: [{ name: 'to', type: 'address' }],
name: 'safeMint',
outputs: [],
}
] as const
function BatchTransactionComponent() {
const account = useAccount()
const { writeContracts } = useWriteContracts()
const handleBatchTransaction = () => {
writeContracts({
contracts: [
{
address: "0x119Ea671030FBf79AB93b436D2E20af6ea469a19",
abi,
functionName: "safeMint",
args: [account.address],
},
// Add more contract interactions as needed
{
address: "0x119Ea671030FBf79AB93b436D2E20af6ea469a19",
abi,
functionName: "safeMint",
args: [account.address],
}
],
})
}
return (
)
}
```
- Add the `useCallsStatus` hook to track transaction status
- Configure polling interval for status updates
- Display transaction status to users
- Handle transaction completion and errors
Pro tip: The polling interval can be adjusted based on your needs, but 1 second is a good default.
```typescript app.tsx
import { useCallsStatus } from 'wagmi/experimental'
function BatchTransactionComponent() {
const { data: id, writeContracts } = useWriteContracts()
const { data: callsStatus } = useCallsStatus({
id: id as string,
query: {
enabled: !!id,
// Poll every second until confirmed
refetchInterval: (data) =>
data.state.data?.status === "CONFIRMED" ? false : 1000,
},
})
// Example response structure:
// {
// status: 'CONFIRMED',
// receipts: [
// {
// logs: [{
// address: '0x...',
// topics: ['0x...'],
// data: '0x...'
// }],
// status: 'success',
// blockHash: '0x...',
// blockNumber: 122414523n,
// gasUsed: 390000n,
// transactionHash: '0x...'
// }
// ]
// }
return (
)
}
```
export const Page = ({ children }) => {children}
export default Page
---
File: /pages/guides/ecosystem/create-wallet-button.mdx
---
import Layout from '@/layouts/DefaultGuideLayout'
import { IconCheck } from '@/components/ui'
import StepHikeCompact from '@/components/StepHikeCompact'
export const meta = {
title: 'Create wallet button',
breadcrumb: 'Ecosystem wallet',
}
For the best onboarding experience, we recommend adding a highly visible 'Create' or 'Create Wallet' button to your app's homepage. Adding this button streamlines the onboarding experience for new users and gets them ready to use your app in a few seconds.
Here is an example of how the button looks:
## Implementation with Wagmi
To make these instructions concrete, we have created a sample ecosystem wallet called **Rapidfire ID**. To interact with it, you can find its SDK in the NPM package directory: [@rapidfire/id](https://www.npmjs.com/package/@rapidfire/id).
You can check out the GitHub [repository for Rapidfire Wallet](https://github.com/openfort-xyz/ecosystem-sample) to learn how to create your own wallet.
Using Wagmi offers a balanced approach that combines flexibility with developer convenience. By integrating the ecosystem wallet with Wagmi, you get access to a comprehensive set of React hooks that handle common wallet operations, state management, and chain interactions. This approach requires both `@rapidfire/id` and `Wagmi` dependencies, along with React Query, but provides a more structured development experience. While you'll still need to build your own UI components, Wagmi's hooks significantly reduce the complexity of handling wallet connections, transactions, and chain switching.
First, set up your Wagmi configuration with the required chain and connector settings.
```ts wagmi.ts
import { http, createConfig } from 'wagmi';
import { polygonAmoy } from 'wagmi/chains';
import { injected } from 'wagmi/connectors';
export const config = createConfig({
chains: [polygonAmoy],
connectors: [
injected(),
],
transports: {
[polygonAmoy.id]: http(),
},
});
declare module 'wagmi' {
interface Register {
config: typeof config;
}
}
```
Create a reusable wallet logo component that will be used in the button.
```tsx WalletLogo.tsx
import React from 'react';
const defaultContainerStyles = {
paddingTop: 2,
display: 'flex',
alignItems: 'center',
};
export function WalletLogo({
size = 24,
containerStyles = defaultContainerStyles,
}) {
return (
);
}
```
Create the main button component using Wagmi's useConnect hook.
```tsx CreateWalletButton.tsx
import React, { useCallback } from 'react';
import { useConnect } from 'wagmi';
import { WalletLogo } from './WalletLogo';
const buttonStyles = {
background: 'linear-gradient(135deg, #2D3436 0%, #000000 100%)',
border: '1px solid rgba(255, 255, 255, 0.1)',
boxSizing: 'border-box' as const,
display: 'flex',
alignItems: 'center',
gap: '12px',
width: 'auto',
minWidth: '200px',
fontFamily: 'Inter, system-ui, sans-serif',
fontWeight: '600',
fontSize: '16px',
color: '#FFFFFF',
padding: '12px 20px',
borderRadius: '12px',
cursor: 'pointer',
transition: 'all 0.2s ease-in-out',
boxShadow: '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)',
':hover': {
transform: 'translateY(-1px)',
boxShadow: '0 6px 8px -1px rgba(0, 0, 0, 0.1), 0 4px 6px -1px rgba(0, 0, 0, 0.06)',
},
};
export function CreateWalletButton() {
const { connectors, connect, data } = useConnect();
const createWallet = useCallback(() => {
const injectedConnector = connectors.find(
(connector) => connector.id === 'injected'
);
if (injectedConnector) {
connect({ connector: injectedConnector });
}
}, [connectors, connect]);
return (
);
}
```
For more detail, view the [`useConnect` documentation](https://wagmi.sh/react/api/hooks/useConnect).
Upon successful connection, account information can be accessed via [data](https://wagmi.sh/react/api/hooks/useConnect#data) returned from `useConnect`, or via [`useAccount`](https://wagmi.sh/react/api/hooks/useAccount).
## Implementation with EIP-1193 Provider
The EIP-1193 Provider approach gives you the most granular control over your ecosystem wallet integration by directly using the SDK's Ethereum provider. This method requires only the `@rapidfire/id` package and allows you to build everything from scratch. You'll handle all wallet interactions through the standard `EIP-1193` provider interface, giving you complete flexibility in implementing wallet creation, connection flows, and transaction handling. While this approach requires more custom development work, it's ideal for applications that need specialized wallet interactions or want to minimize dependencies.
To make these instructions concrete, we have created a sample ecosystem wallet called **Rapidfire ID**. To interact with it, you can find its SDK in the NPM package directory: [@rapidfire/id](https://www.npmjs.com/package/@rapidfire/id).
You can check out the GitHub [repository for Rapidfire Wallet](https://github.com/openfort-xyz/ecosystem-sample) to learn how to create your own wallet.
Create a new SDK instance with your application configuration.
```ts sdk.ts
import EcosystemWallet from '@rapidfire/id';
// Initialize the SDK with required parameters
export const sdk = new EcosystemWallet({
appChainIds: [80002],
appLogoUrl: 'https://a.rgbimg.com/users/b/ba/barunpatro/600/mf6B5Gq.jpg',
appName: 'Example App',
});
```
Configure the Ethereum provider with chain and policy settings.
Make sure to set up your `NEXT_PUBLIC_POLICY_ID` in your environment variables.
```ts provider.ts
import { sdk } from './sdk';
// Configure the provider with chain and policy
export const provider = sdk.getEthereumProvider({
policy: process.env.NEXT_PUBLIC_POLICY_ID
});
```
Create the button component that uses the configured provider.
```tsx CreateWalletButton.tsx
import React, { useCallback } from 'react';
import { WalletLogo } from './WalletLogo';
import { provider } from './provider';
const buttonStyles = {
background: 'linear-gradient(135deg, #2D3436 0%, #000000 100%)',
border: '1px solid rgba(255, 255, 255, 0.1)',
boxSizing: 'border-box' as const,
display: 'flex',
alignItems: 'center',
gap: '12px',
width: 'auto',
minWidth: '200px',
fontFamily: 'Inter, system-ui, sans-serif',
fontWeight: '600',
fontSize: '16px',
color: '#FFFFFF',
padding: '12px 20px',
borderRadius: '12px',
cursor: 'pointer',
transition: 'all 0.2s ease-in-out',
boxShadow: '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)',
':hover': {
transform: 'translateY(-1px)',
boxShadow: '0 6px 8px -1px rgba(0, 0, 0, 0.1), 0 4px 6px -1px rgba(0, 0, 0, 0.06)',
},
};
export function CreateWalletButton({ handleSuccess, handleError }) {
const createWallet = useCallback(async () => {
try {
const [address] = await provider.request({
method: 'eth_requestAccounts',
});
handleSuccess(address);
} catch (error) {
handleError(error);
}
}, [handleSuccess, handleError]);
return (
);
}
```
export const Page = ({ children }) =>
export default Page
---
File: /pages/guides/ecosystem/faqs.mdx
---
import Layout from '@/layouts/DefaultGuideLayout'
export const meta = {
id: 'faqs',
title: 'FAQs',
description: 'Most frequently asked questions about the Openfort platform.',
}
### Can Openfort support my ecosystem's login system?
Yes, Openfort's architecture is built to allow thousands of new gaming ecosystems flourish. You ecosystem can be added as an OAuth provider allowing your community to be recognized.
### What if I can't find my authentication provider in the documentation?
No problem, let us know which provider you want to use and we'll get right into it.
### Can players use their existing wallets alongside Openfort Auth?
Users can link existing wallets to their account. This allows you to store and share these wallet addresses with games via the SDK for read-only use.
### What level of support and Service Level Agreements (SLAs) are provided?
At Openfort, we understand the significance of maintaining a high standard of service. Our Service Level Agreements (SLAs) reflect our commitment to providing a reliable, efficient, and safe environment for your operations.
## Security and Contingency Planning
### If Openfort were to shut down with a one-month notice, would there be scope to change the signer on the Smart Contract Wallet and use it in connection with a different provider that manages the private keys differently?
**TLDR:** With enough time, transitioning is fairly simple. You’d need to invoke the `transferOwnership` function for users to accept the new signer.
**Detailed Answer:** Yes, if Openfort shuts down with a one-month notice, it's possible to change the signer. Since Openfort wallets are non-custodial, users have control over their private keys. The key migration process would involve using the "recovery share" and "device share" from Shamir's Secret Sharing (SSS) to reconstruct the private key, allowing users to accept a new signer through the `transferOwnership` function. The new provider would need to support compatible key management systems.
### If Openfort were shut down with zero notice, would there be any scope to do a migration? Would that rely on a self-hosted Shield for the recovery share and the device share being intact?
**TLDR:** If there is no self-hosted option, users should rely on on-chain social recovery.
**Detailed Answer:** Migration is still possible, but it depends on the self-hosted Shield for the recovery share and the availability of the device share. If a self-hosted Shield is not in place, users can utilize on-chain social recovery. As long as the device share and recovery share are intact, users can reconstruct their private key and migrate to a new provider. On-chain social recovery can also help recover the wallet if the device share is lost.
### If Openfort's API were compromised, what is the risk there? Can that risk be mitigated? What’s the risk of the auth share on the private key being exposed?
**TLDR:** Both Openfort's server and Shield are encrypted. Even if an attacker obtains the auth share, they would need a secret to decrypt it.
**Detailed Answer:** If Openfort's API were compromised, the risk is limited because both the auth share and Shield service are encrypted. Even if an attacker gains access to the auth share, they would still need to decrypt it using a secret. Furthermore, since the private key is split using Shamir's Secret Sharing, the auth share alone is insufficient to reconstruct the full key without the device or recovery share.
export const Page = ({ children }) =>
export default Page
---
File: /pages/guides/ecosystem/gas-policies.mdx
---
import Layout from '@/layouts/DefaultGuideLayout'
import { IconCheck } from '@/components/ui'
export const meta = {
title: 'Sponsor transactions',
breadcrumb: 'Ecosystem wallet',
}
One of the biggest UX enhancements unlocked by smart accounts is the ability for app developers to sponsor their users' transactions. If your ecosystem has a gas policy enabled, you can start sponsorship your user's transactions by using the `policy` in your [dashboard](https://dashboard.openfort.xyz/policies).
To make these instructions concrete, we have created a sample ecosystem wallet called **Rapidfire ID**. To interact with it, you can find its SDK in the NPM package directory: [@rapidfire/id](https://www.npmjs.com/package/@rapidfire/id).
You can check out the GitHub [repository for Rapidfire Wallet](https://github.com/openfort-xyz/ecosystem-sample) to learn how to create your own wallet.
### Use a policy when injecting your provider
Sponsor all transactions that will be made with the injected provider.
```tsx app.tsx
import { sdk } from './sdk'
function App() {
useEffect(() => {
config.getEthereumProvider({policy: 'pol_...'});
}, []);
return (
)
}
```
```ts sdk.ts
import EcosystemWallet from '@rapidfire/id'
// Initialize the SDK with required parameters
export const sdk = new EcosystemWallet({
appChainIds: [80002],
appLogoUrl: 'https://a.rgbimg.com/users/b/ba/barunpatro/600/mf6B5Gq.jpg',
appName: 'Example App',
});
```
### Updating the policy
Updating your policy is useful if you change chain and need to specify a different policy ID.
```tsx app.tsx
import { sdk } from './sdk'
function App() {
useEffect(() => {
config.setPolicy({policy: 'pol_...'});
}, []);
return (
)
}
```
```ts sdk.ts
import EcosystemWallet from '@rapidfire/id'
// Initialize the SDK with required parameters
export const sdk = new EcosystemWallet({
appChainIds: [80002],
appLogoUrl: 'https://a.rgbimg.com/users/b/ba/barunpatro/600/mf6B5Gq.jpg',
appName: 'Example App',
});
```
-----
You can also configure your own app level policy. Check the details in the [dashboard section](/docs/guides/dashboard/gas-sponsorship).
- Using an [**external paymaster** setup.](/docs/guides/dashboard/gas-sponsorship#optional-using-external-paymasters)
- Learn how to [use **erc20 tokens**](/docs/guides/dashboard/gas-erc20) to pay for gas fees.
export const Page = ({ children }) =>
export default Page
---
File: /pages/guides/ecosystem/getting-started.mdx
---
import Layout from '@/layouts/DefaultGuideLayout'
export const meta = {
title: 'Quickstart your wallet',
breadcrumb: 'Ecosystem wallet',
}
This guide and the `configuration` sections are to help developers launch their own ecosystem wallet. If you're looking to use an existing ecosystem wallet SDK, please refer to the `usage` section and install the specific ecosystem package.
The [**Fort SDK**](https://www.npmjs.com/package/@openfort/ecosystem-js) is the easiest way to create you ecosystem wallet. It comes with a [code-splitting environment](https://developer.mozilla.org/en-US/docs/Glossary/Code_splitting), all the necessary tools to make **your wallet SDK** a reality. It is the easier way to create your own ecosystem wallet.
The Fort SDK has **two main parts**:
1. `@openfort/ecosystem-js/client`: The **Client SDK** that you will use to create your wallet SDK.
2. `@openfort/ecosystem-js/core`: The **Core SDK** that you will use to create your wallet UI. Fort also includes a React specific package `@openfort/ecosystem-js/react` that you can use to get started faster.
## 0. Requirements
Your project will need some specific configuration to enable code splitting:
- [Typescript version 5.0.2](https://github.com/microsoft/TypeScript/releases/tag/v5.0.2) or higher.
- TS Config needs to have `compilerOptions.moduleResolution` set to `bundler`.
- Your code editor and project should have the same version of Typescript.
## 1. Install the ecosystem SDK
Install the latest version of [Fort SDK](https://www.npmjs.com/package/@openfort/ecosystem-js) using your package manager of choice:
You will need to install `@openfort/ecosystem-js` at both your wallet SDK and wallet UI projects.
```sh Terminal
npm install @openfort/ecosystem-js
```
```sh Terminal
yarn add @openfort/ecosystem-js
```
## 2. Set your auth providers
Navigate to the **auth providers** page on the [Openfort dashboard](https://dashboard.openfort.xyz) by selecting your project and then clicking Auth providers Methods in the side bar in the [players page](https://dashboard.openfort.xyz/players). Select the account types you'd like users to be able to login with. For more information on how to enable social logins, check out the [dashboard docs](/docs/guides/dashboard/social-login).
## 3. Get your Openfort API keys
From the [Openfort Dashboard](https://dashboard.openfort.xyz) for select your desired app, navigate to the [developers page](https://dashboard.openfort.xyz/developers/api-keys) in the top bar. On the de tab, find the API keys section. Get your Openfort API keys, you will need it in the next step.
You will find two keys:
- **Publishable Key**: This value can be safely exposed in a client-side environment.
- **Secret Key**: This value should never be exposed in a client-side environment. It should be kept secure and used only in a server-side environment. Learn more on how to use it in the [server-side guide](/docs/guides/server). You can [further secure it](/docs/guides/dashboard/keys) for production applications.
To generate non custodial wallets, you will need to create a Shield instance. At the [API keys page](https://dashboard.openfort.xyz/developers/api-keys), scroll down to the Shield section and click on the **Create Shield keys** button.
A **one time pop-up** will appear with a variable called **encryption share**. Its very important that you store it safely. You will not be able to see it again.
Then, in your page, you will see two Shield keys:
- **Publishable Key**: This value can be safely exposed in a client-side environment.
- **Secret Key**: This value should never be exposed in a client-side environment.
## 4. Creating your wallet SDK
The easiest way to get started is to create a [Proxy](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy) object in order to map the already provided functionality of the **Client SDK**. You can nevertheless change or add new methods to fit your needs.
When creating your **client SDK** you need to add the *ecosystem ID*. It can be found in their dashboard at the [settings section](https://dashboard.openfort.xyz/settings/project/overview).
The *ecosystemWalletDomain* is the domain where your wallet UI is hosted.
```tsx main.ts
// See your ecosystem id here: https://dashboard.openfort.xyz/settings/project/overview
import { AppMetadata, Client } from "@openfort/ecosystem-js/client";
class EcosystemWallet extends Client {
constructor(appMetadata?: AppMetadata) {
super({
baseConfig: {
ecosystemWalletDomain: 'https://id.sample.openfort.xyz',
ecosystemId: 'test-226353cd-dd0e-4fba-8208-58dfe29d3581',
},
appMetadata,
});
return new Proxy(this, {
get: (target, prop) => {
if (prop in target) {
const value = target[prop as keyof EcosystemWallet];
return typeof value === 'function' ? value.bind(target) : value;
}
return undefined;
}
});
}
}
export default EcosystemWallet;
```
```json package.json
{
"name": "@ecosystem/wallet",
"version": "0.0.1",
"main": "dist/index.js",
"module": "dist/index.mjs",
"types": "dist/index.d.ts",
"exports": {
".": {
"import": "./dist/index.mjs",
"require": "./dist/index.js",
"types": "./dist/index.d.ts"
}
},
"scripts": {
"build": "tsup src/index.ts --format cjs,esm --dts",
"prepublishOnly": "npm run build"
},
"keywords": [],
"author": "Openfort (https://www.openfort.xyz)",
"devDependencies": {
"@types/node": "^20.4.5",
"tsup": "^7.1.0",
"typescript": "^5.6.2"
},
"dependencies": {
"@openfort/ecosystem-js": "0.0.13"
},
"files": [
"dist"
]
}
```
```json tsconfig.json
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "bundler",
"lib": ["ES2022", "DOM"],
"declaration": true,
"declarationMap": true,
"sourceMap": true,
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"isolatedModules": true,
"resolveJsonModule": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist", "**/*.spec.ts"]
}
```
You're all set! By running the `build` script you'll get a `dist` folder with the compiled code. You can now publish your package to [npm](https://www.npmjs.com/) and share it with the world.
You can check all the available client methods in the [Client SDK reference](/docs/reference/ecosystem-js/classes/client.Client.html).
## 5. Creating your wallet UI
The **wallet UI** is where your users will interact with your wallet.
Openfort `@openfort/ecosystem-js` comes with a set of pre-built components that you can use to create your wallet UI. To learn how to customize it further, head to the [UI screens guide](/docs/guides/ecosystem/configuration/wallet-ui).
In your project, import the **FortProvider** component and wrap your app with it. Set the **publishable key** field to you got from the Dashboard in step 3.
Concretely, the `FortProvider` must wrap any component or page that will use the Fort SDK in your react app. It is generally recommended to render it as close to the root of your application as possible.
For example, in a [NextJS](https://nextjs.org/) or [Create React App](https://create-react-app.dev/) project, you may wrap your components like so:
```tsx App.tsx
// Set your publishable key, shield publishable key and ecosystem id. Remember to switch to your live secret key in production.
// See your keys here: https://dashboard.openfort.xyz/developers/api-keys
// See your ecosystem ID here: https://dashboard.openfort.xyz/settings/project/overview
import {
WalletGrantPermissions,
WalletSendCalls,
EthRequestAccounts,
AppState,
EthSendTransaction,
EthSignTypedDataV4,
FortProvider,
PersonalSign,
withAuthenticationRequired,
Settings,
UnsupportedMethod,
WalletShowCalls,
darkFortTheme
} from '@openfort/ecosystem-js/react';
import { Route, Routes, useNavigate } from 'react-router-dom';
async function getShieldSession(accessToken:string):Promise {
const response = await fetch(`${process.env.REACT_APP_BACKEND_URL!}/api/protected-create-encryption-session`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${accessToken}`
}
});
if (!response.ok) {
throw new Error('Failed to fetch shield session');
}
const data = await response.json();
return data.session;
}
const ProtectedRoute = ({ component, ...args }: any) => {
const Component = withAuthenticationRequired(component, {
onRedirecting: () => ,
});
return ;
};
export default function Providers({children}: {children: React.ReactNode}) {
const nav = useNavigate()
return (
nav((appState && appState.returnTo) || window.location.pathname)}
publishableKey={process.env.REACT_APP_OPENFORT_PUBLIC_KEY!}
ecosystemId={process.env.REACT_APP_OPENFORT_ECOSYSTEM_ID!}
shieldConfig={{
shieldPublishableKey: process.env.REACT_APP_SHIELD_PUBLIC_KEY!,
getShieldSession: getShieldSession
}}
>
} />
} />
} />
} />
} />
} />
} />
} />
} />
} />
);
}
```
```tsx Loading.tsx
import React from 'react';
const Loading: React.FC = () => {
return (
Loading...
);
};
export default Loading;
```
Check all the available core methods in the [Core SDK reference](/docs/reference/ecosystem-js/classes/core.Core.html).
{/*
*/}
{/*
Security Considerations
The Openfort SDK ensures secure transactions using the following mechanisms:
- **SignableHash**: All transactions are represented by a `signableHash`, ensuring the integrity of each user action.
- **Access Tokens**: Authenticated via trusted third-party providers to ensure user identity is securely managed.
*/}
{/*
### 2. Set your login methods
### 3. Get your Openfort ecosystem ID
### 4. Import Fort into your app
### 5. Use Fort! */}
export const Page = ({ children }) =>
export default Page
---
File: /pages/guides/ecosystem/intro.mdx
---
import Layout from '@/layouts/DefaultGuideLayout'
export const meta = {
title: 'The Wallet Framework for Chains.',
breadcrumb: 'Ecosystem wallet',
tocVideo: 'pzMm86rmC3w',
}
The Ecosystem Wallet Framework represents a comprehensive solution for enterprises and developers seeking to implement robust, scalable wallet infrastructure across their blockchain ecosystem. This framework addresses the complexities of wallet architectures while maintaining enterprise-grade security and seamless integration capabilities.
## Why we built this
Let's be honest - building a smart wallet system from the ground up is no walk in the park. You've got to juggle quite a few balls: setting up authentication, picking the right smart contracts for accounts, implementing signers for ownership, and getting all the infrastructure ready for transaction sponsorship and bundling. Phew!
Sure, you could use a third-party provider to handle all this, but here's the tricky part: it needs to be flexible enough to adapt to your needs while still having as little vendore lock-in to integrate. And let's not forget about the developer experience - because nobody wants to spend weeks just figuring out how to implement a wallet system.
### What's in the box?
Here's the cool stuff you get with the Ecosystem SDK:
- **User Management**: Think of it as your bouncer - keeping track of who's who and making sure only the right people get in
- **Smooth Wallet Onboarding**: We make it super easy for users to get started with their wallets, add funds, and jump right in
- **Your Wallet, Your Rules**: Want to make it look and feel like your own? No problem! You've got full control through our whitelabel dashboard and customizable packages
- **Works Everywhere**: Whether you're building on Unity, Unreal Engine, or browsers, we've got you covered
### How it all fits together
The Ecosystem SDK is built like a well-organized kitchen, with three main stations:
1. **Developer Integration Layer**: Where you cook up your integration
2. **Client-Wallet Communication**: The service window where orders (transactions) get passed
3. **Blockchain Interaction**: Where the magic happens on the blockchain
## The main ingredients
### Client SDK (`@openfort/ecosystem/client`)
Think of this as your head chef - it runs the show. It handles everything from creating your custom wallet SDK to managing pop-ups and transactions. The best part? It lives right in your app's front-end and can wear your brand's colors. It even comes with built-in security features and plays nice with all the popular blockchain tools.
The Client SDK is EIP-1193 compatible, so it works great with popular tools like [viem](https://viem.sh)!
### Communication Module (`@openfort/ecosystem/core`)
This is your maitre d' - making sure everything flows smoothly between your client and the wallet. It helps new users get set up with their non-custodial wallets and works in any browser environment. Need more details? Check out our [wallet guide](/docs/guides/wallets).
### Framework Prefabs
These are like your ready-to-use recipe cards. We've got special helpers for different frameworks, including a really nice setup for [React](https://react.dev/) (`@openfort/ecosystem/react`). And yes, you can customize all the components to match your style!
## "But why not just use embedded wallets?"
Good question! While embedded wallets might seem simpler at first glance, they can actually create quite a headache when you're working across an ecosystem. Here's why:
### The Embedded Wallet setup
Picture this: every single app needs its own separate setup - installing packages, generating keys in iframes, handling authentication... It's like having to build a new kitchen for every restaurant in your chain!
### The Not-So-Fun parts of embedded wallets
1. **Authentication gets messy**
- Every app needs its own bouncer (authentication system)
- OAuth2 providers get confused when trying to share wallet access
- There's no good way to keep track of who's logged in where
2. **Less control than you'd like**
- Your partners need access to the master keys (Admin credentials)
- It's harder to keep track of who's spending what
- No central control room for permissions
3. **More work for everyone**
- Each partner has to figure out their own wallet setup
- More chances for security slip-ups
- No easy way to see what's happening across all apps
## Why the Ecosystem SDK is better
What you get:
- One login system that works everywhere (no more authentication headaches!)
- Control all permissions from one place
- A slick dashboard with your brand to onboard projects
- Paymasters and smart accounts by default
- One solid security setup for everything
export const Page = ({ children }) =>
export default Page
---
File: /pages/guides/ecosystem/libraries.mdx
---
import Layout from '@/layouts/DefaultGuideLayout'
import { IconCheck } from '@/components/ui'
export const meta = {
title: 'Integrating with wallet connectors',
breadcrumb: 'Ecosystem wallet',
}
Using a **wallet library** provides the most streamlined path to implementing a wallet UI, offering a complete solution with pre-built UI components and a polished user experience out of the box. This approach builds on top of Wagmi and includes additional UI components like the `ConnectButton`, ready-to-use themes, and built-in transaction interfaces. While it requires the most dependencies (`@rapidfire/id`, `Wagmi`, `React Query`, and `RainbowKit` -for example), it significantly reduces development time by providing a complete wallet interface solution.
To make these instructions concrete, we have created a sample ecosystem wallet called **Rapidfire ID**. To interact with it, you can find its SDK in the NPM package directory: [@rapidfire/id](https://www.npmjs.com/package/@rapidfire/id).
You can check out the GitHub [repository for Rapidfire Wallet](https://github.com/openfort-xyz/ecosystem-sample) to learn how to create your own wallet.
## Getting an EIP-1193 provider
All of Ecosystem SDK wallets can export a standard [EIP-1193 provider](https://eips.ethereum.org/EIPS/eip-1193) object. This allows your app to request signatures and transactions from the wallet, using familiar JSON-RPC requests like `personal_sign` or `eth_sendTransaction`.
[EIP-1193](https://eips.ethereum.org/EIPS/eip-1193), also known as the Ethereum JavaScript API, is a standardized interface for how applications can request information, signatures, and transactions from a connected wallet.
To get a wallet's EIP-1193 provider, use the `getEthereumProvider` method:
```tsx main.tsx
import { ecosystemWalletInstance } from "./rapidfireConfig"
// This example assumes you have already checked that Openfort 'embeddedState' is
// `ready` and the user is `authenticated`
const provider = await ecosystemWalletInstance.getEthereumProvider();
```
```ts rapidfireConfig.ts
import EcosystemWallet from '@rapidfire/id';
export const ecosystemWalletInstance = new EcosystemWallet({
appChainIds: [80002],
appLogoUrl: 'https://a.rgbimg.com/users/b/ba/barunpatro/600/mf6B5Gq.jpg',
appName: 'Example App',
});
```
When requesting signatures and transactions from the wallet, you can either choose to interface with the **EIP-1193** provider directly, or to pass it to a library like `wagmi` or `viem`.
If you want to check out the sample using the `@rapidfire/id` directly, you can find it in the [Rapidfire SDK repository](https://github.com/openfort-xyz/ecosystem-sample/tree/main/ecosystem-sdk/sdk-sample). You will see it includes examples using [ethers](https://docs.ethers.org/v5/), [connectKit](https://docs.family.co/connectkit), [rainbowKit](https://www.rainbowkit.com/) and [wagmi](https://wagmi.sh/).
## Implementation with RainbowKit
### 1. Install dependencies
Install the `@rapidfire/id` SDK and its peer dependencies:
```bash
npm i @rapidfire/id @rainbow-me/rainbowkit @tanstack/react-query
```
### 2. Create the connector
```ts config.ts
import EcosystemWallet from '@rapidfire/id';
export const identityInstance = new EcosystemWallet({
appChainIds: [80002],
appLogoUrl: 'https://a.rgbimg.com/users/b/ba/barunpatro/600/mf6B5Gq.jpg',
appName: 'Example App',
});
```
### 3. Wrap app with providers
At the highest level of your applications, wrap the component with the wagmi, QueryClient, and RainbowKit providers. Pass the configuration you created in step 2 to the wagmi provider.
All of **ecosystem wallets** can export a standard [EIP-1193 provider](https://eips.ethereum.org/EIPS/eip-1193) object. This allows your app to request signatures and transactions from the wallet, using familiar JSON-RPC requests like `personal_sign` or `eth_sendTransaction`.
[EIP-1193](https://eips.ethereum.org/EIPS/eip-1193), also known as the Ethereum JavaScript API, is a standardized interface for how applications can request information, signatures, and transactions from a connected wallet.
To get a wallet's EIP-1193 provider, use the `getEthereumProvider` method:
```tsx _app.tsx
import {QueryClient, QueryClientProvider} from '@tanstack/react-query';
import {WagmiProvider} from 'wagmi';
import {polygonAmoy} from 'wagmi/chains';
import {useEffect} from 'react';
import {config} from './wagmiConfig';
import {identityInstance} from './config';
const queryClient = new QueryClient();
export default function App() {
useEffect(() => {
if (!identityInstance) return;
identityInstance.getEthereumProvider();
}, []);
return (
);
}
```
```ts wagmiConfig.ts
import {http, createConfig} from 'wagmi';
import {polygonAmoy} from 'wagmi/chains';
import {injected} from 'wagmi/connectors';
export const config = createConfig({
chains: [polygonAmoy],
connectors: [injected()],
transports: {
[polygonAmoy.id]: http(),
},
});
```
```ts config.ts
import EcosystemWallet from '@rapidfire/id';
export const identityInstance = new EcosystemWallet({
appChainIds: [80002],
appLogoUrl: 'https://a.rgbimg.com/users/b/ba/barunpatro/600/mf6B5Gq.jpg',
appName: 'Example App',
});
```
### 4. Use the `ConnectButton`
Import the `ConnectButton` and use to prompt users to connect to their provider **ecosystem wallet**.
```tsx
import {ConnectButton} from '@rainbow-me/rainbowkit';
function Page() {
return (
My app
...
);
}
```
Thats it! You can now use any wagmi hook in your application to interact with the connected wallet. When users connect and transact with their wallet, Openfort will open a pop-up for users to authorize any actions.
export const Page = ({ children }) =>
export default Page
---
File: /pages/guides/ecosystem/react-native-integration.mdx
---
import Layout from '@/layouts/DefaultGuideLayout'
import { IconCheck } from '@/components/ui'
export const meta = {
title: 'Create a React Native App',
breadcrumb: 'Ecosystem wallet',
}
To make these instructions concrete, we have created a sample ecosystem wallet called **Rapidfire ID**. To interact with it, you can find its SDK in the NPM package directory: [@rapidfire/id](https://www.npmjs.com/package/@rapidfire/id).
You can check out the GitHub [repository for Rapidfire Wallet](https://github.com/openfort-xyz/ecosystem-sample) to learn how to create your own wallet.
This guide will walk you through adding support for any **ecosystem wallet** into a React Native app by integrating the [Mobile Wallet Protocol Client](https://www.npmjs.com/package/@mobile-wallet-protocol/client).
If you need a template or scaffold to start with, you can check out the [Ecosystem Wallet Expo Example](https://github.com/openfort-xyz/ecosystem-wallet-expo-example).
## Prerequisites
### Install peer dependencies
The Mobile Wallet Protocol Client library requires the [Expo WebBrowser](https://docs.expo.dev/versions/latest/sdk/webbrowser/) and [Async Storage](https://react-native-async-storage.github.io/async-storage/docs/install) packages to be installed.
Follow the instructions on the respective pages for any additional setup.
```zsh [npm]
npm i expo expo-web-browser @react-native-async-storage/async-storage
```
```zsh [yarn]
yarn add expo expo-web-browser @react-native-async-storage/async-storage
```
### Polyfills
Mobile Wallet Protocol Client requires `crypto.randomUUID`, `crypto.getRandomValues`, and `URL` to be polyfilled globally since they are not available in the React Native environment.
Below is an example of how to polyfill these functions in your app using the [expo-crypto](https://docs.expo.dev/versions/latest/sdk/crypto/) and [expo-standard-web-crypto](https://github.com/expo/expo/tree/master/packages/expo-standard-web-crypto/) packages.
```zsh [npm]
npm i expo-crypto expo-standard-web-crypto react-native-url-polyfill
```
```zsh [yarn]
yarn add expo-crypto expo-standard-web-crypto react-native-url-polyfill
```
```js [polyfills.js]
import "react-native-url-polyfill/auto";
import { polyfillWebCrypto } from "expo-standard-web-crypto";
import { randomUUID } from "expo-crypto";
polyfillWebCrypto();
crypto.randomUUID = randomUUID;
```
```tsx [App.tsx]
import "./polyfills"; // import before @mobile-wallet-protocol/client
/// ...
```
## Setup
### Install Mobile Wallet Protocol Client
Add the latest version of Mobile Wallet Protocol Client to your project.
```zsh [npm]
npm i @mobile-wallet-protocol/client@latest
```
```zsh [yarn]
yarn add @mobile-wallet-protocol/client@latest
```
## Usage
Mobile Wallet Protocol Client provides 2 interfaces for mobile app to interact with the Smart Wallet, an EIP-1193 compliant provider interface and a wagmi connector.
If your app is using wallet aggregator, go straight to **Option 2: Wagmi Connector** for 1-line integration. :)
### Option 1: EIP-1193 Provider
Create a new `EIP1193Provider` instance, which is EIP-1193 compliant.
```tsx [App.tsx]
import { EIP1193Provider } from "@mobile-wallet-protocol/client";
// Step 1. Initialize provider with your dapp's metadata and target wallet
const metadata = {
name: "My App Name",
customScheme: "myapp://", // only custom scheme (e.g. `myapp://`) is supported in v1.0.0
chainIds: [8453],
logoUrl: "https://example.com/logo.png",
};
const provider = new EIP1193Provider({
metadata,
wallet: {
type: 'web',
name: "Rapid fire wallet",
scheme: 'https://id.sample.openfort.xyz',
iconUrl: 'https://purple-magnificent-bat-958.mypinata.cloud/ipfs/QmfQrh2BiCzugFauYF9Weu9SFddsVh9qV82uw43cxH8UDV',
},
});
// ...
// 2. Use the provider
const addresses = await provider.request({ method: "eth_requestAccounts" });
const signedData = await provider.request({
method: "personal_sign",
params: ["0x48656c6c6f20776f726c6421", addresses[0]],
});
```
### Option 2: Wagmi Connector
Add the latest verion of Mobile Wallet Protocol wagmi-connectors to your project.
```zsh [npm]
npm i @mobile-wallet-protocol/wagmi-connectors@latest
```
```zsh [yarn]
yarn add @mobile-wallet-protocol/wagmi-connectors@latest
```
Simply import the `createConnectorFromWallet` function and pass in the wallet you want to use to wagmi config.
```ts [config.ts]
import {
createConnectorFromWallet,
Wallets,
} from "@mobile-wallet-protocol/wagmi-connectors";
const metadata = {
name: "My App Name",
customScheme: "myapp://", // only custom scheme (e.g. `myapp://`) is supported in v1.0.0
chainIds: [8453],
logoUrl: "https://example.com/logo.png",
};
export const config = createConfig({
chains: [base],
connectors: [
createConnectorFromWallet({
metadata,
wallet: {
type: 'web',
name: "Rapid fire wallet",
scheme: 'https://id.sample.openfort.xyz',
iconUrl: 'https://purple-magnificent-bat-958.mypinata.cloud/ipfs/QmfQrh2BiCzugFauYF9Weu9SFddsVh9qV82uw43cxH8UDV',
},
}),
],
transports: {
[base.id]: http(),
},
});
```
Then you can use wagmi's react interface to interact with the Smart Wallet.
```tsx [App.tsx]
import { useConnect } from "wagmi";
// ...
const { connect, connectors } = useConnect();
return (