Skip to content

Commit

Permalink
react: add useProfilePrice hook
Browse files Browse the repository at this point in the history
  • Loading branch information
krzysu committed Feb 29, 2024
1 parent 25ac31f commit ec15aec
Show file tree
Hide file tree
Showing 7 changed files with 103 additions and 2 deletions.
7 changes: 7 additions & 0 deletions .changeset/eleven-frogs-battle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@lens-protocol/react": minor
"@lens-protocol/react-native": minor
"@lens-protocol/react-web": minor
---

**feat:** added `useProfilePrice` hook to fetch onchain profile minting price
12 changes: 11 additions & 1 deletion examples/web/src/profiles/UseCreateProfile.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
import { useCreateProfile } from '@lens-protocol/react-web';
import { useCreateProfile, useProfilePrice } from '@lens-protocol/react-web';
import toast from 'react-hot-toast';

import { RequireConnectedWallet } from '../components/auth';

function ProfilePrice() {
const { data: price, loading, error } = useProfilePrice();

if (loading) return 'Fetching price...';
if (error) return 'Error fetching price.';

return <p>{`Price: ${price.toSignificantDigits()} ${price.asset.symbol}`}</p>;
}

export function CreateProfileForm({ address }: { address: string }) {
const { execute, loading } = useCreateProfile();

Expand Down Expand Up @@ -39,6 +48,7 @@ export function CreateProfileForm({ address }: { address: string }) {
<div style={{ display: 'flex', flexDirection: 'row', justifyContent: 'flex-end' }}>
<button disabled={loading}>Submit</button>
</div>
<ProfilePrice />
</fieldset>
</form>
);
Expand Down
1 change: 1 addition & 0 deletions packages/react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
"@ethersproject/hash": "^5.7.0",
"@ethersproject/logger": "^5.7.0",
"@ethersproject/providers": "^5.7.2",
"@ethersproject/units": "^5.7.0",
"@ethersproject/wallet": "^5.7.0",
"@lens-protocol/api-bindings": "workspace:*",
"@lens-protocol/blockchain-bindings": "workspace:*",
Expand Down
37 changes: 37 additions & 0 deletions packages/react/src/misc/adapters/useProfilePriceController.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { formatUnits } from '@ethersproject/units';
import { UnspecifiedError } from '@lens-protocol/api-bindings';
import { permissionlessCreator } from '@lens-protocol/blockchain-bindings';
import {
Amount,
ChainType,
Matic,
PromiseResult,
assertError,
failure,
matic,
success,
} from '@lens-protocol/shared-kernel';

import { useSharedDependencies } from '../../shared';

export function useProfilePriceController() {
const { config, providerFactory } = useSharedDependencies();

return async (): PromiseResult<Amount<Matic>, UnspecifiedError> => {
try {
const provider = await providerFactory.createProvider({ chainType: ChainType.POLYGON });
const contract = permissionlessCreator(
config.environment.contracts.permissionlessCreator,
provider,
);

const priceBN = await contract.getProfileWithHandleCreationPrice();
const result = formatUnits(priceBN, matic().decimals);

return success(Amount.matic(result));
} catch (error) {
assertError(error);
return failure(new UnspecifiedError(error));
}
};
}
1 change: 1 addition & 0 deletions packages/react/src/misc/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ export * from './useCurrencies';
export * from './useInvitedProfiles';
export * from './useInviteWallets';
export * from './useModuleMetadata';
export * from './useProfilePrice';
export * from './useResolveAddress';
export * from './useValidateHandle';
export * from './useWasWalletInvited';
Expand Down
42 changes: 42 additions & 0 deletions packages/react/src/misc/useProfilePrice.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { QueryResult } from '@apollo/client';
import { UnspecifiedError } from '@lens-protocol/api-bindings';
import { Amount, Matic } from '@lens-protocol/shared-kernel';
import { useEffect, useState } from 'react';

import { ReadResult, useReadResult } from '../helpers/reads';
import { useProfilePriceController } from './adapters/useProfilePriceController';

/**
* Fetch the onchain cost in Matic associated with minting a new Lens Profile.
*
* @example
* ```tsx
* const { data, error, loading } = useProfilePrice();
* ```
*
* @category Misc
* @group Hooks
*/
export function useProfilePrice(): ReadResult<Amount<Matic>> {
const [price, setPrice] = useState<Amount<Matic>>();
const [error, setError] = useState<UnspecifiedError>();
const fetchPrice = useProfilePriceController();

useEffect(() => {
const fetchData = async () => {
const result = await fetchPrice();

if (result.isFailure()) {
setError(result.error);
return;
}

setPrice(result.value);
};

void fetchData();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

return useReadResult({ error, data: { result: price } } as QueryResult);
}
5 changes: 4 additions & 1 deletion pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit ec15aec

Please sign in to comment.