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 Mar 15, 2024
1 parent 15e505b commit bd76b98
Show file tree
Hide file tree
Showing 9 changed files with 144 additions and 8 deletions.
8 changes: 8 additions & 0 deletions .changeset/eleven-frogs-battle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"@lens-protocol/domain": minor
"@lens-protocol/react": minor
"@lens-protocol/react-native": minor
"@lens-protocol/react-web": minor
---

**feat:** added `useProfilePrice` hook to fetch profile minting price
14 changes: 13 additions & 1 deletion examples/web/src/profiles/UseCreateProfile.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,19 @@
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: prices, loading, error } = useProfilePrice();

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

const maticPrice = prices.matic;

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

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

Expand Down Expand Up @@ -39,6 +50,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
26 changes: 26 additions & 0 deletions packages/domain/src/use-cases/profile/GetProfilePrice.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { Amount, Matic, success } from '@lens-protocol/shared-kernel';

import { IGenericResultPresenter } from '../transactions/IGenericResultPresenter';

export type ProfilePrices = {
matic: Amount<Matic>;
};

export interface IGetProfilePriceGateway {
getMaticPrice(): Promise<Amount<Matic>>;
}

export type IGetProfilePricePresenter = IGenericResultPresenter<ProfilePrices, never>;

export class GetProfilePrice {
constructor(
private readonly gateway: IGetProfilePriceGateway,
private readonly presenter: IGetProfilePricePresenter,
) {}

async execute() {
const matic = await this.gateway.getMaticPrice();

this.presenter.present(success({ matic }));
}
}
1 change: 1 addition & 0 deletions packages/domain/src/use-cases/profile/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export * from './CreateProfile';
export * from './DismissRecommendedProfiles';
export * from './FollowPolicy';
export * from './FollowProfile';
export * from './GetProfilePrice';
export * from './LinkHandle';
export * from './ReportProfile';
export * from './SetProfileMetadata';
Expand Down
7 changes: 0 additions & 7 deletions packages/gated-content/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -116,12 +116,5 @@
"web/index.ts"
],
"exports": true
},
"pnpm": {
"peerDependencyRules": {
"ignoreMissing": [
"react"
]
}
}
}
26 changes: 26 additions & 0 deletions packages/react/src/misc/adapters/ProfilePriceGateway.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { permissionlessCreator } from '@lens-protocol/blockchain-bindings';
import { IGetProfilePriceGateway } from '@lens-protocol/domain/use-cases/profile';
import { Amount, ChainType, Denomination, Matic } from '@lens-protocol/shared-kernel';

import { RequiredConfig } from '../../config';
import { IProviderFactory } from '../../wallet/adapters/IProviderFactory';

export class ProfilePriceGateway implements IGetProfilePriceGateway {
constructor(
private readonly config: RequiredConfig,
private readonly providerFactory: IProviderFactory,
) {}

async getMaticPrice(): Promise<Amount<Matic>> {
const provider = await this.providerFactory.createProvider({ chainType: ChainType.POLYGON });

const contract = permissionlessCreator(
this.config.environment.contracts.permissionlessCreator,
provider,
);

const priceBN = await contract.getProfileWithHandleCreationPrice();

return Amount.matic(Denomination.wei(priceBN.toString()));
}
}
23 changes: 23 additions & 0 deletions packages/react/src/misc/adapters/useProfilePriceController.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { UnspecifiedError } from '@lens-protocol/api-bindings';
import { GetProfilePrice, ProfilePrices } from '@lens-protocol/domain/use-cases/profile';
import { PromiseResult } from '@lens-protocol/shared-kernel';

import { useSharedDependencies } from '../../shared';
import { PromiseResultPresenter } from '../../transactions/adapters/PromiseResultPresenter';
import { ProfilePriceGateway } from './ProfilePriceGateway';

export type ProfilePriceResult = ProfilePrices;

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

return async (): PromiseResult<ProfilePriceResult, UnspecifiedError> => {
const presenter = new PromiseResultPresenter<ProfilePriceResult, never>();
const gateway = new ProfilePriceGateway(config, providerFactory);
const profilePrice = new GetProfilePrice(gateway, presenter);

void profilePrice.execute();

return presenter.asResult();
};
}
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
46 changes: 46 additions & 0 deletions packages/react/src/misc/useProfilePrice.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { QueryResult } from '@apollo/client';
import { UnspecifiedError } from '@lens-protocol/api-bindings';
import { useEffect, useState } from 'react';

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

export type { ProfilePriceResult };

/**
* Retrieve the prices for minting a new Lens Profile, denominated in various currencies.
*
* @example
* ```tsx
* const { data, error, loading } = useProfilePrice();
* ```
*
* @category Misc
* @group Hooks
*/
export function useProfilePrice(): ReadResult<ProfilePriceResult> {
const [prices, setPrices] = useState<ProfilePriceResult>();
const [error, setError] = useState<UnspecifiedError>();
const fetchPrices = useProfilePriceController();

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

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

setPrices(result.value);
};

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

return useReadResult({ error, data: { result: prices } } as QueryResult);
}

0 comments on commit bd76b98

Please sign in to comment.