@notifi-network/notifi-react
Version:
React components to access Notifi core services
788 lines (554 loc) • 30.1 kB
Markdown
# Notifi React SDK
`@notifi-network/notifi-react` accelerates the development of Notifi integrated dapps.
- [Out of The Box Implementation](#out-of-the-box-implementation)
- [Customized Implementation](#advanced-customized-implementation)
- [Custom Integration](#custom-integration)
- [Migrating from an older version of the SDK ](#migrate-your-card)
> Play around with a Card [Example](notifi-sdk-ts-notifi-dapp-example.vercel.app)
<br/><br/>
# Out of The Box Implementation
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
<br/><br/>
## Getting Started
_Environment_
- Node version >= 18 (with corresponding npm version)
- React version >= 17
> If you haven't created a Notifi tenant account yet [set up an account](https://admin.notifi.network/signup?environment=prd)
<br/><br/>
### Mount the `NotifiCardModal` to your dApp
#### Prerequisites (**IMPORTANT**)
- To use `NotifiCardModal`, you need to wrap your component with `NotifiContextProvider` first.
- Notifi supports both `on-chain` and `off-chain` authentication. The authentication method differs based on the `LoginParamsWithUserParams` [type](https://github.com/notifi-network/notifi-sdk-ts/blob/55b6d24c90d962e5ae4e20508015904754edbf0f/packages/notifi-react/lib/context/NotifiFrontendClientContext.tsx#L56) passed to the `NotifiContextProvider`.
- For `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.
- For `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.
#### **Example Quick Start for Ethereum (On chain)**
```tsx
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>
);
};
```
#### **Example Quick Start for google OIDC (Off chain)**
```tsx
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](https://docs.notifi.network/docs/getting-started)
> - Notifi supported blockchains: [WalletBlockchain Enum document](https://graphdoc.io/preview/enum/WalletBlockchain?endpoint=https://api.dev.notifi.network/gql/)
> - Notifi supported OIDC providers: [OidcProvider Enum document](https://graphdoc.io/preview/enum/OidcProvider?endpoint=https://api.dev.notifi.network/gql/)
> - To enable OIDC login, it requires additional setup to integrate your OIDC provider with Notifi tenant using [Notifi Admin Portal](https://admin.notifi.network/) check on the Notifi Documentation **(WIP: coming soon)**
<br/><br/>
# Customize NotifiCardModal component
`NotifiCardModal` is fully customizable using **global CSS overrides** and **optional properties**.
<br/>
## Global CSS overrides
By overriding the default CSS classes, we can style the elements in the card.
[Default CSS Classes are found here.](https://github.com/notifi-network/notifi-sdk-ts/tree/main/packages/notifi-react/lib/style)
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_
```tsx
import '@notifi-network/notifi-react/dist/index.css';
```
> - Make sure this import is placed at the top level of the component file. [complete example](https://github.com/notifi-network/notifi-sdk-ts/blob/97280b625ef133811d176fbb8add73f6b3f7bd44/packages/notifi-react-example-v2/src/components/OidcGoogle.tsx#L9)
> Find the overrideable CSS classes [here](https://github.com/notifi-network/notifi-sdk-ts/tree/97280b625ef133811d176fbb8add73f6b3f7bd44/packages/notifi-react/lib/style)
<br/><br/>
## Other Optional Properties
`NotifiCardModal` component provides the following additional optional properties to customize the card even further:
- [darkMode](#adjusting-card-color-scheme---darkmode)
- [globalCtas](#additional-optional-cta-call-to-action---globalctas)
- [copy](#customizing-the-card-copy---copy)
- [classNames](#embedding-custom-css-classes-in-components---classnames)
> Check out the [NotifiCardModalProps type documentation ](https://docs.notifi.network/notifi-sdk-ts/notifi-react/types/NotifiCardModalProps.html) to know more details
<br/>
#### Adjusting card color scheme - `darkMode`
The `darkMode` property allows you to switch the card color scheme between light and dark mode.
> Default scheme: `light` (light mode)
**Example**
```tsx
<NotifiCardModal darkMode />
```
<br/>
#### Additional optional CTA (Call to Action) - `globalCtas`
The `globalCtas` property allows to add certain supported CTAs to the card. Now it supports `onClose` CTA.
**Example**
```tsx
// ...
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.

<br/>
#### Customizing the card copy - `copy`
The `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 ](https://docs.notifi.network/notifi-sdk-ts/notifi-react/types/NotifiCardModalProps.html) to know more details
**Common Example: Customizing the Connect view footer**
Connect view footer preview as seen below:

_Example code_
```tsx
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](https://github.com/notifi-network/notifi-sdk-ts/blob/main/packages/notifi-react-example-v2/src/app/notifi/components-example/page.tsx)
<br/>
#### Embedding custom CSS classes in components - `classNames`
You can pass in custom CSS classes to the `NotifiCardModal` component.
Check out the `classNames` property in [NotifiCardModalProps type documentation ](https://docs.notifi.network/notifi-sdk-ts/notifi-react/types/NotifiCardModalProps.html) to know the className customizable components.
_Example_
```tsx
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} />
{/* ... */}
</>
);
};
```
<br/><br/>
# Custom Integration
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.
<br/><br/>
### Important Notifi React Contexts:
- **NotifiContextProvider**: A provider to wrap your dapp with all Notifi contexts.
- **Specific Context Providers**:
- **NotifiFrontendClientContext**: Provides the Notifi Frontend Client instance and user authentication status (Authenticated, Initiated, or Expired)
- **NotifiTenantConfigContext**: Provides the tenant configuration.
- **NotifiUserSettingContext**: Provides available user methods and states
- **NotifiTargetContext**: Provides Notifi Target related methods and state.
- **NotifiTopicContext**: Provides Topic related methods and state.
> By wrapping your app with `NotifiContextProvider`, you can access the Notifi services in your dapp.
_Example_
```tsx
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.
```tsx
import {
NotifiFrontendClientProvider,
NotifiTenantConfigProvider,
} from '@notifi-network/notifi-react';
const App = () => {
const params = {
// params for contexts
};
return (
<NotifiFrontendClientProvider {...params}>
<NotifiTenantConfigProvider {...params}>
<MyComponent />
</NotifiTenantConfigProvider>
</NotifiFrontendClientProvider>
);
};
```
<br></br>
## **NotifiFrontendClientContext**
Provides the Notifi Frontend Client and the user authentication status.
_Example_
```tsx
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:
- **initiated**: The frontend client/user has been initiated but not authenticated.
- **authenticated**: The frontend client/user is authenticated.
- **expired**: The frontend client/user is authentication/authorization expired.
- **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.
<details>
<summary>Example for EVM dapp</summary>
**Case 1**: Plain transaction
```ts
// 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
```ts
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**:
- **Browser extension constraints**: Some browser extensions (Metamask ...) do not allow appending additional info to the calldata of particular smart contract method (example: Token contract (ERC20, ERC721 ...etc)). Browser extension (Metamask) will throw `Message: Invalid token value; should be exactly xx hex digits long` error in this case.
</details>
## **NotifiTenantConfigContext**
Provides the tenant configuration.
```tsx
import { useNotifiTenantConfigContext } from '@/context/NotifiTenantConfigContext';
export const MyComponent = () => {
const { cardConfig, inputs, isLoading, error, fusionEventTopics } =
useNotifiTenantConfigContext();
// Other code ...
};
```
- **cardConfig**: The card UI configuration set in Notifi Admin portal.
- **fusionEventTopics**: The detailed information of the fusion event topics in the specific UI card config. [Interface.](https://github.com/notifi-network/notifi-sdk-ts/blob/main/packages/notifi-react/lib/context/NotifiTenantConfigContext.tsx#L18)
- **inputs**: `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](https://github.com/notifi-network/notifi-sdk-ts/blob/main/packages/notifi-frontend-client/lib/models/FusionEvent.ts#L24) interface.
<br></br>
**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.
<br></br>

**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.
- **Example**:
We want to allow users to define multiple smart contracts' state change (eg. staked value changed). So we want to provide a list of options for users to select. If we set `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 `value` in the `InputObject` should associate with the subscription value in the parser. `label` is the display name in the UI.
>
> - [Additional Documentation](https://docs.notifi.network/docs/next/notifi-hosted-development)
<br></br>
## **NotifiUserSettingContext**
Provides user specific methods and state.
```tsx
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.
<br></br>
## **NotifiTargetContext**
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:
- Email
- Telegram
- SMS
- Discord
- Slack
- Want another destination? [Email Us](sales@notifi.network)
_Example_
```tsx
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.
- **Update single target**: passing `singleTargetRenewArgs` as an argument. **NOTE**: This action does not require updating `targetInputs` manually. `targetInputs` will be updated automatically once `renewTargetGroup` is called successfully.
- **Update all targets**: all targets will be updated according to the `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 `NotifiContextProviderWalletTargetPlugin` context in `@notifi-network/notifi-react-wallet-target-plugin` if Target.wallet.isAvailable is set to `true`. For more details, refer to `@notifi-network/notifi-react-wallet-target-plugin` README.
<br></br>
## **NotifiTopicContext**
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 `Alert` object associated to the users with the respective topic.
> [Additional Information.](https://github.com/notifi-network/notifi-sdk-ts/blob/main/packages/notifi-react/lib/context/NotifiTopicContext.tsx#L60)
_Example_
```tsx
import { useNotifiTopicContext } from '@notifi-network/notifi-react';
export const MyComponent = () => {
const {
isLoading,
error,
subscribeAlertsDefault,
unsubscribeAlerts,
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.
- **unsubscribeAlerts**: A function to unsubscribe to the respective topics. This will remove target alerts 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.](https://github.com/notifi-network/notifi-sdk-ts/tree/main/packages/notifi-card-modal-example)
> For more comprehensive information, please refer to the [notifi-dapp-example.](https://github.com/notifi-network/notifi-sdk-ts/tree/main/packages/notifi-dapp-example)
<br></br>
## **NotifiHistoryContext**
Check or manipulate the notification history of the connected users' account.
_Example_
```tsx
import { useNotifiHistoryContext } from '@notifi-network/notifi-react';
export const MyComponent = () => {
const {
isLoading,
error,
getHistoryItems,
markAsRead,
historyItems,
unreadCount,
hasNextPage,
} = useNotifiHistoryContext();
// Other code ...
};
```
**Input props**
- **notificationCountPerPage** (Optional): The number of notifications per fetch in the notification history. The default value is `20`.
- **unreadCountScope** (Optional): The scope can be `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 `notificationCountPerPage` in the `<NotifiContextProvider />`or `<NotifiHistoryContextProvider />` Property.
> [See an Example.](https://github.com/notifi-network/notifi-sdk-ts/blob/main/packages/notifi-react-example-v2/src/context/NotifiContextWrapper.tsx#L121)
<br> <br>
# Migrate Your Card
#### Migrate from `@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`)._
<br> <br>
#### Migrating to `@notifi-network/notifi-react` will have the following benefits:
- **Optimized bundle size**: the package size reduction of ~20%.
- **Better efficiency and performant**: the network request are reduced by ~50%.
- **Better UI & UX**: The new UI/UX design is more user-friendly, intuitive, and customizable.
- **Advanced new features**: support Notifi Admin Portal V2 new features. Check out Notifi Admin Portal V2 [here](https://admin.notifi.network/) for more information.
> **IMPORTANT** `@notifi-network/notifi-react-card` will no longer be maintained. Please use the `@notifi-network/notifi-react` if you are new to the Notifi React SDK.
> For any existing Dapps utilizing `@notifi-network/notifi-react-card`, follow the migration guide below.
<br> </br>
## Migration Guide
As `@notifi-network/notifi-react` is a separate package from `@notifi-network/notifi-react-card`, new package installation is required.
```json
// 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"
}
// ...
}
```
<br> </br>
### Step 1: Replace the `NotifiContext` with the `NotifiContextProvider`
Many of input props of the `NotifiContextProvider` are the same as `NotifiContext`. Differences are highlighted below.
<br> </br>
**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.](https://github.com/notifi-network/notifi-sdk-ts/blob/main/packages/notifi-react/lib/context/NotifiTargetContext.tsx#L82)
<br> </br>
### Step 2: Replace the `<NotifiSubscriptionCard />` with the `<NotifiCardModal />`
Most of the props of `NotifiCardModal` are the same as `NotifiSubscriptionCard`. The only differences are listed below:
<br> </br>
**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](customizing-the-card-copy)
> Examples Found In [`@notifi-network/notifi-react-example-v2`](https://github.com/notifi-network/notifi-sdk-ts/blob/main/packages/notifi-react-example-v2/src/app/notifi/components-example/page.tsx#L19)
**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)
<br></br>
### Step 3 Restyle the card by using the css override
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.](https://github.com/notifi-network/notifi-sdk-ts/tree/main/packages/notifi-react/lib/style)
<br></br>
### Step 4: Remove all the related code of the `@notifi-network/notifi-react-card`
- Remove 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`.