@notifi-network/notifi-react accelerates the development of Notifi integrated dapps.
Play around with a Card Example
Dapp developers can easily mount the NotifiCardModal component to their dapp to enable the Notifi notification service. The NotifiCardModal component provides the following features to the user:
Login to Notifi Services
Manage Subscriptions to Notifications
Manage Targets/Channels for Notifications
Preview Notification Details
Environment
If you haven't created a Notifi tenant account yet set up an account
NotifiCardModal to your dAppNotifiCardModal, you need to wrap your component with NotifiContextProvider first.on-chain and off-chain authentication. The authentication method differs based on the WalletWithSignParams props passed to the NotifiContextProvider.
on-chain authentication, walletBlockchain='<blockchain>', signMessage callback function, and the respective wallet keys or addresses for the blockchain are required. The common EVM blockchain example is shown above.off-chain authentication, walletBlockchain='OFF_CHAIN', signIn callback function, and userAccount are required. userAccount can be any user-related unique identifier derived from a JWT token. The Google off-chain OIDC authentication example is shown below.import {
NotifiCardModal,
NotifiContextProvider,
} from '@notifi-network/notifi-react';
import { useEthers } from '@usedapp/core';
import { providers } from 'ethers';
const NotifiCard = () => {
const { account, library } = useEthers();
const signer = useMemo(() => {
if (library instanceof providers.JsonRpcProvider) {
return library.getSigner();
}
return undefined;
}, [library]);
if (account === undefined || signer === undefined) {
// account is required
return null;
}
return (
//tenantId/dAppId and cardId are found on the Notifi Tenant Portal. Please see Docs below.
<NotifiContextProvider
tenantId="YOUR_TENANT_ID"
env="Production"
cardId="YOUR_CARD_ID"
signMessage={signMessage}
walletBlockchain="ETHEREUM"
walletPublicKey={account}
{/* ... other optional props */}
>
<NotifiCardModal {/* ... other optional props ex. darkMode */} />
</NotifiContextProvider>
);
};
const NotifiCard = () => {
// ... other codes
const jwt = '<the-oidc-id-token-here>';
const userAccount = jwtDecode(jwt).email; // or any unique identifier
const signIn: OidcSignInFunction = async () => {
return {
oidcProvider: 'GOOGLE',
jwt,
};
};
return (
<NotifiContextProvider
tenantId="YOUR_TENANT_ID"
env="Production"
cardId="YOUR_CARD_ID"
walletBlockchain={'OFF_CHAIN'}
userAccount={userAccount}
signIn={signIn}
{/* ... other optional props */}
>
<NotifiCardModal {/* ... other optional props ex. darkMode */} />
</NotifiContextProvider>
);
};
Reference
- Getting start Docs
- Notifi supported blockchains: WalletBlockchain Enum document
- Notifi supported OIDC providers: OidcProvider Enum document
- To enable OIDC login, it requires additional setup to integrate your OIDC provider with Notifi tenant using Notifi Admin Portal check on the Notifi Documentation (WIP: coming soon)
NotifiCardModal is fully customizable using global CSS overrides and optional properties.
By overriding the default CSS classes, we can style the elements in the card. Default CSS Classes are found here.
Before overriding the CSS classes, we need to adopt the default style of the NotifiCardModal component. To do this, we need to import the default CSS file from the @notifi-network/notifi-react package like below.
Example
import '@notifi-network/notifi-react/dist/index.css';
- Make sure this import is placed at the top level of the component file. complete example Find the overrideable CSS classes here
NotifiCardModal component provides the following additional optional properties to customize the card even further:
Check out the NotifiCardModalProps type documentation to know more details
darkModeThe darkMode property allows you to switch the card color scheme between light and dark mode.
Default scheme:
light(light mode)
Example
<NotifiCardModal darkMode />
globalCtasThe globalCtas property allows to add certain supported CTAs to the card. Now it supports onClose CTA.
Example
// ...
const [isCardModalOpen, setIsCardModalOpen] = useState(false);
// ...
{
isCardModalOpen ? (
<NotifiCardModal
globalCtas={{ onClose: () => setIsCardModalOpen(false) }}
/>
) : null;
}
NOTE
The onClose function enables the close-icon on the card. We are passing a callback function here to update the local state and close the modal.
copyThe copy property allows you to customize the card's default copy.
There are many customizable copy sections in the NotifiCardModal component. Check out the NotifiCardModalProps type documentation to know more details
Common Example: Customizing the Connect view footer
Connect view footer preview as seen below:
Example code
const YourComponent = () => {
// ...
const { frontendClientStatus } = useNotifiFrontendClientContext();
const customCopy: NotifiCardModalProps['copy'] = {
Connect: {
footerContent: [
{
type: 'plain-text',
text: 'This is an example of some footer content that may link to a ',
},
{
type: 'hyperlink',
text: 'privacy policy',
url: 'https://notifi.network',
},
{ type: 'plain-text', text: ' and ' },
{
type: 'hyperlink',
text: 'terms of service',
url: 'https://notifi.network',
},
],
},
// ... other copy customization
};
return (
<>
{/* ... */}
<NotifiCardModal copy={customCopy} />
{/* ... */}
</>
);
};
- Checkout the example project codebase
classNamesYou can pass in custom CSS classes to the NotifiCardModal component.
Check out the classNames property in NotifiCardModalProps type documentation to know the className customizable components.
Example
const YourComponent = () => {
// ...
const customClassName: NotifiCardModalProps['classNames'] = {
container: 'custom-card-modal-container', // This will add 'custom-card-modal-container' class to the card modal container
};
return (
<>
{/* ... */}
<NotifiCardModal classNames={customClassName} />
{/* ... */}
</>
);
};
If you want to build your own UI components instead of using the NotifiCardModal, you can use the Notifi React Context to access the Notifi core services.
By wrapping your app with
NotifiContextProvider, you can access the Notifi services in your dapp.
Example
import { NotifiContextProvider } from '@notifi-network/notifi-react';
const App = () => {
const params = {
// params for contexts
};
return (
<NotifiContextProvider {...params}>
<MyComponent />
</NotifiContextProvider>
);
};
Or use particular contexts to access specific Notifi services.
import {
NotifiFrontendClientProvider,
NotifiTenantConfigProvider,
} from '@notifi-network/notifi-react';
const App = () => {
const params = {
// params for contexts
};
return (
<NotifiFrontendClientProvider {...params}>
<NotifiTenantConfigProvider {...params}>
<MyComponent />
</NotifiTenantConfigProvider>
</NotifiFrontendClientProvider>
);
};
Provides the Notifi Frontend Client and the user authentication status.
Example
import { useNotifiFrontendClientContext } from '@/context/NotifiFrontendClientContext';
export const MyComponent = () => {
const { login, frontendClientStatus, frontendClient } =
useNotifiFrontendClientContext();
// Other code ...
};
Methods
login: A function to trigger the login process.
frontendClientStatus: The status of the frontend client, it can be one of the following:
frontendClient: The frontend client instance, used to interact with the Notifi backend services.
loginViaTransaction: SDK allows Dapp to auto login the user by utilizing this property. See the following detailed information.
We can improve the user experience by auto-login the users as soon as they sign a transaction. This way, users no longer need to manually sign a message to login to Notifi. The loginViaTransaction property is used to achieve this feature.
Step1: Wrap higher (top) level of dapp components with <NotifiContextProvider> (or <NotifiFrontendClientProvider> ).
Step2: put the loginViaTransaction.nonce as memo when user signs a transaction.
Step3: Pass in the signature from Step#2 to the loginViaTransaction.login method.
Case 1: Plain transaction
// Any component in the dapp which has access to the NotifiFrontendClientContext
const {
walletWithSignParams,
loginViaTransaction: {
nonce: nonceForTransactionLogin,
login: loginViaTransaction,
},
} = useNotifiFrontendClientContext();
// EVM transaction (Other supported chains also work in similar manner)
const memo = nonceForTransactionLogin;
const signature = await transactionSigner.request({
method: 'eth_sendTransaction',
params: [
{
from: walletWithSignParams.walletPublicKey,
// ...
data: memo,
},
],
});
loginViaTransaction(signature);
Case 2: smart contract transaction
const {
walletWithSignParams,
loginViaTransaction: {
nonce: nonceForTransactionLogin,
login: loginViaTransaction,
},
} = useNotifiFrontendClientContext();
const smartContract = new ethers.Contract(
`<contract-address>`,
`<contract-abi>`,
provider.getSigner(),
);
// Assume the smart contract has an "example" method with one argument uint amount
const amount = ethers.utils.parseUnits('0.1', 'ether');
// Step 1: Get the calldata for the smart contract method call
const calldata = smartContract.interface.encodeFunctionData('example', [
amount,
]);
// Step 2: Append notifi nonce to the calldata
const txParams = {
to: smartContract.address,
data: calldata + nonceForTransactionLogin.replace('0x', ''),
};
// Step 3: Sign the transaction with new calldata
const { hash } = await provider.getSigner().sendTransaction(txParams);
// Step 4: Use the transaction signature to login to notifi
loginViaTransaction(hash);
IMPORTANT NOTE:
Message: Invalid token value; should be exactly xx hex digits long error in this case.Provides the tenant configuration.
import { useNotifiTenantConfigContext } from '@/context/NotifiTenantConfigContext';
export const MyComponent = () => {
const { cardConfig, inputs, isLoading, error, fusionEventTopics } =
useNotifiTenantConfigContext();
// Other code ...
};
input is a concept which is used when a dynamic topic subscription value needs to be adopted. The input is a key-value pair object. The key is the value associated with the Create a new topic section in Admin Portal. The value is the dynamic value that needs to be passed into the topic subscription. The value needs to be an array of InputObject interface.Example:
We want to allow a user to subscribe the topic which relates to his/her specific wallet address' state (eg, a transaction signed by the wallet). In this case, we need to pass the wallet address to the topic subscription. The input is where we would store the dynamic value.

Case 1: Wallet Address is selected, the key is set to walletAddress. So the input will be
input={ walletAddress: [{label: '', '<USER_WALLET_ADDRESS_GOES_HERE>'}] }
Case 2: No input From User is selected, we do not need to specify the inputs object.
Case 3: User Selects From List is selected with a self-defined value. It means we want to allow users to select preferred targets to subscribe.
farm in Admin portal UX in User Selects From List section. And we want to allow to have BTC/ETH farm and BTC/USDT farm, we can set the inputs object to { farm: [{label: 'BTC/ETH farm', value: 'BTC-ETH'}, {label: 'BTC/USDT farm', value: 'BTC-USDT'}] }. The value is the value that will be passed to the topic subscription.NOTE the
valuein theInputObjectshould associate with the subscription value in the parser.labelis the display name in the UI.
Provides user specific methods and state.
import { useNotifiUserSettingContext } from '@notifi-network/notifi-react';
export const MyComponent = () => {
const { ftuStage, updateFtuStage, isLoading, error } =
useNotifiUserSettingContext();
// Other code ...
};
Methods
ftuStage: The current First Time User stage of the user.
updateFtuStage: A function to update the FTU stage of the user.
Provides the Notifi Target related methods and state.
Target is an important concept in Notifi. It is the destination which need to be notified when the specific event is triggered. Notifi currently supports the following targets:
Example
import { useNotifiTargetContext } from '@notifi-network/notifi-react';
export const MyComponent = () => {
const {
error,
isLoading,
renewTargetGroup,
unVerifiedTargets,
isChangingTargets,
targetDocument: {
targetGroupId,
targetInputs,
targetData,
targetInfoPrompts,
},
updateTargetInputs,
} = useNotifiTargetContext();
// Other code ...
};
Methods
renewTargetGroup: A function to renew the target group. targetGroup is a group of targets which owned by the user.
unVerifiedTargets: The list of targets which are not verified yet.
targetInputs: The targetInputs is the temporary storage which reflects the on-demand target input changes. It is used to store the target input changes before the user confirms the changes.
isChangingTargets: if a target is undergoing a change, it means the users are changing the target inputs and has unsaved changes.
targetInfoPrompts: The targetInfoPrompts is the prompt message which is used to guide the user to input the target destination information.
updateTargetInputs: A function to update the target inputs. It is used to update the target when the user changes/finalizes the target inputs.
renewTargetGroup: A function to update the backend target state according to the targetInputs.
singleTargetRenewArgs as an argument. NOTE: This action does not require updating targetInputs manually. targetInputs will be updated automatically once renewTargetGroup is called successfully.targetInputs state w/o passing any argument.TargetGroupId: The target group id which is the argument to call renewTargetGroup function.
targetData: The target data which is the current state of the targets in the backend.
!!IMPORTANT NOTE: targetData.wallet
For version 6.0.0 or above, Please use
NotifiContextProviderWalletTargetPlugincontext in@notifi-network/notifi-react-wallet-target-pluginif Target.wallet.isAvailable is set totrue. For more details, refer to@notifi-network/notifi-react-wallet-target-pluginREADME.
Provide the topic related methods and state.
Topic is an important concept in Notifi. It is the prototype that shapes the event which will be triggered. Users are able to subscribe to certain topics in order to receive the notification when the event is triggered.
IMPORTANT CONCEPT Once a user subscribes to a topic, Notifi Service creates an
Alertobject associated to the users with the respective topic. Additional Information.
Example
import { useNotifiTopicContext } from '@notifi-network/notifi-react';
export const MyComponent = () => {
const {
isLoading,
error,
subscribeAlertsDefault,
unsubscribeAlert,
isAlertSubscribed,
subscribeAlertsWithFilterOptions,
getAlertFilterOptions,
getTopicStackAlerts,
} = useNotifiTopicContext();
// Other code ...
};
Methods
subscribeAlertsDefault: A function to subscribe to the respective topic with the default filterOptions. This will create an alert configuration for the user.
unsubscribeAlert: A function to unsubscribe to the respective topic. This will remove the alert configuration from the user's alert list.
isAlertSubscribed: A function to check if the topic is subscribed (This checks whether an alert configuration exists).
subscribeAlertsWithFilterOptions: A function to subscribe to the respective topic with custom filter options. This will create an alert configuration for the user.
getAlertFilterOptions: A function to get the filter options from the subscribed topic (Alert configuration/object).
getTopicStackAlerts: A function to get the subscribed stackable topic. (Alert configuration/objects).
Notifi provides an example project to showcase the usage of the Notifi React Context through this Example.
For more comprehensive information, please refer to the notifi-dapp-example.
Check or manipulate the notification history of the connected users' account.
Example
import { useNotifiHistoryContext } from '@notifi-network/notifi-react';
export const MyComponent = () => {
const {
isLoading,
error,
getHistoryItems,
markAsRead,
historyItems,
unreadCount,
hasNextPage,
} = useNotifiHistoryContext();
// Other code ...
};
Input props
20.card or tenant. The default value is card.Methods
getHistoryItems: A function to get the notification history items. This method will update the historyItems state. It takes (initialLoad?: boolean) as input arguments. If initialLoad is true, it will clean the existing historyItem and fetch the first page of the notification history items. If initialLoad is undefined or false, it will fetch the next page from an existing page cursor. You can use hasNextPage to check if there are more pages to fetch.
markAsRead: A function to mark all or particular notification items as read. it takes(ids?: string[]) as input. If ids is not provided, it will mark all the items as read.
historyItems: The Notification History Items.
unreadCount: An integer variable representing the unread notification count in historyItems.
hasNextPage: A boolean variable to check if there is more page to fetch. If true, calling getHistoryItems() will fetch the next page.
NOTE: page counts are set to 20 by default. You can change the page count by setting the
notificationCountPerPagein the<NotifiContextProvider />or<NotifiHistoryContextProvider />Property. See an Example.
@notifi-network/notifi-react-card (v0.) to @notifi-network/notifi-react (v1.)@notifi-network/notifi-react is a major upgrade of @notifi-network/notifi-react-card. @notifi-network/notifi-react which provides more advanced features by adopting the new Notifi infrastructure (called fusion).
@notifi-network/notifi-react will have the following benefits:IMPORTANT
@notifi-network/notifi-react-cardwill no longer be maintained. Please use the@notifi-network/notifi-reactif you are new to the Notifi React SDK. For any existing Dapps utilizing@notifi-network/notifi-react-card, follow the migration guide below.
As @notifi-network/notifi-react is a separate package from @notifi-network/notifi-react-card, new package installation is required.
// package.json
{
// ...
"dependencies": {
"@notifi-network/notifi-frontend-client": "^1.0.0",
"@notifi-network/notifi-graphql": "^1.0.0",
"@notifi-network/notifi-react": "^1.0.0"
}
// ...
}
NotifiContext with the NotifiContextProviderMany of input props of the NotifiContextProvider are the same as NotifiContext. Differences are highlighted below.
Deprecated props
alertConfigurations(Optional) is deprecated. (No longer needed)keepSubscriptionData (Optional) is deprecated. (No longer needed)multiWallet (Optional) is deprecated. (No longer needed)isUsingFrontendClient (Optional) is deprecated. (No longer needed)Newly added props
tenantId (Required): The tenantId or dAppID (as referenced on the Admin Portal) property originally was set in the NotifiSubscriptionCard component as dappAddress. Now it is moved to context provider level.
cardId (Required): The cardId property originally was set in the NotifiSubscriptionCard component. Now it is moved to context provider level.
notificationCountPerPage (Optional): The notificationCountPerPage property is used to set the number of notifications per fetch in the notification history. The default value is 20.
toggleTargetAvailability (Optional): The toggleTargetAvailability property is used to enable/disable the target availability feature. The default value depends on the active destinations set in the Notifi Admin Portal. Additional infromation can be found here.
<NotifiSubscriptionCard /> with the <NotifiCardModal />Most of the props of NotifiCardModal are the same as NotifiSubscriptionCard. The only differences are listed below:
Deprecated props
loadingSpinnerSize (Optional) is deprecated. (No longer needed as we can utilize css overrides to customize the spinner size)
loadingSpinnerColor (Optional) is deprecated. (No longer needed as we can utilize css overrides to customize the spinner color)
cardId (Optional) is deprecated. (No longer needed as we can set the cardId in the NotifiContextProvider)
inputLabels and inputSeparators (Optional) is deprecated. Instead, we can use the copy prop to customize the input labels. Seen Here
Examples Found In
@notifi-network/notifi-react-example-v2
On-going: (SUBJECT TO CHANGES)
disclosureCopy (Optional): Not supported yet. but it is planned to be removed and make use of the copy prop instead (TBD)
onClose (Optional)
Component layout has significant changes, and accordingly the css classes of the NotifiCardModal are also changed. If you are already using the existing NotifiSubscriptionCard with the global css override, you will need to deprecate all the css classes and re-implement the new global css override.
For more detail about CSS classes, please refer to the source code.
@notifi-network/notifi-react-cardRemove the @notifi-network/notifi-react-card package from the package.json file.
Remove the NotifiSubscriptionCard component from the codebase.
Remove the NotifiContext component from the codebase.
Remove the legacy css override related to the NotifiSubscriptionCard.